|
@@ -0,0 +1,432 @@
|
|
1
|
+<template>
|
|
2
|
+ <div v-loading="loading" class="corpCustomerCountStat">
|
|
3
|
+ <div class="screenBox">
|
|
4
|
+ <!-- 企微主体 -->
|
|
5
|
+ <div class="common-screen-item">
|
|
6
|
+ <label class="common-screen-label">企微主体</label>
|
|
7
|
+ <!-- 系统管理员 -->
|
|
8
|
+ <el-cascader v-if="$cookie.getCookie('isSuperManage') == 1" v-model="system_enterprise" size="small" :options="enterpriseList" :props="{value:'self_id',label:'self_name',children:'manage_corp_list'}" @change="onChangeCorpidSystem" clearable filterable placeholder="请选择" class="select-cls cascader" />
|
|
9
|
+ <!-- 非系统管理员 -->
|
|
10
|
+ <el-select v-else v-model="corpid" size="small" filterable placeholder="请选择" @change="onChangeCorpid" clearable class="select-cls">
|
|
11
|
+ <el-option v-for="(item, index) in enterpriseList" :key="index+'enterpriseList'" :label="item.corp_name?item.corp_name:item.corp_full_name?item.corp_full_name:item.corpid" :value="item.corpid" />
|
|
12
|
+ </el-select>
|
|
13
|
+ </div>
|
|
14
|
+ <!-- 搜索客户 -->
|
|
15
|
+ <self-input :reset='resetFlag' @inputChange='(val)=>{input_keyword = val;init()}' />
|
|
16
|
+ <!-- 添加时间 -->
|
|
17
|
+ <date-picker :reset='resetFlag' @changeTime="changeTime" />
|
|
18
|
+ <!-- 添加渠道 -->
|
|
19
|
+ <selfChannelMultiple :reset='resetFlag' @channelDefine="onChangeAddWay" />
|
|
20
|
+ <!-- 性别-->
|
|
21
|
+ <self-gender :reset='resetFlag' @genderChange="(val)=>{gender = val;init()}" />
|
|
22
|
+ <!-- 流失状态 -->
|
|
23
|
+ <loss-body :reset='resetFlag' @lossChange="lossChange" />
|
|
24
|
+ <!-- 付费情况 -->
|
|
25
|
+ <screen-pay :reset='resetFlag' @payChange="payChange" />
|
|
26
|
+ <!-- 充值时间 -->
|
|
27
|
+ <date-picker :reset='resetFlag' title="充值时间" @changeTime="onChangePayTime" />
|
|
28
|
+ <!-- 流失时间 -->
|
|
29
|
+ <date-picker :reset='resetFlag' title="流失时间" timeFlag :pickerOptions="{}" :defaultTime="['00:00:00', '23:59:59']" @changeTime="onChangeLossTime" />
|
|
30
|
+ <!-- 是否新用户 -->
|
|
31
|
+ <selfChannelV2 v-model="is_new_customer_no_loss" type='isNewCustomerNoLoss' title="是否新用户" @change="onChangeIsNewCus" />
|
|
32
|
+ <!-- 可否接收消息 -->
|
|
33
|
+ <selfChannelV2 v-model="can_receive" type='canReceive' title="可否接收消息" @change="onChangeCanReceive" />
|
|
34
|
+ <!-- 是否单主体流失 -->
|
|
35
|
+ <selfChannelV2 v-model="retained_status" type='retainedStatus' title="单主体留存" @change="onChangeRetainedStatus" />
|
|
36
|
+
|
|
37
|
+ <div class="flex">
|
|
38
|
+ <el-button v-if="isCanExport" class="export-btn" type="primary" plain size="mini" @click="init('export')">导出Excel</el-button>
|
|
39
|
+ <div class="reset" @click="resetEvent">重置</div>
|
|
40
|
+ </div>
|
|
41
|
+ </div>
|
|
42
|
+
|
|
43
|
+ <!-- table -->
|
|
44
|
+ <el-table ref="multipleTable" :height='height' :data="tableData" stripe tooltip-effect="dark" style="width: 100%; margin-top: 10px;">
|
|
45
|
+ <el-table-column label="企微主体" show-overflow-tooltip align="center">
|
|
46
|
+ <template slot-scope="scope">
|
|
47
|
+ <div>{{scope.row.corp_name}}</div>
|
|
48
|
+ </template>
|
|
49
|
+ </el-table-column>
|
|
50
|
+ <el-table-column label="客户数" show-overflow-tooltip align="center">
|
|
51
|
+ <template slot-scope="scope">
|
|
52
|
+ <div>{{scope.row.customer_count}}</div>
|
|
53
|
+ </template>
|
|
54
|
+ </el-table-column>
|
|
55
|
+ </el-table>
|
|
56
|
+ </div>
|
|
57
|
+</template>
|
|
58
|
+<script>
|
|
59
|
+import selfInput from '@/components/assembly/screen/input.vue'
|
|
60
|
+import selfCustomerservice from '@/components/assembly/screen/customerService.vue'
|
|
61
|
+import enterpriseTag from '@/components/assembly/screen/enterpriseTag.vue'
|
|
62
|
+import datePicker from '@/components/assembly/screen/datePicker.vue'
|
|
63
|
+import selfChannel from '@/components/assembly/screen/channel.vue'
|
|
64
|
+import selfChannelMultiple from '@/components/assembly/screen/channelMultiple.vue'
|
|
65
|
+import selfChannelV2 from '@/components/assembly/screen/channelV2.vue'
|
|
66
|
+import selfGender from '@/components/assembly/screen/gender.vue'
|
|
67
|
+import lossBody from '@/components/assembly/screen/lossBody.vue'
|
|
68
|
+import screenPay from '@/components/assembly/screen/pay.vue'
|
|
69
|
+import shieldingUser from '@/components/assembly/shieldingUser.vue'
|
|
70
|
+import tagDialog from '@/components/assembly/tagDialog.vue'
|
|
71
|
+import detial from '@/components/detials/index.vue'
|
|
72
|
+import noData from "../assembly/noData";
|
|
73
|
+export default {
|
|
74
|
+ components: { tagDialog, detial, selfInput, selfCustomerservice, enterpriseTag, datePicker, selfChannel, selfChannelMultiple, selfChannelV2, selfGender, lossBody, screenPay, shieldingUser, noData },
|
|
75
|
+ data () {
|
|
76
|
+ return {
|
|
77
|
+ drawerSize: '60%',
|
|
78
|
+ detialDrawer: false,
|
|
79
|
+ rowPro: {},//去详情的此条对象
|
|
80
|
+ loading: false,
|
|
81
|
+ shieldingFlag: false,
|
|
82
|
+ input_keyword: '',
|
|
83
|
+ tableData: [],
|
|
84
|
+ add_way: [],//客户来源
|
|
85
|
+ is_new_customer_no_loss: '', // 是否新用户
|
|
86
|
+ can_receive: '', // 可否接收消息
|
|
87
|
+ retained_status: '', // 是否单主体内全部流失
|
|
88
|
+ add_date_start: '',//添加日期 起始
|
|
89
|
+ add_date_end: '',//添加日期 截止
|
|
90
|
+ last_pay_time_start: '',//充值时间 起始
|
|
91
|
+ last_pay_time_end: '',//充值时间 截止
|
|
92
|
+ loss_time_start: '',//流失时间 起始
|
|
93
|
+ loss_time_end: '',//流失时间 截止
|
|
94
|
+ loss_status: null,//客户流失状态 没有筛选时传null 0未流失 1已流失
|
|
95
|
+ pay_status: null,// 付款状态 没有筛选时传null 0未付款 1已付款
|
|
96
|
+ pay_num_min: '',//最小付款次数,当pay_status是1时必传
|
|
97
|
+ pay_num_max: '',//最大付款次数,当pay_status是1时必传
|
|
98
|
+ resetFlag: false,//重置
|
|
99
|
+ multipleArr: [],
|
|
100
|
+ filter_multipleArr: [],
|
|
101
|
+ selectTotal: 0,
|
|
102
|
+ gender: '',
|
|
103
|
+ height: '',
|
|
104
|
+ tips: '',
|
|
105
|
+ system_enterprise: [], // 企微主体数据
|
|
106
|
+ enterpriseList: [], // 企微主体数据
|
|
107
|
+ enterprise: {}, // 当前选择的企微信息
|
|
108
|
+ corpid: '',
|
|
109
|
+ }
|
|
110
|
+ },
|
|
111
|
+ computed: {
|
|
112
|
+ // 是否有“导出”权限
|
|
113
|
+ isCanExport() {
|
|
114
|
+ return !!this.$store.state.dataBoardAuth.can_export
|
|
115
|
+ },
|
|
116
|
+ },
|
|
117
|
+ created () {
|
|
118
|
+ this.height = document.documentElement.clientHeight - 140 > 140 ? document.documentElement.clientHeight - 140 : 140
|
|
119
|
+ this.init()
|
|
120
|
+ this.handleInitCorpOptions()
|
|
121
|
+ },
|
|
122
|
+ methods: {
|
|
123
|
+ resetEvent () {//重置
|
|
124
|
+ this.resetFlag = !this.resetFlag
|
|
125
|
+ this.input_keyword = '';
|
|
126
|
+ this.add_way = [];
|
|
127
|
+ this.is_new_customer_no_loss = '';
|
|
128
|
+ this.can_receive = '';
|
|
129
|
+ this.retained_status = '';
|
|
130
|
+ this.add_date_start = '';
|
|
131
|
+ this.add_date_end = '';
|
|
132
|
+ this.last_pay_time_start = '';
|
|
133
|
+ this.last_pay_time_end = '';
|
|
134
|
+ this.loss_time_start = '';
|
|
135
|
+ this.loss_time_end = '';
|
|
136
|
+ this.loss_status = null;
|
|
137
|
+ this.pay_status = null;
|
|
138
|
+ this.pay_num_min = '';
|
|
139
|
+ this.pay_num_max = '';
|
|
140
|
+ this.gender = '';
|
|
141
|
+ this.corp_id = '';
|
|
142
|
+ this.init()
|
|
143
|
+ },
|
|
144
|
+ // S 企微主体数据
|
|
145
|
+ onChangeCorpidSystem(val) {//二级联选择器
|
|
146
|
+ if (val.length < 1) {
|
|
147
|
+ this.enterprise = {}
|
|
148
|
+ } else {
|
|
149
|
+ this.enterpriseList.forEach((item) => {
|
|
150
|
+ item.manage_corp_list.forEach((item1) => {
|
|
151
|
+ if (item1.corpid == val[1]) {
|
|
152
|
+ this.enterprise = item1
|
|
153
|
+ }
|
|
154
|
+ })
|
|
155
|
+ })
|
|
156
|
+ }
|
|
157
|
+ this.corpid = this.enterprise.corpid || ''
|
|
158
|
+ this.init()
|
|
159
|
+ },
|
|
160
|
+ onChangeCorpid(val) {
|
|
161
|
+ if (!val) {
|
|
162
|
+ this.enterprise = {}
|
|
163
|
+ } else {
|
|
164
|
+ const res = this.enterpriseList.filter(v => v.corpid == val)[0];
|
|
165
|
+ this.enterprise = res || {}
|
|
166
|
+ }
|
|
167
|
+ this.corpid = this.enterprise.corpid || ''
|
|
168
|
+ this.init()
|
|
169
|
+ },
|
|
170
|
+ // 企业筛选初始化
|
|
171
|
+ handleInitCorpOptions() {
|
|
172
|
+ if (this.$cookie.getCookie('isSuperManage') == 1) {//系统管理员
|
|
173
|
+ const enterpriseList = this.$store.state.authorize_corpList;
|
|
174
|
+ enterpriseList.forEach(item => {//为了el-cascader更改props
|
|
175
|
+ item.self_id = item.group_id.toString();
|
|
176
|
+ item.self_name = item.group_name;
|
|
177
|
+ item.manage_corp_list.forEach(item1 => {
|
|
178
|
+ item1.self_id = item1.corpid;
|
|
179
|
+ item1.self_name = item1.corp_name;
|
|
180
|
+ })
|
|
181
|
+ });
|
|
182
|
+ this.enterpriseList = enterpriseList
|
|
183
|
+ } else {
|
|
184
|
+ this.enterpriseList = this.$store.state.authorize_corpList;
|
|
185
|
+ }
|
|
186
|
+ },
|
|
187
|
+ // E 企微主体数据
|
|
188
|
+
|
|
189
|
+ payChange (data) {//付费情况变化
|
|
190
|
+ this.pay_status = data.radio;
|
|
191
|
+ this.pay_num_min = data.minValue;
|
|
192
|
+ this.pay_num_max = data.maxValue;
|
|
193
|
+ this.init()
|
|
194
|
+ },
|
|
195
|
+ lossChange (val) {//筛选流失状态变化
|
|
196
|
+ if (val == '') {
|
|
197
|
+ this.loss_status = null
|
|
198
|
+ } else {
|
|
199
|
+ this.loss_status = val
|
|
200
|
+ }
|
|
201
|
+ this.init()
|
|
202
|
+ },
|
|
203
|
+ changeTime (time) {//筛选时间变化
|
|
204
|
+ if (!time || time && time.length == 0) {
|
|
205
|
+ this.add_date_start = '';
|
|
206
|
+ this.add_date_end = '';
|
|
207
|
+ } else {
|
|
208
|
+ this.add_date_start = time[0]
|
|
209
|
+ this.add_date_end = time[1]
|
|
210
|
+ }
|
|
211
|
+ this.init()
|
|
212
|
+ },
|
|
213
|
+ // 监听“充值时间”筛选变化
|
|
214
|
+ onChangePayTime (time) {
|
|
215
|
+ if (!time || time && time.length == 0) {
|
|
216
|
+ this.last_pay_time_start = '';
|
|
217
|
+ this.last_pay_time_end = '';
|
|
218
|
+ } else {
|
|
219
|
+ this.last_pay_time_start = time[0]
|
|
220
|
+ this.last_pay_time_end = time[1]
|
|
221
|
+ }
|
|
222
|
+ this.init()
|
|
223
|
+ },
|
|
224
|
+ // 监听“流失时间”筛选变化
|
|
225
|
+ onChangeLossTime (time) {
|
|
226
|
+ if (!time || time && time.length == 0) {
|
|
227
|
+ this.loss_time_start = '';
|
|
228
|
+ this.loss_time_end = '';
|
|
229
|
+ } else {
|
|
230
|
+ this.loss_time_start = time[0]
|
|
231
|
+ this.loss_time_end = time[1]
|
|
232
|
+ }
|
|
233
|
+ this.init()
|
|
234
|
+ },
|
|
235
|
+ // 监听“添加渠道”筛选变化
|
|
236
|
+ onChangeAddWay (val) {
|
|
237
|
+ this.add_way = val
|
|
238
|
+ this.init()
|
|
239
|
+ },
|
|
240
|
+ // 监听“是否新用户”筛选变化
|
|
241
|
+ onChangeIsNewCus (val) {
|
|
242
|
+ this.is_new_customer_no_loss = val
|
|
243
|
+ this.init()
|
|
244
|
+ },
|
|
245
|
+ // 监听“可否接收消息”筛选变化
|
|
246
|
+ onChangeCanReceive (val) {
|
|
247
|
+ this.can_receive = val
|
|
248
|
+ this.init()
|
|
249
|
+ },
|
|
250
|
+ // 监听"是否单主体完全流失"筛选变化
|
|
251
|
+ onChangeRetainedStatus(val) {
|
|
252
|
+ this.retained_status = val
|
|
253
|
+ this.init()
|
|
254
|
+ },
|
|
255
|
+ init (type) {
|
|
256
|
+ if (type == 'export' && this.tableData.length == 0) {
|
|
257
|
+ this.$message({
|
|
258
|
+ message: '暂无数据可导出',
|
|
259
|
+ type: "warning"
|
|
260
|
+ })
|
|
261
|
+ return
|
|
262
|
+
|
|
263
|
+ }
|
|
264
|
+ this.loading = true
|
|
265
|
+ this.$axios.get(this.URL.BASEURL + this.URL.dataBoard_corpCustomerCountStat, {
|
|
266
|
+ params: {
|
|
267
|
+ corp_id: this.corpid,
|
|
268
|
+ customer_name: this.input_keyword,
|
|
269
|
+ add_date_start: this.add_date_start,
|
|
270
|
+ add_date_end: this.add_date_end,
|
|
271
|
+ last_pay_time_start: this.last_pay_time_start,
|
|
272
|
+ last_pay_time_end: this.last_pay_time_end,
|
|
273
|
+ loss_time_start: this.loss_time_start,
|
|
274
|
+ loss_time_end: this.loss_time_end,
|
|
275
|
+ add_way: this.add_way,
|
|
276
|
+ is_new_customer_no_loss: this.is_new_customer_no_loss,
|
|
277
|
+ can_receive: this.can_receive,
|
|
278
|
+ retained_status: this.retained_status,
|
|
279
|
+ pay_status: this.pay_status,
|
|
280
|
+ pay_num_min: this.pay_num_min,
|
|
281
|
+ pay_num_max: this.pay_num_max,
|
|
282
|
+ loss_status: this.loss_status,
|
|
283
|
+ source: 1,
|
|
284
|
+ gender: this.gender
|
|
285
|
+ }
|
|
286
|
+ }).then((res) => {
|
|
287
|
+ var res = res.data
|
|
288
|
+ this.loading = false
|
|
289
|
+ if (res && res.errno == 0) {
|
|
290
|
+ if (type == 'export') {
|
|
291
|
+ this.exportEvent(res.rst)
|
|
292
|
+ } else {
|
|
293
|
+ this.tableData = res.rst;
|
|
294
|
+ }
|
|
295
|
+ } else if (res.errno != 4002) {
|
|
296
|
+ this.$message({
|
|
297
|
+ message: res.err,
|
|
298
|
+ type: "warning"
|
|
299
|
+ })
|
|
300
|
+ }
|
|
301
|
+ }).catch((err) => {
|
|
302
|
+ this.loading = false
|
|
303
|
+ });
|
|
304
|
+ },
|
|
305
|
+ exportEvent (data) {
|
|
306
|
+ let list = data;
|
|
307
|
+ let tHeader = ['企微主体', '客户数']
|
|
308
|
+ let filterVal = ['corp_name', 'customer_count']
|
|
309
|
+ let excelDatas = [
|
|
310
|
+ {
|
|
311
|
+ tHeader: tHeader, // sheet表一头部
|
|
312
|
+ filterVal: filterVal, // 表一的数据字段
|
|
313
|
+ tableDatas: list, // 表一的整体json数据
|
|
314
|
+ sheetName: ''// 表一的sheet名字
|
|
315
|
+ }
|
|
316
|
+ ]
|
|
317
|
+ this.$exportOrder({ excelDatas, name: `企微客户数统计(导出时间:${this.$getDay(0)})` })
|
|
318
|
+ },
|
|
319
|
+ }
|
|
320
|
+}
|
|
321
|
+</script>
|
|
322
|
+<style lang="scss" scoped>
|
|
323
|
+@import "@/style/list.scss";
|
|
324
|
+.corpCustomerCountStat{
|
|
325
|
+ .screenBox {
|
|
326
|
+ background: #fff;
|
|
327
|
+ // padding: 5px 20px 26px;
|
|
328
|
+ padding: 5px 20px 10px;
|
|
329
|
+ position: relative;
|
|
330
|
+ .export-btn {
|
|
331
|
+ position: absolute;
|
|
332
|
+ top: 17px;
|
|
333
|
+ right: 4px;
|
|
334
|
+ }
|
|
335
|
+ }
|
|
336
|
+
|
|
337
|
+ .con{
|
|
338
|
+ position: relative;
|
|
339
|
+ .flex{
|
|
340
|
+ display: flex;
|
|
341
|
+ position: sticky;
|
|
342
|
+ top: 0px;
|
|
343
|
+ margin-left: 10px;
|
|
344
|
+ height: 60px;
|
|
345
|
+ background-color: white;
|
|
346
|
+ }
|
|
347
|
+ .theads{
|
|
348
|
+ background: #FBFBFB;
|
|
349
|
+ border: 1px solid #EBEEF5;
|
|
350
|
+ font-size: 14px;
|
|
351
|
+ color: #666;
|
|
352
|
+ display: flex;
|
|
353
|
+ align-items: center;
|
|
354
|
+ position: sticky;
|
|
355
|
+ top: 60px;
|
|
356
|
+ .thead_item{
|
|
357
|
+ // width: 20%;
|
|
358
|
+ flex: 1;
|
|
359
|
+ padding: 16px;
|
|
360
|
+ color: #666;
|
|
361
|
+ background-color: #fbfbfb;
|
|
362
|
+ border-right: 1px solid #EBEEF5;
|
|
363
|
+ }
|
|
364
|
+ }
|
|
365
|
+ .tbodys{
|
|
366
|
+ .tbody_item{
|
|
367
|
+ display: flex;
|
|
368
|
+ align-items: center;
|
|
369
|
+ color: #333;
|
|
370
|
+ font-size: 13px;
|
|
371
|
+ border: 1px solid #EBEEF5;
|
|
372
|
+ border-top: none;
|
|
373
|
+ div{
|
|
374
|
+ // width: 20%;
|
|
375
|
+ flex: 1;
|
|
376
|
+ word-break:break-all;
|
|
377
|
+ border-right: 1px solid #EBEEF5;
|
|
378
|
+ padding: 16px;
|
|
379
|
+ }
|
|
380
|
+ .c-00B38A{
|
|
381
|
+ color: #00B38A;
|
|
382
|
+ }
|
|
383
|
+ }
|
|
384
|
+ }
|
|
385
|
+ }
|
|
386
|
+ .tips-wrap {
|
|
387
|
+ background-color: #fff;
|
|
388
|
+ margin-bottom: 5px;
|
|
389
|
+ margin-top: 5px;
|
|
390
|
+ padding: 5px 15px;
|
|
391
|
+ display: flex;
|
|
392
|
+ align-items: flex-start;
|
|
393
|
+ font-size: 13px;
|
|
394
|
+ color: #666;
|
|
395
|
+ line-height: 16px;
|
|
396
|
+ i {
|
|
397
|
+ font-size: 14px;
|
|
398
|
+ font-weight: 600;
|
|
399
|
+ margin-right: 4px;
|
|
400
|
+ margin-top: 1px;
|
|
401
|
+ }
|
|
402
|
+ }
|
|
403
|
+ .select-cls {
|
|
404
|
+ /deep/ .el-input__inner {
|
|
405
|
+ width: 210px;
|
|
406
|
+ }
|
|
407
|
+ /deep/ &.el-select .el-input.is-focus .el-input__inner,
|
|
408
|
+ /deep/ &.el-select .el-input__inner:focus,
|
|
409
|
+ /deep/ &.el-cascader .el-input.is-focus .el-input__inner,
|
|
410
|
+ /deep/ &.el-cascader .el-input__inner:focus {
|
|
411
|
+ border-color: #DCDFE6;
|
|
412
|
+ }
|
|
413
|
+ /deep/ .el-input__suffix {
|
|
414
|
+ border-top-right-radius: 4px;
|
|
415
|
+ border-bottom-right-radius: 4px;
|
|
416
|
+ border: 1px solid #DCDFE6;
|
|
417
|
+ right: 0;
|
|
418
|
+ width: 30px;
|
|
419
|
+ background-color: #F1F1F1;
|
|
420
|
+ .el-input__icon {
|
|
421
|
+ color: #909399;
|
|
422
|
+ }
|
|
423
|
+ }
|
|
424
|
+ &.cascader {
|
|
425
|
+ /deep/ .el-input__suffix {
|
|
426
|
+ height: 32px;
|
|
427
|
+ top: 2px;
|
|
428
|
+ }
|
|
429
|
+ }
|
|
430
|
+ }
|
|
431
|
+}
|
|
432
|
+</style>
|