Commit 67050eeaa8047c57df1f5e81bac9e79185f9476a
1 parent
40f01171
trade:【交易售后】确认收货
Showing
6 changed files
with
105 additions
and
6 deletions
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java
| ... | ... | @@ -32,7 +32,8 @@ public interface ErrorCodeConstants { |
| 32 | 32 | ErrorCode AFTER_SALE_CREATE_FAIL_ORDER_ITEM_APPLIED = new ErrorCode(1011000105, "订单项已申请售后,无法重复申请"); |
| 33 | 33 | ErrorCode AFTER_SALE_AUDIT_FAIL_STATUS_NOT_APPLY = new ErrorCode(1011000106, "审批失败,售后状态不处于审批中"); |
| 34 | 34 | ErrorCode AFTER_SALE_UPDATE_STATUS_FAIL = new ErrorCode(1011000107, "操作售后单失败,请刷新后重试"); |
| 35 | - ErrorCode AFTER_SALE_DELIVERY_FAIL_STATUS_NOT_BUYER_RETURN = new ErrorCode(1011000108, "退货失败,售后单状态不处于【买家退货】"); | |
| 35 | + ErrorCode AFTER_SALE_DELIVERY_FAIL_STATUS_NOT_SELLER_PASS = new ErrorCode(1011000108, "退货失败,售后单状态不处于【待买家退货】"); | |
| 36 | + ErrorCode AFTER_SALE_CONFIRM_FAIL_STATUS_NOT_BUYER_RETURN = new ErrorCode(1011000109, "确认收货失败,售后单状态不处于【待确认收货】"); | |
| 36 | 37 | |
| 37 | 38 | // ========== Cart 模块 1-011-001-000 ========== |
| 38 | 39 | 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
| ... | ... | @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.trade.controller.admin.aftersale; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | 4 | import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleAuditReqVO; |
| 5 | +import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleConfirmReqVO; | |
| 5 | 6 | import cn.iocoder.yudao.module.trade.service.aftersale.TradeAfterSaleService; |
| 6 | 7 | import io.swagger.annotations.Api; |
| 7 | 8 | import io.swagger.annotations.ApiOperation; |
| ... | ... | @@ -37,4 +38,12 @@ public class TradeAfterSaleController { |
| 37 | 38 | return success(true); |
| 38 | 39 | } |
| 39 | 40 | |
| 41 | + @PutMapping("/confirm") | |
| 42 | + @ApiOperation("确认收货") | |
| 43 | + @PreAuthorize("@ss.hasPermission('trade:after-sale:audit')") | |
| 44 | + public CommonResult<Boolean> confirmAfterSale(@RequestBody TradeAfterSaleConfirmReqVO confirmReqVO) { | |
| 45 | + afterSaleService.confirmAfterSale(getLoginUserId(), getClientIP(), confirmReqVO); | |
| 46 | + return success(true); | |
| 47 | + } | |
| 48 | + | |
| 40 | 49 | } | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleAuditReqVO.java
| ... | ... | @@ -17,7 +17,7 @@ public class TradeAfterSaleAuditReqVO { |
| 17 | 17 | @ApiModelProperty(value = "审批结果", required = true, example = "true", |
| 18 | 18 | notes = "true - 通过;false - 不通过") |
| 19 | 19 | @NotNull(message = "审批结果不能为空") |
| 20 | - private Boolean audit; | |
| 20 | + private Boolean pass; | |
| 21 | 21 | |
| 22 | 22 | @ApiModelProperty(value = "审批备注", example = "你猜") |
| 23 | 23 | private String auditReason; | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleConfirmReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.trade.controller.admin.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 | + | |
| 9 | +@ApiModel("管理后台 - 交易售后确认收货 Request VO") | |
| 10 | +@Data | |
| 11 | +public class TradeAfterSaleConfirmReqVO { | |
| 12 | + | |
| 13 | + @ApiModelProperty(value = "售后编号", required = true, example = "1024") | |
| 14 | + @NotNull(message = "售后编号不能为空") | |
| 15 | + private Long id; | |
| 16 | + | |
| 17 | + @ApiModelProperty(value = "收货结果", required = true, example = "true", | |
| 18 | + notes = "true - 确认收货;false - 拒绝收货") | |
| 19 | + @NotNull(message = "审批结果不能为空") | |
| 20 | + private Boolean pass; | |
| 21 | + | |
| 22 | + @ApiModelProperty(value = "收货备注", example = "你猜") | |
| 23 | + private String receiptMemo; | |
| 24 | + | |
| 25 | +} | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleService.java
| 1 | 1 | package cn.iocoder.yudao.module.trade.service.aftersale; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleAuditReqVO; |
| 4 | +import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleConfirmReqVO; | |
| 4 | 5 | import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleCreateReqVO; |
| 5 | 6 | import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleDeliveryReqVO; |
| 6 | 7 | |
| ... | ... | @@ -39,4 +40,13 @@ public interface TradeAfterSaleService { |
| 39 | 40 | */ |
| 40 | 41 | void deliveryAfterSale(Long userId, AppTradeAfterSaleDeliveryReqVO deliveryReqVO); |
| 41 | 42 | |
| 43 | + /** | |
| 44 | + * 确认收货 | |
| 45 | + * | |
| 46 | + * @param userId 管理员用户编号 | |
| 47 | + * @param userIp 操作 IP | |
| 48 | + * @param confirmReqVO 收货 Request 信息 | |
| 49 | + */ | |
| 50 | + void confirmAfterSale(Long userId, String userIp, TradeAfterSaleConfirmReqVO confirmReqVO); | |
| 51 | + | |
| 42 | 52 | } | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java
| 1 | 1 | package cn.iocoder.yudao.module.trade.service.aftersale; |
| 2 | 2 | |
| 3 | +import cn.hutool.core.util.ObjectUtil; | |
| 3 | 4 | import cn.hutool.core.util.RandomUtil; |
| 4 | 5 | import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi; |
| 5 | 6 | import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO; |
| 6 | 7 | import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleAuditReqVO; |
| 8 | +import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleConfirmReqVO; | |
| 7 | 9 | import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleCreateReqVO; |
| 8 | 10 | import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleDeliveryReqVO; |
| 9 | 11 | import cn.iocoder.yudao.module.trade.convert.aftersale.TradeAfterSaleConvert; |
| ... | ... | @@ -129,12 +131,12 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService { |
| 129 | 131 | if (afterSale == null) { |
| 130 | 132 | throw exception(AFTER_SALE_NOT_FOUND); |
| 131 | 133 | } |
| 132 | - if (afterSale.getStatus().equals(TradeAfterSaleStatusEnum.APPLY.getStatus())) { | |
| 134 | + if (ObjectUtil.notEqual(afterSale.getStatus(), TradeAfterSaleStatusEnum.APPLY.getStatus())) { | |
| 133 | 135 | throw exception(AFTER_SALE_AUDIT_FAIL_STATUS_NOT_APPLY); |
| 134 | 136 | } |
| 135 | 137 | |
| 136 | 138 | // 进行审批 |
| 137 | - if (auditReqVO.getAudit()) { | |
| 139 | + if (auditReqVO.getPass()) { | |
| 138 | 140 | auditAfterSalePass(userId, userIp, auditReqVO, afterSale); |
| 139 | 141 | } else { |
| 140 | 142 | auditAfterSaleReject(userId, auditReqVO, afterSale); |
| ... | ... | @@ -207,8 +209,8 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService { |
| 207 | 209 | if (afterSale == null) { |
| 208 | 210 | throw exception(AFTER_SALE_NOT_FOUND); |
| 209 | 211 | } |
| 210 | - if (afterSale.getStatus().equals(TradeAfterSaleStatusEnum.SELLER_PASS.getStatus())) { | |
| 211 | - throw exception(AFTER_SALE_DELIVERY_FAIL_STATUS_NOT_BUYER_RETURN); | |
| 212 | + if (ObjectUtil.notEqual(afterSale.getStatus(), TradeAfterSaleStatusEnum.SELLER_PASS.getStatus())) { | |
| 213 | + throw exception(AFTER_SALE_DELIVERY_FAIL_STATUS_NOT_SELLER_PASS); | |
| 212 | 214 | } |
| 213 | 215 | |
| 214 | 216 | // 更新售后单的物流信息 |
| ... | ... | @@ -222,4 +224,56 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService { |
| 222 | 224 | // TODO 发送售后消息 |
| 223 | 225 | } |
| 224 | 226 | |
| 227 | + @Override | |
| 228 | + public void confirmAfterSale(Long userId, String userIp, | |
| 229 | + TradeAfterSaleConfirmReqVO confirmReqVO) { | |
| 230 | + // 校验售后单存在,并状态未审批 | |
| 231 | + TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectById(confirmReqVO.getId()); | |
| 232 | + if (afterSale == null) { | |
| 233 | + throw exception(AFTER_SALE_NOT_FOUND); | |
| 234 | + } | |
| 235 | + if (ObjectUtil.notEqual(afterSale.getStatus(), TradeAfterSaleStatusEnum.BUYER_RETURN.getStatus())) { | |
| 236 | + throw exception(AFTER_SALE_CONFIRM_FAIL_STATUS_NOT_BUYER_RETURN); | |
| 237 | + } | |
| 238 | + | |
| 239 | + // 进行审批 | |
| 240 | + if (confirmReqVO.getPass()) { | |
| 241 | + confirmAfterSalePass(userId, userIp, confirmReqVO, afterSale); | |
| 242 | + } else { | |
| 243 | + confirmAfterSaleReject(userId, confirmReqVO, afterSale); | |
| 244 | + } | |
| 245 | + } | |
| 246 | + | |
| 247 | + private void confirmAfterSalePass(Long userId, String userIp, | |
| 248 | + TradeAfterSaleConfirmReqVO confirmReqVO, TradeAfterSaleDO afterSale) { | |
| 249 | + // 更新售后单的状态 | |
| 250 | + Integer newStatus = TradeAfterSaleStatusEnum.WAIT_REFUND.getStatus(); | |
| 251 | + updateAfterSaleStatus(afterSale.getId(), TradeAfterSaleStatusEnum.BUYER_RETURN.getStatus(), new TradeAfterSaleDO() | |
| 252 | + .setStatus(newStatus).setReceiptTime(LocalDateTime.now()).setReceiptMemo(confirmReqVO.getReceiptMemo())); | |
| 253 | + | |
| 254 | + // 如果直接退款,则发起售后退款 | |
| 255 | + if (afterSale.getType().equals(TradeAfterSaleTypeEnum.REFUND.getType())) { | |
| 256 | + createPayRefund(userIp, afterSale); | |
| 257 | + } | |
| 258 | + | |
| 259 | + // TODO 记录售后日志 | |
| 260 | + | |
| 261 | + // TODO 发送售后消息 | |
| 262 | + } | |
| 263 | + | |
| 264 | + private void confirmAfterSaleReject(Long userId, TradeAfterSaleConfirmReqVO confirmReqVO, TradeAfterSaleDO afterSale) { | |
| 265 | + // 更新售后单的状态 | |
| 266 | + Integer newStatus = TradeAfterSaleStatusEnum.SELLER_TERMINATION.getStatus(); | |
| 267 | + updateAfterSaleStatus(afterSale.getId(), TradeAfterSaleStatusEnum.BUYER_RETURN.getStatus(), new TradeAfterSaleDO() | |
| 268 | + .setStatus(newStatus).setReceiptTime(LocalDateTime.now()).setReceiptMemo(confirmReqVO.getReceiptMemo())); | |
| 269 | + | |
| 270 | + // 更新交易订单项的售后状态为【未申请】 | |
| 271 | + tradeOrderService.updateOrderItemAfterSaleStatus(afterSale.getOrderItemId(), | |
| 272 | + TradeOrderItemAfterSaleStatusEnum.APPLY.getStatus(), TradeOrderItemAfterSaleStatusEnum.NONE.getStatus()); | |
| 273 | + | |
| 274 | + // TODO 记录售后日志 | |
| 275 | + | |
| 276 | + // TODO 发送售后消息 | |
| 277 | + } | |
| 278 | + | |
| 225 | 279 | } | ... | ... |