Procházet zdrojové kódy

增加接单中心page3

Yannay před 2 měsíci
rodič
revize
6337217e85

+ 7 - 1
pages/orderDetailNew/components/common.scss

@@ -183,7 +183,9 @@ transition: box-shadow 0.3s ease;
183 183
 
184 184
 // 公共地址标题样式
185 185
 .address-header {
186
-    @include flex-center;
186
+    display: flex;
187
+    justify-content: space-between;
188
+    align-items: center;
187 189
     margin-bottom: map-get($sizes, margin-sm);
188 190
     padding-bottom: map-get($sizes, margin-sm);
189 191
     border-bottom: 1rpx solid map-get($colors, border);
@@ -199,4 +201,8 @@ transition: box-shadow 0.3s ease;
199 201
     .address-title {
200 202
         margin-left: 16rpx;
201 203
     }
204
+
205
+    .add-image-btn {
206
+        margin-top: -10rpx;
207
+    }
202 208
 }

+ 348 - 27
pages/orderDetailNew/components/pageThree.vue

@@ -1,21 +1,5 @@
1 1
 <template>
2 2
     <view class="page-container">
3
-        <view class="card_wrap">
4
-            <view class="detail-image-section">
5
-                <view class="address-header">
6
-                    <text class="address-title">高清细节图</text>
7
-                </view>
8
-                <view class="detail-image-content">
9
-                    <view v-if="detailImages.length > 0" class="detail-image-list">
10
-                        <view class="detail-image-item" v-for="(item, index) in detailImages" :key="'detail-' + index">
11
-                            <pic-comp :src="item"></pic-comp>
12
-                        </view>
13
-                    </view>
14
-                    <view v-else class="no-images">暂无高清细节图</view>
15
-                </view>
16
-            </view>
17
-        </view>
18
-
19 3
         <!-- 支付信息录入卡片 -->
20 4
         <view class="info-card">
21 5
             <view class="info-card-title">支付信息</view>
@@ -45,6 +29,55 @@
45 29
                 </u-col>
46 30
             </u-row>
47 31
         </view>
32
+
33
+        <view class="card_wrap">
34
+            <view class="detail-image-section">
35
+                <view class="detail-image-header">
36
+                    <div class="detail-image-title">高清实物图(拖拽排序)</div>
37
+                </view>
38
+                <view class="detail-image-content">
39
+                    <view class="detail-image-list">
40
+                        <!-- 替换drag事件为touch事件 -->
41
+                        <view class="detail-image-item" v-for="(item, index) in localDetailImages"
42
+                            :key="'detail-' + index" :style="{ opacity: draggingIndex === index ? 0.5 : 1 }"
43
+                            @touchstart="onTouchStart($event, index)" @touchmove="onTouchMove($event, index)"
44
+                            @touchend="onTouchEnd">
45
+                            <pic-comp :src="item"></pic-comp>
46
+                            <view class="image-type-tag">{{ getImageType(index) }}</view>
47
+                            <view class="detail-delete-btn" @click="deleteImage(index)">×</view>
48
+                        </view>
49
+                        <view class="detail-upload-btn" @click="uploadDetailImage">
50
+                            <u-icon name="plus" size="40rpx" color="#999"></u-icon>
51
+                        </view>
52
+                    </view>
53
+                </view>
54
+            </view>
55
+        </view>
56
+
57
+        <!-- 支付总额卡片 -->
58
+        <view class="card_wrap payment-card">
59
+            <view class="payment-section">
60
+                <view class="payment-total-container">
61
+                    <text class="payment-label">支付总额</text>
62
+                    <text class="payment-amount">¥0.00</text>
63
+                </view>
64
+
65
+                <view class="payment-buttons-row">
66
+                    <view class="payment-button" @click="handleUnpaidClick">
67
+                        <u-icon name="star" size="40rpx" color="#ff9500"></u-icon>
68
+                        <text class="button-text">未收</text>
69
+                    </view>
70
+                    <view class="payment-button" @click="handleFollowUpClick">
71
+                        <u-icon name="chat" size="40rpx" color="#108cff"></u-icon>
72
+                        <text class="button-text">待跟进</text>
73
+                    </view>
74
+                </view>
75
+
76
+                <view class="pay-now-button" @click="handlePayNowClick">
77
+                    <text class="button-text">立即支付</text>
78
+                </view>
79
+            </view>
80
+        </view>
48 81
     </view>
