Commit 40f0117130ee238615e8f3d0acaa01c460ef2869

Authored by YunaiV
1 parent 92dbf093

trade:售后增加发货

yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java
@@ -31,7 +31,8 @@ public interface ErrorCodeConstants { @@ -31,7 +31,8 @@ public interface ErrorCodeConstants {
31 ErrorCode AFTER_SALE_CREATE_FAIL_ORDER_STATUS_NO_DELIVERED = new ErrorCode(1011000104, "订单未发货,无法申请【退货退款】售后"); 31 ErrorCode AFTER_SALE_CREATE_FAIL_ORDER_STATUS_NO_DELIVERED = new ErrorCode(1011000104, "订单未发货,无法申请【退货退款】售后");
32 ErrorCode AFTER_SALE_CREATE_FAIL_ORDER_ITEM_APPLIED = new ErrorCode(1011000105, "订单项已申请售后,无法重复申请"); 32 ErrorCode AFTER_SALE_CREATE_FAIL_ORDER_ITEM_APPLIED = new ErrorCode(1011000105, "订单项已申请售后,无法重复申请");
33 ErrorCode AFTER_SALE_AUDIT_FAIL_STATUS_NOT_APPLY = new ErrorCode(1011000106, "审批失败,售后状态不处于审批中"); 33 ErrorCode AFTER_SALE_AUDIT_FAIL_STATUS_NOT_APPLY = new ErrorCode(1011000106, "审批失败,售后状态不处于审批中");
34 - ErrorCode AFTER_SALE_UPDATE_STATUS_FAIL = new ErrorCode(1011000106, "操作售后单失败,请刷新后重试"); 34 + ErrorCode AFTER_SALE_UPDATE_STATUS_FAIL = new ErrorCode(1011000107, "操作售后单失败,请刷新后重试");
  35 + ErrorCode AFTER_SALE_DELIVERY_FAIL_STATUS_NOT_BUYER_RETURN = new ErrorCode(1011000108, "退货失败,售后单状态不处于【买家退货】");
35 36
36 // ========== Cart 模块 1-011-001-000 ========== 37 // ========== Cart 模块 1-011-001-000 ==========
37 ErrorCode CARD_ITEM_NOT_FOUND = new ErrorCode(1011002000, "购物车项不存在"); 38 ErrorCode CARD_ITEM_NOT_FOUND = new ErrorCode(1011002000, "购物车项不存在");
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/AppTradeAfterSaleController.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.trade.controller.app.aftersale; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.trade.controller.app.aftersale;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleCreateReqVO; 4 import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleCreateReqVO;
  5 +import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleDeliveryReqVO;
5 import cn.iocoder.yudao.module.trade.service.aftersale.TradeAfterSaleService; 6 import cn.iocoder.yudao.module.trade.service.aftersale.TradeAfterSaleService;
6 import io.swagger.annotations.Api; 7 import io.swagger.annotations.Api;
7 import io.swagger.annotations.ApiOperation; 8 import io.swagger.annotations.ApiOperation;
@@ -29,8 +30,15 @@ public class AppTradeAfterSaleController { @@ -29,8 +30,15 @@ public class AppTradeAfterSaleController {
29 30
30 @PostMapping(value = "/create") 31 @PostMapping(value = "/create")
31 @ApiOperation(value = "申请售后") 32 @ApiOperation(value = "申请售后")
32 - private CommonResult<Long> createAfterSale(@RequestBody AppTradeAfterSaleCreateReqVO createReqVO) { 33 + public CommonResult<Long> createAfterSale(@RequestBody AppTradeAfterSaleCreateReqVO createReqVO) {
33 return success(afterSaleService.createAfterSale(getLoginUserId(), createReqVO)); 34 return success(afterSaleService.createAfterSale(getLoginUserId(), createReqVO));
34 } 35 }
35 36
  37 + @PostMapping(value = "/delivery")
  38 + @ApiOperation(value = "退回货物")
  39 + public CommonResult<Boolean> deliveryAfterSale(@RequestBody AppTradeAfterSaleDeliveryReqVO deliveryReqVO) {
  40 + afterSaleService.deliveryAfterSale(getLoginUserId(), deliveryReqVO);
  41 + return success(true);
  42 + }
  43 +
36 } 44 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSaleDeliveryReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.app.aftersale.vo;
  2 +
  3 +import io.swagger.annotations.ApiModel;
  4 +import io.swagger.annotations.ApiModelProperty;
  5 +import lombok.Data;
  6 +
  7 +import javax.validation.constraints.NotNull;
  8 +import java.time.LocalDateTime;
  9 +
  10 +@ApiModel("用户 App - 交易售后退回货物 Request VO")
  11 +@Data
  12 +public class AppTradeAfterSaleDeliveryReqVO {
  13 +
  14 + @ApiModelProperty(name = "售后编号", required = true, example = "1024")
  15 + @NotNull(message = "售后编号不能为空")
  16 + private Long id;
  17 +
  18 + @ApiModelProperty(name = "退货物流公司编号", required = true, example = "1")
  19 + @NotNull(message = "退货物流公司编号不能为空")
  20 + private Long logisticsId;
  21 +
  22 + @ApiModelProperty(name = "退货物流单号", required = true, example = "SF123456789")
  23 + @NotNull(message = "退货物流单号不能为空")
  24 + private String logisticsNo;
  25 +
  26 + @ApiModelProperty(name = "退货时间", required = true)
  27 + @NotNull(message = "退货时间不能为空")
  28 + private LocalDateTime deliveryTime;
  29 +
  30 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/TradeAfterSaleDO.java
@@ -134,26 +134,26 @@ public class TradeAfterSaleDO extends BaseDO { @@ -134,26 +134,26 @@ public class TradeAfterSaleDO extends BaseDO {
134 134
135 // ========== 退货相关 ========== 135 // ========== 退货相关 ==========
136 /** 136 /**
137 - * 退货物流公司编号 TODO 137 + * 退货物流公司编号
138 * 138 *
139 - * 关联 ExpressDO 的 id 编号 139 + * 关联 LogisticsDO 的 id 编号
140 */ 140 */
141 - private Long returnExpressId; // express_name 141 + private Long logisticsId;
142 /** 142 /**
143 - * 退货物流单号 TODO 143 + * 退货物流单号
144 */ 144 */
145 - private String returnExpressNo; // express_no 145 + private String logisticsNo;
146 /** 146 /**
147 - * 退货时间 TODO 147 + * 退货时间
148 */ 148 */
149 - private LocalDateTime deliveryTime; // ship_time 149 + private LocalDateTime deliveryTime;
150 /** 150 /**
151 - * 收获备注 TODO 151 + * 收货时间
152 */ 152 */
153 - private String receiveMemo; // receive_message 153 + private LocalDateTime receiptTime;
154 /** 154 /**
155 - * 收货时间 TODO 155 + * 收货备注
156 */ 156 */
157 - private LocalDateTime receiveDate; // receive_time 157 + private String receiptMemo;
158 158
159 } 159 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleService.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.trade.service.aftersale; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.trade.service.aftersale;
2 2
3 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleAuditReqVO; 3 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleAuditReqVO;
4 import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleCreateReqVO; 4 import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleCreateReqVO;
  5 +import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleDeliveryReqVO;
5 6
6 /** 7 /**
7 * 交易售后 Service 接口 8 * 交易售后 Service 接口
@@ -29,4 +30,13 @@ public interface TradeAfterSaleService { @@ -29,4 +30,13 @@ public interface TradeAfterSaleService {
29 * @param auditReqVO 审批 Request 信息 30 * @param auditReqVO 审批 Request 信息
30 */ 31 */
31 void auditAfterSale(Long userId, String userIp, TradeAfterSaleAuditReqVO auditReqVO); 32 void auditAfterSale(Long userId, String userIp, TradeAfterSaleAuditReqVO auditReqVO);
  33 +
  34 + /**
  35 + * 退回货物
  36 + *
  37 + * @param userId 会员用户编号
  38 + * @param deliveryReqVO 退货 Request 信息
  39 + */
  40 + void deliveryAfterSale(Long userId, AppTradeAfterSaleDeliveryReqVO deliveryReqVO);
  41 +
32 } 42 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java
@@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi; @@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi;
5 import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO; 5 import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO;
6 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleAuditReqVO; 6 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleAuditReqVO;
7 import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleCreateReqVO; 7 import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleCreateReqVO;
  8 +import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleDeliveryReqVO;
8 import cn.iocoder.yudao.module.trade.convert.aftersale.TradeAfterSaleConvert; 9 import cn.iocoder.yudao.module.trade.convert.aftersale.TradeAfterSaleConvert;
9 import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO; 10 import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO;
10 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; 11 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
@@ -147,7 +148,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService { @@ -147,7 +148,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService {
147 // 情况二:退货退款:需要等用户退货后,才能发起退款 148 // 情况二:退货退款:需要等用户退货后,才能发起退款
148 Integer newStatus = afterSale.getType().equals(TradeAfterSaleTypeEnum.REFUND.getType()) ? 149 Integer newStatus = afterSale.getType().equals(TradeAfterSaleTypeEnum.REFUND.getType()) ?
149 TradeAfterSaleStatusEnum.WAIT_REFUND.getStatus() : TradeAfterSaleStatusEnum.SELLER_PASS.getStatus(); 150 TradeAfterSaleStatusEnum.WAIT_REFUND.getStatus() : TradeAfterSaleStatusEnum.SELLER_PASS.getStatus();
150 - updateAfterSaleStatus(afterSale.getId(), TradeAfterSaleStatusEnum.APPLY.getStatus(), new TradeAfterSaleDO() 151 + updateAfterSaleStatus(afterSale.getId(), TradeAfterSaleStatusEnum.APPLY.getStatus(), new TradeAfterSaleDO()
151 .setStatus(newStatus).setAuditUserId(userId) 152 .setStatus(newStatus).setAuditUserId(userId)
152 .setAuditReason(auditReqVO.getAuditReason()).setAuditTime(LocalDateTime.now())); 153 .setAuditReason(auditReqVO.getAuditReason()).setAuditTime(LocalDateTime.now()));
153 154
@@ -165,7 +166,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService { @@ -165,7 +166,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService {
165 TradeAfterSaleAuditReqVO auditReqVO, TradeAfterSaleDO afterSale) { 166 TradeAfterSaleAuditReqVO auditReqVO, TradeAfterSaleDO afterSale) {
166 // 更新售后单的状态 167 // 更新售后单的状态
167 Integer newStatus = TradeAfterSaleStatusEnum.SELLER_REFUSE.getStatus(); 168 Integer newStatus = TradeAfterSaleStatusEnum.SELLER_REFUSE.getStatus();
168 - updateAfterSaleStatus(afterSale.getId(), TradeAfterSaleStatusEnum.APPLY.getStatus(), new TradeAfterSaleDO() 169 + updateAfterSaleStatus(afterSale.getId(), TradeAfterSaleStatusEnum.APPLY.getStatus(), new TradeAfterSaleDO()
169 .setStatus(newStatus).setAuditUserId(userId) 170 .setStatus(newStatus).setAuditUserId(userId)
170 .setAuditReason(auditReqVO.getAuditReason()).setAuditTime(LocalDateTime.now())); 171 .setAuditReason(auditReqVO.getAuditReason()).setAuditTime(LocalDateTime.now()));
171 172
@@ -199,4 +200,26 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService { @@ -199,4 +200,26 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService {
199 } 200 }
200 } 201 }
201 202
  203 + @Override
  204 + public void deliveryAfterSale(Long userId, AppTradeAfterSaleDeliveryReqVO deliveryReqVO) {
  205 + // 校验售后单存在,并状态未退货
  206 + TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectById(deliveryReqVO.getId());
  207 + if (afterSale == null) {
  208 + throw exception(AFTER_SALE_NOT_FOUND);
  209 + }
  210 + if (afterSale.getStatus().equals(TradeAfterSaleStatusEnum.SELLER_PASS.getStatus())) {
  211 + throw exception(AFTER_SALE_DELIVERY_FAIL_STATUS_NOT_BUYER_RETURN);
  212 + }
  213 +
  214 + // 更新售后单的物流信息
  215 + updateAfterSaleStatus(afterSale.getId(), TradeAfterSaleStatusEnum.SELLER_PASS.getStatus(), new TradeAfterSaleDO()
  216 + .setStatus(TradeAfterSaleStatusEnum.BUYER_RETURN.getStatus())
  217 + .setLogisticsId(deliveryReqVO.getLogisticsId()).setLogisticsNo(deliveryReqVO.getLogisticsNo())
  218 + .setDeliveryTime(deliveryReqVO.getDeliveryTime()));
  219 +
  220 + // TODO 记录售后日志
  221 +
  222 + // TODO 发送售后消息
  223 + }
  224 +
202 } 225 }