Pārlūkot izejas kodu

自动外呼、 部门管理

liuyifan 5 gadi atpakaļ
vecāks
revīzija
4c994eb5c4
33 mainītis faili ar 4146 papildinājumiem un 101 dzēšanām
  1. 9 0
      CallCenterWeb.UI/src/api/customerServiceManagement/orderListCustomerService.js
  2. 30 0
      CallCenterWeb.UI/src/api/outbound/allot.js
  3. 21 0
      CallCenterWeb.UI/src/api/outbound/callResult.js
  4. 122 0
      CallCenterWeb.UI/src/api/outbound/plan.js
  5. 66 0
      CallCenterWeb.UI/src/api/outbound/tasks.js
  6. 8 0
      CallCenterWeb.UI/src/api/systemSetup/roleSetting/department.js
  7. 7 0
      CallCenterWeb.UI/src/views/afterSaleManagement/afterSaleList/addOrEdit.vue
  8. 0 5
      CallCenterWeb.UI/src/views/afterSaleManagement/afterSaleOrderList/edit.vue
  9. 15 0
      CallCenterWeb.UI/src/views/afterSaleManagement/afterSaleOrderList/index.vue
  10. 7 0
      CallCenterWeb.UI/src/views/afterSaleManagement/saleOrderList/afterSale.vue
  11. 43 1
      CallCenterWeb.UI/src/views/afterSaleManagement/saleOrderList/index.vue
  12. 15 0
      CallCenterWeb.UI/src/views/custodianManagement/orderListCustodian/index.vue
  13. 41 4
      CallCenterWeb.UI/src/views/customerServiceManagement/orderListCustomerService/index.vue
  14. 3 3
      CallCenterWeb.UI/src/views/customerServiceManagement/orderListCustomerService/label.vue
  15. 89 0
      CallCenterWeb.UI/src/views/customerServiceManagement/orderListCustomerService/logistics.vue
  16. 0 6
      CallCenterWeb.UI/src/views/orderManagement/orderList/edit.vue
  17. 15 0
      CallCenterWeb.UI/src/views/orderManagement/orderList/index.vue
  18. 358 0
      CallCenterWeb.UI/src/views/outbound/allot/components/outboundAllot.vue
  19. 285 0
      CallCenterWeb.UI/src/views/outbound/allot/components/tabAllot.vue
  20. 222 0
      CallCenterWeb.UI/src/views/outbound/allot/index.vue
  21. 234 0
      CallCenterWeb.UI/src/views/outbound/callResult/detail.vue
  22. 182 0
      CallCenterWeb.UI/src/views/outbound/callResult/index.vue
  23. 326 0
      CallCenterWeb.UI/src/views/outbound/joinTask/index.vue
  24. 192 0
      CallCenterWeb.UI/src/views/outbound/myTask/components/tabMyTask.vue
  25. 213 0
      CallCenterWeb.UI/src/views/outbound/myTask/index.vue
  26. 387 0
      CallCenterWeb.UI/src/views/outbound/plan/addOrEdit.vue
  27. 132 0
      CallCenterWeb.UI/src/views/outbound/plan/importTels.vue
  28. 545 0
      CallCenterWeb.UI/src/views/outbound/plan/index.vue
  29. 235 0
      CallCenterWeb.UI/src/views/outbound/tasks/components/tabTask.vue
  30. 231 0
      CallCenterWeb.UI/src/views/outbound/tasks/index.vue
  31. 20 5
      CallCenterWeb.UI/src/views/systemSetup/roleSetting/department/component/addOrEdit.vue
  32. 9 3
      CallCenterWeb.UI/src/views/systemSetup/roleSetting/department/component/addOrEditTeam.vue
  33. 84 74
      CallCenterWeb.UI/src/views/systemSetup/roleSetting/department/index.vue

+ 9 - 0
CallCenterWeb.UI/src/api/customerServiceManagement/orderListCustomerService.js

@@ -114,5 +114,14 @@ export function afterSaleRefundOperation(params) {
114 114
     params
115 115
   })
116 116
 }
117
+
118
+//物流状态
119
+export function logisticsStatusOrderCustomerService(data) {
120
+  return request({
121
+    url: 'api/kforder/addordertag',
122
+    method: 'post',
123
+    data
124
+  })
125
+}
117 126
   
118 127
 

+ 30 - 0
CallCenterWeb.UI/src/api/outbound/allot.js

@@ -0,0 +1,30 @@
1
+import request from '@/utils/request'
2
+
3
+// 获取外呼计划列表数据
4
+export function getPlanLists(params) {
5
+  return request({
6
+    url: 'callcenterapi/api/autocallouttask/getlistbypage',
7
+    method: 'get',
8
+    params
9
+  })
10
+}
11
+
12
+// 获取参与坐席
13
+export function getfplist(taskid) {
14
+  return request({
15
+    url: 'callcenterapi/api/autocallouttask/getfplist',
16
+    method: 'get',
17
+    params: {
18
+      taskid
19
+    }
20
+  })
21
+}
22
+
23
+// 确定分配
24
+export function fpdata(data) {
25
+  return request({
26
+    url: 'callcenterapi/api/autocallouttask/fpdata',
27
+    method: 'post',
28
+    data
29
+  })
30
+}

+ 21 - 0
CallCenterWeb.UI/src/api/outbound/callResult.js

@@ -0,0 +1,21 @@
1
+import request from '@/utils/request'
2
+
3
+// 获取外呼问卷列表 - 自动外呼 结果
4
+export function getAutoPagerLists(params) {
5
+  return request({
6
+    url: 'callcenterapi/api/Questionnaire/getcallpagelistbypage',
7
+    method: 'get',
8
+    params
9
+  })
10
+}
11
+
12
+// 获取外呼问卷详情 - 自动外呼 结果
13
+export function getAutoPager(id) {
14
+  return request({
15
+    url: 'callcenterapi/api/Questionnaire/getcallpagedetails',
16
+    method: 'get',
17
+    params: {
18
+      id
19
+    }
20
+  })
21
+}

+ 122 - 0
CallCenterWeb.UI/src/api/outbound/plan.js

@@ -0,0 +1,122 @@
1
+import request from '@/utils/request'
2
+
3
+// 获取外呼计划(左)列表数据
4
+export function getPlanLists(params) {
5
+  return request({
6
+    url: 'callcenterapi/api/autocallouttask/getlistbypage',
7
+    method: 'get',
8
+    params
9
+  })
10
+}
11
+
12
+// 获取外呼计划(左)数据
13
+export function getPlan(id) {
14
+  return request({
15
+    url: 'callcenterapi/api/autocallouttask/getsingle',
16
+    method: 'get',
17
+    params: {
18
+      id
19
+    }
20
+  })
21
+}
22
+
23
+// 添加外呼计划(左)数据
24
+export function addPlan(data) {
25
+  return request({
26
+    url: 'callcenterapi/api/autocallouttask/add',
27
+    method: 'post',
28
+    data
29
+  })
30
+}
31
+
32
+// 编辑外呼计划(左)数据
33
+export function editPlan(data) {
34
+  return request({
35
+    url: 'callcenterapi/api/autocallouttask/update',
36
+    method: 'post',
37
+    data
38
+  })
39
+}
40
+
41
+// 删除外呼计划(左)数据
42
+export function deletePlan(ids) {
43
+  return request({
44
+    url: 'callcenterapi/api/autocallouttask/delete',
45
+    method: 'post',
46
+    data: {
47
+      ids
48
+    }
49
+  })
50
+}
51
+
52
+// 导入 callcenterapi/api/autocallouttask/importexcel
53
+
54
+// 上架下架
55
+export function updateLine(data) {
56
+  return request({
57
+    url: 'callcenterapi/api/autocallouttask/updateonline',
58
+    method: 'post',
59
+    data
60
+  })
61
+}
62
+
63
+// 启动 停止 暂停(1为启动,10为暂停,11为停止)
64
+export function oparatePlan(data) {
65
+  return request({
66
+    url: 'callcenterapi/api/autocall/precallope',
67
+    method: 'post',
68
+    data
69
+  })
70
+}
71
+
72
+// 清空号码btn_empty
73
+export function emptyTels(id) {
74
+  return request({
75
+    url: 'callcenterapi/api/autocallouttask/removeall',
76
+    method: 'post',
77
+    data: {
78
+      id
79
+    }
80
+  })
81
+}
82
+
83
+// 重复执行
84
+export function restart(taskid) {
85
+  return request({
86
+    url: 'callcenterapi/api/autocall/restart',
87
+    method: 'post',
88
+    data: {
89
+      taskid
90
+    }
91
+  })
92
+}
93
+
94
+// 获取外呼号码(右)列表数据
95
+export function getPlanTelLists(params) {
96
+  return request({
97
+    url: 'callcenterapi/api/autocallouttask/gettellistbypage',
98
+    method: 'get',
99
+    params
100
+  })
101
+}
102
+
103
+// 删除外呼号码(右)数据
104
+export function deletePlanTel(ids) {
105
+  return request({
106
+    url: 'callcenterapi/api/autocallouttask/deletetel',
107
+    method: 'post',
108
+    data: {
109
+      ids
110
+    }
111
+  })
112
+}
113
+
114
+// 获取任务电话详情 - 自动外呼
115
+export function getTelDetail(params) {
116
+  return request({
117
+    url: 'callcenterapi/api/autocallouttask/getteldetails',
118
+    method: 'get',
119
+    params
120
+  })
121
+}
122
+

+ 66 - 0
CallCenterWeb.UI/src/api/outbound/tasks.js

@@ -0,0 +1,66 @@
1
+import request from '@/utils/request'
2
+
3
+// 获取任务列表数据
4
+export function getTaskLists(params) {
5
+  return request({
6
+    url: 'callcenterapi/api/autocallouttask/getmytask',
7
+    method: 'get',
8
+    params
9
+  })
10
+}
11
+
12
+// 坐席参与或取消任务
13
+export function cancelJoin(data) {
14
+  return request({
15
+    url: 'callcenterapi/api/autocall/joinprecall',
16
+    method: 'post',
17
+    data
18
+  })
19
+}
20
+
21
+// 获取任务监控信息
22
+export function getMonitor(id) {
23
+  return request({
24
+    url: 'callcenterapi/api/autocallouttask/getmonitor',
25
+    method: 'get',
26
+    params: {
27
+      id
28
+    }
29
+  })
30
+}
31
+
32
+// 获取参与任务坐席
33
+export function getJoinSeat(params) {
34
+  return request({
35
+    url: 'callcenterapi/api/autocallouttask/getfplist',
36
+    method: 'get',
37
+    params
38
+  })
39
+}
40
+
41
+// 修改并发数
42
+export function setConNum(data) {
43
+  return request({
44
+    url: 'callcenterapi/api/autocall/setbfnum',
45
+    method: 'post',
46
+    data
47
+  })
48
+}
49
+
50
+// 获取当前的任务信息
51
+export function getTaskRealInfo(params) {
52
+  return request({
53
+    url: 'callcenterapi/api/autocallouttask/getjoinlist',
54
+    method: 'get',
55
+    params
56
+  })
57
+}
58
+
59
+// 获取分配给当前坐席的任务列表
60
+export function getAlloList(params) {
61
+  return request({
62
+    url: 'callcenterapi/api/autocallouttask/getqrjoinlist',
63
+    method: 'get',
64
+    params
65
+  })
66
+}

+ 8 - 0
CallCenterWeb.UI/src/api/systemSetup/roleSetting/department.js

@@ -42,4 +42,12 @@ export function getTypeDetail(deptid) {
42 42
     }
43 43
   })
44 44
 }
45
+// 获取分类树
46
+export function getDepartmentList() {
47
+  return request({
48
+    url: 'api/deptment/getallloop',
49
+    method: 'get'
50
+  })
51
+}
52
+
45 53
 

+ 7 - 0
CallCenterWeb.UI/src/views/afterSaleManagement/afterSaleList/addOrEdit.vue

@@ -319,6 +319,13 @@ export default {
319 319
     },
320 320
     //删除商品
321 321
     btn_deleteCommodity (val) {
322
+      if (this.commodityTableData.length <= 1) {
323
+        this.$message({
324
+          message: '不能删除所有商品!',
325
+          type: 'warning'
326
+        });
327
+        return
328
+      }
322 329
       let index = this.commodityTableData.indexOf(val)
323 330
       this.commodityTableData.splice(index, 1)
324 331
     },

+ 0 - 5
CallCenterWeb.UI/src/views/afterSaleManagement/afterSaleOrderList/edit.vue

@@ -116,11 +116,6 @@
116 116
           </el-form-item>
117 117
         </el-col>
118 118
         <el-col :span="12">
119
-          <el-form-item label="快递单号" >
120
-            <el-input v-model="ruleForm.F_TrackingNo" placeholder="请输入快递单号"/>
121
-          </el-form-item>
122
-        </el-col>
123
-        <el-col :span="12">
124 119
           <el-form-item label="收件人" >
125 120
             <el-input v-model="ruleForm.F_Addressee" placeholder="请输入收件人"/>
126 121
           </el-form-item>

+ 15 - 0
CallCenterWeb.UI/src/views/afterSaleManagement/afterSaleOrderList/index.vue

@@ -60,6 +60,11 @@
60 60
       <el-table-column prop="F_BelongName" label="归属员工" align="center" />
61 61
       <el-table-column prop="F_Type" label="订单类型" align="center" />
62 62
       <el-table-column prop="F_Express" label="快递公司" align="center" />
63
+      <el-table-column label="物流状态" align="center" >
64
+        <template slot-scope="scope">
65
+          {{ scope.row.F_Status | judgmentStatusName }}
66
+        </template>
67
+      </el-table-column>
63 68
       <el-table-column label="操作" width="240" align="center" class-name="oparate_btn" fixed="right">
64 69
         <template slot-scope="scope">
65 70
           <el-button v-permission="'HY_edit'" type="text" @click="btn_edit(scope.row.F_Id)">编辑</el-button>
@@ -104,6 +109,16 @@ export default {
104 109
       }
105 110
       return statusMap[status]
106 111
     },
112
+    judgmentStatusName(status) {
113
+      const statusMap = {
114
+        '0': '未发出',
115
+        '1': '未签收',
116
+        '2': '签收',
117
+        '3': '改代收',
118
+        '4': '拒收',
119
+      }
120
+      return statusMap[status]
121
+    },
107 122
     judgmentOrderGoods(status) {
108 123
       let orderGoodsNameQuantity = ''
109 124
       for (let i = 0; i < status.length; i++) {

+ 7 - 0
CallCenterWeb.UI/src/views/afterSaleManagement/saleOrderList/afterSale.vue

@@ -117,6 +117,10 @@ export default {
117 117
       type: String,
118 118
       default: ""
119 119
     },
120
+    collectionAfterSalesReasonType: {
121
+      type: String,
122
+      default: ""
123
+    },
120 124
     layerid: {
121 125
       type: String,
122 126
       default: ""
@@ -203,6 +207,9 @@ export default {
203 207
         this.ruleForm.F_OrderId = this.rowid
204 208
         this.getAfterSaleOrderCommodity(this.rowid)
205 209
       }
210
+      if (this.collectionAfterSalesReasonType) {
211
+        this.ruleForm.F_ReturnType = this.collectionAfterSalesReasonType
212
+      }
206 213
     });
207 214
   },
208 215
   methods: {

+ 43 - 1
CallCenterWeb.UI/src/views/afterSaleManagement/saleOrderList/index.vue

@@ -60,9 +60,15 @@
60 60
       <el-table-column prop="F_BelongName" label="归属员工" align="center" />
61 61
       <el-table-column prop="F_Type" label="订单类型" align="center" />
62 62
       <el-table-column prop="F_Express" label="快递公司" align="center" />
63
+      <el-table-column label="物流状态" align="center" >
64
+        <template slot-scope="scope">
65
+          {{ scope.row.F_Status | judgmentStatusName }}
66
+        </template>
67
+      </el-table-column>
63 68
       <el-table-column label="操作" width="240" align="center" class-name="oparate_btn" fixed="right">
64 69
         <template slot-scope="scope">
65
-          <el-button v-permission="'HY_afterSale'" type="text" @click="btn_afterSale(scope.row.F_Id)">售后</el-button>
70
+          <el-button v-permission="'HY_afterSale'" type="text" v-if="authority_afterSale(scope.row.F_Status)" @click="btn_afterSale(scope.row.F_Id)">售后</el-button>
71
+          <el-button v-permission="'HY_collection'" type="text" v-if="authority_collection(scope.row.F_Status)" @click="btn_collection(scope.row.F_Id)">改代收</el-button>
66 72
         </template>
67 73
       </el-table-column>
68 74
     </el-table>
@@ -104,6 +110,16 @@ export default {
104 110
       }
105 111
       return statusMap[status]
106 112
     },
