duanshenglang 8 ヶ月 前
コミット
4378405ae5

+ 0 - 186
lottery/followUp.html

@@ -1,186 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-
-<head>
-  <meta charset="UTF-8">
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="viewport"
-    content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no, viewport-fit=cover" />
-  <title>微分机器人</title>
-  <!--引入 element-ui 的样式,-->
-  <link rel="stylesheet"
-    href="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1742018383195/element-ui.css">
-  <!-- 必须先引入vue,  后使用element-ui -->
-  <script
-    src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1742017957144/vue.js"></script>
-  <!-- 引入element 的组件库-->
-  <script
-    src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1742017747738/element-ui.js"></script>
-  <!-- <script src="https://unpkg.com/vconsole/dist/vconsole.min.js"></script>
-  <script>
-		  var vConsole = new window.VConsole();
-		</script> -->
-</head>
-<style>
-  body {
-    margin: 0;
-    padding: 0;
-  }
-
-  .box {
-    width: 100vw;
-    height: 100vh;
-    box-sizing: border-box;
-    background: #FAFAFA;
-  }
-
-  .page6 {
-    width: 100vw;
-    height: 100vh;
-    box-sizing: border-box;
-  }
-  .tab_list {
-    width: 100%;
-    height: 48px;
-    background: #FFFFFF;
-  }
-  .client_followUp {
-    width: 100vw;
-    height: calc(100vh - 48px);
-    padding: 20px 10px 10px;
-    box-sizing: border-box;
-  }
-  .stage {
-    width: 100%;
-    background: #F5F7FA;
-    border-radius: 5px;
-    padding: 15px;
-    display: flex;
-    align-items: center;
-    font-weight: 400;
-    font-size: 16px;
-    color: #222222;
-    box-sizing: border-box;
-    margin-bottom: 20px;
-  }
-  .stage img {
-    width: 24px;
-    height: 24px;
-    margin-right: 5px; 
-  }
-  .stage_data {
-    font-weight: 500;
-    font-size: 16px;
-    color: #1677FF;
-  }
-  .followup_list {
-    width: 100%;
-    padding: 15px 10px;
-    background: #FFFFFF;
-    border-radius: 10px;
-    box-sizing: border-box;
-  }
-  .follow_time {
-    display: flex;
-    align-items: center;
-    font-weight: 400;
-    font-size: 14px;
-    color: #222222;
-  }
-  .time_dot {
-    background: #E6F0FF;
-    padding: 3px;
-    border-radius: 50%;
-    margin-right: 10px;
-    box-sizing: border-box;
-  }
-  .dot {
-    width: 6px;
-    height: 6px;
-    background: #1677FF;
-    border-radius: 50%;
-  }
-</style>
-
-<body>
-  <div id="box" class="box">
-    <div class="page6">
-      <el-tabs class="tab_list" v-model="activeName" stretch @tab-click="handleClick">
-        <el-tab-pane label="客户画像" name="first"></el-tab-pane>
-        <el-tab-pane label="客户跟进" name="second"></el-tab-pane>
-      </el-tabs>
-      <div class="client_followUp">
-        <div class="stage">
-          <img src="./img/stage.png" />
-          <div>当前阶段:<span class="stage_data">A2兴趣</span></div>
-        </div>
-        <div class="followup_list">
-          <div class="follow_time">
-            <div class="time_dot">
-              <div class="dot"></div>
-            </div>
-            <span>2024-10-23 星期四</span>
-          </div>
-          <div class="follow_item"></div>
-        </div>
-      </div>
-    </div>
-  </div>
-</body>
-<script>
-  new Vue({
-    el: '#box',
-    data() {
-      return {
-        httpUrl: '',
-        bId: null,
-        env: '',
-        activeName: 'first',
-      }
-    },
-    created() {
-      this.bId = this.getQueryParam('bId')
-      this.env = this.getQueryParam('env')
-      if (!this.env || this.env === 'prod') {
-        this.httpUrl = 'https://wlapi.wefanbot.com'
-      } else {
-        this.httpUrl = 'http://test.wefanbot.com:18993'
-      }
-      // 授权
-      // this.getAuth()
-    },
-    methods: {
-      getAuth() {
-        // 获取url上的code
-        let code = this.getQueryParam('code')
-        if (code) {
-          fetch(this.httpUrl + `/scrm/v1/mp-client/p/getInfoByh5Code?code=${code}&bId=${this.bId}`)
-            .then(res => {
-              return res.json()
-            }).then(result => {
-              let { data, code, msg } = result
-              if (code === 1) {
-                this.openId = data.openId
-              }
-            })
-        } else {
-          let redirect_uri = window.location.href
-          // code 不存在,走微信网页授权逻辑 
-          let url = `https://open.weixin.qq.com/connect/oauth2/authorize?appId=wx99ec0d0828a4d2d3&redirect_uri=${redirect_uri}&scope=snsapi_userinfo&state=STATE#wechat_redirect`
-          window.location.replace(url)
-        }
-      },
-      // 截取url中的数据
-      getQueryParam(paramName) {
-        // 获取当前URL的查询字符串部分  
-        const queryString = window.location.search;
-        // 创建一个URLSearchParams对象  
-        const urlParams = new URLSearchParams(queryString);
-        // 返回指定参数的值,如果不存在则返回null  
-        return urlParams.get(paramName);
-      },
-    }
-  })   
-</script>
-
-</html>

+ 273 - 0
lottery/followUpList.html

