duanshenglang 1 неделя назад
Родитель
Сommit
f1dd8d032b
47 измененных файлов с 8078 добавлено и 0 удалено
  1. 97 0
      lottery/css/select-tag.css
  2. BIN
      lottery/img/qw/ai_call.png
  3. BIN
      lottery/img/qw/article.png
  4. BIN
      lottery/img/qw/client_add.png
  5. BIN
      lottery/img/qw/client_all.png
  6. BIN
      lottery/img/qw/client_mass.png
  7. BIN
      lottery/img/qw/close_icon.png
  8. BIN
      lottery/img/qw/cs.png
  9. BIN
      lottery/img/qw/file.png
  10. BIN
      lottery/img/qw/form.png
  11. BIN
      lottery/img/qw/group_mass.png
  12. BIN
      lottery/img/qw/hhxs.png
  13. BIN
      lottery/img/qw/home_bg.png
  14. BIN
      lottery/img/qw/khdt.png
  15. BIN
      lottery/img/qw/link-icon.png
  16. BIN
      lottery/img/qw/link.png
  17. BIN
      lottery/img/qw/market_bg.png
  18. BIN
      lottery/img/qw/more_icon.png
  19. BIN
      lottery/img/qw/no_task.png
  20. BIN
      lottery/img/qw/play_icon.png
  21. BIN
      lottery/img/qw/pyq_mass.png
  22. BIN
      lottery/img/qw/reach_tools.png
  23. BIN
      lottery/img/qw/search_icon.png
  24. BIN
      lottery/img/qw/tabbar-client.png
  25. BIN
      lottery/img/qw/tabbar-client1.png
  26. BIN
      lottery/img/qw/tabbar-home.png
  27. BIN
      lottery/img/qw/tabbar-home1.png
  28. BIN
      lottery/img/qw/tabbar-market.png
  29. BIN
      lottery/img/qw/tabbar-market1.png
  30. BIN
      lottery/img/qw/task_icon.png
  31. BIN
      lottery/img/qw/time_icon.png
  32. BIN
      lottery/img/qw/time_select.png
  33. BIN
      lottery/img/qw/to-do.png
  34. BIN
      lottery/img/qw/ts.png
  35. BIN
      lottery/img/qw/xsjc.png
  36. BIN
      lottery/img/qw/yxkh.png
  37. 4 0
      lottery/index.html
  38. 97 0
      lottery/js/select-tag.js
  39. 1263 0
      lottery/qw.html
  40. 186 0
      lottery/qw/clientGroupDetail.html
  41. 348 0
      lottery/qw/clientMass.html
  42. 727 0
      lottery/qw/clientMassDetail.html
  43. 427 0
      lottery/qw/mass.html
  44. 4017 0
      lottery/qw/qwJxs.html
  45. 446 0
      lottery/qw/taskDetail.html
  46. 241 0
      lottery/qw/toDoTask.html
  47. 225 0
      lottery/qw/toDoTaskList.html

+ 97 - 0
lottery/css/select-tag.css

@@ -0,0 +1,97 @@
+.clientTag_title {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 13px 15px;
+  box-sizing: border-box;
+  font-weight: 500;
+  font-size: 14px;
+  color: #222222;
+  line-height: 20px;
+}
+
+.close_icon {
+  width: 24px;
+  height: 24px;
+}
+
+.search_box {
+  padding: 0 15px;
+}
+
+.check_group {
+  display: flex;
+  align-items: center;
+  gap: 20px;
+  padding: 15px 15px 5px;
+}
+
+.tag_list {
+  height: 366px;
+  overflow: auto;
+}
+
+.tag_item {
+  padding: 15px;
+  border-bottom: 1px solid #F1F1F1;
+}
+
+.tag_item_title {
+  font-size: 14px;
+  color: #222222;
+  line-height: 20px;
+  padding-bottom: 15px;
+}
+
+.tag_item_data {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 10px;
+}
+
+.tag_item_data span {
+  height: 25px;
+  font-size: 12px;
+  color: #999999;
+  padding: 4px 8px;
+  box-sizing: border-box;
+  background: #FAFAFA;
+  border-radius: 5px;
+  border: 1px solid #F1F1F1;
+}
+
+.tag_footer {
+  display: flex;
+  align-items: center;
+  padding: 10px 29px 10px 30px;
+  box-sizing: border-box;
+  gap: 10px;
+  box-shadow: 0px -3px 6px 1px rgba(0, 0, 0, 0.05);
+}
+
+.tag_re_btn {
+  height: 50px;
+  font-weight: 500;
+  font-size: 14px;
+  color: #999999;
+  line-height: 20px;
+  padding: 15px 62px 15px 63px;
+  box-sizing: border-box;
+  background: #FFFFFF;
+  border-radius: 20px;
+  border: 1px solid #CCCCCC;
+  white-space: nowrap;
+}
+
+.tag_ok_btn {
+  height: 50px;
+  font-weight: 500;
+  font-size: 14px;
+  color: #FFFFFF;
+  line-height: 20px;
+  padding: 15px 62px 15px 63px;
+  box-sizing: border-box;
+  background: #1677FF;
+  border-radius: 20px;
+  white-space: nowrap;
+}

BIN
lottery/img/qw/ai_call.png


BIN
lottery/img/qw/article.png


BIN
lottery/img/qw/client_add.png


BIN
lottery/img/qw/client_all.png


BIN
lottery/img/qw/client_mass.png


BIN
lottery/img/qw/close_icon.png


BIN
lottery/img/qw/cs.png


BIN
lottery/img/qw/file.png


BIN
lottery/img/qw/form.png


BIN
lottery/img/qw/group_mass.png


BIN
lottery/img/qw/hhxs.png


BIN
lottery/img/qw/home_bg.png


BIN
lottery/img/qw/khdt.png


BIN
lottery/img/qw/link-icon.png


BIN
lottery/img/qw/link.png


BIN
lottery/img/qw/market_bg.png


BIN
lottery/img/qw/more_icon.png


BIN
lottery/img/qw/no_task.png


BIN
lottery/img/qw/play_icon.png


BIN
lottery/img/qw/pyq_mass.png


BIN
lottery/img/qw/reach_tools.png


BIN
lottery/img/qw/search_icon.png


BIN
lottery/img/qw/tabbar-client.png


BIN
lottery/img/qw/tabbar-client1.png


BIN
lottery/img/qw/tabbar-home.png


BIN
lottery/img/qw/tabbar-home1.png


BIN
lottery/img/qw/tabbar-market.png


BIN
lottery/img/qw/tabbar-market1.png


BIN
lottery/img/qw/task_icon.png


BIN
lottery/img/qw/time_icon.png


BIN
lottery/img/qw/time_select.png


BIN
lottery/img/qw/to-do.png


BIN
lottery/img/qw/ts.png


BIN
lottery/img/qw/xsjc.png


BIN
lottery/img/qw/yxkh.png


+ 4 - 0
lottery/index.html

@@ -204,6 +204,10 @@
 						// 意向客户列表
 						var currentQueryParams = window.location.search;
 						window.location.replace('intentionClient.html' + currentQueryParams)
+					} else if (this.h5Type == 45) {
+						// 意向客户列表
+						var currentQueryParams = window.location.search;
+						window.location.replace('qw.html' + currentQueryParams)
 					} else if (!this.h5Type && this.bId) {
 						this.getAuth()
 					}

+ 97 - 0
lottery/js/select-tag.js

@@ -0,0 +1,97 @@
+var demo_str = `
+  <van-popup v-model="popupVisible" duration="0.2" round position="bottom" :close-on-click-overlay="false" :style="{ width: '100%', height: '566px' }">
+    <div class="clientTag_title">
+      <div class="close_icon"></div>
+      <div>按客户标签筛选</div>
+      <img class="close_icon" src="./img/qw/close_icon.png" alt="" @click="popupVisible = false">
+    </div>
+    <div class="search_box">
+      <van-search class="search_input" placeholder="搜索客户昵称/客户群昵称" v-model="keyword" search :clearable="false" left-icon="" @search="handleSearch">
+        <!-- 自定义右侧图标 -->
+        <template v-slot:right-icon>
+          <img class="search_icon" src="./img/qw/search_icon.png" alt="" @click="handleSearch" />
+        </template>
+      </van-search>
+    </div>
+    <div class="check_group">
+      <van-checkbox v-model="tagType" @click="changeTagType(e)">
+        <template #icon="props">
+          <div :class="props.tagType ? 'check_div_active' : 'check_div'"></div>
+        </template>
+        <span>标签满足其一</span>
+      </van-checkbox>
+      <van-checkbox v-model="tagType" @click="changeTagType(e)">
+        <template #icon="props">
+          <div :class="props.tagType ? 'check_div_active' : 'check_div'"></div>
+        </template>
+        <span>标签同时满足</span>
+      </van-checkbox>
+    </div>
+    <div class="tag_list">
+      <div class="tag_item">
+        <div class="tag_item_title">标签名称</div>
+        <div class="tag_item_data">
+          <span>标签名称</span><span>标签名称</span><span>标签名称</span><span>标签名称</span><span>标签名称</span>
+        </div>
+      </div>
+      <div class="tag_item">
+        <div class="tag_item_title">标签名称</div>
+        <div class="tag_item_data">
+          <span>标签名称</span><span>标签dsfgdf名称</span><span>标签名称</span><span>标签名ds称</span><span>标签名称</span>
+        </div>
+      </div>
+    </div>
+    <div class="tag_footer">
+      <div class="tag_re_btn" @click="handleTagClick('重选')">重选</div>
+      <div class="tag_ok_btn" @click="handleTagClick('确定')">确定</div>
+    </div>
+  </van-popup>
+`
+var demoComponent = Vue.extend({
+  template:demo_str ,
+  data:function(){
+    return {
+      keyword: '',
+      tagType: false,
+      popupVisible: this.showClientTag, // 本地状态,避免直接修改 prop
+    }
+  },
+  props: {
+    showClientTag: {
+      type: Boolean,
+      default: () => false
+    }
+  },
+  watch: {
+    // 外部修改时同步到内部
+    showClientTag(val) {
+      this.popupVisible = val
+    },
+    // 内部关闭/打开时告知父级
+    popupVisible(val) {
+      this.$emit('update:showClientTag', val)
+    }
+  },
+  created() {
+  },
+  methods: {
+    changeTagType(e) {
+      // this.tagType = e.target.tagType
+    },
+    handleTagClick(type) {
+      if (type === '重选') {
+        this.keyword = ''
+        this.tagType = false
+      } else if (type === '确定') {
+        // this.$emit('change-tag', {
+        //   keyword: this.keyword,
+        //   tagType: this.tagType,
+        // })
+      }
+    },
+    handleSearch () {}
+  },
+})
+
+Vue.component('select-tag',demoComponent )  //注:此处my-demo就是html中组件的名字
+

+ 1263 - 0
lottery/qw.html

