Просмотр исходного кода

feat(order): 优化确认订单会员折扣及购物车项支持

- ApiOrderRefundDto类调整API注释及格式统一
- BasketServiceImpl中购物车列表获取新增会员支持服务调用
- ConfirmOrderListener中新增会员折扣计算事件监听,应用于甄选商品折扣
- 会员折扣计算逻辑包括折扣率获取与优惠金额分摊
- 保留原会员等级折扣逻辑并对代码进行整理和注释优化
- 优化购物车和订单确认流程中会员相关字段的赋值与使用
Sheep 16 часов назад
Родитель
Сommit
31e98f387b
25 измененных файлов с 1050 добавлено и 789 удалено
  1. 2 0
      yami-shop-api/src/main/java/com/yami/shop/api/controller/MyOrderController.java
  2. 93 57
      yami-shop-api/src/main/java/com/yami/shop/api/controller/OrderController.java
  3. 10 1
      yami-shop-api/src/main/java/com/yami/shop/api/controller/OrderRefundController.java
  4. 87 70
      yami-shop-api/src/main/java/com/yami/shop/api/listener/SubmitOrderListener.java
  5. 17 41
      yami-shop-bean/src/main/java/com/yami/shop/bean/app/dto/ApiOrderRefundDto.java
  6. 34 69
      yami-shop-bean/src/main/java/com/yami/shop/bean/app/dto/OrderShopDto.java
  7. 12 0
      yami-shop-bean/src/main/java/com/yami/shop/bean/app/dto/ProductItemDto.java
  8. 4 15
      yami-shop-bean/src/main/java/com/yami/shop/bean/app/dto/RefundOrderItemDto.java
  9. 34 33
      yami-shop-bean/src/main/java/com/yami/shop/bean/app/dto/ShopCartOrderDto.java
  10. 35 34
      yami-shop-bean/src/main/java/com/yami/shop/bean/app/dto/ShopCartOrderMergerDto.java
  11. 10 62
      yami-shop-bean/src/main/java/com/yami/shop/bean/dto/OrderRefundDto.java
  12. 17 0
      yami-shop-bean/src/main/java/com/yami/shop/bean/dto/XsbMemberDiscountInfo.java
  13. 73 63
      yami-shop-bean/src/main/java/com/yami/shop/bean/model/Order.java
  14. 41 36
      yami-shop-bean/src/main/java/com/yami/shop/bean/model/OrderItem.java
  15. 16 11
      yami-shop-bean/src/main/java/com/yami/shop/bean/order/ConfirmOrderOrder.java
  16. 2 2
      yami-shop-service/pom.xml
  17. 17 0
      yami-shop-service/src/main/java/com/yami/shop/service/XsbMemberSupportService.java
  18. 30 78
      yami-shop-service/src/main/java/com/yami/shop/service/impl/BasketServiceImpl.java
  19. 204 172
      yami-shop-service/src/main/java/com/yami/shop/service/impl/OrderRefundServiceImpl.java
  20. 176 0
      yami-shop-service/src/main/java/com/yami/shop/service/impl/XsbMemberSupportServiceImpl.java
  21. 3 1
      yami-shop-service/src/main/java/com/yami/shop/utils/SmqjhUtil.java
  22. 1 0
      yami-shop-service/src/main/resources/mapper/OrderItemMapper.xml
  23. 8 0
      yami-shop-service/src/main/resources/mapper/OrderMapper.xml
  24. 8 0
      yami-shop-service/src/main/resources/mapper/OrderRefundMapper.xml
  25. 116 44
      yami-shop-user/yami-shop-user-api/src/main/java/com/yami/shop/user/api/listener/ConfirmOrderListener.java

+ 2 - 0
yami-shop-api/src/main/java/com/yami/shop/api/controller/MyOrderController.java

