xiuli.gao hace 1 año
padre
commit
55b1114613
Se han modificado 77 ficheros con 860 adiciones y 85 borrados
  1. 1 1
      index.html
  2. 2 0
      project/src/assets/config/interface_api.js
  3. 22 0
      project/src/assets/js/staticTypes.js
  4. 16 3
      project/src/components/assembly/screen/channel.vue
  5. 16 3
      project/src/components/assembly/screen/channelMultiple.vue
  6. 63 0
      project/src/components/assembly/screen/inputV2.vue
  7. 0 1
      project/src/components/dataBoard/adqAccount/list.vue
  8. 511 0
      project/src/components/dataBoard/customerStaff/index.vue
  9. 155 0
      project/src/components/dataBoard/customerStaff/setStatusDialog.vue
  10. 0 4
      project/src/components/dataBoard/operator/operatorData.vue
  11. 0 4
      project/src/components/dataBoard/operator/operatorWxAccount.vue
  12. 0 2
      project/src/components/dataBoard/platformPromote/promoteLink.vue
  13. 0 2
      project/src/components/dataBoard/platformPromote/promotePlaylet.vue
  14. 0 1
      project/src/components/manage/memberComp/batchAssign.vue
  15. 0 1
      project/src/components/manage/memberComp/transferDialog.vue
  16. 0 3
      project/src/components/manage/memberManage.vue
  17. 13 0
      project/src/router/allRouter.js
  18. 1 1
      static/css/app.e5dd51ca05ddc817f8fc3a38e6e7b50b.css
  19. 9 0
      static/js/0.15901049091b96623f7b.js
  20. 0 9
      static/js/0.472945da217b40b2958a.js
  21. 0 1
      static/js/10.5e856c33b456a9232857.js
  22. 1 1
      static/js/12.7c78f26cbc8bac4a96d1.js
  23. 0 1
      static/js/11.3985a84e1aa24ab7b755.js
  24. 1 1
      static/js/13.f833ee5299653d62fe64.js
  25. 1 1
      static/js/14.02744e555ec18048618b.js
  26. 1 1
      static/js/15.5121236387a21d879569.js
  27. 1 1
      static/js/16.4b79d4d4331728d4178b.js
  28. 1 1
      static/js/17.79c43f4ab0a4ade2fbd6.js
  29. 1 0
      static/js/16.e2ff89462cf9407a11c7.js
  30. 1 0
      static/js/17.60ef7946bc76dd41008a.js
  31. 1 1
      static/js/20.bb85bc9181588ac2a3e1.js
  32. 0 0
      static/js/3.7c3ccbbb9c2e1a3a5d1d.js
  33. 0 0
      static/js/31.3c4503cdfaf2cff83edd.js
  34. 0 1
      static/js/42.97f362b97d99c023935f.js
  35. 1 0
      static/js/42.9ca6c58d101af30d4a03.js
  36. 1 1
      static/js/45.4dc80c069c611e3cf21d.js
  37. 0 1
      static/js/44.b8d91f609271eba18bd8.js
  38. 1 0
      static/js/45.88200280168fa664b52b.js
  39. 1 0
      static/js/47.24c33c86e95e98fe62f1.js
  40. 1 1
      static/js/47.5d2fdaff3af27b7a57db.js
  41. 1 1
      static/js/48.94bdc915c4bbda69e8a9.js
  42. 0 1
      static/js/49.84376d0557546ac59c97.js
  43. 1 1
      static/js/51.21796cf3f728b4166f79.js
  44. 1 0
      static/js/53.7facff0b52f43eecda1c.js
  45. 1 1
      static/js/53.6352b93c8978b06cbae7.js
  46. 1 1
      static/js/54.8bc3d2d8759fb54f1b04.js
  47. 1 1
      static/js/55.e29b76702b628bfa0559.js
  48. 1 1
      static/js/56.faec0c75d9b3d5590e57.js
  49. 1 1
      static/js/57.ee380d7f0e90d7c02265.js
  50. 1 1
      static/js/58.977f273bf33f18192ab3.js
  51. 1 1
      static/js/59.b2f6b005aac9534bb44f.js
  52. 1 1
      static/js/60.5fc8f0aad68e35aa666e.js
  53. 1 1
      static/js/61.439730713a22043b1cf1.js
  54. 1 1
      static/js/62.be6eb275c7d0a05ceba9.js
  55. 1 1
      static/js/63.6506a2bd046a6a1ba6a4.js
  56. 1 1
      static/js/64.740536cf7d9ffdb15b17.js
  57. 1 1
      static/js/65.dd47b7860cd9e4fe32df.js
  58. 1 1
      static/js/66.ea51e906cd57c7aa5583.js
  59. 1 1
      static/js/67.50e2a69145f50e67681e.js
  60. 1 1
      static/js/68.1ba1f8ee738f90780db5.js
  61. 0 1
      static/js/7.1e5fd067c0581b71023f.js
  62. 1 1
      static/js/9.6c3d01543536ff99f608.js
  63. 1 1
      static/js/69.baafcd1a132e816ea758.js
  64. 1 1
      static/js/70.f3829487f8dc2130adce.js
  65. 1 1
      static/js/71.c9073be398b440b83433.js
  66. 1 1
      static/js/72.559ec9cfd12365c91b5f.js
  67. 1 1
      static/js/73.2d4c72f1ede7fbcdbc58.js
  68. 1 1
      static/js/74.17b5f73f00fa066f9098.js
  69. 1 1
      static/js/75.ce47205df015ad0ed774.js
  70. 1 1
      static/js/76.414ccd51915b01c855c7.js
  71. 1 1
      static/js/77.98158981d5aedad7fa18.js
  72. 0 1
      static/js/8.04218116eec1b3abc71a.js
  73. 1 0
      static/js/8.a1ad02e4aabc51485230.js
  74. 1 0
      static/js/9.61f35931094d127703e2.js
  75. 5 5
      static/js/app.bbe27b2a99d6bb548482.js
  76. 1 0
      static/js/manifest.21feabaaeb2208f5a7a9.js
  77. 0 1
      static/js/manifest.d23b194131968bc99f65.js

+ 1 - 1
index.html

@@ -7,4 +7,4 @@
7 7
         hm.src = "https://hm.baidu.com/hm.js?d61b9e2caf4d46ccda7471b5385e2333";
8 8
         var s = document.getElementsByTagName("script")[0];
9 9
         s.parentNode.insertBefore(hm, s);
