Parcourir la Source

会员管理代码

wwh il y a 1 semaine
Parent
commit
80f77de129

+ 32 - 0
baqing-shop/src/main/java/com/ruoyi/web/modules/order/dto/OrderAftersaleStatusRow.java

@@ -0,0 +1,32 @@
1
+package com.ruoyi.web.modules.order.dto;
2
+
3
+/**
4
+ * 订单维度售后状态聚合(列表批量查询)
5
+ */
6
+public class OrderAftersaleStatusRow
7
+{
8
+    private Long orderId;
9
+
10
+    /** 1 进行中 2 已完结(同 biz_order_aftersale.aftersale_status) */
11
+    private String aftersaleStatus;
12
+
13
+    public Long getOrderId()
14
+    {
15
+        return orderId;
16
+    }
17
+
18
+    public void setOrderId(Long orderId)
19
+    {
20
+        this.orderId = orderId;
21
+    }
22
+
23
+    public String getAftersaleStatus()
24
+    {
25
+        return aftersaleStatus;
26
+    }
27
+
28
+    public void setAftersaleStatus(String aftersaleStatus)
29
+    {
30
+        this.aftersaleStatus = aftersaleStatus;
31
+    }
32
+}

+ 3 - 0
baqing-shop/src/main/java/com/ruoyi/web/modules/order/mapper/BizOrderAftersaleMapper.java

@@ -3,6 +3,7 @@ package com.ruoyi.web.modules.order.mapper;
3 3
 import java.util.List;
4 4
 import org.apache.ibatis.annotations.Param;
5 5
 import com.ruoyi.web.modules.order.domain.BizOrderAftersale;
6
+import com.ruoyi.web.modules.order.dto.OrderAftersaleStatusRow;
6 7
 import com.ruoyi.web.modules.order.dto.SellerAftersaleQuery;
7 8
 import com.ruoyi.web.modules.order.vo.SellerAftersaleDetailVO;
8 9
 import com.ruoyi.web.modules.order.vo.SellerAftersaleListRowVO;
@@ -17,6 +18,8 @@ public interface BizOrderAftersaleMapper
17 18
 
18 19
     int countInProgressByOrderItem(@Param("orderItemId") Long orderItemId);
19 20
 
21
+    List<OrderAftersaleStatusRow> selectAftersaleStatusByOrderIds(@Param("orderIds") List<Long> orderIds);
22
+
20 23
     List<BizOrderAftersale> selectMemberList(@Param("memberId") Long memberId, @Param("tab") String tab);
21 24
 
22 25
     List<SellerAftersaleListRowVO> selectSellerList(@Param("shopId") Long shopId,

+ 25 - 0
baqing-shop/src/main/java/com/ruoyi/web/modules/order/service/impl/OrderAppServiceImpl.java

@@ -23,6 +23,7 @@ import com.ruoyi.web.modules.order.domain.BizOrder;
23 23
 import com.ruoyi.web.modules.order.domain.BizOrderItem;
24 24
 import com.ruoyi.web.modules.order.domain.BizOrderLogisticsTrace;
25 25
 import com.ruoyi.web.modules.order.dto.OrderAppListQueryDTO;
26
+import com.ruoyi.web.modules.order.dto.OrderAftersaleStatusRow;
26 27
 import com.ruoyi.web.modules.order.mapper.BizGoodsReviewMapper;
27 28
 import com.ruoyi.web.modules.order.mapper.BizOrderAftersaleMapper;
28 29
 import com.ruoyi.web.modules.order.mapper.BizOrderItemMapper;
@@ -219,6 +220,7 @@ public class OrderAppServiceImpl implements IOrderAppService
219 220
         }
220 221
         List<BizGoodsReview> reviews = reviewMapper.selectByOrderIds(orderIds);
221 222
         Map<Long, String> shopAvatarMap = loadShopAvatars(orders);
223
+        Map<Long, String> aftersaleStatusMap = loadAftersaleStatusMap(orderIds);
222 224
         List<OrderAppListRowVO> rows = new ArrayList<>(orders.size());