@@ -0,0 +1,273 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+  <meta charset="UTF-8">
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="viewport"
+    content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no, viewport-fit=cover" />
+  <title>微分机器人</title>
+  <!--引入 element-ui 的样式,-->
+  <link rel="stylesheet"
+    href="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1742018383195/element-ui.css">
+  <!-- 必须先引入vue,  后使用element-ui -->
+  <script
+    src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1742017957144/vue.js"></script>
+  <!-- 引入element 的组件库-->
+  <script
+    src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1742017747738/element-ui.js"></script>
+  <!-- <script src="https://unpkg.com/vconsole/dist/vconsole.min.js"></script>
+  <script>
+		  var vConsole = new window.VConsole();
+		</script> -->
+</head>
+<style>
+  body {
+    margin: 0;
+    padding: 0;
+  }
+
+  .box {
+    width: 100vw;
+    min-height: 100vh;
+    box-sizing: border-box;
+    background: #ECEDF1;
+  }
+
+  .page4 {
+    width: 100vw;
+    box-sizing: border-box;
+    padding: 20px 15px;
+  }
+  .followup_item {
+    width: 100%;
+    background: #FFFFFF;
+    border-radius: 10px;
+    padding: 12px 12px 15px;
+    box-sizing: border-box;
+    margin-bottom: 20px;
+  }
+  .brand {
+    display: flex;
+    align-items: center;
+    padding-bottom: 12px;
+    border-bottom: 1px dashed #CCCCCC;
+    font-weight: 400;
+    font-size: 12px;
+    color: #999999;
+  }
+  .brand img{
+    width: 20px;
+    height: 20px;
+    margin-right: 5px;
+  }
+  .content {  
+    display: flex;
+    align-items: center;
+    padding: 25px 0;
+  }
+  .content img{
+    width: 64px;
+    height: 64px;
+    border-radius: 8px;
+    margin-right: 10px;
+  }
+  .item_msg {
+    flex: 1;
+    font-weight: 400;
+    font-size: 14px;
+    color: #666666;
+  }
+ .item_name {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    font-weight: 500;
+    font-size: 16px;
+    color: #222222;
+    padding-bottom: 10px;
+  }
+  .item_step {
+    font-weight: 500;
+    font-size: 12px;
+    color: #CCCCCC;
+  }
+  .item_btn {
+    width: 100%;
+    font-weight: bold;
+    font-size: 14px;
+    color: #FFFFFF;
+    padding: 10px 0;
+    background: #1677FF;
+    border-radius: 10px;
+    text-align: center;
+  }
+  .loading {
+    text-align: center;
+    margin-top: 10px;
+  }
+  .loading span {
+    display: inline-block;
+    width: 20px;
+    height: 20px;
+    border: 2px solid #409eff;
+    border-left: transparent;
+    animation: zhuan 0.5s linear infinite;
+    border-radius: 50%;
+  }
+  @keyframes zhuan {
+    0% {
+      transform: rotate(0);
+    }
+    100% {
+      transform: rotate(360deg);
+    }
+  }
+  .no_data {
+    text-align: center;
+    color: #999999;
+    font-size: 14px;
+  }
+</style>
+<body>
+  <div id="box" class="box">
+    <!-- 数据查看 -->
+    <div class="page4">
+      <div class="followup_list" v-infinite-scroll="getLoad" :infinite-scroll-disabled="disabled" style="overflow:auto">
+        <div class="followup_item" v-for="(item, index) in followList" :key="index">
+          <div class="brand">
+            <img src="./img/wefan.png" alt="">
+            <span>微分机器人</span>
+          </div>
+          <div class="content">
+            <img :src="item.clientAvatar" />
+            <div class="item_msg">
+              <div class="item_name">
+                <div>{{item.clientName}}</div>
+                <div class="item_step">当前阶段:<span style="color: #1677FF;">{{item.step}}</span></div>
+              </div>
+              <div>该阶段停留时间超过{{item.day}}天</div>
+            </div>
+          </div>
+          <div class="item_btn" @click="toShow(item)">查看</div>
+        </div>
+        <p v-if="loading" class="loading">
+          <span></span>
+        </p>
+        <p v-if="noMore" class="no_data">没有更多了</p>
+      </div>
+    </div>
+  </div>
+</body>
+<script>
+  new Vue({
+    el: '#box',
+    data() {
+      return {
+        httpUrl: '',
+        bId: null,
+        env: '',
+        memberId: null,
+        page: 1,
+        totalPages: 0,
+        followList: [],
+        loading: false,
+      }  
+    },
+    computed: {
+      noMore() {
+        //当起始页数大于总页数时停止加载
+        return this.page >= this.totalPages - 1
+      },
+      disabled() {
+        return this.loading || this.noMore
+      }
+    },
+    created() {
+      this.bId = this.getQueryParam('bId')
+      this.env = this.getQueryParam('env')
+
+      if (!this.env || this.env === 'prod') {
+        this.httpUrl = 'https://wlapi.wefanbot.com'
+      } else {
+        this.httpUrl = 'http://test.wefanbot.com:18993'
+      }
+      if (this.getQueryParam('memberId')) {
+        // 已授权
+        this.memberId = this.getQueryParam('memberId')
+      } else {
+        // 授权
+        this.getAuth()
+      }
+      // this.memberId = "woU17nDAAAnoSca19vZVKiNEKdc9tyYQ"
+      // this.getFollowList()
+    },
+    methods: {
+      getAuth() {
+        fetch(this.httpUrl + `/p/insuite/p/getRedirectUri?env=${this.env}&bId=${this.bId}`)
+          .then(res => {
+            return res.json()
+          }).then(result => {
+            let { data, code, msg } = result
+            if (code === 1) {
+              window.location.replace(data)
+            } else {
+              this.$message({
+                message: msg,
+                type: 'warning'
+              })
+            }
+          })
+      },
+      getFollowList() {
+          fetch(this.httpUrl + '/scrm/v1/wxcp-client-pro/p/stepNoticeList', {
+            method: 'post',
+            body: JSON.stringify({
+              bid: this.bId,
+              memberId: this.memberId,
+              page: this.page,
+              pageCount: 10,
+            }),
+            headers: {
+              'Content-Type': 'application/json'
+            }
+          }).then(res => {
+            return res.json()
+          }).then(result => {
+            let { data, code, msg } = result
+            if (code === 1) {
+              this.followList = this.followList.concat(data.records)
+              this.totalPages = data.pages
+              this.loading = false
+            } else {
+              this.$message({
+                message: msg,
+                type: 'warning'
+              })
+            }
+          })
+      },
+      getLoad() {
+        //滑到底部时进行加载
+        this.loading = true
+        setTimeout(() => {
+          this.page += 1
+          this.getFollowList()
+        }, 2000)
+      },
+      toShow(item) {
+        window.location.href = `userProfile.html?bId=${item.bId}&env=${this.env}&memberId=${this.memberId}&externalUserId=${item.externalUserId}` 
+      },
+      // 截取url中的数据
+      getQueryParam(paramName) {
+        // 获取当前URL的查询字符串部分  
+        const queryString = window.location.search;
+        // 创建一个URLSearchParams对象  
+        const urlParams = new URLSearchParams(queryString);
+        // 返回指定参数的值,如果不存在则返回null  
+        return urlParams.get(paramName);
+      },
+    }
+  })
+</script>
+</html>

