Commit 75ed4486c47ec2fe0cddba58e9bd01ee690deb99

Authored by YunaiV
1 parent 840cfad8

【功能优化】商城:拼团中时,禁止发起售后

yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApi.java
... ... @@ -2,8 +2,8 @@ package cn.iocoder.yudao.module.promotion.api.combination;
2 2  
3 3 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
4 4 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateRespDTO;
  5 +import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO;
5 6 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationValidateJoinRespDTO;
6   -
7 7 import jakarta.validation.Valid;
8 8  
9 9 /**
... ... @@ -33,13 +33,13 @@ public interface CombinationRecordApi {
33 33 CombinationRecordCreateRespDTO createCombinationRecord(@Valid CombinationRecordCreateReqDTO reqDTO);
34 34  
35 35 /**
36   - * 查询拼团记录是否成功
  36 + * 基于订单编号,查询拼团记录
37 37 *
38 38 * @param userId 用户编号
39 39 * @param orderId 订单编号
40   - * @return 拼团是否成功
  40 + * @return 拼团记录
41 41 */
42   - boolean isCombinationRecordSuccess(Long userId, Long orderId);
  42 + CombinationRecordRespDTO getCombinationRecordByOrderId(Long userId, Long orderId);
43 43  
44 44 /**
45 45 * 【下单前】校验是否满足拼团活动条件
... ...
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/dto/CombinationRecordRespDTO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.api.combination.dto;
  2 +
  3 +import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
  4 +import lombok.Data;
  5 +
  6 +import java.time.LocalDateTime;
  7 +
  8 +/**
  9 + * 拼团记录 Response DTO
  10 + *
  11 + * @author 芋道源码
  12 + */
  13 +@Data
  14 +public class CombinationRecordRespDTO {
  15 +
  16 + /**
  17 + * 编号,主键自增
  18 + */
  19 + private Long id;
  20 +
  21 + /**
  22 + * 拼团活动编号
  23 + *
  24 + * 关联 CombinationActivityDO 的 id 字段
  25 + */
  26 + private Long activityId;
  27 + /**
  28 + * 拼团商品单价
  29 + *
  30 + * 冗余 CombinationProductDO 的 combinationPrice 字段
  31 + */
  32 + private Integer combinationPrice;
  33 + /**
  34 + * SPU 编号
  35 + */
  36 + private Long spuId;
  37 + /**
  38 + * 商品名字
  39 + */
  40 + private String spuName;
  41 + /**
  42 + * 商品图片
  43 + */
  44 + private String picUrl;
  45 + /**
  46 + * SKU 编号
  47 + */
  48 + private Long skuId;
  49 + /**
  50 + * 购买的商品数量
  51 + */
  52 + private Integer count;
  53 +
  54 + /**
  55 + * 用户编号
  56 + */
  57 + private Long userId;
  58 +
  59 + /**
  60 + * 用户昵称
  61 + */
  62 + private String nickname;
  63 + /**
  64 + * 用户头像
  65 + */
  66 + private String avatar;
  67 +
  68 + /**
  69 + * 团长编号
  70 + */
  71 + private Long headId;
  72 + /**
  73 + * 开团状态
  74 + *
  75 + * 关联 {@link CombinationRecordStatusEnum}
  76 + */
  77 + private Integer status;
  78 + /**
  79 + * 订单编号
  80 + */
  81 + private Long orderId;
  82 + /**
  83 + * 开团需要人数
  84 + *
  85 + * 关联 CombinationActivityDO 的 userSize 字段
  86 + */
  87 + private Integer userSize;
  88 + /**
  89 + * 已加入拼团人数
  90 + */
  91 + private Integer userCount;
  92 + /**
  93 + * 是否虚拟成团
  94 + */
  95 + private Boolean virtualGroup;
  96 +
  97 + /**
  98 + * 过期时间
  99 + */
  100 + private LocalDateTime expireTime;
  101 + /**
  102 + * 开始时间 (订单付款后开始的时间)
  103 + */
  104 + private LocalDateTime startTime;
  105 + /**
  106 + * 结束时间(成团时间/失败时间)
  107 + */
  108 + private LocalDateTime endTime;
  109 +
  110 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApiImpl.java
1 1 package cn.iocoder.yudao.module.promotion.api.combination;
2 2  
  3 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
3 4 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
4 5 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateRespDTO;
  6 +import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO;
5 7 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationValidateJoinRespDTO;
6 8 import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert;
7 9 import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationRecordDO;
8   -import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
9 10 import cn.iocoder.yudao.module.promotion.service.combination.CombinationRecordService;
10 11 import jakarta.annotation.Resource;
11 12 import org.springframework.stereotype.Service;
12 13 import org.springframework.validation.annotation.Validated;
13 14  
14   -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
15   -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COMBINATION_RECORD_NOT_EXISTS;
16   -
17 15 /**
18 16 * 拼团活动 API 实现类
19 17 *
... ... @@ -37,12 +35,9 @@ public class CombinationRecordApiImpl implements CombinationRecordApi {
37 35 }
38 36  
39 37 @Override
40   - public boolean isCombinationRecordSuccess(Long userId, Long orderId) {
  38 + public CombinationRecordRespDTO getCombinationRecordByOrderId(Long userId, Long orderId) {
41 39 CombinationRecordDO record = combinationRecordService.getCombinationRecord(userId, orderId);
42   - if (record == null) {
43   - throw exception(COMBINATION_RECORD_NOT_EXISTS);
44   - }
45   - return CombinationRecordStatusEnum.isSuccess(record.getStatus());
  40 + return BeanUtils.toBean(record, CombinationRecordRespDTO.class);
46 41 }
47 42  
48 43 @Override
... ...
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java
... ... @@ -51,6 +51,7 @@ public interface ErrorCodeConstants {
51 51 ErrorCode AFTER_SALE_REFUND_FAIL_STATUS_NOT_WAIT_REFUND = new ErrorCode(1_011_000_110, "退款失败,售后单状态不是【待退款】");
52 52 ErrorCode AFTER_SALE_CANCEL_FAIL_STATUS_NOT_APPLY_OR_AGREE_OR_BUYER_DELIVERY =
53 53 new ErrorCode(1_011_000_111, "取消售后单失败,售后单状态不是【待审核】或【卖家同意】或【商家待收货】");
  54 + ErrorCode AFTER_SALE_CREATE_FAIL_ORDER_STATUS_COMBINATION_IN_PROGRESS = new ErrorCode(1_011_000_112, "订单拼团中,无法申请售后");
54 55  
55 56 // ========== Cart 模块 1-011-002-000 ==========
56 57 ErrorCode CARD_ITEM_NOT_FOUND = new ErrorCode(1_011_002_000, "购物车项不存在");
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleServiceImpl.java
... ... @@ -8,6 +8,9 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
8 8 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
9 9 import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi;
10 10 import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO;
  11 +import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi;
  12 +import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO;
  13 +import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
11 14 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSaleDisagreeReqVO;
12 15 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSalePageReqVO;
13 16 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSaleRefuseReqVO;
... ... @@ -26,6 +29,7 @@ import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleTypeEnum;
26 29 import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleWayEnum;
27 30 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum;
28 31 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum;
  32 +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
29 33 import cn.iocoder.yudao.module.trade.framework.aftersale.core.annotations.AfterSaleLog;
30 34 import cn.iocoder.yudao.module.trade.framework.aftersale.core.utils.AfterSaleLogUtils;
31 35 import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
... ... @@ -71,6 +75,8 @@ public class AfterSaleServiceImpl implements AfterSaleService {
71 75  
72 76 @Resource
73 77 private PayRefundApi payRefundApi;
  78 + @Resource
  79 + private CombinationRecordApi combinationRecordApi;
74 80  
75 81 @Resource
76 82 private TradeOrderProperties tradeOrderProperties;
... ... @@ -148,6 +154,14 @@ public class AfterSaleServiceImpl implements AfterSaleService {
148 154 && !TradeOrderStatusEnum.haveDelivered(order.getStatus())) {
149 155 throw exception(AFTER_SALE_CREATE_FAIL_ORDER_STATUS_NO_DELIVERED);
150 156 }
  157 + // 如果是拼团订单,则进行中不允许售后
  158 + if (TradeOrderTypeEnum.isCombination(order.getType())) {
  159 + CombinationRecordRespDTO combinationRecord = combinationRecordApi.getCombinationRecordByOrderId(
  160 + order.getUserId(), order.getId());
  161 + if (combinationRecord != null && CombinationRecordStatusEnum.isInProgress(combinationRecord.getStatus())) {
  162 + throw exception(AFTER_SALE_CREATE_FAIL_ORDER_STATUS_COMBINATION_IN_PROGRESS);
  163 + }
  164 + }
151 165 return orderItem;
152 166 }
153 167  
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java
... ... @@ -887,7 +887,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
887 887 .setAppKey(tradeOrderProperties.getPayAppKey()).setUserIp(getClientIP()) // 支付应用
888 888 .setMerchantOrderId(String.valueOf(order.getId())) // 支付单号
889 889 .setMerchantRefundId(String.valueOf(order.getId()))
890   - .setReason(TradeOrderCancelTypeEnum.COMBINATION_CLOSE.getName()).setPrice(order.getPayPrice()));// 价格信息
  890 + .setReason(TradeOrderCancelTypeEnum.COMBINATION_CLOSE.getName()).setPrice(order.getPayPrice())); // 价格信息
891 891 }
892 892  
893 893 @Override
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeCombinationOrderHandler.java
... ... @@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.trade.service.order.handler;
3 3 import cn.hutool.core.lang.Assert;
4 4 import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi;
5 5 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateRespDTO;
  6 +import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO;
  7 +import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
6 8 import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert;
7 9 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
8 10 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
... ... @@ -84,7 +86,9 @@ public class TradeCombinationOrderHandler implements TradeOrderHandler {
84 86 return;
85 87 }
86 88 // 校验订单拼团是否成功
87   - if (!combinationRecordApi.isCombinationRecordSuccess(order.getUserId(), order.getId())) {
  89 + CombinationRecordRespDTO combinationRecord = combinationRecordApi.getCombinationRecordByOrderId(order.getUserId(), order.getId());
  90 + Assert.notNull(combinationRecord, "订单({})对应的拼团记录不存在", order.getId());
  91 + if (!CombinationRecordStatusEnum.isSuccess(combinationRecord.getStatus())) {
88 92 throw exception(ORDER_DELIVERY_FAIL_COMBINATION_RECORD_STATUS_NOT_SUCCESS);
89 93 }
90 94 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCouponPriceCalculator.java
... ... @@ -43,7 +43,7 @@ public class TradeCouponPriceCalculator implements TradePriceCalculator {
43 43 public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) {
44 44 // 只有【普通】订单,才允许使用优惠劵
45 45 if (ObjectUtil.notEqual(result.getType(), TradeOrderTypeEnum.NORMAL.getType())) {
46   - if (ObjectUtil.notEqual(result.getType(), TradeOrderTypeEnum.NORMAL.getType())) {
  46 + if (param.getCouponId() != null) {
47 47 throw exception(PRICE_CALCULATE_COUPON_NOT_MATCH_NORMAL_ORDER);
48 48 }
49 49 return;
... ...