xsh_1997 1 周之前
父節點
當前提交
45ef88f72f

+ 15 - 3
baqing-shop/src/main/resources/mapper/order/BizOrderMapper.xml

@@ -271,7 +271,13 @@
271 271
         <if test="query != null and query.tab != null and query.tab != '' and query.tab != 'ALL'">
272 272
             <choose>
273 273
                 <when test="query.tab == 'PENDING_PAY'">and o.order_status = '0'</when>
274
-                <when test="query.tab == 'PENDING_SHIP'">and o.order_status = '1'</when>
274
+                <when test="query.tab == 'PENDING_SHIP'">
275
+                    and o.order_status = '1'
276
+                    and not exists (
277
+                        select 1 from biz_order_aftersale a
278
+                        where a.order_id = o.order_id and a.aftersale_status = '2'
279
+                    )
280
+                </when>
275 281
                 <when test="query.tab == 'PENDING_RECEIVE'">and o.order_status = '2'</when>
276 282
                 <when test="query.tab == 'COMPLETED'">and o.order_status = '3'</when>
277 283
                 <when test="query.tab == 'CLOSED'">and o.order_status = '4'</when>
@@ -303,8 +309,14 @@
303 309
     </select>
304 310
 
305 311
     <select id="countMemberByStatus" resultType="int">
306
-        select count(1) from biz_order
307
-        where member_id = #{memberId} and order_status = #{orderStatus} and del_flag = '0'
312
+        select count(1) from biz_order o
313
+        where o.member_id = #{memberId} and o.order_status = #{orderStatus} and o.del_flag = '0'
314
+        <if test="orderStatus == '1'">
315
+            and not exists (
316
+                select 1 from biz_order_aftersale a
317
+                where a.order_id = o.order_id and a.aftersale_status = '2'
318
+            )
319
+        </if>
308 320
     </select>
309 321
 
310 322
     <select id="countShopByStatus" resultType="int">

+ 1 - 1
ruoyi-ui/src/views/agri/seller/aftersale/index.vue

@@ -135,7 +135,7 @@
135 135
     <!-- 处理售后弹窗 -->
136 136
     <el-dialog title="处理售后" :visible.sync="finishOpen" width="560px" append-to-body @close="cancelFinish">
137 137
       <el-alert
138
-        title="完结后不可回退,处理结果将同步展示给买家;本操作不自动退款或变更订单状态。"
138
+        title="完结后不可回退,处理结果将同步展示给买家。"
139 139
         type="warning"
140 140
         :closable="false"
141 141
         show-icon

+ 12 - 2
shop-app/subpackage/order/detail.vue

@@ -106,7 +106,11 @@
106 106
 import { ref, computed } from 'vue'
107 107
 import { onLoad, onShow } from '@dcloudio/uni-app'
108 108
 import { getOrderDetail } from '@/api/order'
109
-import { mapOrderDetail, getItemReviewAction } from '@/utils/orderDisplay'
109
+import {
110
+	mapOrderDetail,
111
+	getItemReviewAction,
112
+	resolveOrderAftersaleStatus
113
+} from '@/utils/orderDisplay'
110 114
 import { ensureApiToken } from '@/utils/apiAuth'
111 115
 import { ORDER_ACTION } from '@/constants/order'
112 116
 import { runOrderAction, openPayModal } from '@/utils/orderAction'
@@ -119,6 +123,7 @@ import OrderActionBar from '@/components/order/OrderActionBar.vue'
119 123
 const actionGuard = useActionGuard()
120 124
 
121 125
 const orderId = ref('')
126
+const routeAftersaleStatus = ref('')
122 127
 const detail = ref(null)
123 128
 const pageLoading = ref(true)
124 129
 const pageError = ref('')
