Commit 64df5ce5f40b2b721ac2dbc5abc4979c1a6b0515

Authored by YunaiV
1 parent ed9c8d4a

trade:【交易售后】增加会员取消售后

yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java
@@ -35,6 +35,7 @@ public interface ErrorCodeConstants { @@ -35,6 +35,7 @@ public interface ErrorCodeConstants {
35 ErrorCode AFTER_SALE_DELIVERY_FAIL_STATUS_NOT_SELLER_AGREE = new ErrorCode(1011000108, "退货失败,售后单状态不处于【待买家退货】"); 35 ErrorCode AFTER_SALE_DELIVERY_FAIL_STATUS_NOT_SELLER_AGREE = new ErrorCode(1011000108, "退货失败,售后单状态不处于【待买家退货】");
36 ErrorCode AFTER_SALE_CONFIRM_FAIL_STATUS_NOT_BUYER_DELIVERY = new ErrorCode(1011000109, "确认收货失败,售后单状态不处于【待确认收货】"); 36 ErrorCode AFTER_SALE_CONFIRM_FAIL_STATUS_NOT_BUYER_DELIVERY = new ErrorCode(1011000109, "确认收货失败,售后单状态不处于【待确认收货】");
37 ErrorCode AFTER_SALE_REFUND_FAIL_STATUS_NOT_WAIT_REFUND = new ErrorCode(1011000110, "退款失败,售后单状态不是【待退款】"); 37 ErrorCode AFTER_SALE_REFUND_FAIL_STATUS_NOT_WAIT_REFUND = new ErrorCode(1011000110, "退款失败,售后单状态不是【待退款】");
  38 + ErrorCode AFTER_SALE_CANCEL_FAIL_STATUS_NOT_APPLY_OR_AGREE = new ErrorCode(1011000111, "取消售后单失败,售后单状态不是【待审核】或【卖家同意】");
38 39
39 // ========== Cart 模块 1-011-001-000 ========== 40 // ========== Cart 模块 1-011-001-000 ==========
40 ErrorCode CARD_ITEM_NOT_FOUND = new ErrorCode(1011002000, "购物车项不存在"); 41 ErrorCode CARD_ITEM_NOT_FOUND = new ErrorCode(1011002000, "购物车项不存在");
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.java
@@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.member.api.user.MemberUserApi; @@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
7 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; 7 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
8 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleDisagreeReqVO; 8 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleDisagreeReqVO;
9 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSalePageReqVO; 9 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSalePageReqVO;
  10 +import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRefuseReqVO;
10 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRespPageItemVO; 11 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRespPageItemVO;
11 import cn.iocoder.yudao.module.trade.convert.aftersale.TradeAfterSaleConvert; 12 import cn.iocoder.yudao.module.trade.convert.aftersale.TradeAfterSaleConvert;
12 import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO; 13 import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO;
@@ -82,6 +83,15 @@ public class TradeAfterSaleController { @@ -82,6 +83,15 @@ public class TradeAfterSaleController {
82 return success(true); 83 return success(true);
83 } 84 }
84 85
  86 + @PutMapping("/receive")
  87 + @ApiOperation("确认收货")
  88 + @ApiImplicitParam(name = "id", value = "售后编号", required = true, example = "1")
  89 + @PreAuthorize("@ss.hasPermission('trade:after-sale:receive')")
  90 + public CommonResult<Boolean> refuseAfterSale(TradeAfterSaleRefuseReqVO refuseReqVO) {
  91 + afterSaleService.refuseAfterSale(getLoginUserId(), refuseReqVO);
  92 + return success(true);
  93 + }
  94 +
85 @PostMapping("/refund") 95 @PostMapping("/refund")
86 @ApiOperation(value = "确认退款") 96 @ApiOperation(value = "确认退款")
87 @ApiImplicitParam(name = "id", value = "售后编号", required = true, example = "1") 97 @ApiImplicitParam(name = "id", value = "售后编号", required = true, example = "1")
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/AppTradeAfterSaleController.java
@@ -5,13 +5,11 @@ import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSa @@ -5,13 +5,11 @@ import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSa
5 import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleDeliveryReqVO; 5 import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleDeliveryReqVO;
6 import cn.iocoder.yudao.module.trade.service.aftersale.TradeAfterSaleService; 6 import cn.iocoder.yudao.module.trade.service.aftersale.TradeAfterSaleService;
7 import io.swagger.annotations.Api; 7 import io.swagger.annotations.Api;
  8 +import io.swagger.annotations.ApiImplicitParam;
8 import io.swagger.annotations.ApiOperation; 9 import io.swagger.annotations.ApiOperation;
9 import lombok.extern.slf4j.Slf4j; 10 import lombok.extern.slf4j.Slf4j;
10 import org.springframework.validation.annotation.Validated; 11 import org.springframework.validation.annotation.Validated;
11 -import org.springframework.web.bind.annotation.PostMapping;  
12 -import org.springframework.web.bind.annotation.RequestBody;  
13 -import org.springframework.web.bind.annotation.RequestMapping;  
14 -import org.springframework.web.bind.annotation.RestController; 12 +import org.springframework.web.bind.annotation.*;
15 13
16 import javax.annotation.Resource; 14 import javax.annotation.Resource;
17 15
@@ -41,4 +39,12 @@ public class AppTradeAfterSaleController { @@ -41,4 +39,12 @@ public class AppTradeAfterSaleController {
41 return success(true); 39 return success(true);
42 } 40 }
43 41
  42 + @DeleteMapping(value = "/cancel")
  43 + @ApiOperation(value = "取消售后")
  44 + @ApiImplicitParam(name = "id", value = "售后编号", required = true, example = "1")
  45 + public CommonResult<Boolean> cancelAfterSale(@RequestParam("id") Long id) {
  46 + afterSaleService.cancelAfterSale(getLoginUserId(), id);
  47 + return success(true);
  48 + }
  49 +
44 } 50 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleService.java
@@ -70,9 +70,9 @@ public interface TradeAfterSaleService { @@ -70,9 +70,9 @@ public interface TradeAfterSaleService {
70 * 【管理员】拒绝收货 70 * 【管理员】拒绝收货
71 * 71 *
72 * @param userId 管理员用户编号 72 * @param userId 管理员用户编号
73 - * @param confirmReqVO 收货 Request 信息 73 + * @param refuseReqVO 拒绝收货 Request 信息
74 */ 74 */
75 - void refuseAfterSale(Long userId, TradeAfterSaleRefuseReqVO confirmReqVO); 75 + void refuseAfterSale(Long userId, TradeAfterSaleRefuseReqVO refuseReqVO);
76 76
77 /** 77 /**
78 * 【管理员】确认退款 78 * 【管理员】确认退款
@@ -83,4 +83,12 @@ public interface TradeAfterSaleService { @@ -83,4 +83,12 @@ public interface TradeAfterSaleService {
83 */ 83 */
84 void refundAfterSale(Long userId, String userIp, Long id); 84 void refundAfterSale(Long userId, String userIp, Long id);
85 85
  86 + /**
  87 + * 【会员】取消售后
  88 + *
  89 + * @param userId 会员用户编号
  90 + * @param id 交易售后编号
  91 + */
  92 + void cancelAfterSale(Long userId, Long id);
  93 +
86 } 94 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java
@@ -4,6 +4,7 @@ import cn.hutool.core.util.ObjectUtil; @@ -4,6 +4,7 @@ import cn.hutool.core.util.ObjectUtil;
4 import cn.hutool.core.util.RandomUtil; 4 import cn.hutool.core.util.RandomUtil;
5 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; 5 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
6 import cn.iocoder.yudao.framework.common.pojo.PageResult; 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
7 import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi; 8 import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi;
8 import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO; 9 import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO;
9 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleDisagreeReqVO; 10 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleDisagreeReqVO;
@@ -262,9 +263,9 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService { @@ -262,9 +263,9 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService {
262 263
263 @Override 264 @Override
264 @Transactional(rollbackFor = Exception.class) 265 @Transactional(rollbackFor = Exception.class)
265 - public void refuseAfterSale(Long userId, TradeAfterSaleRefuseReqVO confirmReqVO) { 266 + public void refuseAfterSale(Long userId, TradeAfterSaleRefuseReqVO refuseReqVO) {
266 // 校验售后单存在,并状态为已退货 267 // 校验售后单存在,并状态为已退货
267 - TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectById(confirmReqVO.getId()); 268 + TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectById(refuseReqVO.getId());
268 if (afterSale == null) { 269 if (afterSale == null) {
269 throw exception(AFTER_SALE_NOT_FOUND); 270 throw exception(AFTER_SALE_NOT_FOUND);
270 } 271 }
@@ -275,7 +276,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService { @@ -275,7 +276,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService {
275 // 更新售后单的状态 276 // 更新售后单的状态
276 updateAfterSaleStatus(afterSale.getId(), TradeAfterSaleStatusEnum.BUYER_DELIVERY.getStatus(), new TradeAfterSaleDO() 277 updateAfterSaleStatus(afterSale.getId(), TradeAfterSaleStatusEnum.BUYER_DELIVERY.getStatus(), new TradeAfterSaleDO()
277 .setStatus(TradeAfterSaleStatusEnum.SELLER_REFUSE.getStatus()).setReceiveTime(LocalDateTime.now()) 278 .setStatus(TradeAfterSaleStatusEnum.SELLER_REFUSE.getStatus()).setReceiveTime(LocalDateTime.now())
278 - .setReceiveReason(confirmReqVO.getRefuseMemo())); 279 + .setReceiveReason(refuseReqVO.getRefuseMemo()));
279 280
280 // 记录售后日志 281 // 记录售后日志
281 createAfterSaleLog(userId, UserTypeEnum.ADMIN.getValue(), 282 createAfterSaleLog(userId, UserTypeEnum.ADMIN.getValue(),
@@ -351,6 +352,34 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService { @@ -351,6 +352,34 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService {
351 }); 352 });
352 } 353 }
353 354
  355 + @Override
  356 + public void cancelAfterSale(Long userId, Long id) {
  357 + // 校验售后单的状态,并状态待退款
  358 + TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectByPayRefundId(id);
  359 + if (afterSale == null) {
  360 + throw exception(AFTER_SALE_NOT_FOUND);
  361 + }
  362 + if (ObjectUtils.equalsAny(afterSale.getStatus(), TradeAfterSaleStatusEnum.APPLY.getStatus(),
  363 + TradeAfterSaleStatusEnum.SELLER_AGREE.getStatus())) {
  364 + throw exception(AFTER_SALE_CANCEL_FAIL_STATUS_NOT_APPLY_OR_AGREE);
  365 + }
  366 +
  367 + // 更新售后单的状态为【已取消】
  368 + updateAfterSaleStatus(afterSale.getId(), afterSale.getStatus(), new TradeAfterSaleDO()
  369 + .setStatus(TradeAfterSaleStatusEnum.BUYER_CANCEL.getStatus()));
  370 +
  371 + // 记录售后日志
  372 + createAfterSaleLog(userId, UserTypeEnum.MEMBER.getValue(),
  373 + afterSale, afterSale.getStatus(), TradeAfterSaleStatusEnum.BUYER_CANCEL.getStatus());
  374 +
  375 + // TODO 发送售后消息
  376 +
  377 + // 更新交易订单项的售后状态为【未申请】
  378 + tradeOrderService.updateOrderItemAfterSaleStatus(afterSale.getOrderItemId(),
  379 + TradeOrderItemAfterSaleStatusEnum.APPLY.getStatus(),
  380 + TradeOrderItemAfterSaleStatusEnum.NONE.getStatus(), null);
  381 + }
  382 +
354 private void createAfterSaleLog(Long userId, Integer userType, TradeAfterSaleDO afterSale, 383 private void createAfterSaleLog(Long userId, Integer userType, TradeAfterSaleDO afterSale,
355 Integer beforeStatus, Integer afterStatus) { 384 Integer beforeStatus, Integer afterStatus) {
356 TradeAfterSaleLogDO afterSaleLog = new TradeAfterSaleLogDO().setUserId(userId).setUserType(userType) 385 TradeAfterSaleLogDO afterSaleLog = new TradeAfterSaleLogDO().setUserId(userId).setUserType(userType)