223 225
         for (BizOrder order : orders)
224 226
         {
@@ -232,6 +234,7 @@ public class OrderAppServiceImpl implements IOrderAppService
232 234
             row.setOrderNo(order.getOrderNo());
233 235
             row.setOrderStatus(order.getOrderStatus());
234 236
             row.setOrderStatusText(orderAppSupport.toStatusText(order.getOrderStatus()));
237
+            row.setAftersaleStatus(aftersaleStatusMap.get(order.getOrderId()));
235 238
             row.setShopId(order.getShopId());
236 239
             row.setShopName(order.getShopName());
237 240
             row.setShopAvatar(shopAvatarMap.get(order.getShopId()));
@@ -260,6 +263,28 @@ public class OrderAppServiceImpl implements IOrderAppService
260 263
         return rows;
261 264
     }
262 265
 
266
+    private Map<Long, String> loadAftersaleStatusMap(List<Long> orderIds)
267
+    {
268
+        if (orderIds == null || orderIds.isEmpty())
269
+        {
270
+            return Collections.emptyMap();
271
+        }
272
+        List<OrderAftersaleStatusRow> rows = aftersaleMapper.selectAftersaleStatusByOrderIds(orderIds);
273
+        if (rows == null || rows.isEmpty())
274
+        {
275
+            return Collections.emptyMap();
276
+        }
277
+        Map<Long, String> map = new HashMap<>(rows.size());
278
+        for (OrderAftersaleStatusRow row : rows)
279
+        {
280
+            if (row.getOrderId() != null)
281
+            {
282
+                map.put(row.getOrderId(), row.getAftersaleStatus());
283
+            }
284
+        }
285
+        return map;
286
+    }
287
+
263 288
     private Map<Long, String> loadShopAvatars(List<BizOrder> orders)
264 289
     {
265 290
         Map<Long, String> map = new HashMap<>();

+ 1 - 1
baqing-shop/src/main/java/com/ruoyi/web/modules/order/support/OrderAppSupport.java

@@ -60,7 +60,7 @@ public class OrderAppSupport
60 60
         {
61 61
             return "已关闭";
62 62
         }
63
-        return dictLabel(OrderConstants.DICT_ORDER_STATUS, orderStatus);
63
+        return toStatusText(orderStatus);
64 64
     }
65 65
 
66 66
     public String toCloseTypeText(String closeType)

+ 13 - 0
baqing-shop/src/main/java/com/ruoyi/web/modules/order/vo/OrderAppListRowVO.java

@@ -45,6 +45,9 @@ public class OrderAppListRowVO
45 45
 
46 46
     private String reviewStatus;
47 47
 
48
+    /** 售后状态:null 无售后;1 进行中;2 已完结 */
49
+    private String aftersaleStatus;
50
+
48 51
     private List<String> actions = new ArrayList<>();
49 52
 
50 53
     public Long getOrderId()
@@ -207,6 +210,16 @@ public class OrderAppListRowVO
207 210
         this.reviewStatus = reviewStatus;
208 211
     }
209 212
 
213
+    public String getAftersaleStatus()
214
+    {
215
+        return aftersaleStatus;
216
+    }
217
+
218
+    public void setAftersaleStatus(String aftersaleStatus)
219
+    {
220
+        this.aftersaleStatus = aftersaleStatus;
221
+    }
222
+
210 223
     public List<String> getActions()
