@@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.trade.service.order;
import cn.hutool.core.collection.CollUtil ;
import cn.hutool.core.lang.Assert ;
import cn.hutool.core.util.IdUtil ;
import cn.hutool.core.util.ObjectUtil ;
import cn.hutool.core.util.StrUtil ;
import cn.hutool.extra.spring.SpringUtil ;
@@ -25,11 +24,14 @@ import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum;
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.promotion.api.bargain.BargainActivityApi ;
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.dto.CombinationRecordRespDTO ;
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.seckill.SeckillActivityApi ;
import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillActivityUpdateStockReqDTO ;
import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum ;
import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO ;
import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderRemarkReqVO ;
@@ -45,6 +47,7 @@ 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.dal.mysql.order.TradeOrderItemMapper ;
import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderMapper ;
import cn.iocoder.yudao.module.trade.dal.redis.no.TradeOrderNoRedisDAO ;
import cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants ;
import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum ;
import cn.iocoder.yudao.module.trade.enums.order.* ;
@@ -70,7 +73,7 @@ import java.util.Set;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception ;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.* ;
import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.ORDER_NOT_FOUND ;
import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.ORDER_UPDATE_PRICE_FAIL_EQUAL ;
import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.ORDER_UPDATE_PRICE_FAIL_PAID ;
import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.* ;
@@ -88,6 +91,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
private TradeOrderMapper tradeOrderMapper ;
@Resource
private TradeOrderItemMapper tradeOrderItemMapper ;
@Resource
private TradeOrderNoRedisDAO orderNoRedisDAO ;
@Resource
private CartService cartService ;
@@ -111,6 +116,10 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
@Resource
private BargainRecordApi bargainRecordApi ;
@Resource
private SeckillActivityApi seckillActivityApi ;
@Resource
private BargainActivityApi bargainActivityApi ;
@Resource
private MemberUserApi memberUserApi ;
@Resource
private MemberLevelApi memberLevelApi ;
@@ -189,22 +198,9 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
// TODO @puhui999: 这个逻辑, 先抽个小方法; 未来要通过设计模式, 把这些拼团之类的逻辑, 抽象出去
// 拼团
if ( Objects . equals ( TradeOrderTypeEnum . COMBINATION . getType ( ) , order . getType ( ) ) ) {
MemberUserRespDTO user = memberUserApi . getUser ( userId ) ;
List < CombinationRecordRespDTO > recordRespDTOS = combinationRecordApi . getRecordListByUserIdAndActivityId ( userId , createReqVO . getCombinationActivityId ( ) ) ;
// TODO 拼团一次应该只能选择一种规格的商品
TradeOrderItemDO orderItemDO = orderItems . get ( 0 ) ;
if ( CollUtil . isNotEmpty ( recordRespDTOS ) ) {
List < Long > skuIds = convertList ( recordRespDTOS , CombinationRecordRespDTO : : getSkuId , item - > ObjectUtil . equals ( item . getStatus ( ) , CombinationRecordStatusEnum . SUCCESS . getStatus ( ) ) ) ;
List < TradeOrderItemDO > tradeOrderItemDOS = tradeOrderItemMapper . selectListByOrderIdAnSkuId ( convertList ( recordRespDTOS ,
CombinationRecordRespDTO : : getOrderId , item - > ObjectUtil . equals ( item . getStatus ( ) , CombinationRecordStatusEnum . SUCCESS . getStatus ( ) ) ) , skuIds ) ;
combinationRecordApi . validateCombinationLimitCount ( createReqVO . getCombinationActivityId ( ) ,
CollectionUtils . getSumValue ( tradeOrderItemDOS , TradeOrderItemDO : : getCount , Integer : : sum ) , orderItemDO . getCount ( ) ) ;
}
combinationRecordApi . createCombinationRecord ( TradeOrderConvert . INSTANCE . convert ( order , orderItemDO , createReqVO , user ) ) ;
createCombinationRecord ( userId , createReqVO , orderItems , order ) ;
}
// 3.2 秒杀的特殊逻辑
// TODO 秒杀扣减库存是下单就扣除还是等待订单支付成功再扣除
if ( Objects . equals ( TradeOrderTypeEnum . SECKILL . getType ( ) , order . getType ( ) ) ) {
}
@@ -214,6 +210,22 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
return order ;
}
private void createCombinationRecord ( Long userId , AppTradeOrderCreateReqVO createReqVO , List < TradeOrderItemDO > orderItems , TradeOrderDO order ) {
MemberUserRespDTO user = memberUserApi . getUser ( userId ) ;
List < CombinationRecordRespDTO > recordRespDTOS = combinationRecordApi . getRecordListByUserIdAndActivityId ( userId , createReqVO . getCombinationActivityId ( ) ) ;
// TODO 拼团一次应该只能选择一种规格的商品
TradeOrderItemDO orderItemDO = orderItems . get ( 0 ) ;
if ( CollUtil . isNotEmpty ( recordRespDTOS ) ) {
List < Long > skuIds = convertList ( recordRespDTOS , CombinationRecordRespDTO : : getSkuId , item - > ObjectUtil . equals ( item . getStatus ( ) , CombinationRecordStatusEnum . SUCCESS . getStatus ( ) ) ) ;
List < TradeOrderItemDO > tradeOrderItemDOS = tradeOrderItemMapper . selectListByOrderIdAnSkuId ( convertList ( recordRespDTOS ,
CombinationRecordRespDTO : : getOrderId , item - > ObjectUtil . equals ( item . getStatus ( ) , CombinationRecordStatusEnum . SUCCESS . getStatus ( ) ) ) , skuIds ) ;
combinationRecordApi . validateCombinationLimitCount ( createReqVO . getCombinationActivityId ( ) ,
CollectionUtils . getSumValue ( tradeOrderItemDOS , TradeOrderItemDO : : getCount , Integer : : sum ) , orderItemDO . getCount ( ) ) ;
}
combinationRecordApi . createCombinationRecord ( TradeOrderConvert . INSTANCE . convert ( order , orderItemDO , createReqVO , user ) ) ;
}
// TODO @puhui999: 订单超时, 自动取消;
/**
@@ -240,8 +252,9 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
address = validateAddress ( userId , createReqVO . getAddressId ( ) ) ;
}
TradeOrderDO order = TradeOrderConvert . INSTANCE . convert ( userId , clientIp , createReqVO , calculateRespBO , address ) ;
String no = orderNoRedisDAO . generate ( TradeOrderNoRedisDAO . TRADE_ORDER_NO_PREFIX ) ;
order . setType ( validateActivity ( createReqVO ) ) ;
order . setNo ( IdUtil . getSnowflakeNextId ( ) + " " ) ; // TODO @puhui999: 参考支付订单,的 no 生成哈 ;
order . setNo ( no ) ;
order . setStatus ( TradeOrderStatusEnum . UNPAID . getStatus ( ) ) ;
order . setRefundStatus ( TradeOrderRefundStatusEnum . NONE . getStatus ( ) ) ;
order . setProductCount ( getSumValue ( calculateRespBO . getItems ( ) , TradePriceCalculateRespBO . OrderItem : : getCount , Integer : : sum ) ) ;
@@ -293,19 +306,23 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
private void afterCreateTradeOrder ( Long userId , AppTradeOrderCreateReqVO createReqVO ,
TradeOrderDO tradeOrderDO , List < TradeOrderItemDO > orderItems ,
TradePriceCalculateRespBO calculateRespBO ) {
// 下单时扣减商品库存
// TODO @puhui999: 扣库存, 需要前置;
Integer count = getSumValue ( orderItems , TradeOrderItemDO : : getCount , Integer : : sum ) ;
// 1) 如果是秒杀商品: 额外扣减秒杀的库存;
// 2) 如果是拼团活动: 额外扣减拼团的库存;
// 3) 如果是砍价活动: 额外扣减砍价的库存;
productSkuApi . updateSkuStock ( TradeOrderConvert . INSTANCE . convertNegative ( orderItems ) ) ;
// 删除购物车商品
Set < Long > cartIds = convertSet ( create ReqV O . getItems ( ) , AppTradeOrderSettlement ReqV O. Item : : getCartId ) ;
if ( CollUtil . isNotEmpty ( cartIds ) ) {
cartService . deleteCart ( userId , cartIds ) ;
if ( Objects . equals ( TradeOrderTypeEnum . SECKILL . getType ( ) , tradeOrderDO . getType ( ) ) ) {
SeckillActivityUpdateStockReqDTO updateStockReqDTO = new SeckillActivityUpdateStockReqDTO ( ) ;
updateStockReqDTO . setActivityId ( createReqVO . getSeckillActivityId ( ) ) ;
updateStockReqDTO . setCount ( count ) ;
updateStockReqDTO . setItems ( CollectionUtils . convertList ( orderItems , item - > {
SeckillActivityUpdateStock ReqDT O . Item item1 = new SeckillActivityUpdateStock ReqDT O. Item ( ) ;
item1 . setSpuId ( item . getSpuId ( ) ) ;
item1 . setSkuId ( item . getSkuId ( ) ) ;
item1 . setCount ( item . getCount ( ) ) ;
return item1 ;
} ) ) ;
seckillActivityApi . updateSeckillStock ( updateStockReqDTO ) ;
}
// 2) 如果是砍价活动: 额外扣减砍价的库存;
bargainActivityApi . updateBargainActivityStock ( createReqVO . getBargainActivityId ( ) , count ) ;
// 扣减积分 TODO 芋艿:待实现,需要前置;
// 这个是不是应该放到支付成功之后?如果支付后的话,可能积分可以重复使用哈。资源类,都要预扣
@@ -315,6 +332,15 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
. setOrderId ( tradeOrderDO . getId ( ) ) ) ;
}
// 下单时扣减商品库存
productSkuApi . updateSkuStock ( TradeOrderConvert . INSTANCE . convertNegative ( orderItems ) ) ;
// 删除购物车商品
Set < Long > cartIds = convertSet ( createReqVO . getItems ( ) , AppTradeOrderSettlementReqVO . Item : : getCartId ) ;
if ( CollUtil . isNotEmpty ( cartIds ) ) {
cartService . deleteCart ( userId , cartIds ) ;
}
// 生成预支付
createPayOrder ( tradeOrderDO , orderItems , calculateRespBO ) ;
@@ -464,11 +490,6 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
*/
private TradeOrderDO validateOrderDeliverable ( Long id ) {
TradeOrderDO order = validateOrderExists ( id ) ;
// 校验订单是否是待发货状态
// TODO @puhui999: 已经发货, 可以重新发货, 修改信息;
if ( ! TradeOrderStatusEnum . isUndelivered ( order . getStatus ( ) ) ) {
throw exception ( ORDER_DELIVERY_FAIL_STATUS_NOT_UNDELIVERED ) ;
}
// 校验订单是否退款
if ( ObjectUtil . notEqual ( TradeOrderRefundStatusEnum . NONE . getStatus ( ) , order . getRefundStatus ( ) ) ) {
throw exception ( ORDER_DELIVERY_FAIL_REFUND_STATUS_NOT_NONE ) ;
@@ -540,14 +561,25 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
if ( order . getPayStatus ( ) ) {
throw exception ( ORDER_UPDATE_PRICE_FAIL_PAID ) ;
}
// TODO @puhui999: 如果改价, 需要校验下是否真的变化;
if ( ObjectUtil . equal ( order . getAdjustPrice ( ) , reqVO . getAdjustPrice ( ) ) ) {
throw exception ( ORDER_UPDATE_PRICE_FAIL_EQUAL ) ;
}
// 更新
// TODO @puhui999: TradeOrderItemDO 需要做 adjustPrice 的分摊;另外,支付订单那的价格,需要 update 下;
List < TradeOrderItemDO > itemDOs = tradeOrderItemMapper . selectListByOrderId ( order . getId ( ) ) ;
// TradeOrderItemDO 需要做 adjustPrice 的分摊
int price = reqVO . getAdjustPrice ( ) / itemDOs . size ( ) ;
itemDOs . forEach ( item - > {
item . setAdjustPrice ( price ) ;
} ) ;
// 更新 TradeOrderItem
tradeOrderItemMapper . updateBatch ( itemDOs ) ;
// 更新订单
TradeOrderDO update = TradeOrderConvert . INSTANCE . convert ( reqVO ) ;
update . setPayPrice ( update . getPayPrice ( ) + update . getAdjustPrice ( ) ) ;
// TODO @芋艿:改价时,赠送的积分,要不要做改动???
tradeOrderMapper . updateById ( update ) ;
// 更新支付订单
payOrderApi . updatePayOrderPriceById ( order . getPayOrderId ( ) , update . getPayPrice ( ) ) ;
}
@Override