@@ -0,0 +1,1263 @@
+<!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>
+  <!-- 引入样式文件 -->
+  <link rel="stylesheet"
+    href="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1758012584633/vant.css" />
+  <link rel="stylesheet" href="css/select-tag.css">
+  <!-- 必须先引入vue,  后使用vant-ui -->
+  <script
+    src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1742017957144/vue.js"></script>
+  <!-- 引入vant的组件库-->
+  <!-- 引入 Vant 的 JS 文件 -->
+  <script
+    src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1758012748487/vant.min.js"></script>
+  
+  <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
+  <script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js"></script>
+  <script src="js/select-tag.js"></script>
+  <script src="js/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: #F7F9FC;
+  }
+
+  .page5 {
+    width: 100vw;
+    height: 100vh;
+    box-sizing: border-box;
+  }
+  .tabbar {
+    width: 100%;
+    height: 46px;
+    background: #FFFFFF;
+    box-shadow: 0px -10px 20px 1px rgba(62,89,132,0.03);
+    border-radius: 20px 20px 0px 0px;
+    position: fixed;
+    bottom: 0;
+    left: 0;
+    z-index: 1;
+    font-size: 10px;
+    color: #858F9B;
+  }
+  .tabbar_box {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 0 60px;
+  }
+  .tabbar_item {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+  }
+  .tabbar_text {
+    font-size: 10px;
+    color: #7D97BF;
+    line-height: 15px;
+  }
+  .tabbar_text_active {
+    font-size: 10px;
+    line-height: 15px;
+    color: #136DFB;
+  }
+  .tabbar_img {
+    width: 32px;
+    height: 32px;
+  }
+  .home_bg {
+    width: 100%;
+    height: 240px;
+    position: absolute;
+    top: 0;
+    left: 0;
+    z-index: 1;
+  }
+  .home_bg img{
+    width: 100%;
+    height: 100%;
+  }
+  .home_box {
+    position: absolute;
+    top: 94px;
+    left: 0;
+    z-index: 2;
+    width: 100%;
+    height: auto;
+    /* padding-bottom: 46px; */
+  }
+  .task_content {
+    padding: 0 15px;
+  }
+  .wel_tip {
+    font-weight: bold;
+    font-size: 16px;
+    color: #222222;
+    line-height: 27px;
+    padding-left: 15px;
+    padding-bottom: 30px;
+  }
+  .task_box {
+    padding: 15px 9px;
+    background: linear-gradient( 180deg, rgba(255,255,255,0.8) 0%, #FFFFFF 100%);
+    border-radius: 15px;
+    border: 1px solid #FFFFFF;
+    box-sizing: border-box;
+    margin-bottom: 15px;
+  }
+  .task_top {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding-bottom: 15px;
+  }
+  .task_top_left {
+    display: flex;
+    align-items: center;
+    font-weight: 500;
+    font-size: 14px;
+    color: #222222;
+    line-height: 20px;
+  }
+  .task_top_left img{
+    width: 20px;
+    height: 20px;
+    margin-right: 5px;
+  }
+  .task_top_right {
+    display: flex;
+    align-items: center;
+    font-size: 12px;
+    color: #136DFB;
+    line-height: 17px;
+  }
+  .task_top_right img{
+    width: 16px;
+    height: 16px;
+  }
+  .notask_tip {
+    font-size: 12px;
+    color: #CCCCCC;
+    line-height: 17px;
+    padding-top: 55px;
+    text-align: center;
+  }
+  .task_list {
+    gap: 10px;
+    display: flex;
+    flex-direction: column;
+  }
+  .task_item {
+    background: #F5F8FC;
+    border-radius: 10px;
+    display: flex;
+    padding: 10px 20px 15px 10px;
+    display: flex;
+    align-items: center;
+  }
+  .task_item_left {
+    display: flex;
+    flex-direction: column;
+  }
+  .task_item_left_top {
+    display: flex;
+    align-items: center;
+    font-size: 12px;
+    color: #666666;
+  }
+  .task_item_left_top img{
+    width: 18px;
+    height: 18px;
+    margin-right: 5px;
+    border-radius: 50%;
+  }
+  .task_item_left_bottom {
+    font-size: 12px;
+    color: #222222;
+    line-height: 17px;
+    padding-top: 10px;
+    max-width: 240px; /* 必须设置宽度 */
+    overflow: hidden;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+  }
+  .task_item_line {
+    width: 1px;
+    height: 40px;
+    margin: 0 15px;
+    background: linear-gradient( 180deg, rgba(217,219,227,0) 0%, #D9DBE3 49%, rgba(217,219,227,0) 100%);
+  }
+  .task_item_right {
+    font-size: 12px;
+    color: #136DFB;
+    line-height: 17px;
+  }
+  .client_box_title {
+    display: flex;
+    align-items: center;
+    font-weight: 500;
+    font-size: 14px;
+    color: #222222;
+    line-height: 20px;
+    margin-bottom: 10px;
+  }
+  .time_box {
+    display: flex;
+    /* align-items: center; */
+    font-size: 12px;
+    color: #FFFFFF;
+    line-height: 17px;
+    background: #136DFB;
+    border-radius: 5px;
+    padding: 1px 4px 2px;
+    margin-left: 10px;
+  }
+  .time_box img {
+    width: 16px;
+    height: 16px;
+  }
+  .time_box span {
+    padding-left: 2px;
+  }
+  .client_box {
+    display: flex;
+    align-items: center;
+    gap: 10px;
+  }
+  .client_data_item {
+    width: 168px;
+    height: 86px;
+    padding: 15px 10px;
+    box-sizing: border-box;
+  }
+  .client_all {
+    background-image: url('./img/qw/client_all.png');
+    background-size: 100% 100%;
+  }
+  .client_add {
+    background-image: url('./img/qw/client_add.png');
+    background-size: 100% 100%;
+  }
+  .client_title {
+    font-size: 12px;
+    color: #666666;
+    line-height: 17px;
+  }
+  .client_num {
+    font-weight: bold;
+    font-size: 20px;
+    line-height: 29px;
+    padding-top: 10px;
+  }
+  .client_all_color {
+    color: #136DFB;
+  }
+  .client_add_color {
+    color: #FFA041;
+  }
+  .date_box {
+    width: 162px;
+    padding: 10px;
+    background: #FFFFFF;
+    box-shadow: 0px 3px 6px 1px rgba(62,89,132,0.05);
+    border-radius: 8px;
+    display: flex;
+    flex-wrap: wrap;
+    gap: 10px;
+    box-sizing: border-box;
+  }
+  .date_item {
+    width: 66px;
+    font-size: 12px;
+    color: #222222;
+    line-height: 17px;
+    padding: 8px 0;
+    background: #F7F9FC;
+    border-radius: 8px;
+    text-align: center;
+  }
+  .date_active {
+    width: 66px;
+    font-size: 12px;
+    color: #FFFFFF;
+    line-height: 17px;
+    padding: 8px 0;
+    background: #136DFB;
+    border-radius: 8px;
+    text-align: center;
+  }
+  .client_top {
+    width: 100%;
+    position: absolute;
+    top: 0;
+    left: 0;
+    z-index: 1;
+    background: #FFFFFF;
+  }
+  .client_top_box {
+    padding: 15px 15px 0px;
+  }
+  .search_icon {
+    width: 24px;
+    height: 24px;
+  }
+  .search_input {
+    padding: 0;
+  }
+  .search_input .van-search__content {
+    padding: 0;
+    border-radius: 19px;
+  }
+  .search_input .van-cell {
+    padding: 0;
+  }
+  .search_input .van-field__body {
+    display: flex;
+    align-items: center;
+    position: relative;
+  }
+  .search_input .van-field__body input{
+    border: none;
+    width: 100%;
+    height: 40px;
+    background: #FAFAFA;
+    padding: 10px 36px 10px 15px;
+    border-radius: 19px;
+  }
+  .search_input .van-field__body input:focus {
+    outline: none;
+  }
+  .search_input .van-field__body .van-field__right-icon{
+    position: absolute;
+    right: 12px;
+  }
+  .van-tabs--line .van-tabs__wrap {
+    height: 40px;
+  }
+  .van-tab--active {
+    color: #136DFB !important;
+  }
+  .van-tab {
+    color: #999999;
+  }
+  .client_top_line {
+    width: 100%;
+    height: 1px;
+    background: #F1F1F1;
+  }
+  .tag_box {
+    display: flex;
+    align-items: center;
+    gap: 10px;
+    padding-top: 10px;
+    padding-left: 15px;
+  }
+  .tag_box_item {
+    font-size: 14px;
+    color: #999999;
+    line-height: 20px;
+    padding: 4px 16px;
+    border-radius: 10px;
+    background: #FAFAFA;
+  }
+  .tag_box_active {
+    font-size: 14px;
+    color: #1677FF;
+    line-height: 20px;
+    padding: 4px 16px;
+    border-radius: 10px;
+    background: rgba(22, 119, 255, 0.1);
+  }
+  .client_content {
+    position: absolute;
+    left: 0;
+    z-index: 1;
+    width: 100%;
+  }
+  .client_content_box {
+    padding: 10px 15px 15px;
+    height: calc(100vh - 144px);
+    box-sizing: border-box;
+  }
+  .client_date {
+    display: flex;
+    align-items: center;
+    gap: 8px;
+    padding-left: 2px;
+    margin-bottom: 10px;
+  }
+  .client_date_item {
+    font-size: 12px;
+    color: #999999;
+    line-height: 17px;
+    padding: 3px 9px;
+    background: #F7F9FC;
+    border: 1px solid #F7F9FC;
+  }
+  .client_date_active {
+    font-size: 12px;
+    color: #1677FF;
+    line-height: 17px;
+    padding: 3px 9px;
+    border-radius: 10px;
+    background: rgba(22,119,255,0.05);
+    border: 1px solid #136DFB;
+  }
+  .client_list {
+    display: flex;
+    flex-direction: column;
+    gap: 10px;
+    height: calc(100vh - 189px);
+    overflow: auto;
+    padding-bottom: 46px;
+    box-sizing: border-box;
+  }
+  .noclient_list {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    height: calc(100vh - 189px);
+    overflow: auto;
+    padding-bottom: 46px;
+    box-sizing: border-box;
+    font-size: 14px;
+    color: #CCCCCC;
+    line-height: 20px;
+    flex-direction: column;
+  }
+  .noclient_list img {
+    width: 102px;
+    height: 90px;
+    margin-bottom: 20px;
+  }
+  .client_item {
+    background: #FFFFFF;
+    border-radius: 15px;
+    border: 1px solid #FFFFFF;
+    padding: 10px 15px;
+    box-sizing: border-box;
+    height: 68px;
+    display: flex;
+  }
+  .check_div {
+    width: 16px;
+    height: 16px;
+    border-radius: 50%;
+    border: 1px solid #CCCCCC;
+    box-sizing: border-box;
+    margin-right: 15px;
+  }
+  .check_div_active {
+    width: 16px;
+    height: 16px;
+    border-radius: 50%;
+    border: 1px solid #136DFB;
+    box-sizing: border-box;
+    margin-right: 15px;
+  }
+  .check_div_active:after{
+    content: "";
+    display: block;
+    width: 10px;
+    height: 10px;
+    border-radius: 50%;
+    background: #136DFB;
+    position: relative;
+    top: 2px;
+    left: 2px;
+  }
+  .client_info {
+    display: flex;
+    align-items: center;
+  }
+  .client_info img{
+    width: 48px;
+    height: 48px;
+    border-radius: 8px;
+    margin-right: 10px;
+  }
+  .client_info_text {
+    font-weight: 500;
+    font-size: 14px;
+    color: #222222;
+    display: flex;
+    flex-direction: column;
+    gap: 9px;
+  }
+  .client_tag {
+    height: 21px;
+    display: flex;
+    align-items: center;
+    gap: 8px;
+  }
+  .client_tag span {
+    height: 21px;
+    font-size: 12px;
+    color: #999999;
+    line-height: 17px;
+    border-radius: 5px;
+    padding: 2px 8px;
+    background: #FAFAFA;
+    border: 1px solid #F1F1F1;
+    box-sizing: border-box;
+    max-width: 100px; /* 必须设置宽度 */
+    overflow: hidden;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+  }
+  .van-checkbox__icon .van-icon {
+    width: 16px;
+    height: 16px;
+    line-height: 16px;
+    border: 1px solid #CCCCCC;
+  }
+  .group_item {
+    background: #FFFFFF;
+    border-radius: 15px;
+    border: 1px solid #FFFFFF;
+    padding: 15px;
+    box-sizing: border-box;
+    height: 102px;
+  }
+  .group_info {
+    display: flex;
+    flex-direction: column;
+  }
+  .group_name {
+    font-weight: 500;
+    font-size: 14px;
+    color: #222222;
+    line-height: 20px;
+  }
+  .group_data {
+    font-weight: 500;
+    font-size: 12px;
+    color: #999999;
+    line-height: 17px;
+    display: flex;
+    align-items: center;
+    padding: 10px 0 8px;
+  }
+  .create_time {
+    font-size: 12px;
+    color: #999999;
+    line-height: 17px;
+  }
+  .send_foot {
+    position: absolute;
+    bottom: 61px;
+    left: 0;
+    width: 100%;
+  }
+  .send_btn {
+    font-weight: 500;
+    font-size: 14px;
+    color: #FFFFFF;
+    line-height: 20px;
+    padding: 15px 0;
+    border-radius: 20px;
+    background: #1677FF;
+    margin: 0 35px;
+    text-align: center;
+  }
+  .marketing_bg {
+    width: 100%;
+    height: 200px;
+    position: absolute;
+    top: 0;
+    left: 0;
+    z-index: 0;
+  }
+  .marketing_bg img{
+    width: 100%;
+    height: 100%;
+  }
+  .marketing_box {
+    position: absolute;
+    top: 138px;
+    left: 0;
+    z-index: 1;
+    width: 100%;
+    height: calc(100vh - 138px);
+    background: linear-gradient( 180deg, rgba(247,249,252,0.8) 0%, #F7F9FC 100%);
+    border-radius: 15px 15px 0 0;
+    border: 1px solid #FFFFFF;
+    box-sizing: border-box;
+  }
+  .marketing_content {
+    padding: 20px 15px;
+  }
+  .reach_tools {
+    display: flex;
+    align-items: center;
+    font-weight: 500;
+    font-size: 14px;
+    line-: #222222;
+  }
+  .reach_tools img {
+    width: 20px;
+    height: 20px;
+    margin-right: 5px;
+  }
+  .reach_tools_title {
+    margin-top: 30px;
+  }
+  .tools_box {
+    width: 165px;
+    height: 72px;
+    box-sizing: border-box;
+    display: flex;
+    align-items: center;
+    padding: 15px 10px;
+    background: linear-gradient( 180deg, rgba(255,255,255,0.5) 0%, #FFFFFF 100%);
+    border-radius: 15px;
+    border: 1px solid #FFFFFF;
+    margin-top: 15px;
+  }
+  .tools_box img {
+    width: 40px;
+    height: 40px;
+    margin-right: 8px;
+  }
+  .tools_box_info {
+    display: flex;
+    flex-direction: column;
+    font-weight: 500;
+    font-size: 14px;
+    color: #222222;
+    line-height: 20px;
+    white-space: nowrap;
+  }
+  .tools_box_info_text {
+    font-weight: 400;
+    font-size: 12px;
+    color: #999999;
+    line-height: 17px;
+    padding-top: 5px;
+  }
+  .tools_box_list {
+    display: flex;
+    flex-wrap: wrap;
+  }
+  .task_manage_item {
+    font-weight: 400;
+    font-size: 12px;
+    color: #666666;
+    line-height: 17px;
+  }
+</style>
+
+<body>
+  <div id="box" class="box">
+    <div class="page5" :style="{'padding': bind ? '0' : '0 15px'}">
+      <!-- 首页 -->
+      <div v-if="activeTabbar === 'home'">
+        <div v-if="bind" :style="{'height': 'calc(100vh - 46px)'}">
+          <iframe src="qw/qwJxs.html" width="100%" height="100%" frameborder="0"></iframe>
+        </div>
+        <div v-else>
+          <div class="home_bg">
+            <img src="./img/qw/home_bg.png" alt="">
+          </div>
+          <div class="home_box">
+            <div class="wel_tip">
+              <div>下午好~</div>
+              <div>LING号玩家-服务官</div>
+            </div>
+            <div class="task_content">
+              <div class="task_box" :style="{'height': taskList.length ? '295px' : '180px'}">
+                <div class="task_top">
+                  <div class="task_top_left">
+                    <img src="./img/qw/to-do.png" alt="">
+                    <div>待办任务</div>
+                  </div>
+                  <div class="task_top_right" @click="handleAllTask">
+                    <div>全部任务</div>
+                    <img src="./img/qw/link-icon.png" alt="">
+                  </div>
+                </div>
+                <div class="task_list" v-if="taskList.length > 0">
+                  <div class="task_item" v-for="item in taskList" :key="item.id">
+                    <div class="task_item_left">
+                      <div class="task_item_left_top">
+                        <img :src="item.clientAvatar ? item.clientAvatar : './img/avatar.png'" alt="">
+                        <div>{{ item.clientName }}</div>
+                      </div>
+                      <div class="task_item_left_bottom">{{ item.taskDesc }}</div>
+                    </div>
+                    <div class="task_item_line"></div>
+                    <div class="task_item_right" @click="handleTaskDetail(item)">查看</div>
+                  </div>
+                </div>
+                <div class="notask_tip" v-else>暂无需要完成的任务</div>
+              </div>
+              <div class="client_box_title">
+                <div>我的客户</div>
+                <van-popover v-model="timePopover" trigger="click" placement="bottom-start">
+                  <div class="date_box">
+                    <div :class="dateIndex === 'today' ? 'date_active' : 'date_item'" @click="handleDate('today')">今日</div>
+                    <div :class="dateIndex === 'week' ? 'date_active' : 'date_item'" @click="handleDate('week')">近7天</div>
+                    <div :class="dateIndex === 'month' ? 'date_active' : 'date_item'" @click="handleDate('month')">近30天</div>
+                    <div :class="dateIndex === 'custom' ? 'date_active' : 'date_item'" @click="handleDate('custom')">自定义</div>
+                  </div>
+                  <template #reference>
+                    <div class="time_box">
+                      <img src="./img/qw/time_icon.png" alt="">
+                      <span>今日</span>
+                      <img src="./img/qw/time_select.png" alt="">
+                    </div>
+                  </template>
+                </van-popover>
+              </div>
+              <div class="client_box">
+                <div class="client_data_item client_all">
+                  <div class="client_title">总客户数</div>
+                  <div class="client_num client_all_color">{{clientTotal}}</div>
+                </div>
+                <div class="client_data_item client_add">
+                  <div class="client_title">新增客户数</div>
+                  <div class="client_num client_add_color">{{clientAdd}}</div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+      <!-- 自定义时间 -->
+      <van-calendar type="range" v-model="showSelfDate" @confirm="onSelfConfirm" color="#1677FF" :min-date="minDate"
+        :max-date="maxDate" :allow-same-day="true"></van-calendar>
+      <!-- 客户 -->
+      <div v-if="activeTabbar === 'client'">
+        <div class="client_top" :style="activeTab === '客户' ? 'height: 144px' : 'height: 100px'">
+          <div class="client_top_box">
+            <van-search class="search_input" placeholder="搜索客户昵称/客户群昵称" v-model="keyword" :clearable="false" left-icon="" @search="handleSearch">
+              <!-- 自定义右侧图标 -->
+              <template v-slot:right-icon>
+                <img class="search_icon" src="./img/qw/search_icon.png" @click="handleSearch" />
+              </template>
+            </van-search>
+          </div>
+          <van-tabs v-model="activeTab" ref="tabs" color="#136DFB" line-width="18px" line-height="2px" @change="handleChange">
+            <van-tab title="客户" name="客户"></van-tab>
+            <van-tab title="客户群" name="客户群"></van-tab>
+          </van-tabs>
+          <div class="client_top_line" v-if="activeTab === '客户'"></div>
+          <div class="tag_box" v-if="activeTab === '客户'">
+            <div :class="activeTag === '全部' ? 'tag_box_active' : 'tag_box_item'" @click="handleTagClick('全部')">全部</div>
+            <div :class="activeTag === '按客户标签筛选' ? 'tag_box_active' : 'tag_box_item'" @click="handleTagClick('按客户标签筛选')">按客户标签筛选</div>
+          </div>
+        </div>
+        <!-- 标签筛选组件 -->
+        <select-tag :show-Client-Tag.sync="showClientTag"></select-tag>
+        <!-- 客户、客户群列表 -->
+        <div class="client_content" :style="activeTab === '客户' ? 'top: 144px' : 'top: 100px'">
+          <div class="client_content_box">
+            <div class="client_date">
+              <div :class="clientDate === 'today' ? 'client_date_active' : 'client_date_item'" @click="handleClientDate('today')">今日</div>
+              <div :class="clientDate === 'week' ? 'client_date_active' : 'client_date_item'" @click="handleClientDate('week')">近7天</div>
+              <div :class="clientDate === 'month' ? 'client_date_active' : 'client_date_item'" @click="handleClientDate('month')">近30天</div>
+              <div :class="clientDate === 'custom' ? 'client_date_active' : 'client_date_item'" @click="handleClientDate('custom')">自定义</div>
+            </div>
+            <div class="client_list" v-if="clientList.length > 0">
+              <!-- 使用 checkbox-group 统一管理选中项 -->
+              <van-checkbox-group v-model="checkedClientIds" @change="onChangeChecked">
+                <div class="client_item" v-for="item in clientList" :key="item.id">
+                  <van-checkbox :name="item.id">
+                    <template #icon="props">
+                      <div :class="props.checked ? 'check_div_active' : 'check_div'"></div>
+                    </template>
+                  </van-checkbox>
+                  <div class="client_info" @click="handleClientDetail(item)">
+                    <img :src="item.avatar ? item.avatar : './img/avatar.png'" alt="">
+                    <div class="client_info_text">
+                      <div>{{item.name}}</div>
+                      <div class="client_tag">
+                        <span v-for="(tag, tagIndex) in item.tagList.slice(0, 2)" :key="tagIndex">{{tag}}</span>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </van-checkbox-group>
+            </div>
+            <div class="client_list" v-else-if="groupList.length > 0">
+              <div class="group_item" v-for="item in groupList" :key="item.id" @click="handleGroupClientDetail">
+                <div class="group_info">
+                  <div class="group_name">{{item.name}}</div>
+                  <div class="group_data">
+                    群主:<span style="color: #136DFB;padding-right: 15px;">{{item.ownAccountName}}</span>
+                    群人数:<span style="color: #FFA041;padding-right: 15px;">{{item.groupMemberNumber}}</span>
+                    群客户数:<span style="color: #5DD565;">{{item.clientNum}}</span>
+                  </div>
+                  <div class="create_time">建群时间:{{formatDate(item.createdGroupTime)}}</div>
+                </div>
+              </div>
+            </div>
+            <div class="noclient_list" v-else>
+              <div v-if="loading">搜寻中...</div>
+              <div v-else>
+                <img src="./img/qw/no_task.png" alt="">
+                <div class="notask_text">暂无数据</div>
+              </div>
+            </div>
+            <div class="send_foot" v-if="checkedClientIds.length > 0">
+              <div class="send_btn" @click="handleMass">创建群发</div>
+            </div>
+          </div>
+        </div>
+      </div>
+      <!-- 营销 -->
+      <div v-if="activeTabbar === 'marketing'">
+        <div class="marketing_bg">
+          <img src="./img/qw/market_bg.png" alt="">
+        </div>
+        <div class="marketing_box">
+          <div class="marketing_content">
+            <div class="reach_tools">
+              <img src="./img/qw/reach_tools.png" alt="">
+              <span>触达工具</span>
+            </div>
+            <div class="tools_box">
+              <img src="./img/qw/ai_call.png" alt="">
+              <div class="tools_box_info">
+                <div>AI外呼</div>
+                <div class="tools_box_info_text">你的专属外呼助理</div>
+              </div>
+            </div>
+            <div v-if="!bind">
+              <div class="reach_tools reach_tools_title">
+                <img src="./img/qw/task_icon.png" alt="">
+                <span>任务管理</span>
+              </div>
+              <div class="tools_box_list">
+                <div class="tools_box" style="margin-right: 13px;" @click="handleClientMass">
+                  <img src="./img/qw/client_mass.png" alt="">
+                  <div class="task_manage_item">客户群发任务</div>
+                </div>
+                <div class="tools_box">
+                  <img src="./img/qw/group_mass.png" alt="">
+                  <div class="task_manage_item">客户群群发任务</div>
+                </div>
+                <div class="tools_box">
+                  <img src="./img/qw/pyq_mass.png" alt="">
+                  <div class="task_manage_item">朋友圈群发任务</div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+      <!-- 底部导航栏 -->
+      <div class="tabbar">
+        <div class="tabbar_box">
+          <div class="tabbar_item" @click="handleTabClick('home')">
+            <img class="tabbar_img" :src="activeTabbar === 'home' ? './img/qw/tabbar-home1.png' : './img/qw/tabbar-home.png'" />
+            <div :class="activeTabbar === 'home' ? 'tabbar_text_active' : 'tabbar_text'">首页</div>
+          </div>
+          <div class="tabbar_item" @click="handleTabClick('client')">
+            <img class="tabbar_img" :src="activeTabbar === 'client' ? './img/qw/tabbar-client1.png' : './img/qw/tabbar-client.png'" />
+            <div :class="activeTabbar === 'client' ? 'tabbar_text_active' : 'tabbar_text'">客户</div>
+          </div>
+          <div class="tabbar_item" @click="handleTabClick('marketing')">
+            <img class="tabbar_img" :src="activeTabbar === 'marketing' ? './img/qw/tabbar-market1.png' : './img/qw/tabbar-market.png'" />
+            <div :class="activeTabbar === 'marketing' ? 'tabbar_text_active' : 'tabbar_text'">营销</div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</body>
+<script>
+  new Vue({
+    el: '#box',
+    data() {
+      return {
+        httpUrl: '',
+        bId: null,
+        env: '',
+        memberId: null,
+        tenancyId: null,
+
+        bind: false, // 首页
+        taskList: [],
+        clientAdd: null,
+        clientTotal: null,
+        dateIndex: 'today',
+        timePopover: false,
+        startTime: null,
+        endTime: null,
+        showSelfDate: false,
+        minDate: '',
+        maxDate: '',
+
+        clientStartTime: null, // 客户
+        clientEndTime: null,
+        clientList: [],
+        groupList: [],
+        clientDate: '',
+        activeTab: '客户',
+        activeTag: '全部',
+        loading: false,
+
+        activeTabbar: 'home',
+        keyword: '',
+        showClientTag: false,
+        // 客户列表勾选的 id 集合
+        checkedClientIds: [],
+        // 勾选的客户列表(包含 id + externalUserid 等信息)
+        selectedClients: [],
+      }
+    },
+    created() {
+      let nowDat = new Date();
+      let dateY = nowDat.getFullYear()
+      let dateM = nowDat.getMonth()
+      let dateD = nowDat.getDate()
+      // 设置日期可选最小值minDate、最大值maxDate
+      this.minDate = new Date(dateY - 1, dateM, dateD)
+      //日历可选范围为一年,dateY + 1
+      this.maxDate = new Date(dateY, dateM, dateD - 1)
+      this.bId = this.getQueryParam('bId')
+      this.env = this.getQueryParam('env')
+
+      if (!this.env || this.env === 'prod') {
+        // this.httpUrl = 'https://wlapi.wefanbot.com'
+        this.httpUrl = 'http://192.168.1.128:18993'
+      } else {
+        // this.httpUrl = 'http://192.168.1.251:18993'
+        this.httpUrl = 'http://192.168.1.128:18993'
+      }
+      if (this.getQueryParam('memberId')) {
+        // 已授权
+        this.memberId = this.getQueryParam('memberId')
+        this.tenancyId = this.getQueryParam('tenancyId')
+        this.getCpH5Login()
+      } else {
+        // 授权
+        this.getAuth()
+      }
+      this.startTime = this.getDateTime(0)
+      this.endTime = this.getDateTime(0)
+    },
+    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 {
+              vant.Toast.fail(msg)
+            }
+          })
+      },
+      getCpH5Login() {
+        fetch(this.httpUrl + '/scrm/v1/wxcp-workbench/p/cpH5Login', {
+          method: 'post',
+          body: JSON.stringify({
+            bid: this.bId,
+            memberId: this.memberId,
+          }),
+          headers: {
+            'Content-Type': 'application/json'
+          }
+        }).then(res => {
+          return res.json()
+        }).then(result => {
+          let { data, code, msg } = result
+          if (code === 1) {
+            this.bind = data.bind
+            if (this.bind) {
+              localStorage.setItem('tokenValue', data.token)
+              localStorage.setItem('tenancyIdValue', data.tenancyId)
+              localStorage.setItem('userId', data.userId)
+            } else {
+              this.clientData()
+              // this.getTaskList()
+            }
+          } else {
+            vant.Toast.fail(msg)
+          }
+        })
+      },
+      // 我的客户
+      clientData() {
+        fetch(this.httpUrl + '/scrm/v1/wxcp-workbench/p/clientData', {
+          method: 'post',
+          body: JSON.stringify({
+            memberId: this.memberId,
+            startTime: this.startTime,
+            endTime: this.endTime
+          }),
+          headers: {
+            'Content-Type': 'application/json'
+          }
+        }).then(res => {
+          return res.json()
+        }).then(result => {
+          let { data, code, msg } = result
+          if (code === 1) {
+            this.clientAdd = data.clientAdd
+            this.clientTotal = data.clientTotal
+          } else {
+            vant.Toast.fail(msg)
+          }
+        })
+      },
+      // 切换日期
+      handleDate(text) {
+        this.dateIndex = text
+        if (text === 'today') {
+          this.startTime = this.getDateTime(0)
+          this.endTime = this.getDateTime(0)
+        } else if (text === 'week') {
+          this.startTime = this.getDateTime(-7)
+          this.endTime = this.getDateTime(-1)
+        } else if (text === 'month') {
+          this.startTime = this.getDateTime(-30)
+          this.endTime = this.getDateTime(-1)
+        } else if (text === 'custom') {
+          this.showSelfDate = true
+        }
+        this.clientData()
+        this.timePopover = false
+      },
+      // 自定义日期
+      onSelfConfirm(date) {
+        const [start, end] = date
+        if (this.formatDate(new Date()) === this.formatDate(end)) {
+          this.formatDate(end) = this.formatDate(start)
+        }
+        this.showSelfDate = false
+        if (this.activeTabbar === 'home') {
+          this.startTime = this.formatDate(start)
+          this.endTime = this.formatDate(end)
+          this.clientData()
+        } else if (this.activeTabbar === 'client') {
+          this.clientStartTime = this.formatDate(start)
+          this.clientEndTime = this.formatDate(end)
+          this.pageClient()
+        }
+      },
+      // 切换底部tabbar
+      handleTabClick(tab) {
+        this.activeTabbar = tab
+        if (tab === 'home') {
+          // this.getTaskList()
+          this.clientData()
+        } else if (tab === 'client') {
+          this.clientStartTime = null
+          this.clientEndTime = null
+          this.clientDate = ''
+          this.pageClient()
+        } else if (tab === 'marketing') {
+        }
+      },
+      // 查询待办任务
+      getTaskList () {
+        fetch(this.httpUrl + `/scrm/v1/wxcp-member-todo-task/p/page?memberId=${this.memberId}&page=1&pageCount=3`)
+        .then(res => {
+          return res.json()
+        }).then(result => {
+          let { data, code, msg } = result
+          if (code === 1) {
+            this.taskList = data.records || []
+          } else {
+            vant.Toast.fail(msg)
+          }
+        })
+      },
+      // 全部任务
+      handleAllTask() {
+        window.location.href = `qw/toDoTask.html?memberId=${this.memberId}`
+      },
+      // 任务详情
+      handleTaskDetail(item) {
+        window.location.href = `qw/taskDetail.html?taskId=${item.todoTaskId}&type=${item.type}&env=${this.env}`
+      },
+      handleChange(tab) {
+        this.activeTab = tab
+        this.clientList = []
+        this.groupList = []
+        if (tab === '客户') {
+          this.pageClient()
+        } else if (tab === '客户群') {
+          this.pageGroup()
+        }
+      },
+      // 搜索客户
+      handleSearch() {
+        this.pageClient()
+      },
+      // 全部客户
+      pageClient() {
+        this.loading = true
+        fetch(this.httpUrl + '/scrm/v1/wxcp-workbench/p/pageClient', {
+          method: 'post',
+          body: JSON.stringify({
+            bid: this.bId,
+            memberId: this.memberId,
+            startTime: this.clientStartTime,
+            endTime: this.clientEndTime,
+            keyword: this.keyword,
+            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.clientList = data.records || []
+            // 刷新列表时清空已勾选项
+            console.log('勾选项', this.selectedClients)
+          } else {
+            vant.Toast.fail(msg)
+          }
+        }).finally(() => {
+          this.loading = false
+        })
+      },
+      // 全部客户群
+      pageGroup () {
+        this.loading = true
+        fetch(this.httpUrl + '/scrm/v1/wxcp-workbench/p/pageGroup', {
+          method: 'post',
+          body: JSON.stringify({
+            bid: this.bId,
+            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.groupList = data.records || []
+          } else {
+            vant.Toast.fail(msg)
+          }
+        }).finally(() => {
+          this.loading = false
+        })
+      },
+      // 客户日期筛选
+      handleClientDate(text) {
+        this.clientDate = text
+        if (text === 'today') {
+          this.clientStartTime = this.getDateTime(0)
+          this.clientEndTime = this.getDateTime(0)
+        } else if (text === 'week') {
+          this.clientStartTime = this.getDateTime(-7)
+          this.clientEndTime = this.getDateTime(-1)
+        } else if (text === 'month') {
+          this.clientStartTime = this.getDateTime(-30)
+          this.clientEndTime = this.getDateTime(-1)
+        } else if (text === 'custom') {
+          this.showSelfDate = true
+        }
+        this.pageClient()
+      },
+      handleTagClick(tag) {
+        this.activeTag = tag
+        if (tag === '按客户标签筛选') {
+          this.showClientTag = true
+        }
+      },
+      // 客户详情
+      handleClientDetail(item) {
+        window.location.href = `userProfile.html?bId=${this.bId}&env=${this.env}&memberId=${item.memberId}&externalUserId=${item.externalUserid}`
+      },
+      // 客户群详情
+      handleGroupClientDetail() {
+        // window.location.href = `qw/clientGroupDetail.html?bId=11`
+      },
+      // 营销群发
+      handleMass() {
+        // window.location.href = `qw/mass.html?bId=11`
+      },
+      // 客户群发任务
+      handleClientMass() {
+        window.location.href = `qw/clientMass.html?bId=11`
+      },
+      // 勾选客户变更
+      onChangeChecked (value) {
+        // value 为当前勾选的 name 数组(即 id 集合)
+        this.checkedClientIds = value
+        // 根据勾选的 id,从 clientList 里筛出完整客户信息
+        this.selectedClients = this.clientList
+          .filter(item => value.includes(item.id))
+          .map(item => ({
+            id: item.id,
+            externalUserid: item.externalUserid,
+            // 如果后面还需要其它字段,也可以一起带上
+          }))
+        console.log('当前选中的客户列表(含 id 和 externalUserid): ', this.selectedClients)
+      },
+      formatDate(input) {
+        // 创建 Date 对象(兼容不同浏览器)
+        const date = new Date(input)
+
+        // 提取年、月、日
+        const year = date.getFullYear()
+        const month = String(date.getMonth() + 1).padStart(2, '0') // 月份从0开始,需要+1
+        const day = String(date.getDate()).padStart(2, '0')
+
+        return `${year}-${month}-${day}`
+      },
+      // 日期格式处理
+      getDateTime(day) {
+        let today = new Date()
+        let targetday_milliseconds = today.getTime() + 1000 * 60 * 60 * 24 * day
+        today.setTime(targetday_milliseconds)
+        let tYear = today.getFullYear()
+        let tMonth = today.getMonth() + 1
+        let tDate = today.getDate()
+        if (tMonth < 10) {
+          tMonth = '0' + tMonth
+        }
+        if (tDate < 10) {
+          tDate = '0' + tDate
+        }
+        return tYear + '-' + tMonth + '-' + tDate
+      },
+      // 截取url中的数据
+      getQueryParam(paramName) {
+        // 获取当前URL的查询字符串部分  
+        const queryString = window.location.search;
+        // 创建一个URLSearchParams对象  
+        const urlParams = new URLSearchParams(queryString);
+        // 返回指定参数的值,如果不存在则返回null  
+        return urlParams.get(paramName);
+      },
+    }
+  })   
+</script>
+
+</html>

+ 186 - 0
lottery/qw/clientGroupDetail.html

@@ -0,0 +1,186 @@
+<!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>
+  <!-- 引入样式文件 -->
+  <link rel="stylesheet"
+    href="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1758012584633/vant.css" />
+  <!-- 必须先引入vue,  后使用vant-ui -->
+  <script
+    src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1742017957144/vue.js"></script>
+  <!-- 引入vant的组件库-->
+  <!-- 引入 Vant 的 JS 文件 -->
+  <script
+    src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1758012748487/vant.min.js"></script>
+
+  <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
+  <script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js"></script>
+  <!-- <script src="js/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: #F7F9FC;
+  }
+
+  .page5 {
+    width: 100vw;
+    box-sizing: border-box;
+    padding: 15px;
+  }
+
+  .task_list {}
+
+  .task_item {
+    width: 100%;
+    background: linear-gradient(180deg, rgba(255, 255, 255, 0.8) 0%, #FFFFFF 100%);
+    border-radius: 15px;
+    border: 1px solid #FFFFFF;
+    box-sizing: border-box;
+    margin-bottom: 15px;
+  }
+
+  .task_item:last-child {
+    margin-bottom: 0;
+  }
+
+  .task_item_title {
+    display: flex;
+    align-items: center;
+    padding: 10px 15px;
+  }
+
+  .task_item_title img {
+    width: 48px;
+    height: 48px;
+    border-radius: 8px;
+    margin-right: 10px;
+  }
+
+  .task_item_text {
+    font-weight: 500;
+    font-size: 14px;
+    color: #222222;
+    display: flex;
+    flex-direction: column;
+    gap: 9px;
+  }
+
+  .client_tag {
+    display: flex;
+    align-items: center;
+    gap: 8px;
+  }
+
+  .client_tag span {
+    height: 21px;
+    font-size: 12px;
+    color: #136DFB;
+    line-height: 17px;
+    border-radius: 5px;
+    padding: 2px 8px;
+    background: rgba(19, 109, 251, 0.05);
+    box-sizing: border-box;
+  }
+
+  .notask {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    padding-top: 198px;
+  }
+
+  .notask img {
+    width: 102px;
+    height: 90px;
+  }
+
+  .notask_text {
+    font-size: 14px;
+    color: #CCCCCC;
+    line-height: 20px;
+    padding-top: 20px;
+  }
+</style>
+
+<body>
+  <div id="box" class="box">
+    <div class="page5">
+      <!-- <div class="notask">
+        <img src="./img/qw/no_task.png" alt="">
+        <div class="notask_text">暂无待办任务</div>
+      </div> -->
+      <div class="task_item">
+        <div class="task_item_title">
+          <img src="../img/avatar.png" alt="">
+          <div class="task_item_text">
+            <div>客户昵称</div>
+            <div class="client_tag">
+              <span>标签</span><span>标签</span><span>标签</span><span>标签</span>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</body>
+<script>
+  new Vue({
+    el: '#box',
+    data() {
+      return {
+        httpUrl: '',
+        bId: null,
+        env: '',
+        memberId: null,
+        corpId: null,
+      }
+    },
+    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.corpId = this.getQueryParam('corpId')
+      // } else {
+      //   // 授权
+      //   this.getAuth()
+      // }
+    },
+    methods: {
+      // 截取url中的数据
+      getQueryParam(paramName) {
+        // 获取当前URL的查询字符串部分  
+        const queryString = window.location.search;
+        // 创建一个URLSearchParams对象  
+        const urlParams = new URLSearchParams(queryString);
+        // 返回指定参数的值,如果不存在则返回null  
+        return urlParams.get(paramName);
+      },
+    }
+  })   
+</script>
+
+</html>

+ 348 - 0
lottery/qw/clientMass.html

@@ -0,0 +1,348 @@
+<!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>
+  <!-- 引入样式文件 -->
+  <link rel="stylesheet"
+    href="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1758012584633/vant.css" />
+  <!-- 必须先引入vue,  后使用vant-ui -->
+  <script
+    src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1742017957144/vue.js"></script>
+  <!-- 引入vant的组件库-->
+  <!-- 引入 Vant 的 JS 文件 -->
+  <script
+    src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1758012748487/vant.min.js"></script>
+
+  <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
+  <script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js"></script>
+  <!-- <script src="js/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: #F7F9FC;
+  }
+
+  .page5 {
+    width: 100vw;
+    box-sizing: border-box;
+    padding: 15px;
+  }
+  .client_top {
+    width: 100%;
+    height: 70px;
+    position: absolute;
+    top: 0;
+    left: 0;
+    z-index: 1;
+    background: #FFFFFF;
+  }
+  .client_top_box {
+    padding: 15px 15px 0px;
+  }
+  .search_icon {
+    width: 24px;
+    height: 24px;
+  }
+  .search_input {
+    padding: 0;
+  }
+  .search_input .van-search__content {
+    padding: 0;
+    border-radius: 19px;
+  }
+  .search_input .van-cell {
+    padding: 0;
+  }
+  .search_input .van-field__body {
+    display: flex;
+    align-items: center;
+    position: relative;
+  }
+  .search_input .van-field__body input{
+    border: none;
+    width: 100%;
+    height: 40px;
+    background: #FAFAFA;
+    padding: 10px 36px 10px 15px;
+    border-radius: 19px;
+  }
+  .search_input .van-field__body input:focus {
+    outline: none;
+  }
+  .search_input .van-field__body .van-field__right-icon{
+    position: absolute;
+    right: 12px;
+  }
+
+  .task_list {
+    width: 100%;
+    height: calc(100vh - 70px);
+    position: absolute;
+    top: 70px;
+    left: 0;
+    z-index: 1;
+    background: #F7F9FC;
+    overflow: auto;
+    padding-bottom: 60px;
+    box-sizing: border-box;
+  }
+  .task_content {
+    padding: 15px;
+  }
+  .task_item {
+    width: 100%;
+    background: #FFFFFF;
+    border-radius: 15px;
+    border: 1px solid #FFFFFF;
+    box-sizing: border-box;
+    margin-bottom: 10px;
+    padding: 15px;
+  }
+
+  .task_item:last-child {
+    margin-bottom: 0;
+  }
+
+  .task_item_title {
+    display: flex;
+    justify-content: space-between;
+    font-weight: 500;
+    font-size: 16px;
+    color: #222222;
+    line-height: 20px;
+  }
+
+  .client_tag {
+    font-size: 12px;
+    line-height: 17px;
+  }
+  .task_item_time {
+    font-size: 12px;
+    color: #999999;
+    line-height: 17px;
+    padding-top: 8px;
+  }
+  .notask {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    padding-top: 198px;
+  }
+
+  .notask img {
+    width: 102px;
+    height: 90px;
+  }
+
+  .notask_text {
+    font-size: 14px;
+    color: #CCCCCC;
+    line-height: 20px;
+    padding-top: 20px;
+  }
+  .send_foot {
+    position: absolute;
+    bottom: 10px;
+    left: 0;
+    width: 100%;
+    z-index: 2;
+  }
+  .send_btn {
+    font-weight: 500;
+    font-size: 14px;
+    color: #FFFFFF;
+    line-height: 20px;
+    padding: 15px 0;
+    border-radius: 20px;
+    background: #1677FF;
+    margin: 0 35px;
+    text-align: center;
+  }
+  .status1 {
+    color: #136DFB;
+  }
+  .status2 {
+    color: #FFA041;
+  }
+  .status3 {
+    color: #FF4141;
+  }
+</style>
+
+<body>
+  <div id="box" class="box">
+    <div class="page5">
+      <!-- <div class="notask">
+        <img src="./img/qw/no_task.png" alt="">
+        <div class="notask_text">暂无数据</div>
+      </div> -->
+      <div class="client_top">
+        <div class="client_top_box">
+          <van-search class="search_input" placeholder="搜索客户昵称/客户群昵称" v-model="keyword" :clearable="false" left-icon="" @search="initData">
+            <!-- 自定义右侧图标 -->
+            <template v-slot:right-icon>
+              <img class="search_icon" src="../img/qw/search_icon.png" alt="" @click="initData" />
+            </template>
+          </van-search>
+        </div>
+      </div>
+      <div class="task_list">
+        <div class="task_content">
+          <div class="task_item" v-for="item in tableData" :key="item.id">
+            <div class="task_item_title">
+              <div>{{item.name}}</div>
+              <div v-if="item.isNotify === -2" class="client_tag status3">无符合条件客户</div>
+              <div v-else-if="item.isNotify === -1" class="client_tag status3">创建失败</div>
+              <div v-else-if="item.isNotify === 0" class="client_tag status2">待通知</div>
+              <div v-else-if="item.isNotify === 1" class="client_tag status1">已通知</div>
+              <div v-else-if="item.isNotify === 3" class="client_tag status2">创建中</div>
+            </div>
+            <div class="task_item_time">创建时间:{{item.createdTime}}</div>
+          </div>
+        </div>
+      </div>
+      <div class="send_foot">
+        <div class="send_btn">创建客户群发</div>
+      </div>
+    </div>
+  </div>
+</body>
+<script>
+  new Vue({
+    el: '#box',
+    data() {
+      return {
+        httpUrl: '',
+        bId: null,
+        env: '',
+        memberId: null,
+        keyword: '',
+        tableData: [],
+      }
+    },
+    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.token = 'k1176129370564100001'
+      this.tenancyId = '103548289110001'
+      this.userId = '103548289110001'
+      this.initData()
+    },
+    methods: {
+      initData() {
+        const headers = new Headers()
+        headers.append('token', this.token)
+        headers.append('tenancyId', this.tenancyId)
+        headers.append('userId', this.userId)
+        fetch(this.httpUrl + '/scrm/v1/wxcp-send/m/findListByPage', {
+          method: 'post',
+          body: JSON.stringify({
+            keyword: this.keyword,
+            page: 1,
+            pageCount: 1000,
+          }),
+          headers: {
+            'Content-Type': 'application/json',
+            'token': this.token,
+            'tenancyId': this.tenancyId,
+            'userId': this.userId,
+          }
+        }).then(res => {
+          return res.json()
+        }).then(result => {
+          let { data, code, msg } = result
+          if (code === 1) {
+            this.tableData = data.records || []
+            this.tableData.forEach(item => {
+              item.createdTime = this.timeFormat(item.createdTime)
+            })
+          } else {
+            vant.Toast.fail(msg)
+          }
+        })
+      },
+      onSearch() {
+        this.initData()
+      },
+      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;
+      },
+      // 截取url中的数据
+      getQueryParam(paramName) {
+        // 获取当前URL的查询字符串部分  
+        const queryString = window.location.search;
+        // 创建一个URLSearchParams对象  
+        const urlParams = new URLSearchParams(queryString);
+        // 返回指定参数的值,如果不存在则返回null  
+        return urlParams.get(paramName);
+      },
+    }
+  })   
+</script>
+
+</html>