@@ -150,7 +155,11 @@ async function loadDetail() {
150 155
 	pageError.value = ''
151 156
 	try {
152 157
 		const res = await getOrderDetail(orderId.value)
153
-		detail.value = mapOrderDetail(res.data)
158
+		let aftersaleStatus = routeAftersaleStatus.value || null
159
+		if (!aftersaleStatus) {
160
+			aftersaleStatus = await resolveOrderAftersaleStatus(orderId.value)
161
+		}
162
+		detail.value = mapOrderDetail(res.data, { aftersaleStatus })
154 163
 		if (!detail.value) {
155 164
 			throw new Error('订单数据异常')
156 165
 		}
@@ -201,6 +210,7 @@ function onAction(code) {
201 210
 
202 211
 onLoad((options) => {
203 212
 	orderId.value = options.orderId || ''
213
+	routeAftersaleStatus.value = options.aftersaleStatus || ''
204 214
 	if (!orderId.value) {
205 215
 		pageError.value = '订单信息缺失'
206 216
 		pageLoading.value = false

+ 1 - 1
shop-app/subpackage/order/list.vue

@@ -194,7 +194,7 @@ function onLoadMore() {
194 194
 }
195 195
 
196 196
 function onCardClick(card) {
197
-	goOrderDetail(card.orderId)
197
+	goOrderDetail(card.orderId, card.aftersaleStatus)
198 198
 }
199 199
 
200 200
 function onItemReview(card, item, code) {

+ 63 - 12
shop-app/utils/orderDisplay.js

@@ -1,13 +1,16 @@
1 1
 import { resolveFileUrl } from '@/utils/image'
2 2
 import { formatPrice } from '@/utils/format'
3 3
 import { parseCartSpecText } from '@/utils/cartSpec'
4
+import { listAftersales } from '@/api/orderAftersale'
4 5
 import {
5 6
   ORDER_ACTION,
6 7
   ORDER_ACTION_LABEL,
7 8
   REVIEW_ITEM_STATUS,
8 9
   AFTERSALE_APPLY_TYPE_OPTIONS,
10
+  AFTERSALE_TAB,
9 11
   ORDER_STATUS,
10
-  ORDER_AFTERSALE_CARD_LABEL
12
+  ORDER_AFTERSALE_CARD_LABEL,
13
+  ORDER_AFTERSALE_CARD_STATUS
11 14
 } from '@/constants/order'
12 15
 
13 16
 /** 订单级不再展示的评价按钮(改在商品行) */
@@ -82,9 +85,20 @@ function mapOrderItemRow(row) {
82 85
   }
83 86
 }
84 87
 
85
-function mapActions(actions) {
88
+/** 订单已有进行中/已完结售后时,不再展示「申请售后」 */
89
+export function hasOrderAftersale(aftersaleStatus) {
90
+  const status = aftersaleStatus != null ? String(aftersaleStatus) : ''
91
+  return (
92
+    status === ORDER_AFTERSALE_CARD_STATUS.IN_PROGRESS ||
93
+    status === ORDER_AFTERSALE_CARD_STATUS.FINISHED
94
+  )
95
+}
96
+
97
+function mapActions(actions, aftersaleStatus) {
98
+  const hideAftersale = hasOrderAftersale(aftersaleStatus)
86 99
   return (actions || [])
87 100
     .filter((code) => !ORDER_LEVEL_REVIEW_CODES.includes(code))
101
+    .filter((code) => !(hideAftersale && code === ORDER_ACTION.AFTERSALE))
88 102
     .map((code) => ({
89 103
       code,
90 104
       label: ORDER_ACTION_LABEL[code] || code
@@ -92,6 +106,34 @@ function mapActions(actions) {
92 106
     .filter((item) => item.label)
93 107
 }
94 108
 
109
+/** 详情页补查订单售后态(列表接口有 aftersaleStatus,详情接口暂无) */
110
+export async function resolveOrderAftersaleStatus(orderId) {
111
+  if (!orderId) return null
112
+  try {
113
+    const inProgressRes = await listAftersales({
114
+      tab: AFTERSALE_TAB.IN_PROGRESS,
115
+      pageNum: 1,
116
+      pageSize: 100
117
+    })
118
+    const inProgressRows = inProgressRes.rows || []
119
+    if (inProgressRows.some((row) => String(row.orderId) === String(orderId))) {
120
+      return ORDER_AFTERSALE_CARD_STATUS.IN_PROGRESS
121
+    }
122
+    const finishedRes = await listAftersales({
123
+      tab: AFTERSALE_TAB.FINISHED,
124
+      pageNum: 1,
125
+      pageSize: 100
126
+    })
127
+    const finishedRows = finishedRes.rows || []
128
+    if (finishedRows.some((row) => String(row.orderId) === String(orderId))) {
129
+      return ORDER_AFTERSALE_CARD_STATUS.FINISHED
130
+    }
131
+  } catch (e) {
132
+    // 查询失败时不阻断详情展示
133
+  }
134
+  return null
135
+}
136
+
95 137
 /** 交易成功商品行:待评价→评价,已评价→查看评价 */
96 138
 export function getItemReviewAction(item) {
97 139
   if (!item || !item.reviewStatus) return null
@@ -154,13 +196,20 @@ function trimText(text, maxLen, emptyFallback = '') {
154 196
 }
155 197
 
156 198
 /**
157
- * 列表卡片状态文案(MO-L4)
158
- * 有 aftersaleStatus 时优先展示售后态,否则用订单主状态文案
199
+ * 列表卡片状态文案(MO-L4 调整
200
+ * 仅「售后处理中」覆盖主状态;售后已完结后订单应变已关闭,列表不再展示「售后已完成」
159 201
  */
160
-export function mapOrderCardStatusText(orderStatusText, aftersaleStatus) {
161
-  if (aftersaleStatus && ORDER_AFTERSALE_CARD_LABEL[aftersaleStatus]) {
202
+export function mapOrderCardStatusText(orderStatusText, aftersaleStatus, orderStatus) {
203
+  if (aftersaleStatus === ORDER_AFTERSALE_CARD_STATUS.IN_PROGRESS) {
162 204
     return ORDER_AFTERSALE_CARD_LABEL[aftersaleStatus]
163 205
   }
206
+  if (aftersaleStatus === ORDER_AFTERSALE_CARD_STATUS.FINISHED) {
207
+    if (orderStatus === ORDER_STATUS.CLOSED) {
208
+      return orderStatusText || '已关闭'
209
+    }
210
+    // 售后已完结但订单主状态未同步(异常数据)时,仍按已关闭展示
211
+    return '已关闭'
212
+  }
164 213
   return orderStatusText || ''
165 214
 }
166 215
 
@@ -182,8 +231,8 @@ export function mapOrderListRow(row) {
182 231
     orderStatus: row.orderStatus,
183 232
     orderStatusText,
184 233
     aftersaleStatus,
185
-    statusText: mapOrderCardStatusText(orderStatusText, aftersaleStatus),
186
-    statusIsAftersale: !!aftersaleStatus,
234
+    statusText: mapOrderCardStatusText(orderStatusText, aftersaleStatus, row.orderStatus),
235
+    statusIsAftersale: aftersaleStatus === ORDER_AFTERSALE_CARD_STATUS.IN_PROGRESS,
187 236
     amountLabel: row.orderStatus === ORDER_STATUS.PENDING_PAY ? '应付' : '实付',
188 237
     shopId: row.shopId,
189 238
     shopName: row.shopName || '',
@@ -198,15 +247,16 @@ export function mapOrderListRow(row) {
198 247
     firstItem,
199 248
     payRemainSeconds: row.payRemainSeconds,
200 249
     reviewStatus: row.reviewStatus,
201
-    actions: mapActions(row.actions)
250
+    actions: mapActions(row.actions, aftersaleStatus)
202 251
   }
203 252
 }
204 253
 
205
-/** 详情 VO → 页面模型 */
206
-export function mapOrderDetail(data) {
254
+/** 详情 VO → 页面模型;options.aftersaleStatus 用于补全售后态并过滤操作按钮 */
255
+export function mapOrderDetail(data, options = {}) {
207 256
   if (!data) return null
208 257
   const items = (data.items || []).map(mapOrderItemRow).filter(Boolean)
209 258
   const latestTrace = data.latestTrace || null
259
+  const aftersaleStatus = data.aftersaleStatus || options.aftersaleStatus || null
210 260
   return {
211 261
     orderId: data.orderId,
212 262
     orderNo: data.orderNo || '',
@@ -253,7 +303,8 @@ export function mapOrderDetail(data) {
253 303
     items,
254 304
     reviewStatus: data.reviewStatus,
255 305
     reviewId: data.reviewId,
256
-    actions: mapActions(data.actions)
306
+    aftersaleStatus,
307
+    actions: mapActions(data.actions, aftersaleStatus)
257 308
   }
258 309
 }
259 310
 

+ 7 - 3
shop-app/utils/orderNav.js

@@ -22,11 +22,15 @@ export function goOrderList(tab = ORDER_TAB.ALL) {
22 22
   })
23 23
 }
24 24
 
25
-/** 订单详情 */
26
-export function goOrderDetail(orderId) {
25
+/** 订单详情(可选带 aftersaleStatus,用于隐藏「申请售后」) */
26
+export function goOrderDetail(orderId, aftersaleStatus) {
27 27
   if (!orderId) return
28
+  const parts = [`orderId=${orderId}`]
29
+  if (aftersaleStatus != null && aftersaleStatus !== '') {
30
+    parts.push(`aftersaleStatus=${aftersaleStatus}`)
31
+  }
28 32
   uni.navigateTo({
29
-    url: `${PAGE_ORDER_DETAIL}?orderId=${orderId}`
33
+    url: `${PAGE_ORDER_DETAIL}?${parts.join('&')}`
30 34
   })
31 35
 }
32 36