Quellcode durchsuchen

1.修复企微昵称搜索下拉框

jzp vor 2 Tagen
Ursprung
Commit
c59969100d

+ 8 - 1
src/api/company/companyDept.js

@@ -33,6 +33,13 @@ export function treeselect() {
   })
 }
 
+export function myDeptTreeselect() {
+  return request({
+    url: '/company/companyDept/myDeptTreeselect',
+    method: 'get'
+  })
+}
+
 // 根据角色ID查询部门树结构
 export function roleDeptTreeselect(roleId) {
   return request({
@@ -73,4 +80,4 @@ export function allTreeselect() {
     url: '/company/companyDept/allTreeselect',
     method: 'get'
   })
-}
+}

+ 9 - 0
src/api/company/companyUser.js

@@ -216,6 +216,15 @@ export function updateCompanyUserAreaList(data) {
   })
 }
 
+// 根据名称模糊查询用户列表
+export function getCompanyUserListLikeName(params) {
+  return request({
+    url: '/company/user/getCompanyUserListLikeName',
+    method: 'get',
+    params: params
+  })
+}
+
 // 查询企业员工信息列表
 export function listCompanyUser(query) {
   return request({

+ 86 - 0
src/api/qw/QwWorkTaskNew.js

@@ -0,0 +1,86 @@
+import request from '@/utils/request'
+
+// 查询企微任务看板列表
+export function listQwWorkTask(query) {
+  return request({
+    url: '/qw/QwWorkTaskNew/list',
+    method: 'get',
+    params: query
+  })
+}
+export function deptListQwWorkTask(query) {
+  return request({
+    url: '/qw/QwWorkTaskNew/deptList',
+    method: 'get',
+    params: query
+  })
+}
+export function allListQwWorkTask(query) {
+  return request({
+    url: '/qw/QwWorkTaskNew/allList',
+    method: 'get',
+    params: query
+  })
+}
+export function glList(query) {
+  return request({
+    url: '/qw/QwWorkTaskNew/glList',
+    method: 'get',
+    params: query
+  })
+}
+// 查询企微任务看板详细
+export function getQwWorkTask(id) {
+  return request({
+    url: '/qw/QwWorkTaskNew/' + id,
+    method: 'get'
+  })
+}
+
+// 新增企微任务看板
+export function addQwWorkTask(data) {
+  return request({
+    url: '/qw/QwWorkTaskNew',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改企微任务看板
+export function updateQwWorkTask(data) {
+  return request({
+    url: '/qw/QwWorkTaskNew',
+    method: 'put',
+    data: data
+  })
+}
+export function updateQwWorkTask2(data) {
+  return request({
+    url: '/qw/QwWorkTaskNew/edit2',
+    method: 'put',
+    data: data
+  })
+}
+export function updateQwWorkTask3(data) {
+  return request({
+    url: '/qw/QwWorkTaskNew/edit3',
+    method: 'put',
+    data: data
+  })
+}
+// 删除企微任务看板
+export function delQwWorkTask(id) {
+  return request({
+    url: '/qw/QwWorkTaskNew/' + id,
+    method: 'delete'
+  })
+}
+
+// 导出企微任务看板
+export function exportQwWorkTask(query) {
+  return request({
+    url: '/qw/QwWorkTaskNew/export',
+    method: 'get',
+    params: query
+  })
+}

+ 7 - 0
src/api/qw/externalContact.js

@@ -195,6 +195,13 @@ export function exportExternalContact(query) {
     params: query
   })
 }
+export function exportMyExternalContact(query) {
+  return request({
+    url: '/qw/externalContact/myExport',
+    method: 'get',
+    params: query
+  })
+}
 
 /**
 * 获取CRM客户列表

+ 19 - 0
src/api/qw/myVoiceLog.js

@@ -0,0 +1,19 @@
+import request from '@/utils/request'
+
+// 查询我的通话记录列表
+export function listMyVoiceLog(query) {
+  return request({
+    url: '/qw/qwUserVoiceLog/myList',
+    method: 'get',
+    params: query
+  })
+}
+
+// 导出我的用户通话记录
+export function exportMyVoiceLog(query) {
+  return request({
+    url: '/qw/qwUserVoiceLog/myExport',
+    method: 'get',
+    params: query
+  })
+}

+ 53 - 0
src/api/qw/qwUserVoiceLog.js

@@ -0,0 +1,53 @@
+import request from '@/utils/request'
+
+// 查询企微用户通话记录列表
+export function listQwUserVoiceLog(query) {
+  return request({
+    url: '/qw/qwUserVoiceLog/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询企微用户通话记录详细
+export function getQwUserVoiceLog(id) {
+  return request({
+    url: '/qw/qwUserVoiceLog/' + id,
+    method: 'get'
+  })
+}
+
+// 新增企微用户通话记录
+export function addQwUserVoiceLog(data) {
+  return request({
+    url: '/qw/qwUserVoiceLog',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改企微用户通话记录
+export function updateQwUserVoiceLog(data) {
+  return request({
+    url: '/qw/qwUserVoiceLog',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除企微用户通话记录
+export function delQwUserVoiceLog(id) {
+  return request({
+    url: '/qw/qwUserVoiceLog/' + id,
+    method: 'delete'
+  })
+}
+
+// 导出企微用户通话记录
+export function exportQwUserVoiceLog(query) {
+  return request({
+    url: '/qw/qwUserVoiceLog/export',
+    method: 'get',
+    params: query
+  })
+}

+ 34 - 0
src/api/qw/qwUserVoiceLogTotal.js

@@ -0,0 +1,34 @@
+import request from '@/utils/request'
+
+// 查询企微用户通话记录列表
+export function listQwUserVoiceLogTotal(query) {
+  return request({
+    url: '/qw/qwUserVoiceLog/totalList',
+    method: 'get',
+    params: query
+  })
+}
+
+export function listQwUserVoiceLogSellTotal(query) {
+  return request({
+    url: '/qw/qwUserVoiceLog/sellTotalList',
+    method: 'get',
+    params: query
+  })
+}
+export function exportQwUserVoiceLogSellTotal(query) {
+  return request({
+    url: '/qw/qwUserVoiceLog/sellTotalExport',
+    method: 'get',
+    params: query
+  })
+}
+
+// 导出企微用户通话记录
+export function exportQwUserVoiceLogTotal(query) {
+  return request({
+    url: '/qw/qwUserVoiceLog/totalExport',
+    method: 'get',
+    params: query
+  })
+}

+ 2 - 0
src/main.js

@@ -10,6 +10,7 @@ import App from './App'
 import store from './store'
 import router from './router'
 import directive from './directive' //directive
+import elementDirective from './directive/select'
 
 import './assets/icons' // icon
 import './permission' // permission control
@@ -75,6 +76,7 @@ Vue.component('H5Editor', H5Editor)
 
 Vue.use(directive)
 Vue.use(VueMeta)
+Vue.use(elementDirective)
 
 /**
  * If you don't want to use mock-server

+ 322 - 247
src/views/company/statistics/myVoiceLogs.vue

@@ -1,96 +1,134 @@
 <template>
-        <div class="app-container">
-            <div class="app-content">
-                 <div class="title">
-                    我的通话统计
-                </div>
-               <el-form class="search-form" :inline="true" >
-                <el-form-item >
-                  <el-select v-model="value" placeholder="请选择日期">
-                    <el-option
-                      v-for="item in options"
-                      :key="item.value"
-                      :label="item.label"
-                      :value="item.value">
-                    </el-option>
-                  </el-select>
-                </el-form-item>
-                <el-form-item>
-                    <el-button type="cyan" icon="el-icon-search"   @click="getVoiceLogs">搜索</el-button>
-                </el-form-item>
-              </el-form>
-               <div class="data-box">
-                  <div class="echart-box">
-                    <div id="echart-customer"></div>
-                  </div>
-                  <div class="table-box">
-                        <el-button class="export" size="small"  @click="handleExport"   v-hasPermi="['statistics:customer:index']">导出</el-button>
-                        <el-table
-                        :data="list"
-                        border
-                        :summary-method="getSummaries"
-                        show-summary
-                        max-height="500"
-                        style="width: 100%;">
-                        <el-table-column
-                          prop="nickName"
-                          label="员工姓名">
-                        </el-table-column>
-                        <el-table-column
-                          prop="callCount"
-                          label="拨打数">
-                        </el-table-column>
-                        <el-table-column
-                          prop="callSuccessCount"
-                          label="接通数">
-                        </el-table-column>
-                        <el-table-column
-                          prop="callRate"
-                          label="接通率(%)">
-                        </el-table-column>
-                        <el-table-column
-                          prop="times"
-                          label="通话时长(秒)">
-                        </el-table-column>
-                        <el-table-column
-                          prop="billingTime"
-                          label="消耗分钟(分)">
-                        </el-table-column>
-                      </el-table>
-                  </div>
-              </div>
-            </div>
-               
-          </div>
+  <div class="app-container">
+    <div class="app-content">
+      <div class="title">
+        通话统计
+      </div>
+      <el-form class="search-form" :inline="true" >
+        <el-form-item >
+          <el-select style="width: 220px" v-model="value" placeholder="请选择日期">
+            <el-option
+              v-for="item in options"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value">
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="公司名" prop="companyId">
+          <el-select filterable style="width: 220px" v-model="companyId" @change="companyChange" placeholder="请选择公司名" clearable size="small">
+            <el-option
+              v-for="item in companys"
+              :key="item.companyId"
+              :label="item.companyName"
+              :value="item.companyId"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item >
+          <treeselect style="width: 220px" :clearable="false"  v-model="deptId"  :options="deptOptions" :show-count="true" placeholder="请选择归属部门" />
+        </el-form-item>
+        <el-form-item>
+          <el-select style="width: 220px" v-model="userIds" multiple  placeholder="请选择员工">
+            <el-option
+              v-for="item in users"
+              :key="item.userId"
+              :label="item.nickName"
+              :value="item.userId">
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="cyan" icon="el-icon-search"   @click="getVoiceLogs">搜索</el-button>
+        </el-form-item>
+      </el-form>
+      <div class="data-box">
+        <div class="echart-box">
+          <div id="echart-customer"></div>
+        </div>
+        <div class="table-box">
+          <el-button class="export" size="small"  @click="handleExport"   v-hasPermi="['statistics:customer:index']">导出</el-button>
+          <el-table
+            :data="list"
+            border
+            :summary-method="getSummaries"
+            show-summary
+            max-height="500"
+            style="width: 100%;">
+            <el-table-column
+              prop="nickName"
+              label="员工姓名">
+            </el-table-column>
+            <el-table-column
+              prop="callCount"
+              label="拨打数">
+            </el-table-column>
+            <el-table-column
+              prop="callSuccessCount"
+              label="接通数">
+            </el-table-column>
+            <el-table-column
+              prop="callRate"
+              label="接通率(%)">
+            </el-table-column>
+            <el-table-column
+              prop="times"
+              label="通话时长(秒)">
+            </el-table-column>
+            <el-table-column
+              prop="billingTime"
+              label="消耗分钟(分)">
+            </el-table-column>
+          </el-table>
+        </div>
+      </div>
+    </div>
+
+  </div>
 </template>
 
 <script>
-import { myVoiceLogs,exportMyVoiceLogs } from "@/api/company/statistics";
+import { voiceLogs,exportVoiceLogs } from "@/api/company/statistics";
+import { getUserListByDeptId} from "@/api/company/companyUser";
 import echarts from 'echarts'
 import resize from '../../dashboard/mixins/resize'
-
+import { treeselect } from "@/api/company/companyDept";
+import Treeselect from "@riophae/vue-treeselect";
+import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+import { getCompanyList } from "@/api/company/company";
 export default {
   name: 'Index',
   mixins: [resize],
+  components: { Treeselect },
+  watch: {
+    // 监听deptId
+    'deptId': 'currDeptChange'
+  },
   data() {
     return {
-       chart: null,
-       options: [{
-          value: '1',
-          label: '今天'
-        }, {
-          value: '2',
-          label: '昨天'
-        }, {
-          value: '3',
-          label: '本周'
-        }, {
-          value: '4',
-          label: '上周'
-        }, {
-          value: '5',
-          label: '本月'
-        }
+      companys:[],
+      deptOptions:[],
+      companyId:undefined,
+      deptId:undefined,
+      userIds:undefined,
+      users:[],
+      chart: null,
+      options: [{
+        value: '1',
+        label: '今天'
+      }, {
+        value: '2',
+        label: '昨天'
+      }, {
+        value: '3',
+        label: '本周'
+      }, {
+        value: '4',
+        label: '上周'
+      }, {
+        value: '5',
+        label: '本月'
+      }
         , {
           value: '6',
           label: '上月'
@@ -111,198 +149,235 @@ export default {
           value: '10',
           label: '上年'
         }],
-        value: '5',
-        list:[],
-        dates:[],
-        billingTime:[],
-        callCount:[],
-        callSuccessCount:[],
-        times:[]
-       
+      value: '5',
+      list:[],
+      dates:[],
+      billingTime:[],
+      callCount:[],
+      callSuccessCount:[],
+      times:[]
+
     }
   },
-   created() {
-      this.getVoiceLogs();
+  created() {
+    getCompanyList().then(response => {
+      this.companys = response.data;
+      if(this.companys!=null&&this.companys.length>0){
+        this.companyId=this.companys[0].companyId;
+        this.getTreeselect();
+      }
+    });
   },
   methods: {
-    handleExport(){
-        var data;
-        if(this.userIds!=undefined){
-            data={type:this.value,userIds:this.userIds+""}
-        }
-        else{
-            data={type:this.value}
+    companyChange(val){
+      console.log(val);
+      this.companyId=val;
+      this.getTreeselect();
+    },
+    currDeptChange(val){
+      console.log(val)
+      this.deptId=val;
+      this.getUserListByDeptId();
+    },
+    /** 查询部门下拉树结构 */
+    getTreeselect() {
+      var that=this;
+      var param={companyId:this.companyId}
+      treeselect(param).then((response) => {
+        this.deptOptions = response.data;
+        console.log(this.deptOptions)
+        if(response.data!=null&&response.data.length>0){
+          this.deptId=response.data[0].id;
+          that.getVoiceLogs()
         }
-        exportMyVoiceLogs(data).then((response) => {
-            console.log(response)
-           this.download(response.msg);
-        });
+      });
+    },
+    handleExport(){
+      var data;
+      if(this.userIds!=undefined){
+        data={type:this.value,userIds:this.userIds+"",deptId:this.deptId}
+      }
+      else{
+        data={type:this.value,deptId:this.deptId}
+      }
+      exportVoiceLogs(data).then((response) => {
+        console.log(response)
+        this.download(response.msg);
+      });
+
+    },
+    getUserListByDeptId() {
+      this.userIds=undefined;
+      var data={deptId:this.deptId};
+      getUserListByDeptId(data).then(response => {
+        this.users = response.data;
 
+      });
     },
-     getVoiceLogs(){
-          var data;
-          if(this.userIds!=undefined){
-              data={type:this.value,userIds:this.userIds+"",deptId:this.deptId}
+    getVoiceLogs(){
+      var data;
+      if(this.userIds!=undefined){
+        data={type:this.value,userIds:this.userIds+"",deptId:this.deptId}
+      }
+      else{
+        data={type:this.value,deptId:this.deptId}
+      }
+      voiceLogs(data).then((response) => {
+        this.list=response.list;
+        this.dates=response.dates;
+        this.callCount=response.callCount;
+        this.callSuccessCount=response.callSuccessCount;
+        this.billingTime=response.billingTime;
+        this.times=response.times;
+        setTimeout(() => {
+          this.initEchart();
+        }, 500);
+      });
+    },
+    initEchart(){
+      var option = {
+        tooltip: {
+          trigger: 'axis',
+          axisPointer: {            // 坐标轴指示器,坐标轴触发有效
+            type: 'shadow'        // 默认为直线,可选为:'line' | 'shadow'
+          }
+        },
+        legend: {
+          data: ['通话时长', '消耗分钟','拨打数','接通数']
+        },
+        grid: {
+          left: '3%',
+          right: '4%',
+          bottom: '3%',
+          containLabel: true
+        },
+        xAxis: [
+          {
+            type: 'category',
+            data: this.dates
           }
-          else{
-              data={type:this.value,deptId:this.deptId}
+        ],
+        yAxis: [
+          {
+            type: 'value',
+            axisLabel:{
+              formatter:'{value}个'
+            }
           }
-          myVoiceLogs(data).then((response) => {
-           this.list=response.list;
-           this.dates=response.dates;
-           this.callCount=response.callCount;
-           this.callSuccessCount=response.callSuccessCount;
-           this.billingTime=response.billingTime;
-           this.times=response.times;
-            setTimeout(() => {
-              this.initEchart();
-            }, 500);
-        });
-      },
-      initEchart(){
-        var option = {
-          tooltip: {
-              trigger: 'axis',
-              axisPointer: {            // 坐标轴指示器,坐标轴触发有效
-                  type: 'shadow'        // 默认为直线,可选为:'line' | 'shadow'
-              }
+        ],
+        series: [
+          {
+
+            name: '通话时长',
+            type: 'bar',
+            emphasis: {
+              focus: 'series'
+            },
+            data: this.times
           },
-          legend: {
-              data: ['通话时长', '消耗分钟','拨打数','接通数']
+          {
+
+            name: '消耗分钟',
+            type: 'bar',
+            emphasis: {
+              focus: 'series'
+            },
+            data: this.billingTime
           },
-          grid: {
-              left: '3%',
-              right: '4%',
-              bottom: '3%',
-              containLabel: true
+          {
+            name: '拨打数',
+            type: 'bar',
+            emphasis: {
+              focus: 'series'
+            },
+            data: this.callCount
           },
-          xAxis: [
-              {
-                  type: 'category',
-                  data: this.dates
-              }
-          ],
-          yAxis: [
-              {
-                  type: 'value',
-                  axisLabel:{
-                    formatter:'{value}个'
-                  }
-              }
-          ],
-          series: [
-              {
-                  
-                  name: '通话时长',
-                  type: 'line',
-                  emphasis: {
-                      focus: 'series'
-                  },
-                  data: this.times
-              },
-              {
-                 
-                  name: '消耗分钟',
-                  type: 'line',
-                  emphasis: {
-                      focus: 'series'
-                  },
-                  data: this.billingTime
-              },
-               {
-                  name: '拨打数',
-                  type: 'line',
-                  emphasis: {
-                      focus: 'series'
-                  },
-                  data: this.callCount
-              },
-               {
-                  name: '接通数',
-                  type: 'line',
-                  emphasis: {
-                      focus: 'series'
-                  },
-                  data: this.callSuccessCount
-              }
-          ]
-        };
-        this.chart=echarts.init(document.getElementById("echart-customer"));
-        this.chart.setOption(option,true);
-      },
-       getSummaries(param) {
-        const { columns, data } = param;
-        const sums = [];
-        columns.forEach((column, index) => {
-          if (index === 0) {
-            sums[index] = '总计';
-            return;
-          }
-          const values = data.map(item => Number(item[column.property]));
-          if (!values.every(value => isNaN(value))) {
-            sums[index] = values.reduce((prev, curr) => {
-              const value = Number(curr);
-              if (!isNaN(value)) {
-                return prev + curr;
-              } else {
-                return prev;
-              }
-            }, 0);
-            sums[index] += ' ';
-          } else {
-            sums[index] = '';
+          {
+            name: '接通数',
+            type: 'bar',
+            emphasis: {
+              focus: 'series'
+            },
+            data: this.callSuccessCount
           }
-        });
+        ]
+      };
+      this.chart=echarts.init(document.getElementById("echart-customer"));
+      this.chart.setOption(option,true);
+    },
+    getSummaries(param) {
+      const { columns, data } = param;
+      const sums = [];
+      columns.forEach((column, index) => {
+        if (index === 0) {
+          sums[index] = '总计';
+          return;
+        }
+        const values = data.map(item => Number(item[column.property]));
+        if (!values.every(value => isNaN(value))) {
+          sums[index] = values.reduce((prev, curr) => {
+            const value = Number(curr);
+            if (!isNaN(value)) {
+              return prev + curr;
+            } else {
+              return prev;
+            }
+          }, 0);
+          sums[index] += ' ';
+        } else {
+          sums[index] = '';
+        }
+      });
 
-        return sums;
-      }
+      return sums;
+    }
   }
 }
 </script>
 
 <style lang="scss" scoped>
 .app-container{
-    border: 1px solid #e6e6e6;
-    padding: 12px;
-    
-    .app-content{
-      background-color: white;
-      .title{
-        padding: 20px 30px 0px 30px;
-        font-size: 18px;
-        font-weight: bold;
-        color: black;
+  border: 1px solid #e6e6e6;
+  padding: 12px;
 
+  .app-content{
+    background-color: white;
+    .title{
+      padding: 20px 30px 0px 30px;
+      font-size: 18px;
+      font-weight: bold;
+      color: black;
+
+    }
+    .search-form{
+      margin: 20px 30px 0px 30px;
+    }
+    .data-box{
+      padding: 30px;
+      background-color:  rgb(255, 255, 255);
+      height: 100%;
+
+      .echart-box{
+        margin: 0 auto;
+        text-align: center;
       }
-      .search-form{
-        margin: 20px 30px 0px 30px;
+      .el-select{
+        margin: 5px 10px;
       }
-      .data-box{
-        padding: 30px;
-        background-color:  rgb(255, 255, 255);
-        height: 100%;
-    
-        .echart-box{
-          margin: 0 auto;
-          text-align: center;
-        }
-        .el-select{
-          margin: 5px 10px;
-        }
-        .table-box{
-          margin-top: 15px;
-          .export{
-            float: right;
-            margin: 10px 0px;
-          }
+      .table-box{
+        margin-top: 15px;
+        .export{
+          float: right;
+          margin: 10px 0px;
         }
       }
     }
-}
-  #echart-customer{
-    width:100%;
-    height:320px
   }
+}
+#echart-customer{
+  width:100%;
+  height:320px
+}
 .vue-treeselect{
   width: 217px;
   height: 36px;

+ 295 - 0
src/views/qw/QwWorkTaskNew/allTask.vue

@@ -0,0 +1,295 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="企微账号" prop="qwUserName">
+             <el-input
+               v-model="queryParams.qwUserName"
+               placeholder="请输入企微昵称"
+               clearable
+               size="small"
+               @keyup.enter.native="handleQuery"
+             />
+      </el-form-item>
+	 <el-form-item label="时间" prop="createTime">
+	     <el-date-picker v-model="createTime" size="small" style="width: 220px" value-format="yyyy-MM-dd" type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" @change="change"></el-date-picker>
+	 </el-form-item>
+
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+
+    <el-table border v-loading="loading" :data="QwWorkTaskList" @selection-change="handleSelectionChange">
+    <el-table-column type="selection" width="55" align="center" />
+    <el-table-column label="企微账号" align="center" prop="qwUserName" />
+	<el-table-column label="销售昵称" align="center" prop="companyUserName" />
+	<el-table-column label="待处理" align="center" prop="status0" />
+	<el-table-column label="已处理" align="center" prop="status1" />
+	<el-table-column label="待处理完课" align="center" prop="status2" />
+	<el-table-column label="已处理完课" align="center" prop="status3" />
+	<el-table-column label="时间" align="center" prop="createTime" />
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改企微任务看板对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="备注" prop="remark">
+          <el-input  v-model="form.remark" placeholder="请输入备注"  type="textarea" :rows="3"/>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { listQwWorkTask, getQwWorkTask, delQwWorkTask, addQwWorkTask, updateQwWorkTask, exportQwWorkTask,allListQwWorkTask } from "@/api/qw/QwWorkTaskNew";
+import {getMyQwUserList, getMyQwCompanyList, handleInputAuthAppKey, updateUser} from "@/api/qw/user";
+export default {
+  name: "QwWorkTaskNew",
+  data() {
+    return {
+	  actName:"0",
+      // 遮罩层
+      loading: true,
+      // 导出遮罩层
+      exportLoading: false,
+      // 选中数组
+      ids: [],
+	  myQwUserList:[],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+	  sTime:null,
+	  eTime:null,
+	   createTime:null,
+      // 企微任务看板表格数据
+      QwWorkTaskList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 状态 0 待处理 1 已处理 3 过期字典
+      statusOptions: [],
+      // 类别 1先导 2 课程 3 大小转 4 转人工字典
+      typeOptions: [],
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        extId: null,
+        qwUserId: null,
+        status: 0,
+        type: null,
+        title: null,
+        score: null,
+        sopId: null,
+        companyId: null,
+        companyUserId: null,
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+      }
+    };
+  },
+  created() {
+	this.handleGetMyQwUserList();
+    this.getDicts("sys_qw_work_task_status").then(response => {
+      this.statusOptions = response.data;
+    });
+    this.getDicts("sys_qw_work_task_type").then(response => {
+      this.typeOptions = response.data;
+    });
+  },
+  methods: {
+	getScoreStyle(score) {
+	let backgroundColor = '';
+	  if (score >= 15) {
+		backgroundColor = '#ff4d4f';    // 红色
+	  } else if (score >= 9) {
+		backgroundColor = '#ff7d45';    // 橘红
+	  } else if (score >= 4) {
+		backgroundColor = '#ffec3d';    // 黄色
+	  } else {
+		backgroundColor = '#ffffff';    // 白色
+	  }
+	  return {
+		'background-color': backgroundColor,
+		'padding': '5px 10px',
+		'border-radius': '4px'
+	  };
+	},
+	formatTime(timeStr) {
+	      if (!timeStr && timeStr !== 0) return '';
+
+	      // 处理数字和字符串输入
+	      const str = String(timeStr).padStart(4, '0');
+
+	      // 提取有效部分
+	      const hours = str.substring(0, 2);
+	      const minutes = str.substring(2, 4);
+
+	      // 简单验证
+	      if (hours > 23 || minutes > 59) return '无效时间';
+
+	      return `${hours}:${minutes}`;
+	    },
+    /** 查询企微任务看板列表 */
+    getList() {
+      this.loading = true;
+      allListQwWorkTask(this.queryParams).then(response => {
+        this.QwWorkTaskList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+	handleClickX(tab, event) {
+	  this.queryParams.status=tab.name;
+	  this.handleQuery();
+	},
+	change(){
+	      if(this.createTime!=null){
+	        this.queryParams.sTime=this.createTime[0];
+	        this.queryParams.eTime=this.createTime[1];
+	      }else{
+	        this.queryParams.sTime=null;
+	        this.queryParams.eTime=null;
+	      }
+
+	},
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        extId: null,
+        qwUserId: null,
+        status: 0,
+        type: null,
+        title: null,
+        remark: null,
+        score: null,
+        sopId: null,
+        companyId: null,
+        companyUserId: null,
+        updateTime: null,
+        sTime:null,
+        eTime:null,
+        createTime:null
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+	handleGetMyQwUserList(){
+	 this.getList();
+	},
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+	   this.createTime=null;
+	  this.queryParams.sTime=null;
+	  this.queryParams.eTime=null;
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length!==1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加企微任务看板";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id || this.ids
+        this.form = row;
+        this.open = true;
+        this.title = "处理任务";
+
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.id != null) {
+            updateQwWorkTask(this.form).then(response => {
+              this.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addQwWorkTask(this.form).then(response => {
+              this.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$confirm('是否确认删除企微任务看板编号为"' + ids + '"的数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(function() {
+          return delQwWorkTask(ids);
+        }).then(() => {
+          this.getList();
+          this.msgSuccess("删除成功");
+        }).catch(() => {});
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      const queryParams = this.queryParams;
+      this.$confirm('是否确认导出所有企微任务看板数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(() => {
+          this.exportLoading = true;
+          return exportQwWorkTask(queryParams);
+        }).then(response => {
+          this.download(response.msg);
+          this.exportLoading = false;
+        }).catch(() => {});
+    }
+  }
+};
+</script>

+ 695 - 0
src/views/qw/QwWorkTaskNew/deptWorkTask.vue

@@ -0,0 +1,695 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+	 <el-form-item label="部门" prop="type">
+	    <treeselect style="width: 220px" :clearable="false"  v-model="queryParams.deptId"  :options="deptOptions" clearable :show-count="true" placeholder="请选择归属部门"  />
+	 </el-form-item>
+     <el-form-item label="企微账号" prop="qwUserName">
+             <el-input
+               v-model="queryParams.qwUserName"
+               placeholder="请输入企微昵称"
+               clearable
+               size="small"
+               @keyup.enter.native="handleQuery"
+             />
+      </el-form-item>
+	  <el-form-item label="所属销售" prop="companyUserId">
+	    <el-select v-model="queryParams.companyUserId" clearable filterable remote
+	               placeholder="请输入关键词" :remote-method="loadCompanyUserOptions"
+	               v-select-load-more="loadMoreCompanyUserOptions"
+	               :loading="companyUserOptionsLoading">
+	      <el-option
+	        v-for="item in companyUserOptions"
+          :key="item.value"
+          :label="item.label"
+          :value="item.value">
+	      </el-option>
+	    </el-select>
+	  </el-form-item>
+      <el-form-item label="类别" prop="type">
+        <el-select v-model="queryParams.type" placeholder="请选择类别" clearable size="small">
+          <el-option
+            v-for="dict in typeOptions"
+            :key="dict.dictValue"
+            :label="dict.dictLabel"
+            :value="dict.dictValue"
+          />
+        </el-select>
+      </el-form-item>
+
+	  <el-form-item label="处理状态" prop="trackType">
+	    <el-select v-model="queryParams.trackType" placeholder="处理状态" clearable size="small">
+	      <el-option
+	        v-for="dict in trackTypeOptions"
+	        :key="dict.dictValue"
+	        :label="dict.dictLabel"
+	        :value="dict.dictValue"
+	      />
+	    </el-select>
+	  </el-form-item>
+      <el-form-item label="sop编号" prop="sopId">
+        <el-input
+          v-model="queryParams.sopId"
+          placeholder="请输入sopid"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="标题" prop="title">
+        <el-input
+          v-model="queryParams.title"
+          placeholder="请输入标题"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+		<el-button icon="el-icon-refresh" size="mini" @click="sm()">色盲模式</el-button>
+      </el-form-item>
+    </el-form>
+
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+	<el-tabs type="card" v-model="actName" @tab-click="handleClickX">
+	  <el-tab-pane v-for="(item,index) in statusOptions" :label="item.dictLabel" :name="item.dictValue"></el-tab-pane>
+	</el-tabs>
+    <el-table border v-loading="loading" :data="QwWorkTaskList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="客户昵称" align="center" prop="name" />
+      <el-table-column label="企微账号" align="center" prop="qwUserName" />
+	  <el-table-column label="企微昵称" align="center" prop="nickName" />
+      <el-table-column label="状态" align="center" prop="status">
+		 <template slot-scope="scope">
+		   <dict-tag :options="statusOptions" :value="scope.row.status"/>
+		 </template>
+      </el-table-column>
+      <el-table-column label="类别" align="center" prop="type">
+        <template slot-scope="scope">
+          <dict-tag :options="typeOptions" :value="scope.row.type"/>
+        </template>
+      </el-table-column>
+	  <el-table-column label="处理状态" align="center" prop="trackType">
+	    <template slot-scope="scope">
+	      <dict-tag :options="trackTypeOptions" :value="scope.row.trackType"/>
+	    </template>
+	  </el-table-column>
+      <el-table-column label="标题" align="center" prop="title" />
+      <el-table-column label="描述" align="center" prop="description" />
+      <el-table-column label="分值" align="center" prop="score">
+        <template slot-scope="scope">
+          <span :style="getScoreStyle(scope.row.score)">{{ scope.row.score }}</span>
+        </template>
+      </el-table-column>
+	  <el-table-column label="用户过往看课记录" align="center" width="200px">
+	    <template slot-scope="scope">
+	    	<div style="display: flex; gap: 4px; justify-content: center;" v-if="!isSM">
+	    	  <span
+	    		v-for="(log, index) in scope.row.logs"
+	    		:key="index"
+	    		:style="{
+	    		  display: 'inline-block',
+	    		  width: '16px',
+	    		  height: '16px',
+	    		  borderRadius: '2px',
+	    		  backgroundColor:
+	    			log === 2 ? '#67C23A' :
+	    					  log === 3 ? '#f55a4f' :
+	    					  log === 4 ? '#FFD700' :
+	    					  log === 1 ? '#0bc6ff' :
+	    					  '#909399'
+	    		}"
+	    	  ></span>
+	    	</div>
+
+	      <div style="display: flex; gap: 4px; justify-content: center;" v-if="isSM">
+	        <span
+	          v-for="(log, index) in scope.row.logs"
+	          :key="index"
+	          :style="{
+	            display: 'inline-block',
+	            width: '16px',
+	            height: '16px',
+	            borderRadius: log === 2 ? '50%' : log === 4 ? '2px 8px' : '2px',
+	            backgroundColor: log === 3 ? 'transparent' : '#f0f0f0',
+	            border: log === 3 ? '2px solid #666' : '1px solid #ddd',
+	            position: 'relative',
+	            transform: log === 4 ? 'rotate(45deg)' : 'none'
+	          }"
+	        >
+	          <!-- 已完成 - 圆形 + 对勾 -->
+	          <span v-if="log === 2" style="
+	            position: absolute;
+	            top: 45%;
+	            left: 50%;
+	            width: 6px;
+	            height: 3px;
+	            border: solid #333;
+	            border-width: 0 0 2px 2px;
+	            transform: translate(-50%, -50%) rotate(-45deg);
+	          "></span>
+
+	          <!-- 未完成 - 方框 + 叉 -->
+	          <span v-if="log === 3" style="
+	            position: absolute;
+	            top: 50%;
+	            left: 50%;
+	            width: 8px;
+	            height: 2px;
+	            background: #666;
+	            transform: translate(-50%, -50%) rotate(45deg);">
+				</span>
+
+
+	          <span v-if="log === 1" style="
+	            position: absolute;
+	            top: 50%;
+	            left: 50%;
+	            width: 8px;
+	            height: 2px;
+	            background: #666;
+	            transform: translate(-50%, -10%) rotate(-15deg);
+	          "></span>
+
+	          <!-- 部分完成 - 菱形 -->
+	          <span v-if="log === 4" style="
+	            position: absolute;
+	            top: 50%;
+	            left: 50%;
+	            width: 6px;
+	            height: 6px;
+	            border: 2px solid #333;
+	            transform: translate(-50%, -50%) rotate(-45deg);
+	          "></span>
+
+	          <!-- 未开始 - 减号 -->
+	          <span v-if="!log" style="
+	            position: absolute;
+	            top: 50%;
+	            left: 50%;
+	            width: 8px;
+	            height: 2px;
+	            background: #999;
+	            transform: translate(-50%, -50%);
+	          "></span>
+
+	          <!-- 图像 - 使用img标签 -->
+	          <img v-if="log === 5" src="/path/to/your-image.png" alt="Custom icon" style="
+	            position: absolute;
+	            top: 50%;
+	            left: 50%;
+	            width: 12px;
+	            height: 12px;
+	            transform: translate(-50%, -50%);
+	          ">
+	        </span>
+	      </div>
+	    </template>
+	  </el-table-column>
+	    <el-table-column label="最晚看课时间" align="center">
+	        <template slot-scope="scope">
+	          {{ formatTime(scope.row.lastWatchTime) }}
+	        </template>
+	      </el-table-column>
+
+      <el-table-column label="sopId" align="center" prop="sopId" />
+      <el-table-column label="创建时间" align="center" prop="createTime" />
+      <el-table-column label="修改时间" align="center" prop="updateTime" />
+<!--      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button v-if="scope.row.status==0"
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+          >处理</el-button>
+        </template>
+      </el-table-column> -->
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+	<div style="margin-top: 20px; padding: 12px; background: #f8f8f8; border-radius: 4px;" v-if="!isSM">
+	  <div style="display: flex; gap: 20px; flex-wrap: wrap;">
+	    <div style="display: flex; align-items: center; gap: 8px;">
+	      <span style="display: inline-block; width: 16px; height: 16px; border-radius: 2px; background-color: #67C23A;"></span>
+	      <span>完课</span>
+	    </div>
+	    <div style="display: flex; align-items: center; gap: 4px;">
+	      <span style="display: inline-block; width: 16px; height: 16px; border-radius: 2px; background-color: #f55a4f;"></span>
+	      <span>待看课</span>
+	    </div>
+	    <div style="display: flex; align-items: center; gap: 4px;">
+	      <span style="display: inline-block; width: 16px; height: 16px; border-radius: 2px; background-color: #FFD700;"></span>
+	      <span>看课中断</span>
+	    </div>
+	    <div style="display: flex; align-items: center; gap: 4px;">
+	      <span style="display: inline-block; width: 16px; height: 16px; border-radius: 2px; background-color: #909399;"></span>
+	      <span>没发课</span>
+	    </div>
+		<div style="display: flex; align-items: center; gap: 4px;">
+		  <span style="display: inline-block; width: 16px; height: 16px; border-radius: 2px; background-color: #0bc6ff;"></span>
+		  <span>看课中</span>
+		</div>
+	  </div>
+	</div>
+
+	<!-- 新增的解释说明区域 -->
+	<div style="margin-top: 20px; padding: 12px; background: #f8f8f8; border-radius: 4px;" v-if="isSM">
+	    <div style="display: flex; gap: 20px; flex-wrap: wrap;">
+	      <div style="display: flex; align-items: center; gap: 8px;">
+	        <span style="
+	          display: inline-block;
+	          width: 16px;
+	          height: 16px;
+	          border-radius: 50%;
+	          background-color: #f0f0f0;
+	          position: relative;
+	        ">
+	          <span style="
+	            position: absolute;
+	            top: 45%;
+	            left: 50%;
+	            width: 6px;
+	            height: 3px;
+	            border: solid #333;
+	            border-width: 0 0 2px 2px;
+	            transform: translate(-50%, -50%) rotate(-45deg);
+	          "></span>
+	        </span>
+	        <span>完课</span>
+	      </div>
+
+	      <div style="display: flex; align-items: center; gap: 8px;">
+	        <span style="
+	          display: inline-block;
+	          width: 16px;
+	          height: 16px;
+	          border-radius: 2px;
+	          border: 2px solid #666;
+	          background-color: transparent;
+	          position: relative;
+	        ">
+	          <span style="
+	            position: absolute;
+	            top: 50%;
+	            left: 50%;
+	            width: 8px;
+	            height: 2px;
+	            background: #666;
+	            transform: translate(-50%, -50%) rotate(45deg);
+	          "></span>
+	          <span style="
+	            position: absolute;
+	            top: 50%;
+	            left: 50%;
+	            width: 8px;
+	            height: 2px;
+	            background: #666;
+	            transform: translate(-50%, -50%) rotate(-45deg);
+	          "></span>
+	        </span>
+	        <span>待看课</span>
+	      </div>
+
+	      <div style="display: flex; align-items: center; gap: 8px;">
+	        <span style="
+	          display: inline-block;
+	          width: 16px;
+	          height: 16px;
+	          border-radius: 2px 8px;
+	          background-color: #f0f0f0;
+	          border: 1px solid #ddd;
+	          position: relative;
+	          transform: rotate(45deg);
+	        ">
+	          <span style="
+	            position: absolute;
+	            top: 50%;
+	            left: 50%;
+	            width: 6px;
+	            height: 6px;
+	            border: 2px solid #333;
+	            transform: translate(-50%, -50%) rotate(-45deg);
+	          "></span>
+	        </span>
+	        <span>看课中断</span>
+	      </div>
+
+	      <div style="display: flex; align-items: center; gap: 8px;">
+	        <span style="
+	          display: inline-block;
+	          width: 16px;
+	          height: 16px;
+	          border-radius: 2px;
+	          background-color: #f0f0f0;
+	          border: 1px solid #ddd;
+	          position: relative;
+	        ">
+	          <span style="
+	            position: absolute;
+	            top: 50%;
+	            left: 50%;
+	            width: 8px;
+	            height: 2px;
+	            background: #999;
+	            transform: translate(-50%, -50%);
+	          "></span>
+	        </span>
+	        <span>没发课</span>
+	      </div>
+
+		  <div style="display: flex; align-items: center; gap: 8px;">
+		    <span style="
+		      display: inline-block;
+		      width: 16px;
+		      height: 16px;
+		      border-radius: 2px;
+		      background-color: #f0f0f0;
+		      border: 1px solid #ddd;
+		      position: relative;
+		    ">
+		      <span  style="
+		        position: absolute;
+		        top: 50%;
+		        left: 50%;
+		        width: 8px;
+		        height: 2px;
+		        background: #666;
+		        transform: translate(-50%, -10%) rotate(-15deg);
+		      "></span>
+		    </span>
+		    <span>看课中</span>
+		  </div>
+
+
+	    </div>
+	  </div>
+    <!-- 添加或修改企微任务看板对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="备注" prop="remark">
+          <el-input  v-model="form.remark" placeholder="请输入备注"  type="textarea" :rows="3"/>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { deptListQwWorkTask, getQwWorkTask, delQwWorkTask, addQwWorkTask, updateQwWorkTask, exportQwWorkTask,glList} from "@/api/qw/QwWorkTaskNew";
+import {getMyQwUserList, getMyQwCompanyList, handleInputAuthAppKey, updateUser} from "@/api/qw/user";
+import { myDeptTreeselect } from "../../../api/company/companyDept";
+import Treeselect from "@riophae/vue-treeselect";
+import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+import { getCompanyUserListLikeName } from "@/api/company/companyUser";
+export default {
+  name: "deptWorkTask",
+  components: { Treeselect  },
+  data() {
+    return {
+	  actName:"0",
+      // 遮罩层
+      loading: true,
+      // 导出遮罩层
+      exportLoading: false,
+	  companyUserOptionsParams: {
+	    name: undefined,
+	    hasNextPage: false,
+	    pageNum: 1,
+	    pageSize: 10
+	  },
+	  isSM:false,
+
+	  companyUserOptionsLoading: false,
+	  companyUserOptions: [],
+      // 选中数组
+      ids: [],
+	  deptOptions:[],
+	  myQwUserList:[],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 企微任务看板表格数据
+      QwWorkTaskList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 状态 0 待处理 1 已处理 3 过期字典
+      statusOptions: [],
+      // 类别 1先导 2 课程 3 大小转 4 转人工字典
+      typeOptions: [],
+	  trackTypeOptions:[],
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        extId: null,
+        qwUserId: null,
+        status: 0,
+        type: null,
+        title: null,
+        score: null,
+        sopId: null,
+        companyId: null,
+        companyUserId: null,
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+      }
+    };
+  },
+  created() {
+	this.handleGetMyQwUserList();
+    this.getDicts("sys_qw_work_task_status").then(response => {
+      this.statusOptions = response.data;
+    });
+    this.getDicts("sys_qw_work_task_type").then(response => {
+      this.typeOptions = response.data;
+    });
+	this.getDicts("sys_qw_work_task_track_type").then(response => {
+	  this.trackTypeOptions = response.data;
+	});
+	this.getTreeselect();
+  },
+  methods: {
+	getScoreStyle(score) {
+	let backgroundColor = '';
+	  if (score >= 15) {
+		backgroundColor = '#ff4d4f';    // 红色
+	  } else if (score >= 9) {
+		backgroundColor = '#ff7d45';    // 橘红
+	  } else if (score >= 4) {
+		backgroundColor = '#ffec3d';    // 黄色
+	  } else {
+		backgroundColor = '#ffffff';    // 白色
+	  }
+	  return {
+		'background-color': backgroundColor,
+		'padding': '5px 10px',
+		'border-radius': '4px'
+	  };
+	},
+	getTreeselect() {
+	  var that=this;
+	  var param={companyId:this.companyId}
+    myDeptTreeselect(param).then((response) => {
+	    this.deptOptions = response.data;
+	    // if(response.data!=null&&response.data.length>0){
+	    //   //this.queryParams.deptId=response.data[0].id;
+	    // }
+	  });
+	},
+	loadCompanyUserOptions(query) {
+	  this.companyUserOptions = [];
+	  if (query === '') {
+	    return;
+	  }
+
+	  this.companyUserOptionsParams.pageNum = 1
+	  this.companyUserOptionsParams.name = query
+	  this.companyUserOptionsLoading = true;
+	  this.getCompanyUserListLikeName()
+    console.log(this.companyUserOptions);
+
+	},
+	getCompanyUserListLikeName() {
+    getCompanyUserListLikeName(this.companyUserOptionsParams).then(response => {
+      const list = response.data.list.map(item => ({
+        value: item.dictValue,   // 注意这里:dictValue -> value
+        label: item.dictLabel    // dictLabel -> label
+      }));
+      this.companyUserOptions = [...this.companyUserOptions, ...list];
+      this.companyUserOptionsParams.hasNextPage = response.data.hasNextPage;
+      this.companyUserOptionsLoading = false;
+    });
+	},
+	loadMoreCompanyUserOptions() {
+	  if (!this.companyUserOptionsParams.hasNextPage) {
+	    return;
+	  }
+
+	  this.companyUserOptionsParams.pageNum += 1
+	  this.getCompanyUserListLikeName()
+	},
+	formatTime(timeStr) {
+	      if (!timeStr && timeStr !== 0) return '';
+
+	      // 处理数字和字符串输入
+	      const str = String(timeStr).padStart(4, '0');
+
+	      // 提取有效部分
+	      const hours = str.substring(0, 2);
+	      const minutes = str.substring(2, 4);
+
+	      // 简单验证
+	      if (hours > 23 || minutes > 59) return '无效时间';
+
+	      return `${hours}:${minutes}`;
+	    },
+    /** 查询企微任务看板列表 */
+    getList() {
+      this.loading = true;
+      deptListQwWorkTask(this.queryParams).then(response => {
+        this.QwWorkTaskList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+	handleClickX(tab, event) {
+	  this.queryParams.status=tab.name;
+	  this.handleQuery();
+	},
+	sm(){
+		this.isSM = this.isSM ? false : true;
+	},
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        extId: null,
+        qwUserId: null,
+        status: 0,
+        type: null,
+        title: null,
+        remark: null,
+        score: null,
+        sopId: null,
+        companyId: null,
+        companyUserId: null,
+        createTime: null,
+        updateTime: null
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+	handleGetMyQwUserList(){
+
+		this.getList();
+	},
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length!==1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加企微任务看板";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id || this.ids
+        this.form = row;
+        this.open = true;
+        this.title = "处理任务";
+
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.id != null) {
+            updateQwWorkTask(this.form).then(response => {
+              this.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addQwWorkTask(this.form).then(response => {
+              this.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$confirm('是否确认删除企微任务看板编号为"' + ids + '"的数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(function() {
+          return delQwWorkTask(ids);
+        }).then(() => {
+          this.getList();
+          this.msgSuccess("删除成功");
+        }).catch(() => {});
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      const queryParams = this.queryParams;
+      this.$confirm('是否确认导出所有企微任务看板数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(() => {
+          this.exportLoading = true;
+          return exportQwWorkTask(queryParams);
+        }).then(response => {
+          this.download(response.msg);
+          this.exportLoading = false;
+        }).catch(() => {});
+    }
+  }
+};
+</script>

+ 678 - 0
src/views/qw/QwWorkTaskNew/index.vue

@@ -0,0 +1,678 @@
+<template>
+  <div class="app-container">
+    <el-row>
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="企微账号" prop="qwUserId">
+              <el-select v-model="queryParams.qwUserId" placeholder="企微账号"  size="small" @change="updateQwuser()">
+                <el-option
+                  v-for="dict in myQwUserList"
+                  :key="dict.dictValue"
+                  :label="dict.dictLabel+'('+dict.corpName+')'"
+                  :value="dict.dictValue"
+                />
+              </el-select>
+      </el-form-item>
+      <el-form-item label="类别" prop="type">
+        <el-select v-model="queryParams.type" placeholder="请选择类别" clearable size="small">
+          <el-option
+            v-for="dict in typeOptions"
+            :key="dict.dictValue"
+            :label="dict.dictLabel"
+            :value="dict.dictValue"
+          />
+        </el-select>
+      </el-form-item>
+
+	  <el-form-item label="处理状态" prop="trackType">
+	    <el-select v-model="queryParams.trackType" placeholder="处理状态" clearable size="small">
+	      <el-option
+	        v-for="dict in trackTypeOptions"
+	        :key="dict.dictValue"
+	        :label="dict.dictLabel"
+	        :value="dict.dictValue"
+	      />
+	    </el-select>
+	  </el-form-item>
+
+      <el-form-item label="sop编号" prop="sopId">
+        <el-input
+          v-model="queryParams.sopId"
+          placeholder="请输入sopid"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="标题" prop="title">
+        <el-input
+          v-model="queryParams.title"
+          placeholder="请输入标题"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+		<el-button icon="el-icon-refresh" size="mini" @click="sm()">色盲模式</el-button>
+
+      </el-form-item>
+    </el-form>
+
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+	<el-tabs type="card" v-model="actName" @tab-click="handleClickX">
+	  <el-tab-pane v-for="(item,index) in statusOptions" :label="item.dictLabel" :name="item.dictValue"></el-tab-pane>
+	</el-tabs>
+    <el-table border v-loading="loading" :data="QwWorkTaskList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="客户昵称" align="center" prop="name" />
+      <el-table-column label="企微账号" align="center" prop="qwUserName" />
+      <el-table-column label="状态" align="center" prop="status">
+		 <template slot-scope="scope">
+		   <dict-tag :options="statusOptions" :value="scope.row.status"/>
+		 </template>
+      </el-table-column>
+      <el-table-column label="类别" align="center" prop="type">
+        <template slot-scope="scope">
+          <dict-tag :options="typeOptions" :value="scope.row.type"/>
+        </template>
+      </el-table-column>
+	  <el-table-column label="处理状态" align="center" prop="trackType">
+	    <template slot-scope="scope">
+	      <dict-tag :options="trackTypeOptions" :value="scope.row.trackType"/>
+	    </template>
+	  </el-table-column>
+      <el-table-column label="标题" align="center" prop="title" />
+      <el-table-column label="描述" align="center" prop="description" />
+      <el-table-column label="分值" align="center" prop="score">
+        <template slot-scope="scope">
+          <span :style="getScoreStyle(scope.row.score)">{{ scope.row.score }}</span>
+        </template>
+      </el-table-column>
+	  <el-table-column label="用户过往看课记录" align="center" width="200px">
+	    <template slot-scope="scope">
+			<div style="display: flex; gap: 4px; justify-content: center;" v-if="!isSM">
+			  <span
+				v-for="(log, index) in scope.row.logs"
+				:key="index"
+				:style="{
+				  display: 'inline-block',
+				  width: '16px',
+				  height: '16px',
+				  borderRadius: '2px',
+				  backgroundColor:
+					log === 2 ? '#67C23A' :
+							  log === 3 ? '#f55a4f' :
+							  log === 4 ? '#FFD700' :
+							  log === 1 ? '#0bc6ff' :
+							  '#909399'
+				}"
+			  ></span>
+			</div>
+
+	      <div style="display: flex; gap: 4px; justify-content: center;" v-if="isSM">
+	        <span
+	          v-for="(log, index) in scope.row.logs"
+	          :key="index"
+	          :style="{
+	            display: 'inline-block',
+	            width: '16px',
+	            height: '16px',
+	            borderRadius: log === 2 ? '50%' : log === 4 ? '2px 8px' : '2px',
+	            backgroundColor: log === 3 ? 'transparent' : '#f0f0f0',
+	            border: log === 3 ? '2px solid #666' : '1px solid #ddd',
+	            position: 'relative',
+	            transform: log === 4 ? 'rotate(45deg)' : 'none'
+	          }"
+	        >
+	          <!-- 已完成 - 圆形 + 对勾 -->
+	          <span v-if="log === 2" style="
+	            position: absolute;
+	            top: 45%;
+	            left: 50%;
+	            width: 6px;
+	            height: 3px;
+	            border: solid #333;
+	            border-width: 0 0 2px 2px;
+	            transform: translate(-50%, -50%) rotate(-45deg);
+	          "></span>
+
+	          <!-- 未完成 - 方框 + 叉 -->
+	          <span v-if="log === 3" style="
+	            position: absolute;
+	            top: 50%;
+	            left: 50%;
+	            width: 8px;
+	            height: 2px;
+	            background: #666;
+	            transform: translate(-50%, -50%) rotate(45deg);"></span>
+	          <span v-if="log === 1" style="
+	            position: absolute;
+	            top: 50%;
+	            left: 50%;
+	            width: 8px;
+	            height: 2px;
+	            background: #666;
+	            transform: translate(-50%, -10%) rotate(-15deg);
+	          "></span>
+
+	          <!-- 部分完成 - 菱形 -->
+	          <span v-if="log === 4" style="
+	            position: absolute;
+	            top: 50%;
+	            left: 50%;
+	            width: 6px;
+	            height: 6px;
+	            border: 2px solid #333;
+	            transform: translate(-50%, -50%) rotate(-45deg);
+	          "></span>
+
+	          <!-- 未开始 - 减号 -->
+	          <span v-if="!log" style="
+	            position: absolute;
+	            top: 50%;
+	            left: 50%;
+	            width: 8px;
+	            height: 2px;
+	            background: #999;
+	            transform: translate(-50%, -50%);
+	          "></span>
+
+	          <!-- 图像 - 使用img标签 -->
+	          <img v-if="log === 5" src="/path/to/your-image.png" alt="Custom icon" style="
+	            position: absolute;
+	            top: 50%;
+	            left: 50%;
+	            width: 12px;
+	            height: 12px;
+	            transform: translate(-50%, -50%);
+	          ">
+	        </span>
+	      </div>
+	    </template>
+	  </el-table-column>
+	    <el-table-column label="最晚看课时间" align="center">
+	        <template slot-scope="scope">
+	          {{ formatTime(scope.row.lastWatchTime) }}
+	        </template>
+	      </el-table-column>
+
+      <el-table-column label="sopId" align="center" prop="sopId" />
+      <el-table-column label="通话时长" align="center" prop="duration" />
+      <el-table-column label="创建时间" align="center" prop="createTime" />
+      <el-table-column label="修改时间" align="center" prop="updateTime" />
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button v-if="scope.row.status==0"
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+          >处理</el-button>
+		  <el-button v-if="scope.row.status==0"
+		    size="mini"
+		    type="text"
+		    @click="handleUpdate2(scope.row)"
+		  >未接通</el-button>
+		  <el-button v-if="scope.row.status==0"
+		    size="mini"
+		    type="text"
+		    @click="handleUpdate3(scope.row)"
+		  >接通</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+		<div style="margin-top: 20px; padding: 12px; background: #f8f8f8; border-radius: 4px;" v-if="!isSM">
+		  <div style="display: flex; gap: 20px; flex-wrap: wrap;">
+		    <div style="display: flex; align-items: center; gap: 8px;">
+		      <span style="display: inline-block; width: 16px; height: 16px; border-radius: 2px; background-color: #67C23A;"></span>
+		      <span>完课</span>
+		    </div>
+		    <div style="display: flex; align-items: center; gap: 4px;">
+		      <span style="display: inline-block; width: 16px; height: 16px; border-radius: 2px; background-color: #f55a4f;"></span>
+		      <span>待看课</span>
+		    </div>
+		    <div style="display: flex; align-items: center; gap: 4px;">
+		      <span style="display: inline-block; width: 16px; height: 16px; border-radius: 2px; background-color: #FFD700;"></span>
+		      <span>看课中断</span>
+		    </div>
+		    <div style="display: flex; align-items: center; gap: 4px;">
+		      <span style="display: inline-block; width: 16px; height: 16px; border-radius: 2px; background-color: #909399;"></span>
+		      <span>没发课</span>
+		    </div>
+			<div style="display: flex; align-items: center; gap: 4px;">
+			  <span style="display: inline-block; width: 16px; height: 16px; border-radius: 2px; background-color: #0bc6ff;"></span>
+			  <span>看课中</span>
+			</div>
+		  </div>
+		</div>
+
+	    <!-- 新增的解释说明区域 -->
+	    <div style="margin-top: 20px; padding: 12px; background: #f8f8f8; border-radius: 4px;" v-if="isSM">
+	        <div style="display: flex; gap: 20px; flex-wrap: wrap;">
+	          <div style="display: flex; align-items: center; gap: 8px;">
+	            <span style="
+	              display: inline-block;
+	              width: 16px;
+	              height: 16px;
+	              border-radius: 50%;
+	              background-color: #f0f0f0;
+	              position: relative;
+	            ">
+	              <span style="
+	                position: absolute;
+	                top: 45%;
+	                left: 50%;
+	                width: 6px;
+	                height: 3px;
+	                border: solid #333;
+	                border-width: 0 0 2px 2px;
+	                transform: translate(-50%, -50%) rotate(-45deg);
+	              "></span>
+	            </span>
+	            <span>完课</span>
+	          </div>
+
+	          <div style="display: flex; align-items: center; gap: 8px;">
+	            <span style="
+	              display: inline-block;
+	              width: 16px;
+	              height: 16px;
+	              border-radius: 2px;
+	              border: 2px solid #666;
+	              background-color: transparent;
+	              position: relative;
+	            ">
+	              <span style="
+	                position: absolute;
+	                top: 50%;
+	                left: 50%;
+	                width: 8px;
+	                height: 2px;
+	                background: #666;
+	                transform: translate(-50%, -50%) rotate(45deg);
+	              "></span>
+	              <span style="
+	                position: absolute;
+	                top: 50%;
+	                left: 50%;
+	                width: 8px;
+	                height: 2px;
+	                background: #666;
+	                transform: translate(-50%, -50%) rotate(-45deg);
+	              "></span>
+	            </span>
+	            <span>待看课</span>
+	          </div>
+
+	          <div style="display: flex; align-items: center; gap: 8px;">
+	            <span style="
+	              display: inline-block;
+	              width: 16px;
+	              height: 16px;
+	              border-radius: 2px 8px;
+	              background-color: #f0f0f0;
+	              border: 1px solid #ddd;
+	              position: relative;
+	              transform: rotate(45deg);
+	            ">
+	              <span style="
+	                position: absolute;
+	                top: 50%;
+	                left: 50%;
+	                width: 6px;
+	                height: 6px;
+	                border: 2px solid #333;
+	                transform: translate(-50%, -50%) rotate(-45deg);
+	              "></span>
+	            </span>
+	            <span>看课中断</span>
+	          </div>
+
+	          <div style="display: flex; align-items: center; gap: 8px;">
+	            <span style="
+	              display: inline-block;
+	              width: 16px;
+	              height: 16px;
+	              border-radius: 2px;
+	              background-color: #f0f0f0;
+	              border: 1px solid #ddd;
+	              position: relative;
+	            ">
+	              <span style="
+	                position: absolute;
+	                top: 50%;
+	                left: 50%;
+	                width: 8px;
+	                height: 2px;
+	                background: #999;
+	                transform: translate(-50%, -50%);
+	              "></span>
+	            </span>
+	            <span>没发课</span>
+	          </div>
+
+			  <div style="display: flex; align-items: center; gap: 8px;">
+			    <span style="
+			      display: inline-block;
+			      width: 16px;
+			      height: 16px;
+			      border-radius: 2px;
+			      background-color: #f0f0f0;
+			      border: 1px solid #ddd;
+			      position: relative;
+			    ">
+			      <span  style="
+			        position: absolute;
+			        top: 50%;
+			        left: 50%;
+			        width: 8px;
+			        height: 2px;
+			        background: #666;
+			        transform: translate(-50%, -10%) rotate(-15deg);
+			      "></span>
+			    </span>
+			    <span>看课中</span>
+			  </div>
+
+
+	        </div>
+	      </div>
+
+
+    <!-- 添加或修改企微任务看板对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+		<el-form-item label="处理类型" prop="trackType">
+		  <el-select v-model="form.trackType" placeholder="状态" clearable size="small">
+			  <el-option
+				v-for="dict in trackTypeOptions"
+				:key="dict.dictValue"
+				:label="dict.dictLabel"
+				:value="dict.dictValue"
+			  />
+		  </el-select>
+		</el-form-item>
+        <el-form-item label="描述" prop="description">
+          <el-input  v-model="form.description" placeholder="请输入描述"  type="textarea" :rows="3"/>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { listQwWorkTask, getQwWorkTask, delQwWorkTask, addQwWorkTask, updateQwWorkTask, exportQwWorkTask,updateQwWorkTask2,updateQwWorkTask3 } from "@/api/qw/QwWorkTaskNew";
+import {getMyQwUserList, getMyQwCompanyList, handleInputAuthAppKey, updateUser} from "@/api/qw/user";
+export default {
+  name: "QwWorkTaskNew",
+  data() {
+    return {
+	  actName:"0",
+      // 遮罩层
+      loading: true,
+      // 导出遮罩层
+      exportLoading: false,
+      // 选中数组
+      ids: [],
+	  isSM:false,
+	  myQwUserList:[],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 企微任务看板表格数据
+      QwWorkTaskList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 状态 0 待处理 1 已处理 3 过期字典
+      statusOptions: [],
+	  trackTypeOptions:[],
+      // 类别 1先导 2 课程 3 大小转 4 转人工字典
+      typeOptions: [],
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        extId: null,
+        qwUserId: null,
+        status: 0,
+        type: null,
+        title: null,
+        score: null,
+        sopId: null,
+        companyId: null,
+        companyUserId: null,
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+		   trackType: [
+		      { required: true, message: '请选择处理类型', trigger: 'change' }
+		    ]
+      }
+    };
+  },
+  created() {
+	this.handleGetMyQwUserList();
+    this.getDicts("sys_qw_work_task_status").then(response => {
+      this.statusOptions = response.data;
+    });
+    this.getDicts("sys_qw_work_task_type").then(response => {
+      this.typeOptions = response.data;
+    });
+	this.getDicts("sys_qw_work_task_track_type").then(response => {
+	  this.trackTypeOptions = response.data;
+	});
+
+
+  },
+  methods: {
+	getScoreStyle(score) {
+	let backgroundColor = '';
+	  if (score >= 15) {
+		backgroundColor = '#ff4d4f';    // 红色
+	  } else if (score >= 9) {
+		backgroundColor = '#ff7d45';    // 橘红
+	  } else if (score >= 4) {
+		backgroundColor = '#ffec3d';    // 黄色
+	  } else {
+		backgroundColor = '#ffffff';    // 白色
+	  }
+	  return {
+		'background-color': backgroundColor,
+		'padding': '5px 10px',
+		'border-radius': '4px'
+	  };
+	},
+	formatTime(timeStr) {
+	      if (!timeStr && timeStr !== 0) return '';
+
+	      // 处理数字和字符串输入
+	      const str = String(timeStr).padStart(4, '0');
+
+	      // 提取有效部分
+	      const hours = str.substring(0, 2);
+	      const minutes = str.substring(2, 4);
+
+	      // 简单验证
+	      if (hours > 23 || minutes > 59) return '无效时间';
+
+	      return `${hours}:${minutes}`;
+	    },
+    /** 查询企微任务看板列表 */
+    getList() {
+      this.loading = true;
+      listQwWorkTask(this.queryParams).then(response => {
+        this.QwWorkTaskList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+	sm(){
+		this.isSM = this.isSM ? false : true;
+	},
+	handleClickX(tab, event) {
+	  this.queryParams.status=tab.name;
+	  this.handleQuery();
+	},
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        extId: null,
+        qwUserId: null,
+        status: 0,
+        type: null,
+        title: null,
+        remark: null,
+        score: null,
+        sopId: null,
+        companyId: null,
+        companyUserId: null,
+        createTime: null,
+        updateTime: null
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+	handleGetMyQwUserList(){
+
+	  getMyQwUserList().then(response => {
+	    this.myQwUserList = response.data;
+	    if(this.myQwUserList!=null && this.myQwUserList.length>0){
+	      this.queryParams.qwUserId=this.myQwUserList[0].dictValue
+	      this.queryParams.corpId=this.myQwUserList[0].corpId
+	    }
+      this.getList();
+
+	  });
+
+	},
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length!==1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加企微任务看板";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id || this.ids
+        this.form = row;
+        this.open = true;
+        this.title = "处理任务";
+
+    },
+
+	handleUpdate2(row) {
+	  var from={id:row.id }
+	  	updateQwWorkTask2(from).then(response => {
+	    this.msgSuccess("修改成功");
+
+	    this.getList();
+	  });
+
+	},
+	handleUpdate3(row) {
+	  var from={id:row.id }
+		updateQwWorkTask3(from).then(response => {
+	  this.msgSuccess("修改成功");
+
+	  this.getList();
+	});
+	},
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.id != null) {
+            updateQwWorkTask(this.form).then(response => {
+              this.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addQwWorkTask(this.form).then(response => {
+              this.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$confirm('是否确认删除企微任务看板编号为"' + ids + '"的数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(function() {
+          return delQwWorkTask(ids);
+        }).then(() => {
+          this.getList();
+          this.msgSuccess("删除成功");
+        }).catch(() => {});
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      const queryParams = this.queryParams;
+      this.$confirm('是否确认导出所有企微任务看板数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(() => {
+          this.exportLoading = true;
+          return exportQwWorkTask(queryParams);
+        }).then(response => {
+          this.download(response.msg);
+          this.exportLoading = false;
+        }).catch(() => {});
+    }
+  }
+};
+</script>

+ 690 - 0
src/views/qw/QwWorkTaskNew/qwWorkTask.vue

@@ -0,0 +1,690 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+	 <el-form-item label="部门" prop="type">
+	    <treeselect style="width: 220px" :clearable="false"  v-model="queryParams.deptId"  :options="deptOptions" clearable :show-count="true" placeholder="请选择归属部门"  />
+	 </el-form-item>
+     <el-form-item label="企微账号" prop="qwUserName">
+             <el-input
+               v-model="queryParams.qwUserName"
+               placeholder="请输入企微昵称"
+               clearable
+               size="small"
+               @keyup.enter.native="handleQuery"
+             />
+      </el-form-item>
+	  <el-form-item label="所属销售" prop="companyUserId">
+	    <el-select v-model="queryParams.companyUserId" clearable filterable remote
+	               placeholder="请输入关键词" :remote-method="loadCompanyUserOptions"
+	               v-select-load-more="loadMoreCompanyUserOptions"
+	               :loading="companyUserOptionsLoading">
+	      <el-option
+	        v-for="item in companyUserOptions"
+	        :key="item.value"
+	        :label="item.label"
+	        :value="item.value">
+	      </el-option>
+	    </el-select>
+	  </el-form-item>
+      <el-form-item label="类别" prop="type">
+        <el-select v-model="queryParams.type" placeholder="请选择类别" clearable size="small">
+          <el-option
+            v-for="dict in typeOptions"
+            :key="dict.dictValue"
+            :label="dict.dictLabel"
+            :value="dict.dictValue"
+          />
+        </el-select>
+      </el-form-item>
+
+	  <el-form-item label="处理状态" prop="trackType">
+	    <el-select v-model="queryParams.trackType" placeholder="处理状态" clearable size="small">
+	      <el-option
+	        v-for="dict in trackTypeOptions"
+	        :key="dict.dictValue"
+	        :label="dict.dictLabel"
+	        :value="dict.dictValue"
+	      />
+	    </el-select>
+	  </el-form-item>
+      <el-form-item label="sop编号" prop="sopId">
+        <el-input
+          v-model="queryParams.sopId"
+          placeholder="请输入sopid"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="标题" prop="title">
+        <el-input
+          v-model="queryParams.title"
+          placeholder="请输入标题"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+		<el-button icon="el-icon-refresh" size="mini" @click="sm()">色盲模式</el-button>
+      </el-form-item>
+    </el-form>
+
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+	<el-tabs type="card" v-model="actName" @tab-click="handleClickX">
+	  <el-tab-pane v-for="(item,index) in statusOptions" :label="item.dictLabel" :name="item.dictValue"></el-tab-pane>
+	</el-tabs>
+    <el-table border v-loading="loading" :data="QwWorkTaskList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="客户昵称" align="center" prop="name" />
+      <el-table-column label="企微账号" align="center" prop="qwUserName" />
+	  <el-table-column label="企微昵称" align="center" prop="nickName" />
+      <el-table-column label="状态" align="center" prop="status">
+		 <template slot-scope="scope">
+		   <dict-tag :options="statusOptions" :value="scope.row.status"/>
+		 </template>
+      </el-table-column>
+      <el-table-column label="类别" align="center" prop="type">
+        <template slot-scope="scope">
+          <dict-tag :options="typeOptions" :value="scope.row.type"/>
+        </template>
+      </el-table-column>
+	  <el-table-column label="处理状态" align="center" prop="trackType">
+	    <template slot-scope="scope">
+	      <dict-tag :options="trackTypeOptions" :value="scope.row.trackType"/>
+	    </template>
+	  </el-table-column>
+      <el-table-column label="标题" align="center" prop="title" />
+      <el-table-column label="描述" align="center" prop="description" />
+      <el-table-column label="分值" align="center" prop="score">
+        <template slot-scope="scope">
+          <span :style="getScoreStyle(scope.row.score)">{{ scope.row.score }}</span>
+        </template>
+      </el-table-column>
+	  <el-table-column label="用户过往看课记录" align="center" width="200px">
+	    <template slot-scope="scope">
+	    	<div style="display: flex; gap: 4px; justify-content: center;" v-if="!isSM">
+	    	  <span
+	    		v-for="(log, index) in scope.row.logs"
+	    		:key="index"
+	    		:style="{
+	    		  display: 'inline-block',
+	    		  width: '16px',
+	    		  height: '16px',
+	    		  borderRadius: '2px',
+	    		  backgroundColor:
+	    			log === 2 ? '#67C23A' :
+	    					  log === 3 ? '#f55a4f' :
+	    					  log === 4 ? '#FFD700' :
+	    					  log === 1 ? '#0bc6ff' :
+	    					  '#909399'
+	    		}"
+	    	  ></span>
+	    	</div>
+
+	      <div style="display: flex; gap: 4px; justify-content: center;" v-if="isSM">
+	        <span
+	          v-for="(log, index) in scope.row.logs"
+	          :key="index"
+	          :style="{
+	            display: 'inline-block',
+	            width: '16px',
+	            height: '16px',
+	            borderRadius: log === 2 ? '50%' : log === 4 ? '2px 8px' : '2px',
+	            backgroundColor: log === 3 ? 'transparent' : '#f0f0f0',
+	            border: log === 3 ? '2px solid #666' : '1px solid #ddd',
+	            position: 'relative',
+	            transform: log === 4 ? 'rotate(45deg)' : 'none'
+	          }"
+	        >
+	          <!-- 已完成 - 圆形 + 对勾 -->
+	          <span v-if="log === 2" style="
+	            position: absolute;
+	            top: 45%;
+	            left: 50%;
+	            width: 6px;
+	            height: 3px;
+	            border: solid #333;
+	            border-width: 0 0 2px 2px;
+	            transform: translate(-50%, -50%) rotate(-45deg);
+	          "></span>
+
+	          <!-- 未完成 - 方框 + 叉 -->
+	          <span v-if="log === 3" style="
+	            position: absolute;
+	            top: 50%;
+	            left: 50%;
+	            width: 8px;
+	            height: 2px;
+	            background: #666;
+	            transform: translate(-50%, -50%) rotate(45deg);">
+				</span>
+
+
+	          <span v-if="log === 1" style="
+	            position: absolute;
+	            top: 50%;
+	            left: 50%;
+	            width: 8px;
+	            height: 2px;
+	            background: #666;
+	            transform: translate(-50%, -10%) rotate(-15deg);
+	          "></span>
+
+	          <!-- 部分完成 - 菱形 -->
+	          <span v-if="log === 4" style="
+	            position: absolute;
+	            top: 50%;
+	            left: 50%;
+	            width: 6px;
+	            height: 6px;
+	            border: 2px solid #333;
+	            transform: translate(-50%, -50%) rotate(-45deg);
+	          "></span>
+
+	          <!-- 未开始 - 减号 -->
+	          <span v-if="!log" style="
+	            position: absolute;
+	            top: 50%;
+	            left: 50%;
+	            width: 8px;
+	            height: 2px;
+	            background: #999;
+	            transform: translate(-50%, -50%);
+	          "></span>
+
+	          <!-- 图像 - 使用img标签 -->
+	          <img v-if="log === 5" src="/path/to/your-image.png" alt="Custom icon" style="
+	            position: absolute;
+	            top: 50%;
+	            left: 50%;
+	            width: 12px;
+	            height: 12px;
+	            transform: translate(-50%, -50%);
+	          ">
+	        </span>
+	      </div>
+	    </template>
+	  </el-table-column>
+	    <el-table-column label="最晚看课时间" align="center">
+	        <template slot-scope="scope">
+	          {{ formatTime(scope.row.lastWatchTime) }}
+	        </template>
+	      </el-table-column>
+
+      <el-table-column label="sopId" align="center" prop="sopId" />
+      <el-table-column label="创建时间" align="center" prop="createTime" />
+      <el-table-column label="修改时间" align="center" prop="updateTime" />
+<!--      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button v-if="scope.row.status==0"
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+          >处理</el-button>
+        </template>
+      </el-table-column> -->
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+	<div style="margin-top: 20px; padding: 12px; background: #f8f8f8; border-radius: 4px;" v-if="!isSM">
+	  <div style="display: flex; gap: 20px; flex-wrap: wrap;">
+	    <div style="display: flex; align-items: center; gap: 8px;">
+	      <span style="display: inline-block; width: 16px; height: 16px; border-radius: 2px; background-color: #67C23A;"></span>
+	      <span>完课</span>
+	    </div>
+	    <div style="display: flex; align-items: center; gap: 4px;">
+	      <span style="display: inline-block; width: 16px; height: 16px; border-radius: 2px; background-color: #f55a4f;"></span>
+	      <span>待看课</span>
+	    </div>
+	    <div style="display: flex; align-items: center; gap: 4px;">
+	      <span style="display: inline-block; width: 16px; height: 16px; border-radius: 2px; background-color: #FFD700;"></span>
+	      <span>看课中断</span>
+	    </div>
+	    <div style="display: flex; align-items: center; gap: 4px;">
+	      <span style="display: inline-block; width: 16px; height: 16px; border-radius: 2px; background-color: #909399;"></span>
+	      <span>没发课</span>
+	    </div>
+		<div style="display: flex; align-items: center; gap: 4px;">
+		  <span style="display: inline-block; width: 16px; height: 16px; border-radius: 2px; background-color: #0bc6ff;"></span>
+		  <span>看课中</span>
+		</div>
+	  </div>
+	</div>
+
+	<!-- 新增的解释说明区域 -->
+	<div style="margin-top: 20px; padding: 12px; background: #f8f8f8; border-radius: 4px;" v-if="isSM">
+	    <div style="display: flex; gap: 20px; flex-wrap: wrap;">
+	      <div style="display: flex; align-items: center; gap: 8px;">
+	        <span style="
+	          display: inline-block;
+	          width: 16px;
+	          height: 16px;
+	          border-radius: 50%;
+	          background-color: #f0f0f0;
+	          position: relative;
+	        ">
+	          <span style="
+	            position: absolute;
+	            top: 45%;
+	            left: 50%;
+	            width: 6px;
+	            height: 3px;
+	            border: solid #333;
+	            border-width: 0 0 2px 2px;
+	            transform: translate(-50%, -50%) rotate(-45deg);
+	          "></span>
+	        </span>
+	        <span>完课</span>
+	      </div>
+
+	      <div style="display: flex; align-items: center; gap: 8px;">
+	        <span style="
+	          display: inline-block;
+	          width: 16px;
+	          height: 16px;
+	          border-radius: 2px;
+	          border: 2px solid #666;
+	          background-color: transparent;
+	          position: relative;
+	        ">
+	          <span style="
+	            position: absolute;
+	            top: 50%;
+	            left: 50%;
+	            width: 8px;
+	            height: 2px;
+	            background: #666;
+	            transform: translate(-50%, -50%) rotate(45deg);
+	          "></span>
+	          <span style="
+	            position: absolute;
+	            top: 50%;
+	            left: 50%;
+	            width: 8px;
+	            height: 2px;
+	            background: #666;
+	            transform: translate(-50%, -50%) rotate(-45deg);
+	          "></span>
+	        </span>
+	        <span>待看课</span>
+	      </div>
+
+	      <div style="display: flex; align-items: center; gap: 8px;">
+	        <span style="
+	          display: inline-block;
+	          width: 16px;
+	          height: 16px;
+	          border-radius: 2px 8px;
+	          background-color: #f0f0f0;
+	          border: 1px solid #ddd;
+	          position: relative;
+	          transform: rotate(45deg);
+	        ">
+	          <span style="
+	            position: absolute;
+	            top: 50%;
+	            left: 50%;
+	            width: 6px;
+	            height: 6px;
+	            border: 2px solid #333;
+	            transform: translate(-50%, -50%) rotate(-45deg);
+	          "></span>
+	        </span>
+	        <span>看课中断</span>
+	      </div>
+
+	      <div style="display: flex; align-items: center; gap: 8px;">
+	        <span style="
+	          display: inline-block;
+	          width: 16px;
+	          height: 16px;
+	          border-radius: 2px;
+	          background-color: #f0f0f0;
+	          border: 1px solid #ddd;
+	          position: relative;
+	        ">
+	          <span style="
+	            position: absolute;
+	            top: 50%;
+	            left: 50%;
+	            width: 8px;
+	            height: 2px;
+	            background: #999;
+	            transform: translate(-50%, -50%);
+	          "></span>
+	        </span>
+	        <span>没发课</span>
+	      </div>
+
+		  <div style="display: flex; align-items: center; gap: 8px;">
+		    <span style="
+		      display: inline-block;
+		      width: 16px;
+		      height: 16px;
+		      border-radius: 2px;
+		      background-color: #f0f0f0;
+		      border: 1px solid #ddd;
+		      position: relative;
+		    ">
+		      <span  style="
+		        position: absolute;
+		        top: 50%;
+		        left: 50%;
+		        width: 8px;
+		        height: 2px;
+		        background: #666;
+		        transform: translate(-50%, -10%) rotate(-15deg);
+		      "></span>
+		    </span>
+		    <span>看课中</span>
+		  </div>
+
+
+	    </div>
+	  </div>
+    <!-- 添加或修改企微任务看板对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="备注" prop="remark">
+          <el-input  v-model="form.remark" placeholder="请输入备注"  type="textarea" :rows="3"/>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { listQwWorkTask, getQwWorkTask, delQwWorkTask, addQwWorkTask, updateQwWorkTask, exportQwWorkTask,glList} from "@/api/qw/QwWorkTaskNew";
+import {getMyQwUserList, getMyQwCompanyList, handleInputAuthAppKey, updateUser} from "@/api/qw/user";
+import { treeselect } from "@/api/company/companyDept";
+import Treeselect from "@riophae/vue-treeselect";
+import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+import { getCompanyUserListLikeName } from "@/api/company/companyUser";
+export default {
+  name: "QwWorkTaskNew",
+  components: { Treeselect  },
+  data() {
+    return {
+	  actName:"0",
+      // 遮罩层
+      loading: true,
+      // 导出遮罩层
+      exportLoading: false,
+	  companyUserOptionsParams: {
+	    name: undefined,
+	    hasNextPage: false,
+	    pageNum: 1,
+	    pageSize: 10
+	  },
+	  isSM:false,
+
+	  companyUserOptionsLoading: false,
+	  companyUserOptions: [],
+      // 选中数组
+      ids: [],
+	  deptOptions:[],
+	  myQwUserList:[],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 企微任务看板表格数据
+      QwWorkTaskList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 状态 0 待处理 1 已处理 3 过期字典
+      statusOptions: [],
+      // 类别 1先导 2 课程 3 大小转 4 转人工字典
+      typeOptions: [],
+	  trackTypeOptions:[],
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        extId: null,
+        qwUserId: null,
+        status: 0,
+        type: null,
+        title: null,
+        score: null,
+        sopId: null,
+        companyId: null,
+        companyUserId: null,
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+      }
+    };
+  },
+  created() {
+	this.handleGetMyQwUserList();
+    this.getDicts("sys_qw_work_task_status").then(response => {
+      this.statusOptions = response.data;
+    });
+    this.getDicts("sys_qw_work_task_type").then(response => {
+      this.typeOptions = response.data;
+    });
+	this.getDicts("sys_qw_work_task_track_type").then(response => {
+	  this.trackTypeOptions = response.data;
+	});
+	this.getTreeselect();
+  },
+  methods: {
+	getScoreStyle(score) {
+	let backgroundColor = '';
+	  if (score >= 15) {
+		backgroundColor = '#ff4d4f';    // 红色
+	  } else if (score >= 9) {
+		backgroundColor = '#ff7d45';    // 橘红
+	  } else if (score >= 4) {
+		backgroundColor = '#ffec3d';    // 黄色
+	  } else {
+		backgroundColor = '#ffffff';    // 白色
+	  }
+	  return {
+		'background-color': backgroundColor,
+		'padding': '5px 10px',
+		'border-radius': '4px'
+	  };
+	},
+	getTreeselect() {
+	  var that=this;
+	  var param={companyId:this.companyId}
+	  treeselect(param).then((response) => {
+	    this.deptOptions = response.data;
+	    console.log(this.deptOptions)
+	    if(response.data!=null&&response.data.length>0){
+	      //this.queryParams.deptId=response.data[0].id;
+	    }
+	  });
+	},
+	loadCompanyUserOptions(query) {
+	  this.companyUserOptions = [];
+	  if (query === '') {
+	    return;
+	  }
+
+	  this.companyUserOptionsParams.pageNum = 1
+	  this.companyUserOptionsParams.name = query
+	  this.companyUserOptionsLoading = true;
+	  this.getCompanyUserListLikeName()
+	},
+	getCompanyUserListLikeName() {
+	  getCompanyUserListLikeName(this.companyUserOptionsParams).then(response => {
+	    this.companyUserOptions = [...this.companyUserOptions, ...response.data.list]
+	    this.companyUserOptionsParams.hasNextPage = response.data.hasNextPage
+	    this.companyUserOptionsLoading = false;
+	  });
+	},
+	loadMoreCompanyUserOptions() {
+	  if (!this.companyUserOptionsParams.hasNextPage) {
+	    return;
+	  }
+
+	  this.companyUserOptionsParams.pageNum += 1
+	  this.getCompanyUserListLikeName()
+	},
+	formatTime(timeStr) {
+	      if (!timeStr && timeStr !== 0) return '';
+
+	      // 处理数字和字符串输入
+	      const str = String(timeStr).padStart(4, '0');
+
+	      // 提取有效部分
+	      const hours = str.substring(0, 2);
+	      const minutes = str.substring(2, 4);
+
+	      // 简单验证
+	      if (hours > 23 || minutes > 59) return '无效时间';
+
+	      return `${hours}:${minutes}`;
+	    },
+    /** 查询企微任务看板列表 */
+    getList() {
+      this.loading = true;
+      glList(this.queryParams).then(response => {
+        this.QwWorkTaskList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+	handleClickX(tab, event) {
+	  this.queryParams.status=tab.name;
+	  this.handleQuery();
+	},
+	sm(){
+		this.isSM = this.isSM ? false : true;
+	},
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        extId: null,
+        qwUserId: null,
+        status: 0,
+        type: null,
+        title: null,
+        remark: null,
+        score: null,
+        sopId: null,
+        companyId: null,
+        companyUserId: null,
+        createTime: null,
+        updateTime: null
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+	handleGetMyQwUserList(){
+
+		this.getList();
+	},
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length!==1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加企微任务看板";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id || this.ids
+        this.form = row;
+        this.open = true;
+        this.title = "处理任务";
+
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.id != null) {
+            updateQwWorkTask(this.form).then(response => {
+              this.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addQwWorkTask(this.form).then(response => {
+              this.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$confirm('是否确认删除企微任务看板编号为"' + ids + '"的数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(function() {
+          return delQwWorkTask(ids);
+        }).then(() => {
+          this.getList();
+          this.msgSuccess("删除成功");
+        }).catch(() => {});
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      const queryParams = this.queryParams;
+      this.$confirm('是否确认导出所有企微任务看板数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(() => {
+          this.exportLoading = true;
+          return exportQwWorkTask(queryParams);
+        }).then(response => {
+          this.download(response.msg);
+          this.exportLoading = false;
+        }).catch(() => {});
+    }
+  }
+};
+</script>

+ 119 - 2
src/views/qw/externalContact/deptIndex.vue

@@ -28,7 +28,22 @@
           clearable
           size="small"
           @keyup.enter.native="handleQuery"
+          @input="searchQwUser"
+          @focus="showQwUserDropdown = true"
+          @blur="hideDropdownWithDelay"
+          @clear="onQwUserNameClear"
         />
+        <!-- 下拉建议 -->
+        <div v-if="showQwUserDropdown && qwUserSuggestions.length > 0" class="suggestion-box"  @scroll="handleScroll">
+          <div
+            v-for="item in qwUserSuggestions"
+            :key="item.dictValue"
+            class="suggestion-item"
+            @click="selectQwUser(item.dictValue,item.dictLabel)"
+          >
+            {{ item.dictLabel }}
+          </div>
+        </div>
       </el-form-item>
       <el-form-item label="用户类别" prop="type">
         <el-select v-model="queryParams.type" placeholder="请选择用户类别" clearable size="small">
@@ -753,7 +768,7 @@ import {
   getRepeat,
   updateExternalContactCall, myDeptExtList
 } from '../../../api/qw/externalContact'
-import {getMyQwCompanyList} from "@/api/qw/user";
+import {getMyQwCompanyList,getQwUserListLikeName} from "@/api/qw/user";
 import {getId} from "@/api/store/healthRecord";
 import {listTag, searchTags,} from "@/api/qw/tag";
 import {allListTagGroup} from "@/api/qw/tagGroup";
@@ -796,6 +811,15 @@ export default {
         open:false,
       },
 
+      // ...其他已有数据
+      qwUserSuggestions: [],       // 已展示的数据
+      showQwUserDropdown: false,   // 控制下拉框显示
+      qwUserLoading: false,        // 加载状态
+      qwUserNoMore: false,         // 是否还有更多数据
+      qwUserPageNum: 1,            // 当前页码
+      qwUserPageSize: 10,          // 每页数量
+      qwUserTotal: 0,               // 总数
+
       isBindMiniOptions:[
         {dictLabel:"已绑定",dictValue:'isBindMini'},
         {dictLabel:"未绑定",dictValue:'noBindMini'},
@@ -1018,6 +1042,81 @@ export default {
 
   },
   methods: {
+
+    onQwUserNameClear() {
+      this.queryParams.qwUserId = null;  // 同时清空 qwUserId
+    },
+    // 搜索企微用户
+    searchQwUser(query) {
+      if (!query.trim()) {
+        this.qwUserSuggestions = [];
+        this.showQwUserDropdown = false;
+        this.qwUserNoMore = false;
+        this.qwUserPageNum = 1;
+        return;
+      }
+
+      this.queryParams.qwUserName = query;
+      this.qwUserPageNum = 1;
+      this.qwUserNoMore = false;
+      this.qwUserSuggestions = [];
+      this.fetchQwUsers(query);
+    },
+
+    fetchQwUsers(query) {
+      const params = {
+        qwUserName: query,
+        pageNum: this.qwUserPageNum,
+        pageSize: this.qwUserPageSize
+      };
+
+      this.qwUserLoading = true;
+
+      getQwUserListLikeName(params).then(res => {
+        const list = res.data.list || [];
+        const total = res.data.total || 0;
+
+        this.qwUserSuggestions = [...this.qwUserSuggestions, ...list];
+        this.qwUserTotal = total;
+
+        // 判断是否还有更多数据
+        if (this.qwUserSuggestions.length >= total) {
+          this.qwUserNoMore = true;
+        }
+
+        this.showQwUserDropdown = true;
+      }).finally(() => {
+        this.qwUserLoading = false;
+      });
+    },
+
+    // 选择企微用户
+    selectQwUser(key,value) {
+      this.queryParams.qwUserName = value;
+      this.queryParams.qwUserId = key;
+      this.showQwUserDropdown = false;
+      this.handleQuery(); // 可选:自动触发查询
+    },
+
+    // 延迟隐藏下拉框,防止点击失效
+    hideDropdownWithDelay() {
+      setTimeout(() => {
+        this.showQwUserDropdown = false;
+      }, 200);
+    },
+    handleScroll(e) {
+      const container = e.target;
+      const scrollTop = container.scrollTop;
+      const scrollHeight = container.scrollHeight;
+      const clientHeight = container.clientHeight;
+
+      // 距离底部小于 20px 触发加载
+      if (scrollHeight - scrollTop - clientHeight < 20 && !this.qwUserLoading && !this.qwUserNoMore) {
+        this.qwUserPageNum += 1;
+        this.fetchQwUsers(this.queryParams.qwUserName);
+      }
+    },
+
     async healthHandledetails(row) {
       try {
         console.log(row.fsUserId);
@@ -1068,7 +1167,8 @@ export default {
     /** 查询企业微信客户列表 */
     getList() {
       this.loading = true;
-      myDeptExtList(this.queryParams).then(response => {
+      const { qwUserName, ...queryParams } = this.queryParams;
+      myDeptExtList(queryParams).then(response => {
         this.externalContactList = response.rows;
         this.total = response.total;
         this.loading = false;
@@ -1904,6 +2004,23 @@ export default {
 }
 
 
+.suggestion-box {
+  position: absolute;
+  z-index: 999;
+  background: #fff;
+  border: 1px solid #ddd;
+  max-height: 200px;
+  overflow-y: auto;
+  width: 100%;
+}
+
+.suggestion-item {
+  padding: 10px;
+  cursor: pointer;
+}
+.suggestion-item:hover {
+  background-color: #f5f7fa;
+}
 
 .button-new-tag {
   margin-left: 10px;

+ 120 - 3
src/views/qw/externalContact/index.vue

@@ -28,7 +28,22 @@
           clearable
           size="small"
           @keyup.enter.native="handleQuery"
+          @input="searchQwUser"
+          @focus="showQwUserDropdown = true"
+          @blur="hideDropdownWithDelay"
+          @clear="onQwUserNameClear"
         />
+        <!-- 下拉建议 -->
+        <div v-if="showQwUserDropdown && qwUserSuggestions.length > 0" class="suggestion-box"  @scroll="handleScroll">
+          <div
+            v-for="item in qwUserSuggestions"
+            :key="item.dictValue"
+            class="suggestion-item"
+            @click="selectQwUser(item.dictValue,item.dictLabel)"
+          >
+            {{ item.dictLabel }}
+          </div>
+        </div>
       </el-form-item>
       <el-form-item label="用户类别" prop="type">
         <el-select v-model="queryParams.type" placeholder="请选择用户类别" clearable size="small">
@@ -644,7 +659,7 @@ import {
   setCustomerCourseSopList,
   unBindUserId, updateExternalContactCall
 } from '@/api/qw/externalContact'
-import {getMyQwUserList, getMyQwCompanyList, updateUser} from "@/api/qw/user";
+import {getMyQwUserList, getMyQwCompanyList, updateUser,getQwUserListLikeName} from "@/api/qw/user";
 import {listTag, getTag, searchTags,} from "@/api/qw/tag";
 import { allListTagGroup} from "@/api/qw/tagGroup";
 import mycustomer from '@/views/qw/externalContact/mycustomer'
@@ -671,7 +686,14 @@ export default {
         title:"用户信息",
         open:false,
       },
-
+      // ...其他已有数据
+      qwUserSuggestions: [],       // 已展示的数据
+      showQwUserDropdown: false,   // 控制下拉框显示
+      qwUserLoading: false,        // 加载状态
+      qwUserNoMore: false,         // 是否还有更多数据
+      qwUserPageNum: 1,            // 当前页码
+      qwUserPageSize: 10,          // 每页数量
+      qwUserTotal: 0,               // 总数
       isBindMiniOptions:[
         {dictLabel:"已绑定",dictValue:'isBindMini'},
         {dictLabel:"未绑定",dictValue:'noBindMini'},
@@ -874,6 +896,81 @@ export default {
 
   },
   methods: {
+    onQwUserNameClear() {
+      this.queryParams.qwUserId = null;  // 同时清空 qwUserId
+    },
+    // 搜索企微用户
+    searchQwUser(query) {
+      if (!query.trim()) {
+        this.qwUserSuggestions = [];
+        this.showQwUserDropdown = false;
+        this.qwUserNoMore = false;
+        this.qwUserPageNum = 1;
+        return;
+      }
+
+      this.queryParams.qwUserName = query;
+      this.qwUserPageNum = 1;
+      this.qwUserNoMore = false;
+      this.qwUserSuggestions = [];
+      this.fetchQwUsers(query);
+    },
+
+    fetchQwUsers(query) {
+      const params = {
+        qwUserName: query,
+        pageNum: this.qwUserPageNum,
+        pageSize: this.qwUserPageSize
+      };
+
+      this.qwUserLoading = true;
+
+      getQwUserListLikeName(params).then(res => {
+        const list = res.data.list || [];
+        const total = res.data.total || 0;
+
+        this.qwUserSuggestions = [...this.qwUserSuggestions, ...list];
+        this.qwUserTotal = total;
+
+        // 判断是否还有更多数据
+        if (this.qwUserSuggestions.length >= total) {
+          this.qwUserNoMore = true;
+        }
+
+        this.showQwUserDropdown = true;
+      }).finally(() => {
+        this.qwUserLoading = false;
+      });
+    },
+
+    // 选择企微用户
+    selectQwUser(key,value) {
+      this.queryParams.qwUserName = value;
+      this.queryParams.qwUserId = key;
+      this.showQwUserDropdown = false;
+      this.handleQuery(); // 可选:自动触发查询
+    },
+
+    // 延迟隐藏下拉框,防止点击失效
+    hideDropdownWithDelay() {
+      setTimeout(() => {
+        this.showQwUserDropdown = false;
+      }, 200);
+    },
+    handleScroll(e) {
+      const container = e.target;
+      const scrollTop = container.scrollTop;
+      const scrollHeight = container.scrollHeight;
+      const clientHeight = container.clientHeight;
+
+      // 距离底部小于 20px 触发加载
+      if (scrollHeight - scrollTop - clientHeight < 20 && !this.qwUserLoading && !this.qwUserNoMore) {
+        this.qwUserPageNum += 1;
+        this.fetchQwUsers(this.queryParams.qwUserName);
+      }
+    },
+
+
 	  change(){
 			if(this.createTime!=null){
 			  this.queryParams.sTime=this.createTime[0];
@@ -894,7 +991,8 @@ export default {
     /** 查询企业微信客户列表 */
     getList() {
       this.loading = true;
-      listExternalContact(this.queryParams).then(response => {
+      const { qwUserName, ...queryParams } = this.queryParams;
+      listExternalContact(queryParams).then(response => {
         this.externalContactList = response.rows;
         this.total = response.total;
         this.loading = false;
@@ -1671,4 +1769,23 @@ export default {
       margin-left: 10px;
       vertical-align: bottom;
     }
+
+
+.suggestion-box {
+  position: absolute;
+  z-index: 999;
+  background: #fff;
+  border: 1px solid #ddd;
+  max-height: 200px;
+  overflow-y: auto;
+  width: 100%;
+}
+
+.suggestion-item {
+  padding: 10px;
+  cursor: pointer;
+}
+.suggestion-item:hover {
+  background-color: #f5f7fa;
+}
 </style>

+ 5 - 5
src/views/qw/externalContact/myExternalContact.vue

@@ -207,7 +207,7 @@
           size="mini"
           :loading="exportLoading"
           @click="handleSyncMyExternalContact"
-          v-hasPermi="['qw:externalContact:export']"
+          v-hasPermi="['qw:externalContact:myExport']"
         >同步我的客户</el-button>
 		<el-button
 		  type="warning"
@@ -216,7 +216,7 @@
 		  size="mini"
 		  :loading="exportLoading"
 		  @click="handleSyncAddMyExternalContact"
-		  v-hasPermi="['qw:externalContact:export']"
+		  v-hasPermi="['qw:externalContact:myExport']"
 		>新客同步</el-button>
       </el-col>
       <el-col :span="1.5">
@@ -227,7 +227,7 @@
           size="mini"
           :loading="exportLoading"
           @click="handleExport"
-          v-hasPermi="['qw:externalContact:export']"
+          v-hasPermi="['qw:externalContact:myExport']"
         >导出</el-button>
       </el-col>
       <el-col :span="1.5">
@@ -652,7 +652,7 @@ import {
   setCustomerCourseSop,
   getCustomerCourseSop,
   setCustomerCourseSopList,
-  syncMyExternalContact, unBindUserId, updateExternalContactCall
+  syncMyExternalContact, unBindUserId, updateExternalContactCall,exportMyExternalContact
 } from '@/api/qw/externalContact'
 import info from "@/views/qw/externalContact/info.vue";
 import {getMyQwUserList, getMyQwCompanyList, handleInputAuthAppKey, updateUser} from "@/api/qw/user";
@@ -1693,7 +1693,7 @@ export default {
           type: "warning"
         }).then(() => {
           this.exportLoading = true;
-          return exportExternalContact(queryParams);
+          return exportMyExternalContact(queryParams);
         }).then(response => {
           this.download(response.msg);
           this.exportLoading = false;

+ 418 - 0
src/views/qw/myVoiceLog/index.vue

@@ -0,0 +1,418 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="148px">
+      <el-form-item label="外部联系人名称" prop="extName">
+        <el-input
+          v-model="queryParams.extName"
+          placeholder="请输入外部联系人名称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="企微用户名称" prop="qwUserName">
+        <el-input
+          v-model="queryParams.qwUserName"
+          placeholder="请输入企微用户名称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+<!--      <el-form-item label="标题" prop="title">
+        <el-input
+          v-model="queryParams.title"
+          placeholder="请输入标题"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>-->
+      <el-form-item label="通话状态" prop="status">
+        <el-select v-model="queryParams.status" placeholder="请选择通话状态" clearable size="small">
+          <el-option
+            v-for="dict in statusOptions"
+            :key="dict.dictValue"
+            :label="dict.dictLabel"
+            :value="dict.dictValue"
+          />
+        </el-select>
+      </el-form-item>
+<!--      <el-form-item label="企微id" prop="corpId">
+        <el-input
+          v-model="queryParams.corpId"
+          placeholder="请输入企微id"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>-->
+      <el-form-item label="公司名称" prop="companyName">
+        <el-input
+          v-model="queryParams.companyName"
+          placeholder="请输入公司名称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="销售用户名称" prop="companyUserName">
+        <el-input
+          v-model="queryParams.companyUserName"
+          placeholder="请输入销售用户名称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+<!--      <el-form-item label="时长秒" prop="duration">
+        <el-input
+          v-model="queryParams.duration"
+          placeholder="请输入时长秒"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>-->
+      <el-form-item label="创建时间" prop="createTime">
+        <el-date-picker v-model="createTime" size="small" style="width: 215px"
+                        value-format="yyyy-MM-dd" type="daterange" range-separator="-"
+                        start-placeholder="开始日期" end-placeholder="结束日期"
+                        @change="changeTime"></el-date-picker>
+      </el-form-item>
+
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+<!--      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          v-hasPermi="['qw:qwUserVoiceLog:add']"
+        >新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="el-icon-edit"
+          size="mini"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['qw:qwUserVoiceLog:edit']"
+        >修改</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['qw:qwUserVoiceLog:remove']"
+        >删除</el-button>
+      </el-col>-->
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="el-icon-download"
+          size="mini"
+          :loading="exportLoading"
+          @click="handleExport"
+          v-hasPermi="['qw:qwUserVoiceLog:myExport']"
+        >导出</el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table border v-loading="loading" :data="qwUserVoiceLogList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="id" align="center" width="80" prop="id" />
+      <el-table-column label="外部联系人名称" align="center" prop="qwExternalContact.name" />
+      <el-table-column label="企微用户名称" align="center" prop="qwUser.qwUserName" />
+      <el-table-column label="时长秒" align="center" prop="duration" />
+      <el-table-column label="标题" align="center" width="80" prop="title" />
+      <el-table-column label="通话状态" align="center" prop="status">
+        <template slot-scope="scope">
+          <dict-tag :options="statusOptions" :value="scope.row.status"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="企微id" align="center" width="80" prop="corpId" />
+      <el-table-column label="公司名称" align="center" prop="company.companyName" />
+      <el-table-column label="销售用户名称" align="center" prop="companyUser.userName" />
+      <el-table-column label="创建时间" align="center" prop="createTime" />
+<!--      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['qw:qwUserVoiceLog:edit']"
+          >修改</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['qw:qwUserVoiceLog:remove']"
+          >删除</el-button>
+        </template>
+      </el-table-column>-->
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改企微用户通话记录对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="外部联系人id" prop="extId">
+          <el-input v-model="form.extId" placeholder="请输入外部联系人id" />
+        </el-form-item>
+        <el-form-item label="企微用户id" prop="qwUserId">
+          <el-input v-model="form.qwUserId" placeholder="请输入企微用户id" />
+        </el-form-item>
+        <el-form-item label="时长秒" prop="duration">
+          <el-input v-model="form.duration" placeholder="请输入时长秒" />
+        </el-form-item>
+        <el-form-item label="标题" prop="title">
+          <el-input v-model="form.title" placeholder="请输入标题" />
+        </el-form-item>
+        <el-form-item label="1接听 2未接">
+          <el-radio-group v-model="form.status">
+            <el-radio
+              v-for="dict in statusOptions"
+              :key="dict.dictValue"
+              :label="parseInt(dict.dictValue)"
+            >{{dict.dictLabel}}</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="企微id" prop="corpId">
+          <el-input v-model="form.corpId" placeholder="请输入企微id" />
+        </el-form-item>
+        <el-form-item label="公司id" prop="companyId">
+          <el-input v-model="form.companyId" placeholder="请输入公司id" />
+        </el-form-item>
+        <el-form-item label="销售用户id" prop="companyUserId">
+          <el-input v-model="form.companyUserId" placeholder="请输入销售用户id" />
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { listMyVoiceLog,  exportMyVoiceLog } from "@/api/qw/myVoiceLog";
+
+export default {
+  name: "QwUserVoiceLog",
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 导出遮罩层
+      exportLoading: false,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      //时间范围
+      createTime:null,
+      beginTime:null,
+      endTime:null,
+      // 总条数
+      total: 0,
+      // 企微用户通话记录表格数据
+      qwUserVoiceLogList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 1接听 2未接字典
+      statusOptions: [],
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        extId: null,
+        extName:null,
+        qwUserId: null,
+        qwUserName: null,
+        duration: null,
+        title: null,
+        status: null,
+        corpId: null,
+        companyId: null,
+        companyName: null,
+        companyUserId: null,
+        companyUserName: null,
+        createTime:null,
+        beginTime:null,
+        endTime:null,
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+      }
+    };
+  },
+  created() {
+    this.getList();
+    this.getDicts("sys_qw_user_voice_status").then(response => {
+      this.statusOptions = response.data;
+    });
+  },
+  methods: {
+    /** 查询企微用户通话记录列表 */
+    getList() {
+      this.loading = true;
+      listMyVoiceLog(this.queryParams).then(response => {
+        this.qwUserVoiceLogList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    changeTime(){
+      if(this.createTime!=null){
+        this.queryParams.beginTime=this.createTime[0];
+        this.queryParams.endTime=this.createTime[1];
+      }else{
+        this.queryParams.beginTime=null;
+        this.queryParams.endTime=null;
+      }
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        extId: null,
+        qwUserId: null,
+        duration: null,
+        title: null,
+        status: 0,
+        corpId: null,
+        companyId: null,
+        companyUserId: null,
+        createTime:null,
+        beginTime:null,
+        endTime:null,
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.createTime=null;
+      this.queryParams.beginTime = null;
+      this.queryParams.endTime = null;
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length!==1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加企微用户通话记录";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id || this.ids
+      getQwUserVoiceLog(id).then(response => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改企微用户通话记录";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.id != null) {
+            updateQwUserVoiceLog(this.form).then(response => {
+              this.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addQwUserVoiceLog(this.form).then(response => {
+              this.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$confirm('是否确认删除企微用户通话记录编号为"' + ids + '"的数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(function() {
+          return delQwUserVoiceLog(ids);
+        }).then(() => {
+          this.getList();
+          this.msgSuccess("删除成功");
+        }).catch(() => {});
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      const queryParams = this.queryParams;
+      this.$confirm('是否确认导出所有企微用户通话记录数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(() => {
+          this.exportLoading = true;
+          return exportMyVoiceLog(queryParams);
+        }).then(response => {
+          this.download(response.msg);
+          this.exportLoading = false;
+        }).catch(() => {});
+    }
+  }
+};
+</script>

+ 418 - 0
src/views/qw/qwUserVoiceLog/index.vue

@@ -0,0 +1,418 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="148px">
+      <el-form-item label="外部联系人名称" prop="extName">
+        <el-input
+          v-model="queryParams.extName"
+          placeholder="请输入外部联系人名称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="企微用户名称" prop="qwUserName">
+        <el-input
+          v-model="queryParams.qwUserName"
+          placeholder="请输入企微用户名称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+<!--      <el-form-item label="标题" prop="title">
+        <el-input
+          v-model="queryParams.title"
+          placeholder="请输入标题"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>-->
+      <el-form-item label="通话状态" prop="status">
+        <el-select v-model="queryParams.status" placeholder="请选择通话状态" clearable size="small">
+          <el-option
+            v-for="dict in statusOptions"
+            :key="dict.dictValue"
+            :label="dict.dictLabel"
+            :value="dict.dictValue"
+          />
+        </el-select>
+      </el-form-item>
+<!--      <el-form-item label="企微id" prop="corpId">
+        <el-input
+          v-model="queryParams.corpId"
+          placeholder="请输入企微id"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>-->
+      <el-form-item label="公司名称" prop="companyName">
+        <el-input
+          v-model="queryParams.companyName"
+          placeholder="请输入公司名称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="销售用户名称" prop="companyUserName">
+        <el-input
+          v-model="queryParams.companyUserName"
+          placeholder="请输入销售用户名称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+<!--      <el-form-item label="时长秒" prop="duration">
+        <el-input
+          v-model="queryParams.duration"
+          placeholder="请输入时长秒"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>-->
+      <el-form-item label="创建时间" prop="createTime">
+        <el-date-picker v-model="createTime" size="small" style="width: 215px"
+                        value-format="yyyy-MM-dd" type="daterange" range-separator="-"
+                        start-placeholder="开始日期" end-placeholder="结束日期"
+                        @change="changeTime"></el-date-picker>
+      </el-form-item>
+
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+<!--      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          v-hasPermi="['qw:qwUserVoiceLog:add']"
+        >新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="el-icon-edit"
+          size="mini"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['qw:qwUserVoiceLog:edit']"
+        >修改</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['qw:qwUserVoiceLog:remove']"
+        >删除</el-button>
+      </el-col>-->
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="el-icon-download"
+          size="mini"
+          :loading="exportLoading"
+          @click="handleExport"
+          v-hasPermi="['qw:qwUserVoiceLog:export']"
+        >导出</el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table border v-loading="loading" :data="qwUserVoiceLogList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="id" align="center" width="80" prop="id" />
+      <el-table-column label="外部联系人名称" align="center" prop="qwExternalContact.name" />
+      <el-table-column label="企微用户名称" align="center" prop="qwUser.qwUserName" />
+      <el-table-column label="时长秒" align="center" prop="duration" />
+      <el-table-column label="标题" align="center" width="80" prop="title" />
+      <el-table-column label="通话状态" align="center" prop="status">
+        <template slot-scope="scope">
+          <dict-tag :options="statusOptions" :value="scope.row.status"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="企微id" align="center" width="80" prop="corpId" />
+      <el-table-column label="公司名称" align="center" prop="company.companyName" />
+      <el-table-column label="销售用户名称" align="center" prop="companyUser.userName" />
+      <el-table-column label="创建时间" align="center" prop="createTime" />
+<!--      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['qw:qwUserVoiceLog:edit']"
+          >修改</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['qw:qwUserVoiceLog:remove']"
+          >删除</el-button>
+        </template>
+      </el-table-column>-->
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改企微用户通话记录对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="外部联系人id" prop="extId">
+          <el-input v-model="form.extId" placeholder="请输入外部联系人id" />
+        </el-form-item>
+        <el-form-item label="企微用户id" prop="qwUserId">
+          <el-input v-model="form.qwUserId" placeholder="请输入企微用户id" />
+        </el-form-item>
+        <el-form-item label="时长秒" prop="duration">
+          <el-input v-model="form.duration" placeholder="请输入时长秒" />
+        </el-form-item>
+        <el-form-item label="标题" prop="title">
+          <el-input v-model="form.title" placeholder="请输入标题" />
+        </el-form-item>
+        <el-form-item label="1接听 2未接">
+          <el-radio-group v-model="form.status">
+            <el-radio
+              v-for="dict in statusOptions"
+              :key="dict.dictValue"
+              :label="parseInt(dict.dictValue)"
+            >{{dict.dictLabel}}</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="企微id" prop="corpId">
+          <el-input v-model="form.corpId" placeholder="请输入企微id" />
+        </el-form-item>
+        <el-form-item label="公司id" prop="companyId">
+          <el-input v-model="form.companyId" placeholder="请输入公司id" />
+        </el-form-item>
+        <el-form-item label="销售用户id" prop="companyUserId">
+          <el-input v-model="form.companyUserId" placeholder="请输入销售用户id" />
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { listQwUserVoiceLog, getQwUserVoiceLog, delQwUserVoiceLog, addQwUserVoiceLog, updateQwUserVoiceLog, exportQwUserVoiceLog } from "@/api/qw/qwUserVoiceLog";
+
+export default {
+  name: "QwUserVoiceLog",
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 导出遮罩层
+      exportLoading: false,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      //时间范围
+      createTime:null,
+      beginTime:null,
+      endTime:null,
+      // 总条数
+      total: 0,
+      // 企微用户通话记录表格数据
+      qwUserVoiceLogList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 1接听 2未接字典
+      statusOptions: [],
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        extId: null,
+        extName:null,
+        qwUserId: null,
+        qwUserName: null,
+        duration: null,
+        title: null,
+        status: null,
+        corpId: null,
+        companyId: null,
+        companyName: null,
+        companyUserId: null,
+        companyUserName: null,
+        createTime:null,
+        beginTime:null,
+        endTime:null,
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+      }
+    };
+  },
+  created() {
+    this.getList();
+    this.getDicts("sys_qw_user_voice_status").then(response => {
+      this.statusOptions = response.data;
+    });
+  },
+  methods: {
+    /** 查询企微用户通话记录列表 */
+    getList() {
+      this.loading = true;
+      listQwUserVoiceLog(this.queryParams).then(response => {
+        this.qwUserVoiceLogList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    changeTime(){
+      if(this.createTime!=null){
+        this.queryParams.beginTime=this.createTime[0];
+        this.queryParams.endTime=this.createTime[1];
+      }else{
+        this.queryParams.beginTime=null;
+        this.queryParams.endTime=null;
+      }
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        extId: null,
+        qwUserId: null,
+        duration: null,
+        title: null,
+        status: 0,
+        corpId: null,
+        companyId: null,
+        companyUserId: null,
+        createTime:null,
+        beginTime:null,
+        endTime:null,
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.createTime=null;
+      this.queryParams.beginTime = null;
+      this.queryParams.endTime = null;
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length!==1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加企微用户通话记录";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id || this.ids
+      getQwUserVoiceLog(id).then(response => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改企微用户通话记录";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.id != null) {
+            updateQwUserVoiceLog(this.form).then(response => {
+              this.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addQwUserVoiceLog(this.form).then(response => {
+              this.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$confirm('是否确认删除企微用户通话记录编号为"' + ids + '"的数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(function() {
+          return delQwUserVoiceLog(ids);
+        }).then(() => {
+          this.getList();
+          this.msgSuccess("删除成功");
+        }).catch(() => {});
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      const queryParams = this.queryParams;
+      this.$confirm('是否确认导出所有企微用户通话记录数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(() => {
+          this.exportLoading = true;
+          return exportQwUserVoiceLog(queryParams);
+        }).then(response => {
+          this.download(response.msg);
+          this.exportLoading = false;
+        }).catch(() => {});
+    }
+  }
+};
+</script>

+ 472 - 0
src/views/qw/qwUserVoiceLogTotal/index.vue

@@ -0,0 +1,472 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="148px">
+<!--      <el-form-item label="外部联系人名称" prop="extName">
+        <el-input
+          v-model="queryParams.extName"
+          placeholder="请输入外部联系人名称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>-->
+      <el-form-item label="所属销售" prop="companyUserId">
+        <el-select v-model="queryParams.companyUserId" clearable filterable remote
+                   placeholder="请输入关键词" :remote-method="loadCompanyUserOptions"
+                   v-select-load-more="loadMoreCompanyUserOptions"
+                   :loading="companyUserOptionsLoading">
+          <el-option
+            v-for="item in companyUserOptions"
+            :key="item.value"
+            :label="item.label"
+            :value="item.value">
+          </el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="企微用户名称" prop="qwUserName">
+        <el-input
+          v-model="queryParams.qwUserName"
+          placeholder="请输入企微用户名称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+<!--      <el-form-item label="标题" prop="title">
+        <el-input
+          v-model="queryParams.title"
+          placeholder="请输入标题"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>-->
+<!--      <el-form-item label="通话状态" prop="status">
+        <el-select v-model="queryParams.status" placeholder="请选择通话状态" clearable size="small">
+          <el-option
+            v-for="dict in statusOptions"
+            :key="dict.dictValue"
+            :label="dict.dictLabel"
+            :value="dict.dictValue"
+          />
+        </el-select>
+      </el-form-item>-->
+<!--      <el-form-item label="企微id" prop="corpId">
+        <el-input
+          v-model="queryParams.corpId"
+          placeholder="请输入企微id"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>-->
+<!--      <el-form-item label="公司名称" prop="companyName">
+        <el-input
+          v-model="queryParams.companyName"
+          placeholder="请输入公司名称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>-->
+
+<!--      <el-form-item label="时长秒" prop="duration">
+        <el-input
+          v-model="queryParams.duration"
+          placeholder="请输入时长秒"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>-->
+      <el-form-item label="创建时间" prop="createTime">
+        <el-date-picker v-model="createTime" size="small" style="width: 220px"
+                        value-format="yyyy-MM-dd" type="daterange" range-separator="-"
+                        start-placeholder="开始日期" end-placeholder="结束日期"
+                        @change="changeTime"></el-date-picker>
+      </el-form-item>
+
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+<!--      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          v-hasPermi="['qw:qwUserVoiceLog:add']"
+        >新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="el-icon-edit"
+          size="mini"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['qw:qwUserVoiceLog:edit']"
+        >修改</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['qw:qwUserVoiceLog:remove']"
+        >删除</el-button>
+      </el-col>-->
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="el-icon-download"
+          size="mini"
+          :loading="exportLoading"
+          @click="handleExport"
+          v-hasPermi="['qw:qwUserVoiceLog:totalExport']"
+        >导出</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          size="mini"
+          @click="getSellList"
+        >切换到销售统计</el-button>
+      </el-col>
+
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          size="mini"
+          @click="getList"
+        >切回企微通话统计</el-button>
+      </el-col>
+
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="handlePagination"></right-toolbar>
+    </el-row>
+
+    <el-table border v-loading="loading" :data="qwUserVoiceLogList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+<!--      <el-table-column label="id" align="center" width="80" prop="id" />-->
+<!--      <el-table-column label="外部联系人名称" align="center" prop="qwExternalContact.name" />-->
+      <el-table-column label="销售名称" align="center" prop="companyUserName" />
+      <el-table-column label="企微用户名称" align="center" prop="qwUser.qwUserName" />
+      <el-table-column label="企微主体名称" align="center" prop="corpName" />
+      <el-table-column label="企微用户id" align="center" prop="qwUser.qwUserId" />
+      <el-table-column label="时长秒" align="center"  prop="duration" />
+      <el-table-column label="接通数量" align="center"  prop="connectCount" />
+      <el-table-column label="未接通数量" align="center"  prop="noConnectCount" />
+<!--      <el-table-column label="标题" align="center" width="80" prop="title" />-->
+<!--      <el-table-column label="通话状态" align="center" prop="status">
+        <template slot-scope="scope">
+          <dict-tag :options="statusOptions" :value="scope.row.status"/>
+        </template>
+      </el-table-column>-->
+      <!--<el-table-column label="公司名称" align="center" prop="company.companyName" />
+      <el-table-column label="销售用户名称" align="center" prop="companyUser.userName" />
+      <el-table-column label="创建时间" align="center" prop="createTime" />-->
+<!--      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['qw:qwUserVoiceLog:edit']"
+          >修改</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['qw:qwUserVoiceLog:remove']"
+          >删除</el-button>
+        </template>
+      </el-table-column>-->
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="handlePagination"
+    />
+  </div>
+</template>
+
+<script>
+import { listQwUserVoiceLog, getQwUserVoiceLog, delQwUserVoiceLog, addQwUserVoiceLog, updateQwUserVoiceLog, exportQwUserVoiceLog } from "@/api/qw/qwUserVoiceLog";
+import {listQwUserVoiceLogTotal,exportQwUserVoiceLogTotal,listQwUserVoiceLogSellTotal,exportQwUserVoiceLogSellTotal} from "@/api/qw/qwUserVoiceLogTotal";
+import {getCompanyUserListLikeName} from "@/api/company/companyUser";
+
+export default {
+  name: "QwUserVoiceLog",
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      status: 0,
+      // 导出遮罩层
+      exportLoading: false,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      //时间范围
+      createTime:null,
+      beginTime:null,
+      endTime:null,
+      // 总条数
+      total: 0,
+      // 企微用户通话记录表格数据
+      qwUserVoiceLogList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 1接听 2未接字典
+      statusOptions: [],
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        extId: null,
+        extName:null,
+        qwUserId: null,
+        qwUserName: null,
+        duration: null,
+        title: null,
+        status: null,
+        corpName: null,
+        companyId: null,
+        companyName: null,
+        companyUserId: null,
+        companyUserName: null,
+        createTime:null,
+        beginTime:null,
+        endTime:null,
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+      },
+      companyUserOptionsLoading: false,
+      companyUserOptions: [],
+      companyUserOptionsParams: {
+        name: undefined,
+        hasNextPage: false,
+        pageNum: 1,
+        pageSize: 10
+      },
+    };
+  },
+  created() {
+    this.handlePagination();
+    this.getDicts("sys_qw_user_voice_status").then(response => {
+      this.statusOptions = response.data;
+    });
+  },
+  methods: {
+    /** 查询企微用户通话记录列表 */
+    getList() {
+      this.loading = true;
+      this.status = 0;
+      listQwUserVoiceLogTotal(this.queryParams).then(response => {
+        this.qwUserVoiceLogList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    getSellList() {
+      this.loading = true;
+      this.status = 1;
+      listQwUserVoiceLogSellTotal(this.queryParams).then(response => {
+        this.qwUserVoiceLogList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 新增 handlePagination 方法
+    handlePagination() {
+      if (this.status === 0) {
+        this.getList();
+      } else {
+        this.getSellList();
+      }
+    },
+    /**
+     * 根据名称模糊查询用户列表
+     * @param query 参数
+     */
+    loadCompanyUserOptions(query) {
+      this.companyUserOptions = [];
+      if (query === '') {
+        return;
+      }
+
+      this.companyUserOptionsParams.pageNum = 1
+      this.companyUserOptionsParams.name = query
+      this.companyUserOptionsLoading = true;
+      this.getCompanyUserListLikeName()
+    },
+    getCompanyUserListLikeName() {
+      getCompanyUserListLikeName(this.companyUserOptionsParams).then(response => {
+        this.companyUserOptions = [...this.companyUserOptions, ...response.data.list]
+        this.companyUserOptionsParams.hasNextPage = response.data.hasNextPage
+        this.companyUserOptionsLoading = false;
+      });
+    },
+    /**
+     * 加载更多员工选项
+     */
+    loadMoreCompanyUserOptions() {
+      if (!this.companyUserOptionsParams.hasNextPage) {
+        return;
+      }
+
+      this.companyUserOptionsParams.pageNum += 1
+      this.getCompanyUserListLikeName()
+    },
+    changeTime(){
+      if(this.createTime!=null){
+        this.queryParams.beginTime=this.createTime[0];
+        this.queryParams.endTime=this.createTime[1];
+      }else{
+        this.queryParams.beginTime=null;
+        this.queryParams.endTime=null;
+      }
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        extId: null,
+        qwUserId: null,
+        duration: null,
+        title: null,
+        status: 0,
+        corpId: null,
+        companyId: null,
+        companyUserId: null,
+        createTime: null,
+        beginTime:null,
+        endTime:null,
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.handlePagination();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.createTime=null;
+      this.queryParams.beginTime = null;
+      this.queryParams.endTime = null;
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length!==1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加企微用户通话记录";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id || this.ids
+      getQwUserVoiceLog(id).then(response => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改企微用户通话记录";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.id != null) {
+            updateQwUserVoiceLog(this.form).then(response => {
+              this.msgSuccess("修改成功");
+              this.open = false;
+              this.handlePagination();
+            });
+          } else {
+            addQwUserVoiceLog(this.form).then(response => {
+              this.msgSuccess("新增成功");
+              this.open = false;
+              this.handlePagination();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$confirm('是否确认删除企微用户通话记录编号为"' + ids + '"的数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(function() {
+          return delQwUserVoiceLog(ids);
+        }).then(() => {
+          this.handlePagination();
+          this.msgSuccess("删除成功");
+        }).catch(() => {});
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      const queryParams = this.queryParams;
+      this.$confirm('是否确认导出所有企微用户通话记录数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(() => {
+          this.exportLoading = true;
+        if(this.status === 0){
+          return exportQwUserVoiceLogTotal(queryParams);
+        }else{
+          return exportQwUserVoiceLogSellTotal(queryParams);
+        }
+
+        }).then(response => {
+          this.download(response.msg);
+          this.exportLoading = false;
+        }).catch(() => {});
+    }
+  }
+};
+</script>