unknown 2 年 前
コミット
5e0b5f14ad

+ 8 - 0
.idea/modules.xml

@@ -0,0 +1,8 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<project version="4">
3
+  <component name="ProjectModuleManager">
4
+    <modules>
5
+      <module fileurl="file://$PROJECT_DIR$/.idea/playlet.iml" filepath="$PROJECT_DIR$/.idea/playlet.iml" />
6
+    </modules>
7
+  </component>
8
+</project>

+ 12 - 0
.idea/playlet.iml

@@ -0,0 +1,12 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<module type="WEB_MODULE" version="4">
3
+  <component name="NewModuleRootManager">
4
+    <content url="file://$MODULE_DIR$">
5
+      <excludeFolder url="file://$MODULE_DIR$/.tmp" />
6
+      <excludeFolder url="file://$MODULE_DIR$/temp" />
7
+      <excludeFolder url="file://$MODULE_DIR$/tmp" />
8
+    </content>
9
+    <orderEntry type="inheritedJdk" />
10
+    <orderEntry type="sourceFolder" forTests="false" />
11
+  </component>
12
+</module>

File diff suppressed because it is too large
+ 743 - 266
project/package-lock.json


+ 2 - 2
project/package.json

@@ -21,8 +21,6 @@
21 21
     "js-sha1": "^0.6.0",
22 22
     "jspdf": "^2.3.1",
23 23
     "md5": "^2.3.0",
24
-    "node-sass": "^4.12.0",
25
-    "sass-loader": "^7.1.0",
26 24
     "switch-address": "^1.0.4",
27 25
     "umy-ui": "^1.1.6",
28 26
     "vue": "^2.5.2",
@@ -57,6 +55,7 @@
57 55
     "friendly-errors-webpack-plugin": "^1.6.1",
58 56
     "html-webpack-plugin": "^2.30.1",
59 57
     "node-notifier": "^5.1.2",
58
+    "node-sass": "^4.7.2",
60 59
     "optimize-css-assets-webpack-plugin": "^3.2.0",
61 60
     "ora": "^1.2.0",
62 61
     "portfinder": "^1.0.13",
@@ -64,6 +63,7 @@
64 63
     "postcss-loader": "^2.0.8",
65 64
     "postcss-url": "^7.2.1",
66 65
     "rimraf": "^2.6.0",
66
+    "sass-loader": "^7.3.1",
67 67
     "script-loader": "^0.7.2",
68 68
     "semver": "^5.3.0",
69 69
     "shelljs": "^0.7.6",

+ 1 - 1
project/src/assets/config/interface_api.js

@@ -191,7 +191,7 @@ var api = {
191 191
   radar_radarEdit:'/api/radar/radarUpdate',
192 192
   radar_radarSort:'/api/radar/radarSortUpdate',
193 193
   radar_radarDele:'/api/radar/radarDelete',
194
-  radar_uploadFileToOss:'/api/material/uploadFileToOss',
194
+  radar_uploadFile:'/api/material/uploadFileToOss',
195 195
   radar_dataView:'/api/radar/dataStatisticsTotal',
196 196
   radar_dataView_list:'/api/radar/dataStatisticsList',
197 197
 

+ 163 - 184
project/src/components/smartRadar/createRadar.vue

@@ -7,7 +7,7 @@
7 7
      </div>
8 8
    </div>
9 9
 
10
-    <div v-if="!loading" class="bg-ffffff createMassMsg" style="padding: 10px 30px 10px;">
10
+    <div v-if="!edit_detial_Flag" v-loading="loading" class="bg-ffffff createMassMsg" style="padding: 10px 30px 10px;">
11 11
       <div class="regulations">
12 12
         <label><em>*</em>名称</label>
13 13
         <el-input placeholder="请输入雷达名称" style="width:500px" v-model.trim="radarName"
@@ -16,19 +16,22 @@
16 16
                   clearable size="small"></el-input>
17 17
       </div>
18 18
       <div class="regulations" style="align-items: center">
19
-        <label>选择分组</label>
20
-        <el-select v-model="group_val" size="small" clearable placeholder="请选择" style="width: 500px">
19
+        <label><em style="opacity: 0">*</em>选择分组</label>
20
+        <el-select v-model="group_id" size="small" clearable placeholder="请选择" style="width: 500px">
21 21
           <el-option
22
-            v-for="item in groupArrs"
23
-            :key="item.value"
24
-            :label="item.label"
25
-            :value="item.value">
22
+            v-for="(item,index) in groupArrs"
23
+            :key="index"
24
+            :label="item.group_name"
25
+            :value="item.group_id">
26 26
           </el-option>
27 27
         </el-select>
28 28
       </div>
29
-      <fileType></fileType>
30
-
31
-
29
+      <fileType v-if="fileShow" ref="fileTypeRef"
30
+                :comeBackParms="{
31
+                  url_list_echo:url_list_echo,
32
+                  type:type
33
+                }"
34
+                @getType="(val)=>{type = val}"></fileType>
32 35
       <div class="regulations">
33 36
         <label><em>*</em>雷达标题</label>
34 37
         <el-input placeholder="请输入雷达标题" style="width:500px" v-model.trim="radartitle"
@@ -38,7 +41,7 @@
38 41
       </div>
39 42
       <div class="regulations">
40 43
         <label><em>*</em>雷达描述</label>
41
-        <el-input type="textarea" placeholder="请输入雷达标题" style="width:500px" v-model.trim="radardesc"
44
+        <el-input type="textarea" placeholder="请输入雷达描述" style="width:500px" v-model.trim="radardesc"
42 45
                   :rows="4"
43 46
                   maxlength="200"
44 47
                   show-word-limit
@@ -50,7 +53,9 @@
50 53
           <el-upload key="imgUpload"
51 54
                      class="imgUploader"
52 55
                      :action="URL.BASEURL + URL.material_upload"
56
+                     name="material_file"
53 57
                       :file-list="coverFileList"
58
+                     :data="extraData"
54 59
                      accept=".jpg,.jpeg,.png"
55 60
                      list-type="picture-card"
56 61
                      :limit="1"
@@ -64,7 +69,10 @@
64 69
               <div class="el-icon-circle-plus f16"></div>
65 70
               <div class="el-upload__text f14">添加图片</div>
66 71
             </div>
67
-            <div class="el-upload__tip" slot="tip">建议尺寸: 200px*200px,大小不超过1MB</div>
72
+            <div class="el-upload__tip" slot="tip">
73
+              建议尺寸: 200px*200px,大小不超过1MB
74
+              <div v-if="coverErrFlag" class="errCss">* 错误:{{coverErrInfo}}</div>
75
+            </div>
68 76
           </el-upload>
69 77
           <el-dialog append-to-body :visible.sync="imgCoverVisible">
70 78
             <img width="100%" :src="imgCoverUrl" alt="">
@@ -75,15 +83,18 @@
75 83
         <label class="fWeight600">智能跟进</label>
76 84
         <div>
77 85
           <el-checkbox-group v-model="smartVal">
78
-            <el-checkbox label="行为通知(当客户点击雷达时,发送雷达的员工将会收到消息提醒)"></el-checkbox>
79
-            <el-checkbox label="动态通知(当客户点击雷达时,会将客户的打开行为记录在客户动态里)"></el-checkbox>
80
-            <el-checkbox label="客户标签(给点击雷达的客户打上选中的标签)"></el-checkbox>
86
+            <el-checkbox label="behavior_notification">行为通知(当客户点击雷达时,发送雷达的员工将会收到消息提醒)</el-checkbox>
87
+            <el-checkbox label="dynamic_notification">动态通知(当客户点击雷达时,会将客户的打开行为记录在客户动态里)</el-checkbox>
88
+            <el-checkbox label="customer_label">客户标签(给点击雷达的客户打上选中的标签)</el-checkbox>
81 89
           </el-checkbox-group>
90
+          <enterprise-tag v-if="smartVal.indexOf('customer_label') > -1" title="" width="300px"
91
+                          :afferent_obj='afferent_tag_obj'
92
+                          :reset='resetFlag' @tagDefine="tagDefine"></enterprise-tag>
82 93
         </div>
83 94
       </div>
84 95
 
85 96
       <div style="margin-top: 20px">
86
-        <el-button type="primary" @click="newCode_click">创建雷达</el-button>
97
+        <el-button type="primary" @click="newCode_click">保存</el-button>
87 98
       </div>
88 99
     </div>
89 100
   </div>
@@ -91,24 +102,22 @@
91 102
 
92 103
 <script>
93 104
 import fileType from './fileType.vue'
