Kaynağa Gözat

Merge branch 'master' of http://106.52.242.177:3000/askqvn/crm-app into permission

zhangxin 2 ay önce
ebeveyn
işleme
a69254dedb

+ 21 - 15
pages/orderDetailNew/components/orderDetailNewView.vue

@@ -20,7 +20,8 @@
20 20
         </view>
21 21
 
22 22
         <ul class="page">
23
-            <li v-for="(tab, index) in tabs" :key="index" :class="{ 'active': activeIndex === index }">{{ tab }}</li>
23
+            <li @click="handleTabClick(index)" v-for="(tab, index) in tabs" :key="index"
24
+                :class="{ 'active': activeIndex === index }">{{ tab }}</li>
24 25
         </ul>
25 26
     </view>
26 27
 </template>
@@ -113,7 +114,6 @@ export default {
113 114
             console.log("all page data:", this.allFroms[nowPage])
114 115
             // 当点击到第三页时,更新第三页的图片列表
115 116
             if (nowPage === 'formTwo') {
116
-                console.log('品牌', this.detail.brand)
117 117
                 this.$refs.pageThreeComp.getList('2', '3', this.currentReceiptInner.id, this.detail.itemBrand);
118 118
             }
119 119
         },
@@ -142,7 +142,7 @@ export default {
142 142
                 "sendFormId": this.orderId, //接单中心的id,就是接单中心列表的id(发单id)
143 143
                 "clueId": this.detail.clueId,
144 144
                 "item": this.detail.item,
145
-                "brand": this.detail.brand,
145
+                // "brand": this.topInfo.brand,
146 146
                 // "needCheckCode": 1,   //先不传
147 147
                 // "code": null,         //先不传
148 148
                 // "paymentAmount": null, //支付总额page3 先不传
@@ -159,7 +159,7 @@ export default {
159 159
                 // "grossPerformance": "7443.00",   //毛利 performance*splitRatio
160 160
                 // "expressOrderNo": null,   //快递单号+后续加上一个键加上图url
161 161
                 "fileIds": this.fileIds,  //传第三部里面排序完成之后的id的数组,参考编辑收单里面的附件传的方法
162
-                "model": this.detail.model,
162
+                // "model": this.detail.model,
163 163
                 // "splitRatio": "25",   //分成比例,先不传
164 164
                 "customerServiceName": "1", //默认传1,判断入库的类型,回收类入库,销售类入库,维保类入库,第四步传,增加选项下拉
165 165
                 "deptId": this.detail.deptId,
@@ -172,12 +172,12 @@ export default {
172 172
                 "customName": this.pageThreeForm.customName,
173 173
             }
174 174
 
175
-            //调用接口保存收单表单
176
-            if (this.detail.receiptId) {
177
-                this.updateData(params);
178
-            } else {
179
-                this.saveData(params);
180
-            }
175
+            // //调用接口保存收单表单
176
+            // if (this.detail.receiptId) {
177
+            //     this.updateData(params);
178
+            // } else {
179
+            //     this.saveData(params);
180
+            // }
181 181
         },
182 182
         // 确认支付
183 183
         handleConfirmPay() {
@@ -195,7 +195,7 @@ export default {
195 195
                 })
196 196
                 uni.$u.toast(response.msg || '支付成功')
197 197
             } catch (error) {
198
-                uni.$u.toast(`支付失败:${response.msg}`)
198
+                uni.$u.toast(`支付失败:${error}`)
199 199
             }
200 200
         },
201 201
         //确认入库
@@ -213,7 +213,7 @@ export default {
213 213
                 "sendFormId": this.orderId, //接单中心的id,就是接单中心列表的id(发单id)
214 214
                 "clueId": this.detail.clueId,
215 215
                 "item": warehouseInfo.item || '',
216
-                "brand": this.detail.brand,
216
+                // "brand": this.detail.brand,
217 217
                 // "needCheckCode": 1,   //先不传
218 218
                 "code": warehouseInfo.codeStorage || '',         //先不传
219 219
                 // "paymentAmount": null, //支付总额page3 先不传
@@ -223,14 +223,14 @@ export default {
223 223
                 "freight": warehouseInfo.freight || '',         //运费page4加上
224 224
                 "checkCodeFee": warehouseInfo.checkCodeFee || '',  //查码费
225 225
                 // "totalCost": "60230.00",   // 成本合计 =   运费 + 好处费 + 查码费 + 表款(支付总额) + 维修费。
226
-                "sellingPrice": this.topInfo.price,   //实际价格(售价)顶上tab里面的第三栏
226
+                // "sellingPrice": this.topInfo.price,   //实际价格(售价)顶上tab里面的第三栏
227 227
                 // "performance": "29772.00",  //sellingPrice - totalCost
228 228
                 "receiptRemark": warehouseInfo.remarks + ';' + warehouseInfo.uploadedImage || '',//"收单之后还需再跟进", 先不传
229 229
                 "repairAmount": warehouseInfo.repairAmount || '', //维修总金额 ,先不传
230 230
                 "grossPerformance": warehouseInfo.grossPerformance || '',   //毛利 performance*splitRatio
231 231
                 "expressOrderNo": warehouseInfo.expressOrderNo,   //快递单号+后续加上一个键加上图url
232 232
                 "fileIds": this.fileIds,  //传第三部里面排序完成之后的id的数组,参考编辑收单里面的附件传的方法
233
-                "model": this.detail.model,
233
+                // "model": this.detail.model,
234 234
                 // "splitRatio": "25",   //分成比例,先不传
235 235
                 "customerServiceName": "1", //默认传1,判断入库的类型,回收类入库,销售类入库,维保类入库,第四步传,增加选项下拉
236 236
                 "deptId": this.detail.deptId,
@@ -284,6 +284,10 @@ export default {
284 284
                 console.error("获取跟进记录失败:", error);
285 285
                 uni.$u.toast("获取跟进记录失败");
286 286
             }
287
+        },
288
+        handleTabClick(index) {
289
+            this.activeIndex = index;
290
+            this.$refs.pageThreeComp.getList('2', '3', this.currentReceiptInner.id, this.detail.itemBrand);
287 291
         }
288 292
     },
289 293
 
@@ -321,9 +325,11 @@ export default {
321 325
         height: 70rpx;
322 326
         line-height: 80rpx;
323 327
         text-align: center;
324
-        margin-bottom: 10rpx;
328
+        margin-bottom: 20rpx;
325 329
         transition: all 0.3s ease-in-out;
326 330
         font-weight: 800;
331
+        /* 阴影 */
332
+        box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
327 333
     }
328 334
 
329 335
     li.active {

+ 130 - 38
pages/orderDetailNew/components/pageFour.vue

@@ -290,9 +290,7 @@ export default {
290 290
                         grossPerformance: data.grossPerformance || '',//毛业绩
291 291
                         remarks: data.receiptRemark?.split(';')[0] || '',//收单备注  截取备注第一部分
292 292
                     }
293
-                    this.$nextTick(() => {
294
-                        this.getShareList()
295
-                    })
293
+                    this.getShareList()
296 294
                 }
297 295
             },
298 296
         }
@@ -326,6 +324,7 @@ export default {
326 324
             showPersonPicker: false,
327 325
 
328 326
             columnsOrgList: [],
327
+            //传入的分成人名单
329 328
             columnsPersonList: [],
330 329
 
331 330
         };
@@ -362,21 +361,41 @@ export default {
362 361
                 deptId: '',
363 362
                 accountType: '1',
364 363
                 userId: '',
365
-                percentage: 0,
364
+                commissionRate: 0,
366 365
                 isCompanyPerformance: '2',
367 366
                 orgName: '',
368 367
                 userName: '',
369 368
                 id: '',
370 369
                 uuid: Math.random()//唯一标识,仅vfor使用
371 370
             });
372
-            // 重新计算所有行的比例
371
+            //重新计算全部行的分成比例
372
+            this.calculateTotalPercentage();
373
+        },
374
+        // 重新计算全部行的分成比例
375
+        calculateTotalPercentage() {
376
+            //获取选择前端的行的数量
377
+            const frontItems = this.profitSharingList.filter(item => item.accountType == '1');
378
+            const backItems = this.profitSharingList.filter(item => item.accountType == '2');
379
+            const totalFrontItems = frontItems.length;
380
+            const totalBackItems = backItems.length;
381
+            console.log('选择前端的行的数量====>', totalFrontItems)
382
+            console.log('选择后端的行的数量====>', totalBackItems)
383
+            //把profitSharingList中的前端行的分成比例按照 100/数量 重新计算
384
+            this.profitSharingList.map(item => {
385
+                if (item.accountType == '1') {
386
+                    item.commissionRate = (100 / totalFrontItems).toFixed()
387
+                }
388
+                if (item.accountType == '2') {
389
+                    item.commissionRate = (100 / totalBackItems).toFixed()
390
+                }
391
+            })
373 392
         },
