Procházet zdrojové kódy

售后:
1、完善整个流程的实现

YunaiV před 1 rokem
rodič
revize
f217ba0807
18 změnil soubory, kde provedl 232 přidání a 158 odebrání
  1. 2 1
      yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java
  2. 8 8
      yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleStatusEnum.java
  3. 29 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.http
  4. 18 12
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.java
  5. 13 44
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/AppTradeAfterSaleController.java
  6. 0 6
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSaleDeliveryReqVO.java
  7. 2 2
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSaleRespVO.java
  8. 39 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/delivery/AppDeliverExpressController.java
  9. 16 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/delivery/vo/express/AppDeliveryExpressRespVO.java
  10. 13 37
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/aftersale/TradeAfterSaleConvert.java
  11. 5 3
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressConvert.java
  12. 2 2
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/TradeAfterSaleDO.java
  13. 10 2
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/aftersale/TradeAfterSaleMapper.java
  14. 5 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressMapper.java
  15. 29 12
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleService.java
  16. 21 9
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java
  17. 11 11
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressService.java
  18. 9 9
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressServiceImpl.java

+ 2 - 1
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java

@@ -45,7 +45,8 @@ public interface ErrorCodeConstants {
     ErrorCode AFTER_SALE_DELIVERY_FAIL_STATUS_NOT_SELLER_AGREE = new ErrorCode(1011000108, "退货失败,售后单状态不处于【待买家退货】");
     ErrorCode AFTER_SALE_CONFIRM_FAIL_STATUS_NOT_BUYER_DELIVERY = new ErrorCode(1011000109, "确认收货失败,售后单状态不处于【待确认收货】");
     ErrorCode AFTER_SALE_REFUND_FAIL_STATUS_NOT_WAIT_REFUND = new ErrorCode(1011000110, "退款失败,售后单状态不是【待退款】");
-    ErrorCode AFTER_SALE_CANCEL_FAIL_STATUS_NOT_APPLY_OR_AGREE = new ErrorCode(1011000111, "取消售后单失败,售后单状态不是【待审核】或【卖家同意】");
+    ErrorCode AFTER_SALE_CANCEL_FAIL_STATUS_NOT_APPLY_OR_AGREE_OR_BUYER_DELIVERY =
+            new ErrorCode(1011000111, "取消售后单失败,售后单状态不是【待审核】或【卖家同意】或【商家待收货】");
 
     // ==========  Cart 模块 1011002000 ==========
     ErrorCode CARD_ITEM_NOT_FOUND = new ErrorCode(1011002000, "购物车项不存在");

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

@@ -22,35 +22,35 @@ public enum TradeAfterSaleStatusEnum implements IntArrayValuable {
     /**
      * 【申请售后】
      */
-    APPLY(10,"申请中", "会员申请退款"),
+    APPLY(10,"申请中", "会员申请退款"), // 有赞的状态提示:退款申请待商家处理
     /**
      * 卖家通过售后;【商品待退货】
      */
-    SELLER_AGREE(20, "卖家通过", "商家同意退款"),
+    SELLER_AGREE(20, "卖家通过", "商家同意退款"), // 有赞的状态提示:请退货并填写物流信息
     /**
      * 买家已退货,等待卖家收货;【商家待收货】
      */
-    BUYER_DELIVERY(30,"待卖家收货", "会员填写退货物流信息"),
+    BUYER_DELIVERY(30,"待卖家收货", "会员填写退货物流信息"), // 有赞的状态提示:退货退款申请待商家处理
     /**
      * 卖家已收货,等待平台退款;等待退款【等待退款】
      */
-    WAIT_REFUND(40, "等待平台退款", "商家收货"),
+    WAIT_REFUND(40, "等待平台退款", "商家收货"), // 有赞的状态提示:无(有赞无该状态)
     /**
      * 完成退款【退款成功】
      */
-    COMPLETE(50, "完成", "商家确认退款"),
+    COMPLETE(50, "完成", "商家确认退款"), // 有赞的状态提示:退款成功
     /**
      * 【买家取消】
      */
-    BUYER_CANCEL(61, "买家取消售后", "会员取消退款"),
+    BUYER_CANCEL(61, "买家取消售后", "会员取消退款"), // 有赞的状态提示:退款关闭
     /**
      * 卖家拒绝售后;商家拒绝【商家拒绝】
      */
-    SELLER_DISAGREE(62,"卖家拒绝", "商家拒绝退款"),
+    SELLER_DISAGREE(62,"卖家拒绝", "商家拒绝退款"), // 有赞的状态提示:商家不同意退款申请
     /**
      * 卖家拒绝收货,终止售后;【商家拒收货】
      */
-    SELLER_REFUSE(63,"卖家拒绝收货", "商家拒绝收货"),
+    SELLER_REFUSE(63,"卖家拒绝收货", "商家拒绝收货"), // 有赞的状态提示:商家拒绝收货,不同意退款
     ;
 
     public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeAfterSaleStatusEnum::getStatus).toArray();

+ 29 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.http

@@ -2,3 +2,32 @@
 GET {{baseUrl}}/trade/after-sale/page?pageNo=1&pageSize=10
 Authorization: Bearer {{token}}
 tenant-id: {{adminTenentId}}
+
+### 同意售后 => 成功
+PUT {{baseUrl}}/trade/after-sale/agree?id=7
+Authorization: Bearer {{token}}
+tenant-id: {{adminTenentId}}
+Content-Type: application/json
+
+### 拒绝售后 => 成功
+PUT {{baseUrl}}/trade/after-sale/disagree
+Authorization: Bearer {{token}}
+tenant-id: {{adminTenentId}}
+Content-Type: application/json
+
+{
+  "id": 6,
+  "auditReason": "阿巴巴"
+}
+
+### 确认退款 => 成功
+PUT {{baseUrl}}/trade/after-sale/refund?id=6
+Authorization: Bearer {{token}}
+tenant-id: {{adminTenentId}}
+Content-Type: application/json
+
+### 确认收货 => 成功
+PUT {{baseUrl}}/trade/after-sale/receive?id=7
+Authorization: Bearer {{token}}
+tenant-id: {{adminTenentId}}
+Content-Type: application/json

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

@@ -3,10 +3,10 @@ package cn.iocoder.yudao.module.trade.controller.admin.aftersale;
 import cn.hutool.core.collection.CollUtil;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
 import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
-import cn.iocoder.yudao.module.product.api.property.ProductPropertyValueApi;
-import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
+import cn.iocoder.yudao.module.pay.api.notify.dto.PayRefundNotifyReqDTO;
 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;
@@ -23,8 +23,8 @@ import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
+import javax.annotation.security.PermitAll;
 import javax.validation.Valid;
-import java.util.List;
 import java.util.Map;
 
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -32,7 +32,7 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.
 import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 
-@Tag(name = "管理后台 - 交易售后")
+@Tag(name = "管理后台 - 售后订单")
 @RestController
 @RequestMapping("/trade/after-sale")
 @Validated
@@ -44,11 +44,9 @@ public class TradeAfterSaleController {
 
     @Resource
     private MemberUserApi memberUserApi;
-    @Resource
-    private ProductPropertyValueApi productPropertyValueApi;
 
     @GetMapping("/page")
-    @Operation(summary = "获得交易售后分页")
+    @Operation(summary = "获得售后订单分页")
     @PreAuthorize("@ss.hasPermission('trade:after-sale:query')")
     public CommonResult<PageResult<TradeAfterSaleRespPageItemVO>> getAfterSalePage(@Valid TradeAfterSalePageReqVO pageVO) {
         // 查询售后
@@ -57,13 +55,10 @@ public class TradeAfterSaleController {
             return success(PageResult.empty());
         }
 
-        // 查询商品属性
-        List<ProductPropertyValueDetailRespDTO> propertyValueDetails = productPropertyValueApi
-                .getPropertyValueDetailList(TradeAfterSaleConvert.INSTANCE.convertPropertyValueIds(pageResult.getList()));
         // 查询会员
         Map<Long, MemberUserRespDTO> memberUsers = memberUserApi.getUserMap(
                 convertSet(pageResult.getList(), TradeAfterSaleDO::getUserId));
-        return success(TradeAfterSaleConvert.INSTANCE.convertPage(pageResult, memberUsers, propertyValueDetails));
+        return success(TradeAfterSaleConvert.INSTANCE.convertPage(pageResult, memberUsers));
     }
 
     @PutMapping("/agree")
@@ -101,7 +96,7 @@ public class TradeAfterSaleController {
         return success(true);
     }
 
-    @PostMapping("/refund")
+    @PutMapping("/refund")
     @Operation(summary = "确认退款")
     @Parameter(name = "id", description = "售后编号", required = true, example = "1")
     @PreAuthorize("@ss.hasPermission('trade:after-sale:refund')")
@@ -110,4 +105,15 @@ public class TradeAfterSaleController {
         return success(true);
     }
 
+    @PostMapping("/update-refunded")
+    @Operation(summary = "更新售后订单为已退款") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob
+    @PermitAll // 无需登录,安全由 PayDemoOrderService 内部校验实现
+    @OperateLog(enable = false) // 禁用操作日志,因为没有操作人
+    public CommonResult<Boolean> updateAfterRefund(@RequestBody PayRefundNotifyReqDTO notifyReqDTO) {
+        // 目前业务逻辑,不需要做任何事情
+        // 当然,退款会有小概率会失败的情况,可以监控失败状态,进行告警
+        log.info("[updateAfterRefund][notifyReqDTO({})]", notifyReqDTO);
+        return success(true);
+    }
+
 }

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

@@ -1,11 +1,12 @@
 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.AppTradeAfterSalePageItemRespVO;
-import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductPropertyValueDetailRespVO;
+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.TradeAfterSaleWayEnum;
 import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.annotations.AfterSaleLog;
@@ -18,7 +19,6 @@ import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
-import java.time.LocalDateTime;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
@@ -36,49 +36,18 @@ public class AppTradeAfterSaleController {
     @Resource
     private TradeAfterSaleService afterSaleService;
 
-    // TODO 芋艿:待实现
     @GetMapping(value = "/page")
     @Operation(summary = "获得售后分页")
-    public CommonResult<PageResult<AppTradeAfterSalePageItemRespVO>> getAfterSalePage() {
-        AppTradeAfterSalePageItemRespVO vo = new AppTradeAfterSalePageItemRespVO();
-        vo.setId(1L);
-        vo.setNo("1146347329394184195");
-        vo.setStatus(61);
-        vo.setWay(10);
-        vo.setType(10);
-        vo.setApplyReason("不想要了");
-        vo.setApplyDescription("这个商品我不喜欢,想退款");
-        vo.setApplyPicUrls(Arrays.asList("pic_url_1", "pic_url_2", "pic_url_3"));
-
-        // 设置订单相关信息
-        vo.setOrderId(2001L);
-        vo.setOrderNo("23456789009876");
-        vo.setOrderItemId(3001L);
-        vo.setSpuId(4001L);
-        vo.setSpuName("商品名");
-        vo.setSkuId(5001L);
-        vo.setProperties(Arrays.asList(
-                new AppProductPropertyValueDetailRespVO().setPropertyId(6001L).setPropertyName("颜色").setValueId(7001L).setValueName("红色"),
-                new AppProductPropertyValueDetailRespVO().setPropertyId(6002L).setPropertyName("尺寸").setValueId(7002L).setValueName("XL")));
-        vo.setPicUrl("https://cdn.pixabay.com/photo/2022/12/06/06/21/lavender-7638368_1280.jpg");
-        vo.setCount(2);
-
-        // 设置审批相关信息
-        vo.setAuditReason("审核通过");
-
-        // 设置退款相关信息
-        vo.setRefundPrice(1000);
-        vo.setRefundTime(LocalDateTime.now());
-
-        // 设置退货相关信息
-        vo.setLogisticsId(7001L);
-        vo.setLogisticsNo("LAGN101010101001");
-        vo.setDeliveryTime(LocalDateTime.now());
-        vo.setReceiveTime(LocalDateTime.now());
-        vo.setReceiveReason("收货正常");
+    public CommonResult<PageResult<AppTradeAfterSaleRespVO>> getAfterSalePage(PageParam pageParam) {
+        return success(TradeAfterSaleConvert.INSTANCE.convertPage02(
+                afterSaleService.getAfterSalePage(getLoginUserId(), pageParam)));
+    }
 
-        return success(new PageResult<>(Arrays.asList(vo), 1L));
-//        return success(afterSaleService.getAfterSalePage(getLoginUserId()));
+    @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)));
     }
 
     // TODO 芋艿:待实现