49 82
 </template>
50 83
 
@@ -69,19 +102,153 @@ export default {
69 102
                 bankName: '', // 银行名称
70 103
                 bankAccount: '', // 银行账号
71 104
                 idNumber: '' // 身份证号
72
-            }
105
+            },
106
+            // Local copy of detailImages prop to avoid direct mutation
107
+            localDetailImages: [...this.detailImages],
108
+            // 拖拽相关状态
109
+            draggingIndex: -1, // 当前正在拖拽的元素索引
110
+            startX: 0, // 触摸起始X坐标
111
+            startY: 0 // 触摸起始Y坐标
73 112
         };
74 113
     },
114
+    watch: {
115
+        detailImages: {
116
+            handler(newVal) {
117
+                this.localDetailImages = [...newVal];
118
+            },
119
+            deep: true
120
+        }
121
+    },
75 122
     methods: {
123
+        // 上传高清细节图
124
+        uploadDetailImage() {
125
+            uni.chooseImage({
126
+                count: 9 - this.localDetailImages.length, // 最多选择9张
127
+                sizeType: ['compressed'], // 压缩图片
128
+                sourceType: ['album', 'camera'], // 从相册选择或拍照
129
+                success: (res) => {
130
+                    const tempFilePaths = res.tempFilePaths;
131
+                    // 将图片路径添加到数组中
132
+                    this.localDetailImages = [...this.localDetailImages, ...tempFilePaths];
133
+                },
134
+                fail: (err) => {
135
+                    console.error('选择图片失败:', err);
136
+                    uni.showToast({
137
+                        title: '选择图片失败',
138
+                        icon: 'none'
139
+                    });
140
+                }
141
+            });
142
+        },
143
+
144
+        // 删除图片
145
+        deleteImage(index) {
146
+            uni.showModal({
147
+                title: '提示',
148
+                content: '确定要删除这张图片吗?',
149
+                success: (res) => {
150
+                    if (res.confirm) {
151
+                        this.localDetailImages.splice(index, 1);
152
+                    }
153
+                }
154
+            });
155
+        },
156
+
157
+        // 获取图片类型
158
+        getImageType(index) {
159
+            const types = ['正面', '反面', '侧面', '扣子', '编号'];
160
+            return types[index] || `细节${index - 4}`;
161
+        },
162
+
163
+        // 触摸开始(替代dragstart)
164
+        onTouchStart(event, index) {
165
+            this.draggingIndex = index;
166
+            // 记录触摸起始坐标
167
+            this.startX = event.touches[0].clientX;
168
+            this.startY = event.touches[0].clientY;
169
+            console.log('开始拖拽:', index);
170
+        },
171
+
172
+        // 触摸移动(替代dragover/drop)
173
+        onTouchMove(event, currentIndex) {
174
+            if (this.draggingIndex === -1) return; // 没有正在拖拽的元素则返回
175
+
176
+            const moveX = event.touches[0].clientX;
177
+            const moveY = event.touches[0].clientY;
178
+            const diffX = moveX - this.startX;
179
+            const diffY = moveY - this.startY;
180
+
181
+            // 简单的拖拽距离判断(避免轻微滑动就触发交换)
182
+            if (Math.abs(diffX) > 20 || Math.abs(diffY) > 20) {
183
+                // 获取当前触摸位置对应的元素索引
184
+                const targetIndex = this.getTargetIndexByPosition(moveX, moveY);
185
+                if (targetIndex !== -1 && targetIndex !== this.draggingIndex) {
186
+                    // 交换数组元素(核心排序逻辑)
187
+                    [this.localDetailImages[this.draggingIndex], this.localDetailImages[targetIndex]] =
188
+                        [this.localDetailImages[targetIndex], this.localDetailImages[this.draggingIndex]];
189
+                    // 更新拖拽索引为目标索引(实现连续拖拽)
190
+                    this.draggingIndex = targetIndex;
191
+                    // 重置起始坐标
192
+                    this.startX = moveX;
193
+                    this.startY = moveY;
194
+                }
195
+            }
196
+        },
197
+
198
+        // 触摸结束(替代dragend)
199
+        onTouchEnd() {
200
+            console.log('拖拽结束');
201
+            this.draggingIndex = -1; // 重置拖拽状态
202
+        },
203
+
204
+        // 根据触摸坐标获取目标元素索引(核心辅助方法)
205
+        getTargetIndexByPosition(x, y) {
206
+            // 获取所有图片元素的位置信息
207
+            const query = uni.createSelectorQuery().in(this);
208
+            return new Promise((resolve) => {
209
+                query.selectAll('.detail-image-item').boundingClientRect(rects => {
210
+                    for (let i = 0; i < rects.length; i++) {
211
+                        const rect = rects[i];
212
+                        // 判断坐标是否在元素范围内
213
+                        if (
214
+                            x >= rect.left &&
215
+                            x <= rect.right &&
216
+                            y >= rect.top &&
217
+                            y <= rect.bottom
218
+                        ) {
219
+                            resolve(i);
220
+                            return;
221
+                        }
222
+                    }
223
+                    resolve(-1);
224
+                }).exec();
225
+            });
226
+        },
227
+
76 228
         // 下一步按钮点击事件
77 229
         handleNextClick() {
78 230
             this.$emit('handleNextClick', {
79 231
                 nowPage: 'formThree',
80 232
                 form: {
81
-                    detailImages: this.detailImages,
233
+                    detailImages: this.localDetailImages,
82 234
                     paymentInfo: this.paymentInfo
83 235
                 }
84 236
             });
237
+        },
238
+
239
+        // 未收按钮点击事件
240
+        handleUnpaidClick() {
241
+            console.log('点击了未收按钮');
242
+        },
243
+
244
+        // 待跟进按钮点击事件
245
+        handleFollowUpClick() {
246
+            console.log('点击了待跟进按钮');
247
+        },
248
+
249
+        // 立即支付按钮点击事件
250
+        handlePayNowClick() {
251
+            console.log('点击了立即支付按钮');
85 252
         }
86 253
     }