113
+    judgmentStatusName(status) {
114
+      const statusMap = {
115
+        '0': '未发出',
116
+        '1': '未签收',
117
+        '2': '签收',
118
+        '3': '改代收',
119
+        '4': '拒收',
120
+      }
121
+      return statusMap[status]
122
+    },
107 123
     judgmentOrderGoods(status) {
108 124
       let orderGoodsNameQuantity = ''
109 125
       for (let i = 0; i < status.length; i++) {
@@ -196,6 +212,20 @@ export default {
196 212
       this.pageParams.pageindex = 1;
197 213
       this.getList();
198 214
     },
215
+    authority_collection(status) {
216
+      if (status == 1) {
217
+        return true
218
+      } else {
219
+        return false
220
+      }
221
+    },
222
+    authority_afterSale(status) {
223
+      if (status == 2) {
224
+        return true
225
+      } else {
226
+        return false
227
+      }
228
+    },
199 229
     //售后
200 230
     btn_afterSale(afterSalesId) {
201 231
       this.$layer.iframe({
@@ -208,6 +238,18 @@ export default {
208 238
         title: "售后内容"
209 239
       });
210 240
     },
241
+    //改代收
242
+    btn_collection(collectionId) {
243
+      this.$layer.iframe({
244
+        content: {
245
+          content: afterSale, // 传递的组件对象
246
+          parent: this, // 当前的vue对象
247
+          data: { rowid: collectionId, collectionAfterSalesReasonType: '改代收' } // props
248
+        },
249
+        area: ["80%", "80%"],
250
+        title: "改代收"
251
+      });
252
+    },
211 253
     //详情
212 254
     hadndleOrderCode(ordercode){
213 255
       this.$layer.iframe({

+ 15 - 0
CallCenterWeb.UI/src/views/custodianManagement/orderListCustodian/index.vue

@@ -50,6 +50,11 @@
50 50
       <el-table-column prop="F_BelongName" label="归属员工" align="center" />
51 51
       <el-table-column prop="F_Type" label="订单类型" align="center" />
52 52
       <el-table-column prop="F_Express" label="快递公司" align="center" />
53
+      <el-table-column label="物流状态" align="center" >
54
+        <template slot-scope="scope">
55
+          {{ scope.row.F_Status | judgmentStatusName }}
56
+        </template>
57
+      </el-table-column>
53 58
       <el-table-column label="操作" width="240" align="center" class-name="oparate_btn" fixed="right">
54 59
         <template slot-scope="scope">
55 60
           <el-button v-permission="'HY_sorting'" type="text" @click="btn_sorting(scope.row.F_Id)">分拣</el-button>
@@ -95,6 +100,16 @@ export default {
95 100
       }
96 101
       return statusMap[status]
97 102
     },
103
+    judgmentStatusName(status) {
104
+      const statusMap = {
105
+        '0': '未发出',
106
+        '1': '未签收',
107
+        '2': '签收',
108
+        '3': '改代收',
109
+        '4': '拒收',
110
+      }
111
+      return statusMap[status]
112
+    },
98 113
     judgmentOrderGoods(status) {
99 114
       let orderGoodsNameQuantity = ''
100 115
       for (let i = 0; i < status.length; i++) {

+ 41 - 4
CallCenterWeb.UI/src/views/customerServiceManagement/orderListCustomerService/index.vue

@@ -40,10 +40,10 @@
40 40
       <el-tab-pane label="暂存" name="0"></el-tab-pane>
41 41
       <el-tab-pane label="提交" name="1"></el-tab-pane>
42 42
       <el-tab-pane label="退回" name="2"></el-tab-pane>
43
-      <el-tab-pane label="通过" name="3"></el-tab-pane>
43
+      <!-- <el-tab-pane label="通过" name="3"></el-tab-pane>
44 44
       <el-tab-pane label="无货" name="4"></el-tab-pane>
45 45
       <el-tab-pane label="已分拣" name="5"></el-tab-pane>
46
-      <el-tab-pane label="已发货" name="6"></el-tab-pane>
46
+      <el-tab-pane label="已发货" name="6"></el-tab-pane> -->
47 47
     </el-tabs>
48 48
     <el-table v-loading="loading" :data="dataLists" border stripe  @selection-change="handleSelectionChange" row-key="F_Id">
49 49
       <el-table-column type="selection" :reserve-selection="true"></el-table-column>
@@ -70,12 +70,18 @@
70 70
       <el-table-column prop="F_BelongName" label="归属员工" align="center" />
71 71
       <el-table-column prop="F_Type" label="订单类型" align="center" />
72 72
       <el-table-column prop="F_Express" label="快递公司" align="center" />
73
+      <el-table-column label="物流状态" align="center" >
74
+        <template slot-scope="scope">
75
+          {{ scope.row.F_Status | judgmentStatusName }}
76
+        </template>
77
+      </el-table-column>
73 78
       <el-table-column label="操作" width="240" align="center" class-name="oparate_btn" fixed="right">
74 79
         <template slot-scope="scope">
75 80
           <el-button v-permission="'HY_edit'" v-if="authority_edit(scope.row.F_State)" type="text" @click="btn_edit(scope.row.F_Id)">编辑</el-button>
76
-          <el-button v-permission="'HY_goback'" v-if="authority_goback(scope.row.F_State)" type="text" @click="btn_goback(scope.row.F_Id)">退回</el-button>
77
-          <el-button v-permission="'HY_through'" v-if="authority_through(scope.row.F_State)" type="text" @click="btn_through(scope.row.F_Id)">通过</el-button>
81
+          <!-- <el-button v-permission="'HY_goback'" v-if="authority_goback(scope.row.F_State)" type="text" @click="btn_goback(scope.row.F_Id)">退回</el-button>
82
+          <el-button v-permission="'HY_through'" v-if="authority_through(scope.row.F_State)" type="text" @click="btn_through(scope.row.F_Id)">通过</el-button> -->
78 83
           <el-button v-permission="'HY_label'" type="text" @click="btn_label(scope.row.F_Id)">标签</el-button>
84
+          <el-button v-permission="'HY_logistics_status'" v-if="authority_logistics_status(scope.row.F_Status)" type="text" @click="btn_logistics_status(scope.row.F_Id)">物流状态</el-button>
79 85
         </template>
80 86
       </el-table-column>
81 87
     </el-table>
@@ -97,6 +103,7 @@ import { pickerOptions, formatterContent } from "@/utils";
97 103
 import goback from "./goback";
98 104
 import through from "./through";
99 105
 import label from "./label";
106
+import logistics from "./logistics";
100 107
 import edit from "./edit";
101 108
 import merge from './merge';
102 109
 import detail from "@/views/orderManagement/orderList/detail"
@@ -122,6 +129,16 @@ export default {
122 129
       }
123 130
       return statusMap[status]
124 131
     },
132
+    judgmentStatusName(status) {
133
+      const statusMap = {
134
+        '0': '未发出',
135
+        '1': '未签收',
136
+        '2': '签收',
137
+        '3': '改代收',
138
+        '4': '拒收',
139
+      }
140
+      return statusMap[status]
141
+    },
125 142
     judgmentOrderGoods(status) {
126 143
       let orderGoodsNameQuantity = ''
127 144
       for (let i = 0; i < status.length; i++) {
@@ -282,6 +299,18 @@ export default {
282 299
         title: "标签"
283 300
       });
284 301
     },
302
+    //标签订单
303
+    btn_logistics_status(orderid) {
304
+      this.$layer.iframe({
305
+        content: {
306
+          content: logistics, // 传递的组件对象
307
+          parent: this, // 当前的vue对象
308
+          data: { rowid: orderid } // props
309
+        },
310
+        area: ["30%", "30%"],
311
+        title: "物流状态"
312
+      });
313
+    },    
285 314
     //合并
286 315
     btn_merge() {
287 316
       if (this.mergeOrderId.length < 2) {
@@ -348,6 +377,14 @@ export default {
348 377
         return true
349 378
       }
350 379
     },
380
+    //物流状态权限
381
+    authority_logistics_status(status) {
382
+      if (status == 0 || status == 1 ) {
383
+        return false
384
+      } else {
385
+        return true
386
+      }
387
+    }
351 388
   }
352 389
 };
353 390
 </script>

+ 3 - 3
CallCenterWeb.UI/src/views/customerServiceManagement/orderListCustomerService/label.vue

@@ -1,8 +1,8 @@
1 1
 <template>
2 2
   <div>
3 3
     <el-form ref="ruleForm" :model="ruleForm" label-width="80px">
4
-      <el-form-item label="订单类型" prop="tags">
5
-        <el-select v-model="ruleForm.tags" class="form_select" multiple filterable clearable placeholder="请选择订单类型">
4
+      <el-form-item label="标签类型" prop="tags">
5
+        <el-select v-model="ruleForm.tags" class="form_select" multiple filterable clearable placeholder="请选择标签类型">
6 6
           <el-option v-for="item in orderTag" :key="item.F_Value" :label="item.F_Value" :value="item.F_Value"/>
7 7
         </el-select>
8 8
       </el-form-item>
@@ -49,7 +49,7 @@ export default {
49 49
           if (response.state.toLowerCase() === 'success') {
50 50
             this.$parent.$layer.close(this.layerid);
51 51
             this.$parent.getList(); // 重新加载父级数据
52
-            this.$message.success('恭喜你,工单信息审核成功!')
52
+            this.$message.success('恭喜你,操作成功!')
53 53
           }
54 54
         }).catch(() => {
55 55
           this.loading = false

+ 89 - 0
CallCenterWeb.UI/src/views/customerServiceManagement/orderListCustomerService/logistics.vue

@@ -0,0 +1,89 @@
1
+<template>
2
+  <div>
3
+    <el-form ref="ruleForm" :model="ruleForm" label-width="80px">
4
+      <el-form-item label="订单类型" prop="tags">
5
+        <el-select
6
+          v-model="ruleForm.status"
7
+          class="form_select"
8
+          filterable
9
+          clearable
10
+          placeholder="请选择订单类型"
11
+        >
12
+          <el-option
13
+            v-for="item in logisticsStatusList"
14
+            :key="item.id"
15
+            :label="item.text"
16
+            :value="item.id"
17
+          />
18
+        </el-select>
19
+      </el-form-item>
20
+      <el-form-item>
21
+        <el-button type="primary" @click="submitForm()">提交</el-button>
22
+      </el-form-item>
23
+    </el-form>
24
+  </div>
25
+</template>
26
+<script>
27
+import { logisticsStatusOrderCustomerService } from "@/api/customerServiceManagement/orderListCustomerService";
28
+export default {
29
+  props: {
30
+    rowid: {
31
+      type: String,
32
+      default: "",
33
+    },
34
+    layerid: {
35
+      type: String,
36
+      default: "",
37
+    },
38
+  },
39
+  data() {
40
+    return {
41
+      ruleForm: {
42
+        orderids: "", //订单编号
43
+        status: "", //标签内容
44
+      },
45
+      logisticsStatusList: [
46
+        {
47
+          id: 1,
48
+          text: '未签收',
49
+        },{
50
+          id: 2,
51
+          text: '签收',
52
+        },{
53
+          id: 3,
54
+          text: '改代收',
55
+        },{
56
+          id: 4,
57
+          text: '拒收',
58
+        }
59
+      ], //物流状态
60
+    };
61
+  },
62
+  created() {
63
+    if (this.rowid) {
64
+      this.ruleForm.orderids = this.rowid;
65
+    }
66
+  },
67
+  methods: {
68
+    submitForm() {
69
+      // this.ruleForm.status = this.ruleForm.status.join(",");
70
+      logisticsStatusOrderCustomerService(this.ruleForm)
71
+        .then((response) => {
72
+          if (response.state.toLowerCase() === "success") {
73
+            this.$parent.$layer.close(this.layerid);
74
+            this.$parent.getList(); // 重新加载父级数据
75
+            this.$message.success("恭喜你,操作成功!");
76
+          }
77
+        })
78
+        .catch(() => {
79
+          this.loading = false;
80
+        });
81
+    },
82
+  },
83
+};
84
+</script>
85
+<style lang="scss" scoped>
86
+.form_select {
87
+  width: 100%;
88
+}
89
+</style>

+ 0 - 6
CallCenterWeb.UI/src/views/orderManagement/orderList/edit.vue

@@ -116,11 +116,6 @@
116 116
           </el-form-item>
117 117
         </el-col>
118 118
         <el-col :span="12">
119
-          <el-form-item label="快递单号" >
120
-            <el-input v-model="ruleForm.F_TrackingNo" placeholder="请输入快递单号"/>
121
-          </el-form-item>
122
-        </el-col>
123
-        <el-col :span="12">
124 119
           <el-form-item label="收件人" >
125 120
             <el-input v-model="ruleForm.F_Addressee" placeholder="请输入收件人"/>
126 121
           </el-form-item>
@@ -774,7 +769,6 @@ export default {
774 769
     },
775 770
     //删除商品
776 771
     btn_deleteCommodity (val) {
777
-      console.log('val',this.commodityTableData.length)
778 772
       if (this.commodityTableData.length <= 1) {
779 773
         this.$message({
780 774
           message: '不能删除所有商品!',

+ 15 - 0
CallCenterWeb.UI/src/views/orderManagement/orderList/index.vue

@@ -64,6 +64,11 @@
64 64
       <el-table-column prop="F_BelongName" label="归属员工" align="center" />
65 65
       <el-table-column prop="F_Type" label="订单类型" align="center" />
66 66
       <el-table-column prop="F_Express" label="快递公司" align="center" />
67
+      <el-table-column label="物流状态" align="center" >
68
+        <template slot-scope="scope">
69
+          {{ scope.row.F_Status | judgmentStatusName }}
70
+        </template>
71
+      </el-table-column>
67 72
       <el-table-column label="操作" width="240" align="center" class-name="oparate_btn" fixed="right">
68 73
         <template slot-scope="scope">
69 74
           <el-button v-permission="'HY_pay_money'" v-if="authority_pay_money(scope.row.F_PayState)" type="text" @click="btn_pay_money(scope.row.F_Id)">支付</el-button>
@@ -117,6 +122,16 @@ export default {
117 122
       }
118 123
       return statusMap[status]
119 124
     },
125
+    judgmentStatusName(status) {
126
+      const statusMap = {
127
+        '0': '未发出',
128
+        '1': '未签收',
129
+        '2': '签收',
130
+        '3': '改代收',
131
+        '4': '拒收',
132
+      }
133
+      return statusMap[status]
134
+    },
120 135
     judgmentOrderGoods(status) {
121 136
       let orderGoodsNameQuantity = ''
122 137
       for (let i = 0; i < status.length; i++) {

+ 358 - 0
CallCenterWeb.UI/src/views/outbound/allot/components/outboundAllot.vue

@@ -0,0 +1,358 @@
1
+<template>
2
+  <div v-loading="loading" class="outboundAllot">
3
+    <el-row :gutter="10">
4
+      <el-col :md="2" class="filter-item">
5
+        <el-checkbox
6
+          :class="{isChecked_all: checkAll, checked_all:true}"
7
+          :indeterminate="isIndeterminate"
8
+          v-model="checkAll"
9
+          @change="checkAllChange">
10
+          {{ checkAll === true ? '已全选' : '全选' }}
11
+        </el-checkbox>
12
+      </el-col>
13
+      <el-col :md="18" class="filter-item">
14
+        <el-input v-model="keyword" placeholder="请输入坐席工号或坐席姓名"/>
15
+      </el-col>
16
+      <el-col :md="3" class="filter-item">
17
+        <el-button type="primary" icon="el-icon-search" @click="btn_search">搜索</el-button>
18
+      </el-col>
19
+
20
+      <el-col :md="24" class="tags_area">
21
+        <el-tag
22
+          v-for="tag in seatListsTags"
23
+          :key="tag"
24
+          :disable-transitions="false"
25
+          class="tags"
26
+          size="medium"
27
+          closable
28
+          @close="closeTag(tag)">
29
+          {{ tag }}
30
+        </el-tag>
31
+      </el-col>
32
+      <el-col :md="24" class="clearfix">
33
+        <el-checkbox-group v-model="seatListsTags" @change="seatListsCheckedChange">
34
+          <el-col v-for="item in seatLists" :md="6" :key="item.id" class="seat_lists">
35
+            <el-card :body-style="{ padding: '0px' }" shadow="always">
36
+              <div class="clearfix">
37
+                <el-col :lg="10" class="left_item" style="padding: 0;">
38
+                  <div class="seat_choice">
39
+                    <img :src="!item.head_small_img ? '/static/img/user.png' : item.head_small_img" class="seat_img" alt="坐席头像" >
40
+                    <p>
41
+                      <el-checkbox
42
+                        :label="item.usercode + '-' + item.username"
43
+                        :key="item.usercode + '-' + item.username"
44
+                        class="seat_check">
45
+                        {{ item.isChecked === true ? '已选择' : '选择' }}
46
+                      </el-checkbox>
47
+                    </p>
48
+                  </div>
49
+                </el-col>
50
+                <el-col :lg="14" class="right_item" style="padding: 0;">
51
+                  <ul class="seat_con">
52
+                    <li>{{ item.usercode }}</li>
53
+                    <li>{{ item.username }}</li>
54
+                    <li>{{ groupFilter(item.group) }}</li>
55
+                    <li class="noborder">{{ roleFilter(item.role_id) }}</li>
56
+                  </ul>
57
+                </el-col>
58
+              </div>
59
+            </el-card>
60
+          </el-col>
61
+        </el-checkbox-group>
62
+      </el-col>
63
+      <el-col :md="24" class="allot_btn">
64
+        <el-button type="primary" @click="submitList">分配</el-button>
65
+      </el-col>
66
+    </el-row>
67
+  </div>
68
+</template>
69
+
70
+<script>
71
+import { getSeatLists } from '@/api/telCall/seatMonitor'
72
+import { fpdata } from '@/api/outbound/allot'
73
+import { getSeatGroup, getRoleSelect } from '@/api/commonAPI'
74
+import { mapGetters } from 'vuex'
75
+
76
+export default {
77
+  name: 'OutboundAllot',
78
+  props: {
79
+    rowid: {
80
+      type: String,
81
+      default: ''
82
+    },
83
+    layerid: {
84
+      type: String,
85
+      default: ''
86
+    }
87
+  },
88
+  data() {
89
+    return {
90
+      seatGroups: [], // 坐席组数据
91
+      seatRoles: [], // 坐席角色数据
92
+      checkAll: true,
93
+      isIndeterminate: false, // 全选获取全不选是false(其他状态是true)
94
+      loading: false,
95
+      keyword: '',
96
+      seatLists: [], // 坐席数据
97
+      seatListsTags: [] // 坐席标签数据,选中坐席的数据
98
+    }
99
+  },
100
+  computed: {
101
+    groupFilter() {
102
+      return function(id) {
103
+        for (let i = 0; i < this.seatGroups.length; i++) {
104
+          if (this.seatGroups[i].id === id) {
105
+            return this.seatGroups[i].name
106
+          }
107
+        }
108
+      }
109
+    },
110
+    roleFilter() {
111
+      return function(id) {
112
+        for (let i = 0; i < this.seatRoles.length; i++) {
113
+          if (this.seatRoles[i].id === id) {
114
+            return this.seatRoles[i].name
115
+          }
116
+        }
117
+      }
118
+    }
119
+  },
120
+  created() {
121
+    if (this.rowid) {
122
+      Promise.all([this.getSeatGroupList(), this.getRoles()])
123
+        .then(() => {
124
+          this.getSeatList()
125
+        })
126
+      document.onkeyup = (e) => {
127
+        if (e.keyCode === 13) {
128
+          this.getSeatList()
129
+        }
130
+      }
131
+    }
132
+  },
133
+  methods: {
134
+    submitList() {
135
+      this.loading = true
136
+      const arruser = this.seatListsTags.map((v, i) => {
137
+        return v.split('-')[0]
138
+      })
139
+      const datas = {
140
+        taskid: this.rowid, //	是	string	任务id
141
+        arruser: arruser //	否	string[]	分配坐席
142
+      }
143
+      fpdata(datas).then(response => {
144
+        this.loading = false
145
+        if (response.state.toLowerCase() === 'success') {
146
+          this.$parent.$layer.close(this.layerid)
147
+          this.$parent.getList() // 重新加载父级数据
148
+          this.$message.success('恭喜你,分配成功!')
149
+        }
150
+      }).catch(() => {
151
+        this.loading = false
152
+      })
153
+    },
154
+    // 获取坐席列表
155
+    getSeatList() {
156
+      const params = {
157
+        key: this.keyword.trim() // 否	string	模糊查询,坐席工号或坐席名字
158
+      }
159
+      getSeatLists(params).then(response => {
160
+        if (response.state.toLowerCase() === 'success') {
161
+          this.seatLists = response.data
162
+          this.seatLists.forEach((v, i) => {
163
+            v.isChecked = true
164
+          })
165
+          this.checkAllChange(true)
166
+        }
167
+      })
168
+    },
169
+    btn_search() {
170
+      this.getSeatList()
171
+    },
172
+    checkAllChange(val) {
173
+      const checkedSeats = []
174
+      if (val) {
175
+        this.seatLists.forEach((v, i) => {
176
+          checkedSeats.push(v.usercode + '-' + v.username)
177
+          v.isChecked = true
178
+        })
179
+      } else {
180
+        this.seatLists.forEach((v, i) => {
181
+          v.isChecked = false
182
+        })
183
+      }
184
+      this.seatListsTags = val ? checkedSeats : []
185
+      this.isIndeterminate = false
186
+    },
187
+    seatListsCheckedChange(value) {
188
+      const checkedCount = value.length
189
+      this.seatListsTags = value
190
+      // 切换选中状态
191
+      this.updateChecked(value)
192
+      this.checkAll = checkedCount === this.seatLists.length
193
+      this.isIndeterminate = checkedCount > 0 && checkedCount < this.seatLists.length
194
+    },
195
+    closeTag(tag) {
196
+      this.seatListsTags.splice(this.seatListsTags.indexOf(tag), 1)
197
+      this.checkAll = false
198
+      this.isIndeterminate = this.seatListsTags.length !== 0
199
+      this.updateChecked(tag)
200
+    },
201
+    // 切换选中状态
202
+    updateChecked(value) {
203
+      this.seatLists.forEach((v, i) => {
204
+        this.$forceUpdate()// 迫使 Vue 实例重新渲染。注意它仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件。
205
+        this.$set(v, 'isChecked', false)
206
+        for (let j = 0, len = value.length; j < len; j++) {
207
+          if (value[j].split('-')[0] === v.usercode) {
208
+            this.$set(v, 'isChecked', true)
209
+            return
210
+          }
211
+        }
212
+      })
213
+    },
214
+    // 获取坐席组数据
215
+    getSeatGroupList() {
216
+      return new Promise(resolve => {
217
+        getSeatGroup().then(response => {
218
+          if (response.state.toLowerCase() === 'success') {
219
+            const res = response.data
220
+            if (res && res.length > 0) {
221
+              for (let i = 0; i < res.length; i++) {
222
+                this.seatGroups.push({
223
+                  id: res[i].id,
224
+                  name: res[i].zxzname
225
+                })
226
+              }
227
+            }
228
+          }
229
+        })
230
+        resolve()
231
+      })
232
+    },
233
+    // 获取角色数据
234
+    getRoles() {
235
+      return new Promise(resolve => {
236
+        getRoleSelect().then(response => {
237
+          if (response.state.toLowerCase() === 'success') {
238
+            const res = response.data
239
+            if (res && res.length > 0) {
240
+              for (let i = 0; i < res.length; i++) {
241
+                this.seatRoles.push({
242
+                  id: res[i].id,
243
+                  name: res[i].role_name
244
+                })
245
+              }
246
+            }
247
+          }
248
+        })
249
+        resolve()
250
+      })
251
+    }
252
+  }
253
+}
254
+</script>
255
+
256
+<style rel="stylesheet/scss" lang="scss">
257
+	.outboundAllot{
258
+		.isChecked_all{
259
+			.el-checkbox__input.is-checked+.el-checkbox__label{
260
+				color: #f56c6c;
261
+			}
262
+			.el-checkbox__input.is-checked .el-checkbox__inner{
263
+				background-color: transparent;
264
+				border-color: #f56c6c;
265
+			}
266
+			.el-checkbox__inner::after{
267
+				border-color: #f56c6c;
268
+			}
269
+		}
270
+
271
+		.seat_check{
272
+			.el-checkbox__inner:hover{
273
+				border-color: #dcdfe6;
274
+			}
275
+			.el-checkbox__input.is-checked+.el-checkbox__label{
276
+				color: #fff;
277
+			}
278
+			.el-checkbox__input .el-checkbox__inner{
279
+				background-color: #409eff;
280
+				border-color: #fff;
281
+			}
282
+			.el-checkbox__input.is-checked .el-checkbox__inner{
283
+				background-color: #f56c6c;
284
+				border-color: #fff;
285
+			}
286
+		}
287
+	}
288
+</style>
289
+<style rel="stylesheet/scss" lang="scss" scoped>
290
+	.outboundAllot{
291
+		.filter-item{
292
+			line-height: 32px;
293
+			overflow: hidden;
294
+			margin-bottom: 15px;
295
+			.checked_all{
296
+				margin-left: 20px;
297
+			}
298
+		}
299
+		.tags_area{
300
+			margin: 0 5px 15px 5px;
301
+		}
302
+		.tags{
303
+			margin: 0 10px 5px 0;
304
+		}
305
+		.seat_lists{
306
+			margin-bottom: 5px;
307
+			.left_item{
308
+				border-right: 1px solid #ebeef5;
309
+				height: 157px;
310
+				.seat_choice{
311
+					text-align: center;
312
+					.seat_img{
313
+						width: 70px;
314
+						height: 70px;
315
+						margin: 18px auto;
316
+						border-radius: 2px;
317
+					}
318
+					.seat_check{
319
+						border-radius: 2px;
320
+						color: #fff;
321
+						padding: 5px 15px!important;
322
+						background-color: #409eff;
323
+					}
324
+					.seat_check.is-checked{
325
+						background-color: #f56c6c;
326
+					}
327
+				}
328
+			}
329
+
330
+			.right_item{
331
+				.seat_con{
332
+					list-style: none;
333
+					margin: 0;
334
+					padding: 0;
335
+					li{
336
+						color: #333333;
337
+						font-size: 14px;
338
+						line-height: 38px;
339
+						border-bottom: 1px solid #ebeef5;
340
+						text-align: center;
341
+					}
342
+					.noborder{
343
+						border: none;
344
+					}
345
+				}
346
+
347
+			}
348
+
349
+		}
350
+		.allot_btn{
351
+			text-align: center;
352
+			margin: 20px auto;
353
+			.el-button{
354
+				width: 200px;
355
+			}
356
+		}
357
+	}
358
+</style>

+ 285 - 0
CallCenterWeb.UI/src/views/outbound/allot/components/tabAllot.vue

@@ -0,0 +1,285 @@
1
+/* eslint-disable vue/require-valid-default-prop */
2
+<template>
3
+  <div class="tab_allot">
4
+    <el-table
5
+      v-loading="loading"
6
+      :data="dataLists"
7
+      :row-key="getRowKeys"
8
+      :expand-row-keys="expands"
9
+      border
10
+      stripe
11
+      highlight-current-row
12
+      @current-change="toggleRowExpansion"
13
+      @row-click="handleTableClick">
14
+      <el-table-column type="expand" align="center" width="1" fixed="left">
15
+        <template slot-scope="props">
16
+          <el-row :gutter="15">
17
+            <el-col v-show="seatLists.length === 0" :md="24" style="text-align: center;">还没有分配坐席。。。</el-col>
18
+            <el-col v-for="item in seatLists" v-show="seatLists.length > 0" :md="6" :key="item.id" class="seat_lists">
19
+              <el-card :body-style="{ padding: '15px' }" shadow="always">
20
+                <ul class="seat_content clearfix">
21
+                  <li>参与坐席:{{ item.usercode }}</li>
22
+                  <li>分配者:{{ item.createusercode }}</li>
23
+                  <li style="width:100%">分配时间:{{ item.createtime }}</li>
24
+                </ul>
25
+              </el-card>
26
+            </el-col>
27
+          </el-row>
28
+        </template>
29
+      </el-table-column>
30
+      <el-table-column type="index" label="编号" align="center" fixed width="80"/>
31
+      <el-table-column label="状态" width="100" align="center">
32
+        <template slot-scope="scope">
33
+          <el-tag :type="scope.row.isstart | isstartTypeFilter" size="mini" disable-transitions>
34
+            {{ scope.row.isstart | isstartTextFilter }}
35
+          </el-tag>
36
+        </template>
37
+      </el-table-column>
38
+      <el-table-column label="上架状态" width="90" align="center">
39
+        <template slot-scope="scope">
40
+          <el-tag :type="scope.row.isonline | isonlineTypeFilter" size="mini" disable-transitions>
41
+            {{ scope.row.isonline | isonlineTextFilter }}
42
+          </el-tag>
43
+        </template>
44
+      </el-table-column>
45
+      <el-table-column prop="taskname" label="计划名称" align="center" min-width=""/>
46
+      <el-table-column prop="taskremark" label="说明" align="center" min-width=""/>
47
+      <el-table-column prop="starttime" label="计划开始时间" align="center" min-width=""/>
48
+      <el-table-column prop="endtime" label="计划结束时间" align="center" min-width=""/>
49
+      <el-table-column label="操作" width="160" align="center" class-name="oparate_btn" fixed="right">
50
+        <template slot-scope="scope">
51
+          <el-button v-permission="'HY_allot'" size="mini" plain type="primary" @click.stop="btn_allot(scope.row.id)">分配</el-button>
52
+        </template>
53
+      </el-table-column>
54
+    </el-table>
55
+    <pagination
56
+      v-show="pageParams.total > 0"
57
+      :total="pageParams.total"
58
+      :pageindex.sync="pageParams.pageindex"
59
+      :pagesize.sync="pageParams.pagesize"
60
+      class="pagination"
61
+      @pagination="getList" />
62
+
63
+  </div>
64
+</template>
65
+
66
+<script>
67
+import {
68
+  getPlanLists
69
+} from '@/api/outbound/plan'
70
+// import { getfplist } from '@/api/outbound/allot'
71
+import outboundAllot from './outboundAllot'
72
+import Pagination from '@/components/Pagination' // 对el-pagination 二次封装
73
+import { mapGetters } from 'vuex'
74
+import store from '@/store'
75
+
76
+export default {
77
+  name: 'TabAllot',
78
+  components: {
79
+    Pagination
80
+  },
81
+  filters: {
82
+    isstartTextFilter(status) {
83
+      const statusMap = {
84
+        0: '未启动',
85
+        1: '已启动',
86
+        2: '暂停',
87
+        3: '处理完成',
88
+        4: '撤销',
89
+        5: '完成'
90
+      }
91
+      return statusMap[status]
92
+    },
93
+    isstartTypeFilter(status) {
94
+      const statusMap = {
95
+        0: 'info',
96
+        1: '',
97
+        2: 'warning',
98
+        3: 'success',
99
+        4: 'danger',
100
+        5: 'success'
101
+      }
102
+      return statusMap[status]
103
+    },
104
+    isonlineTextFilter(status) {
105
+      const statusMap = {
106
+        0: '已下架',
107
+        1: '已上架'
108
+      }
109
+      return statusMap[status]
110
+    },
111
+    isonlineTypeFilter(status) {
112
+      const statusMap = {
113
+        0: 'danger',
114
+        1: 'success'
115
+      }
116
+      return statusMap[status]
117
+    }
118
+  },
119
+  props: {
120
+    searchDatas: {
121
+      type: Object,
122
+      default: function() { return {} }
123
+    }
124
+  },
125
+  data() {
126
+    return {
127
+      loading: false,
128
+      pageParams: {
129
+        pageindex: 1, // 当前第几页
130
+        pagesize: Number(this.$store.getters.serverConfig.PAGESIZE), // 每页几条数据
131
+        total: 0 // 总共多少数据
132
+      },
133
+      // 获取row的key值
134
+      getRowKeys(row) {
135
+        return row.id
136
+      },
137
+      // 要展开的行,数值的元素是row的key值
138
+      expands: [],
139
+      dataLists: [], // 列表数据
140
+      seatLists: []
141
+    }
142
+  },
143
+  computed: {
144
+    ...mapGetters([
145
+      'telTaskIsRefresh' // 是否刷新右上角外呼任务信息/自动外呼监控/外呼分配/我的呼叫任务
146
+    ])
147
+  },
148
+  watch: {
149
+    telTaskIsRefresh: function(newT, oldT) {
150
+      if (newT === true) {
151
+        this.getList()
152
+      }
153
+    }
154
+  },
155
+  created() {
156
+    this.getList()
157
+  },
158
+  methods: {
159
+
160
+    getList() {
161
+      this.loading = true
162
+      return new Promise(resolve => {
163
+        const params = {
164
+          pageindex: this.pageParams.pageindex, // 第几页
165
+          pagesize: this.pageParams.pagesize, // 每页几条信息
166
+          key: this.searchDatas.keyword.replace(/\s+/g, ""), //	否	string	任务名称,可模糊查询
167
+          taskstate: this.searchDatas.sc_state, //	否	int	任务状态 (不传值时查询所有状态)
168
+          stime: this.searchDatas.searchDate && this.searchDatas.searchDate[0], //	否	string	开始时间
169
+          etime: this.searchDatas.searchDate && this.searchDatas.searchDate[1], //	否	string	结束时间
170
+          isallot: this.searchDatas.isallot //	否	int	分配状态 (不传值时查询所有状态)
171
+        }
172
+        getPlanLists(params).then(response => {
173
+          this.loading = false
174
+          store.dispatch('ChangeTaskInfo', false)
175
+          if (response.state.toLowerCase() === 'success') {
176
+            switch (this.searchDatas.isallot) {
177
+              case '':
178
+                this.pageParams.total = response.totalcount
179
+                break
180
+              case 0:
181
+                this.pageParams.total = response.wfpcount
182
+                break
183
+              case 1:
184
+                this.pageParams.total = response.fpcount
185
+                break
186
+              default:
187
+                break
188
+            }
189
+            this.dataLists = response.rows
190
+            console.log(this.dataLists)
191
+            if (response.total >= 100) {
192
+              response.total = '99+'
193
+            }
194
+            if (response.wfpcount >= 100) {
195
+              response.wfpcount = '99+'
196
+            }
197
+            if (response.fpcount >= 100) {
198
+              response.fpcount = '99+'
199
+            }
200
+            // 修改父组件的值
201
+            this.$emit('getTotalNums', {
202
+              totalcount: response.totalcount, // 全部
203
+              wfpcount: response.wfpcount, // 待分配
204
+              fpcount: response.fpcount // 已分配
205
+            })
206
+          }
207
+        })
208
+        resolve()
209
+      })
210
+    },
211
+
212
+    toggleRowExpansion(row) {
213
+      this.expands = []
214
+      this.expands.push(row && row.id)
215
+    },
216
+
217
+    // 点击某一行的table
218
+    handleTableClick(row, event, column) {
219
+      this.getSeatLists(row.id)
220
+    },
221
+
222
+    // 获取参与坐席
223
+    getSeatLists(tid) {
224
+      return new Promise(resolve => {
225
+        getfplist(tid).then(response => {
226
+          if (response.state.toLowerCase() === 'success') {
227
+            response = response.data
228
+            if (response && response.length > 0) {
229
+              this.seatLists = []
230
+              this.seatLists = response
231
+            } else {
232
+              this.seatLists = []
233
+            }
234
+          }
235
+        })
236
+        resolve()
237
+      })
238
+    },
239
+
240
+    // 分配
241
+    btn_allot(rid) {
242
+      this.$layer.iframe({
243
+        content: {
244
+          content: outboundAllot, // 传递的组件对象
245
+          parent: this, // 当前的vue对象
246
+          data: {
247
+            'rowid': rid
248
+          } // props
249
+        },
250
+        area: ['80%', '90%'],
251
+        title: '外呼计划分配'
252
+      })
253
+    }
254
+
255
+  }
256
+}
257
+</script>
258
+
259
+<style rel="stylesheet/scss" lang="scss" scoped>
260
+	.tab_allot {
261
+		.list_wait {
262
+			color: #febd23;
263
+		}
264
+
265
+		.list_done {
266
+			color: #5ccb91;
267
+		}
268
+
269
+		.seat_lists {
270
+			margin-bottom: 10px;
271
+		}
272
+
273
+		.seat_content {
274
+			list-style: none;
275
+			margin: 0;
276
+			padding: 0;
277
+
278
+			li {
279
+				float: left;
280
+				width: 50%;
281
+				margin-bottom: 4px;
282
+			}
283
+		}
284
+	}
285
+</style>

+ 222 - 0
CallCenterWeb.UI/src/views/outbound/allot/index.vue

@@ -0,0 +1,222 @@
1
+<template>
2
+  <div class="app-container allot">
3
+    <div class="filter-container">
4
+      <el-date-picker
5
+        v-model="searchDatas.searchDate"
6
+        :picker-options="pickerOptions"
7
+        class="filter-item"
8
+        type="daterange"
9
+        format="yyyy年MM月dd日"
10
+        value-format="yyyy-MM-dd"
11
+        align="left"
12
+        unlink-panels
13
+        range-separator="至"
14
+        start-placeholder="开始日期"
15
+        end-placeholder="结束日期"/>
16
+      <el-select v-model="searchDatas.sc_state" class="filter-item" filterable clearable placeholder="请选择任务状态">
17
+        <el-option v-for="item in stateOptions" :key="item.id" :label="item.name" :value="item.id"/>
18
+      </el-select>
19
+      <el-input v-model="searchDatas.keyword" placeholder="请输入计划名称" class="filter-item"/>
20
+      <el-button type="primary" class="filter-item" icon="el-icon-search" @click="btn_search">搜索</el-button>
21
+    </div>
22
+
23
+    <el-tabs v-model="activeName" @tab-click="handleClick" v-if="flag">
24
+      <el-tab-pane v-for="item in tabMapOptions" :key="item.key" :name="item.key">
25
+        <span slot="label">{{ item.label }}<span :class="item.listclass">({{ item.num }})</span></span>
26
+        <tabAllot v-if="activeName===item.key" ref="tabtask" :search-datas="searchDatas" @getTotalNums="getTotalNum"/>
27
+      </el-tab-pane>
28
+    </el-tabs>
29
+
30
+  </div>
31
+</template>
32
+
33
+<script>
34
+import {
35
+  pickerOptions
36
+} from '@/utils'
37
+import tabAllot from './components/tabAllot'
38
+import {
39
+  getPlanLists
40
+} from '@/api/outbound/plan'
41
+export default {
42
+  name: 'Allot',
43
+  components: {
44
+    tabAllot
45
+  },
46
+  data() {
47
+    return {
48
+      pickerOptions, // 日期数据
49
+      stateOptions: [{
50
+        'id': '0',
51
+        'name': '未启动'
52
+      },
53
+      {
54
+        'id': '1',
55
+        'name': '已启动'
56
+      },
57
+      {
58
+        'id': '2',
59
+        'name': '暂停'
60
+      },
61
+      {
62
+        'id': '3',
63
+        'name': '处理完成'
64
+      },
65
+      {
66
+        'id': '4',
67
+        'name': '撤销'
68
+      },
69
+      {
70
+        'id': '5',
71
+        'name': '完成'
72
+      }
73
+      ], // 任务状态数据
74
+      searchDatas: {
75
+        searchDate: '', // 日期
76
+        sc_state: '', // 任务状态
77
+        keyword: '', // 计划名称
78
+        isallot: ''
79
+      },
80
+      pageParams: {
81
+        pageindex: 1, // 当前第几页
82
+        pagesize: Number(this.$store.getters.serverConfig.PAGESIZE), // 每页几条数据
83
+        total: 0 // 总共多少数据
84
+      },
85
+      flag:false,//表头数据展示
86
+      activeName: 'first',
87
+      tabMapOptions: [{
88
+        label: '全部',
89
+        key: 'first',
90
+        num: 0,
91
+        listclass: 'list_all'
92
+      },
93
+      {
94
+        label: '待分配',
95
+        key: 'second',
96
+        num: 0,
97
+        listclass: 'list_wait'
98
+      },
99
+      {
100
+        label: '已分配',
101
+        key: 'third',
102
+        num: 0,
103
+        listclass: 'list_done'
104
+      }
105
+      ]
106
+    }
107
+  },
108
+  created() {
109
+    this.getCurrentList()
110
+  },
111
+  mounted() {
112
+    document.onkeyup = (e) => {
113
+      if (e.keyCode === 13) {
114
+        this.$refs.tabtask[0].getList()
115
+      }
116
+    }
117
+  },
118
+
119
+  methods: {
120
+    handleClick(tab, event) {
121
+      switch (tab.name) {
122
+        case 'first':
123
+          this.searchDatas.isallot = ''
124
+          break
125
+        case 'second':
126
+          this.searchDatas.isallot = 0
127
+          break
128
+        case 'third':
129
+          this.searchDatas.isallot = 1
130
+          break
131
+        default:
132
+          break
133
+      }
134
+    },
135
+    btn_search() {
136
+      this.$refs.tabtask[0].pageParams.pageindex = 1
137
+      this.$refs.tabtask[0].getList()
138
+    },
139
+
140
+    // 从子组件获取的 数量值
141
+    getTotalNum(value) {
142
+      this.tabMapOptions[0].num = value.totalcount // 全部
143
+      this.tabMapOptions[1].num = value.wfpcount // 待分配
144
+      this.tabMapOptions[2].num = value.fpcount // 已分配
145
+    },
146
+    getCurrentList() {
147
+      return new Promise(resolve => {
148
+        const params = {
149
+          pageindex: this.pageParams.pageindex, // 第几页
150
+          pagesize: this.pageParams.pagesize, // 每页几条信息
151
+          key: this.searchDatas.keyword.replace(/\s+/g, ""), //	否	string	任务名称,可模糊查询
152
+          taskstate: this.searchDatas.sc_state, //	否	int	任务状态 (不传值时查询所有状态)
153
+          stime: this.searchDatas.searchDate && this.searchDatas.searchDate[0], //	否	string	开始时间
154
+          etime: this.searchDatas.searchDate && this.searchDatas.searchDate[1], //	否	string	结束时间
155
+          isallot: this.searchDatas.isallot //	否	int	分配状态 (不传值时查询所有状态)
156
+        }
157
+        getPlanLists(params).then(response => {
158
+          if (response.state.toLowerCase() === 'success') {
159
+            switch (this.searchDatas.isallot) {
160
+              case '':
161
+                this.pageParams.total = response.totalcount
162
+                break
163
+              case 0:
164
+                this.pageParams.total = response.wfpcount
165
+                break
166
+              case 1:
167
+                this.pageParams.total = response.fpcount
168
+                break
169
+              default:
170
+                break
171
+            }
172
+            console.log(this.dataLists)
173
+            if (response.total >= 100) {
174
+              response.total = '99+'
175
+            }
176
+            if (response.wfpcount >= 100) {
177
+              response.wfpcount = '99+'
178
+            }
179
+            if (response.fpcount >= 100) {
180
+              response.fpcount = '99+'
181
+            }
182
+            this.tabMapOptions[0].num = response.totalcount // 全部
183
+            this.tabMapOptions[1].num = response.wfpcount // 待分配
184
+            this.tabMapOptions[2].num = response.fpcount // 已分配
185
+            this.flag = true
186
+          }
187
+        })
188
+        resolve()
189
+      })
190
+    },
191
+  }
192
+}
193
+</script>
194
+
195
+<style rel="stylesheet/scss" lang="scss">
196
+	.allot {
197
+		.el-table__expand-icon {
198
+			display: none !important;
199
+		}
200
+
201
+		.el-table tr {
202
+			cursor: pointer;
203
+		}
204
+
205
+		.el-table__body tr.current-row>td {
206
+			background: rgba(185, 221, 249, .75);
207
+		}
208
+	}
209
+</style>
210
+<style rel="stylesheet/scss" lang="scss" scoped>
211
+	.allot {
212
+		.list_all {}
213
+
214
+		.list_wait {
215
+			color: #febd23;
216
+		}
217
+
218
+		.list_done {
219
+			color: #5ccb91;
220
+		}
221
+	}
222
+</style>

+ 234 - 0
CallCenterWeb.UI/src/views/outbound/callResult/detail.vue

@@ -0,0 +1,234 @@
1
+<template>
2
+  <div v-loading="loading" class="detailPager">
3
+    <h1 class="pager_title">{{ title }}</h1>
4
+    <p class="remark">
5
+      <el-row :gutter="20">
6
+        <el-col :lg="8">
7
+          <span v-if="fullname">姓名: {{ fullname }}</span>
8
+        </el-col>
9
+        <el-col :lg="8">
10
+          <span v-if="mobile">电话: {{ mobile }}</span>
11
+        </el-col>
12
+        <el-col :lg="8">
13
+          <span v-if="address">地址: {{ address }}</span>
14
+        </el-col>
15
+      </el-row>
16
+    </p>
17
+    <p v-if="remark" class="remark">
18
+      {{ remark }}
19
+    </p>
20
+    <div v-for="item in pagerLists" :key="item.queguid" class="question">
21
+      <div class="title">
22
+        <!-- <b class="sign" v-if="item.isRequire">*</b> -->
23
+        <span class="sort">{{ item.sort + 1 }}</span>
24
+        <b class="option_title">{{ item.quetitle }}</b>
25
+      </div>
26
+      <div class="queOpion">
27
+        <template v-if="item.type === 1">
28
+          <p>{{ item.remark }}</p>
29
+        </template>
30
+        <template v-else-if="item.type === 2">
31
+          <el-radio-group v-model="item.ischeckid">
32
+            <el-radio v-for="optR in item.itemList" :key="optR.itemid" :label="optR.itemid" disabled>
33
+              {{ optR.name }}
34
+            </el-radio>
35
+          </el-radio-group>
36
+        </template>
37
+        <template v-else>
38
+          <el-checkbox-group v-model="item.ischeckid">
39
+            <el-checkbox v-for="optC in item.itemList" :key="optC.itemid" :label="optC.itemid" disabled>
40
+              {{ optC.name }}
41
+            </el-checkbox>
42
+          </el-checkbox-group>
43
+        </template>
44
+      </div>
45
+    </div>
46
+  </div>
47
+</template>
48
+
49
+<script>
50
+import { getAutoPager } from '@/api/outbound/callResult'
51
+
52
+export default {
53
+  name: 'Detail',
54
+  props: {
55
+    rowid: {
56
+      type: String,
57
+      default: ''
58
+    },
59
+    layerid: {
60
+      type: String,
61
+      default: ''
62
+    }
63
+  },
64
+  data() {
65
+    return {
66
+      loading: false,
67
+      fullname: '',
68
+      mobile: '',
69
+      address: '',
70
+      title: '', // 问卷标题
71
+      remark: '', // 问卷简述
72
+      pagerLists: [] // 问卷试题数据
73
+    }
74
+  },
75
+  created() {
76
+    if (this.rowid) {
77
+      this.getDetail()
78
+    }
79
+  },
80
+  methods: {
81
+    getDetail() {
82
+      this.loading = true
83
+      getAutoPager(this.rowid).then(response => {
84
+        this.loading = false
85
+        if (response.state.toLowerCase() === 'success') {
86
+          this.fullname = response.data.fullname
87
+          this.mobile = response.data.mobile
88
+          this.address = response.data.address
89
+          this.title = response.data.pagetitle
90
+          this.remark = response.data.pagecontent
91
+          this.pagerLists = this.changePagerOptions(response.data.result)
92
+        }
93
+      })
94
+    },
95
+
96
+    // 修改获取的试题数据
97
+    changePagerOptions(arr) {
98
+      const tem = []
99
+      arr.forEach((v, i) => {
100
+        const itemTem = []
101
+        let ischeckid = null
102
+        const ischeckids = []
103
+        if (v.itemList.length > 0) {
104
+          v.itemList.forEach((k, i) => {
105
+            itemTem.push({
106
+              'itemid': k.itemid, // 选项id
107
+              'name': k.name
108
+            })
109
+            if (v.type === 2) {
110
+              if (k.ischeck === 1) {
111
+                ischeckid = k.itemid
112
+              }
113
+            }
114
+            if (v.type === 3) {
115
+              if (k.ischeck === 1) {
116
+                ischeckids.push(k.itemid)
117
+              }
118
+              ischeckid = ischeckids
119
+            }
120
+          })
121
+        }
122
+        tem.push({
123
+          'queguid': v.queid,
124
+          'quetitle': v.quetitle,
125
+          'ischeckid': ischeckid,
126
+          'type': v.type,
127
+          'sort': v.sort,
128
+          'remark': v.remark,
129
+          'itemList': itemTem
130
+        })
131
+      })
132
+      return tem
133
+    }
134
+
135
+  }
136
+
137
+}
138
+</script>
139
+
140
+<style rel="stylesheet/scss" lang="scss">
141
+	.detailPager{
142
+		.el-radio__input.is-disabled+span.el-radio__label,
143
+		.el-checkbox__input.is-disabled+span.el-checkbox__label{
144
+			color: #333333;
145
+		}
146
+
147
+		.el-radio__input.is-checked+span.el-radio__label,
148
+		.el-checkbox__input.is-checked+span.el-checkbox__label{
149
+			color: #f56c6c;
150
+		}
151
+
152
+		.el-radio__input.is-disabled.is-checked .el-radio__inner,
153
+		.el-checkbox__input.is-disabled.is-checked .el-checkbox__inner{
154
+			border-color: #f56c6c;
155
+			background-color: transparent;
156
+		}
157
+
158
+		.el-radio__input.is-disabled.is-checked .el-radio__inner::after {
159
+			background-color: #f56c6c;
160
+		}
161
+		.el-checkbox__input.is-disabled.is-checked .el-checkbox__inner::after{
162
+			border-color: #f56c6c;
163
+		}
164
+
165
+	}
166
+</style>
167
+
168
+<style rel="stylesheet/scss" lang="scss" scoped>
169
+	.detailPager{
170
+		.pager_title{
171
+			text-align: center;
172
+			font-size: 24px;
173
+			color: #333333;
174
+		}
175
+		.remark{
176
+			font-size: 16px;
177
+			text-align: justify;
178
+			text-indent: 2em;
179
+			letter-spacing: 1px;
180
+			color: #333333;
181
+			word-break: break-all;
182
+			word-wrap: break-word;
183
+			line-height: 24px;
184
+		}
185
+		.question{
186
+			padding: 20px;
187
+			border-bottom: 2px solid #F1F1F1;
188
+			.title{
189
+				margin-bottom: 30px;
190
+				position: relative;
191
+				.sign{
192
+					color: #F14949;
193
+					vertical-align: middle;
194
+					position: absolute;
195
+					left: 5px;
196
+					top: 5px;
197
+				}
198
+				.sort{
199
+					display: inline-block;
200
+					width: 30px;
201
+					height: 24px;
202
+					background-color: #409EFF;
203
+					border-radius: 2px;
204
+					color: #FFFFFF;
205
+					text-align: center;
206
+					line-height: 24px;
207
+					font-size: 14px;
208
+					margin-left: 10px;
209
+				}
210
+				.option_title{
211
+					padding-left: 20px;
212
+					font-weight: bold;
213
+					font-size: 14px;
214
+					color: #333333;
215
+				}
216
+			}
217
+			.queOpion{
218
+				font-size: 14px;
219
+				padding: 0 12px;
220
+				color: #333333;
221
+			}
222
+			.operate_btn{
223
+				text-align: right;
224
+			}
225
+		}
226
+		.btn{
227
+			width: 100%;
228
+			text-align: center;
229
+			.el-button{
230
+				width: 240px;
231
+			}
232
+		}
233
+	}
234
+</style>

+ 182 - 0
CallCenterWeb.UI/src/views/outbound/callResult/index.vue

@@ -0,0 +1,182 @@
1
+<template>
2
+  <div class="app-container customer">
3
+    <div class="filter-container">
4
+      <el-date-picker
5
+        v-model="searchDate"
6
+        :picker-options="pickerOptions"
7
+        class="filter-item"
8
+        type="daterange"
9
+        format="yyyy年MM月dd日"
10
+        value-format="yyyy-MM-dd"
11
+        align="left"
12
+        unlink-panels
13
+        range-separator="至"
14
+        start-placeholder="开始日期"
15
+        end-placeholder="结束日期"/>
16
+      <el-input v-model="keyword" placeholder="请输入电话号码" class="filter-item"/>
17
+      <el-button type="primary" class="filter-item" icon="el-icon-search" @click="btn_search">搜索</el-button>
18
+    </div>
19
+
20
+    <el-table v-loading="loading" :data="dataLists" border stripe>
21
+      <el-table-column type="index" label="编号" align="center" fixed width="80"/>
22
+      <el-table-column prop="fullname" label="姓名" align="center" min-width=""/>
23
+      <el-table-column prop="mobile" label="电话" align="center" min-width=""/>
24
+      <el-table-column label="地址" align="center" min-width="">
25
+        <template slot-scope="scope">
26
+          {{ scope.row.address | formatterContent }}
27
+        </template>
28
+      </el-table-column>
29
+      <el-table-column prop="pagetitle" label="问卷名称" align="center" min-width=""/>
30
+      <el-table-column label="问卷内容简述" align="center" min-width="">
31
+        <template slot-scope="scope">
32
+          {{ scope.row.pagecontent | formatterContent }}
33
+        </template>
34
+      </el-table-column>
35
+      <!-- 			<el-table-column label="问卷结果简述" align="center" min-width="">
36
+				<template slot-scope="scope">
37
+					{{ scope.row.describe | formatterContent}}
38
+				</template>
39
+			</el-table-column> -->
40
+      <el-table-column label="呼叫结果" align="center" min-width="110">
41
+        <template slot-scope="scope">
42
+          {{ callResultsFilter(scope.row.callresult) }}
43
+        </template>
44
+      </el-table-column>
45
+      <el-table-column prop="createuser" label="坐席工号" align="center" min-width=""/>
46
+      <el-table-column prop="createusername" label="坐席姓名" align="center" min-width=""/>
47
+      <!-- <el-table-column prop="totalnum" label="录音" align="center" min-width=""></el-table-column> -->
48
+      <el-table-column prop="createtime" label="创建时间" align="center" min-width="130"/>
49
+      <el-table-column label="操作" width="160" align="center" class-name="oparate_btn" fixed="right">
50
+        <template slot-scope="scope">
51
+          <el-button v-permission="'HY_detail'" v-if="scope.row.callresult === '5bfe540c5a10b06b7a35a83a'" size="mini" plain type="primary" @click="btn_detail(scope.row.id)">查看问卷</el-button>
52
+        </template>
53
+      </el-table-column>
54
+    </el-table>
55
+    <pagination
56
+      v-show="pageParams.total > 0"
57
+      :total="pageParams.total"
58
+      :pageindex.sync="pageParams.pageindex"
59
+      :pagesize.sync="pageParams.pagesize"
60
+      class="pagination"
61
+      @pagination="getList" />
62
+  </div>
63
+</template>
64
+
65
+<script>
66
+import {
67
+  getAutoPagerLists
68
+} from '@/api/outbound/callResult'
69
+import {
70
+  getDictionary
71
+} from '@/api/commonAPI'
72
+import detail from './detail'
73
+import {
74
+  pickerOptions,
75
+  formatterContent
76
+} from '@/utils'
77
+import Pagination from '@/components/Pagination' // 对el-pagination 二次封装
78
+
79
+export default {
80
+  name: 'CallResult',
81
+  components: {
82
+    Pagination
83
+  },
84
+  data() {
85
+    return {
86
+      loading: false,
87
+      keyword: '',
88
+      searchDate: '',
89
+      pickerOptions,
90
+      pageParams: {
91
+        pageindex: 1, // 当前第几页
92
+        pagesize: Number(this.$store.getters.serverConfig.PAGESIZE), // 每页几条数据
93
+        total: 0 // 总共多少数据
94
+      },
95
+      dataLists: [], // 列表数据
96
+      callResults: [] // 呼叫结果数据
97
+    }
98
+  },
99
+  computed: {
100
+    callResultsFilter() {
101
+      return function(id) {
102
+        for (let i = 0; i < this.callResults.length; i++) {
103
+          if (this.callResults[i].id === id) {
104
+            return this.callResults[i].name
105
+          }
106
+        }
107
+      }
108
+    }
109
+  },
110
+  created() {
111
+    this.getCallResuts().then(() => {
112
+      this.getList()
113
+      document.onkeyup = (e) => {
114
+        if (e.keyCode === 13) {
115
+          this.getList()
116
+        }
117
+      }
118
+    })
119
+  },
120
+  methods: {
121
+
122
+    getList() {
123
+      this.loading = true
124
+      return new Promise(resolve => {
125
+        const params = {
126
+          pageindex: this.pageParams.pageindex, // 第几页
127
+          pagesize: this.pageParams.pagesize, // 每页几条信息
128
+          keyword: this.keyword, // 否	string	模糊查询(电话)
129
+          stime: this.searchDate && this.searchDate[0], // 否	datetime	起始时间
130
+          etime: this.searchDate && this.searchDate[1] // 否	datetime	结束时间
131
+        }
132
+        getAutoPagerLists(params).then(response => {
133
+          this.loading = false
134
+          if (response.state.toLowerCase() === 'success') {
135
+            this.pageParams.total = response.data.total
136
+            this.dataLists = response.data.rows
137
+          }
138
+        })
139
+        resolve()
140
+      })
141
+    },
142
+
143
+    btn_search() {
144
+      this.pageParams.pageindex = 1
145
+      this.getList()
146
+    },
147
+
148
+    btn_detail(editId) {
149
+      this.$layer.iframe({
150
+        content: {
151
+          content: detail, // 传递的组件对象
152
+          parent: this, // 当前的vue对象
153
+          data: {
154
+            'rowid': editId
155
+          } // props
156
+        },
157
+        area: ['80%', '90%'],
158
+        title: '查看问卷'
159
+      })
160
+    },
161
+
162
+    // 获取呼叫结果数据
163
+    getCallResuts() {
164
+      return new Promise(resolve => {
165
+        getDictionary('ZDWHJG').then(response => {
166
+          if (response.state.toLowerCase() === 'success') {
167
+            this.callResults = response.data
168
+          }
169
+        })
170
+        resolve()
171
+      })
172
+    }
173
+
174
+  }
175
+}
176
+</script>
177
+
178
+<style rel="stylesheet/scss" lang="scss">
179
+	.customer .filter-item.el-input {
180
+		width: 260px;
181
+	}
182
+</style>

+ 326 - 0
CallCenterWeb.UI/src/views/outbound/joinTask/index.vue

@@ -0,0 +1,326 @@
1
+<template>
2
+  <div v-loading="loading" class="joinTask">
3
+    <template v-if="taskLists.length">
4
+      <el-checkbox-group v-model="seatListsTags" @change="seatListsCheckedChange">
5
+        <el-card
6
+          v-for="item in taskLists"
7
+          :key="item.id"
8
+          :body-style="{ padding: '15px' }"
9
+          :class="{isJoin:item.joinflag}"
10
+          shadow="always"
11
+          class="join_list">
12
+          <div class="table-responsive">
13
+            <table class="table">
14
+              <tbody>
15
+                <tr>
16
+                  <th>任务名称</th>
17
+                  <td>{{ item.taskname }}</td>
18
+                  <th>任务量</th>
19
+                  <td class="red">{{ item.totalnum }}</td>
20
+                  <td rowspan="2" class="no_bottom_border"/>
21
+                </tr>
22
+                <tr class="bg_gray">
23
+                  <th>创建人</th>
24
+                  <td>{{ item.createusercode }}</td>
25
+                  <th>剩余</th>
26
+                  <td class="red">{{ item.surplusnum }}</td>
27
+                </tr>
28
+                <tr>
29
+                  <th>呼叫方式</th>
30
+                  <td>{{ item.calltype | calltypeFilter }}</td>
31
+                  <th>{{ item.bftype | bftypeFilter }}</th>
32
+                  <td>{{ item.bfnum }}</td>
33
+                  <td rowspan="3" class="join_btns">
34
+                    <el-checkbox :label="item.id" :key="item.id" class="seat_check">
35
+                      {{ item.joinflag === 0 ? '立即参与' : '取消参与' }}
36
+                    </el-checkbox>
37
+                  </td>
38
+                </tr>
39
+                <tr class="bg_gray">
40
+                  <th>起止日期</th>
41
+                  <td>{{ item.starttime+' 到  '+item.endtime }}</td>
42
+                  <th>接通</th>
43
+                  <td class="red">{{ item.successnum }}</td>
44
+                </tr>
45
+                <tr>
46
+                  <th>说明备注</th>
47
+                  <td colspan="3">{{ item.taskremark }}</td>
48
+                </tr>
49
+              </tbody>
50
+            </table>
51
+          </div>
52
+        </el-card>
53
+      </el-checkbox-group>
54
+    </template>
55
+    <p v-else>
56
+      <el-alert :closable="false" title="暂无任务信息。。。" type="warning" center show-icon/>
57
+    </p>
58
+  </div>
59
+</template>
60
+
61
+<script>
62
+import {
63
+  getAlloList,
64
+  cancelJoin,
65
+  getTaskRealInfo
66
+} from '@/api/outbound/tasks'
67
+import {
68
+  mapGetters
69
+} from 'vuex'
70
+import store from '@/store'
71
+
72
+export default {
73
+  name: 'JoinTask',
74
+  filters: {
75
+    calltypeFilter(status) {
76
+      const statusMap = {
77
+        0: '不播放语音直接转坐席',
78
+        1: '播放语音后转坐席',
79
+        2: '播放语音后按1键转坐席',
80
+        3: '不转坐席'
81
+      }
82
+      return statusMap[status]
83
+    },
84
+    bftypeFilter(status) {
85
+      const statusMap = {
86
+        0: '并发数',
87
+        1: '进号码速率'
88
+      }
89
+      return statusMap[status]
90
+    }
91
+  },
92
+  props: {
93
+    rowid: {
94
+      type: String,
95
+      default: ''
96
+    },
97
+    layerid: {
98
+      type: String,
99
+      default: ''
100
+    }
101
+  },
102
+  data() {
103
+    return {
104
+      loading: false,
105
+      taskLists: [], // 任务列表信息
106
+      seatListsTags: [] // 选中坐席的数据
107
+    }
108
+  },
109
+  computed: {
110
+    ...mapGetters([
111
+      'usercode',
112
+      'telIsVisTaskFirst'
113
+    ])
114
+  },
115
+  watch: {
116
+    // 如果 `seatListsTags` 发生改变,这个函数就会运行
117
+    seatListsTags: function(newT, oldT) {
118
+      if (newT.length === 1 && oldT.length === 0) {
119
+        this.joinNow(newT[0], 1) // 立即参与
120
+      }
121
+      if (newT.length === 0 && oldT.length === 1) {
122
+        this.joinNow(oldT[0], 0) // 取消参与
123
+      }
124
+
125
+      if (newT.length === 2 && oldT.length === 1) {
126
+        const joinTid = newT[1]
127
+        // 取消参与
128
+        this.joinNow(oldT[0], 0).then(() => {
129
+          // 立即参与
130
+          this.joinNow(joinTid, 1)
131
+        })
132
+      }
133
+    }
134
+  },
135
+  created() {
136
+    if (this.telIsVisTaskFirst) {
137
+      this.getListFirst()
138
+    } else {
139
+      this.getList()
140
+    }
141
+  },
142
+  methods: {
143
+    // 获取任务信息列表(第一次弹出调用)
144
+    getListFirst() {
145
+      this.loading = true
146
+      return new Promise(resolve => {
147
+        getAlloList().then(response => {
148
+          this.loading = false
149
+          store.dispatch('ChangeTaskFirst', false) // 外呼任务信息是否是第一次弹出
150
+          if (response.state.toLowerCase() === 'success') {
151
+            if (response.data && response.data.length > 0) {
152
+              this.taskLists = response.data
153
+            }
154
+          }
155
+        })
156
+        resolve()
157
+      })
158
+    },
159
+    // 获取任务信息列表
160
+    getList() {
161
+      this.loading = true
162
+      return new Promise(resolve => {
163
+        getTaskRealInfo().then(response => {
164
+          this.loading = false
165
+          if (response.state.toLowerCase() === 'success') {
166
+            if (response.data && response.data.length > 0) {
167
+              this.taskLists = response.data
168
+              for (let i = 0, len = this.taskLists.length; i < len; i++) {
169
+                if (this.taskLists[i].joinflag === 1) {
170
+                  this.seatListsTags.push(this.taskLists[i].id)
171
+                  return
172
+                }
173
+              }
174
+              // console.log(this.seatListsTags)
175
+            }
176
+          }
177
+        })
178
+        resolve()
179
+      })
180
+    },
181
+    // 选择切换
182
+    seatListsCheckedChange(value) {
183
+      this.$forceUpdate() // 迫使 Vue 实例重新渲染。注意它仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件。
184
+      if (value.length === 0) {
185
+        this.taskLists.forEach((v, i) => {
186
+          this.$set(v, 'joinflag', 0)
187
+        })
188
+        return
189
+      }
190
+      if (value.length > 1) {
191
+        this.seatListsTags = value.splice(value.length - 1)
192
+      }
193
+      this.taskLists.forEach((v, i) => {
194
+        this.$set(v, 'joinflag', 0)
195
+        if (this.seatListsTags[0] === v.id) {
196
+          this.$set(v, 'joinflag', 1)
197
+        }
198
+      })
199
+    },
200
+    /**
201
+			 * 参与
202
+			 * taskid 任务id
203
+			 * joinflag 参与标志(1为参与,0为不参与)
204
+			 */
205
+    joinNow(taskid, joinflag) {
206
+      return new Promise(resolve => {
207
+        cancelJoin({
208
+          taskid: taskid, //	是	string	任务id
209
+          agentid: this.usercode, //	是	string	坐席工号
210
+          joinflag: joinflag //	是	int	参与标志(1为参与,0为不参与)
211
+        }).then(response => {
212
+          if (response.state.toLowerCase() === 'success') {
213
+            this.$parent.$layer.close(this.layerid)
214
+            store.dispatch('ChangeTask', false)
215
+            if (joinflag === 1) {
216
+              this.$message.success('恭喜你,参与成功!')
217
+            } else {
218
+              this.$message.success('恭喜你,取消成功!')
219
+            }
220
+            // 更新右上角任务信息/自动外呼监控/外呼分配/我的呼叫任务
221
+            store.dispatch('ChangeTaskInfo', true)
222
+          }
223
+        })
224
+        resolve()
225
+      })
226
+    }
227
+
228
+  }
229
+}
230
+</script>
231
+
232
+<style rel="stylesheet/scss" lang="scss">
233
+	.joinTask {
234
+		.seat_check {
235
+			.el-checkbox__inner {
236
+				border-color: #409eff;
237
+			}
238
+
239
+			.el-checkbox__label {
240
+				color: #409eff;
241
+			}
242
+
243
+			.el-checkbox__input.is-checked+.el-checkbox__label {
244
+				color: #f56c6c;
245
+			}
246
+
247
+			.el-checkbox__input.is-checked .el-checkbox__inner {
248
+				background-color: #fff;
249
+				border-color: #f56c6c;
250
+			}
251
+
252
+			.el-checkbox__inner::after {
253
+				border-color: #f56c6c;
254
+			}
255
+		}
256
+	}
257
+</style>
258
+
259
+<style rel="stylesheet/scss" lang="scss" scoped>
260
+	.joinTask {
261
+		.join_list {
262
+			border: none;
263
+			margin-bottom: 10px;
264
+		}
265
+
266
+		.isJoin {
267
+			-webkit-box-shadow: 0 4px 6px 0 rgba(141, 141, 141, .4);
268
+			box-shadow: 0 4px 6px 0 rgba(141, 141, 141, .4);
269
+		}
270
+
271
+		.table-responsive {
272
+			box-sizing: border-box;
273
+			display: block;
274
+			width: 100%;
275
+			overflow-x: auto;
276
+			-webkit-overflow-scrolling: touch;
277
+			-ms-overflow-style: -ms-autohiding-scrollbar;
278
+		}
279
+
280
+		.table {
281
+			box-sizing: border-box;
282
+			font-size: 14px;
283
+			color: #666666;
284
+			border: 1px solid #ebeef5;
285
+			border-collapse: collapse;
286
+			width: 100%;
287
+			max-width: 100%;
288
+
289
+			td,
290
+			th {
291
+				border: 1px solid #ebeef5;
292
+				padding: .75rem;
293
+				vertical-align: top;
294
+			}
295
+
296
+			td {
297
+				color: #333333;
298
+			}
299
+
300
+			th {
301
+				width: 100px;
302
+				text-align: left;
303
+				font-weight: normal;
304
+			}
305
+
306
+			.bg_gray {
307
+				background-color: #fafafa;
308
+			}
309
+
310
+			.no_bottom_border {
311
+				border-bottom: none;
312
+			}
313
+
314
+			.join_btns {
315
+				text-align: center;
316
+				border-top: none;
317
+				width: 130px;
318
+			}
319
+
320
+		}
321
+
322
+		.red {
323
+			color: red !important;
324
+		}
325
+	}
326
+</style>

+ 192 - 0
CallCenterWeb.UI/src/views/outbound/myTask/components/tabMyTask.vue

@@ -0,0 +1,192 @@
1
+<template>
2
+  <div>
3
+    <el-table
4
+      v-loading="loading"
5
+      :data="dataLists"
6
+      border
7
+      stripe>
8
+      <el-table-column type="index" label="编号" align="center" fixed width="60"/>
9
+      <el-table-column label="状态" width="100" align="center">
10
+        <template slot-scope="scope">
11
+          <el-tag :type="scope.row.isstart | isstartTypeFilter" size="mini" disable-transitions>
12
+            {{ scope.row.isstart | isstartTextFilter }}
13
+          </el-tag>
14
+        </template>
15
+      </el-table-column>
16
+      <el-table-column prop="taskname" label="计划名称" align="center" min-width="160"/>
17
+      <el-table-column prop="totalnum" label="号码数量" align="center"/>
18
+      <el-table-column prop="surplusnum" label="剩余数量" align="center"/>
19
+      <el-table-column prop="callnum" label="已呼叫数量" align="center"/>
20
+      <el-table-column prop="successnum" label="接通数量" align="center"/>
21
+      <el-table-column prop="agentnum" label="坐席数量" align="center"/>
22
+      <el-table-column prop="successpercent" label="接通率" align="center"/>
23
+      <el-table-column prop="agentsuccessnum" label="坐席接通数量" align="center"/>
24
+      <el-table-column prop="agentsuccesspercent" label="坐席接通率" align="center"/>
25
+      <el-table-column prop="starttime" label="任务开始日期" min-width="100" align="center"/>
26
+      <el-table-column label="任务结束日期" min-width="100" align="center">
27
+        <template slot-scope="scope">
28
+          <span :class="scope.row.endtime | endtimeFilter">{{ scope.row.endtime }}</span>
29
+        </template>
30
+      </el-table-column>
31
+      <el-table-column prop="createtime" label="创建时间" min-width="110" align="center"/>
32
+      <el-table-column label="操作" width="180" align="center" class-name="oparate_btn" fixed="right">
33
+        <template slot-scope="scope">
34
+          <el-tooltip class="item" effect="dark" content="点击导出已接通号码" placement="top-start">
35
+            <el-button v-permission="'HY_export'" size="mini" circle type="primary" plain @click="btn_export(scope.row.id, 1)">
36
+              <svg-icon icon-class="daochu"/>
37
+            </el-button>
38
+          </el-tooltip>
39
+          <el-tooltip class="item" effect="dark" content="点击导出未接通号码" placement="top-start">
40
+            <el-button v-permission="'HY_export'" size="mini" circle type="primary" plain @click="btn_export(scope.row.id, 0)">
41
+              <i class="el-icon-upload2"/>
42
+            </el-button>
43
+          </el-tooltip>
44
+        </template>
45
+      </el-table-column>
46
+    </el-table>
47
+    <pagination
48
+      v-show="pageParams.total > 0"
49
+      :total="pageParams.total"
50
+      :pageindex.sync="pageParams.pageindex"
51
+      :pagesize.sync="pageParams.pagesize"
52
+      class="pagination"
53
+      @pagination="getList" />
54
+
55
+  </div>
56
+</template>
57
+
58
+<script>
59
+import { endtimeFilter } from '@/utils'
60
+import { getTaskLists, cancelJoin } from '@/api/outbound/tasks'
61
+import { mapGetters } from 'vuex'
62
+import store from '@/store'
63
+import Pagination from '@/components/Pagination' // 对el-pagination 二次封装
64
+
65
+export default {
66
+  name: 'TabMyTask',
67
+  components: {
68
+    Pagination
69
+  },
70
+  filters: {
71
+    isstartTextFilter(status) {
72
+      const statusMap = {
73
+        0: '未启动',
74
+        1: '已启动',
75
+        2: '暂停',
76
+        3: '处理完成',
77
+        4: '撤销',
78
+        5: '完成'
79
+      }
80
+      return statusMap[status]
81
+    },
82
+    isstartTypeFilter(status) {
83
+      const statusMap = {
84
+        0: 'info',
85
+        1: '',
86
+        2: 'warning',
87
+        3: 'success',
88
+        4: 'danger',
89
+        5: 'success'
90
+      }
91
+      return statusMap[status]
92
+    }
93
+  },
94
+  props: {
95
+    searchDatas: {
96
+      type: Object,
97
+      default: function() {}
98
+    }
99
+  },
100
+  data() {
101
+    return {
102
+      loading: false,
103
+      pageParams: {
104
+        pageindex: 1, // 当前第几页
105
+        pagesize: Number(this.$store.getters.serverConfig.PAGESIZE), // 每页几条数据
106
+        total: 0 // 总共多少数据
107
+      },
108
+      dataLists: [] // 列表数据
109
+    }
110
+  },
111
+  computed: {
112
+    ...mapGetters([
113
+      'usercode',
114
+      'telTaskIsRefresh' // 是否刷新右上角外呼任务信息/自动外呼监控/外呼分配/我的呼叫任务
115
+    ])
116
+  },
117
+  watch: {
118
+    telTaskIsRefresh: function(newT, oldT) {
119
+      if (newT === true) {
120
+        this.getList()
121
+      }
122
+    }
123
+  },
124
+  created() {
125
+    this.getList()
126
+  },
127
+
128
+  methods: {
129
+    getList() {
130
+      this.loading = true
131
+      return new Promise(resolve => {
132
+        const params = {
133
+          pageindex: this.pageParams.pageindex, // 第几页
134
+          pagesize: this.pageParams.pagesize, // 每页几条信息
135
+          infokind: this.searchDatas.ishistory, // 否	int	查询类型(为0或不传时获取全部,为1时获取当前任务,为2时获取历史任务)
136
+          isstart: this.searchDatas.sc_state, //	否	int	任务状态 (不传值时查询所有状态)
137
+          stime: this.searchDatas.searchDate && this.searchDatas.searchDate[0], //	否	string	开始时间
138
+          etime: this.searchDatas.searchDate && this.searchDatas.searchDate[1], //	否	string	结束时间
139
+          agentid: this.usercode, // 否	string	坐席工号(不传值查询全部坐席)
140
+          taskname: this.searchDatas.keyword //	否	string	计划名称,可模糊查询
141
+        }
142
+        getTaskLists(params).then(response => {
143
+          store.dispatch('ChangeTaskInfo', false)
144
+          this.loading = false
145
+          if (response.state.toLowerCase() === 'success') {
146
+            switch (this.searchDatas.ishistory) {
147
+              case 0:
148
+                this.pageParams.total = response.total
149
+                break
150
+              case 1:
151
+                this.pageParams.total = response.dqnum
152
+                break
153
+              case 2:
154
+                this.pageParams.total = response.lsnum
155
+                break
156
+              default:
157
+                break
158
+            }
159
+            this.dataLists = response.rows
160
+            if (response.total >= 100) {
161
+              response.total = '99+'
162
+            }
163
+            if (response.dqnum >= 100) {
164
+              response.dqnum = '99+'
165
+            }
166
+            if (response.lsnum >= 100) {
167
+              response.lsnum = '99+'
168
+            }
169
+            // 修改父组件的值
170
+            this.$emit('getTotalNums', {
171
+              totalcount: response.total, // 全部
172
+              wfpcount: response.dqnum, // 当前任务
173
+              fpcount: response.lsnum // 历史任务
174
+            })
175
+          }
176
+        })
177
+        resolve()
178
+      })
179
+    },
180
+
181
+    // 导出已接通或者未接通  0=导出未接通号码 1=导出已接通号码
182
+    btn_export(tid, type) {
183
+      window.location.href =
184
+					`${this.$store.getters.serverConfig.BASE_API}callcenterapi/api/autocallouttask/exportexcel?taskid=${tid}&calloutok=${type}`
185
+    }
186
+  }
187
+}
188
+</script>
189
+
190
+<style rel="stylesheet/scss" lang="scss" scoped>
191
+
192
+</style>

+ 213 - 0
CallCenterWeb.UI/src/views/outbound/myTask/index.vue

@@ -0,0 +1,213 @@
1
+<template>
2
+  <div class="app-container tasks">
3
+    <div class="filter-container">
4
+      <el-date-picker
5
+        v-model="searchDatas.searchDate"
6
+        :picker-options="pickerOptions"
7
+        class="filter-item"
8
+        type="daterange"
9
+        format="yyyy年MM月dd日"
10
+        value-format="yyyy-MM-dd"
11
+        align="left"
12
+        unlink-panels
13
+        range-separator="至"
14
+        start-placeholder="开始日期"
15
+        end-placeholder="结束日期"/>
16
+      <el-select v-model="searchDatas.sc_state" class="filter-item" filterable clearable placeholder="请选择任务状态">
17
+        <el-option v-for="item in stateOptions" :key="item.id" :label="item.name" :value="item.id"/>
18
+      </el-select>
19
+      <el-input v-model="searchDatas.keyword" placeholder="请输入计划名称" class="filter-item"/>
20
+      <el-button type="primary" class="filter-item" icon="el-icon-search" @click="btn_search">搜索</el-button>
21
+    </div>
22
+    <el-tabs v-model="activeName" @tab-click="handleClick" v-if="flag">
23
+      <el-tab-pane v-for="item in tabMapOptions" :key="item.key" :name="item.key">
24
+        <span slot="label">{{ item.label }}<span :class="item.listclass">({{ item.num }})</span></span>
25
+        <tabMyTask v-if="activeName===item.key" ref="tabtask" :search-datas="searchDatas" @getTotalNums="getTotalNum"/>
26
+      </el-tab-pane>
27
+    </el-tabs>
28
+  </div>
29
+</template>
30
+
31
+<script>
32
+import {
33
+  getNowDate,
34
+  getFirstDayInCurrentMonth,
35
+  pickerOptions
36
+} from '@/utils'
37
+import {
38
+  getSeatLists
39
+} from '@/api/telCall/seatMonitor'
40
+import { mapGetters } from 'vuex'
41
+import tabMyTask from './components/tabMyTask'
42
+import {getTaskLists} from '@/api/outbound/tasks'
43
+
44
+export default {
45
+  name: 'MyTask',
46
+  components: {
47
+    tabMyTask
48
+  },
49
+  data() {
50
+    return {
51
+      pickerOptions, // 日期数据
52
+      stateOptions: [{
53
+        'id': '0',
54
+        'name': '未启动'
55
+      },
56
+      {
57
+        'id': '1',
58
+        'name': '已启动'
59
+      },
60
+      {
61
+        'id': '2',
62
+        'name': '暂停'
63
+      },
64
+      {
65
+        'id': '3',
66
+        'name': '处理完成'
67
+      },
68
+      {
69
+        'id': '4',
70
+        'name': '撤销'
71
+      },
72
+      {
73
+        'id': '5',
74
+        'name': '完成'
75
+      }
76
+      ], // 任务状态数据
77
+      searchDatas: {
78
+        searchDate: [getFirstDayInCurrentMonth(), getNowDate()], // 日期
79
+        sc_state: '', // 任务状态
80
+        keyword: '', // 计划名称
81
+        ishistory: 0
82
+      },
83
+      pageParams: {
84
+        pageindex: 1, // 当前第几页
85
+        pagesize: Number(this.$store.getters.serverConfig.PAGESIZE), // 每页几条数据
86
+        total: 0 // 总共多少数据
87
+      },
88
+      flag:false,//表头数据展示
89
+      activeName: 'first',
90
+      tabMapOptions: [{
91
+        label: '全部',
92
+        key: 'first',
93
+        num: 0,
94
+        listclass: 'list_all'
95
+      },
96
+      {
97
+        label: '当前任务',
98
+        key: 'second',
99
+        num: 0,
100
+        listclass: 'list_wait'
101
+      },
102
+      {
103
+        label: '历史任务',
104
+        key: 'third',
105
+        num: 0,
106
+        listclass: 'list_done'
107
+      }
108
+      ]
109
+    }
110
+  },
111
+  created() {
112
+    this.getCurrentList()
113
+  },
114
+  mounted() {
115
+    document.onkeyup = (e) => {
116
+      if (e.keyCode === 13) {
117
+        this.$refs.tabtask[0].getList()
118
+      }
119
+    }
120
+  },
121
+  computed: {
122
+    ...mapGetters([
123
+      'usercode',
124
+    ])
125
+  },
126
+  methods: {
127
+    handleClick(tab, event) {
128
+      switch (tab.name) {
129
+        case 'first':
130
+          this.searchDatas.ishistory = 0
131
+          break
132
+        case 'second':
133
+          this.searchDatas.ishistory = 1
134
+          break
135
+        case 'third':
136
+          this.searchDatas.ishistory = 2
137
+          break
138
+        default:
139
+          break
140
+      }
141
+    },
142
+
143
+    btn_search() {
144
+      this.$refs.tabtask[0].pageParams.pageindex = 1
145
+      this.$refs.tabtask[0].getList()
146
+    },
147
+
148
+    // 从子组件获取的 数量值
149
+    getTotalNum(value) {
150
+      this.tabMapOptions[0].num = value.totalcount // 全部
151
+      this.tabMapOptions[1].num = value.wfpcount // 当前任务
152
+      this.tabMapOptions[2].num = value.fpcount // 历史任务
153
+    },
154
+    getCurrentList() {
155
+      return new Promise(resolve => {
156
+        const params = {
157
+          pageindex: this.pageParams.pageindex, // 第几页
158
+          pagesize: this.pageParams.pagesize, // 每页几条信息
159
+          infokind: this.searchDatas.ishistory, // 否	int	查询类型(为0或不传时获取全部,为1时获取当前任务,为2时获取历史任务)
160
+          isstart: this.searchDatas.sc_state, //	否	int	任务状态 (不传值时查询所有状态)
161
+          stime: this.searchDatas.searchDate && this.searchDatas.searchDate[0], //	否	string	开始时间
162
+          etime: this.searchDatas.searchDate && this.searchDatas.searchDate[1], //	否	string	结束时间
163
+          agentid: this.usercode, // 否	string	坐席工号(不传值查询全部坐席)
164
+          taskname: this.searchDatas.keyword //	否	string	计划名称,可模糊查询
165
+        }
166
+        getTaskLists(params).then(response => {
167
+          if (response.state.toLowerCase() === 'success') {
168
+            switch (this.searchDatas.ishistory) {
169
+              case 0:
170
+                this.pageParams.total = response.total
171
+                break
172
+              case 1:
173
+                this.pageParams.total = response.dqnum
174
+                break
175
+              case 2:
176
+                this.pageParams.total = response.lsnum
177
+                break
178
+              default:
179
+                break
180
+            }
181
+            if (response.total >= 100) {
182
+              response.total = '99+'
183
+            }
184
+            if (response.dqnum >= 100) {
185
+              response.dqnum = '99+'
186
+            }
187
+            if (response.lsnum >= 100) {
188
+              response.lsnum = '99+'
189
+            }
190
+            this.tabMapOptions[0].num = response.total // 全部
191
+            this.tabMapOptions[1].num = response.dqnum // 当前任务
192
+            this.tabMapOptions[2].num = response.lsnum // 历史任务
193
+            this.flag = true
194
+          }
195
+        })
196
+        resolve()
197
+      })
198
+    },
199
+  }
200
+}
201
+</script>
202
+
203
+<style rel="stylesheet/scss" lang="scss" scoped>
204
+	.tasks {
205
+		.list_wait {
206
+			color: #febd23;
207
+		}
208
+
209
+		.list_done {
210
+			color: #5ccb91;
211
+		}
212
+	}
213
+</style>

+ 387 - 0
CallCenterWeb.UI/src/views/outbound/plan/addOrEdit.vue

@@ -0,0 +1,387 @@
1
+<template>
2
+  <div v-loading="loading" class="plan">
3
+    <el-form ref="ruleForm" :model="ruleForm" :rules="rules" label-width="130px">
4
+      <el-form-item label="计划名称" prop="taskname">
5
+        <el-input v-model="ruleForm.taskname" placeholder="请输入计划名称"/>
6
+      </el-form-item>
7
+      <el-form-item label="计划起止日期" prop="searchDate">
8
+        <el-date-picker
9
+          v-model="ruleForm.searchDate"
10
+          class="date_picker"
11
+          type="daterange"
12
+          format="yyyy年MM月dd日"
13
+          value-format="yyyy-MM-dd"
14
+          align="left"
15
+          unlink-panels
16
+          range-separator="至"
17
+          start-placeholder="开始日期"
18
+          end-placeholder="结束日期"/>
19
+      </el-form-item>
20
+      <el-form-item label="工作时间段一" prop="wtime1">
21
+        <el-time-picker
22
+          v-model="ruleForm.wtime1"
23
+          is-range
24
+          class="date_picker"
25
+          range-separator="至"
26
+          start-placeholder="开始时间"
27
+          end-placeholder="结束时间"
28
+          value-format="HH:mm:ss"
29
+          align="left"/>
30
+      </el-form-item>
31
+      <el-form-item label="工作时间段二" prop="wtime2">
32
+        <el-time-picker
33
+          v-model="ruleForm.wtime2"
34
+          is-range
35
+          class="date_picker"
36
+          range-separator="至"
37
+          start-placeholder="开始时间"
38
+          end-placeholder="结束时间"
39
+          value-format="HH:mm:ss"
40
+          align="left"/>
41
+      </el-form-item>
42
+      <el-form-item v-if="rowid === ''" label="关联问卷" prop="pagerid">
43
+        <el-select
44
+          v-model="ruleForm.pagerid"
45
+          class="select_picker"
46
+          filterable
47
+          clearable
48
+          placeholder="请选择关联问卷">
49
+          <el-option
50
+            v-for="item in pagerOptions"
51
+            :key="item.id"
52
+            :label="item.title"
53
+            :value="item.id"/>
54
+        </el-select>
55
+      </el-form-item>
56
+      <div class="clearfix">
57
+        <el-col :xl="12">
58
+          <el-form-item label="并发类型" prop="bftype">
59
+            <el-radio-group v-model="ruleForm.bftype">
60
+              <el-radio label="0">并发数</el-radio>
61
+              <el-radio label="1">进号速率</el-radio>
62
+            </el-radio-group>
63
+          </el-form-item>
64
+        </el-col>
65
+        <el-col :xl="12">
66
+          <el-form-item label="并发数/进号速率" prop="bfnum">
67
+            <el-input-number v-model="ruleForm.bfnum" :min="0" controls-position="right"/>
68
+          </el-form-item>
69
+        </el-col>
70
+      </div>
71
+      <el-form-item label="呼叫方式" prop="calltype">
72
+        <el-radio-group v-model="ruleForm.calltype">
73
+          <el-radio class="radio_type" border label="0">不播放语音直接转坐席</el-radio>
74
+          <el-radio class="radio_type" border label="1">播放语音后转坐席</el-radio>
75
+          <el-radio class="radio_type" border label="2">播放语音后按1键转坐席</el-radio>
76
+          <!-- <el-radio class="radio_type" border label="3">不转坐席</el-radio> -->
77
+        </el-radio-group>
78
+      </el-form-item>
79
+      <el-form-item v-show="ruleForm.calltype === '1' || ruleForm.calltype === '2'" label="上传文件" prop="voicepath">
80
+        <el-upload
81
+          ref="upload"
82
+          :limit="1"
83
+          :file-list="uploadData.fileList"
84
+          :action= "uploadData.uploadUrl"
85
+          :data = "uploadData.uploaderFiles"
86
+          :on-success="uploadSuccess"
87
+          :on-exceed="uploadExceed"
88
+          :on-error="uploadError"
89
+          :on-remove="uploadRemove"
90
+          class="uploadFiles"
91
+          list-type="text"
92
+          accept="audio/*">
93
+          <el-button size="small" type="primary">上传录音</el-button>
94
+          <!-- <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div> -->
95
+          <!-- <i class="el-icon-plus"></i> -->
96
+        </el-upload>
97
+      </el-form-item>
98
+      <el-collapse-transition>
99
+        <el-form-item v-if="ruleForm.voicepath.length > 0" label="试听录音">
100
+          <aplayer :music="musicList" theme="#41b883"/>
101
+        </el-form-item>
102
+      </el-collapse-transition>
103
+      <el-form-item label="说明备注" prop="taskremark">
104
+        <el-input v-model="ruleForm.taskremark" type="textarea" autosize placeholder="请输入说明备注"/>
105
+      </el-form-item>
106
+      <el-form-item>
107
+        <el-button type="primary" @click="submitForm">保存</el-button>
108
+        <el-button @click="resetForm">重置</el-button>
109
+      </el-form-item>
110
+    </el-form>
111
+  </div>
112
+</template>
113
+
114
+<script>
115
+import { getPlan, addPlan, editPlan } from '@/api/outbound/plan'
116
+// import { getPagerSelect } from '@/api/questionnaire/management'
117
+import { delFiles, filterContent } from '@/utils'
118
+import { validateTel } from '@/utils/validate'
119
+import { mapGetters } from 'vuex'
120
+import Aplayer from 'vue-aplayer'
121
+
122
+export default {
123
+  name: 'AddOrEdit',
124
+  components: {
125
+    Aplayer
126
+  },
127
+
128
+  props: {
129
+    rowid: {
130
+      type: String,
131
+      default: ''
132
+    },
133
+    layerid: {
134
+      type: String,
135
+      default: ''
136
+    }
137
+  },
138
+  data() {
139
+    return {
140
+      uploadData: {// 文件上传数据
141
+        uploadUrl: this.$store.getters.serverConfig.BASE_API + 'fileserverapi/Api/Upload',
142
+        uploaderFiles: {// 上传文件的参数 //是	string	模块code,如:test
143
+          uploadtype: 'outboundFiles'
144
+        },
145
+        fileList: [] // 展示文件的数据
146
+      },
147
+      musicList: {
148
+        title: '录音', // 歌曲名称
149
+        artist: ' ', // 演唱者
150
+        src: ' ', // 音频文件的 URL
151
+        pic: ' '// 封面图片 URL
152
+      },
153
+      ruleForm: {
154
+        id: '',
155
+        taskname: '', // 计划名称
156
+        searchDate: '', // 计划起止日期
157
+        wtime1: ['08:30:00', '12:00:00'], // 工作是时间段二
158
+        wtime2: ['14:00:00', '18:00:00'], // 工作时间段二
159
+        pagerid: '', // 问卷id
160
+        bftype: '0', //	否	int	并发类型
161
+        bfnum: '0', //	否	string	并发数
162
+        calltype: '0', // 否	int	呼叫方式:0为不播放直接转坐席,1为播放转坐席,2为播放后按1键转坐席 3 不转坐席
163
+        voicepath: [], //	否	string	语音文件路径
164
+        pressnum: '', //	否	string	按键
165
+        taskremark: '' // 否	string	说明备注
166
+      },
167
+      rules: {
168
+        taskname: [{
169
+          required: true,
170
+          trigger: 'blur',
171
+          message: '请输入计划名称!'
172
+        }],
173
+        searchDate: [{
174
+          required: true,
175
+          trigger: 'blur',
176
+          message: '请选择计划起止日期!'
177
+        }],
178
+        wtime1: [{
179
+          required: true,
180
+          trigger: 'blur',
181
+          message: '请选择工作时间段一!'
182
+        }],
183
+        wtime2: [{
184
+          required: true,
185
+          trigger: 'blur',
186
+          message: '请选择工作时间段二!'
187
+        }],
188
+        pagerid: [{
189
+          required: true,
190
+          trigger: 'blur',
191
+          message: '请选择关联问卷!'
192
+        }],
193
+        bftype: [{
194
+          required: true,
195
+          trigger: 'blur',
196
+          message: '请选择并发类型!'
197
+        }],
198
+        bfnum: [{
199
+          required: true,
200
+          message: '请输入并发数/进号速率!',
201
+          trigger: 'blur'
202
+        }],
203
+        calltype: [{
204
+          required: true,
205
+          message: '请选择呼叫方式!',
206
+          trigger: 'blur'
207
+        }]
208
+      },
209
+      pagerOptions: [], // 问卷数据
210
+      loading: false
211
+    }
212
+  },
213
+  computed: {
214
+    ...mapGetters([
215
+      'avatar'
216
+    ])
217
+  },
218
+  created() {
219
+    this.musicList.pic = this.avatar
220
+    if (this.rowid) {
221
+      this.ruleForm.id = this.rowid
222
+      this.getPagerSelectList().then(() => {
223
+        this.getDetail(this.rowid)
224
+      })
225
+    } else {
226
+      this.getPagerSelectList()
227
+    }
228
+  },
229
+  methods: {
230
+    submitForm() {
231
+      this.$refs.ruleForm.validate((valid) => {
232
+        if (valid) {
233
+          this.loading = true
234
+          const datas = {
235
+            id: this.ruleForm.id, // edit_id为空的时候添加
236
+            taskname: this.ruleForm.taskname, // 是	string	任务名称
237
+            stime: this.ruleForm.searchDate && this.ruleForm.searchDate[0], // 否	string	任务开始时间
238
+            etime: this.ruleForm.searchDate && this.ruleForm.searchDate[1], // 否	string	任务结束时间
239
+            swtime1: this.ruleForm.wtime1 && this.ruleForm.wtime1[0], //	否	string	工作开始时间1
240
+            ewtime1: this.ruleForm.wtime1 && this.ruleForm.wtime1[1], //	否	string	工作结束时间1
241
+            swtime2: this.ruleForm.wtime2 && this.ruleForm.wtime2[0], //	否	string	工作开始时间2
242
+            ewtime2: this.ruleForm.wtime2 && this.ruleForm.wtime2[1], //	否	string	工作结束时间2
243
+            pagerid: this.ruleForm.pagerid, //	否	string	问卷id
244
+            calltype: this.ruleForm.calltype, //	否	int	呼叫方式:0为不播放直接转坐席,1为播放转坐席,2为播放后按键转坐席
245
+            voicepath: this.ruleForm.voicepath, //	否	string	语音文件路径
246
+            pressnum: this.ruleForm.pressnum, //	否	string	按键
247
+            bftype: this.ruleForm.bftype, //	否	int	并发类型
248
+            bfnum: this.ruleForm.bfnum, //	否	string	并发数
249
+            taskremark: filterContent.delHtmlTag(this.ruleForm.taskremark) // 否	string	说明备注
250
+          }
251
+          // 添加
252
+          if (!this.rowid) {
253
+            addPlan(datas).then(response => {
254
+              this.loading = false
255
+              if (response.state.toLowerCase() === 'success') {
256
+                this.$parent.$layer.close(this.layerid)
257
+                this.$parent.getListL() // 重新加载父级数据
258
+                this.$message.success('恭喜你,外呼计划添加成功!')
259
+              }
260
+            }).catch(() => {
261
+              this.loading = false
262
+            })
263
+            return
264
+          }
265
+          // 编辑
266
+          editPlan(datas).then(response => {
267
+            this.loading = false
268
+            if (response.state.toLowerCase() === 'success') {
269
+              this.$parent.$layer.close(this.layerid)
270
+              this.$parent.getListL() // 重新加载父级数据
271
+              this.$message.success('恭喜你,外呼计划编辑成功!')
272
+            }
273
+          }).catch(() => {
274
+            this.loading = false
275
+          })
276
+        } else {
277
+          this.$message.error('请输入有效的必填项信息!')
278
+          return false
279
+        }
280
+      })
281
+    },
282
+    resetForm() {
283
+      if (this.ruleForm.voicepath.length > 0) {
284
+        for (let i = 0, len = this.ruleForm.voicepath.length; i < len; i++) {
285
+          delFiles(this.ruleForm.voicepath[i].filesmallurl, this.ruleForm.voicepath[i].fileurl)
286
+          this.ruleForm.voicepath.splice(i, 1)
287
+        }
288
+      }
289
+      this.$refs.upload.clearFiles()	// 清空已上传的文件列表(该方法不支持在 before-upload 中调用)
290
+      this.$refs.ruleForm.resetFields()
291
+    },
292
+    // 获取详情
293
+    getDetail(rid) {
294
+      getPlan(rid).then(response => {
295
+        if (response.state.toLowerCase() === 'success') {
296
+          const res = response.data
297
+          if (res) {
298
+            this.ruleForm.taskname = res.taskname
299
+            this.ruleForm.searchDate = [res.starttime, res.endtime]
300
+            this.ruleForm.wtime1 = [res.workstarttimes1, res.workendtimes1]
301
+            this.ruleForm.wtime2 = [res.workstarttimes2, res.workendtimes2]
302
+            this.ruleForm.pagerid = res.pagerid
303
+            this.ruleForm.bftype = res.bftype
304
+            this.ruleForm.bfnum = res.bfnum
305
+            this.ruleForm.calltype = res.calltype.toString()
306
+            if (res.voicepath && res.voicepath.length > 0) {
307
+              for (let i = 0, len = res.voicepath.length; i < len; i++) {
308
+                this.uploadData.fileList.push({
309
+                  'name': res.voicepath[i].filename,
310
+                  'url': res.voicepath[i].fileurl
311
+                })
312
+              }
313
+              this.ruleForm.voicepath = res.voicepath
314
+              this.$set(this.musicList, 'src', res.voicepath[0].fileurl)
315
+              this.$set(this.musicList, 'title', res.voicepath[0].filename)
316
+            }
317
+            this.ruleForm.pressnum = res.pressnum
318
+            this.ruleForm.taskremark = res.taskremark
319
+          }
320
+        }
321
+      })
322
+    },
323
+
324
+    // 文件上传
325
+    uploadSuccess(response, file, fileList) {
326
+      if (response.state.toLowerCase() === 'success') {
327
+        this.musicList.src = response.data[0].fileurl
328
+        this.musicList.title = response.data[0].filename
329
+        this.ruleForm.voicepath.push(response.data[0])
330
+      } else {
331
+        this.$message.error(response.message)
332
+      }
333
+    },
334
+    uploadRemove(file, fileList) {
335
+      if (this.ruleForm.voicepath.length > 0) {
336
+        for (let i = 0, len = this.ruleForm.voicepath.length; i < len; i++) {
337
+          if (this.ruleForm.voicepath[i].filename === file.name) {
338
+            delFiles(this.ruleForm.voicepath[i].filesmallurl, this.ruleForm.voicepath[i].fileurl)
339
+            this.ruleForm.voicepath.splice(i, 1)
340
+            return
341
+          }
342
+        }
343
+      }
344
+    },
345
+    uploadError(err, file, fileList) {
346
+      // console.log(err)
347
+      this.$message.error(err)
348
+    },
349
+    uploadExceed(file, fileList) {
350
+      this.$message.warning('只能选择一个文件!')
351
+    },
352
+    // 获取问卷下拉
353
+    getPagerSelectList() {
354
+      return new Promise(resolve => {
355
+        getPagerSelect().then(response => {
356
+          if (response.state.toLowerCase() === 'success') {
357
+            this.pagerOptions = response.data
358
+          }
359
+        })
360
+        resolve()
361
+      })
362
+    }
363
+  }
364
+}
365
+</script>
366
+
367
+<style rel="stylesheet/scss" lang="scss">
368
+	.plan{
369
+		.aplayer-controller .aplayer-time .aplayer-volume-wrap+.aplayer-icon{
370
+			display: none;
371
+		}
372
+	}
373
+</style>
374
+
375
+<style rel="stylesheet/scss" lang="scss" scoped>
376
+	.plan{
377
+		.radio_type{
378
+			margin-bottom: 8px;
379
+		}
380
+		.date_picker, .select_picker{
381
+			width: 100%;
382
+		}
383
+		div.date_picker input.el-range-input{
384
+			width: 46%;
385
+		}
386
+	}
387
+</style>

+ 132 - 0
CallCenterWeb.UI/src/views/outbound/plan/importTels.vue

@@ -0,0 +1,132 @@
1
+<template>
2
+  <div class="importTels">
3
+    <el-alert
4
+      title="选取的EXCEL文件需要严格按照下载的EXCEL模板进行填写!选择好文件后点击导入即可!"
5
+      type="warning"
6
+      class="md"
7
+      show-icon/>
8
+    <el-row>
9
+      <el-col :lg="7" class="md">
10
+        <a :href="downloadUrl" download="外呼号码导入模板.xlsx" class="download_btn" title="点击下载EXCEL模板" rel="nofollow">
11
+          下载EXCEL模板
12
+        </a>
13
+      </el-col>
14
+      <el-col :lg="17" class="md">
15
+        <el-upload
16
+          ref="upload"
17
+          :limit="1"
18
+          :file-list="uploadData.fileList"
19
+          :action= "uploadData.uploadUrl"
20
+          :data = "uploadData.uploaderFiles"
21
+          :on-success="uploadSuccess"
22
+          :on-error="uploadError"
23
+          :on-exceed="uploadExceed"
24
+          :auto-upload="false"
25
+          class="uploadFiles"
26
+          list-type="text"
27
+          name="upFile"
28
+          accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel">
29
+          <el-button slot="trigger" size="small" type="primary">选取EXCEL文件</el-button>
30
+          <el-button style="margin-left: 10px;" size="small" type="success" @click="submitUpload">导入</el-button>
31
+          <!-- <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div> -->
32
+        </el-upload>
33
+      </el-col>
34
+    </el-row>
35
+  </div>
36
+</template>
37
+
38
+<script>
39
+
40
+export default {
41
+  name: 'ImportTels',
42
+  props: {
43
+    rowid: {
44
+      type: String,
45
+      default: ''
46
+    },
47
+    layerid: {
48
+      type: String,
49
+      default: ''
50
+    }
51
+  },
52
+  data() {
53
+    return {
54
+      downloadUrl: '/static/xls/importPhonesTemplate.xlsx',
55
+      uploadData: {// 文件上传数据
56
+        uploadUrl: this.$store.getters.serverConfig.BASE_API + 'callcenterapi/api/autocallouttask/importexcel',
57
+        uploaderFiles: {// 上传文件的参数
58
+          taskid: this.rowid // 是	string	任务id
59
+        },
60
+        fileList: [] // 展示文件的数据
61
+      }
62
+    }
63
+  },
64
+  created() {
65
+  },
66
+  methods: {
67
+    submitUpload() {
68
+      this.$refs.upload.submit()
69
+    },
70
+    // 文件上传
71
+    uploadSuccess(response, file, fileList) {
72
+      if (response.state.toLowerCase() === 'success') {
73
+        this.$parent.$layer.close(this.layerid)
74
+        this.$parent.getListR() // 重新加载父级数据
75
+        this.$message.success('恭喜你,外呼号码导入成功!')
76
+      } else {
77
+        this.$message.error(response.message)
78
+      }
79
+    },
80
+    uploadExceed(file, fileList) {
81
+      this.$message.warning('只能选择一个文件!')
82
+    },
83
+    uploadError(err, file, fileList) {
84
+      this.$message.error(err)
85
+    }
86
+  }
87
+}
88
+</script>
89
+
90
+<style rel="stylesheet/scss" lang="scss">
91
+
92
+</style>
93
+<style rel="stylesheet/scss" lang="scss" scoped>
94
+	.importTels{
95
+		.md{
96
+			margin-bottom: 20px;
97
+		}
98
+		.download_btn{
99
+			display: inline-block;
100
+			line-height: 1;
101
+			white-space: nowrap;
102
+			cursor: pointer;
103
+			border: 1px solid #dcdfe6;
104
+			-webkit-appearance: none;
105
+			text-align: center;
106
+			-webkit-box-sizing: border-box;
107
+			box-sizing: border-box;
108
+			outline: 0;
109
+			margin: 0;
110
+			-webkit-transition: .1s;
111
+			transition: .1s;
112
+			font-weight: 500;
113
+			padding: 9px 15px;
114
+			font-size: 12px;
115
+			border-radius: 4px;
116
+			color: #fff;
117
+			background-color: #409EFF;
118
+			border-color: #409EFF;
119
+			&:hover{
120
+				background: #66b1ff;
121
+				border-color: #66b1ff;
122
+				color: #fff;
123
+			}
124
+			&:active{
125
+				background: #66b1ff;
126
+				border-color: #66b1ff;
127
+				color: #fff;
128
+			}
129
+		}
130
+	}
131
+
132
+</style>

+ 545 - 0
CallCenterWeb.UI/src/views/outbound/plan/index.vue

@@ -0,0 +1,545 @@
1
+<template>
2
+  <div class="app-container plan">
3
+    <el-row :gutter="20">
4
+      <el-col :md="14">
5
+        <el-alert
6
+          :closable="false"
7
+          title="外呼计划"
8
+          type="success"/>
9
+        <div class="filter-container">
10
+          <el-date-picker
11
+            v-model="searchDate"
12
+            :picker-options="pickerOptions"
13
+            class="filter-item"
14
+            type="daterange"
15
+            format="yyyy年MM月dd日"
16
+            value-format="yyyy-MM-dd"
17
+            align="left"
18
+            unlink-panels
19
+            range-separator="至"
20
+            start-placeholder="开始日期"
21
+            end-placeholder="结束日期"/>
22
+          <el-select v-model="sc_state" class="filter-item" filterable clearable placeholder="请选择任务状态">
23
+            <el-option
24
+              v-for="item in stateOptions"
25
+              :key="item.id"
26
+              :label="item.name"
27
+              :value="item.id"/>
28
+          </el-select>
29
+          <el-input v-model="keyword" placeholder="请输入计划名称" class="filter-item"/>
30
+          <el-button type="primary" class="filter-item" icon="el-icon-search" @click="btn_search">搜索</el-button>
31
+          <el-button v-permission="'HY_add'" type="primary" class="filter-item" icon="el-icon-plus" @click="btn_add">添加</el-button>
32
+        </div>
33
+        <el-table
34
+          v-loading="loadingL"
35
+          :data="planLists"
36
+          border
37
+          stripe
38
+          highlight-current-row
39
+          @row-click="handleTableClick">
40
+          <el-table-column type="index" label="编号" align="center" fixed width="60"/>
41
+          <el-table-column label="状态" width="100" align="center">
42
+            <template slot-scope="scope">
43
+              <el-tag
44
+                :type="scope.row.isstart | isstartTypeFilter"
45
+                size="mini"
46
+                disable-transitions>
47
+                {{ scope.row.isstart | isstartTextFilter }}
48
+              </el-tag>
49
+            </template>
50
+          </el-table-column>
51
+          <el-table-column label="上架状态" width="90" align="center">
52
+            <template slot-scope="scope">
53
+              <el-tag
54
+                :type="scope.row.isonline | isonlineTypeFilter"
55
+                size="mini"
56
+                disable-transitions>
57
+                {{ scope.row.isonline | isonlineTextFilter }}
58
+              </el-tag>
59
+            </template>
60
+          </el-table-column>
61
+          <el-table-column prop="taskname" label="计划名称" align="center" min-width=""/>
62
+          <el-table-column prop="taskremark" label="说明" align="center" min-width=""/>
63
+          <el-table-column prop="starttime" label="计划开始日期" align="center" min-width=""/>
64
+          <el-table-column prop="endtime" label="计划结束日期" align="center" min-width=""/>
65
+          <el-table-column prop="pager_name" label="关联问卷" align="center" min-width=""/>
66
+          <el-table-column label="操作" width="160" align="left" class-name="oparate_btn" fixed="right">
67
+            <template slot-scope="scope">
68
+              <el-button v-permission="'HY_upline'" v-show="scope.row.isstart === 0 && scope.row.isonline === 0" size="mini" type="text" @click.stop="btn_upline(scope.row.id, 1)">上架</el-button>
69
+              <el-button v-permission="'HY_downline'" v-show="scope.row.isstart === 0 && scope.row.isonline === 1" size="mini" type="text" @click.stop="btn_upline(scope.row.id, 0)">下架</el-button>
70
+              <el-button v-permission="'HY_edit'" v-show="scope.row.isstart < 3" size="mini" type="text" @click.stop="btn_edit(scope.row.id, scope.row.isstart)">编辑</el-button>
71
+              <el-button v-permission="'HY_start'" v-show="scope.row.isstart === 0 || scope.row.isstart === 2" size="mini" type="text" @click.stop="btn_oparate(scope.row.id, 1)">启动</el-button>
72
+              <el-button v-permission="'HY_stop'" v-show="scope.row.isstart < 3" size="mini" type="text" @click.stop="btn_oparate(scope.row.id, 11)">停止</el-button>
73
+              <el-button v-permission="'HY_pause'" v-show="scope.row.isstart === 1" size="mini" type="text" @click.stop="btn_oparate(scope.row.id, 10)">暂停</el-button>
74
+              <el-button v-permission="'HY_deleteL'" v-show="scope.row.isstart === 0" size="mini" type="text" @click.stop="btn_deleteL(scope.row.id)">删除</el-button>
75
+              <el-button v-permission="'HY_empty'" v-show="scope.row.isstart === 0" size="mini" type="text" @click.stop="btn_empty(scope.row.id)">清空号码</el-button>
76
+              <el-button v-permission="'HY_repeat'" v-show="scope.row.isstart === 3 && scope.row.secondflag === 0" size="mini" type="text" @click.stop="btn_repeat(scope.row.id)">重新执行</el-button>
77
+            </template>
78
+          </el-table-column>
79
+        </el-table>
80
+        <pagination
81
+          v-show="pageParamsL.total > 0"
82
+          :total="pageParamsL.total"
83
+          :pageindex.sync="pageParamsL.pageindex"
84
+          :pagesize.sync="pageParamsL.pagesize"
85
+          class="pagination"
86
+          @pagination="getListL" />
87
+      </el-col>
88
+      <el-col :md="10" style="overflow: auto;">
89
+        <el-alert
90
+          :closable="false"
91
+          title="外呼号码"
92
+          type="success"/>
93
+        <div class="filter-container">
94
+          <el-button v-permission="'HY_import'" type="primary" class="filter-item" @click="btn_import"><svg-icon icon-class="daoru" />导入</el-button>
95
+          <el-button v-permission="'HY_deleteRs'" type="primary" class="filter-item" icon="el-icon-delete" @click="btn_deletesR()">批量删除</el-button>
96
+        </div>
97
+        <el-table v-loading="loadingR" :data="telLists" border stripe @selection-change="changeSelects">
98
+          <el-table-column type="selection" width="40"/>
99
+          <el-table-column type="index" label="编号" align="center" fixed width="60"/>
100
+          <el-table-column prop="cusname" label="客户姓名" align="center" min-width=""/>
101
+          <el-table-column prop="phone" label="电话" align="center" min-width=""/>
102
+          <el-table-column prop="cusaddr" label="住址" align="center" min-width=""/>
103
+          <el-table-column prop="createtime" label="导入时间" align="center" min-width="120"/>
104
+          <el-table-column label="操作" width="" align="center" class-name="oparate_btn" fixed="right">
105
+            <template slot-scope="scope">
106
+              <el-button v-permission="'HY_deleteR'" size="mini" type="text" @click.stop="btn_deleteR(scope.row.id)">删除</el-button>
107
+            </template>
108
+          </el-table-column>
109
+        </el-table>
110
+        <pagination
111
+          v-show="pageParamsR.total > 0"
112
+          :total="pageParamsR.total"
113
+          :pageindex.sync="pageParamsR.pageindex"
114
+          :pagesize.sync="pageParamsR.pagesize"
115
+          class="pagination"
116
+          @pagination="getListR" />
117
+      </el-col>
118
+    </el-row>
119
+  </div>
120
+</template>
121
+
122
+<script>
123
+
124
+import { getPlanLists, deletePlan, getPlanTelLists, deletePlanTel, updateLine, oparatePlan, restart, emptyTels } from '@/api/outbound/plan'
125
+import addOrEdit from './addOrEdit'
126
+import importTels from './importTels'
127
+import { pickerOptions, formatterContent } from '@/utils'
128
+import Pagination from '@/components/Pagination' // 对el-pagination 二次封装
129
+
130
+export default {
131
+  name: 'Plan',
132
+  components: {
133
+    Pagination
134
+  },
135
+  filters: {
136
+    isstartTextFilter(status) {
137
+      const statusMap = {
138
+        0: '未启动',
139
+        1: '已启动',
140
+        2: '暂停',
141
+        3: '处理完成',
142
+        4: '撤销',
143
+        5: '完成'
144
+      }
145
+      return statusMap[status]
146
+    },
147
+    isstartTypeFilter(status) {
148
+      const statusMap = {
149
+        0: 'info',
150
+        1: '',
151
+        2: 'warning',
152
+        3: 'success',
153
+        4: 'danger',
154
+        5: 'success'
155
+      }
156
+      return statusMap[status]
157
+    },
158
+    isonlineTextFilter(status) {
159
+      const statusMap = {
160
+        0: '已下架',
161
+        1: '已上架'
162
+      }
163
+      return statusMap[status]
164
+    },
165
+    isonlineTypeFilter(status) {
166
+      const statusMap = {
167
+        0: 'danger',
168
+        1: 'success'
169
+      }
170
+      return statusMap[status]
171
+    }
172
+  },
173
+  data() {
174
+    return {
175
+      seatRealSateTimer: null, // 定时器
176
+      isStartTimer: false, // 定时器是否开启
177
+      loadingL: false,
178
+      loadingR: false,
179
+      planLists: [],
180
+      telLists: [],
181
+      pickerOptions, // 日期数据
182
+      searchDate: '', // 日期
183
+      stateOptions: [
184
+        { 'id': '0', 'name': '未启动' },
185
+        { 'id': '1', 'name': '已启动' },
186
+        { 'id': '2', 'name': '暂停' },
187
+        { 'id': '3', 'name': '处理完成' },
188
+        { 'id': '4', 'name': '撤销' },
189
+        { 'id': '5', 'name': '完成' }
190
+      ], // 任务状态数据
191
+      sc_state: '', // 任务状态
192
+      keyword: '', // 计划名称
193
+      pageParamsL: {
194
+        pageindex: 1, // 当前第几页
195
+        pagesize: Number(this.$store.getters.serverConfig.PAGESIZE), // 每页几条数据
196
+        total: 0 // 总共多少数据
197
+      },
198
+      pageParamsR: {
199
+        pageindex: 1, // 当前第几页
200
+        pagesize: Number(this.$store.getters.serverConfig.PAGESIZE), // 每页几条数据
201
+        total: 0 // 总共多少数据
202
+      },
203
+      multipleSelection: [], // 选中的数据
204
+      planId: '', // 计划id
205
+      planStates: '' // 计划的状态
206
+    }
207
+  },
208
+  created() {
209
+    this.getListL().then(() => {
210
+      // this.getListR();
211
+    })
212
+    document.onkeyup = (e) => {
213
+      if (e.keyCode === 13) {
214
+        this.getListL()
215
+      }
216
+    }
217
+  },
218
+  activated() {
219
+    // keep-alive 组件激活时调用。
220
+    // this.refreshDatas(process.env.taskRealInfoTime) // 刷新 监控数据
221
+    this.refreshDatas(Number(this.$store.getters.serverConfig.taskRealInfoTime)) // 刷新 监控数据
222
+    this.isStartTimer = true
223
+  },
224
+  methods: {
225
+    getListL() {
226
+      this.loadingL = true
227
+      return new Promise(resolve => {
228
+        const params = {
229
+          pageindex: this.pageParamsL.pageindex, // 第几页
230
+          pagesize: this.pageParamsL.pagesize, // 每页几条信息
231
+          key: this.keyword, //	否	string	任务名称,可模糊查询
232
+          taskstate: this.sc_state, //	否	int	任务状态 (不传值时查询所有状态)
233
+          stime: this.searchDate && this.searchDate[0], //	否	string	开始时间
234
+          etime: this.searchDate && this.searchDate[1] //	否	string	结束时间
235
+        }
236
+        getPlanLists(params).then(response => {
237
+          this.loadingL = false
238
+          if (response.state.toLowerCase() === 'success') {
239
+            this.pageParamsL.total = response.total
240
+            this.planLists = response.rows
241
+          }
242
+        })
243
+        resolve()
244
+      })
245
+    },
246
+    // 点击某一行的table
247
+    handleTableClick(row, event, column) {
248
+      this.planId = row.id
249
+      this.planStates = row.isstart
250
+      this.getListR()
251
+    },
252
+    btn_search() {
253
+      this.pageParamsL.pageindex = 1
254
+      this.getListL()
255
+    },
256
+    btn_add() {
257
+      this.$layer.iframe({
258
+        content: {
259
+          content: addOrEdit, // 传递的组件对象
260
+          parent: this, // 当前的vue对象
261
+          data: { 'rowid': '' }// props//该方法会自动添加一个key为layerid的值, 该值为创建层的id, 可以直接使用
262
+        },
263
+        area: ['50%', '90%'],
264
+        shadeClose: false,
265
+        title: '添加外呼计划'
266
+      })
267
+    },
268
+    btn_edit(dicid) {
269
+      this.$layer.iframe({
270
+        content: {
271
+          content: addOrEdit, // 传递的组件对象
272
+          parent: this, // 当前的vue对象
273
+          data: { 'rowid': dicid }// props//该方法会自动添加一个key为layerid的值, 该值为创建层的id, 可以直接使用
274
+        },
275
+        area: ['50%', '90%'],
276
+        shadeClose: false,
277
+        title: '编辑外呼计划'
278
+      })
279
+    },
280
+    btn_deleteL(dicid) {
281
+      this.$confirm('此操作将永久当前外呼计划吗, 是否继续?', '提示', {
282
+        confirmButtonText: '确定',
283
+        cancelButtonText: '取消',
284
+        type: 'warning'
285
+      }).then(() => {
286
+        deletePlan(dicid).then(response => {
287
+          if (response.state.toLowerCase() === 'success') {
288
+            this.getListL()
289
+            this.telLists = []
290
+            this.$message.success('删除成功!')
291
+          }
292
+        })
293
+      }).catch(() => {
294
+        this.$message.info('已取消删除')
295
+      })
296
+    },
297
+    btn_import() {
298
+      if (!this.planId) {
299
+        this.$message.warning('请先选择一个外呼计划!')
300
+        return
301
+      }
302
+      if (this.planStates > 0) {
303
+        this.$message.warning('该计划已经启动不能再导入号码!')
304
+        return
305
+      }
306
+      this.$layer.iframe({
307
+        content: {
308
+          content: importTels, // 传递的组件对象
309
+          parent: this, // 当前的vue对象
310
+          data: { 'rowid': this.planId }// props//该方法会自动添加一个key为layerid的值, 该值为创建层的id, 可以直接使用
311
+        },
312
+        area: ['40%', '380px'],
313
+        shadeClose: false,
314
+        title: '导入号码'
315
+      })
316
+    },
317
+
318
+    // 启动(上架) //停止(下架)
319
+    btn_upline(tid, tnum) {
320
+      const ctitle = tnum === 1 ? '您确定要上架当前计划吗?' : '您确定要下架当前计划吗?'
321
+      this.$confirm(ctitle, '提示', {
322
+        confirmButtonText: '确定',
323
+        cancelButtonText: '取消',
324
+        type: 'warning'
325
+      }).then(() => {
326
+        const data = {
327
+          'taskid': tid, // 是	string	任务id
328
+          'state': tnum // 是	int	状态(传值0为下线,传1为上线)
329
+        }
330
+        updateLine(data).then(response => {
331
+          if (response.state.toLowerCase() === 'success') {
332
+            this.getListL()
333
+            this.telLists = []
334
+            const cmsg = tnum === 1 ? '当前计划上架成功' : '当前计划下架成功'
335
+            this.$message.success(cmsg)
336
+          }
337
+        })
338
+      }).catch(() => {
339
+        this.$message.info('已取消操作')
340
+      })
341
+    },
342
+
343
+    // 任务操作类型(1为启动,10为暂停,11为停止)
344
+    btn_oparate(tid, tnum) {
345
+      let ctitle = ''
346
+      let cmsg = ''
347
+      switch (tnum) {
348
+        case 1:
349
+          ctitle = '请您确定已经导入外呼号码,否则启动后无法呼出号码!'
350
+          cmsg = '当前计划启动成功!'
351
+          break
352
+        case 10:
353
+          ctitle = '您确定要暂停当前计划吗?'
354
+          cmsg = '当前计划暂停成功!'
355
+          break
356
+        case 11:
357
+          ctitle = '您确定要停止当前计划吗?'
358
+          cmsg = '当前计划停止成功!'
359
+          break
360
+        default:
361
+          break
362
+      }
363
+      this.$confirm(ctitle, '提示', {
364
+        confirmButtonText: '确定',
365
+        cancelButtonText: '取消',
366
+        type: 'warning'
367
+      }).then(() => {
368
+        const data = {
369
+          'taskid': tid, // 是	string	任务id
370
+          'type': tnum // 是	int	任务操作类型(1为启动,10为暂停,11为停止)
371
+        }
372
+        oparatePlan(data).then(response => {
373
+          if (response.state.toLowerCase() === 'success') {
374
+            this.getListL()
375
+            this.telLists = []
376
+            this.$message.success(cmsg)
377
+          }
378
+        })
379
+      }).catch(() => {
380
+        this.$message.info('已取消操作')
381
+      })
382
+    },
383
+
384
+    // 外呼计划  未呼通号码重新执行
385
+    btn_repeat(tid) {
386
+      this.$confirm('您确定要重新执行当前计划下未呼通的号码吗?', '提示', {
387
+        confirmButtonText: '确定',
388
+        cancelButtonText: '取消',
389
+        type: 'warning'
390
+      }).then(() => {
391
+        restart(tid).then(response => {
392
+          if (response.state.toLowerCase() === 'success') {
393
+            this.getListL()
394
+            this.telLists = []
395
+            this.$message.success('未呼通号码重新执行成功!')
396
+          }
397
+        })
398
+      }).catch(() => {
399
+        this.$message.info('已取消操作')
400
+      })
401
+    },
402
+
403
+    // 外呼计划 清空号码
404
+    btn_empty(tid) {
405
+      this.$confirm('您确定要清空当前计划下的号码吗?', '提示', {
406
+        confirmButtonText: '确定',
407
+        cancelButtonText: '取消',
408
+        type: 'warning'
409
+      }).then(() => {
410
+        emptyTels(tid).then(response => {
411
+          if (response.state.toLowerCase() === 'success') {
412
+            this.getListL()
413
+            this.telLists = []
414
+            this.$message.success('清空号码成功!')
415
+          }
416
+        })
417
+      }).catch(() => {
418
+        this.$message.info('已取消操作')
419
+      })
420
+    },
421
+
422
+    // 外呼号码列表
423
+    getListR() {
424
+      this.loadingR = true
425
+      return new Promise(resolve => {
426
+        const params = {
427
+          pageindex: this.pageParamsR.pageindex, // 第几页
428
+          pagesize: this.pageParamsR.pagesize, // 每页几条信息
429
+          taskid: this.planId // 否	string	任务id
430
+        }
431
+        getPlanTelLists(params).then(response => {
432
+          this.loadingR = false
433
+          if (response.state.toLowerCase() === 'success') {
434
+            this.pageParamsR.total = response.total
435
+            this.telLists = response.rows
436
+          }
437
+        })
438
+        resolve()
439
+      })
440
+    },
441
+
442
+    // 复选框状态改变
443
+    changeSelects(val) {
444
+      this.multipleSelection = val
445
+    },
446
+
447
+    btn_deleteR(dicid) {
448
+      if (this.planStates > 0) {
449
+        this.$alert('该计划已经启动不能再删除号码!', '提示', {
450
+          confirmButtonText: '确定',
451
+          type: 'warning',
452
+          callback: action => {}
453
+        })
454
+        return
455
+      }
456
+      this.$confirm('此操作将永久删除当前外呼号码, 是否继续?', '提示', {
457
+        confirmButtonText: '确定',
458
+        cancelButtonText: '取消',
459
+        type: 'warning'
460
+      }).then(() => {
461
+        deletePlanTel(dicid).then(response => {
462
+          if (response.state.toLowerCase() === 'success') {
463
+            this.getListR()
464
+            this.$message.success('删除成功!')
465
+          }
466
+        })
467
+      }).catch(() => {
468
+        this.$message.info('已取消删除')
469
+      })
470
+    },
471
+    btn_deletesR() {
472
+      const ids = []
473
+      for (let i = 0, len = this.multipleSelection.length; i < len; i++) {
474
+        ids.push(this.multipleSelection[i].id)
475
+      }
476
+      if (ids.length <= 0) {
477
+        this.$message.warning('没有可删除的选项')
478
+        return
479
+      }
480
+      this.btn_deleteR(ids)
481
+    },
482
+    /**
483
+		* 刷新 数据
484
+		* @mTime 刷新间隔
485
+		* */
486
+    refreshDatas(mTime) {
487
+      const _self = this
488
+      const objTime = {
489
+        init: 0,
490
+        time: function() {
491
+          objTime.init += 1000
492
+          // 当页面没有click、keydown、mousewheel 时;每间隔  mTime 刷新数据;
493
+          if (objTime.init === mTime) {
494
+            // console.count()
495
+            _self.getListL()
496
+            _self.telLists = []
497
+            objTime.init = 0
498
+          }
499
+        },
500
+        eventFun: function() {
501
+          clearInterval(_self.seatRealSateTimer)
502
+          objTime.init = 0
503
+          if (_self.isStartTimer) {
504
+            _self.seatRealSateTimer = setInterval(objTime.time, 1000)
505
+          }
506
+        }
507
+      }
508
+      this.seatRealSateTimer = setInterval(objTime.time, 1000)
509
+      const body = document.querySelector('html')
510
+      body.addEventListener('click', objTime.eventFun)
511
+      body.addEventListener('keydown', objTime.eventFun)
512
+      body.addEventListener('mousewheel', objTime.eventFun)
513
+    }
514
+  },
515
+
516
+  beforeRouteLeave(to, from, next) {
517
+    // 导航离开该组件的对应路由时调用
518
+    // 可以访问组件实例 `this`
519
+    clearInterval(this.seatRealSateTimer)
520
+    this.isStartTimer = false
521
+    next()
522
+  }
523
+}
524
+</script>
525
+
526
+<!-- 需要注意的是,修改elementUI的默认样式的css不能使用scoped. -->
527
+<style rel="stylesheet/scss" lang="scss">
528
+	.plan{
529
+		.el-table tr{
530
+			cursor: pointer;
531
+		}
532
+		.el-table__body tr.current-row>td {
533
+			background: rgba(185, 221, 249, .75);
534
+		}
535
+		.filter-container {
536
+			padding-top: 15px;
537
+		}
538
+		.el-button+.el-button{
539
+			margin-left: 0;
540
+		}
541
+	}
542
+</style>
543
+<style rel="stylesheet/scss" lang="scss" scoped>
544
+
545
+</style>

+ 235 - 0
CallCenterWeb.UI/src/views/outbound/tasks/components/tabTask.vue

@@ -0,0 +1,235 @@
1
+<template>
2
+  <div>
3
+    <el-table
4
+      v-loading="loading"
5
+      :data="dataLists.slice(( this.pageParams.pageindex-1)* this.pageParams.pagesize, this.pageParams.pageindex* this.pageParams.pagesize)"
6
+      border
7
+      stripe>
8
+      <el-table-column type="index" label="编号" align="center" fixed width="60"/>
9
+      <el-table-column label="状态" width="100" align="center">
10
+        <template slot-scope="scope">
11
+          <el-tag :type="scope.row.isstart | isstartTypeFilter" size="mini" disable-transitions>
12
+            {{ scope.row.isstart | isstartTextFilter }}
13
+          </el-tag>
14
+        </template>
15
+      </el-table-column>
16
+      <el-table-column prop="taskname" label="计划名称" align="center" min-width="160"/>
17
+      <el-table-column prop="totalnum" label="号码数量" align="center"/>
18
+      <el-table-column prop="surplusnum" label="剩余数量" align="center"/>
19
+      <el-table-column prop="callnum" label="已呼叫数量" align="center"/>
20
+      <el-table-column prop="successnum" label="接通数量" align="center"/>
21
+      <el-table-column prop="agentnum" label="坐席数量" align="center"/>
22
+      <el-table-column prop="successpercent" label="接通率" align="center"/>
23
+      <el-table-column prop="agentsuccessnum" label="坐席接通数量" align="center"/>
24
+      <el-table-column prop="agentsuccesspercent" label="坐席接通率" align="center"/>
25
+      <el-table-column prop="starttime" label="任务开始日期" min-width="100" align="center"/>
26
+      <el-table-column label="任务结束日期" min-width="100" align="center">
27
+        <template slot-scope="scope">
28
+          <span :class="scope.row.endtime | endtimeFilter">{{ scope.row.endtime }}</span>
29
+        </template>
30
+      </el-table-column>
31
+      <el-table-column prop="createtime" label="创建时间" min-width="110" align="center"/>
32
+      <el-table-column label="操作" width="180" align="center" class-name="oparate_btn" fixed="right">
33
+        <template slot-scope="scope">
34
+          <el-tooltip class="item" effect="dark" content="点击取消坐席参与资格" placement="top-start">
35
+            <el-button v-permission="'HY_cancle'" size="mini" circle type="primary" plain @click="btn_cancle(scope.row.id)">
36
+              <svg-icon icon-class="saoraolanjie"/>
37
+            </el-button>
38
+          </el-tooltip>
39
+          <el-tooltip class="item" effect="dark" content="点击打开实时监控" placement="top-start">
40
+            <el-button v-permission="'HY_monitoring'" size="mini" circle type="primary" plain @click="btn_monitoring(scope.row.id)">
41
+              <svg-icon icon-class="shuju3"/>
42
+            </el-button>
43
+          </el-tooltip>
44
+          <el-tooltip class="item" effect="dark" content="点击导出已接通号码" placement="top-start">
45
+            <el-button v-permission="'HY_export'" size="mini" circle type="primary" plain @click="btn_export(scope.row.id, 1)">
46
+              <svg-icon icon-class="daochu"/>
47
+            </el-button>
48
+          </el-tooltip>
49
+          <el-tooltip class="item" effect="dark" content="点击导出未接通号码" placement="top-start">
50
+            <el-button v-permission="'HY_export'" size="mini" circle type="primary" plain @click="btn_export(scope.row.id, 0)">
51
+              <i class="el-icon-upload2"/>
52
+            </el-button>
53
+          </el-tooltip>
54
+        </template>
55
+      </el-table-column>
56
+    </el-table>
57
+    <pagination
58
+      v-show="pageParams.total > 0"
59
+      :total="pageParams.total"
60
+      :pageindex.sync="pageParams.pageindex"
61
+      :pagesize.sync="pageParams.pagesize"
62
+      class="pagination"
63
+      @pagination="getList" />
64
+
65
+  </div>
66
+</template>
67
+
68
+<script>
69
+import { endtimeFilter } from '@/utils'
70
+import { getTaskLists, cancelJoin } from '@/api/outbound/tasks'
71
+
72
+import { mapGetters } from 'vuex'
73
+import store from '@/store'
74
+import Pagination from '@/components/Pagination' // 对el-pagination 二次封装
75
+
76
+export default {
77
+  name: 'TabTask',
78
+  components: {
79
+    Pagination
80
+  },
81
+  filters: {
82
+    isstartTextFilter(status) {
83
+      const statusMap = {
84
+        0: '未启动',
85
+        1: '已启动',
86
+        2: '暂停',
87
+        3: '处理完成',
88
+        4: '撤销',
89
+        5: '完成'
90
+      }
91
+      return statusMap[status]
92
+    },
93
+    isstartTypeFilter(status) {
94
+      const statusMap = {
95
+        0: 'info',
96
+        1: '',
97
+        2: 'warning',
98
+        3: 'success',
99
+        4: 'danger',
100
+        5: 'success'
101
+      }
102
+      return statusMap[status]
103
+    }
104
+  },
105
+  props: {
106
+    searchDatas: {
107
+      type: Object,
108
+      default: function() {}
109
+    }
110
+  },
111
+  data() {
112
+    return {
113
+      loading: false,
114
+      pageParams: {
115
+        pageindex: 1, // 当前第几页
116
+        pagesize: Number(this.$store.getters.serverConfig.PAGESIZE), // 每页几条数据
117
+        total: 0 // 总共多少数据
118
+      },
119
+      dataLists: [] // 列表数据
120
+    }
121
+  },
122
+  computed: {
123
+    ...mapGetters([
124
+      'usercode'
125
+    ])
126
+  },
127
+  created() {
128
+    this.getList()
129
+  },
130
+  methods: {
131
+    getList() {
132
+      this.loading = true
133
+      return new Promise(resolve => {
134
+        const params = {
135
+          pageindex: this.pageParams.pageindex, // 第几页
136
+          pagesize: this.pageParams.pagesize, // 每页几条信息
137
+          infokind: this.searchDatas.ishistory, // 否	int	查询类型(为0或不传时获取全部,为1时获取当前任务,为2时获取历史任务)
138
+          isstart: this.searchDatas.sc_state, //	否	int	任务状态 (不传值时查询所有状态)
139
+          stime: this.searchDatas.searchDate && this.searchDatas.searchDate[0], //	否	string	开始时间
140
+          etime: this.searchDatas.searchDate && this.searchDatas.searchDate[1], //	否	string	结束时间
141
+          agentid: this.searchDatas.seatId, // 否	string	坐席工号(不传值查询全部坐席)
142
+          taskname: this.searchDatas.keyword //	否	string	计划名称,可模糊查询
143
+        }
144
+        getTaskLists(params).then(response => {
145
+          this.loading = false
146
+          if (response.state.toLowerCase() === 'success') {
147
+            switch (this.searchDatas.ishistory) {
148
+              case 0:
149
+                this.pageParams.total = response.total
150
+                break
151
+              case 1:
152
+                this.pageParams.total = response.dqnum
153
+                break
154
+              case 2:
155
+                this.pageParams.total = response.lsnum
156
+                break
157
+              default:
158
+                break
159
+            }
160
+            this.dataLists = response.rows
161
+            if (response.total >= 100) {
162
+              response.total = '99+'
163
+            }
164
+            if (response.dqnum >= 100) {
165
+              response.dqnum = '99+'
166
+            }
167
+            if (response.lsnum >= 100) {
168
+              response.lsnum = '99+'
169
+            }
170
+            // 修改父组件的值
171
+            this.$emit('getTotalNums', {
172
+              totalcount: response.total, // 全部
173
+              wfpcount: response.dqnum, // 当前任务
174
+              fpcount: response.lsnum // 历史任务
175
+            })
176
+          }
177
+        })
178
+        resolve()
179
+      })
180
+    },
181
+
182
+    // 取消坐席参与资格
183
+    btn_cancle(tid) {
184
+      if (!this.searchDatas.seatId) {
185
+        this.$message.warning('请选择您要取消参与资格的坐席!')
186
+        return
187
+      }
188
+      this.$confirm(`此操作将取消坐席工号为${this.searchDatas.seatId}的参与资格, 是否继续?`, '提示', {
189
+        confirmButtonText: '确定',
190
+        cancelButtonText: '取消',
191
+        type: 'warning'
192
+      }).then(() => {
193
+        const datas = {
194
+          'taskid': tid, //	是	string	任务id
195
+          'agentid': this.searchDatas.seatId, //	是	string	坐席工号
196
+          'joinflag': 0 //	是	int	参与标志(1为参与,0为不参与)
197
+        }
198
+        cancelJoin(datas).then(response => {
199
+          if (response.state.toLowerCase() === 'success') {
200
+            this.$message.success(`坐席工号为${this.searchDatas.seatId}的参与资格取消成功!`)
201
+            // 更新右上角信息
202
+            if (this.searchDatas.seatId === this.usercode) {
203
+              store.dispatch('ChangeTaskInfo', true)
204
+            }
205
+            this.searchDatas.seatId = ''
206
+            this.getList()
207
+          }
208
+        })
209
+      }).catch(() => {
210
+        this.$message.info('操作已取消')
211
+      })
212
+    },
213
+    // 导出已接通或者未接通  0=导出未接通号码 1=导出已接通号码
214
+    btn_export(tid, type) {
215
+      window.location.href =
216
+					`${this.$store.getters.serverConfig.BASE_API}callcenterapi/api/autocallouttask/exportexcel?taskid=${tid}&calloutok=${type}`
217
+    },
218
+    // 跳转到自动外呼监控
219
+    btn_monitoring(tid) {
220
+      // this.$router.push({ name: 'autoCallMonitor', params: { tid: tid}});
221
+      this.$router.push({
222
+        path: '/autoCallMonitor',
223
+        query: {
224
+          tid: tid
225
+        }
226
+      })
227
+    }
228
+
229
+  }
230
+}
231
+</script>
232
+
233
+<style rel="stylesheet/scss" lang="scss" scoped>
234
+
235
+</style>

+ 231 - 0
CallCenterWeb.UI/src/views/outbound/tasks/index.vue

@@ -0,0 +1,231 @@
1
+<template>
2
+  <div class="app-container tasks">
3
+    <div class="filter-container">
4
+      <el-date-picker
5
+        v-model="searchDatas.searchDate"
6
+        :picker-options="pickerOptions"
7
+        class="filter-item"
8
+        type="daterange"
9
+        format="yyyy年MM月dd日"
10
+        value-format="yyyy-MM-dd"
11
+        align="left"
12
+        unlink-panels
13
+        range-separator="至"
14
+        start-placeholder="开始日期"
15
+        end-placeholder="结束日期"/>
16
+      <el-select v-model="searchDatas.sc_state" class="filter-item" filterable clearable placeholder="请选择任务状态">
17
+        <el-option v-for="item in stateOptions" :key="item.id" :label="item.name" :value="item.id"/>
18
+      </el-select>
19
+      <el-select v-model="searchDatas.seatId" class="filter-item" filterable clearable placeholder="请选择坐席" @change="updateList">
20
+        <el-option v-for="item in seatOptions" :key="item.id" :label="item.usercode + '-' + item.username" :value="item.usercode"/>
21
+      </el-select>
22
+      <el-input v-model="searchDatas.keyword" placeholder="请输入计划名称" class="filter-item"/>
23
+      <el-button type="primary" class="filter-item" icon="el-icon-search" @click="btn_search">搜索</el-button>
24
+    </div>
25
+    <el-tabs v-model="activeName" @tab-click="handleClick" v-if="flag" >
26
+      <el-tab-pane v-for="item in tabMapOptions" :key="item.key" :name="item.key">
27
+        <span slot="label">{{ item.label }}<span :class="item.listclass">({{ item.num }})</span></span>
28
+        <tabTask v-if="activeName===item.key" ref="tabtask" :search-datas="searchDatas" @getTotalNums="getTotalNum"/>
29
+      </el-tab-pane>
30
+    </el-tabs>
31
+  </div>
32
+</template>
33
+
34
+<script>
35
+import {
36
+  getNowDate,
37
+  getFirstDayInCurrentMonth,
38
+  pickerOptions
39
+} from '@/utils'
40
+import {
41
+  getSeatLists
42
+} from '@/api/telCall/seatMonitor'
43
+import tabTask from './components/tabTask'
44
+import { getTaskLists } from '@/api/outbound/tasks'
45
+export default {
46
+  name: 'Tasks',
47
+  components: {
48
+    tabTask
49
+  },
50
+  data() {
51
+    return {
52
+      pickerOptions, // 日期数据
53
+      stateOptions: [{
54
+        'id': '0',
55
+        'name': '未启动'
56
+      },
57
+      {
58
+        'id': '1',
59
+        'name': '已启动'
60
+      },
61
+      {
62
+        'id': '2',
63
+        'name': '暂停'
64
+      },
65
+      {
66
+        'id': '3',
67
+        'name': '处理完成'
68
+      },
69
+      {
70
+        'id': '4',
71
+        'name': '撤销'
72
+      },
73
+      {
74
+        'id': '5',
75
+        'name': '完成'
76
+      }
77
+      ], // 任务状态数据
78
+      searchDatas: {
79
+        searchDate: [getFirstDayInCurrentMonth(), getNowDate()], // 日期
80
+        sc_state: '', // 任务状态
81
+        seatId: '', // 坐席
82
+        keyword: '', // 计划名称
83
+        ishistory: 0
84
+      },
85
+      flag:false,
86
+      pageParams: {
87
+        pageindex: 1, // 当前第几页
88
+        pagesize: Number(this.$store.getters.serverConfig.PAGESIZE), // 每页几条数据
89
+        total: 0 // 总共多少数据
90
+      },
91
+      seatOptions: [], // 坐席下拉数据
92
+      activeName: 'first',
93
+      tabMapOptions: [{
94
+        label: '全部',
95
+        key: 'first',
96
+        num: 0,
97
+        listclass: 'list_all'
98
+      },
99
+      {
100
+        label: '当前任务',
101
+        key: 'second',
102
+        num: 0,
103
+        listclass: 'list_wait'
104
+      },
105
+      {
106
+        label: '历史任务',
107
+        key: 'third',
108
+        num: 0,
109
+        listclass: 'list_done'
110
+      }
111
+      ]
112
+    }
113
+  },
114
+  created() {
115
+    this.getSeatSelects()
116
+    this.getCurrentList()
117
+  },
118
+  mounted() {
119
+    document.onkeyup = (e) => {
120
+      if (e.keyCode === 13) {
121
+        this.$refs.tabtask[0].getList()
122
+      }
123
+    }
124
+  },
125
+  methods: {
126
+    handleClick(tab, event) {
127
+      switch (tab.name) {
128
+        case 'first':
129
+          this.searchDatas.ishistory = 0
130
+          break
131
+        case 'second':
132
+          this.searchDatas.ishistory = 1
133
+          break
134
+        case 'third':
135
+          this.searchDatas.ishistory = 2
136
+          break
137
+        default:
138
+          break
139
+      }
140
+    },
141
+
142
+    btn_search() {
143
+      this.$refs.tabtask[0].pageParams.pageindex = 1
144
+      this.$refs.tabtask[0].getList()
145
+    },
146
+
147
+    // 从子组件获取的 数量值
148
+    getTotalNum(value) {
149
+      this.tabMapOptions[0].num = value.totalcount // 全部
150
+      this.tabMapOptions[1].num = value.wfpcount // 当前任务
151
+      this.tabMapOptions[2].num = value.fpcount // 历史任务
152
+    },
153
+    //获取列表数据数字
154
+    getCurrentList() {
155
+      return new Promise(resolve => {
156
+        const params = {
157
+          pageindex: this.pageParams.pageindex, // 第几页
158
+          pagesize: this.pageParams.pagesize, // 每页几条信息
159
+          infokind: this.searchDatas.ishistory, // 否	int	查询类型(为0或不传时获取全部,为1时获取当前任务,为2时获取历史任务)
160
+          isstart: this.searchDatas.sc_state, //	否	int	任务状态 (不传值时查询所有状态)
161
+          stime: this.searchDatas.searchDate && this.searchDatas.searchDate[0], //	否	string	开始时间
162
+          etime: this.searchDatas.searchDate && this.searchDatas.searchDate[1], //	否	string	结束时间
163
+          agentid: this.searchDatas.seatId, // 否	string	坐席工号(不传值查询全部坐席)
164
+          taskname: this.searchDatas.keyword //	否	string	计划名称,可模糊查询
165
+        }
166
+        getTaskLists(params).then(response => {
167
+          if (response.state.toLowerCase() === 'success') {
168
+            switch (this.searchDatas.ishistory) {
169
+              case 0:
170
+                this.pageParams.total = response.total
171
+                break
172
+              case 1:
173
+                this.pageParams.total = response.dqnum
174
+                break
175
+              case 2:
176
+                this.pageParams.total = response.lsnum
177
+                break
178
+              default:
179
+                break
180
+            }
181
+            if (response.total >= 100) {
182
+              response.total = '99+'
183
+            }
184
+            if (response.dqnum >= 100) {
185
+              response.dqnum = '99+'
186
+            }
187
+            if (response.lsnum >= 100) {
188
+              response.lsnum = '99+'
189
+            }
190
+            this.tabMapOptions[0].num = response.total // 全部
191
+            this.tabMapOptions[1].num = response.dqnum // 当前任务
192
+            this.tabMapOptions[2].num = response.lsnum // 历史任务
193
+            this.flag=true
194
+          }
195
+        })
196
+        resolve()
197
+      })
198
+    },
199
+    updateList() {
200
+      this.$refs.tabtask[0].getList()
201
+    },
202
+
203
+    // 获取坐席下拉
204
+    getSeatSelects() {
205
+      getSeatLists().then(response => {
206
+        if (response.state.toLowerCase() === 'success') {
207
+          this.seatOptions = response.data
208
+        }
209
+      })
210
+    }
211
+
212
+  }
213
+}
214
+</script>
215
+
216
+<style rel="stylesheet/scss" lang="scss">
217
+
218
+</style>
219
+<style rel="stylesheet/scss" lang="scss" scoped>
220
+	.tasks {
221
+		.list_all {}
222
+
223
+		.list_wait {
224
+			color: #febd23;
225
+		}
226
+
227
+		.list_done {
228
+			color: #5ccb91;
229
+		}
230
+	}
231
+</style>

+ 20 - 5
CallCenterWeb.UI/src/views/systemSetup/roleSetting/department/component/addOrEdit.vue

@@ -16,6 +16,15 @@
16 16
       <el-form-item label="分类名称" prop="deptname">
17 17
         <el-input v-model="ruleForm.deptname" placeholder="请输入分类名称"/>
18 18
       </el-form-item>
19
+      <el-form-item v-if="addEditLock" label="是否锁定:" prop="islock" >
20
+        <el-radio-group v-model="ruleForm.islock">
21
+          <el-radio label="0">否</el-radio>
22
+          <el-radio label="1">是</el-radio>
23
+        </el-radio-group>
24
+      </el-form-item>
25
+      <el-form-item label="任务额:" prop="targetmoney">
26
+        <el-input v-model="ruleForm.targetmoney" type="text" autosize placeholder="请输入任务额"/>
27
+      </el-form-item>
19 28
       <el-form-item label="排列序号" prop="sort">
20 29
         <el-input v-model.number="ruleForm.sort" placeholder="请输入排列序号"/>
21 30
       </el-form-item>
@@ -32,8 +41,8 @@ export default{
32 41
   name: 'AddOrEditKnowledge',
33 42
   props: {
34 43
     rowid: {
35
-      type: Number,
36
-      default: 0
44
+      type: String,
45
+      default: ''
37 46
     },
38 47
     layerid: {
39 48
       type: String,
@@ -48,7 +57,9 @@ export default{
48 57
         parentid: '', // 父节点id
49 58
         deptid: '', // 当前节点id
50 59
         sort: '', // 序号
51
-        deptname: '' // 分类名称
60
+        deptname: '', // 分类名称
61
+        islock: '', //是否锁定
62
+        targetmoney: '', //任务额
52 63
       },
53 64
       rules: {
54 65
         sort: [
@@ -67,12 +78,14 @@ export default{
67 78
         label: 'text'
68 79
       },
69 80
       addEditJudgment: false, // 添加flase 编辑true
81
+      addEditLock: true, //添加true 编辑false
70 82
     }
71 83
   },
72 84
   created() {
73 85
     this.getTypeDrop().then(() => {
74 86
       if (this.rowid) {
75 87
         this.addEditJudgment = true
88
+        this.addEditLock = false
76 89
         this.ruleForm.deptid = this.rowid
77 90
         this.getTypeDetails(this.rowid)
78 91
       }
@@ -97,6 +110,8 @@ export default{
97 110
           const res = response.data.model
98 111
           this.ruleForm.deptname = res.F_DeptName // 分类名称
99 112
           this.ruleForm.sort = res.F_Sort // 排序
113
+          this.ruleForm.islock = res.F_Lock + '' // 排序
114
+          this.ruleForm.sort = res.F_TargetMoney // 排序
100 115
           this.ruleForm.parentid = res.F_ParentId // 父节点id
101 116
           const len = response.data.levelid.length
102 117
           const levelid = response.data.levelid
@@ -116,7 +131,7 @@ export default{
116 131
               this.loading = false
117 132
               if (response.state.toLowerCase() === 'success') {
118 133
                 this.$parent.$layer.close(this.layerid)
119
-                this.$parent.getTreeLists() // 重新加载父级数据
134
+                this.$parent.getDepList() // 重新加载父级数据
120 135
                 this.$message.success('恭喜你,添加成功!')
121 136
               }
122 137
             }).catch(() => {
@@ -130,7 +145,7 @@ export default{
130 145
             if (response.state.toLowerCase() === 'success') {
131 146
               this.$parent.treeclickId=0;
132 147
               this.$parent.$layer.close(this.layerid)
133
-              this.$parent.getTreeLists() // 重新加载父级数据
148
+              this.$parent.getDepList() // 重新加载父级数据
134 149
               this.$message.success('恭喜你,编辑成功!')
135 150
             }
136 151
           }).catch(() => {

+ 9 - 3
CallCenterWeb.UI/src/views/systemSetup/roleSetting/department/component/addOrEditTeam.vue

@@ -10,6 +10,9 @@
10 10
       <el-form-item label="描述说明:" prop="des">
11 11
         <el-input v-model="ruleForm.des" type="textarea" autosize placeholder="请输入描述说明"/>
12 12
       </el-form-item>
13
+      <el-form-item label="任务额:" prop="targetmoney">
14
+        <el-input v-model="ruleForm.targetmoney" type="text" autosize placeholder="请输入任务额"/>
15
+      </el-form-item>
13 16
       <el-form-item>
14 17
         <el-button type="primary" @click="submitForm">保存</el-button>
15 18
         <el-button @click="resetForm">重置</el-button>
@@ -53,7 +56,8 @@ export default {
53 56
         id: '',
54 57
         position: '',
55 58
         department: [],
56
-        des: ''
59
+        des: '',
60
+        targetmoney: '',
57 61
       },
58 62
       rules: {
59 63
         position: [{
@@ -79,8 +83,9 @@ export default {
79 83
           this.loading = true
80 84
           const datas = {
81 85
             id: this.ruleForm.id,
82
-            name:this.ruleForm.position,
83
-            deptid:this.depId,
86
+            name: this.ruleForm.position,
87
+            deptid: this.depId,
88
+            targetmoney: this.ruleForm.targetmoney,
84 89
             des: filterContent.delHtmlTag(this.ruleForm.des)
85 90
           }
86 91
 
@@ -129,6 +134,7 @@ export default {
129 134
           const res = response.data
130 135
           this.ruleForm.position = res.F_Name
131 136
           this.ruleForm.des = res.F_Des
137
+          this.ruleForm.targetmoney = res.F_TargetMoney
132 138
         }
133 139
       })
134 140
     },

+ 84 - 74
CallCenterWeb.UI/src/views/systemSetup/roleSetting/department/index.vue

@@ -8,30 +8,48 @@
8 8
           <el-button type="primary" class="filter-item" icon="el-icon-delete" @click="btn_delete()">删除</el-button>
9 9
         </div>
10 10
         <el-alert :closable="false" title="部门分类" type="success"/>
11
-        <el-tree
12
-          ref="treeRef"
13
-          :data="treelists"
14
-          :default-expand-all="defaultExpandAll"
15
-          :expand-on-click-node="expandOnNode"
16
-          node-key="id"
17
-          check-strictly
18
-          highlight-current
19
-          @node-click="treeNodeClick"/>
11
+        <el-table 
12
+        v-loading="loading" 
13
+        :data="departmentDataLists"
14
+        highlight-current-row
15
+        @current-change="handleCurrentChange" 
16
+        border
17
+        row-key="F_DeptId"
18
+        default-expand-all
19
+        :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
20
+        @selection-change="changeSelects">
21
+          <el-table-column type="selection" width="40" fixed></el-table-column>
22
+          <el-table-column prop="F_DeptName" label="部门名称" align="center" min-width=""/>
23
+          <el-table-column prop="F_Lock" label="锁定" align="center" min-width="">
24
+            <template slot-scope="scope">
25
+              {{ scope.row.F_Lock | judgmentLockName }}
26
+            </template>
27
+          </el-table-column>
28
+          <el-table-column prop="F_TargetMoney" label="任务额" align="center" min-width="">
29
+            <template slot-scope="scope">
30
+              {{ scope.row.F_TargetMoney | judgmentTargetMoney }}
31
+            </template>
32
+          </el-table-column>
33
+        </el-table>
20 34
       </el-col>
21 35
       <el-col :span="16">
22
-        <div >
36
+        <div>
23 37
           <div class="filter-container search">
24 38
             <el-input v-model="keyword" placeholder="请输入关键字" class="filter-item"/>
25 39
             <el-button type="primary" class="filter-item" icon="el-icon-search" @click="btn_search">搜索</el-button>
26 40
             <el-button v-permission="'HY_add'" type="primary" class="filter-item" icon="el-icon-plus" @click="btn_addR">添加</el-button>
27 41
           </div>
28
-
29 42
           <el-table v-loading="loading" :data="dataLists" border stripe>
30 43
             <el-table-column type="index" label="编号" align="center" fixed width="80"/>
31 44
             <el-table-column prop="F_DeptName" label="部门名称" align="center" min-width=""/>
32 45
             <el-table-column prop="F_Name" label="团队名称" align="center" min-width=""/>
33 46
             <el-table-column prop="F_CreateBy" label="创建人" align="center" min-width=""/>
34 47
             <el-table-column prop="F_CreateOn" label="创建时间" align="center" min-width=""/>
48
+            <el-table-column prop="F_TargetMoney" label="任务额" align="center" min-width="">
49
+              <template slot-scope="scope">
50
+                {{ scope.row.F_TargetMoney | judgmentTargetMoney }}
51
+              </template>
52
+            </el-table-column>
35 53
             <el-table-column prop="F_Des" label="描述说明" align="center" min-width=""/>
36 54
             <el-table-column label="操作" width="160" align="center" class-name="oparate_btn" fixed="right">
37 55
               <template slot-scope="scope">
@@ -53,7 +71,7 @@
53 71
   </div>
54 72
 </template>
55 73
 <script>
56
-import { getTreeList, getScoreList, deleteType, deleteScore } from '@/api/systemSetup/roleSetting/department'
74
+import { getScoreList, deleteType, deleteScore, getDepartmentList } from '@/api/systemSetup/roleSetting/department'
57 75
 import { getTeamLists, deleteTeam, getDepidTeam } from '@/api/systemSetup/sysSetting/teamManagement'
58 76
 import addOrEditKnowledge from './component/addOrEdit'
59 77
 import addOrEditTeam from './component/addOrEditTeam'
@@ -62,26 +80,40 @@ export default {
62 80
   components: {
63 81
     Pagination
64 82
   },
83
+  filters: {
84
+    judgmentLockName(status) {
85
+      const statusMap = {
86
+        '0': '未锁定',
87
+        '1': '锁定',
88
+      }
89
+      return statusMap[status]
90
+    },
91
+    judgmentTargetMoney(status) {
92
+      if (status == 0) {
93
+        return ''
94
+      } else {
95
+        return status
96
+      }
97
+    }
98
+  },
65 99
   data() {
66 100
     return {
67 101
       keyword: '',
68
-      treelists: [], // 分类树列表
69
-      treeclickId: 0,
102
+      selectedId: [],
70 103
       depId: 0,//最后一级部门id
71 104
       depName: '',//最后一级部门名称
72
-      defaultExpandAll: true,
73
-      expandOnNode: false,
74 105
       loading: false,
75 106
       pageParams: {
76 107
         pageindex: 1, // 当前第几页
77 108
         pagesize: Number(this.$store.getters.serverConfig.PAGESIZE), // 每页几条数据
78 109
         total: 0 // 总共多少数据
79 110
       },
80
-      dataLists: [] // 团队管理列表数据
111
+      dataLists: [], // 团队管理列表数据
112
+      departmentDataLists: [], //部门列表数据
81 113
     }
82 114
   },
83 115
   created() {
84
-    this.getTreeLists()// 分类指标
116
+    this.getDepList() //部门列表
85 117
     this.getList()// 团队管理数据
86 118
     document.onkeyup = (e) => {
87 119
         if (e.keyCode === 13) {
@@ -92,13 +124,21 @@ export default {
92 124
   mounted: function() {
93 125
   },
94 126
   methods: {
95
-    // 分类树
96
-    getTreeLists() {
127
+    // 部门分类
128
+    getDepList() {
129
+      this.loading = true
97 130
       return new Promise(resolve => {
98
-        getTreeList().then(response => {
99
-          if (response.state.toLowerCase() === 'success') {
100
-            this.treelists = this.buildTree(response.data)
101
-          }
131
+        const params = {
132
+          pageindex: this.pageParams.pageindex, // 第几页
133
+          pagesize: this.pageParams.pagesize, // 每页几条信息
134
+          keyword: this.keyword.trim(),
135
+        }
136
+        getDepartmentList(params).then(response => {
137
+          this.loading = false
138
+          this.departmentDataLists = response
139
+        }).catch(result=>{
140
+          this.loading = false
141
+          this.departmentDataLists=[]
102 142
         })
103 143
         resolve()
104 144
       })
@@ -118,18 +158,19 @@ export default {
118 158
     },
119 159
 		//编辑
120 160
     btn_edit() {
121
-      if (this.treeclickId === 0) {
161
+      if (this.selectedId.length !== 1) {
122 162
         this.$message({
123 163
           message: '请选择一行编辑!',
124 164
           type: 'warning'
125 165
         })
126 166
         return
127 167
       }
168
+      let rowId = this.selectedId[0]
128 169
       this.$layer.iframe({
129 170
         content: {
130 171
           content: addOrEditKnowledge, // 传递的组件对象
131 172
           parent: this, // 当前的vue对象
132
-          data: { rowid: this.treeclickId } // props//该方法会自动添加一个key为layerid的值, 该值为创建层的id, 可以直接使用
173
+          data: { rowid: rowId } // props//该方法会自动添加一个key为layerid的值, 该值为创建层的id, 可以直接使用
133 174
         },
134 175
         area: ['80%', '90%'],
135 176
         shadeClose: false,
@@ -138,13 +179,14 @@ export default {
138 179
     },
139 180
     //删除
140 181
     btn_delete() {
141
-      if (this.treeclickId === 0) {
182
+      if (this.selectedId.length === 0) {
142 183
         this.$message({
143 184
           message: '没有可删除的选项!',
144 185
           type: 'warning'
145 186
         })
146 187
       } else {
147
-        this.deleteType(this.treeclickId)
188
+        let ids = this.selectedId.join(',')
189
+        this.deleteType(this.selectedId)
148 190
       }
149 191
     },
150 192
     //删除
@@ -157,9 +199,8 @@ export default {
157 199
         .then(() => {
158 200
           deleteType(ids).then(response => {
159 201
             if (response.state.toLowerCase() === 'success') {
160
-              this.getTreeLists()
202
+              this.getDepList()
161 203
               this.$message.success('删除成功!')
162
-              this.treeclickId=0
163 204
             }
164 205
           })
165 206
         })
@@ -167,55 +208,24 @@ export default {
167 208
           this.$message.info('已取消删除')
168 209
         })
169 210
     },
170
-    buildTree(list) {
171
-      const temp = {}
172
-      const tree = {}
173
-      for (const j in list) {
174
-        temp[list[j].id] = list[j]
175
-      }
176
-
177
-      for (const i in temp) {
178
-        if (temp[i].parentid) {
179
-          if (!temp[temp[i].parentid].children) {
180
-            temp[temp[i].parentid].children = []
181
-          }
182
-          temp[temp[i].parentid].children[temp[i].id] = temp[i]
183
-        } else {
184
-          tree[temp[i].id] = temp[i]
185
-        }
186
-      }
187
-      return this.filterTreeDatas(tree)
188
-    },
189
-    // 处理数据格式
190
-    filterTreeDatas(treeDatas) {
191
-      const accessedRouters = []
192
-      let j = -1
193
-      for (const i in treeDatas) {
194
-        j++
195
-        accessedRouters.push({
196
-          id: treeDatas[i].id,
197
-          label: treeDatas[i].text,
198
-          children: []
199
-        })
200
-        if (treeDatas[i].children) {
201
-          accessedRouters[j].children = this.filterTreeDatas(
202
-            treeDatas[i].children
203
-          )
204
-        }
211
+    changeSelects(val) {
212
+      const ids = []
213
+      this.multipleSelection = val
214
+      for (let i=0; i<this.multipleSelection.length; i++) {
215
+        ids.push(this.multipleSelection[i].F_DeptId)
205 216
       }
206
-      return accessedRouters
217
+      this.selectedId = ids;
207 218
     },
208
-    treeNodeClick(data) {
209
-      this.treeclickId = data.id
210
-      if (data.id !== 0) {
211
-        this.depId = data.id
212
-        console.log(data)
213
-        this.depName = data.label
219
+    handleCurrentChange(data) {
220
+      if (data.F_DeptId !== 0) {
221
+        this.depId = data.F_DeptId
222
+        this.depName = data.F_DeptName
214 223
         this.getList()
215 224
       } else {
216 225
         this.depId = 0
217 226
       }
218 227
     },
228
+
219 229
     //获取团队列表数据
220 230
     getList() {
221 231
       this.loading = true
@@ -250,7 +260,7 @@ export default {
250 260
             parent: this, // 当前的vue对象
251 261
             data: {'depId':this.depId,'depName':this.depName }// props//该方法会自动添加一个key为layerid的值, 该值为创建层的id, 可以直接使用
252 262
           },
253
-          area: ['40%', '320px'],
263
+          area: ['80%', '80%'],
254 264
           title: '添加团队管理信息'
255 265
         })
256 266
       }else{
@@ -266,7 +276,7 @@ export default {
266 276
             parent: this, // 当前的vue对象
267 277
             data: { 'rowid': editId,'depId':this.depId,'depName':this.depName}// props
268 278
           },
269
-          area: ['40%', '320px'],
279
+          area: ['80%', '80%'],
270 280
           title: '编辑团队管理信息'
271 281
         })
272 282
       } else {