@@ -99,7 +68,7 @@ public class AppTradeAfterSaleController {
         return success(afterSaleService.createAfterSale(getLoginUserId(), createReqVO));
     }
 
-    @PostMapping(value = "/delivery")
+    @PutMapping(value = "/delivery")
     @Operation(summary = "退回货物")
     public CommonResult<Boolean> deliveryAfterSale(@RequestBody AppTradeAfterSaleDeliveryReqVO deliveryReqVO) {
         afterSaleService.deliveryAfterSale(getLoginUserId(), deliveryReqVO);

+ 0 - 6
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSaleDeliveryReqVO.java

@@ -3,9 +3,7 @@ package cn.iocoder.yudao.module.trade.controller.app.aftersale.vo;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
-import javax.validation.constraints.NotEmpty;
 import javax.validation.constraints.NotNull;
-import java.time.LocalDateTime;
 
 @Schema(description = "用户 App - 交易售后退回货物 Request VO")
 @Data
@@ -23,8 +21,4 @@ public class AppTradeAfterSaleDeliveryReqVO {
     @NotNull(message = "退货物流单号不能为空")
     private String logisticsNo;
 
-    @Schema(description = "退货时间", requiredMode = Schema.RequiredMode.REQUIRED)
-    @NotEmpty(message = "退货时间不能为空")
-    private LocalDateTime deliveryTime;
-
 }

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

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

+ 39 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/delivery/AppDeliverExpressController.java

@@ -0,0 +1,39 @@
+package cn.iocoder.yudao.module.trade.controller.app.delivery;
+
+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.express.AppDeliveryExpressRespVO;
+import cn.iocoder.yudao.module.trade.convert.delivery.DeliveryExpressConvert;
+import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO;
+import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.Comparator;
+import java.util.List;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+@Tag(name = "用户 App - 快递公司")
+@RestController
+@RequestMapping("/trade/delivery/express")
+@Validated
+public class AppDeliverExpressController {
+
+    @Resource
+    private DeliveryExpressService deliveryExpressService;
+
+    @GetMapping("/list")
+    @Operation(summary = "获得快递公司列表")
+    public CommonResult<List<AppDeliveryExpressRespVO>> getDeliveryExpressList() {
+        List<DeliveryExpressDO> list = deliveryExpressService.getDeliveryExpressList(CommonStatusEnum.ENABLE.getStatus());
+        list.sort(Comparator.comparing(DeliveryExpressDO::getSort));
+        return success(DeliveryExpressConvert.INSTANCE.convertList03(list));
+    }
+
+}

+ 16 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/delivery/vo/express/AppDeliveryExpressRespVO.java

@@ -0,0 +1,16 @@
+package cn.iocoder.yudao.module.trade.controller.app.delivery.vo.express;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Schema(description = "用户 App - 快递公司 Response VO")
+@Data
+public class AppDeliveryExpressRespVO {
+
+    @Schema(description = "编号", required = true, example = "1")
+    private Long id;
+
+    @Schema(description = "门店名称", required = true, example = "顺丰")
+    private String name;
+
+}

+ 13 - 37
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/aftersale/TradeAfterSaleConvert.java

@@ -1,6 +1,5 @@
 package cn.iocoder.yudao.module.trade.convert.aftersale;
 
-import cn.hutool.core.collection.CollUtil;
 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;
@@ -9,6 +8,7 @@ import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSal
 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.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.order.TradeOrderItemDO;
 import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
@@ -17,10 +17,7 @@ import org.mapstruct.Mapping;
 import org.mapstruct.Mappings;
 import org.mapstruct.factory.Mappers;
 
-import java.util.*;
-import java.util.stream.Collectors;
-
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
+import java.util.Map;
 
 @Mapper
 public interface TradeAfterSaleConvert {
@@ -37,6 +34,8 @@ public interface TradeAfterSaleConvert {
     TradeAfterSaleDO convert(AppTradeAfterSaleCreateReqVO createReqVO, TradeOrderItemDO tradeOrderItem);
 
     @Mappings({
+            @Mapping(source = "afterSale.orderId", target = "merchantOrderId"),
+            @Mapping(source = "afterSale.id", target = "merchantRefundId"),
             @Mapping(source = "afterSale.applyReason", target = "reason"),
             @Mapping(source = "afterSale.refundPrice", target = "price")
     })
@@ -48,41 +47,18 @@ public interface TradeAfterSaleConvert {
     PageResult<TradeAfterSaleRespPageItemVO> convertPage(PageResult<TradeAfterSaleDO> page);
 
     default PageResult<TradeAfterSaleRespPageItemVO> convertPage(PageResult<TradeAfterSaleDO> pageResult,
-                                                                 Map<Long, MemberUserRespDTO> memberUsers, List<ProductPropertyValueDetailRespDTO> propertyValueDetails) {
-        PageResult<TradeAfterSaleRespPageItemVO> pageVOResult = convertPage(pageResult);
-        // 处理会员 + 商品属性等关联信息
-        Map<Long, ProductPropertyValueDetailRespDTO> propertyValueDetailMap = convertMap(propertyValueDetails, ProductPropertyValueDetailRespDTO::getValueId);
-        for (int i = 0; i < pageResult.getList().size(); i++) {
-            TradeAfterSaleRespPageItemVO afterSaleVO = pageVOResult.getList().get(i);
-            TradeAfterSaleDO afterSaleDO = pageResult.getList().get(i);
-            // 会员
-            afterSaleVO.setUser(convert(memberUsers.get(afterSaleDO.getUserId())));
-            // 商品属性
-            if (CollUtil.isNotEmpty(afterSaleDO.getProperties())) {
-                afterSaleVO.setProperties(new ArrayList<>(afterSaleDO.getProperties().size()));
-                // 遍历每个 properties,设置到 TradeOrderPageItemRespVO.Item 中
-                afterSaleDO.getProperties().forEach(property -> {
-                    ProductPropertyValueDetailRespDTO propertyValueDetail = propertyValueDetailMap.get(property.getValueId());
-                    if (propertyValueDetail == null) {
-                        return;
-                    }
-                    afterSaleVO.getProperties().add(convert(propertyValueDetail));
-                });
-            }
-        }
-        return pageVOResult;
+                                                                 Map<Long, MemberUserRespDTO> memberUsers) {
+        PageResult<TradeAfterSaleRespPageItemVO> voPageResult = convertPage(pageResult);
+        // 处理会员
+        voPageResult.getList().forEach(afterSale -> afterSale.setUser(
+                convert(memberUsers.get(afterSale.getUserId()))));
+        return voPageResult;
     }
 
     ProductPropertyValueDetailRespVO convert(ProductPropertyValueDetailRespDTO bean);
 
-    default Set<Long> convertPropertyValueIds(List<TradeAfterSaleDO> list) {
-        if (CollUtil.isEmpty(list)) {
-            return new HashSet<>();
-        }
-        return list.stream().filter(item -> item.getProperties() != null)
-                .flatMap(p -> p.getProperties().stream()) // 遍历多个 Property 属性
-                .map(TradeOrderItemDO.Property::getValueId) // 将每个 Property 转换成对应的 propertyId,最后形成集合
-                .collect(Collectors.toSet());
-    }
+    AppTradeAfterSaleRespVO convert(TradeAfterSaleDO bean);
+
+    PageResult<AppTradeAfterSaleRespVO> convertPage02(PageResult<TradeAfterSaleDO> page);
 
 }

+ 5 - 3
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryExpressConvert.java

@@ -1,17 +1,17 @@
 package cn.iocoder.yudao.module.trade.convert.delivery;
 
-import java.util.*;
-
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-
 import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.express.DeliveryExpressCreateReqVO;
 import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.express.DeliveryExpressExcelVO;
 import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.express.DeliveryExpressRespVO;
 import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.express.DeliveryExpressUpdateReqVO;
+import cn.iocoder.yudao.module.trade.controller.app.delivery.vo.express.AppDeliveryExpressRespVO;
 import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO;
 import org.mapstruct.Mapper;
 import org.mapstruct.factory.Mappers;
 
+import java.util.List;
+
 @Mapper
 public interface DeliveryExpressConvert {
 
@@ -29,4 +29,6 @@ public interface DeliveryExpressConvert {
 
     List<DeliveryExpressExcelVO> convertList02(List<DeliveryExpressDO> list);
 
+    List<AppDeliveryExpressRespVO> convertList03(List<DeliveryExpressDO> list);
+
 }

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

@@ -17,7 +17,7 @@ import java.time.LocalDateTime;
 import java.util.List;
 
 /**
- * 交易售后,用于处理 {@link TradeOrderDO} 交易订单的退款退货流程
+ * 售后订单,用于处理 {@link TradeOrderDO} 交易订单的退款退货流程
  *
  * @author 芋道源码
  */
@@ -32,7 +32,7 @@ public class TradeAfterSaleDO extends BaseDO {
      */
     private Long id;
     /**
-     * 售后流水
+     * 售后
      *
      * 例如说,1146347329394184195
      */

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

@@ -1,5 +1,6 @@
 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;
@@ -23,13 +24,20 @@ public interface TradeAfterSaleMapper extends BaseMapperX<TradeAfterSaleDO> {
                 .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 selectByPayRefundId(Long payRefundId) {
-        return selectOne(TradeAfterSaleDO::getPayRefundId, payRefundId);
+    default TradeAfterSaleDO selectByIdAndUserId(Long id, Long userId) {
+        return selectOne(TradeAfterSaleDO::getId, id,
+                TradeAfterSaleDO::getUserId, userId);
     }
 
 }

+ 5 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/delivery/DeliveryExpressMapper.java

@@ -36,6 +36,11 @@ public interface DeliveryExpressMapper extends BaseMapperX<DeliveryExpressDO> {
         return selectOne(new LambdaQueryWrapper<DeliveryExpressDO>()
                 .eq(DeliveryExpressDO::getCode, code));
     }
+
+    default List<DeliveryExpressDO> selectListByStatus(Integer status) {
+        return selectList(DeliveryExpressDO::getStatus, status);
+    }
+
 }
 
 

+ 29 - 12
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleService.java

@@ -1,5 +1,6 @@
 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;
@@ -9,41 +10,57 @@ import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSa
 import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO;
 
 /**
- * 交易售后 Service 接口
+ * 售后订单 Service 接口
  *
  * @author 芋道源码
  */
 public interface TradeAfterSaleService {
 
     /**
-     * 获得交易售后分页
+     * 【管理员】获得售后订单分页
      *
      * @param pageReqVO 分页查询
-     * @return 交易售后分页
+     * @return 售后订单分页
      */
     PageResult<TradeAfterSaleDO> getAfterSalePage(TradeAfterSalePageReqVO pageReqVO);
 
     /**
-     * 【会员】创建交易售后
-     * <p>
-     * 一般是用户发起售后请求
+     * 【会员】获得售后订单分页
+     *
+     * @param userId 用户编号
+     * @param pageParam 分页参数
+     * @return 售后订单分页
+     */
+    PageResult<TradeAfterSaleDO> getAfterSalePage(Long userId, PageParam pageParam);
+
+    /**
+     * 【会员】获得售后单
+     *
+     * @param userId 用户编号
+     * @param id 售后编号
+     * @return 售后订单
+     */
+    TradeAfterSaleDO getAfterSale(Long userId, Long id);
+
+    /**
+     * 【会员】创建售后订单
      *
      * @param userId 会员用户编号
      * @param createReqVO 创建 Request 信息
-     * @return 交易售后编号
+     * @return 售后编号
      */
     Long createAfterSale(Long userId, AppTradeAfterSaleCreateReqVO createReqVO);
 
     /**
-     * 【管理员】同意交易售后
+     * 【管理员】同意售后订单
      *
      * @param userId 管理员用户编号
-     * @param id 交易售后编号
+     * @param id 售后编号
      */
     void agreeAfterSale(Long userId, Long id);
 
     /**
-     * 【管理员】拒绝交易售后
+     * 【管理员】拒绝售后订单
      *
      * @param userId 管理员用户编号
      * @param auditReqVO 审批 Request 信息
@@ -62,7 +79,7 @@ public interface TradeAfterSaleService {
      * 【管理员】确认收货
      *
      * @param userId 管理员编号
-     * @param id 交易售后编号
+     * @param id 售后编号
      */
     void receiveAfterSale(Long userId, Long id);
 
@@ -87,7 +104,7 @@ public interface TradeAfterSaleService {
      * 【会员】取消售后
      *
      * @param userId 会员用户编号
-     * @param id 交易售后编号
+     * @param id 售后编号
      */
     void cancelAfterSale(Long userId, Long id);
 

+ 21 - 9
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java

@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.trade.service.aftersale;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.RandomUtil;
 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
+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;
@@ -45,7 +46,7 @@ import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString
 import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
 
 /**
- * 交易售后 Service 实现类
+ * 售后订单 Service 实现类
  *
  * @author 芋道源码
  */
@@ -75,13 +76,23 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
         return tradeAfterSaleMapper.selectPage(pageReqVO);
     }
 
+    @Override
+    public PageResult<TradeAfterSaleDO> getAfterSalePage(Long userId, PageParam pageParam) {
+        return tradeAfterSaleMapper.selectPage(userId, pageParam);
+    }
+
+    @Override
+    public TradeAfterSaleDO getAfterSale(Long userId, Long id) {
+         return tradeAfterSaleMapper.selectByIdAndUserId(id, userId);
+    }
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Long createAfterSale(Long userId, AppTradeAfterSaleCreateReqVO createReqVO) {
         // 第一步,前置校验
         TradeOrderItemDO tradeOrderItem = validateOrderItemApplicable(userId, createReqVO);
 
-        // 第二步,存储交易售后
+        // 第二步,存储售后订单
         TradeAfterSaleDO afterSale = createAfterSale(createReqVO, tradeOrderItem);
         return afterSale.getId();
     }
@@ -168,7 +179,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
         // 更新售后单的状态
         // 情况一:退款:标记为 WAIT_REFUND 状态。后续等退款发起成功后,在标记为 COMPLETE 状态
         // 情况二:退货退款:需要等用户退货后,才能发起退款
-        Integer newStatus = afterSale.getType().equals(TradeAfterSaleWayEnum.REFUND.getWay()) ?
+        Integer newStatus = afterSale.getWay().equals(TradeAfterSaleWayEnum.REFUND.getWay()) ?
                 TradeAfterSaleStatusEnum.WAIT_REFUND.getStatus() : TradeAfterSaleStatusEnum.SELLER_AGREE.getStatus();
         updateAfterSaleStatus(afterSale.getId(), TradeAfterSaleStatusEnum.APPLY.getStatus(), new TradeAfterSaleDO()
                 .setStatus(newStatus).setAuditUserId(userId).setAuditTime(LocalDateTime.now()));
@@ -243,7 +254,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
         updateAfterSaleStatus(afterSale.getId(), TradeAfterSaleStatusEnum.SELLER_AGREE.getStatus(), new TradeAfterSaleDO()
                 .setStatus(TradeAfterSaleStatusEnum.BUYER_DELIVERY.getStatus())
                 .setLogisticsId(deliveryReqVO.getLogisticsId()).setLogisticsNo(deliveryReqVO.getLogisticsNo())
-                .setDeliveryTime(deliveryReqVO.getDeliveryTime()));
+                .setDeliveryTime(LocalDateTime.now()));
 
         // 记录售后日志
         createAfterSaleLog(userId, UserTypeEnum.MEMBER.getValue(),
@@ -318,7 +329,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
     @Transactional(rollbackFor = Exception.class)
     public void refundAfterSale(Long userId, String userIp, Long id) {
         // 校验售后单的状态,并状态待退款
-        TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectByPayRefundId(id);
+        TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectById(id);
         if (afterSale == null) {
             throw exception(AFTER_SALE_NOT_FOUND);
         }
@@ -362,13 +373,14 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
     @Override
     public void cancelAfterSale(Long userId, Long id) {
         // 校验售后单的状态,并状态待退款
-        TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectByPayRefundId(id);
+        TradeAfterSaleDO 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())) {
-            throw exception(AFTER_SALE_CANCEL_FAIL_STATUS_NOT_APPLY_OR_AGREE);
+        if (!ObjectUtils.equalsAny(afterSale.getStatus(), TradeAfterSaleStatusEnum.APPLY.getStatus(),
+                TradeAfterSaleStatusEnum.SELLER_AGREE.getStatus(),
+                TradeAfterSaleStatusEnum.BUYER_DELIVERY.getStatus())) {
+            throw exception(AFTER_SALE_CANCEL_FAIL_STATUS_NOT_APPLY_OR_AGREE_OR_BUYER_DELIVERY);
         }
 
         // 更新售后单的状态为【已取消】

+ 11 - 11
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressService.java

@@ -1,8 +1,5 @@
 package cn.iocoder.yudao.module.trade.service.delivery;
 
-import java.util.*;
-import javax.validation.*;
-
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.express.DeliveryExpressCreateReqVO;
 import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.express.DeliveryExpressExportReqVO;
@@ -10,6 +7,9 @@ import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.express.Delive
 import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.express.DeliveryExpressUpdateReqVO;
 import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO;
 
+import javax.validation.Valid;
+import java.util.List;
+
 /**
  * 快递公司 Service 接口
  *
@@ -47,14 +47,6 @@ public interface DeliveryExpressService {
      */
     DeliveryExpressDO getDeliveryExpress(Long id);
 
-    /**
-     * 获得快递公司列表
-     *
-     * @param ids 编号
-     * @return 快递公司列表
-     */
-    List<DeliveryExpressDO> getDeliveryExpressList(Collection<Long> ids);
-
     /**
      * 获得快递公司分页
      *
@@ -71,4 +63,12 @@ public interface DeliveryExpressService {
      */
     List<DeliveryExpressDO> getDeliveryExpressList(DeliveryExpressExportReqVO exportReqVO);
 
+    /**
+     * 获得快递公司列表
+     *
+     * @param status 状态
+     * @return 快递公司列表
+     */
+    List<DeliveryExpressDO> getDeliveryExpressList(Integer status);
+
 }

+ 9 - 9
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressServiceImpl.java

@@ -9,14 +9,14 @@ import cn.iocoder.yudao.module.trade.convert.delivery.DeliveryExpressConvert;
 import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO;
 import cn.iocoder.yudao.module.trade.dal.mysql.delivery.DeliveryExpressMapper;
 import org.springframework.stereotype.Service;
-import javax.annotation.Resource;
 import org.springframework.validation.annotation.Validated;
 
-import java.util.*;
-
+import javax.annotation.Resource;
+import java.util.List;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
-import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
+import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.EXPRESS_CODE_DUPLICATE;
+import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.EXPRESS_NOT_EXISTS;
 
 /**
  * 快递公司 Service 实现类
@@ -84,11 +84,6 @@ public class DeliveryExpressServiceImpl implements DeliveryExpressService {
         return deliveryExpressMapper.selectById(id);
     }
 
-    @Override
-    public List<DeliveryExpressDO> getDeliveryExpressList(Collection<Long> ids) {
-        return deliveryExpressMapper.selectBatchIds(ids);
-    }
-
     @Override
     public PageResult<DeliveryExpressDO> getDeliveryExpressPage(DeliveryExpressPageReqVO pageReqVO) {
         return deliveryExpressMapper.selectPage(pageReqVO);
@@ -99,4 +94,9 @@ public class DeliveryExpressServiceImpl implements DeliveryExpressService {
         return deliveryExpressMapper.selectList(exportReqVO);
     }
 
+    @Override
+    public List<DeliveryExpressDO> getDeliveryExpressList(Integer status) {
+        return deliveryExpressMapper.selectListByStatus(status);
+    }
+
 }