10
-      })();</script><link href=./static/css/app.e5dd51ca05ddc817f8fc3a38e6e7b50b.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=./static/js/manifest.d23b194131968bc99f65.js></script><script type=text/javascript src=./static/js/app.bbe27b2a99d6bb548482.js></script></body></html>
10
+      })();</script><link href=./static/css/app.bb2d0cf85c6068087c877c72bce46bf5.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=./static/js/manifest.21feabaaeb2208f5a7a9.js></script><script type=text/javascript src=./static/js/app.f3d506759c96fdb4bb60.js></script></body></html>

+ 2 - 0
project/src/assets/config/interface_api.js

@@ -302,6 +302,8 @@ var api = {
302 302
   dataBoard_officialAccount_summary: "/api/statistics/publicAccountDataSummary", // 公众号数据 - 汇总
303 303
   dataBoard_officialAccount_list: "/api/statistics/publicAccountDataList", // 公众号数据 - 列表
304 304
   dataBoard_recharge_list: "/api/statistics/cumulativeRecoveryData", // 充值数据 - 列表
305
+  dataBoard_customerStaff_list: "/api/statistics/customerServiceData", // 客服数据统计 - 列表
306
+  dataBoard_customerStaff_setStatus: "/api/user/updateUserStatus", // 客服数据统计 - 更新客服状态
305 307
 
306 308
   getPlatformOptions: "/api/intelligentMassSending/platformIndex", // 平台筛选选项
307 309
   accountManage_accountIndex: "/api/intelligentMassSending/accountIndex", // 平台账号管理 - 账号列表

+ 22 - 0
project/src/assets/js/staticTypes.js

@@ -52,3 +52,25 @@ export const routePathType = {
52 52
   GROUP_SEND: '/employee_bulk_messaging_log', // 客户群发
53 53
   WELCOME_MSG: '/welcom_message_create', // 欢迎语
54 54
 }
55
+
56
+// 客服激活状态
57
+export const kfActiveStatusCode = {
58
+  'NOT_ACTIVATED': 0,
59
+  'ACTIVATED': 1,
60
+}
61
+export const kfActiveStatusMap = new Map([
62
+  [kfActiveStatusCode.NOT_ACTIVATED, '未激活'],
63
+  [kfActiveStatusCode.ACTIVATED, '已激活'],
64
+])
65
+
66
+// 客服状态
67
+export const customerStaffStatusCode = {
68
+  'USING': 1,
69
+  'STOPPED': 2,
70
+  'BANNED': 3,
71
+}
72
+export const customerStaffStatusMap = new Map([
73
+  [customerStaffStatusCode.USING, '运营中'],
74
+  [customerStaffStatusCode.STOPPED, '已停用'],
75
+  [customerStaffStatusCode.BANNED, '已封禁'],
76
+])

+ 16 - 3
project/src/components/assembly/screen/channel.vue

@@ -35,7 +35,13 @@
35 35
   </div>
36 36
 </template>
37 37
 <script>
38
-import { promotionTypeCode, incomeSourceCode, launchTypeCode } from '@/assets/js/staticTypes'
38
+import {
39
+  promotionTypeCode,
40
+  incomeSourceCode,
41
+  launchTypeCode,
42
+  customerStaffStatusCode,
43
+  kfActiveStatusCode,
44
+} from '@/assets/js/staticTypes'
39 45
 export default {
40 46
   props: {
41 47
     afferent_value: '',
@@ -211,8 +217,8 @@ export default {
211 217
       this.placeholderVal = '请选择账号'
212 218
     } else if (this.type == 'isActive') { // 成员管理 激活状态
213 219
       this.options = [
214
-        { key: 0, val: '未激活' },
215
-        { key: 1, val: '已激活' },
220
+        { key: kfActiveStatusCode.NOT_ACTIVATED, val: '未激活' },
221
+        { key: kfActiveStatusCode.ACTIVATED, val: '已激活' },
216 222
       ]
217 223
       this.placeholderVal = '请选择激活状态'
218 224
     } else if (this.type == 'orderSource') { // 付费来源
@@ -227,6 +233,13 @@ export default {
227 233
     } else if (this.type == 'materialLibrary') { // 图片组
228 234
       this.getPicturesGroup()
229 235
       this.placeholderVal = '图片组'
236
+    } else if (this.type == 'customerStaffStatus') { // 客服状态
237
+      this.options = [
238
+        { key: customerStaffStatusCode.USING, val: '运营中' },
239
+        { key: customerStaffStatusCode.STOPPED, val: '已停用' },
240
+        { key: customerStaffStatusCode.BANNED, val: '已封禁' },
241
+      ]
242
+      this.placeholderVal = '请选择'
230 243
     } else {
231 244
       this.init()
232 245
     }

+ 16 - 3
project/src/components/assembly/screen/channelMultiple.vue

@@ -20,7 +20,13 @@
20 20
   </div>
21 21
 </template>
22 22
 <script>
23
-import { promotionTypeCode, incomeSourceCode, launchTypeCode } from '@/assets/js/staticTypes'
23
+import {
24
+  promotionTypeCode,
25
+  incomeSourceCode,
26
+  launchTypeCode,
27
+  customerStaffStatusCode,
28
+  kfActiveStatusCode,
29
+} from '@/assets/js/staticTypes'
24 30
 export default {
25 31
   props: {
26 32
     afferent_value: '',
@@ -194,8 +200,8 @@ export default {
194 200
       this.placeholderVal = '请选择账号'
195 201
     } else if (this.type == 'isActive') { // 成员管理 激活状态
196 202
       this.options = [
197
-        { key: 0, val: '未激活' },
198
-        { key: 1, val: '已激活' },
203
+        { key: kfActiveStatusCode.NOT_ACTIVATED, val: '未激活' },
204
+        { key: kfActiveStatusCode.ACTIVATED, val: '已激活' },
199 205
       ]
200 206
       this.placeholderVal = '请选择激活状态'
201 207
     } else if (this.type == 'orderSource') { // 付费来源
@@ -207,6 +213,13 @@ export default {
207 213
     } else if (this.type == 'operatorGroup') { // 运营组
208 214
       this.getOperatorGroup()
209 215
       this.placeholderVal = '运营组'
216
+    } else if (this.type == 'customerStaffStatus') { // 客服状态
217
+      this.options = [
218
+        { key: customerStaffStatusCode.USING, val: '运营中' },
219
+        { key: customerStaffStatusCode.STOPPED, val: '已停用' },
220
+        { key: customerStaffStatusCode.BANNED, val: '已封禁' },
221
+      ]
222
+      this.placeholderVal = '请选择'
210 223
     } else {
211 224
       this.init()
212 225
     }

+ 63 - 0
project/src/components/assembly/screen/inputV2.vue

@@ -0,0 +1,63 @@
1
+<template>
2
+  <div class="common-screen-item">
3
+    <label class="common-screen-label" :style="labelWidth ? 'width:auto;margin-left:20px' : ''"
4
+      v-if="hasLabel">{{ label_name }}</label>
5
+    <el-input :style="width ? 'width:' + width : ''" :placeholder="placeholder || `请输入${label_name}`" v-model="input_keyword" clearable size="small" class="common-input-select" @input="onInput" @change="onChange">
6
+      <el-button slot="append" icon="el-icon-search" @click="onClickBtn" />
7
+    </el-input>
8
+  </div>
9
+</template>
10
+<script>
11
+export default {
12
+  props: {
13
+    value: {
14
+      type: String | Number,
15
+      default: () => '',
16
+    },
17
+    labelWidth: {
18
+      type: Boolean,
19
+      default: false
20
+    },
21
+    label_name: {
22
+      type: String,
23
+      default: '搜索客户'
24
+    },
25
+    placeholder: {
26
+      type: String,
27
+      default: () => ''
28
+    },
29
+    hasLabel: {
30
+      type: Boolean,
31
+      default: true
32
+    },
33
+    width: {
34
+      type: String
35
+    },
36
+  },
37
+  computed: {
38
+    input_keyword: {
39
+      get() {
40
+        return this.value
41
+      },
42
+      set(newValue) {
43
+        this.$emit('input', newValue)
44
+      },
45
+    },
46
+  },
47
+  methods: {
48
+    async onInput(val) {
49
+      this.input_keyword = val
50
+      await this.$nextTick()
51
+      this.$emit('onInput', this.input_keyword)
52
+    },
53
+    async onChange(val) {
54
+      this.input_keyword = val
55
+      await this.$nextTick()
56
+      this.$emit('change', this.input_keyword)
57
+    },
58
+    onClickBtn() {
59
+      this.$emit('change', this.input_keyword)
60
+    },
61
+  }
62
+}
63
+</script>

+ 0 - 1
project/src/components/dataBoard/adqAccount/list.vue

@@ -265,7 +265,6 @@ export default {
265 265
     },
266 266
     // 监听搜索账号
267 267
     onInputKeyword(val) {
268
-      console.log('val => ', val)
269 268
       this.keyword = val || ''
270 269
       this.gzh_init(1)
271 270
     },

+ 511 - 0
project/src/components/dataBoard/customerStaff/index.vue

@@ -0,0 +1,511 @@
1
+<template>
2
+  <div class="customerStaff-wrap" v-loading="pageLoading">
3
+    <!-- S 筛选区 -->
4
+    <div class="screenBox" style="padding-right: 100px;">
5
+      <!-- 企微主体 -->
6
+      <div class="common-screen-item">
7
+        <label class="common-screen-label">企微主体</label>
8
+        <!-- 系统管理员 -->
9
+        <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" />
10
+        <!-- 非系统管理员 -->
11
+        <el-select v-else v-model="filter.corpid" size="small" filterable placeholder="请选择" @change="onChangeCorpid" clearable class="select-cls">
12
+          <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" />
13
+        </el-select>
14
+      </div>
15
+      <!-- 成员 -->
16
+      <selfInputV2 v-model="filter.user_name" label_name="成员" placeholder="请输入" @change="onChangeUserName" />
17
+      <!-- 客服状态 -->
18
+      <selfChannel title="客服状态" type="customerStaffStatus" :reset="reset" placeholder="请选择" @channelDefine="onChangeStatus" />
19
+      <!-- 激活状态 -->
20
+      <selfChannel title="激活状态" type="isActive" :reset="reset" placeholder="请选择" @channelDefine="onChangeActiveStatus" />
21
+      <!-- 运营人员 -->
22
+      <selfChannel title="运营人员" type="circleCreate" :reset="reset" placeholder="请选择" @channelDefine="onChangeOperatorUid" />
23
+
24
+      <div class="reset" @click="onClickReset">重置</div>
25
+      <el-button v-if="isCanExport" class="export-btn" type="primary" size="mini" @click="onClickExport">导出Excel</el-button>
26
+    </div>
27
+    <!-- E 筛选区 -->
28
+    <!-- S 数据更新时间 -->
29
+    <!-- <div class="update-time"><i class="el-icon-warning-outline" />数据更新时间:{{ updateTime || '-' }}</div> -->
30
+    <!-- E 数据更新时间 -->
31
+    <!-- S 明细表 detailsTable -->
32
+    <div v-loading="detailLoading">
33
+      <ux-grid class="detailsTable" ref="detailsTable" :border="false" @row-click="() => { return }" :header-cell-style="getHeaderCellStyle" show-footer-overflow="tooltip" show-overflow="tooltip" size="mini" :height="height">
34
+        <ux-table-column v-for="(item, idx) in detailsTableCol" :key="item.column + item.name" :resizable="true" :field="item.column" :title="item.name" :min-width="item.min_width ? item.min_width : 160" :fixed="item.fixed ? item.fixed : ''" align="center">
35
+          <template #header>
36
+            <div class="flex-align-jus-center">
37
+              {{ item.name }}
38
+              <el-tooltip v-if="item.notes" :content="item.notes" placement="top">
39
+                <div><i class="el-icon-question" /></div>
40
+              </el-tooltip>
41
+              <div v-if="item.enable_to_sort" class="sort-wrap">
42
+                <i class="el-icon-caret-top" :class="{ 'active': filter.sort_field === item.column && filter.sort_type === 'asc' }" @click="onClickSort(item.column, 'asc')" />
43
+                <i class="el-icon-caret-bottom" :class="{ 'active': filter.sort_field === item.column && filter.sort_type === 'desc' }" @click="onClickSort(item.column, 'desc')" />
44
+              </div>
45
+            </div>
46
+          </template>
47
+          <template v-slot="{ row }">
48
+            <!-- 客服状态 -->
49
+            <span v-if="item.column === 'status'">{{ handleGetStatus(row['status']) }}</span>
50
+            <!-- 激活状态 -->
51
+            <span v-else-if="item.column === 'active_status'">{{ handleGetActiveStatus(row['active_status']) }}</span>
52
+            <!-- 激活状态 -->
53
+            <span v-else-if="item.column === 'operator_name'">{{ row['operator_name'] || '-' }}</span>
54
+            <!-- 其他字段 -->
55
+            <span v-else>{{ (row[item.column] || row[item.column] == 0) ? $formatNum(row[item.column]) : '-' }}</span>
56
+          </template>
57
+        </ux-table-column>
58
+
59
+        <ux-table-column v-if="detailsTableCol && detailsTableCol.length" :width="120" fixed="right" align="center" title="操作">
60
+          <template v-slot="{ row }">
61
+            <span class="c-00B38A pointer" @click="onClickStatus(row)">客服状态</span>
62
+          </template>
63
+        </ux-table-column>
64
+      </ux-grid>
65
+      <div class="pagination" v-show="pagination.total > 0">
66
+        <el-pagination background :current-page="pagination.page" @current-change="handleCurrentChange" layout="prev, pager, next" :page-count='Number(pagination.pages)' />
67
+      </div>
68
+    </div>
69
+    <!-- E 明细表 detailsTable -->
70
+
71
+    <!-- S 设置客服状态 -->
72
+    <setStatusDialog
73
+      :dialogVisible="setStatusDialogVisible"
74
+      :currentCustomer="currentCustomer"
75
+      @confirm="handleSetStatusConfirm"
76
+      @cancel="handleSetStatusCancel"
77
+    />
78
+    <!-- E 设置客服状态 -->
79
+  </div>
80
+</template>
81
+
82
+<script>
83
+import selfChannel from '@/components/assembly/screen/channel.vue'
84
+import selfInputV2 from '@/components/assembly/screen/inputV2.vue'
85
+import setStatusDialog from './setStatusDialog.vue'
86
+import { customerStaffStatusMap, kfActiveStatusMap } from '@/assets/js/staticTypes'
87
+
88
+export default {
89
+  components: {
90
+    selfChannel,
91
+    selfInputV2,
92
+    setStatusDialog,
93
+  },
94
+  data() {
95
+    return{
96
+      reset: false,
97
+      pageLoading: false,
98
+      height: '',
99
+
100
+      detailLoading: false,
101
+      detailsTableCol: [],
102
+
103
+      pagination: {
104
+        page: 1,
105
+        page_size: 20,
106
+        pages: 0,
107
+        total: 0,
108
+      },
109
+
110
+      system_enterprise: [], // 企微主体数据
111
+      enterpriseList: [], // 企微主体数据
112
+      enterprise: {}, // 当前选择的企微信息
113
+
114
+      filter: {
115
+        sort_field: '', // 排序字段 - 默认值
116
+        sort_type: '', // 升序/降序
117
+        corpid: '', // 企微主体
118
+        user_name: '', // 成员
119
+        status: '', // 客服状态
120
+        operator_uid: '', // 运营人员
121
+        active_status: '', // 激活状态
122
+      },
123
+      updateTime: '', // 数据更新时间
124
+
125
+      setStatusDialogVisible: false,
126
+      currentCustomer: {},
127
+    }
128
+  },
129
+  computed: {
130
+    // 是否有“导出”权限
131
+    isCanExport() {
132
+      return !!this.$store.state.dataBoardAuth.can_export
133
+    },
134
+  },
135
+  created() {
136
+    this.initTableHeight()
137
+    this.handleInitCorpOptions()
138
+    this.handleGetData()
139
+  },
140
+  methods: {
141
+    handleGetStatus(status) {
142
+      return customerStaffStatusMap.get(status) || '-'
143
+    },
144
+    handleGetActiveStatus(active_status) {
145
+      return kfActiveStatusMap.get(active_status) || '-'
146
+    },
147
+    handleGetData() {
148
+      this.handleGetList()
149
+      // this.handleGetUpdateTime()
150
+    },
151
+    // 获取"数据更新时间"
152
+    async handleGetUpdateTime() {
153
+      try {
154
+        const params = { type: '' }
155
+        const { data: res = {} } = await this.$axios.get(`${this.URL.BASEURL}${this.URL.dataBoard_uptime}`, { params })
156
+        if (res && res.errno == 0) {
157
+          this.updateTime = res.rst.uptime
158
+        } else if (res.errno != 4002) {
159
+          this.$message.warning(res.err)
160
+          this.updateTime = ''
161
+        }
162
+      } catch (error) {
163
+        this.updateTime = ''
164
+      }
165
+    },
166
+    // 获取列表数据
167
+    async handleGetList() {
168
+      try {
169
+        this.detailLoading = true
170
+        const params = {
171
+          corp_id: this.filter.corpid,
172
+          user_name: this.filter.user_name,
173
+          status: this.filter.status,
174
+          operator_uid: this.filter.operator_uid,
175
+          active_status: this.filter.active_status,
176
+
177
+          sort_field: this.filter.sort_field,
178
+          sort_type: this.filter.sort_type,
179
+          page: this.pagination.page,
180
+          page_size: this.pagination.page_size,
181
+        }
182
+        const url = `${this.URL.BASEURL}${this.URL.dataBoard_customerStaff_list}`
183
+        const { data: res = {} } = await this.$axios.get(url, { params })
184
+        if (res && res.errno == 0) {
185
+          res.rst.extra[0].fixed = 'left' // 前1列固定左侧
186
+          const detailsTableCol = []
187
+          res.rst.extra.forEach(item => {
188
+            if (item.name && item.name.length > 6) { // 长字符宽度
189
+              item['min_width'] = item.name.length * 25
190
+            }
191
+            detailsTableCol.push(item) // 收集普通表头
192
+          })
193
+          this.detailsTableCol = Object.freeze(detailsTableCol)
194
+          await this.$nextTick()
195
+          const detailsTableList = Array.isArray(res.rst.data) ? res.rst.data : []
196
+          this.$refs.detailsTable.reloadData(detailsTableList)
197
+          this.pagination.total = res.rst.pageInfo.total
198
+          this.pagination.pages = res.rst.pageInfo.pages
199
+        } else if (res.errno != 4002) {
200
+          this.$message.warning(res.err)
201
+          this.$refs.detailsTable.reloadData([])
202
+          this.pagination.total = 0
203
+          this.pagination.pages = 0
204
+        }
205
+      } catch (error) {
206
+        console.log(error)
207
+        this.$refs.detailsTable.reloadData([])
208
+        this.pagination.total = 0
209
+        this.pagination.pages = 0
210
+      } finally {
211
+        this.detailLoading = false
212
+      }
213
+    },
214
+    // 监听排序变化
215
+    onClickSort(sort_field, sort_type) {
216
+      // sort_type:升序asc、降序desc
217
+      if (this.filter.sort_field === sort_field) {
218
+        if (this.filter.sort_type === sort_type) {
219
+          // 点击的是当前排序字段 && 是当前排序类型 => 重置 取消排序
220
+          this.filter.sort_field = ''
221
+          this.filter.sort_type = ''
222
+        } else {
223
+          // 点击的是当前排序字段 && 非当前排序类型 => 设置排序类型
224
+          this.filter.sort_type = sort_type
225
+        }
226
+      } else {
227
+        // 点击的不是当前排序字段 => 设置排序字段和类型
228
+        this.filter.sort_field = sort_field
229
+        this.filter.sort_type = sort_type
230
+      }
231
+      // 后端排序 => 获取最新数据
232
+      this.pagination.page = 1
233
+      this.handleGetData()
234
+    },
235
+    // 监听当前页变化
236
+    handleCurrentChange(currentPage) {
237
+      this.pagination.page = currentPage
238
+      this.handleGetData()
239
+    },
240
+    // 监听客服输入变化
241
+    onChangeUserName(val) {
242
+      this.filter.user_name = val
243
+      this.pagination.page = 1
244
+      this.handleGetData()
245
+    },
246
+    // 监听“客服状态”变化
247
+    onChangeStatus(val) {
248
+      this.filter.status = val
249
+      this.pagination.page = 1
250
+      this.handleGetData()
251
+    },
252
+    // 监听“运营人员”变化
253
+    onChangeOperatorUid(val) {
254
+      this.filter.operator_uid = val
255
+      this.pagination.page = 1
256
+      this.handleGetData()
257
+    },
258
+    // 监听“激活状态”变化
259
+    onChangeActiveStatus(val) {
260
+      this.filter.active_status = val
261
+      this.pagination.page = 1
262
+      this.handleGetData()
263
+    },
264
+    // 监听点击"重置"按钮
265
+    onClickReset() {
266
+      this.reset = !this.reset
267
+
268
+      this.system_enterprise = []
269
+      this.enterprise = {}
270
+      this.filter.corpid = ''
271
+      this.filter.user_name = ''
272
+      this.filter.status = ''
273
+      this.filter.operator_uid = ''
274
+      this.filter.active_status = ''
275
+
276
+      this.filter.sort_field = ''
277
+      this.filter.sort_type = ''
278
+      this.pagination.page = 1
279
+      this.handleGetData()
280
+    },
281
+    // 监听点击"导出"按钮
282
+    async onClickExport() {
283
+      if (!this.pagination.total) return this.$message.warning('暂无数据可导出')
284
+      try {
285
+        this.pageLoading = true
286
+        const url = {
287
+          detail: `${this.URL.BASEURL}${this.URL.dataBoard_customerStaff_list}`,
288
+        }
289
+        const params = {
290
+          corp_id: this.filter.corpid,
291
+          user_name: this.filter.user_name,
292
+          status: this.filter.status,
293
+          operator_uid: this.filter.operator_uid,
294
+          active_status: this.filter.active_status,
295
+        }
296
+        const [{ data: detailRes = {} }] = await Promise.all([
297
+          this.$axios.get(url.detail, {
298
+            params: {
299
+              ...params,
300
+              sort_field: this.filter.sort_field,
301
+              sort_type: this.filter.sort_type,
302
+              page: 1,
303
+              page_size: this.$store.state.exportNumber,
304
+            }
305
+          })
306
+        ])
307
+        if (detailRes && detailRes.errno == 0) {
308
+          this.handleExport({
309
+            detailData: detailRes.rst,
310
+          })
311
+        } else if (detailRes.errno != 4002) {
312
+          this.$message.warning(detailRes.err)
313
+        }
314
+      } catch (error) {
315
+        console.log(error)
316
+        this.$message.warning('导出失败,请重试')
317
+      } finally {
318
+        this.pageLoading = false
319
+      }
320
+    },
321
+    // 执行导出逻辑
322
+    handleExport({ detailData = {} }) {
323
+      let tHeader = []
324
+      let filterVal = []
325
+      let tableDatas = []
326
+
327
+      detailData.data.forEach(item => {
328
+        item['status'] = this.handleGetStatus(item['status'])
329
+        item['active_status'] = this.handleGetActiveStatus(item['active_status'])
330
+      })
331
+
332
+      tHeader = [
333
+        ...detailData.extra.map(d => `${d.name}`),
334
+      ]
335
+
336
+      filterVal = [
337
+        ...detailData.extra.map(d => d.column),
338
+      ]
339
+
340
+      tableDatas = [
341
+        ...detailData.data,
342
+      ]
343
+
344
+      const excelDatas = [
345
+        {
346
+          tHeader, // sheet表一头部
347
+          filterVal, // 表一的数据字段
348
+          tableDatas, // 表一的整体json数据
349
+          sheetName: ''// 表一的sheet名字
350
+        }
351
+      ]
352
+      this.$exportOrder({ excelDatas, name: `客服数据统计(导出时间:${this.$getDay(0)})` })
353
+    },
354
+    getHeaderCellStyle() {
355
+      return { backgroundColor: '#FFFFFF !important', border: 'none!important' }
356
+    },
357
+    initTableHeight() {
358
+      this.height = document.documentElement.clientHeight - 240 > 400 ? document.documentElement.clientHeight - 240 : 400
359
+    },
360
+
361
+    // S 企微主体数据
362
+    onChangeCorpidSystem(val) {//二级联选择器
363
+      if (val.length < 1) {
364
+        this.enterprise = {}
365
+      } else {
366
+        this.enterpriseList.forEach((item) => {
367
+          item.manage_corp_list.forEach((item1) => {
368
+            if (item1.corpid == val[1]) {
369
+              this.enterprise = item1
370
+            }
371
+          })
372
+        })
373
+      }
374
+      this.filter.corpid = this.enterprise.corpid || ''
375
+      this.pagination.page = 1
376
+      this.handleGetData()
377
+    },
378
+    onChangeCorpid(val) {
379
+      if (!val) {
380
+        this.enterprise = {}
381
+      } else {
382
+        const res = this.enterpriseList.filter(v => v.corpid == val)[0];
383
+        this.enterprise = res || {}
384
+      }
385
+      this.filter.corpid = this.enterprise.corpid || ''
386
+      this.pagination.page = 1
387
+      this.handleGetData()
388
+    },
389
+    // 企业筛选初始化
390
+    handleInitCorpOptions() {
391
+      if (this.$cookie.getCookie('isSuperManage') == 1) {//系统管理员
392
+        const enterpriseList = this.$store.state.authorize_corpList;
393
+        enterpriseList.forEach(item => {//为了el-cascader更改props
394
+          item.self_id = item.group_id.toString();
395
+          item.self_name = item.group_name;
396
+          item.manage_corp_list.forEach(item1 => {
397
+            item1.self_id = item1.corpid;
398
+            item1.self_name = item1.corp_name;
399
+          })
400
+        });
401
+        this.enterpriseList = enterpriseList
402
+      } else {
403
+        this.enterpriseList = this.$store.state.authorize_corpList;
404
+      }
405
+    },
406
+    // E 企微主体数据
407
+
408
+    onClickStatus(row) {
409
+      this.currentCustomer = {...row}
410
+      this.setStatusDialogVisible = true
411
+    },
412
+    handleSetStatusConfirm() {
413
+      this.currentCustomer = {}
414
+      this.setStatusDialogVisible = false
415
+      this.handleGetData()
416
+    },
417
+    handleSetStatusCancel() {
418
+      this.currentCustomer = {}
419
+      this.setStatusDialogVisible = false
420
+    },
421
+  },
422
+}
423
+</script>
424
+
425
+<style lang="scss" scoped>
426
+@import "@/style/list.scss";
427
+.customerStaff-wrap {
428
+  position: relative;
429
+  min-height: calc(100vh - 70px);
430
+  .empty-wrap {
431
+    position: absolute;
432
+    top: 50%;
433
+    left: 50%;
434
+    transform: translate(-50%, -50%);
435
+  }
436
+  .screenBox {
437
+    background: #fff;
438
+    // padding: 5px 20px 26px;
439
+    padding: 5px 20px 10px;
440
+    position: relative;
441
+    .export-btn {
442
+      position: absolute;
443
+      top: 17px;
444
+      right: 4px;
445
+    }
446
+  }
447
+  .update-time {
448
+    margin-top: 10px;
449
+    padding-left: 20px;
450
+    display: flex;
451
+    align-items: center;
452
+    font-size: 12px;
453
+    color: #999;
454
+    i {
455
+      font-size: 14px;
456
+      font-weight: 600;
457
+      margin-right: 4px;
458
+    }
459
+  }
460
+  .summaryTable {
461
+    margin-top: 10px;
462
+  }
463
+  .detailsTable {
464
+    margin-top: 10px;
465
+  }
466
+  .sort-wrap {
467
+    display: flex;
468
+    flex-direction: column;
469
+    i {
470
+      cursor: pointer;
471
+      &.active {
472
+        color: #32B38A;
473
+      }
474
+    }
475
+    i:first-child {
476
+      margin-bottom: -3px;
477
+    }
478
+    i:last-child {
479
+      margin-top: -3px;
480
+    }
481
+  }
482
+  .select-cls {
483
+    /deep/ .el-input__inner {
484
+      width: 210px;
485
+    }
486
+    /deep/ &.el-select .el-input.is-focus .el-input__inner,
487
+    /deep/ &.el-select .el-input__inner:focus,
488
+    /deep/ &.el-cascader .el-input.is-focus .el-input__inner,
489
+    /deep/ &.el-cascader .el-input__inner:focus {
490
+      border-color: #DCDFE6;
491
+    }
492
+    /deep/ .el-input__suffix {
493
+      border-top-right-radius: 4px;
494
+      border-bottom-right-radius: 4px;
495
+      border: 1px solid #DCDFE6;
496
+      right: 0;
497
+      width: 30px;
498
+      background-color: #F1F1F1;
499
+      .el-input__icon {
500
+        color: #909399;
501
+      }
502
+    }
503
+    &.cascader {
504
+      /deep/ .el-input__suffix {
505
+        height: 32px;
506
+        top: 2px;
507
+      }
508
+    }
509
+  }
510
+}
511
+</style>

+ 155 - 0
project/src/components/dataBoard/customerStaff/setStatusDialog.vue

@@ -0,0 +1,155 @@
1
+<template>
2
+  <el-dialog
3
+    :visible.sync="dialogVisible"
4
+    :before-close="handleCancel"
5
+    class="setStatus-dialog"
6
+    :title="dialogTitle"
7
+    width="450px"
8
+  >
9
+    <div class="form-wrap" v-loading="loading">
10
+      <div class="form-item">
11
+        <span class="lable">请选择</span>
12
+        <selfChannel ref="statusEl" title="" type="customerStaffStatus" placeholder="状态" :labelWidth="true" width="240px" :afferent_value="form.status" @channelDefine="onChangeStatus" />
13
+      </div>
14
+    </div>
15
+    <div slot="footer" class="dialog-footer">
16
+      <el-button size="mini" @click="handleCancel">取 消</el-button>
17
+      <el-button size="mini" type="primary" @click="handleConfirm" :disabled="loading">确 定</el-button>
18
+    </div>
19
+  </el-dialog>
20
+</template>
21
+
22
+<script>
23
+import selfChannel from '@/components/assembly/screen/channel.vue'
24
+
25
+export default {
26
+  name: "setStatusDialog",
27
+  components: {
28
+    selfChannel,
29
+  },
30
+  props: {
31
+    // 控制弹框是否显示
32
+    dialogVisible: {
33
+      type: Boolean,
34
+      default: () => false
35
+    },
36
+    // 当前客服信息
37
+    currentCustomer: {
38
+      type: Object,
39
+      default: () => ({})
40
+    },
41
+  },
42
+  data() {
43
+    return {
44
+      loading: false,
45
+      form: {
46
+        status: '',
47
+      }
48
+    }
49
+  },
50
+  computed: {
51
+    // 弹框标题
52
+    dialogTitle() {
53
+      return '客服状态'
54
+    }
55
+  },
56
+  watch: {
57
+    dialogVisible(isShow) {
58
+      // 弹框显示 => 初始化表单数据
59
+      if (isShow) {
60
+        this.handleInitData()
61
+      } else {
62
+        this.form.status = ''
63
+      }
64
+    },
65
+  },
66
+  methods: {
67
+    // 获取弹框表单数据
68
+    async handleInitData() {
69
+      this.loading = false
70
+      const { status } = this.currentCustomer
71
+      this.form.status = status || ''
72
+      await this.$nextTick()
73
+      if (this.form.status) {
74
+        this.$refs.statusEl && this.$refs.statusEl.init_afferent()
75
+      } else {
76
+        this.$refs.statusEl && this.$refs.statusEl.clear()
77
+      }
78
+    },
79
+    async handleConfirm() {
80
+      try {
81
+        // 表单校验
82
+        await this.handleFormValidate()
83
+        const url = `${this.URL.BASEURL}${this.URL.dataBoard_customerStaff_setStatus}`
84
+        const params = {
85
+          corp_id: this.currentCustomer.corpid,
86
+          user_id: this.currentCustomer.user_id,
87
+          status: this.form.status,
88
+        }
89
+        this.loading = true
90
+        const { data: res = {} } = await this.$axios.post(url, params)
91
+        if (res && res.errno == 0) {
92
+          this.$message.success('操作成功')
93
+          this.$emit('confirm')
94
+        } else if (res.errno != 4002) {
95
+          this.$message.warning(res.err || '操作失败')
96
+        }
97
+      } catch (error) {
98
+        console.log(error)
99
+      } finally {
100
+        this.loading = false
101
+      }
102
+    },
103
+    handleCancel() {
104
+      this.$emit('cancel')
105
+    },
106
+    // 执行表单校验
107
+    handleFormValidate() {
108
+      return new Promise((resolve, reject) => {
109
+        const { status } = this.form
110
+        if (!status) {
111
+          this.$message.warning('请选择客服状态')
112
+          reject('表单校验未通过')
113
+        } else {
114
+          resolve('表单校验通过')
115
+        }
116
+      })
117
+    },
118
+    onChangeStatus(val) {
119
+      this.form.status = val
120
+    },
121
+  },
122
+};
123
+</script>
124
+
125
+<style lang="scss" scoped>
126
+.setStatus-dialog {
127
+  .form-wrap {
128
+    padding: 0 10px;
129
+    .form-item {
130
+      display: flex;
131
+      align-items: center;
132
+      margin-top: 16px;
133
+      &:first-child {
134
+        margin-top: 0;
135
+      }
136
+      .lable {
137
+        width: 82px;
138
+        margin-right: 16px;
139
+        font-weight: 500;
140
+        flex-shrink: 0;
141
+        text-align: right;
142
+        em {
143
+          color: red;
144
+        }
145
+      }
146
+      .el-select {
147
+        width: 100%;
148
+      }
149
+    }
150
+  }
151
+  .dialog-footer {
152
+    text-align: center;
153
+  }
154
+}
155
+</style>

+ 0 - 4
project/src/components/dataBoard/operator/operatorData.vue

@@ -136,14 +136,12 @@ export default {
136 136
       // }
137 137
     },
138 138
     handleGetData() {
139
-      console.log('handleGetData 运营数据 => ')
140 139
       this.handleGetSummaryList()
141 140
       this.handleGetList()
142 141
       this.handleGetUpdateTime()
143 142
     },
144 143
     // 获取列表数据
145 144
     async handleGetList() {
146
-      console.log('handleGetList => ')
147 145
       try {
148 146
         this.detailLoading = true
149 147
         const params = {
@@ -191,7 +189,6 @@ export default {
191 189
     },
192 190
     // 获取汇总表数据
193 191
     async handleGetSummaryList() {
194
-      console.log('handleGetSummaryList => ')
195 192
       try {
196 193
         this.summaryLoading = true
197 194
         const params = {
@@ -229,7 +226,6 @@ export default {
229 226
     },
230 227
     // 获取"数据更新时间"
231 228
     async handleGetUpdateTime() {
232
-      console.log('handleGetUpdateTime => ')
233 229
       try {
234 230
         const params = { type: 'operate_data_trend' }
235 231
         const { data: res = {} } = await this.$axios.get(`${this.URL.BASEURL}${this.URL.dataBoard_uptime}`, { params })

+ 0 - 4
project/src/components/dataBoard/operator/operatorWxAccount.vue

@@ -139,14 +139,12 @@ export default {
139 139
       // }
140 140
     },
141 141
     handleGetData() {
142
-      console.log('handleGetData 运营公众号数据 => ')
143 142
       this.handleGetSummaryList()
144 143
       this.handleGetList()
145 144
       this.handleGetUpdateTime()
146 145
     },
147 146
     // 获取列表数据
148 147
     async handleGetList() {
149
-      console.log('handleGetList => ')
150 148
       try {
151 149
         this.detailLoading = true
152 150
         const params = {
@@ -195,7 +193,6 @@ export default {
195 193
     },
196 194
     // 获取汇总表数据
197 195
     async handleGetSummaryList() {
198
-      console.log('handleGetSummaryList => ')
199 196
       try {
200 197
         this.summaryLoading = true
201 198
         const params = {
@@ -234,7 +231,6 @@ export default {
234 231
     },
235 232
     // 获取"数据更新时间"
236 233
     async handleGetUpdateTime() {
237
-      console.log('handleGetUpdateTime => ')
238 234
       try {
239 235
         const params = { type: 'operate_data_trend' }
240 236
         const { data: res = {} } = await this.$axios.get(`${this.URL.BASEURL}${this.URL.dataBoard_uptime}`, { params })

+ 0 - 2
project/src/components/dataBoard/platformPromote/promoteLink.vue

@@ -101,7 +101,6 @@ export default {
101 101
     },
102 102
     // 获取列表数据
103 103
     async handleGetList() {
104
-      console.log('handleGetList => ',)
105 104
       try {
106 105
         this.detailLoading = true
107 106
         const params = {
@@ -154,7 +153,6 @@ export default {
154 153
       // this.handleGetList()
155 154
     },
156 155
     onChangePlaylet(val) {
157
-      console.log('val => ', val)
158 156
       this.filter.playlet = val
159 157
       this.pagination.page = 1
160 158
       // this.handleGetList()

+ 0 - 2
project/src/components/dataBoard/platformPromote/promotePlaylet.vue

@@ -98,7 +98,6 @@ export default {
98 98
     },
99 99
     // 获取列表数据
100 100
     async handleGetList() {
101
-      console.log('handleGetList => ',)
102 101
       try {
103 102
         this.detailLoading = true
104 103
         const params = {
@@ -151,7 +150,6 @@ export default {
151 150
     },
152 151
     // 监听剧集筛选变化
153 152
     onChangePlaylet(val) {
154
-      console.log('val => ', val)
155 153
       this.filter.playlet = val
156 154
       this.pagination.page = 1
157 155
       // this.handleGetList()

+ 0 - 1
project/src/components/manage/memberComp/batchAssign.vue

@@ -174,7 +174,6 @@ export default {
174 174
       }
175 175
     },
176 176
     handleReset() {
177
-      console.log('handleReset => ')
178 177
       this.selectUser = [];
179 178
       this.final_result = []
180 179
       this.changeSelect()

+ 0 - 1
project/src/components/manage/memberComp/transferDialog.vue

@@ -85,7 +85,6 @@ export default {
85 85
       this.form.handover_userid = ''
86 86
     },
87 87
     onChangeTransferUser (val) {
88
-      console.log('onChangeTransferUser => ', val)
89 88
       this.form.takeover_userid = val ? val.user_id : ''
90 89
     },
91 90
     async handleConfirm() {

+ 0 - 3
project/src/components/manage/memberManage.vue

@@ -546,7 +546,6 @@ export default {
546 546
     },
547 547
     // 监听点击“分配许可”
548 548
     async onClickAssign(current) {
549
-      console.log('onClickAssign => ', JSON.parse(JSON.stringify(current)))
550 549
       this.currentAssignInfo = {...current}
551 550
       const num = await this.handleGetWaitForAssignNum()
552 551
       if (!num) return this.$message.warning('暂无待分配许可')
@@ -566,7 +565,6 @@ export default {
566 565
 
567 566
     // 监听点击“转移许可”
568 567
     onClickTransfer(current) {
569
-      console.log('onClickTransfer => ', JSON.parse(JSON.stringify(current)))
570 568
       this.currentTransferInfo = {...current}
571 569
       this.transferDialogVisible = true
572 570
     },
@@ -584,7 +582,6 @@ export default {
584 582
 
585 583
     // 监听“批量分配许可”变化
586 584
     onResBatchAssign(res) {
587
-      console.log('onResBatchAssign => ', res)
588 585
       this.init(undefined, this.keyword)
589 586
       this.handleGetWaitForAssignNum()
590 587
       setTimeout(() => {

+ 13 - 0
project/src/router/allRouter.js

@@ -77,6 +77,8 @@ const operator = () => import(/* webpackChunkName: 'operator' */ '@/components/d
77 77
 const officialAccount = () => import(/* webpackChunkName: 'officialAccount' */ '@/components/dataBoard/officialAccount.vue')
78 78
 // 数据看板 - 充值数据
79 79
 const recharge = () => import(/* webpackChunkName: 'recharge' */ '@/components/dataBoard/recharge.vue')
80
+// 数据看板 - 客服数据统计
81
+const customerStaff = () => import(/* webpackChunkName: 'customerStaff' */ '@/components/dataBoard/customerStaff/index.vue')
80 82
 
81 83
 // 平台账号管理
82 84
 const accountManage = () => import(/* webpackChunkName: 'accountManage' */ '@/components/manage/accountManage/accountManage.vue')
@@ -655,6 +657,17 @@ export var allRouter = [
655 657
         }
656 658
       },
657 659
       {
660
+        path: 'customerStaff',
661
+        name: 'customerStaff',
662
+        component: customerStaff,
663
+        meta: {
664
+          keepAlive: false,
665
+          isLogin: true,
666
+          title: '客服数据统计',
667
+          isData: true
668
+        }
669
+      },
670
+      {
658 671
         path: 'thePublic',
659 672
         name: 'thePublic',
660 673
         component: thePublic,

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/css/app.e5dd51ca05ddc817f8fc3a38e6e7b50b.css


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 9 - 0
static/js/0.15901049091b96623f7b.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 9
static/js/0.472945da217b40b2958a.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 1
static/js/10.5e856c33b456a9232857.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/12.7c78f26cbc8bac4a96d1.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 1
static/js/11.3985a84e1aa24ab7b755.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/13.f833ee5299653d62fe64.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/14.02744e555ec18048618b.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/15.5121236387a21d879569.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/16.4b79d4d4331728d4178b.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/17.79c43f4ab0a4ade2fbd6.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
static/js/16.e2ff89462cf9407a11c7.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
static/js/17.60ef7946bc76dd41008a.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/20.bb85bc9181588ac2a3e1.js


static/js/3.de1a03ddf00b92f1ae56.js → static/js/3.7c3ccbbb9c2e1a3a5d1d.js


static/js/31.c79feb0132b01ad9951c.js → static/js/31.3c4503cdfaf2cff83edd.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 1
static/js/42.97f362b97d99c023935f.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
static/js/42.9ca6c58d101af30d4a03.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/45.4dc80c069c611e3cf21d.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 1
static/js/44.b8d91f609271eba18bd8.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
static/js/45.88200280168fa664b52b.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
static/js/47.24c33c86e95e98fe62f1.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/47.5d2fdaff3af27b7a57db.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/48.94bdc915c4bbda69e8a9.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 1
static/js/49.84376d0557546ac59c97.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/51.21796cf3f728b4166f79.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
static/js/53.7facff0b52f43eecda1c.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/53.6352b93c8978b06cbae7.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/54.8bc3d2d8759fb54f1b04.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/55.e29b76702b628bfa0559.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/56.faec0c75d9b3d5590e57.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/57.ee380d7f0e90d7c02265.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/58.977f273bf33f18192ab3.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/59.b2f6b005aac9534bb44f.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/60.5fc8f0aad68e35aa666e.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/61.439730713a22043b1cf1.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/62.be6eb275c7d0a05ceba9.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/63.6506a2bd046a6a1ba6a4.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/64.740536cf7d9ffdb15b17.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/65.dd47b7860cd9e4fe32df.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/66.ea51e906cd57c7aa5583.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/67.50e2a69145f50e67681e.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/68.1ba1f8ee738f90780db5.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 1
static/js/7.1e5fd067c0581b71023f.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/9.6c3d01543536ff99f608.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/69.baafcd1a132e816ea758.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/70.f3829487f8dc2130adce.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/71.c9073be398b440b83433.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/72.559ec9cfd12365c91b5f.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/73.2d4c72f1ede7fbcdbc58.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/74.17b5f73f00fa066f9098.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/75.ce47205df015ad0ed774.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/76.414ccd51915b01c855c7.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
static/js/77.98158981d5aedad7fa18.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 1
static/js/8.04218116eec1b3abc71a.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
static/js/8.a1ad02e4aabc51485230.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
static/js/9.61f35931094d127703e2.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 5 - 5
static/js/app.bbe27b2a99d6bb548482.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
static/js/manifest.21feabaaeb2208f5a7a9.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 1
static/js/manifest.d23b194131968bc99f65.js