trade:1、重构 order handler 的参数;2、增加砍价商品的价格计算
This commit is contained in:
parent
dc1347184f
commit
8dbabb9efc
|
@ -1,6 +1,7 @@
|
||||||
package cn.iocoder.yudao.module.promotion.api.bargain;
|
package cn.iocoder.yudao.module.promotion.api.bargain;
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.promotion.api.bargain.dto.BargainRecordCreateReqDTO;
|
import cn.iocoder.yudao.module.promotion.api.bargain.dto.BargainRecordCreateReqDTO;
|
||||||
|
import cn.iocoder.yudao.module.promotion.api.bargain.dto.BargainValidateJoinRespDTO;
|
||||||
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
|
||||||
|
@ -20,4 +21,16 @@ public interface BargainRecordApi {
|
||||||
*/
|
*/
|
||||||
void createBargainRecord(@Valid BargainRecordCreateReqDTO reqDTO);
|
void createBargainRecord(@Valid BargainRecordCreateReqDTO reqDTO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【下单前】校验是否参与砍价活动
|
||||||
|
* <p>
|
||||||
|
* 如果校验失败,则抛出业务异常
|
||||||
|
*
|
||||||
|
* @param userId 用户编号
|
||||||
|
* @param bargainRecordId 砍价活动编号
|
||||||
|
* @param skuId SKU 编号
|
||||||
|
* @return 砍价信息
|
||||||
|
*/
|
||||||
|
BargainValidateJoinRespDTO validateJoinBargain(Long userId, Long bargainRecordId, Long skuId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,7 @@ public class BargainRecordCreateReqDTO {
|
||||||
@NotNull(message = "商品原价不能为空")
|
@NotNull(message = "商品原价不能为空")
|
||||||
private Integer price;
|
private Integer price;
|
||||||
|
|
||||||
|
// TODO @puhui999:创建时,这个参数不应该传递哈;
|
||||||
/**
|
/**
|
||||||
* 开团状态:进行中 砍价成功 砍价失败
|
* 开团状态:进行中 砍价成功 砍价失败
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package cn.iocoder.yudao.module.promotion.api.bargain.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验参与砍价 Response DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class BargainValidateJoinRespDTO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 砍价活动编号
|
||||||
|
*/
|
||||||
|
private Long activityId;
|
||||||
|
/**
|
||||||
|
* 砍价活动名称
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 砍价金额
|
||||||
|
*/
|
||||||
|
private Integer bargainPrice;
|
||||||
|
|
||||||
|
}
|
|
@ -19,13 +19,14 @@ public interface SeckillActivityApi {
|
||||||
void updateSeckillStock(Long id, Long skuId, Integer count);
|
void updateSeckillStock(Long id, Long skuId, Integer count);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验是否参与秒杀商品
|
* 【下单前】校验是否参与秒杀活动
|
||||||
*
|
*
|
||||||
* 如果校验失败,则抛出业务异常
|
* 如果校验失败,则抛出业务异常
|
||||||
*
|
*
|
||||||
* @param activityId 活动编号
|
* @param activityId 活动编号
|
||||||
* @param skuId SKU 编号
|
* @param skuId SKU 编号
|
||||||
* @param count 数量
|
* @param count 数量
|
||||||
|
* @return 秒杀信息
|
||||||
*/
|
*/
|
||||||
SeckillValidateJoinRespDTO validateJoinSeckill(Long activityId, Long skuId, Integer count);
|
SeckillValidateJoinRespDTO validateJoinSeckill(Long activityId, Long skuId, Integer count);
|
||||||
|
|
||||||
|
|
|
@ -97,5 +97,8 @@ public interface ErrorCodeConstants {
|
||||||
ErrorCode BARGAIN_RECORD_EXISTS = new ErrorCode(1_013_013_001, "砍价失败,已参与过该砍价");
|
ErrorCode BARGAIN_RECORD_EXISTS = new ErrorCode(1_013_013_001, "砍价失败,已参与过该砍价");
|
||||||
ErrorCode BARGAIN_RECORD_HEAD_NOT_EXISTS = new ErrorCode(1_013_013_002, "砍价失败,父砍价不存在");
|
ErrorCode BARGAIN_RECORD_HEAD_NOT_EXISTS = new ErrorCode(1_013_013_002, "砍价失败,父砍价不存在");
|
||||||
ErrorCode BARGAIN_RECORD_USER_FULL = new ErrorCode(1_013_013_003, "砍价失败,砍价人数已满");
|
ErrorCode BARGAIN_RECORD_USER_FULL = new ErrorCode(1_013_013_003, "砍价失败,砍价人数已满");
|
||||||
|
ErrorCode BARGAIN_JOIN_RECORD_NOT_IN_PROGRESS = new ErrorCode(1_013_013_004, "砍价失败,砍价记录不在进行中");
|
||||||
|
ErrorCode BARGAIN_JOIN_FAILED_ACTIVITY_TIME_END = new ErrorCode(1_013_013_005, "砍价失败,活动已经结束");
|
||||||
|
ErrorCode BARGAIN_JOIN_ACTIVITY_STATUS_CLOSED = new ErrorCode(1_013_013_006, "砍价失败,原因:砍价活动已关闭");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
package cn.iocoder.yudao.module.promotion.enums.bargain;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 砍价记录的状态枚举
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Getter
|
||||||
|
public enum BargainRecordStatusEnum implements IntArrayValuable {
|
||||||
|
|
||||||
|
IN_PROGRESS(1, "砍价中"),
|
||||||
|
SUCCESS(2, "砍价成功"),
|
||||||
|
FAILED(3, "砍价失败"),
|
||||||
|
;
|
||||||
|
|
||||||
|
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BargainRecordStatusEnum::getStatus).toArray();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 值
|
||||||
|
*/
|
||||||
|
private final Integer status;
|
||||||
|
/**
|
||||||
|
* 名字
|
||||||
|
*/
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int[] array() {
|
||||||
|
return ARRAYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -16,8 +16,8 @@ import java.util.Arrays;
|
||||||
public enum PromotionTypeEnum implements IntArrayValuable {
|
public enum PromotionTypeEnum implements IntArrayValuable {
|
||||||
|
|
||||||
SECKILL_ACTIVITY(1, "秒杀活动"),
|
SECKILL_ACTIVITY(1, "秒杀活动"),
|
||||||
BARGAIN_ACTIVITY(2, "拼团活动"),
|
BARGAIN_ACTIVITY(2, "砍价活动"),
|
||||||
COMBINATION_ACTIVITY(3, "砍价活动"),
|
COMBINATION_ACTIVITY(3, "拼团活动"),
|
||||||
|
|
||||||
DISCOUNT_ACTIVITY(4, "限时折扣"),
|
DISCOUNT_ACTIVITY(4, "限时折扣"),
|
||||||
REWARD_ACTIVITY(5, "满减送"),
|
REWARD_ACTIVITY(5, "满减送"),
|
||||||
|
|
|
@ -1,19 +1,30 @@
|
||||||
package cn.iocoder.yudao.module.promotion.api.bargain;
|
package cn.iocoder.yudao.module.promotion.api.bargain;
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.promotion.api.bargain.dto.BargainRecordCreateReqDTO;
|
import cn.iocoder.yudao.module.promotion.api.bargain.dto.BargainRecordCreateReqDTO;
|
||||||
|
import cn.iocoder.yudao.module.promotion.api.bargain.dto.BargainValidateJoinRespDTO;
|
||||||
|
import cn.iocoder.yudao.module.promotion.service.bargain.BargainRecordService;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 砍价活动 API 实现类 TODO @puhui999
|
* 砍价活动 API 实现类
|
||||||
*
|
*
|
||||||
* @author HUIHUI
|
* @author HUIHUI
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class BargainRecordApiImpl implements BargainRecordApi {
|
public class BargainRecordApiImpl implements BargainRecordApi {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private BargainRecordService bargainRecordService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createBargainRecord(BargainRecordCreateReqDTO reqDTO) {
|
public void createBargainRecord(BargainRecordCreateReqDTO reqDTO) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BargainValidateJoinRespDTO validateJoinBargain(Long userId, Long bargainRecordId, Long skuId) {
|
||||||
|
return bargainRecordService.validateJoinBargain(userId, bargainRecordId, skuId);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package cn.iocoder.yudao.module.promotion.dal.dataobject.bargain;
|
package cn.iocoder.yudao.module.promotion.dal.dataobject.bargain;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
|
import cn.iocoder.yudao.module.promotion.enums.bargain.BargainRecordStatusEnum;
|
||||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
@ -43,7 +44,6 @@ public class BargainRecordDO extends BaseDO {
|
||||||
* 商品 SPU 编号
|
* 商品 SPU 编号
|
||||||
*/
|
*/
|
||||||
private Long spuId;
|
private Long spuId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 商品 SKU 编号
|
* 商品 SKU 编号
|
||||||
*/
|
*/
|
||||||
|
@ -53,19 +53,19 @@ public class BargainRecordDO extends BaseDO {
|
||||||
* 砍价底价,单位分
|
* 砍价底价,单位分
|
||||||
*/
|
*/
|
||||||
private Integer bargainPrice;
|
private Integer bargainPrice;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 商品原价,单位分
|
* 商品原价,单位分
|
||||||
*/
|
*/
|
||||||
private Integer price;
|
private Integer price;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 应付金额,单位分
|
* 应付金额,单位分
|
||||||
*/
|
*/
|
||||||
private Integer payPrice;
|
private Integer payPrice;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 状态1 - 砍价中;2- 砍价成功;3 - 砍价失败
|
* 砍价状态
|
||||||
|
*
|
||||||
|
* 枚举 {@link BargainRecordStatusEnum}
|
||||||
*/
|
*/
|
||||||
private Integer status;
|
private Integer status;
|
||||||
|
|
||||||
|
@ -81,7 +81,9 @@ public class BargainRecordDO extends BaseDO {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 过期时间
|
* 过期时间
|
||||||
|
*
|
||||||
|
* 到达该时间时,其他用户无法帮助砍价,但是还是允许下单
|
||||||
*/
|
*/
|
||||||
private Data expireTime;
|
private LocalDateTime expireTime;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,4 +12,9 @@ import org.apache.ibatis.annotations.Mapper;
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface BargainRecordMapper extends BaseMapperX<BargainRecordDO> {
|
public interface BargainRecordMapper extends BaseMapperX<BargainRecordDO> {
|
||||||
|
|
||||||
|
default BargainRecordDO selectByIdAndUserId(Long id, Long userId) {
|
||||||
|
return selectOne(BargainRecordDO::getId, id,
|
||||||
|
BargainRecordDO::getUserId, userId);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package cn.iocoder.yudao.module.promotion.service.bargain;
|
package cn.iocoder.yudao.module.promotion.service.bargain;
|
||||||
|
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.promotion.api.bargain.dto.BargainValidateJoinRespDTO;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 砍价记录 service 接口
|
* 砍价记录 service 接口
|
||||||
*
|
*
|
||||||
|
@ -8,6 +10,16 @@ package cn.iocoder.yudao.module.promotion.service.bargain;
|
||||||
*/
|
*/
|
||||||
public interface BargainRecordService {
|
public interface BargainRecordService {
|
||||||
|
|
||||||
// TODO
|
/**
|
||||||
|
* 【下单前】校验是否参与砍价活动
|
||||||
|
* <p>
|
||||||
|
* 如果校验失败,则抛出业务异常
|
||||||
|
*
|
||||||
|
* @param userId 用户编号
|
||||||
|
* @param bargainRecordId 砍价活动编号
|
||||||
|
* @param skuId SKU 编号
|
||||||
|
* @return 砍价信息
|
||||||
|
*/
|
||||||
|
BargainValidateJoinRespDTO validateJoinBargain(Long userId, Long bargainRecordId, Long skuId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,24 @@
|
||||||
package cn.iocoder.yudao.module.promotion.service.bargain;
|
package cn.iocoder.yudao.module.promotion.service.bargain;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Assert;
|
||||||
|
import cn.hutool.core.util.ObjUtil;
|
||||||
|
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
|
||||||
|
import cn.iocoder.yudao.module.promotion.api.bargain.dto.BargainValidateJoinRespDTO;
|
||||||
|
import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO;
|
||||||
|
import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainRecordDO;
|
||||||
|
import cn.iocoder.yudao.module.promotion.dal.mysql.bargain.BargainRecordMapper;
|
||||||
|
import cn.iocoder.yudao.module.promotion.enums.bargain.BargainRecordStatusEnum;
|
||||||
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 java.util.Objects;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
|
import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 砍价记录 Service 实现类
|
* 砍价记录 Service 实现类
|
||||||
*
|
*
|
||||||
|
@ -11,4 +27,46 @@ import org.springframework.validation.annotation.Validated;
|
||||||
@Service
|
@Service
|
||||||
@Validated
|
@Validated
|
||||||
public class BargainRecordServiceImpl implements BargainRecordService {
|
public class BargainRecordServiceImpl implements BargainRecordService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private BargainActivityService bargainActivityService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private BargainRecordMapper bargainRecordMapper;
|
||||||
|
|
||||||
|
// TODO puhui999:create 时,需要校验下限购数量;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BargainValidateJoinRespDTO validateJoinBargain(Long userId, Long bargainRecordId, Long skuId) {
|
||||||
|
// 1.1 拼团记录不存在
|
||||||
|
BargainRecordDO record = bargainRecordMapper.selectByIdAndUserId(bargainRecordId, userId);
|
||||||
|
if (record == null) {
|
||||||
|
throw exception(BARGAIN_RECORD_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
// 1.2 拼团记录未在进行中
|
||||||
|
if (ObjUtil.notEqual(record.getStatus(), BargainRecordStatusEnum.IN_PROGRESS)) {
|
||||||
|
throw exception(BARGAIN_JOIN_RECORD_NOT_IN_PROGRESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2.1 砍价活动不存在
|
||||||
|
BargainActivityDO activity = bargainActivityService.getBargainActivity(record.getActivityId());
|
||||||
|
if (activity == null) {
|
||||||
|
throw exception(BARGAIN_ACTIVITY_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
if (ObjUtil.notEqual(activity.getStatus(), CommonStatusEnum.ENABLE.getStatus())) {
|
||||||
|
throw exception(BARGAIN_JOIN_ACTIVITY_STATUS_CLOSED);
|
||||||
|
}
|
||||||
|
Assert.isTrue(Objects.equals(skuId, activity.getSkuId()), "砍价商品不匹配"); // 防御性校验
|
||||||
|
// 2.2 活动已过期
|
||||||
|
if (LocalDateTimeUtils.isBetween(activity.getStartTime(), activity.getEndTime())) {
|
||||||
|
throw exception(BARGAIN_JOIN_FAILED_ACTIVITY_TIME_END);
|
||||||
|
}
|
||||||
|
// 2.3 库存不足
|
||||||
|
if (activity.getStock() <= 0) {
|
||||||
|
throw exception(BARGAIN_ACTIVITY_UPDATE_STOCK_FAIL);
|
||||||
|
}
|
||||||
|
return new BargainValidateJoinRespDTO().setActivityId(activity.getId()).setName(activity.getName())
|
||||||
|
.setBargainPrice(record.getPayPrice());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,15 +107,6 @@ public interface SeckillActivityService {
|
||||||
*/
|
*/
|
||||||
PageResult<SeckillActivityDO> getSeckillActivityAppPageByConfigId(AppSeckillActivityPageReqVO pageReqVO);
|
PageResult<SeckillActivityDO> getSeckillActivityAppPageByConfigId(AppSeckillActivityPageReqVO pageReqVO);
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取秒杀活动商品信息
|
|
||||||
*
|
|
||||||
* @param id 活动编号
|
|
||||||
* @param skuIds sku 编号
|
|
||||||
* @return 秒杀活动商品信息列表
|
|
||||||
*/
|
|
||||||
List<SeckillProductDO> getSeckillActivityProductList(Long id, Collection<Long> skuIds);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验是否参与秒杀商品
|
* 校验是否参与秒杀商品
|
||||||
*
|
*
|
||||||
|
@ -124,6 +115,7 @@ public interface SeckillActivityService {
|
||||||
* @param activityId 活动编号
|
* @param activityId 活动编号
|
||||||
* @param skuId SKU 编号
|
* @param skuId SKU 编号
|
||||||
* @param count 数量
|
* @param count 数量
|
||||||
|
* @return 秒杀信息
|
||||||
*/
|
*/
|
||||||
SeckillValidateJoinRespDTO validateJoinSeckill(Long activityId, Long skuId, Integer count);
|
SeckillValidateJoinRespDTO validateJoinSeckill(Long activityId, Long skuId, Integer count);
|
||||||
|
|
||||||
|
|
|
@ -278,18 +278,6 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
|
||||||
return seckillActivityMapper.selectPage(pageReqVO, CommonStatusEnum.ENABLE.getStatus());
|
return seckillActivityMapper.selectPage(pageReqVO, CommonStatusEnum.ENABLE.getStatus());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<SeckillProductDO> getSeckillActivityProductList(Long id, Collection<Long> skuIds) {
|
|
||||||
|
|
||||||
// 2、校验活动商品是否存在
|
|
||||||
List<SeckillProductDO> productList = filterList(seckillProductMapper.selectListByActivityId(id),
|
|
||||||
item -> skuIds.contains(item.getSkuId()));
|
|
||||||
if (CollectionUtil.isEmpty(productList)) {
|
|
||||||
throw exception(SKU_NOT_EXISTS);
|
|
||||||
}
|
|
||||||
return productList;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SeckillValidateJoinRespDTO validateJoinSeckill(Long activityId, Long skuId, Integer count) {
|
public SeckillValidateJoinRespDTO validateJoinSeckill(Long activityId, Long skuId, Integer count) {
|
||||||
// 1.1 校验秒杀活动是否存在
|
// 1.1 校验秒杀活动是否存在
|
||||||
|
|
|
@ -60,15 +60,14 @@ public class AppTradeOrderSettlementReqVO {
|
||||||
private Long combinationHeadId;
|
private Long combinationHeadId;
|
||||||
|
|
||||||
// ========== 砍价活动相关字段 ==========
|
// ========== 砍价活动相关字段 ==========
|
||||||
// TODO @puhui999:是不是砍价记录的编号哈?
|
@Schema(description = "砍价记录编号", example = "123")
|
||||||
@Schema(description = "砍价活动编号", example = "123")
|
private Long bargainRecordId;
|
||||||
private Long bargainActivityId;
|
|
||||||
|
|
||||||
@AssertTrue(message = "活动商品每次只能购买一种规格")
|
@AssertTrue(message = "活动商品每次只能购买一种规格")
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
public boolean isValidActivityItems() {
|
public boolean isValidActivityItems() {
|
||||||
// 校验是否是活动订单
|
// 校验是否是活动订单
|
||||||
if (ObjUtil.isAllEmpty(seckillActivityId, combinationActivityId, combinationHeadId)) {
|
if (ObjUtil.isAllEmpty(seckillActivityId, combinationActivityId, combinationHeadId, bargainRecordId)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// 校验订单项是否超出
|
// 校验订单项是否超出
|
||||||
|
|
|
@ -16,7 +16,6 @@ import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDeta
|
||||||
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
|
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
|
||||||
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
|
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
|
||||||
import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
|
import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
|
||||||
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
|
|
||||||
import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO;
|
import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO;
|
||||||
import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO;
|
import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO;
|
||||||
import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO;
|
import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO;
|
||||||
|
@ -34,8 +33,6 @@ import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEn
|
||||||
import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackRespDTO;
|
import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackRespDTO;
|
||||||
import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
|
import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
|
||||||
import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageAddReqBO;
|
import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageAddReqBO;
|
||||||
import cn.iocoder.yudao.module.trade.service.order.bo.TradeAfterOrderCreateReqBO;
|
|
||||||
import cn.iocoder.yudao.module.trade.service.order.bo.TradeBeforeOrderCreateReqBO;
|
|
||||||
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
|
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
|
||||||
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO;
|
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO;
|
||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
|
@ -94,19 +91,19 @@ public interface TradeOrderConvert {
|
||||||
return new ProductSkuUpdateStockReqDTO(items);
|
return new ProductSkuUpdateStockReqDTO(items);
|
||||||
}
|
}
|
||||||
|
|
||||||
default ProductSkuUpdateStockReqDTO convertNegative(List<AppTradeOrderSettlementReqVO.Item> list) {
|
default ProductSkuUpdateStockReqDTO convertNegative(List<TradeOrderItemDO> 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()));
|
||||||
return new ProductSkuUpdateStockReqDTO(items);
|
return new ProductSkuUpdateStockReqDTO(items);
|
||||||
}
|
}
|
||||||
|
|
||||||
default PayOrderCreateReqDTO convert(TradeOrderDO order, List<TradeOrderItemDO> orderItems,
|
default PayOrderCreateReqDTO convert(TradeOrderDO order, List<TradeOrderItemDO> orderItems,
|
||||||
TradePriceCalculateRespBO calculateRespBO, TradeOrderProperties orderProperties) {
|
TradeOrderProperties orderProperties) {
|
||||||
PayOrderCreateReqDTO createReqDTO = new PayOrderCreateReqDTO()
|
PayOrderCreateReqDTO createReqDTO = new PayOrderCreateReqDTO()
|
||||||
.setAppId(orderProperties.getAppId()).setUserIp(order.getUserIp());
|
.setAppId(orderProperties.getAppId()).setUserIp(order.getUserIp());
|
||||||
// 商户相关字段
|
// 商户相关字段
|
||||||
createReqDTO.setMerchantOrderId(String.valueOf(order.getId()));
|
createReqDTO.setMerchantOrderId(String.valueOf(order.getId()));
|
||||||
String subject = calculateRespBO.getItems().get(0).getSpuName();
|
String subject = orderItems.get(0).getSpuName();
|
||||||
subject = StrUtils.maxLength(subject, PayOrderCreateReqDTO.SUBJECT_MAX_LENGTH); // 避免超过 32 位
|
subject = StrUtils.maxLength(subject, PayOrderCreateReqDTO.SUBJECT_MAX_LENGTH); // 避免超过 32 位
|
||||||
createReqDTO.setSubject(subject);
|
createReqDTO.setSubject(subject);
|
||||||
createReqDTO.setBody(subject); // TODO 芋艿:临时写死
|
createReqDTO.setBody(subject); // TODO 芋艿:临时写死
|
||||||
|
@ -263,36 +260,4 @@ public interface TradeOrderConvert {
|
||||||
return bo;
|
return bo;
|
||||||
}
|
}
|
||||||
|
|
||||||
@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({
|
|
||||||
@Mapping(target = "userId", source = "userId"),
|
|
||||||
@Mapping(target = "orderId", source = "tradeOrderDO.id"),
|
|
||||||
@Mapping(target = "payPrice", source = "tradeOrderDO.payPrice"),
|
|
||||||
@Mapping(target = "items", source = "orderItems"),
|
|
||||||
})
|
|
||||||
TradeAfterOrderCreateReqBO convert(Long userId, AppTradeOrderCreateReqVO createReqVO,
|
|
||||||
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);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package cn.iocoder.yudao.module.trade.convert.order;
|
package cn.iocoder.yudao.module.trade.convert.order;
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderLogDO;
|
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderLogDO;
|
||||||
import cn.iocoder.yudao.module.trade.service.order.bo.logger.TradeOrderLogCreateReqBO;
|
import cn.iocoder.yudao.module.trade.service.order.bo.TradeOrderLogCreateReqBO;
|
||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
import org.mapstruct.factory.Mappers;
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
|
|
@ -295,4 +295,17 @@ public class TradeOrderDO extends BaseDO {
|
||||||
*/
|
*/
|
||||||
private Long seckillActivityId;
|
private Long seckillActivityId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 砍价活动编号
|
||||||
|
*
|
||||||
|
* 关联 BargainActivityDO 的 id 字段
|
||||||
|
*/
|
||||||
|
private Long bargainActivityId;
|
||||||
|
/**
|
||||||
|
* 砍价记录编号
|
||||||
|
*
|
||||||
|
* 关联 BargainRecordDO 的 id 字段
|
||||||
|
*/
|
||||||
|
private Long bargainRecordId;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderLogDO;
|
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderLogDO;
|
||||||
import cn.iocoder.yudao.module.trade.framework.order.core.annotations.TradeOrderLog;
|
import cn.iocoder.yudao.module.trade.framework.order.core.annotations.TradeOrderLog;
|
||||||
import cn.iocoder.yudao.module.trade.service.order.TradeOrderLogService;
|
import cn.iocoder.yudao.module.trade.service.order.TradeOrderLogService;
|
||||||
import cn.iocoder.yudao.module.trade.service.order.bo.logger.TradeOrderLogCreateReqBO;
|
import cn.iocoder.yudao.module.trade.service.order.bo.TradeOrderLogCreateReqBO;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.aspectj.lang.JoinPoint;
|
import org.aspectj.lang.JoinPoint;
|
||||||
import org.aspectj.lang.annotation.AfterReturning;
|
import org.aspectj.lang.annotation.AfterReturning;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package cn.iocoder.yudao.module.trade.service.order;
|
package cn.iocoder.yudao.module.trade.service.order;
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderLogDO;
|
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderLogDO;
|
||||||
import cn.iocoder.yudao.module.trade.service.order.bo.logger.TradeOrderLogCreateReqBO;
|
import cn.iocoder.yudao.module.trade.service.order.bo.TradeOrderLogCreateReqBO;
|
||||||
import org.springframework.scheduling.annotation.Async;
|
import org.springframework.scheduling.annotation.Async;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
|
@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.trade.service.order;
|
||||||
import cn.iocoder.yudao.module.trade.convert.order.TradeOrderLogConvert;
|
import cn.iocoder.yudao.module.trade.convert.order.TradeOrderLogConvert;
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderLogDO;
|
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderLogDO;
|
||||||
import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderLogMapper;
|
import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderLogMapper;
|
||||||
import cn.iocoder.yudao.module.trade.service.order.bo.logger.TradeOrderLogCreateReqBO;
|
import cn.iocoder.yudao.module.trade.service.order.bo.TradeOrderLogCreateReqBO;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
|
|
@ -27,7 +27,6 @@ import cn.iocoder.yudao.module.product.api.comment.ProductCommentApi;
|
||||||
import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
|
import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
|
||||||
import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
|
import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
|
||||||
import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
|
import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
|
||||||
import cn.iocoder.yudao.module.promotion.api.bargain.BargainRecordApi;
|
|
||||||
import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi;
|
import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi;
|
||||||
import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi;
|
import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi;
|
||||||
import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO;
|
import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO;
|
||||||
|
@ -61,7 +60,6 @@ import cn.iocoder.yudao.module.trade.service.cart.CartService;
|
||||||
import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService;
|
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.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;
|
||||||
|
@ -128,8 +126,6 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
||||||
@Resource
|
@Resource
|
||||||
private CombinationRecordApi combinationRecordApi;
|
private CombinationRecordApi combinationRecordApi;
|
||||||
@Resource
|
@Resource
|
||||||
private BargainRecordApi bargainRecordApi;
|
|
||||||
@Resource
|
|
||||||
private MemberUserApi memberUserApi;
|
private MemberUserApi memberUserApi;
|
||||||
@Resource
|
@Resource
|
||||||
private MemberLevelApi memberLevelApi;
|
private MemberLevelApi memberLevelApi;
|
||||||
|
@ -195,24 +191,27 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
@TradeOrderLog(operateType = TradeOrderOperateTypeEnum.MEMBER_CREATE)
|
@TradeOrderLog(operateType = TradeOrderOperateTypeEnum.MEMBER_CREATE)
|
||||||
public TradeOrderDO createOrder(Long userId, String userIp, AppTradeOrderCreateReqVO createReqVO) {
|
public TradeOrderDO createOrder(Long userId, String userIp, AppTradeOrderCreateReqVO createReqVO) {
|
||||||
// 0. 价格计算
|
// 1.1 价格计算
|
||||||
TradePriceCalculateRespBO calculateRespBO = calculatePrice(userId, createReqVO);
|
TradePriceCalculateRespBO calculateRespBO = calculatePrice(userId, createReqVO);
|
||||||
|
// 1.2 构建订单
|
||||||
|
TradeOrderDO order = buildTradeOrder(userId, userIp, createReqVO, calculateRespBO);
|
||||||
|
List<TradeOrderItemDO> orderItems = buildTradeOrderItems(order, calculateRespBO);
|
||||||
|
|
||||||
// 1. 订单创建前的逻辑
|
// 2. 订单创建前的逻辑
|
||||||
beforeCreateTradeOrder(userId, createReqVO, calculateRespBO);
|
beforeCreateTradeOrder(order, orderItems);
|
||||||
|
|
||||||
// 2.1 插入 TradeOrderDO 订单
|
// 3. 保存订单
|
||||||
TradeOrderDO order = createTradeOrder(userId, userIp, createReqVO, calculateRespBO);
|
tradeOrderMapper.insert(order);
|
||||||
// 2.2 插入 TradeOrderItemDO 订单项
|
orderItems.forEach(orderItem -> orderItem.setOrderId(order.getId()));
|
||||||
List<TradeOrderItemDO> orderItems = createTradeOrderItems(order, calculateRespBO);
|
tradeOrderItemMapper.insertBatch(orderItems);
|
||||||
|
|
||||||
// 3. 订单创建后的逻辑
|
// 4. 订单创建后的逻辑
|
||||||
afterCreateTradeOrder(userId, createReqVO, order, orderItems, calculateRespBO);
|
afterCreateTradeOrder(order, orderItems, createReqVO);
|
||||||
return order;
|
return order;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TradeOrderDO createTradeOrder(Long userId, String clientIp, AppTradeOrderCreateReqVO createReqVO,
|
private TradeOrderDO buildTradeOrder(Long userId, String clientIp, AppTradeOrderCreateReqVO createReqVO,
|
||||||
TradePriceCalculateRespBO calculateRespBO) {
|
TradePriceCalculateRespBO calculateRespBO) {
|
||||||
TradeOrderDO order = TradeOrderConvert.INSTANCE.convert(userId, clientIp, createReqVO, calculateRespBO);
|
TradeOrderDO order = TradeOrderConvert.INSTANCE.convert(userId, clientIp, createReqVO, calculateRespBO);
|
||||||
order.setType(calculateRespBO.getType());
|
order.setType(calculateRespBO.getType());
|
||||||
order.setNo(tradeNoRedisDAO.generate(TradeNoRedisDAO.TRADE_ORDER_NO_PREFIX));
|
order.setNo(tradeNoRedisDAO.generate(TradeNoRedisDAO.TRADE_ORDER_NO_PREFIX));
|
||||||
|
@ -235,33 +234,27 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
||||||
order.setPickUpVerifyCode(RandomUtil.randomNumbers(8)); // 随机一个核销码,长度为 8 位
|
order.setPickUpVerifyCode(RandomUtil.randomNumbers(8)); // 随机一个核销码,长度为 8 位
|
||||||
}
|
}
|
||||||
// TODO @疯狂:是不是可以在这里设置下推广人哈;
|
// TODO @疯狂:是不是可以在这里设置下推广人哈;
|
||||||
tradeOrderMapper.insert(order);
|
|
||||||
return order;
|
return order;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<TradeOrderItemDO> createTradeOrderItems(TradeOrderDO tradeOrderDO,
|
private List<TradeOrderItemDO> buildTradeOrderItems(TradeOrderDO tradeOrderDO,
|
||||||
TradePriceCalculateRespBO calculateRespBO) {
|
TradePriceCalculateRespBO calculateRespBO) {
|
||||||
List<TradeOrderItemDO> orderItems = TradeOrderConvert.INSTANCE.convertList(tradeOrderDO, calculateRespBO);
|
return TradeOrderConvert.INSTANCE.convertList(tradeOrderDO, calculateRespBO);
|
||||||
tradeOrderItemMapper.insertBatch(orderItems);
|
|
||||||
return orderItems;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 订单创建前,执行前置逻辑
|
* 订单创建前,执行前置逻辑
|
||||||
*
|
*
|
||||||
* @param userId 用户编号
|
* @param order 订单
|
||||||
* @param createReqVO 创建订单请求
|
* @param orderItems 订单项
|
||||||
* @param calculateRespBO 订单价格计算结果
|
|
||||||
*/
|
*/
|
||||||
private void beforeCreateTradeOrder(Long userId, AppTradeOrderCreateReqVO createReqVO,
|
private void beforeCreateTradeOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
|
||||||
TradePriceCalculateRespBO calculateRespBO) {
|
|
||||||
// 1. 执行订单创建前置处理器
|
// 1. 执行订单创建前置处理器
|
||||||
// TODO @puhui999:这里有个纠结点;handler 的定义是只处理指定类型的订单的拓展逻辑;还是通用的 handler,类似可以处理优惠劵等等
|
// TODO @puhui999:这里有个纠结点;handler 的定义是只处理指定类型的订单的拓展逻辑;还是通用的 handler,类似可以处理优惠劵等等
|
||||||
tradeOrderHandlers.forEach(handler ->
|
tradeOrderHandlers.forEach(handler -> handler.beforeOrderCreate(order, orderItems));
|
||||||
handler.beforeOrderCreate(TradeOrderConvert.INSTANCE.convert(userId, createReqVO, calculateRespBO)));
|
|
||||||
|
|
||||||
// 2. 下单时扣减商品库存
|
// 2. 下单时扣减商品库存
|
||||||
productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convertNegative(createReqVO.getItems()));
|
productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convertNegative(orderItems));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -269,22 +262,19 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
||||||
* <p>
|
* <p>
|
||||||
* 例如说:优惠劵的扣减、积分的扣减、支付单的创建等等
|
* 例如说:优惠劵的扣减、积分的扣减、支付单的创建等等
|
||||||
*
|
*
|
||||||
* @param userId 用户编号
|
* @param order 订单
|
||||||
|
* @param orderItems 订单项
|
||||||
* @param createReqVO 创建订单请求
|
* @param createReqVO 创建订单请求
|
||||||
* @param order 交易订单
|
|
||||||
* @param calculateRespBO 订单价格计算结果
|
|
||||||
*/
|
*/
|
||||||
private void afterCreateTradeOrder(Long userId, AppTradeOrderCreateReqVO createReqVO,
|
private void afterCreateTradeOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems,
|
||||||
TradeOrderDO order, List<TradeOrderItemDO> orderItems,
|
AppTradeOrderCreateReqVO createReqVO) {
|
||||||
TradePriceCalculateRespBO calculateRespBO) {
|
|
||||||
// 1. 执行订单创建后置处理器
|
// 1. 执行订单创建后置处理器
|
||||||
tradeOrderHandlers.forEach(handler -> handler.afterOrderCreate(
|
tradeOrderHandlers.forEach(handler -> handler.afterOrderCreate(order, orderItems));
|
||||||
TradeOrderConvert.INSTANCE.convert(userId, createReqVO, order, orderItems)));
|
|
||||||
|
|
||||||
// 2. 有使用优惠券时更新
|
// 2. 有使用优惠券时更新
|
||||||
// 不在前置扣减的原因,是因为优惠劵要记录使用的订单号
|
// 不在前置扣减的原因,是因为优惠劵要记录使用的订单号
|
||||||
if (createReqVO.getCouponId() != null) {
|
if (order.getCouponId() != null) {
|
||||||
couponApi.useCoupon(new CouponUseReqDTO().setId(createReqVO.getCouponId()).setUserId(userId)
|
couponApi.useCoupon(new CouponUseReqDTO().setId(order.getCouponId()).setUserId(order.getUserId())
|
||||||
.setOrderId(order.getId()));
|
.setOrderId(order.getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,11 +285,11 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
||||||
// 4. 删除购物车商品
|
// 4. 删除购物车商品
|
||||||
Set<Long> cartIds = convertSet(createReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCartId);
|
Set<Long> cartIds = convertSet(createReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCartId);
|
||||||
if (CollUtil.isNotEmpty(cartIds)) {
|
if (CollUtil.isNotEmpty(cartIds)) {
|
||||||
cartService.deleteCart(userId, cartIds);
|
cartService.deleteCart(order.getUserId(), cartIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. 生成预支付
|
// 5. 生成预支付
|
||||||
createPayOrder(order, orderItems, calculateRespBO);
|
createPayOrder(order, orderItems);
|
||||||
|
|
||||||
// 6. 插入订单日志
|
// 6. 插入订单日志
|
||||||
TradeOrderLogUtils.setOrderInfo(order.getId(), null, order.getStatus());
|
TradeOrderLogUtils.setOrderInfo(order.getId(), null, order.getStatus());
|
||||||
|
@ -313,11 +303,10 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
||||||
// TODO @LeeYan9: 是可以思考下, 订单的营销优惠记录, 应该记录在哪里, 微信讨论起来!
|
// TODO @LeeYan9: 是可以思考下, 订单的营销优惠记录, 应该记录在哪里, 微信讨论起来!
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createPayOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems,
|
private void createPayOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
|
||||||
TradePriceCalculateRespBO calculateRespBO) {
|
|
||||||
// 创建支付单,用于后续的支付
|
// 创建支付单,用于后续的支付
|
||||||
PayOrderCreateReqDTO payOrderCreateReqDTO = TradeOrderConvert.INSTANCE.convert(
|
PayOrderCreateReqDTO payOrderCreateReqDTO = TradeOrderConvert.INSTANCE.convert(
|
||||||
order, orderItems, calculateRespBO, tradeOrderProperties);
|
order, orderItems, tradeOrderProperties);
|
||||||
Long payOrderId = payOrderApi.createOrder(payOrderCreateReqDTO);
|
Long payOrderId = payOrderApi.createOrder(payOrderCreateReqDTO);
|
||||||
|
|
||||||
// 更新到交易单上
|
// 更新到交易单上
|
||||||
|
@ -343,8 +332,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3、订单支付成功后
|
// 3、订单支付成功后
|
||||||
tradeOrderHandlers.forEach(tradeOrderHandler -> tradeOrderHandler.afterPayOrder(new TradeAfterPayOrderReqBO()
|
tradeOrderHandlers.forEach(handler -> handler.afterPayOrder(order));
|
||||||
.setOrderId(order.getId()).setOrderType(order.getType()).setUserId(order.getUserId()).setPayTime(LocalDateTime.now())));
|
|
||||||
|
|
||||||
// 4.1 增加用户积分(赠送)
|
// 4.1 增加用户积分(赠送)
|
||||||
addUserPoint(order.getUserId(), order.getGivePoint(), MemberPointBizTypeEnum.ORDER_GIVE, order.getId());
|
addUserPoint(order.getUserId(), order.getGivePoint(), MemberPointBizTypeEnum.ORDER_GIVE, order.getId());
|
||||||
|
|
|
@ -1,87 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.trade.service.order.bo;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import javax.validation.Valid;
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
// TODO 芋艿:在想想这些参数的定义
|
|
||||||
/**
|
|
||||||
* 订单创建之后 Request BO
|
|
||||||
*
|
|
||||||
* @author HUIHUI
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class TradeAfterOrderCreateReqBO {
|
|
||||||
|
|
||||||
// ========== 拼团活动相关字段 ==========
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 拼团活动编号
|
|
||||||
*/
|
|
||||||
private Long combinationActivityId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 拼团团长编号
|
|
||||||
*/
|
|
||||||
private Long combinationHeadId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 订单编号
|
|
||||||
*/
|
|
||||||
@NotNull(message = "订单编号不能为空")
|
|
||||||
private Long orderId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户编号
|
|
||||||
*/
|
|
||||||
@NotNull(message = "用户编号不能为空")
|
|
||||||
private Long userId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 支付金额
|
|
||||||
*/
|
|
||||||
@NotNull(message = "支付金额不能为空")
|
|
||||||
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,43 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.trade.service.order.bo;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 订单支付后 Request BO
|
|
||||||
*
|
|
||||||
* @author HUIHUI
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class TradeAfterPayOrderReqBO {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 订单编号
|
|
||||||
*/
|
|
||||||
@Schema(description = "订单编号", example = "6")
|
|
||||||
private Long orderId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 订单类型
|
|
||||||
*
|
|
||||||
* 枚举 {@link TradeOrderTypeEnum}
|
|
||||||
*/
|
|
||||||
@Schema(description = "订单类型", example = "3")
|
|
||||||
private Integer orderType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户编号
|
|
||||||
*/
|
|
||||||
@Schema(description = "用户编号", example = "11")
|
|
||||||
private Long userId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 订单支付时间
|
|
||||||
*/
|
|
||||||
@Schema(description = "订单支付时间", example = "2023-08-15 10:00:00")
|
|
||||||
private LocalDateTime payTime;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,94 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.trade.service.order.bo;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import javax.validation.Valid;
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import java.util.List;
|
|
||||||
// TODO 芋艿:在想想这些参数的定义
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 订单创建之前 Request BO
|
|
||||||
*
|
|
||||||
* @author HUIHUI
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class TradeBeforeOrderCreateReqBO {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 订单类型
|
|
||||||
*
|
|
||||||
* 枚举 {@link TradeOrderTypeEnum}
|
|
||||||
*/
|
|
||||||
@NotNull(message = "订单类型不能为空")
|
|
||||||
private Integer orderType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户编号
|
|
||||||
*
|
|
||||||
* 关联 MemberUserDO 的 id 编号
|
|
||||||
*/
|
|
||||||
@NotNull(message = "用户编号不能为空")
|
|
||||||
private Long userId;
|
|
||||||
|
|
||||||
// ========== 秒杀活动相关字段 ==========
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 秒杀活动编号
|
|
||||||
*/
|
|
||||||
private Long seckillActivityId;
|
|
||||||
|
|
||||||
// ========== 拼团活动相关字段 ==========
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 拼团活动编号
|
|
||||||
*/
|
|
||||||
private Long combinationActivityId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 拼团团长编号
|
|
||||||
*/
|
|
||||||
private Long combinationHeadId;
|
|
||||||
|
|
||||||
// ========== 砍价活动相关字段 ==========
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 砍价活动编号
|
|
||||||
*/
|
|
||||||
private Long bargainActivityId;
|
|
||||||
|
|
||||||
// ========== 购买商品相关字段 ==========
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 订单购买的商品信息
|
|
||||||
*/
|
|
||||||
private List<Item> items;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 订单商品信息
|
|
||||||
* 记录购买商品的简要核心信息
|
|
||||||
*
|
|
||||||
* @author HUIHUI
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Valid
|
|
||||||
public static class Item {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商品 SKU 编号
|
|
||||||
*
|
|
||||||
* 关联 ProductSkuDO 的 id 编号
|
|
||||||
*/
|
|
||||||
@NotNull(message = "SKU 编号活动商品不能为空")
|
|
||||||
private Long skuId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 购买的商品数量
|
|
||||||
*/
|
|
||||||
@NotNull(message = "购买数量不能为空")
|
|
||||||
private Integer count;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.iocoder.yudao.module.trade.service.order.bo.logger;
|
package cn.iocoder.yudao.module.trade.service.order.bo;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
|
@ -2,11 +2,13 @@ package cn.iocoder.yudao.module.trade.service.order.handler;
|
||||||
|
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.iocoder.yudao.module.promotion.api.bargain.BargainActivityApi;
|
import cn.iocoder.yudao.module.promotion.api.bargain.BargainActivityApi;
|
||||||
|
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
|
||||||
|
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
|
||||||
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
|
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
|
||||||
import cn.iocoder.yudao.module.trade.service.order.bo.TradeBeforeOrderCreateReqBO;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 砍价订单 handler 实现类
|
* 砍价订单 handler 实现类
|
||||||
|
@ -19,21 +21,14 @@ public class TradeBargainHandler implements TradeOrderHandler {
|
||||||
@Resource
|
@Resource
|
||||||
private BargainActivityApi bargainActivityApi;
|
private BargainActivityApi bargainActivityApi;
|
||||||
|
|
||||||
// TODO @puhui999:先临时写在这里;在价格计算时,如果是秒杀商品,需要校验如下条件:
|
|
||||||
// 1. 商品存在、库存充足、单次限购;
|
|
||||||
// 2. 活动进行中、时间段符合
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void beforeOrderCreate(TradeBeforeOrderCreateReqBO reqBO) {
|
public void beforeOrderCreate(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
|
||||||
// 如果是砍价订单
|
if (ObjectUtil.notEqual(TradeOrderTypeEnum.BARGAIN.getType(), order.getType())) {
|
||||||
if (ObjectUtil.notEqual(TradeOrderTypeEnum.BARGAIN.getType(), reqBO.getOrderType())) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取商品信息
|
|
||||||
TradeBeforeOrderCreateReqBO.Item item = reqBO.getItems().get(0);
|
|
||||||
// 扣减砍价活动的库存
|
// 扣减砍价活动的库存
|
||||||
bargainActivityApi.updateBargainActivityStock(reqBO.getBargainActivityId(), item.getCount());
|
bargainActivityApi.updateBargainActivityStock(order.getBargainActivityId(),
|
||||||
|
orderItems.get(0).getCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,6 @@
|
||||||
package cn.iocoder.yudao.module.trade.service.order.handler;
|
package cn.iocoder.yudao.module.trade.service.order.handler;
|
||||||
|
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
|
||||||
import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi;
|
import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi;
|
||||||
import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert;
|
|
||||||
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
|
|
||||||
import cn.iocoder.yudao.module.trade.service.order.bo.TradeAfterOrderCreateReqBO;
|
|
||||||
import cn.iocoder.yudao.module.trade.service.order.bo.TradeAfterPayOrderReqBO;
|
|
||||||
import cn.iocoder.yudao.module.trade.service.order.bo.TradeBeforeOrderCreateReqBO;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
@ -22,38 +16,38 @@ public class TradeCombinationHandler implements TradeOrderHandler {
|
||||||
@Resource
|
@Resource
|
||||||
private CombinationRecordApi combinationRecordApi;
|
private CombinationRecordApi combinationRecordApi;
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
public void beforeOrderCreate(TradeBeforeOrderCreateReqBO reqBO) {
|
// public void beforeOrderCreate(TradeBeforeOrderCreateReqBO reqBO) {
|
||||||
// 如果不是拼团订单则结束
|
// // 如果不是拼团订单则结束
|
||||||
if (ObjectUtil.notEqual(TradeOrderTypeEnum.COMBINATION.getType(), reqBO.getOrderType())) {
|
// if (ObjectUtil.notEqual(TradeOrderTypeEnum.COMBINATION.getType(), reqBO.getOrderType())) {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
// // 获取商品信息
|
||||||
|
// TradeBeforeOrderCreateReqBO.Item item = reqBO.getItems().get(0);
|
||||||
|
// // 校验是否满足拼团活动相关限制
|
||||||
|
// combinationRecordApi.validateCombinationRecord(reqBO.getCombinationActivityId(), reqBO.getUserId(), item.getSkuId(), item.getCount());
|
||||||
|
// }
|
||||||
|
|
||||||
// 获取商品信息
|
// @Override
|
||||||
TradeBeforeOrderCreateReqBO.Item item = reqBO.getItems().get(0);
|
// public void afterOrderCreate(TradeAfterOrderCreateReqBO reqBO) {
|
||||||
// 校验是否满足拼团活动相关限制
|
// if (reqBO.getCombinationActivityId() == null) {
|
||||||
combinationRecordApi.validateCombinationRecord(reqBO.getCombinationActivityId(), reqBO.getUserId(), item.getSkuId(), item.getCount());
|
// return;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
// // 创建砍价记录
|
||||||
|
// combinationRecordApi.createCombinationRecord(TradeOrderConvert.INSTANCE.convert(reqBO));
|
||||||
|
// }
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
public void afterOrderCreate(TradeAfterOrderCreateReqBO reqBO) {
|
// public void afterPayOrder(TradeAfterPayOrderReqBO reqBO) {
|
||||||
if (reqBO.getCombinationActivityId() == null) {
|
// // 如果不是拼团订单则结束
|
||||||
return;
|
// if (ObjectUtil.notEqual(TradeOrderTypeEnum.COMBINATION.getType(), reqBO.getOrderType())) {
|
||||||
}
|
// return;
|
||||||
|
// }
|
||||||
// 创建砍价记录
|
//
|
||||||
combinationRecordApi.createCombinationRecord(TradeOrderConvert.INSTANCE.convert(reqBO));
|
// // 更新拼团状态 TODO puhui999:订单支付失败或订单支付过期删除这条拼团记录
|
||||||
}
|
// combinationRecordApi.updateRecordStatusToInProgress(reqBO.getUserId(), reqBO.getOrderId(), reqBO.getPayTime());
|
||||||
|
// }
|
||||||
@Override
|
|
||||||
public void afterPayOrder(TradeAfterPayOrderReqBO reqBO) {
|
|
||||||
// 如果不是拼团订单则结束
|
|
||||||
if (ObjectUtil.notEqual(TradeOrderTypeEnum.COMBINATION.getType(), reqBO.getOrderType())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新拼团状态 TODO puhui999:订单支付失败或订单支付过期删除这条拼团记录
|
|
||||||
combinationRecordApi.updateRecordStatusToInProgress(reqBO.getUserId(), reqBO.getOrderId(), reqBO.getPayTime());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package cn.iocoder.yudao.module.trade.service.order.handler;
|
package cn.iocoder.yudao.module.trade.service.order.handler;
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.trade.service.order.bo.TradeAfterOrderCreateReqBO;
|
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
|
||||||
import cn.iocoder.yudao.module.trade.service.order.bo.TradeAfterPayOrderReqBO;
|
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
|
||||||
import cn.iocoder.yudao.module.trade.service.order.bo.TradeBeforeOrderCreateReqBO;
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 订单活动特殊逻辑处理器 handler 接口
|
* 订单活动特殊逻辑处理器 handler 接口
|
||||||
|
@ -15,23 +16,25 @@ public interface TradeOrderHandler {
|
||||||
/**
|
/**
|
||||||
* 订单创建前
|
* 订单创建前
|
||||||
*
|
*
|
||||||
* @param reqBO 请求
|
* @param order 订单
|
||||||
|
* @param orderItems 订单项
|
||||||
*/
|
*/
|
||||||
default void beforeOrderCreate(TradeBeforeOrderCreateReqBO reqBO) {}
|
default void beforeOrderCreate(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 订单创建后
|
* 订单创建后
|
||||||
*
|
*
|
||||||
* @param reqBO 请求
|
* @param order 订单
|
||||||
|
* @param orderItems 订单项
|
||||||
*/
|
*/
|
||||||
default void afterOrderCreate(TradeAfterOrderCreateReqBO reqBO) {}
|
default void afterOrderCreate(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支付订单后
|
* 支付订单后
|
||||||
*
|
*
|
||||||
* @param reqBO 请求
|
* @param order 订单
|
||||||
*/
|
*/
|
||||||
default void afterPayOrder(TradeAfterPayOrderReqBO reqBO) {}
|
default void afterPayOrder(TradeOrderDO order) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 订单取消
|
* 订单取消
|
||||||
|
|
|
@ -2,11 +2,13 @@ package cn.iocoder.yudao.module.trade.service.order.handler;
|
||||||
|
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.iocoder.yudao.module.promotion.api.seckill.SeckillActivityApi;
|
import cn.iocoder.yudao.module.promotion.api.seckill.SeckillActivityApi;
|
||||||
|
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
|
||||||
|
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
|
||||||
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
|
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
|
||||||
import cn.iocoder.yudao.module.trade.service.order.bo.TradeBeforeOrderCreateReqBO;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 秒杀订单 handler 实现类
|
* 秒杀订单 handler 实现类
|
||||||
|
@ -19,21 +21,14 @@ public class TradeSeckillHandler implements TradeOrderHandler {
|
||||||
@Resource
|
@Resource
|
||||||
private SeckillActivityApi seckillActivityApi;
|
private SeckillActivityApi seckillActivityApi;
|
||||||
|
|
||||||
// TODO @puhui999:先临时写在这里;在价格计算时,如果是秒杀商品,需要校验如下条件:
|
|
||||||
// 1. 商品存在、库存充足、单次限购;
|
|
||||||
// 2. 活动进行中、时间段符合
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void beforeOrderCreate(TradeBeforeOrderCreateReqBO reqBO) {
|
public void beforeOrderCreate(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
|
||||||
// 如果是秒杀订单:额外扣减秒杀的库存;
|
if (ObjectUtil.notEqual(TradeOrderTypeEnum.SECKILL.getType(), order.getType())) {
|
||||||
if (ObjectUtil.notEqual(TradeOrderTypeEnum.SECKILL.getType(), reqBO.getOrderType())) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取商品信息
|
|
||||||
TradeBeforeOrderCreateReqBO.Item item = reqBO.getItems().get(0);
|
|
||||||
// 扣减秒杀活动的库存
|
// 扣减秒杀活动的库存
|
||||||
seckillActivityApi.updateSeckillStock(reqBO.getSeckillActivityId(), item.getSkuId(), item.getCount());
|
seckillActivityApi.updateSeckillStock(order.getSeckillActivityId(),
|
||||||
|
orderItems.get(0).getSkuId(), orderItems.get(0).getCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,9 +81,9 @@ public class TradePriceCalculateReqBO {
|
||||||
|
|
||||||
// ========== 砍价活动相关字段 ==========
|
// ========== 砍价活动相关字段 ==========
|
||||||
/**
|
/**
|
||||||
* 砍价活动编号
|
* 砍价记录编号
|
||||||
*/
|
*/
|
||||||
private Long bargainActivityId;
|
private Long bargainRecordId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 商品 SKU
|
* 商品 SKU
|
||||||
|
|
|
@ -58,6 +58,11 @@ public class TradePriceCalculateRespBO {
|
||||||
*/
|
*/
|
||||||
private Integer givePoint;
|
private Integer givePoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 砍价活动编号
|
||||||
|
*/
|
||||||
|
private Long bargainActivityId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 订单价格
|
* 订单价格
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
package cn.iocoder.yudao.module.trade.service.price.calculator;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Assert;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.iocoder.yudao.module.promotion.api.bargain.BargainRecordApi;
|
||||||
|
import cn.iocoder.yudao.module.promotion.api.bargain.dto.BargainValidateJoinRespDTO;
|
||||||
|
import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum;
|
||||||
|
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
|
||||||
|
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO;
|
||||||
|
import org.springframework.core.annotation.Order;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
// TODO huihui:单测需要补充
|
||||||
|
/**
|
||||||
|
* 砍价活动的 {@link TradePriceCalculator} 实现类
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Order(TradePriceCalculator.ORDER_BARGAIN_ACTIVITY)
|
||||||
|
public class TradeBargainActivityPriceCalculator implements TradePriceCalculator {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private BargainRecordApi bargainRecordApi;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) {
|
||||||
|
// 1. 判断订单类型和是否具有拼团记录编号
|
||||||
|
if (param.getBargainRecordId() != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Assert.isTrue(param.getItems().size() == 1, "砍价时,只允许选择一个商品");
|
||||||
|
Assert.isTrue(param.getItems().get(0).getCount() == 1, "砍价时,只允许选择一个商品");
|
||||||
|
// 2. 校验是否可以参与砍价
|
||||||
|
TradePriceCalculateRespBO.OrderItem orderItem = result.getItems().get(0);
|
||||||
|
BargainValidateJoinRespDTO bargainActivity = bargainRecordApi.validateJoinBargain(
|
||||||
|
param.getUserId(), param.getBargainRecordId(), orderItem.getSkuId());
|
||||||
|
|
||||||
|
// 3.1 记录优惠明细
|
||||||
|
Integer discountPrice = orderItem.getPayPrice() - bargainActivity.getBargainPrice() * orderItem.getCount();
|
||||||
|
TradePriceCalculatorHelper.addPromotion(result, orderItem,
|
||||||
|
param.getSeckillActivityId(), bargainActivity.getName(), PromotionTypeEnum.BARGAIN_ACTIVITY.getType(),
|
||||||
|
StrUtil.format("砍价活动:省 {} 元", TradePriceCalculatorHelper.formatPrice(discountPrice)),
|
||||||
|
discountPrice);
|
||||||
|
// 3.2 更新 SKU 优惠金额
|
||||||
|
orderItem.setDiscountPrice(orderItem.getDiscountPrice() + discountPrice);
|
||||||
|
TradePriceCalculatorHelper.recountPayPrice(orderItem);
|
||||||
|
TradePriceCalculatorHelper.recountAllPrice(result);
|
||||||
|
// 4. 特殊:设置对应的砍价活动编号
|
||||||
|
result.setBargainActivityId(bargainActivity.getActivityId());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -14,6 +14,10 @@ import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO;
|
||||||
public interface TradePriceCalculator {
|
public interface TradePriceCalculator {
|
||||||
|
|
||||||
int ORDER_MEMBER_LEVEL = 5;
|
int ORDER_MEMBER_LEVEL = 5;
|
||||||
|
|
||||||
|
int ORDER_SECKILL_ACTIVITY = 8;
|
||||||
|
int ORDER_BARGAIN_ACTIVITY = 8;
|
||||||
|
|
||||||
int ORDER_DISCOUNT_ACTIVITY = 10;
|
int ORDER_DISCOUNT_ACTIVITY = 10;
|
||||||
int ORDER_REWARD_ACTIVITY = 20;
|
int ORDER_REWARD_ACTIVITY = 20;
|
||||||
int ORDER_COUPON = 30;
|
int ORDER_COUPON = 30;
|
||||||
|
|
|
@ -23,7 +23,7 @@ import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.PRICE_CALCU
|
||||||
* @author HUIHUI
|
* @author HUIHUI
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@Order(TradePriceCalculator.ORDER_DISCOUNT_ACTIVITY)
|
@Order(TradePriceCalculator.ORDER_SECKILL_ACTIVITY)
|
||||||
public class TradeSeckillActivityPriceCalculator implements TradePriceCalculator {
|
public class TradeSeckillActivityPriceCalculator implements TradePriceCalculator {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
|
|
Loading…
Reference in New Issue