374
-
375 393
 
376 394
         // 切换账户类型
377 395
         toggleAccountType(item) {
378 396
             item.accountType = item.accountType == '1' ? '2' : '1';
379 397
             // 重新计算分成比例
398
+            this.calculateTotalPercentage();
380 399
         },
381 400
         // 处理百分比输入
382 401
         handlePercentageInput(item) {
@@ -401,7 +420,8 @@ export default {
401 420
         },
402 421
 
403 422
         // 确认入库方法
404
-        confirmWarehouseEntry() {
423
+        async confirmWarehouseEntry() {
424
+
405 425
 
406 426
             console.log('确认入库', this.orderDetail.id)
407 427
 
@@ -410,15 +430,32 @@ export default {
410 430
                 content: `是否确认入库改订单:${this.orderDetail.item}?`,
411 431
                 success: async (res) => {
412 432
                     if (res.confirm) {
433
+                        //修改状态
413 434
                         await uni.$u.api.oderForm({
414 435
                             status: "3",
415 436
                             id: this.orderDetail.id,
416 437
                         });
417 438
 
439
+                        await uni.$u.api.updateReceiptForm({
440
+                            id: this.currentReceipt.id,
441
+                            code: this.warehouseInfo.codeStorage || '',//编码
442
+                            expressOrderNo: this.warehouseInfo.expressOrderNo || '',//快递单号
443
+                            item: this.warehouseInfo.item || '',//收单物品
444
+                            checkCodeFee: this.warehouseInfo.checkCodeFee || '',//查码费
445
+                            tableFee: this.warehouseInfo.watchPrice || '',//表款
446
+                            benefitFee: this.warehouseInfo.benefitFee || '',//好处费
447
+                            freight: this.warehouseInfo.freight || '',//运费
448
+                            repairAmount: this.warehouseInfo.repairAmount || '',//维修金额
449
+                            grossPerformance: this.warehouseInfo.grossPerformance || '',//毛业绩
450
+                            receiptRemark: this.warehouseInfo.remarks + ';' + this.warehouseInfo.uploadedImage || '',//收单备注
451
+                        });
452
+
418 453
                         //上传物流表单数据
419
-                        this.$emit('confirmInterStore', {
420
-                            warehouseInfo: this.warehouseInfo,
421
-                        })
454
+                        // this.$emit('confirmInterStore', {
455
+                        //     warehouseInfo: this.warehouseInfo,
456
+                        // })
457
+                        //保存入库信息
458
+
422 459
 
423 460
                         //上传分成数据
424 461
                         await this.addShare()
@@ -452,15 +489,18 @@ export default {
452 489
 
453 490
         //初始化分成比例
454 491
         async getShareList() {
492
+
493
+            console.log('当前收单信息', this.currentReceipt.id)
455 494
             const { rows, total } = await uni.$u.api.selectCommissionList({
456 495
                 pageSize: 9999,
457 496
                 pageNum: 1,
458 497
             }, { sendFormId: this.currentReceipt.sendFormId, });
459 498
             console.log('分成比例表格数据', rows)
460
-            rows.map(item => {
499
+            const newRows = rows.filter(item => item.receiptFormId == this.currentReceipt.id)
500
+            newRows.map(item => {
461 501
                 item.uuid = Math.random()//唯一标识
462 502
             })
463
-            this.profitSharingList = rows
503
+            this.profitSharingList = newRows
464 504
         },
465 505
 
466 506
 
@@ -481,6 +521,7 @@ export default {
481 521
                     sendFormId: this.currentReceipt.sendFormId,
482 522
                     userId: item.userId,
483 523
                     userName: item.userName,
524
+                    receiptFormId: this.currentReceipt.id,//关联的收单id
484 525
                 }
485 526
                 if (item.id) {
486 527
                     //更新
@@ -495,26 +536,44 @@ export default {
495 536
         //删除分成
496 537
         async deleteRow(id, uuid) {
497 538
             console.log(id, 'id', uuid, 'uuid')
498
-            //如果没有id说明是新增的,直接删除数组中的项
499
-            if (!id) {
500
-                this.profitSharingList = this.profitSharingList.filter(item => item.uuid != uuid)
501
-                uni.$u.toast('删除成功')
502
-                return
503
-            }
504
-            try {
505
-                await uni.$u.api.deleteClueCommissionForm(id)
506
-                uni.$u.toast('删除成功')
507
-                this.getShareList()
508
-            } catch (error) {
509
-                uni.$u.toast('删除失败,请稍后重试')
510
-            }
539
+            // 确认删除
540
+            uni.showModal({
541
+                title: '确认删除',
542
+                content: '是否确认删除当前行分成比例?',
543
+                success: async (res) => {
544
+                    if (res.confirm) {
545
+                        //如果没有id说明是新增的,直接删除数组中的项
546
+                        if (!id) {
547
+                            this.profitSharingList = this.profitSharingList.filter(item => item.uuid != uuid)
548
+                            uni.$u.toast('删除成功')
549
+                            this.calculateTotalPercentage();
550
+
551
+                            return
552
+                        }
553
+                        try {
554
+                            await uni.$u.api.deleteClueCommissionForm(id)
555
+                            uni.$u.toast('删除成功')
556
+                            this.getShareList()
557
+                        } catch (error) {
558
+                            uni.$u.toast('删除失败,请稍后重试')
559
+                        }
560
+                        //重新计算全部行的分成比例
561
+                        this.calculateTotalPercentage();
562
+                    } else {
563
+                        uni.$u.toast('已取消删除')
564
+                    }
565
+                }
566
+            })
511 567
         },
512 568
 
513 569
         //打开选择框
514 570
         handleSelectOrg(item) {
515 571
             console.log(item.uuid, '当前选择的行的uuid')
516 572
             this.currentEditItem = item.uuid
517
-            this.showOrgPicker = true
573
+            // this.showOrgPicker = true
574
+            this.showPersonPicker = true
575
+            //把当前的组织赋值给当前的组件
576
+            this.columnsPersonList = this.columnsOrgList//获取到的分成人名单
518 577
         },
519 578
         //选择当前的分成人
520 579
         handleSelectPerson(item) {
@@ -523,15 +582,31 @@ export default {
523 582
             //获取当前选择组织的分成人名单
524 583
             // 获取当前行的关联id
525 584
             const deptId = item.deptId
526
-            const org = this.columnsOrgList[0].find(org => org.id == deptId)
527
-            console.log(org, '当前选择的行的组织')
585
+            //递归查找当前选择的组织
586
+            const org = this.findOrg(this.columnsOrgList[0], deptId)
587
+            // const org = this.columnsOrgList[0].find(org => org.id == deptId)
588
+            console.log(org, '当前选择的组织')
528 589
             if (org) {
529 590
                 this.columnsPersonList = [org.children]
530 591
             }
531 592
             // 把当前选择组织的分成人名单赋值给当前行的分成人选项列表
532
-
533 593
             this.showPersonPicker = true
534 594
         },
595
+        //递归查找当前选择的组织
596
+        findOrg(orgList, deptId) {
597
+            for (const org of orgList) {
598
+                if (org.id == deptId) {
599
+                    return org
600
+                }
601
+                if (org.children && org.children.length > 0) {
602
+                    const found = this.findOrg(org.children, deptId)
603
+                    if (found) {
604
+                        return found
605
+                    }
606
+                }
607
+            }
608
+            return null
609
+        },
535 610
 
536 611
         //确认选择组织
537 612
         handleOrgConfirmOrg({ columnIndex, value, values },) {
@@ -554,16 +629,33 @@ export default {
554 629
 
555 630
         //确认选择人
556 631
         handleConfirmPerson({ columnIndex, value, values },) {
557
-            console.log(value, '选择的人')
632
+            console.log(value[0], '选择的人')
633
+            console.log(value[0].isUser, '是否是用户')
558 634
             //把值赋值给当前行
559
-            this.profitSharingList.forEach(item => {
560
-                if (item.uuid == this.currentEditItem) {
561
-                    item.userName = value[0].label
562
-                    item.userId = value[0].id
563
-                }
564
-            })
565
-            this.columnsPersonList = []
566
-            this.showPersonPicker = false
635
+            if (value[0].isUser) {
636
+                //当前选择是用户
637
+                this.profitSharingList.forEach(item => {
638
+                    if (item.uuid == this.currentEditItem) {
639
+                        item.userName = value[0].label
640
+                        item.userId = value[0].id
641
+                    }
642
+                })
643
+                this.columnsPersonList = []
644
+                this.showPersonPicker = false
645
+            } else {
646
+                //当前选择是组织
647
+                // 把组织的label赋值给当前的行的关联
648
+                this.profitSharingList.forEach(item => {
649
+                    if (item.uuid == this.currentEditItem) {
650
+                        item.orgName = value[0].label
651
+                        item.deptId = value[0].id
652
+                    }
653
+                })
654
+                const childrens = value[0].children
655
+                console.log('当前分公司的内部分成人', childrens)
656
+
657
+                this.columnsPersonList = [childrens]
658
+            }
567 659
         },
568 660
         // 取消选择人
569 661
         handleCancelPerson() {

+ 155 - 40
pages/orderDetailNew/components/pageOne.vue

@@ -6,7 +6,7 @@
6 6
             </u-col>
7 7
             <u-col span="3.5">
8 8
                 <u-button size="small" @click="copyAllImages"
9
-                    style="border-radius: 20rpx;border-color: #007AFF;color: #007AFF;">复制全部图片</u-button>
9
+                    style="border-radius: 20rpx;border-color: #007AFF;color: #007AFF;">保存全部图片</u-button>
10 10
             </u-col>
11 11
         </u-row>
12 12
 
@@ -133,45 +133,35 @@ export default {
133 133
                 console.log('currentReceipt 变化了', newVal);
134 134
                 if (newVal) {
135 135
                     //刷新图片列表
136
-                    this.getList('2', '1', newVal.id, this.orderDetail.itemBrand);
137
-                    this.getList('2', '2', newVal.id, this.orderDetail.itemBrand);
136
+                    setTimeout(() => {
137
+                        this.getList('2', '1', newVal.id, this.orderDetail.itemBrand);
138
+                        this.getList('2', '2', newVal.id, this.orderDetail.itemBrand);
139
+                    }, 100)
140
+
138 141
                 }
139 142
             }
140 143
         },
141 144
     },
142 145
     methods: {
143 146
 
144
-
145
-
146
-
147
-
148
-
149
-
150 147
         // 电话卡片点击事件
151 148
         handlePhoneClick() {
152 149
             console.log('电话卡片被点击', '电话号码:', this.orderDetail.phone)
153 150
             if (this.orderDetail.phone) {
154 151
                 //拨打电话
155
-                // uni.makePhoneCall({
156
-                //     phoneNumber: this.orderDetail.phone,
157
-                //     success: () => {
158
-                //         this.$store.commit("call/SET_FORM", {
159
-                //             clueId: this.orderDetail.clueId,
160
-                //             type: "3",
161
-                //             callee: this.orderDetail.phone,
162
-                //         });
163
-                //     },
164
-                // });
152
+                uni.makePhoneCall({
153
+                    phoneNumber: this.orderDetail.phone
154
+                });
165 155
                 //先暂时复制电话号码
166
-                uni.setClipboardData({
167
-                    data: this.orderDetail.phone,
168
-                    success: () => {
169
-                        uni.showToast({
170
-                            title: '电话号码已复制',
171
-                            icon: 'none'
172
-                        })
173
-                    }
174
-                })
156
+                // uni.setClipboardData({
157
+                //     data: this.orderDetail.phone,
158
+                //     success: () => {
159
+                //         uni.showToast({
160
+                //             title: '电话号码已复制',
161
+                //             icon: 'none'
162
+                //         })
163
+                //     }
164
+                // })
175 165
             } else {
176 166
                 uni.showToast({
177 167
                     title: '该订单暂时没有电话号码',
@@ -226,30 +216,155 @@ export default {
226 216
         //一键复制
227 217
         copyAllImages() {
228 218
             // 合并所有图片
229
-            const allImages = [...this.trueUploadList, ...this.chatRecordsUploadList];
219
+            const allImages = [...this.trueUploadList];
230 220
             //取出所有图的url
231 221
             const allUrls = allImages.map(item => item.fileUrl);
232
-            console.log('所有图片:', allUrls)
233
-            console.log('合并后的图片列表:', allUrls)
234 222
             if (allUrls.length > 0) {
235
-                // 复制到剪贴板
236
-                uni.setClipboardData({
237
-                    data: JSON.stringify(allUrls),
238
-                    success: () => {
239
-                        uni.showToast({
240
-                            title: '所有图片已复制',
241
-                            icon: 'none'
242
-                        })
223
+                // 显示保存图片确认弹窗
224
+                uni.showModal({
225
+                    title: '保存图片',
226
+                    content: `是否将 ${allUrls.length} 张图片保存到本地相册?`,
227
+                    confirmText: '保存',
228
+                    // cancelText: '仅复制链接',
229
+                    success: (res) => {
230
+                        if (res.confirm) {
231
+                            // 用户选择保存图片
232
+                            this.saveImagesToLocal(allUrls);
233
+                        } else if (res.cancel) {
234
+                            // 用户选择仅复制链接
235
+                            this.copyImageUrls(allUrls);
236
+                        }
243 237
                     }
244 238
                 })
245 239
             } else {
246 240
                 uni.showToast({
247
-                    title: '没有图片可复制',
241
+                    title: '没有图片可保存',
248 242
                     icon: 'none'
249 243
                 })
250 244
             }
251 245
         },
252 246
 
247
+        // 保存图片到本地相册
248
+        async saveImagesToLocal(imageUrls) {
249
+            try {
250
+                uni.showLoading({
251
+                    title: '正在保存图片...',
252
+                    mask: true
253
+                });
254
+
255
+                const savedImages = [];
256
+                const failedImages = [];
257
+
258
+                // 逐个保存图片
259
+                for (let i = 0; i < imageUrls.length; i++) {
260
+                    const url = imageUrls[i];
261
+                    try {
262
+                        await this.saveSingleImage(url);
263
+                        savedImages.push(url);
264
+                    } catch (error) {
265
+                        console.error(`保存图片失败: ${url}`, error);
266
+                        failedImages.push(url);
267
+                    }
268
+
269
+                    // 更新进度
270
+                    uni.showLoading({
271
+                        title: `正在保存图片... (${i + 1}/${imageUrls.length})`,
272
+                        mask: true
273
+                    });
274
+                }
275
+
276
+                uni.hideLoading();
277
+
278
+                // 显示结果
279
+                let message = `成功保存 ${savedImages.length} 张图片`;
280
+                if (failedImages.length > 0) {
281
+                    message += `,${failedImages.length} 张保存失败`;
282
+                }
283
+
284
+                uni.showToast({
285
+                    title: message,
286
+                    icon: 'none',
287
+                    duration: 3000
288
+                });
289
+
290
+                // 如果有失败的图片,也复制链接作为备选
291
+                if (failedImages.length > 0) {
292
+                    const allUrls = [...savedImages, ...failedImages];
293
+                    this.copyImageUrls(allUrls);
294
+                }
295
+
296
+            } catch (error) {
297
+                uni.hideLoading();
298
+                console.error('保存图片过程中发生错误:', error);
299
+                uni.showToast({
300
+                    title: '保存图片失败',
301
+                    icon: 'error'
302
+                });
303
+            }
304
+        },
305
+
306
+        // 保存单张图片
307
+        saveSingleImage(url) {
308
+            return new Promise((resolve, reject) => {
309
+                // 先下载图片
310
+                uni.downloadFile({
311
+                    url: url,
312
+                    success: (res) => {
313
+                        if (res.statusCode === 200) {
314
+                            // 保存到相册
315
+                            uni.saveImageToPhotosAlbum({
316
+                                filePath: res.tempFilePath,
317
+                                success: () => {
318
+                                    console.log('图片保存成功:', url);
319
+                                    resolve();
320
+                                },
321
+                                fail: (err) => {
322
+                                    console.error('保存到相册失败:', err);
323
+                                    // 如果是权限问题,尝试请求权限
324
+                                    if (err.errMsg.includes('auth denied')) {
325
+                                        uni.showModal({
326
+                                            title: '权限不足',
327
+                                            content: '需要访问相册权限来保存图片,是否去设置?',
328
+                                            success: (modalRes) => {
329
+                                                if (modalRes.confirm) {
330
+                                                    // 打开设置页面
331
+                                                    uni.openSetting({
332
+                                                        success: (settingRes) => {
333
+                                                            console.log('设置页面结果:', settingRes);
334
+                                                        }
335
+                                                    });
336
+                                                }
337
+                                            }
338
+                                        });
339
+                                    }
340
+                                    reject(err);
341
+                                }
342
+                            });
343
+                        } else {
344
+                            reject(new Error('下载失败'));
345
+                        }
346
+                    },
347
+                    fail: (err) => {
348
+                        console.error('下载图片失败:', err);
349
+                        reject(err);
350
+                    }
351
+                });
352
+            });
353
+        },
354
+
355
+        // 复制图片链接
356
+        copyImageUrls(urls) {
357
+            uni.setClipboardData({
358
+                data: JSON.stringify(urls),
359
+                success: () => {
360
+                    uni.showToast({
361
+                        title: '图片链接已复制',
362
+                        icon: 'none'
363
+                    })
364
+                }
365
+            })
366
+        },
367
+
253 368
     },
254 369
 
255 370
 }

+ 69 - 24
pages/orderDetailNew/components/pageThree.vue

@@ -38,21 +38,21 @@
38 38
                 <view class="detail-image-content">
39 39
                     <view class="detail-image-list">
40 40
                         <!-- 占位符元素 -->
41
-                        <view v-show="placeholderIndex !== -1" class="detail-image-placeholder"
41
+                        <!-- <view v-show="placeholderIndex !== -1" class="detail-image-placeholder"
42 42
                             :style="{ transform: placeholderStyle }">
43 43
                             <u-icon name="arrow-right" size="40rpx" color="#108cff"></u-icon>
44
-                        </view>
44
+                        </view> -->
45 45
 
46 46
                         <!-- 图片列表 -->
47
-                        <view class="detail-image-item" v-for="(item, index) in detailImages" :key="'detail-' + index"
48
-                            :class="{
47
+                        <view class="detail-image-item" v-for="(item, index) in detailImages.slice(0, 6)"
48
+                            :key="'detail-' + index" :class="{
49 49
                                 'dragging': draggingIndex === index,
50 50
                                 'can-drop': canDropIndex === index
51 51
                             }" @touchstart.stop="onTouchStart($event, index)" @touchmove.stop="onTouchMove($event)"
52 52
                             @touchend.stop="onTouchEnd" @touchcancel.stop="onTouchEnd">
53 53
                             <pic-comp :src="item.fileUrl"></pic-comp>
54 54
                             <view class="image-type-tag">{{ getImageType(index) }}</view>
55
-                            <view class="detail-delete-btn" @click.stop="deleteImage(item)">×</view>
55
+                            <view class="detail-delete-btn" @click.stop="handleYinCang(item, index)">×</view>
56 56
                         </view>
57 57
 
58 58
                         <!-- 上传按钮 -->
@@ -130,6 +130,9 @@
130 130
                 <!-- 确认转账按钮 -->
131 131
                 <u-button type="primary" size="large" @click="confirmTransfer"
132 132
                     style="margin-top: 40rpx;">确认转账</u-button>
133
+                <u-button type="primary" :plain="true" @click="payNowModelShow = false" size="large"
134
+                    style="margin-top: 40rpx;">取消</u-button>
135
+
133 136
             </view>
134 137
         </u-modal>
135 138
     </view>
@@ -163,7 +166,7 @@ export default {
163 166
                     this.paymentInfo.bankName = newVal.bankName || ''
164 167
                     this.paymentInfo.bankAccount = newVal.bankCardNumber || ''
165 168
                     this.paymentInfo.idNumber = newVal.idCard || ''
166
-                    this.paymentAmount = newVal.tableFee || '0.00'
169
+                    // this.paymentAmount = newVal.tableFee || '0.00'
167 170
                 }
168 171
             },
169 172
             deep: true,
@@ -173,7 +176,9 @@ export default {
173 176
                 if (newVal) {
174 177
                     console.log('这里是page3的', newVal.tableFee)
175 178
                     this.paymentAmount = newVal.tableFee || '0.00'
176
-                    this.getList('2', '3', newVal.id, this.orderDetail.itemBrand);
179
+                    setTimeout(() => {
180
+                        this.getList('2', '3', newVal.id, this.orderDetail.itemBrand);
181
+                    }, 100);
177 182
                 }
178 183
             },
179 184
             deep: true,
@@ -349,19 +354,35 @@ export default {
349 354
         },
350 355
 
351 356
         // 立即支付按钮点击事件
352
-        handlePayNowClick() {
357
+        async handlePayNowClick() {
358
+            //保存
359
+            await uni.$u.api.updateReceiptForm({
360
+                id: this.currentReceipt.id,
361
+                tableFee: this.paymentAmount,
362
+                fileIds: this.detailImages.map(item => item.id).join(',')
363
+            });
364
+
365
+            //保存上面的支付信息
366
+            await uni.$u.api.updateClueOrderForm({
367
+                id: this.orderDetail.id,
368
+                customName: this.paymentInfo.customName || '',
369
+                bankName: this.paymentInfo.bankName || '',
370
+                bankCardNumber: this.paymentInfo.bankAccount || '',
371
+                idCard: this.paymentInfo.idNumber || '',
372
+            });
373
+
353 374
             console.log('点击了立即支付按钮');
354 375
             this.payNowModelShow = true;
355 376
 
356 377
             //让父组件保存数据
357
-            this.$emit('handleNeedSave', {
358
-                fileIds: this.detailImages.map(item => item.id).join(','),
359
-                nowPage: 'formThree',
360
-                form: {
361
-                    ...this.paymentInfo,
362
-                    paymentAmount: this.paymentAmount
363
-                }
364
-            });
378
+            // this.$emit('handleNeedSave', {
379
+            //     fileIds: this.detailImages.map(item => item.id).join(','),
380
+            //     nowPage: 'formThree',
381
+            //     form: {
382
+            //         ...this.paymentInfo,
383
+            //         paymentAmount: this.paymentAmount
384
+            //     }
385
+            // });
365 386
         },
366 387
 
367 388
 
@@ -375,14 +396,28 @@ export default {
375 396
             this.$emit('handleConfirmPay');
376 397
         },
377 398
         // 下一步按钮点击事件
378
-        handleNextClick() {
379
-            console.log('page3点击了下一步按钮', this.detailImages);
380
-            this.$emit('handleNextClick', {
381
-                nowPage: 'formThree',
382
-                form: {
383
-                    ...this.paymentInfo
384
-                }
399
+        async handleNextClick() {
400
+            await uni.$u.api.updateReceiptForm({
401
+                id: this.currentReceipt.id,
402
+                tableFee: this.paymentAmount,
403
+                fileIds: this.detailImages.map(item => item.id).join(',')
385 404
             });
405
+
406
+            await uni.$u.api.updateClueOrderForm({
407
+                id: this.orderDetail.id,
408
+                customName: this.paymentInfo.customName || '',
409
+                bankName: this.paymentInfo.bankName || '',
410
+                bankCardNumber: this.paymentInfo.bankAccount || '',
411
+                idCard: this.paymentInfo.idNumber || '',
412
+            });
413
+
414
+            console.log('page3点击了下一步按钮', this.detailImages);
415
+            // this.$emit('handleNextClick', {
416
+            //     nowPage: 'formThree',
417
+            //     form: {
418
+            //         ...this.paymentInfo
419
+            //     }
420
+            // });
386 421
         },
387 422
 
388 423
         // 确认未收按钮点击事件
@@ -419,6 +454,15 @@ export default {
419 454
                 uni.$u.toast('提交待跟进记录成功');
420 455
             }
421 456
         },
457
+        handleYinCang(item, index) {
458
+            console.log('删除图片:', item, '索引:', index);
459
+            // 从detailImages数组中移除当前项,后续图片会自动前移
460
+            const itemIndex = this.detailImages.findIndex(img => img.fileUrl === item.fileUrl);
461
+            if (itemIndex !== -1) {
462
+                this.detailImages.splice(itemIndex, 1);
463
+                uni.$u.toast('图片已隐藏');
464
+            }
465
+        }
422 466
     }
423 467
 }
424 468
 </script>
@@ -457,6 +501,7 @@ export default {
457 501
         display: flex;
458 502
         flex-wrap: wrap;
459 503
         gap: 20rpx;
504
+        position: relative;
460 505
     }
461 506
 
462 507
     .detail-image-item {
@@ -490,7 +535,7 @@ export default {
490 535
         position: absolute;
491 536
         width: 200rpx;
492 537
         height: 200rpx;
493
-        border: 2rpx dashed #108cff;
538
+        border: 2rpx dashed red;
494 539
         background-color: rgba(16, 140, 255, 0.1);
495 540
         border-radius: 8rpx;
496 541
         display: flex;

+ 147 - 5
pages/orderDetailNew/components/pageTwo.vue

@@ -173,7 +173,9 @@ export default {
173 173
             handler(newVal) {
174 174
                 if (newVal) {
175 175
                     this.approvedPrice = Number(newVal.sellingPrice) || 0;
176
-                    this.getList('2', '3', newVal.id, this.orderDetail.itemBrand);
176
+                    setTimeout(() => {
177
+                        this.getList('2', '3', newVal.id, this.orderDetail.itemBrand);
178
+                    }, 100)
177 179
                 }
178 180
             },
179 181
             deep: true,
@@ -229,11 +231,145 @@ export default {
229 231
 
230 232
         // 复制所有高清细节图链接
231 233
         copyAllDetailImages() {
234
+            // 合并所有图片
235
+            const allImages = [...this.detailImages];
236
+            //取出所有图的url
237
+            const allUrls = allImages.map(item => item.fileUrl);
238
+            if (allUrls.length > 0) {
239
+                // 显示保存图片确认弹窗
240
+                uni.showModal({
241
+                    title: '保存图片',
242
+                    content: `是否将 ${allUrls.length} 张图片保存到本地相册?`,
243
+                    confirmText: '保存',
244
+                    success: (res) => {
245
+                        if (res.confirm) {
246
+                            // 用户选择保存图片
247
+                            this.saveImagesToLocal(allUrls);
248
+                        }
249
+                    }
250
+                })
251
+            } else {
252
+                uni.showToast({
253
+                    title: '没有图片可复制',
254
+                    icon: 'none'
255
+                })
256
+            }
257
+        },
258
+        // 保存图片到本地相册
259
+        async saveImagesToLocal(imageUrls) {
260
+            try {
261
+                uni.showLoading({
262
+                    title: '正在保存图片...',
263
+                    mask: true
264
+                });
265
+
266
+                const savedImages = [];
267
+                const failedImages = [];
268
+
269
+                // 逐个保存图片
270
+                for (let i = 0; i < imageUrls.length; i++) {
271
+                    const url = imageUrls[i];
272
+                    try {
273
+                        await this.saveSingleImage(url);
274
+                        savedImages.push(url);
275
+                    } catch (error) {
276
+                        console.error(`保存图片失败: ${url}`, error);
277
+                        failedImages.push(url);
278
+                    }
279
+                    
280
+                    // 更新进度
281
+                    uni.showLoading({
282
+                        title: `正在保存图片... (${i + 1}/${imageUrls.length})`,
283
+                        mask: true
284
+                    });
285
+                }
286
+
287
+                uni.hideLoading();
232 288
 
289
+                // 显示结果
290
+                let message = `成功保存 ${savedImages.length} 张图片`;
291
+                if (failedImages.length > 0) {
292
+                    message += `,${failedImages.length} 张保存失败`;
293
+                }
294
+
295
+                uni.showToast({
296
+                    title: message,
297
+                    icon: 'none',
298
+                    duration: 3000
299
+                });
300
+
301
+                // 如果有失败的图片,也复制链接作为备选
302
+                if (failedImages.length > 0) {
303
+                    const allUrls = [...savedImages, ...failedImages];
304
+                    this.copyImageUrls(allUrls);
305
+                }
306
+
307
+            } catch (error) {
308
+                uni.hideLoading();
309
+                console.error('保存图片过程中发生错误:', error);
310
+                uni.showToast({
311
+                    title: '保存图片失败',
312
+                    icon: 'error'
313
+                });
314
+            }
315
+        },
316
+        // 保存单张图片
317
+        saveSingleImage(url) {
318
+            return new Promise((resolve, reject) => {
319
+                // 先下载图片
320
+                uni.downloadFile({
321
+                    url: url,
322
+                    success: (res) => {
323
+                        if (res.statusCode === 200) {
324
+                            // 保存到相册
325
+                            uni.saveImageToPhotosAlbum({
326
+                                filePath: res.tempFilePath,
327
+                                success: () => {
328
+                                    console.log('图片保存成功:', url);
329
+                                    resolve();
330
+                                },
331
+                                fail: (err) => {
332
+                                    console.error('保存到相册失败:', err);
333
+                                    // 如果是权限问题,尝试请求权限
334
+                                    if (err.errMsg.includes('auth denied')) {
335
+                                        uni.showModal({
336
+                                            title: '权限不足',
337
+                                            content: '需要访问相册权限来保存图片,是否去设置?',
338
+                                            success: (modalRes) => {
339
+                                                if (modalRes.confirm) {
340
+                                                    // 打开设置页面
341
+                                                    uni.openSetting({
342
+                                                        success: (settingRes) => {
343
+                                                            console.log('设置页面结果:', settingRes);
344
+                                                        }
345
+                                                    });
346
+                                                }
347
+                                            }
348
+                                        });
349
+                                    }
350
+                                    reject(err);
351
+                                }
352
+                            });
353
+                        } else {
354
+                            reject(new Error('下载失败'));
355
+                        }
356
+                    },
357
+                    fail: (err) => {
358
+                        console.error('下载图片失败:', err);
359
+                        reject(err);
360
+                    }
361
+                });
362
+            });
233 363
         },
234 364
 
235 365
         // 下一步按钮点击事件
236 366
         async handleNextClick() {
367
+            //调接口保存当前的核准价
368
+            await uni.$u.api.updateReceiptForm({
369
+                id: this.currentReceipt.id,
370
+                sellingPrice: this.approvedPrice,
371
+            });
372
+
237 373
             // 创建一个只包含被勾选checkbox对应数据的对象
238 374
             const result = {};
239 375
 
@@ -310,17 +446,22 @@ export default {
310 446
         },
311 447
         checkFollowUpContent() {
312 448
             // 检查跟进记录是否包含上面的三个选择
449
+            //每个检查到一个就不继续检查了
450
+            let hasContactMaster = false;
451
+            let hasPhotoTips = false;
452
+            let hasFace2face = false;
313 453
             this.followUpListInner.forEach(item => {
314 454
                 console.log('这里是跟进记录', item)
315 455
                 // 判断内容是否含有联系师傅,师傅拍图技巧,到达客户面对面,如果包含的话就上面对应的box就打上对勾
316
-                if (item.includes('联系师傅')) {
456
+                if (item.includes('联系师傅') && !hasContactMaster) {
317 457
                     this.selectedCheckbox.push('contact师傅');
318 458
                     // 联系师傅的手机号,已:为分割,取后面的内容
319 459
                     const phone = item.split(';')[1] || '';
320 460
                     console.log('联系师傅的手机号111111', phone)
321 461
                     this.formData.contactPhone = phone;
462
+                    hasContactMaster = true;
322 463
                 }
323
-                if (item.includes('师傅拍图技巧')) {
464
+                if (item.includes('师傅拍图技巧') && !hasPhotoTips) {
324 465
                     this.selectedCheckbox.push('photo技巧');
325 466
                     // 师傅拍图技巧的内容,已:为分割,取后面的内容
326 467
                     const photoTips = item.split(';')[1] || '';
@@ -329,9 +470,9 @@ export default {
329 470
                     //把url转为数组
330 471
                     const urlArray = urls.split(',').map(url => url.trim());
331 472
                     this.photoTipsImages = [...this.photoTipsImages, ...urlArray];
332
-
473
+                    hasPhotoTips = true;
333 474
                 }
334
-                if (item.includes('到达客户面对面')) {
475
+                if (item.includes('到达客户面对面') && !hasFace2face) {
335 476
                     this.selectedCheckbox.push('face2face');
336 477
                     // 到达客户面对面的内容,已:为分割,取后面的内容
337 478
                     const face2faceNotes = item.split(';')[1] || '';
@@ -340,6 +481,7 @@ export default {
340 481
                     //把url转为数组
341 482
                     const urlArray = urls.split(',').map(url => url.trim());
342 483
                     this.face2faceImages = [...this.face2faceImages, ...urlArray];
484
+                    hasFace2face = true;
343 485
                 }
344 486
             })
345 487
         },

+ 2 - 2
pages/orderDetailNew/mixin/imgUploadAndDownLoad.js

@@ -34,12 +34,12 @@ export default {
34 34
         },
35 35
         //获取文件列表
36 36
         async getList(type, orderFileType, receiptID, itemBrand) {
37
-            console.log('获取文件列表', type, receiptID)
37
+            console.log('获取文件列表', itemBrand, type, receiptID, orderFileType)
38 38
             // console.log('当前的订单id', this.orderDetail.id)
39 39
             // console.log('当前的收单id', this.currentReceipt.id)
40 40
             try {
41 41
                 const params = {
42
-                    clueId: this.orderDetail.clueId,
42
+                    clueId: this.currentReceipt.clueId,
43 43
                     sourceId: this.currentReceipt.id,//默认先用receiptID查,如果没有返回情况下用orderID查
44 44
                     type,
45 45
                     orderFileType,

+ 173 - 89
pages/orderForm/index.vue

@@ -7,76 +7,73 @@
7 7
 		<view class="form_wrap">
8 8
 			<u--form labelPosition="top" labelWidth="100" :model="form" :rules="rules" ref="form" class="form_wrap"
9 9
 				:errorType="'toast'">
10
-				<u-form-item label="物品品牌" prop="brand">
10
+				<u-form-item label="品牌" prop="brand" class="brand_wrap">
11 11
 					<ld-select :list="brandDict" label-key="dictLabel" value-key="dictValue" placeholder="请选择物品品牌"
12
-						v-model="form.brand" :border="false"></ld-select>
12
+						v-model="form.brand" :border="false" border></ld-select>
13 13
 					<u-icon slot="right" name="arrow-right"></u-icon>
14 14
 				</u-form-item>
15 15
 
16
-				<u-row justify="space-between">
17
-					<u-form-item label="型号" prop="model">
18
-						<u-col span="6">
19
-							<u--input v-model="form.model" placeholder="请输入型号" border="none"></u--input>
20
-
21
-						</u-col>
22
-					</u-form-item>
23
-
24
-					<u-form-item label="实价" prop="price">
25
-						<u-col span="6">
26
-							<u--input v-model="form.price" placeholder="请输入实价" border="none"></u--input>
27
-						</u-col>
16
+				<u-row gutter="5" justify="space-between">
17
+					<u-col span="6">
18
+						<u-form-item label="型号" prop="model">
19
+							<u--input v-model="form.model" placeholder="例如:CF小号" border="surround"></u--input>
20
+						</u-form-item>
21
+					</u-col>
22
+					 <u-col span="6">
23
+                        <u-form-item label="实价" prop="price">
24
+							<u--input v-model="form.price" placeholder="0.00" border="surround"></u--input>
28 25
 					</u-form-item>
26
+                    </u-col>
29 27
 				</u-row>
30 28
 
31
-				<u-row justify="space-between">
32
-					<u-form-item label="客户电话" prop="phone">
33
-						<u-col span="6">
34
-							<u--input v-model="form.phone" placeholder="请输入客户电话" border="none"></u--input>
35
-
36
-						</u-col>
37
-					</u-form-item>
38
-
39
-					<u-form-item label="客户微信" prop="wechat">
40
-						<u-col span="6">
41
-							<u--input v-model="form.wechat" placeholder="请输入客户微信" border="none"></u--input>
42
-						</u-col>
43
-					</u-form-item>
29
+				<u-row gutter="5" justify="space-between">
30
+					<u-col span="6">
31
+						<u-form-item label="客户电话" prop="phone">
32
+							<u--input v-model="form.phone" placeholder="电话号" border="surround"></u--input>
33
+						</u-form-item>
34
+					</u-col>
35
+					 <u-col span="6">
36
+						<u-form-item label="客户微信" prop="wechat">
37
+							<u--input v-model="form.wechat" placeholder="微信号" border="surround"></u--input>
38
+						</u-form-item>
39
+					</u-col>
44 40
 				</u-row>
45
-
46
-				<u-form-item label="省市区">
47
-					<pick-regions :defaultRegion="defaultRegion" @getRegion="handleGetRegion">
48
-						<view class="region-picker">
49
-							<template v-if="form.province">
50
-								<u--input :value="form.province + '/' + form.city + '/' + form.area" placeholder="点击选择"
51
-									readonly suffixIcon="arrow-right" suffixIconStyle="color : #c0c4cc"></u--input>
52
-							</template>
53
-							<template v-else>
54
-								<u--input placeholder="点击选择" readonly suffixIcon="arrow-right"
55
-									suffixIconStyle="color : #c0c4cc"></u--input>
56
-							</template>
57
-						</view>
58
-					</pick-regions>
59
-				</u-form-item>
60
-
61
-				<u-form-item label="详细地址" prop="address" class='form_card'>
62
-					<u--textarea v-model="form.address" placeholder="请输入详细地址" count confirmType="done"></u--textarea>
63
-				</u-form-item>
64
-
65
-				<u-form-item label="上门时间" prop="visitTime">
41
+				<view class="address_wrap">
42
+					<view class="address_title">
43
+						<u-icon name="map" color="#3b82f6" size="16"></u-icon>
44
+						<view>地址信息</view>
45
+					</view>
46
+					<u-form-item label="详细地址" prop="address" class='form_card'>
47
+						<pick-regions :defaultRegion="defaultRegion" @getRegion="handleGetRegion" clearable class="region-picker">
48
+							<view>
49
+								<template v-if="form.province">
50
+									<u--input :value="form.province + '/' + form.city + '/' + form.area" placeholder="点击选择"
51
+										readonly suffixIcon="arrow-right" suffixIconStyle="color : #c0c4cc"></u--input>
52
+								</template>
53
+								<template v-else>
54
+									<u--input placeholder="点击选择" readonly suffixIcon="arrow-right"
55
+										suffixIconStyle="color : #c0c4cc"></u--input>
56
+								</template>
57
+							</view>
58
+						</pick-regions>
59
+					</u-form-item>
60
+					<u--textarea v-model="form.address" placeholder="粘贴地址自动识别(例如:浙江省杭州市...)" confirmType="done" @blur="handleAddressBlur"></u--textarea>
61
+				</view>
62
+				<u-form-item label="上门时间" prop="visitTime" class="visit_time_wrap">
66 63
 					<date-time-picker v-model="form.visitTime" :value-format="'YYYY-MM-DD HH:mm:ss'" :type="'datetime'">
67 64
 					</date-time-picker>
68 65
 				</u-form-item>
69 66
 
70
-				<u-form-item label="类型" prop="category">
71
-					<ld-select :list="categoryDict" label-key="dictLabel" value-key="dictValue" placeholder="请选择类型"
72
-						v-model="form.category" :border="false"></ld-select>
73
-					<u-icon slot="right" name="arrow-right"></u-icon>
67
+				<u-form-item label="类型" prop="category" class="category_wrap">
68
+					<view class="category_select_wrap">
69
+						<ld-select :list="categoryDict" label-key="dictLabel" value-key="dictValue" placeholder="请选择类型"
70
+							v-model="form.category" :border="false"></ld-select>
71
+						<u-icon slot="right" name="arrow-right"></u-icon>
72
+					</view>
74 73
 				</u-form-item>
75 74
 
76
-
77
-
78 75
 				<u-form-item label="价格范围" prop="priceRange">
79
-					<u--input v-model="form.priceRange" placeholder="请输入价格范围" border="none"></u--input>
76
+					<u--input v-model="form.priceRange" placeholder="请输入价格范围" border="surround"></u--input>
80 77
 				</u-form-item>
81 78
 
82 79
 				<u-form-item label="战术选择" prop="tactic">
@@ -88,8 +85,8 @@
88 85
 					</view>
89 86
 				</u-form-item>
90 87
 
91
-				<u-form-item label="备注消息" prop="remarks">
92
-					<u--textarea v-model="form.remarks" placeholder="请输入备注消息" count confirmType="done"></u--textarea>
88
+				<u-form-item label="备注信息" prop="remarks" class="remarks_wrap">
89
+					<u--textarea v-model="form.remarks" placeholder="填写线索来源、客户特殊要求等..." count confirmType="done"></u--textarea>
93 90
 				</u-form-item>
94 91
 
95 92
 			</u--form>
@@ -263,12 +260,31 @@ export default {
263 260
 			this.form.province = provinceData.name;
264 261
 			this.form.city = cityData.name;
265 262
 			this.form.area = areaData.name;
266
-			// 只在详细地址为空时自动填充省市区
267
-			if (!this.form.address || this.form.address.trim() === '') {
268
-				this.form.address = this.form.province + this.form.city + this.form.area;
263
+			
264
+			// 构建完整的地区信息
265
+			const regionText = this.form.province + this.form.city + this.form.area;
266
+			
267
+			// 检查当前地址内容是否为纯地区信息(没有具体街道等)
268
+			const isPureRegion = !this.form.address || 
269
+								this.form.address.trim() === '' ||
270
+								this.form.address.trim().includes(this.form.province) ||
271
+								this.form.address.trim().includes(this.form.city) ||
272
+								this.form.address.trim().includes(this.form.area);
273
+			
274
+			// 如果是纯地区信息或者是空地址,则更新为选择的地区
275
+			if (isPureRegion) {
276
+				this.form.address = regionText;
277
+			} else {
278
+				// 如果有具体地址信息,保留原有地址,但更新地区部分
279
+				// 这里可以保持原有地址不变,让用户自己选择是否更新
280
+				// 或者可以选择性地更新地区信息
269 281
 			}
270 282
 		},
271 283
 
284
+		// 地址失焦时自动解析地址信息
285
+		handleAddressBlur() {
286
+		},
287
+
272 288
 		// 更新各类附件
273 289
 		updateChatFiles(fileList) {
274 290
 			this.form.chatAttachmentList = fileList;
@@ -385,21 +401,16 @@ export default {
385 401
 
386 402
 <style lang="scss" scoped>
387 403
 .oder_form_wrap {
388
-	background-color: #f5f5f5;
404
+	background-color: #f8f9fa;
389 405
 	min-height: 100vh;
390
-	padding-bottom: 100rpx;
406
+	padding-bottom: 10rpx;
391 407
 	padding-top: 10px;
392 408
 	padding-left: 20rpx;
393 409
 	padding-right: 20rpx;
394 410
 }
395 411
 
396
-.form_wrap {
397
-	/* 移除整体背景和边框,让每个form-item成为独立卡片 */
398
-}
399
-
400 412
 .upload_area {
401
-	padding: 0 0rpx;
402
-	margin: 20rpx 0;
413
+	padding: 0 10rpx;
403 414
 }
404 415
 
405 416
 .bottom_btn {
@@ -412,9 +423,7 @@ export default {
412 423
 	box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.1);
413 424
 }
414 425
 
415
-.region-picker {
416
-	width: 100%;
417
-}
426
+
418 427
 
419 428
 ::v-deep .u-form-item {
420 429
 	/* 移除底部边框 */
@@ -422,19 +431,96 @@ export default {
422 431
 	/* 添加卡片样式 */
423 432
 	// background-color: #fff;
424 433
 	border-radius: 16rpx;
425
-	/* 添加阴影效果 */
426
-	/* 添加外边距 */
427
-	margin-bottom: 20rpx;
428 434
 	/* 添加内边距 */
429
-	padding: 20rpx;
435
+	padding: 10rpx;
430 436
 	/* 确保内容不会溢出 */
431 437
 	overflow: hidden;
438
+	.u-input--square{
439
+		border-radius: 20rpx;
440
+	}
441
+	.u-input--square:focus-within,
442
+	.u-input--square.u-input--focus {
443
+		border: 2rpx solid #2563eb !important;
444
+		background-color: #fff !important;
445
+	}
432 446
 }
433
-
434
-.form_card {
447
+.brand_wrap{
448
+	::v-deep .u-form-item__body__right__content{
449
+		border:1px solid #dadbde;
450
+		padding:10rpx;
451
+		border-radius: 20rpx;
452
+		.inputWrap{
453
+			border:none;
454
+		}
455
+	}
456
+}
457
+.address_wrap {
458
+	border-radius: 20rpx;
459
+	padding:24rpx;
460
+	display: flex;
461
+	flex-direction: column;
435 462
 	background-color: #fff;
436 463
 	box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
464
+	margin: 0 10rpx;
465
+	.address_title {
466
+		display: flex;
467
+		align-items: center;
468
+		background-color: #fff;
469
+		padding-bottom: 12rpx;
470
+		gap:16rpx;
471
+		font-size:26rpx;
472
+		color: #6b7280;
473
+		font-weight: 600;
474
+	}
475
+	::v-deep .u-form-item{
476
+		margin-bottom:0 !important;
477
+		padding:0;
478
+		.u-input--square{
479
+			background-color: #f9fafb;
480
+		}
481
+	}
482
+	::v-deep .u-textarea--radius{
483
+		border-radius: 20rpx;
484
+	}
485
+	.region-picker {
486
+		width: 100%;
487
+	}
488
+	::v-deep .u-textarea{
489
+		background-color: #f9fafb;
490
+	}
491
+}
437 492
 
493
+.visit_time_wrap{
494
+	::v-deep .uni-date-x{
495
+		border-radius: 10px;
496
+		padding: 8rpx 10rpx;
497
+		border:1px solid #dadbde;
498
+		background-color: #f8f9fa;
499
+	}
500
+}
501
+.category_wrap{
502
+	.category_select_wrap{
503
+		border-radius: 20rpx;
504
+		border:1px solid #dadbde;
505
+		padding:6rpx;
506
+		width:100%;
507
+		::v-deep .ldSelectInput{
508
+			font-size: 28rpx !important;
509
+		}
510
+	}
511
+	.category_select_wrap:focus-within,
512
+	.category_select_wrap:focus {
513
+		border: 2rpx solid #2563eb !important;
514
+		background-color: #fff !important;
515
+	}
516
+}
517
+.remarks_wrap{
518
+	.u-textarea{
519
+		background-color: #fff;
520
+	}
521
+	::v-deep .u-textarea--radius{
522
+		border-radius: 20rpx;
523
+	}
438 524
 }
439 525
 
440 526
 ::v-deep .u-form-item__body {
@@ -444,20 +530,17 @@ export default {
444 530
 
445 531
 ::v-deep .u-form-item__body__left__content__label {
446 532
 	color: rgb(107 114 128 / 1) !important;
447
-	font-size: 0.75rem;
448
-	line-height: 1rem;
533
+	font-size: 28rpx;
449 534
 	font-weight: 700;
450 535
 }
451 536
 
452
-
453 537
 .u-button {
454 538
 	border-radius: 40rpx;
455
-	background-color: rgb(29 78 216 / var(--tw-bg-opacity, 1));
456
-	--tw-text-opacity: 1;
457
-	color: rgb(255 255 255 / var(--tw-text-opacity, 1));
539
+	background-color:#2563eb;
540
+	border:none;
541
+	color:#fff;
458 542
 	font-weight: 700;
459
-	font-size: 1rem;
460
-	line-height: 1.5rem;
543
+	font-size: 40rpx;
461 544
 	height: 100rpx;
462 545
 }
463 546
 
@@ -478,7 +561,7 @@ export default {
478 561
 	line-height: 80rpx;
479 562
 	text-align: center;
480 563
 	border-radius: 30rpx;
481
-	background-color: #f5f5f5;
564
+	background-color: #f9fafb;
482 565
 	color: rgb(107 114 128 / 1);
483 566
 	font-size: 28rpx;
484 567
 	transition: all 0.3s ease;
@@ -486,8 +569,9 @@ export default {
486 569
 }
487 570
 
488 571
 .tactic-button.active {
489
-	border-color: rgb(29 78 216 / 1);
490
-	color: rgb(29 78 216 / 1);
572
+	border-color: #3b82f6;
573
+	color: #3b82f6;
574
+	background-color: #eff6ff;
491 575
 }
492 576
 
493 577
 .tactic-button::after {
@@ -503,7 +587,7 @@ export default {
503 587
 	width: 25rpx;
504 588
 	height: 25rpx;
505 589
 	border-radius: 50%;
506
-	background-color: rgb(29 78 216 / 1);
590
+	background-color: #3b82f6;
507 591
 	opacity: 0;
508 592
 	transition: all 0.3s ease;
509 593
 }

+ 88 - 21
pages/pagereceivecenter/pagereceivecenter.vue

@@ -19,16 +19,41 @@ export default {
19 19
             currentOrder: {},
20 20
             followUpModelShow: false,
21 21
             followUpNotes: '',
22
+            countdown: 300,
23
+            countdownIntervals: null
22 24
         }
23 25
     },
24 26
     onLoad() {
25 27
         //初始调用
26 28
         this.getOrderList();
29
+        this.countdownInterval()
27 30
         // uni.navigateTo({
28 31
         //     url: `/pages/orderDetailNew/index?orderId=5464&item=测试发单&type=undefined&clueId=1973381744953516033`,
29 32
         // })
30 33
     },
34
+    onUnload() {
35
+        clearInterval(this.countdownInterval);
36
+    },
37
+    watch: {
38
+        countdown: {
39
+            handler(newVal, oldVal) {
40
+                if (newVal <= 0) {
41
+                    this.orderList.forEach(order => {
42
+                        if (order.status == 1) {
43
+                            this.handleBtnClick('isBusy', order)
44
+                        }
45
+                    })
46
+                }
47
+            },
48
+            immediate: true
49
+        }
50
+    },
31 51
     methods: {
52
+        countdownInterval() {
53
+            this.countdownInterval = setInterval(() => {
54
+                this.countdown--
55
+            }, 1000);
56
+        },
32 57
         //获取列表数据
33 58
         async getOrderList() {
34 59
             try {
@@ -175,6 +200,7 @@ export default {
175 200
             if (res.code == 200) {
176 201
                 uni.$u.toast('提交待跟进记录成功');
177 202
             }
203
+            this.followUpNotes = '';
178 204
         },
179 205
     }
180 206
 }
@@ -201,10 +227,33 @@ export default {
201 227
                             <!-- <view class="mainLindImg">
202 228
                                 <image :src="'/static/acceptOrder/orderCardPic.jpg'" v-if="item.src" />
203 229
                             </view> -->
230
+                            <view class="itemName">{{ item.item || '暂无项目' }}</view>
231
+
204 232
                             <view class="mainLindInfo">
205
-                                <view class="itemName">{{ item.item || '暂无项目' }}</view>
206
-                                <view>发单人:{{ item.createNickName || '未知' }}</view>
207
-                                <view>{{ item.sendDate || '暂无时间' }}</view>
233
+                                <view class="infoItem">
234
+                                    <view class="infoItemTitle">发单人:</view>
235
+                                    <view>{{ item.createNickName || '未知' }}</view>
236
+                                </view>
237
+                                <view class="infoItem">
238
+                                    <view class="infoItemTitle">机构:</view>
239
+                                    <view>{{ item.orgName || '暂无机构' }}</view>
240
+                                </view>
241
+                                <view class="infoItem">
242
+                                    <view class="infoItemTitle">电话:</view>
243
+                                    <view>{{ item.phone || '暂无电话' }}</view>
244
+                                </view>
245
+                                <view class="infoItem">
246
+                                    <view class="infoItemTitle">接单人:</view>
247
+                                    <view>{{ item.identificationName || '暂无所属人' }}</view>
248
+                                </view>
249
+                                <view class="infoItem">
250
+                                    <view class="infoItemTitle">运营人:</view>
251
+                                    <view>{{ item.clueOperationName || '暂无运营人' }}</view>
252
+                                </view>
253
+                                <view class="infoItem">
254
+                                    <view class="infoItemTitle">发单日期:</view>
255
+                                    <view>{{ item.sendDate || '暂无时间' }}</view>
256
+                                </view>
208 257
                             </view>
209 258
                         </view>
210 259
 
@@ -217,27 +266,24 @@ export default {
217 266
 
218 267
                         <view class="Btns">
219 268
 
220
-                            <view class="btnGroup"
221
-                                v-if="item && (item.status == '1' || item.status == null || item.status === undefined)">
269
+                            <view class="btnGroup" v-if="item && (item.status == '1')">
222 270
                                 <view class="card-button" @click.stop="handleBtnClick('acceptOrder', item)">立即接单</view>
223
-                                <view class=" card-button isBusy" @click.stop="handleBtnClick('isBusy', item)">在忙</view>
271
+                                <view class=" card-button isBusy" @click.stop="handleBtnClick('isBusy', item)">
272
+                                    在忙({{ countdown }}s)</view>
224 273
                             </view>
225 274
 
226
-                            <view class="btnGroup"
227
-                                v-if="item && (item.status == '2' || item.status == null || item.status === undefined)">
275
+                            <view class="btnGroup" v-if="item && (item.status == '2')">
228 276
                                 <view class="card-button willFollow" @click.stop="handleBtnClick('willFollow', item)">
229 277
                                     待跟进
230 278
                                 </view>
231 279
                                 <view class="card-button isBusy" @click.stop="handleBtnClick('tag', item)">打标签</view>
232 280
                             </view>
233 281
 
234
-                            <view class="btnGroup"
235
-                                v-if="item && (item.status == '3' || item.status == null || item.status === undefined)">
282
+                            <!-- <view class="btnGroup" v-if="item && (item.status == '3')">
236 283
                                 <view class="card-button share" @click.stop="handleBtnClick('share', item)">一键分享</view>
237
-                            </view>
284
+                            </view> -->
238 285
 
239
-                            <view class="btnGroup"
240
-                                v-if="item && (item.status == '4' || item.status == null || item.status === undefined)">
286
+                            <view class="btnGroup" v-if="item && (item.status == '4')">
241 287
                                 <view class="card-button oneFollow" @click.stop="handleBtnClick('oneFollow', item)">待跟进
242 288
                                 </view>
243 289
                             </view>
@@ -255,9 +301,9 @@ export default {
255 301
 
256 302
 
257 303
         <!-- 打标签模态窗 -->
258
-        <u-modal :show="tagModalVisible" title="选择标签" @confirm="confirmTag" @cancel="cancelTag">
304
+        <u-modal showCancelButton :show="tagModalVisible" title="选择标签" @confirm="confirmTag" @cancel="cancelTag">
259 305
             <view class="slot-content">
260
-                <u-checkbox-group v-model="currentTags" placement="column">
306
+                <u-checkbox-group class="tagCheckboxGroup" v-model="currentTags" placement="column">
261 307
                     <u-checkbox :customStyle="{ marginBottom: '8px' }" v-for="(item, index) in tagList" :key="item.id"
262 308
                         :label="item.name" :name="item.id">
263 309
                     </u-checkbox>
@@ -265,12 +311,11 @@ export default {
265 311
             </view>
266 312
         </u-modal>
267 313
 
268
-        <u-modal :show="followUpModelShow" :title="'填写跟进细节'" :showConfirmButton="false">
314
+        <u-modal showCancelButton :show="followUpModelShow" :title="'填写跟进细节'" @confirm="confirmFollowUp"
315
+            @cancel="followUpModelShow = false">
269 316
             <view class="modal-content">
270 317
                 <u--textarea v-model="followUpNotes" placeholder="请输入情况" confirm-type="done"
271 318
                     style="width: 400rpx; margin-bottom: 30rpx;"></u--textarea>
272
-
273
-                <u-button type="primary" size="large" @click="confirmFollowUp">确认</u-button>
274 319
             </view>
275 320
         </u-modal>
276 321
     </view>
@@ -358,6 +403,7 @@ export default {
358 403
     justify-content: space-between;
359 404
     align-items: center;
360 405
     gap: 20rpx;
406
+    flex-direction: column;
361 407
 }
362 408
 
363 409
 /* 主要内容行图片容器 */
@@ -369,19 +415,30 @@ export default {
369 415
 
370 416
 /* 主要内容行信息容器 */
371 417
 .orderCard .mainLind .mainLindInfo {
372
-    flex: 1;
373
-    display: flex;
418
+    display: grid;
419
+    grid-template-columns: 1fr 1fr;
374 420
     flex-direction: column;
375 421
     gap: 10rpx;
376 422
     font-size: 24rpx;
377 423
     color: #6b7280;
424
+    text-wrap: nowrap;
425
+
426
+    .infoItem {
427
+        display: flex;
428
+
429
+        .infoItemTitle {
430
+            font-weight: 700;
431
+        }
432
+    }
378 433
 }
379 434
 
380 435
 /* 商品名称 */
381
-.orderCard .mainLind .mainLindInfo .itemName {
436
+.orderCard .mainLind .itemName {
382 437
     font-size: 30rpx;
383 438
     font-weight: 700;
384 439
     color: #374751;
440
+    width: 100%;
441
+    text-align: left;
385 442
 }
386 443
 
387 444
 /* 标签区域 */
@@ -453,4 +510,14 @@ export default {
453 510
     background-color: #EFF6FF;
454 511
     color: #2563EB;
455 512
 }
513
+
514
+.cancelBtn {
515
+    margin-top: 20rpx;
516
+}
517
+
518
+
519
+.tagCheckboxGroup {
520
+    display: grid;
521
+    grid-template-columns: repeat(2, 1fr);
522
+}
456 523
 </style>

+ 24 - 24
pages/person/cards/index.vue

@@ -108,7 +108,7 @@
108 108
             </view>
109 109
         </view>
110 110
         <!-- 最新线索 -->
111
-        <view class="latest_clue"  v-if="clueList.length > 0">
111
+        <view class="latest_clue" v-if="clueList.length > 0">
112 112
             <view class="clue_header">
113 113
                 <text class="card_title">最新线索</text>
114 114
                 <view class="more_btn" @click="toPrivateClue">
@@ -232,28 +232,28 @@ export default {
232 232
     },
233 233
 
234 234
     methods: {
235
-        getCardData() {
236
-            uni.$u.api.getPersonCards().then(res => {
237
-              if (res.code === 200) {
238
-                this.cardData = res.data;
239
-              }
240
-            });
241
-        },
242
-        getClueList() {
243
-            uni.$u.api.getPersonLatestClue().then(res => {
244
-                if (res.code === 200) {
245
-                    this.clueList = res.data;
246
-                }
247
-            });
248
-        },
249
-        getChartData() {
250
-            uni.$u.api.getPersonRanking().then(res => {
251
-                if (res.code === 200) {
252
-                    this.chartData.categories = res.data.map(item => item.x);
253
-                    this.chartData.series[0].data = res.data.map(item => item.y);
254
-                }
255
-            });
256
-        },
235
+        // getCardData() {
236
+        //     uni.$u.api.getPersonCards().then(res => {
237
+        //       if (res.code === 200) {
238
+        //         this.cardData = res.data;
239
+        //       }
240
+        //     });
241
+        // },
242
+        // getClueList() {
243
+        //     uni.$u.api.getPersonLatestClue().then(res => {
244
+        //         if (res.code === 200) {
245
+        //             this.clueList = res.data;
246
+        //         }
247
+        //     });
248
+        // },
249
+        // getChartData() {
250
+        //     uni.$u.api.getPersonRanking().then(res => {
251
+        //         if (res.code === 200) {
252
+        //             this.chartData.categories = res.data.map(item => item.x);
253
+        //             this.chartData.series[0].data = res.data.map(item => item.y);
254
+        //         }
255
+        //     });
256
+        // },
257 257
         // 跳转私有线索页面
258 258
         toPrivateClue() {
259 259
             uni.switchTab({ url: '/pages/privateClue/index' });
@@ -264,7 +264,7 @@ export default {
264 264
         this.getClueList();
265 265
         this.getChartData();
266 266
     },
267
-    
267
+
268 268
 };
269 269
 </script>
270 270
 

+ 2 - 2
store/modules/user.js

@@ -28,8 +28,8 @@ export default {
28 28
 		netConfig: {
29 29
 			// http://59.42.9.166:9520/proxy
30 30
 			// http://10.0.7.100:9500
31
-			// ip: "https://crm.nanjingshiyu.com/prod-api", // ip
32
-			ip: "https://crmtest.nanjingshiyu.com/prod-api", // 测试环境ip
31
+			ip: "https://crm.nanjingshiyu.com/prod-api", // ip
32
+			// ip: "https://crmtest.nanjingshiyu.com/prod-api", // 测试环境ip
33 33
 			// ip : "/api", // 测试环境ip
34 34
 			// ip : "http://47.113.184.101", // 测试环境ip
35 35
 			// ip: "http://172.16.7.200", // ip