mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-11-04 12:18:42 +08:00 
			
		
		
		
	订单:完善拼团活动
This commit is contained in:
		@@ -20,13 +20,4 @@ public interface BargainRecordApi {
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    void createBargainRecord(@Valid BargainRecordCreateReqDTO reqDTO);
 | 
					    void createBargainRecord(@Valid BargainRecordCreateReqDTO reqDTO);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * 查询砍价是否成功
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @param userId  用户编号
 | 
					 | 
				
			||||||
     * @param orderId 订单编号
 | 
					 | 
				
			||||||
     * @return 砍价是否成功
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    boolean isBargainRecordSuccess(Long userId, Long orderId);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,6 +28,11 @@ public class CombinationRecordCreateReqDTO {
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    @NotNull(message = "sku 编号不能为空")
 | 
					    @NotNull(message = "sku 编号不能为空")
 | 
				
			||||||
    private Long skuId;
 | 
					    private Long skuId;
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 购买的商品数量
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    @NotNull(message = "购买数量不能为空")
 | 
				
			||||||
 | 
					    private Integer count;
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 订单编号
 | 
					     * 订单编号
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -75,19 +75,11 @@ public interface ErrorCodeConstants {
 | 
				
			|||||||
    ErrorCode COMBINATION_RECORD_HEAD_NOT_EXISTS = new ErrorCode(1_013_011_002, "拼团失败,父拼团不存在");
 | 
					    ErrorCode COMBINATION_RECORD_HEAD_NOT_EXISTS = new ErrorCode(1_013_011_002, "拼团失败,父拼团不存在");
 | 
				
			||||||
    ErrorCode COMBINATION_RECORD_USER_FULL = new ErrorCode(1_013_011_003, "拼团失败,拼团人数已满");
 | 
					    ErrorCode COMBINATION_RECORD_USER_FULL = new ErrorCode(1_013_011_003, "拼团失败,拼团人数已满");
 | 
				
			||||||
    ErrorCode COMBINATION_RECORD_FAILED_HAVE_JOINED = new ErrorCode(1_013_011_004, "拼团失败,已参与其它拼团");
 | 
					    ErrorCode COMBINATION_RECORD_FAILED_HAVE_JOINED = new ErrorCode(1_013_011_004, "拼团失败,已参与其它拼团");
 | 
				
			||||||
    ErrorCode COMBINATION_RECORD_FAILED_TIME_END = new ErrorCode(1_013_011_005, "拼团失败,活动已经结束");
 | 
					    ErrorCode COMBINATION_RECORD_FAILED_TIME_NOT_START = new ErrorCode(1_013_011_005, "拼团失败,活动未开始");
 | 
				
			||||||
    ErrorCode COMBINATION_RECORD_FAILED_SINGLE_LIMIT_COUNT_EXCEED = new ErrorCode(1_013_011_006, "拼团失败,原因:单次限购超出");
 | 
					    ErrorCode COMBINATION_RECORD_FAILED_TIME_END = new ErrorCode(1_013_011_006, "拼团失败,活动已经结束");
 | 
				
			||||||
    ErrorCode COMBINATION_RECORD_FAILED_TOTAL_LIMIT_COUNT_EXCEED = new ErrorCode(1_013_011_007, "拼团失败,原因:超出总购买次数");
 | 
					    ErrorCode COMBINATION_RECORD_FAILED_SINGLE_LIMIT_COUNT_EXCEED = new ErrorCode(1_013_011_007, "拼团失败,原因:单次限购超出");
 | 
				
			||||||
    // ========== 拼团记录 1013011000 ==========
 | 
					    ErrorCode COMBINATION_RECORD_FAILED_TOTAL_LIMIT_COUNT_EXCEED = new ErrorCode(1_013_011_008, "拼团失败,原因:超出总购买次数");
 | 
				
			||||||
    ErrorCode COMBINATION_RECORD_NOT_EXISTS = new ErrorCode(1013011000, "拼团不存在");
 | 
					    ErrorCode COMBINATION_RECORD_FAILED_ORDER_STATUS_UNPAID = new ErrorCode(1_013_011_009, "拼团失败,原因:存在未支付订单,请先支付");
 | 
				
			||||||
    ErrorCode COMBINATION_RECORD_EXISTS = new ErrorCode(1013011001, "拼团失败,已参与过该拼团");
 | 
					 | 
				
			||||||
    ErrorCode COMBINATION_RECORD_HEAD_NOT_EXISTS = new ErrorCode(1013011002, "拼团失败,父拼团不存在");
 | 
					 | 
				
			||||||
    ErrorCode COMBINATION_RECORD_USER_FULL = new ErrorCode(1013011003, "拼团失败,拼团人数已满");
 | 
					 | 
				
			||||||
    ErrorCode COMBINATION_RECORD_FAILED_HAVE_JOINED = new ErrorCode(1013011004, "拼团失败,已参与其它拼团");
 | 
					 | 
				
			||||||
    ErrorCode COMBINATION_RECORD_FAILED_TIME_NOT_START = new ErrorCode(1013011005, "拼团失败,活动未开始");
 | 
					 | 
				
			||||||
    ErrorCode COMBINATION_RECORD_FAILED_TIME_END = new ErrorCode(1013011006, "拼团失败,活动已经结束");
 | 
					 | 
				
			||||||
    ErrorCode COMBINATION_RECORD_FAILED_SINGLE_LIMIT_COUNT_EXCEED = new ErrorCode(1013011007, "拼团失败,原因:单次限购超出");
 | 
					 | 
				
			||||||
    ErrorCode COMBINATION_RECORD_FAILED_TOTAL_LIMIT_COUNT_EXCEED = new ErrorCode(1013011008, "拼团失败,原因:超出总购买次数");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // ========== 砍价活动 1-013-012-000 ==========
 | 
					    // ========== 砍价活动 1-013-012-000 ==========
 | 
				
			||||||
    ErrorCode BARGAIN_ACTIVITY_NOT_EXISTS = new ErrorCode(1_013_012_000, "砍价活动不存在");
 | 
					    ErrorCode BARGAIN_ACTIVITY_NOT_EXISTS = new ErrorCode(1_013_012_000, "砍价活动不存在");
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,9 +16,4 @@ public class BargainRecordApiImpl implements BargainRecordApi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					 | 
				
			||||||
    public boolean isBargainRecordSuccess(Long userId, Long orderId) {
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -97,8 +97,8 @@ public interface CombinationActivityConvert {
 | 
				
			|||||||
    default CombinationRecordDO convert(CombinationRecordCreateReqDTO reqDTO,
 | 
					    default CombinationRecordDO convert(CombinationRecordCreateReqDTO reqDTO,
 | 
				
			||||||
                                        CombinationActivityDO activity, MemberUserRespDTO user,
 | 
					                                        CombinationActivityDO activity, MemberUserRespDTO user,
 | 
				
			||||||
                                        ProductSpuRespDTO spu, ProductSkuRespDTO sku) {
 | 
					                                        ProductSpuRespDTO spu, ProductSkuRespDTO sku) {
 | 
				
			||||||
        // TODO @puhui999:订单付款后需要设置开始时间和结束时间;
 | 
					 | 
				
			||||||
        return convert(reqDTO)
 | 
					        return convert(reqDTO)
 | 
				
			||||||
 | 
					                .setCount(reqDTO.getCount())
 | 
				
			||||||
                .setVirtualGroup(false)
 | 
					                .setVirtualGroup(false)
 | 
				
			||||||
                .setExpireTime(activity.getStartTime().plusHours(activity.getLimitDuration()))
 | 
					                .setExpireTime(activity.getStartTime().plusHours(activity.getLimitDuration()))
 | 
				
			||||||
                .setUserSize(activity.getUserSize())
 | 
					                .setUserSize(activity.getUserSize())
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -62,6 +62,10 @@ public class CombinationRecordDO extends BaseDO {
 | 
				
			|||||||
     * SKU 编号
 | 
					     * SKU 编号
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private Long skuId;
 | 
					    private Long skuId;
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 购买的商品数量
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private Integer count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 用户编号
 | 
					     * 用户编号
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -116,10 +116,10 @@ public class BargainActivityServiceImpl implements BargainActivityService {
 | 
				
			|||||||
    public void deleteBargainActivity(Long id) {
 | 
					    public void deleteBargainActivity(Long id) {
 | 
				
			||||||
        // 校验存在
 | 
					        // 校验存在
 | 
				
			||||||
        BargainActivityDO activityDO = validateBargainActivityExists(id);
 | 
					        BargainActivityDO activityDO = validateBargainActivityExists(id);
 | 
				
			||||||
        // 校验状态 TODO puhui: 测试完成后需要恢复校验
 | 
					        // 校验状态
 | 
				
			||||||
        //if (ObjectUtil.equal(activityDO.getStatus(), CommonStatusEnum.ENABLE.getStatus())) {
 | 
					        if (ObjectUtil.equal(activityDO.getStatus(), CommonStatusEnum.ENABLE.getStatus())) {
 | 
				
			||||||
        //    throw exception(BARGAIN_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END);
 | 
					            throw exception(BARGAIN_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END);
 | 
				
			||||||
        //}
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // 删除
 | 
					        // 删除
 | 
				
			||||||
        bargainActivityMapper.deleteById(id);
 | 
					        bargainActivityMapper.deleteById(id);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,6 +16,7 @@ import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationR
 | 
				
			|||||||
import cn.iocoder.yudao.module.promotion.dal.mysql.combination.CombinationRecordMapper;
 | 
					import cn.iocoder.yudao.module.promotion.dal.mysql.combination.CombinationRecordMapper;
 | 
				
			||||||
import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
 | 
					import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
 | 
				
			||||||
import cn.iocoder.yudao.module.trade.api.order.TradeOrderApi;
 | 
					import cn.iocoder.yudao.module.trade.api.order.TradeOrderApi;
 | 
				
			||||||
 | 
					import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum;
 | 
				
			||||||
import org.springframework.context.annotation.Lazy;
 | 
					import org.springframework.context.annotation.Lazy;
 | 
				
			||||||
import org.springframework.stereotype.Service;
 | 
					import org.springframework.stereotype.Service;
 | 
				
			||||||
import org.springframework.transaction.annotation.Transactional;
 | 
					import org.springframework.transaction.annotation.Transactional;
 | 
				
			||||||
@@ -26,7 +27,7 @@ import java.time.LocalDateTime;
 | 
				
			|||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 | 
					import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 | 
				
			||||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
 | 
					import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
 | 
				
			||||||
import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
 | 
					import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TODO 芋艿:等拼团记录做完,完整 review 下
 | 
					// TODO 芋艿:等拼团记录做完,完整 review 下
 | 
				
			||||||
@@ -101,7 +102,6 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
 | 
				
			|||||||
        return recordDO;
 | 
					        return recordDO;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // TODO @puhui999:有一个应该在创建那要做下;就是当前 activityId 已经有未支付的订单,不允许在发起新的;要么支付,要么去掉先;
 | 
					 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public void validateCombinationRecord(Long activityId, Long userId, Long skuId, Integer count) {
 | 
					    public void validateCombinationRecord(Long activityId, Long userId, Long skuId, Integer count) {
 | 
				
			||||||
        // 1.1 校验拼团活动是否存在
 | 
					        // 1.1 校验拼团活动是否存在
 | 
				
			||||||
@@ -110,55 +110,69 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
 | 
				
			|||||||
        if (ObjectUtil.equal(activity.getStatus(), CommonStatusEnum.DISABLE.getStatus())) {
 | 
					        if (ObjectUtil.equal(activity.getStatus(), CommonStatusEnum.DISABLE.getStatus())) {
 | 
				
			||||||
            throw exception(COMBINATION_ACTIVITY_STATUS_DISABLE);
 | 
					            throw exception(COMBINATION_ACTIVITY_STATUS_DISABLE);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        // 1.3 校验是否超出单次限购数量
 | 
					        // 2 校验是否超出单次限购数量
 | 
				
			||||||
        if (count > activity.getSingleLimitCount()) {
 | 
					        if (count > activity.getSingleLimitCount()) {
 | 
				
			||||||
            throw exception(COMBINATION_RECORD_FAILED_SINGLE_LIMIT_COUNT_EXCEED);
 | 
					            throw exception(COMBINATION_RECORD_FAILED_SINGLE_LIMIT_COUNT_EXCEED);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        // 3、校验是否有拼团记录
 | 
				
			||||||
        // 2. 校验是否超出总限购数量
 | 
					 | 
				
			||||||
        List<CombinationRecordDO> recordList = getRecordListByUserIdAndActivityId(userId, activityId);
 | 
					        List<CombinationRecordDO> recordList = getRecordListByUserIdAndActivityId(userId, activityId);
 | 
				
			||||||
        if (CollUtil.isEmpty(recordList)) {
 | 
					        if (CollUtil.isEmpty(recordList)) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        // 过滤出拼团成功的
 | 
					        // 4、校验是否超出总限购数量
 | 
				
			||||||
        // TODO @puhui999:count 要不存一个在 record 里?
 | 
					        Integer sumValue = getSumValue(convertList(recordList, CombinationRecordDO::getCount,
 | 
				
			||||||
        List<Long> skuIds = convertList(recordList, CombinationRecordDO::getSkuId,
 | 
					                item -> ObjectUtil.equals(item.getStatus(), CombinationRecordStatusEnum.SUCCESS.getStatus())), i -> i, Integer::sum);
 | 
				
			||||||
                item -> ObjectUtil.equals(item.getStatus(), CombinationRecordStatusEnum.SUCCESS.getStatus()));
 | 
					        if ((sumValue + count) > activity.getTotalLimitCount()) {
 | 
				
			||||||
        Integer countSum = tradeOrderApi.getOrderItemCountSumByOrderIdAndSkuId(convertList(recordList,
 | 
					 | 
				
			||||||
                CombinationRecordDO::getOrderId,
 | 
					 | 
				
			||||||
                item -> ObjectUtil.equals(item.getStatus(), CombinationRecordStatusEnum.SUCCESS.getStatus())), skuIds);
 | 
					 | 
				
			||||||
        if (activity.getTotalLimitCount() < countSum) {
 | 
					 | 
				
			||||||
            throw exception(COMBINATION_RECORD_FAILED_TOTAL_LIMIT_COUNT_EXCEED);
 | 
					            throw exception(COMBINATION_RECORD_FAILED_TOTAL_LIMIT_COUNT_EXCEED);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        // 5、校验拼团记录是否存在未支付的订单(如果存在未支付的订单则不允许发起新的拼团)
 | 
				
			||||||
 | 
					        CombinationRecordDO record = findFirst(recordList, item -> ObjectUtil.equals(item.getStatus(), null));
 | 
				
			||||||
 | 
					        if (record == null) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // 5.1、查询关联的订单是否已经支付
 | 
				
			||||||
 | 
					        // 当前 activityId 已经有未支付的订单,不允许在发起新的;要么支付,要么去掉先;
 | 
				
			||||||
 | 
					        Integer orderStatus = tradeOrderApi.getOrderStatus(record.getOrderId());
 | 
				
			||||||
 | 
					        if (ObjectUtil.equal(orderStatus, TradeOrderStatusEnum.UNPAID.getStatus())) {
 | 
				
			||||||
 | 
					            throw exception(COMBINATION_RECORD_FAILED_ORDER_STATUS_UNPAID);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    @Transactional(rollbackFor = Exception.class)
 | 
					    @Transactional(rollbackFor = Exception.class)
 | 
				
			||||||
    public void createCombinationRecord(CombinationRecordCreateReqDTO reqDTO) {
 | 
					    public void createCombinationRecord(CombinationRecordCreateReqDTO reqDTO) {
 | 
				
			||||||
        // 1.1 校验拼团活动
 | 
					 | 
				
			||||||
        CombinationActivityDO activity = combinationActivityService.validateCombinationActivityExists(reqDTO.getActivityId());
 | 
					 | 
				
			||||||
        // 1.2 需要校验下,他当前是不是已经参加了该拼团;
 | 
					 | 
				
			||||||
        // TODO @puhui999:拼团应该可以重复参加;应该去校验总共的上限哈,就是 activity.totalLimitCount
 | 
					 | 
				
			||||||
        List<CombinationRecordDO> records = recordMapper.selectListByUserId(reqDTO.getUserId());
 | 
					 | 
				
			||||||
        List<Long> orderIds = convertList(records, CombinationRecordDO::getOrderId);
 | 
					 | 
				
			||||||
        // 1.2.1 如果存在订单才去校验
 | 
					 | 
				
			||||||
        if (CollUtil.isNotEmpty(orderIds)) {
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 1.1、 校验拼团活动
 | 
				
			||||||
 | 
					        CombinationActivityDO activity = combinationActivityService.validateCombinationActivityExists(reqDTO.getActivityId());
 | 
				
			||||||
 | 
					        // 1.2 校验是否超出单次限购数量
 | 
				
			||||||
 | 
					        if (reqDTO.getCount() > activity.getSingleLimitCount()) {
 | 
				
			||||||
 | 
					            throw exception(COMBINATION_RECORD_FAILED_SINGLE_LIMIT_COUNT_EXCEED);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        // 1.3 校验用户是否参加了其它拼团
 | 
					        // 1.3、校验是否有拼团记录
 | 
				
			||||||
 | 
					        List<CombinationRecordDO> records = getRecordListByUserIdAndActivityId(reqDTO.getUserId(), reqDTO.getActivityId());
 | 
				
			||||||
 | 
					        if (CollUtil.isEmpty(records)) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // 1.4、校验是否超出总限购数量
 | 
				
			||||||
 | 
					        Integer sumValue = getSumValue(convertList(records, CombinationRecordDO::getCount,
 | 
				
			||||||
 | 
					                item -> ObjectUtil.equals(item.getStatus(), CombinationRecordStatusEnum.SUCCESS.getStatus())), i -> i, Integer::sum);
 | 
				
			||||||
 | 
					        if ((sumValue + reqDTO.getCount()) > activity.getTotalLimitCount()) {
 | 
				
			||||||
 | 
					            throw exception(COMBINATION_RECORD_FAILED_TOTAL_LIMIT_COUNT_EXCEED);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // 2、 校验用户是否参加了其它拼团
 | 
				
			||||||
        List<CombinationRecordDO> recordDOList = recordMapper.selectListByUserIdAndStatus(reqDTO.getUserId(), CombinationRecordStatusEnum.IN_PROGRESS.getStatus());
 | 
					        List<CombinationRecordDO> recordDOList = recordMapper.selectListByUserIdAndStatus(reqDTO.getUserId(), CombinationRecordStatusEnum.IN_PROGRESS.getStatus());
 | 
				
			||||||
        if (CollUtil.isNotEmpty(recordDOList)) {
 | 
					        if (CollUtil.isNotEmpty(recordDOList)) {
 | 
				
			||||||
            throw exception(COMBINATION_RECORD_FAILED_HAVE_JOINED);
 | 
					            throw exception(COMBINATION_RECORD_FAILED_HAVE_JOINED);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        // 1、4 校验活动是否开启
 | 
					        // 3、 校验活动是否开启
 | 
				
			||||||
        if (LocalDateTime.now().isAfter(activity.getStartTime())) {
 | 
					        if (LocalDateTime.now().isAfter(activity.getStartTime())) {
 | 
				
			||||||
            throw exception(COMBINATION_RECORD_FAILED_TIME_NOT_START);
 | 
					            throw exception(COMBINATION_RECORD_FAILED_TIME_NOT_START);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        // 1.5 校验当前活动是否过期
 | 
					        // 4、 校验当前活动是否过期
 | 
				
			||||||
        if (LocalDateTime.now().isAfter(activity.getEndTime())) {
 | 
					        if (LocalDateTime.now().isAfter(activity.getEndTime())) {
 | 
				
			||||||
            throw exception(COMBINATION_RECORD_FAILED_TIME_END);
 | 
					            throw exception(COMBINATION_RECORD_FAILED_TIME_END);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        // 1.6 父拼团是否存在,是否已经满了
 | 
					        // 5、 父拼团是否存在,是否已经满了
 | 
				
			||||||
        if (reqDTO.getHeadId() != null) {
 | 
					        if (reqDTO.getHeadId() != null) {
 | 
				
			||||||
            // 查询进行中的父拼团
 | 
					            // 查询进行中的父拼团
 | 
				
			||||||
            CombinationRecordDO record = recordMapper.selectOneByHeadId(reqDTO.getHeadId(), CombinationRecordStatusEnum.IN_PROGRESS.getStatus());
 | 
					            CombinationRecordDO record = recordMapper.selectOneByHeadId(reqDTO.getHeadId(), CombinationRecordStatusEnum.IN_PROGRESS.getStatus());
 | 
				
			||||||
@@ -171,8 +185,6 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // TODO @puhui999:单次限购
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // 2. 创建拼团记录
 | 
					        // 2. 创建拼团记录
 | 
				
			||||||
        MemberUserRespDTO user = memberUserApi.getUser(reqDTO.getUserId());
 | 
					        MemberUserRespDTO user = memberUserApi.getUser(reqDTO.getUserId());
 | 
				
			||||||
        ProductSpuRespDTO spu = productSpuApi.getSpu(reqDTO.getSpuId());
 | 
					        ProductSpuRespDTO spu = productSpuApi.getSpu(reqDTO.getSpuId());
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,5 @@
 | 
				
			|||||||
package cn.iocoder.yudao.module.trade.api.order;
 | 
					package cn.iocoder.yudao.module.trade.api.order;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.Collection;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * 订单 API 接口
 | 
					 * 订单 API 接口
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@@ -10,21 +8,11 @@ import java.util.Collection;
 | 
				
			|||||||
public interface TradeOrderApi {
 | 
					public interface TradeOrderApi {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 验证订单
 | 
					     * 获取订单状态
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param userId      用户 id
 | 
					     * @param id 订单编号
 | 
				
			||||||
     * @param orderItemId 订单项 id
 | 
					     * @return 订单状态
 | 
				
			||||||
     * @return 校验通过返回订单 id
 | 
					 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    Long validateOrder(Long userId, Long orderItemId);
 | 
					    Integer getOrderStatus(Long id);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * 获取订单项商品购买数量总和
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @param orderIds 订单编号
 | 
					 | 
				
			||||||
     * @param skuIds   sku 编号
 | 
					 | 
				
			||||||
     * @return 订单项商品购买数量总和
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    Integer getOrderItemCountSumByOrderIdAndSkuId(Collection<Long> orderIds, Collection<Long> skuIds);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,15 +1,14 @@
 | 
				
			|||||||
package cn.iocoder.yudao.module.trade.api.order;
 | 
					package cn.iocoder.yudao.module.trade.api.order;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
 | 
					import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
 | 
				
			||||||
import cn.iocoder.yudao.module.trade.service.order.TradeOrderQueryService;
 | 
					import cn.iocoder.yudao.module.trade.service.order.TradeOrderQueryService;
 | 
				
			||||||
import org.springframework.stereotype.Service;
 | 
					import org.springframework.stereotype.Service;
 | 
				
			||||||
import org.springframework.validation.annotation.Validated;
 | 
					import org.springframework.validation.annotation.Validated;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Resource;
 | 
					import javax.annotation.Resource;
 | 
				
			||||||
import java.util.Collection;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 | 
					import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 | 
				
			||||||
import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_ITEM_NOT_FOUND;
 | 
					import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_NOT_FOUND;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * 订单 API 接口实现类
 | 
					 * 订单 API 接口实现类
 | 
				
			||||||
@@ -24,18 +23,12 @@ public class TradeOrderApiImpl implements TradeOrderApi {
 | 
				
			|||||||
    private TradeOrderQueryService tradeOrderQueryService;
 | 
					    private TradeOrderQueryService tradeOrderQueryService;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public Long validateOrder(Long userId, Long orderItemId) {
 | 
					    public Integer getOrderStatus(Long id) {
 | 
				
			||||||
        // 校验订单项,订单项存在订单就存在
 | 
					        TradeOrderDO order = tradeOrderQueryService.getOrder(id);
 | 
				
			||||||
        TradeOrderItemDO item = tradeOrderQueryService.getOrderItem(userId, orderItemId);
 | 
					        if (order == null) {
 | 
				
			||||||
        if (item == null) {
 | 
					            throw exception(ORDER_NOT_FOUND);
 | 
				
			||||||
            throw exception(ORDER_ITEM_NOT_FOUND);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return item.getOrderId();
 | 
					        return order.getStatus();
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Override
 | 
					 | 
				
			||||||
    public Integer getOrderItemCountSumByOrderIdAndSkuId(Collection<Long> orderIds, Collection<Long> skuIds) {
 | 
					 | 
				
			||||||
        return tradeOrderQueryService.getOrderItemCountSumByOrderIdAndSkuId(orderIds, skuIds);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,6 +16,7 @@ import java.util.List;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
@Schema(description = "用户 App - 交易订单结算 Request VO")
 | 
					@Schema(description = "用户 App - 交易订单结算 Request VO")
 | 
				
			||||||
@Data
 | 
					@Data
 | 
				
			||||||
 | 
					@Valid
 | 
				
			||||||
public class AppTradeOrderSettlementReqVO {
 | 
					public class AppTradeOrderSettlementReqVO {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Schema(description = "商品项数组", requiredMode = Schema.RequiredMode.REQUIRED)
 | 
					    @Schema(description = "商品项数组", requiredMode = Schema.RequiredMode.REQUIRED)
 | 
				
			||||||
@@ -62,7 +63,16 @@ public class AppTradeOrderSettlementReqVO {
 | 
				
			|||||||
    @Schema(description = "砍价活动编号", example = "123")
 | 
					    @Schema(description = "砍价活动编号", example = "123")
 | 
				
			||||||
    private Long bargainActivityId;
 | 
					    private Long bargainActivityId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // TODO @puhui999:可以写个参数校验,如果 seckillActivityId 或 combinationActivityId 或 combinationHeadId 的情况,items 应该只有一个
 | 
					    @AssertTrue(message = "活动商品每次只能购买一种规格")
 | 
				
			||||||
 | 
					    @JsonIgnore
 | 
				
			||||||
 | 
					    public boolean isValidActivityItems() {
 | 
				
			||||||
 | 
					        // 校验是否是活动订单
 | 
				
			||||||
 | 
					        if (seckillActivityId == null && combinationActivityId == null && combinationHeadId == null) {
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // 校验订单项是否超出
 | 
				
			||||||
 | 
					        return items.size() == 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Data
 | 
					    @Data
 | 
				
			||||||
    @Schema(description = "用户 App - 商品项")
 | 
					    @Schema(description = "用户 App - 商品项")
 | 
				
			||||||
@@ -70,7 +80,9 @@ public class AppTradeOrderSettlementReqVO {
 | 
				
			|||||||
    public static class Item {
 | 
					    public static class Item {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        @Schema(description = "商品 SKU 编号", example = "2048")
 | 
					        @Schema(description = "商品 SKU 编号", example = "2048")
 | 
				
			||||||
 | 
					        @NotNull(message = "商品 SKU 编号不能为空")
 | 
				
			||||||
        private Long skuId;
 | 
					        private Long skuId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        @Schema(description = "购买数量", example = "1")
 | 
					        @Schema(description = "购买数量", example = "1")
 | 
				
			||||||
        @Min(value = 1, message = "购买数量最小值为 {value}")
 | 
					        @Min(value = 1, message = "购买数量最小值为 {value}")
 | 
				
			||||||
        private Integer count;
 | 
					        private Integer count;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -93,6 +93,7 @@ public interface TradeOrderConvert {
 | 
				
			|||||||
                new ProductSkuUpdateStockReqDTO.Item().setId(item.getSkuId()).setIncrCount(item.getCount()));
 | 
					                new ProductSkuUpdateStockReqDTO.Item().setId(item.getSkuId()).setIncrCount(item.getCount()));
 | 
				
			||||||
        return new ProductSkuUpdateStockReqDTO(items);
 | 
					        return new ProductSkuUpdateStockReqDTO(items);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    default ProductSkuUpdateStockReqDTO convertNegative(List<AppTradeOrderSettlementReqVO.Item> list) {
 | 
					    default ProductSkuUpdateStockReqDTO convertNegative(List<AppTradeOrderSettlementReqVO.Item> list) {
 | 
				
			||||||
        List<ProductSkuUpdateStockReqDTO.Item> items = CollectionUtils.convertList(list, item ->
 | 
					        List<ProductSkuUpdateStockReqDTO.Item> items = CollectionUtils.convertList(list, item ->
 | 
				
			||||||
                new ProductSkuUpdateStockReqDTO.Item().setId(item.getSkuId()).setIncrCount(-item.getCount()));
 | 
					                new ProductSkuUpdateStockReqDTO.Item().setId(item.getSkuId()).setIncrCount(-item.getCount()));
 | 
				
			||||||
@@ -251,17 +252,6 @@ public interface TradeOrderConvert {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    AppTradeOrderSettlementRespVO convert0(TradePriceCalculateRespBO calculate, AddressRespDTO address);
 | 
					    AppTradeOrderSettlementRespVO convert0(TradePriceCalculateRespBO calculate, AddressRespDTO address);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Mappings({
 | 
					 | 
				
			||||||
            @Mapping(target = "activityId", source = "afterOrderCreateReqBO.combinationActivityId"),
 | 
					 | 
				
			||||||
            @Mapping(target = "spuId", source = "afterOrderCreateReqBO.spuId"),
 | 
					 | 
				
			||||||
            @Mapping(target = "skuId", source = "afterOrderCreateReqBO.skuId"),
 | 
					 | 
				
			||||||
            @Mapping(target = "orderId", source = "afterOrderCreateReqBO.orderId"),
 | 
					 | 
				
			||||||
            @Mapping(target = "userId", source = "afterOrderCreateReqBO.userId"),
 | 
					 | 
				
			||||||
            @Mapping(target = "headId", source = "afterOrderCreateReqBO.combinationHeadId"),
 | 
					 | 
				
			||||||
            @Mapping(target = "combinationPrice", source = "afterOrderCreateReqBO.payPrice"),
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
    CombinationRecordCreateReqDTO convert(TradeAfterOrderCreateReqBO afterOrderCreateReqBO);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    List<AppOrderExpressTrackRespDTO> convertList02(List<ExpressTrackRespDTO> list);
 | 
					    List<AppOrderExpressTrackRespDTO> convertList02(List<ExpressTrackRespDTO> list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    TradeOrderDO convert(TradeOrderUpdateAddressReqVO reqVO);
 | 
					    TradeOrderDO convert(TradeOrderUpdateAddressReqVO reqVO);
 | 
				
			||||||
@@ -282,18 +272,36 @@ public interface TradeOrderConvert {
 | 
				
			|||||||
        return bo;
 | 
					        return bo;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    TradeBeforeOrderCreateReqBO convert(AppTradeOrderCreateReqVO createReqVO);
 | 
					    @Mappings({
 | 
				
			||||||
 | 
					            @Mapping(target = "userId", source = "userId"),
 | 
				
			||||||
 | 
					            @Mapping(target = "orderType", source = "calculateRespBO.type"),
 | 
				
			||||||
 | 
					            @Mapping(target = "items", source = "createReqVO.items"),
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					    TradeBeforeOrderCreateReqBO convert(Long userId, AppTradeOrderCreateReqVO createReqVO, TradePriceCalculateRespBO calculateRespBO);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    List<TradeAfterOrderCreateReqBO.Item> convertList(List<TradeOrderItemDO> orderItems);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Mappings({
 | 
					    @Mappings({
 | 
				
			||||||
            @Mapping(target = "combinationActivityId", source = "createReqVO.combinationActivityId"),
 | 
					 | 
				
			||||||
            @Mapping(target = "combinationHeadId", source = "createReqVO.combinationHeadId"),
 | 
					 | 
				
			||||||
            @Mapping(target = "spuId", source = "orderItem.spuId"),
 | 
					 | 
				
			||||||
            @Mapping(target = "skuId", source = "orderItem.skuId"),
 | 
					 | 
				
			||||||
            @Mapping(target = "orderId", source = "tradeOrderDO.id"),
 | 
					 | 
				
			||||||
            @Mapping(target = "userId", source = "userId"),
 | 
					            @Mapping(target = "userId", source = "userId"),
 | 
				
			||||||
 | 
					            @Mapping(target = "orderId", source = "tradeOrderDO.id"),
 | 
				
			||||||
            @Mapping(target = "payPrice", source = "tradeOrderDO.payPrice"),
 | 
					            @Mapping(target = "payPrice", source = "tradeOrderDO.payPrice"),
 | 
				
			||||||
 | 
					            @Mapping(target = "items", source = "orderItems"),
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
    TradeAfterOrderCreateReqBO convert(Long userId, AppTradeOrderCreateReqVO createReqVO,
 | 
					    TradeAfterOrderCreateReqBO convert(Long userId, AppTradeOrderCreateReqVO createReqVO,
 | 
				
			||||||
                                       TradeOrderDO tradeOrderDO, TradeOrderItemDO orderItem);
 | 
					                                       TradeOrderDO tradeOrderDO, List<TradeOrderItemDO> orderItems);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Mappings({
 | 
				
			||||||
 | 
					            @Mapping(target = "activityId", source = "combinationActivityId"),
 | 
				
			||||||
 | 
					            @Mapping(target = "spuId", expression = "java(reqBO.getItems().get(0).getSpuId())"),
 | 
				
			||||||
 | 
					            @Mapping(target = "skuId", expression = "java(reqBO.getItems().get(0).getSkuId())"),// TODO 艿艿看看这里
 | 
				
			||||||
 | 
					            @Mapping(target = "count", expression = "java(reqBO.getItems().get(0).getCount())"),
 | 
				
			||||||
 | 
					            @Mapping(target = "orderId", source = "orderId"),
 | 
				
			||||||
 | 
					            @Mapping(target = "userId", source = "userId"),
 | 
				
			||||||
 | 
					            @Mapping(target = "headId", source = "combinationHeadId"),
 | 
				
			||||||
 | 
					            @Mapping(target = "combinationPrice", source = "payPrice")
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					    CombinationRecordCreateReqDTO convert(TradeAfterOrderCreateReqBO reqBO);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,12 +26,6 @@ public interface TradeOrderItemMapper extends BaseMapperX<TradeOrderItemDO> {
 | 
				
			|||||||
        return selectList(TradeOrderItemDO::getOrderId, orderIds);
 | 
					        return selectList(TradeOrderItemDO::getOrderId, orderIds);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    default List<TradeOrderItemDO> selectListByOrderIdAnSkuId(Collection<Long> orderIds, Collection<Long> skuIds) {
 | 
					 | 
				
			||||||
        return selectList(new LambdaQueryWrapperX<TradeOrderItemDO>()
 | 
					 | 
				
			||||||
                .in(TradeOrderItemDO::getOrderId, orderIds)
 | 
					 | 
				
			||||||
                .in(TradeOrderItemDO::getSkuId, skuIds));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    default TradeOrderItemDO selectByIdAndUserId(Long orderItemId, Long loginUserId) {
 | 
					    default TradeOrderItemDO selectByIdAndUserId(Long orderItemId, Long loginUserId) {
 | 
				
			||||||
        return selectOne(new LambdaQueryWrapperX<TradeOrderItemDO>()
 | 
					        return selectOne(new LambdaQueryWrapperX<TradeOrderItemDO>()
 | 
				
			||||||
                .eq(TradeOrderItemDO::getId, orderItemId)
 | 
					                .eq(TradeOrderItemDO::getId, orderItemId)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -119,13 +119,5 @@ public interface TradeOrderQueryService {
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    List<TradeOrderItemDO> getOrderItemListByOrderId(Collection<Long> orderIds);
 | 
					    List<TradeOrderItemDO> getOrderItemListByOrderId(Collection<Long> orderIds);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * 获取订单项商品购买数量总和
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @param orderIds 订单编号
 | 
					 | 
				
			||||||
     * @param skuIds   sku 编号
 | 
					 | 
				
			||||||
     * @return 订单项商品购买数量总和
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    Integer getOrderItemCountSumByOrderIdAndSkuId(Collection<Long> orderIds, Collection<Long> skuIds);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,6 @@ import cn.hutool.core.collection.CollUtil;
 | 
				
			|||||||
import cn.hutool.core.util.ObjectUtil;
 | 
					import cn.hutool.core.util.ObjectUtil;
 | 
				
			||||||
import cn.hutool.core.util.StrUtil;
 | 
					import cn.hutool.core.util.StrUtil;
 | 
				
			||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
 | 
					import cn.iocoder.yudao.framework.common.pojo.PageResult;
 | 
				
			||||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 | 
					 | 
				
			||||||
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
 | 
					import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
 | 
				
			||||||
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
 | 
					import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
 | 
				
			||||||
import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageReqVO;
 | 
					import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageReqVO;
 | 
				
			||||||
@@ -168,10 +167,4 @@ public class TradeOrderQueryServiceImpl implements TradeOrderQueryService {
 | 
				
			|||||||
        return tradeOrderItemMapper.selectListByOrderId(orderIds);
 | 
					        return tradeOrderItemMapper.selectListByOrderId(orderIds);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					 | 
				
			||||||
    public Integer getOrderItemCountSumByOrderIdAndSkuId(Collection<Long> orderIds, Collection<Long> skuIds) {
 | 
					 | 
				
			||||||
        List<TradeOrderItemDO> tradeOrderItems = tradeOrderItemMapper.selectListByOrderIdAnSkuId(orderIds, skuIds);
 | 
					 | 
				
			||||||
        return CollectionUtils.getSumValue(tradeOrderItems, TradeOrderItemDO::getCount, Integer::sum);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -60,7 +60,6 @@ import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService;
 | 
				
			|||||||
import cn.iocoder.yudao.module.trade.service.message.TradeMessageService;
 | 
					import cn.iocoder.yudao.module.trade.service.message.TradeMessageService;
 | 
				
			||||||
import cn.iocoder.yudao.module.trade.service.message.bo.TradeOrderMessageWhenDeliveryOrderReqBO;
 | 
					import cn.iocoder.yudao.module.trade.service.message.bo.TradeOrderMessageWhenDeliveryOrderReqBO;
 | 
				
			||||||
import cn.iocoder.yudao.module.trade.service.order.bo.TradeAfterPayOrderReqBO;
 | 
					import cn.iocoder.yudao.module.trade.service.order.bo.TradeAfterPayOrderReqBO;
 | 
				
			||||||
import cn.iocoder.yudao.module.trade.service.order.bo.TradeBeforeOrderCreateReqBO;
 | 
					 | 
				
			||||||
import cn.iocoder.yudao.module.trade.service.order.handler.TradeOrderHandler;
 | 
					import cn.iocoder.yudao.module.trade.service.order.handler.TradeOrderHandler;
 | 
				
			||||||
import cn.iocoder.yudao.module.trade.service.price.TradePriceService;
 | 
					import cn.iocoder.yudao.module.trade.service.price.TradePriceService;
 | 
				
			||||||
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
 | 
					import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
 | 
				
			||||||
@@ -254,12 +253,9 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
 | 
				
			|||||||
    private void beforeCreateTradeOrder(Long userId, AppTradeOrderCreateReqVO createReqVO,
 | 
					    private void beforeCreateTradeOrder(Long userId, AppTradeOrderCreateReqVO createReqVO,
 | 
				
			||||||
                                        TradePriceCalculateRespBO calculateRespBO) {
 | 
					                                        TradePriceCalculateRespBO calculateRespBO) {
 | 
				
			||||||
        // 1. 执行订单创建前置处理器
 | 
					        // 1. 执行订单创建前置处理器
 | 
				
			||||||
        TradeBeforeOrderCreateReqBO beforeOrderCreateReqBO = TradeOrderConvert.INSTANCE.convert(createReqVO);
 | 
					 | 
				
			||||||
        beforeOrderCreateReqBO.setOrderType(calculateRespBO.getType());
 | 
					 | 
				
			||||||
        beforeOrderCreateReqBO.setUserId(userId);
 | 
					 | 
				
			||||||
        beforeOrderCreateReqBO.setCount(getSumValue(createReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCount, Integer::sum));
 | 
					 | 
				
			||||||
        // TODO @puhui999:这里有个纠结点;handler 的定义是只处理指定类型的订单的拓展逻辑;还是通用的 handler,类似可以处理优惠劵等等
 | 
					        // TODO @puhui999:这里有个纠结点;handler 的定义是只处理指定类型的订单的拓展逻辑;还是通用的 handler,类似可以处理优惠劵等等
 | 
				
			||||||
        tradeOrderHandlers.forEach(handler -> handler.beforeOrderCreate(beforeOrderCreateReqBO));
 | 
					        tradeOrderHandlers.forEach(handler ->
 | 
				
			||||||
 | 
					                handler.beforeOrderCreate(TradeOrderConvert.INSTANCE.convert(userId, createReqVO, calculateRespBO)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // 2. 下单时扣减商品库存
 | 
					        // 2. 下单时扣减商品库存
 | 
				
			||||||
        productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convertNegative(createReqVO.getItems()));
 | 
					        productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convertNegative(createReqVO.getItems()));
 | 
				
			||||||
@@ -279,9 +275,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
 | 
				
			|||||||
                                       TradeOrderDO order, List<TradeOrderItemDO> orderItems,
 | 
					                                       TradeOrderDO order, List<TradeOrderItemDO> orderItems,
 | 
				
			||||||
                                       TradePriceCalculateRespBO calculateRespBO) {
 | 
					                                       TradePriceCalculateRespBO calculateRespBO) {
 | 
				
			||||||
        // 1. 执行订单创建后置处理器
 | 
					        // 1. 执行订单创建后置处理器
 | 
				
			||||||
        // TODO @puhui999:从通用性来说,应该不用 orderItems.get(0)
 | 
					 | 
				
			||||||
        tradeOrderHandlers.forEach(handler -> handler.afterOrderCreate(
 | 
					        tradeOrderHandlers.forEach(handler -> handler.afterOrderCreate(
 | 
				
			||||||
                TradeOrderConvert.INSTANCE.convert(userId, createReqVO, order, orderItems.get(0))));
 | 
					                TradeOrderConvert.INSTANCE.convert(userId, createReqVO, order, orderItems)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // 2. 有使用优惠券时更新
 | 
					        // 2. 有使用优惠券时更新
 | 
				
			||||||
        // 不在前置扣减的原因,是因为优惠劵要记录使用的订单号
 | 
					        // 不在前置扣减的原因,是因为优惠劵要记录使用的订单号
 | 
				
			||||||
@@ -467,14 +462,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
 | 
				
			|||||||
                throw exception(ORDER_DELIVERY_FAIL_COMBINATION_RECORD_STATUS_NOT_SUCCESS);
 | 
					                throw exception(ORDER_DELIVERY_FAIL_COMBINATION_RECORD_STATUS_NOT_SUCCESS);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        // 订单类类型:砍价
 | 
					
 | 
				
			||||||
        if (Objects.equals(TradeOrderTypeEnum.BARGAIN.getType(), order.getType())) {
 | 
					 | 
				
			||||||
            // 校验订单砍价是否成功
 | 
					 | 
				
			||||||
            // TODO @puhui999:砍价的话,应该不用校验。因为是砍价成功后,才可以下单
 | 
					 | 
				
			||||||
            if (!bargainRecordApi.isBargainRecordSuccess(order.getUserId(), order.getId())) {
 | 
					 | 
				
			||||||
                throw exception(ORDER_DELIVERY_FAIL_BARGAIN_RECORD_STATUS_NOT_SUCCESS);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return order;
 | 
					        return order;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -641,8 +629,6 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // 2. TODO 活动相关库存回滚需要活动 id,活动 id 怎么获取?app 端能否传过来;回复:从订单里拿呀
 | 
					        // 2. TODO 活动相关库存回滚需要活动 id,活动 id 怎么获取?app 端能否传过来;回复:从订单里拿呀
 | 
				
			||||||
        tradeOrderHandlers.forEach(handler -> handler.rollback());
 | 
					 | 
				
			||||||
        // 3. TODO 活动相关库存回滚需要活动 id,活动 id 怎么获取?app 端能否传过来;回复:从订单里拿呀
 | 
					 | 
				
			||||||
        tradeOrderHandlers.forEach(handler -> handler.cancelOrder());
 | 
					        tradeOrderHandlers.forEach(handler -> handler.cancelOrder());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // 3. 回滚库存
 | 
					        // 3. 回滚库存
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,10 @@
 | 
				
			|||||||
package cn.iocoder.yudao.module.trade.service.order.bo;
 | 
					package cn.iocoder.yudao.module.trade.service.order.bo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import io.swagger.v3.oas.annotations.media.Schema;
 | 
					 | 
				
			||||||
import lombok.Data;
 | 
					import lombok.Data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import javax.validation.Valid;
 | 
				
			||||||
import javax.validation.constraints.NotNull;
 | 
					import javax.validation.constraints.NotNull;
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TODO 芋艿:在想想这些参数的定义
 | 
					// TODO 芋艿:在想想这些参数的定义
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@@ -16,25 +17,71 @@ public class TradeAfterOrderCreateReqBO {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // ========== 拼团活动相关字段 ==========
 | 
					    // ========== 拼团活动相关字段 ==========
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Schema(description = "拼团活动编号", example = "1024")
 | 
					    /**
 | 
				
			||||||
 | 
					     * 拼团活动编号
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    private Long combinationActivityId;
 | 
					    private Long combinationActivityId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Schema(description = "拼团团长编号", example = "2048")
 | 
					    /**
 | 
				
			||||||
 | 
					     * 拼团团长编号
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    private Long combinationHeadId;
 | 
					    private Long combinationHeadId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @NotNull(message = "SPU 编号不能为空")
 | 
					    /**
 | 
				
			||||||
    private Long spuId;
 | 
					     * 订单编号
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    @NotNull(message = "SKU 编号活动商品不能为空")
 | 
					 | 
				
			||||||
    private Long skuId;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @NotNull(message = "订单编号不能为空")
 | 
					    @NotNull(message = "订单编号不能为空")
 | 
				
			||||||
    private Long orderId;
 | 
					    private Long orderId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 用户编号
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    @NotNull(message = "用户编号不能为空")
 | 
					    @NotNull(message = "用户编号不能为空")
 | 
				
			||||||
    private Long userId;
 | 
					    private Long userId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 支付金额
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    @NotNull(message = "支付金额不能为空")
 | 
					    @NotNull(message = "支付金额不能为空")
 | 
				
			||||||
    private Integer payPrice;
 | 
					    private Integer payPrice;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // ========== 购买商品相关字段 ==========
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 订单购买的商品信息
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private List<Item> items;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 订单商品信息
 | 
				
			||||||
 | 
					     * 记录购买商品的简要核心信息
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @author HUIHUI
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    @Data
 | 
				
			||||||
 | 
					    @Valid
 | 
				
			||||||
 | 
					    public static class Item {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * SPU 编号
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        @NotNull(message = "SPU 编号不能为空")
 | 
				
			||||||
 | 
					        private Long spuId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * 商品 SKU 编号
 | 
				
			||||||
 | 
					         *
 | 
				
			||||||
 | 
					         * 关联 ProductSkuDO 的 id 编号
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        @NotNull(message = "SKU 编号活动商品不能为空")
 | 
				
			||||||
 | 
					        private Long skuId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * 购买的商品数量
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        @NotNull(message = "购买数量不能为空")
 | 
				
			||||||
 | 
					        private Integer count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,12 +1,13 @@
 | 
				
			|||||||
package cn.iocoder.yudao.module.trade.service.order.bo;
 | 
					package cn.iocoder.yudao.module.trade.service.order.bo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
 | 
					import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
 | 
				
			||||||
import io.swagger.v3.oas.annotations.media.Schema;
 | 
					 | 
				
			||||||
import lombok.Data;
 | 
					import lombok.Data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import javax.validation.Valid;
 | 
				
			||||||
import javax.validation.constraints.NotNull;
 | 
					import javax.validation.constraints.NotNull;
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
// TODO 芋艿:在想想这些参数的定义
 | 
					// TODO 芋艿:在想想这些参数的定义
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * 订单创建之前 Request BO
 | 
					 * 订单创建之前 Request BO
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@@ -34,9 +35,8 @@ public class TradeBeforeOrderCreateReqBO {
 | 
				
			|||||||
    // ========== 秒杀活动相关字段 ==========
 | 
					    // ========== 秒杀活动相关字段 ==========
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     *
 | 
					     * 秒杀活动编号
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    @Schema(description = "秒杀活动编号", example = "1024")
 | 
					 | 
				
			||||||
    private Long seckillActivityId;
 | 
					    private Long seckillActivityId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // ========== 拼团活动相关字段 ==========
 | 
					    // ========== 拼团活动相关字段 ==========
 | 
				
			||||||
@@ -44,13 +44,11 @@ public class TradeBeforeOrderCreateReqBO {
 | 
				
			|||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 拼团活动编号
 | 
					     * 拼团活动编号
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    @Schema(description = "拼团活动编号", example = "1024")
 | 
					 | 
				
			||||||
    private Long combinationActivityId;
 | 
					    private Long combinationActivityId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 拼团团长编号
 | 
					     * 拼团团长编号
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    @Schema(description = "拼团团长编号", example = "2048")
 | 
					 | 
				
			||||||
    private Long combinationHeadId;
 | 
					    private Long combinationHeadId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // ========== 砍价活动相关字段 ==========
 | 
					    // ========== 砍价活动相关字段 ==========
 | 
				
			||||||
@@ -58,31 +56,39 @@ public class TradeBeforeOrderCreateReqBO {
 | 
				
			|||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 砍价活动编号
 | 
					     * 砍价活动编号
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    @Schema(description = "砍价活动编号", example = "123")
 | 
					 | 
				
			||||||
    private Long bargainActivityId;
 | 
					    private Long bargainActivityId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // ========== 活动购买商品相关字段 ==========
 | 
					    // ========== 购买商品相关字段 ==========
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 商品 SPU 编号
 | 
					     * 订单购买的商品信息
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private List<Item> items;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 订单商品信息
 | 
				
			||||||
 | 
					     * 记录购买商品的简要核心信息
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * 关联 ProductSkuDO 的 spuId 编号
 | 
					     * @author HUIHUI
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    @NotNull(message = "SPU 编号不能为空")
 | 
					    @Data
 | 
				
			||||||
    private Long spuId;
 | 
					    @Valid
 | 
				
			||||||
 | 
					    public static class Item {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					        /**
 | 
				
			||||||
     * 商品 SKU 编号
 | 
					         * 商品 SKU 编号
 | 
				
			||||||
     *
 | 
					         *
 | 
				
			||||||
     * 关联 ProductSkuDO 的 id 编号
 | 
					         * 关联 ProductSkuDO 的 id 编号
 | 
				
			||||||
     */
 | 
					         */
 | 
				
			||||||
    @NotNull(message = "SKU 编号活动商品不能为空")
 | 
					        @NotNull(message = "SKU 编号活动商品不能为空")
 | 
				
			||||||
    private Long skuId;
 | 
					        private Long skuId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					        /**
 | 
				
			||||||
     * 购买的商品数量
 | 
					         * 购买的商品数量
 | 
				
			||||||
     */
 | 
					         */
 | 
				
			||||||
    @NotNull(message = "购买数量不能为空")
 | 
					        @NotNull(message = "购买数量不能为空")
 | 
				
			||||||
    private Integer count;
 | 
					        private Integer count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,8 +29,11 @@ public class TradeBargainHandler extends TradeOrderDefaultHandler {
 | 
				
			|||||||
        if (ObjectUtil.notEqual(TradeOrderTypeEnum.BARGAIN.getType(), reqBO.getOrderType())) {
 | 
					        if (ObjectUtil.notEqual(TradeOrderTypeEnum.BARGAIN.getType(), reqBO.getOrderType())) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 获取商品信息
 | 
				
			||||||
 | 
					        TradeBeforeOrderCreateReqBO.Item item = reqBO.getItems().get(0);
 | 
				
			||||||
        // 扣减砍价活动的库存
 | 
					        // 扣减砍价活动的库存
 | 
				
			||||||
        bargainActivityApi.updateBargainActivityStock(reqBO.getBargainActivityId(), reqBO.getCount());
 | 
					        bargainActivityApi.updateBargainActivityStock(reqBO.getBargainActivityId(), item.getCount());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,8 +29,10 @@ public class TradeCombinationHandler extends TradeOrderDefaultHandler {
 | 
				
			|||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 获取商品信息
 | 
				
			||||||
 | 
					        TradeBeforeOrderCreateReqBO.Item item = reqBO.getItems().get(0);
 | 
				
			||||||
        // 校验是否满足拼团活动相关限制
 | 
					        // 校验是否满足拼团活动相关限制
 | 
				
			||||||
        combinationRecordApi.validateCombinationRecord(reqBO.getCombinationActivityId(), reqBO.getUserId(), reqBO.getSkuId(), reqBO.getCount());
 | 
					        combinationRecordApi.validateCombinationRecord(reqBO.getCombinationActivityId(), reqBO.getUserId(), item.getSkuId(), item.getCount());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,8 +29,11 @@ public class TradeSeckillHandler extends TradeOrderDefaultHandler {
 | 
				
			|||||||
        if (ObjectUtil.notEqual(TradeOrderTypeEnum.SECKILL.getType(), reqBO.getOrderType())) {
 | 
					        if (ObjectUtil.notEqual(TradeOrderTypeEnum.SECKILL.getType(), reqBO.getOrderType())) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 获取商品信息
 | 
				
			||||||
 | 
					        TradeBeforeOrderCreateReqBO.Item item = reqBO.getItems().get(0);
 | 
				
			||||||
        // 扣减秒杀活动的库存
 | 
					        // 扣减秒杀活动的库存
 | 
				
			||||||
        seckillActivityApi.updateSeckillStock(reqBO.getSeckillActivityId(), reqBO.getSkuId(), reqBO.getCount());
 | 
					        seckillActivityApi.updateSeckillStock(reqBO.getSeckillActivityId(), item.getSkuId(), item.getCount());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user