trade:1、重构 order handler 的参数;2、增加砍价商品的价格计算

This commit is contained in:
YunaiV
2023-10-04 11:29:38 +08:00
parent dc1347184f
commit 8dbabb9efc
35 changed files with 363 additions and 421 deletions

View File

@@ -60,15 +60,14 @@ public class AppTradeOrderSettlementReqVO {
private Long combinationHeadId;
// ========== 砍价活动相关字段 ==========
// TODO @puhui999是不是砍价记录编号哈?
@Schema(description = "砍价活动编号", example = "123")
private Long bargainActivityId;
@Schema(description = "砍价记录编号", example = "123")
private Long bargainRecordId;
@AssertTrue(message = "活动商品每次只能购买一种规格")
@JsonIgnore
public boolean isValidActivityItems() {
// 校验是否是活动订单
if (ObjUtil.isAllEmpty(seckillActivityId, combinationActivityId, combinationHeadId)) {
if (ObjUtil.isAllEmpty(seckillActivityId, combinationActivityId, combinationHeadId, bargainRecordId)) {
return true;
}
// 校验订单项是否超出

View File

@@ -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.ProductSkuUpdateStockReqDTO;
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.controller.admin.base.member.user.MemberUserRespVO;
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.order.config.TradeOrderProperties;
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.TradePriceCalculateRespBO;
import org.mapstruct.Mapper;
@@ -94,19 +91,19 @@ public interface TradeOrderConvert {
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 ->
new ProductSkuUpdateStockReqDTO.Item().setId(item.getSkuId()).setIncrCount(-item.getCount()));
return new ProductSkuUpdateStockReqDTO(items);
}
default PayOrderCreateReqDTO convert(TradeOrderDO order, List<TradeOrderItemDO> orderItems,
TradePriceCalculateRespBO calculateRespBO, TradeOrderProperties orderProperties) {
TradeOrderProperties orderProperties) {
PayOrderCreateReqDTO createReqDTO = new PayOrderCreateReqDTO()
.setAppId(orderProperties.getAppId()).setUserIp(order.getUserIp());
// 商户相关字段
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 位
createReqDTO.setSubject(subject);
createReqDTO.setBody(subject); // TODO 芋艿:临时写死
@@ -263,36 +260,4 @@ public interface TradeOrderConvert {
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);
}

View File

@@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.trade.convert.order;
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.factory.Mappers;

View File

@@ -295,4 +295,17 @@ public class TradeOrderDO extends BaseDO {
*/
private Long seckillActivityId;
/**
* 砍价活动编号
*
* 关联 BargainActivityDO 的 id 字段
*/
private Long bargainActivityId;
/**
* 砍价记录编号
*
* 关联 BargainRecordDO 的 id 字段
*/
private Long bargainRecordId;
}

View File

@@ -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.framework.order.core.annotations.TradeOrderLog;
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 org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;

View File

@@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.trade.service.order;
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 java.util.List;

View File

@@ -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.dal.dataobject.order.TradeOrderLogDO;
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 javax.annotation.Resource;

View File

@@ -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.sku.ProductSkuApi;
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.coupon.CouponApi;
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.message.TradeMessageService;
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.price.TradePriceService;
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
@@ -128,8 +126,6 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
@Resource
private CombinationRecordApi combinationRecordApi;
@Resource
private BargainRecordApi bargainRecordApi;
@Resource
private MemberUserApi memberUserApi;
@Resource
private MemberLevelApi memberLevelApi;
@@ -195,24 +191,27 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
@Transactional(rollbackFor = Exception.class)
@TradeOrderLog(operateType = TradeOrderOperateTypeEnum.MEMBER_CREATE)
public TradeOrderDO createOrder(Long userId, String userIp, AppTradeOrderCreateReqVO createReqVO) {
// 0. 价格计算
// 1.1 价格计算
TradePriceCalculateRespBO calculateRespBO = calculatePrice(userId, createReqVO);
// 1.2 构建订单
TradeOrderDO order = buildTradeOrder(userId, userIp, createReqVO, calculateRespBO);
List<TradeOrderItemDO> orderItems = buildTradeOrderItems(order, calculateRespBO);
// 1. 订单创建前的逻辑
beforeCreateTradeOrder(userId, createReqVO, calculateRespBO);
// 2. 订单创建前的逻辑
beforeCreateTradeOrder(order, orderItems);
// 2.1 插入 TradeOrderDO 订单
TradeOrderDO order = createTradeOrder(userId, userIp, createReqVO, calculateRespBO);
// 2.2 插入 TradeOrderItemDO 订单项
List<TradeOrderItemDO> orderItems = createTradeOrderItems(order, calculateRespBO);
// 3. 保存订单
tradeOrderMapper.insert(order);
orderItems.forEach(orderItem -> orderItem.setOrderId(order.getId()));
tradeOrderItemMapper.insertBatch(orderItems);
// 3. 订单创建后的逻辑
afterCreateTradeOrder(userId, createReqVO, order, orderItems, calculateRespBO);
// 4. 订单创建后的逻辑
afterCreateTradeOrder(order, orderItems, createReqVO);
return order;
}
private TradeOrderDO createTradeOrder(Long userId, String clientIp, AppTradeOrderCreateReqVO createReqVO,
TradePriceCalculateRespBO calculateRespBO) {
private TradeOrderDO buildTradeOrder(Long userId, String clientIp, AppTradeOrderCreateReqVO createReqVO,
TradePriceCalculateRespBO calculateRespBO) {
TradeOrderDO order = TradeOrderConvert.INSTANCE.convert(userId, clientIp, createReqVO, calculateRespBO);
order.setType(calculateRespBO.getType());
order.setNo(tradeNoRedisDAO.generate(TradeNoRedisDAO.TRADE_ORDER_NO_PREFIX));
@@ -235,33 +234,27 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
order.setPickUpVerifyCode(RandomUtil.randomNumbers(8)); // 随机一个核销码,长度为 8 位
}
// TODO @疯狂:是不是可以在这里设置下推广人哈;
tradeOrderMapper.insert(order);
return order;
}
private List<TradeOrderItemDO> createTradeOrderItems(TradeOrderDO tradeOrderDO,
TradePriceCalculateRespBO calculateRespBO) {
List<TradeOrderItemDO> orderItems = TradeOrderConvert.INSTANCE.convertList(tradeOrderDO, calculateRespBO);
tradeOrderItemMapper.insertBatch(orderItems);
return orderItems;
private List<TradeOrderItemDO> buildTradeOrderItems(TradeOrderDO tradeOrderDO,
TradePriceCalculateRespBO calculateRespBO) {
return TradeOrderConvert.INSTANCE.convertList(tradeOrderDO, calculateRespBO);
}
/**
* 订单创建前,执行前置逻辑
*
* @param userId 用户编号
* @param createReqVO 创建订单请求
* @param calculateRespBO 订单价格计算结果
* @param order 订单
* @param orderItems 订单项
*/
private void beforeCreateTradeOrder(Long userId, AppTradeOrderCreateReqVO createReqVO,
TradePriceCalculateRespBO calculateRespBO) {
private void beforeCreateTradeOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
// 1. 执行订单创建前置处理器
// TODO @puhui999这里有个纠结点handler 的定义是只处理指定类型的订单的拓展逻辑;还是通用的 handler类似可以处理优惠劵等等
tradeOrderHandlers.forEach(handler ->
handler.beforeOrderCreate(TradeOrderConvert.INSTANCE.convert(userId, createReqVO, calculateRespBO)));
tradeOrderHandlers.forEach(handler -> handler.beforeOrderCreate(order, orderItems));
// 2. 下单时扣减商品库存
productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convertNegative(createReqVO.getItems()));
productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convertNegative(orderItems));
}
/**
@@ -269,22 +262,19 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
* <p>
* 例如说:优惠劵的扣减、积分的扣减、支付单的创建等等
*
* @param userId 用户编号
* @param order 订单
* @param orderItems 订单项
* @param createReqVO 创建订单请求
* @param order 交易订单
* @param calculateRespBO 订单价格计算结果
*/
private void afterCreateTradeOrder(Long userId, AppTradeOrderCreateReqVO createReqVO,
TradeOrderDO order, List<TradeOrderItemDO> orderItems,
TradePriceCalculateRespBO calculateRespBO) {
private void afterCreateTradeOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems,
AppTradeOrderCreateReqVO createReqVO) {
// 1. 执行订单创建后置处理器
tradeOrderHandlers.forEach(handler -> handler.afterOrderCreate(
TradeOrderConvert.INSTANCE.convert(userId, createReqVO, order, orderItems)));
tradeOrderHandlers.forEach(handler -> handler.afterOrderCreate(order, orderItems));
// 2. 有使用优惠券时更新
// 不在前置扣减的原因,是因为优惠劵要记录使用的订单号
if (createReqVO.getCouponId() != null) {
couponApi.useCoupon(new CouponUseReqDTO().setId(createReqVO.getCouponId()).setUserId(userId)
if (order.getCouponId() != null) {
couponApi.useCoupon(new CouponUseReqDTO().setId(order.getCouponId()).setUserId(order.getUserId())
.setOrderId(order.getId()));
}
@@ -295,11 +285,11 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
// 4. 删除购物车商品
Set<Long> cartIds = convertSet(createReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCartId);
if (CollUtil.isNotEmpty(cartIds)) {
cartService.deleteCart(userId, cartIds);
cartService.deleteCart(order.getUserId(), cartIds);
}
// 5. 生成预支付
createPayOrder(order, orderItems, calculateRespBO);
createPayOrder(order, orderItems);
// 6. 插入订单日志
TradeOrderLogUtils.setOrderInfo(order.getId(), null, order.getStatus());
@@ -313,11 +303,10 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
// TODO @LeeYan9: 是可以思考下, 订单的营销优惠记录, 应该记录在哪里, 微信讨论起来!
}
private void createPayOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems,
TradePriceCalculateRespBO calculateRespBO) {
private void createPayOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
// 创建支付单,用于后续的支付
PayOrderCreateReqDTO payOrderCreateReqDTO = TradeOrderConvert.INSTANCE.convert(
order, orderItems, calculateRespBO, tradeOrderProperties);
order, orderItems, tradeOrderProperties);
Long payOrderId = payOrderApi.createOrder(payOrderCreateReqDTO);
// 更新到交易单上
@@ -343,8 +332,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
}
// 3、订单支付成功后
tradeOrderHandlers.forEach(tradeOrderHandler -> tradeOrderHandler.afterPayOrder(new TradeAfterPayOrderReqBO()
.setOrderId(order.getId()).setOrderType(order.getType()).setUserId(order.getUserId()).setPayTime(LocalDateTime.now())));
tradeOrderHandlers.forEach(handler -> handler.afterPayOrder(order));
// 4.1 增加用户积分(赠送)
addUserPoint(order.getUserId(), order.getGivePoint(), MemberPointBizTypeEnum.ORDER_GIVE, order.getId());

View File

@@ -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;
}
}

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -2,11 +2,13 @@ package cn.iocoder.yudao.module.trade.service.order.handler;
import cn.hutool.core.util.ObjectUtil;
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.service.order.bo.TradeBeforeOrderCreateReqBO;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
/**
* 砍价订单 handler 实现类
@@ -19,21 +21,14 @@ public class TradeBargainHandler implements TradeOrderHandler {
@Resource
private BargainActivityApi bargainActivityApi;
// TODO @puhui999先临时写在这里在价格计算时如果是秒杀商品需要校验如下条件
// 1. 商品存在、库存充足、单次限购;
// 2. 活动进行中、时间段符合
@Override
public void beforeOrderCreate(TradeBeforeOrderCreateReqBO reqBO) {
// 如果是砍价订单
if (ObjectUtil.notEqual(TradeOrderTypeEnum.BARGAIN.getType(), reqBO.getOrderType())) {
public void beforeOrderCreate(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
if (ObjectUtil.notEqual(TradeOrderTypeEnum.BARGAIN.getType(), order.getType())) {
return;
}
// 获取商品信息
TradeBeforeOrderCreateReqBO.Item item = reqBO.getItems().get(0);
// 扣减砍价活动的库存
bargainActivityApi.updateBargainActivityStock(reqBO.getBargainActivityId(), item.getCount());
bargainActivityApi.updateBargainActivityStock(order.getBargainActivityId(),
orderItems.get(0).getCount());
}
}

View File

@@ -1,12 +1,6 @@
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.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 javax.annotation.Resource;
@@ -22,38 +16,38 @@ public class TradeCombinationHandler implements TradeOrderHandler {
@Resource
private CombinationRecordApi combinationRecordApi;
@Override
public void beforeOrderCreate(TradeBeforeOrderCreateReqBO reqBO) {
// 如果不是拼团订单则结束
if (ObjectUtil.notEqual(TradeOrderTypeEnum.COMBINATION.getType(), reqBO.getOrderType())) {
return;
}
// @Override
// public void beforeOrderCreate(TradeBeforeOrderCreateReqBO reqBO) {
// // 如果不是拼团订单则结束
// if (ObjectUtil.notEqual(TradeOrderTypeEnum.COMBINATION.getType(), reqBO.getOrderType())) {
// return;
// }
//
// // 获取商品信息
// TradeBeforeOrderCreateReqBO.Item item = reqBO.getItems().get(0);
// // 校验是否满足拼团活动相关限制
// combinationRecordApi.validateCombinationRecord(reqBO.getCombinationActivityId(), reqBO.getUserId(), item.getSkuId(), item.getCount());
// }
// 获取商品信息
TradeBeforeOrderCreateReqBO.Item item = reqBO.getItems().get(0);
// 校验是否满足拼团活动相关限制
combinationRecordApi.validateCombinationRecord(reqBO.getCombinationActivityId(), reqBO.getUserId(), item.getSkuId(), item.getCount());
}
// @Override
// public void afterOrderCreate(TradeAfterOrderCreateReqBO reqBO) {
// if (reqBO.getCombinationActivityId() == null) {
// return;
// }
//
// // 创建砍价记录
// combinationRecordApi.createCombinationRecord(TradeOrderConvert.INSTANCE.convert(reqBO));
// }
@Override
public void afterOrderCreate(TradeAfterOrderCreateReqBO reqBO) {
if (reqBO.getCombinationActivityId() == null) {
return;
}
// 创建砍价记录
combinationRecordApi.createCombinationRecord(TradeOrderConvert.INSTANCE.convert(reqBO));
}
@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());
}
// @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());
// }
}

View File

@@ -1,8 +1,9 @@
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.service.order.bo.TradeAfterPayOrderReqBO;
import cn.iocoder.yudao.module.trade.service.order.bo.TradeBeforeOrderCreateReqBO;
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
import java.util.List;
/**
* 订单活动特殊逻辑处理器 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) {}
/**
* 订单取消

View File

@@ -2,11 +2,13 @@ package cn.iocoder.yudao.module.trade.service.order.handler;
import cn.hutool.core.util.ObjectUtil;
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.service.order.bo.TradeBeforeOrderCreateReqBO;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
/**
* 秒杀订单 handler 实现类
@@ -19,21 +21,14 @@ public class TradeSeckillHandler implements TradeOrderHandler {
@Resource
private SeckillActivityApi seckillActivityApi;
// TODO @puhui999先临时写在这里在价格计算时如果是秒杀商品需要校验如下条件
// 1. 商品存在、库存充足、单次限购;
// 2. 活动进行中、时间段符合
@Override
public void beforeOrderCreate(TradeBeforeOrderCreateReqBO reqBO) {
// 如果是秒杀订单:额外扣减秒杀的库存;
if (ObjectUtil.notEqual(TradeOrderTypeEnum.SECKILL.getType(), reqBO.getOrderType())) {
public void beforeOrderCreate(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
if (ObjectUtil.notEqual(TradeOrderTypeEnum.SECKILL.getType(), order.getType())) {
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());
}
}

View File

@@ -81,9 +81,9 @@ public class TradePriceCalculateReqBO {
// ========== 砍价活动相关字段 ==========
/**
* 砍价活动编号
* 砍价记录编号
*/
private Long bargainActivityId;
private Long bargainRecordId;
/**
* 商品 SKU

View File

@@ -58,6 +58,11 @@ public class TradePriceCalculateRespBO {
*/
private Integer givePoint;
/**
* 砍价活动编号
*/
private Long bargainActivityId;
/**
* 订单价格
*/

View File

@@ -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());
}
}

View File

@@ -14,6 +14,10 @@ import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO;
public interface TradePriceCalculator {
int ORDER_MEMBER_LEVEL = 5;
int ORDER_SECKILL_ACTIVITY = 8;
int ORDER_BARGAIN_ACTIVITY = 8;
int ORDER_DISCOUNT_ACTIVITY = 10;
int ORDER_REWARD_ACTIVITY = 20;
int ORDER_COUPON = 30;

View File

@@ -23,7 +23,7 @@ import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.PRICE_CALCU
* @author HUIHUI
*/
@Component
@Order(TradePriceCalculator.ORDER_DISCOUNT_ACTIVITY)
@Order(TradePriceCalculator.ORDER_SECKILL_ACTIVITY)
public class TradeSeckillActivityPriceCalculator implements TradePriceCalculator {
@Resource