87 254
 }
@@ -115,25 +282,70 @@ export default {
115 282
 }
116 283
 
117 284
 .detail-image-content {
285
+    margin-top: 20rpx;
118 286
 
119 287
     .detail-image-list {
120 288
         display: flex;
121 289
         flex-wrap: wrap;
122
-        gap: 24rpx;
290
+        gap: 20rpx;
123 291
     }
124 292
 
125 293
     .detail-image-item {
126
-        width: calc((100% - 24rpx * 2) / 3);
127
-        aspect-ratio: 1 / 1;
294
+        position: relative;
295
+        width: 200rpx;
296
+        height: 200rpx;
297
+        box-sizing: border-box;
298
+        touch-action: none; // 禁止浏览器默认触摸行为
299
+        transition: opacity 0.2s; // 拖拽时的透明度过渡
300
+
301
+        &:active {
302
+            opacity: 0.7;
303
+        }
304
+    }
305
+
306
+    .image-type-tag {
307
+        position: absolute;
308
+        top: 10rpx;
309
+        left: 10rpx;
310
+        background-color: rgba(0, 0, 0, 0.6);
311
+        color: white;
312
+        padding: 5rpx 10rpx;
128 313
         border-radius: 12rpx;
129
-        overflow: hidden;
130
-        box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
314
+        font-size: 22rpx;
315
+        z-index: 1;
316
+    }
317
+
318
+    .detail-delete-btn {
319
+        position: absolute;
320
+        top: -10rpx;
321
+        right: -10rpx;
322
+        width: 40rpx;
323
+        height: 40rpx;
324
+        background-color: #ff4d4f;
325
+        color: #fff;
326
+        border-radius: 50%;
327
+        display: flex;
328
+        align-items: center;
329
+        justify-content: center;
330
+        @include font-styles($size: small, $weight: bold);
331
+        z-index: 10;
332
+    }
333
+
334
+    .detail-upload-btn {
335
+        width: 200rpx;
336
+        height: 200rpx;
337
+        border: 8rpx dashed #ddd;
338
+        border-radius: 30rpx;
339
+        display: flex;
340
+        align-items: center;
341
+        justify-content: center;
131 342
         background-color: #f9f9f9;
132
-        transition: all 0.3s ease;
343
+        box-sizing: border-box;
344
+        cursor: pointer;
133 345
 
134 346
         &:hover {
135
-            transform: translateY(-2rpx);
136
-            box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.15);
347
+            border-color: #108cff;
348
+            background-color: rgba(16, 140, 255, 0.05);
137 349
         }
138 350
     }