211 224
     {
212 225
         return actions;

+ 12 - 0
baqing-shop/src/main/resources/mapper/order/BizOrderAftersaleMapper.xml

@@ -60,6 +60,18 @@
60 60
         where order_item_id = #{orderItemId} and aftersale_status = '1'
61 61
     </select>
62 62
 
63
+    <select id="selectAftersaleStatusByOrderIds"
64
+            resultType="com.ruoyi.web.modules.order.dto.OrderAftersaleStatusRow">
65
+        select order_id as orderId,
66
+               if(sum(case when aftersale_status = '1' then 1 else 0 end) &gt; 0, '1', '2') as aftersaleStatus
67
+        from biz_order_aftersale
68
+        where order_id in
69
+        <foreach collection="orderIds" item="orderId" open="(" separator="," close=")">
70
+            #{orderId}
71
+        </foreach>
72
+        group by order_id
73
+    </select>
74
+
63 75
     <select id="selectMemberList" resultMap="BizOrderAftersaleResult">
64 76
         select * from biz_order_aftersale
65 77
         where member_id = #{memberId}

+ 72 - 0
baqing-shop/src/test/java/com/ruoyi/web/modules/order/service/OrderAppServiceImplTest.java

@@ -113,6 +113,8 @@ class OrderAppServiceImplTest
113 113
         when(orderItemMapper.selectByOrderIds(Collections.singletonList(ORDER_ID)))
114 114
                 .thenReturn(java.util.Arrays.asList(item1, item2));
115 115
         when(reviewMapper.selectByOrderIds(Collections.singletonList(ORDER_ID))).thenReturn(Collections.emptyList());
116
+        when(aftersaleMapper.selectAftersaleStatusByOrderIds(Collections.singletonList(ORDER_ID)))
117
+                .thenReturn(Collections.emptyList());
116 118
         when(shopMapper.selectById(10L)).thenReturn(null);
117 119
         when(orderAppSupport.toStatusText(order.getOrderStatus())).thenReturn("待付款");
118 120
         when(orderAppSupport.toItemSummary(item1)).thenReturn(summary(item1));
@@ -133,6 +135,76 @@ class OrderAppServiceImplTest
133 135
         assertEquals(row.getItems().get(0), row.getFirstItem());
134 136
     }
135 137
 