@@ -163,6 +163,8 @@ public class MyOrderController {
         orderShopDto.setDvyType(order.getDvyType());
         orderShopDto.setShopName(shopDetail.getShopName());
         orderShopDto.setActualTotal(order.getActualTotal());
+        orderShopDto.setMemberDiscountAmount(order.getMemberDiscountAmount() == null ? 0.0 : order.getMemberDiscountAmount());
+        orderShopDto.setMemberDiscountDesc(order.getMemberDiscountDesc());
         orderShopDto.setUserAddrDto(userAddrDto);
         orderShopDto.setPayType(order.getPayType());
         orderShopDto.setTransfee(order.getFreightAmount());

+ 93 - 57
yami-shop-api/src/main/java/com/yami/shop/api/controller/OrderController.java

@@ -1,11 +1,11 @@
 /*
- * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
+ * Copyright (c) 2018-2999 楠炲灝绐炴禍姘辫儗娣団剝浼呯粔鎴炲Η閺堝妾洪崗顒€寰?All rights reserved.
  *
  * https://www.gz-yami.com/
  *
- * 未经允许,不可做商业用途!
+ * 閺堫亞绮¢崗浣筋啅閿涘奔绗夐崣顖氫粵閸熷棔绗熼悽銊┾偓鏃撶磼
  *
- * 版权所有,侵权必究!
+ * 閻楀牊娼堥幍鈧張澶涚礉娓氬灚娼堣箛鍛敀閿?
  */
 
 package com.yami.shop.api.controller;
@@ -43,7 +43,7 @@ import java.util.stream.Collectors;
 
 @RestController
 @RequestMapping("/p/order")
-@Api(tags = "订单接口")
+@Api(tags = "Order API")
 public class OrderController {
 
     @Autowired
@@ -75,25 +75,25 @@ public class OrderController {
     private SysConfigService sysConfigService;
 
     /**
-     * 弹窗开关配置key
+     * 瀵湱鐛ュ鈧崗鎶藉帳缂冪敿ey
      */
     private static final String POPUP_SWITCH = "POPUP_SWITCH";
 
     /**
-     * 生成订单
+     * 閻㈢喐鍨氱拋銏犲礋
      */
     @PostMapping("/confirm")
-    @ApiOperation(value = "结算,生成订单信息", notes = "传入下单所需要的参数进行下单")
+    @ApiOperation(value = "Confirm order", notes = "Build order confirmation data from cart items or direct-buy items")
     public ResponseEntity<ShopCartOrderMergerDto> confirm(@Valid @RequestBody OrderParam orderParam) {
-        // 检查弹窗开关,如果开启则暂停下单
+        // 濡偓閺屻儱鑴婄粣妤€绱戦崗绛圭礉婵″倹鐏夊鈧崥顖氬灟閺嗗倸浠犳稉瀣礋
         String popupSwitch = sysConfigService.getValue(POPUP_SWITCH);
         if ("true".equalsIgnoreCase(popupSwitch)) {
-            throw new GlobalException("春节期间暂停下单,感谢您的理解!");
+            throw new GlobalException("Ordering is temporarily unavailable");
         }
 
         if (orderParam.getShopId() == null) {
 //            orderParam.setShopId(1L);
-            throw new GlobalException("请选择店铺!");
+            throw new GlobalException("Shop id is required");
         }
         String userId = SecurityUtils.getUser().getUserId();
 
@@ -103,28 +103,27 @@ public class OrderController {
                 Sku byIdss = skuService.getById(byId);
                 ShopSku shopSku = shopSkuMapper.selectByShopAndSku(byIdss.getSkuId(), orderParam.getShopId());
                 if (shopSku.getShopSkuStocks() == null || shopSku.getShopSkuStocks() == 0) {
-                    throw new GlobalException("当前选择的商品[" + byIdss.getSkuName() + "]库存为空!请重新选择商品!");
+                    throw new GlobalException("Product[" + byIdss.getSkuName() + "] is sold out");
                 }
                 if (shopSku.getShopSkuStocks() < byId.getBasketCount()) {
-                    throw new GlobalException("当前选择的商品[" + byIdss.getSkuName() + "]库存不足!");
+                    throw new GlobalException("Product[" + byIdss.getSkuName() + "] has insufficient stock");
                 }
 
             });
         } else {
             ShopSku shopSku = shopSkuMapper.selectByShopAndSku(orderParam.getOrderItem().getSkuId(), orderParam.getShopId());
             if (shopSku.getShopSkuStocks() == null || shopSku.getShopSkuStocks() == 0) {
-                throw new GlobalException("商品:[" + shopSku.getSkuName() + "]库存为空!请重新选择商品!");
+                throw new GlobalException("Product[" + shopSku.getSkuName() + "] is sold out");
             }
             if (shopSku.getShopSkuStocks() < orderParam.getOrderItem().getProdCount()) {
-                throw new GlobalException("商品:[" + shopSku.getSkuName() + "]库存不足!");
+                throw new GlobalException("Product[" + shopSku.getSkuName() + "] has insufficient stock");
             }
         }
 
-        // 订单的地址信息
         UserAddr userAddr = userAddrService.getUserAddrByUserId(orderParam.getAddrId(), userId);
         validateGuizhouAddress(userAddr);
         UserAddrDto userAddrDto = mapperFacade.map(userAddr, UserAddrDto.class);
-        // 组装获取用户提交的购物车商品项
+        // 缂佸嫯顥婇懢宄板絿閻劍鍩涢幓鎰唉閻ㄥ嫯鍠橀悧鈺勬簠閸熷棗鎼фい?
         OrderItemParam orderItem = orderParam.getOrderItem();
         if (null != orderItem) {
             orderItem.setChannelId(orderParam.getChannelId());
@@ -135,24 +134,24 @@ public class OrderController {
         System.out.println("userId" + userId);
         List<ShopCartItemDto> shopCartItems = basketService.getShopCartItemsByOrderItems(orderParam.getBasketIds(), orderItem, userId, orderParam.getChannelId());
         if (CollectionUtil.isEmpty(shopCartItems)) {
-            throw new GlobalException("请选择您需要的商品加入购物车");
+            throw new GlobalException("No valid cart items were found");
         }
-        // 根据店铺组装购车中的商品信息,返回每个店铺中的购物车商品信息
+        // 閺嶈宓佹惔妤呮懙缂佸嫯顥婄拹顓℃簠娑擃厾娈戦崯鍡楁惂娣団剝浼呴敍宀冪箲閸ョ偞鐦℃稉顏勭暗闁捐桨鑵戦惃鍕枠閻椻晞婧呴崯鍡楁惂娣団剝浼?
         List<ShopCartDto> shopCarts = basketService.getShopCarts(shopCartItems, 0L);
 
         Long point = pointsRecordMapper.statisticsPoint(userId, orderParam.getChannelId());
         double v = 0.0;
-        // 将要返回给前端的完整的订单信息
+        // 鐏忓棜顩︽潻鏂挎礀缂佹瑥澧犵粩顖滄畱鐎瑰本鏆i惃鍕吂閸楁洑淇婇幁?
         ShopCartOrderMergerDto shopCartOrderMergerDto = new ShopCartOrderMergerDto();
         shopCartOrderMergerDto.setUserAddr(userAddrDto);
         shopCartOrderMergerDto.setIsScorePay(orderParam.getIsScorePay());
         if (null != point) {
             v = ((double) point / 100);
-            //总的可用积分
+            //閹崵娈戦崣顖滄暏缁夘垰鍨?
 //        shopCartOrderMergerDto.setTotalAvailableScore(point);
         }
 
-        // 所有店铺的订单信息
+        // 閹碘偓閺堝绨甸柧铏规畱鐠併垹宕熸穱鈩冧紖
         List<ShopCartOrderDto> shopCartOrders = new ArrayList<>();
 
         double actualTotal = 0.0;
@@ -162,18 +161,18 @@ public class OrderController {
         double totalTransfee = 0.0;
         double weight = 0.0;
 
-        // 所有店铺所有的商品item
+        // 閹碘偓閺堝绨甸柧鐑樺閺堝娈戦崯鍡楁惂item
         List<ShopCartItemDto> allCartItem = new ArrayList<>();
 
 //        List<CouponOrderDto> coupons = new ArrayList<>();
         for (ShopCartDto shopCart : shopCarts) {
-            // 每个店铺的订单信息
+            // 濮e繋閲滄惔妤呮懙閻ㄥ嫯顓归崡鏇氫繆閹?
             ShopCartOrderDto shopCartOrder = new ShopCartOrderDto();
             shopCartOrder.setShopId(shopCart.getShopId());
             shopCartOrder.setShopName(shopCart.getShopName());
 
             List<ShopCartItemDiscountDto> shopCartItemDiscounts = shopCart.getShopCartItemDiscounts();
-            // 店铺中的所有商品项信息
+            // 鎼存鎽垫稉顓犳畱閹碘偓閺堝鏅㈤崫渚€銆嶆穱鈩冧紖
             List<ShopCartItemDto> shopAllShopCartItems = new ArrayList<>();
             for (ShopCartItemDiscountDto shopCartItemDiscount : shopCartItemDiscounts) {
                 List<ShopCartItemDto> discountShopCartItems = shopCartItemDiscount.getShopCartItems();
@@ -193,7 +192,7 @@ public class OrderController {
         }
         shopCartOrderMergerDto.setDvyType(orderParam.getDvyType());
 
-        //根据价格进行店铺、满减、商品项的价格升序操作
+        //閺嶈宓佹禒閿嬬壐鏉╂稖顢戞惔妤呮懙閵嗕焦寮ч崙蹇嬧偓浣告櫌閸濅線銆嶉惃鍕幆閺嶇厧宕屾惔蹇旀惙娴?
         for (int n = 0; n < shopCartOrders.size(); n++) {
             shopCartOrders = shopCartOrders.stream().sorted(Comparator.comparing(ShopCartOrderDto::getActualTotal)).collect(Collectors.toList());
             ShopCartOrderDto shopCartOrderDto = shopCartOrders.get(n);
@@ -206,7 +205,7 @@ public class OrderController {
                 double totalAmount = shopCartItemDiscount.getShopCartItems().stream().mapToDouble(ProductItemDto::getActualTotal).sum();
                 shopCartItemDiscount.setTotalAmount(totalAmount);
             }
-            // 如果是折扣特别小的情况下,导致实际金额为0是,改变最小支付金额为0.01元,并且优惠金额减去0.01。
+            // 婵″倹鐏夐弰顖涘閹碉絿澹掗崚顐㈢毈閻ㄥ嫭鍎忛崘鍏哥瑓閿涘苯顕遍懛鏉戠杽闂勫懘鍣炬0婵呰礋0閺勵垽绱濋弨鐟板綁閺堚偓鐏忓繑鏁禒姗€鍣炬0婵呰礋0.01閸?楠炴湹绗栨导妯诲劕闁叉垿顤傞崙蹇撳箵0.01閵?
             if (shopCartOrderDto.getActualTotal() <= 0) {
                 shopCartOrderDto.setActualTotal(0.01);
                 shopCartOrderDto.setShopReduce(Arith.sub(shopCartOrderDto.getShopReduce(), 0.01));
@@ -221,10 +220,10 @@ public class OrderController {
         }
         //v
         shopCartOrderMergerDto.setActualTotal(Arith.sub(actualTotal, v) < 0 ? 0 : Arith.sub(actualTotal, v));
-        shopCartOrderMergerDto.setTotalUsableScore(Arith.sub(actualTotal, v) < 0 ? actualTotal : v);//总共消耗的积分
+        shopCartOrderMergerDto.setTotalUsableScore(Arith.sub(actualTotal, v) < 0 ? actualTotal : v);//閹鍙″☉鍫b偓妤冩畱缁夘垰鍨?
 //        shopCartOrderMergerDto.setTotalAvailableScore(point);
 
-        shopCartOrderMergerDto.setTotalAvailableScore((long) Arith.mul(shopCartOrderMergerDto.getTotalUsableScore(), 100));//总共消耗的积分
+        shopCartOrderMergerDto.setTotalAvailableScore((long) Arith.mul(shopCartOrderMergerDto.getTotalUsableScore(), 100));//閹鍙″☉鍫b偓妤冩畱缁夘垰鍨?
         shopCartOrderMergerDto.setTotal(total);
         shopCartOrderMergerDto.setTotalCount(totalCount);
         shopCartOrderMergerDto.setOrderReduce(allOrderReduce);
@@ -235,19 +234,19 @@ public class OrderController {
 
         applicationContext.publishEvent(new PlatformConfirmOrderEvent(shopCartOrderMergerDto, orderParam, allCartItem));
 
-        // ============  通过订单项的金额,计算出订单总金额  ==============
+        // ============  闁俺绻冪拋銏犲礋妞ゅ湱娈戦柌鎴︻杺閿涘矁顓哥粻妤€鍤拋銏犲礋閹鍣炬0? ==============
 
-        //所有订单实际金额
+        //閹碘偓閺堝顓归崡鏇炵杽闂勫懘鍣炬0?
         actualTotal = 0.00;
-        //所有订单优惠金额
+        //閹碘偓閺堝顓归崡鏇氱喘閹娀鍣炬0?
         allOrderReduce = 0.00;
         totalTransfee = 0.00;
         for (ShopCartOrderDto shopCartOrder : shopCartOrders) {
-            //订单实际金额
+            //鐠併垹宕熺€圭偤妾柌鎴︻杺
             double orderActualTotal = 0.00;
-            //商家优惠金额
+            //閸熷棗顔嶆导妯诲劕闁叉垿顤?
             double orderReduceAmount = 0.00;
-            //商家优惠金额
+            //閸熷棗顔嶆导妯诲劕闁叉垿顤?
             double orderPlatformAmount = 0.00;
 
             for (ShopCartItemDiscountDto shopCartItemDiscount : shopCartOrder.getShopCartItemDiscounts()) {
@@ -262,9 +261,9 @@ public class OrderController {
             }
             shopCartOrder.setActualTotal(Arith.add(orderActualTotal, shopCartOrder.getTransfee()));
 //            shopCartOrder.setActualTotal(100.0);
-            //放入优惠金额
+            //閺€鎯у弳娴兼ɑ鍎柌鎴︻杺
             shopCartOrder.setShopReduce(Arith.add(orderReduceAmount, shopCartOrder.getFreeTransfee()));
-            //放入平台优惠金额,如果用户等级免自营店运费也要放进去
+            //閺€鎯у弳楠炲啿褰存导妯诲劕闁叉垿顤?婵″倹鐏夐悽銊﹀煕缁涘楠囬崗宥堝殰閽€銉ョ暗鏉╂劘鍨傛稊鐔活洣閺€鎹愮箻閸?
             shopCartOrder.setPlatformAmount(Arith.add(orderPlatformAmount, shopCartOrder.getFreeTransfee()));
 
             actualTotal = Arith.add(actualTotal, shopCartOrder.getActualTotal());
@@ -272,36 +271,37 @@ public class OrderController {
             totalTransfee = Arith.add(totalTransfee, shopCartOrder.getTransfee());
         }
         shopCartOrderMergerDto.setActualTotal(Arith.sub(actualTotal, v) < 0 ? 0 : Arith.sub(actualTotal, v));
-        shopCartOrderMergerDto.setTotalUsableScore(Arith.sub(actualTotal, v) < 0 ? actualTotal : v);//总共消耗的积分
+        shopCartOrderMergerDto.setTotalUsableScore(Arith.sub(actualTotal, v) < 0 ? actualTotal : v);//閹鍙″☉鍫b偓妤冩畱缁夘垰鍨?
         shopCartOrderMergerDto.setTotalAvailableScore((long) Arith.mul(shopCartOrderMergerDto.getTotalUsableScore(), 100));
         shopCartOrderMergerDto.setTotalTransfee(totalTransfee);
         shopCartOrderMergerDto.setOrderReduce(allOrderReduce);
 
         applicationContext.publishEvent(new ScoreConfirmOrderEvent(shopCartOrderMergerDto, orderParam, allCartItem));
+        mergeMemberDiscount(shopCartOrderMergerDto);
         orderService.putConfirmOrderCache(userId + orderParam.getUuid(), shopCartOrderMergerDto);
 
         return ResponseEntity.ok(shopCartOrderMergerDto);
     }
 
     /**
-     * 购物车/立即购买  提交订单,根据店铺拆单
+     * 鐠愵厾澧挎潪?缁斿宓嗙拹顓濇嫳  閹绘劒姘︾拋銏犲礋,閺嶈宓佹惔妤呮懙閹峰棗宕?
      */
     @PostMapping("/submit")
-    @ApiOperation(value = "提交订单,返回支付流水号", notes = "根据传入的参数判断是否为购物车提交订单,同时对购物车进行删除,用户开始进行支付")
+    @ApiOperation(value = "Submit order", notes = "Submit the confirmed order and create order numbers")
     public ResponseEntity<OrderNumbersDto> submitOrders(@Valid @RequestBody SubmitOrderParam submitOrderParam) {
-        //扣减积分,先获取当前用户的所以积分,计算扣除之后是否还需要微信支付
+        //閹碉絽鍣虹粔顖氬瀻,閸忓牐骞忛崣鏍х秼閸撳秶鏁ら幋椋庢畱閹碘偓娴犮儳袧閸掑棴绱濈拋锛勭暬閹碉綁娅庢稊瀣倵閺勵垰鎯佹潻姗€娓剁憰浣镐簳娣団剝鏁禒?
         String userId = SecurityUtils.getUser().getUserId();
         ShopCartOrderMergerDto mergerOrder = orderService.getConfirmOrderCache(userId + submitOrderParam.getUuid());
 
         if (mergerOrder == null) {
-            throw new GlobalException("订单已过期,请重新下单");
+            throw new GlobalException("Order confirmation has expired, please confirm again");
         }
-        // 校验商品是否删除
+        // 閺嶏繝鐛欓崯鍡楁惂閺勵垰鎯侀崚鐘绘珟
 
 
         List<OrderShopParam> orderShopParams = submitOrderParam.getOrderShopParam();
         List<ShopCartOrderDto> shopCartOrders = mergerOrder.getShopCartOrders();
-        // 设置备注
+        // 鐠佸墽鐤嗘径鍥ㄦ暈
         if (CollectionUtil.isNotEmpty(orderShopParams)) {
             for (ShopCartOrderDto shopCartOrder : shopCartOrders) {
                 for (OrderShopParam orderShopParam : orderShopParams) {
@@ -321,7 +321,7 @@ public class OrderController {
         orderNumbers.deleteCharAt(orderNumbers.length() - 1);
 
         boolean isShopCartOrder = false;
-        // 移除缓存
+        // 缁夊娅庣紓鎾崇摠
         for (ShopCartOrderDto shopCartOrder : shopCartOrders) {
             for (ShopCartItemDiscountDto shopCartItemDiscount : shopCartOrder.getShopCartItemDiscounts()) {
                 for (ShopCartItemDto shopCartItem : shopCartItemDiscount.getShopCartItems()) {
@@ -334,16 +334,16 @@ public class OrderController {
                 }
             }
         }
-        // 购物车提交订单时(即有购物车ID时)
+        // 鐠愵厾澧挎潪锔藉絹娴溿倛顓归崡鏇熸(閸楄櫕婀佺拹顓犲⒖鏉烆毌D閺?
         if (isShopCartOrder) {
             basketService.removeShopCartItemsCacheByUserId(userId);
         }
         orderService.removeConfirmOrderCache(userId + submitOrderParam.getUuid());
         for (Order order : orders) {
             if (!order.getNextPay()) {
-                //不拆单和已拆单推到海博
+                //娑撳秵濯堕崡鏇炴嫲瀹稿弶濯堕崡鏇熷腹閸掔増鎹i崡?
 //                if (order.getSplitStatus() == 1 || order.getOrderLevel() == 1) {
-                    //推送海博订单
+                    //閹恒劑鈧焦鎹i崡姘愁吂閸?
                     hbOrderService.createOrderAsync(order.getOrderNumber());
 //                }
             }
@@ -353,28 +353,28 @@ public class OrderController {
     }
 
     @GetMapping("/getOrderPayInfoByOrderNumber")
-    @ApiOperation(value = "获取订单支付信息", notes = "获取订单支付的商品/地址信息")
-    @ApiImplicitParam(name = "orderNumbers", value = "订单流水号", required = true, dataType = "String")
+    @ApiOperation(value = "Get order pay info", notes = "Load payment info by order numbers")
+    @ApiImplicitParam(name = "orderNumbers", value = "Comma-separated order numbers", required = true, dataType = "String")
     public ResponseEntity<OrderPayInfoParam> getOrderPayInfoByOrderNumber(@RequestParam("orderNumbers") String orderNumbers) {
         List<String> orderNumberList = Arrays.asList(orderNumbers.split(","));
-        //获取订单信息
+        //閼惧嘲褰囩拋銏犲礋娣団剝浼?
         List<Order> orderList = orderService.getOrderPayInfoByOrderNumber(orderNumberList);
         List<String> prodNameList = Lists.newArrayList();
         Long addrOrderId = null;
         Date endTime = null;
         int totalScore = 0;
         double totalFee = 0.0;
-        //获取商品名集合
+        //閼惧嘲褰囬崯鍡楁惂閸氬秹娉﹂崥?
         for (Order order : orderList) {
             for (OrderItem orderItem : order.getOrderItems()) {
                 prodNameList.add(orderItem.getProdName());
                 totalScore += orderItem.getUseScore() != null ? orderItem.getUseScore() : 0;
             }
-            //第一次循环,获取订单地址id,订单过期时间
+            //缁楊兛绔村▎鈥虫儕閻滎垽绱濋懢宄板絿鐠併垹宕熼崷鏉挎絻id閿涘矁顓归崡鏇$箖閺堢喐妞傞梻?
             if (Objects.isNull(addrOrderId)) {
                 addrOrderId = order.getAddrOrderId();
                 if (Objects.equals(2, order.getOrderType())) {
-                    // 获取秒杀订单的取消订单时间
+                    // 閼惧嘲褰囩粔鎺撴絻鐠併垹宕熼惃鍕絿濞戝牐顓归崡鏇熸闂?
                     Integer maxCancelTime = 0;
                     SubmitSeckillOrderEvent event = new SubmitSeckillOrderEvent(order, maxCancelTime);
                     applicationContext.publishEvent(event);
@@ -389,7 +389,7 @@ public class OrderController {
             }
             totalFee = Arith.add(totalFee, order.getActualTotal());
         }
-        //写入商品名、收货地址/电话
+        //閸愭瑥鍙嗛崯鍡楁惂閸氬秲鈧焦鏁圭拹褍婀撮崸鈧?閻絻鐦?
         UserAddrOrder userAddrOrder = userAddrOrderService.getById(addrOrderId);
         String addr = userAddrOrder.getProvince() + userAddrOrder.getCity() + userAddrOrder.getArea() + userAddrOrder.getAddr();
         OrderPayInfoParam orderPayInfoParam = new OrderPayInfoParam();
@@ -403,9 +403,45 @@ public class OrderController {
         return ResponseEntity.ok(orderPayInfoParam);
     }
 
+
+    private void mergeMemberDiscount(ShopCartOrderMergerDto shopCartOrderMergerDto) {
+        if (shopCartOrderMergerDto == null) {
+            return;
+        }
+        if (CollectionUtil.isEmpty(shopCartOrderMergerDto.getShopCartOrders())) {
+            shopCartOrderMergerDto.setMemberDiscountAmount(0.0);
+            shopCartOrderMergerDto.setMemberDiscountDesc(null);
+            shopCartOrderMergerDto.setMemberBenefitDesc(null);
+            shopCartOrderMergerDto.setMemberDiscountRate(null);
+            return;
+        }
+        double memberDiscountAmount = 0.0;
+        String memberDiscountDesc = null;
+        String memberBenefitDesc = null;
+        Double memberDiscountRate = null;
+        for (ShopCartOrderDto shopCartOrder : shopCartOrderMergerDto.getShopCartOrders()) {
+            Double orderMemberDiscount = shopCartOrder.getMemberDiscountAmount();
+            if (orderMemberDiscount != null && orderMemberDiscount > 0) {
+                memberDiscountAmount = Arith.add(memberDiscountAmount, orderMemberDiscount);
+                if (memberDiscountDesc == null) {
+                    memberDiscountDesc = shopCartOrder.getMemberDiscountDesc();
+                }
+                if (memberBenefitDesc == null) {
+                    memberBenefitDesc = shopCartOrder.getMemberBenefitDesc();
+                }
+                if (memberDiscountRate == null) {
+                    memberDiscountRate = shopCartOrder.getMemberDiscountRate();
+                }
+            }
+        }
+        shopCartOrderMergerDto.setMemberDiscountAmount(memberDiscountAmount);
+        shopCartOrderMergerDto.setMemberDiscountDesc(memberDiscountAmount > 0 ? memberDiscountDesc : null);
+        shopCartOrderMergerDto.setMemberBenefitDesc(memberDiscountAmount > 0 ? memberBenefitDesc : null);
+        shopCartOrderMergerDto.setMemberDiscountRate(memberDiscountAmount > 0 ? memberDiscountRate : null);
+    }
     private void validateGuizhouAddress(UserAddr userAddr) {
         if (userAddr == null) {
-            throw new GlobalException("请选择收货地址");
+            throw new GlobalException("Shipping address is required");
         }
         String fullAddress = safeString(userAddr.getProvince())
                 + safeString(userAddr.getCity())
@@ -415,12 +451,12 @@ public class OrderController {
                 + safeString(userAddr.getAddressName())
                 + safeString(userAddr.getAddrDetail());
         if (!containsGuizhou(userAddr.getProvince()) && !containsGuizhou(fullAddress)) {
-            throw new GlobalException("仅支持贵州省收货地址下单");
+            throw new GlobalException("Only Guizhou addresses are supported");
         }
     }
 
     private boolean containsGuizhou(String text) {
-        return text != null && text.contains("贵州");
+        return text != null && text.contains("??");
     }
 
     private String safeString(String text) {

+ 10 - 1
yami-shop-api/src/main/java/com/yami/shop/api/controller/OrderRefundController.java

@@ -674,6 +674,9 @@ public class OrderRefundController {
             throw new GlobalException("查看失败 该退款订单不存在");
         }
         ApiOrderRefundDto apiOrderRefundDto = mapperFacade.map(orderRefundDto, ApiOrderRefundDto.class);
+        if (apiOrderRefundDto.getMemberDiscountAmount() == null) {
+            apiOrderRefundDto.setMemberDiscountAmount(0.0);
+        }
         return ResponseEntity.ok(apiOrderRefundDto);
     }
 
@@ -699,7 +702,13 @@ public class OrderRefundController {
 
         // 克隆对象
         @SuppressWarnings("unchecked") IPage<ApiOrderRefundDto> apiPageList = mapperFacade.map(pageList, IPage.class);
-        apiPageList.setRecords(mapperFacade.mapAsList(pageList.getRecords(), ApiOrderRefundDto.class));
+        List<ApiOrderRefundDto> records = mapperFacade.mapAsList(pageList.getRecords(), ApiOrderRefundDto.class);
+        records.forEach(item -> {
+            if (item.getMemberDiscountAmount() == null) {
+                item.setMemberDiscountAmount(0.0);
+            }
+        });
+        apiPageList.setRecords(records);
         return ResponseEntity.ok(apiPageList);
     }
 

+ 87 - 70
yami-shop-api/src/main/java/com/yami/shop/api/listener/SubmitOrderListener.java

@@ -1,11 +1,11 @@
 /*
- * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
+ * Copyright (c) 2018-2999 骞垮窞浜氱背淇℃伅绉戞妧鏈夐檺鍏徃 All rights reserved.
  *
  * https://www.gz-yami.com/
  *
- * 未经允许,不可做商业用途!
+ * 鏈粡鍏佽锛屼笉鍙仛鍟嗕笟鐢ㄩ€旓紒
  *
- * 版权所有,侵权必究!
+ * 鐗堟潈鎵€鏈夛紝渚垫潈蹇呯┒锛?
  */
 
 package com.yami.shop.api.listener;
@@ -45,7 +45,7 @@ import java.util.*;
 import java.util.stream.Collectors;
 
 /**
- * 确认订单信息时的默认操作
+ * 纭璁㈠崟淇℃伅鏃剁殑榛樿鎿嶄綔
  *
  * @author LGH
  */
@@ -53,6 +53,8 @@ import java.util.stream.Collectors;
 @AllArgsConstructor
 public class SubmitOrderListener {
 
+    private static final String XSB = "XSB";
+
     private final MapperFacade mapperFacade;
 
     private final UserAddrOrderService userAddrOrderService;
@@ -70,7 +72,7 @@ public class SubmitOrderListener {
     private final BasketMapper basketMapper;
 
     /**
-     * 计算订单金额
+     * 璁$畻璁㈠崟閲戦
      */
     @EventListener(SubmitOrderEvent.class)
     @Order(SubmitOrderOrder.DEFAULT)
@@ -81,24 +83,24 @@ public class SubmitOrderListener {
 
         ShopCartOrderMergerDto mergerOrder = event.getMergerOrder();
 
-        // 订单商品参数
+        // 璁㈠崟鍟嗗搧鍙傛暟
         List<ShopCartOrderDto> shopCartOrders = mergerOrder.getShopCartOrders();
 
         List<Long> basketIds = new ArrayList<>();
-        // 商品skuid为key 需要更新的sku为value的map
+        // 鍟嗗搧skuid涓簁ey 闇€瑕佹洿鏂扮殑sku涓簐alue鐨刴ap
         Map<Long, Sku> skuStocksMap = new HashMap<>(16);
-        // 商品productid为key 需要更新的product为value的map
+        // 鍟嗗搧productid涓簁ey 闇€瑕佹洿鏂扮殑product涓簐alue鐨刴ap
         Map<Long, Product> prodStocksMap = new HashMap<>(16);
 
-        // 把订单地址保存到数据库
+        // 鎶婅鍗曞湴鍧€淇濆瓨鍒版暟鎹簱
         UserAddrOrder userAddrOrder = mapperFacade.map(mergerOrder.getUserAddr(), UserAddrOrder.class);
         if (userAddrOrder == null) {
-            throw new GlobalException("请填写收货地址");
+            throw new GlobalException("璇峰~鍐欐敹璐у湴鍧€");
         }
         userAddrOrder.setUserId(userId);
         userAddrOrder.setCreateTime(now);
         userAddrOrderService.save(userAddrOrder);
-        //所有当前用户可用的积分记录
+        //鎵€鏈夊綋鍓嶇敤鎴峰彲鐢ㄧ殑绉垎璁板綍
         List<PointsRecord> pointsRecords = pointsRecordMapper.selectList(new LambdaQueryWrapper<PointsRecord>()
                         .eq(PointsRecord::getUserId, userId)
                         .eq(PointsRecord::getChannelId, mergerOrder.getChannelId())
@@ -114,32 +116,32 @@ public class SubmitOrderListener {
                         .thenComparing(PointsRecord::getId))
                 .collect(Collectors.toList());
         ;
-        // 将记录添加到队列中
+        // 灏嗚褰曟坊鍔犲埌闃熷垪涓?
         ArrayDeque<PointsRecord> expiryQueue = new ArrayDeque<>(pointsRecords);
-        // 订单地址id
+        // 璁㈠崟鍦板潃id
         Long addrOrderId = userAddrOrder.getAddrOrderId();
 
         if (CollectionUtils.isNotEmpty(shopCartOrders)) {
-            // 每个店铺生成一个订单
+            // 姣忎釜搴楅摵鐢熸垚涓€涓鍗?
             for (ShopCartOrderDto shopCartOrderDto : shopCartOrders) {
-                //兑换人民币是分,必须要实时统计计算
+                //鍏戞崲浜烘皯甯佹槸鍒?蹇呴』瑕佸疄鏃剁粺璁¤绠?
                 Long point = pointsRecordMapper.statisticsPoint(userId, mergerOrder.getChannelId());
-                // 使用雪花算法生成的订单号
+                // 浣跨敤闆姳绠楁硶鐢熸垚鐨勮鍗曞彿
                 String orderNumber = "FD" + snowflake.nextId();
                 shopCartOrderDto.setOrderNumber(orderNumber);
 
                 Long shopId = shopCartOrderDto.getShopId();
-                // 订单信息
+                // 璁㈠崟淇℃伅
                 com.yami.shop.bean.model.Order order = new com.yami.shop.bean.model.Order();
                 order.setIsPayed(0);
                 order.setHbOrderStatus(OrderStatus.UNPAY.value());
                 order.setOrderType(OrderType.ORDINARY.value());
-                //这个运费是已经算过的了
+                //杩欎釜杩愯垂鏄凡缁忕畻杩囩殑浜?
                 double actualTotal = shopCartOrderDto.getActualTotal();
-                //企业用户才进这个判断,并且该用户的积分必须大于0
+                //浼佷笟鐢ㄦ埛鎵嶈繘杩欎釜鍒ゆ柇,骞朵笖璇ョ敤鎴风殑绉垎蹇呴』澶т簬0
                 if (null != point && point > 0) {
                     order.setOrderType(OrderType.SCORE.value());
-                    // 计算商品金额和积分
+                    // 璁$畻鍟嗗搧閲戦鍜岀Н鍒?
                     Double mul = Arith.mul(actualTotal, 100);
                     Double vp = Double.valueOf(point);
                     if (vp >= mul) {
@@ -147,14 +149,14 @@ public class SubmitOrderListener {
                         order.setIsPayed(1);
                         order.setPayTime(new Date());
                         order.setHbOrderStatus(OrderStatus.CONSIGNMENT.value());
-                        //积分完全足够支付
+                        //绉垎瀹屽叏瓒冲鏀粯
                         order.setOffsetPoints(Long.valueOf(String.valueOf(mul).split("\\.")[0]));
-                        actualTotal = 0.0;//剩下需要付的钱
+                        actualTotal = 0.0;//鍓╀笅闇€瑕佷粯鐨勯挶
                     } else {
-                        //积分不够抵扣
+                        //绉垎涓嶅鎶垫墸
                         double sub = Arith.sub(mul, vp);
                         order.setOffsetPoints(point);
-                        //剩下需要付的钱
+                        //鍓╀笅闇€瑕佷粯鐨勯挶
                         actualTotal = sub / 100;
                         mergerOrder.setNextPay(Boolean.TRUE);
                     }
@@ -162,7 +164,8 @@ public class SubmitOrderListener {
                     mergerOrder.setNextPay(Boolean.TRUE);
                 }
                 double sumItemA = 0.0;
-                // 订单商品名称
+                boolean hasXsbMemberDiscount = false;
+                // 璁㈠崟鍟嗗搧鍚嶇О
                 StringBuilder orderProdName = new StringBuilder(100);
                 List<OrderItem> orderItems = new ArrayList<>();
                 List<ShopCartItemDiscountDto> shopCartItemDiscounts = shopCartOrderDto.getShopCartItemDiscounts();
@@ -187,36 +190,43 @@ public class SubmitOrderListener {
                         orderItem.setRecTime(now);
                         orderItem.setCommSts(0);
                         orderItem.setBasketDate(shopCartItem.getBasketDate());
-                        //平台的补贴优惠金额
+                        //骞冲彴鐨勮ˉ璐翠紭鎯犻噾棰?
                         orderItem.setPlatformShareReduce(shopCartItem.getPlatformShareReduce());
+                        if (XSB.equalsIgnoreCase(shopCartItem.getBusinessType())) {
+                            Double memberDiscountShareAmount = shopCartItem.getMemberDiscountShareAmount();
+                            orderItem.setMemberDiscountShareAmount(memberDiscountShareAmount == null ? 0.0 : memberDiscountShareAmount);
+                            hasXsbMemberDiscount = hasXsbMemberDiscount || (memberDiscountShareAmount != null && memberDiscountShareAmount > 0);
+                        } else {
+                            orderItem.setMemberDiscountShareAmount(0.0);
+                        }
                         Double actualItem = shopCartItem.getActualTotal();
-                        //后台充值的积分
+                        //鍚庡彴鍏呭€肩殑绉垎
                         if (null != point && point > 0) {
                             Double useActualItem = actualItem;
-                            if (!isUseTransfee) {//每个订单增加运费,都只扣一次
+                            if (!isUseTransfee) {//姣忎釜璁㈠崟澧炲姞杩愯垂锛岄兘鍙墸涓€娆?
                                 Double transfee = shopCartOrderDto.getTransfee();
                                 useActualItem = Arith.add(useActualItem, transfee);
                                 isUseTransfee = Boolean.TRUE;
                             }
-                            //把钱换算成积分
+                            //鎶婇挶鎹㈢畻鎴愮Н鍒?
                             actualItem = this.doGetOrderItemPoints(Arith.mul(useActualItem, 100), expiryQueue, orderNumber, userId, mergerOrder.getChannelId());
-                            //把积分换算成钱
+                            //鎶婄Н鍒嗘崲绠楁垚閽?
                             if (actualItem > 0) {
                                 actualItem = Arith.div(actualItem, 100);
                             }
                         }
-                        //用于判定是否需要微信支付
+                        //鐢ㄤ簬鍒ゅ畾鏄惁闇€瑕佸井淇℃敮浠?
                         sumItemA = Arith.add(sumItemA, actualItem);
-                        // 实际订单项支付金额
-                        // 根据platform来计算是否优先扣减积分抵扣
+                        // 瀹為檯璁㈠崟椤规敮浠橀噾棰?
+                        // 鏍规嵁platform鏉ヨ绠楁槸鍚︿紭鍏堟墸鍑忕Н鍒嗘姷鎵?
                         orderItem.setActualTotal(actualItem);
-                        // 分摊优惠金额
+                        // 鍒嗘憡浼樻儬閲戦
                         orderItem.setShareReduce(shopCartItem.getShareReduce());
                         orderProdName.append(orderItem.getProdName()).append(",");
-                        //推广员卡号
+                        //鎺ㄥ箍鍛樺崱鍙?
                         orderItem.setDistributionCardNo(shopCartItem.getDistributionCardNo());
                         orderItem.setWeight( shopCartItem.getWeight());
-                        //使用积分价格
+                        //浣跨敤绉垎浠锋牸
                         orderItem.setUseScore((int) Arith.mul(Arith.sub(shopCartItem.getActualTotal(), actualItem), 100));
                         orderItems.add(orderItem);
 
@@ -234,15 +244,15 @@ public class SubmitOrderListener {
 
                 order.setShopId(shopId);
                 order.setOrderNumber(orderNumber);
-                // 订单商品名称
+                // 璁㈠崟鍟嗗搧鍚嶇О
                 order.setProdName(orderProdName.toString());
-                // 用户id
+                // 鐢ㄦ埛id
                 order.setUserId(userId);
-                // 商品总额
+                // 鍟嗗搧鎬婚
                 order.setTotal(shopCartOrderDto.getTotal());
-                // 实际总额
+                // 瀹為檯鎬婚
                 order.setActualTotal(actualTotal);
-                order.setNextPay(sumItemA > 0);//true是需要微信支付
+                order.setNextPay(sumItemA > 0);//true鏄渶瑕佸井淇℃敮浠?
                 order.setChannelId(Long.valueOf(mergerOrder.getChannelId()));
                 order.setUpdateTime(now);
                 order.setCreateTime(now);
@@ -251,6 +261,13 @@ public class SubmitOrderListener {
                 order.setAddrOrderId(addrOrderId);
                 order.setDvyType(mergerOrder.getDvyType());
                 order.setReduceAmount(shopCartOrderDto.getShopReduce());
+                if (hasXsbMemberDiscount) {
+                    order.setMemberDiscountAmount(shopCartOrderDto.getMemberDiscountAmount());
+                    order.setMemberDiscountDesc(shopCartOrderDto.getMemberDiscountDesc());
+                } else {
+                    order.setMemberDiscountAmount(0.0);
+                    order.setMemberDiscountDesc(null);
+                }
                 order.setFreightAmount(shopCartOrderDto.getTransfee());
                 order.setRemarks(shopCartOrderDto.getRemarks());
 
@@ -259,7 +276,7 @@ public class SubmitOrderListener {
                 order.setScore(shopCartOrderDto.getUseScore());
                 order.setDvyType(mergerOrder.getDvyType());
                 event.getOrders().add(order);
-                // 插入订单结算表
+                // 鎻掑叆璁㈠崟缁撶畻琛?
                 OrderSettlement orderSettlement = new OrderSettlement();
                 orderSettlement.setUserId(userId);
                 orderSettlement.setIsClearing(0);
@@ -269,7 +286,7 @@ public class SubmitOrderListener {
                 orderSettlement.setPayStatus(0);
                 orderSettlement.setVersion(0);
                 orderSettlement.setPayScore(0);
-                //如果用使用积分,结算表将积分价格插入
+                //濡傛灉鐢ㄤ娇鐢ㄧН鍒嗭紝缁撶畻琛ㄥ皢绉垎浠锋牸鎻掑叆
                 if (mergerOrder.getIsScorePay() != null && mergerOrder.getIsScorePay() == 1) {
                     orderSettlement.setPayScore(shopCartOrderDto.getUseScore());
                 }
@@ -277,7 +294,7 @@ public class SubmitOrderListener {
             }
         }
 
-        // 删除购物车的商品信息
+        // 鍒犻櫎璐墿杞︾殑鍟嗗搧淇℃伅
         if (!basketIds.isEmpty()) {
             basketMapper.deleteShopCartItemsByBasketIds(userId, basketIds);
         }
@@ -287,14 +304,14 @@ public class SubmitOrderListener {
     private Product checkAndGetProd(Long prodId, ShopCartItemDto shopCartItem, Map<Long, Product> prodStocksMap,Long shopId) {
         Product product = productService.getProductByProdIdAndShopId(prodId, shopId);
         if (product == null) {
-            throw new GlobalException("购物车包含无法识别的商品");
+            throw new GlobalException("璐墿杞﹀寘鍚棤娉曡瘑鍒殑鍟嗗搧");
         }
 
         if (product.getStatus() != 1) {
-            throw new GlobalException("商品[" + product.getProdName() + "]已下架");
+            throw new GlobalException("Product[" + product.getProdName() + "] is unavailable");
         }
 
-        // 商品需要改变的库存
+        // 鍟嗗搧闇€瑕佹敼鍙樼殑搴撳瓨
         Product mapProduct = prodStocksMap.get(prodId);
 
         if (mapProduct == null) {
@@ -310,9 +327,9 @@ public class SubmitOrderListener {
             prodStocksMap.put(product.getProdId(), mapProduct);
         }
 
-        // -1为无限库存
+        // -1涓烘棤闄愬簱瀛?
         if (product.getTotalStocks() != -1 && mapProduct.getTotalStocks() > product.getTotalStocks()) {
-            throw new GlobalException("商品:[" + product.getProdName() + "]库存不足5");
+            throw new GlobalException("鍟嗗搧锛歔" + product.getProdName() + "]搴撳瓨涓嶈冻5");
         }
 
         return product;
@@ -320,24 +337,24 @@ public class SubmitOrderListener {
 
     @SuppressWarnings({"Duplicates"})
     private Sku checkAndGetSku(Long skuId, ShopCartItemDto shopCartItem, Map<Long, Sku> skuStocksMap) {
-        // 获取sku信息
+        // 鑾峰彇sku淇℃伅
         Sku sku = skuService.getSkuBySkuId(skuId);
         if (sku == null) {
-            throw new GlobalException("购物车包含无法识别的商品");
+            throw new GlobalException("璐墿杞﹀寘鍚棤娉曡瘑鍒殑鍟嗗搧");
         }
 
         if (sku.getStatus() != 1) {
-            throw new GlobalException("商品[" + sku.getProdName() + "]已下架");
+            throw new GlobalException("Product[" + sku.getProdName() + "] is unavailable");
         }
-        // -1为无限库存
+        // -1涓烘棤闄愬簱瀛?
         if (sku.getActualStocks() != -1 && shopCartItem.getProdCount() > sku.getActualStocks()) {
-            throw new GlobalException("商品:[" + sku.getProdName() + "]库存不足6");
+            throw new GlobalException("鍟嗗搧锛歔" + sku.getProdName() + "]搴撳瓨涓嶈冻6");
         }
 
         if (sku.getActualStocks() != -1) {
             Sku mapSku = new Sku();
             mapSku.setProdId(sku.getProdId());
-            // 这里的库存是改变的库存
+            // 杩欓噷鐨勫簱瀛樻槸鏀瑰彉鐨勫簱瀛?
             mapSku.setStocks(shopCartItem.getProdCount());
             mapSku.setSkuId(sku.getSkuId());
             mapSku.setProdName(sku.getProdName());
@@ -348,24 +365,24 @@ public class SubmitOrderListener {
 
     @SuppressWarnings({"Duplicates"})
     private Sku checkAndGetSku(Long skuId, Long channelId, ShopCartItemDto shopCartItem, Map<Long, Sku> skuStocksMap) {
-        // 获取sku信息
+        // 鑾峰彇sku淇℃伅
         Sku sku = skuService.getSkuBySkuId(skuId, channelId, shopCartItem.getShopId());
         if (sku == null) {
-            throw new GlobalException("购物车包含无法识别的商品");
+            throw new GlobalException("璐墿杞﹀寘鍚棤娉曡瘑鍒殑鍟嗗搧");
         }
 
         if (sku.getStatus() != 1) {
-            throw new GlobalException("商品[" + sku.getProdName() + "]已下架");
+            throw new GlobalException("Product[" + sku.getProdName() + "] is unavailable");
         }
-        // -1为无限库存
+        // -1涓烘棤闄愬簱瀛?
         if (sku.getActualStocks() != -1 && shopCartItem.getProdCount() > sku.getActualStocks()) {
-            throw new GlobalException("商品:[" + sku.getProdName() + "]库存不足7");
+            throw new GlobalException("鍟嗗搧锛歔" + sku.getProdName() + "]搴撳瓨涓嶈冻7");
         }
 
         if (sku.getActualStocks() != -1) {
             Sku mapSku = new Sku();
             mapSku.setProdId(sku.getProdId());
-            // 这里的库存是改变的库存
+            // 杩欓噷鐨勫簱瀛樻槸鏀瑰彉鐨勫簱瀛?
             mapSku.setStocks(shopCartItem.getProdCount());
             mapSku.setSkuId(sku.getSkuId());
             mapSku.setProdName(sku.getProdName());
@@ -380,30 +397,30 @@ public class SubmitOrderListener {
         PointsRecord pr = new PointsRecord();
         if (pointsRecord != null) {
             Long point = pointsRecordMapper.statisticsPoint(userId, channelId);
-            //判定可用金额
+            //鍒ゅ畾鍙敤閲戦
             BigDecimal points = pointsRecord.getPoints() != null ? pointsRecord.getPoints() : BigDecimal.ZERO;
             BigDecimal variablePoints = pointsRecord.getVariablePoints() != null ? pointsRecord.getVariablePoints() : BigDecimal.ZERO;
-            //充值记录中可用的记录
+            //鍏呭€艰褰曚腑鍙敤鐨勮褰?
             double available = points.subtract(variablePoints).doubleValue();
             BeanUtil.copyProperties(pointsRecord, pr);
             if (available > actualTotal) {
-                //钱已经抵扣完,但是当条积分还有剩余,所以不要重新把剩余的放入队列。钱少积分多
-                //剩余的积分
+                //閽卞凡缁忔姷鎵e畬锛屼絾鏄綋鏉$Н鍒嗚繕鏈夊墿浣欙紝鎵€浠ヤ笉瑕侀噸鏂版妸鍓╀綑鐨勬斁鍏ラ槦鍒椼€傞挶灏戠Н鍒嗗
+                //鍓╀綑鐨勭Н鍒?
                 pointsRecord.setVariablePoints(variablePoints.add(BigDecimal.valueOf(actualTotal)));
                 pr.setVariablePoints(BigDecimal.valueOf(actualTotal));
                 expiryQueue.addFirst(pointsRecord);
-                pointsRecord.setPointsAudit(2);//部分使用
-                pr.setPointsAudit(2);//部分使用
+                pointsRecord.setPointsAudit(2);//閮ㄥ垎浣跨敤
+                pr.setPointsAudit(2);//閮ㄥ垎浣跨敤
                 actualTotal = 0.0;
             } else if (actualTotal > available) {
                 actualTotal = Arith.sub(actualTotal, available);
-                //把当前积分已扣完,但是还有钱。钱多积分少
+                //鎶婂綋鍓嶇Н鍒嗗凡鎵e畬,浣嗘槸杩樻湁閽便€傞挶澶氱Н鍒嗗皯
                 pointsRecord.setVariablePoints(BigDecimal.valueOf(available));
                 pr.setVariablePoints(BigDecimal.valueOf(available));
                 pr.setPointsAudit(3);
                 pointsRecord.setPointsAudit(3);
             } else {
-                //恰好等于
+                //鎭板ソ绛変簬
                 pr.setPointsAudit(3);
                 pointsRecord.setPointsAudit(3);
                 pointsRecord.setVariablePoints(variablePoints.add(BigDecimal.valueOf(actualTotal)));
@@ -419,7 +436,7 @@ public class SubmitOrderListener {
                 pr.setCreationDate(new Date());
                 pointsRecordMapper.insert(pr);
             }
-            //  插入数据库
+            //  鎻掑叆鏁版嵁搴?
             if (actualTotal > 0.0) {
                 actualTotal = this.doGetOrderItemPoints(actualTotal, expiryQueue, orderNumber, userId, channelId);
             }

+ 17 - 41
yami-shop-bean/src/main/java/com/yami/shop/bean/app/dto/ApiOrderRefundDto.java

@@ -31,10 +31,10 @@ public class ApiOrderRefundDto {
     @ApiModelProperty("退款编号")
     private String refundSn;
 
-    @ApiModelProperty("第三方退款单号(微信/支付宝退款单号)")
+    @ApiModelProperty("第三方退款单号")
     private String orderPayNo;
 
-    @ApiModelProperty("订单支付方式(1 微信支付 2 支付宝)")
+    @ApiModelProperty("订单支付方式")
     private Integer payType;
 
     @ApiModelProperty("订单支付名称")
@@ -44,15 +44,15 @@ public class ApiOrderRefundDto {
     private Integer goodsNum;
 
     @ApiModelProperty("退款金额")
-    private Double refundAmount=0.0;
+    private Double refundAmount = 0.0;
 
     @ApiModelProperty("退还积分")
     private Integer refundScore;
 
-    @ApiModelProperty("申请类型:1,仅退款,2退款退货")
+    @ApiModelProperty("申请类型")
     private Integer applyType;
 
-    @ApiModelProperty("处理退款状态:(1.买家申请 2.卖家接受 3.买家发货 4.卖家收货 5.退款成功 6.买家撤回申请 7.商家拒绝 -1.退款关闭)")
+    @ApiModelProperty("处理退款状态")
     private Integer returnMoneySts;
 
     @ApiModelProperty("申请时间")
@@ -73,7 +73,7 @@ public class ApiOrderRefundDto {
     @ApiModelProperty("用户退货发货时间")
     private Date shipTime;
 
-    @ApiModelProperty("卖家收到用户退的货物时间")
+    @ApiModelProperty("卖家收货时间")
     private Date receiveTime;
 
     @ApiModelProperty("撤销时间")
@@ -109,15 +109,12 @@ public class ApiOrderRefundDto {
     @ApiModelProperty("店铺名称")
     private String shopName;
 
-    @ApiModelProperty("true:可以取消退款  false:不可以取消退款")
+    @ApiModelProperty("是否可以取消退款")
     private Boolean isCancel;
 
-    /**
-     * 是否填写了退货物流信息(1:已填写,0:未填写)
-     */
+    @ApiModelProperty("是否已填写退货物流信息")
     private Boolean isReturnLogistics;
 
-
     @ApiModelProperty("卖家备注")
     private String sellerMsg;
 
@@ -125,41 +122,20 @@ public class ApiOrderRefundDto {
     private Double freightAmount;
 
     @ApiModelProperty("积分")
-    private Long offsetPoints=0L;
+    private Long offsetPoints = 0L;
 
     @ApiModelProperty("商品总额")
-    private Double goodsTotal=0.0;
-
-    @ApiModelProperty("过期的积分")
-    private Long refundExpiredScore=0L;
-    /*
-ac
-    @ApiModelProperty("物流公司名称")
-    private String expressName;
-
-    @ApiModelProperty("物流单号")
-    private String expressNo;
-
-    @ApiModelProperty("发货时间")
-    private Date shipTime;
-
-    @ApiModelProperty("收货时间")
-    private Date receiveTime;
-
-    @ApiModelProperty("撤销时间")
-    private Date cancelTime;
-
-    @ApiModelProperty("决定时间")
-    private Date decisionTime;
-
-    @ApiModelProperty("退款申请状态(0:未申请 1:申请中 2:已完成 -1:失败)")
-    private Integer refundApplySts;
+    private Double goodsTotal = 0.0;
 
-    @ApiModelProperty("退款物流信息")
-    private RefundDelivery refundDelivery;*/
+    @ApiModelProperty("退还的过期积分")
+    private Long refundExpiredScore = 0L;
 
-    @ApiModelProperty("配送类型 1:快递 2:自提 3:及时配送")
+    @ApiModelProperty("配送类型")
     private Integer dvyType;
 
+    @ApiModelProperty("会员优惠金额")
+    private Double memberDiscountAmount = 0.0;
 
+    @ApiModelProperty("会员优惠说明")
+    private String memberDiscountDesc;
 }

+ 34 - 69
yami-shop-bean/src/main/java/com/yami/shop/bean/app/dto/OrderShopDto.java

@@ -1,13 +1,3 @@
-/*
- * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
- *
- * https://www.gz-yami.com/
- *
- * 未经允许,不可做商业用途!
- *
- * 版权所有,侵权必究!
- */
-
 package com.yami.shop.bean.app.dto;
 
 import io.swagger.annotations.ApiModelProperty;
@@ -18,142 +8,117 @@ import java.io.Serializable;
 import java.util.Date;
 import java.util.List;
 
-/**
- * 订单下的每个店铺
- *
- * @author YaMi
- */
 @Data
 public class OrderShopDto implements Serializable {
 
-    /**
-     * 店铺ID
-     **/
     @ApiModelProperty(value = "店铺id", required = true)
     private Long shopId;
 
-    /**
-     * 店铺名称
-     **/
     @ApiModelProperty(value = "店铺名称", required = true)
     private String shopName;
 
-    @ApiModelProperty(value = "实际总", required = true)
+    @ApiModelProperty(value = "实际总", required = true)
     private Double actualTotal;
 
-    @ApiModelProperty(value = "商品总", required = true)
+    @ApiModelProperty(value = "商品总", required = true)
     private Double total;
 
-    @ApiModelProperty(value = "商品总数", required = true)
+    @ApiModelProperty(value = "商品总数", required = true)
     private Integer totalNum;
 
-    @ApiModelProperty(value = "地址Dto", required = true)
+    @ApiModelProperty(value = "地址信息", required = true)
     private UserAddrDto userAddrDto;
 
-    @ApiModelProperty(value = "支付方式",required=true)
+    @ApiModelProperty(value = "支付方式", required = true)
     private Integer payType;
 
-    @ApiModelProperty(value = "品信息", required = true)
+    @ApiModelProperty(value = "品信息", required = true)
     private List<OrderItemDto> orderItemDtos;
 
     @ApiModelProperty(value = "运费", required = true)
     private Double transfee;
 
-    @ApiModelProperty(value = "使用积分换算的钱", required = true)
-    private Double reduceAmount= 0.0;
+    @ApiModelProperty(value = "积分抵扣金额", required = true)
+    private Double reduceAmount = 0.0;
 
-    @ApiModelProperty(value = "整个订单使用积分", required = true)
-    private Double totalUsableScore=0.0;
+    @ApiModelProperty(value = "订单使用积分", required = true)
+    private Double totalUsableScore = 0.0;
 
-    @ApiModelProperty(value = "所有可用积分")
-    private Long totalAvailableScore=0L;
+    @ApiModelProperty(value = "可用积分")
+    private Long totalAvailableScore = 0L;
 
-    @ApiModelProperty(value = "促销活动优惠金额", required = true)
+    @ApiModelProperty(value = "促销优惠金额", required = true)
     private Double discountMoney;
 
     @ApiModelProperty(value = "优惠券优惠金额", required = true)
     private Double couponMoney;
 
+    @ApiModelProperty(value = "会员优惠金额", required = true)
+    private Double memberDiscountAmount = 0.0;
+
+    @ApiModelProperty(value = "会员优惠说明")
+    private String memberDiscountDesc;
 
-    /**
-     * 创建时间
-     */
     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     @ApiModelProperty(value = "订单创建时间", required = true)
     private Date createTime;
 
     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-    @ApiModelProperty(value = "订单付款时间", required = false)
+    @ApiModelProperty(value = "订单付款时间")
     private Date payTime;
 
     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-    @ApiModelProperty(value = "订单发货时间", required = false)
+    @ApiModelProperty(value = "订单发货时间")
     private Date dvyTime;
 
     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-    @ApiModelProperty(value = "订单完成时间", required = false)
+    @ApiModelProperty(value = "订单完成时间")
     private Date fianllyTime;
 
     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-    @ApiModelProperty(value = "订单取消时间", required = false)
+    @ApiModelProperty(value = "订单取消时间")
     private Date cancelTime;
 
-    @ApiModelProperty(value = "订单取消原因", required = true)
+    @ApiModelProperty(value = "订单取消原因")
     private String cancelReason;
 
-
     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-    @ApiModelProperty(value = "订单更新时间", required = false)
+    @ApiModelProperty(value = "订单更新时间")
     private Date updateTime;
 
-    /**
-     * 订单备注信息
-     */
-    @ApiModelProperty(value = "订单备注信息", required = true)
+    @ApiModelProperty(value = "订单备注")
     private String remarks;
 
-    /**
-     * 配送类型
-     */
-    @ApiModelProperty(value = "配送类型 1:快递 2:自提 3:无需快递", required = true)
+    @ApiModelProperty(value = "配送类型", required = true)
     private Integer dvyType;
 
-    @ApiModelProperty(value = "物流单号", required = true)
+    @ApiModelProperty(value = "物流单号")
     private String dvyFlowId;
 
-    @ApiModelProperty(value = "物流公司名称", required = true)
+    @ApiModelProperty(value = "物流公司名称")
     private String dvyName;
 
-    /**
-     * 订单类型1团购订单 2秒杀订单
-     */
-    @ApiModelProperty(value = "订单类型(1团购订单 2秒杀订单)", required = true)
+    @ApiModelProperty(value = "订单类型", required = true)
     private Integer orderType;
 
-    /**
-     * 订单状态
-     */
     @ApiModelProperty(value = "订单状态", required = true)
     private Integer status;
 
-    @ApiModelProperty(value = "能否退款", required = true)
+    @ApiModelProperty(value = "是否可退款", required = true)
     private Boolean canRefund = false;
 
-    @ApiModelProperty(value = "能否整单退款", required = true)
+    @ApiModelProperty(value = "是否可整单退款", required = true)
     private Boolean canAllRefund = false;
 
     @ApiModelProperty(value = "订单积分")
     private Integer orderScore = 0;
 
-    @ApiModelProperty(value = "订单预计送达日期", required = true, example = "3月8日")
+    @ApiModelProperty(value = "预计送达日期")
     private String estimatedTimeStr;
 
-    @ApiModelProperty(value = "订单预计送达时间", required = true, example = "10:40")
+    @ApiModelProperty(value = "预计送达时间")
     private String estimatedTime;
 
-    /**
-     * 评论状态: 0 未评价  1 已评价
-     */
-    @ApiModelProperty(value = "评论状态: 0 未评价  1 已评价")
+    @ApiModelProperty(value = "评论状态")
     private Integer commSts;
 }

+ 12 - 0
yami-shop-bean/src/main/java/com/yami/shop/bean/app/dto/ProductItemDto.java

@@ -86,6 +86,18 @@ public class ProductItemDto implements Serializable {
     @ApiModelProperty("参与满减活动列表")
     private List<DiscountDto> discounts = new ArrayList<>();
 
+    @ApiModelProperty(value = "业务类型")
+    private String businessType;
+
+    @ApiModelProperty(value = "是否会员价商品")
+    private Boolean isMember = Boolean.FALSE;
+
+    @ApiModelProperty(value = "会员价")
+    private Double memberPrice;
+
+    @ApiModelProperty(value = "会员优惠分摊金额")
+    private Double memberDiscountShareAmount = 0.0;
+
     private Double weight;
 
     private String weightUnit;

+ 4 - 15
yami-shop-bean/src/main/java/com/yami/shop/bean/app/dto/RefundOrderItemDto.java

@@ -1,13 +1,3 @@
-/*
- * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
- *
- * https://www.gz-yami.com/
- *
- * 未经允许,不可做商业用途!
- *
- * 版权所有,侵权必究!
- */
-
 package com.yami.shop.bean.app.dto;
 
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
@@ -15,10 +5,6 @@ import com.yami.shop.common.serializer.json.ImgJsonSerializer;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
-/**
- * 退款订单项
- * @author LGH
- */
 @Data
 public class RefundOrderItemDto {
 
@@ -38,7 +24,7 @@ public class RefundOrderItemDto {
     @ApiModelProperty("物品数量")
     private Integer prodCount;
 
-    @ApiModelProperty("物品数量2")
+    @ApiModelProperty("退款商品数量")
     private Integer productCount;
 
     @ApiModelProperty("产品总价格")
@@ -46,4 +32,7 @@ public class RefundOrderItemDto {
 
     @ApiModelProperty("商品实际金额")
     private Double actualTotal;
+
+    @ApiModelProperty("会员优惠分摊金额")
+    private Double memberDiscountShareAmount = 0.0;
 }

+ 34 - 33
yami-shop-bean/src/main/java/com/yami/shop/bean/app/dto/ShopCartOrderDto.java

@@ -1,13 +1,3 @@
-/*
- * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
- *
- * https://www.gz-yami.com/
- *
- * 未经允许,不可做商业用途!
- *
- * 版权所有,侵权必究!
- */
-
 package com.yami.shop.bean.app.dto;
 
 import io.swagger.annotations.ApiModelProperty;
@@ -17,66 +7,77 @@ import java.io.Serializable;
 import java.util.List;
 
 /**
- * 单个店铺的订单信息
+ * Single shop order summary used by order confirm.
  */
 @Data
-public class ShopCartOrderDto implements Serializable{
+public class ShopCartOrderDto implements Serializable {
 
-    @ApiModelProperty(value = "店铺id", required = true)
+    @ApiModelProperty(value = "Shop id", required = true)
     private Long shopId;
 
-    @ApiModelProperty(value = "店铺名称", required = true)
+    @ApiModelProperty(value = "Shop name", required = true)
     private String shopName;
 
-    @ApiModelProperty(value = "实际总值", required = true)
+    @ApiModelProperty(value = "Actual total", required = true)
     private Double actualTotal;
 
-    @ApiModelProperty(value = "商品总值", required = true)
+    @ApiModelProperty(value = "Product total", required = true)
     private Double total;
 
-    @ApiModelProperty(value = "商品总数", required = true)
+    @ApiModelProperty(value = "Product count", required = true)
     private Integer totalCount;
 
-    @ApiModelProperty(value = "用户等级免运费金额", required = true)
+    @ApiModelProperty(value = "Free shipping amount", required = true)
     private Double freeTransfee = 0.0;
 
-    @ApiModelProperty(value = "运费", required = true)
+    @ApiModelProperty(value = "Shipping fee", required = true)
     private Double transfee;
 
-    @ApiModelProperty(value = "促销活动优惠金额", required = true)
+    @ApiModelProperty(value = "Promotion discount amount", required = true)
     private Double discountReduce;
 
-    @ApiModelProperty(value = "优惠券优惠金额", required = true)
+    @ApiModelProperty(value = "Coupon discount amount", required = true)
     private Double couponReduce;
 
-    @ApiModelProperty(value = "积分优惠金额", required = true)
+    @ApiModelProperty(value = "Score discount amount", required = true)
     private Double scoreReduce;
 
-    @ApiModelProperty(value = "使用积分", required = true)
+    @ApiModelProperty(value = "Used score", required = true)
     private Integer useScore;
 
-    @ApiModelProperty(value = "平台优惠金额", required = true)
+    @ApiModelProperty(value = "Platform discount amount", required = true)
     private Double platformAmount;
 
-    @ApiModelProperty(value = "等级优惠券金额", required = true)
+    @ApiModelProperty(value = "Level discount amount", required = true)
     private Double levelReduce;
 
-    @ApiModelProperty(value = "店铺优惠金额(促销活动 + 优惠券 + 积分优惠金额 + 其他)", required = true)
+    @ApiModelProperty(value = "Member discount amount", required = true)
+    private Double memberDiscountAmount = 0.0;
+
+    @ApiModelProperty(value = "Member discount description")
+    private String memberDiscountDesc;
+
+    @ApiModelProperty(value = "Member benefit description for confirm page")
+    private String memberBenefitDesc;
+
+    @ApiModelProperty(value = "Member discount rate, 0.95 means 9.5 discount")
+    private Double memberDiscountRate;
+
+    @ApiModelProperty(value = "Shop total discount amount", required = true)
     private Double shopReduce = 0.0;
 
-    @ApiModelProperty(value = "订单备注信息", required = true)
+    @ApiModelProperty(value = "Order remarks", required = true)
     private String remarks;
 
-    @ApiModelProperty(value = "购物车商品", required = true)
+    @ApiModelProperty(value = "Cart item discounts", required = true)
     private List<ShopCartItemDiscountDto> shopCartItemDiscounts;
 
-    @ApiModelProperty(value = "整个店铺可以使用的优惠券列表", required = true)
+    @ApiModelProperty(value = "Available coupons for the shop", required = true)
     private List<CouponOrderDto> coupons;
 
-    @ApiModelProperty(value = "订单编号", required = true)
+    @ApiModelProperty(value = "Order number", required = true)
     private String orderNumber;
 
-   private Double totalWeight;
-
-
+    @ApiModelProperty(value = "Total weight")
+    private Double totalWeight;
 }

+ 35 - 34
yami-shop-bean/src/main/java/com/yami/shop/bean/app/dto/ShopCartOrderMergerDto.java

@@ -1,13 +1,3 @@
-/*
- * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
- *
- * https://www.gz-yami.com/
- *
- * 未经允许,不可做商业用途!
- *
- * 版权所有,侵权必究!
- */
-
 package com.yami.shop.bean.app.dto;
 
 import io.swagger.annotations.ApiModelProperty;
@@ -17,67 +7,78 @@ import java.io.Serializable;
 import java.util.List;
 
 /**
- * 多个店铺订单合并在一起的合并类
- * "/confirm" 使用
+ * Merged order view used by /confirm.
  */
 @Data
 public class ShopCartOrderMergerDto implements Serializable {
 
-    @ApiModelProperty(value = "实际总值", required = true)
+    @ApiModelProperty(value = "Actual total", required = true)
     private Double actualTotal;
 
-    @ApiModelProperty(value = "商品总值", required = true)
+    @ApiModelProperty(value = "Product total", required = true)
     private Double total;
 
-    @ApiModelProperty(value = "商品总数", required = true)
+    @ApiModelProperty(value = "Product count", required = true)
     private Integer totalCount;
 
-    @ApiModelProperty(value = "订单优惠金额(所有店铺优惠金额和使用积分抵现相加)", required = true)
+    @ApiModelProperty(value = "Total order discount amount", required = true)
     private Double orderReduce = 0.0;
 
-    @ApiModelProperty(value = "订单所需积分", required = true)
-    private Integer scorePrice=0;
+    @ApiModelProperty(value = "Required score", required = true)
+    private Integer scorePrice = 0;
 
-    @ApiModelProperty(value = "整个订单使用的积分数", required = true)
+    @ApiModelProperty(value = "Usable score in this order", required = true)
     private Double totalUsableScore = 0.0;
 
-    @ApiModelProperty(value = "所有可用积分")
-    private Long totalAvailableScore=0L;
+    @ApiModelProperty(value = "Available score")
+    private Long totalAvailableScore = 0L;
 
-    @ApiModelProperty(value = "整个订单最多可以使用的积分数", required = true)
+    @ApiModelProperty(value = "Max usable score", required = true)
     private Integer maxUsableScore = 0;
 
-    @ApiModelProperty(value = "积分抵扣金额", required = true)
-    private Double totalScoreAmount=0.0;
+    @ApiModelProperty(value = "Score discount amount", required = true)
+    private Double totalScoreAmount = 0.0;
 
-    @ApiModelProperty(value = "购物积分抵现比例", required = true)
+    @ApiModelProperty(value = "Shop score rate", required = true)
     private Double shopUseScore;
 
-    @ApiModelProperty(value = "等级折扣金额", required = true)
+    @ApiModelProperty(value = "Level discount amount", required = true)
     private Double totalLevelAmount;
 
-    @ApiModelProperty(value = "免运费金额", required = true)
+    @ApiModelProperty(value = "Member discount amount", required = true)
+    private Double memberDiscountAmount = 0.0;
+
+    @ApiModelProperty(value = "Member discount description")
+    private String memberDiscountDesc;
+
+    @ApiModelProperty(value = "Member benefit description for confirm page")
+    private String memberBenefitDesc;
+
+    @ApiModelProperty(value = "Member discount rate, 0.95 means 9.5 discount")
+    private Double memberDiscountRate;
+
+    @ApiModelProperty(value = "Free shipping amount", required = true)
     private Double freeTransfee = 0.0;
 
-    @ApiModelProperty(value = "总运费", required = true)
+    @ApiModelProperty(value = "Total shipping fee", required = true)
     private Double totalTransfee;
 
-    @ApiModelProperty(value = "地址Dto", required = true)
+    @ApiModelProperty(value = "User address", required = true)
     private UserAddrDto userAddr;
 
-    @ApiModelProperty(value = "每个店铺的购物车信息", required = true)
+    @ApiModelProperty(value = "Per-shop cart orders", required = true)
     private List<ShopCartOrderDto> shopCartOrders;
 
-    @ApiModelProperty(value = "整个订单可以使用的优惠券列表", required = true)
+    @ApiModelProperty(value = "Available coupons for the order", required = true)
     private List<CouponOrderDto> coupons;
 
-    @ApiModelProperty(value = "每次订单提交时的uuid")
+    @ApiModelProperty(value = "Submit uuid")
     private String uuid;
 
-    @ApiModelProperty(value = "用户是否选择积分抵现(0不使用 1使用 默认不使用)")
+    @ApiModelProperty(value = "Whether score pay is enabled")
     private Integer isScorePay;
 
-    @ApiModelProperty(value = "配送类型 1:快递 2:自提 3:无需快递")
+    @ApiModelProperty(value = "Delivery type")
     private Integer dvyType;
 
     private Long channelId;

+ 10 - 62
yami-shop-bean/src/main/java/com/yami/shop/bean/dto/OrderRefundDto.java

@@ -1,13 +1,3 @@
-/*
- * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
- *
- * https://www.gz-yami.com/
- *
- * 未经允许,不可做商业用途!
- *
- * 版权所有,侵权必究!
- */
-
 package com.yami.shop.bean.dto;
 
 import com.yami.shop.bean.model.OrderItem;
@@ -26,86 +16,40 @@ import java.util.List;
 @EqualsAndHashCode(callSuper = false)
 public class OrderRefundDto extends OrderRefund implements Serializable {
 
-    /**
-     * 退款单id
-     */
     private Long refundId;
 
-    /**
-     * 订单编号
-     */
     private String orderNumber;
-    /**
-     * 退款单号
-     */
+
     private String refundSn;
 
-    /**
-     * 实际总值
-     */
     private Double orderAmount;
 
-    /**
-     * 支付单ID
-     */
     private Long settlementId;
 
-    /**
-     * 支付单号
-     */
     private String orderPayNo;
 
-    /**
-     * 收货地址对象
-     */
     private RefundDelivery refundDelivery;
 
-    /**
-     * 门店ID
-     */
     private Long shopId;
 
-    /**
-     * 店铺名称
-     */
     private String shopName;
 
-    /**
-     * 订单支付时间
-     */
     private Date orderPayTime;
 
-    /**
-     * 申请类型:1,仅退款,2退款退货
-     */
     private Integer applyType;
 
-    /**
-     * 订单项
-     */
     private List<OrderItem> orderItems = new ArrayList<>();
-    /**
-     * 退款流程
-     */
+
     private List<OrderRefundRecord> records = new ArrayList<>();
-    /**
-     * 订单退款状态
-     */
+
     private String refundStatus;
-    /**
-     * 订单状态
-     */
+
     private Integer status;
-    /**
-     * 订单类型 1团购订单 2秒杀订单 3积分订单
-     */
+
     private Integer orderType;
 
     private Integer dvyType;
 
-    /**
-     * true:可以取消退款  false:不可以取消退款(待发货状态->非整单退款->所有商品已经申请退款->不可取消退款)
-     */
     private Boolean isCancel;
 
     private Double freightAmount = 0.0;
@@ -113,6 +57,10 @@ public class OrderRefundDto extends OrderRefund implements Serializable {
     private Long offsetPoints = 0L;
 
     private Double goodsTotal;
-    //过期的积分
+
     private Long refundExpiredScore = 0L;
+
+    private Double memberDiscountAmount = 0.0;
+
+    private String memberDiscountDesc;
 }

+ 17 - 0
yami-shop-bean/src/main/java/com/yami/shop/bean/dto/XsbMemberDiscountInfo.java

@@ -0,0 +1,17 @@
+package com.yami.shop.bean.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class XsbMemberDiscountInfo implements Serializable {
+
+    private static final long serialVersionUID = -5375470066488917313L;
+
+    private Boolean member = Boolean.FALSE;
+
+    private Double discountRate = 1.0;
+
+    private String memberTypeName;
+}

+ 73 - 63
yami-shop-bean/src/main/java/com/yami/shop/bean/model/Order.java

@@ -1,11 +1,11 @@
 /*
- * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
+ * Copyright (c) 2018-2999 楠炲灝绐炴禍姘辫儗娣団剝浼呯粔鎴炲Η閺堝愭洪崗顒寰 All rights reserved.
  *
  * https://www.gz-yami.com/
  *
- * 未经允许,不可做商业用途!
+ * 閺堫亞绮¢崗浣筋啅閿涘奔绗夐崣顖氫粵閸熷棔绗熼悽銊┾偓鏃撶磼
  *
- * 版权所有,侵权必究!
+ * 閻楀牊娼堥幍鈧閺堝涚礉娓氬灚娼堣箛鍛鈹掗敍?
  */
 
 package com.yami.shop.bean.model;
@@ -26,128 +26,128 @@ import java.util.List;
 public class Order implements Serializable {
     private static final long serialVersionUID = 6222259729062826852L;
     /**
-     * 订单ID
+     * 鐠併垹宕烮D
      */
     @TableId
     private Long orderId;
 
     /**
-     * 店铺id
+     * 鎼存呮懙id
      */
     private Long shopId;
     @TableField(exist = false)
     private String shopName;
     /**
-     * 渠道ID
+     * 濞撶娀浜綢D
      */
     private Long channelId;
     @TableField(exist = false)
     private String channelName;
 
     /**
-     * 产品名称,多个产品将会以逗号隔开
+     * 娴溠冩惂閸氬秶袨,婢舵矮閲滄禍褍鎼х亸鍡曠窗娴犮儵鈧妤褰块梾鏂跨磻
      */
     private String prodName;
 
     /**
-     * 订购用户ID
+     * 鐠併垼鍠橀悽銊﹀煕ID
      */
     private String userId;
     /**
-     * 父订单编号
+     * 閻栨儼顓归崡鏇犵椽閸?
      */
     private String parentOrderNumber;
 
     /**
-     * 订购流水号
+     * 鐠併垼鍠樺ù浣规寜閸?
      */
     private String orderNumber;
 
     /**
-     * 总值
+     * 閹璇测偓?
      */
     private Double total;
 
     /**
-     * 实际总值
+     * 鐎圭偤妾閹璇测偓?
      */
     private Double actualTotal;
 
     /**
-     * 支付方式 1 微信支付 2 支付宝
+     * 閺顖欑帛閺傜懓绱 1 瀵邦喕淇婇弨顖欑帛 2 閺顖欑帛鐎?
      */
     private Integer payType;
 
     /**
-     * 用户备注
+     * 閻銊﹀煕婢跺洦鏁
      */
     private String remarks;
 
     /**
-     * 卖家备注
+     * 閸楁牕顔嶆径鍥ㄦ暈
      */
     private String shopRemarks;
 
 
     /**
-     * 海博订单状态
-     * 0-待支付 20-订单已接单(待拣货),30-订单待配送(拣货完成/自提类订单为待自提),40-订单配送中 ,50-订单取消待审核,60-订单已取消,70-订单已送达,80-订单已完成
+     * 濞村嘲宕ョ拋銏犲礋閻樿埖鈧?
+     * 0-瀵板懏鏁娴?20-鐠併垹宕熷稿弶甯撮崡?瀵板懏瀚炵拹?,30-鐠併垹宕熷板懘鍘ら柅渚婄礄閹凤綀鎻g瑰本鍨/閼奉亝褰佺猾鏄忣吂閸楁洑璐熷板懓鍤滈幓鎰剁礆,40-鐠併垹宕熼柊宥夆偓浣疯厬 ,50-鐠併垹宕熼崣鏍ㄧХ瀵板懎顓搁弽?60-鐠併垹宕熷告彃褰囧☉?70-鐠併垹宕熷告煡鈧浣芥彧,80-鐠併垹宕熷告彃鐣閹?
      */
     private Integer hbOrderStatus;
 
     /**
-     * 海博物流状态
-     * 20:已抢单,30:配送员到店,40:取货完成,50:配送单取消,100:已送达
+     * 濞村嘲宕ラ悧鈺傜ウ閻樿埖鈧?
+     * 20:瀹稿弶濮犻崡鏇绱30:闁板秹鈧浣告喅閸掓澘绨甸敍?0:閸欐牞鎻g瑰本鍨氶敍?0:闁板秹鈧浣稿礋閸欐牗绉,100:瀹告煡鈧浣芥彧
      */
     private Integer hbLogisticStatus;
 
     /**
-     * 配送类型(1:快递 2:自提 3:及时配送 10-商家转自送)
+     * 闁板秹鈧浣鸿閸ㄥ剁礄1:韫囶偊鈧?2:閼奉亝褰 3閿涙艾寮烽弮鍫曞帳闁?10-閸熷棗顔嶆潪顒冨殰闁渚婄礆
      */
     private Integer dvyType;
 
     /**
-     * 配送方式ID
+     * 闁板秹鈧浣规煙瀵寤擠
      */
     private Long dvyId;
 
     /**
-     * 物流单号
+     * 閻椻晜绁﹂崡鏇炲娇
      */
     private String dvyFlowId;
 
     /**
-     * 订单运费
+     * 鐠併垹宕熸潻鎰鍨
      */
     private Double freightAmount;
 
     /**
-     * 用户订单地址Id
+     * 閻銊﹀煕鐠併垹宕熼崷鏉挎絻Id
      */
     private Long addrOrderId;
 
     /**
-     * 是否为超重订单(0-未超重,1-超重 )
+     * 閺勵垰鎯佹稉楦跨Т闁插秷顓归崡鏇绱0-閺堫亣绉撮柌宥忕礉1-鐡掑懘鍣 閿?
      */
     private Integer orderSplitStatus;
     /**
-     * 子订单数量命名
+     * 鐎涙劘顓归崡鏇熸殶闁插繐鎳¢崥?
      */
     private Integer orderSplitNumber;
     /**
-     * 是否自动拆单(0-手动拆单,1-自动拆单)
+     * 閺勵垰鎯侀懛顏勫З閹峰棗宕(0-閹靛濮╅幏鍡楀礋閿?-閼奉亜濮╅幏鍡楀礋)
      */
     private Integer autoSplit;
     /**
-     * 是否需要拆单(0-拆单临时保存,1-不拆单,2-待拆单,3-拆单中,4-已拆单)
+     * 閺勵垰鎯侀棁鈧鐟曚焦濯堕崡鏇绱0-閹峰棗宕熸稉瀛樻傛穱婵嗙摠閿?-娑撳秵濯堕崡鏇绱2-瀵板懏濯堕崡鏇绱3-閹峰棗宕熸稉顓ㄧ礉4-瀹稿弶濯堕崡鏇绱
      */
     private Integer splitStatus;
     /**
-     * 订单等级(0-父订单,1-子订单)
+     * 鐠併垹宕熺粵澶岄獓閿?-閻栨儼顓归崡鏇绱1-鐎涙劘顓归崡鏇绱
      */
     private Integer orderLevel;
     /**
-     * 拆单操作人ID
+     * 閹峰棗宕熼幙宥勭稊娴滅瘨D
      */
     private Long splitUserId;
 
@@ -162,156 +162,166 @@ public class Order implements Serializable {
     private Double longitude;
 
     @TableField(exist = false)
-    @ApiModelProperty("拆单操作人名称")
+    @ApiModelProperty("Split user name")
     private String splitUserName;
 
 
     /**
-     * 订单商品总数
+     * 鐠併垹宕熼崯鍡楁惂閹缁樻殶
      */
     private Integer productNums;
-    @ApiModelProperty("牵牛花订单id")
+    @ApiModelProperty("閻楃數澧伴懞杈顓归崡鏄砫")
     private  String qnhOrderId;
 
-    @ApiModelProperty("牵牛花订单状态 0 失败 1 成功 null为暂未创建")
+    @ApiModelProperty("QNH order status")
     private  String qnhOrderStatus;
 
     /**
-     * 订购时间
+     * 鐠併垼鍠橀弮鍫曟?
      */
     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date createTime;
 
     /**
-     * 订单更新时间
+     * 鐠併垹宕熼弴瀛樻煀閺冨爼妫
      */
     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date updateTime;
 
     /**
-     * 付款时间
+     * 娴犳ɑ顑欓弮鍫曟?
      */
     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date payTime;
 
     /**
-     * 发货时间
+     * 閸欐垼鎻i弮鍫曟?
      */
     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date dvyTime;
 
     /**
-     * 完成时间
+     * 鐎瑰本鍨氶弮鍫曟?
      */
     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date finallyTime;
 
 
     /**
-     * 订单取消原因
+     * 鐠併垹宕熼崣鏍ㄧХ閸樼喎娲
      */
     private String cancelReason;
 
     /**
-     * 取消时间
+     * 閸欐牗绉烽弮鍫曟?
      */
     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date cancelTime;
 
     /**
-     * 是否已经支付,1:已经支付过,0:,没有支付过
+     * 閺勵垰鎯佸歌尙绮¢弨顖欑帛閿?閿涙艾鍑$紒蹇旀暜娴犳跨箖閿?閿涙熬绱濆▽鈩冩箒閺顖欑帛鏉?
      */
     private Integer isPayed;
 
     /**
-     * 用户订单删除状态,0:没有删除, 1:回收站, 2:永久删除
+     * 閻銊﹀煕鐠併垹宕熼崚鐘绘珟閻樿埖鈧渚婄礉0閿涙碍鐥呴張澶婂灩闂勩倧绱 1閿涙艾娲栭弨鍓佺彲閿?2閿涙碍妗堟稊鍛鍨归梽?
      */
     private Integer deleteStatus;
 
     /**
-     * 订单退款状态(1:申请退款 2:退款成功 3:部分退款成功 4:退款失败)
+     * 鐠併垹宕熼柅鈧濞嗗墽濮搁幀渚婄礄1:閻㈠疇顕闁鈧濞?2:闁鈧濞嗙偓鍨氶崝?3:闁銊ュ瀻闁鈧濞嗙偓鍨氶崝?4:闁鈧濞嗘儳銇戠拹銉绱
      */
     private Integer refundStatus;
 
     /**
-     * 平台优惠总额
+     * 楠炲啿褰存导妯诲劕閹濠氼杺
      */
     private Double platformAmount;
 
     /**
-     * 优惠总额
+     * 娴兼ɑ鍎閹濠氼杺
      */
     private Double reduceAmount;
 
     /**
-     * 订单类型参考orderType ,1团购订单 2秒杀订单,3积分订单
+     * 浼氬憳浼樻儬閲戦
+     */
+    private Double memberDiscountAmount;
+
+    /**
+     * 浼氬憳浼樻儬璇存槑
+     */
+    private String memberDiscountDesc;
+
+    /**
+     * 鐠併垹宕熺猾璇茬烽崣鍌濃偓鍍秗derType ,1閸ャ垼鍠樼拋銏犲礋 2缁夋帗娼冪拋銏犲礋,3缁夘垰鍨庣拋銏犲礋
      */
     private Integer orderType;
 
     /**
-     * 订单关闭原因 (1:超时未支付 2:退款关闭 4:买家取消 15:已通过货到付款交易)
+     * 鐠併垹宕熼崗鎶芥4閸樼喎娲 (1:鐡掑懏妞傞張顏呮暜娴?2:闁鈧濞嗘儳鍙ч梻?4:娑旀澘顔嶉崣鏍ㄧХ 15:瀹告煡鈧姘崇箖鐠愌冨煂娴犳ɑ顑欐禍銈嗘)
      */
     private Integer closeType;
 
-    @ApiModelProperty("麦芽条状态 0 失败 1 成功 null为暂未创建")
+    @ApiModelProperty("Delivery status")
     private Integer dvyStatus;
 
 
     /**
-     * 买家昵称
+     * 娑旀澘顔嶉弰鐢敌
      */
     @TableField(exist = false)
-    @ApiModelProperty("买家名称")
+    @ApiModelProperty("Nickname")
     private String nickName;
     /**
-     * 买家手机号
+     * 娑旀澘顔嶉幍瀣婧閸?
      */
     @TableField(exist = false)
-    @ApiModelProperty("买家手机号")
+    @ApiModelProperty("User mobile")
     private String userMobile;
 
     @TableField(exist = false)
-    @ApiModelProperty("收货人")
+    @ApiModelProperty("Receiver")
     private String receiver;
 
     @TableField(exist = false)
     private List<OrderItem> orderItems;
 
     /**
-     * 用户订单地址
+     * 閻銊﹀煕鐠併垹宕熼崷鏉挎絻
      */
     @TableField(exist = false)
     private UserAddrOrder userAddrOrder;
 
     /**
-     * 退款订单编号
+     * 闁鈧濞嗘崘顓归崡鏇犵椽閸?
      */
     @TableField(exist = false)
     private String refundSn;
 
     /**
-     * 订单所用积分
+     * 鐠併垹宕熼幍鈧閻銊袧閸?
      */
     @TableField(exist = false)
     private Integer score;
     /**
-     * 评论状态: 0 未评价  1 已评价
+     * 鐠囧嫯顔戦悩鑸碘偓渚婄窗 0 閺堫亣鐦庢禒? 1 瀹歌尪鐦庢禒?
      */
     private Integer commSts;
     /**
-     * 退款状态
+     * 闁鈧濞嗗墽濮搁幀?
      */
     @TableField(exist = false)
     private Integer returnMoneySts;
 
     /**
-     * 退款类型
+     * 闁鈧濞嗗墽琚閸?
      */
     @TableField(exist = false)
     private Integer refundType;
 
     /**
-     * 亏损金额
+     * 娴滃繑宕闁叉垿顤
      */
     @TableField(exist = false)
     private Double lossAmount;
@@ -320,7 +330,7 @@ public class Order implements Serializable {
     private Integer payScore;
 
     /**
-     * 是否需要支付
+     * 閺勵垰鎯侀棁鈧鐟曚焦鏁娴?
      */
     @TableField(exist = false)
     private Boolean nextPay = Boolean.FALSE;
@@ -333,7 +343,7 @@ public class Order implements Serializable {
 
 
     /**
-     * 子订单信息
+     * 鐎涙劘顓归崡鏇氫繆閹?
      */
     @TableField(exist = false)
     private List<Order> subOrders;

+ 41 - 36
yami-shop-bean/src/main/java/com/yami/shop/bean/model/OrderItem.java

@@ -1,11 +1,11 @@
 /*
- * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
+ * Copyright (c) 2018-2999 骞垮窞浜氱背淇℃伅绉戞妧鏈夐檺鍏徃 All rights reserved.
  *
  * https://www.gz-yami.com/
  *
- * 未经允许,不可做商业用途!
+ * 鏈粡鍏佽锛屼笉鍙仛鍟嗕笟鐢ㄩ€旓紒
  *
- * 版权所有,侵权必究!
+ * 鐗堟潈鎵€鏈夛紝渚垫潈蹇呯┒锛?
  */
 
 package com.yami.shop.bean.model;
@@ -25,7 +25,7 @@ public class OrderItem implements Serializable {
 
     private static final long serialVersionUID = 7307405761190788407L;
     /**
-     * 订单项ID
+     * 璁㈠崟椤笽D
      */
     @TableId(type = IdType.AUTO)
     private Long orderItemId;
@@ -33,156 +33,161 @@ public class OrderItem implements Serializable {
     private Long shopId;
 
     /**
-     * 订单orderNumber
+     * 璁㈠崟orderNumber
      */
     private String orderNumber;
 
     /**
-     * 产品ID
+     * 浜у搧ID
      */
     private Long prodId;
 
     /**
-     * 产品SkuID
+     * 浜у搧SkuID
      */
 
     private Long skuId;
 
     /**
-     * 购物车产品个数
+     * 璐墿杞︿骇鍝佷釜鏁?
      */
     private Integer prodCount;
 
     /**
-     * 商品重量(g)
+     * 鍟嗗搧閲嶉噺锛坓锛?
      */
     private Double weight;
     /**
-     * 已拆单数量
+     * 宸叉媶鍗曟暟閲?
      */
     private Integer splitCount;
 
     /**
-     * 产品名称
+     * 浜у搧鍚嶇О
      */
     private String prodName;
 
     /**
-     * sku名称
+     * sku鍚嶇О
      */
     private String skuName;
 
     /**
-     * 产品主图片路径
+     * 浜у搧涓诲浘鐗囪矾寰?
      */
     private String pic;
 
     /**
-     * 产品价格
+     * 浜у搧浠锋牸
      */
     private Double price;
 
     /**
-     * 用户Id
+     * 鐢ㄦ埛Id
      */
 
     private String userId;
 
     /**
-     * 商品总金额
+     * 鍟嗗搧鎬婚噾棰?
      */
     private Double productTotalAmount;
 
     /**
-     * 购物时间
+     * 璐墿鏃堕棿
      */
 
     private Date recTime;
 
     /**
-     * 评论状态: 0 未评价  1 已评价
+     * 璇勮鐘舵€侊細 0 鏈瘎浠? 1 宸茶瘎浠?
      */
     private Integer commSts;
 
     /**
-     * 推广员使用的推销卡号
+     * 鎺ㄥ箍鍛樹娇鐢ㄧ殑鎺ㄩ攢鍗″彿
      */
     private String distributionCardNo;
 
     /**
-     * 加入购物车的时间
+     * 鍔犲叆璐墿杞︾殑鏃堕棿
      */
     private Date basketDate;
 
     /**
-     * 商品实际金额 = 商品总金额 - 分摊的优惠金额
+     * 鍟嗗搧瀹為檯閲戦 = 鍟嗗搧鎬婚噾棰?- 鍒嗘憡鐨勪紭鎯犻噾棰?
      */
     private Double actualTotal;
 
     /**
-     * 分摊的优惠金额
+     * 鍒嗘憡鐨勪紭鎯犻噾棰?
      */
     private Double shareReduce;
 
     /**
-     * 使用积分
+     * 会员优惠分摊金额
+     */
+    private Double memberDiscountShareAmount;
+
+    /**
+     * 浣跨敤绉垎
      */
     private Integer useScore;
     /**
-     * 状态 -1待发货 0全部发货 其他数量为剩余待发货数量
+     * 鐘舵€?-1寰呭彂璐?0鍏ㄩ儴鍙戣揣 鍏朵粬鏁伴噺涓哄墿浣欏緟鍙戣揣鏁伴噺
      */
     private Integer status;
     /**
-     * 订单确认收货获取的积分
+     * 璁㈠崟纭鏀惰揣鑾峰彇鐨勭Н鍒?
      */
     private Integer gainScore;
 //
 //    /**
-//     * 补贴的优惠金额
+//     * 琛ヨ创鐨勪紭鎯犻噾棰?
 //     */
 //    private Double subsidyAmount;
 
     /**
-     * 平台补贴的优惠金额
+     * 骞冲彴琛ヨ创鐨勪紭鎯犻噾棰?
      */
     private Double platformShareReduce;
 
     /**
-     * 分销佣金
+     * 鍒嗛攢浣i噾
      */
     private Double distributionAmount;
 
     /**
-     * 上级分销佣金
+     * 涓婄骇鍒嗛攢浣i噾
      */
     private Double distributionParentAmount;
 
     /**
-     * 单个orderItem的配送类型 1:快递 2:自提 3:无需快递
+     * 鍗曚釜orderItem鐨勯厤閫佺被鍨?1:蹇€?2:鑷彁 3锛氭棤闇€蹇€?
      */
     private Integer dvyType;
 
     /**
-     * 发货改变的数量
+     * 鍙戣揣鏀瑰彉鐨勬暟閲?
      */
     @TableField(exist = false)
     private Integer changeNum;
 
 
     /**
-     * 退款编号(退款编号为null时,说明订单为正常状态)
+     * 閫€娆剧紪鍙凤紙閫€娆剧紪鍙蜂负null鏃讹紝璇存槑璁㈠崟涓烘甯哥姸鎬侊級
      */
     @TableField(exist = false)
     private String refundSn;
 
     /**
-     * 退款状态
+     * 閫€娆剧姸鎬?
      */
     @TableField(exist = false)
     private Integer returnMoneySts;
 
     /**
-     * 订单减少金额
+     * 璁㈠崟鍑忓皯閲戦
      */
     @TableField(exist = false)
     private Double chageAmount;
@@ -206,13 +211,13 @@ public class OrderItem implements Serializable {
     private String spec;
 
     /**
-     * 海博商品ID
+     * 娴峰崥鍟嗗搧ID
      */
     @TableField(exist = false)
     private String hbSkuId;
 
     /**
-     * 商品编码
+     * 鍟嗗搧缂栫爜
      */
     @TableField(exist = false)
     private String skuCode;

+ 16 - 11
yami-shop-bean/src/main/java/com/yami/shop/bean/order/ConfirmOrderOrder.java

@@ -1,53 +1,58 @@
 /*
- * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
+ * Copyright (c) 2018-2999 骞垮窞浜氱背淇℃伅绉戞妧鏈夐檺鍏徃 All rights reserved.
  *
  * https://www.gz-yami.com/
  *
- * 未经允许,不可做商业用途!
+ * 鏈粡鍏佽锛屼笉鍙仛鍟嗕笟鐢ㄩ€旓紒
  *
- * 版权所有,侵权必究!
+ * 鐗堟潈鎵€鏈夛紝渚垫潈蹇呯┒锛?
  */
 
 package com.yami.shop.bean.order;
 
 /**
- * 提交订单事件先后顺序
+ * 鎻愪氦璁㈠崟浜嬩欢鍏堝悗椤哄簭
  * @author LGH
  */
 public interface ConfirmOrderOrder {
 
     /**
-     * 没有任何活动时的顺序
+     * 娌℃湁浠讳綍娲诲姩鏃剁殑椤哄簭
      */
     int DEFAULT = 0;
 
     /**
-     * 满减,排在DEFAULT后面
+     * 婊″噺锛屾帓鍦―EFAULT鍚庨潰
      */
     int DISCOUNT = 100;
 
     /**
-     * 优惠券,排在DISCOUNT后面
+     * 会员优惠,排在DISCOUNT后面
+     */
+    int MEMBER = 150;
+
+    /**
+     * 浼樻儬鍒革紝鎺掑湪DISCOUNT鍚庨潰
      */
     int COUPON = 200;
 
     /**
-     * 分销,排在COUPON后面
+     * 鍒嗛攢锛屾帓鍦–OUPON鍚庨潰
      */
     int DISTRIBUTION = 300;
 
     /**
-     * 平台优惠券
+     * 骞冲彴浼樻儬鍒?
      */
     int PLATFORM_COUPON = 400;
 
     /**
-     * 等级
+     * 绛夌骇
      */
     int LEVEL = 500;
 
     /**
-     * 积分
+     * 绉垎
      */
     int SCORE = 600;
 

+ 2 - 2
yami-shop-service/pom.xml

@@ -13,8 +13,8 @@
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-compiler-plugin</artifactId>
                 <configuration>
-                    <source>10</source>
-                    <target>10</target>
+                    <source>9</source>
+                    <target>9</target>
                 </configuration>
             </plugin>
         </plugins>

+ 17 - 0
yami-shop-service/src/main/java/com/yami/shop/service/XsbMemberSupportService.java

@@ -0,0 +1,17 @@
+package com.yami.shop.service;
+
+import com.yami.shop.bean.app.dto.ShopCartItemDto;
+import com.yami.shop.bean.dto.XsbMemberDiscountInfo;
+
+import java.util.List;
+
+public interface XsbMemberSupportService {
+
+    void enrichShopCartItems(List<ShopCartItemDto> shopCartItems, String userId);
+
+    XsbMemberDiscountInfo getMemberDiscountInfo(String userId);
+
+    boolean isXsbItem(ShopCartItemDto shopCartItem);
+
+    boolean hasXsbBusinessType(List<Long> skuIds);
+}

+ 30 - 78
yami-shop-service/src/main/java/com/yami/shop/service/impl/BasketServiceImpl.java

@@ -1,13 +1,3 @@
-/*
- * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
- *
- * https://www.gz-yami.com/
- *
- * 未经允许,不可做商业用途!
- *
- * 版权所有,侵权必究!
- */
-
 package com.yami.shop.service.impl;
 
 import cn.hutool.core.collection.CollectionUtil;
@@ -33,41 +23,36 @@ import com.yami.shop.service.BasketService;
 import com.yami.shop.service.ProductService;
 import com.yami.shop.service.ShopDetailService;
 import com.yami.shop.service.SkuService;
+import com.yami.shop.service.XsbMemberSupportService;
 import lombok.AllArgsConstructor;
-import org.apache.commons.lang3.ObjectUtils;
 import org.springframework.context.ApplicationContext;
 import org.springframework.stereotype.Service;
 
-import java.util.*;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 import java.util.stream.Collectors;
 
-/**
- * @author lgh on 2018/10/18.
- */
 @Service
 @AllArgsConstructor
 public class BasketServiceImpl extends ServiceImpl<BasketMapper, Basket> implements BasketService {
 
     private final BasketMapper basketMapper;
-
     private final CacheManagerUtil cacheManagerUtil;
-
     private final ApplicationContext applicationContext;
-
     private final SkuService skuService;
-
     private final ShopDetailService shopDetailService;
-
     private final ProductService productService;
+    private final XsbMemberSupportService xsbMemberSupportService;
 
     @Override
-//    @CacheEvict(cacheNames = "ShopCartItems", key = "#userId")
     public void deleteShopCartItemsByBasketIds(String userId, List<Long> basketIds) {
         basketMapper.deleteShopCartItemsByBasketIds(userId, basketIds);
     }
 
     @Override
-//    @CacheEvict(cacheNames = "ShopCartItems", key = "#userId")
     public void addShopCartItem(ChangeShopCartParam param, String userId) {
         Basket basket = new Basket();
         basket.setBasketCount(param.getCount());
@@ -77,44 +62,28 @@ public class BasketServiceImpl extends ServiceImpl<BasketMapper, Basket> impleme
         basket.setChannelId(param.getChannelId());
         basket.setUserId(userId);
         basket.setSkuId(param.getSkuId());
-//        basket.setDistributionCardNo(param.getDistributionCardNo());
         basketMapper.insert(basket);
     }
 
     @Override
-//    @CacheEvict(cacheNames = "ShopCartItems", key = "#basket.userId")
     public void updateShopCartItem(Basket basket) {
         basketMapper.updateById(basket);
     }
 
     @Override
-//    @CacheEvict(cacheNames = "ShopCartItems", key = "#userId")
     public void deleteAllShopCartItems(String userId) {
         basketMapper.deleteAllShopCartItems(userId);
     }
 
-//    @Override
-//    public List<ShopCartItemDto> getShopCartItems(Long channelId,String userId) {
-//        // 在这个类里面要调用这里的缓存信息,并没有使用aop,所以不使用注解
-//
-//        List<ShopCartItemDto> shopCartItemDtoList = basketMapper.getShopCartItems(userId);
-//        for (ShopCartItemDto shopCartItemDto : shopCartItemDtoList) {
-//            shopCartItemDto.setProductTotalAmount(Arith.mul(shopCartItemDto.getProdCount(), shopCartItemDto.getPrice()));
-//            shopCartItemDto.setWeight(shopCartItemDto.getWeight());
-//            shopCartItemDto.setWeightUnit(shopCartItemDto.getWeightUnit());
-//        }
-//        return shopCartItemDtoList;
-//    }
-
     @Override
     public List<ShopCartItemDto> getShopCartItems(String userId, Long channelId) {
-        // 在这个类里面要调用这里的缓存信息,并没有使用aop,所以不使用注解
         List<ShopCartItemDto> shopCartItemDtoList = basketMapper.getShopCartItemsByPlatform(userId, channelId);
         for (ShopCartItemDto shopCartItemDto : shopCartItemDtoList) {
             shopCartItemDto.setProductTotalAmount(Arith.mul(shopCartItemDto.getProdCount(), shopCartItemDto.getPrice()));
             shopCartItemDto.setWeight(shopCartItemDto.getWeight());
             shopCartItemDto.setWeightUnit(shopCartItemDto.getWeightUnit());
         }
+        xsbMemberSupportService.enrichShopCartItems(shopCartItemDtoList, userId);
         return shopCartItemDtoList;
     }
 
@@ -124,21 +93,18 @@ public class BasketServiceImpl extends ServiceImpl<BasketMapper, Basket> impleme
     }
 
     @Override
-//    @CacheEvict(cacheNames = "ShopCartItems", key = "#userId")
     public void cleanExpiryProdList(String userId) {
         basketMapper.cleanExpiryProdList(userId);
     }
 
     @Override
-//    @CacheEvict(cacheNames = "ShopCartItems", key = "#userId")
     public void updateBasketByShopCartParam(String userId, List<ShopCartParam> shopCartParams) {
         basketMapper.updateDiscountItemId(userId, shopCartParams);
     }
 
     @Override
-//    @CacheEvict(cacheNames = "ShopCartItems", key = "#userId")
     public void removeShopCartItemsCacheByUserId(String userId) {
-
+        // no-op
     }
 
     @Override
@@ -148,83 +114,69 @@ public class BasketServiceImpl extends ServiceImpl<BasketMapper, Basket> impleme
 
     @Override
     public List<ShopCartDto> getShopCarts(List<ShopCartItemDto> shopCartItems, Long shopId1) {
-        // 根据店铺ID划分item
-        Map<Long, List<ShopCartItemDto>> shopCartMap = shopCartItems.stream().collect(Collectors.groupingBy(ShopCartItemDto::getShopId));
+        Map<Long, List<ShopCartItemDto>> shopCartMap = shopCartItems.stream()
+                .collect(Collectors.groupingBy(ShopCartItemDto::getShopId));
         if (shopId1 != null && shopId1 > 0) {
-            List<ShopCartDto> shopCartDtos2 = Lists.newArrayList();
-            //获取店铺的所有商品项
-            List<ShopCartItemDto> shopCartItemDtoList2 = shopCartMap.get(shopId1);
-            if (shopCartItemDtoList2 != null) {
-                // 构建每个店铺的购物车信息
-                ShopCartDto shopCart2 = new ShopCartDto();
-                //店铺信息
-                shopCart2.setShopId(shopId1);
-                shopCart2.setShopName(shopCartItemDtoList2.get(0).getShopName());
-                applicationContext.publishEvent(new ShopCartEvent(shopCart2, shopCartItemDtoList2));
-                // 自营店的购物车位置是放在第一的
+            List<ShopCartDto> shopCartDtos = Lists.newArrayList();
+            List<ShopCartItemDto> shopCartItemDtoList = shopCartMap.get(shopId1);
+            if (shopCartItemDtoList != null) {
+                ShopCartDto shopCart = new ShopCartDto();
+                shopCart.setShopId(shopId1);
+                shopCart.setShopName(shopCartItemDtoList.get(0).getShopName());
+                applicationContext.publishEvent(new ShopCartEvent(shopCart, shopCartItemDtoList));
                 if (Objects.equals(1L, shopId1)) {
-                    shopCartDtos2.add(0, shopCart2);
+                    shopCartDtos.add(0, shopCart);
                 } else {
-                    shopCartDtos2.add(shopCart2);
+                    shopCartDtos.add(shopCart);
                 }
             }
-            return shopCartDtos2;
+            return shopCartDtos;
         }
-        // 返回一个店铺的所有信息
+
         List<ShopCartDto> shopCartDtos = Lists.newArrayList();
         for (Long shopId : shopCartMap.keySet()) {
-            //获取店铺的所有商品项
             List<ShopCartItemDto> shopCartItemDtoList = shopCartMap.get(shopId);
-            // 构建每个店铺的购物车信息
             ShopCartDto shopCart = new ShopCartDto();
-            //店铺信息
             shopCart.setShopId(shopId);
             shopCart.setShopName(shopCartItemDtoList.get(0).getShopName());
             applicationContext.publishEvent(new ShopCartEvent(shopCart, shopCartItemDtoList));
-            // 自营店的购物车位置是放在第一的
             if (Objects.equals(1L, shopId)) {
                 shopCartDtos.add(0, shopCart);
             } else {
                 shopCartDtos.add(shopCart);
             }
         }
-
         return shopCartDtos;
     }
 
     @Override
-    public List<ShopCartItemDto> getShopCartItemsByOrderItems(List<Long> basketId, OrderItemParam orderItem, String userId,Long channelId) {
+    public List<ShopCartItemDto> getShopCartItemsByOrderItems(List<Long> basketId, OrderItemParam orderItem, String userId, Long channelId) {
         if (orderItem == null && CollectionUtil.isEmpty(basketId)) {
             return Collections.emptyList();
         }
-        // 当立即购买时,没有提交的订单是没有购物车信息的
         if (CollectionUtil.isEmpty(basketId) && orderItem != null) {
-            return Collections.singletonList(getShopCartItem(orderItem));
+            List<ShopCartItemDto> directBuyItems = Collections.singletonList(getShopCartItem(orderItem));
+            xsbMemberSupportService.enrichShopCartItems(directBuyItems, userId);
+            return directBuyItems;
         }
 
-        List<ShopCartItemDto> dbShopCartItems = getShopCartItems(userId,channelId);
-
-        // 返回购物车选择的商品信息
-        List<ShopCartItemDto> collect = dbShopCartItems
-                .stream()
+        List<ShopCartItemDto> dbShopCartItems = getShopCartItems(userId, channelId);
+        return dbShopCartItems.stream()
                 .filter(shopCartItemDto -> basketId.contains(shopCartItemDto.getBasketId()))
                 .collect(Collectors.toList());
-        return collect;
     }
 
     @Override
     public ShopCartItemDto getShopCartItem(OrderItemParam orderItem) {
-        //Integer platform, Long shopId
         Sku sku = skuService.getSkuBySkuId(orderItem.getSkuId(), orderItem.getChannelId(), orderItem.getShopId());
         if (sku == null) {
-            throw new RuntimeException("订单包含无法识别的商品");
+            throw new RuntimeException("Order contains an unrecognized sku");
         }
         Product prod = productService.getProductByProdId(orderItem.getProdId());
         if (prod == null) {
-            throw new RuntimeException("订单包含无法识别的商品");
+            throw new RuntimeException("Order contains an unrecognized product");
         }
 
-        // 拿到购物车的所有item
         ShopCartItemDto shopCartItemDto = new ShopCartItemDto();
         shopCartItemDto.setBasketId(-1L);
         shopCartItemDto.setSkuId(orderItem.getSkuId());

Разница между файлами не показана из-за своего большого размера
+ 204 - 172
yami-shop-service/src/main/java/com/yami/shop/service/impl/OrderRefundServiceImpl.java


+ 176 - 0
yami-shop-service/src/main/java/com/yami/shop/service/impl/XsbMemberSupportServiceImpl.java

@@ -0,0 +1,176 @@
+package com.yami.shop.service.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.yami.shop.bean.app.dto.ShopCartItemDto;
+import com.yami.shop.bean.dto.XsbMemberDiscountInfo;
+import com.yami.shop.bean.model.User;
+import com.yami.shop.common.util.Arith;
+import com.yami.shop.common.util.HttpUtil;
+import com.yami.shop.service.UserService;
+import com.yami.shop.service.XsbMemberSupportService;
+import com.yami.shop.utils.SmqjhUtil;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.web.util.UriUtils;
+
+import java.math.BigDecimal;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class XsbMemberSupportServiceImpl implements XsbMemberSupportService {
+
+    private static final String XSB = "XSB";
+
+    private final UserService userService;
+    private final SmqjhUtil smqjhUtil;
+
+    @Override
+    public void enrichShopCartItems(List<ShopCartItemDto> shopCartItems, String userId) {
+        if (shopCartItems == null || shopCartItems.isEmpty()) {
+            return;
+        }
+        Map<String, String> businessTypeMap = queryBusinessTypeMap(shopCartItems);
+        XsbMemberDiscountInfo memberInfo = getMemberDiscountInfo(userId);
+        for (ShopCartItemDto shopCartItem : shopCartItems) {
+            String businessType = businessTypeMap.get(String.valueOf(shopCartItem.getSkuId()));
+            shopCartItem.setBusinessType(businessType);
+            shopCartItem.setMemberDiscountShareAmount(0.0);
+            if (!XSB.equalsIgnoreCase(businessType)) {
+                shopCartItem.setIsMember(Boolean.FALSE);
+                shopCartItem.setMemberPrice(null);
+                continue;
+            }
+            shopCartItem.setIsMember(Boolean.TRUE.equals(memberInfo.getMember()));
+            if (Boolean.TRUE.equals(memberInfo.getMember())) {
+                shopCartItem.setMemberPrice(calculateMemberPrice(shopCartItem.getPrice(), memberInfo.getDiscountRate()));
+            } else {
+                shopCartItem.setMemberPrice(null);
+            }
+        }
+    }
+
+    @Override
+    public XsbMemberDiscountInfo getMemberDiscountInfo(String userId) {
+        XsbMemberDiscountInfo emptyInfo = defaultMemberInfo();
+        if (StringUtils.isBlank(userId)) {
+            return emptyInfo;
+        }
+        User user = userService.getUserByUserId(userId);
+        if (user == null || StringUtils.isBlank(user.getUserMobile()) || StringUtils.isBlank(smqjhUtil.getSystemUrl())) {
+            return emptyInfo;
+        }
+        try {
+            String mobile = UriUtils.encodeQueryParam(user.getUserMobile(), StandardCharsets.UTF_8);
+            String response = HttpUtil.get(smqjhUtil.getSystemUrl() + "/sys-api/member/discount/mobile?mobile=" + mobile);
+            if (StringUtils.isBlank(response)) {
+                return emptyInfo;
+            }
+            JSONObject root = JSONObject.parseObject(response);
+            JSONObject data = root.getJSONObject("data");
+            if (data == null) {
+                return emptyInfo;
+            }
+            XsbMemberDiscountInfo info = new XsbMemberDiscountInfo();
+            info.setMember(Boolean.TRUE.equals(data.getBoolean("isMember")));
+            info.setDiscountRate(normalizeDiscountRate(data.getDouble("discountRate")));
+            info.setMemberTypeName(data.getString("memberTypeName"));
+            return info;
+        } catch (Exception e) {
+            log.warn("查询XSB会员折扣失败,userId={}", userId, e);
+            return emptyInfo;
+        }
+    }
+
+    @Override
+    public boolean isXsbItem(ShopCartItemDto shopCartItem) {
+        return shopCartItem != null && XSB.equalsIgnoreCase(shopCartItem.getBusinessType());
+    }
+
+    @Override
+    public boolean hasXsbBusinessType(List<Long> skuIds) {
+        if (CollectionUtils.isEmpty(skuIds)) {
+            return false;
+        }
+        return queryBusinessTypeMapBySkuIds(skuIds.stream()
+                        .filter(Objects::nonNull)
+                        .map(String::valueOf)
+                        .distinct()
+                        .collect(Collectors.toList()))
+                .values()
+                .stream()
+                .anyMatch(XSB::equalsIgnoreCase);
+    }
+
+    private Map<String, String> queryBusinessTypeMap(List<ShopCartItemDto> shopCartItems) {
+        if (CollectionUtils.isEmpty(shopCartItems)) {
+            return Collections.emptyMap();
+        }
+        List<String> skuIds = shopCartItems.stream()
+                .map(ShopCartItemDto::getSkuId)
+                .filter(Objects::nonNull)
+                .map(String::valueOf)
+                .distinct()
+                .collect(Collectors.toList());
+        return queryBusinessTypeMapBySkuIds(skuIds);
+    }
+
+    private Map<String, String> queryBusinessTypeMapBySkuIds(List<String> skuIds) {
+        if (StringUtils.isBlank(smqjhUtil.getSmqjhPmsUrl()) || CollectionUtils.isEmpty(skuIds)) {
+            return Collections.emptyMap();
+        }
+        try {
+            String response = HttpUtil.post(smqjhUtil.getSmqjhPmsUrl() + "/querySkuBusinessTypes", skuIds);
+            if (StringUtils.isBlank(response)) {
+                return Collections.emptyMap();
+            }
+            JSONObject root = JSONObject.parseObject(response);
+            JSONObject data = root.getJSONObject("data");
+            return data == null ? Collections.emptyMap() : data.getInnerMap().entrySet().stream()
+                    .collect(Collectors.toMap(Map.Entry::getKey, entry -> String.valueOf(entry.getValue()), (left, right) -> left));
+        } catch (Exception e) {
+            log.warn("查询SKU业务类型失败, skuIds={}", skuIds, e);
+            return Collections.emptyMap();
+        }
+    }
+
+    private Double calculateMemberPrice(Double basePrice, Double discountRate) {
+        if (basePrice == null) {
+            return null;
+        }
+        double normalizedRate = normalizeDiscountRate(discountRate);
+        BigDecimal price = BigDecimal.valueOf(basePrice);
+        BigDecimal memberPrice = price.multiply(BigDecimal.valueOf(normalizedRate)).setScale(2, BigDecimal.ROUND_HALF_UP);
+        if (memberPrice.compareTo(price) > 0) {
+            memberPrice = price;
+        }
+        if (memberPrice.compareTo(BigDecimal.ZERO) < 0) {
+            memberPrice = BigDecimal.ZERO;
+        }
+        return memberPrice.doubleValue();
+    }
+
+    private Double normalizeDiscountRate(Double discountRate) {
+        if (discountRate == null || discountRate <= 0 || discountRate > 1) {
+            return 1.0;
+        }
+        return discountRate;
+    }
+
+    private XsbMemberDiscountInfo defaultMemberInfo() {
+        XsbMemberDiscountInfo info = new XsbMemberDiscountInfo();
+        info.setMember(Boolean.FALSE);
+        info.setDiscountRate(1.0);
+        info.setMemberTypeName(null);
+        return info;
+    }
+}

+ 3 - 1
yami-shop-service/src/main/java/com/yami/shop/utils/SmqjhUtil.java

@@ -20,7 +20,9 @@ public class SmqjhUtil {
     @Value("${smqjh.pms-url}")
     private String smqjhPmsUrl;
 
-
+    @Getter
+    @Value("${smqjh.systemUrl:}")
+    private String systemUrl;
 
     @Getter
     @Value("${smqjh.omsBaseUrl}")

+ 1 - 0
yami-shop-service/src/main/resources/mapper/OrderItemMapper.xml

@@ -25,6 +25,7 @@
         <result column="basket_date" property="basketDate"/>
         <result column="distribution_card_no" property="distributionCardNo"/>
         <result column="share_reduce" jdbcType="DECIMAL" property="shareReduce"/>
+        <result column="member_discount_share_amount" jdbcType="DECIMAL" property="memberDiscountShareAmount"/>
         <result column="dvy_type" jdbcType="INTEGER" property="dvyType"/>
     </resultMap>
 

+ 8 - 0
yami-shop-service/src/main/resources/mapper/OrderMapper.xml

@@ -31,6 +31,8 @@
         <result column="is_payed" jdbcType="BIT" property="isPayed"/>
         <result column="delete_status" jdbcType="INTEGER" property="deleteStatus"/>
         <result column="refund_status" jdbcType="INTEGER" property="refundStatus"/>
+        <result column="member_discount_amount" jdbcType="DECIMAL" property="memberDiscountAmount"/>
+        <result column="member_discount_desc" jdbcType="VARCHAR" property="memberDiscountDesc"/>
         <result column="close_type" jdbcType="INTEGER" property="closeType"/>
         <result column="user_mobile" jdbcType="VARCHAR" property="userMobile"/>
         <result column="receiver" jdbcType="VARCHAR" property="receiver"/>
@@ -120,6 +122,8 @@
         <result column="hb_order_status" jdbcType="INTEGER" property="hbOrderStatus"/>
         <result column="delete_status" jdbcType="INTEGER" property="deleteStatus"/>
         <result column="refund_status" jdbcType="INTEGER" property="refundStatus"/>
+        <result column="member_discount_amount" jdbcType="DECIMAL" property="memberDiscountAmount"/>
+        <result column="member_discount_desc" jdbcType="VARCHAR" property="memberDiscountDesc"/>
         <result column="order_type" jdbcType="INTEGER" property="orderType"/>
         <result column="close_type" jdbcType="INTEGER" property="closeType"/>
         <result column="consignee_name" jdbcType="INTEGER" property="consigneeName"/>
@@ -146,6 +150,7 @@
             <result column="distribution_card_no" property="distributionCardNo"/>
             <result column="basket_date" property="basketDate"/>
             <result column="share_reduce" property="shareReduce"/>
+            <result column="member_discount_share_amount" property="memberDiscountShareAmount"/>
             <result column="distribution_amount" property="distributionAmount"/>
             <result column="distribution_parent_amount" property="distributionParentAmount"/>
             <result column="return_money_sts" property="returnMoneySts"/>
@@ -182,6 +187,8 @@
         <result column="delete_status" jdbcType="INTEGER" property="deleteStatus"/>
         <result column="pay_score" jdbcType="INTEGER" property="score"/>
         <result column="refund_status" jdbcType="INTEGER" property="refundStatus"/>
+        <result column="member_discount_amount" jdbcType="DECIMAL" property="memberDiscountAmount"/>
+        <result column="member_discount_desc" jdbcType="VARCHAR" property="memberDiscountDesc"/>
         <result column="close_type" jdbcType="INTEGER" property="closeType"/>
         <result column="shop_name" jdbcType="VARCHAR" property="shopName"/>
         <result column="pay_score" jdbcType="INTEGER" property="payScore"/>
@@ -223,6 +230,7 @@
             <result column="distribution_card_no" property="distributionCardNo"/>
             <result column="basket_date" property="basketDate"/>
             <result column="share_reduce" property="shareReduce"/>
+            <result column="member_discount_share_amount" property="memberDiscountShareAmount"/>
             <result column="platform_share_reduce" property="platformShareReduce"/>
             <result column="oi_return_money_sts" property="returnMoneySts"/>
             <result column="oi_status" property="status"/>

+ 8 - 0
yami-shop-service/src/main/resources/mapper/OrderRefundMapper.xml

@@ -107,6 +107,8 @@
         <result column="o_refund_status" property="refundStatus"/>
         <result column="freight_amount" property="freightAmount"/>
         <result column="offset_points" property="offsetPoints"/>
+        <result column="o_member_discount_amount" property="memberDiscountAmount"/>
+        <result column="o_member_discount_desc" property="memberDiscountDesc"/>
 
         <!-- 退货地址信息 -->
         <association property="refundDelivery" javaType="com.yami.shop.bean.model.RefundDelivery">
@@ -175,6 +177,8 @@
 
         <result column="freight_amount" property="freightAmount"/>
         <result column="offset_points" property="offsetPoints"/>
+        <result column="o_member_discount_amount" property="memberDiscountAmount"/>
+        <result column="o_member_discount_desc" property="memberDiscountDesc"/>
 
         <!-- 退货地址信息 -->
         <association property="refundDelivery" javaType="com.yami.shop.bean.model.RefundDelivery">
@@ -208,6 +212,8 @@
                o.pay_time        as o_pay_time,
                o.order_number    AS o_order_number,
                o.actual_total    AS o_actual_total,
+               o.member_discount_amount AS o_member_discount_amount,
+               o.member_discount_desc   AS o_member_discount_desc,
                o.hb_order_status AS o_status,
                s.pay_no          AS s_order_pay_no,
                sp.shop_name      AS shop_name,
@@ -230,6 +236,8 @@
         o.order_number AS o_order_number,
         o.pay_time as o_pay_time,
         o.actual_total AS o_actual_total,
+        o.member_discount_amount AS o_member_discount_amount,
+        o.member_discount_desc AS o_member_discount_desc,
         o.product_nums AS product_nums,
         o.hb_order_status AS o_status,
         o.dvy_type        as o_dvy_type,

+ 116 - 44
yami-shop-user/yami-shop-user-api/src/main/java/com/yami/shop/user/api/listener/ConfirmOrderListener.java

@@ -4,8 +4,10 @@ import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.yami.shop.bean.app.dto.*;
 import com.yami.shop.bean.app.param.OrderParam;
+import com.yami.shop.bean.event.ConfirmOrderEvent;
 import com.yami.shop.bean.event.PlatformConfirmOrderEvent;
 import com.yami.shop.bean.event.ScoreConfirmOrderEvent;
+import com.yami.shop.bean.dto.XsbMemberDiscountInfo;
 import com.yami.shop.bean.model.Category;
 import com.yami.shop.bean.model.UserExtension;
 import com.yami.shop.bean.order.ConfirmOrderOrder;
@@ -16,6 +18,7 @@ import com.yami.shop.security.api.util.SecurityUtils;
 import com.yami.shop.service.CategoryService;
 import com.yami.shop.service.SysConfigService;
 import com.yami.shop.service.UserExtensionService;
+import com.yami.shop.service.XsbMemberSupportService;
 import com.yami.shop.user.comment.dao.UserLevelMapper;
 import com.yami.shop.user.comment.model.UserLevel;
 import com.yami.shop.user.comment.util.CategoryScale;
@@ -26,11 +29,12 @@ import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Component;
 
 import javax.swing.text.StyledEditorKit;
+import java.math.BigDecimal;
 import java.util.*;
 import java.util.stream.Collectors;
 
 /**
- * 计算订单时的积分及成长值抵现和折扣信息
+ * 閻犱緤绱曢悾鑽ゆ媼閵忕姴绀嬮柡鍐ㄥ濞堟垹绮旈姘€婚柛娆忥攻閸ㄦ岸姊归崹顔瑰亾閸忕厧啸闁绘粍婢橀幏浼村箮濡鈷忓ǎ鍥e墲娴?
  */
 @Component("userConfirmOrderListener")
 @AllArgsConstructor
@@ -40,18 +44,19 @@ public class ConfirmOrderListener {
     private final SysConfigService sysConfigService;
     private final UserLevelMapper userLevelMapper;
     private final CategoryService categoryService;
+    private final XsbMemberSupportService xsbMemberSupportService;
 
     /**
-     * 计算积分抵现和分摊
+     * 閻犱緤绱曢悾鑽ょ矓椤栨艾鐎婚柟鍓佹暩楠炲洭宕仦钘夌€婚柟?
      */
     @EventListener(ScoreConfirmOrderEvent.class)
     @Order(ConfirmOrderOrder.SCORE)
     public void scoreSubmitOrderListener(ScoreConfirmOrderEvent event) {
         System.out.println(JSONObject.toJSONString(event));
-//        //获取用户等级积分详细表
+//        //闁兼儳鍢茶ぐ鍥偨閵婏箑鐓曠紒娑橆槺妤犲洨绮旈姘€婚悹鍥峰缁繒鎮?
 //        UserExtension extension = userExtensionService.getOne(
 //                new LambdaQueryWrapper<UserExtension>().eq(UserExtension::getUserId, SecurityUtils.getUser().getUserId()));
-//        //获取配置信息
+//        //闁兼儳鍢茶ぐ鍥煀瀹ュ洨鏋傚ǎ鍥e墲娴?
 //        ScoreConfigParam scoreParam = sysConfigService.getSysConfigObject(Constant.SCORE_CONFIG,ScoreConfigParam.class);
 //        if(Objects.nonNull(scoreParam)  && scoreParam.getShopScoreSwitch() != null && !scoreParam.getShopScoreSwitch()){
 //            return;
@@ -61,33 +66,33 @@ public class ConfirmOrderListener {
 //        if(orderParam.getUserUseScore() != null && orderParam.getUserUseScore() < 0 && extension.getScore() < 0){
 //            return;
 //        }
-//        //计算积分最多抵现金额
+//        //閻犱緤绱曢悾鑽ょ矓椤栨艾鐎婚柡鍫氬亾濠㈣埖纰嶆慨鐑芥偝娴兼潙娅ㄥΛ?
 //        double totalScoreAmount = 0.0;
 //        List<Category> categories = categoryService.listByShopId(Constant.PLATFORM_SHOP_ID);
 //        Map<Long, Double> categoryMap = CategoryScale.getScaleByCategory(categories,scoreParam,0);
-//        // 积分抵现金额可用上限 = 订单可使用积分比例 * ((实际总值)/100)
+//        // 缂佸鍨伴崹搴ㄥ箮閻㈤潧绠涢梺鍙夊灴椤ゅ倿宕i婊勬殢濞戞挸锕?= 閻犱降鍨瑰畷鐔煎矗椤栨瑥鈻忛柣顫妿琚ч柛鎺戞閻︻喗绗?* ((閻庡湱鍋ゅ顖炲箑鐠囨祴鍋?/100闁?
 //        if(scoreParam.getUseDiscountRange() == 0){
-//            // 如果有等级优惠金额,还需减去等级的优惠金额、运费才是实际金额,包邮时运费为0
+//            // 濠碘€冲€归悘澶愬嫉婢跺瞼鎼肩紒鐙欏倻鍠橀柟顖滃█閸g偓锛愬┑鎾剁閺夆晜锕㈠〒鍫曞礄韫囨挸绠电紒娑橆槺妤犲洭鎯冮崟顏嗗枠闁诡垳濞€閸g偓锛愬┑鍕ㄥ亾娴g晫绠ラ悹鎰潐婢х娀寮伴姘辨澖闂傚嫬鎳橀崳鐐紣濠垫挾绀夐柛鏍ф嚇閸嬫牠寮幆鎵閻犳劙鈧稖绀?
 //            double actualTotal = Arith.sub(shopCartOrderMergerDto.getActualTotal(),shopCartOrderMergerDto.getTotalTransfee());
 //            totalScoreAmount = Arith.div(Arith.mul(actualTotal, scoreParam.getUseDiscount()), 100);
 //        }else{
-//            //获取大类的比例并转成map
+//            //闁兼儳鍢茶ぐ鍥ㄥ緞瑜忕悮顐︽儍閸曨剛妲峰〒姘儏閼荤喐娼浣哥亣map
 //            for (ShopCartItemDto shopCartItem : event.getAllCartItem()) {
 //                if(!categoryMap.containsKey(shopCartItem.getCategoryId())) {
 //                    continue;
 //                }
-//                // 商品总额减去商家优惠、平台优惠,就是商品项的实际金额
+//                // 闁哥喎妫楅幖褔骞€婵犳凹鏉洪柛鎴濈箰楠炴捇宕崱妤婂晙濞村吋蓱閸庮剟濡存担鎼佹尙闁告瑩顣︾槐顓㈠箚閻欏懐绀夐悘蹇氶哺濡叉悂宕崱妤佹儌濡炪倕婀卞▓鎴犫偓鍦仱濡绢垶鏌岄幋锔绘澓
 //                double actualTotal = Arith.sub(Arith.sub(shopCartItem.getProductTotalAmount(), shopCartItem.getShareReduce()),shopCartItem.getPlatformShareReduce());
 //                double scoreReduce = Arith.div(Arith.mul(actualTotal, categoryMap.get(shopCartItem.getCategoryId())),100);
 //                totalScoreAmount = Arith.add(totalScoreAmount,scoreReduce);
 //            }
 //        }
-//        //计算用户可用积分 如果大于总共的积分使用比例直接使用,如果小于根据比例使用
+//        //閻犱緤绱曢悾濠氭偨閵婏箑鐓曢柛娆樺灣閺併倗绮旈姘€?濠碘€冲€归悘澶嬪緞瑜岀花顒勫箑鐠囨彃褰欓柣銊ュ琚ч柛鎺戞婵炲洭鎮介妸锔炬Х濞撴艾顑囧ú鍧楀箳閵夈倕鈻忛柣銏╃厜缁辨繃淇婇崒娑氫函閻忓繐绻嬬花顒勫冀鐟欏嫬绁︽慨锝嗘煣缁躲儲鎷呯捄銊︽殢
 //        int canUseScore = (int) Arith.mul(totalScoreAmount, scoreParam.getShopUseScore());
 ////        totalScoreAmount = Arith.div(canUseScore, scoreParam.getShopUseScore(),2);
 //        Integer userUseScore = extension.getScore();
 //        Integer totalUsableScore = extension.getScore();
-//        //如果是用户选择的积分数额,则用此积分数额
+//        //濠碘€冲€归悘澶愬及椤栨粍鏆忛柟瀵稿厴閳ь剙顦扮€氥劑鎯冮崟顓夋繈宕氶崱妯绘濡増绻愮槐婵嬪礆濞嗘垶鏆忔慨婵勫€楄ⅶ闁告帒妫欓弳鐔革紣?
 //        if(orderParam.getUserUseScore() != null && orderParam.getIsScorePay() == 1 && orderParam.getUserUseScore() >= 0){
 //            userUseScore = Math.min(orderParam.getUserUseScore(),userUseScore);
 //        }else{
@@ -99,19 +104,19 @@ public class ConfirmOrderListener {
 //        }
 //        int maxScore = Math.min(totalUsableScore,canUseScore);
 //        userUseScore = Math.min(userUseScore, canUseScore);
-//        // 如果为大于100的比例,则积分需要整10使用
+//        // 濠碘€冲€归悘澶嬬▔閸濆嫨浜eù?00闁汇劌瀚惁顔界瑹鐎e墎绀夐柛鎺撶懅琚ч柛鎺戞濞撳墎鎲版担瑙勬10濞达綀娉曢弫?
 //        if(scoreParam.getShopUseScore() > 100){
 //            userUseScore = userUseScore - userUseScore % 10;
 //            maxScore = maxScore - maxScore % 10;
 //        }
-//        // 计算最大可抵扣金额,并且如果小数大于两位四舍五入,还需在计算一遍实际使用积分
+//        // 閻犱緤绱曢悾濠氬嫉閳ь剚寰勮瑜版煡骞庨崹顐⑩拸闂佸弶鍨块·鍌炴晬鐏炲€熷珯濞戞挻鏌ㄩ々褔寮稿鍐瘓闁轰焦婢橀妵鍥ㄧ鎼存繆鈷堝ù锝呯Т濞叉捇鎳滃鍕畨闁稿繈鍎荤槐婵囨交濮椻偓濞撳爼宕烽妸顭戝悁缂佺姵銇炵粩鎾焼瀹ュ懐鏉介梻鍕噸婵炲洭鎮介妸顬繈宕?
 //        totalScoreAmount = Arith.div(userUseScore,scoreParam.getShopUseScore(),2);
 //        userUseScore = (int) Arith.mul(totalScoreAmount, scoreParam.getShopUseScore());
-//        //用户选择积分抵现,组装积分信息
+//        //闁活潿鍔嶉崺娑㈡焻婢跺顏ョ紒澶樺灠閸ㄥ酣骞庨悽闈涚疀闁挎稑鐬肩划宥囨啑閸涱垍婵嬪礆閸℃洑绻嗛柟?
 //        List<ShopCartOrderDto> shopCartOrders = shopCartOrderMergerDto.getShopCartOrders();
 //        double totalScoreReduce = 0.0;
 //        int totalScore = 0;
-//        //通过for i找出最后一项,将计算偏差的1积分给最后的最大的一项
+//        //闂侇偅淇虹换鍍╫r i闁瑰灚鍎抽崵顓㈠嫉閳ь剟宕ユ惔婵堫伇濡炪倗娅㈢槐婵堜焊閸℃凹鍚€缂佺姵顨呮禍绋款啅椤旂偓鐣?缂佸鍨伴崹搴g磼濞嗘劖浠橀柛姘捣濞堟垿寮甸埀顒佸緞瑜忓▓鎴炵▔閳ь剚銇?
 //        for (int shopIndex = 0; shopIndex < shopCartOrders.size(); shopIndex++) {
 //            ShopCartOrderDto shopCartOrder = shopCartOrders.get(shopIndex);
 //            double reduceSum = 0.0;
@@ -122,9 +127,9 @@ public class ConfirmOrderListener {
 //                for (int itemIndex = 0; itemIndex< shopCartItems.size(); itemIndex++) {
 //                    ShopCartItemDto shopCartItem = shopCartItems.get(itemIndex);
 //                    double scoreReduceProd = 0.0;
-//                    //判断是否最后一项
+//                    //闁告帇鍊栭弻鍥及椤栨碍鍎婇柡鍫氬亾闁告艾绨肩粩瀛樸亜?
 //                    boolean isEnd =  shopIndex == shopCartOrders.size() - 1 && discountIndex ==shopCartItemDiscounts.size() - 1 && itemIndex == shopCartItems.size() - 1;
-//                    //计算商品分摊的金额,需要乘以比例
+//                    //閻犱緤绱曢悾濠氬疮閸℃鎯傞柛鎺戞閹诧繝鎯冮崟顖氭濡増绻愮槐婵嬫閳ь剛鎲版担椋庮啋濞寸姰鍎查惁顔界瑹?
 //                    if(scoreParam.getUseDiscountRange() == 0){
 //                        scoreReduceProd = Arith.div(Arith.mul(shopCartItem.getActualTotal(),scoreParam.getUseDiscount()),100,2);
 //                    }else if(categoryMap.containsKey(shopCartItem.getCategoryId())){
@@ -132,9 +137,9 @@ public class ConfirmOrderListener {
 //                    }
 //                    int useScore = (int) Arith.mul(Arith.round(Arith.mul(scoreReduceProd,scale),2), scoreParam.getShopUseScore());
 //                    scoreReduceProd = Arith.div(useScore, scoreParam.getShopUseScore(),2);
-//                    //如果大于可用上限则直接等于,或者如果是最后一项直接将剩余的抵扣金额全部赋予最后一个,积分和金额直接等于 使用的 - 已经抵扣的
+//                    //濠碘€冲€归悘澶嬪緞瑜岀花顒勫矗椤栨粍鏆忓☉鎾筹躬濡炬椽宕氬▎鎴炵函闁规亽鍎抽悺鎴炵鎼搭垳绀夐柟瀛樼墳閳ь剙鎳庨々褔寮稿鍕﹂柡鍫氬亾闁告艾绨肩粩瀛樸亜閸︻厽绾柟鎭掑劚閻ㄣ垽宕滈埡鈧紞鎴︽儍閸曨剙啸闁圭缍侀崳鐐紣濠靛棗寮块梺顔哄姀缁佸瓨绂嶉崼鐔镐粯闁告艾绨肩粩瀛樼▔椤忓海绀夌紒澶樺灠閸ㄥ酣宕畝鍕濡増绻勫ú鍧楀箳閵壯呮惣濞?濞达綀娉曢弫銈夋儍?- 鐎规瓕灏欑划锟犲箮閸偄鈷忛柣?
 //                    if(Arith.add(totalScoreReduce,scoreReduceProd) > totalScoreAmount || isEnd){
-//                        //减去当前总共的积分,减去店铺已分摊的积分
+//                        //闁告垵绻愰獮鎾广亹閹惧啿顤呴柟顒冾嚙閸欙繝鎯冮崟顓夋繈宕氶崱顓犵闁告垵绻愰獮鎾存償濡ゅ懏鎳欑€瑰憡褰冮崹搴ㄥ箺婵犲嫭鐣辩紒澶樺灠閸?
 //                        useScore = userUseScore - totalScore - shopScore;
 //                        scoreReduceProd = Arith.sub(totalScoreAmount ,totalScoreReduce);
 //                    }
@@ -152,19 +157,19 @@ public class ConfirmOrderListener {
 //                    }
 //                }
 //            }
-//            //设置店铺的实际总值、积分优惠金额和订单优惠金额
+//            //閻犱礁澧介悿鍡樻償濡ゅ懏鎳欓柣銊ュ閻ゅ嫰姊介崨顔瑰亾鐠囨祴鍋撶粭琛″亾娴g洅婵嬪礆閸℃洜鍠橀柟顖滃█閸g偓锛愬┑鍡樺閻犱降鍨瑰畷鐔稿濡鍔曢梺鍙夊灴椤?
 //            shopCartOrder.setScoreReduce(reduceSum);
 //            shopCartOrder.setActualTotal(Arith.sub(shopCartOrder.getActualTotal(),reduceSum));
-//            //放入优惠金额
+//            //闁衡偓閹冨汲濞村吋蓱閸庮剟鏌岄幋锔绘澓
 //            shopCartOrder.setShopReduce(Arith.add(shopCartOrder.getShopReduce(),reduceSum));
-//            //放入平台优惠金额,如果用户等级免自营店运费也要放进去
+//            //闁衡偓閹冨汲妤犵偛鍟胯ぐ瀛樺濡鍔曢梺鍙夊灴椤?濠碘€冲€归悘澶愭偨閵婏箑鐓曠紒娑橆槺妤犲洭宕楀鍫濇闁解偓閵夈儳鏆楅弶鈺傚姌閸ㄥ倹绋婇悢娲绘矗闁衡偓閹规劗绠婚柛?
 //            shopCartOrder.setPlatformAmount(Arith.add(shopCartOrder.getPlatformAmount(),reduceSum));
 //            totalScore += shopScore;
 //            if (orderParam.getIsScorePay() != null && orderParam.getIsScorePay() == 1) {
 //                shopCartOrder.setUseScore(shopScore);
 //            }
 //        }
-//        //设置订单的实际总值和订单优惠金额
+//        //閻犱礁澧介悿鍡欐媼閵忕姴绀嬮柣銊ュ閻ゅ嫰姊介崨顔瑰亾鐠囨祴鍋撻悡搴㈠閻犱降鍨瑰畷鐔稿濡鍔曢梺鍙夊灴椤?
 //        shopCartOrderMergerDto.setTotalScoreAmount(totalScoreReduce);
 //        shopCartOrderMergerDto.setShopUseScore(scoreParam.getShopUseScore());
 //        shopCartOrderMergerDto.setTotalUsableScore(totalScore);
@@ -177,7 +182,74 @@ public class ConfirmOrderListener {
     }
 
     /**
-     * 计算等级折扣比例和分摊比例
+     * Apply member discount for XSB mall items only.
+     */
+    @EventListener(ConfirmOrderEvent.class)
+    @Order(ConfirmOrderOrder.MEMBER)
+    public void memberDiscountConfirmOrderListener(ConfirmOrderEvent event) {
+        ShopCartOrderDto shopCartOrderDto = event.getShopCartOrderDto();
+        List<ShopCartItemDto> xsbItems = event.getShopCartItems().stream()
+                .filter(xsbMemberSupportService::isXsbItem)
+                .filter(item -> Boolean.TRUE.equals(item.getIsMember()))
+                .filter(item -> item.getMemberPrice() != null)
+                .collect(Collectors.toList());
+        if (CollectionUtils.isEmpty(xsbItems)) {
+            return;
+        }
+        Double memberDiscountRate = resolveMemberDiscountRate();
+        double memberReduce = 0.0;
+        for (ShopCartItemDto shopCartItem : xsbItems) {
+            double productTotal = shopCartItem.getProductTotalAmount() == null ? 0.0 : shopCartItem.getProductTotalAmount();
+            double memberTotal = Arith.mul(shopCartItem.getMemberPrice(), shopCartItem.getProdCount());
+            double reduceAmount = Arith.round(Arith.sub(productTotal, memberTotal), 2);
+            if (reduceAmount < 0) {
+                reduceAmount = 0.0;
+            }
+            if (reduceAmount > productTotal) {
+                reduceAmount = productTotal;
+            }
+            if (reduceAmount <= 0) {
+                shopCartItem.setMemberDiscountShareAmount(0.0);
+                continue;
+            }
+            shopCartItem.setMemberDiscountShareAmount(reduceAmount);
+            shopCartItem.setShareReduce(Arith.add(shopCartItem.getShareReduce(), reduceAmount));
+            shopCartItem.setActualTotal(Arith.sub(shopCartItem.getActualTotal(), reduceAmount));
+            memberReduce = Arith.add(memberReduce, reduceAmount);
+        }
+        if (memberReduce <= 0) {
+            return;
+        }
+        shopCartOrderDto.setMemberDiscountAmount(memberReduce);
+        shopCartOrderDto.setMemberDiscountDesc("Member discount");
+        shopCartOrderDto.setMemberDiscountRate(memberDiscountRate);
+        shopCartOrderDto.setMemberBenefitDesc(buildMemberBenefitDesc(memberDiscountRate));
+        shopCartOrderDto.setActualTotal(Arith.sub(shopCartOrderDto.getActualTotal(), memberReduce));
+        shopCartOrderDto.setShopReduce(Arith.add(shopCartOrderDto.getShopReduce(), memberReduce));
+    }
+
+    private Double resolveMemberDiscountRate() {
+        XsbMemberDiscountInfo memberInfo = xsbMemberSupportService.getMemberDiscountInfo(SecurityUtils.getUser().getUserId());
+        if (memberInfo == null || !Boolean.TRUE.equals(memberInfo.getMember())) {
+            return null;
+        }
+        Double discountRate = memberInfo.getDiscountRate();
+        if (discountRate == null || discountRate <= 0 || discountRate >= 1) {
+            return null;
+        }
+        return discountRate;
+    }
+
+    private String buildMemberBenefitDesc(Double memberDiscountRate) {
+        if (memberDiscountRate == null) {
+            return "会员权益";
+        }
+        BigDecimal discountValue = BigDecimal.valueOf(memberDiscountRate).multiply(BigDecimal.TEN).stripTrailingZeros();
+        return "会员权益(" + discountValue.toPlainString() + "折)";
+    }
+
+    /**
+     * Apply original level discount logic.
      */
     @EventListener(PlatformConfirmOrderEvent.class)
     @Order(ConfirmOrderOrder.LEVEL)
@@ -193,8 +265,8 @@ public class ConfirmOrderListener {
         }
         ShopCartOrderMergerDto shopCartOrderMergerDto = event.getShopCartOrderMergerDto();
         List<ShopCartOrderDto> shopCartOrders = shopCartOrderMergerDto.getShopCartOrders();
-        //获取分类比例
-        //最后计算成长值折扣
+        //闁兼儳鍢茶ぐ鍥礆閸℃瑨顫︽慨锝嗘煣缁?
+        //闁哄牃鍋撻柛姘唉椤撳摜绮诲Δ浣哥亣闂傗偓閸喒鍋撻崗鐓庮潙闁?
         if (extension.getLevel() == null) {
             extension.setLevel(Constant.USER_LEVEL_INIT);
         }
@@ -203,18 +275,18 @@ public class ConfirmOrderListener {
 //        double levelDiscountActualTotal= 0.0;
         double discount = Arith.sub(10, level.getDiscount());
 
-        //将分类转成map
+        //閻忓繐妫楅崹搴g尵閺勫繑绁柟瀛樹粣ap
         List<Long> categoryIds = level.getCategoryIds();
         Map<Long, Long> categoryMap = new HashMap<>(100);
         if (CollectionUtils.isNotEmpty(categoryIds)) {
             categoryIds.forEach(categoryId -> categoryMap.put(categoryId, categoryId));
         }
-        //计算折扣总额
+        //閻犱緤绱曢悾濠氬箮濡鈷忛柟顒€顭烽·?
         double maxlevelFeeTotal = getLevelFeeTotal(shopCartOrders, level, categoryMap);
-        //通过for i找出最后一项,将计算偏差的1积分给最后的最大的一项
+        //闂侇偅淇虹换鍍╫r i闁瑰灚鍎抽崵顓㈠嫉閳ь剟宕ユ惔婵堫伇濡炪倗娅㈢槐婵堜焊閸℃凹鍚€缂佺姵顨呮禍绋款啅椤旂偓鐣?缂佸鍨伴崹搴g磼濞嗘劖浠橀柛姘捣濞堟垿寮甸埀顒佸緞瑜忓▓鎴炵▔閳ь剚銇?
         for (int shopIndex = 0; shopIndex < shopCartOrders.size(); shopIndex++) {
             ShopCartOrderDto shopCartOrder = shopCartOrders.get(shopIndex);
-            //如果可用范围为自营店不为当前店铺直接下一次循环
+            //濠碘€冲€归悘澶愬矗椤栨粍鏆忛柤鐓庡暙濞叉寧绋夋ウ鍨闁解偓閵夈儳鏆楀☉鎾崇С鐠愮喕銇愰幘鍐差枀閹煎瓨顨婇幗鐢告儎鐎涙ê澶嶅☉鎾愁儎缁旀潙鈻庨垾铏剷闁?
             if (level.getDiscountRange() == 1 && !Objects.equals(shopCartOrder.getShopId(), 1L)) {
                 continue;
             }
@@ -225,25 +297,25 @@ public class ConfirmOrderListener {
                 for (int itemIndex = 0; itemIndex < shopCartItems.size(); itemIndex++) {
                     ShopCartItemDto shopCartItem = shopCartItems.get(itemIndex);
                     double prodDiscount = 0.0;
-                    //判断是否最后一项
+                    //闁告帇鍊栭弻鍥及椤栨碍鍎婇柡鍫氬亾闁告艾绨肩粩瀛樸亜?
                     boolean isEnd = shopIndex == shopCartOrders.size() - 1 && discountIndex == shopCartItemDiscounts.size() - 1 && itemIndex == shopCartItems.size() - 1;
-                    //折扣
+                    //闁硅埖蓱婢?
                     if (level.getDiscountType() == 0 || categoryMap.containsKey(shopCartItem.getCategoryId())) {
                         prodDiscount = Arith.div(Arith.mul(shopCartItem.getActualTotal(), discount), 10, 2);
                         if (isEnd || Arith.add(Arith.add(levelDiscount, reduceSum), prodDiscount) > maxlevelFeeTotal) {
-                            //总折扣金额减去当前累计的折扣金额,就为最后一件商品分摊的等级优惠金额
+                            //闁诡剛绮慨宀勫箥閿濆娅ㄥΛ鐗堢箓閸f椽宕㈢拠鑼Ъ闁告挸绉堕悿顔炬媼閿涘嫭鐣遍柟鑸瞪戞晶鎼佹煂閹达富鏉洪柨娑樿嫰濮樸劍绋夐悜妯讳粯闁告艾绨肩粩瀛樼鐠虹儤娅岄柛婵呯閸ㄥ酣骞楁繝鍕暠缂佹稑顦辨鍥ㄥ濡鍔曢梺鍙夊灴椤?
                             prodDiscount = Arith.sub(Arith.sub(maxlevelFeeTotal, levelDiscount), reduceSum);
                         }
                     }
-                    //计算商品分摊的金额
+                    //閻犱緤绱曢悾濠氬疮閸℃鎯傞柛鎺戞閹诧繝鎯冮崟顖氭濡?
                     shopCartItem.setPlatformShareReduce(Arith.add(shopCartItem.getPlatformShareReduce(), prodDiscount));
                     reduceSum = Arith.add(reduceSum, Arith.round(prodDiscount, 2));
                 }
             }
-            //设置店铺的实际总值、积分优惠金额和订单优惠金额
+            //閻犱礁澧介悿鍡樻償濡ゅ懏鎳欓柣銊ュ閻ゅ嫰姊介崨顔瑰亾鐠囨祴鍋撶粭琛″亾娴g洅婵嬪礆閸℃洜鍠橀柟顖滃█閸g偓锛愬┑鍡樺閻犱降鍨瑰畷鐔稿濡鍔曢梺鍙夊灴椤?
             shopCartOrder.setLevelReduce(reduceSum);
             levelDiscount = Arith.add(levelDiscount, reduceSum);
-            //判断用户等级是否自营店包邮
+            //闁告帇鍊栭弻鍥偨閵婏箑鐓曠紒娑橆槺妤犲洭寮伴姘剨闁煎浜i幆鈧幖瀛橆殔鐎垫﹢鏌?
             //&& level.getCategoryIds()
             if (Objects.equals(shopCartOrder.getShopId(), Constant.MAIN_SHOP) && level.getIsFreeFee() == 1) {
                 freeTransfee = shopCartOrder.getTransfee();
@@ -252,22 +324,22 @@ public class ConfirmOrderListener {
             }
         }
         shopCartOrderMergerDto.setTotalLevelAmount(levelDiscount);
-        //设置运费优惠金额
+        //閻犱礁澧介悿鍡樻交閹邦垰鐎ù鍏忌戦崕顒勬煂閹达富鏉?
         shopCartOrderMergerDto.setFreeTransfee(freeTransfee);
     }
 
     /**
-     * 计算出总共可以折扣的金额
+     * 閻犱緤绱曢悾濠氬礄閻戞ǚ鍋撶拠鎻掑綑闁告瑯鍨禍鎺楀箮濡鈷忛柣銊ュ閸g偓锛?
      *
-     * @param shopCartOrders 全部商品项
-     * @param level          等级
-     * @param categoryMap    分类
-     * @return 总折扣金额
+     * @param shopCartOrders 闁稿繈鍔戦崕鎾疮閸℃鎯傚?
+     * @param level          缂佹稑顦辨?
+     * @param categoryMap    闁告帒妫涚悮?
+     * @return 闁诡剛绮慨宀勫箥閿濆娅ㄥΛ?
      */
     private double getLevelFeeTotal(List<ShopCartOrderDto> shopCartOrders, UserLevel level, Map<Long, Long> categoryMap) {
         double totalFee = 0.0;
         for (ShopCartOrderDto shopCartOrder : shopCartOrders) {
-            //如果可用范围为自营店不为当前店铺直接下一次循环
+            //濠碘€冲€归悘澶愬矗椤栨粍鏆忛柤鐓庡暙濞叉寧绋夋ウ鍨闁解偓閵夈儳鏆楀☉鎾崇С鐠愮喕銇愰幘鍐差枀閹煎瓨顨婇幗鐢告儎鐎涙ê澶嶅☉鎾愁儎缁旀潙鈻庨垾铏剷闁?
             if (level.getDiscountRange() == 1 && !Objects.equals(shopCartOrder.getShopId(), 1L)) {
                 continue;
             }
@@ -275,7 +347,7 @@ public class ConfirmOrderListener {
             for (ShopCartItemDiscountDto shopCartItemDiscount : shopCartItemDiscounts) {
                 List<ShopCartItemDto> shopCartItems = shopCartItemDiscount.getShopCartItems();
                 for (ShopCartItemDto shopCartItem : shopCartItems) {
-                    //折扣
+                    //闁硅埖蓱婢?
                     if (level.getDiscountType() == 0 || categoryMap.containsKey(shopCartItem.getCategoryId())) {
                         totalFee = Arith.add(totalFee, shopCartItem.getActualTotal());
                     }

Некоторые файлы не были показаны из-за большого количества измененных файлов