139 351
 
@@ -143,9 +355,23 @@ export default {
143 355
         padding: 80rpx 0;
144 356
         background-color: #f9f9f9;
145 357
         border-radius: 12rpx;
358
+        margin-top: 20rpx;
146 359
     }
147 360
 }
148 361
 
362
+.detail-image-header {
363
+    display: flex;
364
+    justify-content: space-between;
365
+    align-items: center;
366
+    margin-bottom: map-get($sizes, margin-sm);
367
+    padding-bottom: map-get($sizes, margin-sm);
368
+    border-bottom: 1rpx solid map-get($colors, border);
369
+}
370
+
371
+.detail-image-title {
372
+    @include font-styles($size: content, $weight: bold, $color: primary);
373
+}
374
+
149 375
 /* 支付信息卡片样式 */
150 376
 .info-card {
151 377
     @include card;
@@ -199,4 +425,99 @@ export default {
199 425
     box-sizing: border-box;
200 426
     @include font-styles($size: small, $weight: regular, $color: secondary);
201 427
 }
202
-</style>
428
+
429
+/* 支付总额卡片样式 */
430
+.payment-card {
431
+    @include card;
432
+    margin-top: 20rpx;
433
+    margin-bottom: 20rpx;
434
+}
435
+
436
+.payment-section {
437
+    padding: map-get($sizes, padding-sm) map-get($sizes, padding);
438
+}
439
+
440
+.payment-total-container {
441
+    background-color: #f5f7fa;
442
+    border: 2rpx solid #e5e7eb;
443
+    border-radius: 12rpx;
444
+    padding: 24rpx 30rpx;
445
+    box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
446
+    display: flex;
447
+    align-items: center;
448
+    justify-content: space-between;
449
+    margin-bottom: 24rpx;
450
+}
451
+
452
+.payment-label {
453
+    font-size: 36rpx;
454
+    color: map-get($colors, text-primary);
455
+    font-weight: 700;
456
+    min-width: 140rpx;
457
+}
458
+
459
+.payment-amount {
460
+    font-size: 48rpx;
461
+    font-weight: 600;
462
+    color: #f53f3f;
463
+    font-family: Consolas, 'Courier New', monospace, -apple-system, BlinkMacSystemFont;
464
+}
465
+
466
+/* 支付按钮行样式 */
467
+.payment-buttons-row {
468
+    display: flex;
469
+    gap: 20rpx;
470
+    margin-bottom: 24rpx;
471
+}
472
+
473
+.payment-button {
474
+    flex: 1;
475
+    border-radius: 12rpx;
476
+    padding: 24rpx 0;
477
+    display: flex;
478
+    flex-direction: column;
479
+    align-items: center;
480
+    justify-content: center;
481
+    background-color: #f5f7fa;
482
+    border: 2rpx solid #e5e7eb;
483
+    cursor: pointer;
484
+    transition: all 0.3s ease;
485
+    gap: 12rpx;
486
+}
487
+
488
+.payment-button:hover {
489
+    background-color: #e6f7ed;
490
+    border-color: #00b42a;
491
+    transform: translateY(-2rpx);
492
+    box-shadow: 0 4rpx 12rpx rgba(0, 180, 42, 0.15);
493
+}
494
+
495
+/* 立即支付按钮样式 */
496
+.pay-now-button {
497
+    width: 100%;
498
+    border-radius: 12rpx;
499
+    padding: 32rpx 0;
500
+    display: flex;
501
+    flex-direction: column;
502
+    align-items: center;
503
+    justify-content: center;
504
+    background-color: #108cff;
505
+    color: #fff;
506
+    cursor: pointer;
507
+    transition: all 0.3s ease;
508
+    gap: 12rpx;
509
+    box-shadow: 0 4rpx 12rpx rgba(16, 140, 255, 0.2);
510
+}
511
+
512
+.pay-now-button:hover {
513
+    background-color: #007aff;
514
+    transform: translateY(-2rpx);
515
+    box-shadow: 0 6rpx 16rpx rgba(16, 140, 255, 0.25);
516
+}
517
+
518
+.button-text {
519
+    font-size: 28rpx;
520
+    font-weight: 500;
521
+    color: inherit;
522
+}
523
+</style>