Browse Source

Merge remote-tracking branch 'origin/feature/mall_product' into feature/mall_product

owen 1 year ago
parent
commit
b7359706db
71 changed files with 815 additions and 913 deletions
  1. 24 0
      yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/number/NumberUtils.java
  2. 0 44
      yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/spring/SpringExpressionUtils.java
  3. 3 3
      yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/AfterSaleStatusEnum.java
  4. 2 2
      yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/AfterSaleTypeEnum.java
  5. 2 2
      yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/AfterSaleWayEnum.java
  6. 18 43
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/AfterSaleController.java
  7. 2 2
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/AfterSaleBaseVO.java
  8. 9 8
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/AfterSaleDetailRespVO.java
  9. 1 1
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/AfterSaleDisagreeReqVO.java
  10. 7 7
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/AfterSalePageReqVO.java
  11. 1 1
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/AfterSaleRefuseReqVO.java
  12. 1 1
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/AfterSaleRespPageItemVO.java
  13. 1 9
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/log/AfterSaleLogRespVO.java
  14. 9 1
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/config/TradeConfigController.java
  15. 4 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/config/vo/TradeConfigBaseVO.java
  16. 3 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/config/vo/TradeConfigRespVO.java
  17. 4 1
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateChargeBaseVO.java
  18. 2 3
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateCreateReqVO.java
  19. 2 2
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateDetailRespVO.java
  20. 1 1
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateFreeBaseVO.java
  21. 2 28
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateUpdateReqVO.java
  22. 13 20
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/AppAfterSaleController.java
  23. 3 3
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppAfterSaleCreateReqVO.java
  24. 1 1
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppAfterSaleDeliveryReqVO.java
  25. 1 1
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppAfterSaleRespVO.java
  26. 6 2
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/config/AppTradeConfigController.java
  27. 10 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/config/vo/AppTradeConfigRespVO.java
  28. 18 37
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/delivery/AppDeliverPickUpStoreController.java
  29. 2 2
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/delivery/vo/pickup/AppDeliveryPickUpStoreRespVO.java
  30. 25 26
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/aftersale/AfterSaleConvert.java
  31. 15 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/aftersale/AfterSaleLogConvert.java
  32. 9 12
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java
  33. 17 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryPickUpStoreConvert.java
  34. 1 1
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderLogConvert.java
  35. 7 7
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/AfterSaleDO.java
  36. 13 6
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/AfterSaleLogDO.java
  37. 5 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/config/TradeConfigDO.java
  38. 2 2
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java
  39. 16 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/aftersale/AfterSaleLogMapper.java
  40. 51 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/aftersale/AfterSaleMapper.java
  41. 0 9
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/aftersale/TradeAfterSaleLogMapper.java
  42. 0 51
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/aftersale/TradeAfterSaleMapper.java
  43. 18 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/redis/RedisKeyConstants.java
  44. 11 3
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/redis/no/TradeNoRedisDAO.java
  45. 2 2
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersale/config/AfterSaleLogConfiguration.java
  46. 3 14
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersale/core/annotations/AfterSaleLog.java
  47. 133 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersale/core/aop/AfterSaleLogAspect.java
  48. 3 11
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersale/core/utils/AfterSaleLogUtils.java
  49. 0 122
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersalelog/core/aop/AfterSaleLogAspect.java
  50. 0 54
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersalelog/core/dto/TradeAfterSaleLogCreateReqDTO.java
  51. 0 34
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersalelog/core/service/AfterSaleLogService.java
  52. 2 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/annotations/TradeOrderLog.java
  53. 2 2
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/aop/TradeOrderLogAspect.java
  54. 34 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleLogService.java
  55. 36 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleLogServiceImpl.java
  56. 16 16
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleService.java
  57. 79 132
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleServiceImpl.java
  58. 57 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/bo/AfterSaleLogCreateReqBO.java
  59. 44 77
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java
  60. 4 5
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryService.java
  61. 2 2
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryServiceImpl.java
  62. 3 3
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java
  63. 1 1
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/bo/logger/TradeOrderLogCreateReqBO.java
  64. 34 34
      yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleServiceTest.java
  65. 1 1
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/redis/RedisKeyConstants.java
  66. 11 3
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/redis/no/PayNoRedisDAO.java
  67. 4 26
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/AreaController.java
  68. 0 19
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/vo/AreaNodeSimpleRespVO.java
  69. 0 13
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/ip/AreaConvert.java
  70. 1 0
      yudao-server/src/main/resources/application-dev.yaml
  71. 1 0
      yudao-server/src/main/resources/application-local.yaml

+ 24 - 0
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/number/NumberUtils.java

@@ -13,4 +13,28 @@ public class NumberUtils {
         return StrUtil.isNotEmpty(str) ? Long.valueOf(str) : null;
     }
 
+    /**
+     * 通过经纬度获取地球上两点之间的距离
+     *
+     * 参考 <<a href="https://gitee.com/dromara/hutool/blob/1caabb586b1f95aec66a21d039c5695df5e0f4c1/hutool-core/src/main/java/cn/hutool/core/util/DistanceUtil.java">DistanceUtil</a>> 实现,目前它已经被 hutool 删除
+     *
+     * @param lat1 经度1
+     * @param lng1 纬度1
+     * @param lat2 经度2
+     * @param lng2 纬度2
+     * @return 距离,单位:千米
+     */
+    public static double getDistance(double lat1, double lng1, double lat2, double lng2) {
+        double radLat1 = lat1 * Math.PI / 180.0;
+        double radLat2 = lat2 * Math.PI / 180.0;
+        double a = radLat1 - radLat2;
+        double b = lng1 * Math.PI / 180.0 - lng2 * Math.PI / 180.0;
+        double distance = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
+                + Math.cos(radLat1) * Math.cos(radLat2)
+                * Math.pow(Math.sin(b / 2), 2)));
+        distance = distance * 6378.137;
+        distance = Math.round(distance * 10000d) / 10000d;
+        return distance;
+    }
+
 }

+ 0 - 44
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/spring/SpringExpressionUtils.java

@@ -3,7 +3,6 @@ package cn.iocoder.yudao.framework.common.util.spring;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.ArrayUtil;
-import org.aspectj.lang.JoinPoint;
 import org.aspectj.lang.ProceedingJoinPoint;
 import org.aspectj.lang.reflect.MethodSignature;
 import org.springframework.core.DefaultParameterNameDiscoverer;
@@ -87,47 +86,4 @@ public class SpringExpressionUtils {
         return result;
     }
 
-    /**
-     * JoinPoint 切面 批量解析 EL 表达式,转换 jspl参数
-     *
-     * @param joinPoint         切面点
-     * @param info              返回值
-     * @param expressionStrings EL 表达式数组
-     * @return Map<String, Object> 结果
-     * @author 陈賝
-     * @since 2023/6/18 11:20
-     */
-    // TODO @chenchen: 这个方法,和 parseExpressions 比较接近,是不是可以合并下;
-    public static Map<String, Object> parseExpression(JoinPoint joinPoint, Object info, List<String> expressionStrings) {
-        // 如果为空,则不进行解析
-        if (CollUtil.isEmpty(expressionStrings)) {
-            return MapUtil.newHashMap();
-        }
-
-        // 第一步,构建解析的上下文 EvaluationContext
-        // 通过 joinPoint 获取被注解方法
-        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
-        Method method = signature.getMethod();
-        // 使用 spring 的 ParameterNameDiscoverer 获取方法形参名数组
-        String[] parameterNames = PARAMETER_NAME_DISCOVERER.getParameterNames(method);
-        // Spring 的表达式上下文对象
-        EvaluationContext context = new StandardEvaluationContext();
-        if (ArrayUtil.isNotEmpty(parameterNames)) {
-            //获取方法参数值
-            Object[] args = joinPoint.getArgs();
-            for (int i = 0; i < args.length; i++) {
-                // 替换 SP EL 里的变量值为实际值, 比如 #user --> user对象
-                context.setVariable(parameterNames[i], args[i]);
-            }
-            context.setVariable("info", info);
-        }
-        // 第二步,逐个参数解析
-        Map<String, Object> result = MapUtil.newHashMap(expressionStrings.size(), true);
-        expressionStrings.forEach(key -> {
-            Object value = EXPRESSION_PARSER.parseExpression(key).getValue(context);
-            result.put(key, value);
-        });
-        return result;
-    }
-
 }

+ 3 - 3
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleStatusEnum.java → yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/AfterSaleStatusEnum.java

@@ -18,7 +18,7 @@ import static cn.hutool.core.util.ArrayUtil.firstMatch;
  */
 @AllArgsConstructor
 @Getter