+ 727 - 0
lottery/qw/clientMassDetail.html

@@ -0,0 +1,727 @@
+<!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>
+  <!-- 引入样式文件 -->
+  <link rel="stylesheet"
+    href="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1758012584633/vant.css" />
+  <!-- 必须先引入vue,  后使用vant-ui -->
+  <script
+    src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1742017957144/vue.js"></script>
+  <!-- 引入vant的组件库-->
+  <!-- 引入 Vant 的 JS 文件 -->
+  <script
+    src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1758012748487/vant.min.js"></script>
+
+  <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
+  <script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js"></script>
+  <!-- <script src="js/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: #F7F9FC;
+  }
+
+  .page5 {
+    width: 100vw;
+    box-sizing: border-box;
+  }
+
+  .task_content {
+    padding: 15px 10px;
+  }
+
+  .task_item {
+    width: 100%;
+    background: #FFFFFF;
+    border-radius: 15px;
+    box-sizing: border-box;
+    padding: 15px 10px;
+  }
+
+  .task_item_title {
+    display: flex;
+    justify-content: space-between;
+    font-weight: 500;
+    font-size: 16px;
+    color: #222222;
+    line-height: 20px;
+  }
+
+  .client_tag {
+    font-size: 12px;
+    line-height: 17px;
+  }
+
+
+  .status1 {
+    color: #136DFB;
+  }
+
+  .status2 {
+    color: #FFA041;
+  }
+
+  .status3 {
+    color: #FF4141;
+  }
+  .detail_item {
+    display: flex;
+    align-items: center;
+    flex-wrap: wrap;
+  }
+  .time_item {
+    display: flex;
+    align-items: center;
+    font-size: 12px;
+    line-height: 17px;
+    padding-top: 12px;
+  }
+  .label {
+    color: #999999;
+  }
+  .isAll_type {
+    color: #136DFB;
+  }
+  .time {
+    color: #666666;
+  }
+  .item_space {
+    margin-right: 20px;
+  }
+  .mem_title {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 15px 0 10px;
+  }
+  .mem_title_left {
+    font-size: 14px;
+    color: #222222;
+    line-height: 20px;
+    padding-left: 5px;
+    position: relative;
+    display: flex;
+    align-items: center;
+  }
+  .mem_title_left::after {
+    position: absolute;
+    left: 0;
+    content: '';
+    width: 2px;
+    height: 12px;
+    background: #136DFB;
+    border-radius: 1px;
+  }
+  .mem_title_right {
+    display: flex;
+    align-items: center;
+    font-size: 12px;
+    color: #999999;
+    line-height: 17px;
+  }
+  .mem_title_right img{
+    width: 16px;
+    height: 16px;
+  }
+  .mem_tag {
+    display: flex;
+    flex-wrap: wrap;
+    align-items: center;
+    gap: 10px;
+  }
+  .mem_tag span {
+    padding: 2px 8px;
+    background: rgba(19,109,251,0.05);
+    border-radius: 5px;
+    font-size: 12px;
+    line-height: 17px;
+    color: #136DFB;
+  }
+  .send_detail {
+    height: calc(100vh - 204px);
+    background: #FFFFFF;
+    border-radius: 15px 15px 0 0;
+  }
+  .van-tabs .van-tabs__wrap{
+    border-radius: 15px 15px 0 0;
+  }
+  .van-tabs--line .van-tabs__wrap {
+    height: 40px;
+  }
+  .van-tabs__nav {
+    padding: 0 25px 15px;
+  }
+  .van-tab--active {
+    color: #222222 !important;
+  }
+  .van-tab {
+    color: #999999;
+  }
+  .send_centent {
+    padding: 20px 15px;
+  }
+  .send_text {
+    font-size: 14px;
+    color: #222222;
+    line-height: 20px;
+    padding-bottom: 10px;
+  }
+  .send_contentText {
+    font-size: 14px;
+    line-height: 23px;
+    color: #666666;
+    padding-bottom: 20px;
+  }
+  .img_list {
+    display: flex;
+    flex-wrap: nowrap;
+    overflow-x: auto;
+    gap: 10px;
+    padding: 0 5px 10px;
+  }
+  .img_list img {
+    min-width: 105px;
+    height: 140px;
+    border-radius: 10px;
+    object-fit: cover;
+  }
+  .video_container {
+    position: relative;
+    width: 105px;
+    height: 140px;
+  }
+  .play_button {
+    width: 24px;
+    height: 24px;
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%);
+  }
+  .matters_item {
+    width: 163px;
+    height: 60px;
+    border-radius: 10px;
+    display: flex;
+    align-items: center;
+    padding: 10px;
+    box-sizing: border-box;
+    border: 1px solid #EFEFEF;
+  }
+  .matters_item img {
+    width: 40px;
+    height: 40px;
+    margin-right: 8px;
+  }
+  .matters_item_info {
+    display: flex;
+    flex-direction: column;
+    font-size: 12px;
+    color: #999999;
+    line-height: 17px;
+  }
+  .matters_item_title {
+    font-size: 12px;
+    color: #222222;
+    line-height: 17px;
+    width: 96px; /* 必须设置宽度 */
+    overflow: hidden;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+    padding-bottom: 4px;
+  }
+  .matters_list {
+    display: flex;
+    flex-wrap: wrap;
+    gap: 10px;
+  }
+  .mem_centent {
+    padding: 10px 15px;
+  }
+  .filter_list {
+    display: flex;
+    flex-wrap: nowrap;
+    white-space: nowrap;
+    width: 100%;
+    overflow-x: auto;
+    gap: 10px;
+  }
+  .filter_span {
+    height: 25px;
+    box-sizing: border-box;
+    font-size: 12px;
+    color: #999999;
+    padding: 4px 12px;
+    background: #FAFAFA;
+    border-radius: 10px;
+  }
+  .active {
+    height: 25px;
+    box-sizing: border-box;
+    font-size: 12px;
+    color: #1677FF;
+    background: rgba(22,119,255,0.1);
+    padding: 4px 12px;
+    border-radius: 10px;
+  }
+  .send_num_data {
+    display: flex;
+    align-items: center;
+    padding: 15px 5px 10px;
+    font-size: 12px;
+    color: #222222;
+    line-height: 17px;
+  }
+  .color1 {
+    color: #1677FF;
+    padding-right: 20px;
+  }
+  .color2 {
+    color: #FFA041;
+    padding-right: 20px;
+  }
+  .color3 {
+    color: #FF4E4E;
+    padding-right: 20px;
+  }
+  .color4 {
+    color: #7D97BF;
+    padding-right: 20px;
+  }
+  .send_mem_item {
+    height: 100px;
+    display: flex;
+    flex-direction: column;
+    justify-content: space-between;
+    padding: 15px;
+    background: #FAFAFA;
+    border-radius: 15px;
+    box-sizing: border-box;
+    margin-bottom: 10px;
+  }
+  .send_mem_name {
+    font-weight: 500;
+    font-size: 14px;
+    color: #222222;
+    line-height: 20px;
+  }
+  .send_mem_data {
+    display: flex;
+    align-items: center;
+    font-size: 12px;
+    color: #999999;
+    line-height: 17px;
+  }
+  .send_mem_time {
+    font-size: 12px;
+    color: #999999;
+    line-height: 17px;
+  }
+</style>
+
+<body>
+  <div id="box" class="box">
+    <div class="page5">
+      <div class="task_content">
+        <div class="task_item">
+          <div class="task_item_title">
+            <div>{{formValidate.name}}</div>
+            <div v-if="formValidate.isNotify === -2" class="client_tag status3">无符合条件客户</div>
+            <div v-else-if="formValidate.isNotify === -1" class="client_tag status3">创建失败</div>
+            <div v-else-if="formValidate.isNotify === 0" class="client_tag status2">待通知</div>
+            <div v-else-if="formValidate.isNotify === 1" class="client_tag status1">已通知</div>
+            <div v-else-if="formValidate.isNotify === 3" class="client_tag status2">创建中</div>
+          </div>
+          <div class="detail_item">
+            <div class="time_item item_space">
+              <div class="label">群发客户:</div>
+              <div class="isAll_type">{{ formValidate.isAll ? '全部客户' : '部分客户' }}</div>
+            </div>
+            <div class="time_item">
+              <div class="label">创建时间:</div>
+              <div class="time">{{ formValidate.createdTime }}</div>
+            </div>
+            <div class="time_item">
+              <div class="label">通知时间:</div>
+              <div class="time">{{ formValidate.notifyTime }}</div>
+            </div>
+          </div>
+          <div class="mem_title">
+            <div class="mem_title_left">生效成员</div>
+            <div class="mem_title_right">
+              <div>全部成员</div>
+              <img src="../img/qw/more_icon.png" alt="">
+            </div>
+          </div>
+          <div class="mem_tag">
+            <span v-for="(item, index) in formValidate.memberList" :key="index">{{item.name}}</span>
+          </div>
+        </div>
+      </div>
+      <div class="send_detail">
+        <van-tabs v-model="activeTab" ref="tabs" color="#1677FF" line-width="16px" line-height="3px" @change="handleChange">
+          <van-tab title="群发内容" name="群发内容"></van-tab>
+          <van-tab title="成员详情" name="成员详情"></van-tab>
+          <van-tab title="客户详情" name="客户详情"></van-tab>
+        </van-tabs>
+        <div class="send_centent" v-if="activeTab === '群发内容'">
+          <div class="send_text">文本:</div>
+          <div class="send_contentText">{{formValidate.contentText}}</div>
+          <div class="send_text">素材:</div>
+          <template v-if="formValidate.ctOthers && formValidate.ctOthers.length > 0">
+            <div class="img_list" v-if="formValidate.ctOthers[0].matterType === 1">
+              <img :src="item.imgUrl"  v-for="(item, index) in formValidate.ctOthers" :key="index" alt="">
+            </div>
+            <div class="video_container" v-if="formValidate.ctOthers[0].matterType === 2">
+              <video id="myVideo" style="width: 105px; height: 140px;" :src="formValidate.ctOthers[0].videoPath"></video>
+              <img id="playButton" class="play_button" src="../img/qw/play_icon.png" alt="" @click="playPause">
+            </div>
+            <div class="matters_item" v-if="formValidate.ctOthers[0].matterType === 5">
+              <img src="../img/qw/link.png" alt="">
+              <div class="matters_item_info">
+                <div class="matters_item_title">{{formValidate.ctOthers[0].linkTitle}}</div>
+                <div>自定义链接</div>
+              </div>
+            </div>
+          </template>
+          <template v-if="formValidate.matters && formValidate.matters.length > 0">
+            <div class="img_list" v-if="matterImgList.length > 0">
+              <img :src="item.headUrl" v-for="(item, index) in matterImgList" :key="index" alt="">
+            </div>
+            <div class="matters_list">
+              <div class="matters_item" v-for="(item, index) in matterOthersList" :key="index">
+                <img v-if="item.contentType === 0" src="../img/qw/article.png" alt="">
+                <img v-else-if="item.contentType === 2" src="../img/qw/form.png" alt="">
+                <img v-else-if="item.contentType === 3" src="../img/qw/file.png" alt="">
+                <img v-else src="../img/qw/link.png" alt="">
+                <div class="matters_item_info">
+                  <div class="matters_item_title">{{item.title}}</div>
+                  <div>{{matterTypeList.find(type => type.contentType === item.contentType)?.name || '未知类型'}}</div>
+                </div>
+              </div>
+            </div>
+          </template>
+        </div>
+        <div class="mem_centent" v-if="activeTab === '成员详情'">
+          <div class="filter_list">
+            <span :class="filterIndex === null ? 'active' : 'filter_span'" @click="handleFilter('全部')">全部</span>
+            <span :class="filterIndex === 1 ? 'active' : 'filter_span'" @click="handleFilter(1)">已发送</span>
+            <span :class="filterIndex === 0 ? 'active' : 'filter_span'" @click="handleFilter(0)">未发送</span>
+            <span :class="filterIndex === 2 ? 'active' : 'filter_span'" @click="handleFilter(2)">发送失败</span>
+            <span :class="filterIndex === -1 ? 'active' : 'filter_span'" @click="handleFilter(-1)">无客户可发送</span>
+          </div>
+          <div class="send_num_data">
+            已发送:<span class="color1">{{memberExtra.sendSuccess}}</span>
+            未发送:<span class="color2">{{memberExtra.unSend}}</span>
+            发送失败:<span class="color3">{{memberExtra.sendFail}}</span>
+          </div>
+          <div class="send_mem_list">
+            <div class="send_mem_item" v-for="(item, index) in sendMemberList" :key="index">
+              <div class="send_mem_name">{{item.name}}</div>
+              <div class="send_mem_data">
+                发送人数:<span class="color1">{{item.sendNum}}</span>
+                发送状态:<span class="color1" v-if="item.sendStatus === -1">无可发送客户</span>
+                <span class="color2" v-if="item.sendStatus === 0">未发送</span>
+                <span class="color1" v-if="item.sendStatus === 1">已发送</span>
+                <span class="color3" v-if="item.sendStatus === 2">发送失败</span>
+              </div>
+              <div class="send_mem_time">发送时间:<span style="color: #666666;">{{item.sendTime}}</span></div>
+            </div>
+          </div>
+        </div>
+        <div class="mem_centent" v-if="activeTab === '客户详情'">
+          <div class="filter_list">
+            <span :class="filterIndex === null ? 'active' : 'filter_span'" @click="handleFilter('全部')">全部</span>
+            <span :class="filterIndex === 1 ? 'active' : 'filter_span'" @click="handleFilter(1)">已发送</span>
+            <span :class="filterIndex === 0 ? 'active' : 'filter_span'" @click="handleFilter(0)">未发送</span>
+            <span :class="filterIndex === 2 ? 'active' : 'filter_span'" @click="handleFilter(2)">发送失败</span>
+            <span :class="filterIndex === -1 ? 'active' : 'filter_span'" @click="handleFilter(-1)">无客户可发送</span>
+          </div>
+          <div class="send_num_data">
+            已接收客户:<span class="color1">{{clientExtra.sendSuccess}}</span>
+            未接收客户:<span class="color2">{{clientExtra.unSend}}</span>
+            接收失败客户:<span class="color3">{{clientExtra.sendFail}}</span>
+          </div>
+          <div class="send_mem_list">
+            <div class="send_mem_item" v-for="(item, index) in clientList" :key="index">
+              <div class="send_mem_name">{{item.clientName}}</div>
+              <div class="send_mem_data">
+                所属成员:<span class="color1">{{item.memberName}}</span>
+                接收状态:<span class="color1" v-if="item.sendStatus === -1">无可发送客户</span>
+                <span class="color2" v-if="item.sendStatus === 0">未发送</span>
+                <span class="color1" v-if="item.sendStatus === 1">已发送</span>
+                <span class="color3" v-if="item.sendStatus === 2">发送失败</span>
+              </div>
+              <div class="send_mem_time">接收时间:<span style="color: #666666;">{{item.recvTime}}</span></div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</body>
+<script>
+  new Vue({
+    el: '#box',
+    data() {
+      return {
+        httpUrl: '',
+        bId: null,
+        env: '',
+        memberId: null,
+        keyword: '',
+        formValidate: {
+          name: '',
+          memberList: [],
+          contentText: '',
+          ctOthers: [],
+          matters: [],
+          isAll: 1,
+          id: null,
+          type: 1,
+          sendTime: '',
+          notifyTime: '',
+          createdTime: ''
+        },
+        activeTab: '群发内容',
+        matterImgList: [],
+        matterOthersList: [],
+        matterTypeList: [
+          { contentType: 0, name: '文章'},
+          { contentType: 2, name: '表单'},
+          { contentType: 3, name: '文件'},
+          { contentType: 4, name: '外部链接' },
+          { contentType: 15, name: '视频'},
+          { contentType: 16, name: '视频链接' },
+          { contentType: 17, name: '图集链接' },
+        ],
+        filterIndex: null,
+        memberExtra: {
+          sendSuccess: null,
+          unSend: null,
+          sendFail: null,
+        },
+        sendMemberList: [],
+        clientExtra: {
+          sendSuccess: null,
+          unSend: null,
+          sendFail: null,
+        },
+        clientList: [],
+      }
+    },
+    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.token = 'k1176129370564100001'
+      this.tenancyId = '103548289110001'
+      this.userId = '103548289110001'
+      this.id = '117654331810001'
+      this.getDetail()
+    },
+    methods: {
+      handleChange(tab) {
+        this.activeTab = tab
+        if (tab === '群发内容') {
+          this.getDetail()
+        } else if (tab === '成员详情') {
+          this.handleMember()
+        } else if (tab === '客户详情') {
+          this.handleClient()
+        }
+      },
+      // 群发内容
+      getDetail() {
+        const headers = new Headers()
+        headers.append('token', this.token)
+        headers.append('tenancyId', this.tenancyId)
+        headers.append('userId', this.userId)
+        fetch(this.httpUrl + `/scrm/v1/wxcp-send/m/findById2?id=${this.id}`, {
+          method: 'GET',
+          headers: headers
+        }).then(res => {
+          return res.json()
+        }).then(result => {
+          let { data, code, msg } = result
+          if (code === 1) {
+            this.formValidate = data
+            this.formValidate.createdTime = this.timeFormat(this.formValidate.createdTime)
+            this.formValidate.notifyTime = this.timeFormat(this.formValidate.notifyTime)
+            if (this.formValidate.matters && this.formValidate.matters.length > 0) {
+              this.formValidate.matters.forEach(item => {
+                if (item.contentType === 19) {
+                  this.matterImgList.push(item)
+                } else {
+                  this.matterOthersList.push(item)
+                }
+              })
+            }
+          } else {
+            vant.Toast.fail(msg)
+          }
+        })
+      },
+      // 播放暂停视频
+      playPause() {
+        const video = document.getElementById('myVideo')
+        const playButton = document.getElementById("playButton")
+        if (video.paused) {
+          video.play()
+        } else {
+          video.pause()
+        }
+      },
+      // 筛选发送状态
+      handleFilter(index) {
+        if (index === '全部') {
+          this.filterIndex = null
+        } else {
+          this.filterIndex = index
+        }
+        this.handleMember()
+      },
+      handleMember() {
+        const headers = new Headers()
+        headers.append('token', this.token)
+        headers.append('tenancyId', this.tenancyId)
+        headers.append('userId', this.userId)
+        fetch(this.httpUrl + '/scrm/v1/wxcp-send/m/findMembersPage', {
+          method: 'post',
+          body: JSON.stringify({
+            sendId: this.id ,
+            status: this.filterIndex,
+            page: 1,
+            pageCount: 1000,
+          }),
+          headers: {
+            'Content-Type': 'application/json',
+            'token': this.token,
+            'tenancyId': this.tenancyId,
+            'userId': this.userId,
+          }
+        }).then(res => {
+          return res.json()
+        }).then(result => {
+          let { data, code, msg } = result
+          if (code === 1) {
+            this.memberExtra = data.extra
+            this.sendMemberList = data.records || []
+          } else {
+            vant.Toast.fail(msg)
+          }
+        })
+      },
+      handleClient () {
+        const headers = new Headers()
+        headers.append('token', this.token)
+        headers.append('tenancyId', this.tenancyId)
+        headers.append('userId', this.userId)
+        fetch(this.httpUrl + '/scrm/v1/wxcp-send/m/findClientsPage', {
+          method: 'post',
+          body: JSON.stringify({
+            sendId: this.id,
+            status: this.filterIndex,
+            page: 1,
+            pageCount: 1000,
+          }),
+          headers: {
+            'Content-Type': 'application/json',
+            'token': this.token,
+            'tenancyId': this.tenancyId,
+            'userId': this.userId,
+          }
+        }).then(res => {
+          return res.json()
+        }).then(result => {
+          let { data, code, msg } = result
+          if (code === 1) {
+            this.clientExtra = data.extra
+            this.clientList = data.records || []
+          } else {
+            vant.Toast.fail(msg)
+          }
+        })
+      },
+      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;
+      },
+      // 截取url中的数据
+      getQueryParam(paramName) {
+        // 获取当前URL的查询字符串部分  
+        const queryString = window.location.search;
+        // 创建一个URLSearchParams对象  
+        const urlParams = new URLSearchParams(queryString);
+        // 返回指定参数的值,如果不存在则返回null  
+        return urlParams.get(paramName);
+      },
+    }
+  })   
+</script>
+
+</html>

+ 427 - 0
lottery/qw/mass.html

@@ -0,0 +1,427 @@
+<!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>
+  <!-- 引入样式文件 -->
+  <link rel="stylesheet"
+    href="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1758012584633/vant.css" />
+  <!-- 必须先引入vue,  后使用vant-ui -->
+  <script
+    src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1742017957144/vue.js"></script>
+  <!-- 引入vant的组件库-->
+  <!-- 引入 Vant 的 JS 文件 -->
+  <script
+    src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1758012748487/vant.min.js"></script>
+
+  <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
+  <script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js"></script>
+  <!-- <script src="js/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: #F7F9FC;
+  }
+
+  .page5 {
+    width: 100vw;
+    box-sizing: border-box;
+  }
+
+  .task_content {
+    padding: 15px 10px;
+  }
+
+  .task_item {
+    width: 100%;
+    background: #FFFFFF;
+    border-radius: 15px;
+    box-sizing: border-box;
+    padding: 15px 10px;
+  }
+
+
+  .client_tag {
+    font-size: 12px;
+    line-height: 17px;
+  }
+
+
+  .status1 {
+    color: #136DFB;
+  }
+
+  .status2 {
+    color: #FFA041;
+  }
+
+  .status3 {
+    color: #FF4141;
+  }
+
+  .mem_title {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding-bottom: 10px;
+  }
+
+  .mem_title_left {
+    font-size: 14px;
+    color: #222222;
+    line-height: 20px;
+    padding-left: 5px;
+    position: relative;
+    display: flex;
+    align-items: center;
+  }
+
+  .mem_title_left::after {
+    position: absolute;
+    left: 0;
+    content: '';
+    width: 2px;
+    height: 12px;
+    background: #136DFB;
+    border-radius: 1px;
+  }
+
+  .mem_title_right {
+    display: flex;
+    align-items: center;
+    font-size: 12px;
+    color: #999999;
+    line-height: 17px;
+  }
+
+  .mem_title_right img {
+    width: 16px;
+    height: 16px;
+  }
+
+  .mem_tag {
+    display: flex;
+    flex-wrap: wrap;
+    align-items: center;
+    gap: 10px;
+  }
+
+  .mem_tag span {
+    padding: 2px 8px;
+    background: rgba(19, 109, 251, 0.05);
+    border-radius: 5px;
+    font-size: 12px;
+    line-height: 17px;
+    color: #136DFB;
+  }
+
+  .send_detail {
+    height: calc(100vh - 204px);
+    background: #FFFFFF;
+    border-radius: 15px 15px 0 0;
+  }
+
+  .van-tabs .van-tabs__wrap {
+    border-radius: 15px 15px 0 0;
+  }
+
+  .van-tabs--line .van-tabs__wrap {
+    height: 40px;
+  }
+
+  .van-tabs__nav {
+    padding: 0 25px 15px;
+  }
+
+  .van-tab--active {
+    color: #222222 !important;
+  }
+
+  .van-tab {
+    color: #999999;
+  }
+
+  .send_centent {
+    padding: 20px 15px;
+  }
+
+  .send_text {
+    font-size: 14px;
+    color: #222222;
+    line-height: 20px;
+    padding-bottom: 10px;
+  }
+
+  .send_contentText {
+    font-size: 14px;
+    line-height: 23px;
+    color: #666666;
+    padding-bottom: 20px;
+  }
+
+  .img_list {
+    display: flex;
+    flex-wrap: nowrap;
+    overflow-x: auto;
+    gap: 10px;
+    padding: 0 5px 10px;
+  }
+
+  .img_list img {
+    min-width: 105px;
+    height: 140px;
+    border-radius: 10px;
+    object-fit: cover;
+  }
+
+  .video_container {
+    position: relative;
+    width: 105px;
+    height: 140px;
+  }
+
+  .play_button {
+    width: 24px;
+    height: 24px;
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%);
+  }
+
+  .matters_item {
+    width: 163px;
+    height: 60px;
+    border-radius: 10px;
+    display: flex;
+    align-items: center;
+    padding: 10px;
+    box-sizing: border-box;
+    border: 1px solid #EFEFEF;
+  }
+
+  .matters_item img {
+    width: 40px;
+    height: 40px;
+    margin-right: 8px;
+  }
+
+  .matters_item_info {
+    display: flex;
+    flex-direction: column;
+    font-size: 12px;
+    color: #999999;
+    line-height: 17px;
+  }
+
+  .matters_item_title {
+    font-size: 12px;
+    color: #222222;
+    line-height: 17px;
+    width: 96px;
+    /* 必须设置宽度 */
+    overflow: hidden;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+    padding-bottom: 4px;
+  }
+
+  .matters_list {
+    display: flex;
+    flex-wrap: wrap;
+    gap: 10px;
+  }
+
+  .mem_centent {
+    padding: 10px 15px;
+  }
+
+  .filter_list {
+    display: flex;
+    flex-wrap: nowrap;
+    white-space: nowrap;
+    width: 100%;
+    overflow-x: auto;
+    gap: 10px;
+  }
+
+  .filter_span {
+    height: 25px;
+    box-sizing: border-box;
+    font-size: 12px;
+    color: #999999;
+    padding: 4px 12px;
+    background: #FAFAFA;
+    border-radius: 10px;
+  }
+
+  .active {
+    height: 25px;
+    box-sizing: border-box;
+    font-size: 12px;
+    color: #1677FF;
+    background: rgba(22, 119, 255, 0.1);
+    padding: 4px 12px;
+    border-radius: 10px;
+  }
+
+  .send_num_data {
+    display: flex;
+    align-items: center;
+    padding: 15px 5px 10px;
+    font-size: 12px;
+    color: #222222;
+    line-height: 17px;
+  }
+
+  .color1 {
+    color: #1677FF;
+    padding-right: 20px;
+  }
+
+  .color2 {
+    color: #FFA041;
+    padding-right: 20px;
+  }
+
+  .color3 {
+    color: #FF4E4E;
+    padding-right: 20px;
+  }
+
+  .color4 {
+    color: #7D97BF;
+    padding-right: 20px;
+  }
+
+  .send_mem_item {
+    height: 100px;
+    display: flex;
+    flex-direction: column;
+    justify-content: space-between;
+    padding: 15px;
+    background: #FAFAFA;
+    border-radius: 15px;
+    box-sizing: border-box;
+    margin-bottom: 10px;
+  }
+
+  .send_mem_name {
+    font-weight: 500;
+    font-size: 14px;
+    color: #222222;
+    line-height: 20px;
+  }
+
+  .send_mem_data {
+    display: flex;
+    align-items: center;
+    font-size: 12px;
+    color: #999999;
+    line-height: 17px;
+  }
+
+  .send_mem_time {
+    font-size: 12px;
+    color: #999999;
+    line-height: 17px;
+  }
+</style>
+
+<body>
+  <div id="box" class="box">
+    <div class="page5">
+      <div class="task_content">
+        <div class="task_item">
+          <div class="mem_title">
+            <div class="mem_title_left">生效成员</div>
+            <div class="mem_title_right">
+              <div>全部成员</div>
+              <img src="../img/qw/more_icon.png" alt="">
+            </div>
+          </div>
+          <div class="mem_tag">
+            <span v-for="(item, index) in formValidate.memberList" :key="index">{{item.name}}</span>
+          </div>
+        </div>
+      </div>
+      <div class="send_detail">
+      </div>
+    </div>
+  </div>
+</body>
+<script>
+  new Vue({
+    el: '#box',
+    data() {
+      return {
+        httpUrl: '',
+        bId: null,
+        env: '',
+        memberId: null,
+        formValidate: {
+          name: '',
+          memberList: [],
+          contentText: '',
+          ctOthers: [],
+          matters: [],
+          isAll: 1,
+          id: null,
+          type: 1,
+          sendTime: '',
+          notifyTime: '',
+          createdTime: ''
+        },
+        matterImgList: [],
+        matterOthersList: [],
+        matterTypeList: [
+          { contentType: 0, name: '文章' },
+          { contentType: 2, name: '表单' },
+          { contentType: 3, name: '文件' },
+          { contentType: 4, name: '外部链接' },
+          { contentType: 15, name: '视频' },
+          { contentType: 16, name: '视频链接' },
+          { contentType: 17, name: '图集链接' },
+        ],
+      }
+    },
+    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'
+      }
+    },
+    methods: {
+      // 截取url中的数据
+      getQueryParam(paramName) {
+        // 获取当前URL的查询字符串部分  
+        const queryString = window.location.search;
+        // 创建一个URLSearchParams对象  
+        const urlParams = new URLSearchParams(queryString);
+        // 返回指定参数的值,如果不存在则返回null  
+        return urlParams.get(paramName);
+      },
+    }
+  })   
+</script>
+
+</html>