BIN
lottery/img/edit.png


+ 8 - 0
lottery/index.html

@@ -767,6 +767,14 @@
 						// 核销
 						var currentQueryParams = window.location.search;
 						window.location.replace('signUp.html' + currentQueryParams)
+					} else if (this.h5Type == 33) {
+						// 跟进列表
+						var currentQueryParams = window.location.search;
+						window.location.replace('followUpList.html' + currentQueryParams)
+					} else if (this.h5Type == 34) {
+						// 客户画像
+						var currentQueryParams = window.location.search;
+						window.location.replace('userProfile.html' + currentQueryParams)
 					} else if (!this.h5Type) {
 						this.getAuth()
 					}

+ 4 - 2
lottery/lightUpWl.html

@@ -105,16 +105,18 @@
     display: flex;
     justify-content: center;
     align-items: center;
-    gap: 10px;
     margin-top: 20px;
   }
 
   .ask_btn img {
     width: 50px;
     height: 50px;
+    margin-right: 10px;
     border-radius: 50%;
   }
-
+  .ask_btn img:last-child {
+    margin-right: 0;
+  }
   .activity_box {
     width: 100%;
     background: #FEE8D0;

+ 20 - 12
lottery/registrationActivity.html

@@ -35,22 +35,31 @@
   .page6 {
     width: 100vw;
     height: 100%;
-    background-size: 100vw 200px;
+    background-size: 100vw 300px;
     background-repeat: no-repeat;
-    display: flex;
-    justify-content: center;
-    align-items: center;
     position: relative;
+    overflow-y: auto;
+  }
+  .enrollment {
+    width: 100%;
+    height: 25px;
+    background: #C30011;
+    opacity: 0.8;
+    font-weight: 400;
+    font-size: 12px;
+    color: #FFFFFF;
+    line-height: 25px;
+    text-align: center;
+    position: fixed;
+    top: 0;
+    left: 0;
   }
-
   .activity_content {
     width: 100%;
-    height: calc(100vh - 180px);
-    margin-top: 180px;
+    margin-top: 250px;
     background: #FFFFFF;
     border-radius: 20px 20px 0px 0px;
     padding: 30px 20px 66px;
-    overflow-y: auto;
     box-sizing: border-box;
   }
 
@@ -78,7 +87,7 @@
   }
 
   .foot_btn {
-    position: absolute;
+    position: fixed;
     bottom: 14px;
     padding: 0 35px;
     width: 100%;
@@ -98,13 +107,11 @@
 
   .form_content {
     width: 100%;
-    height: calc(100vh - 180px);
     position: fixed;
-    top: 180px;
+    top: 250px;
     background: #FFFFFF;
     border-radius: 20px 20px 0px 0px;
     padding: 20px 20px 66px;
-    overflow-y: auto;
     box-sizing: border-box;
   }
 
@@ -339,6 +346,7 @@
       </div>
     </div>
     <div class="page6" :style="{'background-image': 'url('+toshopData.banner+')'}" v-else-if="step === 1 || step === 2">
+      <div class="enrollment">已有23333人参与活动</div>
       <div class="activity_content" v-if="step === 1">
         <div class="activity_item">
           <div class="item_title">活动主题:</div>

+ 1084 - 0
lottery/userProfile.html

@@ -0,0 +1,1084 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+  <meta charset="UTF-8">
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="viewport"
+    content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no, viewport-fit=cover" />
+  <title>微分机器人</title>
+  <!--引入 element-ui 的样式,-->
+  <link rel="stylesheet"
+    href="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1742018383195/element-ui.css">
+  <!-- 必须先引入vue,  后使用element-ui -->
+  <script
+    src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1742017957144/vue.js"></script>
+  <!-- 引入element 的组件库-->
+  <script
+    src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1742017747738/element-ui.js"></script>
+  <!-- <script src="https://unpkg.com/vconsole/dist/vconsole.min.js"></script>
+  <script>
+		  var vConsole = new window.VConsole();
+		</script> -->
+</head>
+<style>
+  body {
+    margin: 0;
+    padding: 0;
+  }
+
+  .box {
+    width: 100vw;
+    height: auto;
+    box-sizing: border-box;
+    background: #FAFAFA;
+  }
+
+  .page6 {
+    width: 100vw;
+    box-sizing: border-box;
+  }
+  .tab_list {
+    width: 100%;
+    height: 48px;
+    background: #FFFFFF;
+  }
+  .client_detail {
+    width: 100vw;
+    min-height: 100vh;
+    padding: 10px 10px 12px;
+    box-sizing: border-box;
+  }
+  .client_msg {
+    width: 100%;
+    background: #FFFFFF;
+    border-radius: 10px;
+    padding: 15px 15px 20px;
+    box-sizing: border-box;
+    margin-bottom: 10px;
+  }
+  .client_wx {
+    display: flex;
+    align-items: center;
+    margin-bottom: 15px;
+  }
+  .client_wx img {
+    width: 64px;
+    height: 64px;
+    border-radius: 8px;
+    margin-right: 12px;
+  }
+  .wx_msg {
+    display: flex;
+    flex-direction: column;
+    font-weight: 500;
+    font-size: 16px;
+    color: #222222;
+  }
+  .wx_tag {
+    color: #05D167;
+    padding-left: 10px;
+  }
+  .add_time {
+    font-weight: 400;
+    font-size: 14px;
+    color: #CCCCCC;
+    padding-top: 10px;
+  }
+  .msg_title {
+    font-weight: 400;
+    font-size: 14px;
+    color: #222222;
+    line-height: 20px;
+    position: relative;
+    display: flex;
+    align-items: center;
+    padding-left: 5px;
+    margin-bottom: 15px;
+    &::before {
+        content: '';
+        position: absolute;
+        width: 3px;
+        height: 12px;
+        left: 0;
+        background: #1677FF;
+        border-radius: 2px;
+    }
+  }
+  .msg_title_line {
+    padding-top: 15px;
+    border-top: 1px dashed #E5E8ED;
+  }
+  .basic_msg {
+    display: flex;
+    flex-wrap: wrap;
+  }
+  .basic_msg_item {
+    font-weight: 400;
+    font-size: 14px;
+    color: #222222;
+    line-height: 20px;
+    margin-bottom: 15px;
+    display: flex;
+    align-items: flex-start;
+    justify-content: flex-start;
+  }
+  .basic_msg_item img {
+    width: 16px;
+    height: 16px;
+    margin-left: 4px;
+    margin-top: 2px;
+  }
+  .basic_msg_data {
+    color: #999999;
+    padding-right: 5px;
+    flex-shrink: 0;
+  }
+  .three_tab_list {
+    width: 100%;
+    height: 58px;
+    background: #FFFFFF;
+  }
+  .three_tab {
+    width: 100%;
+    background: #FFFFFF;
+    border-radius: 10px;
+    padding: 0 10px 10px;
+    box-sizing: border-box;
+  }
+  .data_box {
+    width: 100%;
+    padding: 15px;
+    background: #F7F9FC;
+    border-radius: 5px;
+    margin-bottom: 20px;
+    box-sizing: border-box;
+  }
+  .belong_item {
+    display: flex;
+    align-items: center;
+    margin-bottom: 15px;
+    font-weight: 400;
+    font-size: 14px;
+    color: #222222;
+  }
+  .belong_item:last-child {
+    margin-bottom: 0; 
+  }
+  .belong_title {
+    color: #999999;
+    margin-right: 5px;
+    flex-shrink: 0;
+  }
+  .client_followUp {
+    width: 100vw;
+    height: calc(100vh - 48px);
+    padding: 20px 10px 60px;
+    box-sizing: border-box;
+    overflow-y: auto;
+  }
+  .stage {
+    width: 100%;
+    background: #F5F7FA;
+    border-radius: 5px;
+    padding: 15px;
+    display: flex;
+    align-items: center;
+    font-weight: 400;
+    font-size: 16px;
+    color: #222222;
+    box-sizing: border-box;
+    margin-bottom: 20px;
+  }
+  .stage img {
+    width: 24px;
+    height: 24px;
+    margin-right: 5px; 
+  }
+  .stage_data {
+    font-weight: 500;
+    font-size: 16px;
+    color: #1677FF;
+  }
+  .followup_list {
+    width: 100%;
+    padding: 15px 10px;
+    background: #FFFFFF;
+    border-radius: 10px;
+    box-sizing: border-box;
+  }
+  .follow_time {
+    display: flex;
+    align-items: center;
+    font-weight: 400;
+    font-size: 14px;
+    color: #222222;
+    margin-bottom: 15px;
+  }
+  .time_dot {
+    background: #E6F0FF;
+    padding: 3px;
+    border-radius: 50%;
+    margin-right: 10px;
+    box-sizing: border-box;
+  }
+  .dot {
+    width: 6px;
+    height: 6px;
+    background: #1677FF;
+    border-radius: 50%;
+  }
+  .follow_item {
+    margin-left: 22px;
+    padding-right: 10px;
+    padding-left: 14px;
+    padding-bottom: 6px;
+  }
+  .follow_padding {
+    padding-top: 15px; 
+    padding-bottom: 4px;
+    background: #F7F9FC;
+    border-radius: 5px;
+  }
+  .follow_item_time {
+    font-weight: 500;
+    font-size: 14px;
+    color: #222222;
+    display: flex;
+    align-items: center;
+    margin-bottom: 3px;
+  }
+  .item_time {
+    font-weight: 400;
+    font-size: 12px;
+    color: #999999;
+    padding-right: 10px;
+  }
+  .item_box {
+    display: flex;
+    align-items: flex-end;
+  }
+  .follow_item_line {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    padding-left: 13px;
+    padding-right: 21px;
+  }
+  .line_dot {
+    width: 6px;
+    height: 6px;
+    background: #1677FF;
+    border-radius: 50%;
+    margin-bottom: 5px;
+  }
+  .line {
+      width: 1px;
+      height: 66px;
+      border-left: 1px dashed #1677FF;
+    }
+  .item_content {
+    background: #FFFFFF;
+    border-radius: 5px;
+    padding: 10px;
+    font-weight: 400;
+    font-size: 12px;
+    color: #222222;
+    width: 100%;
+    height: 100%;
+  }
+  .item_tip {
+    font-weight: 400;
+    font-size: 12px;
+    color: #999999;
+    margin-top: 6px;
+  }
+  .item_p {
+    color: #1677FF; 
+  }
+  .tag_list {
+    display: flex;
+    flex-wrap: wrap;
+  }
+  .tag_item {
+    font-weight: 400;
+    font-size: 12px;
+    color: #1677FF;
+    padding: 6px 10px;
+    border-radius: 5px;
+    border: 1px solid #1677FF;
+    margin-right: 10px;
+    margin-bottom: 15px;
+  }
+  .tag_item:last-child {
+    margin-right: 0; 
+  }
+  .read_content {
+    display: flex;
+  }
+  .read_box {
+    width: 100%;
+    padding: 15px 15px 10px;
+    font-weight: 400;
+    font-size: 14px;
+    color: #222222;
+    background: #F7F9FC;
+    border-radius: 5px;
+  }
+  .read_title {
+    padding-bottom: 10px;
+  }
+  .read_num {
+    font-weight: bold;
+    font-size: 20px;
+    color: #222222;
+    line-height: 29px;
+  }
+  
+  .foot_btn {
+    position: fixed;
+    bottom: 10px;
+    padding: 0 35px;
+    width: 100%;
+    box-sizing: border-box;
+  }
+
+  .signUp_btn {
+    height: 50px;
+    width: 100%;
+    background: #1677FF;
+    border-radius: 10px;
+    font-weight: bold;
+    font-size: 14px;
+    color: #FFFFFF;
+    text-align: center;
+  }
+  .el-dialog {
+		width: 335px;
+		border-radius: 20px;
+	}
+
+	.el-dialog__header {
+		text-align: center;
+	}
+
+	.el-dialog__title {
+		font-weight: 500;
+		font-size: 16px;
+		color: #222222;
+	}
+
+	.el-dialog__body {
+		height: 260px;
+		overflow-y: auto;
+	}
+	.prize_form .el-form-item {
+		padding: 0;
+	}
+
+	.prize_form .el-form-item__label {
+		line-height: 20px;
+	}
+
+	.prize_form .el-input {
+		width: 295px;
+	}
+
+	.prize_form .el-input__inner {
+		text-align: left;
+	}
+
+	.prize_form .el-textarea.is-active .el-textarea__inner,
+	.prize_form .el-textarea__inner:focus {
+		border: 1px solid #1677FF;
+	}
+
+	.el-radio__input.is-checked .el-radio__inner {
+		border-color: #1677FF;
+		background: #1677FF;
+	}
+
+	.el-radio__input.is-checked+.el-radio__label {
+		color: #1677FF;
+	}
+  .el-radio {
+    margin-top: 10px;
+  }
+	.el-select .el-input.is-focus .el-input__inner {
+		border-color: #1677FF;
+	}
+
+	.dialog-footer {
+		text-align: center;
+	}
+
+	.dialog-footer button {
+		width: 100%;
+		height: 46px;
+		background: #1677FF;
+		border-radius: 20px;
+		font-weight: 500;
+		font-size: 16px;
+		color: #FFFFFF;
+		border: none;
+	}
+</style>
+
+<body>
+  <div id="box" class="box">
+    <div class="page6">
+      <el-tabs class="tab_list" v-model="activeName" stretch @tab-click="handleClick">
+        <el-tab-pane label="客户画像" name="first"></el-tab-pane>
+        <el-tab-pane label="客户跟进" name="second"></el-tab-pane>
+      </el-tabs>
+      <div class="client_detail" v-if="activeName ==='first'">
+        <div class="client_msg">
+          <div class="client_wx">
+            <img :src="clientData.avatar" />
+            <div class="wx_msg">
+              <div>{{clientData.name}}<span class="wx_tag">@微信</span></div>
+              <div class="add_time">添加时间:{{clientData.addTime}}</div>
+            </div>
+          </div>
+          <div class="msg_title msg_title_line">基本信息</div>
+          <div class="basic_msg" style="width: 100%;">
+            <div class="basic_msg_item" style="width: 50%;">
+              <span class="basic_msg_data">姓名:</span>
+              <span>{{clientData.realName}}</span>
+            </div>
+            <div class="basic_msg_item" style="width: 50%;">
+              <span class="basic_msg_data">手机:</span>
+              <span>{{clientData.phone}}</span>
+              <img src="./img/edit.png" alt="" @click="handleEdit('手机', clientData.phone, 'phone')">
+            </div>
+            <div class="basic_msg_item" style="width: 50%;">
+              <span class="basic_msg_data">省市:</span>
+              <span>{{clientData.province}}-{{clientData.city}}</span>
+            </div>
+            <div class="basic_msg_item" style="width: 50%;">
+              <span class="basic_msg_data">意向车型:</span>
+              <span>{{clientData.intenModel}}</span>
+            </div>
+            <div class="basic_msg_item" style="width: 50%;">
+              <span class="basic_msg_data">已购车型:</span>
+              <span>{{clientData.buyModel}}</span>
+            </div>
+            <div class="basic_msg_item" style="width: 50%;" v-for="(item, index) in clientData.cols">
+              <span class="basic_msg_data">{{item.name}}:</span>
+              <span v-if="item.value">{{item.value[0]}}</span>
+              <img src="./img/edit.png" alt="" @click="handleEditOther">
+            </div>
+          </div>
+          <!-- <div class="msg_title msg_title_line">服务信息</div>
+          <div class="basic_msg">
+            <div class="basic_msg_item">
+              <span class="basic_msg_data">上次到店时间:</span>
+              <span>2024/03/10 12:30:53</span>
+            </div>
+            <div class="basic_msg_item">
+              <span class="basic_msg_data">到店业务类型:</span>
+              <span>维修</span>
+            </div>
+            <div class="basic_msg_item">
+              <span class="basic_msg_data">备注:</span>
+              <span>水电费收到水电费收到水电费收到水电费收到水电费收到</span>
+            </div>
+          </div> -->
+        </div>
+        <div class="three_tab">
+          <el-tabs class="three_tab_list" v-model="itemActiveName" stretch @tab-click="handleDetailTab">
+            <el-tab-pane label="画像" name="first"></el-tab-pane>
+            <el-tab-pane label="记录" name="second"></el-tab-pane>
+            <!-- <el-tab-pane label="车辆" name="third"></el-tab-pane> -->
+          </el-tabs>
+          <div v-if="itemActiveName === 'first'">
+            <div class="data_box">
+              <div class="belong_item">
+                <div class="belong_title">所属成员:</div>
+                <template v-if="clientData.memberList">
+                  <div v-if="clientData.memberList.length > 1">
+                    {{ clientData.memberList[0] }}等<span style="color: #1677FF;">{{ clientData.memberList.length }}</span>人
+                  </div>
+                  <div v-else-if="clientData.memberList.length === 1">
+                    {{ clientData.memberList[0] }}
+                  </div>
+                </template>
+              </div>
+              <div class="belong_item">
+                <div class="belong_title">所在群聊:</div>
+                <template v-if="clientData.groupChatList">
+                  <div v-if="clientData.groupChatList.length > 1">
+                    「{{ clientData.groupChatList[0] }}」等<span style="color: #1677FF;">{{ clientData.groupChatList.length }}</span>个群聊
+                  </div>
+                  <div v-else-if="clientData.groupChatList.length === 1">
+                    「{{ clientData.groupChatList[0] }}」
+                  </div>
+                </template>
+              </div>
+            </div>
+            <div class="msg_title">客户阶段</div>
+            <div class="data_box">
+              <div class="belong_item">
+                <div class="belong_title">当前阶段:</div>
+                <div style="color: #1677FF;" v-if="clientData.stepList && clientData.stepList.length">
+                  <span v-for="(item, i) in clientData.stepList" :key="i">「{{ item }}」</span>
+                </div>
+              </div>
+            </div>
+            <div class="msg_title">客户标签</div>
+            <div class="data_box" style="padding-bottom: 0;">
+              <div class="tag_list">
+                <span class="tag_item" v-for="(item, i) in clientData.tagList" :key="i">{{ item }}</span>
+              </div>
+            </div>
+          </div>
+          <div v-if="itemActiveName === 'second'">
+            <!-- <div class="read_content">
+              <div class="read_box" style="margin-right: 10px;">
+                <div class="read_title">阅读次数</div>
+                <div><span class="read_num">7282</span> 次</div>
+              </div>
+              <div class="read_box">
+                <div class="read_title">平均阅读时长</div>
+                <div><span class="read_num">7282</span> min</div>
+              </div>
+            </div> -->
+            <div class="followup_list" v-for="(item, key) in recordList" :key="key">
+              <div class="follow_time">
+                <div class="time_dot">
+                  <div class="dot"></div>
+                </div>
+                <span>{{key}}</span>
+              </div>
+              <div class="follow_padding">
+                <div class="follow_item" v-for="(dt, dtIndex) in item" :key="dtIndex">
+                  <div class="follow_item_time">
+                    <span class="item_time">{{timeFormat(dt.createdTime, 'hh:mm')}}</span>
+                    <span v-if="dt.type === 1">阅读日志</span>
+                    <span v-else-if="dt.type === 2">行为日志</span>
+                    <span v-else-if="dt.type === 3">修改日志</span>
+                  </div>
+                  <div class="item_box">
+                    <div class="follow_item_line">
+                      <div class="line_dot"></div>
+                      <div class="line"></div>
+                    </div>
+                    <div class="item_content">
+                      <div>{{dt.title}}</div>
+                      <div class="item_tip">{{dt.content}}</div>
+                      <div class="item_tip" v-if="dt.type === 1">持续时间:<span class="item_p">{{dt.duration}}</span>秒</div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+      <div class="client_followUp" v-if="activeName === 'second'">
+        <div class="stage">
+          <img src="./img/stage.png" />
+          <div>当前阶段:<span class="stage_data" v-for="(item, key) in stepData" :key="key">「{{item}}」</span></div>
+        </div>
+        <div class="followup_list" v-for="(item, key) in stepFollowList" :key="key">
+          <div class="follow_time">
+            <div class="time_dot">
+              <div class="dot"></div>
+            </div>
+            <span>{{item.date}}</span>
+          </div>
+          <div class="follow_padding">
+            <div class="follow_item" v-for="(c, cIndex) in item.content" :key="cIndex">
+              <div class="follow_item_time">
+                <span class="item_time">{{timeFormat(c.updatedTime, 'hh:mm')}}</span>跟进方式:
+                <span v-if="item.followType === 0">电话联系</span>
+                <span v-else-if="item.followType === 1">面聊</span>
+                <span v-else-if="item.followType === 2">微信联系</span>
+                <span v-else-if="item.followType === 3">线上会议</span>
+                <span v-else-if="item.followType === 4">其他</span>
+              </div>
+              <div class="item_box">
+                <div class="follow_item_line">
+                  <div class="line_dot"></div>
+                  <div class="line"></div>
+                </div>
+                <div class="item_content">
+                  <div>{{c.remark}}</div>
+                  <div class="item_tip">跟进成员:由<span class="item_p">「{{c.memberName}}」</span>跟进</div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+        <div class="foot_btn">
+          <el-button class="signUp_btn" :loading="loading" @click="toSignUp">去跟进</el-button>
+        </div>
+      </div>
+    </div>
+    <el-dialog title="添加客户跟进" :visible.sync="showDialog">
+      <el-form :model="form" class="prize_form">
+        <el-form-item label="跟进方式:" required>
+          <el-radio-group v-model="form.followType">
+            <el-radio :label="0">电话联系</el-radio>
+            <el-radio :label="1">面聊</el-radio>
+            <el-radio :label="2">微信联系</el-radio>
+            <el-radio :label="3">线上会议</el-radio>
+            <el-radio :label="4">其他跟进</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="跟进内容:" required>
+          <el-input v-model="form.remark" type="textarea" autosize></el-input>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="handleSave">确定</el-button>
+      </div>
+    </el-dialog>
+    <el-dialog title="编辑信息" :visible.sync="showEditDialog">
+      <el-form class="prize_form">
+        <el-form-item :label="item.name" required v-for="(item, index) in editFormList" :key="index">
+          <el-input v-model="item.value[0]"></el-input>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="handleEditSave">确定</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</body>
+<script>
+  new Vue({
+    el: '#box',
+    data() {
+      return {
+        httpUrl: '',
+        bId: null,
+        env: '',
+        memberId: null,
+        externalUserId: null,
+        activeName: 'first',
+        itemActiveName: 'first',
+        clientData: {},
+        recordList: {},
+        stepData: [], // 阶段
+        stepFollowList: [], // 跟进数据
+        showDialog: false,
+        form: {
+          followType: 0,
+          remark: '' 
+        },
+        loading: false,
+        showEditDialog: false,
+        editFormList: [],
+        editType: '',
+      }
+    },
+    created() {
+      this.bId = this.getQueryParam('bId')
+      this.env = this.getQueryParam('env')
+      if (!this.env || this.env === 'prod') {
+        this.httpUrl = 'https://wlapi.wefanbot.com'
+      } else {
+        this.httpUrl = 'http://test.wefanbot.com:18993'
+      }
+      if (this.getQueryParam('memberId')) {
+        // 已授权
+        this.memberId = this.getQueryParam('memberId')
+        this.getQyWxSign()
+      } else {
+        // 授权
+        this.getAuth()
+      }
+      // this.memberId = "woU17nDAAAnoSca19vZVKiNEKdc9tyYQ"
+      // this.externalUserId = "wmU17nDAAAqZkemA_hZuM5JIIYoA_GIA"
+      // this.getClientExt()
+    },
+    methods: {
+      getAuth() {
+        fetch(this.httpUrl + `/p/insuite/p/getRedirectUri?env=${this.env}&bId=${this.bId}`)
+          .then(res => {
+            return res.json()
+          }).then(result => {
+            let { data, code, msg } = result
+            if (code === 1) {
+              window.location.replace(data)
+            } else {
+              this.$message({
+                message: msg,
+                type: 'warning'
+              })
+            }
+          })
+      },
+      getQyWxSign() {
+        fetch(this.httpUrl + '/scrm/v1/wxcp-corp/p/getAgentConfig', {
+          method: 'post',
+          body: JSON.stringify({
+            bId: this.bId,
+            url: window.location.href,
+          }),
+          headers: {
+            'Content-Type': 'application/json'
+          }
+        }).then(res => {
+          return res.json()
+        }).then(result => {
+          let { data, code, msg } = result
+          if (code === 1) {
+            let that = this
+            wx.agentConfig({
+              corpid: data.corpid,
+              agentid: data.agentId,
+              timestamp: data.timestamp, // 必填,生成签名的时间戳
+              nonceStr: data.nonceStr, // 必填,生成签名的随机串
+              signature: data.agentSignature, // 必填,签名,见附录1
+              jsApiList: ['getCurExternalContact'], // 必填,需要使用的JS接口列表
+              success: function (res) {
+                // 回调
+                // 此处直接在注入回调中调用了获取当前外部联系人userId的接口,注意此接口是从聊天框的工具栏进入才能获取
+                wx.invoke('getCurExternalContact', {
+                }, function (res) {
+                  if (res.err_msg == "getCurExternalContact:ok") {
+                    console.log('invoke成功:', res.userId);
+                    that.externalUserId = res.userId
+                    that.getClientExt()
+                  } else {
+                    //错误处理
+                    console.log('invoke失败:', res)
+                  }
+                });
+
+              },
+              fail: function (res) {
+                if (res.errMsg.indexOf('function not exist') > -1) {
+                  alert('版本过低请升级');
+                }
+              },
+              complete: function (res) {
+                // 回调
+                console.log('complete1', res);
+              }
+            });
+
+          } else {
+            this.$message({
+              message: msg,
+              type: 'warning'
+            })
+          }
+        })
+      },
+      handleClick(tab) {
+        this.activeName = tab.name
+        if (tab.name ==='first') {
+          this.getClientExt() 
+        } else if (tab.name === 'second') {
+          this.getClientFollow()
+        }
+      },
+      getClientFollow() {
+        // 获取阶段
+        this.getStep()
+        // 获取阶段跟进数据
+        this.getStepFollow()
+      },
+      // 获取客户画像
+      getClientExt() {
+        fetch(this.httpUrl + `/scrm/v1/wxcp-client-pro/p/clientExt?bId=${this.bId}&externalUserId=${this.externalUserId}&memberId=${this.memberId}`)
+          .then(res => {
+            return res.json()
+          }).then(result => {
+            let { data, code, msg } = result
+            if (code === 1) {
+              this.clientData = data
+              if (this.clientData.cols && this.clientData.cols.length) {
+                this.clientData.cols.forEach(item => {
+                  if (!item.value) {
+                    item.value = []
+                  }
+                })
+              }
+            } else {
+              this.$message({
+                message: msg,
+                type: 'warning'
+              })
+            }
+          })
+      },
+      handleDetailTab(tab) {
+        this.itemActiveName = tab.name
+        if (tab.name === 'second') {
+          this.getClientLog()
+        }
+      },
+      // 客户画像-记录
+      getClientLog() {
+        fetch(this.httpUrl + '/scrm/v1/wxcp-client-pro/p/clientLog', {
+          method: 'post',
+          body: JSON.stringify({
+            bid: this.bId,
+            externalUserId: this.externalUserId,
+            memberId: this.memberId,
+            page: 1,
+            pageCount: 1000,
+          }),
+          headers: {
+            'Content-Type': 'application/json'
+          }
+        }).then(res => {
+          return res.json()
+        }).then(result => {
+          let { data, code, msg } = result
+          if (code === 1) {
+            this.recordList = data
+          } else {
+            this.$message({
+              message: msg,
+              type: 'warning'
+            })
+          }
+        })
+      },
+      // 获取阶段
+      getStep() {
+        fetch(this.httpUrl + `/scrm/v1/wxcp-client-pro/p/clientStepList?bId=${this.bId}&externalUserId=${this.externalUserId}`)
+          .then(res => {
+            return res.json()
+          }).then(result => {
+            let { data, code, msg } = result
+            if (code === 1) {
+              this.stepData = data
+            } else {
+              this.$message({
+                message: msg,
+                type: 'warning'
+              })
+            }
+          })
+      },
+      // 获取阶段跟进数据
+      getStepFollow() {
+        fetch(this.httpUrl + '/scrm/v1/wxcp-client-pro/p/clientFollow', {
+          method: 'post',
+          body: JSON.stringify({
+            bid: this.bId,
+            externalUserId: this.externalUserId,
+            memberId: this.memberId,
+            page: 1,
+            pageCount: 1000,
+          }),
+          headers: {
+            'Content-Type': 'application/json'
+          }
+        }).then(res => {
+          return res.json()
+        }).then(result => {
+          let { data, code, msg } = result
+          if (code === 1) {
+            let arr = this.groupDataByDate(data.records)
+            this.stepFollowList = arr.reverse()
+          } else {
+            this.$message({
+              message: msg,
+              type: 'warning'
+            })
+          }
+        })
+      },
+      // 按日期分组数据
+      groupDataByDate(data) {
+        const grouped = {}
+        // 按日期分组
+        data.forEach(item => {
+          const dateStr = item.updatedTime.slice(0, 10); // 提取年月日
+          if (!grouped[dateStr]) {
+            grouped[dateStr] = []
+          }
+          grouped[dateStr].push(item)
+        })
+        // 转换为指定格式并排序
+        return Object.keys(grouped)
+          .sort() // 按日期升序排列
+          .map(date => ({
+            date,
+            content: grouped[date]
+          }))
+      },
+      toSignUp() {
+        this.showDialog = true
+        this.form = {
+          followType: 0,
+          remark: ''
+        }
+      },
+      // 添加客户跟进
+      handleSave() {
+        fetch(this.httpUrl + '/scrm/v1/wxcp-client-pro/p/addFollow', {
+          method: 'post',
+          body: JSON.stringify({
+            bid: this.bId,
+            externalUserId: this.externalUserId,
+            memberId: this.memberId,
+            followType: this.form.followType,
+            remark: this.form.remark,
+          }),
+          headers: {
+            'Content-Type': 'application/json'
+          }
+        }).then(res => {
+          return res.json()
+        }).then(result => {
+          let { data, code, msg } = result
+          if (code === 1) {
+            this.showDialog = false
+            this.getClientFollow()
+            this.$message({
+              message: '添加成功',
+              type: 'success' 
+            })
+          } else {
+            this.$message({
+              message: msg,
+              type: 'warning'
+            })
+          }
+        })
+      },
+      // 编辑手机号
+      handleEdit(title, value, type) {
+        this.editFormList = [{
+          name: title,
+          type: 0,
+          value: [value]
+        }]
+        this.editType = type
+        this.showEditDialog = true 
+      },
+      // 编辑其他字段
+      handleEditOther() {
+        this.editFormList = this.clientData.cols
+        this.editType = 'other'
+        this.showEditDialog = true
+      },
+      handleEditSave() {
+        if (this.editType === 'phone') {
+          this.editPhone()
+        } else if (this.editType === 'other') {
+          this.editOthers()
+        }
+      },
+      // 修改手机号
+      editPhone() {
+        fetch(this.httpUrl + `/scrm/v1/wxcp-client-pro/p/updatePhone?bId=${this.bId}&externalUserId=${this.externalUserId}&memberId=${this.memberId}&phone=${this.editFormList[0].value[0]}`)
+          .then(res => {
+            return res.json()
+          }).then(result => {
+            let { data, code, msg } = result
+            if (code === 1) {
+              this.showEditDialog = false
+              this.getClientExt()
+              this.$message({
+                message: '编辑成功',
+                type: 'success'
+              })
+            } else {
+              this.$message({
+                message: msg,
+                type: 'warning'
+              })
+            }
+          })
+      },
+      // 编辑其他字段
+      editOthers() {
+        fetch(this.httpUrl + '/scrm/v1/wxcp-client-pro/p/updateExt', {
+          method: 'post',
+          body: JSON.stringify({
+            bid: this.bId,
+            externalUserId: this.externalUserId,
+            memberId: this.memberId,
+            cols: this.clientData.cols
+          }),
+          headers: {
+            'Content-Type': 'application/json'
+          }
+        }).then(res => {
+          return res.json()
+        }).then(result => {
+          let { data, code, msg } = result
+          if (code === 1) {
+            this.showEditDialog = false
+            this.getClientExt()
+            this.$message({
+              message: '添加成功',
+              type: 'success'
+            })
+          } else {
+            this.$message({
+              message: msg,
+              type: 'warning'
+            })
+          }
+        })
+      },
+      // 截取url中的数据
+      getQueryParam(paramName) {
+        // 获取当前URL的查询字符串部分  
+        const queryString = window.location.search;
+        // 创建一个URLSearchParams对象  
+        const urlParams = new URLSearchParams(queryString);
+        // 返回指定参数的值,如果不存在则返回null  
+        return urlParams.get(paramName);
+      },
+      timeFormat(time, format = 'yyyy-MM-dd hh:mm:ss') {
+        if (time === undefined || time === '' || time === null) {
+          return '/';
+        }
+
+        const date = new Date(time);
+        const o = {
+          'M+': date.getMonth() + 1, // 月份
+          'd+': date.getDate(),      // 日
+          'h+': date.getHours(),     // 小时
+          'm+': date.getMinutes(),   // 分钟
+          's+': date.getSeconds(),   // 秒
+          'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
+          'S': date.getMilliseconds() // 毫秒
+        };
+
+        // 处理年份
+        if (/(y+)/.test(format)) {
+          format = format.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
+        }
+
+        // 处理日期和时间部分
+        for (let k in o) {
+          if (new RegExp('(' + k + ')').test(format)) {
+            let value = o[k];
+            let padding = RegExp.$1.length === 1 ? '' : '00'; // 根据格式字符串中的长度决定是否补零
+            format = format.replace(RegExp.$1, ('' + value).padStart(padding.length + value.toString().length - value.toString().length, '0'));
+          }
+        }
+
+        // 如果格式只包含时间部分,移除日期部分可能的占位符
+        if (!/(M+|d+)/.test(format)) {
+          // 移除任何可能存在的日期占位符(如:'yyyy-MM-dd ')
+          format = format.replace(/(\s*-\s*){2}/g, ''); // 移除两个'-'之间的任何内容
+          format = format.replace(/^\s*yyyy-\s*/, ''); // 移除开头的'yyyy-'
+        }
+
+        // 如果格式只包含日期部分,移除时间部分可能的占位符
+        if (!/(h+|m+|s+)/.test(format)) {
+          // 移除任何可能存在的时间占位符(如:' hh:mm:ss')
+          format = format.replace(/(\s*:\s*){2}/g, ''); // 移除两个':'之间的任何内容
+          format = format.replace(/\s*hh:\s*$/, ''); // 移除结尾的' hh:'
+        }
+
+        return format;
+      }
+    }
+  })   
+</script>
+
+</html>