138
+    @Test
139
+    void list_withInProgressAftersale_setsAftersaleStatus()
140
+    {
141
+        when(memberFacade.isMemberEnabled(MEMBER_ID)).thenReturn(true);
142
+        BizOrder order = pendingOrder();
143
+        order.setOrderStatus(OrderConstants.STATUS_PENDING_SHIP);
144
+        order.setShopId(10L);
145
+        when(orderMapper.selectMemberAppList(eq(MEMBER_ID), any())).thenReturn(Collections.singletonList(order));
146
+        when(orderItemMapper.selectByOrderIds(Collections.singletonList(ORDER_ID)))
147
+                .thenReturn(Collections.singletonList(singleItem()));
148
+        when(reviewMapper.selectByOrderIds(Collections.singletonList(ORDER_ID))).thenReturn(Collections.emptyList());
149
+        com.ruoyi.web.modules.order.dto.OrderAftersaleStatusRow statusRow =
150
+                new com.ruoyi.web.modules.order.dto.OrderAftersaleStatusRow();
151
+        statusRow.setOrderId(ORDER_ID);
152
+        statusRow.setAftersaleStatus(OrderAppConstants.AFTERSALE_STATUS_IN_PROGRESS);
153
+        when(aftersaleMapper.selectAftersaleStatusByOrderIds(Collections.singletonList(ORDER_ID)))
154
+                .thenReturn(Collections.singletonList(statusRow));
155
+        when(shopMapper.selectById(10L)).thenReturn(null);
156
+        when(orderAppSupport.toStatusText(order.getOrderStatus())).thenReturn("待发货");
157
+        when(orderAppSupport.toItemSummary(any())).thenReturn(new com.ruoyi.web.modules.order.vo.OrderAppItemSummaryVO());
158
+        when(orderAppSupport.indexReviewsByItemId(any(), any())).thenReturn(Collections.emptyMap());
159
+        when(orderAppSupport.calcPayRemainSeconds(order)).thenReturn(0L);
160
+        when(orderAppSupport.resolveReviewStatus(eq(order), any(), any()))
161
+                .thenReturn(OrderAppConstants.REVIEW_STATUS_NONE);
162
+        when(orderAppSupport.resolveActions(order)).thenReturn(Collections.emptyList());
163
+
164
+        com.ruoyi.web.modules.order.vo.OrderAppListRowVO row =
165
+                orderAppService.list(MEMBER_ID, new com.ruoyi.web.modules.order.dto.OrderAppListQueryDTO()).get(0);
166
+
167
+        assertEquals("待发货", row.getOrderStatusText());
168
+        assertEquals(OrderAppConstants.AFTERSALE_STATUS_IN_PROGRESS, row.getAftersaleStatus());
169
+    }
170
+
171
+    @Test
172
+    void list_withoutAftersale_aftersaleStatusNull()
173
+    {
174
+        when(memberFacade.isMemberEnabled(MEMBER_ID)).thenReturn(true);
175
+        BizOrder order = pendingOrder();
176
+        order.setShopId(10L);
177
+        when(orderMapper.selectMemberAppList(eq(MEMBER_ID), any())).thenReturn(Collections.singletonList(order));
178
+        when(orderItemMapper.selectByOrderIds(Collections.singletonList(ORDER_ID)))
179
+                .thenReturn(Collections.singletonList(singleItem()));
180
+        when(reviewMapper.selectByOrderIds(Collections.singletonList(ORDER_ID))).thenReturn(Collections.emptyList());
181
+        when(aftersaleMapper.selectAftersaleStatusByOrderIds(Collections.singletonList(ORDER_ID)))
182
+                .thenReturn(Collections.emptyList());
183
+        when(shopMapper.selectById(10L)).thenReturn(null);
184
+        when(orderAppSupport.toStatusText(order.getOrderStatus())).thenReturn("待付款");
185
+        when(orderAppSupport.toItemSummary(any())).thenReturn(new com.ruoyi.web.modules.order.vo.OrderAppItemSummaryVO());
186
+        when(orderAppSupport.indexReviewsByItemId(any(), any())).thenReturn(Collections.emptyMap());
187
+        when(orderAppSupport.calcPayRemainSeconds(order)).thenReturn(3600L);
188
+        when(orderAppSupport.resolveReviewStatus(eq(order), any(), any()))
189
+                .thenReturn(OrderAppConstants.REVIEW_STATUS_NONE);
190
+        when(orderAppSupport.resolveActions(order)).thenReturn(Collections.emptyList());
191
+
192
+        com.ruoyi.web.modules.order.vo.OrderAppListRowVO row =
193
+                orderAppService.list(MEMBER_ID, new com.ruoyi.web.modules.order.dto.OrderAppListQueryDTO()).get(0);
194
+
195
+        assertEquals(null, row.getAftersaleStatus());
196
+    }
197
+
198
+    private BizOrderItem singleItem()
199
+    {
200
+        BizOrderItem item = new BizOrderItem();
201
+        item.setItemId(1L);
202
+        item.setOrderId(ORDER_ID);
203
+        item.setGoodsId(101L);
204
+        item.setGoodsName("商品A");
205
+        return item;
206
+    }
207
+
136 208
     private com.ruoyi.web.modules.order.vo.OrderAppItemSummaryVO summary(BizOrderItem item)