+ 4017 - 0
lottery/qw/qwJxs.html

@@ -0,0 +1,4017 @@
+<!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>
+  <!-- 引入样式文件 -->
+  <link rel="stylesheet"
+    href="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1758012584633/vant.css" />
+  <!-- 必须先引入vue,  后使用vant-ui -->
+  <script
+    src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1742017957144/vue.js"></script>
+  <!-- 引入vant的组件库-->
+  <!-- 引入 Vant 的 JS 文件 -->
+  <script
+    src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1758012748487/vant.min.js"></script>
+
+  <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
+  <script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js"></script>
+  <script src="../js/select-date.js"></script>
+  <script
+    src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1758187289797/echarts.js"></script>
+  <script src="../js/echarts-wordcloud.js"></script>
+  <!-- <script src="js/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;
+  }
+
+  .page4 {
+    width: 100vw;
+    /* height: 100vh; */
+    box-sizing: border-box;
+    display: flex;
+    flex-direction: column;
+  }
+
+  .popup_list {
+    width: 100%;
+    height: 100%;
+    box-sizing: border-box;
+    display: flex;
+    flex-direction: column;
+    padding: 44px 30px 10px;
+
+  }
+
+  .popup_item {
+    padding: 15px 0;
+    font-weight: bold;
+    font-size: 16px;
+    color: #222222;
+    line-height: 24px;
+  }
+
+  .popup_line {
+    height: 1px;
+    background: linear-gradient(90deg, #000000 0%, rgba(0, 0, 0, 0) 100%);
+    opacity: 0.1;
+  }
+
+  .mer_item {
+    padding: 15px 0;
+    font-weight: bold;
+    font-size: 16px;
+    color: #222222;
+    line-height: 24px;
+    border-bottom: 1px solid transparent;
+    /* 占位 */
+    border-image: linear-gradient(90deg, rgba(0, 0, 0, 0.1) 0%, transparent 100%) 1;
+  }
+
+  .mer_item_active {
+    color: #1677FF;
+  }
+
+  .van-nav-bar__content {
+    height: 44px;
+  }
+
+  .van-nav-bar__title {
+    font-weight: bold;
+    font-size: 14px;
+    color: #222222;
+  }
+
+  .explain_list {
+    display: flex;
+    flex-direction: column;
+    padding: 10px;
+    font-weight: 400;
+    font-size: 12px;
+    color: #FFFFFF;
+    line-height: 18px;
+  }
+
+  .explain_list div {
+    padding-bottom: 10px;
+  }
+
+  .explain_list div:last-child {
+    padding-bottom: 0;
+  }
+
+  .explain_icon {
+    width: 20px;
+    height: 20px;
+    margin-left: 5px;
+  }
+
+  .navbar_icon {
+    width: 24px;
+    height: 24px;
+  }
+
+  .van-nav-bar__left {
+    padding: 0 10px;
+  }
+
+  .van-nav-bar__right {
+    padding: 0 10px;
+  }
+
+  .van-hairline--bottom::after {
+    border-bottom: none;
+  }
+
+  .top_data {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    padding: 10px;
+    height: 54px;
+    background: #FFFFFF;
+    box-sizing: border-box;
+    position: fixed;
+    top: 44px;
+    left: 0;
+    width: 100%;
+    z-index: 2;
+  }
+
+  .top_data_bottom {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    position: fixed;
+    top: 98px;
+    right: 0;
+    width: 100%;
+    z-index: 1;
+    padding-right: 10px;
+    background: #FAFAFA;
+  }
+
+  .outlet_data {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    height: 34px;
+    background: #FAFAFA;
+    box-sizing: border-box;
+  }
+
+  .close_icon {
+    width: 24px;
+    height: 24px;
+  }
+
+  .memberReply_title {
+    font-weight: 500;
+    font-size: 14px;
+    color: #222222;
+    line-height: 20px;
+    background: #FFFFFF;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    height: 44px;
+    padding: 0 10px;
+    width: 100%;
+    box-sizing: border-box;
+  }
+
+  .pop_content {
+    padding: 10px 10px 10px;
+    background: #FAFAFA;
+    height: calc(100vh - 44px);
+    overflow: auto;
+    box-sizing: border-box;
+  }
+
+  .select_box {
+    display: flex;
+    margin-bottom: 10px;
+  }
+
+  .select_day {
+    display: flex;
+    align-items: center;
+    background: #FFFFFF;
+    box-sizing: border-box;
+    padding: 10px 15px;
+    font-weight: 400;
+    font-size: 12px;
+    color: #222222;
+    margin-right: 10px;
+    border-radius: 10px;
+  }
+
+  .search_input {
+    width: 160px;
+    height: 38px;
+    border-radius: 10px;
+  }
+
+  .van-search__content {
+    background: #FFFFFF;
+    padding-left: 0;
+  }
+
+  .van-search__label {
+    font-weight: 400;
+    font-size: 12px;
+    color: #222222;
+    width: unset;
+  }
+
+  .van-popover__wrapper {
+    height: unset;
+  }
+
+  .top_data_title {
+    display: flex;
+    align-items: center;
+  }
+
+  .top_data_right {
+    display: flex;
+    align-items: center;
+  }
+
+  .item_gap {
+    margin-right: 10px;
+  }
+
+  .top_data_title_text {
+    font-weight: 500;
+    font-size: 14px;
+    color: #222222;
+    padding-left: 5px;
+  }
+
+  .top_data_title_branch {
+    font-weight: 400;
+    font-size: 12px;
+    color: #222222;
+    max-width: 90px;
+    white-space: nowrap;
+    /* 禁止换行 */
+    overflow: hidden;
+    /* 隐藏溢出内容 */
+    text-overflow: ellipsis;
+    /* 显示省略号 */
+  }
+
+  .triangle {
+    width: 0;
+    height: 0;
+    border: 6px solid transparent;
+    border-top-color: #222222;
+    margin-top: 6px;
+    border-radius: 5px;
+    margin-left: 5px;
+  }
+
+  .page4_content {
+    padding: 113px 10px 10px;
+  }
+
+  .page4_content2 {
+    padding: 131px 10px 10px;
+  }
+
+  .box_connect {
+    width: 100%;
+    background: #FFFFFF;
+    padding: 10px 10px 15px;
+    box-sizing: border-box;
+    border-radius: 10px;
+    margin-bottom: 15px;
+  }
+
+  .clientCharts_title_box {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+  }
+
+  .clientCharts_title {
+    font-weight: 500;
+    font-size: 12px;
+    color: #222222;
+    display: flex;
+    align-items: center;
+    margin-bottom: 15px;
+  }
+
+  .clientCharts_title::before {
+    content: '';
+    width: 2px;
+    height: 13px;
+    background: #1677FF;
+    border-radius: 1px;
+    margin-right: 5px;
+    display: inline-block;
+  }
+
+  .clientCharts_title_right {
+    font-weight: 400;
+    font-size: 12px;
+    color: #1677FF;
+    text-decoration-line: underline;
+    margin-bottom: 15px;
+  }
+
+  .all_data {
+    display: flex;
+    align-items: center;
+    flex-wrap: wrap;
+    margin-top: 15px;
+  }
+
+  .add_data_p {
+    font-weight: 400;
+    font-size: 12px;
+    color: #999999;
+    padding: 4px 10px;
+    background: #FFFFFF;
+    border-radius: 5px;
+    border: 1px solid #CCCCCC;
+    margin-top: 0;
+    margin-right: 15px;
+    margin-bottom: 10px;
+  }
+
+  .allData_bg {
+    background: #1677FF;
+    border-radius: 5px;
+    border: 1px solid #1677FF;
+    color: #FFFFFF;
+  }
+
+  /* 选择日期组件开始 */
+  .select_date {
+    display: flex;
+    align-items: center;
+  }
+
+  .date_list {
+    width: 212px;
+    box-sizing: border-box;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    background: #EDF3F8;
+    border-radius: 20px;
+    padding: 2px;
+  }
+
+  .filter_time_item {
+    padding: 4px 0 3px;
+    font-weight: 400;
+    font-size: 12px;
+    color: #222222;
+    line-height: 17px;
+    white-space: nowrap;
+  }
+
+  .filter_time1 {
+    padding-left: 14px;
+    padding-right: 14px;
+  }
+
+  .filter_time2 {
+    padding-left: 11px;
+    padding-right: 11px;
+  }
+
+  .filter_time3 {
+    padding-left: 7px;
+    padding-right: 7px;
+  }
+
+  .filter_time4 {
+    padding-left: 8px;
+    padding-right: 8px;
+  }
+
+  .current_date {
+    font-weight: 400;
+    font-size: 12px;
+    color: #1677FF;
+    line-height: 17px;
+    background: #FFFFFF;
+    border-radius: 12px;
+  }
+
+  /* 选择日期组件结束 */
+  .num_item_title {
+    font-weight: 400;
+    font-size: 12px;
+    line-height: 17px;
+    padding-bottom: 5px;
+    color: #666666;
+  }
+
+  .num_item_count {
+    font-weight: bold;
+    font-size: 16px;
+    line-height: 24px;
+    padding-bottom: 5px;
+    color: #222222;
+  }
+
+  .num_item_data {
+    display: flex;
+    align-items: center;
+    font-weight: 400;
+    font-size: 10px;
+    color: #999999;
+  }
+
+  .selected_color {
+    color: #1677FF;
+  }
+
+  .client_item_icon {
+    width: 12px;
+    height: 12px;
+  }
+
+  .branch_table {
+    overflow-x: auto;
+    width: 100%;
+  }
+
+  .branch_header {
+    padding: 10px;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    background: #F7F9FC;
+    border-radius: 10px;
+    font-weight: 500;
+    font-size: 12px;
+    color: #222222;
+    min-width: max-content;
+    text-align: center;
+  }
+
+  .branch_header div {
+    min-width: 30px;
+  }
+
+  .branch_item {
+    padding: 10px;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    font-weight: 400;
+    font-size: 12px;
+    color: #222222;
+    border-bottom: 1px solid #E5E8ED;
+    text-align: center;
+    word-wrap: break-word;
+    min-width: max-content;
+  }
+
+  .branch_item div {
+    min-width: 30px;
+  }
+
+  .interact_box_bottom {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+  }
+
+  .interact_box_bottom {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+  }
+
+  .interact_line {
+    width: 1px;
+    /* margin: 0 8px; */
+    height: 66px;
+    background: linear-gradient(180deg, rgba(229, 232, 237, 0) 0%, #E5E8ED 51%, rgba(229, 232, 237, 0) 100%);
+  }
+
+  .interact_item {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    text-align: center;
+  }
+
+  .leadGen_box {
+    padding: 10px;
+    background: #FAFAFA;
+    border-radius: 10px;
+  }
+
+  .leadGen_box {
+    padding: 10px;
+    background: #FAFAFA;
+    border-radius: 10px;
+  }
+
+  .table_carList {
+    width: 100%;
+    display: flex;
+    align-items: center;
+    overflow-x: auto;
+    margin-bottom: 20px;
+  }
+
+  .table_carBox {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    font-weight: 400;
+    font-size: 12px;
+    color: #222222;
+    border-radius: 34px;
+    margin-right: 10px;
+    padding: 0 15px;
+  }
+
+  .table_carBox_bg {
+    background: linear-gradient(#FFFFFF 0%, #E6F0FF 100%);
+  }
+
+  .table_car {
+    width: 90px;
+    height: 45px;
+  }
+
+  .table_carline {
+    width: 16px;
+    height: 3px;
+    border-radius: 34px;
+    margin-top: 2px;
+  }
+
+  .table_carline_bg {
+    background: #1677FF;
+  }
+
+  .data_tips {
+    font-weight: 400;
+    font-size: 12px;
+    line-height: 17px;
+    color: #C4CFDA;
+    text-align: center;
+    margin: 5px 0 24px;
+  }
+
+  .step_list {
+    width: 100%;
+    display: flex;
+    align-items: center;
+    overflow-x: auto;
+  }
+
+  .step_box {
+    min-width: 125px;
+    padding: 10px;
+    font-weight: 400;
+    font-size: 12px;
+    color: #666666;
+    background: #F7F9FC;
+    border-radius: 10px;
+    margin-right: 10px;
+  }
+
+  .step_box_bg {
+    background: #1677FF;
+    color: #FFFFFF;
+  }
+
+  .step_num {
+    font-weight: bold;
+    font-size: 16px;
+    color: #1677FF;
+    padding-top: 10px;
+    line-height: 24px;
+  }
+
+  .step_num_bg {
+    color: #FFFFFF;
+  }
+
+  .van_loading {
+    height: 400px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+  .qwjxs_tabs {
+    position: fixed;
+    top: 0;
+    left: 0;
+    width: 100%;
+    z-index: 2;
+  }
+  .qwjxs_tabs .van-tabs--line .van-tabs__wrap {
+    height: 40px;
+  }
+  .qwjxs_tabs .van-tab--active {
+    color: #136DFB !important;
+  }
+  .qwjxs_tabs .van-tab {
+    color: #999999;
+  }
+</style>
+
+<body>
+  <div id="qwJxs" class="box">
+    <!-- 数据查看 -->
+    <div class="page4">
+      <van-tabs class="qwjxs_tabs" v-model="pageTitle" ref="tabs" color="#136DFB" line-width="18px" line-height="2px"  @click="onClickTabs">
+        <van-tab title="客户资产" name="客户资产"></van-tab>
+        <van-tab title="聊天分析" name="聊天分析"></van-tab>
+        <van-tab title="员工监测" name="员工监测"></van-tab>
+        <van-tab title="运营任务" name="运营任务"></van-tab>
+      </van-tabs>
+      <div class="top_data">
+        <div class="top_data_right" v-if="pageTitle === '客户资产'">
+          <div class="top_data_title item_gap" @click="showPicker = true">
+            <div class="top_data_title_branch">网点:{{outletName}}</div>
+            <div class="triangle"></div>
+          </div>
+          <div class="top_data_title" @click="showDeptPicker = true">
+            <div class="top_data_title_branch">部门:{{deptName}}</div>
+            <div class="triangle"></div>
+          </div>
+        </div>
+        <select-date v-else :page-date="pageDate" @change-date="handleChangeDate"></select-date>
+      </div>
+      <div class="top_data_bottom" v-show="pageTitle !== '客户资产'">
+        <div class="outlet_data item_gap" @click="showPicker = true">
+          <div class="top_data_title_branch">网点:{{outletName}}</div>
+          <div class="triangle"></div>
+        </div>
+        <div class="outlet_data" @click="showDeptPicker = true">
+          <div class="top_data_title_branch">部门:{{deptName}}</div>
+          <div class="triangle"></div>
+        </div>
+      </div>
+      <!-- <van-popup v-model="showPopup" duration="0.2" closeable position="top" :lock-scroll="false"
+        :style="{ height: '100vh' }" @close="handleClosePopup">
+        <div class="popup_list" v-show="!showMer">
+          <div class="popup_item" @click="handlePage(1)">客户资产</div>
+          <div class="popup_line"></div>
+          <div class="popup_item" @click="handlePage(2)">聊天分析</div>
+          <div class="popup_line"></div>
+          <div class="popup_item" @click="handlePage(3)">员工监测</div>
+          <div class="popup_line"></div>
+          <div class="popup_item" @click="handlePage(4)">运营任务</div>
+          <div class="popup_line"></div>
+          <div class="popup_item" @click="showMer = true">切换商户</div>
+          <div class="popup_line"></div>
+          <div class="popup_item" @click="handleLoginOut">退出登录</div>
+        </div>
+        <div class="popup_list" v-show="showMer">
+          <div class="mer_item" :class="{'mer_item_active': tenancyId == item.id}" v-for="(item, index) in merList"
+            :key="index" @click="handleSelectMer(item)">{{item.name}}</div>
+        </div>
+      </van-popup> -->
+      <van-popup v-model="showPicker" duration="0.2" round position="bottom">
+        <van-picker title="网点" show-toolbar :columns="outletsData" @confirm="onConfirm" @cancel="showPicker = false" />
+      </van-popup>
+      <van-popup v-model="showDeptPicker" duration="0.2" round position="bottom">
+        <van-picker title="部门" show-toolbar :columns="deptData" @confirm="onDeptConfirm"
+          @cancel="showDeptPicker = false" />
+      </van-popup>
+      <!-- 顾问响应统计 -->
+      <van-popup v-model="showMemberReply" duration="0.2" position="right" :overlay="false" :lock-scroll="false"
+        :style="{ width: '100%', height: '100vh' }">
+        <div class="memberReply_title">
+          <image class="close_icon" src="../img/close.png" @click="closeReply"></image>
+          <div>顾问响应统计</div>
+          <div class="close_icon"></div>
+        </div>
+        <div class="pop_content">
+          <div class="select_box">
+            <van-popover v-model="showDatePicker" trigger="click" close-on-click-action close-on-click-outside
+              :actions="actions" @select="onSelect">
+              <template #reference>
+                <div class="select_day">
+                  <div class="top_data_title_branch">时间:{{timeData}}</div>
+                  <div class="triangle"></div>
+                </div>
+              </template>
+            </van-popover>
+            <van-search class="search_input" v-model="keyword" search :clearable="false" label="顾问:" left-icon=""
+              right-icon="search" @search="handleSearch" @click-right-icon="handleSearch"></van-search>
+            <van-calendar type="range" v-model="showSelfDate" @confirm="onSelfConfirm" color="#1677FF"
+              :min-date="minDate" :max-date="maxDate" :allow-same-day="true"></van-calendar>
+          </div>
+          <div class="box_connect">
+            <van-loading type="spinner" color="#1989fa" class="van_loading" v-if="loading"></van-loading>
+            <div class="branch_table" style="margin-bottom: 20px;" v-if="!loading">
+              <div class="branch_header" style="box-sizing: border-box;">
+                <div style="width: 80px;">顾问</div>
+                <div style="width: 50px;">今日处理<br />消息数</div>
+                <div style="width: 40px;">超时<br />消息数</div>
+                <div style="width: 50px;">平均响应<br />时间</div>
+                <div style="width: 30px;">管理</div>
+              </div>
+              <div class="branch_item" style="box-sizing: border-box;" v-for="(item, index) in memberReplyData"
+                :key="index">
+                <div style="width: 80px;max-width: 80px;">{{item.memberName}}</div>
+                <div style="width: 50px;">{{item.replyMsg}}</div>
+                <div style="width: 40px;">{{item.timeoutMsg}}</div>
+                <div style="width: 50px;">{{formatTime(item.avgReplyDuration)}}</div>
+                <div style="width: 30px;color: #1677FF;" @click="handleItemMemberReply(item)">详情</div>
+              </div>
+            </div>
+            <van-pagination v-model="currentPage" :total-items="totalItems" :show-page-size="3" force-ellipses
+              @change="handleChangePage" />
+          </div>
+        </div>
+      </van-popup>
+      <!-- 顾问响应统计详情 -->
+      <van-popup v-model="showItemMemberReply" position="right" duration="0.2" :lock-scroll="false" :overlay="false"
+        :style="{ width: '100%', height: '100vh' }">
+        <div class="memberReply_title">
+          <image class="close_icon" src="../img/close.png" @click="closeItemMemberReply"></image>
+          <div>顾问:{{currentMemberName}}</div>
+          <div class="close_icon"></div>
+        </div>
+        <div class="pop_content">
+          <div class="select_box">
+            <van-popover v-model="showDatePicker2" trigger="click" close-on-click-action close-on-click-outside
+              :actions="actions" @select="onSelect">
+              <template #reference>
+                <div class="select_day">
+                  <div class="top_data_title_branch">时间:{{timeData}}</div>
+                  <div class="triangle"></div>
+                </div>
+              </template>
+            </van-popover>
+            <van-calendar type="range" v-model="showSelfDate" @confirm="onSelfConfirm" color="#1677FF"
+              :min-date="minDate" :max-date="maxDate" :allow-same-day="true"></van-calendar>
+          </div>
+          <div class="box_connect">
+            <van-loading type="spinner" color="#1989fa" class="van_loading" v-if="loading"></van-loading>
+            <div class="branch_table" style="margin-bottom: 20px;" v-if="!loading">
+              <div class="branch_header">
+                <div style="width: 60px;">客户昵称</div>
+                <div style="width: 100px;">手机号</div>
+                <div style="width: 80px;">最新消息<br />时间</div>
+                <div style="width: 60px;">等待时间</div>
+                <div style="width: 100px;">最新消息<br />内容</div>
+              </div>
+              <div class="branch_item" v-for="(item, index) in memberDetailReplyData" :key="index">
+                <div style="width: 60px;">{{item.clientName}}</div>
+                <div style="width: 100px;">{{item.clientPhone}}</div>
+                <div style="width: 80px;">{{timeFormat(item.msgTime)}}</div>
+                <div style="width: 60px;">{{formatTime(item.waitSeconds)}}</div>
+                <div style="width: 100px;">{{item.content}}</div>
+              </div>
+            </div>
+            <van-pagination v-model="currentItemPage" :total-items="itemTotalItems" :show-page-size="3" force-ellipses
+              @change="handleChangeItemPage" />
+          </div>
+        </div>
+      </van-popup>
+      <!-- 顾问完成情况统计 -->
+      <van-popup v-model="showDoneReply" position="right" duration="0.2" :overlay="false" :lock-scroll="false"
+        :style="{ width: '100%', height: '100vh' }">
+        <div class="memberReply_title">
+          <image class="close_icon" src="../img/close.png" @click="closeReply"></image>
+          <div>顾问完成情况统计</div>
+          <div class="close_icon"></div>
+        </div>
+        <div class="pop_content">
+          <div class="select_box">
+            <van-popover v-model="showDatePicker3" trigger="click" close-on-click-action close-on-click-outside
+              :actions="actions" @select="onSelect">
+              <template #reference>
+                <div class="select_day">
+                  <div class="top_data_title_branch">时间:{{timeData}}</div>
+                  <div class="triangle"></div>
+                </div>
+              </template>
+            </van-popover>
+            <van-calendar type="range" v-model="showSelfDate" @confirm="onSelfConfirm" color="#1677FF"
+              :min-date="minDate" :max-date="maxDate" :allow-same-day="true"></van-calendar>
+          </div>
+          <div class="box_connect">
+            <div class="branch_table" style="margin-bottom: 20px;">
+              <div class="branch_header" style="box-sizing: border-box;">
+                <div style="width: 60px;">顾问</div>
+                <div style="width: 60px;">网点</div>
+                <div style="width: 60px;">下发任务数</div>
+                <div style="width: 60px;">完成任务数</div>
+              </div>
+              <div class="branch_item" style="box-sizing: border-box;" v-for="(item, index) in doneReplyData"
+                :key="index">
+                <div style="width: 60px;">{{item.memberName}}</div>
+                <div style="width: 60px;">{{item.outletName}}</div>
+                <div style="width: 60px;">{{item.taskNum}}</div>
+                <div style="width: 60px;">{{item.completeNum}}</div>
+              </div>
+            </div>
+            <van-pagination v-model="currentPage" :total-items="totalItems" :show-page-size="3" force-ellipses
+              @change="handleChangePage" />
+          </div>
+        </div>
+      </van-popup>
+      <div class="page4_content" v-show="pageTitle === '客户资产'">
+        <!-- 客户资产 -->
+        <div class="box_connect">
+          <div class="clientCharts_title" style="margin-bottom: 0;">总数据
+            <van-popover style="height: 20px;" v-model="showPopover" trigger="click" theme="dark" placement="right">
+              <div class="explain_list">
+                <div>总客户数:添加企微的客户总数</div>
+                <div>互动客户数:有产生过客户动态(包括不限于内容浏览、活动浏览、聊天等)的客户数</div>
+                <div>留资报名客户数:填写过表单(含留资/活动报名等)的客户数</div>
+                <div>到店客户:展厅进店及售后回站客户数</div>
+                <div>成交客户:已购车的客户数(不含下订客戶)</div>
+              </div>
+              <template #reference>
+                <image class="explain_icon" src="../img/jxs7.png"></image>
+              </template>
+            </van-popover>
+          </div>
+          <div id="funnelChart" :style="{ width: '100%', height: '200px', marginBottom: '20px' }"></div>
+          <select-date :page-date="pageDate" @change-date="handleChangeDate"></select-date>
+          <div class="all_data">
+            <p class="add_data_p" :class="{'allData_bg': index === 1}" @click="handleClickItem(1)">总客户数</p>
+            <p class="add_data_p" :class="{'allData_bg': index === 2}" @click="handleClickItem(2)">互动客户数</p>
+            <p class="add_data_p" :class="{'allData_bg': index === 3}" @click="handleClickItem(3)">留资/报名客户数</p>
+            <p class="add_data_p" :class="{'allData_bg': index === 4}" @click="handleClickItem(4)">邀约到店客户数</p>
+            <p class="add_data_p" :class="{'allData_bg': index === 5}" @click="handleClickItem(5)">成交客户数</p>
+          </div>
+          <div id="adviserChart" v-if="index === 1" style="width: 100%;height: 200px;"></div>
+          <div id="labelChart" v-else style="width: 100%;height: 200px;"></div>
+        </div>
+        <div class="box_connect">
+          <div class="clientCharts_title">客群包分布</div>
+          <div class="table_carList">
+            <div class="table_carBox" :class="{'table_carBox_bg': carIndex === index}"
+              v-for="(item, index) in tableList" :key="index" @click="handleClickCar(item, index)">
+              <image class="table_car" :src="item.carModelImg"></image>
+              <div>{{item.carModel}}</div>
+              <div class="table_carline" :class="{'table_carline_bg': carIndex === index}"></div>
+            </div>
+          </div>
+          <div class="branch_table" v-if="carStepData.length > 0">
+            <div class="branch_header">
+              <div style="width: 40px;">阶段</div>
+              <div style="width: 60px;" v-for="(item, index) in carStepData[0].packageList[0].cols" :key="index">
+                {{item.name}}
+              </div>
+            </div>
+            <div class="branch_item" v-for="(item, index) in carStepData[0].packageList" :key="index">
+              <div style="width: 40px;">{{item.stepName}}</div>
+              <!-- 此处先循环carStepData[0].packageList[0].cols,是表格头以第一条数据为准 -->
+              <div style="min-width: 60px;" v-for="(val, valIndex) in carStepData[0].packageList[0].cols"
+                :key="valIndex">
+                <span style="min-width: 60px;" v-for="(col, colIndex) in item.cols" :key="colIndex">
+                  {{val.name === col.name ? col.value[0] : ''}}
+                </span>
+              </div>
+            </div>
+          </div>
+        </div>
+        <div class="box_connect">
+          <div class="clientCharts_title">意向车型标签排名</div>
+          <div id="intentRankChart" style="width: 100%;height: 100%;"></div>
+        </div>
+        <div class="box_connect">
+          <div class="clientCharts_title">已购车型标签排名</div>
+          <div id="buyRankChart" style="width: 100%;height: 100%;"></div>
+        </div>
+        <div class="data_tips">—— 每日5:00更新数据 ——</div>
+      </div>
+      <div class="page4_content2" v-show="pageTitle === '聊天分析'">
+        <!-- 聊天分析 -->
+        <div class="box_connect">
+          <div class="clientCharts_title">总数据</div>
+          <div class="leadGen_box">
+            <div class="interact_box_bottom">
+              <div class="interact_item">
+                <div class="num_item_title">私聊客户数</div>
+                <div class="num_item_count">{{chatIndicators.total.privateChat}}</div>
+                <div class="num_item_data">
+                  <div>昨日新增:
+                    <span class="selected_color">{{chatIndicators.yda.privateChat}}</span>
+                  </div>
+                  <image class="client_item_icon" src="../img/jxs-up1.png"></image>
+                </div>
+              </div>
+              <div class="interact_line"></div>
+              <div class="interact_item">
+                <div class="num_item_title">私聊消息数</div>
+                <div class="num_item_count">{{chatIndicators.total.privateMsgNum}}</div>
+                <div class="num_item_data">
+                  <div>昨日新增:
+                    <span class="selected_color">{{chatIndicators.yda.privateMsgNum}}</span>
+                  </div>
+                  <image class="client_item_icon" src="../img/jxs-up1.png"></image>
+                </div>
+              </div>
+              <div class="interact_line"></div>
+              <div class="interact_item">
+                <div class="num_item_title">群消息数</div>
+                <div class="num_item_count">{{chatIndicators.total.groupMsgNum}}</div>
+                <div class="num_item_data">
+                  <div>昨日新增:
+                    <span class="selected_color">{{chatIndicators.yda.groupMsgNum}}</span>
+                  </div>
+                  <image class="client_item_icon" src="../img/jxs-up1.png"></image>
+                </div>
+              </div>
+            </div>
+          </div>
+          <div id="interactChart" style="width: 100%;height: 200px"></div>
+        </div>
+        <div class="box_connect">
+          <div class="clientCharts_title">员工服务</div>
+          <div class="leadGen_box">
+            <div class="interact_box_bottom">
+              <div class="interact_item">
+                <div class="num_item_title">主动服务会话数</div>
+                <div class="num_item_count">{{chatIndicators.total.proactiveServe}}</div>
+                <div class="num_item_data">
+                  <div>昨日新增:
+                    <span class="selected_color">{{chatIndicators.yda.proactiveServe}}</span>
+                  </div>
+                  <image class="client_item_icon" src="../img/jxs-up1.png"></image>
+                </div>
+              </div>
+              <div class="interact_line"></div>
+              <div class="interact_item">
+                <div class="num_item_title">客户回复会话数</div>
+                <div class="num_item_count">{{chatIndicators.total.clientReply}}</div>
+                <div class="num_item_data">
+                  <div>昨日新增:
+                    <span class="selected_color">{{chatIndicators.yda.clientReply}}</span>
+                  </div>
+                  <image class="client_item_icon" src="../img/jxs-up1.png"></image>
+                </div>
+              </div>
+              <div class="interact_line"></div>
+              <div class="interact_item">
+                <div class="num_item_title">客户回复率</div>
+                <div class="num_item_count">{{chatIndicators.total.clientReplyPercent ?
+                  chatIndicators.total.clientReplyPercent + '%' : ''}}</div>
+                <div class="num_item_data">
+                  <div>较昨日:
+                    <span v-if="chatIndicators.yda.clientReplyPercent" class="selected_color"
+                      :style="{color: chatIndicators.yda.clientReplyPercent > 0 ? '#1677FF' : '#FF4E4E'}">
+                      {{chatIndicators.yda.clientReplyPercent > 0 ? '+' :
+                      ''}}{{chatIndicators.yda.clientReplyPercent}}%</span>
+                  </div>
+                  <image class="client_item_icon" v-if="chatIndicators.yda.clientReplyPercent"
+                    :src="chatIndicators.yda.clientReplyPercent > 0 ? '../img/jxs-up1.png' : '../img/jxs-down2.png'">
+                  </image>
+                </div>
+              </div>
+            </div>
+          </div>
+          <div id="staffChart" style="width: 100%;height: 200px"></div>
+        </div>
+        <div class="box_connect">
+          <div class="clientCharts_title">客户咨询</div>
+          <div class="leadGen_box">
+            <div class="interact_box_bottom">
+              <div class="interact_item">
+                <div class="num_item_title">主动咨询会话数</div>
+                <div class="num_item_count">{{chatIndicators.total.proactiveConsult}}</div>
+                <div class="num_item_data">
+                  <div>昨日新增:
+                    <span class="selected_color">{{chatIndicators.yda.proactiveConsult}}</span>
+                  </div>
+                  <image class="client_item_icon" src="../img/jxs-up1.png"></image>
+                </div>
+              </div>
+              <div class="interact_line"></div>
+              <div class="interact_item">
+                <div class="num_item_title">员工回复会话数</div>
+                <div class="num_item_count">{{chatIndicators.total.memberReply}}</div>
+                <div class="num_item_data">
+                  <div>昨日新增:
+                    <span class="selected_color">{{chatIndicators.yda.memberReply}}</span>
+                  </div>
+                  <image class="client_item_icon" src="../img/jxs-up1.png"></image>
+                </div>
+              </div>
+              <div class="interact_line"></div>
+              <div class="interact_item">
+                <div class="num_item_title">员工平均响应时长</div>
+                <div class="num_item_count">{{chatIndicators.total.avgReplyDuration ?
+                  formatTime(chatIndicators.total.avgReplyDuration) : ''}}</div>
+                <div class="num_item_data">
+                  <div>较昨日:
+                    <span v-if="chatIndicators.yda.avgReplyDuration" class="selected_color"
+                      :style="{color: chatIndicators.yda.avgReplyDuration > 0 ? '#FF4E4E' : '#1677FF'}">
+                      {{chatIndicators.yda.avgReplyDuration > 0 ? '+' :
+                      ''}}{{formatTime(chatIndicators.yda.avgReplyDuration)}}</span>
+                  </div>
+                  <image class="client_item_icon" v-if="chatIndicators.yda.avgReplyDuration"
+                    :src="chatIndicators.yda.avgReplyDuration > 0 ? '../img/jxs-up2.png' : '../img/jxs-down1.png'">
+                  </image>
+                </div>
+              </div>
+            </div>
+          </div>
+          <div id="clientChart" style="width: 100%;height: 200px"></div>
+        </div>
+        <div class="box_connect">
+          <div class="clientCharts_title">消息舆情分析</div>
+          <div id="opinionChart" style="width: 100%;height: 380px"></div>
+        </div>
+        <div class="box_connect">
+          <div class="clientCharts_title">客户关注词云图</div>
+          <div id="wordCloudChart" style="width: 100%;height: 200px"></div>
+        </div>
+        <div class="data_tips">—— 每日5:00更新数据 ——</div>
+      </div>
+      <div class="page4_content2" v-show="pageTitle === '员工监测'">
+        <div class="box_connect">
+          <div class="clientCharts_title">销售进程客户数</div>
+          <div class="step_list">
+            <div class="step_box" :class="{'step_box_bg': clientIndex === index}"
+              v-for="(item, index) in saleIndicators" :key="index" @click="handleClickClient(item, index)">
+              <div>{{item.processName}}</div>
+              <div class="step_num" :class="{'step_num_bg': clientIndex === index}">{{item.clientNum}}</div>
+            </div>
+          </div>
+          <div id="clientStepChart" style="width: 100%;height: 200px"></div>
+        </div>
+        <div class="box_connect">
+          <div class="clientCharts_title">销售统计排名</div>
+          <div class="branch_table" v-if="saleRankData.length > 0">
+            <div class="branch_header">
+              <div style="width: 30px;">排名</div>
+              <div style="width: 80px;">顾问</div>
+              <div style="width: 40px;">网点</div>
+              <div style="width: 60px;" v-for="(item, index) in saleRankData[0].cols" :key="index">
+                {{item.name}}
+              </div>
+            </div>
+            <div class="branch_item" v-for="(item, index) in saleRankData" :key="index">
+              <div style="width: 30px;">{{index + 1}}</div>
+              <div style="width: 80px;max-width: 80px;">{{item.memberName}}</div>
+              <div style="width: 40px;">{{item.outletName}}</div>
+              <!-- 此处先循环saleRankData[0].cols,是表格头以第一条数据为准 -->
+              <div style="min-width: 60px;" v-for="(val, valIndex) in saleRankData[0].cols" :key="valIndex">
+                <span style="min-width: 60px;" v-for="(col, colIndex) in item.cols" :key="colIndex">
+                  {{val.name === col.name ? (col.value ? col.value[0] : '-') : ''}}
+                </span>
+              </div>
+            </div>
+          </div>
+        </div>
+        <div class="box_connect">
+          <div class="clientCharts_title_box">
+            <div class="clientCharts_title">聊天超时监测</div>
+            <div class="clientCharts_title_right" @click="handleMemberReply">查看详情</div>
+          </div>
+          <div id="timeOutTrendChart" style="width: 100%;height: 230px"></div>
+        </div>
+        <div class="box_connect">
+          <div class="clientCharts_title">聊天排行榜</div>
+          <div class="branch_table">
+            <div class="branch_header" style="box-sizing: border-box;">
+              <div style="width: 30px;">排名</div>
+              <div style="width: 80px;">员工</div>
+              <div style="width: 50px;">聊天客户数</div>
+              <div style="width: 50px;">主动会话<br />服务数</div>
+              <div style="width: 50px;">客户回复<br />会话数</div>
+            </div>
+            <div class="branch_item" style="box-sizing: border-box;" v-for="(item, index) in chatRankData" :key="index">
+              <div style="width: 30px;">{{index + 1}}</div>
+              <div style="width: 80px;max-width: 80px;">{{item.memberName}}</div>
+              <div style="width: 50px;">{{item.privateChat}}</div>
+              <div style="width: 50px;">{{item.proactiveServe}}</div>
+              <div style="width: 50px;">{{item.clientReply}}</div>
+            </div>
+          </div>
+        </div>
+        <div class="data_tips">—— 每日5:00更新数据 ——</div>
+      </div>
+      <div class="page4_content2" v-show="pageTitle === '运营任务'">
+        <div class="box_connect">
+          <div class="clientCharts_title_box">
+            <div class="clientCharts_title">总数据</div>
+            <div class="clientCharts_title_right" @click="handleDoneReply">查看更多</div>
+          </div>
+          <div class="branch_table">
+            <div class="branch_header" style="box-sizing: border-box;">
+              <div style="width: 60px;">网点</div>
+              <div style="width: 60px;">下发任务数</div>
+              <div style="width: 60px;">任务完成率</div>
+              <div style="width: 60px;">互动客户数</div>
+              <div>激活率</div>
+            </div>
+            <div class="branch_item" style="box-sizing: border-box;" v-for="(item, index) in outletCount" :key="index">
+              <div style="width: 60px;">{{item.outletName}}</div>
+              <div style="width: 60px;">{{item.taskNum}}</div>
+              <div style="width: 60px;">{{item.taskCompletePercent ? item.taskCompletePercent + '%' : '-'}}</div>
+              <div style="width: 60px;">{{item.interactClient}}</div>
+              <div>{{item.activatePercent ? item.activatePercent + '%' : '-'}}</div>
+            </div>
+          </div>
+        </div>
+        <div class="box_connect">
+          <div class="clientCharts_title">任务完成率</div>
+          <div id="taskCompleteChart" style="width: 100%;height: 200px"></div>
+        </div>
+        <div class="box_connect">
+          <div class="clientCharts_title">互动客户数</div>
+          <div id="opInteractChart" style="width: 100%;height: 200px"></div>
+        </div>
+        <div class="box_connect">
+          <div class="clientCharts_title">素材排行榜</div>
+          <div id="contentRank" style="width: 100%;"></div>
+        </div>
+        <div class="data_tips">—— 每日5:00更新数据 ——</div>
+      </div>
+    </div>
+  </div>
+</body>
+<script>
+  new Vue({
+    el: '#qwJxs',
+    data() {
+      return {
+        httpUrl: '',
+        bId: null,
+        env: '',
+        jxsName: '',
+        token: '',
+        tenancyId: '',
+        showPopup: false,
+        showMer: false,
+        showDatePicker: false,
+        showDatePicker2: false,
+        showDatePicker3: false,
+        actions: [
+          { text: '昨日' }, { text: '近7天' }, { text: '近30天' }, { text: '自定义' }
+        ],
+        keyword: '',
+        showSelfDate: false,
+        minDate: '',
+        maxDate: '',
+
+        merList: [], // 商户列表
+        outletsList: [], // 网点列表
+        outletsData: [], // 网点列表数据
+        deptList: [], // 部门列表
+        deptData: [], // 部门列表数据
+        pageTitle: '客户资产',
+        showPicker: false, // 网点选择器
+        showDeptPicker: false, // 部门选择器
+        deptName: '', // 部门名称
+        deptId: null, // 部门id
+        outletName: '', // 网点名称
+        outletId: null, // 网点id
+
+        clientIndicators: [], // 客户资产-总数据
+        pageStartTime: '',
+        pageEndTime: '',
+        index: 1,
+        showPopover: false,
+
+        lineDate: [], // 客户资产-统计趋势图
+        saleAdd: [],
+        serveAdd: [],
+        interactClient: [],
+        formClient: [],
+        storeClient: [],
+        dealClient: [],
+
+        tableList: [], // 客群包阶段车型
+        carIndex: 0,
+        carStepData: [], // 客群包阶段车型数据
+
+        intentRankData: [], // 意向车型标签排名
+        buyRankData: [], // 已购车型标签排名
+
+        chatIndicators: {
+          dayList: [], // 聊天分析-日数据
+          opinion: {},
+          total: {
+            privateChat: 0,
+            privateMsgNum: 0,
+            groupMsgNum: 0,
+            proactiveServe: 0,
+            clientReply: 0,
+            clientReplyPercent: 0,
+            proactiveConsult: 0,
+            memberReply: 0,
+            avgReplyDuration: 0,
+
+          },
+          yda: {
+            privateChat: 0,
+            privateMsgNum: 0,
+            groupMsgNum: 0,
+            proactiveServe: 0,
+            clientReply: 0,
+            clientReplyPercent: 0,
+            proactiveConsult: 0,
+            memberReply: 0,
+            avgReplyDuration: 0,
+          },
+        },
+
+        interactDate: [], // 聊天分析-总数据图数据
+        privateChat: [],
+        privateMsgNum: [],
+        groupMsgNum: [],
+        proactiveServe: [],
+        clientReply: [],
+        clientReplyPercent: [],
+        proactiveConsult: [],
+
+        memberReply: [],
+
+        showItemMemberReply: false, // 显示客户详情响应数据
+        currentMemberName: '', // 当前客户名称
+        memberId: '', // 当前客户id
+        memberDetailReplyData: [], // 客户详情响应数据
+        currentItemPage: 1, // 当前客户详情响应数据页码
+        itemTotalItems: 0, // 客户详情响应数据总页数
+
+        avgReplyDuration: [],
+        totalMsg: [],
+        privateMsg: [],
+        groupMsg: [],
+        maxValue: null,
+
+        wordCloudMap: [], // 客户关注词云图
+
+        saleIndicators: [], // 销售进程客户数
+        clientIndex: 0, // 销售进程客户数索引
+        clientStepDate: [], // 销售进程客户数-日期
+        clientStepNum: [], // 销售进程客户数-客户数
+
+        saleRankData: [], // 销售统计排名数据
+        timeOutDate: [], // 聊天超时监测-日期
+        timeoutMember: [], // 聊天超时监测-超时客户数
+        timeData: '',
+        memberStartTime: '',
+        memberEndTime: '',
+        showDoneReply: false, // 显示已完成响应数据
+        doneReplyData: [], // 已完成响应数据
+
+        showMemberReply: false,
+        currentPage: 1,
+        totalItems: 0,
+        memberReplyData: [], // 顾问响应统计数据
+        chatRankData: [], // 聊天排行榜数据
+
+        outletCount: [], // 运营任务-总数据
+        taskCompleteDate: [], // 运营任务-任务完成率-日期
+        taskCompletePercent: [], // 运营任务-任务完成率
+        opInteractDate: [], // 运营任务-互动客户数-日期
+        opInteractClient: [], // 运营任务-互动客户数
+
+        contentRankData: [], // 运营任务-素材排行榜
+        loading: false,
+        pageDate: [], // 日期范围
+      }
+    },
+    created() {
+      let nowDat = new Date();
+      let dateY = nowDat.getFullYear()
+      let dateM = nowDat.getMonth()
+      let dateD = nowDat.getDate()
+      // 设置日期可选最小值minDate、最大值maxDate
+      this.minDate = new Date(dateY - 1, dateM, dateD)
+      //日历可选范围为一年,dateY + 1
+      this.maxDate = new Date(dateY, dateM, dateD - 1)
+
+      this.bId = this.getQueryParam('bId')
+      this.env = this.getQueryParam('env')
+
+      if (!this.env || this.env === 'prod') {
+        this.httpUrl = 'https://wlapi.wefanbot.com'
+        // this.httpUrl = 'http://192.168.1.128:18993'
+      } else {
+        this.httpUrl = 'http://test.wefanbot.com:18993'
+        // this.httpUrl = 'http://192.168.1.128:18993'
+      }
+      this.token = localStorage.getItem('tokenValue')
+      this.tenancyId = localStorage.getItem('tenancyIdValue')
+      this.jxsName = localStorage.getItem('tenancyNameValue') || ''
+
+      this.pageStartTime = this.getDateTime(-7)
+      this.pageEndTime = this.getDateTime(-1)
+      this.memberStartTime = this.getDateTime(-7)
+      this.memberEndTime = this.getDateTime(-1)
+
+      this.initialization()
+      this.getAdminList()
+    },
+    methods: {
+      onClickTabs(name) {
+        this.pageTitle = name
+        this.requestData()
+      },
+      // 初始化
+      initialization() {
+        this.clientIndicators = []
+        this.pageStartTime = this.getDateTime(-7)
+        this.pageEndTime = this.getDateTime(-1)
+        this.index = 1
+        this.outletName = ''
+        this.outletId = null
+        this.getOutletsData()
+        this.deptName = ''
+        this.deptId = null
+        this.getDeptData() // 部门列表数据
+      },
+      requestData() {
+        if (this.pageTitle === '客户资产') {
+          this.getClientIndicators() // 客户资产-总数据
+          this.getTrend() // 客户资产-统计趋势图
+          this.stepStatistic() // 客户资产-客群包分布
+          this.getIntentRank() // 意向车型标签排名
+          this.getBuyRank() // 已购车型标签排名
+          this.$nextTick(() => {
+            this.funnelDraw()
+            this.passValue()
+            this.intentRankChart()
+            this.buyRankChart()
+          })
+        } else if (this.pageTitle === '聊天分析') {
+          this.handlePage(2)
+          this.$nextTick(() => {
+            this.interactChart()
+            this.staffChart()
+            this.clientChart()
+            this.opinionChart()
+            this.wordCloudChart()
+          })
+        } else if (this.pageTitle === '员工监测') {
+          this.handlePage(3)
+          this.$nextTick(() => {
+            this.clientStepChart()
+            this.timeOutTrendChart()
+          })
+        } else if (this.pageTitle === '运营任务') {
+          this.handlePage(4)
+          this.$nextTick(() => {
+            this.taskCompleteChart()
+            this.opInteractChart()
+            this.contentRankChart()
+          })
+        }
+      },
+      // 获取商户列表(右上角)
+      getAdminList() {
+        const headers = new Headers()
+        headers.append('token', this.token)
+        fetch(this.httpUrl + `/scrm/v1/user-info/o/adminList`, {
+          method: 'GET',
+          headers: headers
+        }).then(res => {
+          return res.json()
+        }).then(result => {
+          let { data, code, msg } = result
+          if (code === 1) {
+            this.merList = data || []
+          } else if (code === 10001) {
+            this.loginOut()
+          } else {
+            vant.Toast.fail(msg)
+          }
+        })
+      },
+      // 获取网点列表
+      getOutletsData() {
+        const headers = new Headers()
+        headers.append('token', this.token)
+        headers.append('tenancyId', this.tenancyId)
+        this.outletsList = []
+        this.outletsData = []
+        fetch(this.httpUrl + `/scrm/v1/tenancy-outlet/options`, {
+          method: 'GET',
+          headers: headers
+        }).then(res => {
+          return res.json()
+        }).then(result => {
+          let { data, code, msg } = result
+          if (code === 1) {
+            this.outletsList = data || []
+            this.outletsData = data && data.length > 0 ? data.map(item => item.name) : []
+          } else if (code === 10001) {
+            this.loginOut()
+          } else {
+            vant.Toast.fail(msg)
+          }
+        }).finally(() => {
+          if (this.outletsList.length === 1) {
+            this.outletName = this.outletsData[0]
+            this.outletId = this.outletsList.find(item => item.name === this.outletName).id || null
+          } else if (this.outletsList.length === 0 || this.outletsList.length > 1) {
+            this.outletsData.unshift('全部')
+            this.outletName = '全部'
+            this.outletId = null
+          }
+          this.requestData()
+        })
+      },
+      // 获取网点列表
+      getDeptData() {
+        const headers = new Headers()
+        headers.append('token', this.token)
+        headers.append('tenancyId', this.tenancyId)
+        this.deptList = []
+        this.deptData = []
+        fetch(this.httpUrl + `/scrm/v1/tenancy-outlet-department/options`, {
+          method: 'post',
+          body: JSON.stringify({
+            outletIds: this.outletId ? [this.outletId] : []
+          }),
+          headers: {
+            'Content-Type': 'application/json',
+            'token': this.token,
+            'tenancyId': this.tenancyId
+          }
+        }).then(res => {
+          return res.json()
+        }).then(result => {
+          let { data, code, msg } = result
+          if (code === 1) {
+            this.deptList = data || []
+            this.deptData = data && data.length > 0 ? data.map(item => item.name) : []
+          } else if (code === 10001) {
+            this.loginOut()
+          } else {
+            vant.Toast.fail(msg)
+          }
+        }).finally(() => {
+          if (this.deptList.length === 1) {
+            this.deptName = this.deptData[0]
+            this.deptId = this.deptList.find(item => item.name === this.deptName).id || null
+          } else if (this.deptList.length === 0 || this.deptList.length > 1) {
+            this.deptData.unshift('全部')
+            this.deptName = '全部'
+            this.deptId = null
+          }
+        })
+      },
+      onConfirm(val) {
+        this.outletName = val
+        if (this.outletName === '全部') {
+          this.outletId = null
+        } else {
+          this.outletId = this.outletsList.find(item => item.name === this.outletName).id || null
+        }
+        this.showPicker = false
+        this.deptId = null
+        this.deptName = '全部'
+        this.getDeptData()
+        if (this.pageTitle === '客户资产') {
+          this.getClientIndicators() // 客户资产-总数据
+          this.getTrend() // 客户资产-统计趋势图
+          this.stepStatistic() // 客户资产-客群包分布
+          this.getIntentRank() // 意向车型标签排名
+          this.getBuyRank() // 已购车型标签排名
+        } else if (this.pageTitle === '聊天分析') {
+          this.handlePage(2)
+        } else if (this.pageTitle === '员工监测') {
+          this.handlePage(3)
+        } else if (this.pageTitle === '运营任务') {
+          this.handlePage(4)
+        }
+      },
+      onDeptConfirm(val) {
+        this.deptName = val
+        if (this.deptName === '全部') {
+          this.deptId = null
+        } else {
+          this.deptId = this.deptList.find(item => item.name === this.deptName).id || null
+        }
+        this.showDeptPicker = false
+        if (this.pageTitle === '客户资产') {
+          this.getClientIndicators() // 客户资产-总数据
+          this.getTrend() // 客户资产-统计趋势图
+          this.stepStatistic() // 客户资产-客群包分布
+          this.getIntentRank() // 意向车型标签排名
+          this.getBuyRank() // 已购车型标签排名
+        } else if (this.pageTitle === '聊天分析') {
+          this.handlePage(2)
+        } else if (this.pageTitle === '员工监测') {
+          this.handlePage(3)
+        } else if (this.pageTitle === '运营任务') {
+          this.handlePage(4)
+        }
+      },
+      handlePage(index) {
+        switch (index) {
+          case 1:
+            this.pageTitle = '客户资产'
+            this.initialization()
+            break
+          case 2:
+            this.pageTitle = '聊天分析'
+            this.getChatIndicators() // 聊天分析 - 总数据
+            this.getWordCloudMap() // 聊天分析 - 词云图
+            break
+          case 3:
+            this.pageTitle = '员工监测'
+            this.getSaleIndicators() // 员工监测 - 销售进程
+            this.getSaleRank() // 员工监测 - 销售统计排名
+            this.getTimeOutTrendChart() // 员工监测 - 聊天超时监测
+            this.getChatRank() // 员工监测 - 聊天统计排名
+            break
+          case 4:
+            this.pageTitle = '运营任务'
+            this.getOutletCount() // 运营任务 - 总数据
+            this.getTaskCompleteChart() // 运营任务 - 任务完成率
+            this.getOpInteractChart() // 运营任务 - 互动客户数
+            this.getContentRank() // 运营任务 - 素材排行榜
+            break
+        }
+        this.showPopup = false
+      },
+      // 客户资产-总数据
+      getClientIndicators() {
+        this.clientIndicators = []
+        fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/clientIndicators`, {
+          method: 'post',
+          body: JSON.stringify({
+            outletId: this.outletId,
+            departmentIds: this.deptId ? [this.deptId] : []
+          }),
+          headers: {
+            'Content-Type': 'application/json',
+            'token': this.token,
+            'tenancyId': this.tenancyId
+          }
+        }).then(res => {
+          return res.json()
+        }).then(result => {
+          let { data, code, msg } = result
+          if (code === 1) {
+            this.clientIndicators = data.reverse() || []
+            this.$nextTick(() => {
+              this.funnelDraw()
+            })
+          } else if (code === 10001) {
+            this.loginOut()
+          } else {
+            vant.Toast.fail(msg)
+          }
+        })
+      },
+
+      // 客户资产-总数据(梯形图)
+      funnelDraw() {
+        let clientIndicators = this.clientIndicators
+        let funnelChart = echarts.getInstanceByDom(document.getElementById('funnelChart'))
+        if (funnelChart == null) {
+          funnelChart = echarts.init(document.getElementById('funnelChart'))
+        }
+
+        window.addEventListener('resize', function () {
+          funnelChart.resize()
+        })
+        funnelChart.setOption({
+          tooltip: {
+            trigger: 'item',
+            formatter(param) {
+              let label = ''
+              clientIndicators.forEach(item => {
+                if (item.name === param.data.name) {
+                  label = item.value
+                }
+              })
+              return param.data.name + ':' + label
+            }
+          },
+          series: [
+            {
+              type: 'funnel',
+              min: 0,
+              max: 100,
+              width: '50%',
+              minSize: '0%', //漏斗最小值的宽度
+              maxSize: '100%', //漏斗最大值的宽度
+              left: '0%',
+              right: '8%',
+              top: '8%',
+              bottom: '2%',
+              gap: 2,
+              label: {
+                show: false,
+                position: 'inside',
+                color: '#fff',
+              },
+              data: clientIndicators.map((item, index) => {
+                return {
+                  value: 40 + (index + 1) * 10,
+                  name: item.name,
+                  itemStyle: {
+                    color: `hsl(215, 100%, ${54 + index * 8}%)`
+                  },
+                }
+              })
+            },
+            {
+              type: 'funnel',
+              label: {
+                position: 'right',
+                lineHeight: 20,
+                padding: [0, 0, 0, 10],
+                formatter: function (param) {
+                  let label = ''
+                  let percent = ''
+                  let showPercent = true; // 默认显示占比
+                  clientIndicators.forEach(item => {
+                    if (item.name === param.data.name) {
+                      label = item.value
+                      percent = item.percent
+                    }
+                  });
+                  // 特殊处理长文本换行
+                  const secondLineText = label
+                    ? `${label}人`
+                    : (['到店客户', '成交客户'].includes(param.data.name)
+                      ? '待ONE-ID\n数据打通'  // 手动插入换行符
+                      : '');
+                  // 关键修改:当显示特殊文本时隐藏占比行
+                  if (['到店客户', '成交客户'].includes(param.data.name) && !label) {
+                    showPercent = false;
+                  }
+                  const lines = [];
+                  lines.push(`{firstLine|${param.data.name}:}{secondLine|${secondLineText}}`);
+
+                  // 只有需要显示占比时才添加第三行
+                  if (showPercent) {
+                    lines.push(`{thirdLine|占比:${percent ? percent + '%' : ''}}`);
+                  }
+
+                  return lines.join('\n');
+                },
+                // 新增 rich 样式定义
+                rich: {
+                  firstLine: {
+                    color: '#899EB2',  // 第一行颜色
+                    fontSize: 12,      // 第一行字号
+                    lineHeight: 20     // 保持与外层 lineHeight 一致
+                  },
+                  secondLine: {
+                    color: '#1677FF',
+                    fontWeight: 'bold',
+                    fontSize: 14,
+                    lineHeight: 20,
+                    width: 150,  // 关键:限制宽度触发自动换行
+                    overflow: 'break', // 允许文本换行
+                  },
+                  thirdLine: {
+                    color: '#1677FF',  // 第二行颜色(示例用红色)
+                    fontSize: 10,      // 第二行字号
+                    lineHeight: 10,     // 保持与外层 lineHeight 一致
+                  }
+                }
+              },
+              labelLine: {
+                show: true,
+                length: 40, // label拉线的长度根据自己的场景进行设置即可
+                lineStyle: {
+                  width: 1,
+                  type: 'solid'
+                }
+              },
+              min: 0,
+              max: 100,
+              minSize: '0%',
+              maxSize: 0,
+              left: '-20%',
+              right: '8%',
+              top: '10%',
+              bottom: '2%',
+              z: 1,
+              gap: 2,
+              data: clientIndicators.map((item, index) => {
+                return {
+                  value: 40 + (index + 1) * 10,
+                  name: item.name,
+                  itemStyle: {
+                    color: `hsl(215, 100%, ${54 + index * 8}%)`
+                  },
+                }
+              })
+            }
+          ]
+        }, true)
+      },
+      // 切换日期范围
+      handleChangeDate(date) {
+        this.pageStartTime = date[0]
+        this.pageEndTime = date[1]
+        this.pageDate = date
+        if (this.pageTitle === '客户资产') {
+          this.getTrend() // 客户资产-统计趋势图
+        } else if (this.pageTitle === '聊天分析') {
+          this.handlePage(2)
+        } else if (this.pageTitle === '员工监测') {
+          this.handlePage(3)
+        } else if (this.pageTitle === '运营任务') {
+          this.handlePage(4)
+        }
+      },
+      // 客户资产-统计趋势图
+      getTrend() {
+        this.lineDate = []
+        this.saleAdd = []
+        this.serveAdd = []
+        this.interactClient = []
+        this.formClient = []
+        this.storeClient = []
+        this.dealClient = []
+        fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/trend`, {
+          method: 'post',
+          body: JSON.stringify({
+            outletId: this.outletId,
+            departmentIds: this.deptId ? [this.deptId] : [],
+            startTime: this.pageStartTime,
+            endTime: this.pageEndTime,
+          }),
+          headers: {
+            'Content-Type': 'application/json',
+            'token': this.token,
+            'tenancyId': this.tenancyId
+          }
+        }).then(res => {
+          return res.json()
+        }).then(result => {
+          let { data, code, msg } = result
+          if (code === 1) {
+            if (data && data.length > 0) {
+              data.forEach(item => {
+                this.lineDate.push(item.time)
+                this.saleAdd.push(item.saleAdd)
+                this.serveAdd.push(item.serveAdd)
+                this.interactClient.push(item.interactClient)
+                this.formClient.push(item.formClient)
+                this.storeClient.push(item.storeClient)
+                this.dealClient.push(item.dealClient)
+              })
+            }
+            this.$nextTick(() => {
+              this.passValue()
+            })
+          } else if (code === 10001) {
+            this.loginOut()
+          } else {
+            vant.Toast.fail(msg)
+          }
+        })
+      },
+      // 切换5个模块(总客户数、互动客户数、留资/报名客户数、邀约到店客户数、成交客户数)
+      handleClickItem(index) {
+        this.index = index
+        this.passValue()
+      },
+      // 切换三个图表(总客户数、一客一群、销售顾问+服务顾问)
+      passValue() {
+        if (this.index === 1) {
+          this.$nextTick(() => {
+            this.adviserChart()
+          })
+        } else {
+          this.$nextTick(() => {
+            this.labelChart()
+          })
+        }
+      },
+      // 互动客户数、留资/报名客户数、邀约到店客户数、成交客户数(趋势图)
+      labelChart() {
+        let labelChart = echarts.getInstanceByDom(document.getElementById('labelChart'))
+        if (labelChart == null) {
+          labelChart = echarts.init(document.getElementById('labelChart'))
+        }
+
+        window.addEventListener('resize', function () {
+          labelChart.resize()
+        })
+        let dataText = ''
+        let labelData = []
+        if (this.index === 2) {
+          labelData = this.interactClient
+          dataText = '互动客户数'
+        } else if (this.index === 3) {
+          labelData = this.formClient
+          dataText = '留资/报名客户数'
+        } else if (this.index === 4) {
+          labelData = this.storeClient
+          dataText = '邀约到店客户数'
+        } else if (this.index === 5) {
+          labelData = this.dealClient
+          dataText = '成交客户数'
+        }
+        labelChart.setOption({
+          legend: {
+            data: [dataText],
+            orient: 'horizontal',
+            x: 'center',
+            y: 'top',
+            align: 'right',
+            itemWidth: 20,
+            itemHeight: 5,
+            itemGap: 20,
+            textStyle: {//图例文字的样式
+              color: '#666666', //图例文字颜色
+              fontSize: 10//图例文字大小
+            }
+          },
+          tooltip: {
+            trigger: 'axis',
+            axisPointer: {
+              type: 'shadow'
+            },
+          },
+          grid: {
+            top: '10%',
+            left: '10%',
+            right: '10%',
+            bottom: '10%'
+          },
+          xAxis: {
+            type: 'category',
+            axisLabel: {
+              show: true,
+              color: "#666666",
+              fontSize: '8',
+            },
+            data: this.lineDate,
+          },
+          yAxis: [
+            {// 第一种方式
+              type: 'value',
+              min: 0,
+              max: Math.max(...labelData),
+              splitNumber: 5,
+              interval: Math.max(...labelData) / 5,
+
+              position: 'left',
+              axisLabel: {
+                show: true,
+                color: "#222222",
+                fontSize: '8',
+                formatter: function (v) {
+                  return v.toFixed(0) //0表示小数为0位,1表示1位小数,2表示2位小数
+                }
+              },
+              splitLine: { //网格线
+                lineStyle: {
+                  type: 'dashed'//设置网格线类型 dotted:虚线   solid:实线
+                },
+              },
+              axisTick: { show: false },
+            },
+          ],
+          series: [
+            {
+              name: dataText,
+              type: 'bar',
+              stack: 'total',
+              color: '#1677FF ',
+              data: labelData,
+              itemStyle: {
+                // 设置柱形图圆角 [左上角,右上角,右下角,左下角]
+                borderRadius: [5, 5, 0, 0]
+              }
+            }
+          ],
+        }, true)
+      },
+      // 销售顾问+服务顾问(趋势图)
+      adviserChart() {
+        let adviserChart = echarts.getInstanceByDom(document.getElementById('adviserChart'))
+        if (adviserChart == null) {
+          adviserChart = echarts.init(document.getElementById('adviserChart'))
+        }
+
+        window.addEventListener('resize', function () {
+          adviserChart.resize()
+        })
+        adviserChart.setOption({
+          legend: {
+            show: true,
+            data: ['销售', '服务'],
+            orient: 'horizontal',
+            x: 'center',
+            y: 'top',
+            align: 'right',
+            itemWidth: 20,
+            itemHeight: 5,
+            itemGap: 20,
+            textStyle: {//图例文字的样式
+              color: '#666666', //图例文字颜色
+              fontSize: 10,//图例文字大小
+            }
+          },
+          tooltip: {
+            trigger: 'axis',
+            axisPointer: {
+              type: 'shadow'
+            },
+          },
+          grid: {
+            top: '10%',
+            left: '10%',
+            right: '10%',
+            bottom: '10%'
+          },
+          xAxis: {
+            type: 'category',
+            axisLabel: {
+              show: true,
+              color: '#666666',
+              fontSize: '8',
+            },
+            data: this.lineDate,
+          },
+          yAxis: [
+            {// 第一种方式
+              type: 'value',
+              min: 0,
+              max: Math.max(...this.saleAdd, ...this.serveAdd) * 2,
+              splitNumber: 5,
+              interval: Math.max(...this.saleAdd, ...this.serveAdd) * 2 / 5,
+
+              position: 'left',
+              axisLabel: {
+                show: true,
+                color: '#222222',
+                fontSize: '8',
+                formatter: function (v) {
+                  return v.toFixed(0) //0表示小数为0位,1表示1位小数,2表示2位小数
+                }
+              },
+              splitLine: { //网格线
+                lineStyle: {
+                  type: 'dashed'//设置网格线类型 dotted:虚线   solid:实线
+                },
+              },
+              axisTick: { show: false },
+            },
+          ],
+          series: [
+            {
+              name: '销售',
+              type: 'bar',
+              stack: 'total',
+              color: '#1677FF',
+              data: this.saleAdd,
+            },
+            {
+              name: '服务',
+              type: 'bar',
+              stack: 'total',
+              color: '#5CE56E ',
+              data: this.serveAdd,
+              itemStyle: {
+                // 设置柱形图圆角 [左上角,右上角,右下角,左下角]
+                borderRadius: [5, 5, 0, 0]
+              }
+            }
+          ],
+        }, true)
+      },
+      // 切换车型(客户资产-客群包统计)
+      handleClickCar(item, index) {
+        this.carIndex = index
+        this.carStepData = []
+        this.carStepData.push(this.tableList.find(ele => ele.carModel === item.carModel))
+      },
+      //  客户资产-客群包统计数据
+      stepStatistic() {
+        this.tableList = []
+        this.carStepData = []
+        fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/stepStatistic`, {
+          method: 'post',
+          body: JSON.stringify({
+            outletId: this.outletId,
+            departmentIds: this.deptId ? [this.deptId] : [],
+          }),
+          headers: {
+            'Content-Type': 'application/json',
+            'token': this.token,
+            'tenancyId': this.tenancyId
+          }
+        }).then(res => {
+          return res.json()
+        }).then(result => {
+          let { data, code, msg } = result
+          if (code === 1) {
+            this.tableList = data || []
+            if (this.tableList.length > 0) {
+              this.carStepData.push(this.tableList[0])
+            }
+          } else if (code === 10001) {
+            this.loginOut()
+          } else {
+            vant.Toast.fail(msg)
+          }
+        })
+      },
+      // 意向车型标签排名
+      getIntentRank() {
+        this.intentRankData = []
+        fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/intentRank`, {
+          method: 'post',
+          body: JSON.stringify({
+            outletId: this.outletId,
+            departmentIds: this.deptId ? [this.deptId] : [],
+          }),
+          headers: {
+            'Content-Type': 'application/json',
+            'token': this.token,
+            'tenancyId': this.tenancyId
+          }
+        }).then(res => {
+          return res.json()
+        }).then(result => {
+          let { data, code, msg } = result
+          if (code === 1) {
+            this.intentRankData = data || []
+            this.$nextTick(() => {
+              this.intentRankChart()
+            })
+          } else if (code === 10001) {
+            this.loginOut()
+          } else {
+            vant.Toast.fail(msg)
+          }
+        })
+      },
+      intentRankChart() {
+        let intentRankData = this.intentRankData.sort((a, b) => a.clientNum - b.clientNum)
+        let rankChart = echarts.getInstanceByDom(document.getElementById('intentRankChart'))
+        if (rankChart == null) {
+          rankChart = echarts.init(document.getElementById('intentRankChart'))
+        }
+
+        rankChart.resize({ height: this.intentRankData.length * 50 + 20 })
+        window.addEventListener('resize', function () {
+          rankChart.resize()
+        })
+        rankChart.setOption({
+          tooltip: {
+            trigger: 'item',
+            formatter: '{b}: {c}'
+          },
+          legend: {
+            left: 'center',
+            icon: 'circle', //小圆点
+            itemWidth: 10,
+            itemHeight: 10,
+            itemGap: 10, //间隔
+            bottom: '10%',
+          },
+          grid: {
+            bottom: "0",
+            top: "0",
+            left: "0",
+            containLabel: true,
+          },
+          xAxis: {
+            type: 'value',
+            axisLabel: {
+              show: true,
+              color: '#666666',
+              fontSize: '8',
+            },
+            splitLine: {
+              show: true,
+              lineStyle: {
+                type: 'dashed' // 设置为虚线
+              }
+            },
+          },
+          yAxis: {
+            type: 'category',
+            axisLabel: {
+              formatter: function (value) {
+                return value.length > 4 ? value.substring(0, 4) + '...' : value
+              },
+              showTooltip: true,
+            },
+            data: this.intentRankData.map(item => {
+              return item.tagName
+            }) || [],
+          },
+          series: [
+            {
+              type: 'bar',
+              barWidth: 24,
+              barGap: 12,
+              itemStyle: {
+                color: function (p) {
+                  // 亮度随索引递增实现渐变
+                  const lightness = 94 - p.dataIndex * 8;
+                  return `hsl(127.9, 72.5%, ${Math.min(100, lightness)}%)`;
+                }
+              },
+              data: this.intentRankData.map(item => {
+                return item.clientNum
+              }) || []
+            }
+          ]
+        })
+      },
+      // 已购车型标签排名
+      getBuyRank() {
+        this.buyRankData = []
+        fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/buyRank`, {
+          method: 'post',
+          body: JSON.stringify({
+            outletId: this.outletId,
+            departmentIds: this.deptId ? [this.deptId] : [],
+          }),
+          headers: {
+            'Content-Type': 'application/json',
+            'token': this.token,
+            'tenancyId': this.tenancyId
+          }
+        }).then(res => {
+          return res.json()
+        }).then(result => {
+          let { data, code, msg } = result
+          if (code === 1) {
+            this.buyRankData = data || []
+            this.$nextTick(() => {
+              this.buyRankChart()
+            })
+          } else if (code === 10001) {
+            this.loginOut()
+          } else {
+            vant.Toast.fail(msg)
+          }
+        })
+      },
+      buyRankChart() {
+        let buyRankData = this.buyRankData.sort((a, b) => a.clientNum - b.clientNum)
+        let rankChart = echarts.getInstanceByDom(document.getElementById('buyRankChart'))
+        if (rankChart == null) {
+          rankChart = echarts.init(document.getElementById('buyRankChart'))
+        }
+
+        rankChart.resize({ height: this.buyRankData.length * 50 + 20 })
+        window.addEventListener('resize', function () {
+          rankChart.resize()
+        })
+        rankChart.setOption({
+          tooltip: {
+            trigger: 'item',
+            formatter: '{b}: {c}'
+          },
+          legend: {
+            left: 'center',
+            icon: 'circle', //小圆点
+            itemWidth: 10,
+            itemHeight: 10,
+            itemGap: 10, //间隔
+            bottom: '10%',
+          },
+          grid: {
+            bottom: "0",
+            top: "0",
+            left: "0",
+            containLabel: true,
+          },
+          xAxis: {
+            type: 'value',
+            axisLabel: {
+              show: true,
+              color: '#666666',
+              fontSize: '8',
+            },
+            splitLine: {
+              show: true,
+              lineStyle: {
+                type: 'dashed' // 设置为虚线
+              }
+            },
+          },
+          yAxis: {
+            type: 'category',
+            axisLabel: {
+              formatter: function (value) {
+                return value.length > 4 ? value.substring(0, 4) + '...' : value
+              },
+              showTooltip: true,
+            },
+            data: this.buyRankData.map(item => {
+              return item.tagName
+            }) || [],
+          },
+          series: [
+            {
+              type: 'bar',
+              barWidth: 24,
+              barGap: 12,
+              itemStyle: {
+                color: function (p) {
+                  // 亮度随索引递增实现渐变
+                  const lightness = 87 - p.dataIndex * 8;
+                  return `hsl(215, 100%, ${Math.min(100, lightness)}%)`;
+                }
+              },
+              data: this.buyRankData.map(item => {
+                return item.clientNum
+              }) || []
+            }
+          ]
+        })
+      },
+      // 聊天分析 - 总数据
+      getChatIndicators() {
+        this.chatIndicators = {
+          dayList: [], // 聊天分析-日数据
+          opinion: {},
+          total: {
+            privateChat: 0,
+            privateMsgNum: 0,
+            groupMsgNum: 0,
+            proactiveServe: 0,
+            clientReply: 0,
+            clientReplyPercent: 0,
+            proactiveConsult: 0,
+            memberReply: 0,
+            avgReplyDuration: 0,
+
+          },
+          yda: {
+            privateChat: 0,
+            privateMsgNum: 0,
+            groupMsgNum: 0,
+            proactiveServe: 0,
+            clientReply: 0,
+            clientReplyPercent: 0,
+            proactiveConsult: 0,
+            memberReply: 0,
+            avgReplyDuration: 0,
+          },
+        }
+        this.interactDate = []
+        this.privateChat = []
+        this.privateMsgNum = []
+        this.groupMsgNum = []
+        this.proactiveServe = []
+        this.clientReply = []
+        this.clientReplyPercent = []
+        this.proactiveConsult = []
+        this.memberReply = []
+        this.avgReplyDuration = []
+        this.totalMsg = []
+        this.privateMsg = []
+        this.groupMsg = []
+        this.maxValue = null
+        fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/chatIndicators`, {
+          method: 'post',
+          body: JSON.stringify({
+            outletId: this.outletId,
+            departmentIds: this.deptId ? [this.deptId] : [],
+            startTime: this.pageStartTime,
+            endTime: this.pageEndTime,
+          }),
+          headers: {
+            'Content-Type': 'application/json',
+            'token': this.token,
+            'tenancyId': this.tenancyId
+          }
+        }).then(res => {
+          return res.json()
+        }).then(result => {
+          let { data, code, msg } = result
+          if (code === 1) {
+            this.chatIndicators = {
+              dayList: data.dayList || [], // 聊天分析-日数据
+              opinion: data.opinion ? data.opinion : {
+                negativeGroup: 0,
+                positiveGroup: 0,
+                neutralGroup: 0,
+                negativePrivate: 0,
+                positivePrivate: 0,
+                neutralPrivate: 0,
+                negativeTotal: 0,
+                positiveTotal: 0,
+                neutralTotal: 0,
+              },
+              total: data.total ? data.total : {
+                privateChat: 0,
+                privateMsgNum: 0,
+                groupMsgNum: 0,
+                proactiveServe: 0,
+                clientReply: 0,
+                clientReplyPercent: 0,
+                proactiveConsult: 0,
+                memberReply: 0,
+                avgReplyDuration: 0,
+              },
+              yda: data.yda ? data.yda : {
+                privateChat: 0,
+                privateMsgNum: 0,
+                groupMsgNum: 0,
+                proactiveServe: 0,
+                clientReply: 0,
+                clientReplyPercent: 0,
+                proactiveConsult: 0,
+                memberReply: 0,
+                avgReplyDuration: 0,
+              }, // 昨日数据
+            }
+
+            this.interactDate = []
+            this.privateChat = []
+            this.privateMsgNum = []
+            this.groupMsgNum = []
+            this.proactiveServe = []
+            this.clientReply = []
+            this.clientReplyPercent = []
+            this.proactiveConsult = []
+            this.memberReply = []
+            this.avgReplyDuration = []
+
+            if (data.dayList && data.dayList.length > 0) {
+              data.dayList.forEach(item => {
+                this.interactDate.push(item.time)
+                this.privateChat.push(item.privateChat)
+                this.privateMsgNum.push(item.privateMsgNum)
+                this.groupMsgNum.push(item.groupMsgNum)
+                this.proactiveServe.push(item.proactiveServe)
+                this.clientReply.push(item.clientReply)
+                this.clientReplyPercent.push(item.clientReplyPercent)
+                this.proactiveConsult.push(item.proactiveConsult)
+                this.memberReply.push(item.memberReply)
+                this.avgReplyDuration.push(item.avgReplyDuration)
+              })
+              this.$nextTick(() => {
+                this.interactChart()
+                this.staffChart()
+                this.clientChart()
+              })
+            }
+
+            this.totalMsg = []
+            this.privateMsg = []
+            this.groupMsg = []
+            this.maxValue = null
+            if (data.opinion) {
+              this.totalMsg = [data.opinion.negativeTotal, data.opinion.positiveTotal, data.opinion.neutralTotal]
+              this.privateMsg = [data.opinion.positivePrivate, data.opinion.negativePrivate, data.opinion.neutralPrivate]
+              this.groupMsg = [data.opinion.positiveGroup, data.opinion.negativeGroup, data.opinion.neutralGroup]
+              this.maxValue = Math.max.apply(null, [...this.totalMsg, ...this.privateMsg, ...this.groupMsg])
+              this.$nextTick(() => {
+                this.opinionChart()
+              })
+            }
+
+          } else if (code === 10001) {
+            this.loginOut()
+          } else {
+            vant.Toast.fail(msg)
+          }
+        })
+      },
+      // 聊天分析-总数据趋势图数据
+      interactChart() {
+        let interactChart = echarts.getInstanceByDom(document.getElementById('interactChart'))
+        if (interactChart == null) {
+          interactChart = echarts.init(document.getElementById('interactChart'))
+        }
+        window.addEventListener('resize', function () {
+          interactChart.resize()
+        })
+        interactChart.setOption({
+          legend: {
+            x: 'center',
+            y: 10,
+            align: 'right',
+            itemWidth: 20,
+            itemHeight: 5,
+            itemGap: 20,
+            textStyle: {//图例文字的样式
+              color: '#666666', //图例文字颜色
+              fontSize: 10//图例文字大小
+            },
+            data: [
+              {
+                name: "私聊客户数",
+                // 单独设置图例空心圆,通过设置边框颜色+背景颜色白色实现空心圆
+                itemStyle: {
+                  color: "#fff",
+                  borderColor: '#1677FF',
+                  borderWidth: 1,
+                },
+              },
+              {
+                name: "私聊消息数",
+                // 单独设置图例空心圆,通过设置边框颜色+背景颜色白色实现空心圆
+                itemStyle: {
+                  color: "#fff",
+                  borderColor: '#5CE56E',
+                  borderWidth: 1,
+                },
+              },
+              {
+                name: "群消息数",
+                itemStyle: {
+                  width: 20,
+                  height: 5,
+                  color: "#E6F0FF",
+                },
+              },
+            ]
+          },
+          tooltip: {
+            trigger: 'axis'
+          },
+          grid: {
+            top: '20%',
+            left: '10%',
+            right: '10%',
+            bottom: '10%'
+          },
+          xAxis: {
+            type: 'category',
+            axisLabel: {
+              show: true,
+              color: "#666666",
+              fontSize: '8',
+            },
+            data: this.interactDate,
+          },
+          yAxis: [
+            {// 第一种方式
+              type: 'value',
+              min: 0,
+              max: Math.max(...this.privateMsgNum, ...this.privateChat, ...this.groupMsgNum),
+              splitNumber: 5,
+              interval: Math.max(...this.privateMsgNum, ...this.privateChat, ...this.groupMsgNum) / 5,
+              axisLabel: {
+                show: true,
+                color: "#222222",
+                fontSize: '8',
+                formatter: function (v) {
+                  return v.toFixed(0) //0表示小数为0位,1表示1位小数,2表示2位小数
+                }
+              },
+              splitLine: { //网格线
+                lineStyle: {
+                  type: 'dashed'//设置网格线类型 dotted:虚线   solid:实线
+                },
+              },
+              axisTick: { show: false },
+            },
+          ],
+          series: [
+            {
+              name: '私聊客户数',
+              type: 'line',
+              color: '#1677FF',
+              data: this.privateChat,
+              symbol: 'none', //去掉折线图中的节点
+              smooth: true, //true 为平滑曲线,false为直线
+            },
+            {
+              name: '私聊消息数',
+              type: 'line',
+              color: '#5CE56E',
+              data: this.privateMsgNum,
+              symbol: 'none', //去掉折线图中的节点
+              smooth: true, //true 为平滑曲线,false为直线
+            },
+            {
+              name: '群消息数',
+              type: 'bar', //形状为柱状图
+              data: this.groupMsgNum,
+              itemStyle: {
+                color: ' #E6F0FF',
+              },
+              emphasis: {
+                itemStyle: {
+                  color: 'rgb(0, 157, 255)'
+                }
+              },
+            }
+          ],
+        }, true)
+      },
+      // 聊天分析-员工服务趋势图数据
+      staffChart() {
+        let staffChart = echarts.getInstanceByDom(document.getElementById('staffChart'))
+        if (staffChart == null) {
+          staffChart = echarts.init(document.getElementById('staffChart'))
+        }
+
+        window.addEventListener('resize', function () {
+          staffChart.resize()
+        })
+        staffChart.setOption({
+          legend: {
+            orient: 'horizontal',
+            x: 'center',
+            y: 10,
+            align: 'right',
+            itemWidth: 20,
+            itemHeight: 5,
+            itemGap: 20,
+            textStyle: {//图例文字的样式
+              color: '#666666', //图例文字颜色
+              fontSize: 10//图例文字大小
+            },
+            data: [
+              {
+                name: "主动服务会话数",
+                // 单独设置图例空心圆,通过设置边框颜色+背景颜色白色实现空心圆
+                itemStyle: {
+                  width: 20,
+                  height: 5,
+                  color: "#1677FF",
+                },
+              },
+              {
+                name: "客户回复会话数",
+                // 单独设置图例空心圆,通过设置边框颜色+背景颜色白色实现空心圆
+                itemStyle: {
+                  width: 20,
+                  height: 5,
+                  color: "#5CE56E",
+                },
+              },
+              {
+                name: "客户回复率",
+                itemStyle: {
+                  color: "#fff",
+                  borderColor: '#FFA64E',
+                  borderWidth: 1,
+                },
+              },
+            ]
+          },
+          tooltip: {
+            trigger: 'axis'
+          },
+          grid: {
+            top: '20%',
+            left: '10%',
+            right: '10%',
+            bottom: '10%'
+          },
+          xAxis: {
+            type: 'category',
+            axisLabel: {
+              show: true,
+              color: "#666666",
+              fontSize: '8',
+            },
+            data: this.interactDate,
+          },
+          yAxis: [
+            {// 第一种方式
+              type: 'value',
+              min: 0,
+              max: Math.max(...this.proactiveServe, ...this.clientReply),
+              splitNumber: 5,
+              interval: Math.max(...this.proactiveServe, ...this.clientReply) / 5,
+              axisLabel: {
+                show: true,
+                color: "#222222",
+                fontSize: '8',
+                formatter: function (v) {
+                  return v.toFixed(0) //0表示小数为0位,1表示1位小数,2表示2位小数
+                }
+              },
+              splitLine: { //网格线
+                lineStyle: {
+                  type: 'dashed'//设置网格线类型 dotted:虚线   solid:实线
+                },
+              },
+              axisTick: { show: false },
+            },
+            {// 第二种方式
+              type: 'value',
+              min: 0,
+              max: Math.max(...this.clientReplyPercent),
+              splitNumber: 5,
+              interval: Math.max(...this.clientReplyPercent) / 5,
+              axisLabel: {
+                show: true,
+                color: "#222222",
+                fontSize: '8',
+                formatter: function (v) {
+                  return v.toFixed(0) + ' %'; //0表示小数为0位,1表示1位小数,2表示2位小数
+                }
+              },
+              splitLine: { //网格线
+                lineStyle: {
+                  type: 'dashed'//设置网格线类型 dotted:虚线   solid:实线
+                },
+              },
+              axisTick: { show: false },
+            },
+          ],
+          series: [
+            {
+              name: '主动服务会话数',
+              type: 'bar', //形状为柱状图
+              data: this.proactiveServe,
+              itemStyle: {
+                color: ' #1677FF',
+                borderRadius: [5, 5, 0, 0]
+              },
+              emphasis: {
+                itemStyle: {
+                  color: 'rgb(0, 157, 255)'
+                }
+              },
+            },
+            {
+              name: '客户回复会话数',
+              type: 'bar', //形状为柱状图
+              data: this.clientReply,
+              itemStyle: {
+                color: ' #5CE56E',
+                borderRadius: [5, 5, 0, 0]
+              },
+              emphasis: {
+                itemStyle: {
+                  color: 'rgb(0, 157, 255)'
+                }
+              },
+            },
+            {
+              name: '客户回复率',
+              type: 'line',
+              color: '#FFA64E',
+              symbol: 'none',
+              yAxisIndex: 1,
+              data: this.clientReplyPercent,
+              tooltip: {
+                valueFormatter: function (value) {
+                  return value ? value + ' %' : ''
+                }
+              },
+              smooth: true, //true 为平滑曲线,false为直线
+            }
+          ],
+        }, true)
+      },
+      // 聊天分析-客户咨询趋势图数据
+      clientChart() {
+        let clientChart = echarts.getInstanceByDom(document.getElementById('clientChart'))
+        if (clientChart == null) {
+          clientChart = echarts.init(document.getElementById('clientChart'))
+        }
+
+        window.addEventListener('resize', function () {
+          clientChart.resize()
+        })
+        clientChart.setOption({
+          legend: {
+            orient: 'horizontal',
+            x: 'center',
+            y: 10,
+            align: 'right',
+            itemWidth: 16,
+            itemHeight: 4,
+            itemGap: 10,
+            textStyle: {//图例文字的样式
+              color: '#666666', //图例文字颜色
+              fontSize: 10//图例文字大小
+            },
+            data: [
+              {
+                name: "主动咨询会话数",
+                // 单独设置图例空心圆,通过设置边框颜色+背景颜色白色实现空心圆
+                itemStyle: {
+                  width: 20,
+                  height: 5,
+                  color: "#1677FF",
+                },
+              },
+              {
+                name: "员工回复会话数",
+                // 单独设置图例空心圆,通过设置边框颜色+背景颜色白色实现空心圆
+                itemStyle: {
+                  width: 20,
+                  height: 5,
+                  color: "#5CE56E",
+                },
+              },
+              {
+                name: "员工平均响应时长",
+                itemStyle: {
+                  color: "#fff",
+                  borderColor: '#FFA64E',
+                  borderWidth: 1,
+                },
+              },
+            ]
+          },
+          tooltip: {
+            trigger: 'axis'
+          },
+          grid: {
+            top: '20%',
+            left: '10%',
+            right: '10%',
+            bottom: '10%'
+          },
+          xAxis: {
+            type: 'category',
+            axisLabel: {
+              show: true,
+              color: "#666666",
+              fontSize: '8',
+            },
+            data: this.interactDate,
+          },
+          yAxis: [
+            {// 第一种方式
+              type: 'value',
+              min: 0,
+              max: Math.max(...this.proactiveConsult, ...this.memberReply),
+              splitNumber: 5,
+              interval: Math.max(...this.proactiveConsult, ...this.memberReply) / 5,
+              axisLabel: {
+                show: true,
+                color: "#222222",
+                fontSize: '8',
+                formatter: function (v) {
+                  return v.toFixed(0) //0表示小数为0位,1表示1位小数,2表示2位小数
+                }
+              },
+              splitLine: { //网格线
+                lineStyle: {
+                  type: 'dashed'//设置网格线类型 dotted:虚线   solid:实线
+                },
+              },
+              axisTick: { show: false },
+            },
+            {// 第二种方式
+              type: 'value',
+              min: 0,
+              max: Math.max(...this.avgReplyDuration),
+              splitNumber: 5,
+              interval: Math.max(...this.avgReplyDuration) / 5,
+              axisLabel: {
+                show: true,
+                color: "#222222",
+                fontSize: '8',
+                formatter: function (v) {
+                  return v.toFixed(0) + ' s'; //0表示小数为0位,1表示1位小数,2表示2位小数
+                }
+              },
+              splitLine: { //网格线
+                lineStyle: {
+                  type: 'dashed'//设置网格线类型 dotted:虚线   solid:实线
+                },
+              },
+              axisTick: { show: false },
+            },
+          ],
+          series: [
+            {
+              name: '主动咨询会话数',
+              type: 'bar', //形状为柱状图
+              data: this.proactiveConsult,
+              itemStyle: {
+                color: ' #1677FF',
+                borderRadius: [5, 5, 0, 0]
+              },
+              emphasis: {
+                itemStyle: {
+                  color: 'rgb(0, 157, 255)'
+                }
+              },
+            },
+            {
+              name: '员工回复会话数',
+              type: 'bar', //形状为柱状图
+              data: this.memberReply,
+              itemStyle: {
+                color: ' #5CE56E',
+                borderRadius: [5, 5, 0, 0]
+              },
+              emphasis: {
+                itemStyle: {
+                  color: 'rgb(0, 157, 255)'
+                }
+              },
+            },
+            {
+              name: '员工平均响应时长',
+              type: 'line',
+              color: '#FFA64E',
+              symbol: 'none',
+              yAxisIndex: 1,
+              tooltip: {
+                valueFormatter: function (value) {
+                  return value ? value.toFixed(0) + ' s' : ''
+                }
+              },
+              data: this.avgReplyDuration,
+              smooth: true, //true 为平滑曲线,false为直线
+            }
+          ],
+        }, true)
+      },
+      // 聊天分析-消息舆情分析
+      opinionChart() {
+        let opinionChart = echarts.getInstanceByDom(document.getElementById('opinionChart'))
+        if (opinionChart == null) {
+          opinionChart = echarts.init(document.getElementById('opinionChart'))
+        }
+
+        window.addEventListener('resize', function () {
+          opinionChart.resize()
+        })
+        opinionChart.setOption({
+          legend: {
+            orient: 'horizontal',
+            align: 'right',
+            itemWidth: 20,
+            itemHeight: 4,
+            itemGap: 20,
+            textStyle: {//图例文字的样式
+              color: '#666666', //图例文字颜色
+              fontSize: 10//图例文字大小
+            }
+          },
+          radar: {
+            indicator: [
+              { name: '负面', max: this.maxValue },
+              { name: '中性', max: this.maxValue },
+              { name: '正面', max: this.maxValue },
+            ],
+            radius: 150,
+          },
+          series: [
+            {
+              type: 'radar',
+              color: '#1677FF',
+              data: [
+                {
+                  value: this.totalMsg,
+                  name: '全部消息',
+                  itemStyle: {
+                    color: '#1677FF',
+                    lineStyle: {
+                      color: '#1677FF',
+                    },
+                  },
+                },
+                {
+                  value: this.privateMsg,
+                  name: '单聊消息',
+                  itemStyle: {
+                    color: '#5CE56E',
+                    lineStyle: {
+                      color: '#5CE56E',
+                    },
+                  },
+
+                },
+                {
+                  value: this.groupMsg,
+                  name: '群聊消息',
+                  itemStyle: {
+                    color: '#FFA64E',
+                    lineStyle: {
+                      color: '#FFA64E',
+                    },
+                  },
+
+                }
+              ]
+            },
+          ]
+        }, true)
+      },
+      // 聊天分析-词云图
+      getWordCloudMap() {
+        this.wordCloudMap = []
+        fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/wordCloudMap`, {
+          method: 'post',
+          body: JSON.stringify({
+            outletId: this.outletId,
+            departmentIds: this.deptId ? [this.deptId] : [],
+            startTime: this.pageStartTime,
+            endTime: this.pageEndTime,
+          }),
+          headers: {
+            'Content-Type': 'application/json',
+            'token': this.token,
+            'tenancyId': this.tenancyId
+          }
+        }).then(res => {
+          return res.json()
+        }).then(result => {
+          let { data, code, msg } = result
+          if (code === 1) {
+            this.wordCloudMap = data || []
+            this.$nextTick(() => {
+              this.wordCloudChart()
+            })
+          } else if (code === 10001) {
+            this.loginOut()
+          } else {
+            vant.Toast.fail(msg)
+          }
+        })
+      },
+      wordCloudChart() {
+        let wordCloudChart = echarts.getInstanceByDom(document.getElementById('wordCloudChart'))
+        if (wordCloudChart == null) {
+          wordCloudChart = echarts.init(document.getElementById('wordCloudChart'))
+        }
+
+        window.addEventListener('resize', function () {
+          wordCloudChart.resize()
+        })
+        wordCloudChart.setOption({
+          series: [{
+            type: 'wordCloud',
+            //maskImage: maskImage,
+            sizeRange: [12, 24],
+            rotationRange: [0, 0],
+            rotationStep: 45,
+            gridSize: 8,
+            shape: 'pentagon',
+            width: '100%',
+            height: '100%',
+            textStyle: {
+              fontFamily: '微软雅黑',
+              color: (v) => {
+                switch (true) {
+                  case v.dataIndex <= 5:
+                    return '#1677FF'
+                  case 5 < v.dataIndex && v.dataIndex <= 10:
+                    return 'rgba(22, 119, 255, 0.6)'
+                  default:
+                    return 'rgba(22, 119, 255, 0.4)'
+                }
+              }
+            },
+            data: this.wordCloudMap,
+          }]
+        }, true)
+      },
+      // 销售进程客户数
+      getSaleIndicators() {
+        this.saleIndicators = []
+        this.clientStepDate = []
+        this.clientStepNum = []
+        fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/saleIndicators`, {
+          method: 'post',
+          body: JSON.stringify({
+            outletId: this.outletId,
+            departmentIds: this.deptId ? [this.deptId] : [],
+            startTime: this.pageStartTime,
+            endTime: this.pageEndTime,
+          }),
+          headers: {
+            'Content-Type': 'application/json',
+            'token': this.token,
+            'tenancyId': this.tenancyId
+          }
+        }).then(res => {
+          return res.json()
+        }).then(result => {
+          let { data, code, msg } = result
+          if (code === 1) {
+            this.saleIndicators = data || []
+            if (data && data.length) {
+              data[0].dayList.forEach(item => {
+                this.clientStepDate.push(item.time)
+                this.clientStepNum.push(item.clientNum)
+              })
+              this.$nextTick(() => {
+                this.clientStepChart()
+              })
+            }
+          } else if (code === 10001) {
+            this.loginOut()
+          } else {
+            vant.Toast.fail(msg)
+          }
+        })
+      },
+      handleClickClient(item, index) {
+        this.clientIndex = index
+        this.clientStepDate = []
+        this.clientStepNum = []
+
+        if (item.dayList && item.dayList.length) {
+          this.clientStepDate = item.dayList.map(item => item.time)
+          this.clientStepNum = item.dayList.map(item => item.clientNum)
+          this.$nextTick(() => {
+            this.clientStepChart()
+          })
+        }
+
+      },
+      clientStepChart() {
+        let clientStepChart = echarts.getInstanceByDom(document.getElementById('clientStepChart'))
+        if (clientStepChart == null) {
+          clientStepChart = echarts.init(document.getElementById('clientStepChart'))
+        }
+        window.addEventListener('resize', function () {
+          clientStepChart.resize()
+        })
+        let text = this.saleIndicators[this.clientIndex].processName
+        clientStepChart.setOption({
+          legend: {
+            show: false,
+          },
+          tooltip: {
+            trigger: 'axis',
+            formatter: function (params) {
+              return params[0].name + '<br>'
+                + text + ': ' + params[0].value
+            }
+          },
+          grid: {
+            top: '10%',
+            left: '10%',
+            right: '10%',
+            bottom: '10%'
+          },
+          xAxis: {
+            type: 'category',
+            axisLabel: {
+              show: true,
+              color: "#666666",
+              fontSize: '8',
+            },
+            data: this.clientStepDate,
+          },
+          yAxis: [
+            {// 第一种方式
+              type: 'value',
+              min: 0,
+              max: Math.max(...this.clientStepNum),
+              splitNumber: 5,
+              interval: Math.max(...this.clientStepNum) / 5,
+              position: 'left',
+              axisLabel: {
+                show: true,
+                color: "#222222",
+                fontSize: '8',
+                formatter: function (v) {
+                  return v.toFixed(0) //0表示小数为0位,1表示1位小数,2表示2位小数
+                }
+              },
+              splitLine: { //网格线
+                lineStyle: {
+                  type: 'dashed'//设置网格线类型 dotted:虚线   solid:实线
+                },
+              },
+              axisTick: { show: false },
+            },
+          ],
+          series: [
+            {
+              type: 'line',
+              color: '#1677FF',
+              areaStyle: {
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                  { offset: 0, color: 'rgba(22,119,255,0.43)' },
+                  { offset: 1, color: 'rgba(22,119,255,0)' }
+                ])
+              }, //填充区域样式
+              data: this.clientStepNum,
+              symbol: 'none', //去掉折线图中的节点
+              smooth: true, //true 为平滑曲线,false为直线
+            }
+          ],
+        }, true)
+      },
+      // 销售统计排名
+      getSaleRank() {
+        this.saleRankData = []
+        fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/saleRank`, {
+          method: 'post',
+          body: JSON.stringify({
+            outletId: this.outletId,
+            departmentIds: this.deptId ? [this.deptId] : [],
+            startTime: this.pageStartTime,
+            endTime: this.pageEndTime,
+          }),
+          headers: {
+            'Content-Type': 'application/json',
+            'token': this.token,
+            'tenancyId': this.tenancyId
+          }
+        }).then(res => {
+          return res.json()
+        }).then(result => {
+          let { data, code, msg } = result
+          if (code === 1) {
+            this.saleRankData = data || []
+          } else if (code === 10001) {
+            this.loginOut()
+          } else {
+            vant.Toast.fail(msg)
+          }
+        })
+      },
+      // 聊天超时监测
+      getTimeOutTrendChart() {
+        this.timeOutDate = []
+        this.timeoutMember = []
+        fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/timeOutTrend`, {
+          method: 'post',
+          body: JSON.stringify({
+            outletId: this.outletId,
+            departmentIds: this.deptId ? [this.deptId] : [],
+            startTime: this.pageStartTime,
+            endTime: this.pageEndTime,
+          }),
+          headers: {
+            'Content-Type': 'application/json',
+            'token': this.token,
+            'tenancyId': this.tenancyId
+          }
+        }).then(res => {
+          return res.json()
+        }).then(result => {
+          let { data, code, msg } = result
+          if (code === 1) {
+            if (data && data.length) {
+              data.forEach(item => {
+                this.timeOutDate.push(item.time)
+                this.timeoutMember.push(item.timeoutMember)
+              })
+              this.$nextTick(() => {
+                this.timeOutTrendChart()
+              })
+            }
+          } else if (code === 10001) {
+            this.loginOut()
+          } else {
+            vant.Toast.fail(msg)
+          }
+        })
+      },
+      timeOutTrendChart() {
+        let timeOutTrendChart = echarts.getInstanceByDom(document.getElementById('timeOutTrendChart'))
+        if (timeOutTrendChart == null) {
+          timeOutTrendChart = echarts.init(document.getElementById('timeOutTrendChart'))
+        }
+
+        window.addEventListener('resize', function () {
+          timeOutTrendChart.resize()
+        })
+        timeOutTrendChart.setOption({
+          legend: {
+            show: false,
+          },
+          tooltip: {
+            trigger: 'axis',
+            formatter: function (params) {
+              return params[0].name + ': ' + params[0].value
+            }
+          },
+          grid: {
+            top: '10%',
+            left: '10%',
+            right: '10%',
+            bottom: '10%'
+          },
+          xAxis: {
+            type: 'category',
+            axisLabel: {
+              show: true,
+              color: "#666666",
+              fontSize: '8',
+            },
+            data: this.timeOutDate,
+          },
+          yAxis: [
+            {// 第一种方式
+              type: 'value',
+              min: 0,
+              max: Math.max(...this.timeoutMember),
+              splitNumber: 5,
+              interval: Math.max(...this.timeoutMember) / 5,
+              position: 'left',
+              axisLabel: {
+                show: true,
+                color: "#222222",
+                fontSize: '8',
+                formatter: function (v) {
+                  return v.toFixed(0) //0表示小数为0位,1表示1位小数,2表示2位小数
+                }
+              },
+              splitLine: { //网格线
+                lineStyle: {
+                  type: 'dashed'//设置网格线类型 dotted:虚线   solid:实线
+                },
+              },
+              axisTick: { show: false },
+            },
+          ],
+          series: [
+            {
+              type: 'line',
+              color: '#FF4E4E',
+              areaStyle: {
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                  { offset: 0, color: 'rgba(255, 78, 78,0.43)' },
+                  { offset: 1, color: 'rgba(255, 78, 78,0)' }
+                ])
+              }, //填充区域样式
+              data: this.timeoutMember,
+              symbol: 'none', //去掉折线图中的节点
+              smooth: true, //true 为平滑曲线,false为直线
+            }
+          ],
+        }, true)
+      },
+      returnOutsideDate() {
+        this.memberStartTime = this.pageStartTime
+        this.memberEndTime = this.pageEndTime
+        if (this.pageStartTime === this.getDateTime(-1) && this.pageEndTime === this.getDateTime(-1)) {
+          this.timeData = '昨日'
+        } else if (this.pageStartTime === this.getDateTime(-7) && this.pageEndTime === this.getDateTime(-1)) {
+          this.timeData = '近7天'
+        } else if (this.pageStartTime === this.getDateTime(-30) && this.pageEndTime === this.getDateTime(-1)) {
+          this.timeData = '近30天'
+        } else {
+          this.timeData = '自定义'
+        }
+      },
+      // 顾问响应统计
+      handleMemberReply() {
+        this.showMemberReply = true
+        this.returnOutsideDate()
+        this.getMemberReply()
+      },
+      getMemberReply() {
+        this.loading = true
+        fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/memberReply`, {
+          method: 'post',
+          body: JSON.stringify({
+            outletId: this.outletId,
+            departmentIds: this.deptId ? [this.deptId] : [],
+            startTime: this.memberStartTime,
+            endTime: this.memberEndTime,
+            page: this.currentPage,
+            pageCount: 10,
+            keyword: this.keyword,
+          }),
+          headers: {
+            'Content-Type': 'application/json',
+            'token': this.token,
+            'tenancyId': this.tenancyId
+          }
+        }).then(res => {
+          return res.json()
+        }).then(result => {
+          let { data, code, msg } = result
+          if (code === 1) {
+            this.memberReplyData = data.records || []
+            this.totalItems = data.total || 0
+          } else if (code === 10001) {
+            this.loginOut()
+          } else {
+            vant.Toast.fail(msg)
+          }
+        }).finally(() => {
+          this.loading = false
+        })
+      },
+      onSelect(val) {
+        this.timeData = val.text
+        if (this.timeData === '自定义') {
+          this.showSelfDate = true
+        } else {
+          if (this.timeData === '昨日') {
+            this.memberStartTime = this.getDateTime(-1)
+            this.memberEndTime = this.getDateTime(-1)
+          } else if (this.timeData === '近7天') {
+            this.memberStartTime = this.getDateTime(-7)
+            this.memberEndTime = this.getDateTime(-1)
+          } else if (this.timeData === '近30天') {
+            this.memberStartTime = this.getDateTime(-30)
+            this.memberEndTime = this.getDateTime(-1)
+          }
+          this.$nextTick(() => {
+            if (this.showDoneReply) {
+              this.getDoneReply()
+            } else {
+              if (this.memberId) {
+                this.handleItemMemberReplyDetail()
+              } else {
+                this.getMemberReply()
+              }
+            }
+          })
+
+        }
+      },
+      onSelfConfirm(date) {
+        const [start, end] = date
+        if (this.formatDate(new Date()) === this.formatDate(end)) {
+          this.formatDate(end) = this.formatDate(start)
+        }
+        this.memberStartTime = this.formatDate(start)
+        this.memberEndTime = this.formatDate(end)
+        this.showSelfDate = false
+        if (this.showDoneReply) {
+          this.getDoneReply()
+        } else {
+          if (this.memberId) {
+            this.handleItemMemberReplyDetail()
+          } else {
+            this.getMemberReply()
+          }
+        }
+      },
+      formatDate(date) {
+        return `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`
+      },
+      handleSearch() {
+        this.getMemberReply()
+      },
+      handleChangePage(val) {
+        this.currentPage = val
+        if (this.showDoneReply) {
+          this.getDoneReply()
+        } else {
+          this.getMemberReply()
+        }
+      },
+      closeReply() {
+        this.currentPage = 1
+        this.totalItems = 0
+        this.keyword = ''
+        this.timeData = '近7天'
+        this.memberStartTime = this.getDateTime(-7)
+        this.memberEndTime = this.getDateTime(-1)
+        this.memberReplyData = []
+        this.showMemberReply = false
+        this.showDoneReply = false
+      },
+      handleItemMemberReply(item) {
+        this.showItemMemberReply = true
+        this.currentMemberName = item.memberName
+        this.memberId = item.memberId
+        this.currentItemPage = 1
+        this.itemTotalItems = 0
+        this.memberDetailReplyData = []
+        this.handleItemMemberReplyDetail(item)
+      },
+      closeItemMemberReply() {
+        this.showItemMemberReply = false
+      },
+      handleChangeItemPage(val) {
+        this.currentItemPage = val
+        this.handleItemMemberReplyDetail()
+      },
+      // 顾客响应统计-详情
+      handleItemMemberReplyDetail() {
+        this.loading = true
+        fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/memberReplyDetail`, {
+          method: 'post',
+          body: JSON.stringify({
+            outletId: this.outletId,
+            departmentIds: this.deptId ? [this.deptId] : [],
+            startTime: this.memberStartTime,
+            endTime: this.memberEndTime,
+            page: this.currentItemPage,
+            pageCount: 10,
+            memberId: this.memberId,
+          }),
+          headers: {
+            'Content-Type': 'application/json',
+            'token': this.token,
+            'tenancyId': this.tenancyId
+          }
+        }).then(res => {
+          return res.json()
+        }).then(result => {
+          let { data, code, msg } = result
+          if (code === 1) {
+            this.memberDetailReplyData = data.records || []
+            this.itemTotalItems = data.total || 0
+          } else if (code === 10001) {
+            this.loginOut()
+          } else {
+            vant.Toast.fail(msg)
+          }
+        }).finally(() => {
+          this.loading = false
+        })
+      },
+      // 顾客完成情况统计
+      handleDoneReply() {
+        this.showDoneReply = true
+        this.returnOutsideDate()
+        this.getDoneReply()
+      },
+      getDoneReply() {
+        fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/operationMemberCnt`, {
+          method: 'post',
+          body: JSON.stringify({
+            outletId: this.outletId,
+            departmentIds: this.deptId ? [this.deptId] : [],
+            startTime: this.memberStartTime,
+            endTime: this.memberEndTime,
+            page: this.currentPage,
+            pageCount: 10,
+          }),
+          headers: {
+            'Content-Type': 'application/json',
+            'token': this.token,
+            'tenancyId': this.tenancyId
+          }
+        }).then(res => {
+          return res.json()
+        }).then(result => {
+          let { data, code, msg } = result
+          if (code === 1) {
+            this.doneReplyData = data.records || []
+            this.totalItems = data.total || 0
+          } else if (code === 10001) {
+            this.loginOut()
+          } else {
+            vant.Toast.fail(msg)
+          }
+        })
+      },
+      // 聊天排行榜
+      getChatRank() {
+        this.chatRankData = []
+        fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/chatRank`, {
+          method: 'post',
+          body: JSON.stringify({
+            outletId: this.outletId,
+            departmentIds: this.deptId ? [this.deptId] : [],
+            startTime: this.pageStartTime,
+            endTime: this.pageEndTime,
+          }),
+          headers: {
+            'Content-Type': 'application/json',
+            'token': this.token,
+            'tenancyId': this.tenancyId
+          }
+        }).then(res => {
+          return res.json()
+        }).then(result => {
+          let { data, code, msg } = result
+          if (code === 1) {
+            this.chatRankData = data || []
+          } else if (code === 10001) {
+            this.loginOut()
+          } else {
+            vant.Toast.fail(msg)
+          }
+        })
+      },
+      // 运营任务-总数据
+      getOutletCount() {
+        this.outletCount = []
+        fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/outletCount`, {
+          method: 'post',
+          body: JSON.stringify({
+            outletId: this.outletId,
+            departmentIds: this.deptId ? [this.deptId] : [],
+            startTime: this.pageStartTime,
+            endTime: this.pageEndTime,
+          }),
+          headers: {
+            'Content-Type': 'application/json',
+            'token': this.token,
+            'tenancyId': this.tenancyId
+          }
+        }).then(res => {
+          return res.json()
+        }).then(result => {
+          let { data, code, msg } = result
+          if (code === 1) {
+            this.outletCount = data || []
+          } else if (code === 10001) {
+            this.loginOut()
+          } else {
+            vant.Toast.fail(msg)
+          }
+        })
+      },
+      // 运营任务-任务完成率
+      getTaskCompleteChart() {
+        this.taskCompleteDate = []
+        this.taskCompletePercent = []
+        fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/taskCompletePercent`, {
+          method: 'post',
+          body: JSON.stringify({
+            outletId: this.outletId,
+            departmentIds: this.deptId ? [this.deptId] : [],
+            startTime: this.pageStartTime,
+            endTime: this.pageEndTime,
+          }),
+          headers: {
+            'Content-Type': 'application/json',
+            'token': this.token,
+            'tenancyId': this.tenancyId
+          }
+        }).then(res => {
+          return res.json()
+        }).then(result => {
+          let { data, code, msg } = result
+          if (code === 1) {
+            if (data && data.length) {
+              data.forEach(item => {
+                this.taskCompleteDate.push(item.time)
+                this.taskCompletePercent.push(item.taskCompletePercent)
+              })
+              this.$nextTick(() => {
+                this.taskCompleteChart()
+              })
+            }
+          } else if (code === 10001) {
+            this.loginOut()
+          } else {
+            vant.Toast.fail(msg)
+          }
+        })
+      },
+      taskCompleteChart() {
+        let taskCompleteChart = echarts.getInstanceByDom(document.getElementById('taskCompleteChart'))
+        if (taskCompleteChart == null) {
+          taskCompleteChart = echarts.init(document.getElementById('taskCompleteChart'))
+        }
+        window.addEventListener('resize', function () {
+          taskCompleteChart.resize()
+        })
+        taskCompleteChart.setOption({
+          legend: {
+            show: false,
+          },
+          tooltip: {
+            trigger: 'axis',
+            valueFormatter: function (value) {
+              return value ? value.toFixed(2) + ' %' : ''
+            }
+          },
+          grid: {
+            top: '10%',
+            left: '10%',
+            right: '10%',
+            bottom: '10%'
+          },
+          xAxis: {
+            type: 'category',
+            axisLabel: {
+              show: true,
+              color: "#666666",
+              fontSize: '8',
+            },
+            data: this.taskCompleteDate,
+          },
+          yAxis: [
+            {// 第一种方式
+              type: 'value',
+              min: 0,
+              max: Math.max(...this.taskCompletePercent),
+              splitNumber: 5,
+              interval: Math.max(...this.taskCompletePercent) / 5,
+              position: 'left',
+              axisLabel: {
+                show: true,
+                color: "#222222",
+                fontSize: '8',
+                formatter: function (v) {
+                  return v.toFixed(0) //0表示小数为0位,1表示1位小数,2表示2位小数
+                }
+              },
+              splitLine: { //网格线
+                lineStyle: {
+                  type: 'dashed'//设置网格线类型 dotted:虚线   solid:实线
+                },
+              },
+              axisTick: { show: false },
+            },
+          ],
+          series: [
+            {
+              type: 'line',
+              color: '#1677FF',
+              areaStyle: {
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                  { offset: 0, color: 'rgba(22,119,255,0.43)' },
+                  { offset: 1, color: 'rgba(22,119,255,0)' }
+                ])
+              }, //填充区域样式
+              data: this.taskCompletePercent,
+              symbol: 'none', //去掉折线图中的节点
+              smooth: true, //true 为平滑曲线,false为直线
+            }
+          ],
+        }, true)
+      },
+      // 运营任务 - 互动客户数
+      getOpInteractChart() {
+        this.opInteractDate = []
+        this.opInteractClient = []
+        fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/interact`, {
+          method: 'post',
+          body: JSON.stringify({
+            outletId: this.outletId,
+            departmentIds: this.deptId ? [this.deptId] : [],
+            startTime: this.pageStartTime,
+            endTime: this.pageEndTime,
+          }),
+          headers: {
+            'Content-Type': 'application/json',
+            'token': this.token,
+            'tenancyId': this.tenancyId
+          }
+        }).then(res => {
+          return res.json()
+        }).then(result => {
+          let { data, code, msg } = result
+          if (code === 1) {
+            if (data && data.length) {
+              data.forEach(item => {
+                this.opInteractDate.push(item.time)
+                this.opInteractClient.push(item.interactClient)
+              })
+              this.$nextTick(() => {
+                this.opInteractChart()
+              })
+            }
+          } else if (code === 10001) {
+            this.loginOut()
+          } else {
+            vant.Toast.fail(msg)
+          }
+        })
+      },
+      opInteractChart() {
+        let opInteractChart = echarts.getInstanceByDom(document.getElementById('opInteractChart'))
+        if (opInteractChart == null) {
+          opInteractChart = echarts.init(document.getElementById('opInteractChart'))
+        }
+
+        window.addEventListener('resize', function () {
+          opInteractChart.resize()
+        })
+        opInteractChart.setOption({
+          legend: {
+            show: false,
+          },
+          tooltip: {
+            trigger: 'axis',
+            formatter: function (params) {
+              return params[0].name + '<br>'
+                + '互动客户数: ' + params[0].value
+            }
+          },
+          grid: {
+            top: '10%',
+            left: '10%',
+            right: '10%',
+            bottom: '10%'
+          },
+          xAxis: {
+            type: 'category',
+            axisLabel: {
+              show: true,
+              color: "#666666",
+              fontSize: '8',
+            },
+            data: this.opInteractDate,
+          },
+          yAxis: [
+            {// 第一种方式
+              type: 'value',
+              min: 0,
+              max: Math.max(...this.opInteractClient),
+              splitNumber: 5,
+              interval: Math.max(...this.opInteractClient) / 5,
+              position: 'left',
+              axisLabel: {
+                show: true,
+                color: "#222222",
+                fontSize: '8',
+                formatter: function (v) {
+                  return v.toFixed(0) //0表示小数为0位,1表示1位小数,2表示2位小数
+                }
+              },
+              splitLine: { //网格线
+                lineStyle: {
+                  type: 'dashed'//设置网格线类型 dotted:虚线   solid:实线
+                },
+              },
+              axisTick: { show: false },
+            },
+          ],
+          series: [
+            {
+              type: 'line',
+              color: '#FFA64E',
+              areaStyle: {
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                  { offset: 0, color: 'rgba(255, 166, 78 ,0.43)' },
+                  { offset: 1, color: 'rgba(255, 166, 78 ,0)' }
+                ])
+              }, //填充区域样式
+              data: this.opInteractClient,
+              symbol: 'none', //去掉折线图中的节点
+              smooth: true, //true 为平滑曲线,false为直线
+            }
+          ],
+        }, true)
+      },
+      // 运营任务 - 素材排行榜
+      getContentRank() {
+        this.contentRankData = []
+        fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/contentRank`, {
+          method: 'post',
+          body: JSON.stringify({
+            outletId: this.outletId,
+            departmentIds: this.deptId ? [this.deptId] : [],
+            startTime: this.pageStartTime,
+            endTime: this.pageEndTime,
+          }),
+          headers: {
+            'Content-Type': 'application/json',
+            'token': this.token,
+            'tenancyId': this.tenancyId
+          }
+        }).then(res => {
+          return res.json()
+        }).then(result => {
+          let { data, code, msg } = result
+          if (code === 1) {
+            this.contentRankData = data.reverse() || []
+            this.$nextTick(() => {
+              this.contentRankChart()
+            })
+          } else if (code === 10001) {
+            this.loginOut()
+          } else {
+            vant.Toast.fail(msg)
+          }
+        })
+      },
+      contentRankChart() {
+        let contentRankData = this.contentRankData.sort((a, b) => a.clientNum - b.clientNum)
+        let rankChart = echarts.getInstanceByDom(document.getElementById('contentRank'))
+        if (rankChart == null) {
+          rankChart = echarts.init(document.getElementById('contentRank'))
+        }
+        rankChart.resize({ height: this.contentRankData.length * 50 + 20 })
+        window.addEventListener('resize', function () {
+          rankChart.resize()
+        })
+        rankChart.setOption({
+          tooltip: {
+            trigger: 'item',
+            confine: true,
+            extraCssText: 'max-width:200px; white-space:pre-wrap',
+            formatter: '{b}: {c}'
+          },
+          legend: {
+            left: 'center',
+            icon: 'circle', //小圆点
+            itemWidth: 10,
+            itemHeight: 10,
+            itemGap: 10, //间隔
+            bottom: '10%',
+          },
+          grid: {
+            bottom: "0",
+            top: "0",
+            left: "0",
+            containLabel: true,
+          },
+          xAxis: {
+            type: 'value',
+            axisLabel: {
+              show: true,
+              color: '#666666',
+              fontSize: '8',
+            },
+            splitLine: {
+              show: true,
+              lineStyle: {
+                type: 'dashed' // 设置为虚线
+              }
+            },
+          },
+          yAxis: {
+            type: 'category',
+            axisLabel: {
+              formatter: function (value) {
+                return value.length > 4 ? value.substring(0, 4) + '...' : value
+              },
+              showTooltip: true,
+            },
+            data: this.contentRankData.map(item => {
+              return item.title
+            }) || [],
+          },
+          series: [
+            {
+              type: 'bar',
+              barWidth: 24,
+              barGap: 12,
+              itemStyle: {
+                color: function (p) {
+                  // 亮度随索引递增实现渐变
+                  const lightness = 87 - p.dataIndex * 8;
+                  return `hsl(215, 100%, ${Math.min(100, lightness)}%)`;
+                }
+              },
+              data: this.contentRankData.map(item => {
+                return item.readNum
+              }) || []
+            }
+          ]
+        })
+      },
+      // 打开右上角弹窗
+      handleShowPopup() {
+        this.showPopup = true
+      },
+      // 关闭右上角弹窗
+      handleClosePopup() {
+        this.showPopup = false
+        this.showMer = false
+      },
+      // 切换商户
+      handleSelectMer(item) {
+        localStorage.setItem('tenancyIdValue', item.id)
+        localStorage.setItem('tenancyNameValue', item.name || '')
+        this.tenancyId = item.id
+        this.jxsName = item.name || ''
+        this.showPopup = false
+        this.showMer = false
+        this.getDealerIds()
+      },
+      getDealerIds() {
+        const headers = new Headers()
+        headers.append('token', this.token)
+        headers.append('tenancyId', this.tenancyId)
+        fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/getDealers`, {
+          method: 'GET',
+          headers: headers
+        }).then(res => {
+          return res.json()
+        }).then(result => {
+          let { data, code, msg } = result
+          if (code === 1) {
+            if (data && data.length) {
+              if (data[0].type === 1) {
+                var currentQueryParams = window.location.search
+                window.location.replace('miniJxs.html' + currentQueryParams)
+              } else {
+                this.initialization()
+              }
+            }
+          } else if (code === 10001) {
+            this.loginOut()
+          } else {
+            vant.Toast.fail(msg)
+          }
+        })
+      },
+      // 退出登录
+      handleLoginOut() {
+        localStorage.removeItem('tokenValue')
+        var currentQueryParams = window.location.search
+        window.location.replace('jxsLogin.html' + currentQueryParams)
+      },
+      // token过期,退出登录
+      loginOut() {
+        vant.Toast({
+          message: '登录信息过期,请重新登录',
+        })
+        // this.handleLoginOut()
+      },
+      formatTime(seconds) {
+        // 处理无效输入(空值/非数字)
+        if (seconds == null || seconds === '' || typeof seconds !== 'number') {
+          return '--';
+        }
+        // 确定时间符号和绝对值
+        const isNegative = seconds < 0;
+        const absSeconds = Math.abs(seconds);
+        // 内部格式化函数(处理绝对值)
+        const format = (val, unit) => {
+          const num = Math.round(val);
+          return `${num}${unit}${num > 1 ? '' : ''}`;
+        };
+        // 根据绝对值大小转换单位
+        let formatted;
+        if (absSeconds >= 3600) {
+          formatted = format(absSeconds / 3600, '小时');
+        } else if (absSeconds >= 60) {
+          formatted = format(absSeconds / 60, '分钟');
+        } else {
+          formatted = format(absSeconds, '秒');
+        }
+        // 添加负号(当原始值为负时)
+        return isNegative ? `-${formatted}` : formatted;
+      },
+      formatNumber(num) {
+        const number = Number(num);
+
+        if (isNaN(number) || !isFinite(number)) {
+          return num;
+        }
+
+        // 整数直接返回
+        if (Number.isInteger(number)) {
+          return number.toString();
+        }
+
+        // 非整数处理:先保留两位小数,再移除末尾的零
+        let str = number.toFixed(2);
+        // 正则表达式移除末尾的零(保留有效小数位)
+        return str.replace(/(\.[1-9]?0+)$|(\.[1-9])0+$/g, '$1$2');
+      },
+      // 日期格式处理
+      getDateTime(day) {
+        let today = new Date()
+        let targetday_milliseconds = today.getTime() + 1000 * 60 * 60 * 24 * day
+        today.setTime(targetday_milliseconds)
+        let tYear = today.getFullYear()
+        let tMonth = today.getMonth() + 1
+        let tDate = today.getDate()
+        if (tMonth < 10) {
+          tMonth = '0' + tMonth
+        }
+        if (tDate < 10) {
+          tDate = '0' + tDate
+        }
+        return tYear + '-' + tMonth + '-' + tDate
+      },
+      // 截取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 '--'
+        } else {
+          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)) {
+              format = format.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)))
+            }
+          }
+          return format
+        }
+      },
+    }
+
+  })
+</script>
+
+</html>

+ 446 - 0
lottery/qw/taskDetail.html

@@ -0,0 +1,446 @@
+<!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>
+  <!-- 引入样式文件 -->
+  <link rel="stylesheet"
+    href="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1758012584633/vant.css" />
+  <!-- 必须先引入vue,  后使用vant-ui -->
+  <script
+    src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1742017957144/vue.js"></script>
+  <!-- 引入vant的组件库-->
+  <!-- 引入 Vant 的 JS 文件 -->
+  <script
+    src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1758012748487/vant.min.js"></script>
+
+  <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
+  <script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js"></script>
+  <!-- <script src="js/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: #F7F9FC;
+  }
+
+  .page5 {
+    width: 100vw;
+    box-sizing: border-box;
+    padding: 15px 10px;
+  }
+
+  .task_list {}
+
+  .task_item {
+    width: 100%;
+    background: linear-gradient(180deg, rgba(255, 255, 255, 0.8) 0%, #FFFFFF 100%);
+    border-radius: 15px;
+    border: 1px solid #FFFFFF;
+    box-sizing: border-box;
+    margin-bottom: 15px;
+  }
+
+  .task_item:last-child {
+    margin-bottom: 0;
+  }
+
+  .task_item_title {
+    display: flex;
+    align-items: center;
+    padding: 15px 15px 0;
+  }
+
+  .task_item_title img {
+    width: 53px;
+    height: 53px;
+    border-radius: 10px;
+    margin-right: 10px;
+  }
+
+  .task_item_text {
+    font-weight: 500;
+    font-size: 16px;
+    color: #222222;
+    line-height: 24px;
+    display: flex;
+    flex-direction: column;
+    gap: 8px;
+  }
+  .task_item_time {
+    font-size: 12px;
+    color: #999999;
+    line-height: 17px;
+  }
+  .client_tag {
+    display: flex;
+    align-items: center;
+    flex-wrap: wrap;
+    padding: 0 15px 9px;
+    gap: 8px;
+  }
+  .client_tag_title {
+    font-size: 12px;
+    color: #999999;
+    line-height: 17px;
+    white-space: nowrap;
+    padding-right: 5px;
+  }
+  
+  .client_tag span {
+    height: 21px;
+    font-size: 12px;
+    color: #1677FF;
+    line-height: 17px;
+    border-radius: 5px;
+    padding: 2px 8px;
+    background: rgba(22, 119, 255, 0.1);
+    box-sizing: border-box;
+    white-space: nowrap;
+  }
+
+  .task_item_line {
+    width: 100%;
+    height: 1px;
+    margin: 15px 0 14px;
+    background: linear-gradient(90deg, rgba(217,219,227,0) 0%, #D9DBE3 49%, rgba(217,219,227,0) 100%);
+  }
+
+  .task_item_des {
+    display: flex;
+    align-items: flex-start;
+    padding: 0 15px 10px;
+  }
+
+  .task_des_title {
+    font-size: 14px;
+    color: #222222;
+    line-height: 20px;
+    padding-bottom: 17px;
+  }
+
+  .task_des {
+    font-size: 12px;
+    color: #999999;
+    line-height: 18px;
+    display: -webkit-box;
+    -webkit-line-clamp: 2;
+    -webkit-box-orient: vertical;
+    overflow: hidden;
+    text-overflow: ellipsis;
+  }
+
+  .task_detail {
+    padding: 15px 15px 20px;
+    background: linear-gradient( 180deg, rgba(255,255,255,0.8) 0%, #FFFFFF 100%);
+    border-radius: 15px;
+    border: 1px solid #FFFFFF;
+    margin-bottom: 15px;
+  }
+
+  .task_btn {
+    width: 100%;
+    height: 40px;
+    background: #1677FF;
+    border-radius: 22px;
+    font-weight: bold;
+    font-size: 14px;
+    color: #FFFFFF;
+    line-height: 40px;
+    text-align: center;
+    margin-top: 25px;
+  }
+  .task_detail_con {
+    display: flex;
+    flex-wrap: wrap;
+    justify-content: space-between;
+    gap: 20px;
+  }
+  .task_detail_con_item {
+    display: flex;
+    flex-direction: column;
+    font-size: 12px;
+    color: #666666;
+  }
+  .task_detail_con_data {
+    font-weight: 500;
+    font-size: 14px;
+    color: #136DFB;
+    line-height: 20px;
+    padding-top: 10px;
+  }
+  .inten_title {
+    font-weight: 500;
+    font-size: 14px;
+    color: #222222;
+    line-height: 20px;
+    padding-bottom: 15px;
+    padding-left: 5px;
+    position: relative;
+    display: flex;
+    align-items: center;
+  }
+  .inten_title::after {
+    position: absolute;
+    left: 0;
+    content: '';
+    width: 2px;
+    height: 12px;
+    background: #FF4141;
+    border-radius: 1px;
+  }
+  .ai_title {
+    font-size: 12px;
+    color: #666666;
+    line-height: 17px;
+    padding-bottom: 10px;
+  }
+  .task_ai_des {
+    font-size: 14px;
+    color: #222222;
+    line-height: 23px;
+  }
+  .clue_data {
+    display: flex;
+    justify-content: space-between;
+    margin-bottom: 20px;
+  }
+  .clue_data_item {
+    display: flex;
+    flex-direction: column;
+  }
+  .clue_data_time {
+    font-weight: 500;
+    font-size: 14px;
+    color: #136DFB;
+    line-height: 20px;
+  }
+</style>
+
+<body>
+  <div id="box" class="box">
+    <div class="page5">
+      <!-- 任务详情 -->
+      <div class="task_item">
+        <div class="task_item_title">
+          <img :src="taskData.clientAvatar || '../img/avatar.png'" alt="">
+          <div class="task_item_text">
+            <div>{{taskData.clientName}}</div>
+            <div class="task_item_time">任务时间: {{formatDate(taskData.createdTime)}}</div>
+          </div>
+        </div>
+        <div class="task_item_line"></div>
+        <div class="client_tag">
+          <div class="client_tag_title">客户标签:</div>
+          <span v-for="(item, index) in taskData.clientTags" :key="index">{{item}}</span>
+        </div>
+        <!-- <div class="task_item_des">
+          <div class="task_des_title task_ai">AI分析:</div>
+          <div class="task_des task_ai_des">{{taskData.analysisReason}}</div>
+        </div> -->
+      </div>
+      <div class="task_detail" v-if="type === 'SELL_PROCESS'">
+        <div class="task_des_title">{{taskData.sellProcessName}}</div>
+        <div class="task_detail_con">
+          <div class="task_detail_con_item">
+            <div>进入当前阶段:</div>
+            <div class="task_detail_con_data">{{taskData.sellProcessName}}</div>
+          </div>
+          <div class="task_detail_con_item">
+            <div>停留时间:</div>
+            <div class="task_detail_con_data">{{taskData.lastContactTime}}</div>
+          </div>
+          <div class="task_detail_con_item">
+            <div>上次联系时间:</div>
+            <div class="task_detail_con_data">{{taskData.lastContactTime}}</div>
+          </div>
+          <div class="task_detail_con_item">
+            <div>未联系时间:</div>
+            <div class="task_detail_con_data">{{taskData.lastContactTime}}</div>
+          </div>
+        </div>
+      </div>
+      <div v-if="type === 'INTENTION_SESSION' && taskData.intentionGroupList && taskData.intentionGroupList.length > 0">
+        <div class="task_detail" v-for="(item, index) in taskData.intentionGroupList" :key="index">
+          <div class="inten_title">{{item.nameList[0]}}</div>
+          <div class="ai_title">AI分析:</div>
+          <div class="task_ai_des">{{item.reason}}</div>
+        </div>
+      </div>
+      <div class="task_detail" v-if="type === 'SESSION_CLUE'">
+        <div class="clue_data">
+          <div class="clue_data_item">
+            <div class="ai_title">添加企微时间:</div>
+            <div class="clue_data_time">{{timeFormat(taskData.createdTime)}}</div>
+          </div>
+          <div class="clue_data_item">
+            <div class="ai_title">线索分类:</div>
+            <div class="clue_data_time">
+              <span>{{taskData.category}}</span>
+              <span style="color: #CCCCCC;">—</span>
+              <span style="color: #7D97BF;">{{taskData.subCategory}}</span></div>
+          </div>
+        </div>
+        <div class="ai_title">线索依据:</div>
+        <div class="task_ai_des" style="margin-bottom: 20px;">{{taskData.analysisReason}}</div>
+        <div class="ai_title">AI分析:</div>
+        <div class="task_ai_des">{{taskData.analysisReason}}</div>
+      </div>
+      <div class="task_detail" v-if="type === 'SENTIMENT_SESSION'">
+        <div class="ai_title">AI情绪分析:</div>
+        <div class="task_ai_des">{{taskData.sentimentReason}}</div>
+      </div>
+    </div>
+  </div>
+</body>
+<script>
+  new Vue({
+    el: '#box',
+    data() {
+      return {
+        httpUrl: '',
+        bId: null,
+        env: '',
+        taskId: null,
+        type: null,
+        taskData: {}
+      }
+    },
+    created() {
+      this.bId = this.getQueryParam('bId')
+      this.env = this.getQueryParam('env')
+      this.taskId = this.getQueryParam('taskId')
+      this.type = this.getQueryParam('type')
+      if (!this.env || this.env === 'prod') {
+        this.httpUrl = 'http://test.wefanbot.com:18993'
+      } else {
+        this.httpUrl = 'http://test.wefanbot.com:18993'
+      }
+      this.toRead()
+      this.getDetail()
+    },
+    methods: {
+      toRead() {
+        fetch(this.httpUrl + `/scrm/v1/wxcp-member-todo-task/p/read?taskId=${this.taskId}`)
+          .then(res => {
+            return res.json()
+          }).then(result => {
+            let { data, code, msg } = result
+            if (code === 1) {
+            } else {
+              vant.Toast.fail(msg)
+            }
+          })
+      },
+      getDetail() {
+        let url = ''
+        if (this.type === 'SELL_PROCESS') {
+          // 销售进程
+          url = `/wxcp/sell-process/p/member/todo-task-info?todoTaskId=${this.taskId}`
+        } else if (this.type === 'INTENTION_SESSION') {
+          // 意向客户
+          url = `/scrm/v1/wxc-intention-session/p/member/todo-task-info?todoTaskId=${this.taskId}`
+        } else if (this.type === 'SESSION_CLUE') {
+          // 会话线索
+          url = `/wxcp/sessionClue/p/member/todo-task-info?todoTaskId=${this.taskId}`
+        } else if (this.type === 'SENTIMENT_SESSION') {
+          // 投诉
+          url = `/scrm/v1/wxc-sentiment-session/p/member/todo-task-info?todoTaskId=${this.taskId}`
+        }
+        fetch(this.httpUrl + url)
+          .then(res => {
+            return res.json()
+          }).then(result => {
+            let { data, code, msg } = result
+            if (code === 1) {
+              this.taskData = data
+            } else {
+              vant.Toast.fail(msg)
+            }
+          })
+      },
+      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;
+      },
+      formatDate(input) {
+        // 创建 Date 对象(兼容不同浏览器)
+        const date = new Date(input)
+
+        // 提取年、月、日
+        const year = date.getFullYear()
+        const month = String(date.getMonth() + 1).padStart(2, '0') // 月份从0开始,需要+1
+        const day = String(date.getDate()).padStart(2, '0')
+
+        return `${year}-${month}-${day}`
+      },
+      // 截取url中的数据
+      getQueryParam(paramName) {
+        // 获取当前URL的查询字符串部分  
+        const queryString = window.location.search;
+        // 创建一个URLSearchParams对象  
+        const urlParams = new URLSearchParams(queryString);
+        // 返回指定参数的值,如果不存在则返回null  
+        return urlParams.get(paramName);
+      },
+    }
+  })   
+</script>
+
+</html>

+ 241 - 0
lottery/qw/toDoTask.html

@@ -0,0 +1,241 @@
+<!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>
+  <!-- 引入样式文件 -->
+  <link rel="stylesheet"
+    href="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1758012584633/vant.css" />
+  <!-- 必须先引入vue,  后使用vant-ui -->
+  <script
+    src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1742017957144/vue.js"></script>
+  <!-- 引入vant的组件库-->
+  <!-- 引入 Vant 的 JS 文件 -->
+  <script
+    src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1758012748487/vant.min.js"></script>
+
+  <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
+  <script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js"></script>
+  <!-- <script src="js/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: #F7F9FC;
+  }
+
+  .page5 {
+    width: 100vw;
+    box-sizing: border-box;
+    padding: 15px;
+  }
+  .task_list {
+  }
+  .task_item {
+    width: 100%;
+    background: linear-gradient( 180deg, rgba(255,255,255,0.8) 0%, #FFFFFF 100%);
+    border-radius: 15px ;
+    border: 1px solid #FFFFFF;
+    box-sizing: border-box;
+    margin-bottom: 15px;
+  }
+  .task_item:last-child {
+    margin-bottom: 0;
+  }
+  .task_item_title {
+    display: flex;
+    align-items: center;
+    padding: 15px 15px 0;
+  }
+  .task_item_title img {
+    width: 48px;
+    height: 48px;
+    border-radius: 8px;
+    margin-right: 10px;
+  }
+  .task_item_text {
+    font-weight: 500;
+    font-size: 14px;
+    color: #222222;
+    display: flex;
+    flex-direction: column;
+    gap: 9px;
+  }
+  .client_tag {
+    display: flex;
+    align-items: center;
+    gap: 8px;
+    height: 21px;
+  }
+  .client_tag span {
+    height: 21px;
+    font-size: 12px;
+    color: #FF4141;
+    line-height: 17px;
+    border-radius: 5px;
+    padding: 2px 8px;
+    background: rgba(255, 65, 65, 0.05);
+    box-sizing: border-box;
+  }
+  .task_item_line {
+    width: 100%;
+    height: 1px;
+    margin: 14px 0 10px;
+    background: linear-gradient( 180deg, rgba(217,219,227,0) 0%, #D9DBE3 49%, rgba(217,219,227,0) 100%);
+  }
+  .task_item_des {
+    display: flex;
+    align-items: flex-start;
+    padding: 0 15px 20px;
+  }
+  .task_des_title {
+    font-size: 12px;
+    color: #222222;
+    line-height: 17px;
+    white-space: nowrap;
+  }
+  .task_des {
+    font-size: 12px;
+    color: #999999;
+    line-height: 18px;
+    display: -webkit-box;
+    -webkit-line-clamp: 2;
+    -webkit-box-orient: vertical;
+    overflow: hidden;
+    text-overflow: ellipsis;
+  }
+  .notask {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    padding-top: 198px;
+  }
+  .notask img {
+    width: 102px;
+    height: 90px;
+  }
+  .notask_text {
+    font-size: 14px;
+    color: #CCCCCC;
+    line-height: 20px;
+    padding-top: 20px;
+  }
+  .task_btn_box {
+    padding: 0 20px 15px;
+  }
+  .task_btn {
+    width: 100%;
+    height: 50px;
+    color: #136DFB;
+    border-radius: 20px;
+    font-weight: 500;
+    font-size: 14px;
+    background: rgba(22, 119, 255, 0.1);
+    line-height: 50px;
+    text-align: center;
+  }
+</style>
+<body>
+  <div id="box" class="box">
+    <div class="page5">
+      <div class="task_list" v-if="taskList.length > 0">
+        <div class="task_item" v-for="item in taskList" :key="item.id" @click="handleTaskDetail(item)">
+          <div class="task_item_title">
+            <img :src="item.clientAvatar ? item.clientAvatar : '../img/avatar.png'" alt="">
+            <div class="task_item_text">
+              <div>{{ item.clientName }}</div>
+              <div class="client_tag">
+                <span v-for="(tag, tagIndex) in item.businessTags" :key="tagIndex">{{ tag }}</span>
+              </div>
+            </div>
+          </div>
+          <div class="task_item_line"></div>
+          <div class="task_item_des">
+            <div class="task_des_title">任务描述:</div>
+            <div class="task_des">{{ item.taskDesc }}</div>
+          </div>
+          <div class="task_btn_box">
+            <div class="task_btn">查看详情</div>
+          </div>
+        </div>
+      </div>
+      <div class="notask" v-else>
+        <img src="../img/qw/no_task.png" alt="">
+        <div class="notask_text">暂无待办任务</div>
+      </div>
+    </div>
+  </div>
+</body>
+<script>
+  new Vue({
+    el: '#box',
+    data() {
+      return {
+        httpUrl: '',
+        bId: null,
+        env: '',
+        memberId: null,
+        taskType: null,
+        taskList: [],
+      }
+    },
+    created() {
+      this.bId = this.getQueryParam('bId')
+      this.env = this.getQueryParam('env')
+
+      if (!this.env || this.env === 'prod') {
+        this.httpUrl = 'http://test.wefanbot.com:18993'
+      } else {
+        this.httpUrl = 'http://test.wefanbot.com:18993'
+      }
+      if (this.getQueryParam('memberId')) {
+        this.memberId = this.getQueryParam('memberId')
+        this.taskType = this.getQueryParam('type')
+        this.getTaskList()
+      }
+    },
+    methods: {
+      getTaskList() {
+        fetch(this.httpUrl + `/scrm/v1/wxcp-member-todo-task/p/page?memberId=${this.memberId}&taskType=${this.taskType}&page=1&pageCount=1000`)
+          .then(res => {
+            return res.json()
+          }).then(result => {
+            let { data, code, msg } = result
+            if (code === 1) {
+              this.taskList = data.records || []
+            } else {
+              vant.Toast.fail(msg)
+            }
+          })
+      },
+      handleTaskDetail(item) {
+        window.location.href = `taskDetail.html?taskId=${item.todoTaskId}&type=${item.type}&env=${this.env}`
+      },
+      // 截取url中的数据
+      getQueryParam(paramName) {
+        // 获取当前URL的查询字符串部分  
+        const queryString = window.location.search;
+        // 创建一个URLSearchParams对象  
+        const urlParams = new URLSearchParams(queryString);
+        // 返回指定参数的值,如果不存在则返回null  
+        return urlParams.get(paramName);
+      },
+    }
+  })   
+</script>
+
+</html>

+ 225 - 0
lottery/qw/toDoTaskList.html

@@ -0,0 +1,225 @@
+<!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>
+  <!-- 引入样式文件 -->
+  <link rel="stylesheet"
+    href="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1758012584633/vant.css" />
+  <!-- 必须先引入vue,  后使用vant-ui -->
+  <script
+    src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1742017957144/vue.js"></script>
+  <!-- 引入vant的组件库-->
+  <!-- 引入 Vant 的 JS 文件 -->
+  <script
+    src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1758012748487/vant.min.js"></script>
+
+  <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
+  <script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js"></script>
+  <!-- <script src="js/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: #F7F9FC;
+  }
+
+  .page5 {
+    width: 100vw;
+    box-sizing: border-box;
+    padding: 15px;
+  }
+
+  .task_list {}
+
+  .task_item {
+    width: 100%;
+    background: linear-gradient(180deg, rgba(255, 255, 255, 0.8) 0%, #FFFFFF 100%);
+    border-radius: 15px;
+    border: 1px solid #FFFFFF;
+    box-sizing: border-box;
+    margin-bottom: 15px;
+    padding: 15px 30px 15px 15px ;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    height: 70px;
+  }
+  .task_item_left {
+    display: flex;
+    align-items: center;
+  }
+  .task_item:last-child {
+    margin-bottom: 0;
+  }
+  .task_item_img {
+    width: 40px;
+    height: 40px;
+    margin-right: 15px;
+  }
+
+
+  .task_item_title {
+    display: flex;
+    flex-direction: column;
+  }
+  .task_item_text {
+    font-weight: 500;
+    font-size: 14px;
+    color: #222222;
+    line-height: 20px;
+  }
+  .task_item_num {
+    font-size: 12px;
+    color: #999999;
+    line-height: 17px;
+    padding-top: 6px;
+  }
+  .notask {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    padding-top: 198px;
+  }
+
+  .notask img {
+    width: 102px;
+    height: 90px;
+  }
+
+  .notask_text {
+    font-size: 14px;
+    color: #CCCCCC;
+    line-height: 20px;
+    padding-top: 20px;
+  }
+  .task_show {
+    font-size: 12px;
+    color: #136DFB;
+    line-height: 17px;
+  }
+</style>
+
+<body>
+  <div id="box" class="box">
+    <div class="page5">
+      <div class="task_list" v-if="taskList.length > 0">
+        <div class="task_item" v-for="(item, index) in taskList" :key="index">
+          <div class="task_item_left">
+            <img class="task_item_img" v-if="item.type === 'SELL_PROCESS'" src="../img/qw/xsjc.png" alt="">
+            <img class="task_item_img" v-if="item.type === 'INTENTION_SESSION'" src="../img/qw/yxkh.png" alt="">
+            <img class="task_item_img" v-if="item.type === 'SESSION_CLUE'" src="../img/qw/hhxs.png" alt="">
+            <img class="task_item_img" v-if="item.type === 'MONITORED_MESSAGE'" src="../img/qw/cs.png" alt="">
+            <img class="task_item_img" v-if="item.type === 'SENTIMENT_SESSION'" src="../img/qw/ts.png" alt="">
+            <img class="task_item_img" v-if="item.type === 'CLIENT_LOG'" src="../img/qw/khdt.png" alt="">
+            <div class="task_item_title">
+              <div class="task_item_text">{{taskType.find(t => t.type === item.type)?.name || '未知类型'}}</div>
+              <div class="task_item_num">未处理任务:<span :style="item.unreadCount > 0 ? 'color: #FF4141;' : ''">{{item.unreadCount}}</span></div>
+            </div>
+          </div>
+          <div class="task_show" @click="handleTaskDetail(item)">查看</div>
+        </div>
+      </div>
+      <div class="notask" v-else>
+        <img src="../img/qw/no_task.png" alt="">
+        <div class="notask_text">暂无待办任务</div>
+      </div>
+    </div>
+  </div>
+</body>
+<script>
+  new Vue({
+    el: '#box',
+    data() {
+      return {
+        httpUrl: '',
+        bId: null,
+        env: '',
+        memberId: null,
+        taskList: [],
+        taskType: [
+          {
+            type: 'SELL_PROCESS',
+            name: '销售进程'
+          },
+          {
+            type: 'INTENTION_SESSION',
+            name: '意向客户'
+          },
+          {
+            type: 'SESSION_CLUE',
+            name: '会话线索'
+          },
+          {
+            type: 'MONITORED_MESSAGE',
+            name: '超时'
+          }, {
+            type: 'SENTIMENT_SESSION',
+            name: '投诉'
+          },
+          {
+            type: 'CLIENT_LOG',
+            name: '客户动态'
+          }
+        ]
+      }
+    },
+    created() {
+      this.bId = this.getQueryParam('bId')
+      this.env = this.getQueryParam('env')
+
+      if (!this.env || this.env === 'prod') {
+        this.httpUrl = 'http://test.wefanbot.com:18993'
+      } else {
+        this.httpUrl = 'http://test.wefanbot.com:18993'
+      }
+      if (this.getQueryParam('memberId')) {
+        this.memberId = this.getQueryParam('memberId')
+        this.getTaskList()
+      }
+    },
+    methods: {
+      getTaskList() {
+        fetch(this.httpUrl + `/scrm/v1/wxcp-member-todo-task/p/tag-new-list?memberId=${this.memberId}`)
+          .then(res => {
+            return res.json()
+          }).then(result => {
+            let { data, code, msg } = result
+            if (code === 1) {
+              this.taskList = data || []
+            } else {
+              vant.Toast.fail(msg)
+            }
+          })
+      },
+      handleTaskDetail(item) {
+        window.location.href = `toDoTask.html?memberId=${this.memberId}&type=${item.type}&env=${this.env}`
+      },
+      // 截取url中的数据
+      getQueryParam(paramName) {
+        // 获取当前URL的查询字符串部分  
+        const queryString = window.location.search;
+        // 创建一个URLSearchParams对象  
+        const urlParams = new URLSearchParams(queryString);
+        // 返回指定参数的值,如果不存在则返回null  
+        return urlParams.get(paramName);
+      },
+    }
+  })   
+</script>
+
+</html>