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,8 +2,8 @@ package cn.iocoder.yudao.module.promotion.api.combination;
2 2
3 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; 3 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
4 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateRespDTO; 4 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateRespDTO;
  5 +import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO;
5 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationValidateJoinRespDTO; 6 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationValidateJoinRespDTO;
6 -  
7 import jakarta.validation.Valid; 7 import jakarta.validation.Valid;
8 8
9 /** 9 /**
@@ -33,13 +33,13 @@ public interface CombinationRecordApi { @@ -33,13 +33,13 @@ public interface CombinationRecordApi {
33 CombinationRecordCreateRespDTO createCombinationRecord(@Valid CombinationRecordCreateReqDTO reqDTO); 33 CombinationRecordCreateRespDTO createCombinationRecord(@Valid CombinationRecordCreateReqDTO reqDTO);
34 34
35 /** 35 /**
36 - * 查询拼团记录是否成功 36 + * 基于订单编号,查询拼团记录
37 * 37 *
38 * @param userId 用户编号 38 * @param userId 用户编号
39 * @param orderId 订单编号 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 package cn.iocoder.yudao.module.promotion.api.combination; 1 package cn.iocoder.yudao.module.promotion.api.combination;
2 2
  3 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
3 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; 4 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
4 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateRespDTO; 5 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateRespDTO;
  6 +import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO;
5 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationValidateJoinRespDTO; 7 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationValidateJoinRespDTO;
6 import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert; 8 import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert;
7 import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationRecordDO; 9 import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationRecordDO;
8 -import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;  
9 import cn.iocoder.yudao.module.promotion.service.combination.CombinationRecordService; 10 import cn.iocoder.yudao.module.promotion.service.combination.CombinationRecordService;
10 import jakarta.annotation.Resource; 11 import jakarta.annotation.Resource;
11 import org.springframework.stereotype.Service; 12 import org.springframework.stereotype.Service;
12 import org.springframework.validation.annotation.Validated; 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 * 拼团活动 API 实现类 16 * 拼团活动 API 实现类
19 * 17 *
@@ -37,12 +35,9 @@ public class CombinationRecordApiImpl implements CombinationRecordApi { @@ -37,12 +35,9 @@ public class CombinationRecordApiImpl implements CombinationRecordApi {
37 } 35 }
38 36
39 @Override 37 @Override
40 - public boolean isCombinationRecordSuccess(Long userId, Long orderId) { 38 + public CombinationRecordRespDTO getCombinationRecordByOrderId(Long userId, Long orderId) {
41 CombinationRecordDO record = combinationRecordService.getCombinationRecord(userId, orderId); 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 @Override 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,6 +51,7 @@ public interface ErrorCodeConstants {
51 ErrorCode AFTER_SALE_REFUND_FAIL_STATUS_NOT_WAIT_REFUND = new ErrorCode(1_011_000_110, "退款失败,售后单状态不是【待退款】"); 51 ErrorCode AFTER_SALE_REFUND_FAIL_STATUS_NOT_WAIT_REFUND = new ErrorCode(1_011_000_110, "退款失败,售后单状态不是【待退款】");
52 ErrorCode AFTER_SALE_CANCEL_FAIL_STATUS_NOT_APPLY_OR_AGREE_OR_BUYER_DELIVERY = 52 ErrorCode AFTER_SALE_CANCEL_FAIL_STATUS_NOT_APPLY_OR_AGREE_OR_BUYER_DELIVERY =
53 new ErrorCode(1_011_000_111, "取消售后单失败,售后单状态不是【待审核】或【卖家同意】或【商家待收货】"); 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 // ========== Cart 模块 1-011-002-000 ========== 56 // ========== Cart 模块 1-011-002-000 ==========
56 ErrorCode CARD_ITEM_NOT_FOUND = new ErrorCode(1_011_002_000, "购物车项不存在"); 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,6 +8,9 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
8 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; 8 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
9 import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi; 9 import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi;
10 import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO; 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 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSaleDisagreeReqVO; 14 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSaleDisagreeReqVO;
12 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSalePageReqVO; 15 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSalePageReqVO;
13 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSaleRefuseReqVO; 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,6 +29,7 @@ import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleTypeEnum;
26 import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleWayEnum; 29 import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleWayEnum;
27 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum; 30 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum;
28 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; 31 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum;
  32 +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
29 import cn.iocoder.yudao.module.trade.framework.aftersale.core.annotations.AfterSaleLog; 33 import cn.iocoder.yudao.module.trade.framework.aftersale.core.annotations.AfterSaleLog;
30 import cn.iocoder.yudao.module.trade.framework.aftersale.core.utils.AfterSaleLogUtils; 34 import cn.iocoder.yudao.module.trade.framework.aftersale.core.utils.AfterSaleLogUtils;
31 import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; 35 import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
@@ -71,6 +75,8 @@ public class AfterSaleServiceImpl implements AfterSaleService { @@ -71,6 +75,8 @@ public class AfterSaleServiceImpl implements AfterSaleService {
71 75
72 @Resource 76 @Resource
73 private PayRefundApi payRefundApi; 77 private PayRefundApi payRefundApi;
  78 + @Resource
  79 + private CombinationRecordApi combinationRecordApi;
74 80
75 @Resource 81 @Resource
76 private TradeOrderProperties tradeOrderProperties; 82 private TradeOrderProperties tradeOrderProperties;
@@ -148,6 +154,14 @@ public class AfterSaleServiceImpl implements AfterSaleService { @@ -148,6 +154,14 @@ public class AfterSaleServiceImpl implements AfterSaleService {
148 && !TradeOrderStatusEnum.haveDelivered(order.getStatus())) { 154 && !TradeOrderStatusEnum.haveDelivered(order.getStatus())) {
149 throw exception(AFTER_SALE_CREATE_FAIL_ORDER_STATUS_NO_DELIVERED); 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 return orderItem; 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,7 +887,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
887 .setAppKey(tradeOrderProperties.getPayAppKey()).setUserIp(getClientIP()) // 支付应用 887 .setAppKey(tradeOrderProperties.getPayAppKey()).setUserIp(getClientIP()) // 支付应用
888 .setMerchantOrderId(String.valueOf(order.getId())) // 支付单号 888 .setMerchantOrderId(String.valueOf(order.getId())) // 支付单号
889 .setMerchantRefundId(String.valueOf(order.getId())) 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 @Override 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,6 +3,8 @@ package cn.iocoder.yudao.module.trade.service.order.handler;
3 import cn.hutool.core.lang.Assert; 3 import cn.hutool.core.lang.Assert;
4 import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi; 4 import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi;
5 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateRespDTO; 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 import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; 8 import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert;
7 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; 9 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
8 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; 10 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
@@ -84,7 +86,9 @@ public class TradeCombinationOrderHandler implements TradeOrderHandler { @@ -84,7 +86,9 @@ public class TradeCombinationOrderHandler implements TradeOrderHandler {
84 return; 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 throw exception(ORDER_DELIVERY_FAIL_COMBINATION_RECORD_STATUS_NOT_SUCCESS); 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,7 +43,7 @@ public class TradeCouponPriceCalculator implements TradePriceCalculator {
43 public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) { 43 public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) {
44 // 只有【普通】订单,才允许使用优惠劵 44 // 只有【普通】订单,才允许使用优惠劵
45 if (ObjectUtil.notEqual(result.getType(), TradeOrderTypeEnum.NORMAL.getType())) { 45 if (ObjectUtil.notEqual(result.getType(), TradeOrderTypeEnum.NORMAL.getType())) {
46 - if (ObjectUtil.notEqual(result.getType(), TradeOrderTypeEnum.NORMAL.getType())) { 46 + if (param.getCouponId() != null) {
47 throw exception(PRICE_CALCULATE_COUPON_NOT_MATCH_NORMAL_ORDER); 47 throw exception(PRICE_CALCULATE_COUPON_NOT_MATCH_NORMAL_ORDER);
48 } 48 }
49 return; 49 return;