Bladeren bron

待细节调整

Huanyi 1 maand geleden
bovenliggende
commit
162c865e74

+ 49 - 1
api/fulfiller.js

@@ -48,13 +48,15 @@ export function getAreaChildren(parentId = 0) {
  */
 export function uploadFile(filePath) {
   return new Promise((resolve, reject) => {
+    const token = uni.getStorageSync('fulfiller_token')
     uni.uploadFile({
       url: BASE_URL + '/fulfiller/app/upload',
       filePath: filePath,
       name: 'file',
       header: {
         'clientid': CLIENT_ID,
-        'X-Platform-Code': PLATFORM_CODE
+        'X-Platform-Code': PLATFORM_CODE,
+        'Authorization': token ? `Bearer ${token}` : ''
       },
       success: (res) => {
         try {
@@ -269,3 +271,49 @@ export function getOrderCount() {
     method: 'GET'
   })
 }
+
+/**
+ * 获取我的订单列表
+ * @param {Object} params - { status, content, service, startServiceTime, endServiceTime }
+ */
+export function getMyOrders(params) {
+  return request({
+    url: '/order/subOrder/listOnMyOrder',
+    method: 'GET',
+    data: params
+  })
+}
+
+/**
+ * 获取订单详情
+ * @param {number} id - 订单ID
+ */
+export function getOrderInfo(id) {
+  return request({
+    url: `/order/subOrder/getInfo?id=${id}`,
+    method: 'GET'
+  })
+}
+
+/**
+ * 获取订单日志列表
+ * @param {string} orderId - 订单ID
+ */
+export function getOrderLogs(orderId) {
+  return request({
+    url: `/order/subOrderLog/list?orderId=${orderId}`,
+    method: 'GET'
+  })
+}
+
+/**
+ * 订单打卡
+ * @param {Object} data - { orderId, photos, content, type, title }
+ */
+export function clockIn(data) {
+  return request({
+    url: '/order/subOrder/clockIn',
+    method: 'PUT',
+    data
+  })
+}

+ 239 - 75
pages/orders/detail-logic.js

@@ -1,55 +1,53 @@
+import { getOrderInfo, getOrderLogs, uploadFile, clockIn } from '@/api/fulfiller'
+import { getServiceList } from '@/api/service'
+
 export default {
     data() {
         return {
-            orderType: 1, // 1:接送, 2:喂遛, 3:洗护
+            orderId: null,
+            orderType: 1,
+            orderStatus: 2,
 
-            // Define steps dynamically based on type
-            stepsPickup: ['接单', '到达', '出发', '送达', '完成'],
-            stepsWalkWash: ['接单', '到达', '开始', '结束', '完成'],
+            stepsPickup: ['到达打卡', '确认出发', '送达打卡'],
+            stepsWalkWash: ['到达打卡', '开始服务', '服务结束'],
 
-            currentStep: 1, // 0-indexed (1 means 到达)
+            currentStep: 1,
 
-            // Mock Data
             orderDetail: {
                 type: 1,
-                price: '20.00',
-                timeLabel: '取货时间',
-                time: '2026/02/10 10:00',
+                price: '0.00',
+                timeLabel: '服务时间',
+                time: '',
                 petAvatar: '/static/dog.png',
-                petName: '哈士奇宝宝',
-                petBreed: '哈士奇',
-                serviceTag: '宠物接送',
-                startLocation: '武汉大学宠物店',
-                startAddress: '武汉市洪山区珞喻路458号',
-                endLocation: '张** 189****8451',
-                endAddress: '武汉市武昌区新区大道凤凰广场A座一楼25号',
-                serviceContent: '这里是订单服务内容。',
-                remark: '这里是订单备注信息。',
-                orderNo: 'T1001',
-                createTime: '2026/02/10 09:30',
-                progressLogs: [
-                    { status: '您已接单', time: '2026-02-10 10:00' }
-                ]
+                petName: '',
+                petBreed: '',
+                serviceTag: '',
+                startLocation: '',
+                startAddress: '',
+                endLocation: '',
+                endAddress: '',
+                serviceContent: '',
+                remark: '',
+                orderNo: '',
+                createTime: '',
+                progressLogs: []
             },
 
-            // Modal states
+            serviceList: [],
             showPetModal: false,
             currentPetInfo: {},
             showNavModal: false,
             navTargetPointType: '',
 
-            // Upload Modal State
             showUploadModal: false,
             modalMediaList: [],
             modalRemark: '',
 
-            // 宠护小结弹窗状态
             showSumModal: false,
             sumContent: '',
             sumDate: '',
             sumSigner: '张*哥',
 
-            // 宠物备注弹窗状态
             showPetRemarkInput: false,
             petRemarkText: ''
         }
@@ -59,56 +57,175 @@ export default {
             return this.orderType === 1 ? this.stepsPickup : this.stepsWalkWash;
         },
         displayStatusText() {
+            if (this.currentStep === 4) return '待商家确认';
+            if (this.currentStep >= this.steps.length) return '已完成';
             let status = this.steps[this.currentStep];
             if (status === '已完成' || status === '完成') return '已完成';
             if (status === '已拒绝') return '已拒绝';
             if (status === '接单') {
                 return this.orderType === 1 ? '待接送' : '待服务';
             }
-            // For other active states (出发, 到达, 送达, 开始, 结束)
+            // 对于其他活跃状态 (出发, 到达, 送达, 开始, 结束)
             return this.orderType === 1 ? '配送中' : '服务中';
         },
         currentStatusText() {
-            return this.steps[this.currentStep];
+            if (this.currentStep === 4) return '待确认';
+            return this.currentStep >= this.steps.length ? '已完成' : this.steps[this.currentStep];
         },
         currentTaskTitle() {
+            if (this.currentStep === 4) return '待商家确认';
+            if (this.currentStep >= this.steps.length) return '订单已完成';
             let action = this.steps[this.currentStep];
-            if (action === '到达') return '到达打卡';
-            if (action === '开始') return '开始服务';
-            if (action === '出发') return '确认出发';
-            if (action === '送达' || action === '结束') return '服务完成';
+            if (action === '到达打卡') return '到达打卡';
+            if (action === '开始服务') return '开始服务';
+            if (action === '确认出发') return '确认出发';
+            if (action === '送达打卡' || action === '服务结束') return '服务完成';
             return action;
         },
         currentTaskDesc() {
+            if (this.currentStep === 4) return '服务已提交,请等待商家确认完成后即可结束订单';
+            if (this.currentStep >= this.steps.length) return '感谢您的服务,请注意休息';
             let action = this.steps[this.currentStep];
-            if (action === '到达') {
+            if (action === '到达打卡') {
                 return '打卡穿着工装消毒站门口的照片或视频';
             }
-            if (this.orderType === 1) { // 送货
-                if (action === '出发') return '拍摄宠物上车/出发时的状态照片或视频';
-                if (action === '送达') return '打卡确认送达的照片或视频';
-            } else if (this.orderType === 2) { // 喂遛
-                if (action === '开始') return '开始服务并拍摄照片或视频';
-                if (action === '结束') return '服务完成拍摄照片或视频';
-            } else if (this.orderType === 3) { // 洗护
-                if (action === '开始') return '开始服务并拍摄照片或视频';
-                if (action === '结束') return '服务完成拍摄照片或视频';
+            if (this.orderType === 1) {
+                if (action === '确认出发') return '拍摄宠物上车/出发时的状态照片或视频';
+                if (action === '送达打卡') return '打卡确认送达的照片或视频';
+            } else {
+                if (action === '开始服务') return '开始服务并拍摄照片 or 视频';
+                if (action === '服务结束') return '服务完成拍摄照片或视频';
             }
             return '请按要求提交照片或视频及备注';
         }
     },
-    onLoad(options) {
-        if (options.type) {
-            this.orderType = parseInt(options.type);
-            this.orderDetail.type = this.orderType;
-            if (this.orderType === 2 || this.orderType === 3) {
-                this.orderDetail.serviceTag = this.orderType === 2 ? '上门喂遛' : '上门洗护';
-                this.orderDetail.orderNo = this.orderType === 2 ? 'W1002' : 'X1003';
-                this.currentStep = 1;
-            }
+    async onLoad(options) {
+        if (options.id) {
+            this.orderId = options.id
         }
+        await this.loadServiceList()
+        await this.loadOrderDetail()
     },
     methods: {
+        async loadServiceList() {
+            try {
+                const res = await getServiceList()
+                this.serviceList = res.data || []
+            } catch (err) {
+                console.error('获取服务类型失败:', err)
+            }
+        },
+        async loadOrderDetail() {
+            if (!this.orderId) {
+                console.log('订单ID缺失')
+                uni.showToast({ title: '订单ID缺失', icon: 'none' })
+                return
+            }
+            try {
+                console.log('请求订单详情,ID:', this.orderId)
+                const res = await getOrderInfo(this.orderId)
+                console.log('订单详情响应:', res)
+                const order = res.data
+                if (!order) {
+                    console.log('订单数据为空')
+                    uni.showToast({ title: '订单不存在', icon: 'none' })
+                    return
+                }
+                console.log('订单数据:', order)
+                this.transformOrderData(order)
+                await this.loadOrderLogs()
+            } catch (err) {
+                console.error('获取订单详情失败:', err)
+                uni.showToast({ title: '加载失败', icon: 'none' })
+            }
+        },
+        async loadOrderLogs() {
+            try {
+                const res = await getOrderLogs(this.orderId)
+                const logs = res.data || []
+                console.log('订单日志:', logs)
+                if (logs.length > 0) {
+                    console.log('第一条日志详情:', JSON.stringify(logs[0]))
+                }
+                const progressLogs = logs.filter(log => log.logType === 1)
+                this.orderDetail.progressLogs = progressLogs.map(log => ({
+                    status: log.title || '',
+                    time: log.createTime || '',
+                    medias: log.photoUrls || [],
+                    remark: log.content || ''
+                }))
+
+                // 根据打卡日志的 actionType 确定下一步骤。规则:最新的打卡记录是什么,下一步就往后延。
+                // 仅筛选打卡类型的日志(logType: 1),并按时间倒序排列,取最新的一条作为当前进度的基准
+                const validLogs = logs.filter(log => log.logType === 1 && log.actionType !== undefined)
+                    .sort((a, b) => new Date(b.createTime).getTime() - new Date(a.createTime).getTime())
+
+                if (validLogs.length > 0) {
+                    const latestLog = validLogs[0]
+                    const actionType = latestLog.actionType
+
+                    // 如果日志显示待商家确认,则为无需打卡
+                    if (latestLog.actionType >= 7) {
+                        this.currentStep = 4 // 无需打卡状态
+                    } else if (actionType === 7) {
+                        this.currentStep = 3 // 已完成
+                    } else if (actionType === 6) {
+                        this.currentStep = 2 // 当前应进行:送达打卡/服务结束
+                    } else if (actionType === 4) {
+                        this.currentStep = 1 // 当前应进行:确认出发/开始服务
+                    } else if (actionType === 2 || actionType === 3) {
+                        this.currentStep = 0 // 已接单,当前应进行:到达打卡
+                    } else {
+                        this.currentStep = 0
+                    }
+                } else {
+                    this.currentStep = 0
+                }
+                console.log('根据最新日志推算的当前步骤:', this.currentStep)
+            } catch (err) {
+                console.error('获取订单日志失败:', err)
+            }
+        },
+        transformOrderData(order) {
+            const mode = order.mode || 0
+            const isRoundTrip = mode === 1
+
+            this.orderType = isRoundTrip ? 1 : 2
+            this.orderStatus = order.status || 2
+
+            this.orderDetail = {
+                type: this.orderType,
+                price: (order.price / 100).toFixed(2),
+                timeLabel: isRoundTrip ? '取货时间' : '服务时间',
+                time: order.serviceTime || '',
+                petAvatar: '/static/dog.png',
+                petName: order.petName || order.contact || '',
+                petBreed: order.breed || '',
+                serviceTag: order.groupPurchasePackageName || '',
+                startLocation: order.fromAddress || '',
+                startAddress: order.fromAddress || '',
+                endLocation: (order.contact || '') + ' ' + (order.contactPhoneNumber || ''),
+                endAddress: order.toAddress || '',
+                serviceContent: '',
+                remark: '',
+                orderNo: order.code || 'T' + order.id,
+                createTime: order.serviceTime || '',
+                progressLogs: [
+                    { status: '您已接单', time: order.serviceTime || '' }
+                ]
+            }
+        },
+        updateStepByStatus() {
+            if (this.orderStatus === 2) {
+                this.currentStep = 0
+            } else if (this.orderStatus === 3) {
+                this.currentStep = 1
+            } else if (this.orderStatus === 5) {
+                this.currentStep = this.steps.length - 1
+            } else {
+                this.currentStep = 0
+            }
+        },
         showPetProfile() {
             // Use orderDetail basic info and mock the rest
             this.currentPetInfo = {
@@ -196,12 +313,42 @@ export default {
         closeUploadModal() {
             this.showUploadModal = false;
         },
-        chooseModalMedia() {
+        handleConfirmUpload() {
+            console.log('handleConfirmUpload被调用');
+            this.confirmUploadModal();
+        },
+        async chooseModalMedia() {
+            console.log('chooseModalMedia被调用');
             uni.chooseImage({
                 count: 5 - this.modalMediaList.length,
-                success: (res) => {
-                    this.modalMediaList = this.modalMediaList.concat(res.tempFilePaths);
-                    uni.showToast({ title: '添加成功', icon: 'none' });
+                success: async (res) => {
+                    console.log('选择图片成功,文件路径:', res.tempFilePaths);
+                    uni.showLoading({ title: '上传中...' });
+                    try {
+                        for (const filePath of res.tempFilePaths) {
+                            console.log('上传文件:', filePath);
+                            const uploadRes = await uploadFile(filePath);
+                            console.log('上传响应:', uploadRes);
+                            if (uploadRes.code === 200) {
+                                this.modalMediaList.push({
+                                    url: uploadRes.data.url,
+                                    ossId: uploadRes.data.ossId,
+                                    localPath: filePath
+                                });
+                                console.log('上传成功,url:', uploadRes.data.url);
+                            }
+                        }
+                        uni.hideLoading();
+                        console.log('当前modalMediaList:', this.modalMediaList);
+                        uni.showToast({ title: '上传成功', icon: 'success' });
+                    } catch (err) {
+                        uni.hideLoading();
+                        console.error('上传失败:', err);
+                        uni.showToast({ title: '上传失败', icon: 'none' });
+                    }
+                },
+                fail: (err) => {
+                    console.error('选择图片失败:', err);
                 }
             });
         },
@@ -217,33 +364,50 @@ export default {
             const min = String(now.getMinutes()).padStart(2, '0');
             return `${y}/${m}/${d} ${h}:${min}`;
         },
-        confirmUploadModal() {
+        async confirmUploadModal() {
+            console.log('confirmUploadModal被调用,文件数量:', this.modalMediaList.length);
             if (this.modalMediaList.length === 0) {
                 uni.showToast({ title: '请上传至少一张图片或视频', icon: 'none' });
                 return;
             }
 
-            // Append to timeline
-            this.orderDetail.progressLogs.unshift({
-                status: this.currentTaskTitle,
-                time: this.getCurrentTime(),
-                medias: [...this.modalMediaList],
-                remark: this.modalRemark
-            });
+            try {
+                uni.showLoading({ title: '提交中...' });
+                const uploadedMedias = this.modalMediaList.map(item => item.url);
+                const ossIds = this.modalMediaList.map(item => item.ossId);
 
-            // Advance step
-            if (this.currentStep < this.steps.length - 1) {
-                this.currentStep++;
-            }
+                console.log('准备打卡,ossIds:', ossIds);
+
+                const currentAction = this.steps[this.currentStep];
+                let clockInType = 4;
+                if (currentAction === '到达打卡') {
+                    clockInType = 4;
+                } else if (currentAction === '确认出发' || currentAction === '开始服务') {
+                    clockInType = 6;
+                } else if (currentAction === '送达打卡' || currentAction === '服务结束') {
+                    clockInType = 7;
+                }
+
+                const clockInData = {
+                    orderId: this.orderId,
+                    photos: ossIds,
+                    content: this.modalRemark || '',
+                    type: clockInType,
+                    title: this.currentTaskTitle
+                };
+
+                console.log('打卡数据:', clockInData);
+                await clockIn(clockInData);
+                uni.hideLoading();
 
-            this.closeUploadModal();
-            uni.showToast({ title: '打卡成功', icon: 'success' });
+                this.closeUploadModal();
+                uni.showToast({ title: '打卡成功', icon: 'success' });
 
-            // Check if it's finished now
-            if (this.currentStep === this.steps.length - 1) {
-                setTimeout(() => {
-                    uni.showToast({ title: '订单已完成', icon: 'none' });
-                }, 1500);
+                await this.loadOrderDetail();
+            } catch (err) {
+                uni.hideLoading();
+                console.error('打卡失败:', err);
+                uni.showToast({ title: '打卡失败,请重试', icon: 'none' });
             }
         },
         copyOrderNo() {

+ 1 - 0
pages/orders/detail-style.css

@@ -836,6 +836,7 @@ page {
     background-color: #E0E0E0;
     color: #fff;
     border: none;
+    text-align: center;
 }
 
 .um-submit-btn.active {

+ 25 - 14
pages/orders/detail.vue

@@ -8,10 +8,12 @@
             </view>
             <!-- 进度条区域 -->
             <view class="progress-bar">
-                <view class="step-item" v-for="(step, index) in steps" :key="index" :class="{ 'active': index <= currentStep }">
+                <view class="step-item" v-for="(step, index) in steps" :key="index"
+                    :class="{ 'active': index === currentStep }">
                     <view class="step-circle-wrapper">
                         <!-- Connecting Line before circle, except first item -->
-                        <view class="step-line" v-if="index !== 0" :class="{ 'active-line': index <= currentStep }"></view>
+                        <view class="step-line" v-if="index !== 0" :class="{ 'active-line': index <= currentStep }">
+                        </view>
                         <view class="step-circle">{{ index + 1 }}</view>
                     </view>
                     <text class="step-text">{{ step }}</text>
@@ -58,7 +60,7 @@
                 <!-- 接送类型的地址展现 -->
                 <template v-if="orderDetail.type === 1">
                     <view class="si-row addr-row start-addr">
-                        <view class="icon-circle start"></view>
+                        <view class="icon-circle start"></view>
                         <view class="route-line-vertical"></view>
                         <view class="si-content">
                             <text class="si-addr-title">{{ orderDetail.startLocation }}</text>
@@ -70,7 +72,7 @@
                     </view>
 
                     <view class="si-row addr-row end-addr">
-                        <view class="icon-circle end"></view>
+                        <view class="icon-circle end"></view>
                         <view class="si-content">
                             <text class="si-addr-title">{{ orderDetail.endLocation }}</text>
                             <text class="si-addr-desc">{{ orderDetail.endAddress }}</text>
@@ -112,10 +114,10 @@
             </view>
 
             <!-- 打卡任务 -->
-            <view class="white-card task-card" v-if="currentStep < steps.length - 1">
+            <view class="white-card task-card" v-if="currentStep < steps.length">
                 <text class="tc-title">当前任务:{{ currentTaskTitle }}</text>
                 <text class="tc-desc">{{ currentTaskDesc }}</text>
-                
+
                 <!-- 单个巨大点击区触发弹窗 -->
                 <view class="full-media-add" @click="openUploadModal">
                     <image class="upload-icon-large" src="/static/icons/camera_grey.svg"></image>
@@ -162,7 +164,9 @@
                             </view>
                             <!-- 图片展示 -->
                             <view class="tl-medias" v-if="log.medias && log.medias.length > 0">
-                                <image class="tl-img" v-for="(img, midx) in log.medias" :key="midx" :src="img" mode="aspectFill"></image>
+                                <image class="tl-img" v-for="(img, midx) in log.medias" :key="midx" :src="img"
+                                    mode="aspectFill">
+                                </image>
                             </view>
                             <!-- 备注展示 -->
                             <view class="tl-remark" v-if="log.remark">
@@ -183,11 +187,12 @@
                 <button class="action-btn outline orange-outline" @click="openSumModal">宠护小结</button>
             </view>
             <view class="action-right">
-                <button class="action-btn primary" @click="openUploadModal" v-if="currentStep < steps.length - 1">{{ currentTaskTitle }}</button>
+                <button class="action-btn primary" @click="openUploadModal" v-if="currentStep < steps.length">{{
+                    currentTaskTitle }}</button>
                 <button class="action-btn primary grey-bg" v-else>已完成</button>
             </view>
         </view>
-        
+
         <!-- 宠物档案弹窗 -->
         <view class="pet-modal-mask" v-if="showPetModal" @click="closePetProfile">
             <view class="pet-modal-content" @click.stop>
@@ -249,7 +254,9 @@
                     <!-- 备注日志 -->
                     <view class="pm-log-section">
                         <view class="pm-log-header">
-                            <view style="width:6rpx; height:28rpx; background:#FF9800; border-radius:3rpx; margin-right:12rpx;"></view>
+                            <view
+                                style="width:6rpx; height:28rpx; background:#FF9800; border-radius:3rpx; margin-right:12rpx;">
+                            </view>
                             <text class="pm-log-section-title">备注日志</text>
                         </view>
                         <view class="pm-log-item" v-for="(log, lIndex) in currentPetInfo.petLogs" :key="lIndex">
@@ -300,7 +307,7 @@
                 <view class="um-body">
                     <view class="um-grid">
                         <view class="um-item" v-for="(img, idx) in modalMediaList" :key="idx">
-                            <image class="um-preview" :src="img" mode="aspectFill"></image>
+                            <image class="um-preview" :src="img.url || img.localPath || img" mode="aspectFill"></image>
                             <view class="um-del" @click="removeModalMedia(idx)">×</view>
                         </view>
                         <view class="um-add" @click="chooseModalMedia" v-if="modalMediaList.length < 5">
@@ -308,10 +315,13 @@
                             <text class="um-add-text">拍摄/上传</text>
                         </view>
                     </view>
-                    <textarea class="um-textarea" v-model="modalRemark" placeholder="在此输入备注信息..." placeholder-style="color:#ccc; font-size:26rpx;"></textarea>
+                    <textarea class="um-textarea" v-model="modalRemark" placeholder="在此输入备注信息..."
+                        placeholder-style="color:#ccc; font-size:26rpx;"></textarea>
                 </view>
                 <view class="um-footer">
-                    <button class="um-submit-btn" :class="{'active': modalMediaList.length > 0}" @click="confirmUploadModal">确认提交</button>
+                    <view class="um-submit-btn" :class="{ 'active': modalMediaList.length > 0 }"
+                        @click="handleConfirmUpload">
+                        确认提交</view>
                 </view>
             </view>
         </view>
@@ -345,7 +355,8 @@
                             </view>
                         </view>
                         <view class="sum-section-title">服务内容记录</view>
-                        <textarea class="sum-textarea" v-model="sumContent" auto-height placeholder="请填写服务内容..." placeholder-style="color:#ccc"></textarea>
+                        <textarea class="sum-textarea" v-model="sumContent" auto-height placeholder="请填写服务内容..."
+                            placeholder-style="color:#ccc"></textarea>
                         <view class="sum-sign-row">
                             <text class="sum-sign-label">护宠师签名:</text>
                             <text class="sum-sign-val">{{ sumSigner }}</text>

+ 103 - 121
pages/orders/index.vue

@@ -4,13 +4,8 @@
         <view class="sticky-header">
             <!-- 顶部 Tab (待接送/服务中...) -->
             <view class="status-tabs">
-                <view 
-                    class="tab-item" 
-                    v-for="(tab, index) in tabs" 
-                    :key="index"
-                    :class="{ active: currentTab === index }"
-                    @click="currentTab = index"
-                >
+                <view class="tab-item" v-for="(tab, index) in tabs" :key="index"
+                    :class="{ active: currentTab === index }" @click="currentTab = index">
                     <text>{{ tab }}</text>
                     <view class="indicator" v-if="currentTab === index"></view>
                 </view>
@@ -25,67 +20,57 @@
 
             <!-- 筛选栏 (支持自定义下拉) -->
             <view class="filter-wrapper">
-            <view class="filter-bar">
-                <!-- 订单类型下拉视图 -->
-                <view class="filter-item" :class="{ 'active': activeDropdown === 1 }" @click="toggleDropdown(1)">
-                    <text :class="{ 'active-text': activeDropdown === 1 || currentTypeFilterIdx > 0 }">
-                        {{ currentTypeFilterIdx > 0 ? typeFilterOptions[currentTypeFilterIdx] : '全部类型' }}
-                    </text>
-                    <view class="triangle" :class="activeDropdown === 1 ? 'up' : 'down'"></view>
-                </view>
-                
-                <!-- 服务时间下拉视图 -->
-                <view class="filter-item" :class="{ 'active': activeDropdown === 2 }" @click="toggleDropdown(2)">
-                    <text :class="{ 'active-text': activeDropdown === 2 || hasTimeFilter }">服务时间</text>
-                    <view class="triangle" :class="activeDropdown === 2 ? 'up' : 'down'"></view>
-                </view>
-            </view>
-            
-            <!-- 下拉内容面板与遮罩 -->
-            <view class="dropdown-mask" v-if="activeDropdown !== 0" @click="closeDropdown"></view>
-            <view class="dropdown-panel" v-if="activeDropdown === 1">
-                <view 
-                    class="type-option" 
-                    v-for="(item, index) in typeFilterOptions" 
-                    :key="index"
-                    :class="{ 'selected': currentTypeFilterIdx === index }"
-                    @click="selectType(index)"
-                >
-                    <text>{{ item }}</text>
-                </view>
-            </view>
-            <view class="dropdown-panel calendar-panel" v-if="activeDropdown === 2">
-                <view class="custom-calendar-container">
-                    <!-- 头部 -->
-                    <view class="cal-header">
-                        <uni-icons type="left" size="18" color="#666" @click="prevMonth"></uni-icons>
-                        <text class="cal-title">{{ currentMonth }}</text>
-                        <uni-icons type="right" size="18" color="#666" @click="nextMonth"></uni-icons>
+                <view class="filter-bar">
+                    <!-- 订单类型下拉视图 -->
+                    <view class="filter-item" :class="{ 'active': activeDropdown === 1 }" @click="toggleDropdown(1)">
+                        <text :class="{ 'active-text': activeDropdown === 1 || currentTypeFilterIdx > 0 }">
+                            {{ currentTypeFilterIdx > 0 ? typeFilterOptions[currentTypeFilterIdx] : '全部类型' }}
+                        </text>
+                        <view class="triangle" :class="activeDropdown === 1 ? 'up' : 'down'"></view>
                     </view>
-                    <!-- 星期条 -->
-                    <view class="cal-weekdays">
-                        <text v-for="(wk, idx) in weekDays" :key="idx" class="wk-item">{{ wk }}</text>
+
+                    <!-- 服务时间下拉视图 -->
+                    <view class="filter-item" :class="{ 'active': activeDropdown === 2 }" @click="toggleDropdown(2)">
+                        <text :class="{ 'active-text': activeDropdown === 2 || hasTimeFilter }">服务时间</text>
+                        <view class="triangle" :class="activeDropdown === 2 ? 'up' : 'down'"></view>
                     </view>
-                    <!-- 日期网格 -->
-                    <view class="cal-body">
-                        <!-- Feb 2026 starts on Sunday (index 0), so no empty padding needed for first row -->
-                        <view 
-                            v-for="(day, idx) in calendarDays" 
-                            :key="idx"
-                            class="cal-day-box"
-                            :class="getDateClass(day)"
-                            @click="selectDateItem(day)"
-                        >
-                            <view class="cal-day-text">{{ day }}</view>
-                        </view>
+                </view>
+
+                <!-- 下拉内容面板与遮罩 -->
+                <view class="dropdown-mask" v-if="activeDropdown !== 0" @click="closeDropdown"></view>
+                <view class="dropdown-panel" v-if="activeDropdown === 1">
+                    <view class="type-option" v-for="(item, index) in typeFilterOptions" :key="index"
+                        :class="{ 'selected': currentTypeFilterIdx === index }" @click="selectType(index)">
+                        <text>{{ item }}</text>
                     </view>
                 </view>
-                <view class="calendar-actions">
-                    <button class="cal-btn reset" @click="resetTimeFilter">重置</button>
-                    <button class="cal-btn confirm" @click="confirmTimeFilter">确定</button>
+                <view class="dropdown-panel calendar-panel" v-if="activeDropdown === 2">
+                    <view class="custom-calendar-container">
+                        <!-- 头部 -->
+                        <view class="cal-header">
+                            <text class="cal-nav-btn" @click="prevMonth">‹</text>
+                            <text class="cal-title">{{ currentMonth }}</text>
+                            <text class="cal-nav-btn" @click="nextMonth">›</text>
+                        </view>
+                        <!-- 星期条 -->
+                        <view class="cal-weekdays">
+                            <text v-for="(wk, idx) in weekDays" :key="idx" class="wk-item">{{ wk }}</text>
+                        </view>
+                        <!-- 日期网格 -->
+                        <view class="cal-body">
+                            <!-- Feb 2026 starts on Sunday (index 0), so no empty padding needed for first row -->
+                            <view v-for="(day, idx) in calendarDays" :key="idx" class="cal-day-box"
+                                :class="getDateClass(day)" @click="selectDateItem(day)">
+                                <view class="cal-day-text">{{ day }}</view>
+                            </view>
+                        </view>
+                    </view>
+                    <view class="calendar-actions">
+                        <button class="cal-btn reset" @click="resetTimeFilter">重置</button>
+                        <button class="cal-btn confirm" @click="confirmTimeFilter">确定</button>
+                    </view>
                 </view>
-            </view>
-        </view><!-- end filter-wrapper -->
+            </view><!-- end filter-wrapper -->
         </view><!-- end sticky-header -->
 
         <!-- 订单列表 -->
@@ -118,63 +103,63 @@
                         <view class="pet-profile-btn" @click.stop="showPetProfile(item)">宠物档案</view>
                     </view>
 
-                <!-- 路线信息 (完全复用 Home 样式) -->
-                <view class="route-info">
-                    <template v-if="item.type === 1">
-                        <view class="route-item" @click.stop="openNavigation(item, 'start')">
-                            <view class="icon-circle start">取</view>
-                            <view class="route-line-vertical"></view>
-                            <view class="address-box">
-                                <text class="addr-title">{{ item.startLocation }}</text>
-                                <text class="addr-desc">{{ item.startAddress }}</text>
-                            </view>
-                            <view class="distance-tag">
-                                <text class="distance-text">{{ item.startDistance }}</text>
-                                <view class="nav-icon-circle">
-                                    <image class="nav-arrow" src="/static/icons/nav_arrow.svg"></image>
+                    <!-- 路线信息 (完全复用 Home 样式) -->
+                    <view class="route-info">
+                        <template v-if="item.type === 1">
+                            <view class="route-item" @click.stop="openNavigation(item, 'start')">
+                                <view class="icon-circle start">起</view>
+                                <view class="route-line-vertical"></view>
+                                <view class="address-box">
+                                    <text class="addr-title">{{ item.startLocation }}</text>
+                                    <text class="addr-desc">{{ item.startAddress }}</text>
+                                </view>
+                                <view class="distance-tag">
+                                    <text class="distance-text">{{ item.startDistance }}</text>
+                                    <view class="nav-icon-circle">
+                                        <image class="nav-arrow" src="/static/icons/nav_arrow.svg"></image>
+                                    </view>
                                 </view>
                             </view>
-                        </view>
 
-                        <view class="route-item" @click.stop="openNavigation(item, 'end')">
-                            <view class="icon-circle end">送</view>
-                            <view class="address-box">
-                                <text class="addr-title">{{ item.endLocation }}</text>
-                                <text class="addr-desc">{{ item.endAddress }}</text>
-                            </view>
-                            <view class="distance-tag">
-                                <text class="distance-text">{{ item.endDistance }}</text>
-                                <view class="nav-icon-circle">
-                                    <image class="nav-arrow" src="/static/icons/nav_arrow.svg"></image>
+                            <view class="route-item" @click.stop="openNavigation(item, 'end')">
+                                <view class="icon-circle end">终</view>
+                                <view class="address-box">
+                                    <text class="addr-title">{{ item.endLocation }}</text>
+                                    <text class="addr-desc">{{ item.endAddress }}</text>
+                                </view>
+                                <view class="distance-tag">
+                                    <text class="distance-text">{{ item.endDistance }}</text>
+                                    <view class="nav-icon-circle">
+                                        <image class="nav-arrow" src="/static/icons/nav_arrow.svg"></image>
+                                    </view>
                                 </view>
                             </view>
-                        </view>
-                    </template>
-                    <template v-else>
-                        <view class="route-item" @click.stop="openNavigation(item, 'end')">
-                            <view class="icon-circle service">服</view>
-                            <view class="address-box">
-                                <text class="addr-title">{{ item.endLocation }}</text>
-                                <text class="addr-desc">{{ item.endAddress }}</text>
-                            </view>
-                            <view class="distance-tag">
-                                <text class="distance-text">{{ item.endDistance }}</text>
-                                <view class="nav-icon-circle">
-                                    <image class="nav-arrow" src="/static/icons/nav_arrow.svg"></image>
+                        </template>
+                        <template v-else>
+                            <view class="route-item" @click.stop="openNavigation(item, 'end')">
+                                <view class="icon-circle service">服</view>
+                                <view class="address-box">
+                                    <text class="addr-title">{{ item.endLocation }}</text>
+                                    <text class="addr-desc">{{ item.endAddress }}</text>
+                                </view>
+                                <view class="distance-tag">
+                                    <text class="distance-text">{{ item.endDistance }}</text>
+                                    <view class="nav-icon-circle">
+                                        <image class="nav-arrow" src="/static/icons/nav_arrow.svg"></image>
+                                    </view>
                                 </view>
                             </view>
-                        </view>
-                        <view class="service-content" v-if="item.serviceContent">
-                            <text class="content-label">服务内容:</text>
-                            <text>{{ item.serviceContent }}</text>
-                        </view>
-                    </template>
-                </view>
+                            <view class="service-content" v-if="item.serviceContent">
+                                <text class="content-label">服务内容:</text>
+                                <text>{{ item.serviceContent }}</text>
+                            </view>
+                        </template>
+                    </view>
 
-                <!-- 备注 -->
-                <view class="remark-box" v-if="item.remark">
-                    <text>备注:{{ item.remark }}</text>
-                </view>
+                    <!-- 备注 -->
+                    <view class="remark-box" v-if="item.remark">
+                        <text>备注:{{ item.remark }}</text>
+                    </view>
                 </view><!-- End of card-body -->
 
                 <!-- 按钮组 -->
@@ -188,7 +173,8 @@
                     </view>
                     <view class="action-right">
                         <button class="btn normal" @click.stop="reportAbnormal(item)">异常上报</button>
-                        <button class="btn primary" @click.stop="mainAction(item)">{{ getMainActionText(item) }}</button>
+                        <button class="btn primary" @click.stop="mainAction(item)">{{ getMainActionText(item)
+                            }}</button>
                     </view>
                 </view>
             </view>
@@ -264,7 +250,8 @@
                     <view class="pm-log-item" v-for="(log, lIndex) in currentPetInfo.petLogs" :key="lIndex">
                         <text class="pm-log-date">{{ log.date }}</text>
                         <text class="pm-log-text">{{ log.content }}</text>
-                        <text class="pm-log-recorder">{{ log.recorder === '系统记录' ? '' : '记录人: '}}{{ log.recorder }}</text>
+                        <text class="pm-log-recorder">{{ log.recorder === '系统记录' ? '' : '记录人: ' }}{{ log.recorder
+                            }}</text>
                     </view>
                 </view>
                 <view style="height: 30rpx;"></view>
@@ -279,13 +266,8 @@
                 <text class="remark-sheet-title">添加备注</text>
                 <view class="close-icon-btn" @click="closeRemarkInput">×</view>
             </view>
-            <textarea
-                class="remark-textarea"
-                v-model="remarkText"
-                placeholder="请输入备注内容..."
-                maxlength="500"
-                auto-height
-            />
+            <textarea class="remark-textarea" v-model="remarkText" placeholder="请输入备注内容..." maxlength="500"
+                auto-height />
             <view class="remark-submit-btn" @click="submitRemark">提交备注</view>
         </view>
     </view>

+ 108 - 111
pages/orders/logic.js

@@ -1,50 +1,30 @@
+import { getMyOrders } from '@/api/fulfiller'
+import { getServiceList } from '@/api/service'
+
 export default {
     data() {
         return {
             currentTab: 0,
             tabs: ['待接送/服务', '配送/服务中', '已完成', '已拒绝'],
-            // Filter dropdown states
-            typeFilterOptions: ['全部类型', '接送', '喂遛', '洗护'],
+            typeFilterOptions: ['全部类型'],
             currentTypeFilterIdx: 0,
-            activeDropdown: 0, // 0 = none, 1 = type filter, 2 = time filter
+            activeDropdown: 0,
             hasTimeFilter: false,
-
-            // Custom Calendar State (Mock Feb 2026)
             currentMonth: '2026年2月',
             weekDays: ['日', '一', '二', '三', '四', '五', '六'],
-            calendarDays: [], // Generated in onLoad or created
-            selectedDateRange: [], // stores [start, end]
-
-            allOrderList: [
-                // === Tab 1: 待接送/服务 (Status: 接单) ===
-                { type: 1, typeText: '接送', typeIcon: '/static/icons/car.svg', statusText: '接单', price: '20.00', timeLabel: '取货时间', time: '2026/02/10 10:00', petAvatar: '/static/dog.png', petName: '哈士奇宝宝', petBreed: '哈士奇', startLocation: '武汉大学宠物店', startAddress: '武汉市洪山区珞喻路458号', startDistance: '0.5km', endLocation: '张** 189****8451', endAddress: '武汉市武昌区新区大道凤凰广场25号', endDistance: '2.5km', remark: '尽快接单。' },
-                { type: 2, typeText: '喂遛', typeIcon: '/static/icons/walk.svg', statusText: '接单', price: '30.00', timeLabel: '服务时间', time: '2026/02/10 14:00', petAvatar: '/static/dog.png', petName: '边牧', petBreed: '边境牧羊犬', endLocation: '李** 138****0001', endAddress: '武汉市洪山区保利花园', endDistance: '1.5km', serviceContent: '需自带牵引绳。', remark: '狗狗很活泼。' },
-                { type: 3, typeText: '洗护', typeIcon: '/static/icons/wash.svg', statusText: '接单', price: '60.00', timeLabel: '服务时间', time: '2026/02/10 16:00', petAvatar: '/static/dog.png', petName: '布偶', petBreed: '布偶猫', endLocation: '王** 139****0002', endAddress: '武汉市汉阳区钟家村', endDistance: '3.5km', serviceContent: '上门洗护、全身检查', remark: '猫咪怕水。' },
-
-                // === Tab 2: 配送/服务中 (Status: 出发/开始/到达等) ===
-                { type: 1, typeText: '接送', typeIcon: '/static/icons/car.svg', statusText: '出发', price: '25.00', timeLabel: '取货时间', time: '2026/02/11 09:00', petAvatar: '/static/dog.png', petName: '柯基', petBreed: '柯基犬', startLocation: '南湖宠物店', startAddress: '武汉市洪山区南湖大道', startDistance: '1.0km', endLocation: '陈** 158****0003', endAddress: '武汉市江夏区藏龙岛', endDistance: '6.5km', remark: '已接到狗狗,送往目的地。' },
-                { type: 2, typeText: '喂遛', typeIcon: '/static/icons/walk.svg', statusText: '开始', price: '35.00', timeLabel: '服务时间', time: '2026/02/11 15:00', petAvatar: '/static/dog.png', petName: '金毛', petBreed: '金毛寻回犬', endLocation: '赵** 159****0004', endAddress: '武汉市江汉区泛海国际', endDistance: '4.5km', serviceContent: '遛弯一小时', remark: '注意避开大型犬。' },
-                { type: 3, typeText: '洗护', typeIcon: '/static/icons/wash.svg', statusText: '开始', price: '80.00', timeLabel: '服务时间', time: '2026/02/11 18:00', petAvatar: '/static/dog.png', petName: '英短', petBreed: '英国短毛猫', endLocation: '钱** 177****0005', endAddress: '武汉市武昌区楚河汉街', endDistance: '2.0km', serviceContent: '深度去污、洗护', remark: '客户要求修剪指甲。' },
-
-                // === Tab 3: 已完成 (Status: 已完成) ===
-                { type: 1, typeText: '接送', typeIcon: '/static/icons/car.svg', statusText: '已完成', price: '40.00', timeLabel: '取货时间', time: '2026/02/12 10:00', petAvatar: '/static/dog.png', petName: '柴犬', petBreed: '柴犬', startLocation: '汉口宠物医院', startAddress: '武汉市江岸区解放大道', startDistance: '2.0km', endLocation: '孙** 186****0006', endAddress: '武汉市东西湖区金银湖', endDistance: '10.5km', remark: '安全抵达。' },
-                { type: 2, typeText: '喂遛', typeIcon: '/static/icons/walk.svg', statusText: '已完成', price: '28.00', timeLabel: '服务时间', time: '2026/02/12 16:00', petAvatar: '/static/dog.png', petName: '萨摩耶', petBreed: '萨摩耶犬', endLocation: '周** 188****0007', endAddress: '武汉市洪山区软件园', endDistance: '0.8km', serviceContent: '遛狗', remark: '遛得很开心。' },
-                { type: 3, typeText: '洗护', typeIcon: '/static/icons/wash.svg', statusText: '已完成', price: '120.00', timeLabel: '服务时间', time: '2026/02/12 19:00', petAvatar: '/static/dog.png', petName: '加菲', petBreed: '加菲猫', endLocation: '吴** 189****0008', endAddress: '武汉市青山区别区', endDistance: '5.0km', serviceContent: '全套美容洗护', remark: '客户非常满意。' },
-
-                // === Tab 4: 已拒绝 (Status: 已拒绝) ===
-                { type: 1, typeText: '接送', typeIcon: '/static/icons/car.svg', statusText: '已拒绝', price: '15.00', timeLabel: '取货时间', time: '2026/02/13 09:00', petAvatar: '/static/dog.png', petName: '吉娃娃', petBreed: '吉娃娃', startLocation: '宠物乐园', startAddress: '武汉市黄陂区盘龙城', startDistance: '3.0km', endLocation: '郑** 133****0009', endAddress: '武汉市汉南区', endDistance: '20.5km', remark: '路程太远。' },
-                { type: 2, typeText: '喂遛', typeIcon: '/static/icons/walk.svg', statusText: '已拒绝', price: '22.00', timeLabel: '服务时间', time: '2026/02/13 14:00', petAvatar: '/static/dog.png', petName: '博美', petBreed: '博美犬', endLocation: '刘** 134****0010', endAddress: '武汉市蔡甸区', endDistance: '15.0km', serviceContent: '公园遛弯', remark: '天气原因取消。' },
-                { type: 3, typeText: '洗护', typeIcon: '/static/icons/wash.svg', statusText: '已拒绝', price: '45.00', timeLabel: '服务时间', time: '2026/02/13 17:00', petAvatar: '/static/dog.png', petName: '暹罗', petBreed: '暹罗猫', endLocation: '张** 135****0011', endAddress: '武汉市新洲区', endDistance: '18.0km', serviceContent: '洗澡', remark: '时间冲突。' }
-            ],
+            calendarDays: [],
+            selectedDateRange: [],
+            allOrderList: [],
+            serviceList: [],
+            searchContent: '',
+            startServiceTime: '',
+            endServiceTime: '',
             showPetModal: false,
             currentPetInfo: {},
             showNavModal: false,
             navTargetItem: null,
             navTargetPointType: '',
-
-            // Popover control
             activeCallItem: null,
-            // 备注输入弹窗
             showRemarkInput: false,
             remarkText: ''
         }
@@ -52,51 +32,104 @@ export default {
     created() {
         this.initCalendar();
     },
+    async onLoad() {
+        await this.loadServiceList()
+        await this.loadOrders()
+    },
+    onShow() {
+        this.loadOrders()
+    },
+    watch: {
+        currentTab() {
+            this.loadOrders()
+        },
+        currentTypeFilterIdx() {
+            this.loadOrders()
+        }
+    },
     computed: {
         orderList() {
-            return this.allOrderList.filter(item => {
-                // 1. Tab Status Filter
-                // 待接送/服务: [接送]的接单, [喂遛/洗护]的接单
-                // 配送/服务中: [接送]的到达、出发、送达; [喂遛/洗护]的到达、开始、结束
-                // 已完成: 完成
-                let matchTab = false;
-                if (this.currentTab === 0) {
-                    matchTab = item.statusText === '接单';
-                } else if (this.currentTab === 1) {
-                    let pickingTypes = ['到达', '出发', '送达'];
-                    let serviceTypes = ['到达', '开始', '结束'];
-                    if (item.type === 1) {
-                        matchTab = pickingTypes.includes(item.statusText);
-                    } else {
-                        matchTab = serviceTypes.includes(item.statusText);
-                    }
-                } else if (this.currentTab === 2) {
-                    matchTab = item.statusText === '已完成';
-                } else if (this.currentTab === 3) {
-                    matchTab = item.statusText === '已拒绝';
-                }
-
-                // 2. Type Filter
-                let matchType = true;
-                if (this.currentTypeFilterIdx > 0) {
-                    matchType = item.type === parseInt(this.currentTypeFilterIdx);
-                }
-
-                // 3. Time Filter (Mocked)
-                let matchTime = true; // For now treat all equally unless parsed
-
-                return matchTab && matchType && matchTime;
-            });
+            return this.allOrderList;
         }
     },
     methods: {
+        async loadServiceList() {
+            try {
+                const res = await getServiceList()
+                this.serviceList = res.data || []
+                this.typeFilterOptions = ['全部类型', ...this.serviceList.map(s => s.name)]
+            } catch (err) {
+                console.error('获取服务类型失败:', err)
+            }
+        },
+        async loadOrders() {
+            try {
+                const statusMap = { 0: 2, 1: 3, 2: 5, 3: null }
+                const serviceId = this.currentTypeFilterIdx > 0 ? this.serviceList[this.currentTypeFilterIdx - 1]?.id : undefined
+                const params = {
+                    status: statusMap[this.currentTab],
+                    content: this.searchContent || undefined,
+                    service: serviceId,
+                    startServiceTime: this.startServiceTime || undefined,
+                    endServiceTime: this.endServiceTime || undefined
+                }
+                console.log('订单列表请求参数:', params)
+                const res = await getMyOrders(params)
+                console.log('订单列表响应:', res)
+                const orders = res.rows || []
+                console.log('订单数量:', orders.length)
+                this.allOrderList = orders.map(order => this.transformOrder(order, this.currentTab))
+            } catch (err) {
+                console.error('获取订单列表失败:', err)
+                this.allOrderList = []
+            }
+        },
+        transformOrder(order, tabIndex) {
+            const service = this.serviceList.find(s => s.id === order.service)
+            const serviceText = service?.name || '未知'
+            const serviceIcon = service?.icon || '/static/icons/car.svg'
+            const mode = service?.mode || 0
+            const isRoundTrip = mode === 1
+
+            // 根据 Tab 索引强制指定状态文字,忽略后端缺失的 status 字段
+            let statusText = '接单'
+            if (tabIndex === 0) {
+                statusText = '接单' // 待接送/服务
+            } else if (tabIndex === 1) {
+                statusText = isRoundTrip ? '出发' : '开始' // 配送/服务中
+            } else if (tabIndex === 2) {
+                statusText = '已完成' // 已完成
+            } else if (tabIndex === 3) {
+                statusText = '已拒绝' // 已拒绝
+            }
+            return {
+                id: order.id,
+                type: isRoundTrip ? 1 : 2,
+                typeText: serviceText,
+                typeIcon: serviceIcon,
+                statusText: statusText,
+                price: (order.price / 100).toFixed(2),
+                timeLabel: isRoundTrip ? '取货时间' : '服务时间',
+                time: order.serviceTime || '',
+                petAvatar: '/static/dog.png',
+                petName: order.petName || '',
+                petBreed: order.breed || '',
+                startLocation: order.fromAddress || '',
+                startAddress: order.fromAddress || '',
+                startDistance: '0km',
+                endLocation: (order.customerName || '') + ' ' + (order.customerPhone || ''),
+                endAddress: order.toAddress || '',
+                endDistance: '0km',
+                serviceContent: order.remark || '',
+                remark: order.remark || ''
+            }
+        },
         getDisplayStatus(item) {
             if (item.statusText === '已完成') return '已完成';
             if (item.statusText === '已拒绝') return '已拒绝';
             if (item.statusText === '接单') {
                 return item.type === 1 ? '待接送' : '待服务';
             }
-            // For other active states (出发, 到达, 送达, 开始, 结束)
             return item.type === 1 ? '配送中' : '服务中';
         },
         getStatusClass(item) {
@@ -107,13 +140,9 @@ export default {
             return 'highlight';
         },
         goToDetail(item) {
-            // 将在 detail 页面实现
-            uni.navigateTo({
-                url: `/pages/orders/detail?type=${item.type}`
-            });
+            uni.navigateTo({ url: `/pages/orders/detail?id=${item.id}` });
         },
         showPetProfile(item) {
-            // 补全 mock 数据
             this.currentPetInfo = {
                 ...item,
                 petGender: 'M',
@@ -147,12 +176,10 @@ export default {
             let pointType = this.navTargetPointType;
             let name = pointType === 'start' ? item.startLocation : item.endLocation;
             let address = pointType === 'start' ? item.startAddress : item.endAddress;
-
             this.showNavModal = false;
-
             uni.openLocation({
-                latitude: 30.52, // Mock lat
-                longitude: 114.31, // Mock lng
+                latitude: 30.52,
+                longitude: 114.31,
                 name: name || '目的地',
                 address: address || '默认地址',
                 success: function () {
@@ -173,9 +200,9 @@ export default {
         doCall(type) {
             let phoneNum = ''
             if (type === 'merchant') {
-                phoneNum = '18900008451' // Mock merchant
+                phoneNum = '18900008451'
             } else if (type === 'customer') {
-                phoneNum = '13800000001' // Mock customer
+                phoneNum = '13800000001'
             }
             if (phoneNum) {
                 uni.makePhoneCall({ phoneNumber: phoneNum })
@@ -183,10 +210,9 @@ export default {
             this.activeCallItem = null;
         },
         reportAbnormal(item) {
-            uni.showToast({ title: '上报功能待开发', icon: 'none' });
+            uni.navigateTo({ url: '/pages/orders/anomaly?orderId=' + (item.id || '') });
         },
         toggleDropdown(idx) {
-            // If clicking the currently open one, close it
             if (this.activeDropdown === idx) {
                 this.activeDropdown = 0;
             } else {
@@ -201,21 +227,18 @@ export default {
             this.closeDropdown();
         },
         initCalendar() {
-            // Mock Feb 2026 (1 is Sunday, 28 is Saturday)
             let days = [];
             for (let i = 1; i <= 28; i++) {
                 days.push(i);
             }
             this.calendarDays = days;
-            // Pre-select 2, 3, 4 for the demo in Figure 2
             this.selectedDateRange = [2, 4];
         },
         prevMonth() { uni.showToast({ title: '上个月', icon: 'none' }); },
         nextMonth() { uni.showToast({ title: '下个月', icon: 'none' }); },
         selectDateItem(day) {
-            // Simple range toggle logic
             if (this.selectedDateRange.length === 2) {
-                this.selectedDateRange = [day]; // Reset to new start
+                this.selectedDateRange = [day];
             } else if (this.selectedDateRange.length === 1) {
                 let start = this.selectedDateRange[0];
                 if (day > start) {
@@ -223,7 +246,7 @@ export default {
                 } else if (day < start) {
                     this.selectedDateRange = [day, start];
                 } else {
-                    this.selectedDateRange = []; // clear if same clicked
+                    this.selectedDateRange = [];
                 }
             } else {
                 this.selectedDateRange = [day];
@@ -260,53 +283,27 @@ export default {
             this.closeDropdown();
         },
         getMainActionText(item) {
-            if (item.statusText === '接单') {
-                return '到达打卡'; // Next step
-            } else if (item.statusText === '到达' && item.type === 1) {
-                return '确认出发';
-            } else if (item.statusText === '到达' && item.type !== 1) {
-                return '开始服务';
-            } else if (item.statusText === '出发') {
-                return '送达打卡';
-            } else if (item.statusText === '开始') {
-                return '结束服务';
-            } else if (item.statusText === '送达' || item.statusText === '结束') {
-                return '服务完成';
-            }
             return '查看详情';
         },
         mainAction(item) {
-            // Simply navigate to detail page, where the real action button lives
-            uni.navigateTo({
-                url: `/pages/orders/detail?type=${item.type}`
-            });
-        },
-        reportAbnormal(item) {
-            uni.navigateTo({
-                url: '/pages/orders/anomaly?orderId=' + (item.orderNo || '')
-            });
+            uni.navigateTo({ url: `/pages/orders/detail?id=${item.id}` });
         },
-        // 打开备注输入弹窗
         openRemarkInput() {
             this.remarkText = '';
             this.showRemarkInput = true;
         },
-        // 关闭备注输入弹窗
         closeRemarkInput() {
             this.showRemarkInput = false;
             this.remarkText = '';
         },
-        // 提交备注,追加到宠物档案日志列表
         submitRemark() {
             const text = this.remarkText.trim();
             if (!text) {
                 uni.showToast({ title: '备注内容不能为空', icon: 'none' });
                 return;
             }
-            // 获取当前时间
             const now = new Date();
             const dateStr = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`;
-            // 追加到当前宠物的日志列表头部
             if (!this.currentPetInfo.petLogs) {
                 this.$set(this.currentPetInfo, 'petLogs', []);
             }

+ 3 - 3
unpackage/dist/cache/.vite/deps/_metadata.json

@@ -1,8 +1,8 @@
 {
-  "hash": "a87165aa",
-  "configHash": "1c48c81f",
+  "hash": "fd71fe9a",
+  "configHash": "b19c648e",
   "lockfileHash": "e3b0c442",
-  "browserHash": "a288dfff",
+  "browserHash": "262e9795",
   "optimized": {},
   "chunks": {}
 }

+ 395 - 202
unpackage/dist/dev/app-plus/app-service.js

@@ -116,7 +116,7 @@ if (uni.restoreGlobal) {
   function resolveEasycom(component, easycom) {
     return typeof component === "string" ? easycom : component;
   }
-  const BASE_URL = "http://192.168.0.102:8080";
+  const BASE_URL = "http://192.168.1.118:8080";
   const CLIENT_ID = "3";
   const PLATFORM_CODE = "FlfAppPlatformCodeX9kR7mT3wQ5vZ8nB1jY6pD4sL0hC2gA";
   const PLATFORM_ID = 2;
@@ -755,13 +755,15 @@ if (uni.restoreGlobal) {
   }
   function uploadFile(filePath) {
     return new Promise((resolve, reject) => {
+      const token = uni.getStorageSync("fulfiller_token");
       uni.uploadFile({
         url: BASE_URL + "/fulfiller/app/upload",
         filePath,
         name: "file",
         header: {
           "clientid": CLIENT_ID,
-          "X-Platform-Code": PLATFORM_CODE
+          "X-Platform-Code": PLATFORM_CODE,
+          "Authorization": token ? `Bearer ${token}` : ""
         },
         success: (res) => {
           try {
@@ -864,6 +866,32 @@ if (uni.restoreGlobal) {
       method: "GET"
     });
   }
+  function getMyOrders(params) {
+    return request({
+      url: "/order/subOrder/listOnMyOrder",
+      method: "GET",
+      data: params
+    });
+  }
+  function getOrderInfo(id) {
+    return request({
+      url: `/order/subOrder/getInfo?id=${id}`,
+      method: "GET"
+    });
+  }
+  function getOrderLogs(orderId) {
+    return request({
+      url: `/order/subOrderLog/list?orderId=${orderId}`,
+      method: "GET"
+    });
+  }
+  function clockIn(data) {
+    return request({
+      url: "/order/subOrder/clockIn",
+      method: "PUT",
+      data
+    });
+  }
   const logic$7 = {
     data() {
       return {
@@ -3824,45 +3852,25 @@ if (uni.restoreGlobal) {
       return {
         currentTab: 0,
         tabs: ["待接送/服务", "配送/服务中", "已完成", "已拒绝"],
-        // Filter dropdown states
-        typeFilterOptions: ["全部类型", "接送", "喂遛", "洗护"],
+        typeFilterOptions: ["全部类型"],
         currentTypeFilterIdx: 0,
         activeDropdown: 0,
-        // 0 = none, 1 = type filter, 2 = time filter
         hasTimeFilter: false,
-        // Custom Calendar State (Mock Feb 2026)
         currentMonth: "2026年2月",
         weekDays: ["日", "一", "二", "三", "四", "五", "六"],
         calendarDays: [],
-        // Generated in onLoad or created
         selectedDateRange: [],
-        // stores [start, end]
-        allOrderList: [
-          // === Tab 1: 待接送/服务 (Status: 接单) ===
-          { type: 1, typeText: "接送", typeIcon: "/static/icons/car.svg", statusText: "接单", price: "20.00", timeLabel: "取货时间", time: "2026/02/10 10:00", petAvatar: "/static/dog.png", petName: "哈士奇宝宝", petBreed: "哈士奇", startLocation: "武汉大学宠物店", startAddress: "武汉市洪山区珞喻路458号", startDistance: "0.5km", endLocation: "张** 189****8451", endAddress: "武汉市武昌区新区大道凤凰广场25号", endDistance: "2.5km", remark: "尽快接单。" },
-          { type: 2, typeText: "喂遛", typeIcon: "/static/icons/walk.svg", statusText: "接单", price: "30.00", timeLabel: "服务时间", time: "2026/02/10 14:00", petAvatar: "/static/dog.png", petName: "边牧", petBreed: "边境牧羊犬", endLocation: "李** 138****0001", endAddress: "武汉市洪山区保利花园", endDistance: "1.5km", serviceContent: "需自带牵引绳。", remark: "狗狗很活泼。" },
-          { type: 3, typeText: "洗护", typeIcon: "/static/icons/wash.svg", statusText: "接单", price: "60.00", timeLabel: "服务时间", time: "2026/02/10 16:00", petAvatar: "/static/dog.png", petName: "布偶", petBreed: "布偶猫", endLocation: "王** 139****0002", endAddress: "武汉市汉阳区钟家村", endDistance: "3.5km", serviceContent: "上门洗护、全身检查", remark: "猫咪怕水。" },
-          // === Tab 2: 配送/服务中 (Status: 出发/开始/到达等) ===
-          { type: 1, typeText: "接送", typeIcon: "/static/icons/car.svg", statusText: "出发", price: "25.00", timeLabel: "取货时间", time: "2026/02/11 09:00", petAvatar: "/static/dog.png", petName: "柯基", petBreed: "柯基犬", startLocation: "南湖宠物店", startAddress: "武汉市洪山区南湖大道", startDistance: "1.0km", endLocation: "陈** 158****0003", endAddress: "武汉市江夏区藏龙岛", endDistance: "6.5km", remark: "已接到狗狗,送往目的地。" },
-          { type: 2, typeText: "喂遛", typeIcon: "/static/icons/walk.svg", statusText: "开始", price: "35.00", timeLabel: "服务时间", time: "2026/02/11 15:00", petAvatar: "/static/dog.png", petName: "金毛", petBreed: "金毛寻回犬", endLocation: "赵** 159****0004", endAddress: "武汉市江汉区泛海国际", endDistance: "4.5km", serviceContent: "遛弯一小时", remark: "注意避开大型犬。" },
-          { type: 3, typeText: "洗护", typeIcon: "/static/icons/wash.svg", statusText: "开始", price: "80.00", timeLabel: "服务时间", time: "2026/02/11 18:00", petAvatar: "/static/dog.png", petName: "英短", petBreed: "英国短毛猫", endLocation: "钱** 177****0005", endAddress: "武汉市武昌区楚河汉街", endDistance: "2.0km", serviceContent: "深度去污、洗护", remark: "客户要求修剪指甲。" },
-          // === Tab 3: 已完成 (Status: 已完成) ===
-          { type: 1, typeText: "接送", typeIcon: "/static/icons/car.svg", statusText: "已完成", price: "40.00", timeLabel: "取货时间", time: "2026/02/12 10:00", petAvatar: "/static/dog.png", petName: "柴犬", petBreed: "柴犬", startLocation: "汉口宠物医院", startAddress: "武汉市江岸区解放大道", startDistance: "2.0km", endLocation: "孙** 186****0006", endAddress: "武汉市东西湖区金银湖", endDistance: "10.5km", remark: "安全抵达。" },
-          { type: 2, typeText: "喂遛", typeIcon: "/static/icons/walk.svg", statusText: "已完成", price: "28.00", timeLabel: "服务时间", time: "2026/02/12 16:00", petAvatar: "/static/dog.png", petName: "萨摩耶", petBreed: "萨摩耶犬", endLocation: "周** 188****0007", endAddress: "武汉市洪山区软件园", endDistance: "0.8km", serviceContent: "遛狗", remark: "遛得很开心。" },
-          { type: 3, typeText: "洗护", typeIcon: "/static/icons/wash.svg", statusText: "已完成", price: "120.00", timeLabel: "服务时间", time: "2026/02/12 19:00", petAvatar: "/static/dog.png", petName: "加菲", petBreed: "加菲猫", endLocation: "吴** 189****0008", endAddress: "武汉市青山区别区", endDistance: "5.0km", serviceContent: "全套美容洗护", remark: "客户非常满意。" },
-          // === Tab 4: 已拒绝 (Status: 已拒绝) ===
-          { type: 1, typeText: "接送", typeIcon: "/static/icons/car.svg", statusText: "已拒绝", price: "15.00", timeLabel: "取货时间", time: "2026/02/13 09:00", petAvatar: "/static/dog.png", petName: "吉娃娃", petBreed: "吉娃娃", startLocation: "宠物乐园", startAddress: "武汉市黄陂区盘龙城", startDistance: "3.0km", endLocation: "郑** 133****0009", endAddress: "武汉市汉南区", endDistance: "20.5km", remark: "路程太远。" },
-          { type: 2, typeText: "喂遛", typeIcon: "/static/icons/walk.svg", statusText: "已拒绝", price: "22.00", timeLabel: "服务时间", time: "2026/02/13 14:00", petAvatar: "/static/dog.png", petName: "博美", petBreed: "博美犬", endLocation: "刘** 134****0010", endAddress: "武汉市蔡甸区", endDistance: "15.0km", serviceContent: "公园遛弯", remark: "天气原因取消。" },
-          { type: 3, typeText: "洗护", typeIcon: "/static/icons/wash.svg", statusText: "已拒绝", price: "45.00", timeLabel: "服务时间", time: "2026/02/13 17:00", petAvatar: "/static/dog.png", petName: "暹罗", petBreed: "暹罗猫", endLocation: "张** 135****0011", endAddress: "武汉市新洲区", endDistance: "18.0km", serviceContent: "洗澡", remark: "时间冲突。" }
-        ],
+        allOrderList: [],
+        serviceList: [],
+        searchContent: "",
+        startServiceTime: "",
+        endServiceTime: "",
         showPetModal: false,
         currentPetInfo: {},
         showNavModal: false,
         navTargetItem: null,
         navTargetPointType: "",
-        // Popover control
         activeCallItem: null,
-        // 备注输入弹窗
         showRemarkInput: false,
         remarkText: ""
       };
@@ -3870,35 +3878,97 @@ if (uni.restoreGlobal) {
     created() {
       this.initCalendar();
     },
+    async onLoad() {
+      await this.loadServiceList();
+      await this.loadOrders();
+    },
+    onShow() {
+      this.loadOrders();
+    },
+    watch: {
+      currentTab() {
+        this.loadOrders();
+      },
+      currentTypeFilterIdx() {
+        this.loadOrders();
+      }
+    },
     computed: {
       orderList() {
-        return this.allOrderList.filter((item) => {
-          let matchTab = false;
-          if (this.currentTab === 0) {
-            matchTab = item.statusText === "接单";
-          } else if (this.currentTab === 1) {
-            let pickingTypes = ["到达", "出发", "送达"];
-            let serviceTypes = ["到达", "开始", "结束"];
-            if (item.type === 1) {
-              matchTab = pickingTypes.includes(item.statusText);
-            } else {
-              matchTab = serviceTypes.includes(item.statusText);
-            }
-          } else if (this.currentTab === 2) {
-            matchTab = item.statusText === "已完成";
-          } else if (this.currentTab === 3) {
-            matchTab = item.statusText === "已拒绝";
-          }
-          let matchType = true;
-          if (this.currentTypeFilterIdx > 0) {
-            matchType = item.type === parseInt(this.currentTypeFilterIdx);
-          }
-          let matchTime = true;
-          return matchTab && matchType && matchTime;
-        });
+        return this.allOrderList;
       }
     },
     methods: {
+      async loadServiceList() {
+        try {
+          const res = await getServiceList();
+          this.serviceList = res.data || [];
+          this.typeFilterOptions = ["全部类型", ...this.serviceList.map((s) => s.name)];
+        } catch (err) {
+          formatAppLog("error", "at pages/orders/logic.js:62", "获取服务类型失败:", err);
+        }
+      },
+      async loadOrders() {
+        var _a;
+        try {
+          const statusMap = { 0: 2, 1: 3, 2: 5, 3: null };
+          const serviceId = this.currentTypeFilterIdx > 0 ? (_a = this.serviceList[this.currentTypeFilterIdx - 1]) == null ? void 0 : _a.id : void 0;
+          const params = {
+            status: statusMap[this.currentTab],
+            content: this.searchContent || void 0,
+            service: serviceId,
+            startServiceTime: this.startServiceTime || void 0,
+            endServiceTime: this.endServiceTime || void 0
+          };
+          formatAppLog("log", "at pages/orders/logic.js:76", "订单列表请求参数:", params);
+          const res = await getMyOrders(params);
+          formatAppLog("log", "at pages/orders/logic.js:78", "订单列表响应:", res);
+          const orders = res.rows || [];
+          formatAppLog("log", "at pages/orders/logic.js:80", "订单数量:", orders.length);
+          this.allOrderList = orders.map((order) => this.transformOrder(order, this.currentTab));
+        } catch (err) {
+          formatAppLog("error", "at pages/orders/logic.js:83", "获取订单列表失败:", err);
+          this.allOrderList = [];
+        }
+      },
+      transformOrder(order, tabIndex) {
+        const service = this.serviceList.find((s) => s.id === order.service);
+        const serviceText = (service == null ? void 0 : service.name) || "未知";
+        const serviceIcon = (service == null ? void 0 : service.icon) || "/static/icons/car.svg";
+        const mode = (service == null ? void 0 : service.mode) || 0;
+        const isRoundTrip = mode === 1;
+        let statusText = "接单";
+        if (tabIndex === 0) {
+          statusText = "接单";
+        } else if (tabIndex === 1) {
+          statusText = isRoundTrip ? "出发" : "开始";
+        } else if (tabIndex === 2) {
+          statusText = "已完成";
+        } else if (tabIndex === 3) {
+          statusText = "已拒绝";
+        }
+        return {
+          id: order.id,
+          type: isRoundTrip ? 1 : 2,
+          typeText: serviceText,
+          typeIcon: serviceIcon,
+          statusText,
+          price: (order.price / 100).toFixed(2),
+          timeLabel: isRoundTrip ? "取货时间" : "服务时间",
+          time: order.serviceTime || "",
+          petAvatar: "/static/dog.png",
+          petName: order.petName || "",
+          petBreed: order.breed || "",
+          startLocation: order.fromAddress || "",
+          startAddress: order.fromAddress || "",
+          startDistance: "0km",
+          endLocation: (order.customerName || "") + " " + (order.customerPhone || ""),
+          endAddress: order.toAddress || "",
+          endDistance: "0km",
+          serviceContent: order.remark || "",
+          remark: order.remark || ""
+        };
+      },
       getDisplayStatus(item) {
         if (item.statusText === "已完成")
           return "已完成";
@@ -3920,9 +3990,7 @@ if (uni.restoreGlobal) {
         return "highlight";
       },
       goToDetail(item) {
-        uni.navigateTo({
-          url: `/pages/orders/detail?type=${item.type}`
-        });
+        uni.navigateTo({ url: `/pages/orders/detail?id=${item.id}` });
       },
       showPetProfile(item) {
         this.currentPetInfo = {
@@ -3961,13 +4029,11 @@ if (uni.restoreGlobal) {
         this.showNavModal = false;
         uni.openLocation({
           latitude: 30.52,
-          // Mock lat
           longitude: 114.31,
-          // Mock lng
           name: name || "目的地",
           address: address || "默认地址",
           success: function() {
-            formatAppLog("log", "at pages/orders/logic.js:159", "打开导航成功: " + mapType);
+            formatAppLog("log", "at pages/orders/logic.js:186", "打开导航成功: " + mapType);
           }
         });
       },
@@ -3994,7 +4060,7 @@ if (uni.restoreGlobal) {
         this.activeCallItem = null;
       },
       reportAbnormal(item) {
-        uni.showToast({ title: "上报功能待开发", icon: "none" });
+        uni.navigateTo({ url: "/pages/orders/anomaly?orderId=" + (item.id || "") });
       },
       toggleDropdown(idx) {
         if (this.activeDropdown === idx) {
@@ -4073,42 +4139,19 @@ if (uni.restoreGlobal) {
         this.closeDropdown();
       },
       getMainActionText(item) {
-        if (item.statusText === "接单") {
-          return "到达打卡";
-        } else if (item.statusText === "到达" && item.type === 1) {
-          return "确认出发";
-        } else if (item.statusText === "到达" && item.type !== 1) {
-          return "开始服务";
-        } else if (item.statusText === "出发") {
-          return "送达打卡";
-        } else if (item.statusText === "开始") {
-          return "结束服务";
-        } else if (item.statusText === "送达" || item.statusText === "结束") {
-          return "服务完成";
-        }
         return "查看详情";
       },
       mainAction(item) {
-        uni.navigateTo({
-          url: `/pages/orders/detail?type=${item.type}`
-        });
+        uni.navigateTo({ url: `/pages/orders/detail?id=${item.id}` });
       },
-      reportAbnormal(item) {
-        uni.navigateTo({
-          url: "/pages/orders/anomaly?orderId=" + (item.orderNo || "")
-        });
-      },
-      // 打开备注输入弹窗
       openRemarkInput() {
         this.remarkText = "";
         this.showRemarkInput = true;
       },
-      // 关闭备注输入弹窗
       closeRemarkInput() {
         this.showRemarkInput = false;
         this.remarkText = "";
       },
-      // 提交备注,追加到宠物档案日志列表
       submitRemark() {
         const text = this.remarkText.trim();
         if (!text) {
@@ -4134,7 +4177,6 @@ if (uni.restoreGlobal) {
     ...logic$2
   };
   function _sfc_render$q(_ctx, _cache, $props, $setup, $data, $options) {
-    const _component_uni_icons = vue.resolveComponent("uni-icons");
     return vue.openBlock(), vue.createElementBlock(
       vue.Fragment,
       null,
@@ -4275,12 +4317,10 @@ if (uni.restoreGlobal) {
               }, [
                 vue.createElementVNode("view", { class: "custom-calendar-container" }, [
                   vue.createElementVNode("view", { class: "cal-header" }, [
-                    vue.createVNode(_component_uni_icons, {
-                      type: "left",
-                      size: "18",
-                      color: "#666",
-                      onClick: _ctx.prevMonth
-                    }, null, 8, ["onClick"]),
+                    vue.createElementVNode("text", {
+                      class: "cal-nav-btn",
+                      onClick: _cache[3] || (_cache[3] = (...args) => _ctx.prevMonth && _ctx.prevMonth(...args))
+                    }, "‹"),
                     vue.createElementVNode(
                       "text",
                       { class: "cal-title" },
@@ -4288,12 +4328,10 @@ if (uni.restoreGlobal) {
                       1
                       /* TEXT */
                     ),
-                    vue.createVNode(_component_uni_icons, {
-                      type: "right",
-                      size: "18",
-                      color: "#666",
-                      onClick: _ctx.nextMonth
-                    }, null, 8, ["onClick"])
+                    vue.createElementVNode("text", {
+                      class: "cal-nav-btn",
+                      onClick: _cache[4] || (_cache[4] = (...args) => _ctx.nextMonth && _ctx.nextMonth(...args))
+                    }, "›")
                   ]),
                   vue.createElementVNode("view", { class: "cal-weekdays" }, [
                     (vue.openBlock(true), vue.createElementBlock(
@@ -4342,11 +4380,11 @@ if (uni.restoreGlobal) {
                 vue.createElementVNode("view", { class: "calendar-actions" }, [
                   vue.createElementVNode("button", {
                     class: "cal-btn reset",
-                    onClick: _cache[3] || (_cache[3] = (...args) => _ctx.resetTimeFilter && _ctx.resetTimeFilter(...args))
+                    onClick: _cache[5] || (_cache[5] = (...args) => _ctx.resetTimeFilter && _ctx.resetTimeFilter(...args))
                   }, "重置"),
                   vue.createElementVNode("button", {
                     class: "cal-btn confirm",
-                    onClick: _cache[4] || (_cache[4] = (...args) => _ctx.confirmTimeFilter && _ctx.confirmTimeFilter(...args))
+                    onClick: _cache[6] || (_cache[6] = (...args) => _ctx.confirmTimeFilter && _ctx.confirmTimeFilter(...args))
                   }, "确定")
                 ])
               ])) : vue.createCommentVNode("v-if", true)
@@ -4451,7 +4489,7 @@ if (uni.restoreGlobal) {
                             class: "route-item",
                             onClick: vue.withModifiers(($event) => _ctx.openNavigation(item, "start"), ["stop"])
                           }, [
-                            vue.createElementVNode("view", { class: "icon-circle start" }, ""),
+                            vue.createElementVNode("view", { class: "icon-circle start" }, ""),
                             vue.createElementVNode("view", { class: "route-line-vertical" }),
                             vue.createElementVNode("view", { class: "address-box" }, [
                               vue.createElementVNode(
@@ -4489,7 +4527,7 @@ if (uni.restoreGlobal) {
                             class: "route-item",
                             onClick: vue.withModifiers(($event) => _ctx.openNavigation(item, "end"), ["stop"])
                           }, [
-                            vue.createElementVNode("view", { class: "icon-circle end" }, ""),
+                            vue.createElementVNode("view", { class: "icon-circle end" }, ""),
                             vue.createElementVNode("view", { class: "address-box" }, [
                               vue.createElementVNode(
                                 "text",
@@ -4609,16 +4647,16 @@ if (uni.restoreGlobal) {
                       _ctx.activeCallItem === item ? (vue.openBlock(), vue.createElementBlock("view", {
                         key: 0,
                         class: "call-popover",
-                        onClick: _cache[7] || (_cache[7] = vue.withModifiers(() => {
+                        onClick: _cache[9] || (_cache[9] = vue.withModifiers(() => {
                         }, ["stop"]))
                       }, [
                         vue.createElementVNode("view", {
                           class: "call-pop-item",
-                          onClick: _cache[5] || (_cache[5] = ($event) => _ctx.doCall("merchant"))
+                          onClick: _cache[7] || (_cache[7] = ($event) => _ctx.doCall("merchant"))
                         }, "联系商家"),
                         vue.createElementVNode("view", {
                           class: "call-pop-item",
-                          onClick: _cache[6] || (_cache[6] = ($event) => _ctx.doCall("customer"))
+                          onClick: _cache[8] || (_cache[8] = ($event) => _ctx.doCall("customer"))
                         }, "联系客户")
                       ])) : vue.createCommentVNode("v-if", true)
                     ]),
@@ -4644,17 +4682,17 @@ if (uni.restoreGlobal) {
           _ctx.activeCallItem ? (vue.openBlock(), vue.createElementBlock("view", {
             key: 0,
             class: "call-mask",
-            onClick: _cache[8] || (_cache[8] = (...args) => _ctx.closeCallMenu && _ctx.closeCallMenu(...args))
+            onClick: _cache[10] || (_cache[10] = (...args) => _ctx.closeCallMenu && _ctx.closeCallMenu(...args))
           })) : vue.createCommentVNode("v-if", true)
         ]),
         _ctx.showPetModal ? (vue.openBlock(), vue.createElementBlock("view", {
           key: 0,
           class: "pet-modal-mask",
-          onClick: _cache[12] || (_cache[12] = (...args) => _ctx.closePetProfile && _ctx.closePetProfile(...args))
+          onClick: _cache[14] || (_cache[14] = (...args) => _ctx.closePetProfile && _ctx.closePetProfile(...args))
         }, [
           vue.createElementVNode("view", {
             class: "pet-modal-content",
-            onClick: _cache[11] || (_cache[11] = vue.withModifiers(() => {
+            onClick: _cache[13] || (_cache[13] = vue.withModifiers(() => {
             }, ["stop"]))
           }, [
             vue.createElementVNode("view", { class: "pet-modal-header" }, [
@@ -4662,11 +4700,11 @@ if (uni.restoreGlobal) {
               vue.createElementVNode("view", { class: "pm-header-actions" }, [
                 vue.createElementVNode("view", {
                   class: "pm-remark-btn",
-                  onClick: _cache[9] || (_cache[9] = (...args) => _ctx.openRemarkInput && _ctx.openRemarkInput(...args))
+                  onClick: _cache[11] || (_cache[11] = (...args) => _ctx.openRemarkInput && _ctx.openRemarkInput(...args))
                 }, "备注"),
                 vue.createElementVNode("view", {
                   class: "close-icon-btn",
-                  onClick: _cache[10] || (_cache[10] = (...args) => _ctx.closePetProfile && _ctx.closePetProfile(...args))
+                  onClick: _cache[12] || (_cache[12] = (...args) => _ctx.closePetProfile && _ctx.closePetProfile(...args))
                 }, "×")
               ])
             ]),
@@ -4834,25 +4872,25 @@ if (uni.restoreGlobal) {
         _ctx.showRemarkInput ? (vue.openBlock(), vue.createElementBlock("view", {
           key: 1,
           class: "remark-mask",
-          onClick: _cache[17] || (_cache[17] = (...args) => _ctx.closeRemarkInput && _ctx.closeRemarkInput(...args))
+          onClick: _cache[19] || (_cache[19] = (...args) => _ctx.closeRemarkInput && _ctx.closeRemarkInput(...args))
         }, [
           vue.createElementVNode("view", {
             class: "remark-sheet",
-            onClick: _cache[16] || (_cache[16] = vue.withModifiers(() => {
+            onClick: _cache[18] || (_cache[18] = vue.withModifiers(() => {
             }, ["stop"]))
           }, [
             vue.createElementVNode("view", { class: "remark-sheet-header" }, [
               vue.createElementVNode("text", { class: "remark-sheet-title" }, "添加备注"),
               vue.createElementVNode("view", {
                 class: "close-icon-btn",
-                onClick: _cache[13] || (_cache[13] = (...args) => _ctx.closeRemarkInput && _ctx.closeRemarkInput(...args))
+                onClick: _cache[15] || (_cache[15] = (...args) => _ctx.closeRemarkInput && _ctx.closeRemarkInput(...args))
               }, "×")
             ]),
             vue.withDirectives(vue.createElementVNode(
               "textarea",
               {
                 class: "remark-textarea",
-                "onUpdate:modelValue": _cache[14] || (_cache[14] = ($event) => _ctx.remarkText = $event),
+                "onUpdate:modelValue": _cache[16] || (_cache[16] = ($event) => _ctx.remarkText = $event),
                 placeholder: "请输入备注内容...",
                 maxlength: "500",
                 "auto-height": ""
@@ -4865,37 +4903,37 @@ if (uni.restoreGlobal) {
             ]),
             vue.createElementVNode("view", {
               class: "remark-submit-btn",
-              onClick: _cache[15] || (_cache[15] = (...args) => _ctx.submitRemark && _ctx.submitRemark(...args))
+              onClick: _cache[17] || (_cache[17] = (...args) => _ctx.submitRemark && _ctx.submitRemark(...args))
             }, "提交备注")
           ])
         ])) : vue.createCommentVNode("v-if", true),
         _ctx.showNavModal ? (vue.openBlock(), vue.createElementBlock("view", {
           key: 2,
           class: "nav-modal-mask",
-          onClick: _cache[23] || (_cache[23] = (...args) => _ctx.closeNavModal && _ctx.closeNavModal(...args))
+          onClick: _cache[25] || (_cache[25] = (...args) => _ctx.closeNavModal && _ctx.closeNavModal(...args))
         }, [
           vue.createElementVNode("view", {
             class: "nav-action-sheet",
-            onClick: _cache[22] || (_cache[22] = vue.withModifiers(() => {
+            onClick: _cache[24] || (_cache[24] = vue.withModifiers(() => {
             }, ["stop"]))
           }, [
             vue.createElementVNode("view", { class: "nav-sheet-title" }, "选择地图进行导航"),
             vue.createElementVNode("view", {
               class: "nav-sheet-item",
-              onClick: _cache[18] || (_cache[18] = ($event) => _ctx.chooseMap("高德"))
+              onClick: _cache[20] || (_cache[20] = ($event) => _ctx.chooseMap("高德"))
             }, "高德地图"),
             vue.createElementVNode("view", {
               class: "nav-sheet-item",
-              onClick: _cache[19] || (_cache[19] = ($event) => _ctx.chooseMap("腾讯"))
+              onClick: _cache[21] || (_cache[21] = ($event) => _ctx.chooseMap("腾讯"))
             }, "腾讯地图"),
             vue.createElementVNode("view", {
               class: "nav-sheet-item",
-              onClick: _cache[20] || (_cache[20] = ($event) => _ctx.chooseMap("百度"))
+              onClick: _cache[22] || (_cache[22] = ($event) => _ctx.chooseMap("百度"))
             }, "百度地图"),
             vue.createElementVNode("view", { class: "nav-sheet-gap" }),
             vue.createElementVNode("view", {
               class: "nav-sheet-item cancel",
-              onClick: _cache[21] || (_cache[21] = (...args) => _ctx.closeNavModal && _ctx.closeNavModal(...args))
+              onClick: _cache[23] || (_cache[23] = (...args) => _ctx.closeNavModal && _ctx.closeNavModal(...args))
             }, "取消")
           ])
         ])) : vue.createCommentVNode("v-if", true)
@@ -4908,50 +4946,43 @@ if (uni.restoreGlobal) {
   const logic$1 = {
     data() {
       return {
+        orderId: null,
         orderType: 1,
-        // 1:接送, 2:喂遛, 3:洗护
-        // Define steps dynamically based on type
-        stepsPickup: ["接单", "到达", "出发", "送达", "完成"],
-        stepsWalkWash: ["接单", "到达", "开始", "结束", "完成"],
+        orderStatus: 2,
+        stepsPickup: ["到达打卡", "确认出发", "送达打卡"],
+        stepsWalkWash: ["到达打卡", "开始服务", "服务结束"],
         currentStep: 1,
-        // 0-indexed (1 means 到达)
-        // Mock Data
         orderDetail: {
           type: 1,
-          price: "20.00",
-          timeLabel: "取货时间",
-          time: "2026/02/10 10:00",
+          price: "0.00",
+          timeLabel: "服务时间",
+          time: "",
           petAvatar: "/static/dog.png",
-          petName: "哈士奇宝宝",
-          petBreed: "哈士奇",
-          serviceTag: "宠物接送",
-          startLocation: "武汉大学宠物店",
-          startAddress: "武汉市洪山区珞喻路458号",
-          endLocation: "张** 189****8451",
-          endAddress: "武汉市武昌区新区大道凤凰广场A座一楼25号",
-          serviceContent: "这里是订单服务内容。",
-          remark: "这里是订单备注信息。",
-          orderNo: "T1001",
-          createTime: "2026/02/10 09:30",
-          progressLogs: [
-            { status: "您已接单", time: "2026-02-10 10:00" }
-          ]
+          petName: "",
+          petBreed: "",
+          serviceTag: "",
+          startLocation: "",
+          startAddress: "",
+          endLocation: "",
+          endAddress: "",
+          serviceContent: "",
+          remark: "",
+          orderNo: "",
+          createTime: "",
+          progressLogs: []
         },
-        // Modal states
+        serviceList: [],
         showPetModal: false,
         currentPetInfo: {},
         showNavModal: false,
         navTargetPointType: "",
-        // Upload Modal State
         showUploadModal: false,
         modalMediaList: [],
         modalRemark: "",
-        // 宠护小结弹窗状态
         showSumModal: false,
         sumContent: "",
         sumDate: "",
         sumSigner: "张*哥",
-        // 宠物备注弹窗状态
         showPetRemarkInput: false,
         petRemarkText: ""
       };
@@ -4961,6 +4992,10 @@ if (uni.restoreGlobal) {
         return this.orderType === 1 ? this.stepsPickup : this.stepsWalkWash;
       },
       displayStatusText() {
+        if (this.currentStep === 4)
+          return "待商家确认";
+        if (this.currentStep >= this.steps.length)
+          return "已完成";
         let status = this.steps[this.currentStep];
         if (status === "已完成" || status === "完成")
           return "已完成";
@@ -4972,56 +5007,167 @@ if (uni.restoreGlobal) {
         return this.orderType === 1 ? "配送中" : "服务中";
       },
       currentStatusText() {
-        return this.steps[this.currentStep];
+        if (this.currentStep === 4)
+          return "待确认";
+        return this.currentStep >= this.steps.length ? "已完成" : this.steps[this.currentStep];
       },
       currentTaskTitle() {
+        if (this.currentStep === 4)
+          return "待商家确认";
+        if (this.currentStep >= this.steps.length)
+          return "订单已完成";
         let action = this.steps[this.currentStep];
-        if (action === "到达")
+        if (action === "到达打卡")
           return "到达打卡";
-        if (action === "开始")
+        if (action === "开始服务")
           return "开始服务";
-        if (action === "出发")
+        if (action === "确认出发")
           return "确认出发";
-        if (action === "送达" || action === "结束")
+        if (action === "送达打卡" || action === "服务结束")
           return "服务完成";
         return action;
       },
       currentTaskDesc() {
+        if (this.currentStep === 4)
+          return "服务已提交,请等待商家确认完成后即可结束订单";
+        if (this.currentStep >= this.steps.length)
+          return "感谢您的服务,请注意休息";
         let action = this.steps[this.currentStep];
-        if (action === "到达") {
+        if (action === "到达打卡") {
           return "打卡穿着工装消毒站门口的照片或视频";
         }
         if (this.orderType === 1) {
-          if (action === "出发")
+          if (action === "确认出发")
             return "拍摄宠物上车/出发时的状态照片或视频";
-          if (action === "送达")
+          if (action === "送达打卡")
             return "打卡确认送达的照片或视频";
-        } else if (this.orderType === 2) {
-          if (action === "开始")
-            return "开始服务并拍摄照片或视频";
-          if (action === "结束")
-            return "服务完成拍摄照片或视频";
-        } else if (this.orderType === 3) {
-          if (action === "开始")
-            return "开始服务并拍摄照片或视频";
-          if (action === "结束")
+        } else {
+          if (action === "开始服务")
+            return "开始服务并拍摄照片 or 视频";
+          if (action === "服务结束")
             return "服务完成拍摄照片或视频";
         }
         return "请按要求提交照片或视频及备注";
       }
     },
-    onLoad(options) {
-      if (options.type) {
-        this.orderType = parseInt(options.type);
-        this.orderDetail.type = this.orderType;
-        if (this.orderType === 2 || this.orderType === 3) {
-          this.orderDetail.serviceTag = this.orderType === 2 ? "上门喂遛" : "上门洗护";
-          this.orderDetail.orderNo = this.orderType === 2 ? "W1002" : "X1003";
-          this.currentStep = 1;
-        }
+    async onLoad(options) {
+      if (options.id) {
+        this.orderId = options.id;
       }
+      await this.loadServiceList();
+      await this.loadOrderDetail();
     },
     methods: {
+      async loadServiceList() {
+        try {
+          const res = await getServiceList();
+          this.serviceList = res.data || [];
+        } catch (err) {
+          formatAppLog("error", "at pages/orders/detail-logic.js:115", "获取服务类型失败:", err);
+        }
+      },
+      async loadOrderDetail() {
+        if (!this.orderId) {
+          formatAppLog("log", "at pages/orders/detail-logic.js:120", "订单ID缺失");
+          uni.showToast({ title: "订单ID缺失", icon: "none" });
+          return;
+        }
+        try {
+          formatAppLog("log", "at pages/orders/detail-logic.js:125", "请求订单详情,ID:", this.orderId);
+          const res = await getOrderInfo(this.orderId);
+          formatAppLog("log", "at pages/orders/detail-logic.js:127", "订单详情响应:", res);
+          const order = res.data;
+          if (!order) {
+            formatAppLog("log", "at pages/orders/detail-logic.js:130", "订单数据为空");
+            uni.showToast({ title: "订单不存在", icon: "none" });
+            return;
+          }
+          formatAppLog("log", "at pages/orders/detail-logic.js:134", "订单数据:", order);
+          this.transformOrderData(order);
+          await this.loadOrderLogs();
+        } catch (err) {
+          formatAppLog("error", "at pages/orders/detail-logic.js:138", "获取订单详情失败:", err);
+          uni.showToast({ title: "加载失败", icon: "none" });
+        }
+      },
+      async loadOrderLogs() {
+        try {
+          const res = await getOrderLogs(this.orderId);
+          const logs = res.data || [];
+          formatAppLog("log", "at pages/orders/detail-logic.js:146", "订单日志:", logs);
+          if (logs.length > 0) {
+            formatAppLog("log", "at pages/orders/detail-logic.js:148", "第一条日志详情:", JSON.stringify(logs[0]));
+          }
+          const progressLogs = logs.filter((log) => log.logType === 1);
+          this.orderDetail.progressLogs = progressLogs.map((log) => ({
+            status: log.title || "",
+            time: log.createTime || "",
+            medias: log.photoUrls || [],
+            remark: log.content || ""
+          }));
+          const validLogs = logs.filter((log) => log.logType === 1 && log.actionType !== void 0).sort((a, b) => new Date(b.createTime).getTime() - new Date(a.createTime).getTime());
+          if (validLogs.length > 0) {
+            const latestLog = validLogs[0];
+            const actionType = latestLog.actionType;
+            if (latestLog.actionType >= 7) {
+              this.currentStep = 4;
+            } else if (actionType === 7) {
+              this.currentStep = 3;
+            } else if (actionType === 6) {
+              this.currentStep = 2;
+            } else if (actionType === 4) {
+              this.currentStep = 1;
+            } else if (actionType === 2 || actionType === 3) {
+              this.currentStep = 0;
+            } else {
+              this.currentStep = 0;
+            }
+          } else {
+            this.currentStep = 0;
+          }
+          formatAppLog("log", "at pages/orders/detail-logic.js:184", "根据最新日志推算的当前步骤:", this.currentStep);
+        } catch (err) {
+          formatAppLog("error", "at pages/orders/detail-logic.js:186", "获取订单日志失败:", err);
+        }
+      },
+      transformOrderData(order) {
+        const mode = order.mode || 0;
+        const isRoundTrip = mode === 1;
+        this.orderType = isRoundTrip ? 1 : 2;
+        this.orderStatus = order.status || 2;
+        this.orderDetail = {
+          type: this.orderType,
+          price: (order.price / 100).toFixed(2),
+          timeLabel: isRoundTrip ? "取货时间" : "服务时间",
+          time: order.serviceTime || "",
+          petAvatar: "/static/dog.png",
+          petName: order.petName || order.contact || "",
+          petBreed: order.breed || "",
+          serviceTag: order.groupPurchasePackageName || "",
+          startLocation: order.fromAddress || "",
+          startAddress: order.fromAddress || "",
+          endLocation: (order.contact || "") + " " + (order.contactPhoneNumber || ""),
+          endAddress: order.toAddress || "",
+          serviceContent: "",
+          remark: "",
+          orderNo: order.code || "T" + order.id,
+          createTime: order.serviceTime || "",
+          progressLogs: [
+            { status: "您已接单", time: order.serviceTime || "" }
+          ]
+        };
+      },
+      updateStepByStatus() {
+        if (this.orderStatus === 2) {
+          this.currentStep = 0;
+        } else if (this.orderStatus === 3) {
+          this.currentStep = 1;
+        } else if (this.orderStatus === 5) {
+          this.currentStep = this.steps.length - 1;
+        } else {
+          this.currentStep = 0;
+        }
+      },
       showPetProfile() {
         this.currentPetInfo = {
           ...this.orderDetail,
@@ -5096,7 +5242,7 @@ if (uni.restoreGlobal) {
           name: name || "目的地",
           address: address || "默认地址",
           success: function() {
-            formatAppLog("log", "at pages/orders/detail-logic.js:187", "打开导航成功: " + mapType);
+            formatAppLog("log", "at pages/orders/detail-logic.js:304", "打开导航成功: " + mapType);
           }
         });
       },
@@ -5108,12 +5254,42 @@ if (uni.restoreGlobal) {
       closeUploadModal() {
         this.showUploadModal = false;
       },
-      chooseModalMedia() {
+      handleConfirmUpload() {
+        formatAppLog("log", "at pages/orders/detail-logic.js:317", "handleConfirmUpload被调用");
+        this.confirmUploadModal();
+      },
+      async chooseModalMedia() {
+        formatAppLog("log", "at pages/orders/detail-logic.js:321", "chooseModalMedia被调用");
         uni.chooseImage({
           count: 5 - this.modalMediaList.length,
-          success: (res) => {
-            this.modalMediaList = this.modalMediaList.concat(res.tempFilePaths);
-            uni.showToast({ title: "添加成功", icon: "none" });
+          success: async (res) => {
+            formatAppLog("log", "at pages/orders/detail-logic.js:325", "选择图片成功,文件路径:", res.tempFilePaths);
+            uni.showLoading({ title: "上传中..." });
+            try {
+              for (const filePath of res.tempFilePaths) {
+                formatAppLog("log", "at pages/orders/detail-logic.js:329", "上传文件:", filePath);
+                const uploadRes = await uploadFile(filePath);
+                formatAppLog("log", "at pages/orders/detail-logic.js:331", "上传响应:", uploadRes);
+                if (uploadRes.code === 200) {
+                  this.modalMediaList.push({
+                    url: uploadRes.data.url,
+                    ossId: uploadRes.data.ossId,
+                    localPath: filePath
+                  });
+                  formatAppLog("log", "at pages/orders/detail-logic.js:338", "上传成功,url:", uploadRes.data.url);
+                }
+              }
+              uni.hideLoading();
+              formatAppLog("log", "at pages/orders/detail-logic.js:342", "当前modalMediaList:", this.modalMediaList);
+              uni.showToast({ title: "上传成功", icon: "success" });
+            } catch (err) {
+              uni.hideLoading();
+              formatAppLog("error", "at pages/orders/detail-logic.js:346", "上传失败:", err);
+              uni.showToast({ title: "上传失败", icon: "none" });
+            }
+          },
+          fail: (err) => {
+            formatAppLog("error", "at pages/orders/detail-logic.js:351", "选择图片失败:", err);
           }
         });
       },
@@ -5129,26 +5305,43 @@ if (uni.restoreGlobal) {
         const min = String(now.getMinutes()).padStart(2, "0");
         return `${y}/${m}/${d} ${h}:${min}`;
       },
-      confirmUploadModal() {
+      async confirmUploadModal() {
+        formatAppLog("log", "at pages/orders/detail-logic.js:368", "confirmUploadModal被调用,文件数量:", this.modalMediaList.length);
         if (this.modalMediaList.length === 0) {
           uni.showToast({ title: "请上传至少一张图片或视频", icon: "none" });
           return;
         }
-        this.orderDetail.progressLogs.unshift({
-          status: this.currentTaskTitle,
-          time: this.getCurrentTime(),
-          medias: [...this.modalMediaList],
-          remark: this.modalRemark
-        });
-        if (this.currentStep < this.steps.length - 1) {
-          this.currentStep++;
-        }
-        this.closeUploadModal();
-        uni.showToast({ title: "打卡成功", icon: "success" });
-        if (this.currentStep === this.steps.length - 1) {
-          setTimeout(() => {
-            uni.showToast({ title: "订单已完成", icon: "none" });
-          }, 1500);
+        try {
+          uni.showLoading({ title: "提交中..." });
+          const uploadedMedias = this.modalMediaList.map((item) => item.url);
+          const ossIds = this.modalMediaList.map((item) => item.ossId);
+          formatAppLog("log", "at pages/orders/detail-logic.js:379", "准备打卡,ossIds:", ossIds);
+          const currentAction = this.steps[this.currentStep];
+          let clockInType = 4;
+          if (currentAction === "到达打卡") {
+            clockInType = 4;
+          } else if (currentAction === "确认出发" || currentAction === "开始服务") {
+            clockInType = 6;
+          } else if (currentAction === "送达打卡" || currentAction === "服务结束") {
+            clockInType = 7;
+          }
+          const clockInData = {
+            orderId: this.orderId,
+            photos: ossIds,
+            content: this.modalRemark || "",
+            type: clockInType,
+            title: this.currentTaskTitle
+          };
+          formatAppLog("log", "at pages/orders/detail-logic.js:399", "打卡数据:", clockInData);
+          await clockIn(clockInData);
+          uni.hideLoading();
+          this.closeUploadModal();
+          uni.showToast({ title: "打卡成功", icon: "success" });
+          await this.loadOrderDetail();
+        } catch (err) {
+          uni.hideLoading();
+          formatAppLog("error", "at pages/orders/detail-logic.js:409", "打卡失败:", err);
+          uni.showToast({ title: "打卡失败,请重试", icon: "none" });
         }
       },
       copyOrderNo() {
@@ -5220,7 +5413,7 @@ if (uni.restoreGlobal) {
               return vue.openBlock(), vue.createElementBlock(
                 "view",
                 {
-                  class: vue.normalizeClass(["step-item", { "active": index <= _ctx.currentStep }]),
+                  class: vue.normalizeClass(["step-item", { "active": index === _ctx.currentStep }]),
                   key: index
                 },
                 [
@@ -5342,7 +5535,7 @@ if (uni.restoreGlobal) {
             { key: 0 },
             [
               vue.createElementVNode("view", { class: "si-row addr-row start-addr" }, [
-                vue.createElementVNode("view", { class: "icon-circle start" }, ""),
+                vue.createElementVNode("view", { class: "icon-circle start" }, ""),
                 vue.createElementVNode("view", { class: "route-line-vertical" }),
                 vue.createElementVNode("view", { class: "si-content" }, [
                   vue.createElementVNode(
@@ -5371,7 +5564,7 @@ if (uni.restoreGlobal) {
                 ])
               ]),
               vue.createElementVNode("view", { class: "si-row addr-row end-addr" }, [
-                vue.createElementVNode("view", { class: "icon-circle end" }, ""),
+                vue.createElementVNode("view", { class: "icon-circle end" }, ""),
                 vue.createElementVNode("view", { class: "si-content" }, [
                   vue.createElementVNode(
                     "text",
@@ -5470,7 +5663,7 @@ if (uni.restoreGlobal) {
             ])
           ])
         ]),
-        _ctx.currentStep < _ctx.steps.length - 1 ? (vue.openBlock(), vue.createElementBlock("view", {
+        _ctx.currentStep < _ctx.steps.length ? (vue.openBlock(), vue.createElementBlock("view", {
           key: 0,
           class: "white-card task-card"
         }, [
@@ -5626,7 +5819,7 @@ if (uni.restoreGlobal) {
           }, "宠护小结")
         ]),
         vue.createElementVNode("view", { class: "action-right" }, [
-          _ctx.currentStep < _ctx.steps.length - 1 ? (vue.openBlock(), vue.createElementBlock(
+          _ctx.currentStep < _ctx.steps.length ? (vue.openBlock(), vue.createElementBlock(
             "button",
             {
               key: 0,
@@ -5932,7 +6125,7 @@ if (uni.restoreGlobal) {
                   }, [
                     vue.createElementVNode("image", {
                       class: "um-preview",
-                      src: img,
+                      src: img.url || img.localPath || img,
                       mode: "aspectFill"
                     }, null, 8, ["src"]),
                     vue.createElementVNode("view", {
@@ -5973,12 +6166,12 @@ if (uni.restoreGlobal) {
           ]),
           vue.createElementVNode("view", { class: "um-footer" }, [
             vue.createElementVNode(
-              "button",
+              "view",
               {
                 class: vue.normalizeClass(["um-submit-btn", { "active": _ctx.modalMediaList.length > 0 }]),
-                onClick: _cache[26] || (_cache[26] = (...args) => _ctx.confirmUploadModal && _ctx.confirmUploadModal(...args))
+                onClick: _cache[26] || (_cache[26] = (...args) => _ctx.handleConfirmUpload && _ctx.handleConfirmUpload(...args))
               },
-              "确认提交",
+              " 确认提交",
               2
               /* CLASS */
             )

+ 1 - 0
unpackage/dist/dev/app-plus/pages/orders/detail.css

@@ -720,6 +720,7 @@ body {
     background-color: #E0E0E0;
     color: #fff;
     border: none;
+    text-align: center;
 }
 .um-submit-btn.active {
     background: linear-gradient(90deg, #FF9800 0%, #FF5722 100%);

+ 1 - 1
utils/config.js

@@ -4,7 +4,7 @@
  */
 
 // API 基础地址(开发环境)
-export const BASE_URL = 'http://192.168.0.102:8080'
+export const BASE_URL = 'http://192.168.1.118:8080'
 
 // 履约者App客户端ID(需要在 sys_client 表中配置)
 export const CLIENT_ID = '3'