137 209
     {
138 210
         com.ruoyi.web.modules.order.vo.OrderAppItemSummaryVO vo =

+ 16 - 4
doc/消费者APP/我的订单/我的订单技术方案.md

@@ -286,7 +286,8 @@ CREATE TABLE IF NOT EXISTS `biz_order_aftersale` (
286 286
 | 字段 | 说明 |
287 287
 |------|------|
288 288
 | orderId / orderNo / orderStatus | |
289
-| orderStatusText | C 端文案:待付款/待发货/待收货/交易成功/已关闭 |
289
+| orderStatusText | **订单主状态**文案:待付款/待发货/待收货/交易成功/已关闭;**不因售后覆盖** |
290
+| aftersaleStatus | **售后状态**:`null` 无售后;`1` 进行中;`2` 已完结;与 `biz_order_aftersale.aftersale_status` 一致(同订单多条售后时:**有进行中则 1**,否则 **2**) |
290 291
 | shopId / shopName / shopAvatar | |
291 292
 | payAmount / goodsAmount / freightAmount | |
292 293
 | createTime | 下单时间;JSON **`yyyy-MM-dd HH:mm:ss`** |
@@ -498,7 +499,7 @@ public static final String REVIEW_TAB_PENDING = "PENDING";
498 499
 public static final String REVIEW_TAB_DONE = "DONE";
499 500
 ```
500 501
 
501
-**C 端状态文案映射:**
502
+**C 端状态文案映射(`orderStatusText`):**
502 503
 
503 504
 | order_status | orderStatusText |
504 505
 |--------------|-----------------|
@@ -508,6 +509,16 @@ public static final String REVIEW_TAB_DONE = "DONE";
508 509
 | 3 | 交易成功 |
509 510
 | 4 | 已关闭 |
510 511
 
512
+**列表卡片售后展示(前端,`aftersaleStatus` → 卡片角标/状态区文案):**
513
+
514
+| aftersaleStatus | 前端展示文案 |
515
+|-----------------|--------------|
516
+| null | 使用 `orderStatusText` |
517
+| 1 | 售后处理中 |
518
+| 2 | 售后已完成 |
519
+
520
+> **实现:** `OrderAppServiceImpl.buildListRows` 批量 `selectAftersaleStatusByOrderIds`;**不修改** `orderStatusText`。映射见《我的订单前端技术方案》`orderDisplay.js` · `mapOrderListRow`。
521
+
511 522
 ---
512 523
 
513 524
 ## 6. 与平台后台联动
@@ -519,7 +530,7 @@ public static final String REVIEW_TAB_DONE = "DONE";
519 530
 | O8 超时关单 | 待付款消失;**已关闭**;续付失败 |
520 531
 | 运营关闭 | **已关闭** + closeTypeText |
521 532
 | 会员禁用 | **403**;历史单只读 **不可操作** |
522
-| 商家完结售后 | 售后列表 **已完结**;展示 processResult |
533
+| 商家完结售后 | 列表 `aftersaleStatus=2`;订单主状态可能为 **已关闭**(`order_status=4`);售后专区 **已完结** |
523 534
 
524 535
 ---
525 536
 
@@ -599,8 +610,9 @@ public static final String REVIEW_TAB_DONE = "DONE";
599 610
 | 版本 | 说明 |
600 611
 |------|------|
601 612
 | **v1.2** | 列表返回 `items[]` 全量;评价改 **一行一评**;行级 `reviewStatus`;底部 actions 不含评价 |
613
+| **v1.3** | 列表新增 `aftersaleStatus`(null/1/2);`orderStatusText` 保持订单主状态;售后展示文案由 **前端** 映射 |
602 614
 | **v1.0** | 首版:列表/详情/角标/确认收货/评价/售后;复用 order 模块与 checkout 已建 pay;新增 aftersale DDL 规划 |
603 615
 
604 616
 ---
605 617
 
606
-*文档版本:v1.2 · 关联《我的订单功能需求.md》v1.1、《确认订单页(多商品)技术方案.md》v1.1、《订单管理技术方案.md》v1.0.2 · DDL:[`sql/biz_order.sql`](../../../sql/biz_order.sql)、[`sql/biz_goods_review.sql`](../../../sql/biz_goods_review.sql)、[`sql/biz_goods_review_order_item_uk.sql`](../../../sql/biz_goods_review_order_item_uk.sql)、`sql/biz_order_aftersale.sql`*
618
+*文档版本:v1.3 · 关联《我的订单功能需求.md》v1.2、《确认订单页(多商品)技术方案.md》v1.1、《订单管理技术方案.md》v1.0.2 · DDL:[`sql/biz_order.sql`](../../../sql/biz_order.sql)、[`sql/biz_goods_review.sql`](../../../sql/biz_goods_review.sql)、[`sql/biz_goods_review_order_item_uk.sql`](../../../sql/biz_goods_review_order_item_uk.sql)、`sql/biz_order_aftersale.sql`*