Commit 75ed4486c47ec2fe0cddba58e9bd01ee690deb99
1 parent
840cfad8
【功能优化】商城:拼团中时,禁止发起售后
Showing
8 changed files
with
140 additions
and
16 deletions
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; | ... | ... |