-public enum TradeAfterSaleStatusEnum implements IntArrayValuable {
+public enum AfterSaleStatusEnum implements IntArrayValuable {
 
     /**
      * 【申请售后】
@@ -54,7 +54,7 @@ public enum TradeAfterSaleStatusEnum implements IntArrayValuable {
     SELLER_REFUSE(63,"卖家拒绝收货", "商家拒绝收货"), // 有赞的状态提示:商家拒绝收货,不同意退款
     ;
 
-    public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeAfterSaleStatusEnum::getStatus).toArray();
+    public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(AfterSaleStatusEnum::getStatus).toArray();
 
     /**
      * 进行中的售后状态
@@ -88,7 +88,7 @@ public enum TradeAfterSaleStatusEnum implements IntArrayValuable {
         return ARRAYS;
     }
 
-    public static TradeAfterSaleStatusEnum valueOf(Integer status) {
+    public static AfterSaleStatusEnum valueOf(Integer status) {
         return firstMatch(value -> value.getStatus().equals(status), values());
     }
 

+ 2 - 2
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleTypeEnum.java → yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/AfterSaleTypeEnum.java

@@ -13,12 +13,12 @@ import java.util.Arrays;
  */
 @RequiredArgsConstructor
 @Getter
-public enum TradeAfterSaleTypeEnum implements IntArrayValuable {
+public enum AfterSaleTypeEnum implements IntArrayValuable {
 
     IN_SALE(10, "售中退款"), // 交易完成前买家申请退款
     AFTER_SALE(20, "售后退款"); // 交易完成后买家申请退款
 
-    public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeAfterSaleTypeEnum::getType).toArray();
+    public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(AfterSaleTypeEnum::getType).toArray();
 
     /**
      * 类型

+ 2 - 2
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleWayEnum.java → yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/AfterSaleWayEnum.java

@@ -13,12 +13,12 @@ import java.util.Arrays;
  */
 @RequiredArgsConstructor
 @Getter
-public enum TradeAfterSaleWayEnum implements IntArrayValuable {
+public enum AfterSaleWayEnum implements IntArrayValuable {
 
     REFUND(10, "仅退款"),
     RETURN_AND_REFUND(20, "退货退款");
 
-    public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeAfterSaleWayEnum::getWay).toArray();
+    public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(AfterSaleWayEnum::getWay).toArray();
 
     /**
      * 方式

+ 18 - 43
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.java → yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/AfterSaleController.java

@@ -8,13 +8,13 @@ import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
 import cn.iocoder.yudao.module.pay.api.notify.dto.PayRefundNotifyReqDTO;
 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.*;
-import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.log.TradeAfterSaleLogRespVO;
-import cn.iocoder.yudao.module.trade.convert.aftersale.TradeAfterSaleConvert;
-import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO;
+import cn.iocoder.yudao.module.trade.convert.aftersale.AfterSaleConvert;
+import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.AfterSaleDO;
+import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.AfterSaleLogDO;
 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
-import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.service.AfterSaleLogService;
-import cn.iocoder.yudao.module.trade.service.aftersale.TradeAfterSaleService;
+import cn.iocoder.yudao.module.trade.service.aftersale.AfterSaleLogService;
+import cn.iocoder.yudao.module.trade.service.aftersale.AfterSaleService;
 import cn.iocoder.yudao.module.trade.service.order.TradeOrderQueryService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
@@ -27,8 +27,6 @@ import org.springframework.web.bind.annotation.*;
 import javax.annotation.Resource;
 import javax.annotation.security.PermitAll;
 import javax.validation.Valid;
-import java.time.LocalDateTime;
-import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
@@ -42,10 +40,10 @@ import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUti
 @RequestMapping("/trade/after-sale")
 @Validated
 @Slf4j
-public class TradeAfterSaleController {
+public class AfterSaleController {
 
     @Resource
-    private TradeAfterSaleService afterSaleService;
+    private AfterSaleService afterSaleService;
     @Resource
     private TradeOrderQueryService tradeOrderQueryService;
     @Resource
@@ -56,26 +54,26 @@ public class TradeAfterSaleController {
     @GetMapping("/page")
     @Operation(summary = "获得售后订单分页")
     @PreAuthorize("@ss.hasPermission('trade:after-sale:query')")
-    public CommonResult<PageResult<TradeAfterSaleRespPageItemVO>> getAfterSalePage(@Valid TradeAfterSalePageReqVO pageVO) {
+    public CommonResult<PageResult<AfterSaleRespPageItemVO>> getAfterSalePage(@Valid AfterSalePageReqVO pageVO) {
         // 查询售后
-        PageResult<TradeAfterSaleDO> pageResult = afterSaleService.getAfterSalePage(pageVO);
+        PageResult<AfterSaleDO> pageResult = afterSaleService.getAfterSalePage(pageVO);
         if (CollUtil.isEmpty(pageResult.getList())) {
             return success(PageResult.empty());
         }
 
         // 查询会员
         Map<Long, MemberUserRespDTO> memberUsers = memberUserApi.getUserMap(
-                convertSet(pageResult.getList(), TradeAfterSaleDO::getUserId));
-        return success(TradeAfterSaleConvert.INSTANCE.convertPage(pageResult, memberUsers));
+                convertSet(pageResult.getList(), AfterSaleDO::getUserId));
+        return success(AfterSaleConvert.INSTANCE.convertPage(pageResult, memberUsers));
     }
 
     @GetMapping("/get-detail")
     @Operation(summary = "获得售后订单详情")
     @Parameter(name = "id", description = "售后编号", required = true, example = "1")
     @PreAuthorize("@ss.hasPermission('trade:after-sale:query')")
-    public CommonResult<TradeAfterSaleDetailRespVO> getOrderDetail(@RequestParam("id") Long id) {
+    public CommonResult<AfterSaleDetailRespVO> getOrderDetail(@RequestParam("id") Long id) {
         // 查询订单
-        TradeAfterSaleDO afterSale = afterSaleService.getAfterSale(id);
+        AfterSaleDO afterSale = afterSaleService.getAfterSale(id);
         if (afterSale == null) {
             return success(null);
         }
@@ -83,34 +81,11 @@ public class TradeAfterSaleController {
         // 查询订单
         TradeOrderDO order = tradeOrderQueryService.getOrder(afterSale.getOrderId());
         // 查询订单项
-        List<TradeOrderItemDO> orderItems = tradeOrderQueryService.getOrderItemListByOrderId(id);
+        TradeOrderItemDO orderItem = tradeOrderQueryService.getOrderItem(afterSale.getOrderItemId());
         // 拼接数据
         MemberUserRespDTO user = memberUserApi.getUser(afterSale.getUserId());
-        // 获取售后日志
-        List<TradeAfterSaleLogRespVO> logs = afterSaleLogService.getLog(afterSale.getId());
-        // TODO 方便测试看效果,review 后移除
-        if (logs == null) {
-            logs = new ArrayList<>();
-        }
-        for (int i = 1; i <= 6; i++) {
-            TradeAfterSaleLogRespVO respVO = new TradeAfterSaleLogRespVO();
-            respVO.setId((long) i);
-            respVO.setUserId((long) i);
-            respVO.setUserType(i % 2 == 0 ? 2 : 1);
-            // 模拟系统操作
-            if (i == 2) {
-                respVO.setUserType(3);
-            }
-            respVO.setAfterSaleId(id);
-            respVO.setOrderId((long) i);
-            respVO.setOrderItemId((long) i);
-            respVO.setBeforeStatus((i - 1) * 10);
-            respVO.setAfterStatus(i * 10);
-            respVO.setContent("66+6");
-            respVO.setCreateTime(LocalDateTime.now());
-            logs.add(respVO);
-        }
-        return success(TradeAfterSaleConvert.INSTANCE.convert(afterSale, order, orderItems, user, logs));
+        List<AfterSaleLogDO> logs = afterSaleLogService.getAfterSaleLogList(afterSale.getId());
+        return success(AfterSaleConvert.INSTANCE.convert(afterSale, order, orderItem, user, logs));
     }
 
     @PutMapping("/agree")
@@ -125,7 +100,7 @@ public class TradeAfterSaleController {
     @PutMapping("/disagree")
     @Operation(summary = "拒绝售后")
     @PreAuthorize("@ss.hasPermission('trade:after-sale:disagree')")
-    public CommonResult<Boolean> disagreeAfterSale(@RequestBody TradeAfterSaleDisagreeReqVO confirmReqVO) {
+    public CommonResult<Boolean> disagreeAfterSale(@RequestBody AfterSaleDisagreeReqVO confirmReqVO) {
         afterSaleService.disagreeAfterSale(getLoginUserId(), confirmReqVO);
         return success(true);
     }
@@ -143,7 +118,7 @@ public class TradeAfterSaleController {
     @Operation(summary = "拒绝收货")
     @Parameter(name = "id", description = "售后编号", required = true, example = "1")
     @PreAuthorize("@ss.hasPermission('trade:after-sale:receive')")
-    public CommonResult<Boolean> refuseAfterSale(TradeAfterSaleRefuseReqVO refuseReqVO) {
+    public CommonResult<Boolean> refuseAfterSale(AfterSaleRefuseReqVO refuseReqVO) {
         afterSaleService.refuseAfterSale(getLoginUserId(), refuseReqVO);
         return success(true);
     }

+ 2 - 2
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleBaseVO.java → yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/AfterSaleBaseVO.java

@@ -15,7 +15,7 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
 * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
 */
 @Data
-public class TradeAfterSaleBaseVO {
+public class AfterSaleBaseVO {
 
     @Schema(description = "售后流水号", requiredMode = Schema.RequiredMode.REQUIRED, example = "202211190847450020500077")
     @NotNull(message = "售后流水号不能为空")
@@ -53,7 +53,7 @@ public class TradeAfterSaleBaseVO {
 
     @Schema(description = "订单流水号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2022111917190001")
     @NotNull(message = "订单流水号不能为空")
-    private Long orderNo;
+    private String orderNo;
 
     @Schema(description = "订单项编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "572")
     @NotNull(message = "订单项编号不能为空")

+ 9 - 8
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleDetailRespVO.java → yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/AfterSaleDetailRespVO.java

@@ -1,6 +1,6 @@
 package cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo;
 
-import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.log.TradeAfterSaleLogRespVO;
+import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.log.AfterSaleLogRespVO;
 import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO;
 import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO;
 import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderBaseVO;
@@ -12,20 +12,21 @@ import java.util.List;
 
 @Schema(description = "管理后台 - 售后订单的详情 Response VO")
 @Data
-public class TradeAfterSaleDetailRespVO extends TradeAfterSaleBaseVO {
+public class AfterSaleDetailRespVO extends AfterSaleBaseVO {
 
     @Schema(description = "售后编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
     private Long id;
 
-    /**
-     * 订单项列表
-     */
-    private List<Item> items;
+
 
     /**
      * 订单基本信息
      */
     private TradeOrderBaseVO order;
+    /**
+     * 订单项列表
+     */
+    private OrderItem orderItem;
 
     /**
      * 用户信息
@@ -35,11 +36,11 @@ public class TradeAfterSaleDetailRespVO extends TradeAfterSaleBaseVO {
     /**
      * 售后日志
      */
-    private List<TradeAfterSaleLogRespVO> logs;
+    private List<AfterSaleLogRespVO> logs;
 
     @Schema(description = "管理后台 - 交易订单的详情的订单项目")
     @Data
-    public static class Item extends TradeOrderItemBaseVO {
+    public static class OrderItem extends TradeOrderItemBaseVO {
 
         /**
          * 属性数组

+ 1 - 1
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleDisagreeReqVO.java → yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/AfterSaleDisagreeReqVO.java

@@ -8,7 +8,7 @@ import javax.validation.constraints.NotNull;
 
 @Schema(description = "管理后台 - 交易售后拒绝 Request VO")
 @Data
-public class TradeAfterSaleDisagreeReqVO {
+public class AfterSaleDisagreeReqVO {
 
     @Schema(description = "售后编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
     @NotNull(message = "售后编号不能为空")

+ 7 - 7
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSalePageReqVO.java → yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/AfterSalePageReqVO.java

@@ -2,9 +2,9 @@ package cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo;
 
 import cn.iocoder.yudao.framework.common.pojo.PageParam;
 import cn.iocoder.yudao.framework.common.validation.InEnum;
-import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleStatusEnum;
-import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleTypeEnum;
-import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleWayEnum;
+import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleStatusEnum;
+import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleTypeEnum;
+import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleWayEnum;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
@@ -19,21 +19,21 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
 @Data
 @EqualsAndHashCode(callSuper = true)
 @ToString(callSuper = true)
-public class TradeAfterSalePageReqVO extends PageParam {
+public class AfterSalePageReqVO extends PageParam {
 
     @Schema(description = "售后流水号", example = "202211190847450020500077")
     private String no;
 
     @Schema(description = "售后状态", example = "10")
-    @InEnum(value = TradeAfterSaleStatusEnum.class, message = "售后状态必须是 {value}")
+    @InEnum(value = AfterSaleStatusEnum.class, message = "售后状态必须是 {value}")
     private Integer status;
 
     @Schema(description = "售后类型", example = "20")
-    @InEnum(value = TradeAfterSaleTypeEnum.class, message = "售后类型必须是 {value}")
+    @InEnum(value = AfterSaleTypeEnum.class, message = "售后类型必须是 {value}")
     private Integer type;
 
     @Schema(description = "售后方式", example = "10")
-    @InEnum(value = TradeAfterSaleWayEnum.class, message = "售后方式必须是 {value}")
+    @InEnum(value = AfterSaleWayEnum.class, message = "售后方式必须是 {value}")
     private Integer way;
 
     @Schema(description = "订单编号", example = "18078")

+ 1 - 1
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleRefuseReqVO.java → yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/AfterSaleRefuseReqVO.java

@@ -7,7 +7,7 @@ import javax.validation.constraints.NotNull;
 
 @Schema(description = "管理后台 - 交易售后拒绝收货 Request VO")
 @Data
-public class TradeAfterSaleRefuseReqVO {
+public class AfterSaleRefuseReqVO {
 
     @Schema(description = "售后编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
     @NotNull(message = "售后编号不能为空")

+ 1 - 1
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleRespPageItemVO.java → yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/AfterSaleRespPageItemVO.java

@@ -14,7 +14,7 @@ import java.util.List;
 @Data
 @EqualsAndHashCode(callSuper = true)
 @ToString(callSuper = true)
-public class TradeAfterSaleRespPageItemVO extends TradeAfterSaleBaseVO {
+public class AfterSaleRespPageItemVO extends AfterSaleBaseVO {
 
     @Schema(description = "售后编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "27630")
     private Long id;

+ 1 - 9
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/log/TradeAfterSaleLogRespVO.java → yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/log/AfterSaleLogRespVO.java

@@ -8,7 +8,7 @@ import java.time.LocalDateTime;
 
 @Schema(description = "管理后台 - 交易售后日志 Response VO")
 @Data
-public class TradeAfterSaleLogRespVO {
+public class AfterSaleLogRespVO {
 
     @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20669")
     private Long id;
@@ -25,14 +25,6 @@ public class TradeAfterSaleLogRespVO {
     @NotNull(message = "售后编号不能为空")
     private Long afterSaleId;
 
-    @Schema(description = "订单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "25870")
-    @NotNull(message = "订单编号不能为空")
-    private Long orderId;
-
-    @Schema(description = "订单项编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23154")
-    @NotNull(message = "订单项编号不能为空")
-    private Long orderItemId;
-
     @Schema(description = "售后状态(之前)", example = "2")
     private Integer beforeStatus;
 

+ 9 - 1
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/config/TradeConfigController.java

@@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO;
 import cn.iocoder.yudao.module.trade.service.config.TradeConfigService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
@@ -26,6 +27,9 @@ public class TradeConfigController {
     @Resource
     private TradeConfigService tradeConfigService;
 
+    @Value("${yudao.tencent-lbs-key}")
+    private String tencentLbsKey;
+
     @PutMapping("/save")
     @Operation(summary = "更新交易中心配置")
     @PreAuthorize("@ss.hasPermission('trade:config:save')")
@@ -39,7 +43,11 @@ public class TradeConfigController {
     @PreAuthorize("@ss.hasPermission('trade:config:query')")
     public CommonResult<TradeConfigRespVO> getConfig() {
         TradeConfigDO config = tradeConfigService.getTradeConfig();
-        return success(TradeConfigConvert.INSTANCE.convert(config));
+        TradeConfigRespVO configVO = TradeConfigConvert.INSTANCE.convert(config);
+        if (configVO != null) {
+            configVO.setTencentLbsKey(tencentLbsKey);
+        }
+        return success(configVO);
     }
 
 }

+ 4 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/config/vo/TradeConfigBaseVO.java

@@ -44,6 +44,10 @@ public class TradeConfigBaseVO {
     @PositiveOrZero(message = "全场包邮的最小金额不能是负数")
     private Integer deliveryExpressFreePrice;
 
+    @Schema(description = "是否开启自提", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
+    @NotNull(message = "是否开启自提不能为空")
+    private Boolean deliveryPickUpEnabled;
+
     // ========== 分销相关 ==========
 
     @Schema(description = "是否启用分佣", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")

+ 3 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/config/vo/TradeConfigRespVO.java

@@ -14,4 +14,7 @@ public class TradeConfigRespVO extends TradeConfigBaseVO {
     @Schema(description = "自增主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
     private Long id;
 
+    @Schema(description = "腾讯地图 KEY", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456")
+    private String tencentLbsKey;
+
 }

+ 4 - 1
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/ExpressTemplateChargeBaseVO.java → yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateChargeBaseVO.java

@@ -11,7 +11,10 @@ import java.util.List;
  * 快递运费模板运费设置 Base VO,提供给添加运费模板使用
  */
 @Data
-public class ExpressTemplateChargeBaseVO {
+public class DeliveryExpressTemplateChargeBaseVO {
+
+    @Schema(description = "编号", example = "6592", hidden = true) // 由于想简单一点,复用这个 VO 在更新操作,所以 hidden 为 false
+    private Long id;
 
     @Schema(description = "区域编号列表", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1,120000]")
     @NotEmpty(message = "区域编号列表不能为空")

+ 2 - 3
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateCreateReqVO.java

@@ -6,7 +6,6 @@ import lombok.EqualsAndHashCode;
 import lombok.ToString;
 
 import javax.validation.Valid;
-import java.util.Collections;
 import java.util.List;
 
 @Schema(description = "管理后台 - 快递运费模板创建 Request VO")
@@ -17,10 +16,10 @@ public class DeliveryExpressTemplateCreateReqVO extends DeliveryExpressTemplateB
 
     @Schema(description = "区域运费列表")
     @Valid
-    private List<ExpressTemplateChargeBaseVO> templateCharge;
+    private List<DeliveryExpressTemplateChargeBaseVO> charges;
 
     @Schema(description = "包邮区域列表")
     @Valid
-    private List<ExpressTemplateFreeBaseVO> templateFree;
+    private List<DeliveryExpressTemplateFreeBaseVO> frees;
 
 }

+ 2 - 2
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateDetailRespVO.java

@@ -17,9 +17,9 @@ public class DeliveryExpressTemplateDetailRespVO extends DeliveryExpressTemplate
     private Long id;
 
     @Schema(description = "运费模板运费设置", requiredMode = Schema.RequiredMode.REQUIRED)
-    private List<ExpressTemplateChargeBaseVO> templateCharge;
+    private List<DeliveryExpressTemplateChargeBaseVO> charges;
 
     @Schema(description = "运费模板包邮区域", requiredMode = Schema.RequiredMode.REQUIRED)
-    private List<ExpressTemplateFreeBaseVO> templateFree;
+    private List<DeliveryExpressTemplateFreeBaseVO> frees;
 
 }

+ 1 - 1
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/ExpressTemplateFreeBaseVO.java → yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateFreeBaseVO.java

@@ -11,7 +11,7 @@ import java.util.List;
  * 快递运费模板包邮 Base VO,提供给添加运费模板使用
  */
 @Data
-public class ExpressTemplateFreeBaseVO {
+public class DeliveryExpressTemplateFreeBaseVO {
 
     @Schema(description = "区域编号列表", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1,120000]")
     @NotEmpty(message = "区域编号列表不能为空")

+ 2 - 28
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/expresstemplate/DeliveryExpressTemplateUpdateReqVO.java

@@ -21,36 +21,10 @@ public class DeliveryExpressTemplateUpdateReqVO extends DeliveryExpressTemplateB
 
     @Schema(description = "区域运费列表")
     @Valid
-    private List<ExpressTemplateChargeUpdateVO> templateCharge;
+    private List<DeliveryExpressTemplateChargeBaseVO> charges;
 
     @Schema(description = "包邮区域列表")
     @Valid
-    private List<ExpressTemplateFreeUpdateVO> templateFree;
+    private List<DeliveryExpressTemplateFreeBaseVO> frees;
 
-    @Schema(description = "管理后台 - 快递运费模板区域运费更新 Request VO")
-    @Data
-    public static class ExpressTemplateChargeUpdateVO extends ExpressTemplateChargeBaseVO {
-
-        @Schema(description = "编号", example = "6592")
-        private Long id;
-
-        // TODO @jason:这几个字段,应该不通过前端传递,而是后端查询后去赋值的
-        @Schema(description = "配送模板编号", example = "1")
-        private Long templateId;
-
-        @Schema(description = "配送计费方式", example = "1")
-        private Integer chargeMode;
-
-    }
-
-    @Schema(description = "管理后台 - 快递运费模板包邮区域更新 Request VO")
-    @Data
-    public static class ExpressTemplateFreeUpdateVO extends ExpressTemplateFreeBaseVO {
-
-        @Schema(description = "编号", example = "6592")
-        private Long id;
-
-        @Schema(description = "配送模板编号", example = "1")
-        private Long templateId;
-    }
 }

+ 13 - 20
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/AppTradeAfterSaleController.java → yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/AppAfterSaleController.java

@@ -3,15 +3,11 @@ package cn.iocoder.yudao.module.trade.controller.app.aftersale;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageParam;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleCreateReqVO;
-import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleDeliveryReqVO;
-import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleRespVO;
-import cn.iocoder.yudao.module.trade.convert.aftersale.TradeAfterSaleConvert;
-import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleOperateTypeEnum;
-import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleStatusEnum;
-import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.annotations.AfterSaleLog;
-import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.util.AfterSaleLogUtils;
-import cn.iocoder.yudao.module.trade.service.aftersale.TradeAfterSaleService;
+import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppAfterSaleCreateReqVO;
+import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppAfterSaleDeliveryReqVO;
+import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppAfterSaleRespVO;
+import cn.iocoder.yudao.module.trade.convert.aftersale.AfterSaleConvert;
+import cn.iocoder.yudao.module.trade.service.aftersale.AfterSaleService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -29,23 +25,23 @@ import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUti
 @RequestMapping("/trade/after-sale")
 @Validated
 @Slf4j
-public class AppTradeAfterSaleController {
+public class AppAfterSaleController {
 
     @Resource
-    private TradeAfterSaleService afterSaleService;
+    private AfterSaleService afterSaleService;
 
     @GetMapping(value = "/page")
     @Operation(summary = "获得售后分页")
-    public CommonResult<PageResult<AppTradeAfterSaleRespVO>> getAfterSalePage(PageParam pageParam) {
-        return success(TradeAfterSaleConvert.INSTANCE.convertPage02(
+    public CommonResult<PageResult<AppAfterSaleRespVO>> getAfterSalePage(PageParam pageParam) {
+        return success(AfterSaleConvert.INSTANCE.convertPage02(
                 afterSaleService.getAfterSalePage(getLoginUserId(), pageParam)));
     }
 
     @GetMapping(value = "/get")
     @Operation(summary = "获得售后订单")
     @Parameter(name = "id", description = "售后编号", required = true, example = "1")
-    public CommonResult<AppTradeAfterSaleRespVO> getAfterSale(@RequestParam("id") Long id) {
-        return success(TradeAfterSaleConvert.INSTANCE.convert(afterSaleService.getAfterSale(getLoginUserId(), id)));
+    public CommonResult<AppAfterSaleRespVO> getAfterSale(@RequestParam("id") Long id) {
+        return success(AfterSaleConvert.INSTANCE.convert(afterSaleService.getAfterSale(getLoginUserId(), id)));
     }
 
     @GetMapping(value = "/get-applying-count")
@@ -56,16 +52,13 @@ public class AppTradeAfterSaleController {
 
     @PostMapping(value = "/create")
     @Operation(summary = "申请售后")
-    @AfterSaleLog(id = "#info.data", content = "'申请售后:售后编号['+#info.data+'],订单编号['+#createReqVO.orderItemId+'], '", operateType = AfterSaleOperateTypeEnum.MEMBER_CREATE)
-    public CommonResult<Long> createAfterSale(@RequestBody AppTradeAfterSaleCreateReqVO createReqVO) {
-        AfterSaleLogUtils.setBeforeStatus(0);
-        AfterSaleLogUtils.setAfterStatus(TradeAfterSaleStatusEnum.APPLY.getStatus());
+    public CommonResult<Long> createAfterSale(@RequestBody AppAfterSaleCreateReqVO createReqVO) {
         return success(afterSaleService.createAfterSale(getLoginUserId(), createReqVO));
     }
 
     @PutMapping(value = "/delivery")
     @Operation(summary = "退回货物")
-    public CommonResult<Boolean> deliveryAfterSale(@RequestBody AppTradeAfterSaleDeliveryReqVO deliveryReqVO) {
+    public CommonResult<Boolean> deliveryAfterSale(@RequestBody AppAfterSaleDeliveryReqVO deliveryReqVO) {
         afterSaleService.deliveryAfterSale(getLoginUserId(), deliveryReqVO);
         return success(true);
     }

+ 3 - 3
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSaleCreateReqVO.java → yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppAfterSaleCreateReqVO.java

@@ -1,7 +1,7 @@
 package cn.iocoder.yudao.module.trade.controller.app.aftersale.vo;
 
 import cn.iocoder.yudao.framework.common.validation.InEnum;
-import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleWayEnum;
+import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleWayEnum;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
@@ -11,7 +11,7 @@ import java.util.List;
 
 @Schema(description = "用户 App - 交易售后创建 Request VO")
 @Data
-public class AppTradeAfterSaleCreateReqVO {
+public class AppAfterSaleCreateReqVO {
 
     @Schema(description = "订单项编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
     @NotNull(message = "订单项编号不能为空")
@@ -19,7 +19,7 @@ public class AppTradeAfterSaleCreateReqVO {
 
     @Schema(description = "售后方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
     @NotNull(message = "售后方式不能为空")
-    @InEnum(value = TradeAfterSaleWayEnum.class, message = "售后方式必须是 {value}")
+    @InEnum(value = AfterSaleWayEnum.class, message = "售后方式必须是 {value}")
     private Integer way;
 
     @Schema(description = "退款金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")

+ 1 - 1
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSaleDeliveryReqVO.java → yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppAfterSaleDeliveryReqVO.java

@@ -7,7 +7,7 @@ import javax.validation.constraints.NotNull;
 
 @Schema(description = "用户 App - 交易售后退回货物 Request VO")
 @Data
-public class AppTradeAfterSaleDeliveryReqVO {
+public class AppAfterSaleDeliveryReqVO {
 
     @Schema(description = "售后编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
     @NotNull(message = "售后编号不能为空")

+ 1 - 1
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSaleRespVO.java → yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppAfterSaleRespVO.java

@@ -9,7 +9,7 @@ import java.util.List;
 
 @Schema(description = "用户 App - 交易售后 Response VO")
 @Data
-public class AppTradeAfterSaleRespVO {
+public class AppAfterSaleRespVO {
 
     @Schema(description = "售后编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
     private Long id;

+ 6 - 2
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/config/AppTradeConfigController.java

@@ -10,6 +10,7 @@ import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -30,11 +31,14 @@ public class AppTradeConfigController {
     @Resource
     private TradeConfigService tradeConfigService;
 
+    @Value("${yudao.tencent-lbs-key}")
+    private String tencentLbsKey;
+
     @GetMapping("/get")
     @Operation(summary = "获得交易配置")
     public CommonResult<AppTradeConfigRespVO> getTradeConfig() {
-        TradeConfigDO tradeConfig = ObjUtil.defaultIfNull(tradeConfigService.getTradeConfig(), new TradeConfigDO());
-        return success(TradeConfigConvert.INSTANCE.convert02(tradeConfig));
+        TradeConfigDO config = ObjUtil.defaultIfNull(tradeConfigService.getTradeConfig(), new TradeConfigDO());
+        return success(TradeConfigConvert.INSTANCE.convert02(config).setTencentLbsKey(tencentLbsKey));
     }
 
 }

+ 10 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/config/vo/AppTradeConfigRespVO.java

@@ -3,12 +3,22 @@ package cn.iocoder.yudao.module.trade.controller.app.config.vo;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
+import javax.validation.constraints.NotNull;
 import java.util.List;
 
 @Schema(description = "用户 App - 交易配置 Response VO")
 @Data
 public class AppTradeConfigRespVO {
 
+    @Schema(description = "腾讯地图 KEY", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456")
+    private String tencentLbsKey;
+
+    // ========== 配送相关 ==========
+
+    @Schema(description = "是否开启自提", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
+    @NotNull(message = "是否开启自提不能为空")
+    private Boolean deliveryPickUpEnabled;
+
     // ========== 售后相关 ==========
 
     @Schema(description = "售后的退款理由", requiredMode = Schema.RequiredMode.REQUIRED)

+ 18 - 37
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/delivery/AppDeliverPickUpStoreController.java

@@ -1,10 +1,14 @@
 package cn.iocoder.yudao.module.trade.controller.app.delivery;
 
-import cn.hutool.core.util.RandomUtil;
+import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.module.trade.controller.app.delivery.vo.pickup.AppDeliveryPickUpStoreRespVO;
+import cn.iocoder.yudao.module.trade.convert.delivery.DeliveryPickUpStoreConvert;
+import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryPickUpStoreDO;
+import cn.iocoder.yudao.module.trade.service.delivery.DeliveryPickUpStoreService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.Parameters;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -12,9 +16,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
-import java.util.ArrayList;
+import javax.annotation.Resource;
 import java.util.List;
-import java.util.Random;
 
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 
@@ -24,51 +27,29 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 @Validated
 public class AppDeliverPickUpStoreController {
 
-    // TODO 待实现[门店自提]:如果 latitude、longitude 非空,计算经纬度,并排序。计算的库,可以使用 hutool 的 DistanceUtil 计算。
+    @Resource
+    private DeliveryPickUpStoreService deliveryPickUpStoreService;
+
     @GetMapping("/list")
     @Operation(summary = "获得自提门店列表")
+    @Parameters({
+            @Parameter(name = "latitude", description = "精度", example = "110"),
+            @Parameter(name = "longitude", description = "纬度", example = "120")
+    })
     public CommonResult<List<AppDeliveryPickUpStoreRespVO>> getDeliveryPickUpStoreList(
             @RequestParam(value = "latitude", required = false) Double latitude,
             @RequestParam(value = "longitude", required = false) Double longitude) {
-        List<AppDeliveryPickUpStoreRespVO> list = new ArrayList<>();
-        Random random = new Random();
-        for (int i = 0; i < 10; i++) {
-            AppDeliveryPickUpStoreRespVO store = new AppDeliveryPickUpStoreRespVO();
-            store.setId(random.nextLong());
-            store.setName(RandomUtil.randomString(10));
-            store.setLogo("https://www.iocoder.cn/" + (i + 1) + ".png");
-            store.setPhone("15601691300");
-            store.setAreaId(random.nextInt(100000));
-            store.setAreaName("上海-" + RandomUtil.randomString(10));
-            store.setDetailAddress("普陀区-" + RandomUtil.randomString(10));
-            store.setLatitude(random.nextDouble() * 10);
-            store.setLongitude(random.nextDouble() * 10);
-            store.setDistance(random.nextInt(1000));
-
-            list.add(store);
-        }
-
-        return success(list);
+        List<DeliveryPickUpStoreDO> list = deliveryPickUpStoreService.getDeliveryPickUpStoreListByStatus(
+                CommonStatusEnum.ENABLE.getStatus());
+        return success(DeliveryPickUpStoreConvert.INSTANCE.convertList(list, latitude, longitude));
     }
 
-    // TODO 待实现[门店自提]:
     @GetMapping("/get")
     @Operation(summary = "获得自提门店")
     @Parameter(name = "id", description = "门店编号")
     public CommonResult<AppDeliveryPickUpStoreRespVO> getOrder(@RequestParam("id") Long id) {
-        AppDeliveryPickUpStoreRespVO store = new AppDeliveryPickUpStoreRespVO();
-        Random random = new Random();
-        store.setId(random.nextLong());
-        store.setName(RandomUtil.randomString(10));
-        store.setLogo("https://www.iocoder.cn/" + (1) + ".png");
-        store.setPhone("15601691300");
-        store.setAreaId(random.nextInt(100000));
-        store.setAreaName("上海-" + RandomUtil.randomString(10));
-        store.setDetailAddress("普陀区-" + RandomUtil.randomString(10));
-        store.setLatitude(random.nextDouble() * 10);
-        store.setLongitude(random.nextDouble() * 10);
-        store.setDistance(random.nextInt(1000));
-        return success(store);
+        DeliveryPickUpStoreDO store = deliveryPickUpStoreService.getDeliveryPickUpStore(id);
+        return success(DeliveryPickUpStoreConvert.INSTANCE.convert03(store));
     }
 
 }

+ 2 - 2
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/delivery/vo/pickup/AppDeliveryPickUpStoreRespVO.java

@@ -34,7 +34,7 @@ public class AppDeliveryPickUpStoreRespVO {
     @Schema(description = "经度", requiredMode = Schema.RequiredMode.REQUIRED, example = "6.99")
     private Double longitude;
 
-    @Schema(description = "距离,单位:米", example = "100") // 只有在用户传递了经纬度时,才进行计算
-    private Integer distance;
+    @Schema(description = "距离,单位:米", example = "100") // 只有在用户传递了经纬度时,才进行计算
+    private Double distance;
 
 }

+ 25 - 26
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/aftersale/TradeAfterSaleConvert.java → yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/aftersale/AfterSaleConvert.java

@@ -4,16 +4,16 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
 import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO;
 import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
-import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleDetailRespVO;
-import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRespPageItemVO;
-import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.log.TradeAfterSaleLogRespVO;
+import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSaleDetailRespVO;
+import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSaleRespPageItemVO;
+import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.log.AfterSaleLogRespVO;
 import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO;
 import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO;
 import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderBaseVO;
-import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleCreateReqVO;
-import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleRespVO;
-import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO;
-import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleLogDO;
+import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppAfterSaleCreateReqVO;
+import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppAfterSaleRespVO;
+import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.AfterSaleDO;
+import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.AfterSaleLogDO;
 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
 import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
@@ -26,9 +26,9 @@ import java.util.List;
 import java.util.Map;
 
 @Mapper
-public interface TradeAfterSaleConvert {
+public interface AfterSaleConvert {
 
-    TradeAfterSaleConvert INSTANCE = Mappers.getMapper(TradeAfterSaleConvert.class);
+    AfterSaleConvert INSTANCE = Mappers.getMapper(AfterSaleConvert.class);
 
     @Mappings({
             @Mapping(target = "id", ignore = true),
@@ -37,7 +37,7 @@ public interface TradeAfterSaleConvert {
             @Mapping(target = "creator", ignore = true),
             @Mapping(target = "updater", ignore = true),
     })
-    TradeAfterSaleDO convert(AppTradeAfterSaleCreateReqVO createReqVO, TradeOrderItemDO tradeOrderItem);
+    AfterSaleDO convert(AppAfterSaleCreateReqVO createReqVO, TradeOrderItemDO tradeOrderItem);
 
     @Mappings({
             @Mapping(source = "afterSale.orderId", target = "merchantOrderId"),
@@ -45,16 +45,16 @@ public interface TradeAfterSaleConvert {
             @Mapping(source = "afterSale.applyReason", target = "reason"),
             @Mapping(source = "afterSale.refundPrice", target = "price")
     })
-    PayRefundCreateReqDTO convert(String userIp, TradeAfterSaleDO afterSale,
+    PayRefundCreateReqDTO convert(String userIp, AfterSaleDO afterSale,
                                   TradeOrderProperties orderProperties);
 
     MemberUserRespVO convert(MemberUserRespDTO bean);
 
-    PageResult<TradeAfterSaleRespPageItemVO> convertPage(PageResult<TradeAfterSaleDO> page);
+    PageResult<AfterSaleRespPageItemVO> convertPage(PageResult<AfterSaleDO> page);
 
-    default PageResult<TradeAfterSaleRespPageItemVO> convertPage(PageResult<TradeAfterSaleDO> pageResult,
-                                                                 Map<Long, MemberUserRespDTO> memberUsers) {
-        PageResult<TradeAfterSaleRespPageItemVO> voPageResult = convertPage(pageResult);
+    default PageResult<AfterSaleRespPageItemVO> convertPage(PageResult<AfterSaleDO> pageResult,
+                                                            Map<Long, MemberUserRespDTO> memberUsers) {
+        PageResult<AfterSaleRespPageItemVO> voPageResult = convertPage(pageResult);
         // 处理会员
         voPageResult.getList().forEach(afterSale -> afterSale.setUser(
                 convert(memberUsers.get(afterSale.getUserId()))));
@@ -63,27 +63,26 @@ public interface TradeAfterSaleConvert {
 
     ProductPropertyValueDetailRespVO convert(ProductPropertyValueDetailRespDTO bean);
 
-    AppTradeAfterSaleRespVO convert(TradeAfterSaleDO bean);
+    AppAfterSaleRespVO convert(AfterSaleDO bean);
 
-    PageResult<AppTradeAfterSaleRespVO> convertPage02(PageResult<TradeAfterSaleDO> page);
+    PageResult<AppAfterSaleRespVO> convertPage02(PageResult<AfterSaleDO> page);
 
-    List<TradeAfterSaleLogRespVO> convertList(List<TradeAfterSaleLogDO> list);
-
-    default TradeAfterSaleDetailRespVO convert(TradeAfterSaleDO afterSale, TradeOrderDO order, List<TradeOrderItemDO> orderItems,
-                                               MemberUserRespDTO user, List<TradeAfterSaleLogRespVO> logs) {
-        TradeAfterSaleDetailRespVO respVO = convert(afterSale, orderItems);
+    default AfterSaleDetailRespVO convert(AfterSaleDO afterSale, TradeOrderDO order, TradeOrderItemDO orderItem,
+                                          MemberUserRespDTO user, List<AfterSaleLogDO> logs) {
+        AfterSaleDetailRespVO respVO = convert02(afterSale);
         // 处理用户信息
         respVO.setUser(convert(user));
         // 处理订单信息
         respVO.setOrder(convert(order));
+        respVO.setOrderItem(convert02(orderItem));
         // 处理售后日志
         respVO.setLogs(convertList1(logs));
         return respVO;
     }
 
-    List<TradeAfterSaleLogRespVO> convertList1(List<TradeAfterSaleLogRespVO> list);
-    @Mapping(target = "id", source = "afterSale.id")
-    TradeAfterSaleDetailRespVO convert(TradeAfterSaleDO afterSale, List<TradeOrderItemDO> orderItems);
-    TradeOrderBaseVO convert(TradeOrderDO order);
+    List<AfterSaleLogRespVO> convertList1(List<AfterSaleLogDO> list);
+    AfterSaleDetailRespVO convert02(AfterSaleDO bean);
+    AfterSaleDetailRespVO.OrderItem convert02(TradeOrderItemDO bean);
+    TradeOrderBaseVO convert(TradeOrderDO bean);
 
 }

+ 15 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/aftersale/AfterSaleLogConvert.java

@@ -0,0 +1,15 @@
+package cn.iocoder.yudao.module.trade.convert.aftersale;
+
+import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.AfterSaleLogDO;
+import cn.iocoder.yudao.module.trade.service.aftersale.bo.AfterSaleLogCreateReqBO;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+@Mapper
+public interface AfterSaleLogConvert {
+
+    AfterSaleLogConvert INSTANCE = Mappers.getMapper(AfterSaleLogConvert.class);
+
+    AfterSaleLogDO convert(AfterSaleLogCreateReqBO bean);
+
+}

+ 9 - 12
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressTemplateConvert.java

@@ -42,36 +42,32 @@ public interface DeliveryExpressTemplateConvert {
                                                         List<DeliveryExpressTemplateChargeDO> chargeList,
                                                         List<DeliveryExpressTemplateFreeDO> freeList) {
         DeliveryExpressTemplateDetailRespVO respVO = convert2(bean);
-        respVO.setTemplateCharge(convertTemplateChargeList(chargeList));
-        respVO.setTemplateFree(convertTemplateFreeList(freeList));
+        respVO.setCharges(convertTemplateChargeList(chargeList));
+        respVO.setFrees(convertTemplateFreeList(freeList));
         return respVO;
     }
 
     // ========== Template Charge ==========
 
-    DeliveryExpressTemplateChargeDO convertTemplateCharge(Long templateId, Integer chargeMode, ExpressTemplateChargeBaseVO vo);
-
-    DeliveryExpressTemplateChargeDO convertTemplateCharge(DeliveryExpressTemplateUpdateReqVO.ExpressTemplateChargeUpdateVO vo);
+    DeliveryExpressTemplateChargeDO convertTemplateCharge(Long templateId, Integer chargeMode, DeliveryExpressTemplateChargeBaseVO vo);
 
     DeliveryExpressTemplateRespBO.Charge convertTemplateCharge(DeliveryExpressTemplateChargeDO bean);
 
-    default List<DeliveryExpressTemplateChargeDO> convertTemplateChargeList(Long templateId, Integer chargeMode, List<ExpressTemplateChargeBaseVO> list) {
+    default List<DeliveryExpressTemplateChargeDO> convertTemplateChargeList(Long templateId, Integer chargeMode, List<DeliveryExpressTemplateChargeBaseVO> list) {
         return CollectionUtils.convertList(list, vo -> convertTemplateCharge(templateId, chargeMode, vo));
     }
 
     // ========== Template Free ==========
 
-    DeliveryExpressTemplateFreeDO convertTemplateFree(Long templateId, ExpressTemplateFreeBaseVO vo);
-
-    DeliveryExpressTemplateFreeDO convertTemplateFree(DeliveryExpressTemplateUpdateReqVO.ExpressTemplateFreeUpdateVO vo);
+    DeliveryExpressTemplateFreeDO convertTemplateFree(Long templateId, DeliveryExpressTemplateFreeBaseVO vo);
 
     DeliveryExpressTemplateRespBO.Free convertTemplateFree(DeliveryExpressTemplateFreeDO bean);
 
-    List<ExpressTemplateChargeBaseVO> convertTemplateChargeList(List<DeliveryExpressTemplateChargeDO> list);
+    List<DeliveryExpressTemplateChargeBaseVO> convertTemplateChargeList(List<DeliveryExpressTemplateChargeDO> list);
 
-    List<ExpressTemplateFreeBaseVO> convertTemplateFreeList(List<DeliveryExpressTemplateFreeDO> list);
+    List<DeliveryExpressTemplateFreeBaseVO> convertTemplateFreeList(List<DeliveryExpressTemplateFreeDO> list);
 
-    default List<DeliveryExpressTemplateFreeDO> convertTemplateFreeList(Long templateId, List<ExpressTemplateFreeBaseVO> list) {
+    default List<DeliveryExpressTemplateFreeDO> convertTemplateFreeList(Long templateId, List<DeliveryExpressTemplateFreeBaseVO> list) {
         return CollectionUtils.convertList(list, vo -> convertTemplateFree(templateId, vo));
     }
 
@@ -93,4 +89,5 @@ public interface DeliveryExpressTemplateConvert {
         });
         return result;
     }
+
 }

+ 17 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryPickUpStoreConvert.java

@@ -1,11 +1,14 @@
 package cn.iocoder.yudao.module.trade.convert.delivery;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
+import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
 import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
 import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup.DeliveryPickUpStoreCreateReqVO;
 import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup.DeliveryPickUpStoreRespVO;
 import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup.DeliveryPickUpStoreSimpleRespVO;
 import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup.DeliveryPickUpStoreUpdateReqVO;
+import cn.iocoder.yudao.module.trade.controller.app.delivery.vo.pickup.AppDeliveryPickUpStoreRespVO;
 import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryPickUpStoreDO;
 import org.mapstruct.Mapper;
 import org.mapstruct.Mapping;
@@ -38,4 +41,18 @@ public interface DeliveryPickUpStoreConvert {
         return AreaUtils.format(areaId);
     }
 
+    default List<AppDeliveryPickUpStoreRespVO> convertList(List<DeliveryPickUpStoreDO> list,
+                                                           Double latitude, Double longitude) {
+        List<AppDeliveryPickUpStoreRespVO> voList =  CollectionUtils.convertList(list, store -> {
+            AppDeliveryPickUpStoreRespVO storeVO = convert03(store);
+            if (latitude != null && longitude != null) {
+                storeVO.setDistance(NumberUtils.getDistance(latitude, longitude, storeVO.getLatitude(), storeVO.getLongitude()));
+            }
+            return storeVO;
+        });
+        return voList;
+    }
+    @Mapping(source = "areaId", target = "areaName", qualifiedByName = "convertAreaIdToAreaName")
+    AppDeliveryPickUpStoreRespVO convert03(DeliveryPickUpStoreDO bean);
+
 }

+ 1 - 1
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderLogConvert.java

@@ -10,6 +10,6 @@ public interface TradeOrderLogConvert {
 
     TradeOrderLogConvert INSTANCE = Mappers.getMapper(TradeOrderLogConvert.class);
 
-    TradeOrderLogDO convert(TradeOrderLogCreateReqBO createReqBO);
+    TradeOrderLogDO convert(TradeOrderLogCreateReqBO bean);
 
 }

+ 7 - 7
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/TradeAfterSaleDO.java → yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/AfterSaleDO.java

@@ -3,9 +3,9 @@ package cn.iocoder.yudao.module.trade.dal.dataobject.aftersale;
 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
-import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleStatusEnum;
-import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleTypeEnum;
-import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleWayEnum;
+import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleStatusEnum;
+import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleTypeEnum;
+import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleWayEnum;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
@@ -25,7 +25,7 @@ import java.util.List;
 @Data
 @EqualsAndHashCode(callSuper = true)
 @Accessors(chain = true)
-public class TradeAfterSaleDO extends BaseDO {
+public class AfterSaleDO extends BaseDO {
 
     /**
      * 售后编号,主键自增
@@ -40,19 +40,19 @@ public class TradeAfterSaleDO extends BaseDO {
     /**
      * 退款状态
      *
-     * 枚举 {@link TradeAfterSaleStatusEnum}
+     * 枚举 {@link AfterSaleStatusEnum}
      */
     private Integer status;
     /**
      * 售后方式
      *
-     * 枚举 {@link TradeAfterSaleWayEnum}
+     * 枚举 {@link AfterSaleWayEnum}
      */
     private Integer way;
     /**
      * 售后类型
      *
-     * 枚举 {@link TradeAfterSaleTypeEnum}
+     * 枚举 {@link AfterSaleTypeEnum}
      */
     private Integer type;
     /**

+ 13 - 6
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/TradeAfterSaleLogDO.java → yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/AfterSaleLogDO.java

@@ -11,8 +11,6 @@ import lombok.*;
 /**
  * 交易售后日志 DO
  *
- * // TODO 可优化:参考淘宝或者有赞:1)增加 action 表示什么操作;2)content 记录每个操作的明细
- *
  * @author 芋道源码
  */
 @TableName("trade_after_sale_log")
@@ -23,7 +21,7 @@ import lombok.*;
 @Builder
 @NoArgsConstructor
 @AllArgsConstructor
-public class TradeAfterSaleLogDO extends BaseDO {
+public class AfterSaleLogDO extends BaseDO {
 
     /**
      * 编号
@@ -43,19 +41,28 @@ public class TradeAfterSaleLogDO extends BaseDO {
      * 枚举 {@link UserTypeEnum}
      */
     private Integer userType;
+
     /**
      * 售后编号
      *
-     * 关联 {@link TradeAfterSaleDO#getId()}
+     * 关联 {@link AfterSaleDO#getId()}
      */
     private Long afterSaleId;
-    // todo @CHENCHEN: 改成 Integer 哈;主要未来改文案,不好洗 log 存的字段;
+    /**
+     * 操作前状态
+     */
+    private Integer beforeStatus;
+    /**
+     * 操作后状态
+     */
+    private Integer afterStatus;
+
     /**
      * 操作类型
      *
      * 枚举 {@link AfterSaleOperateTypeEnum}
      */
-    private String operateType;
+    private Integer operateType;
     /**
      * 操作明细
      */

+ 5 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/config/TradeConfigDO.java

@@ -59,6 +59,11 @@ public class TradeConfigDO extends BaseDO {
      */
     private Integer deliveryExpressFreePrice;
 
+    /**
+     * 是否开启自提
+     */
+    private Boolean deliveryPickUpEnabled;
+
     // ========== 分销相关 ==========
 
     /**

+ 2 - 2
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java

@@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.trade.dal.dataobject.order;
 
 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
-import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO;
+import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.AfterSaleDO;
 import cn.iocoder.yudao.module.trade.dal.dataobject.cart.CartDO;
 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum;
 import com.baomidou.mybatisplus.annotation.TableField;
@@ -166,7 +166,7 @@ public class TradeOrderItemDO extends BaseDO {
     /**
      * 售后单编号
      *
-     * 关联 {@link TradeAfterSaleDO#getId()} 字段
+     * 关联 {@link AfterSaleDO#getId()} 字段
      */
     private Long afterSaleId;
     /**

+ 16 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/aftersale/AfterSaleLogMapper.java

@@ -0,0 +1,16 @@
+package cn.iocoder.yudao.module.trade.dal.mysql.aftersale;
+
+import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.AfterSaleLogDO;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+@Mapper
+public interface AfterSaleLogMapper extends BaseMapperX<AfterSaleLogDO> {
+
+    default List<AfterSaleLogDO> selectListByAfterSaleId(Long afterSaleId) {
+        return selectList(AfterSaleLogDO::getAfterSaleId, afterSaleId);
+    }
+
+}

+ 51 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/aftersale/AfterSaleMapper.java

@@ -0,0 +1,51 @@
+package cn.iocoder.yudao.module.trade.dal.mysql.aftersale;
+
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSalePageReqVO;
+import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.AfterSaleDO;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.Collection;
+
+@Mapper
+public interface AfterSaleMapper extends BaseMapperX<AfterSaleDO> {
+
+    default PageResult<AfterSaleDO> selectPage(AfterSalePageReqVO reqVO) {
+        return selectPage(reqVO, new LambdaQueryWrapperX<AfterSaleDO>()
+                .likeIfPresent(AfterSaleDO::getNo, reqVO.getNo())
+                .eqIfPresent(AfterSaleDO::getStatus, reqVO.getStatus())
+                .eqIfPresent(AfterSaleDO::getType, reqVO.getType())
+                .eqIfPresent(AfterSaleDO::getWay, reqVO.getWay())
+                .likeIfPresent(AfterSaleDO::getOrderNo, reqVO.getOrderNo())
+                .likeIfPresent(AfterSaleDO::getSpuName, reqVO.getSpuName())
+                .betweenIfPresent(AfterSaleDO::getCreateTime, reqVO.getCreateTime())
+                .orderByDesc(AfterSaleDO::getId));
+    }
+
+    default PageResult<AfterSaleDO> selectPage(Long userId, PageParam pageParam) {
+        return selectPage(pageParam, new LambdaQueryWrapperX<AfterSaleDO>()
+                .eqIfPresent(AfterSaleDO::getUserId, userId)
+                .orderByDesc(AfterSaleDO::getId));
+    }
+
+    default int updateByIdAndStatus(Long id, Integer status, AfterSaleDO update) {
+        return update(update, new LambdaUpdateWrapper<AfterSaleDO>()
+                .eq(AfterSaleDO::getId, id).eq(AfterSaleDO::getStatus, status));
+    }
+
+    default AfterSaleDO selectByIdAndUserId(Long id, Long userId) {
+        return selectOne(AfterSaleDO::getId, id,
+                AfterSaleDO::getUserId, userId);
+    }
+
+    default Long selectCountByUserIdAndStatus(Long userId, Collection<Integer> statuses) {
+        return selectCount(new LambdaQueryWrapperX<AfterSaleDO>()
+                .eq(AfterSaleDO::getUserId, userId)
+                .in(AfterSaleDO::getStatus, statuses));
+    }
+
+}

+ 0 - 9
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/aftersale/TradeAfterSaleLogMapper.java

@@ -1,9 +0,0 @@
-package cn.iocoder.yudao.module.trade.dal.mysql.aftersale;
-
-import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
-import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleLogDO;
-import org.apache.ibatis.annotations.Mapper;
-
-@Mapper
-public interface TradeAfterSaleLogMapper extends BaseMapperX<TradeAfterSaleLogDO> {
-}

+ 0 - 51
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/aftersale/TradeAfterSaleMapper.java

@@ -1,51 +0,0 @@
-package cn.iocoder.yudao.module.trade.dal.mysql.aftersale;
-
-import cn.iocoder.yudao.framework.common.pojo.PageParam;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
-import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
-import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSalePageReqVO;
-import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO;
-import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
-import org.apache.ibatis.annotations.Mapper;
-
-import java.util.Collection;
-
-@Mapper
-public interface TradeAfterSaleMapper extends BaseMapperX<TradeAfterSaleDO> {
-
-    default PageResult<TradeAfterSaleDO> selectPage(TradeAfterSalePageReqVO reqVO) {
-        return selectPage(reqVO, new LambdaQueryWrapperX<TradeAfterSaleDO>()
-                .likeIfPresent(TradeAfterSaleDO::getNo, reqVO.getNo())
-                .eqIfPresent(TradeAfterSaleDO::getStatus, reqVO.getStatus())
-                .eqIfPresent(TradeAfterSaleDO::getType, reqVO.getType())
-                .eqIfPresent(TradeAfterSaleDO::getWay, reqVO.getWay())
-                .likeIfPresent(TradeAfterSaleDO::getOrderNo, reqVO.getOrderNo())
-                .likeIfPresent(TradeAfterSaleDO::getSpuName, reqVO.getSpuName())
-                .betweenIfPresent(TradeAfterSaleDO::getCreateTime, reqVO.getCreateTime())
-                .orderByDesc(TradeAfterSaleDO::getId));
-    }
-
-    default PageResult<TradeAfterSaleDO> selectPage(Long userId, PageParam pageParam) {
-        return selectPage(pageParam, new LambdaQueryWrapperX<TradeAfterSaleDO>()
-                .eqIfPresent(TradeAfterSaleDO::getUserId, userId)
-                .orderByDesc(TradeAfterSaleDO::getId));
-    }
-
-    default int updateByIdAndStatus(Long id, Integer status, TradeAfterSaleDO update) {
-        return update(update, new LambdaUpdateWrapper<TradeAfterSaleDO>()
-                .eq(TradeAfterSaleDO::getId, id).eq(TradeAfterSaleDO::getStatus, status));
-    }
-
-    default TradeAfterSaleDO selectByIdAndUserId(Long id, Long userId) {
-        return selectOne(TradeAfterSaleDO::getId, id,
-                TradeAfterSaleDO::getUserId, userId);
-    }
-
-    default Long selectCountByUserIdAndStatus(Long userId, Collection<Integer> statuses) {
-        return selectCount(new LambdaQueryWrapperX<TradeAfterSaleDO>()
-                .eq(TradeAfterSaleDO::getUserId, userId)
-                .in(TradeAfterSaleDO::getStatus, statuses));
-    }
-
-}

+ 18 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/redis/RedisKeyConstants.java

@@ -0,0 +1,18 @@
+package cn.iocoder.yudao.module.trade.dal.redis;
+
+/**
+ * 交易 Redis Key 枚举类
+ *
+ * @author 芋道源码
+ */
+public interface RedisKeyConstants {
+
+    /**
+     * 交易序号的缓存
+     *
+     * KEY 格式:trade_no:{prefix}
+     * VALUE 数据格式:编号自增
+     */
+    String TRADE_NO = "trade_no:";
+
+}

+ 11 - 3
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/redis/no/TradeOrderNoRedisDAO.java → yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/redis/no/TradeNoRedisDAO.java

@@ -2,10 +2,12 @@ package cn.iocoder.yudao.module.trade.dal.redis.no;
 
 import cn.hutool.core.date.DatePattern;
 import cn.hutool.core.date.DateUtil;
+import cn.iocoder.yudao.module.trade.dal.redis.RedisKeyConstants;
 import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.stereotype.Repository;
 
 import javax.annotation.Resource;
+import java.time.Duration;
 import java.time.LocalDateTime;
 
 /**
@@ -14,9 +16,11 @@ import java.time.LocalDateTime;
  * @author HUIHUI
  */
 @Repository
-public class TradeOrderNoRedisDAO {
+public class TradeNoRedisDAO {
 
-    public static final String TRADE_ORDER_NO_PREFIX = "O";
+    public static final String TRADE_ORDER_NO_PREFIX = "o";
+
+    public static final String AFTER_SALE_NO_PREFIX = "r";
 
     @Resource
     private StringRedisTemplate stringRedisTemplate;
@@ -28,8 +32,12 @@ public class TradeOrderNoRedisDAO {
      * @return 序号
      */
     public String generate(String prefix) {
+        // 递增序号
         String noPrefix = prefix + DateUtil.format(LocalDateTime.now(), DatePattern.PURE_DATETIME_PATTERN);
-        Long no = stringRedisTemplate.opsForValue().increment(noPrefix);
+        String key = RedisKeyConstants.TRADE_NO + noPrefix;
+        Long no = stringRedisTemplate.opsForValue().increment(key);
+        // 设置过期时间
+        stringRedisTemplate.expire(key, Duration.ofMinutes(1L));
         return noPrefix + no;
     }
 

+ 2 - 2
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersalelog/config/AfterSaleLogConfiguration.java → yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersale/config/AfterSaleLogConfiguration.java

@@ -1,6 +1,6 @@
-package cn.iocoder.yudao.module.trade.framework.aftersalelog.config;
+package cn.iocoder.yudao.module.trade.framework.aftersale.config;
 
-import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.aop.AfterSaleLogAspect;
+import cn.iocoder.yudao.module.trade.framework.aftersale.core.aop.AfterSaleLogAspect;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 

+ 3 - 14
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersalelog/core/annotations/AfterSaleLog.java → yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersale/core/annotations/AfterSaleLog.java

@@ -1,6 +1,7 @@
-package cn.iocoder.yudao.module.trade.framework.aftersalelog.core.annotations;
+package cn.iocoder.yudao.module.trade.framework.aftersale.core.annotations;
 
 import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleOperateTypeEnum;
+import cn.iocoder.yudao.module.trade.framework.aftersale.core.aop.AfterSaleLogAspect;
 
 import java.lang.annotation.*;
 
@@ -11,28 +12,16 @@ import java.lang.annotation.*;
  *
  * @author 陈賝
  * @since 2023/6/8 17:04
- * @see cn.iocoder.yudao.module.trade.framework.aftersalelog.core.aop.AfterSaleLogAspect
+ * @see AfterSaleLogAspect
  */
 @Target({ElementType.METHOD, ElementType.TYPE})
 @Retention(RetentionPolicy.RUNTIME)
 @Documented
 public @interface AfterSaleLog {
 
-    /**
-     * 售后 ID
-     */
-    @Deprecated
-    String id() default "";
-
     /**
      * 操作类型
      */
     AfterSaleOperateTypeEnum operateType();
 
-    /**
-     * 日志内容
-     */
-    @Deprecated
-    String content() default "";
-
 }

+ 133 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersale/core/aop/AfterSaleLogAspect.java

@@ -0,0 +1,133 @@
+package cn.iocoder.yudao.module.trade.framework.aftersale.core.aop;
+
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
+import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderLogDO;
+import cn.iocoder.yudao.module.trade.framework.aftersale.core.annotations.AfterSaleLog;
+import cn.iocoder.yudao.module.trade.service.aftersale.AfterSaleLogService;
+import cn.iocoder.yudao.module.trade.service.aftersale.bo.AfterSaleLogCreateReqBO;
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.AfterReturning;
+import org.aspectj.lang.annotation.Aspect;
+
+import javax.annotation.Resource;
+import java.util.Map;
+
+import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
+import static java.util.Collections.emptyMap;
+
+/**
+ * 售后订单的操作记录的 AOP 切面
+ *
+ * @author 陈賝
+ * @since 2023/6/13 13:54
+ */
+@Slf4j
+@Aspect
+public class AfterSaleLogAspect {
+
+    /**
+     * 用户编号
+     *
+     * 目前的使用场景:支付回调时,需要强制设置下用户编号
+     */
+    private static final ThreadLocal<Long> USER_ID = new ThreadLocal<>();
+    /**
+     * 用户类型
+     */
+    private static final ThreadLocal<Integer> USER_TYPE = new ThreadLocal<>();
+    /**
+     * 订单编号
+     */
+    private static final ThreadLocal<Long> AFTER_SALE_ID = new ThreadLocal<>();
+    /**
+     * 操作前的状态
+     */
+    private static final ThreadLocal<Integer> BEFORE_STATUS = new ThreadLocal<>();
+    /**
+     * 操作后的状态
+     */
+    private static final ThreadLocal<Integer> AFTER_STATUS = new ThreadLocal<>();
+    /**
+     * 拓展参数 Map,用于格式化操作内容
+     */
+    private static final ThreadLocal<Map<String, Object>> EXTS = new ThreadLocal<>();
+
+    @Resource
+    private AfterSaleLogService afterSaleLogService;
+
+    @AfterReturning(pointcut = "@annotation(afterSaleLog)")
+    public void doAfterReturning(JoinPoint joinPoint, AfterSaleLog afterSaleLog) {
+        try {
+            // 1.1 操作用户
+            Integer userType = getUserType();
+            Long userId = getUserId();
+            // 1.2 售后信息
+            Long afterSaleId = AFTER_SALE_ID.get();
+            if (afterSaleId == null) { // 如果未设置,只有注解,说明不需要记录日志
+                return;
+            }
+            Integer beforeStatus = BEFORE_STATUS.get();
+            Integer afterStatus = AFTER_STATUS.get();
+            Map<String, Object> exts = ObjectUtil.defaultIfNull(EXTS.get(), emptyMap());
+            String content = StrUtil.format(afterSaleLog.operateType().getContent(), exts);
+
+            // 2. 记录日志
+            AfterSaleLogCreateReqBO createBO = new AfterSaleLogCreateReqBO()
+                    .setUserId(userId).setUserType(userType)
+                    .setAfterSaleId(afterSaleId).setBeforeStatus(beforeStatus).setAfterStatus(afterStatus)
+                    .setOperateType(afterSaleLog.operateType().getType()).setContent(content);
+            afterSaleLogService.createAfterSaleLog(createBO);
+        } catch (Exception exception) {
+            log.error("[doAfterReturning][afterSaleLog({}) 日志记录错误]", toJsonString(afterSaleLog), exception);
+        } finally {
+            clear();
+        }
+    }
+
+    /**
+     * 获得用户类型
+     *
+     * 如果没有,则约定为 {@link TradeOrderLogDO#getUserType()} 系统
+     *
+     * @return 用户类型
+     */
+    private static Integer getUserType() {
+        return ObjectUtil.defaultIfNull(WebFrameworkUtils.getLoginUserType(), TradeOrderLogDO.USER_TYPE_SYSTEM);
+    }
+
+    /**
+     * 获得用户编号
+     *
+     * 如果没有,则约定为 {@link TradeOrderLogDO#getUserId()} 系统
+     *
+     * @return 用户类型
+     */
+    private static Long getUserId() {
+        return ObjectUtil.defaultIfNull(WebFrameworkUtils.getLoginUserId(), TradeOrderLogDO.USER_ID_SYSTEM);
+    }
+
+    public static void setAfterSale(Long id, Integer beforeStatus, Integer afterStatus, Map<String, Object> exts) {
+        AFTER_SALE_ID.set(id);
+        BEFORE_STATUS.set(beforeStatus);
+        AFTER_STATUS.set(afterStatus);
+        EXTS.set(exts);
+    }
+
+    public static void setUserInfo(Long userId, Integer userType) {
+        USER_ID.set(userId);
+        USER_TYPE.set(userType);
+    }
+
+    private static void clear() {
+        USER_ID.remove();
+        USER_TYPE.remove();
+        AFTER_SALE_ID.remove();
+        BEFORE_STATUS.remove();
+        AFTER_STATUS.remove();
+        EXTS.remove();
+    }
+
+}

+ 3 - 11
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersalelog/core/util/AfterSaleLogUtils.java → yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersale/core/utils/AfterSaleLogUtils.java

@@ -1,7 +1,7 @@
-package cn.iocoder.yudao.module.trade.framework.aftersalelog.core.util;
+package cn.iocoder.yudao.module.trade.framework.aftersale.core.utils;
 
 
-import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.aop.AfterSaleLogAspect;
+import cn.iocoder.yudao.module.trade.framework.aftersale.core.aop.AfterSaleLogAspect;
 
 import java.util.Map;
 
@@ -13,21 +13,13 @@ import java.util.Map;
  */
 public class AfterSaleLogUtils {
 
-    public static void setBeforeStatus(Integer status) {
-        AfterSaleLogAspect.setBeforeStatus(status);
-    }
-
-    public static void setAfterStatus(Integer status) {
-        AfterSaleLogAspect.setAfterStatus(status);
-    }
-
     public static void setAfterSaleInfo(Long id, Integer beforeStatus, Integer afterStatus) {
         setAfterSaleInfo(id, beforeStatus, afterStatus, null);
     }
 
     public static void setAfterSaleInfo(Long id, Integer beforeStatus, Integer afterStatus,
                                         Map<String, Object> exts) {
-        // TODO 待实现
+        AfterSaleLogAspect.setAfterSale(id, beforeStatus, afterStatus, exts);
     }
 
 }

+ 0 - 122
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersalelog/core/aop/AfterSaleLogAspect.java

@@ -1,122 +0,0 @@
-package cn.iocoder.yudao.module.trade.framework.aftersalelog.core.aop;
-
-import cn.hutool.core.map.MapUtil;
-import cn.hutool.core.util.ObjectUtil;
-import cn.iocoder.yudao.framework.common.util.spring.SpringExpressionUtils;
-import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
-import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.annotations.AfterSaleLog;
-import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.dto.TradeAfterSaleLogCreateReqDTO;
-import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.service.AfterSaleLogService;
-import com.google.common.collect.Maps;
-import lombok.extern.slf4j.Slf4j;
-import org.aspectj.lang.JoinPoint;
-import org.aspectj.lang.annotation.AfterReturning;
-import org.aspectj.lang.annotation.Aspect;
-import org.aspectj.lang.reflect.MethodSignature;
-
-import javax.annotation.Resource;
-import java.util.HashMap;
-import java.util.Map;
-
-import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
-import static java.util.Arrays.asList;
-
-/**
- * 记录售后日志的 AOP 切面
- *
- * @author 陈賝
- * @since 2023/6/13 13:54
- */
-@Slf4j
-@Aspect
-public class AfterSaleLogAspect {
-
-    @Resource
-    private AfterSaleLogService afterSaleLogService;
-    /**
-     * 售前状态
-     */
-    private static final ThreadLocal<Integer> BEFORE_STATUS = new ThreadLocal<>();
-    /**
-     * 售后状态
-     */
-    private static final ThreadLocal<Integer> AFTER_STATUS = new ThreadLocal<>();
-    /**
-     * 操作类型
-     */
-    private final static String OPERATE_TYPE = "operateType";
-    /**
-     * ID
-     */
-    private final static String ID = "id";
-    /**
-     * 操作明细
-     */
-    private final static String CONTENT = "content";
-
-    /**
-     * 切面存入日志
-     */
-    @AfterReturning(pointcut = "@annotation(afterSaleLog)", returning = "info")
-    public void doAfterReturning(JoinPoint joinPoint, AfterSaleLog afterSaleLog, Object info) {
-        try {
-            // 日志对象拼接
-            Integer userType = WebFrameworkUtils.getLoginUserType();
-            Long id = WebFrameworkUtils.getLoginUserId();
-            Map<String, String> formatObj = spelFormat(joinPoint, info);
-            TradeAfterSaleLogCreateReqDTO dto = new TradeAfterSaleLogCreateReqDTO()
-                    .setUserId(id)
-                    .setUserType(userType)
-                    .setAfterSaleId(MapUtil.getLong(formatObj, ID))
-                    .setOperateType(MapUtil.getStr(formatObj, OPERATE_TYPE))
-                    .setBeforeStatus(BEFORE_STATUS.get())
-                    .setAfterStatus(AFTER_STATUS.get())
-                    .setContent(MapUtil.getStr(formatObj, CONTENT));
-            // 异步存入数据库
-            afterSaleLogService.createLog(dto);
-        } catch (Exception exception) {
-            log.error("[doAfterReturning][afterSaleLog({}) 日志记录错误]", toJsonString(afterSaleLog), exception);
-        }finally {
-            clearThreadLocal();
-        }
-    }
-
-    /**
-     * 获取描述信息
-     */
-    public static Map<String, String> spelFormat(JoinPoint joinPoint, Object info) {
-        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
-        AfterSaleLog afterSaleLogPoint = signature.getMethod().getAnnotation(AfterSaleLog.class);
-        HashMap<String, String> result = Maps.newHashMapWithExpectedSize(2);
-        Map<String, Object> spelMap = SpringExpressionUtils.parseExpression(joinPoint, info,
-                asList(afterSaleLogPoint.id(), afterSaleLogPoint.content()));
-        // TODO @chenchen:是不是抽成 3 个方法好点;毕竟 map 太抽象了;;
-        // 售后ID
-        String id = MapUtil.getStr(spelMap, afterSaleLogPoint.id());
-        result.put(ID, id);
-        // 操作类型
-        String operateType = afterSaleLogPoint.operateType().getContent();
-        result.put(OPERATE_TYPE, operateType);
-        // 日志内容
-        String content = MapUtil.getStr(spelMap, afterSaleLogPoint.content());
-        if (ObjectUtil.isNotNull(afterSaleLogPoint.operateType())) {
-            content += operateType;
-        }
-        result.put(CONTENT, content);
-        return result;
-    }
-
-    public static void setBeforeStatus(Integer beforestatus) {
-        BEFORE_STATUS.set(beforestatus);
-    }
-
-    public static void setAfterStatus(Integer afterStatus) {
-        AFTER_STATUS.set(afterStatus);
-    }
-
-    private static void clearThreadLocal() {
-        AFTER_STATUS.remove();
-        BEFORE_STATUS.remove();
-    }
-
-}

+ 0 - 54
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersalelog/core/dto/TradeAfterSaleLogCreateReqDTO.java

@@ -1,54 +0,0 @@
-package cn.iocoder.yudao.module.trade.framework.aftersalelog.core.dto;
-
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-/**
- * 售后日志的创建 Request DTO
- *
- * @author 陈賝
- * @since 2023/6/19 09:54
- */
-@Data
-@NoArgsConstructor
-@AllArgsConstructor
-public class TradeAfterSaleLogCreateReqDTO {
-
-    /**
-     * 编号
-     */
-    private Long id;
-    /**
-     * 用户编号
-     *
-     * 关联 1:AdminUserDO 的 id 字段
-     * 关联 2:MemberUserDO 的 id 字段
-     */
-    private Long userId;
-    /**
-     * 用户类型
-     */
-    private Integer userType;
-    /**
-     * 售后编号
-     */
-    private Long afterSaleId;
-    /**
-     * 操作类型
-     */
-    private String operateType;
-    /**
-     * 操作明细
-     */
-    private String content;
-    /**
-     * 售前状态
-     */
-    private Integer beforeStatus;
-    /**
-     * 售后状态
-     */
-    private Integer afterStatus;
-
-}

+ 0 - 34
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersalelog/core/service/AfterSaleLogService.java

@@ -1,34 +0,0 @@
-package cn.iocoder.yudao.module.trade.framework.aftersalelog.core.service;
-
-
-import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.log.TradeAfterSaleLogRespVO;
-import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.dto.TradeAfterSaleLogCreateReqDTO;
-
-import java.util.List;
-
-/**
- * 交易售后日志 Service 接口
- *
- * @author 陈賝
- * @since 2023/6/12 14:18
- */
-public interface AfterSaleLogService {
-
-    /**
-     * 创建售后日志
-     *
-     * @param logDTO 日志记录
-     * @author 陈賝
-     * @since 2023/6/12 14:18
-     */
-    void createLog(TradeAfterSaleLogCreateReqDTO logDTO);
-
-    /**
-     * 获取售后日志
-     *
-     * @param afterSaleId 售后编号
-     * @return 售后日志
-     */
-    List<TradeAfterSaleLogRespVO> getLog(Long afterSaleId);
-
-}

+ 2 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/annotations/TradeOrderLog.java

@@ -1,6 +1,7 @@
 package cn.iocoder.yudao.module.trade.framework.order.core.annotations;
 
 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderOperateTypeEnum;
+import cn.iocoder.yudao.module.trade.framework.order.core.aop.TradeOrderLogAspect;
 
 import java.lang.annotation.Documented;
 import java.lang.annotation.Retention;
@@ -15,6 +16,7 @@ import static java.lang.annotation.ElementType.METHOD;
  *
  * @author 陈賝
  * @since 2023/7/6 15:37
+ * @see TradeOrderLogAspect
  */
 @Target({METHOD, ANNOTATION_TYPE})
 @Retention(RetentionPolicy.RUNTIME)

+ 2 - 2
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/aop/TradeOrderLogAspect.java

@@ -73,7 +73,7 @@ public class TradeOrderLogAspect {
             Long userId = getUserId();
             // 1.2 订单信息
             Long orderId = ORDER_ID.get();
-            if (orderId == null) { // 如果未设置,只有注解,说明不需要记录订单日志
+            if (orderId == null) { // 如果未设置,只有注解,说明不需要记录日志
                 return;
             }
             Integer beforeStatus = BEFORE_STATUS.get();
@@ -81,7 +81,7 @@ public class TradeOrderLogAspect {
             Map<String, Object> exts = ObjectUtil.defaultIfNull(EXTS.get(), emptyMap());
             String content = StrUtil.format(orderLog.operateType().getContent(), exts);
 
-            // 2.1 记录日志
+            // 2. 记录日志
             TradeOrderLogCreateReqBO createBO = new TradeOrderLogCreateReqBO()
                     .setUserId(userId).setUserType(userType)
                     .setOrderId(orderId).setBeforeStatus(beforeStatus).setAfterStatus(afterStatus)

+ 34 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleLogService.java

@@ -0,0 +1,34 @@
+package cn.iocoder.yudao.module.trade.service.aftersale;
+
+
+import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.AfterSaleLogDO;
+import cn.iocoder.yudao.module.trade.service.aftersale.bo.AfterSaleLogCreateReqBO;
+
+import java.util.List;
+
+/**
+ * 交易售后日志 Service 接口
+ *
+ * @author 陈賝
+ * @since 2023/6/12 14:18
+ */
+public interface AfterSaleLogService {
+
+    /**
+     * 创建售后日志
+     *
+     * @param createReqBO 日志记录
+     * @author 陈賝
+     * @since 2023/6/12 14:18
+     */
+    void createAfterSaleLog(AfterSaleLogCreateReqBO createReqBO);
+
+    /**
+     * 获取售后日志
+     *
+     * @param afterSaleId 售后编号
+     * @return 售后日志
+     */
+    List<AfterSaleLogDO> getAfterSaleLogList(Long afterSaleId);
+
+}

+ 36 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleLogServiceImpl.java

@@ -0,0 +1,36 @@
+package cn.iocoder.yudao.module.trade.service.aftersale;
+
+import cn.iocoder.yudao.module.trade.convert.aftersale.AfterSaleLogConvert;
+import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.AfterSaleLogDO;
+import cn.iocoder.yudao.module.trade.dal.mysql.aftersale.AfterSaleLogMapper;
+import cn.iocoder.yudao.module.trade.service.aftersale.bo.AfterSaleLogCreateReqBO;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 交易售后日志 Service 实现类
+ *
+ * @author 芋道源码
+ */
+@Service
+@Validated
+public class AfterSaleLogServiceImpl implements AfterSaleLogService {
+
+    @Resource
+    private AfterSaleLogMapper afterSaleLogMapper;
+
+    @Override
+    public void createAfterSaleLog(AfterSaleLogCreateReqBO createReqBO) {
+        AfterSaleLogDO afterSaleLog = AfterSaleLogConvert.INSTANCE.convert(createReqBO);
+        afterSaleLogMapper.insert(afterSaleLog);
+    }
+
+    @Override
+    public List<AfterSaleLogDO> getAfterSaleLogList(Long afterSaleId) {
+        return afterSaleLogMapper.selectListByAfterSaleId(afterSaleId);
+    }
+
+}

+ 16 - 16
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleService.java → yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleService.java

@@ -2,19 +2,19 @@ package cn.iocoder.yudao.module.trade.service.aftersale;
 
 import cn.iocoder.yudao.framework.common.pojo.PageParam;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleDisagreeReqVO;
-import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSalePageReqVO;
-import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRefuseReqVO;
-import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleCreateReqVO;
-import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleDeliveryReqVO;
-import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO;
+import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSaleDisagreeReqVO;
+import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSalePageReqVO;
+import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSaleRefuseReqVO;
+import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppAfterSaleCreateReqVO;
+import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppAfterSaleDeliveryReqVO;
+import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.AfterSaleDO;
 
 /**
  * 售后订单 Service 接口
  *
  * @author 芋道源码
  */
-public interface TradeAfterSaleService {
+public interface AfterSaleService {
 
     /**
      * 【管理员】获得售后订单分页
@@ -22,7 +22,7 @@ public interface TradeAfterSaleService {
      * @param pageReqVO 分页查询
      * @return 售后订单分页
      */
-    PageResult<TradeAfterSaleDO> getAfterSalePage(TradeAfterSalePageReqVO pageReqVO);
+    PageResult<AfterSaleDO> getAfterSalePage(AfterSalePageReqVO pageReqVO);
 
     /**
      * 【会员】获得售后订单分页
@@ -31,7 +31,7 @@ public interface TradeAfterSaleService {
      * @param pageParam 分页参数
      * @return 售后订单分页
      */
-    PageResult<TradeAfterSaleDO> getAfterSalePage(Long userId, PageParam pageParam);
+    PageResult<AfterSaleDO> getAfterSalePage(Long userId, PageParam pageParam);
 
     /**
      * 【会员】获得售后单
@@ -40,7 +40,7 @@ public interface TradeAfterSaleService {
      * @param id 售后编号
      * @return 售后订单
      */
-    TradeAfterSaleDO getAfterSale(Long userId, Long id);
+    AfterSaleDO getAfterSale(Long userId, Long id);
 
     /**
      * 【管理员】获得售后单
@@ -48,7 +48,7 @@ public interface TradeAfterSaleService {
      * @param id 售后编号
      * @return 售后订单
      */
-    TradeAfterSaleDO getAfterSale(Long id);
+    AfterSaleDO getAfterSale(Long id);
 
     /**
      * 【会员】创建售后订单
@@ -57,7 +57,7 @@ public interface TradeAfterSaleService {
      * @param createReqVO 创建 Request 信息
      * @return 售后编号
      */
-    Long createAfterSale(Long userId, AppTradeAfterSaleCreateReqVO createReqVO);
+    Long createAfterSale(Long userId, AppAfterSaleCreateReqVO createReqVO);
 
     /**
      * 【管理员】同意售后订单
@@ -73,7 +73,7 @@ public interface TradeAfterSaleService {
      * @param userId 管理员用户编号
      * @param auditReqVO 审批 Request 信息
      */
-    void disagreeAfterSale(Long userId, TradeAfterSaleDisagreeReqVO auditReqVO);
+    void disagreeAfterSale(Long userId, AfterSaleDisagreeReqVO auditReqVO);
 
     /**
      * 【会员】退回货物
@@ -81,7 +81,7 @@ public interface TradeAfterSaleService {
      * @param userId 会员用户编号
      * @param deliveryReqVO 退货 Request 信息
      */
-    void deliveryAfterSale(Long userId, AppTradeAfterSaleDeliveryReqVO deliveryReqVO);
+    void deliveryAfterSale(Long userId, AppAfterSaleDeliveryReqVO deliveryReqVO);
 
     /**
      * 【管理员】确认收货
@@ -97,7 +97,7 @@ public interface TradeAfterSaleService {
      * @param userId 管理员用户编号
      * @param refuseReqVO 拒绝收货 Request 信息
      */
-    void refuseAfterSale(Long userId, TradeAfterSaleRefuseReqVO refuseReqVO);
+    void refuseAfterSale(Long userId, AfterSaleRefuseReqVO refuseReqVO);
 
     /**
      * 【管理员】确认退款
@@ -119,7 +119,7 @@ public interface TradeAfterSaleService {
     /**
      * 【会员】获得正在进行中的售后订单数量
      *
-     * @param userId
+     * @param userId 用户编号
      * @return 数量
      */
     Long getApplyingAfterSaleCount(Long userId);

+ 79 - 132
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java → yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleServiceImpl.java

@@ -2,42 +2,36 @@ package cn.iocoder.yudao.module.trade.service.aftersale;
 
 import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.core.util.RandomUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageParam;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
 import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi;
 import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO;
-import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleDisagreeReqVO;
-import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSalePageReqVO;
-import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRefuseReqVO;
-import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.log.TradeAfterSaleLogRespVO;
-import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleCreateReqVO;
-import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleDeliveryReqVO;
-import cn.iocoder.yudao.module.trade.convert.aftersale.TradeAfterSaleConvert;
-import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO;
-import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleLogDO;
+import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSaleDisagreeReqVO;
+import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSalePageReqVO;
+import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSaleRefuseReqVO;
+import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppAfterSaleCreateReqVO;
+import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppAfterSaleDeliveryReqVO;
+import cn.iocoder.yudao.module.trade.convert.aftersale.AfterSaleConvert;
+import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.AfterSaleDO;
 import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO;
 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
-import cn.iocoder.yudao.module.trade.dal.mysql.aftersale.TradeAfterSaleLogMapper;
-import cn.iocoder.yudao.module.trade.dal.mysql.aftersale.TradeAfterSaleMapper;
+import cn.iocoder.yudao.module.trade.dal.mysql.aftersale.AfterSaleMapper;
+import cn.iocoder.yudao.module.trade.dal.redis.no.TradeNoRedisDAO;
 import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleOperateTypeEnum;
-import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleStatusEnum;
-import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleTypeEnum;
-import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleWayEnum;
+import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleStatusEnum;
+import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleTypeEnum;
+import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleWayEnum;
 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum;
 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum;
-import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.annotations.AfterSaleLog;
-import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.dto.TradeAfterSaleLogCreateReqDTO;
-import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.service.AfterSaleLogService;
-import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.util.AfterSaleLogUtils;
+import cn.iocoder.yudao.module.trade.framework.aftersale.core.annotations.AfterSaleLog;
+import cn.iocoder.yudao.module.trade.framework.aftersale.core.utils.AfterSaleLogUtils;
 import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
 import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService;
 import cn.iocoder.yudao.module.trade.service.order.TradeOrderQueryService;
 import cn.iocoder.yudao.module.trade.service.order.TradeOrderUpdateService;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.support.TransactionSynchronization;
@@ -46,10 +40,8 @@ import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
 import java.time.LocalDateTime;
-import java.util.List;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
-import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
 import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
 
 /**
@@ -60,7 +52,7 @@ import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
 @Slf4j
 @Service
 @Validated
-public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSaleLogService {
+public class AfterSaleServiceImpl implements AfterSaleService {
 
     @Resource
     private TradeOrderUpdateService tradeOrderUpdateService;
@@ -70,9 +62,9 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
     private DeliveryExpressService deliveryExpressService;
 
     @Resource
-    private TradeAfterSaleMapper tradeAfterSaleMapper;
+    private AfterSaleMapper tradeAfterSaleMapper;
     @Resource
-    private TradeAfterSaleLogMapper tradeAfterSaleLogMapper;
+    private TradeNoRedisDAO tradeNoRedisDAO;
 
     @Resource
     private PayRefundApi payRefundApi;
@@ -81,34 +73,34 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
     private TradeOrderProperties tradeOrderProperties;
 
     @Override
-    public PageResult<TradeAfterSaleDO> getAfterSalePage(TradeAfterSalePageReqVO pageReqVO) {
+    public PageResult<AfterSaleDO> getAfterSalePage(AfterSalePageReqVO pageReqVO) {
         return tradeAfterSaleMapper.selectPage(pageReqVO);
     }
 
     @Override
-    public PageResult<TradeAfterSaleDO> getAfterSalePage(Long userId, PageParam pageParam) {
+    public PageResult<AfterSaleDO> getAfterSalePage(Long userId, PageParam pageParam) {
         return tradeAfterSaleMapper.selectPage(userId, pageParam);
     }
 
     @Override
-    public TradeAfterSaleDO getAfterSale(Long userId, Long id) {
+    public AfterSaleDO getAfterSale(Long userId, Long id) {
         return tradeAfterSaleMapper.selectByIdAndUserId(id, userId);
     }
 
     @Override
-    public TradeAfterSaleDO getAfterSale(Long id) {
+    public AfterSaleDO getAfterSale(Long id) {
         return tradeAfterSaleMapper.selectById(id);
     }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
     @AfterSaleLog(operateType = AfterSaleOperateTypeEnum.MEMBER_CREATE)
-    public Long createAfterSale(Long userId, AppTradeAfterSaleCreateReqVO createReqVO) {
+    public Long createAfterSale(Long userId, AppAfterSaleCreateReqVO createReqVO) {
         // 第一步,前置校验
         TradeOrderItemDO tradeOrderItem = validateOrderItemApplicable(userId, createReqVO);
 
         // 第二步,存储售后订单
-        TradeAfterSaleDO afterSale = createAfterSale(createReqVO, tradeOrderItem);
+        AfterSaleDO afterSale = createAfterSale(createReqVO, tradeOrderItem);
         return afterSale.getId();
     }
 
@@ -119,7 +111,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
      * @param createReqVO 售后创建信息
      * @return 交易订单项
      */
-    private TradeOrderItemDO validateOrderItemApplicable(Long userId, AppTradeAfterSaleCreateReqVO createReqVO) {
+    private TradeOrderItemDO validateOrderItemApplicable(Long userId, AppAfterSaleCreateReqVO createReqVO) {
         // 校验订单项存在
         TradeOrderItemDO orderItem = tradeOrderQueryService.getOrderItem(userId, createReqVO.getOrderItemId());
         if (orderItem == null) {
@@ -149,24 +141,24 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
             throw exception(AFTER_SALE_CREATE_FAIL_ORDER_STATUS_NO_PAID);
         }
         // 如果是【退货退款】的情况,需要额外校验是否发货
-        if (createReqVO.getWay().equals(TradeAfterSaleWayEnum.RETURN_AND_REFUND.getWay())
+        if (createReqVO.getWay().equals(AfterSaleWayEnum.RETURN_AND_REFUND.getWay())
                 && !TradeOrderStatusEnum.haveDelivered(order.getStatus())) {
             throw exception(AFTER_SALE_CREATE_FAIL_ORDER_STATUS_NO_DELIVERED);
         }
         return orderItem;
     }
 
-    private TradeAfterSaleDO createAfterSale(AppTradeAfterSaleCreateReqVO createReqVO,
-                                             TradeOrderItemDO orderItem) {
+    private AfterSaleDO createAfterSale(AppAfterSaleCreateReqVO createReqVO,
+                                        TradeOrderItemDO orderItem) {
         // 创建售后单
-        TradeAfterSaleDO afterSale = TradeAfterSaleConvert.INSTANCE.convert(createReqVO, orderItem);
-        afterSale.setNo(RandomUtil.randomString(10)); // TODO 芋艿:优化 no 生成逻辑
-        afterSale.setStatus(TradeAfterSaleStatusEnum.APPLY.getStatus());
+        AfterSaleDO afterSale = AfterSaleConvert.INSTANCE.convert(createReqVO, orderItem);
+        afterSale.setNo(tradeNoRedisDAO.generate(TradeNoRedisDAO.AFTER_SALE_NO_PREFIX));
+        afterSale.setStatus(AfterSaleStatusEnum.APPLY.getStatus());
         // 标记是售中还是售后
         TradeOrderDO order = tradeOrderQueryService.getOrder(orderItem.getUserId(), orderItem.getOrderId());
         afterSale.setOrderNo(order.getNo()); // 记录 orderNo 订单流水,方便后续检索
         afterSale.setType(TradeOrderStatusEnum.isCompleted(order.getStatus())
-                ? TradeAfterSaleTypeEnum.AFTER_SALE.getType() : TradeAfterSaleTypeEnum.IN_SALE.getType());
+                ? AfterSaleTypeEnum.AFTER_SALE.getType() : AfterSaleTypeEnum.IN_SALE.getType());
         tradeAfterSaleMapper.insert(afterSale);
 
         // 更新交易订单项的售后状态
@@ -174,7 +166,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
 
         // 记录售后日志
         AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), null,
-                TradeAfterSaleStatusEnum.APPLY.getStatus());
+                AfterSaleStatusEnum.APPLY.getStatus());
 
         // TODO 发送售后消息
         return afterSale;
@@ -185,14 +177,14 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
     @AfterSaleLog(operateType = AfterSaleOperateTypeEnum.ADMIN_AGREE_APPLY)
     public void agreeAfterSale(Long userId, Long id) {
         // 校验售后单存在,并状态未审批
-        TradeAfterSaleDO afterSale = validateAfterSaleAuditable(id);
+        AfterSaleDO afterSale = validateAfterSaleAuditable(id);
 
         // 更新售后单的状态
         // 情况一:退款:标记为 WAIT_REFUND 状态。后续等退款发起成功后,在标记为 COMPLETE 状态
         // 情况二:退货退款:需要等用户退货后,才能发起退款
-        Integer newStatus = afterSale.getWay().equals(TradeAfterSaleWayEnum.REFUND.getWay()) ?
-                TradeAfterSaleStatusEnum.WAIT_REFUND.getStatus() : TradeAfterSaleStatusEnum.SELLER_AGREE.getStatus();
-        updateAfterSaleStatus(afterSale.getId(), TradeAfterSaleStatusEnum.APPLY.getStatus(), new TradeAfterSaleDO()
+        Integer newStatus = afterSale.getWay().equals(AfterSaleWayEnum.REFUND.getWay()) ?
+                AfterSaleStatusEnum.WAIT_REFUND.getStatus() : AfterSaleStatusEnum.SELLER_AGREE.getStatus();
+        updateAfterSaleStatus(afterSale.getId(), AfterSaleStatusEnum.APPLY.getStatus(), new AfterSaleDO()
                 .setStatus(newStatus).setAuditUserId(userId).setAuditTime(LocalDateTime.now()));
 
         // 记录售后日志
@@ -204,13 +196,13 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
     @Override
     @Transactional(rollbackFor = Exception.class)
     @AfterSaleLog(operateType = AfterSaleOperateTypeEnum.ADMIN_DISAGREE_APPLY)
-    public void disagreeAfterSale(Long userId, TradeAfterSaleDisagreeReqVO auditReqVO) {
+    public void disagreeAfterSale(Long userId, AfterSaleDisagreeReqVO auditReqVO) {
         // 校验售后单存在,并状态未审批
-        TradeAfterSaleDO afterSale = validateAfterSaleAuditable(auditReqVO.getId());
+        AfterSaleDO afterSale = validateAfterSaleAuditable(auditReqVO.getId());
 
         // 更新售后单的状态
-        Integer newStatus = TradeAfterSaleStatusEnum.SELLER_DISAGREE.getStatus();
-        updateAfterSaleStatus(afterSale.getId(), TradeAfterSaleStatusEnum.APPLY.getStatus(), new TradeAfterSaleDO()
+        Integer newStatus = AfterSaleStatusEnum.SELLER_DISAGREE.getStatus();
+        updateAfterSaleStatus(afterSale.getId(), AfterSaleStatusEnum.APPLY.getStatus(), new AfterSaleDO()
                 .setStatus(newStatus).setAuditUserId(userId).setAuditTime(LocalDateTime.now())
                 .setAuditReason(auditReqVO.getAuditReason()));
 
@@ -229,18 +221,18 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
      * @param id 售后编号
      * @return 售后单
      */
-    private TradeAfterSaleDO validateAfterSaleAuditable(Long id) {
-        TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectById(id);
+    private AfterSaleDO validateAfterSaleAuditable(Long id) {
+        AfterSaleDO afterSale = tradeAfterSaleMapper.selectById(id);
         if (afterSale == null) {
             throw exception(AFTER_SALE_NOT_FOUND);
         }
-        if (ObjectUtil.notEqual(afterSale.getStatus(), TradeAfterSaleStatusEnum.APPLY.getStatus())) {
+        if (ObjectUtil.notEqual(afterSale.getStatus(), AfterSaleStatusEnum.APPLY.getStatus())) {
             throw exception(AFTER_SALE_AUDIT_FAIL_STATUS_NOT_APPLY);
         }
         return afterSale;
     }
 
-    private void updateAfterSaleStatus(Long id, Integer status, TradeAfterSaleDO updateObj) {
+    private void updateAfterSaleStatus(Long id, Integer status, AfterSaleDO updateObj) {
         int updateCount = tradeAfterSaleMapper.updateByIdAndStatus(id, status, updateObj);
         if (updateCount == 0) {
             throw exception(AFTER_SALE_UPDATE_STATUS_FAIL);
@@ -250,26 +242,26 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
     @Override
     @Transactional(rollbackFor = Exception.class)
     @AfterSaleLog(operateType = AfterSaleOperateTypeEnum.MEMBER_DELIVERY)
-    public void deliveryAfterSale(Long userId, AppTradeAfterSaleDeliveryReqVO deliveryReqVO) {
+    public void deliveryAfterSale(Long userId, AppAfterSaleDeliveryReqVO deliveryReqVO) {
         // 校验售后单存在,并状态未退货
-        TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectById(deliveryReqVO.getId());
+        AfterSaleDO afterSale = tradeAfterSaleMapper.selectById(deliveryReqVO.getId());
         if (afterSale == null) {
             throw exception(AFTER_SALE_NOT_FOUND);
         }
-        if (ObjectUtil.notEqual(afterSale.getStatus(), TradeAfterSaleStatusEnum.SELLER_AGREE.getStatus())) {
+        if (ObjectUtil.notEqual(afterSale.getStatus(), AfterSaleStatusEnum.SELLER_AGREE.getStatus())) {
             throw exception(AFTER_SALE_DELIVERY_FAIL_STATUS_NOT_SELLER_AGREE);
         }
         DeliveryExpressDO express = deliveryExpressService.validateDeliveryExpress(deliveryReqVO.getLogisticsId());
 
         // 更新售后单的物流信息
-        updateAfterSaleStatus(afterSale.getId(), TradeAfterSaleStatusEnum.SELLER_AGREE.getStatus(), new TradeAfterSaleDO()
-                .setStatus(TradeAfterSaleStatusEnum.BUYER_DELIVERY.getStatus())
+        updateAfterSaleStatus(afterSale.getId(), AfterSaleStatusEnum.SELLER_AGREE.getStatus(), new AfterSaleDO()
+                .setStatus(AfterSaleStatusEnum.BUYER_DELIVERY.getStatus())
                 .setLogisticsId(deliveryReqVO.getLogisticsId()).setLogisticsNo(deliveryReqVO.getLogisticsNo())
                 .setDeliveryTime(LocalDateTime.now()));
 
         // 记录售后日志
         AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(),
-                TradeAfterSaleStatusEnum.BUYER_DELIVERY.getStatus(),
+                AfterSaleStatusEnum.BUYER_DELIVERY.getStatus(),
                 MapUtil.<String, Object>builder().put("expressName", express.getName())
                         .put("logisticsNo", deliveryReqVO.getLogisticsNo()).build());
 
@@ -281,15 +273,15 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
     @AfterSaleLog(operateType = AfterSaleOperateTypeEnum.ADMIN_AGREE_RECEIVE)
     public void receiveAfterSale(Long userId, Long id) {
         // 校验售后单存在,并状态为已退货
-        TradeAfterSaleDO afterSale = validateAfterSaleReceivable(id);
+        AfterSaleDO afterSale = validateAfterSaleReceivable(id);
 
         // 更新售后单的状态
-        updateAfterSaleStatus(afterSale.getId(), TradeAfterSaleStatusEnum.BUYER_DELIVERY.getStatus(), new TradeAfterSaleDO()
-                .setStatus(TradeAfterSaleStatusEnum.WAIT_REFUND.getStatus()).setReceiveTime(LocalDateTime.now()));
+        updateAfterSaleStatus(afterSale.getId(), AfterSaleStatusEnum.BUYER_DELIVERY.getStatus(), new AfterSaleDO()
+                .setStatus(AfterSaleStatusEnum.WAIT_REFUND.getStatus()).setReceiveTime(LocalDateTime.now()));
 
         // 记录售后日志
         AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(),
-                TradeAfterSaleStatusEnum.WAIT_REFUND.getStatus());
+                AfterSaleStatusEnum.WAIT_REFUND.getStatus());
 
         // TODO 发送售后消息
     }
@@ -297,24 +289,24 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
     @Override
     @Transactional(rollbackFor = Exception.class)
     @AfterSaleLog(operateType = AfterSaleOperateTypeEnum.ADMIN_DISAGREE_RECEIVE)
-    public void refuseAfterSale(Long userId, TradeAfterSaleRefuseReqVO refuseReqVO) {
+    public void refuseAfterSale(Long userId, AfterSaleRefuseReqVO refuseReqVO) {
         // 校验售后单存在,并状态为已退货
-        TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectById(refuseReqVO.getId());
+        AfterSaleDO afterSale = tradeAfterSaleMapper.selectById(refuseReqVO.getId());
         if (afterSale == null) {
             throw exception(AFTER_SALE_NOT_FOUND);
         }
-        if (ObjectUtil.notEqual(afterSale.getStatus(), TradeAfterSaleStatusEnum.BUYER_DELIVERY.getStatus())) {
+        if (ObjectUtil.notEqual(afterSale.getStatus(), AfterSaleStatusEnum.BUYER_DELIVERY.getStatus())) {
             throw exception(AFTER_SALE_CONFIRM_FAIL_STATUS_NOT_BUYER_DELIVERY);
         }
 
         // 更新售后单的状态
-        updateAfterSaleStatus(afterSale.getId(), TradeAfterSaleStatusEnum.BUYER_DELIVERY.getStatus(), new TradeAfterSaleDO()
-                .setStatus(TradeAfterSaleStatusEnum.SELLER_REFUSE.getStatus()).setReceiveTime(LocalDateTime.now())
+        updateAfterSaleStatus(afterSale.getId(), AfterSaleStatusEnum.BUYER_DELIVERY.getStatus(), new AfterSaleDO()
+                .setStatus(AfterSaleStatusEnum.SELLER_REFUSE.getStatus()).setReceiveTime(LocalDateTime.now())
                 .setReceiveReason(refuseReqVO.getRefuseMemo()));
 
         // 记录售后日志
         AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(),
-                TradeAfterSaleStatusEnum.SELLER_REFUSE.getStatus(),
+                AfterSaleStatusEnum.SELLER_REFUSE.getStatus(),
                 MapUtil.of("reason", refuseReqVO.getRefuseMemo()));
 
         // TODO 发送售后消息
@@ -329,12 +321,12 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
      * @param id 售后编号
      * @return 售后单
      */
-    private TradeAfterSaleDO validateAfterSaleReceivable(Long id) {
-        TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectById(id);
+    private AfterSaleDO validateAfterSaleReceivable(Long id) {
+        AfterSaleDO afterSale = tradeAfterSaleMapper.selectById(id);
         if (afterSale == null) {
             throw exception(AFTER_SALE_NOT_FOUND);
         }
-        if (ObjectUtil.notEqual(afterSale.getStatus(), TradeAfterSaleStatusEnum.BUYER_DELIVERY.getStatus())) {
+        if (ObjectUtil.notEqual(afterSale.getStatus(), AfterSaleStatusEnum.BUYER_DELIVERY.getStatus())) {
             throw exception(AFTER_SALE_CONFIRM_FAIL_STATUS_NOT_BUYER_DELIVERY);
         }
         return afterSale;
@@ -345,11 +337,11 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
     @AfterSaleLog(operateType = AfterSaleOperateTypeEnum.ADMIN_REFUND)
     public void refundAfterSale(Long userId, String userIp, Long id) {
         // 校验售后单的状态,并状态待退款
-        TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectById(id);
+        AfterSaleDO afterSale = tradeAfterSaleMapper.selectById(id);
         if (afterSale == null) {
             throw exception(AFTER_SALE_NOT_FOUND);
         }
-        if (ObjectUtil.notEqual(afterSale.getStatus(), TradeAfterSaleStatusEnum.WAIT_REFUND.getStatus())) {
+        if (ObjectUtil.notEqual(afterSale.getStatus(), AfterSaleStatusEnum.WAIT_REFUND.getStatus())) {
             throw exception(AFTER_SALE_REFUND_FAIL_STATUS_NOT_WAIT_REFUND);
         }
 
@@ -357,12 +349,12 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
         createPayRefund(userIp, afterSale);
 
         // 更新售后单的状态为【已完成】
-        updateAfterSaleStatus(afterSale.getId(), TradeAfterSaleStatusEnum.WAIT_REFUND.getStatus(), new TradeAfterSaleDO()
-                .setStatus(TradeAfterSaleStatusEnum.COMPLETE.getStatus()).setRefundTime(LocalDateTime.now()));
+        updateAfterSaleStatus(afterSale.getId(), AfterSaleStatusEnum.WAIT_REFUND.getStatus(), new AfterSaleDO()
+                .setStatus(AfterSaleStatusEnum.COMPLETE.getStatus()).setRefundTime(LocalDateTime.now()));
 
         // 记录售后日志
         AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(),
-                TradeAfterSaleStatusEnum.COMPLETE.getStatus());
+                AfterSaleStatusEnum.COMPLETE.getStatus());
 
         // TODO 发送售后消息
 
@@ -370,16 +362,16 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
         tradeOrderUpdateService.updateOrderItemWhenAfterSaleSuccess(afterSale.getOrderItemId(), afterSale.getRefundPrice());
     }
 
-    private void createPayRefund(String userIp, TradeAfterSaleDO afterSale) {
+    private void createPayRefund(String userIp, AfterSaleDO afterSale) {
         TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
 
             @Override
             public void afterCommit() {
                 // 创建退款单
-                PayRefundCreateReqDTO createReqDTO = TradeAfterSaleConvert.INSTANCE.convert(userIp, afterSale, tradeOrderProperties);
+                PayRefundCreateReqDTO createReqDTO = AfterSaleConvert.INSTANCE.convert(userIp, afterSale, tradeOrderProperties);
                 Long payRefundId = payRefundApi.createRefund(createReqDTO);
                 // 更新售后单的退款单号
-                tradeAfterSaleMapper.updateById(new TradeAfterSaleDO().setId(afterSale.getId()).setPayRefundId(payRefundId));
+                tradeAfterSaleMapper.updateById(new AfterSaleDO().setId(afterSale.getId()).setPayRefundId(payRefundId));
             }
         });
     }
@@ -389,23 +381,23 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
     @AfterSaleLog(operateType = AfterSaleOperateTypeEnum.MEMBER_CANCEL)
     public void cancelAfterSale(Long userId, Long id) {
         // 校验售后单的状态,并状态待退款
-        TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectById(id);
+        AfterSaleDO afterSale = tradeAfterSaleMapper.selectById(id);
         if (afterSale == null) {
             throw exception(AFTER_SALE_NOT_FOUND);
         }
-        if (!ObjectUtils.equalsAny(afterSale.getStatus(), TradeAfterSaleStatusEnum.APPLY.getStatus(),
-                TradeAfterSaleStatusEnum.SELLER_AGREE.getStatus(),
-                TradeAfterSaleStatusEnum.BUYER_DELIVERY.getStatus())) {
+        if (!ObjectUtils.equalsAny(afterSale.getStatus(), AfterSaleStatusEnum.APPLY.getStatus(),
+                AfterSaleStatusEnum.SELLER_AGREE.getStatus(),
+                AfterSaleStatusEnum.BUYER_DELIVERY.getStatus())) {
             throw exception(AFTER_SALE_CANCEL_FAIL_STATUS_NOT_APPLY_OR_AGREE_OR_BUYER_DELIVERY);
         }
 
         // 更新售后单的状态为【已取消】
-        updateAfterSaleStatus(afterSale.getId(), afterSale.getStatus(), new TradeAfterSaleDO()
-                .setStatus(TradeAfterSaleStatusEnum.BUYER_CANCEL.getStatus()));
+        updateAfterSaleStatus(afterSale.getId(), afterSale.getStatus(), new AfterSaleDO()
+                .setStatus(AfterSaleStatusEnum.BUYER_CANCEL.getStatus()));
 
         // 记录售后日志
         AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(),
-                TradeAfterSaleStatusEnum.BUYER_CANCEL.getStatus());
+                AfterSaleStatusEnum.BUYER_CANCEL.getStatus());
 
         // TODO 发送售后消息
 
@@ -415,52 +407,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
 
     @Override
     public Long getApplyingAfterSaleCount(Long userId) {
-        return tradeAfterSaleMapper.selectCountByUserIdAndStatus(userId, TradeAfterSaleStatusEnum.APPLYING_STATUSES);
-    }
-
-    @Deprecated
-    private void createAfterSaleLog(Long userId, Integer userType, TradeAfterSaleDO afterSale,
-                                    Integer beforeStatus, Integer afterStatus) {
-        TradeAfterSaleLogCreateReqDTO logDTO = new TradeAfterSaleLogCreateReqDTO()
-                .setUserId(userId)
-                .setUserType(userType)
-                .setAfterSaleId(afterSale.getId())
-                .setOperateType(afterStatus.toString());
-        // TODO 废弃,待删除
-        this.createLog(logDTO);
-    }
-
-    // TODO @CHENCHEN:这个注释,写在接口就好了,补充重复写哈;@date 应该是 @since
-    /**
-     * 日志记录
-     *
-     * @param logDTO 日志记录
-     * @author 陈賝
-     * @date 2023/6/12 14:18
-     */
-    @Override
-    @Async
-    public void createLog(TradeAfterSaleLogCreateReqDTO logDTO) {
-        try {
-            TradeAfterSaleLogDO afterSaleLog = new TradeAfterSaleLogDO()
-                    .setUserId(logDTO.getUserId())
-                    .setUserType(logDTO.getUserType())
-                    .setAfterSaleId(logDTO.getAfterSaleId())
-                    .setOperateType(logDTO.getOperateType())
-                    .setContent(logDTO.getContent());
-            tradeAfterSaleLogMapper.insert(afterSaleLog);
-       // TODO @CHENCHEN:代码排版哈;空格要正确
-        }catch (Exception exception){
-            log.error("[createLog][request({}) 日志记录错误]", toJsonString(logDTO), exception);
-        }
-    }
-
-    // TODO @puhui999:应该返回 do 哈。
-    @Override
-    public List<TradeAfterSaleLogRespVO> getLog(Long afterSaleId) {
-        // TODO 不熟悉流程先这么滴
-        List<TradeAfterSaleLogDO> saleLogDOs = tradeAfterSaleLogMapper.selectList(TradeAfterSaleLogDO::getAfterSaleId, afterSaleId);
-        return TradeAfterSaleConvert.INSTANCE.convertList(saleLogDOs);
+        return tradeAfterSaleMapper.selectCountByUserIdAndStatus(userId, AfterSaleStatusEnum.APPLYING_STATUSES);
     }
 
 }

+ 57 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/bo/AfterSaleLogCreateReqBO.java

@@ -0,0 +1,57 @@
+package cn.iocoder.yudao.module.trade.service.aftersale.bo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+
+/**
+ * 售后日志的创建 Request BO
+ *
+ * @author 陈賝
+ * @since 2023/6/19 09:54
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class AfterSaleLogCreateReqBO {
+
+    /**
+     * 用户编号
+     */
+    @NotNull(message = "用户编号不能为空")
+    private Long userId;
+    /**
+     * 用户类型
+     */
+    @NotNull(message = "用户类型不能为空")
+    private Integer userType;
+
+    /**
+     * 售后编号
+     */
+    @NotNull(message = "售后编号不能为空")
+    private Long afterSaleId;
+    /**
+     * 操作前状态
+     */
+    private Integer beforeStatus;
+    /**
+     * 操作后状态
+     */
+    @NotNull(message = "操作后的状态不能为空")
+    private Integer afterStatus;
+
+    /**
+     * 操作类型
+     */
+    @NotNull(message = "操作类型不能为空")
+    private Integer operateType;
+    /**
+     * 操作明细
+     */
+    @NotEmpty(message = "操作明细不能为空")
+    private String content;
+}

+ 44 - 77
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressTemplateServiceImpl.java

@@ -2,11 +2,10 @@ package cn.iocoder.yudao.module.trade.service.delivery;
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.lang.Assert;
+import cn.hutool.core.util.ObjectUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.DeliveryExpressTemplateCreateReqVO;
-import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.DeliveryExpressTemplateDetailRespVO;
-import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.DeliveryExpressTemplatePageReqVO;
-import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.DeliveryExpressTemplateUpdateReqVO;
+import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
+import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.*;
 import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateChargeDO;
 import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateDO;
 import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateFreeDO;
@@ -50,21 +49,21 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla
         validateTemplateNameUnique(createReqVO.getName(), null);
 
         // 插入
-        DeliveryExpressTemplateDO deliveryExpressTemplate = INSTANCE.convert(createReqVO);
-        expressTemplateMapper.insert(deliveryExpressTemplate);
+        DeliveryExpressTemplateDO template = INSTANCE.convert(createReqVO);
+        expressTemplateMapper.insert(template);
         // 插入运费模板计费表
-        if (CollUtil.isNotEmpty(createReqVO.getTemplateCharge())) {
+        if (CollUtil.isNotEmpty(createReqVO.getCharges())) {
             expressTemplateChargeMapper.insertBatch(
-                    INSTANCE.convertTemplateChargeList(deliveryExpressTemplate.getId(), createReqVO.getChargeMode(), createReqVO.getTemplateCharge())
+                    INSTANCE.convertTemplateChargeList(template.getId(), createReqVO.getChargeMode(), createReqVO.getCharges())
             );
         }
         // 插入运费模板包邮表
-        if (CollUtil.isNotEmpty(createReqVO.getTemplateFree())) {
+        if (CollUtil.isNotEmpty(createReqVO.getFrees())) {
             expressTemplateFreeMapper.insertBatch(
-                    INSTANCE.convertTemplateFreeList(deliveryExpressTemplate.getId(), createReqVO.getTemplateFree())
+                    INSTANCE.convertTemplateFreeList(template.getId(), createReqVO.getFrees())
             );
         }
-        return deliveryExpressTemplate.getId();
+        return template.getId();
     }
 
     @Override
@@ -76,76 +75,54 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla
         validateTemplateNameUnique(updateReqVO.getName(), updateReqVO.getId());
 
         // 更新运费从表
-        updateExpressTemplateCharge(updateReqVO);
+        updateExpressTemplateCharge(updateReqVO.getId(), updateReqVO.getChargeMode(), updateReqVO.getCharges());
         // 更新包邮从表
-        updateExpressTemplateFree(updateReqVO);
+        updateExpressTemplateFree(updateReqVO.getId(), updateReqVO.getFrees());
         // 更新模板主表
         DeliveryExpressTemplateDO updateObj = INSTANCE.convert(updateReqVO);
         expressTemplateMapper.updateById(updateObj);
     }
 
-    private void updateExpressTemplateFree(DeliveryExpressTemplateUpdateReqVO updateReqVO) {
-        // 1.1 获得新增/修改的区域列表
-        List<DeliveryExpressTemplateFreeDO> oldFreeList = expressTemplateFreeMapper.selectListByTemplateId(updateReqVO.getId());
-        List<DeliveryExpressTemplateUpdateReqVO.ExpressTemplateFreeUpdateVO> newFreeList = updateReqVO.getTemplateFree();
-        List<DeliveryExpressTemplateFreeDO> addFreeList = new ArrayList<>(newFreeList.size()); // 新增包邮区域列表
-        List<DeliveryExpressTemplateFreeDO> updateFreeList = new ArrayList<>(newFreeList.size()); // 更新包邮区域列表
-        for (DeliveryExpressTemplateUpdateReqVO.ExpressTemplateFreeUpdateVO item : newFreeList) {
-            if (Objects.nonNull(item.getId())) {
-                updateFreeList.add(INSTANCE.convertTemplateFree(item));
-            } else {
-                item.setTemplateId(updateReqVO.getId());
-                addFreeList.add(INSTANCE.convertTemplateFree(item));
-            }
-        }
-        // 1.2 新增
-        if (CollUtil.isNotEmpty(addFreeList)) {
-            expressTemplateFreeMapper.insertBatch(addFreeList);
+    private void updateExpressTemplateFree(Long templateId, List<DeliveryExpressTemplateFreeBaseVO> frees) {
+        // 第一步,对比新老数据,获得添加、修改、删除的列表
+        List<DeliveryExpressTemplateFreeDO> oldList = expressTemplateFreeMapper.selectListByTemplateId(templateId);
+        List<DeliveryExpressTemplateFreeDO> newList = INSTANCE.convertTemplateFreeList(templateId, frees);
+        List<List<DeliveryExpressTemplateFreeDO>> diffList = CollectionUtils.diffList(oldList, newList,
+                (oldVal, newVal) -> ObjectUtil.equal(oldVal.getId(), newVal.getTemplateId()));
+
+        // 第二步,批量添加、修改、删除
+        if (CollUtil.isNotEmpty(diffList.get(0))) {
+            expressTemplateFreeMapper.insertBatch(diffList.get(0));
         }
-        // 1.3 修改
-        if (CollUtil.isNotEmpty(updateFreeList)) {
-            expressTemplateFreeMapper.updateBatch(updateFreeList);
+        if (CollUtil.isNotEmpty(diffList.get(1))) {
+            expressTemplateFreeMapper.updateBatch(diffList.get(1));
         }
-
-        // 2. 删除
-        Set<Long> deleteFreeIds = convertSet(oldFreeList, DeliveryExpressTemplateFreeDO::getId);
-        deleteFreeIds.removeAll(convertSet(updateFreeList, DeliveryExpressTemplateFreeDO::getId));
-        if (CollUtil.isNotEmpty(deleteFreeIds)) {
-            expressTemplateFreeMapper.deleteBatchIds(deleteFreeIds);
+        if (CollUtil.isNotEmpty(diffList.get(2))) {
+            expressTemplateFreeMapper.deleteBatchIds(convertList(diffList.get(2), DeliveryExpressTemplateFreeDO::getId));
         }
     }
 
-    private void updateExpressTemplateCharge(DeliveryExpressTemplateUpdateReqVO updateReqVO) {
-        // 1.1 获得新增/修改的区域列表
-        List<DeliveryExpressTemplateChargeDO> oldChargeList = expressTemplateChargeMapper.selectListByTemplateId(updateReqVO.getId());
-        List<DeliveryExpressTemplateUpdateReqVO.ExpressTemplateChargeUpdateVO> newChargeList = updateReqVO.getTemplateCharge();
-        List<DeliveryExpressTemplateChargeDO> addList = new ArrayList<>(newChargeList.size()); // 新增运费区域列表
-        List<DeliveryExpressTemplateChargeDO> updateList = new ArrayList<>(newChargeList.size()); // 更新运费区域列表
-        for (DeliveryExpressTemplateUpdateReqVO.ExpressTemplateChargeUpdateVO item : newChargeList) {
-            if (item.getId() != null) {
-                // 计费模式以主表为准
-                item.setChargeMode(updateReqVO.getChargeMode());
-                updateList.add(INSTANCE.convertTemplateCharge(item));
-            } else {
-                item.setTemplateId(updateReqVO.getId());
-                item.setChargeMode(updateReqVO.getChargeMode());
-                addList.add(INSTANCE.convertTemplateCharge(item));
+    private void updateExpressTemplateCharge(Long templateId, Integer chargeMode, List<DeliveryExpressTemplateChargeBaseVO> charges) {
+        // 第一步,对比新老数据,获得添加、修改、删除的列表
+        List<DeliveryExpressTemplateChargeDO> oldList = expressTemplateChargeMapper.selectListByTemplateId(templateId);
+        List<DeliveryExpressTemplateChargeDO> newList = INSTANCE.convertTemplateChargeList(templateId, chargeMode, charges);
+        List<List<DeliveryExpressTemplateChargeDO>> diffList = diffList(oldList, newList, (oldVal, newVal) -> {
+            boolean same = ObjectUtil.equal(oldVal.getId(), newVal.getId());
+            if (same) {
+                newVal.setChargeMode(chargeMode); // 更新下收费模式
             }
+            return same;
+        });
+
+        // 第二步,批量添加、修改、删除
+        if (CollUtil.isNotEmpty(diffList.get(0))) {
+            expressTemplateChargeMapper.insertBatch(diffList.get(0));
         }
-        // 1.2 新增
-        if (CollUtil.isNotEmpty(addList)) {
-            expressTemplateChargeMapper.insertBatch(addList);
+        if (CollUtil.isNotEmpty(diffList.get(1))) {
+            expressTemplateChargeMapper.updateBatch(diffList.get(1));
         }
-        // 1.3 修改
-        if (CollUtil.isNotEmpty(updateList)) {
-            expressTemplateChargeMapper.updateBatch(updateList);
-        }
-
-        // 2. 删除
-        Set<Long> deleteChargeIds = convertSet(oldChargeList, DeliveryExpressTemplateChargeDO::getId);
-        deleteChargeIds.removeAll(convertSet(updateList, DeliveryExpressTemplateChargeDO::getId));
-        if (CollUtil.isNotEmpty(deleteChargeIds)) {
-            expressTemplateChargeMapper.deleteBatchIds(deleteChargeIds);
+        if (CollUtil.isNotEmpty(diffList.get(2))) {
+            expressTemplateChargeMapper.deleteBatchIds(convertList(diffList.get(2), DeliveryExpressTemplateChargeDO::getId));
         }
     }
 
@@ -238,14 +215,4 @@ public class DeliveryExpressTemplateServiceImpl implements DeliveryExpressTempla
         return INSTANCE.convertMap(areaId, templateList, chargeList, freeList);
     }
 
-    private DeliveryExpressTemplateRespBO.Charge findMatchExpressTemplateCharge(
-            List<DeliveryExpressTemplateChargeDO> templateChargeList, Integer areaId) {
-        return INSTANCE.convertTemplateCharge(findFirst(templateChargeList, item -> item.getAreaIds().contains(areaId)));
-    }
-
-    private DeliveryExpressTemplateRespBO.Free findMatchExpressTemplateFree(
-            List<DeliveryExpressTemplateFreeDO> templateFreeList, Integer areaId) {
-        return INSTANCE.convertTemplateFree(findFirst(templateFreeList, item -> item.getAreaIds().contains(areaId)));
-    }
-
 }

+ 4 - 5
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryService.java

@@ -94,12 +94,12 @@ public interface TradeOrderQueryService {
     TradeOrderItemDO getOrderItem(Long userId, Long itemId);
 
     /**
-     * 根据交易订单项编号数组,查询交易订单项
+     * 获得交易订单项
      *
-     * @param ids 交易订单项编号数组
-     * @return 交易订单项数组
+     * @param id 交易订单项编号 itemId
+     * @return 交易订单项
      */
-    List<TradeOrderItemDO> getOrderItemList(Collection<Long> ids);
+    TradeOrderItemDO getOrderItem(Long id);
 
     /**
      * 根据交易订单编号,查询交易订单项
@@ -119,5 +119,4 @@ public interface TradeOrderQueryService {
      */
     List<TradeOrderItemDO> getOrderItemListByOrderId(Collection<Long> orderIds);
 
-
 }

+ 2 - 2
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryServiceImpl.java

@@ -156,8 +156,8 @@ public class TradeOrderQueryServiceImpl implements TradeOrderQueryService {
     }
 
     @Override
-    public List<TradeOrderItemDO> getOrderItemList(Collection<Long> ids) {
-        return tradeOrderItemMapper.selectBatchIds(ids);
+    public TradeOrderItemDO getOrderItem(Long id) {
+        return tradeOrderItemMapper.selectById(id);
     }
 
     @Override

+ 3 - 3
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java

@@ -47,7 +47,7 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
 import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderItemMapper;
 import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderMapper;
-import cn.iocoder.yudao.module.trade.dal.redis.no.TradeOrderNoRedisDAO;
+import cn.iocoder.yudao.module.trade.dal.redis.no.TradeNoRedisDAO;
 import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum;
 import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum;
 import cn.iocoder.yudao.module.trade.enums.order.*;
@@ -97,7 +97,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
     @Resource
     private TradeOrderItemMapper tradeOrderItemMapper;
     @Resource
-    private TradeOrderNoRedisDAO orderNoRedisDAO;
+    private TradeNoRedisDAO tradeNoRedisDAO;
 
     @Resource
     private List<TradeOrderHandler> tradeOrderHandlers;
@@ -215,7 +215,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
                                           TradePriceCalculateRespBO calculateRespBO) {
         TradeOrderDO order = TradeOrderConvert.INSTANCE.convert(userId, clientIp, createReqVO, calculateRespBO);
         order.setType(calculateRespBO.getType());
-        order.setNo(orderNoRedisDAO.generate(TradeOrderNoRedisDAO.TRADE_ORDER_NO_PREFIX));
+        order.setNo(tradeNoRedisDAO.generate(TradeNoRedisDAO.TRADE_ORDER_NO_PREFIX));
         order.setStatus(TradeOrderStatusEnum.UNPAID.getStatus());
         order.setRefundStatus(TradeOrderRefundStatusEnum.NONE.getStatus());
         order.setProductCount(getSumValue(calculateRespBO.getItems(), TradePriceCalculateRespBO.OrderItem::getCount, Integer::sum));

+ 1 - 1
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/bo/logger/TradeOrderLogCreateReqBO.java

@@ -28,7 +28,7 @@ public class TradeOrderLogCreateReqBO {
     /**
      * 订单编号
      */
-    @NotNull(message = "订单编号")
+    @NotNull(message = "订单编号不能为空")
     private Long orderId;
     /**
      * 操作前状态

+ 34 - 34
yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceTest.java → yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleServiceTest.java

@@ -4,17 +4,17 @@ import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
 import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi;
-import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSalePageReqVO;
-import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleCreateReqVO;
-import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO;
-import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleLogDO;
+import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSalePageReqVO;
+import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppAfterSaleCreateReqVO;
+import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.AfterSaleDO;
+import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.AfterSaleLogDO;
 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
-import cn.iocoder.yudao.module.trade.dal.mysql.aftersale.TradeAfterSaleLogMapper;
-import cn.iocoder.yudao.module.trade.dal.mysql.aftersale.TradeAfterSaleMapper;
-import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleStatusEnum;
-import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleTypeEnum;
-import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleWayEnum;
+import cn.iocoder.yudao.module.trade.dal.mysql.aftersale.AfterSaleLogMapper;
+import cn.iocoder.yudao.module.trade.dal.mysql.aftersale.AfterSaleMapper;
+import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleStatusEnum;
+import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleTypeEnum;
+import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleWayEnum;
 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum;
 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum;
 import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
@@ -37,20 +37,20 @@ import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.when;
 
 /**
- * {@link TradeAfterSaleService} 的单元测试
+ * {@link AfterSaleService} 的单元测试
  *
  * @author 芋道源码
  */
-@Import(TradeAfterSaleServiceImpl.class)
-public class TradeAfterSaleServiceTest extends BaseDbUnitTest {
+@Import(AfterSaleServiceImpl.class)
+public class AfterSaleServiceTest extends BaseDbUnitTest {
 
     @Resource
-    private TradeAfterSaleServiceImpl tradeAfterSaleService;
+    private AfterSaleServiceImpl tradeAfterSaleService;
 
     @Resource
-    private TradeAfterSaleMapper tradeAfterSaleMapper;
+    private AfterSaleMapper tradeAfterSaleMapper;
     @Resource
-    private TradeAfterSaleLogMapper tradeAfterSaleLogMapper;
+    private AfterSaleLogMapper tradeAfterSaleLogMapper;
 
     @MockBean
     private TradeOrderUpdateService tradeOrderUpdateService;
@@ -67,8 +67,8 @@ public class TradeAfterSaleServiceTest extends BaseDbUnitTest {
     public void testCreateAfterSale() {
         // 准备参数
         Long userId = 1024L;
-        AppTradeAfterSaleCreateReqVO createReqVO = new AppTradeAfterSaleCreateReqVO()
-                .setOrderItemId(1L).setRefundPrice(100).setWay(TradeAfterSaleWayEnum.RETURN_AND_REFUND.getWay())
+        AppAfterSaleCreateReqVO createReqVO = new AppAfterSaleCreateReqVO()
+                .setOrderItemId(1L).setRefundPrice(100).setWay(AfterSaleWayEnum.RETURN_AND_REFUND.getWay())
                 .setApplyReason("退钱").setApplyDescription("快退")
                 .setApplyPicUrls(asList("https://www.baidu.com/1.png", "https://www.baidu.com/2.png"));
         // mock 方法(交易订单项)
@@ -86,10 +86,10 @@ public class TradeAfterSaleServiceTest extends BaseDbUnitTest {
         // 调用
         Long afterSaleId = tradeAfterSaleService.createAfterSale(userId, createReqVO);
         // 断言(TradeAfterSaleDO)
-        TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectById(afterSaleId);
+        AfterSaleDO afterSale = tradeAfterSaleMapper.selectById(afterSaleId);
         assertNotNull(afterSale.getNo());
-        assertEquals(afterSale.getStatus(), TradeAfterSaleStatusEnum.APPLY.getStatus());
-        assertEquals(afterSale.getType(), TradeAfterSaleTypeEnum.IN_SALE.getType());
+        assertEquals(afterSale.getStatus(), AfterSaleStatusEnum.APPLY.getStatus());
+        assertEquals(afterSale.getType(), AfterSaleTypeEnum.IN_SALE.getType());
         assertPojoEquals(afterSale, createReqVO);
         assertEquals(afterSale.getUserId(), 1024L);
         assertPojoEquals(afterSale, orderItem, "id", "creator", "createTime", "updater", "updateTime");
@@ -101,22 +101,22 @@ public class TradeAfterSaleServiceTest extends BaseDbUnitTest {
         assertNull(afterSale.getDeliveryTime());
         assertNull(afterSale.getReceiveReason());
         // 断言(TradeAfterSaleLogDO)
-        TradeAfterSaleLogDO afterSaleLog = tradeAfterSaleLogMapper.selectList().get(0);
+        AfterSaleLogDO afterSaleLog = tradeAfterSaleLogMapper.selectList().get(0);
         assertEquals(afterSaleLog.getUserId(), userId);
         assertEquals(afterSaleLog.getUserType(), UserTypeEnum.MEMBER.getValue());
         assertEquals(afterSaleLog.getAfterSaleId(), afterSaleId);
         assertPojoEquals(afterSale, orderItem, "id", "creator", "createTime", "updater", "updateTime");
-        assertEquals(afterSaleLog.getContent(), TradeAfterSaleStatusEnum.APPLY.getContent());
+        assertEquals(afterSaleLog.getContent(), AfterSaleStatusEnum.APPLY.getContent());
     }
 
     @Test
     public void testGetAfterSalePage() {
         // mock 数据
-        TradeAfterSaleDO dbAfterSale = randomPojo(TradeAfterSaleDO.class, o -> { // 等会查询到
+        AfterSaleDO dbAfterSale = randomPojo(AfterSaleDO.class, o -> { // 等会查询到
             o.setNo("202211190847450020500077");
-            o.setStatus(TradeAfterSaleStatusEnum.APPLY.getStatus());
-            o.setWay(TradeAfterSaleWayEnum.RETURN_AND_REFUND.getWay());
-            o.setType(TradeAfterSaleTypeEnum.IN_SALE.getType());
+            o.setStatus(AfterSaleStatusEnum.APPLY.getStatus());
+            o.setWay(AfterSaleWayEnum.RETURN_AND_REFUND.getWay());
+            o.setType(AfterSaleTypeEnum.IN_SALE.getType());
             o.setOrderNo("202211190847450020500011");
             o.setSpuName("芋艿");
             o.setCreateTime(buildTime(2022, 1, 15));
@@ -125,11 +125,11 @@ public class TradeAfterSaleServiceTest extends BaseDbUnitTest {
         // 测试 no 不匹配
         tradeAfterSaleMapper.insert(cloneIgnoreId(dbAfterSale, o -> o.setNo("202211190847450020500066")));
         // 测试 status 不匹配
-        tradeAfterSaleMapper.insert(cloneIgnoreId(dbAfterSale, o -> o.setStatus(TradeAfterSaleStatusEnum.SELLER_REFUSE.getStatus())));
+        tradeAfterSaleMapper.insert(cloneIgnoreId(dbAfterSale, o -> o.setStatus(AfterSaleStatusEnum.SELLER_REFUSE.getStatus())));
         // 测试 way 不匹配
-        tradeAfterSaleMapper.insert(cloneIgnoreId(dbAfterSale, o -> o.setWay(TradeAfterSaleWayEnum.REFUND.getWay())));
+        tradeAfterSaleMapper.insert(cloneIgnoreId(dbAfterSale, o -> o.setWay(AfterSaleWayEnum.REFUND.getWay())));
         // 测试 type 不匹配
-        tradeAfterSaleMapper.insert(cloneIgnoreId(dbAfterSale, o -> o.setType(TradeAfterSaleTypeEnum.AFTER_SALE.getType())));
+        tradeAfterSaleMapper.insert(cloneIgnoreId(dbAfterSale, o -> o.setType(AfterSaleTypeEnum.AFTER_SALE.getType())));
         // 测试 orderNo 不匹配
         tradeAfterSaleMapper.insert(cloneIgnoreId(dbAfterSale, o -> o.setOrderNo("202211190847450020500022")));
         // 测试 spuName 不匹配
@@ -137,17 +137,17 @@ public class TradeAfterSaleServiceTest extends BaseDbUnitTest {
         // 测试 createTime 不匹配
         tradeAfterSaleMapper.insert(cloneIgnoreId(dbAfterSale, o -> o.setCreateTime(buildTime(2022, 1, 20))));
         // 准备参数
-        TradeAfterSalePageReqVO reqVO = new TradeAfterSalePageReqVO();
+        AfterSalePageReqVO reqVO = new AfterSalePageReqVO();
         reqVO.setNo("20221119084745002050007");
-        reqVO.setStatus(TradeAfterSaleStatusEnum.APPLY.getStatus());
-        reqVO.setWay(TradeAfterSaleWayEnum.RETURN_AND_REFUND.getWay());
-        reqVO.setType(TradeAfterSaleTypeEnum.IN_SALE.getType());
+        reqVO.setStatus(AfterSaleStatusEnum.APPLY.getStatus());
+        reqVO.setWay(AfterSaleWayEnum.RETURN_AND_REFUND.getWay());
+        reqVO.setType(AfterSaleTypeEnum.IN_SALE.getType());
         reqVO.setOrderNo("20221119084745002050001");
         reqVO.setSpuName("芋");
         reqVO.setCreateTime(new LocalDateTime[]{buildTime(2022, 1, 1), buildTime(2022, 1, 16)});
 
         // 调用
-        PageResult<TradeAfterSaleDO> pageResult = tradeAfterSaleService.getAfterSalePage(reqVO);
+        PageResult<AfterSaleDO> pageResult = tradeAfterSaleService.getAfterSalePage(reqVO);
         // 断言
         assertEquals(1, pageResult.getTotal());
         assertEquals(1, pageResult.getList().size());

+ 1 - 1
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/redis/RedisKeyConstants.java

@@ -22,6 +22,6 @@ public interface RedisKeyConstants {
      * KEY 格式:pay_no:{prefix}
      * VALUE 数据格式:编号自增
      */
-    String PAY_NO = "pay_no";
+    String PAY_NO = "pay_no:";
 
 }

+ 11 - 3
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/redis/no/PayNoRedisDAO.java

@@ -1,9 +1,13 @@
 package cn.iocoder.yudao.module.pay.dal.redis.no;
 
-import cn.hutool.core.date.DatePattern;import cn.hutool.core.date.DateUtil;import org.springframework.data.redis.core.StringRedisTemplate;
+import cn.hutool.core.date.DatePattern;import cn.hutool.core.date.DateUtil;
+import cn.iocoder.yudao.module.pay.dal.redis.RedisKeyConstants;
+import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.stereotype.Repository;
 
-import javax.annotation.Resource;import java.time.LocalDateTime;
+import javax.annotation.Resource;
+import java.time.Duration;
+import java.time.LocalDateTime;
 
 /**
  * 支付序号的 Redis DAO
@@ -23,8 +27,12 @@ public class PayNoRedisDAO {
      * @return 序号
      */
     public String generate(String prefix) {
+        // 递增序号
         String noPrefix = prefix + DateUtil.format(LocalDateTime.now(), DatePattern.PURE_DATETIME_PATTERN);
-        Long no = stringRedisTemplate.opsForValue().increment(noPrefix);
+        String key = RedisKeyConstants.PAY_NO + noPrefix;
+        Long no = stringRedisTemplate.opsForValue().increment(key);
+        // 设置过期时间
+        stringRedisTemplate.expire(key, Duration.ofMinutes(1L));
         return noPrefix + no;
     }
 

+ 4 - 26
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/AreaController.java

@@ -6,17 +6,17 @@ import cn.iocoder.yudao.framework.ip.core.Area;
 import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
 import cn.iocoder.yudao.framework.ip.core.utils.IPUtils;
 import cn.iocoder.yudao.module.system.controller.admin.ip.vo.AreaNodeRespVO;
-import cn.iocoder.yudao.module.system.controller.admin.ip.vo.AreaNodeSimpleRespVO;
 import cn.iocoder.yudao.module.system.convert.ip.AreaConvert;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
 
-import java.util.ArrayList;
 import java.util.List;
-import java.util.Set;
 
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 
@@ -34,28 +34,6 @@ public class AreaController {
         return success(AreaConvert.INSTANCE.convertList(area.getChildren()));
     }
 
-    @GetMapping("/get-children")
-    @Operation(summary = "获得地区的下级区域")
-    @Parameter(name = "id", description = "区域编号", required = true, example = "150000")
-    public CommonResult<List<AreaNodeSimpleRespVO>> getChildren(@RequestParam("id") Integer id) {
-        Area area = AreaUtils.getArea(id);
-        Assert.notNull(area, String.format("获取不到 id : %d 的区域", id));
-        return success(AreaConvert.INSTANCE.convertList2(area.getChildren()));
-    }
-
-    // 4)方法改成 getAreaChildrenList 获得子节点们;5)url 可以已改成 children-list
-    //@芋艿 是不是叫 getAreaListByIds 更合适。 因为不一定是子节点。 用于前端树选择获取缓存数据。 见 <el-tree-select :cache-data="areaCache">
-    @GetMapping("/get-by-ids")
-    @Operation(summary = "通过区域 ids 获得地区列表")
-    @Parameter(name = "ids", description = "区域编号 ids", required = true, example = "1,150000")
-    public CommonResult<List<AreaNodeSimpleRespVO>> getAreaListByIds(@RequestParam("ids") Set<Integer> ids) {
-        List<Area> areaList = new ArrayList<>(ids.size());
-        for (Integer areaId : ids) {
-            areaList.add(AreaUtils.getArea(areaId));
-        }
-        return success(AreaConvert.INSTANCE.convertList2(areaList));
-    }
-
     @GetMapping("/get-by-ip")
     @Operation(summary = "获得 IP 对应的地区名")
     @Parameter(name = "ip", description = "IP", required = true)

+ 0 - 19
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/vo/AreaNodeSimpleRespVO.java

@@ -1,19 +0,0 @@
-package cn.iocoder.yudao.module.system.controller.admin.ip.vo;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-@Schema(description = "管理后台 - 简洁的地区节点 Response VO")
-@Data
-public class AreaNodeSimpleRespVO {
-
-    @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "110000")
-    private Integer id;
-
-    @Schema(description = "名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "北京")
-    private String name;
-
-    @Schema(description = "是否叶子节点", example = "false")
-    private Boolean leaf;
-
-}

+ 0 - 13
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/ip/AreaConvert.java

@@ -1,16 +1,12 @@
 package cn.iocoder.yudao.module.system.convert.ip;
 
 import cn.iocoder.yudao.framework.ip.core.Area;
-import cn.iocoder.yudao.framework.ip.core.enums.AreaTypeEnum;
 import cn.iocoder.yudao.module.system.controller.admin.ip.vo.AreaNodeRespVO;
-import cn.iocoder.yudao.module.system.controller.admin.ip.vo.AreaNodeSimpleRespVO;
 import cn.iocoder.yudao.module.system.controller.app.ip.vo.AppAreaNodeRespVO;
 import org.mapstruct.Mapper;
-import org.mapstruct.Mapping;
 import org.mapstruct.factory.Mappers;
 
 import java.util.List;
-import java.util.Objects;
 
 @Mapper
 public interface AreaConvert {
@@ -19,15 +15,6 @@ public interface AreaConvert {
 
     List<AreaNodeRespVO> convertList(List<Area> list);
 
-    List<AreaNodeSimpleRespVO> convertList2(List<Area> list);
-
-    @Mapping(source = "type", target = "leaf")
-    AreaNodeSimpleRespVO convert(Area area);
-
-    default Boolean convertAreaType(Integer type) {
-        return Objects.equals(AreaTypeEnum.DISTRICT.getType(), type);
-    }
-
     List<AppAreaNodeRespVO> convertList3(List<Area> list);
 
 }

+ 1 - 0
yudao-server/src/main/resources/application-dev.yaml

@@ -170,6 +170,7 @@ yudao:
     order-notify-url: http://yunai.natapp1.cc/admin-api/pay/notify/order # 支付渠道的【支付】回调地址
     refund-notify-url: http://yunai.natapp1.cc/admin-api/pay/notify/refund # 支付渠道的【退款】回调地址
   demo: true # 开启演示模式
+  tencent-lbs-key: TVDBZ-TDILD-4ON4B-PFDZA-RNLKH-VVF6E # QQ 地图的密钥 https://lbs.qq.com/service/staticV2/staticGuide/staticDoc
 
 justauth:
   enabled: true

+ 1 - 0
yudao-server/src/main/resources/application-local.yaml

@@ -213,6 +213,7 @@ yudao:
   error-code: # 错误码相关配置项
     enable: false
   demo: false # 关闭演示模式
+  tencent-lbs-key: TVDBZ-TDILD-4ON4B-PFDZA-RNLKH-VVF6E # QQ 地图的密钥 https://lbs.qq.com/service/staticV2/staticGuide/staticDoc
   clean-job:
     access-retain-day: 7
     error-retain-day: 8