hookehuyr

feat(订单): 添加订单发货和收货功能

- 在订单列表中添加待发货/待收货状态展示
- 实现卖家发货和买家收货功能
- 添加相关API接口和状态处理
- 更新订单状态显示和样式
- 处理微信小程序确认收货组件回调
1 /* 1 /*
2 * @Date: 2025-07-03 17:21:45 2 * @Date: 2025-07-03 17:21:45
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-07-14 14:43:05 4 + * @LastEditTime: 2025-07-28 11:51:11
5 * @FilePath: /jgdl/src/api/orders.js 5 * @FilePath: /jgdl/src/api/orders.js
6 * @Description: 文件描述 6 * @Description: 文件描述
7 */ 7 */
...@@ -14,6 +14,8 @@ const Api = { ...@@ -14,6 +14,8 @@ const Api = {
14 REVIEW_ORDER: '/srv/?a=order&t=review', 14 REVIEW_ORDER: '/srv/?a=order&t=review',
15 DELETE_ORDER: '/srv/?a=order&t=del', 15 DELETE_ORDER: '/srv/?a=order&t=del',
16 CANCEL_ORDER: '/srv/?a=order&t=cancel', 16 CANCEL_ORDER: '/srv/?a=order&t=cancel',
17 + SHIP_ORDER: '/srv/?a=order&t=ship',
18 + RECEIPT_ORDER_STATUS: '/srv/?a=order&t=receipt_status',
17 } 19 }
18 20
19 /** 21 /**
...@@ -21,7 +23,7 @@ const Api = { ...@@ -21,7 +23,7 @@ const Api = {
21 * @param page 页码,从0开始 23 * @param page 页码,从0开始
22 * @param page_size 每页数量 24 * @param page_size 每页数量
23 * @param type 列表类型。buy=我买的,sell=我卖的 25 * @param type 列表类型。buy=我买的,sell=我卖的
24 - * @param status 订单状态(3=待支付, 5=已完成, 7=已取消 26 + * @param status 订单状态(3=待支付, 5=已支付待发货, 7=已取消, 9=已发货/待收货, 11=已收货
25 * @returns data{ list[{ id, title, total_amount, status, create_time, payment_time, details{ id, vehicle_id, quantity, vehicle{} } }] } 27 * @returns data{ list[{ id, title, total_amount, status, create_time, payment_time, details{ id, vehicle_id, quantity, vehicle{} } }] }
26 */ 28 */
27 export const getOrderListAPI = (params) => fn(fetch.get(Api.GET_ORDER_LIST, params)); 29 export const getOrderListAPI = (params) => fn(fetch.get(Api.GET_ORDER_LIST, params));
...@@ -63,3 +65,17 @@ export const deleteOrderAPI = (params) => fn(fetch.post(Api.DELETE_ORDER, params ...@@ -63,3 +65,17 @@ export const deleteOrderAPI = (params) => fn(fetch.post(Api.DELETE_ORDER, params
63 * @returns data{} 65 * @returns data{}
64 */ 66 */
65 export const cancelOrderAPI = (params) => fn(fetch.post(Api.CANCEL_ORDER, params)); 67 export const cancelOrderAPI = (params) => fn(fetch.post(Api.CANCEL_ORDER, params));
68 +
69 +/**
70 + * @description: 发货订单
71 + * @param order_id 订单ID
72 + * @returns data{}
73 + */
74 +export const shipOrderAPI = (params) => fn(fetch.post(Api.SHIP_ORDER, params));
75 +
76 +/**
77 + * @description: 确认收货订单状态
78 + * @param order_id 订单ID
79 + * @returns data{ status 3=待支付, 5=已支付待发货, 7=已取消, 9=已发货/待收货, 11=已收货 }
80 + */
81 +export const receiptOrderStatusAPI = (params) => fn(fetch.get(Api.RECEIPT_ORDER_STATUS, params));
......
1 /* 1 /*
2 * @Date: 2025-06-28 10:33:00 2 * @Date: 2025-06-28 10:33:00
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-07-14 16:45:23 4 + * @LastEditTime: 2025-07-25 15:53:11
5 * @FilePath: /jgdl/src/app.js 5 * @FilePath: /jgdl/src/app.js
6 * @Description: 文件描述 6 * @Description: 文件描述
7 */ 7 */
...@@ -42,6 +42,32 @@ const App = createApp({ ...@@ -42,6 +42,32 @@ const App = createApp({
42 } 42 }
43 }, 43 },
44 onShow(options) { 44 onShow(options) {
45 + // 处理确认收货组件回调
46 + if (options && options.referrerInfo && options.referrerInfo.extraData) {
47 + const { status, errormsg, req_extradata } = options.referrerInfo.extraData
48 +
49 + if (status === 'success') {
50 + // 确认收货成功,通过事件总线通知订单页面
51 + Taro.eventCenter.trigger('confirmReceiveSuccess', {
52 + merchantId: req_extradata.merchant_id,
53 + transactionId: req_extradata.transaction_id,
54 + merchantTradeNo: req_extradata.merchant_trade_no,
55 + })
56 +
57 + Taro.showToast({
58 + title: '确认收货成功',
59 + icon: 'success',
60 + duration: 2000
61 + })
62 + } else if (status === 'fail') {
63 + Taro.showToast({
64 + title: errormsg || '确认收货失败',
65 + icon: 'error',
66 + duration: 2000
67 + })
68 + }
69 + // status === 'cancel' 时用户取消操作,不需要特殊处理
70 + }
45 }, 71 },
46 // 入口组件不需要实现 render 方法,即使实现了也会被 taro 所覆盖 72 // 入口组件不需要实现 render 方法,即使实现了也会被 taro 所覆盖
47 }); 73 });
......
1 <!-- 1 <!--
2 * @Date: 2025-06-28 10:33:00 2 * @Date: 2025-06-28 10:33:00
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-07-24 14:21:19 4 + * @LastEditTime: 2025-07-28 09:32:03
5 * @FilePath: /jgdl/src/pages/index/index.vue 5 * @FilePath: /jgdl/src/pages/index/index.vue
6 * @Description: 捡个电驴首页 6 * @Description: 捡个电驴首页
7 --> 7 -->
...@@ -153,8 +153,8 @@ useDidShow(() => { ...@@ -153,8 +153,8 @@ useDidShow(() => {
153 153
154 useReady(async () => { 154 useReady(async () => {
155 // 版本更新检查 155 // 版本更新检查
156 - if (!wx.canIUse("getUpdateManager")) { 156 + if (!Taro.canIUse("getUpdateManager")) {
157 - wx.showModal({ 157 + Taro.showModal({
158 title: "提示", 158 title: "提示",
159 content: "当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试", 159 content: "当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试",
160 showCancel: false, 160 showCancel: false,
...@@ -163,7 +163,7 @@ useReady(async () => { ...@@ -163,7 +163,7 @@ useReady(async () => {
163 } 163 }
164 164
165 // https://developers.weixin.qq.com/miniprogram/dev/api/base/update/UpdateManager.html 165 // https://developers.weixin.qq.com/miniprogram/dev/api/base/update/UpdateManager.html
166 - const updateManager = wx.getUpdateManager(); 166 + const updateManager = Taro.getUpdateManager();
167 167
168 updateManager.onCheckForUpdate((res) => { 168 updateManager.onCheckForUpdate((res) => {
169 // 请求完新版本信息的回调 169 // 请求完新版本信息的回调
......
...@@ -224,6 +224,10 @@ ...@@ -224,6 +224,10 @@
224 color: #f97316; 224 color: #f97316;
225 } 225 }
226 226
227 + &.status-shipping {
228 + color: #f97316;
229 + }
230 +
227 &.status-completed { 231 &.status-completed {
228 color: #10b981; 232 color: #10b981;
229 } 233 }
......
1 <!-- 1 <!--
2 * @Date: 2022-09-19 14:11:06 2 * @Date: 2022-09-19 14:11:06
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-07-25 10:55:07 4 + * @LastEditTime: 2025-07-28 11:52:38
5 * @FilePath: /jgdl/src/pages/myOrders/index.vue 5 * @FilePath: /jgdl/src/pages/myOrders/index.vue
6 * @Description: 订单管理页面 6 * @Description: 订单管理页面
7 --> 7 -->
...@@ -25,10 +25,12 @@ ...@@ -25,10 +25,12 @@
25 <view class="tab-item" :class="{ active: activeTab === '' }" @click="setActiveTab('')"> 25 <view class="tab-item" :class="{ active: activeTab === '' }" @click="setActiveTab('')">
26 全部 26 全部
27 </view> 27 </view>
28 - <view v-if="viewMode === 'buy'" class="tab-item" :class="{ active: activeTab === 3 }" 28 + <view v-if="viewMode === 'buy'" class="tab-item" :class="{ active: activeTab === 3 }" @click="setActiveTab(3)">
29 - @click="setActiveTab(3)">
30 待支付 29 待支付
31 </view> 30 </view>
31 + <view class="tab-item" :class="{ active: activeTab === 4 }" @click="setActiveTab(4)">
32 + {{ viewMode === 'buy' ? '待收货' : '待发货' }}
33 + </view>
32 <view class="tab-item" :class="{ active: activeTab === 5 }" @click="setActiveTab(5)"> 34 <view class="tab-item" :class="{ active: activeTab === 5 }" @click="setActiveTab(5)">
33 已完成 35 已完成
34 </view> 36 </view>
...@@ -41,8 +43,8 @@ ...@@ -41,8 +43,8 @@
41 <!-- 订单列表 --> 43 <!-- 订单列表 -->
42 <view class="order-list"> 44 <view class="order-list">
43 <!-- 滚动列表 --> 45 <!-- 滚动列表 -->
44 - <scroll-view ref="scrollViewRef" class="order-scroll-view" :style="scrollStyle" :scroll-y="true" @scrolltolower="loadMore" 46 + <scroll-view ref="scrollViewRef" class="order-scroll-view" :style="scrollStyle" :scroll-y="true"
45 - @scroll="scroll" :lower-threshold="50" :enable-flex="false" :scroll-top="scrollTop"> 47 + @scrolltolower="loadMore" @scroll="scroll" :lower-threshold="50" :enable-flex="false" :scroll-top="scrollTop">
46 <!-- 空状态 --> 48 <!-- 空状态 -->
47 <view v-if="filteredOrders.length === 0" class="empty-state"> 49 <view v-if="filteredOrders.length === 0" class="empty-state">
48 <text class="empty-text">暂无订单</text> 50 <text class="empty-text">暂无订单</text>
...@@ -62,7 +64,8 @@ ...@@ -62,7 +64,8 @@
62 <!-- 车辆信息 --> 64 <!-- 车辆信息 -->
63 <nut-row :gutter="12" class="vehicle-info" @click="goToProductDetail(order)"> 65 <nut-row :gutter="12" class="vehicle-info" @click="goToProductDetail(order)">
64 <nut-col :span="6"> 66 <nut-col :span="6">
65 - <image :src="order.details.vehicle.front_photo || DEFAULT_COVER_IMG" :alt="order.details.vehicle.brand + ' ' + order.details.vehicle.model" class="vehicle-image" 67 + <image :src="order.details.vehicle.front_photo || DEFAULT_COVER_IMG"
68 + :alt="order.details.vehicle.brand + ' ' + order.details.vehicle.model" class="vehicle-image"
66 mode="aspectFill" /> 69 mode="aspectFill" />
67 </nut-col> 70 </nut-col>
68 <nut-col :span="18"> 71 <nut-col :span="18">
...@@ -95,6 +98,28 @@ ...@@ -95,6 +98,28 @@
95 </nut-button> 98 </nut-button>
96 </template> 99 </template>
97 100
101 + <!-- 买车模式:待收货状态 -->
102 + <template v-if="viewMode === 'buy' && order.status === 4">
103 + <nut-button type="default" size="small" @click="viewOrderDetail(order.id)">
104 + 查看详情
105 + </nut-button>
106 + <nut-button type="primary" size="small" @click="handleConfirmReceive(order)" color="orange"
107 + class="ml-2" :loading="receivingOrderId === order.id" :disabled="receivingOrderId === order.id">
108 + {{ receivingOrderId === order.id ? '收货中...' : '确认收货' }}
109 + </nut-button>
110 + </template>
111 +
112 + <!-- 卖车模式:待发货状态 -->
113 + <template v-if="viewMode === 'sell' && order.status === 4">
114 + <nut-button type="default" size="small" @click="viewOrderDetail(order.id)">
115 + 查看详情
116 + </nut-button>
117 + <nut-button type="primary" size="small" @click="handleConfirmShip(order)" color="orange" class="ml-2"
118 + :loading="shippingOrderId === order.id" :disabled="shippingOrderId === order.id">
119 + {{ shippingOrderId === order.id ? '发货中...' : '确认发货' }}
120 + </nut-button>
121 + </template>
122 +
98 <!-- 已完成状态 --> 123 <!-- 已完成状态 -->
99 <template v-if="order.status === 5"> 124 <template v-if="order.status === 5">
100 <nut-button type="default" size="small" @click="viewOrderDetail(order.id)"> 125 <nut-button type="default" size="small" @click="viewOrderDetail(order.id)">
...@@ -132,8 +157,8 @@ ...@@ -132,8 +157,8 @@
132 <payCard :visible="show_pay" :data="payData" @close="onPayClose" @paySuccess="onPaySuccess" /> 157 <payCard :visible="show_pay" :data="payData" @close="onPayClose" @paySuccess="onPaySuccess" />
133 158
134 <!-- 评价弹窗 --> 159 <!-- 评价弹窗 -->
135 - <nut-popup v-model:visible="showRatePopup" position="right" :catch-move="true" :style="{ width: '100%', height: '100%' }" closeable 160 + <nut-popup v-model:visible="showRatePopup" position="right" :catch-move="true"
136 - close-icon-position="top-right" @close="closeRatePopup"> 161 + :style="{ width: '100%', height: '100%' }" closeable close-icon-position="top-right" @close="closeRatePopup">
137 <view class="rate-popup"> 162 <view class="rate-popup">
138 <view class="rate-header"> 163 <view class="rate-header">
139 <text class="rate-title">{{ isReadOnlyMode ? '查看评价' : '商品评价' }}</text> 164 <text class="rate-title">{{ isReadOnlyMode ? '查看评价' : '商品评价' }}</text>
...@@ -142,10 +167,13 @@ ...@@ -142,10 +167,13 @@
142 <view class="rate-content"> 167 <view class="rate-content">
143 <!-- 商品信息展示 --> 168 <!-- 商品信息展示 -->
144 <view class="product-info"> 169 <view class="product-info">
145 - <image :src="currentRateOrder?.details?.vehicle?.front_photo || DEFAULT_COVER_IMG" class="product-image" mode="aspectFill" /> 170 + <image :src="currentRateOrder?.details?.vehicle?.front_photo || DEFAULT_COVER_IMG" class="product-image"
171 + mode="aspectFill" />
146 <view class="product-details"> 172 <view class="product-details">
147 - <text class="product-name">{{ currentRateOrder?.details?.vehicle?.brand }} {{ currentRateOrder?.details?.vehicle?.model }}</text> 173 + <text class="product-name">{{ currentRateOrder?.details?.vehicle?.brand }} {{
148 - <text class="product-specs">{{ currentRateOrder?.details?.vehicle?.manufacture_year }}年 · 里程: {{ currentRateOrder?.details?.vehicle?.range_km }}km</text> 174 + currentRateOrder?.details?.vehicle?.model }}</text>
175 + <text class="product-specs">{{ currentRateOrder?.details?.vehicle?.manufacture_year }}年 · 里程: {{
176 + currentRateOrder?.details?.vehicle?.range_km }}km</text>
149 <text class="product-price">¥ {{ currentRateOrder?.details?.vehicle?.price }}</text> 177 <text class="product-price">¥ {{ currentRateOrder?.details?.vehicle?.price }}</text>
150 </view> 178 </view>
151 </view> 179 </view>
...@@ -162,8 +190,8 @@ ...@@ -162,8 +190,8 @@
162 <view class="rate-input-section"> 190 <view class="rate-input-section">
163 <text class="input-label">{{ isReadOnlyMode ? '评价内容' : '请输入评价内容' }}</text> 191 <text class="input-label">{{ isReadOnlyMode ? '评价内容' : '请输入评价内容' }}</text>
164 <view class="border border-gray-100"> 192 <view class="border border-gray-100">
165 - <nut-textarea v-model="rateContent" :placeholder="isReadOnlyMode ? '' : '请输入您的评价内容...'" :max-length="200" :cursorSpacing="100" 193 + <nut-textarea v-model="rateContent" :placeholder="isReadOnlyMode ? '' : '请输入您的评价内容...'" :max-length="200"
166 - :rows="4" :show-word-limit="!isReadOnlyMode" :readonly="isReadOnlyMode" 194 + :cursorSpacing="100" :rows="4" :show-word-limit="!isReadOnlyMode" :readonly="isReadOnlyMode"
167 :class="{ 'readonly': isReadOnlyMode }" /> 195 :class="{ 'readonly': isReadOnlyMode }" />
168 </view> 196 </view>
169 <!-- <text v-if="isReadOnlyMode && currentRateOrder?.details?.review?.date" class="review-date"> 197 <!-- <text v-if="isReadOnlyMode && currentRateOrder?.details?.review?.date" class="review-date">
...@@ -182,8 +210,8 @@ ...@@ -182,8 +210,8 @@
182 </nut-popup> 210 </nut-popup>
183 211
184 <!-- 订单详情弹窗 --> 212 <!-- 订单详情弹窗 -->
185 - <nut-popup v-model:visible="showOrderDetailPopup" position="right" :catch-move="true" :style="{ width: '100%', height: '100%' }" 213 + <nut-popup v-model:visible="showOrderDetailPopup" position="right" :catch-move="true"
186 - @close="closeOrderDetailPopup"> 214 + :style="{ width: '100%', height: '100%' }" @close="closeOrderDetailPopup">
187 <view class="order-detail-popup"> 215 <view class="order-detail-popup">
188 <view class="detail-header"> 216 <view class="detail-header">
189 <text class="detail-title">订单详情</text> 217 <text class="detail-title">订单详情</text>
...@@ -221,12 +249,16 @@ ...@@ -221,12 +249,16 @@
221 <view class="detail-section"> 249 <view class="detail-section">
222 <text class="section-title">商品信息</text> 250 <text class="section-title">商品信息</text>
223 <view class="product-detail-info"> 251 <view class="product-detail-info">
224 - <image :src="currentOrderDetail?.details?.vehicle?.front_photo || DEFAULT_COVER_IMG" class="product-detail-image" mode="aspectFill" /> 252 + <image :src="currentOrderDetail?.details?.vehicle?.front_photo || DEFAULT_COVER_IMG"
253 + class="product-detail-image" mode="aspectFill" />
225 <view class="product-detail-content"> 254 <view class="product-detail-content">
226 - <text class="product-detail-name">{{ currentOrderDetail?.details?.vehicle?.brand }} {{ currentOrderDetail?.details?.vehicle?.model }}</text> 255 + <text class="product-detail-name">{{ currentOrderDetail?.details?.vehicle?.brand }} {{
227 - <text class="product-detail-specs">{{ currentOrderDetail?.details?.vehicle?.manufacture_year }}年 · 续航: {{ 256 + currentOrderDetail?.details?.vehicle?.model }}</text>
257 + <text class="product-detail-specs">{{ currentOrderDetail?.details?.vehicle?.manufacture_year }}年 · 续航:
258 + {{
228 currentOrderDetail?.details?.vehicle?.range_km }}km/h</text> 259 currentOrderDetail?.details?.vehicle?.range_km }}km/h</text>
229 - <text class="product-detail-battery">电池容量: {{ currentOrderDetail?.details?.vehicle?.battery_capacity_ah }}Ah</text> 260 + <text class="product-detail-battery">电池容量: {{ currentOrderDetail?.details?.vehicle?.battery_capacity_ah
261 + }}Ah</text>
230 <text class="product-detail-price">¥ {{ currentOrderDetail?.details?.vehicle?.price }}</text> 262 <text class="product-detail-price">¥ {{ currentOrderDetail?.details?.vehicle?.price }}</text>
231 </view> 263 </view>
232 </view> 264 </view>
...@@ -237,11 +269,13 @@ ...@@ -237,11 +269,13 @@
237 <text class="section-title">交易信息</text> 269 <text class="section-title">交易信息</text>
238 <view class="info-row"> 270 <view class="info-row">
239 <text class="info-label">{{ viewMode === 'buy' ? '卖家' : '买家' }}</text> 271 <text class="info-label">{{ viewMode === 'buy' ? '卖家' : '买家' }}</text>
240 - <text class="info-value">{{ viewMode === 'buy' ? currentOrderDetail?.details?.vehicle?.seller?.nickname : currentOrderDetail?.buyer?.nickname }}</text> 272 + <text class="info-value">{{ viewMode === 'buy' ? currentOrderDetail?.details?.vehicle?.seller?.nickname :
273 + currentOrderDetail?.buyer?.nickname }}</text>
241 </view> 274 </view>
242 <view class="info-row"> 275 <view class="info-row">
243 <text class="info-label">联系电话</text> 276 <text class="info-label">联系电话</text>
244 - <text class="info-value">{{ viewMode === 'buy' ? currentOrderDetail?.details?.vehicle?.seller?.phone : currentOrderDetail?.buyer?.phone }}</text> 277 + <text class="info-value">{{ viewMode === 'buy' ? currentOrderDetail?.details?.vehicle?.seller?.phone :
278 + currentOrderDetail?.buyer?.phone }}</text>
245 </view> 279 </view>
246 <!-- <view class="info-row"> 280 <!-- <view class="info-row">
247 <text class="info-label">交易地点</text> 281 <text class="info-label">交易地点</text>
...@@ -255,8 +289,8 @@ ...@@ -255,8 +289,8 @@
255 <view class="review-info"> 289 <view class="review-info">
256 <view class="review-rating"> 290 <view class="review-rating">
257 <text class="rating-label">评分:</text> 291 <text class="rating-label">评分:</text>
258 - <nut-rate :model-value="currentOrderDetail?.details?.review?.rating" readonly size="20" active-color="#ff6b35" 292 + <nut-rate :model-value="currentOrderDetail?.details?.review?.rating" readonly size="20"
259 - void-color="#e5e5e5" /> 293 + active-color="#ff6b35" void-color="#e5e5e5" />
260 <!-- <text class="rating-text">{{ currentOrderDetail?.details?.review?.rating }}/5分</text> --> 294 <!-- <text class="rating-text">{{ currentOrderDetail?.details?.review?.rating }}/5分</text> -->
261 </view> 295 </view>
262 <view class="review-content"> 296 <view class="review-content">
...@@ -280,14 +314,8 @@ ...@@ -280,14 +314,8 @@
280 </nut-popup> 314 </nut-popup>
281 315
282 <!-- Delete Confirmation Modal --> 316 <!-- Delete Confirmation Modal -->
283 - <nut-dialog 317 + <nut-dialog v-model:visible="showConfirmModal" title="温馨提示" cancel-text="取消" ok-text="确认"
284 - v-model:visible="showConfirmModal" 318 + @cancel="showConfirmModal = false" @ok="performDeleteOrder(pendingDeleteOrderId)">
285 - title="温馨提示"
286 - cancel-text="取消"
287 - ok-text="确认"
288 - @cancel="showConfirmModal = false"
289 - @ok="performDeleteOrder(pendingDeleteOrderId)"
290 - >
291 <template #default> 319 <template #default>
292 <view> 320 <view>
293 <text style="font-size: 1rem;">是否确认删除订单?</text> 321 <text style="font-size: 1rem;">是否确认删除订单?</text>
...@@ -296,20 +324,34 @@ ...@@ -296,20 +324,34 @@
296 </nut-dialog> 324 </nut-dialog>
297 325
298 <!-- Cancel Order Confirmation Modal --> 326 <!-- Cancel Order Confirmation Modal -->
299 - <nut-dialog 327 + <nut-dialog v-model:visible="showCancelConfirmModal" title="温馨提示" cancel-text="我再想想" ok-text="确定取消"
300 - v-model:visible="showCancelConfirmModal" 328 + @cancel="showCancelConfirmModal = false" @ok="performCancelOrder(pendingCancelOrderId)">
301 - title="温馨提示"
302 - cancel-text="我再想想"
303 - ok-text="确定取消"
304 - @cancel="showCancelConfirmModal = false"
305 - @ok="performCancelOrder(pendingCancelOrderId)"
306 - >
307 <template #default> 329 <template #default>
308 <view> 330 <view>
309 <text style="font-size: 1rem;">是否确认取消订单?</text> 331 <text style="font-size: 1rem;">是否确认取消订单?</text>
310 </view> 332 </view>
311 </template> 333 </template>
312 </nut-dialog> 334 </nut-dialog>
335 +
336 + <!-- 确认发货弹窗 -->
337 + <nut-dialog v-model:visible="showShipConfirmModal" title="确认发货" cancel-text="取消" ok-text="确认发货"
338 + @cancel="showShipConfirmModal = false" @ok="performConfirmShip(pendingShipOrderId)">
339 + <template #default>
340 + <view>
341 + <text style="font-size: 1rem;">确认已将车辆发货给买家?</text>
342 + </view>
343 + </template>
344 + </nut-dialog>
345 +
346 + <!-- 确认收货弹窗 -->
347 + <nut-dialog v-model:visible="showReceiveConfirmModal" title="确认收货" cancel-text="取消" ok-text="确认收货"
348 + @cancel="showReceiveConfirmModal = false" @ok="performConfirmReceive(pendingReceiveOrderId)">
349 + <template #default>
350 + <view>
351 + <text style="font-size: 1rem;">确认已收到车辆?</text>
352 + </view>
353 + </template>
354 + </nut-dialog>
313 </view> 355 </view>
314 </template> 356 </template>
315 357
...@@ -391,6 +433,7 @@ const filteredOrders = computed(() => { ...@@ -391,6 +433,7 @@ const filteredOrders = computed(() => {
391 433
392 return orders.filter(order => { 434 return orders.filter(order => {
393 if (activeTab.value === 3) return order.status === 3 435 if (activeTab.value === 3) return order.status === 3
436 + if (activeTab.value === 4) return order.status === 4
394 if (activeTab.value === 5) return order.status === 5 437 if (activeTab.value === 5) return order.status === 5
395 if (activeTab.value === 7) return order.status === 7 438 if (activeTab.value === 7) return order.status === 7
396 return true 439 return true
...@@ -432,6 +475,41 @@ const loadOrderData = async (isLoadMore = false) => { ...@@ -432,6 +475,41 @@ const loadOrderData = async (isLoadMore = false) => {
432 const status = activeTab.value || undefined 475 const status = activeTab.value || undefined
433 const page = isLoadMore ? currentPage.value + 1 : 0 476 const page = isLoadMore ? currentPage.value + 1 : 0
434 477
478 + // 添加mock数据用于测试
479 + if (page === 0) {
480 + const mockOrder = {
481 + id: `mock_${type}_${Date.now()}`,
482 + status: 4, // 待收货/待发货状态
483 + created_time: new Date().toLocaleString('zh-CN'),
484 + total_amount: 15000,
485 + details: {
486 + id: `detail_${Date.now()}`,
487 + vehicle: {
488 + id: `vehicle_${Date.now()}`,
489 + brand: '雅迪',
490 + model: 'DE2',
491 + manufacture_year: 2023,
492 + range_km: 60,
493 + battery_capacity_ah: 48,
494 + price: 15000,
495 + front_photo: DEFAULT_COVER_IMG,
496 + seller: {
497 + nickname: '测试卖家',
498 + phone: '138****8888'
499 + }
500 + }
501 + },
502 + buyer: {
503 + nickname: '测试买家',
504 + phone: '139****9999'
505 + },
506 + is_sold: false
507 + }
508 +
509 + const targetOrders = viewMode.value === 'buy' ? boughtOrders : soldOrders
510 + targetOrders.value = [mockOrder]
511 + }
512 +
435 const response = await getOrderListAPI({ 513 const response = await getOrderListAPI({
436 type, 514 type,
437 status, 515 status,
...@@ -546,6 +624,8 @@ const getStatusText = (status) => { ...@@ -546,6 +624,8 @@ const getStatusText = (status) => {
546 switch (status) { 624 switch (status) {
547 case 3: 625 case 3:
548 return '待支付' 626 return '待支付'
627 + case 4:
628 + return viewMode.value === 'buy' ? '待收货' : '待发货'
549 case 5: 629 case 5:
550 return '已完成' 630 return '已完成'
551 case 7: 631 case 7:
...@@ -562,6 +642,8 @@ const getStatusClass = (status) => { ...@@ -562,6 +642,8 @@ const getStatusClass = (status) => {
562 switch (status) { 642 switch (status) {
563 case 3: 643 case 3:
564 return 'status-pending' 644 return 'status-pending'
645 + case 4:
646 + return 'status-shipping'
565 case 5: 647 case 5:
566 return 'status-completed' 648 return 'status-completed'
567 case 7: 649 case 7:
...@@ -889,6 +971,36 @@ const showCancelConfirmModal = ref(false) ...@@ -889,6 +971,36 @@ const showCancelConfirmModal = ref(false)
889 const pendingCancelOrderId = ref('') 971 const pendingCancelOrderId = ref('')
890 972
891 /** 973 /**
974 + * 确认发货弹窗显示状态
975 + */
976 +const showShipConfirmModal = ref(false)
977 +
978 +/**
979 + * 待发货的订单ID
980 + */
981 +const pendingShipOrderId = ref('')
982 +
983 +/**
984 + * 发货中的订单ID
985 + */
986 +const shippingOrderId = ref('')
987 +
988 +/**
989 + * 确认收货弹窗显示状态
990 + */
991 +const showReceiveConfirmModal = ref(false)
992 +
993 +/**
994 + * 待收货的订单ID
995 + */
996 +const pendingReceiveOrderId = ref('')
997 +
998 +/**
999 + * 收货中的订单ID
1000 + */
1001 +const receivingOrderId = ref('')
1002 +
1003 +/**
892 * 取消订单 1004 * 取消订单
893 * @param {string} orderId - 订单ID 1005 * @param {string} orderId - 订单ID
894 */ 1006 */
...@@ -986,6 +1098,147 @@ const deleteOrder = async (orderId) => { ...@@ -986,6 +1098,147 @@ const deleteOrder = async (orderId) => {
986 } 1098 }
987 1099
988 /** 1100 /**
1101 + * 确认收货处理
1102 + * @param {Object} order - 订单对象
1103 + */
1104 +const handleConfirmReceive = async (order) => {
1105 + try {
1106 + // 保存待收货的订单ID
1107 + pendingReceiveOrderId.value = order.id
1108 + showReceiveConfirmModal.value = true
1109 + } catch (error) {
1110 + Taro.showToast({
1111 + title: '操作失败',
1112 + icon: 'error',
1113 + duration: 2000
1114 + })
1115 + }
1116 +}
1117 +
1118 +/**
1119 + * 执行确认收货操作
1120 + * @param {string} orderId - 订单ID
1121 + */
1122 +const performConfirmReceive = async (orderId) => {
1123 + // 关闭确认弹窗
1124 + showReceiveConfirmModal.value = false
1125 +
1126 + // 设置收货状态,用于显示加载效果
1127 + receivingOrderId.value = orderId
1128 +
1129 + try {
1130 + const order = boughtOrders.value.find(o => o.id === orderId)
1131 +
1132 + if (wx.openBusinessView) {
1133 + wx.openBusinessView({
1134 + businessType: 'weappOrderConfirm',
1135 + extraData: {
1136 + merchant_id: '1230000109',
1137 + merchant_trade_no: order.id,
1138 + transaction_id: order.transaction_id || ''
1139 + },
1140 + success() {
1141 + // 确认收货组件调用成功
1142 + },
1143 + fail(err) {
1144 + Taro.showToast({
1145 + title: '确认收货失败',
1146 + icon: 'error',
1147 + duration: 2000
1148 + })
1149 + },
1150 + complete() {
1151 + receivingOrderId.value = ''
1152 + }
1153 + });
1154 + } else {
1155 + // 引导用户升级微信版本
1156 + Taro.showModal({
1157 + title: '提示',
1158 + content: '当前微信版本过低,请升级微信版本后重试',
1159 + showCancel: false
1160 + })
1161 + }
1162 + } catch (error) {
1163 + Taro.showToast({
1164 + title: '操作失败',
1165 + icon: 'error',
1166 + duration: 2000
1167 + })
1168 + } finally {
1169 + // 清除收货状态
1170 + receivingOrderId.value = ''
1171 + // 清除待收货订单ID
1172 + pendingReceiveOrderId.value = ''
1173 + }
1174 +}
1175 +
1176 +/**
1177 + * 确认发货处理
1178 + * @param {Object} order - 订单对象
1179 + */
1180 +const handleConfirmShip = async (order) => {
1181 + try {
1182 + // 保存待发货的订单ID
1183 + pendingShipOrderId.value = order.id
1184 + showShipConfirmModal.value = true
1185 + } catch (error) {
1186 + console.error('确认发货失败:', error)
1187 + }
1188 +}
1189 +
1190 +/**
1191 + * 执行确认发货操作
1192 + * @param {string} orderId - 订单ID
1193 + */
1194 +const performConfirmShip = async (orderId) => {
1195 + // 关闭确认弹窗
1196 + showShipConfirmModal.value = false
1197 +
1198 + // 设置发货状态,用于显示加载效果
1199 + shippingOrderId.value = orderId
1200 +
1201 + try {
1202 + // TODO: 调用确认发货API(暂时使用mock)
1203 + // const response = await confirmShipAPI({ id: orderId })
1204 +
1205 + // Mock API响应
1206 + const response = { code: true, msg: '发货成功' }
1207 +
1208 + if (response.code) {
1209 + // API发货成功后的处理
1210 + const orders = viewMode.value === 'buy' ? boughtOrders : soldOrders
1211 + const order = orders.value.find(o => o.id === orderId)
1212 +
1213 + if (order) {
1214 + // 更新订单状态为已完成
1215 + order.status = 5
1216 +
1217 + Taro.showToast({
1218 + title: response.msg || '发货成功',
1219 + icon: 'success',
1220 + duration: 2000
1221 + })
1222 + }
1223 + } else {
1224 + throw new Error(response.msg || '发货失败')
1225 + }
1226 + } catch (error) {
1227 + console.error('确认发货失败:', error)
1228 + Taro.showToast({
1229 + title: error.msg || '确认发货失败,请重试',
1230 + icon: 'error',
1231 + duration: 2000
1232 + })
1233 + } finally {
1234 + // 清除发货状态
1235 + shippingOrderId.value = ''
1236 + // 清除待发货订单ID
1237 + pendingShipOrderId.value = ''
1238 + }
1239 +}
1240 +
1241 +/**
989 * 执行删除订单操作 1242 * 执行删除订单操作
990 * @param {string} orderId - 订单ID 1243 * @param {string} orderId - 订单ID
991 */ 1244 */
...@@ -1034,6 +1287,19 @@ const performDeleteOrder = async (orderId) => { ...@@ -1034,6 +1287,19 @@ const performDeleteOrder = async (orderId) => {
1034 } 1287 }
1035 } 1288 }
1036 1289
1290 +/**
1291 + * 处理确认收货成功事件
1292 + * @param {Object} data - 事件数据
1293 + */
1294 +const handleConfirmReceiveSuccess = ({ merchantId, transactionId, merchantTradeNo }) => {
1295 + const orders = boughtOrders.value
1296 + const order = orders.find(o => o.id === merchantTradeNo)
1297 +
1298 + if (order) {
1299 + order.status = 5 // 更新为已完成状态
1300 + }
1301 +}
1302 +
1037 // 页面加载时的初始化 1303 // 页面加载时的初始化
1038 onMounted(async () => { 1304 onMounted(async () => {
1039 // 加载订单数据 1305 // 加载订单数据
...@@ -1048,11 +1314,16 @@ onMounted(async () => { ...@@ -1048,11 +1314,16 @@ onMounted(async () => {
1048 height: windowHeight - headerHeight - navHeight + 'px' 1314 height: windowHeight - headerHeight - navHeight + 'px'
1049 } 1315 }
1050 }, 500); 1316 }, 500);
1317 +
1318 + // 监听确认收货成功事件
1319 + Taro.eventCenter.on('confirmReceiveSuccess', handleConfirmReceiveSuccess)
1051 }) 1320 })
1052 1321
1053 -// 页面卸载时清理定时器 1322 +// 页面卸载时清理定时器和事件监听器
1054 onUnmounted(() => { 1323 onUnmounted(() => {
1055 clearAllCountdowns() 1324 clearAllCountdowns()
1325 + // 移除确认收货成功事件监听器
1326 + Taro.eventCenter.off('confirmReceiveSuccess', handleConfirmReceiveSuccess)
1056 }) 1327 })
1057 </script> 1328 </script>
1058 1329
......