hookehuyr

feat(订单): 重构订单模块,实现真实API对接

- 修改订单API接口,简化并适配后端接口
- 商品详情页增加卖家判断逻辑,隐藏不相关操作
- 订单列表页重构,对接真实数据并优化分页加载
- 实现订单评价功能,对接真实API
- 优化订单详情展示,显示更多真实数据
1 /* 1 /*
2 - * @Date: 2024-01-01 00:00:00 2 + * @Date: 2025-07-03 17:21:45
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-07-09 15:00:24 4 + * @LastEditTime: 2025-07-14 09:34:58
5 * @FilePath: /jgdl/src/api/orders.js 5 * @FilePath: /jgdl/src/api/orders.js
6 - * @Description: 车辆订单相关API接口 6 + * @Description: 文件描述
7 */ 7 */
8 -import { fn, fetch } from './fn'; 8 +import { fn, fetch } from '@/api/fn';
9 9
10 -// API 端点定义 10 +const Api = {
11 -const OrderApi = { 11 + GET_ORDER_LIST: '/srv/?a=order&t=list',
12 - // 获取我的订单列表 12 + GET_ORDER_DETAIL: '/srv/?a=order&t=detail',
13 - GET_MY_ORDERS: '/api/orders/my-orders', 13 + CREATE_ORDER: '/srv/?a=order&t=add',
14 - // 获取订单详情 14 + REVIEW_ORDER: '/srv/?a=order&t=review',
15 - GET_ORDER_DETAIL: '/api/orders/detail', 15 + DELETE_ORDER: '/srv/?a=order&t=del',
16 - // 删除订单 16 +}
17 - DELETE_ORDER: '/api/orders/delete',
18 - // 取消订单
19 - CANCEL_ORDER: '/api/orders/cancel',
20 - // 确认收货
21 - CONFIRM_ORDER: '/api/orders/confirm',
22 - // 提交评价
23 - SUBMIT_REVIEW: '/api/orders/review',
24 - // 申请退款
25 - REQUEST_REFUND: '/api/orders/refund',
26 -};
27 17
28 /** 18 /**
29 - * @description: 获取我的订单列表 19 + * @description: 获取订单列表
30 - * @param {Object} params 20 + * @param page 页码,从0开始
31 - * @param {string} params.type - 订单类型 'bought' | 'sold' 21 + * @param page_size 每页数量
32 - * @param {number} params.page - 页码 22 + * @param type 列表类型。buy=我买的,sell=我卖的
33 - * @param {number} params.limit - 每页数量 23 + * @param status 订单状态(3=待支付, 5=已完成, 7=已取消)
34 - * @param {string} params.status - 订单状态筛选(可选) 24 + * @returns data{ list[{ id, title, total_amount, status, create_time, payment_time, details{ id, vehicle_id, quantity, vehicle{} } }] }
35 - * @returns {Promise}
36 */ 25 */
37 -export const getMyOrdersAPI = (params) => { 26 +export const getOrderListAPI = (params) => fn(fetch.get(Api.GET_ORDER_LIST, params));
38 - // TODO: 替换为真实的API调用
39 - return fn(fetch.get(OrderApi.GET_MY_ORDERS, params));
40 -};
41 27
42 /** 28 /**
43 * @description: 获取订单详情 29 * @description: 获取订单详情
44 - * @param {Object} params 30 + * @param id 订单ID
45 - * @param {string} params.orderId - 订单ID 31 + * @returns data{ id, title, total_amount, status, create_time, payment_time, details{ id, vehicle_id, quantity, vehicle{ id, title, price, cover_image } } }
46 - * @returns {Promise}
47 */ 32 */
48 -export const getOrderDetailAPI = (params) => { 33 +export const getOrderDetailAPI = (params) => fn(fetch.get(Api.GET_ORDER_DETAIL, params));
49 - // TODO: 替换为真实的API调用
50 - return fn(fetch.get(OrderApi.GET_ORDER_DETAIL, params));
51 -};
52 34
53 /** 35 /**
54 - * @description: 删除订单 36 + * @description: 创建订单
55 - * @param {Object} params 37 + * @param vehicle_id 车辆ID
56 - * @param {string} params.orderId - 订单ID 38 + * @param total_amount 总价
57 - * @returns {Promise} 39 + * @returns data{ id }
58 - *
59 - * @example
60 - * // 使用示例:
61 - * try {
62 - * const response = await deleteOrderAPI({ orderId: 'ORDER_123' });
63 - * if (response.success) {
64 - * console.log('删除成功:', response.message);
65 - * }
66 - * } catch (error) {
67 - * console.error('删除失败:', error.message);
68 - * }
69 - *
70 - * @apiResponse
71 - * {
72 - * success: true,
73 - * message: '订单删除成功',
74 - * data: null
75 - * }
76 */ 40 */
77 -export const deleteOrderAPI = (params) => { 41 +export const createOrderAPI = (params) => fn(fetch.post(Api.CREATE_ORDER, params));
78 - // TODO: 替换为真实的API调用
79 - // 当集成真实API时,请确保:
80 - // 1. 处理网络错误和超时
81 - // 2. 验证用户权限(只能删除自己的订单)
82 - // 3. 检查订单状态(只有特定状态的订单才能删除)
83 - // 4. 返回统一的响应格式
84 - return fn(fetch.delete(OrderApi.DELETE_ORDER, params));
85 -};
86 42
87 /** 43 /**
88 - * @description: 取消订单 44 + * @description: 订单评价
89 - * @param {Object} params 45 + * @param detail_id 订单ID
90 - * @param {string} params.orderId - 订单ID 46 + * @param rating 评级(1到5分)
91 - * @param {string} params.reason - 取消原因(可选) 47 + * @param note 评价内容
92 - * @returns {Promise} 48 + * @returns data{}
93 */ 49 */
94 -export const cancelOrderAPI = (params) => { 50 +export const reviewOrderAPI = (params) => fn(fetch.post(Api.REVIEW_ORDER, params));
95 - // TODO: 替换为真实的API调用
96 - return fn(fetch.post(OrderApi.CANCEL_ORDER, params));
97 -};
98 51
99 /** 52 /**
100 - * @description: 确认收货/完成交易 53 + * @description: 删除订单
101 - * @param {Object} params 54 + * @param order_id 订单ID
102 - * @param {string} params.orderId - 订单ID 55 + * @returns data{}
103 - * @returns {Promise}
104 - */
105 -export const confirmOrderAPI = (params) => {
106 - // TODO: 替换为真实的API调用
107 - return fn(fetch.post(OrderApi.CONFIRM_ORDER, params));
108 -};
109 -
110 -/**
111 - * @description: 提交订单评价
112 - * @param {Object} params
113 - * @param {string} params.orderId - 订单ID
114 - * @param {number} params.rating - 评分 (1-5)
115 - * @param {string} params.comment - 评价内容
116 - * @param {Array} params.images - 评价图片(可选)
117 - * @returns {Promise}
118 - *
119 - * @example
120 - * // 使用示例:
121 - * try {
122 - * const response = await submitReviewAPI({
123 - * orderId: 'ORDER_123',
124 - * rating: 5,
125 - * comment: '车况很好,卖家服务态度也很棒!',
126 - * images: ['image1.jpg', 'image2.jpg'] // 可选
127 - * });
128 - * if (response.success) {
129 - * console.log('评价提交成功:', response.message);
130 - * }
131 - * } catch (error) {
132 - * console.error('评价提交失败:', error.message);
133 - * }
134 - *
135 - * @apiResponse
136 - * {
137 - * success: true,
138 - * message: '评价提交成功',
139 - * data: {
140 - * reviewId: 'REVIEW_123',
141 - * createdAt: '2024-01-01T12:00:00Z'
142 - * }
143 - * }
144 - */
145 -export const submitReviewAPI = (params) => {
146 - // TODO: 替换为真实的API调用
147 - // 当集成真实API时,请确保:
148 - // 1. 验证评分范围(1-5)
149 - // 2. 验证评价内容长度限制
150 - // 3. 处理图片上传(如果有)
151 - // 4. 检查订单状态(只有已完成的订单才能评价)
152 - // 5. 防止重复评价
153 - return fn(fetch.post(OrderApi.SUBMIT_REVIEW, params));
154 -};
155 -
156 -/**
157 - * @description: 申请退款
158 - * @param {Object} params
159 - * @param {string} params.orderId - 订单ID
160 - * @param {string} params.reason - 退款原因
161 - * @param {number} params.amount - 退款金额
162 - * @param {Array} params.evidence - 退款凭证(可选)
163 - * @returns {Promise}
164 */ 56 */
165 -export const requestRefundAPI = (params) => { 57 +export const deleteOrderAPI = (params) => fn(fetch.post(Api.DELETE_ORDER, params));
166 - // TODO: 替换为真实的API调用
167 - return fn(fetch.post(OrderApi.REQUEST_REFUND, params));
168 -};
169 -
170 -// 导出所有API
171 -export default {
172 - getMyOrdersAPI,
173 - getOrderDetailAPI,
174 - deleteOrderAPI,
175 - cancelOrderAPI,
176 - confirmOrderAPI,
177 - submitReviewAPI,
178 - requestRefundAPI,
179 -};
......
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-07 16:32:43 4 + * @LastEditTime: 2025-07-14 14:36:50
5 * @FilePath: /jgdl/src/pages/myOrders/index.vue 5 * @FilePath: /jgdl/src/pages/myOrders/index.vue
6 * @Description: 订单管理页面 6 * @Description: 订单管理页面
7 --> 7 -->
...@@ -11,10 +11,10 @@ ...@@ -11,10 +11,10 @@
11 <!-- 买车/卖车切换 --> 11 <!-- 买车/卖车切换 -->
12 <view id="mode-toggle" class="view-mode-toggle"> 12 <view id="mode-toggle" class="view-mode-toggle">
13 <view class="toggle-container"> 13 <view class="toggle-container">
14 - <view class="toggle-option" :class="{ active: viewMode === 'bought' }" @click="setViewMode('bought')"> 14 + <view class="toggle-option" :class="{ active: viewMode === 'buy' }" @click="setViewMode('buy')">
15 我买的车 15 我买的车
16 </view> 16 </view>
17 - <view class="toggle-option" :class="{ active: viewMode === 'sold' }" @click="setViewMode('sold')"> 17 + <view class="toggle-option" :class="{ active: viewMode === 'sell' }" @click="setViewMode('sell')">
18 我卖的车 18 我卖的车
19 </view> 19 </view>
20 </view> 20 </view>
...@@ -22,17 +22,17 @@ ...@@ -22,17 +22,17 @@
22 22
23 <!-- 状态筛选标签 --> 23 <!-- 状态筛选标签 -->
24 <view id="status-tabs" class="status-tabs"> 24 <view id="status-tabs" class="status-tabs">
25 - <view class="tab-item" :class="{ active: activeTab === 'all' }" @click="setActiveTab('all')"> 25 + <view class="tab-item" :class="{ active: activeTab === '' }" @click="setActiveTab('')">
26 全部 26 全部
27 </view> 27 </view>
28 - <view v-if="viewMode === 'bought'" class="tab-item" :class="{ active: activeTab === 'pending' }" 28 + <view v-if="viewMode === 'buy'" class="tab-item" :class="{ active: activeTab === 3 }"
29 - @click="setActiveTab('pending')"> 29 + @click="setActiveTab(3)">
30 待支付 30 待支付
31 </view> 31 </view>
32 - <view class="tab-item" :class="{ active: activeTab === 'completed' }" @click="setActiveTab('completed')"> 32 + <view class="tab-item" :class="{ active: activeTab === 5 }" @click="setActiveTab(5)">
33 已完成 33 已完成
34 </view> 34 </view>
35 - <view class="tab-item" :class="{ active: activeTab === 'cancelled' }" @click="setActiveTab('cancelled')"> 35 + <view class="tab-item" :class="{ active: activeTab === 7 }" @click="setActiveTab(7)">
36 已取消 36 已取消
37 </view> 37 </view>
38 </view> 38 </view>
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
53 <view v-for="order in filteredOrders" :key="order.id" class="order-card"> 53 <view v-for="order in filteredOrders" :key="order.id" class="order-card">
54 <!-- 订单头部信息 --> 54 <!-- 订单头部信息 -->
55 <view class="order-header"> 55 <view class="order-header">
56 - <text class="order-date">{{ order.date }}</text> 56 + <text class="order-date">{{ order.created_time }}</text>
57 <text class="order-status" :class="getStatusClass(order.status)"> 57 <text class="order-status" :class="getStatusClass(order.status)">
58 {{ getStatusText(order.status) }} 58 {{ getStatusText(order.status) }}
59 </text> 59 </text>
...@@ -62,17 +62,17 @@ ...@@ -62,17 +62,17 @@
62 <!-- 车辆信息 --> 62 <!-- 车辆信息 -->
63 <nut-row :gutter="12" class="vehicle-info"> 63 <nut-row :gutter="12" class="vehicle-info">
64 <nut-col :span="6"> 64 <nut-col :span="6">
65 - <image :src="order.vehicle.imageUrl" :alt="order.vehicle.name" class="vehicle-image" 65 + <image :src="order.details.vehicle.front_photo || DEFAULT_COVER_IMG" :alt="order.details.vehicle.brand + ' ' + order.details.vehicle.model" class="vehicle-image"
66 mode="aspectFill" /> 66 mode="aspectFill" />
67 </nut-col> 67 </nut-col>
68 <nut-col :span="18"> 68 <nut-col :span="18">
69 <view class="vehicle-details"> 69 <view class="vehicle-details">
70 - <text class="vehicle-name">{{ order.vehicle.name }}</text> 70 + <text class="vehicle-name">{{ order.details.vehicle.brand }} {{ order.details.vehicle.model }}</text>
71 <text class="vehicle-specs"> 71 <text class="vehicle-specs">
72 - {{ order.vehicle.year }} | {{ order.vehicle.mileage }} 72 + {{ order.details.vehicle.manufacture_year }}年 | 续航{{ order.details.vehicle.range_km }}km
73 </text> 73 </text>
74 - <text class="vehicle-battery">{{ order.vehicle.batteryCapacity }}</text> 74 + <text class="vehicle-battery">电池容量:{{ order.details.vehicle.battery_capacity_ah }}Ah</text>
75 - <text class="vehicle-price">¥{{ order.vehicle.price }}</text> 75 + <text class="vehicle-price">¥{{ order.details.vehicle.price }}</text>
76 </view> 76 </view>
77 </nut-col> 77 </nut-col>
78 </nut-row> 78 </nut-row>
...@@ -80,24 +80,24 @@ ...@@ -80,24 +80,24 @@
80 <!-- 操作按钮 --> 80 <!-- 操作按钮 -->
81 <view class="order-actions"> 81 <view class="order-actions">
82 <!-- 买车模式:待支付状态 --> 82 <!-- 买车模式:待支付状态 -->
83 - <template v-if="viewMode === 'bought' && order.status === 'pending'"> 83 + <template v-if="viewMode === 'buy' && order.status === 3">
84 <nut-button type="primary" size="small" @click="handlePayment(order)" color="orange"> 84 <nut-button type="primary" size="small" @click="handlePayment(order)" color="orange">
85 去支付 85 去支付
86 </nut-button> 86 </nut-button>
87 </template> 87 </template>
88 88
89 <!-- 已完成状态 --> 89 <!-- 已完成状态 -->
90 - <template v-if="order.status === 'completed'"> 90 + <template v-if="order.status === 5">
91 <nut-button type="default" size="small" @click="viewOrderDetail(order.id)"> 91 <nut-button type="default" size="small" @click="viewOrderDetail(order.id)">
92 查看详情 92 查看详情
93 </nut-button> 93 </nut-button>
94 <nut-button type="primary" size="small" @click="rateOrder(order.id)" class="ml-2" color="orange" plain> 94 <nut-button type="primary" size="small" @click="rateOrder(order.id)" class="ml-2" color="orange" plain>
95 - {{ order.review ? '查看评价' : '评价' }} 95 + {{ order.details.review ? '查看评价' : '评价' }}
96 </nut-button> 96 </nut-button>
97 </template> 97 </template>
98 98
99 <!-- 已取消状态 --> 99 <!-- 已取消状态 -->
100 - <template v-if="order.status === 'cancelled'"> 100 + <template v-if="order.status === 7">
101 <nut-button type="default" size="small" @click="deleteOrder(order.id)" 101 <nut-button type="default" size="small" @click="deleteOrder(order.id)"
102 :loading="deletingOrderId === order.id" :disabled="deletingOrderId === order.id"> 102 :loading="deletingOrderId === order.id" :disabled="deletingOrderId === order.id">
103 {{ deletingOrderId === order.id ? '删除中...' : '删除订单' }} 103 {{ deletingOrderId === order.id ? '删除中...' : '删除订单' }}
...@@ -133,12 +133,11 @@ ...@@ -133,12 +133,11 @@
133 <view class="rate-content"> 133 <view class="rate-content">
134 <!-- 商品信息展示 --> 134 <!-- 商品信息展示 -->
135 <view class="product-info"> 135 <view class="product-info">
136 - <image :src="currentRateOrder?.vehicle?.imageUrl" class="product-image" mode="aspectFill" /> 136 + <image :src="currentRateOrder?.details?.vehicle?.front_photo || DEFAULT_COVER_IMG" class="product-image" mode="aspectFill" />
137 <view class="product-details"> 137 <view class="product-details">
138 - <text class="product-name">{{ currentRateOrder?.vehicle?.name }}</text> 138 + <text class="product-name">{{ currentRateOrder?.details?.vehicle?.brand }} {{ currentRateOrder?.details?.vehicle?.model }}</text>
139 - <text class="product-specs">{{ currentRateOrder?.vehicle?.year }} · {{ currentRateOrder?.vehicle?.mileage 139 + <text class="product-specs">{{ currentRateOrder?.details?.vehicle?.manufacture_year }}年 · 里程: {{ currentRateOrder?.details?.vehicle?.range_km }}km</text>
140 - }}</text> 140 + <text class="product-price">¥ {{ currentRateOrder?.details?.vehicle?.price }}</text>
141 - <text class="product-price">¥{{ currentRateOrder?.vehicle?.price }}</text>
142 </view> 141 </view>
143 </view> 142 </view>
144 143
...@@ -158,9 +157,9 @@ ...@@ -158,9 +157,9 @@
158 :rows="4" :show-word-limit="!isReadOnlyMode" :readonly="isReadOnlyMode" 157 :rows="4" :show-word-limit="!isReadOnlyMode" :readonly="isReadOnlyMode"
159 :class="{ 'readonly': isReadOnlyMode }" /> 158 :class="{ 'readonly': isReadOnlyMode }" />
160 </view> 159 </view>
161 - <text v-if="isReadOnlyMode && currentRateOrder?.review?.date" class="review-date"> 160 + <!-- <text v-if="isReadOnlyMode && currentRateOrder?.details?.review?.date" class="review-date">
162 - 评价时间:{{ currentRateOrder?.review?.date }} 161 + 评价时间:{{ currentRateOrder?.details?.review?.date }}
163 - </text> 162 + </text> -->
164 </view> 163 </view>
165 </view> 164 </view>
166 165
...@@ -175,7 +174,7 @@ ...@@ -175,7 +174,7 @@
175 174
176 <!-- 订单详情弹窗 --> 175 <!-- 订单详情弹窗 -->
177 <nut-popup v-model:visible="showOrderDetailPopup" position="right" :style="{ width: '100%', height: '100%' }" 176 <nut-popup v-model:visible="showOrderDetailPopup" position="right" :style="{ width: '100%', height: '100%' }"
178 - closeable close-icon-position="top-right" @close="closeOrderDetailPopup"> 177 + @close="closeOrderDetailPopup">
179 <view class="order-detail-popup"> 178 <view class="order-detail-popup">
180 <view class="detail-header"> 179 <view class="detail-header">
181 <text class="detail-title">订单详情</text> 180 <text class="detail-title">订单详情</text>
...@@ -191,7 +190,11 @@ ...@@ -191,7 +190,11 @@
191 </view> 190 </view>
192 <view class="info-row"> 191 <view class="info-row">
193 <text class="info-label">下单时间</text> 192 <text class="info-label">下单时间</text>
194 - <text class="info-value">{{ currentOrderDetail?.date }}</text> 193 + <text class="info-value">{{ currentOrderDetail?.created_time }}</text>
194 + </view>
195 + <view class="info-row">
196 + <text class="info-label">支付时间</text>
197 + <text class="info-value">{{ currentOrderDetail?.payment_time }}</text>
195 </view> 198 </view>
196 <view class="info-row"> 199 <view class="info-row">
197 <text class="info-label">订单状态</text> 200 <text class="info-label">订单状态</text>
...@@ -201,7 +204,7 @@ ...@@ -201,7 +204,7 @@
201 </view> 204 </view>
202 <view class="info-row"> 205 <view class="info-row">
203 <text class="info-label">订单金额</text> 206 <text class="info-label">订单金额</text>
204 - <text class="info-value price">¥{{ currentOrderDetail?.price }}</text> 207 + <text class="info-value price">¥ {{ currentOrderDetail?.total_amount }}</text>
205 </view> 208 </view>
206 </view> 209 </view>
207 210
...@@ -209,13 +212,13 @@ ...@@ -209,13 +212,13 @@
209 <view class="detail-section"> 212 <view class="detail-section">
210 <text class="section-title">商品信息</text> 213 <text class="section-title">商品信息</text>
211 <view class="product-detail-info"> 214 <view class="product-detail-info">
212 - <image :src="currentOrderDetail?.vehicle?.imageUrl" class="product-detail-image" mode="aspectFill" /> 215 + <image :src="currentOrderDetail?.details?.vehicle?.front_photo || DEFAULT_COVER_IMG" class="product-detail-image" mode="aspectFill" />
213 <view class="product-detail-content"> 216 <view class="product-detail-content">
214 - <text class="product-detail-name">{{ currentOrderDetail?.vehicle?.name }}</text> 217 + <text class="product-detail-name">{{ currentOrderDetail?.details?.vehicle?.brand }} {{ currentOrderDetail?.details?.vehicle?.model }}</text>
215 - <text class="product-detail-specs">{{ currentOrderDetail?.vehicle?.year }} · {{ 218 + <text class="product-detail-specs">{{ currentOrderDetail?.details?.vehicle?.manufacture_year }}年 · 续航: {{
216 - currentOrderDetail?.vehicle?.mileage }}</text> 219 + currentOrderDetail?.details?.vehicle?.range_km }}km/h</text>
217 - <text class="product-detail-battery">{{ currentOrderDetail?.vehicle?.batteryCapacity }}</text> 220 + <text class="product-detail-battery">电池容量: {{ currentOrderDetail?.details?.vehicle?.battery_capacity_ah }}Ah</text>
218 - <text class="product-detail-price">¥{{ currentOrderDetail?.vehicle?.price }}</text> 221 + <text class="product-detail-price">¥ {{ currentOrderDetail?.details?.vehicle?.price }}</text>
219 </view> 222 </view>
220 </view> 223 </view>
221 </view> 224 </view>
...@@ -224,35 +227,35 @@ ...@@ -224,35 +227,35 @@
224 <view class="detail-section"> 227 <view class="detail-section">
225 <text class="section-title">交易信息</text> 228 <text class="section-title">交易信息</text>
226 <view class="info-row"> 229 <view class="info-row">
227 - <text class="info-label">{{ viewMode === 'bought' ? '卖家' : '买家' }}</text> 230 + <text class="info-label">{{ viewMode === 'buy' ? '卖家' : '买家' }}</text>
228 - <text class="info-value">{{ viewMode === 'bought' ? '张先生' : '李女士' }}</text> 231 + <text class="info-value">{{ viewMode === 'buy' ? currentOrderDetail?.details?.vehicle?.seller?.nickname : currentOrderDetail?.buyer?.nickname }}</text>
229 </view> 232 </view>
230 <view class="info-row"> 233 <view class="info-row">
231 <text class="info-label">联系电话</text> 234 <text class="info-label">联系电话</text>
232 - <text class="info-value">{{ viewMode === 'bought' ? '138****5678' : '139****1234' }}</text> 235 + <text class="info-value">{{ viewMode === 'buy' ? currentOrderDetail?.details?.vehicle?.seller?.phone : currentOrderDetail?.buyer?.phone }}</text>
233 </view> 236 </view>
234 - <view class="info-row"> 237 + <!-- <view class="info-row">
235 <text class="info-label">交易地点</text> 238 <text class="info-label">交易地点</text>
236 <text class="info-value">北京市朝阳区望京SOHO</text> 239 <text class="info-value">北京市朝阳区望京SOHO</text>
237 - </view> 240 + </view> -->
238 </view> 241 </view>
239 242
240 <!-- 评价信息(如果有) --> 243 <!-- 评价信息(如果有) -->
241 - <view class="detail-section" v-if="currentOrderDetail?.review"> 244 + <view class="detail-section" v-if="currentOrderDetail?.details?.review">
242 <text class="section-title">评价信息</text> 245 <text class="section-title">评价信息</text>
243 <view class="review-info"> 246 <view class="review-info">
244 <view class="review-rating"> 247 <view class="review-rating">
245 <text class="rating-label">评分:</text> 248 <text class="rating-label">评分:</text>
246 - <nut-rate :model-value="currentOrderDetail?.review?.rating" readonly size="20" active-color="#ff6b35" 249 + <nut-rate :model-value="currentOrderDetail?.details?.review?.rating" readonly size="20" active-color="#ff6b35"
247 void-color="#e5e5e5" /> 250 void-color="#e5e5e5" />
248 - <!-- <text class="rating-text">{{ currentOrderDetail?.review?.rating }}/5分</text> --> 251 + <!-- <text class="rating-text">{{ currentOrderDetail?.details?.review?.rating }}/5分</text> -->
249 </view> 252 </view>
250 <view class="review-content"> 253 <view class="review-content">
251 <text class="content-label">评价内容:</text> 254 <text class="content-label">评价内容:</text>
252 - <text class="content-text">{{ currentOrderDetail?.review?.content }}</text> 255 + <text class="content-text">{{ currentOrderDetail?.details?.review?.note }}</text>
253 </view> 256 </view>
254 <view class="review-time"> 257 <view class="review-time">
255 - <text class="time-text">评价时间:{{ currentOrderDetail?.review?.date }}</text> 258 + <text class="time-text">评价时间:{{ currentOrderDetail?.details?.review?.created_time }}</text>
256 </view> 259 </view>
257 </view> 260 </view>
258 </view> 261 </view>
...@@ -282,24 +285,18 @@ ...@@ -282,24 +285,18 @@
282 </view> 285 </view>
283 </template> 286 </template>
284 </nut-dialog> 287 </nut-dialog>
285 -
286 - <!-- 成功提示 -->
287 - <nut-toast
288 - v-model:visible="toastVisible"
289 - :msg="toastMessage"
290 - :type="toastType"
291 - />
292 </view> 288 </view>
293 </template> 289 </template>
294 290
295 <script setup> 291 <script setup>
296 import { ref, computed, onMounted } from 'vue' 292 import { ref, computed, onMounted } from 'vue'
297 import Taro from '@tarojs/taro' 293 import Taro from '@tarojs/taro'
298 -// import { deleteOrderAPI, submitReviewAPI } from '@/api/orders' // 预留真实API调用
299 import './index.less' 294 import './index.less'
300 import { $ } from '@tarojs/extend' 295 import { $ } from '@tarojs/extend'
301 import payCard from '@/components/payCard.vue' 296 import payCard from '@/components/payCard.vue'
302 -// NutUI组件已全局注册,无需单独导入Rate 297 +// 导入接口
298 +import { getOrderListAPI, getOrderDetailAPI, reviewOrderAPI } from '@/api/orders'
299 +import { DEFAULT_COVER_IMG } from '@/utils/config'
303 300
304 const scrollStyle = ref({ 301 const scrollStyle = ref({
305 height: '' 302 height: ''
...@@ -310,8 +307,8 @@ const scrollViewRef = ref(null) ...@@ -310,8 +307,8 @@ const scrollViewRef = ref(null)
310 const scrollTop = ref(0) 307 const scrollTop = ref(0)
311 308
312 // 页面状态 309 // 页面状态
313 -const activeTab = ref('all') 310 +const activeTab = ref('')
314 -const viewMode = ref('bought') 311 +const viewMode = ref('buy')
315 const loading = ref(false) 312 const loading = ref(false)
316 const hasMore = ref(true) 313 const hasMore = ref(true)
317 314
...@@ -334,188 +331,30 @@ const isReadOnlyMode = ref(false) ...@@ -334,188 +331,30 @@ const isReadOnlyMode = ref(false)
334 const showOrderDetailPopup = ref(false) 331 const showOrderDetailPopup = ref(false)
335 const currentOrderDetail = ref(null) 332 const currentOrderDetail = ref(null)
336 333
337 -// 模拟订单数据 - 我买的车 334 +// 订单数据 - 我买的车
338 -const boughtOrders = ref([ 335 +const boughtOrders = ref([])
339 - { 336 +
340 - id: 'B001', 337 +// 订单数据 - 我卖的车
341 - price: 3999, 338 +const soldOrders = ref([])
342 - date: '2023-11-15 14:30', 339 +
343 - status: 'pending', 340 +// 分页相关状态
344 - vehicle: { 341 +const currentPage = ref(0)
345 - name: '小牛 U1 Pro', 342 +const pageLimit = ref(10)
346 - year: '2022年',
347 - mileage: '续航120km',
348 - batteryCapacity: '电池容量:1.5kWh',
349 - price: 3999,
350 - imageUrl: 'https://images.unsplash.com/photo-1558981285-6f0c94958bb6?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60'
351 - }
352 - },
353 - {
354 - id: 'B002',
355 - price: 5299,
356 - date: '2023-10-28 09:15',
357 - status: 'completed',
358 - vehicle: {
359 - name: '雅迪 DE2',
360 - year: '2023年',
361 - mileage: '续航80km',
362 - batteryCapacity: '电池容量:1.2kWh',
363 - price: 5299,
364 - imageUrl: 'https://images.unsplash.com/photo-1571068316344-75bc76f77890?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60'
365 - },
366 - review: {
367 - rating: 4,
368 - content: '车子质量不错,续航也够用,就是充电时间有点长。',
369 - date: '2023-10-30 16:20'
370 - }
371 - },
372 - {
373 - id: 'B003',
374 - price: 2899,
375 - date: '2023-09-20 11:30',
376 - status: 'cancelled',
377 - vehicle: {
378 - name: '台铃 小狮子',
379 - year: '2021年',
380 - mileage: '续航65km',
381 - batteryCapacity: '电池容量:1.0kWh',
382 - price: 2899,
383 - imageUrl: 'https://images.unsplash.com/photo-1544191696-15693072b5a5?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60'
384 - }
385 - },
386 - {
387 - id: 'B004',
388 - price: 4599,
389 - date: '2023-08-15 15:45',
390 - status: 'completed',
391 - vehicle: {
392 - name: '九号 E80C',
393 - year: '2023年',
394 - mileage: '续航80km',
395 - batteryCapacity: '电池容量:1.44kWh',
396 - price: 4599,
397 - imageUrl: 'https://images.unsplash.com/photo-1558618666-fcd25c85cd64?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60'
398 - },
399 - review: {
400 - rating: 5,
401 - content: '非常满意!车况很好,卖家服务态度也很棒,推荐!',
402 - date: '2023-08-18 10:30'
403 - }
404 - },
405 - {
406 - id: 'B005',
407 - price: 1899,
408 - date: '2023-07-22 13:20',
409 - status: 'pending',
410 - vehicle: {
411 - name: '绿源 MH5',
412 - year: '2020年',
413 - mileage: '续航50km',
414 - batteryCapacity: '电池容量:0.9kWh',
415 - price: 1899,
416 - imageUrl: 'https://images.unsplash.com/photo-1571068316344-75bc76f77890?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60'
417 - }
418 - }
419 -])
420 -
421 -// 模拟订单数据 - 我卖的车
422 -const soldOrders = ref([
423 - {
424 - id: 'S001',
425 - price: 3200,
426 - date: '2023-11-10 16:45',
427 - status: 'completed',
428 - vehicle: {
429 - name: '爱玛 小蜜豆',
430 - year: '2021年',
431 - mileage: '续航60km',
432 - batteryCapacity: '电池容量:0.8kWh',
433 - price: 3200,
434 - imageUrl: 'https://images.unsplash.com/photo-1544191696-15693072b5a5?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60'
435 - },
436 - review: {
437 - rating: 5,
438 - content: '买家很爽快,交易很顺利,车子也很满意!',
439 - date: '2023-11-12 14:20'
440 - }
441 - },
442 - {
443 - id: 'S002',
444 - price: 2800,
445 - date: '2023-10-05 10:30',
446 - status: 'pending',
447 - vehicle: {
448 - name: '小刀 长征版',
449 - year: '2022年',
450 - mileage: '续航70km',
451 - batteryCapacity: '电池容量:1.1kWh',
452 - price: 2800,
453 - imageUrl: 'https://images.unsplash.com/photo-1558618666-fcd25c85cd64?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60'
454 - }
455 - },
456 - {
457 - id: 'S003',
458 - price: 4200,
459 - date: '2023-09-18 14:15',
460 - status: 'cancelled',
461 - vehicle: {
462 - name: '立马 威风',
463 - year: '2023年',
464 - mileage: '续航90km',
465 - batteryCapacity: '电池容量:1.6kWh',
466 - price: 4200,
467 - imageUrl: 'https://images.unsplash.com/photo-1558981285-6f0c94958bb6?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60'
468 - }
469 - },
470 - {
471 - id: 'S004',
472 - price: 1650,
473 - date: '2023-08-28 09:45',
474 - status: 'completed',
475 - vehicle: {
476 - name: '新日 XC1',
477 - year: '2020年',
478 - mileage: '续航45km',
479 - batteryCapacity: '电池容量:0.7kWh',
480 - price: 1650,
481 - imageUrl: 'https://images.unsplash.com/photo-1571068316344-75bc76f77890?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60'
482 - }
483 - },
484 - {
485 - id: 'S005',
486 - price: 3800,
487 - date: '2023-07-12 16:20',
488 - status: 'completed',
489 - vehicle: {
490 - name: '哈啰 A80',
491 - year: '2022年',
492 - mileage: '续航85km',
493 - batteryCapacity: '电池容量:1.3kWh',
494 - price: 3800,
495 - imageUrl: 'https://images.unsplash.com/photo-1544191696-15693072b5a5?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60'
496 - },
497 - review: {
498 - rating: 4,
499 - content: '车子成色不错,买家也很好沟通,交易愉快!',
500 - date: '2023-07-15 11:30'
501 - }
502 - }
503 -])
504 343
505 /** 344 /**
506 * 根据当前视图模式和筛选条件获取过滤后的订单列表 345 * 根据当前视图模式和筛选条件获取过滤后的订单列表
507 */ 346 */
508 const filteredOrders = computed(() => { 347 const filteredOrders = computed(() => {
509 - const orders = viewMode.value === 'bought' ? boughtOrders.value : soldOrders.value 348 + const orders = viewMode.value === 'buy' ? boughtOrders.value : soldOrders.value
510 349
511 - if (activeTab.value === 'all') { 350 + if (activeTab.value === '') {
512 return orders 351 return orders
513 } 352 }
514 353
515 return orders.filter(order => { 354 return orders.filter(order => {
516 - if (activeTab.value === 'pending') return order.status === 'pending' 355 + if (activeTab.value === 3) return order.status === 3
517 - if (activeTab.value === 'completed') return order.status === 'completed' 356 + if (activeTab.value === 5) return order.status === 5
518 - if (activeTab.value === 'cancelled') return order.status === 'cancelled' 357 + if (activeTab.value === 7) return order.status === 7
519 return true 358 return true
520 }) 359 })
521 }) 360 })
...@@ -526,7 +365,7 @@ const filteredOrders = computed(() => { ...@@ -526,7 +365,7 @@ const filteredOrders = computed(() => {
526 const setViewMode = (mode) => { 365 const setViewMode = (mode) => {
527 viewMode.value = mode 366 viewMode.value = mode
528 // 重置状态筛选标签到全部 367 // 重置状态筛选标签到全部
529 - activeTab.value = 'all' 368 + activeTab.value = ''
530 // 重置列表状态和数据 369 // 重置列表状态和数据
531 resetListState(true) 370 resetListState(true)
532 } 371 }
...@@ -536,8 +375,68 @@ const setViewMode = (mode) => { ...@@ -536,8 +375,68 @@ const setViewMode = (mode) => {
536 */ 375 */
537 const setActiveTab = (tab) => { 376 const setActiveTab = (tab) => {
538 activeTab.value = tab 377 activeTab.value = tab
539 - // 重置列表加载状态 378 + // 重置列表加载状态并重新加载数据
540 - resetListState(false) 379 + currentPage.value = 0
380 + loadOrderData(false)
381 +}
382 +
383 +/**
384 + * 加载订单数据
385 + * @param {boolean} isLoadMore - 是否为加载更多
386 + */
387 +const loadOrderData = async (isLoadMore = false) => {
388 + if (loading.value) return
389 +
390 + try {
391 + loading.value = true
392 +
393 + const type = viewMode.value === 'buy' ? 'buy' : 'sell'
394 + const status = activeTab.value || undefined
395 + const page = isLoadMore ? currentPage.value + 1 : 0
396 +
397 + const response = await getOrderListAPI({
398 + type,
399 + status,
400 + page,
401 + limit: pageLimit.value
402 + })
403 +
404 + if (response.code && response.data && response.data.list && response.data.list.length > 0) {
405 + // 处理多个订单数据
406 + const newOrders = response.data.list.map(orderData => {
407 + // 处理details数组,取第一个元素作为details对象
408 + return {
409 + ...orderData,
410 + details: orderData.details && orderData.details.length > 0 ? orderData.details[0] : null
411 + }
412 + })
413 +
414 + const targetOrders = viewMode.value === 'buy' ? boughtOrders : soldOrders
415 +
416 + if (isLoadMore) {
417 + targetOrders.value = [...targetOrders.value, ...newOrders]
418 + currentPage.value = page
419 + } else {
420 + targetOrders.value = newOrders
421 + currentPage.value = 0
422 + }
423 +
424 + // 判断是否还有更多数据
425 + hasMore.value = newOrders.length === pageLimit.value
426 + } else {
427 + hasMore.value = false
428 + }
429 + } catch (error) {
430 + console.error('加载订单数据失败:', error)
431 + Taro.showToast({
432 + title: '加载失败,请重试',
433 + icon: 'error',
434 + duration: 2000
435 + })
436 + hasMore.value = false
437 + } finally {
438 + loading.value = false
439 + }
541 } 440 }
542 441
543 /** 442 /**
...@@ -547,18 +446,17 @@ const setActiveTab = (tab) => { ...@@ -547,18 +446,17 @@ const setActiveTab = (tab) => {
547 const resetListState = (resetData = false) => { 446 const resetListState = (resetData = false) => {
548 loading.value = false 447 loading.value = false
549 hasMore.value = true 448 hasMore.value = true
449 + currentPage.value = 0
550 450
551 // 重置滚动位置到顶部 451 // 重置滚动位置到顶部
552 scrollTop.value = Math.random() // 使用随机数触发scroll-view重新渲染 452 scrollTop.value = Math.random() // 使用随机数触发scroll-view重新渲染
553 453
554 if (resetData) { 454 if (resetData) {
555 - // 重置已加载的数据索引 455 + // 清空订单数据
556 - loadedBoughtIndex.value = 0 456 + boughtOrders.value = []
557 - loadedSoldIndex.value = 0 457 + soldOrders.value = []
558 - 458 + // 重新加载数据
559 - // 重置订单数据到初始状态 459 + loadOrderData(false)
560 - boughtOrders.value = boughtOrders.value.slice(0, 5) // 保留前5条初始数据
561 - soldOrders.value = soldOrders.value.slice(0, 5) // 保留前5条初始数据
562 } 460 }
563 461
564 // 延迟重置scrollTop为0,确保滚动位置正确 462 // 延迟重置scrollTop为0,确保滚动位置正确
...@@ -574,147 +472,14 @@ const scroll = (e) => { ...@@ -574,147 +472,14 @@ const scroll = (e) => {
574 // 可以在这里处理滚动事件 472 // 可以在这里处理滚动事件
575 } 473 }
576 474
577 -// 模拟更多数据池 - 买车订单
578 -const moreBoughtOrders = [
579 - {
580 - id: 'B006',
581 - price: 2299,
582 - date: '2023-06-18 14:30',
583 - status: 'completed',
584 - vehicle: {
585 - name: '小鸟 V1',
586 - year: '2019年',
587 - mileage: '续航55km',
588 - batteryCapacity: '电池容量:0.8kWh',
589 - price: 2299,
590 - imageUrl: 'https://images.unsplash.com/photo-1558981285-6f0c94958bb6?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60'
591 - },
592 - review: {
593 - rating: 3,
594 - content: '车子还行,就是电池续航有点短,价格还算合理。',
595 - date: '2023-06-20 09:15'
596 - }
597 - },
598 - {
599 - id: 'B007',
600 - price: 3599,
601 - date: '2023-05-25 16:45',
602 - status: 'cancelled',
603 - vehicle: {
604 - name: '速珂 TC Max',
605 - year: '2022年',
606 - mileage: '续航100km',
607 - batteryCapacity: '电池容量:1.8kWh',
608 - price: 3599,
609 - imageUrl: 'https://images.unsplash.com/photo-1571068316344-75bc76f77890?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60'
610 - }
611 - },
612 - {
613 - id: 'B008',
614 - price: 4899,
615 - date: '2023-04-12 11:20',
616 - status: 'pending',
617 - vehicle: {
618 - name: '小牛 NGT',
619 - year: '2023年',
620 - mileage: '续航130km',
621 - batteryCapacity: '电池容量:2.0kWh',
622 - price: 4899,
623 - imageUrl: 'https://images.unsplash.com/photo-1558618666-fcd25c85cd64?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60'
624 - }
625 - }
626 -]
627 -
628 -// 模拟更多数据池 - 卖车订单
629 -const moreSoldOrders = [
630 - {
631 - id: 'S006',
632 - price: 2100,
633 - date: '2023-06-08 13:15',
634 - status: 'completed',
635 - vehicle: {
636 - name: '绿佳 FDT',
637 - year: '2020年',
638 - mileage: '续航50km',
639 - batteryCapacity: '电池容量:0.9kWh',
640 - price: 2100,
641 - imageUrl: 'https://images.unsplash.com/photo-1544191696-15693072b5a5?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60'
642 - }
643 - },
644 - {
645 - id: 'S007',
646 - price: 3500,
647 - date: '2023-05-20 10:30',
648 - status: 'pending',
649 - vehicle: {
650 - name: '雅迪 G5 Pro',
651 - year: '2022年',
652 - mileage: '续航85km',
653 - batteryCapacity: '电池容量:1.4kWh',
654 - price: 3500,
655 - imageUrl: 'https://images.unsplash.com/photo-1558981285-6f0c94958bb6?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60'
656 - }
657 - },
658 - {
659 - id: 'S008',
660 - price: 1800,
661 - date: '2023-04-15 15:45',
662 - status: 'cancelled',
663 - vehicle: {
664 - name: '爱玛 麦',
665 - year: '2019年',
666 - mileage: '续航40km',
667 - batteryCapacity: '电池容量:0.6kWh',
668 - price: 1800,
669 - imageUrl: 'https://images.unsplash.com/photo-1571068316344-75bc76f77890?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60'
670 - }
671 - }
672 -]
673 475
674 -// 记录已加载的数据索引
675 -const loadedBoughtIndex = ref(0)
676 -const loadedSoldIndex = ref(0)
677 476
678 /** 477 /**
679 * 加载更多数据 478 * 加载更多数据
680 */ 479 */
681 const loadMore = () => { 480 const loadMore = () => {
682 if (loading.value || !hasMore.value) return 481 if (loading.value || !hasMore.value) return
683 - 482 + loadOrderData(true)
684 - loading.value = true
685 -
686 - // 模拟加载延迟
687 - setTimeout(() => {
688 - const currentOrders = viewMode.value === 'bought' ? boughtOrders : soldOrders
689 - const moreOrders = viewMode.value === 'bought' ? moreBoughtOrders : moreSoldOrders
690 - const loadedIndex = viewMode.value === 'bought' ? loadedBoughtIndex : loadedSoldIndex
691 -
692 - // 每次加载2条数据
693 - const batchSize = 2
694 - const startIndex = loadedIndex.value
695 - const endIndex = Math.min(startIndex + batchSize, moreOrders.length)
696 -
697 - if (startIndex < moreOrders.length) {
698 - // 添加新数据
699 - const newOrders = moreOrders.slice(startIndex, endIndex)
700 - currentOrders.value.push(...newOrders)
701 -
702 - // 更新已加载索引
703 - if (viewMode.value === 'bought') {
704 - loadedBoughtIndex.value = endIndex
705 - } else {
706 - loadedSoldIndex.value = endIndex
707 - }
708 -
709 - // 检查是否还有更多数据
710 - hasMore.value = endIndex < moreOrders.length
711 - } else {
712 - // 没有更多数据了
713 - hasMore.value = false
714 - }
715 -
716 - loading.value = false
717 - }, 1000)
718 } 483 }
719 484
720 /** 485 /**
...@@ -722,11 +487,11 @@ const loadMore = () => { ...@@ -722,11 +487,11 @@ const loadMore = () => {
722 */ 487 */
723 const getStatusText = (status) => { 488 const getStatusText = (status) => {
724 switch (status) { 489 switch (status) {
725 - case 'pending': 490 + case 3:
726 return '待支付' 491 return '待支付'
727 - case 'completed': 492 + case 5:
728 return '已完成' 493 return '已完成'
729 - case 'cancelled': 494 + case 7:
730 return '已取消' 495 return '已取消'
731 default: 496 default:
732 return '未知状态' 497 return '未知状态'
...@@ -738,27 +503,25 @@ const getStatusText = (status) => { ...@@ -738,27 +503,25 @@ const getStatusText = (status) => {
738 */ 503 */
739 const getStatusClass = (status) => { 504 const getStatusClass = (status) => {
740 switch (status) { 505 switch (status) {
741 - case 'pending': 506 + case 3:
742 return 'status-pending' 507 return 'status-pending'
743 - case 'completed': 508 + case 5:
744 return 'status-completed' 509 return 'status-completed'
745 - case 'cancelled': 510 + case 7:
746 return 'status-cancelled' 511 return 'status-cancelled'
747 default: 512 default:
748 return '' 513 return ''
749 } 514 }
750 } 515 }
751 516
752 -// 页面导航相关方法可以在需要时添加
753 -
754 /** 517 /**
755 * 处理支付 518 * 处理支付
756 */ 519 */
757 -const handlePayment = ({ id, price }) => { 520 +const handlePayment = ({ id, total_amount }) => {
758 onPay({ 521 onPay({
759 id, 522 id,
760 remain_time: 1800, // 30分钟 523 remain_time: 1800, // 30分钟
761 - price 524 + price: total_amount
762 }) 525 })
763 } 526 }
764 527
...@@ -790,12 +553,12 @@ const onPayClose = () => { ...@@ -790,12 +553,12 @@ const onPayClose = () => {
790 */ 553 */
791 const onPaySuccess = ({ orderId }) => { 554 const onPaySuccess = ({ orderId }) => {
792 // 找到对应的订单并更新状态 555 // 找到对应的订单并更新状态
793 - const orders = viewMode.value === 'bought' ? boughtOrders.value : soldOrders.value 556 + const orders = viewMode.value === 'buy' ? boughtOrders.value : soldOrders.value
794 const order = orders.find(o => o.id === orderId) 557 const order = orders.find(o => o.id === orderId)
795 558
796 if (order) { 559 if (order) {
797 // 更新订单状态为已完成 560 // 更新订单状态为已完成
798 - order.status = 'completed' 561 + order.status = 5
799 562
800 Taro.showToast({ 563 Taro.showToast({
801 title: '支付成功,订单已更新', 564 title: '支付成功,订单已更新',
...@@ -808,15 +571,18 @@ const onPaySuccess = ({ orderId }) => { ...@@ -808,15 +571,18 @@ const onPaySuccess = ({ orderId }) => {
808 /** 571 /**
809 * 查看订单详情 572 * 查看订单详情
810 */ 573 */
811 -const viewOrderDetail = (orderId) => { 574 +const viewOrderDetail = async (orderId) => {
812 // 找到对应的订单 575 // 找到对应的订单
813 - const orders = viewMode.value === 'bought' ? boughtOrders.value : soldOrders.value 576 + const orders = viewMode.value === 'buy' ? boughtOrders.value : soldOrders.value
814 const order = orders.find(o => o.id === orderId) 577 const order = orders.find(o => o.id === orderId)
815 578
816 if (order) { 579 if (order) {
817 - currentOrderDetail.value = order 580 + const { code, data } = await getOrderDetailAPI({ id: orderId })
581 + if (code) {
582 + currentOrderDetail.value = { ...data, details: data.details[0] }
818 showOrderDetailPopup.value = true 583 showOrderDetailPopup.value = true
819 } 584 }
585 + }
820 } 586 }
821 587
822 /** 588 /**
...@@ -832,7 +598,7 @@ const closeOrderDetailPopup = () => { ...@@ -832,7 +598,7 @@ const closeOrderDetailPopup = () => {
832 */ 598 */
833 const rateOrder = (orderId) => { 599 const rateOrder = (orderId) => {
834 // 找到对应的订单 600 // 找到对应的订单
835 - const orders = viewMode.value === 'bought' ? boughtOrders.value : soldOrders.value 601 + const orders = viewMode.value === 'buy' ? boughtOrders.value : soldOrders.value
836 const order = orders.find(o => o.id === orderId) 602 const order = orders.find(o => o.id === orderId)
837 603
838 if (order) { 604 if (order) {
...@@ -882,52 +648,28 @@ const submitRate = async () => { ...@@ -882,52 +648,28 @@ const submitRate = async () => {
882 try { 648 try {
883 submittingRate.value = true 649 submittingRate.value = true
884 650
885 - // 真实的API调用(当前注释掉,使用模拟数据) 651 + const response = await reviewOrderAPI({
886 - // const response = await submitReviewAPI({ 652 + detail_id: currentRateOrder.value.id,
887 - // orderId: currentRateOrder.value.id, 653 + rating: rateScore.value,
888 - // rating: rateScore.value, 654 + note: rateContent.value
889 - // comment: rateContent.value 655 + })
890 - // }) 656 + if (response.code) {
891 - // if (response.success) { 657 + // API提交成功后的处理
892 - // // API提交成功后的处理 658 + const currentOrders = viewMode.value === 'buy' ? boughtOrders : soldOrders
893 - // const currentOrders = viewMode.value === 'bought' ? boughtOrders : soldOrders
894 - // const order = currentOrders.value.find(o => o.id === currentRateOrder.value.id)
895 - // if (order) {
896 - // order.review = {
897 - // rating: rateScore.value,
898 - // content: rateContent.value,
899 - // date: new Date().toLocaleString('zh-CN')
900 - // }
901 - // order.status = 'completed'
902 - // }
903 - // Toast.success(response.message || '评价提交成功')
904 - // closeRatePopup()
905 - // } else {
906 - // throw new Error(response.message || '提交失败')
907 - // }
908 -
909 - // 模拟API调用延迟(开发阶段使用)
910 - await new Promise(resolve => setTimeout(resolve, 1500))
911 -
912 - // 更新本地数据
913 - const currentOrders = viewMode.value === 'bought' ? boughtOrders : soldOrders
914 const order = currentOrders.value.find(o => o.id === currentRateOrder.value.id) 659 const order = currentOrders.value.find(o => o.id === currentRateOrder.value.id)
915 if (order) { 660 if (order) {
916 order.review = { 661 order.review = {
917 rating: rateScore.value, 662 rating: rateScore.value,
918 - content: rateContent.value, 663 + note: rateContent.value,
919 date: new Date().toLocaleString('zh-CN') 664 date: new Date().toLocaleString('zh-CN')
920 } 665 }
921 - order.status = 'completed' 666 + order.status = 5
922 } 667 }
923 - 668 + Toast.success(response.message || '评价提交成功')
924 - Taro.showToast({
925 - title: '评价提交成功',
926 - icon: 'success',
927 - duration: 2000
928 - })
929 -
930 closeRatePopup() 669 closeRatePopup()
670 + } else {
671 + throw new Error(response.message || '提交失败')
672 + }
931 673
932 } catch (error) { 674 } catch (error) {
933 // console.error('提交评价失败:', error) 675 // console.error('提交评价失败:', error)
...@@ -955,22 +697,6 @@ const showConfirmModal = ref(false) ...@@ -955,22 +697,6 @@ const showConfirmModal = ref(false)
955 const pendingDeleteOrderId = ref('') 697 const pendingDeleteOrderId = ref('')
956 698
957 /** 699 /**
958 - * Toast提示
959 - */
960 -const toastVisible = ref(false)
961 -const toastMessage = ref('')
962 -const toastType = ref('success')
963 -
964 -/**
965 - * 显示提示信息
966 - */
967 -const showToast = (message, type = 'success') => {
968 - toastMessage.value = message
969 - toastType.value = type
970 - toastVisible.value = true
971 -}
972 -
973 -/**
974 * 删除订单 700 * 删除订单
975 * @param {string} orderId - 订单ID 701 * @param {string} orderId - 订单ID
976 */ 702 */
...@@ -999,9 +725,9 @@ const performDeleteOrder = async (orderId) => { ...@@ -999,9 +725,9 @@ const performDeleteOrder = async (orderId) => {
999 try { 725 try {
1000 // 真实的API调用(当前注释掉,使用模拟数据) 726 // 真实的API调用(当前注释掉,使用模拟数据)
1001 // const response = await deleteOrderAPI({ orderId }) 727 // const response = await deleteOrderAPI({ orderId })
1002 - // if (response.success) { 728 + // if (response.code) {
1003 // // API删除成功后的处理 729 // // API删除成功后的处理
1004 - // const orders = viewMode.value === 'bought' ? boughtOrders : soldOrders 730 + // const orders = viewMode.value === 'buy' ? boughtOrders : soldOrders
1005 // const orderIndex = orders.value.findIndex(order => order.id === orderId) 731 // const orderIndex = orders.value.findIndex(order => order.id === orderId)
1006 // if (orderIndex !== -1) { 732 // if (orderIndex !== -1) {
1007 // orders.value.splice(orderIndex, 1) 733 // orders.value.splice(orderIndex, 1)
...@@ -1015,13 +741,17 @@ const performDeleteOrder = async (orderId) => { ...@@ -1015,13 +741,17 @@ const performDeleteOrder = async (orderId) => {
1015 await new Promise(resolve => setTimeout(resolve, 1000)) 741 await new Promise(resolve => setTimeout(resolve, 1000))
1016 742
1017 // 从本地数据中移除订单 743 // 从本地数据中移除订单
1018 - const orders = viewMode.value === 'bought' ? boughtOrders : soldOrders 744 + const orders = viewMode.value === 'buy' ? boughtOrders : soldOrders
1019 const orderIndex = orders.value.findIndex(order => order.id === orderId) 745 const orderIndex = orders.value.findIndex(order => order.id === orderId)
1020 746
1021 if (orderIndex !== -1) { 747 if (orderIndex !== -1) {
1022 orders.value.splice(orderIndex, 1) 748 orders.value.splice(orderIndex, 1)
1023 749
1024 - showToast('订单删除成功', 'success') 750 + Taro.showToast({
751 + title: '订单删除成功',
752 + icon: 'success',
753 + duration: 2000
754 + })
1025 } else { 755 } else {
1026 throw new Error('订单不存在') 756 throw new Error('订单不存在')
1027 } 757 }
...@@ -1029,7 +759,11 @@ const performDeleteOrder = async (orderId) => { ...@@ -1029,7 +759,11 @@ const performDeleteOrder = async (orderId) => {
1029 } catch (error) { 759 } catch (error) {
1030 // console.error('删除订单失败:', error) 760 // console.error('删除订单失败:', error)
1031 761
1032 - showToast('删除订单失败', 'error') 762 + Taro.showToast({
763 + title: '删除订单失败',
764 + icon: 'error',
765 + duration: 2000
766 + })
1033 } finally { 767 } finally {
1034 // 清除删除状态 768 // 清除删除状态
1035 deletingOrderId.value = '' 769 deletingOrderId.value = ''
...@@ -1040,7 +774,9 @@ const performDeleteOrder = async (orderId) => { ...@@ -1040,7 +774,9 @@ const performDeleteOrder = async (orderId) => {
1040 774
1041 // 页面加载时的初始化 775 // 页面加载时的初始化
1042 onMounted(async () => { 776 onMounted(async () => {
1043 - // TODO: 加载订单数据 777 + // 加载订单数据
778 + loadOrderData(false)
779 +
1044 // 设置滚动列表可视高度 780 // 设置滚动列表可视高度
1045 const windowHeight = wx.getWindowInfo().windowHeight; 781 const windowHeight = wx.getWindowInfo().windowHeight;
1046 setTimeout(async () => { 782 setTimeout(async () => {
...@@ -1058,7 +794,3 @@ export default { ...@@ -1058,7 +794,3 @@ export default {
1058 name: "OrderManagementPage", 794 name: "OrderManagementPage",
1059 }; 795 };
1060 </script> 796 </script>
1061 -
1062 -<style lang="less">
1063 -/* 样式已移至 index.less 文件 */
1064 -</style>
......
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-11 14:56:02 4 + * @LastEditTime: 2025-07-14 09:34:00
5 * @FilePath: /jgdl/src/pages/productDetail/index.vue 5 * @FilePath: /jgdl/src/pages/productDetail/index.vue
6 * @Description: 商品详情页 6 * @Description: 商品详情页
7 --> 7 -->
...@@ -136,7 +136,7 @@ ...@@ -136,7 +136,7 @@
136 </view> 136 </view>
137 137
138 <!-- 卖家信息 --> 138 <!-- 卖家信息 -->
139 - <view class="seller-info bg-white mt-2 p-4 mb-2"> 139 + <view v-if="!isCurrentUserSeller" class="seller-info bg-white mt-2 p-4 mb-2">
140 <text class="text-lg font-medium mb-3 block">卖家信息</text> 140 <text class="text-lg font-medium mb-3 block">卖家信息</text>
141 <view class="flex items-center justify-between"> 141 <view class="flex items-center justify-between">
142 <view class="flex items-center"> 142 <view class="flex items-center">
...@@ -167,7 +167,7 @@ ...@@ -167,7 +167,7 @@
167 </view> 167 </view>
168 168
169 <!-- 底部按钮 --> 169 <!-- 底部按钮 -->
170 - <view class="bottom-actions"> 170 + <view v-if="!isCurrentUserSeller" class="bottom-actions">
171 <nut-row :gutter="10"> 171 <nut-row :gutter="10">
172 <nut-col :span="12"> 172 <nut-col :span="12">
173 <nut-button @click="handleContactSeller" block type="default" shape="round" 173 <nut-button @click="handleContactSeller" block type="default" shape="round"
...@@ -245,17 +245,20 @@ ...@@ -245,17 +245,20 @@
245 </template> 245 </template>
246 246
247 <script setup> 247 <script setup>
248 -import { ref, onMounted } from 'vue' 248 +import { ref, onMounted, computed } from 'vue'
249 import Taro, { useShareAppMessage } from '@tarojs/taro' 249 import Taro, { useShareAppMessage } from '@tarojs/taro'
250 import { Share, Heart1, HeartFill, Message } from '@nutui/icons-vue-taro' 250 import { Share, Heart1, HeartFill, Message } from '@nutui/icons-vue-taro'
251 import payCard from '@/components/payCard.vue' 251 import payCard from '@/components/payCard.vue'
252 import { useFavorite } from '@/composables/useFavorite' 252 import { useFavorite } from '@/composables/useFavorite'
253 -import avatarImg from '@/assets/images/avatar.png' 253 +// import avatarImg from '@/assets/images/avatar.png'
254 import { getCurrentPageParam } from "@/utils/weapp" 254 import { getCurrentPageParam } from "@/utils/weapp"
255 import { checkPermission, PERMISSION_TYPES } from '@/utils/permission' 255 import { checkPermission, PERMISSION_TYPES } from '@/utils/permission'
256 // 导入接口 256 // 导入接口
257 import { getVehicleDetailAPI } from '@/api/car' 257 import { getVehicleDetailAPI } from '@/api/car'
258 +import { createOrderAPI } from '@/api/orders'
258 import { DEFAULT_COVER_IMG } from '@/utils/config' 259 import { DEFAULT_COVER_IMG } from '@/utils/config'
260 +// 导入用户 store
261 +import { useUserStore } from '@/stores/user'
259 262
260 // 默认头像 263 // 默认头像
261 const defaultAvatar = 'https://cdn.ipadbiz.cn/mlaj/images/icon_1.jpeg' 264 const defaultAvatar = 'https://cdn.ipadbiz.cn/mlaj/images/icon_1.jpeg'
...@@ -288,14 +291,14 @@ const quickTags = ref([ ...@@ -288,14 +291,14 @@ const quickTags = ref([
288 ]) 291 ])
289 292
290 // 备用图片数组 293 // 备用图片数组
291 -const fallbackImages = ref([ 294 +// const fallbackImages = ref([
292 - avatarImg, 295 +// avatarImg,
293 - avatarImg, 296 +// avatarImg,
294 - avatarImg, 297 +// avatarImg,
295 - avatarImg, 298 +// avatarImg,
296 - avatarImg 299 +// avatarImg
297 -]) 300 +// ])
298 -const imageLoadErrors = ref(new Set()) 301 +// const imageLoadErrors = ref(new Set())
299 302
300 // 模拟商品数据 303 // 模拟商品数据
301 const product = ref({}) 304 const product = ref({})
...@@ -304,13 +307,23 @@ const product = ref({}) ...@@ -304,13 +307,23 @@ const product = ref({})
304 * 轮播图切换事件 307 * 轮播图切换事件
305 * @param {number} index - 当前图片索引 308 * @param {number} index - 当前图片索引
306 */ 309 */
307 -// const onSwiperChange = (index) => { 310 +const onSwiperChange = (index) => {
308 -// currentImageIndex.value = index 311 + currentImageIndex.value = index
309 -// } 312 +}
310 313
311 // 使用收藏功能composables 314 // 使用收藏功能composables
312 const { toggleFavorite } = useFavorite() 315 const { toggleFavorite } = useFavorite()
313 316
317 +// 使用用户 store
318 +const userStore = useUserStore()
319 +
320 +/**
321 + * 判断当前用户是否为卖家
322 + */
323 +const isCurrentUserSeller = computed(() => {
324 + return product.value.seller?.id && userStore.userInfo.id && product.value.seller.id === userStore.userInfo.id
325 +})
326 +
314 /** 327 /**
315 * 显示微信号弹框 328 * 显示微信号弹框
316 */ 329 */
...@@ -406,11 +419,21 @@ const handlePurchase = async () => { ...@@ -406,11 +419,21 @@ const handlePurchase = async () => {
406 * @param {number} payInfo.remain_time - 剩余时间 419 * @param {number} payInfo.remain_time - 剩余时间
407 * @param {number} payInfo.price - 价格 420 * @param {number} payInfo.price - 价格
408 */ 421 */
409 -const onPay = ({ id, remain_time, price }) => { 422 +const onPay = async ({ id, remain_time, price }) => {
423 + try {
424 + const { code, data } = await createOrderAPI({
425 + vehicle_id: id,
426 + total_amount: price
427 + })
428 + if (code) {
410 show_pay.value = true 429 show_pay.value = true
411 - payData.value.id = id 430 + payData.value.id = data.id
412 payData.value.price = price 431 payData.value.price = price
413 payData.value.remain_time = remain_time 432 payData.value.remain_time = remain_time
433 + }
434 + } catch (error) {
435 + console.error('创建订单失败:', error)
436 + }
414 } 437 }
415 438
416 /** 439 /**
...@@ -471,6 +494,9 @@ function filterEmptyValues(arr) { ...@@ -471,6 +494,9 @@ function filterEmptyValues(arr) {
471 } 494 }
472 495
473 onMounted(async () => { 496 onMounted(async () => {
497 + // 获取用户信息
498 + await userStore.fetchUserInfo()
499 +
474 // 获取商品详情 500 // 获取商品详情
475 let params = getCurrentPageParam(); 501 let params = getCurrentPageParam();
476 const { code, data } = await getVehicleDetailAPI({ id: params.id }) 502 const { code, data } = await getVehicleDetailAPI({ id: params.id })
......