105
+import enterpriseTag from '@/components/assembly/screen/enterpriseTagFC.vue'
94 106
 export default {
95 107
   name: "createRadar",
96 108
   components:{
97
-    fileType
109
+    fileType,
110
+    enterpriseTag
98 111
   },
99 112
   data(){
100 113
     return{
101 114
       loading:false,
115
+      edit_detial_Flag:false,
102 116
       radarName:'',
103 117
       radartitle:'',
104 118
       radardesc:'',
105
-      group_val:0,
106
-      groupArrs:[
107
-        {
108
-          label:'分组一',
109
-          value:0
110
-        }
111
-      ],
119
+      group_id:'',
120
+      groupArrs:[],
112 121
       user_id_list: [],
113 122
 
114 123
       resetFlag: false,
@@ -116,6 +125,23 @@ export default {
116 125
       coverFileList:[],
117 126
       imgCoverVisible: false,
118 127
       imgCoverUrl: false,
128
+      cover_id:'',
129
+      coverErrInfo:'',
130
+      coverErrFlag:false,
131
+      type:1,
132
+      extraData:{
133
+        admin_id: this.$cookie.getCookie('admin_id'),
134
+        ttl: this.$cookie.getCookie('ttl'),
135
+        sign: this.$cookie.getCookie('sign'),
136
+        corpid: this.$localSelfStore.getLocal('defaultCorp') && this.$localSelfStore.getLocal('defaultCorp') != 'undefined' ? JSON.parse(this.$localSelfStore.getLocal('defaultCorp')).corpid : '',
137
+        type: 1,//素材类型。1图片 2语音 3视频
138
+      },
139
+      afferent_tag_obj: {
140
+        tag_id_list: []
141
+      },
142
+      tag_info:[],
143
+      url_list_echo:[],
144
+      fileShow:false,
119 145
 
120 146
     }
121 147
   },
@@ -123,9 +149,40 @@ export default {
123 149
 
124 150
   },
125 151
   created(){
126
-
152
+    this.init_groupList()
153
+    if (this.$route.query.id) {//详情
154
+      this.detail()
155
+    }else{
156
+      this.edit_detial_Flag=false
157
+      this.fileShow=true
158
+    }
127 159
   },
128 160
   methods:{
161
+    tagDefine (data) {//标签选择回调
162
+      if (data.tag_id_list && data.tag_id_list.length != 0) {
163
+        this.tag_info = data.tag_id_list
164
+      } else {
165
+        this.tag_info = []
166
+      }
167
+    },
168
+    init_groupList(){//分组列表
169
+      this.$axios.get(this.URL.BASEURL + this.URL.radar_groupList, {
170
+        params:{
171
+          page: 1,
172
+          page_size: 500,
173
+        }
174
+      }).then((res) => {
175
+        var res = res.data
176
+      if (res && res.errno == 0) {
177
+        this.groupArrs = res.rst.data
178
+      } else if (res.errno != 4002) {
179
+        this.$message({
180
+          message: res.err,
181
+          type: "warning"
182
+        })
183
+      }
184
+    })
185
+    },
129 186
     handleSee(file){
130 187
       this.imgCoverVisible = true
131 188
       this.imgCoverUrl = file.url;
@@ -134,10 +191,21 @@ export default {
134 191
       this.$loading(this.$loadingConfig);
135 192
     },
136 193
     handleRemove(){
137
-
194
+      this.cover_id = ''
195
+      this.coverErrFlag=false
138 196
     },
139
-    uploadSuccess(){
197
+    uploadSuccess(res){
140 198
       this.$loading(this.$loadingConfig).close()
199
+      if(res&&res.errno == 0){
200
+        this.cover_id = res.rst.material_id
201
+      }else{
202
+        this.$message({
203
+          type: 'error',
204
+          message: res.err
205
+        });
206
+        this.coverErrFlag = true
207
+        this.coverErrInfo = res.err
208
+      }
141 209
     },
142 210
     uploadFail(){
143 211
       this.$message({
@@ -153,36 +221,37 @@ export default {
153 221
     },
154 222
     detail () {//详情
155 223
       this.loading = true
156
-      this.$axios.get(this.URL.BASEURL + this.URL.welcomeMsg_detail, {
224
+      this.$axios.get(this.URL.BASEURL + this.URL.radar_radarDetail, {
157 225
         params: {
158
-          rule_id: this.$route.query.id
226
+          radar_id: this.$route.query.id
159 227
         }
160 228
       }).then((res) => {
161
-        var res = res.data
162 229
         this.loading = false
230
+        var res = res.data
163 231
         if (res && res.errno == 0) {
164
-          this.dataInfo = res.rst;
165
-          this.is_for_all = res.rst.is_for_all;
166
-          this.user_id_list = res.rst.users ? res.rst.users.split(',') : [];
167
-          this.name = res.rst.name;
168
-          let msg_list = res.rst.msg_list;
169
-          msg_list.forEach((item) => {
170
-            item.content = item.content ? item.content.replace('%NICKNAME%', '「客户昵称」') : '';
171
-            item.attachments = item.attachments && item.attachments != '' ? JSON.parse(item.attachments) : [];
172
-            item.weeks = item.weeks ? item.weeks.split(',') : []
173
-          })
174
-          let main_msg_data = msg_list.filter((v) => {//特定有一个主欢迎语内容
175
-            return v.is_day_parting == 0
176
-          })
177
-          this.main_msg_data = main_msg_data && main_msg_data.length > 0 ? main_msg_data[0] : {};
178
-
179
-          this.timeIntervalList = msg_list.filter((v) => {//分时段欢迎语内容
180
-            return v.is_day_parting == 1
232
+          let dataInfo = res.rst
233
+          this.radarName = dataInfo.name
234
+          this.group_id = dataInfo.group_id
235
+          this.radartitle = dataInfo.title
236
+          this.radardesc = dataInfo.description
237
+          this.type = dataInfo.type
238
+          this.cover_id = dataInfo.cover_id
239
+          this.coverFileList.push({
240
+            url:dataInfo.cover_url
181 241
           })
242
+          this.url_list_echo = dataInfo.url_list
243
+          this.tag_info = dataInfo.tag_list
244
+          this.afferent_tag_obj.tag_id_list = dataInfo.tag_list
182 245
 
183
-          if (msg_list.length > 1) {
184
-            this.is_day_parting = true
246
+          this.smartVal = []
247
+          if(dataInfo.behavior_notification==1){
248
+            this.smartVal.push('behavior_notification')
249
+          }else if(dataInfo.customer_label==1){
250
+            this.smartVal.push('customer_label')
251
+          }else if(dataInfo.dynamic_notification==1){
252
+            this.smartVal.push('dynamic_notification')
185 253
           }
254
+          this.fileShow=true
186 255
         } else if (res.errno != 4002) {
187 256
           this.$message({
188 257
             message: res.err,
@@ -193,126 +262,70 @@ export default {
193 262
         this.loading = false
194 263
       });
195 264
     },
196
-    tipsClick(){
197
-      if(this.user_id_list&&this.user_id_list.length==0){
198
-        this.$message({
199
-          type: 'error',
200
-          message: '请先选择使用客服!'
201
-        });
202
-      }
203
-    },
204
-    newCode_click(){//新建活码
265
+    newCode_click(){//保存(新建编辑)
205 266
       if(this.radarName == ''){
206 267
         this.$message({
207 268
           type: 'error',
208
-          message: '渠道名称不能为空!'
269
+          message: '雷达名称不能为空!'
209 270
         });
210 271
         return
211 272
       }
212
-      if(this.user_id_list&&this.user_id_list.length==0){
213
-        this.$message({
214
-          type: 'error',
215
-          message: '使用客服不能为空!'
216
-        });
273
+      var fileRef = this.$refs.fileTypeRef
274
+      fileRef.judgeType()
275
+      if(fileRef.returnFlag){
217 276
         return
218 277
       }
219
-      if(this.customerNote_val==''){
278
+      if(this.radartitle == ''){
220 279
         this.$message({
221 280
           type: 'error',
222
-          message: '客户备注不能为空!'
281
+          message: '雷达标题不能为空!'
223 282
         });
224 283
         return
225 284
       }
226
-      if (this.main_msg_data.content == '' && (!this.main_msg_data.attachments || this.main_msg_data.attachments == '' || this.main_msg_data.attachments.length == 0)) {
285
+      if(this.radardesc == ''){
227 286
         this.$message({
228
-          message: '请输入【主】欢迎语内容!',
229
-          type: "warning"
230
-        })
287
+          type: 'error',
288
+          message: '雷达描述不能为空!'
289
+        });
231 290
         return
232 291
       }
233
-      if (this.main_msg_data.content != '' && this.$getStrBytes(this.main_msg_data.content) > 4000) {
292
+      if(this.cover_id == ''){
234 293
         this.$message({
235
-          message: '请检查【主】欢迎语内容,最多4000个字节,已超出!',
236
-          type: "error"
237
-        })
294
+          type: 'error',
295
+          message: '雷达封面不能为空!'
296
+        });
238 297
         return
239 298
       }
240
-
241
-      let msg_data = []
242
-      if (this.is_day_parting) {//开启分段欢迎语
243
-        for (let i = 0; i < this.timeIntervalList.length; i++) {
244
-          let item = this.timeIntervalList[i];
245
-          if (item.content == '' && (!item.attachments || item.attachments == '' || item.attachments.length == 0)) {
246
-            this.$message({
247
-              message: `请输入【时段${i + 1}】欢迎语内容!`,
248
-              type: "warning"
249
-            })
250
-            return
251
-          }
252
-          if (item.content != '' && this.$getStrBytes(item.content) > 4000) {
253
-            this.$message({
254
-              message: `请检查【时段${i + 1}】欢迎语内容,最多4000个字节,已超出!`,
255
-              type: "error"
256
-            })
257
-            return
258
-          }
259
-          if (!item.weeks || item.weeks.length == 0) {
260
-            this.$message({
261
-              message: `请选择【时段${i + 1}】发送日期!`,
262
-              type: "warning"
263
-            })
264
-            return
265
-          }
266
-          if (!item.start_time || item.start_time == '') {
267
-            this.$message({
268
-              message: `请输入【时段${i + 1}】发送开始时间!`,
269
-              type: "warning"
270
-            })
271
-            return
272
-          }
273
-          if (!item.end_time || item.end_time == '') {
274
-            this.$message({
275
-              message: `请输入【时段${i + 1}】发送结束时间!`,
276
-              type: "warning"
277
-            })
278
-            return
279
-          }
280
-          if (this.$date_compatible(('2020-04-01 ' + item.start_time)).getTime() > this.$date_compatible(('2020-04-01 ' + item.end_time)).getTime()) {
281
-            this.$message({
282
-              message: `请正确输入【时段${i + 1}】发送时间!`,
283
-              type: "warning"
284
-            })
285
-            return
286
-          }
299
+      if(this.smartVal.indexOf('customer_label') > -1){
300
+        if(this.tag_info&&this.tag_info.length==0){
301
+          this.$message({
302
+            type: 'error',
303
+            message: '智能跟进-客户标签 选中后,标签不能为空'
304
+          });
305
+          return
287 306
         }
288
-        msg_data = msg_data.concat(this.timeIntervalList)
289
-      } else {//关闭分段欢迎语
290
-        let delete_arr = JSON.parse(JSON.stringify(this.timeIntervalList));
291
-        delete_arr = delete_arr.filter((v) => {
292
-          return v.msg_id
293
-        })
294
-        delete_arr.forEach((item) => {
295
-          item.operate = 'del'
296
-        })
297
-        this.deleteTimeIntervalList = this.deleteTimeIntervalList.concat(delete_arr)
298 307
       }
299
-      msg_data = msg_data.concat(this.deleteTimeIntervalList);//删除的分时段内容
300
-
301
-      msg_data.push(this.main_msg_data)
302
-      msg_data.forEach((item) => {
303
-        item.weeks = item.weeks.join(',');
304
-        item.content = item.content.replace('「客户昵称」', '%NICKNAME%')
305
-        item.attachments = item.attachments == '' || item.attachments.length == 0 ? '' : JSON.stringify(item.attachments)
306
-      })
307 308
 
308 309
       this.$loading(this.$loadingConfig)
309
-
310
-      this.$axios.post(this.URL.BASEURL + this.URL.welcomeMsg_set, {
311
-        rule_id: this.$route.query.id ? this.$route.query.id : '',
312
-        radarName: this.radarName,
313
-        is_for_all: this.is_for_all,
314
-        users: this.is_for_all == 0 ? this.user_id_list.join(',') : '',
315
-        msg_data: msg_data
310
+      let api=''
311
+      if(this.$route.query.id){//编辑
312
+        api=this.URL.radar_radarEdit
313
+      }else{
314
+        api=this.URL.radar_addRadar
315
+      }
316
+      this.$axios.post(this.URL.BASEURL + api, {
317
+        radar_id: this.$route.query.id ? this.$route.query.id : '',
318
+        group_id:this.group_id,
319
+        name: this.radarName,
320
+        type:this.type,
321
+        url_list:fileRef.ur_list,
322
+        title:this.radartitle,
323
+        description:this.radardesc,
324
+        cover_id:this.cover_id,
325
+        behavior_notification:this.smartVal.indexOf('behavior_notification') > -1 ? 1 : 0,
326
+        dynamic_notification:this.smartVal.indexOf('dynamic_notification') > -1 ? 1 : 0,
327
+        customer_label:this.smartVal.indexOf('customer_label') > -1 ? 1 : 0,
328
+        tag_list:this.tag_info
316 329
       }).then((res) => {
317 330
         var res = res.data
318 331
         this.$loading(this.$loadingConfig).close()
@@ -328,45 +341,7 @@ export default {
328 341
         this.$loading(this.$loadingConfig).close()
329 342
       });
330 343
     },
331
-    tagDefine (data) {//标签选择回调
332
-      if (data.tag_id_list && data.tag_id_list.length != 0) {
333
-        this.tag_info = data.tag_id_list
334
-      } else {
335
-        this.tag_info = []
336
-      }
337
-    },
338
-    getAttachment (val) {
339
-      this.main_msg_data.attachments = val;
340
-    },
341
-    switchChange () {//分时段开关打开
342
-      if (this.is_day_parting && this.timeIntervalList.length == 0) {
343
-        this.timeIntervalList.push(this.init_welcom_con)
344
-      }
345
-    },
346
-    getWelcomEdit (val, index) {//分时段编辑
347
-      this.$set(this.timeIntervalList, index, val)
348
-    },
349
-    deleteWelcomCon (index) {//删除分时段
350
-      if (this.$route.query.id && this.timeIntervalList[index].msg_id) {//删除的分时段内容
351
-        let obj = JSON.parse(JSON.stringify(this.timeIntervalList[index]))
352
-        obj.operate = 'del';
353
-        this.deleteTimeIntervalList.push(obj)
354
-      }
355
-      this.timeIntervalList.splice(index, 1)
356
-    },
357
-    addWelcom () {//添加分时段
358
-      this.timeIntervalList.push(this.init_welcom_con)
359
-    },
360
-    switchLimit(){
361
-      if(this.user_id_list&&this.user_id_list.length==0){
362
-        this.$message({
363
-          type: 'error',
364
-          message: '使用客服不能为空!'
365
-        });
366
-        return
367
-      }
368 344
 
369
-    }
370 345
   }
371 346
 }
372 347
 </script>
@@ -426,4 +401,8 @@ export default {
426 401
   cursor: pointer;
427 402
   display: inline-block;
428 403
 }
404
+  .errCss{
405
+    margin:10px 0;
406
+    color:red;
407
+  }
429 408
 </style>

+ 8 - 45
project/src/components/smartRadar/dataAnalyse.vue

@@ -16,24 +16,11 @@
16 16
     </div>
17 17
 
18 18
     <div class="topTagBox">
19
-      <div class="span_title">打开链接的客户</div>
20
-      <div class="flex-align-center">
21
-        <self-input :hasLabel="false" label_name="搜索客户" @inputChange='(val)=>{kehu_val = val;initFlag=!initFlag}'></self-input>
22
-        <div style="width: 20px"></div>
23
-        <self-input :hasLabel="false" label_name="选择渠道" @inputChange='(val)=>{kehu_val = val;initFlag=!initFlag}'></self-input>
24
-        <div style="width: 20px"></div>
25
-        <date-picker title="" :quickFlag="false" :afferent_time="default_time"
26
-                     :clearFlag='false' :reset="resetFlag" @changeTime="changeTime"></date-picker>
27
-        <div style="width: 20px"></div>
28
-        <self-input :hasLabel="false" label_name="所属成员" @inputChange='(val)=>{kehu_val = val;initFlag=!initFlag}'></self-input>
29
-        <div style="width: 20px"></div>
30
-        <el-button type="primary" size="small" >重置</el-button>
31
-      </div>
19
+
32 20
       <publicTable
33 21
         :propsData="{
34 22
           desCol:desCol,
35
-          source:'dataAnalyse',
36
-          initFlag:initFlag
23
+          source:'dataAnalyse'
37 24
         }"
38 25
       ></publicTable>
39 26
     </div>
@@ -41,15 +28,11 @@
41 28
 </template>
42 29
 
43 30
 <script>
44
-import datePicker from '@/components/assembly/screen/datePicker.vue'
45
-import selfInput from '@/components/assembly/screen/input.vue'
46 31
 import publicTable from './publicTable.vue'
47 32
 export default {
48 33
   name: "dataAnalyse",
49 34
   components:{
50
-    publicTable,
51
-    selfInput,
52
-    datePicker
35
+    publicTable
53 36
   },
54 37
   data(){
55 38
     return{
@@ -76,17 +59,12 @@ export default {
76 59
           bigKey:'today_pv_count',
77 60
         }
78 61
       ],
79
-      default_time: [this.$getDay(-30, false), this.$getDay(0, false)],
80
-      resetFlag: false,
81
-      kehu_val:'',
82
-      initFlag:false,
83
-      time:[],
84 62
       desCol:[
85
-        { prop: "name", label: "客户" },
86
-        { prop: "assign_count", label: "所属成员" },
87
-        { prop: "name", label: "最近点击时间" },
88
-        { prop: "waiting_add_count", label: "最近点击渠道" },
89
-        { prop: "passed_count", label: "客户访问总次数"}
63
+        { prop: "customer_name", label: "客户" },
64
+        { prop: "user_name", label: "所属成员" },
65
+        { prop: "last_click_time", label: "最近点击时间" },
66
+        { prop: "last_click_channel", label: "最近点击渠道" },
67
+        { prop: "pv_count", label: "客户访问总次数"}
90 68
       ]
91 69
     }
92 70
   },
@@ -94,7 +72,6 @@ export default {
94 72
     this.init_preview()
95 73
   },
96 74
   methods:{
97
-
98 75
     init_preview(){//数据概览
99 76
       this.loading = true
100 77
       this.$axios.get(this.URL.BASEURL + this.URL.radar_dataView, {
@@ -118,15 +95,6 @@ export default {
118 95
         this.loading = false
119 96
       });
120 97
     },
121
-    changeTime (time) {//筛选时间变化
122
-      if (!time || time && time.length == 0) {
123
-        this.time = []
124
-      } else {
125
-        this.time = time
126
-      }
127
-      this.initFlag=!this.initFlag
128
-
129
-    },
130 98
   }
131 99
 }
132 100
 </script>
@@ -155,10 +123,5 @@ export default {
155 123
 .topTagBox{
156 124
   margin-top: 10px;
157 125
   font-size: 14px;
158
-  .span_title{
159
-    font-weight: 600;
160
-    color: #000;
161
-    margin: 10px 0 ;
162
-  }
163 126
 }
164 127
 </style>

+ 223 - 39
project/src/components/smartRadar/fileType.vue

@@ -10,7 +10,7 @@
10 10
       </div>
11 11
     </div>
12 12
 <!--链接-->
13
-    <template v-if="fileType_Val==1">
13
+    <div v-show="fileType_Val==1">
14 14
       <div class="regulations">
15 15
         <label><em>*</em>跳转链接</label>
16 16
         <el-input placeholder="请输入跳转链接" style="width:500px" v-model.trim="jumplink_val"
@@ -18,19 +18,22 @@
18 18
                   show-word-limit
19 19
                   clearable size="small"></el-input>
20 20
       </div>
21
-    </template>
21
+    </div>
22 22
     <!--PDF-->
23
-    <template v-if="fileType_Val==2">
23
+    <div v-show="fileType_Val==2">
24 24
       <div class="regulations">
25 25
         <label></label>
26
-        <el-upload
27
-          :action="URL.BASEURL + URL.material_upload"
26
+        <el-upload key="pdfUpload"
27
+          :action="URL.BASEURL + URL.radar_uploadFile"
28
+          :data="extraData_pdf"
28 29
           accept=".pdf,.PDF"
29 30
           :limit="1"
30 31
           :before-upload="()=>{$loading($loadingConfig)}"
31
-          :on-preview="handlePreview"
32
-          :on-remove="handleRemove"
33
-          :on-success="uploadSuccess"
32
+          :on-preview="(file)=>{handlePreview(file,'pdf')}"
33
+                   :on-remove="(file,fileList)=>{handleRemove(file,fileList,'pdf')}"
34
+          :on-success="(response, file, fileList) => {
35
+                  return uploadSuccess(response, file, fileList, 'pdf');
36
+          }"
34 37
           :on-error='uploadFail'
35 38
           :on-exceed="handleExceed"
36 39
           :file-list="pdfList">
@@ -38,26 +41,30 @@
38 41
           <div slot="tip" class="el-upload__tip">
39 42
             <div>只能上传pdf文件,且不超过20MB</div>
40 43
             <div class="tMar5">文件将自动转为成网页链接,员工发送给客户后可记录客户打开数据</div>
44
+            <div v-if="coverErrFlag" class="errCss">* 错误:{{coverErrInfo}}</div>
41 45
           </div>
42 46
         </el-upload>
43 47
       </div>
44
-    </template>
48
+    </div>
45 49
     <!--图片-->
46
-    <template v-if="fileType_Val==3">
50
+    <div v-show="fileType_Val==3">
47 51
       <div class="regulations radar_cover_box">
48 52
         <label></label>
49 53
         <el-upload key="imgUpload"
50 54
                    class="imgUploader"
51 55
                    multiple
52
-                   :action="URL.BASEURL + URL.material_upload"
56
+                   :action="URL.BASEURL + URL.radar_uploadFile"
57
+                   :data="extraData_img"
53 58
                    :file-list="typeImgList"
54
-                   accept=".jpg,.jpeg,.png"
59
+                   accept=".jpg,.png"
55 60
                    list-type="picture-card"
56 61
                    :limit="9"
57 62
                    :before-upload="()=>{$loading($loadingConfig)}"
58
-                   :on-preview="handlePreview"
59
-                   :on-remove="handleRemove"
60
-                   :on-success="uploadSuccess"
63
+                   :on-preview="(file)=>{handlePreview(file,'img')}"
64
+                   :on-remove="(file,fileList)=>{handleRemove(file,fileList,'img')}"
65
+                   :on-success="(response, file, fileList) => {
66
+                      return uploadSuccess(response, file, fileList, 'img');
67
+                    }"
61 68
                    :on-error='uploadFail'
62 69
                    :on-exceed="handleExceed">
63 70
           <div>
@@ -67,25 +74,26 @@
67 74
           <div class="el-upload__tip" slot="tip">
68 75
             <div> 图片大小不超过1MB,最多上传9张</div>
69 76
             <div class="tMar5">文件将自动转为成网页链接,员工发送给客户后可记录客户打开数据</div>
77
+            <div v-if="coverErrFlag" class="errCss">* 错误:{{coverErrInfo}}</div>
70 78
            </div>
71 79
         </el-upload>
72
-        <el-dialog append-to-body :visible.sync="imgTypeVisible">
73
-          <img width="100%" :src="imgTypeUrl" alt="">
74
-        </el-dialog>
75 80
       </div>
76
-    </template>
81
+    </div>
77 82
     <!--视频-->
78
-    <template v-if="fileType_Val==4">
83
+    <div v-show="fileType_Val==4">
79 84
       <div class="regulations">
80 85
         <label></label>
81
-        <el-upload
82
-          :action="URL.BASEURL + URL.material_upload"
83
-          accept=".mp4,.mov"
86
+        <el-upload key="mp4Upload"
87
+          :action="URL.BASEURL + URL.radar_uploadFile"
88
+                   :data="extraData_mp4"
89
+          accept=".mp4,.MP4"
84 90
           :limit="1"
85 91
           :before-upload="()=>{$loading($loadingConfig)}"
86
-          :on-preview="handlePreview"
87
-          :on-remove="handleRemove"
88
-          :on-success="uploadSuccess"
92
+                   :on-preview="(file)=>{handlePreview(file,'mp4')}"
93
+          :on-remove="(file,fileList)=>{handleRemove(file,fileList,'mp4')}"
94
+           :on-success="(response, file, fileList) => {
95
+              return uploadSuccess(response, file, fileList, 'mp4');
96
+            }"
89 97
           :on-error='uploadFail'
90 98
           :on-exceed="handleExceed"
91 99
           :file-list="mp4List">
@@ -93,43 +101,219 @@
93 101
           <div slot="tip" class="el-upload__tip">
94 102
             <div>只能上传.mp4,.mov文件,且不超过100MB</div>
95 103
             <div class="tMar5">文件将自动转为成网页链接,员工发送给客户后可记录客户打开数据</div>
104
+            <div v-if="coverErrFlag" class="errCss">* 错误:{{coverErrInfo}}</div>
96 105
           </div>
97 106
         </el-upload>
107
+
98 108
       </div>
99
-    </template>
109
+    </div>
110
+
111
+    <!--放大看-->
112
+    <el-dialog append-to-body :visible.sync="dialogVisible">
113
+      <iframe :src="pdfUrl" frameborder="0" style="width: 100%;height: 300px;" v-if="fileType_Val==2"></iframe>
114
+      <img width="100%" :src="imgTypeUrl" alt="" v-show="fileType_Val==3">
115
+      <video :src="mp4Url" v-show="fileType_Val==4"  controls="controls" style="width: 100%;height: 300px;"></video>
116
+    </el-dialog>
100 117
   </div>
101 118
 </template>
102 119
 
103 120
 <script>
104 121
 export default {
105 122
   name: "fileType",
123
+  props:['comeBackParms'],
106 124
   data(){
107 125
     return{
108 126
       fileType_Val:1,
109 127
       jumplink_val:'',
110 128
       pdfList:[],
129
+      pdfVal:[],
111 130
       typeImgList:[],
131
+      imgVals:[],
112 132
       mp4List:[],
113
-      imgTypeVisible:false,
114
-      imgTypeUrl:false
133
+      mp4Val:[],
134
+      dialogVisible:false,
135
+      imgTypeUrl:false,
136
+      extraData_img:{
137
+        admin_id: this.$cookie.getCookie('admin_id'),
138
+        ttl: this.$cookie.getCookie('ttl'),
139
+        sign: this.$cookie.getCookie('sign'),
140
+        corpid: this.$localSelfStore.getLocal('defaultCorp') && this.$localSelfStore.getLocal('defaultCorp') != 'undefined' ? JSON.parse(this.$localSelfStore.getLocal('defaultCorp')).corpid : '',
141
+        type:1
142
+      },
143
+      extraData_pdf:{
144
+        admin_id: this.$cookie.getCookie('admin_id'),
145
+        ttl: this.$cookie.getCookie('ttl'),
146
+        sign: this.$cookie.getCookie('sign'),
147
+        corpid: this.$localSelfStore.getLocal('defaultCorp') && this.$localSelfStore.getLocal('defaultCorp') != 'undefined' ? JSON.parse(this.$localSelfStore.getLocal('defaultCorp')).corpid : '',
148
+        type:4
149
+      },
150
+      extraData_mp4:{
151
+        admin_id: this.$cookie.getCookie('admin_id'),
152
+        ttl: this.$cookie.getCookie('ttl'),
153
+        sign: this.$cookie.getCookie('sign'),
154
+        corpid: this.$localSelfStore.getLocal('defaultCorp') && this.$localSelfStore.getLocal('defaultCorp') != 'undefined' ? JSON.parse(this.$localSelfStore.getLocal('defaultCorp')).corpid : '',
155
+        type:3
156
+      },
157
+      returnFlag:false,
158
+      ur_list:[],
159
+      coverErrInfo:'',
160
+      coverErrFlag:false,
161
+      mp4Url:'',
162
+      pdfUrl:'',
163
+    }
164
+  },
165
+  watch:{
166
+    fileType_Val(){
167
+      this.$emit('getType',this.fileType_Val)
168
+    }
169
+  },
170
+  created(){
171
+    if (this.$route.query.id) {
172
+      let paramsType = this.comeBackParms.type
173
+      let paramsurl = this.comeBackParms.url_list_echo
174
+      this.fileType_Val = paramsType
175
+      if(paramsType==1){
176
+        this.jumplink_val=paramsurl[0]
177
+      }else if(paramsType==2){
178
+        this.pdfList.push({
179
+          url:paramsurl[0]
180
+        })
181
+        this.pdfVal = paramsurl
182
+      }else if(paramsType==3){
183
+        paramsurl.forEach(item=>{
184
+          this.typeImgList.push({
185
+            url:item
186
+          })
187
+        })
188
+        this.imgVals = paramsurl
189
+      }else if(paramsType==4){
190
+          this.mp4List.push({
191
+            url:paramsurl[0]
192
+          })
193
+        this.mp4Val = paramsurl
194
+      }
115 195
     }
116 196
   },
117 197
   methods:{
118
-    handlePreview(file){
119
-      this.imgCoverVisible = true
120
-      this.imgCoverUrl = file.url;
121
-    },
122
-    handleRemove(){
198
+    judgeType(){
199
+      this.returnFlag = false
200
+      this.ur_list=[]
201
+      if(this.fileType_Val == 1){
202
+        if(this.jumplink_val==''){
203
+          this.$message({
204
+            type: 'error',
205
+            message: '文件类型- 跳转链接不能为空!'
206
+          });
207
+          this.returnFlag = true
208
+        }else{
209
+          this.ur_list.push(this.jumplink_val)
210
+        }
211
+      }else if(this.fileType_Val == 2){
212
+        if(this.pdfVal&&this.pdfVal.length==0){
213
+          this.$message({
214
+            type: 'error',
215
+            message: '文件类型- PDF不能为空!'
216
+          });
217
+          this.returnFlag = true
218
+        }else{
219
+          this.ur_list=this.pdfVal
220
+        }
221
+      }else if(this.fileType_Val == 3){
222
+        if(this.imgVals&&this.imgVals.length==0){
223
+          this.$message({
224
+            type: 'error',
225
+            message: '文件类型- 图片不能为空!'
226
+          });
227
+          this.returnFlag = true
228
+        }else{
229
+          this.ur_list=this.imgVals
230
+        }
231
+      }else if(this.fileType_Val == 4){
232
+        if(this.mp4Val&&this.mp4Val.length==0){
233
+          this.$message({
234
+            type: 'error',
235
+            message: '文件类型- 视频不能为空!'
236
+          });
237
+          this.returnFlag = true
238
+        }else{
239
+          this.ur_list=this.mp4Val
240
+        }
241
+      }else{
242
+        this.ur_list=[]
243
+      }
123 244
 
124 245
     },
125
-    uploadSuccess(res, file, fileList){
246
+    handlePreview(file,type){
247
+      this.dialogVisible = true
248
+      let path_url = file.response&&file.response.rst ? file.response.rst.url : file.url
249
+      if(type=='img'){
250
+        this.imgTypeUrl = path_url
251
+      }else if(type=='mp4'){
252
+        this.mp4Url = path_url
253
+      }else if(type=='pdf'){
254
+        this.pdfUrl = path_url
255
+      }
256
+    },
257
+    handleRemove(file, fileList,type){
258
+      this.coverErrFlag=false
259
+      if(type=='img'){
260
+        let path_url = file.response&&file.response.rst ? file.response.rst.url : file.url
261
+        this.imgVals.forEach((item,idx)=>{
262
+          if(path_url == item){
263
+          this.imgVals.splice(idx,1)
264
+          }
265
+        })
266
+        console.log(this.imgVals,'imgVals,handleRemove');
267
+      }else if(type=='mp4'){
268
+        this.mp4Val = []
269
+      }else if(type=='pdf'){
270
+        this.pdfVal = []
271
+      }
272
+    },
273
+    uploadSuccess(res, file, fileList,type){
126 274
       this.$loading(this.$loadingConfig).close()
127
-      console.log(res, file, fileList);
275
+      if(res&&res.errno==0){
276
+        if(type == 'pdf'){
277
+          this.pdfVal = []
278
+          this.pdfVal.push(res.rst.url)
279
+          this.$loading(this.$loadingConfig).close()
280
+        }else if(type == 'img'){
281
+          let arr = []
282
+          fileList.forEach(item=>{
283
+            let obj=''
284
+            if(item.response&&item.response.rst&&item.response.rst.url){
285
+              obj = item.response.rst.url
286
+            }
287
+           arr.push(obj)
288
+          })
289
+          this.imgVals=arr
290
+          let loadingflag = true//假设都上传完毕
291
+          this.imgVals.forEach(item=>{
292
+            if(item==''){//如果有一个为空,就是没有上传完毕
293
+              loadingflag = false
294
+            }
295
+          })
296
+          if(loadingflag){
297
+            this.$loading(this.$loadingConfig).close()
298
+          }
299
+        }else if(type == 'mp4'){
300
+          this.mp4Val = []
301
+          this.mp4Val.push(res.rst.url)
302
+          this.$loading(this.$loadingConfig).close()
303
+        }
304
+      }else{
305
+        this.$message({
306
+          type: 'error',
307
+          message: res.err
308
+        });
309
+        this.coverErrFlag = true
310
+        this.coverErrInfo = res.err
311
+      }
128 312
     },
129
-    uploadFail(){
313
+    uploadFail(err, file, fileList){
130 314
       this.$message({
131
-        message: '上传失败',
132
-        type: 'fail'
315
+        message: err.err,
316
+        type: 'error'
133 317
       })
134 318
     },
135 319
     handleExceed(){

+ 71 - 44
project/src/components/smartRadar/groupList.vue

@@ -7,22 +7,26 @@
7 7
         添加分组
8 8
       </span>
9 9
     </div>
10
-    <div class="listBox" v-loading="loading">
11
-      <div class="item_css" :class="[acIdx==null? 'ac_css' : '']" @click="itemClick(null)"><i class="el-icon-folder"></i>全部雷达</div>
12
-      <draggable class="syllable_ul" element="ul"
13
-                 @sort="draggableSort"
14
-                 :list="tableData"
15
-                 :emptyInsertThreshold="0"
16
-                 :options="{group:'name',
10
+    <div class="listBox infinite-list-wrapper" v-loading.body="loading">
11
+      <div v-infinite-scroll="load"
12
+           :infinite-scroll-distance="20"
13
+           :infinite-scroll-immediate="false"
14
+           infinite-scroll-disabled="disabled">
15
+        <div class="item_css" :class="[acIdx==null? 'ac_css' : '']" @click="itemClick(null)"><i class="el-icon-folder"></i>全部雷达</div>
16
+        <draggable class="syllable_ul" element="ul"
17
+                   @sort="draggableSort"
18
+                   :list="tableData"
19
+                   :emptyInsertThreshold="0"
20
+                   :options="{group:'name',
17 21
                  animation:200,
18 22
                  ghostClass:'ghostClass',
19 23
                  dragClass:'dragClass'}">
20
-        <div v-for="(item,index) in tableData" :key="item.group_id" class="item_css"
21
-             @click="itemClick(item.group_id)"
22
-             :class="[acIdx==item.group_id ? 'ac_css' : '']">
23
-          <i class="el-icon-folder" style="cursor: move;"></i>
24
-          <span>{{item.group_name ? item.group_name : '-'}}</span>
25
-          <span class="lMarauto">
24
+          <div v-for="(item,index) in tableData" :key="item.group_id" class="item_css"
25
+               @click="itemClick(item.group_id)"
26
+               :class="[acIdx==item.group_id ? 'ac_css' : '']">
27
+            <i class="el-icon-folder" style="cursor: move;"></i>
28
+            <span>{{item.group_name ? item.group_name : '-'}}</span>
29
+            <span class="lMarauto">
26 30
             <el-dropdown @command="handleCommand">
27 31
               <span class="el-dropdown-link">
28 32
                 <i class="el-icon-more"></i>
@@ -34,8 +38,11 @@
34 38
             </el-dropdown>
35 39
 
36 40
           </span>
37
-        </div>
38
-      </draggable>
41
+          </div>
42
+        </draggable>
43
+      </div>
44
+      <p class="text-center f14 tMar8 c-d3" v-if="moreloading">加载中...</p>
45
+      <p class="text-center f14 tMar8 c-d3" v-if="noMore">没有更多了</p>
39 46
     </div>
40 47
 
41 48
     <dialogGroup
@@ -49,68 +56,86 @@
49 56
 </template>
50 57
 
51 58
 <script>
52
-import order from '@/components/mixins/order'
53 59
 import dialogGroup from './dialogGroup.vue'
54 60
 import draggable from "vuedraggable"
55 61
 export default {
56 62
   name: "groupList",
57
-  mixins:[order],
58 63
   components:{
59 64
     dialogGroup,
60 65
     draggable
61 66
   },
67
+  computed: {
68
+    noMore () {
69
+      return this.currPage_len < this.page_size
70
+    },
71
+    disabled () {
72
+      return this.moreloading || this.noMore
73
+    }
74
+  },
62 75
   data(){
63 76
     return{
64 77
       dialogTitle:'添加',
65 78
       acIdx:null,
66 79
       tableData:[],
80
+      copy_tableData:[],
67 81
       loading:false,
68 82
       page: 1,
69
-      pages: 0,
70
-      total: 0,
71
-      page_size: 500,
72
-      groupId:''
73
-
83
+      page_size: 20,
84
+      groupId:'',
85
+      currPage_len:0,
86
+      moreloading: false,
74 87
     }
75 88
   },
76 89
   created(){
77 90
     this.init()
78 91
   },
79 92
   methods:{
93
+    load(){
94
+      this.page += 1
95
+      this.init()
96
+    },
80 97
     draggableSort({to,from,item,clone,oldIndex,newIndex}){
81
-      // let ids = []
82
-      // this.tableData.forEach(item=>{
83
-      //   ids.push(item.id)
84
-      // })
85
-      // this.$axios.post(this.URL.BASEURL + this.URL.channel_sortGroup, {
86
-      //   ids : ids
87
-      // }).then((res) => {
88
-      //   var res = res.data
89
-      //   this.loading = false
90
-      //   if (res && res.errno == 0) {
91
-      //     // this.init()
92
-      //   } else if (res.errno != 4002) {
93
-      //     this.$message({
94
-      //       message: res.err,
95
-      //       type: "warning"
96
-      //     })
97
-      //   }
98
-      // })
98
+      if(!this.copy_tableData[oldIndex].group_id){
99
+        this.$message({
100
+          message: '被拖动的雷达组id错误',
101
+          type: "warning"
102
+        })
103
+        return
104
+      }
105
+      this.$axios.post(this.URL.BASEURL + this.URL.radar_sortGroup, {
106
+        operate_group_id:this.copy_tableData[oldIndex].group_id,
107
+        behind_group_id:newIndex-1>=0?this.tableData[newIndex-1].group_id:'',
108
+        front_group_id:newIndex+1<this.tableData.length?this.tableData[newIndex+1].group_id:'',
109
+      }).then((res) => {
110
+        var res = res.data
111
+        if (res && res.errno == 0) {
112
+
113
+        } else if (res.errno != 4002) {
114
+          this.$message({
115
+            message: res.err,
116
+            type: "warning"
117
+          })
118
+        }
119
+      })
99 120
     },
100 121
     init(){//分组列表
101 122
       this.loading = true
123
+      if(this.currPage_len>=this.page_size){
124
+        this.moreloading = true
125
+      }
102 126
       this.$axios.get(this.URL.BASEURL + this.URL.radar_groupList, {
103 127
         params:{
104 128
           page: this.page,
105
-          pagesize: this.page_size,
129
+          page_size: this.page_size,
106 130
         }
107 131
       }).then((res) => {
108 132
         var res = res.data
109 133
         this.loading = false
110 134
         if (res && res.errno == 0) {
111
-          this.tableData = res.rst.data
112
-          this.total = res.rst.pageInfo.total;
113
-          this.pages = res.rst.pageInfo.pages;
135
+          this.tableData = [...this.tableData,...res.rst.data]
136
+          this.copy_tableData =  JSON.parse(JSON.stringify(this.tableData))
137
+          this.currPage_len=res.rst.data.length
138
+          this.moreloading = false
114 139
         } else if (res.errno != 4002) {
115 140
           this.$message({
116 141
             message: res.err,
@@ -192,6 +217,8 @@ export default {
192 217
 }
193 218
 .listBox{
194 219
   margin-top: 10px;
220
+  height: calc(100vh - 60px - 62px - 20px - 10px - 50px);
221
+  overflow-y:auto;
195 222
   .item_css{
196 223
     display: flex;
197 224
     align-items: center;

+ 5 - 17
project/src/components/smartRadar/index.vue

@@ -10,15 +10,12 @@
10 10
         <groupList @getId="val=>{group_id=val,initFlag=!initFlag}"></groupList>
11 11
       </div>
12 12
       <div class="tableBox">
13
-        <publicTable
13
+        <radarList
14 14
           :propsData="{
15
-            desCol:desCol,
16
-            source:'radarIndex',
17 15
             initFlag:initFlag,
18 16
             radar_val:radar_val,
19 17
             group_id:group_id
20
-          }"
21
-          ></publicTable>
18
+          }"></radarList>
22 19
       </div>
23 20
     </div>
24 21
   </div>
@@ -26,28 +23,19 @@
26 23
 
27 24
 <script>
28 25
 import selfInput from '@/components/assembly/screen/input.vue'
29
-import publicTable from './publicTable.vue'
30 26
 import groupList from './groupList.vue'
27
+import radarList from './radarList.vue'
31 28
 export default {
32 29
   name: "codeIndex",
33 30
   components:{
34
-    publicTable,
35 31
     selfInput,
36
-    groupList
32
+    groupList,
33
+    radarList
37 34
   },
38 35
   data() {
39 36
     return {
40 37
       initFlag:false,
41 38
       radar_val:'',
42
-      desCol:[
43
-        { prop: "name", label: "名称" },
44
-        { prop: "type", label: "类型" },
45
-        { prop: "group_name", label: "分组" },
46
-        { prop: "tag_list", label: "客户标签" },
47
-        { prop: "uv_count", label: "总访问人数",},
48
-        { prop: "send_count", label: "总发送次数",},
49
-        { prop: "create_time", label: "添加时间", min_width:'160'}
50
-      ],
51 39
       reset:false,
52 40
       group_id:''
53 41
     }

+ 67 - 11
project/src/components/smartRadar/publicTable.vue

@@ -1,5 +1,21 @@
1 1
 <template>
2 2
   <div>
3
+    <template v-if="propsData.source == 'dataAnalyse'">
4
+      <div class="span_title">打开链接的客户 ({{customer_count||customer_count==0 ? customer_count : '-'}})</div>
5
+      <div class="flex-align-center">
6
+        <self-input :reset="reset" :hasLabel="true" label_name="搜索客户" @inputChange='(val)=>{customer_name = val;source_init()}'></self-input>
7
+        <div style="width: 20px"></div>
8
+        <self-input :reset="reset" :hasLabel="true" label_name="选择渠道" @inputChange='(val)=>{channel = val;source_init()}'></self-input>
9
+        <div style="width: 20px"></div>
10
+        <date-picker :reset="reset" title="选择时间"  :quickFlag="false" :afferent_time="default_time"
11
+                     :clearFlag='false' @changeTime="changeTime"></date-picker>
12
+        <div style="width: 20px"></div>
13
+        <self-input :reset="reset" :hasLabel="true" label_name="所属成员" @inputChange='(val)=>{user_list = val;source_init()}'></self-input>
14
+        <div style="width: 20px"></div>
15
+        <el-button type="primary" size="small" @click="resetAll">重置</el-button>
16
+      </div>
17
+    </template>
18
+
3 19
   <!-- table -->
4 20
     <el-table v-loading="loading" ref="multipleTable"
5 21
               border
@@ -41,7 +57,7 @@
41 57
         <el-table-column label="操作" align="center" min-width="180px">
42 58
           <template slot-scope="scope">
43 59
               <div class="flex">
44
-                <div class="c-00B38A pointer">编辑</div>
60
+                <div class="c-00B38A pointer" @click="editRadar(scope.row.radar_id)">编辑</div>
45 61
                 <el-popconfirm @confirm="deleRadar(scope.row.radar_id)" :title="`确定删除【${scope.row.name}】渠道活码?`">
46 62
                   <div slot="reference" class="c-00B38A pointer lMar8">删除</div>
47 63
                 </el-popconfirm>
@@ -59,9 +75,15 @@
59 75
 </template>
60 76
 
61 77
 <script>
78
+  import datePicker from '@/components/assembly/screen/datePicker.vue'
79
+  import selfInput from '@/components/assembly/screen/input.vue'
62 80
 export default {
63 81
   name: "publicTable",
64 82
   props:['propsData'],
83
+  components:{
84
+    selfInput,
85
+    datePicker
86
+  },
65 87
   data(){
66 88
     return{
67 89
       loading: false,
@@ -71,7 +93,14 @@ export default {
71 93
       total: 0,
72 94
       page_size: 20,
73 95
       height: '',
74
-      tableData:[]
96
+      tableData:[],
97
+      default_time: [this.$getDay(-30, false), this.$getDay(0, false)],
98
+      time:[],
99
+      customer_name:'',
100
+      channel:'',
101
+      user_list:'',
102
+      reset:false,
103
+      customer_count:0
75 104
     }
76 105
   },
77 106
   watch:{
@@ -80,34 +109,54 @@ export default {
80 109
     }
81 110
   },
82 111
   created() {
112
+    this.time = this.default_time
83 113
     this.height = document.documentElement.clientHeight - 300 > 400 ? document.documentElement.clientHeight - 300 : 400
84 114
     this.source_init()
85 115
   },
86 116
   methods:{
117
+    resetAll(){
118
+      this.customer_name=''
119
+        this.channel=''
120
+        this.user_list=''
121
+      this.reset = !this.reset
122
+
123
+    },
124
+    changeTime (time) {//筛选时间变化
125
+      if (!time || time && time.length == 0) {
126
+        this.time = []
127
+      } else {
128
+        this.time = time
129
+      }
130
+      this.source_init(1)
131
+    },
87 132
     source_init(val){
88 133
       val=val?val:1
89 134
       if(this.propsData.source=='radarIndex'){
90 135
         this.init(val)
91 136
         this.height = document.documentElement.clientHeight - 220 > 400 ? document.documentElement.clientHeight - 220 : 400
92
-      }else if(this.propsData.source=='channelAnalyse'){
93
-        this.tableData = this.propsData.tableData
137
+      }else if(this.propsData.source=='dataAnalyse'){
138
+        this.init_analyse_list(val)
94 139
       }
95 140
     },
96
-    init_analyse_list(){//数据概览
141
+    init_analyse_list(){//数据概览列表
97 142
       this.loading = true
98 143
       this.$axios.get(this.URL.BASEURL + this.URL.radar_dataView_list, {
99 144
         params:{
100 145
           radar_id:this.$route.params.id,
101
-          customer_name:'',
102
-          channel:''
146
+          customer_name:this.customer_name,
147
+          channel:this.channel,
148
+          user_list:this.user_list,
149
+          start_date:this.time[0],
150
+          end_date:this.time[1],
151
+          page:this.page,
152
+          page_size:this.page_size,
103 153
         }
104 154
       }).then((res) => {
105 155
         var res = res.data
106 156
         this.loading = false
107 157
         if (res && res.errno == 0) {
108
-          this.dataPreview.forEach(item=>{
109
-            item.bigNum = res.rst[item.bigKey]
110
-          })
158
+         this.tableData = res.rst.data.list
159
+         this.customer_count = res.rst.data.customer_count
111 160
         } else if (res.errno != 4002) {
112 161
           this.$message({
113 162
             message: res.err,
@@ -121,6 +170,9 @@ export default {
121 170
     goDataAanlyse(id){
122 171
       this.$router.push('/radar_dataAnalyse/'+id)
123 172
     },
173
+    editRadar(id){
174
+      this.$router.push({path:'/createRadar',query: {id:id}})
175
+    },
124 176
     deleRadar(id){
125 177
       this.loading = true
126 178
       this.$axios.post(this.URL.BASEURL + this.URL.radar_radarDele, {
@@ -174,5 +226,9 @@ export default {
174 226
 </script>
175 227
 
176 228
 <style lang="scss" scoped>
177
-
229
+  .span_title{
230
+    font-weight: 600;
231
+    color: #000;
232
+    margin: 10px 0 ;
233
+  }
178 234
 </style>

+ 253 - 0
project/src/components/smartRadar/radarList.vue

@@ -0,0 +1,253 @@
1
+<template>
2
+  <div>
3
+  <!-- table -->
4
+    <div class="infinite-list-wrapper" v-loading.body="loading">
5
+      <div class="tHead">
6
+        <div v-for="item in desCol"
7
+             :style="{width:item.min_width?item.min_width:'11%'}">{{item.label?item.label:'-'}}</div>
8
+      </div>
9
+      <div class="tBody"
10
+           v-if="tableData&&tableData.length>0"
11
+           v-infinite-scroll="load"
12
+           :infinite-scroll-distance="20"
13
+           :infinite-scroll-immediate="false"
14
+           infinite-scroll-disabled="disabled">
15
+        <draggable class="syllable_ul" element="ul"
16
+                   @sort="draggableSort"
17
+                   :list="tableData"
18
+                   :emptyInsertThreshold="0"
19
+                   :options="{group:'name',
20
+                 animation:200,
21
+                 ghostClass:'ghostClass',
22
+                 dragClass:'dragClass'}">
23
+          <div class="body_item" v-for="(row,index) in tableData"
24
+               :class="index == tableData.length-1 ? 'borderBottomline' : ''">
25
+          <div class="body_cell" v-for="item in desCol"
26
+               :style="{width:item.min_width?item.min_width:'11%'}">
27
+            <div v-if="item.prop=='type'">
28
+              <span v-if="row.type==1">链接</span>
29
+              <span v-else-if="row.type==2">PDF</span>
30
+              <span v-else-if="row.type==3">图片</span>
31
+              <span v-else-if="row.type==4">视频</span>
32
+              <span v-else="row.type==1">-</span>
33
+            </div>
34
+            <div v-else-if="item.prop=='tag_list'" class="flex-align-jus-center">
35
+              <template v-if="row.tag_list&&row.tag_list.length==0 || !row.tag_list">-</template>
36
+              <div class="customerServiceTagBox biaoqian" v-else>
37
+                <div class="customerServiceTag" v-for="(item,index) in row.tag_list" :key="index+'biaoqian'">{{item}}</div>
38
+              </div>
39
+            </div>
40
+            <div v-else-if="item.prop=='oprate'">
41
+              <div class="flex" style="padding: 0 10px">
42
+                <div class="c-00B38A pointer" @click="editRadar(row.radar_id)">编辑</div>
43
+                <el-popconfirm @confirm="deleRadar(row.radar_id)" :title="`确定删除【${row.name}】渠道活码?`">
44
+                  <div slot="reference" class="c-00B38A pointer lMar8">删除</div>
45
+                </el-popconfirm>
46
+                <div class="c-00B38A pointer lMar8" @click="goDataAanlyse(row.radar_id)">分析数据</div>
47
+              </div>
48
+            </div>
49
+            <div v-else>{{row[item.prop] ||row[item.prop]==0 ? row[item.prop] : '-'}}</div>
50
+          </div>
51
+        </div>
52
+        </draggable>
53
+          <p class="text-center f14 tMar8 c-d3" v-if="moreloading">加载中...</p>
54
+        <p class="text-center f14 tMar8 c-d3" v-if="noMore">没有更多了</p>
55
+      </div>
56
+      <div class="noData" v-else>暂无数据</div>
57
+
58
+    </div>
59
+
60
+  </div>
61
+</template>
62
+
63
+<script>
64
+  import draggable from "vuedraggable"
65
+export default {
66
+  name: "radarList",
67
+  components:{
68
+    draggable
69
+  },
70
+  props:['propsData'],
71
+  computed: {
72
+    noMore () {
73
+      return this.currPage_len < this.page_size
74
+    },
75
+    disabled () {
76
+      return this.moreloading || this.noMore
77
+    }
78
+  },
79
+  data(){
80
+    return{
81
+      loading: false,
82
+      moreloading: false,
83
+      page: 1,
84
+      page_size: 20,
85
+      height: '',
86
+      tableData:[],
87
+      copy_tableData:[],
88
+      currPage_len:0,
89
+      desCol:[
90
+        { prop: "name", label: "名称" },
91
+        { prop: "type", label: "类型" },
92
+        { prop: "group_name", label: "分组" },
93
+        { prop: "tag_list", label: "客户标签" },
94
+        { prop: "uv_count", label: "总访问人数",},
95
+        { prop: "send_count", label: "总发送次数",},
96
+        { prop: "create_time", label: "添加时间", min_width:'17%'},
97
+        { prop: "oprate", label: "操作", min_width:'17%'}
98
+      ],
99
+    }
100
+  },
101
+  watch:{
102
+    'propsData.initFlag'(){
103
+      this.page=1
104
+      this.tableData=[]
105
+      this.copy_tableData=[]
106
+      this.init()
107
+    }
108
+  },
109
+  created() {
110
+    this.height = document.documentElement.clientHeight - 300 > 400 ? document.documentElement.clientHeight - 300 : 400
111
+    this.init(1)
112
+  },
113
+  methods:{
114
+    load(){
115
+      this.page += 1
116
+      this.init()
117
+    },
118
+    goDataAanlyse(id){
119
+      this.$router.push('/radar_dataAnalyse/'+id)
120
+    },
121
+    editRadar(id){
122
+      this.$router.push({path:'/createRadar',query: {id:id}})
123
+    },
124
+    deleRadar(id){
125
+      this.loading = true
126
+      this.$axios.post(this.URL.BASEURL + this.URL.radar_radarDele, {
127
+        radar_id:id
128
+      }).then((res) => {
129
+        var res = res.data
130
+        this.loading = false
131
+        this.$message({
132
+          message: res.err,
133
+          type: "warning"
134
+        })
135
+        if (res && res.errno == 0) {
136
+          this.init(1)
137
+        }
138
+      }).catch((err) => {
139
+        this.loading = false
140
+      });
141
+    },
142
+
143
+    draggableSort({to,from,item,clone,oldIndex,newIndex}){
144
+      if(!this.copy_tableData[oldIndex].radar_id){
145
+        this.$message({
146
+          message: '被拖动的雷达id错误',
147
+          type: "warning"
148
+        })
149
+        return
150
+      }
151
+      this.$axios.post(this.URL.BASEURL + this.URL.radar_radarSort, {
152
+        operate_radar_id:this.copy_tableData[oldIndex].radar_id,
153
+        behind_radar_id:newIndex-1>=0?this.tableData[newIndex-1].radar_id:'',
154
+        front_radar_id:newIndex+1<this.tableData.length?this.tableData[newIndex+1].radar_id:'',
155
+      }).then((res) => {
156
+        var res = res.data
157
+        if (res && res.errno == 0) {
158
+
159
+      } else if (res.errno != 4002) {
160
+        this.$message({
161
+          message: res.err,
162
+          type: "warning"
163
+        })
164
+      }
165
+    })
166
+    },
167
+    init () {
168
+      this.loading = true
169
+      if(this.currPage_len>=this.page_size){
170
+        this.moreloading = true
171
+      }
172
+      this.$axios.get(this.URL.BASEURL + this.URL.radar_radarList, {
173
+        params:{
174
+          group_id:this.propsData.group_id,
175
+          name:this.propsData.radar_val,
176
+          page: this.page,
177
+          page_size: this.page_size,
178
+        }
179
+      }).then((res) => {
180
+        var res = res.data
181
+        this.loading = false
182
+        if (res && res.errno == 0) {
183
+          this.tableData = [...this.tableData,...res.rst.data]
184
+          this.copy_tableData =  JSON.parse(JSON.stringify(this.tableData))
185
+          this.currPage_len=res.rst.data.length
186
+          this.moreloading = false
187
+        } else if (res.errno != 4002) {
188
+          this.$message({
189
+            message: res.err,
190
+            type: "warning"
191
+          })
192
+        }
193
+      }).catch((err) => {
194
+        this.loading = false
195
+      });
196
+    },
197
+  }
198
+}
199
+</script>
200
+
201
+<style lang="scss" scoped>
202
+  .span_title{
203
+    font-weight: 600;
204
+    color: #000;
205
+    margin: 10px 0 ;
206
+  }
207
+  .ghostClass{
208
+    font-weight: 600;
209
+  }
210
+  .tHead{
211
+    border:1px solid #ddd;
212
+    border-bottom: none;
213
+    div{
214
+      background-color: #f6f6f6 ;
215
+      font-size:14px;
216
+      display:inline-block;
217
+      font-weight:600;
218
+      color:#777;
219
+      text-align: center;
220
+      height:48px;
221
+      line-height:48px
222
+    };
223
+
224
+  }
225
+  .tBody{
226
+    height: calc(100vh - 60px - 62px - 20px - 10px - 50px);
227
+    overflow-y: auto;
228
+    .body_item{
229
+      display: flex;
230
+      align-items: center;
231
+      cursor: move;
232
+      padding:20px 0;
233
+      border:1px solid #ddd;
234
+      border-bottom:none;
235
+      .body_cell{
236
+        font-size:14px;
237
+        color:#333;
238
+        text-align: center;
239
+
240
+      }
241
+    }
242
+  }
243
+  .borderBottomline{
244
+    border-bottom:1px solid #ddd!important;
245
+  }
246
+  .c-00B38A {
247
+    color: #00B38A!important;
248
+  }
249
+  .noData{
250
+    text-align:center;
251
+    margin:20px auto;
252
+  }
253
+</style>

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

@@ -44,6 +44,7 @@ const createChannelCode = () => import(/* webpackChunkName: 'createChannelCode'
44 44
 const codeIndex_radar = () => import(/* webpackChunkName: 'codeIndex_radar' */ '@/components/smartRadar/index.vue')
45 45
 const radar_dataAnalyse = () => import(/* webpackChunkName: 'radar_dataAnalyse' */ '@/components/smartRadar/dataAnalyse.vue')
46 46
 const createRadar = () => import(/* webpackChunkName: 'createRadar' */ '@/components/smartRadar/createRadar.vue')
47
+const h5test = () => import(/* webpackChunkName: 'h5test' */ '@/components/h5test.vue')
47 48
 
48 49
 // name与菜单配置的页面路由一致
49 50
 // meta下isData:true为数据看板,否则为助手