mirror of
https://gitee.com/hhyykk/ipms-sjy.git
synced 2025-08-12 09:11:53 +08:00
【代码优化】商城: 满减送活动
This commit is contained in:
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.trade.dal.dataobject.order;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.TerminalEnum;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler;
|
||||
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
|
||||
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageUserDO;
|
||||
import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO;
|
||||
@@ -18,6 +19,7 @@ import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||
import lombok.*;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -294,17 +296,23 @@ public class TradeOrderDO extends BaseDO {
|
||||
*/
|
||||
private Integer vipPrice;
|
||||
|
||||
// TODO @puhui999:项了下,貌似这里存储 List<Long> giveCouponIds 更合适。因为优惠劵赠送到最后是对应的编号,然后从而进行取消?
|
||||
/**
|
||||
* 赠送的优惠劵
|
||||
*
|
||||
* key: 优惠劵编号
|
||||
* value:对应的优惠券数量
|
||||
*
|
||||
* 目的:用于后续取消或者售后订单时,需要扣减赠送
|
||||
* 目的:用于订单支付后赠送优惠券
|
||||
*/
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private Map<Long, Integer> giveCouponsMap;
|
||||
/**
|
||||
* 赠送的优惠劵编号
|
||||
*
|
||||
* 目的:用于后续取消或者售后订单时,需要扣减赠送
|
||||
*/
|
||||
@TableField(typeHandler = LongListTypeHandler.class)
|
||||
private List<Long> giveCouponIds;
|
||||
|
||||
/**
|
||||
* 秒杀活动编号
|
||||
|
@@ -11,6 +11,8 @@ import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderI
|
||||
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 交易订单【写】Service 接口
|
||||
*
|
||||
@@ -194,4 +196,13 @@ public interface TradeOrderUpdateService {
|
||||
*/
|
||||
void cancelPaidOrder(Long userId, Long orderId, Integer cancelType);
|
||||
|
||||
/**
|
||||
* 更新下单赠送的优惠券编号到订单
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param orderId 订单编号
|
||||
* @param giveCouponIds 赠送的优惠券编号列表
|
||||
*/
|
||||
void updateOrderGiveCouponIds(Long userId, Long orderId, List<Long> giveCouponIds);
|
||||
|
||||
}
|
||||
|
@@ -202,7 +202,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
||||
order.setProductCount(getSumValue(calculateRespBO.getItems(), TradePriceCalculateRespBO.OrderItem::getCount, Integer::sum));
|
||||
order.setUserIp(getClientIP()).setTerminal(getTerminal());
|
||||
// 使用 + 赠送优惠券
|
||||
order.setGiveCouponsMap(calculateRespBO.getGiveCouponsMap());
|
||||
order.setGiveCouponsMap(calculateRespBO.getGiveCoupons());
|
||||
// 支付 + 退款信息
|
||||
order.setAdjustPrice(0).setPayStatus(false);
|
||||
order.setRefundStatus(TradeOrderRefundStatusEnum.NONE.getStatus()).setRefundPrice(0);
|
||||
@@ -890,6 +890,22 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
||||
.setReason(TradeOrderCancelTypeEnum.COMBINATION_CLOSE.getName()).setPrice(order.getPayPrice()));// 价格信息
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateOrderGiveCouponIds(Long userId, Long orderId, List<Long> giveCouponIds) {
|
||||
// 1.1 检验订单存在
|
||||
TradeOrderDO order = tradeOrderMapper.selectOrderByIdAndUserId(orderId, userId);
|
||||
if (order == null) {
|
||||
throw exception(ORDER_NOT_FOUND);
|
||||
}
|
||||
// 1.2 校验订单是否支付
|
||||
if (!order.getPayStatus()) {
|
||||
throw exception(ORDER_CANCEL_PAID_FAIL, "已支付");
|
||||
}
|
||||
|
||||
// 2. 更新订单赠送的优惠券编号列表
|
||||
tradeOrderMapper.updateById(new TradeOrderDO().setId(orderId).setGiveCouponIds(giveCouponIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建单个订单的评论
|
||||
*
|
||||
|
@@ -5,7 +5,10 @@ import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi;
|
||||
import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO;
|
||||
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.service.order.TradeOrderQueryService;
|
||||
import cn.iocoder.yudao.module.trade.service.order.TradeOrderUpdateService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
@@ -18,6 +21,12 @@ import java.util.List;
|
||||
@Component
|
||||
public class TradeCouponOrderHandler implements TradeOrderHandler {
|
||||
|
||||
@Resource
|
||||
@Lazy // 延迟加载,避免循环依赖
|
||||
private TradeOrderUpdateService orderUpdateService;
|
||||
@Resource
|
||||
private TradeOrderQueryService orderQueryService;
|
||||
|
||||
@Resource
|
||||
private CouponApi couponApi;
|
||||
|
||||
@@ -37,7 +46,11 @@ public class TradeCouponOrderHandler implements TradeOrderHandler {
|
||||
return;
|
||||
}
|
||||
// 赠送优惠券
|
||||
couponApi.takeCouponsByAdmin(order.getGiveCouponsMap(), order.getUserId());
|
||||
List<Long> couponIds = couponApi.takeCouponsByAdmin(order.getGiveCouponsMap(), order.getUserId());
|
||||
if (CollUtil.isEmpty(couponIds)) {
|
||||
return;
|
||||
}
|
||||
orderUpdateService.updateOrderGiveCouponIds(order.getUserId(), order.getId(), couponIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -48,10 +61,10 @@ public class TradeCouponOrderHandler implements TradeOrderHandler {
|
||||
couponApi.returnUsedCoupon(order.getCouponId());
|
||||
}
|
||||
// 情况二:收回赠送的优惠券
|
||||
if (CollUtil.isEmpty(order.getGiveCouponsMap())) {
|
||||
if (CollUtil.isEmpty(order.getGiveCouponIds())) {
|
||||
return;
|
||||
}
|
||||
couponApi.invalidateCouponsByAdmin(order.getGiveCouponsMap(), order.getUserId());
|
||||
couponApi.invalidateCouponsByAdmin(order.getGiveCouponIds(), order.getUserId());
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -79,7 +79,7 @@ public class TradePriceCalculateRespBO {
|
||||
* key: 优惠劵编号,value:对应的优惠券数量
|
||||
* 目的:用于后续取消或者售后订单时,需要扣减赠送
|
||||
*/
|
||||
private Map<Long, Integer> giveCouponsMap;
|
||||
private Map<Long, Integer> giveCoupons;
|
||||
|
||||
/**
|
||||
* 订单价格
|
||||
|
@@ -32,7 +32,7 @@ public class TradePriceCalculatorHelper {
|
||||
List<ProductSpuRespDTO> spuList, List<ProductSkuRespDTO> skuList) {
|
||||
// 创建 PriceCalculateRespDTO 对象
|
||||
TradePriceCalculateRespBO result = new TradePriceCalculateRespBO();
|
||||
result.setType(getOrderType(param)).setPromotions(new ArrayList<>()).setGiveCouponsMap(new LinkedHashMap<>());
|
||||
result.setType(getOrderType(param)).setPromotions(new ArrayList<>()).setGiveCoupons(new LinkedHashMap<>());
|
||||
|
||||
// 创建它的 OrderItem 属性
|
||||
result.setItems(new ArrayList<>(param.getItems().size()));
|
||||
|
@@ -93,7 +93,7 @@ public class TradeRewardActivityPriceCalculator implements TradePriceCalculator
|
||||
TradePriceCalculatorHelper.recountAllPrice(result);
|
||||
|
||||
// 4.1 记录赠送的积分
|
||||
if (Boolean.TRUE.equals(rule.getGivePoint())) {
|
||||
if (rule.getPoint() != null && rule.getPoint() > 0) {
|
||||
List<Integer> dividePoints = TradePriceCalculatorHelper.dividePrice(orderItems, rule.getPoint());
|
||||
for (int i = 0; i < orderItems.size(); i++) {
|
||||
// 商品可能赠送了积分,所以这里要加上
|
||||
@@ -107,13 +107,13 @@ public class TradeRewardActivityPriceCalculator implements TradePriceCalculator
|
||||
result.setFreeDelivery(true);
|
||||
}
|
||||
// 4.3 记录赠送的优惠券
|
||||
if (Boolean.TRUE.equals(rule.getGiveCoupon())) {
|
||||
for (Map.Entry<Long, Integer> entry : rule.getGiveCouponsMap().entrySet()) {
|
||||
Map<Long, Integer> giveCouponsMap = result.getGiveCouponsMap();
|
||||
if (giveCouponsMap.get(entry.getKey()) == null) { // 情况一:还没有赠送的优惠券
|
||||
result.setGiveCouponsMap(rule.getGiveCouponsMap());
|
||||
if (CollUtil.isNotEmpty(rule.getGiveCoupons())) {
|
||||
for (Map.Entry<Long, Integer> entry : rule.getGiveCoupons().entrySet()) {
|
||||
Map<Long, Integer> giveCoupons = result.getGiveCoupons();
|
||||
if (giveCoupons.get(entry.getKey()) == null) { // 情况一:还没有赠送的优惠券
|
||||
result.setGiveCoupons(rule.getGiveCoupons());
|
||||
} else { // 情况二:别的满减活动送过同类优惠券,则直接增加数量
|
||||
giveCouponsMap.put(entry.getKey(), giveCouponsMap.get(entry.getKey()) + entry.getValue());
|
||||
giveCoupons.put(entry.getKey(), giveCoupons.get(entry.getKey()) + entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -49,7 +49,7 @@ public class TradeRewardActivityPriceCalculatorTest extends BaseMockitoUnitTest
|
||||
TradePriceCalculateRespBO result = new TradePriceCalculateRespBO()
|
||||
.setType(TradeOrderTypeEnum.NORMAL.getType())
|
||||
.setPrice(new TradePriceCalculateRespBO.Price())
|
||||
.setPromotions(new ArrayList<>()).setGiveCouponsMap(new LinkedHashMap<>())
|
||||
.setPromotions(new ArrayList<>()).setGiveCoupons(new LinkedHashMap<>())
|
||||
.setItems(asList(
|
||||
new TradePriceCalculateRespBO.OrderItem().setSkuId(10L).setCount(2).setSelected(true)
|
||||
.setPrice(100).setSpuId(1L),
|
||||
@@ -68,16 +68,16 @@ public class TradeRewardActivityPriceCalculatorTest extends BaseMockitoUnitTest
|
||||
.setConditionType(PromotionConditionTypeEnum.PRICE.getType())
|
||||
.setProductScope(PromotionProductScopeEnum.SPU.getScope()).setProductScopeValues(asList(1L, 2L))
|
||||
.setRules(singletonList(new RewardActivityMatchRespDTO.Rule().setLimit(20).setDiscountPrice(70)
|
||||
.setGivePoint(false).setFreeDelivery(false)))),
|
||||
.setFreeDelivery(false)))),
|
||||
randomPojo(RewardActivityMatchRespDTO.class, o -> o.setId(2000L).setName("活动 2000 号")
|
||||
.setConditionType(PromotionConditionTypeEnum.COUNT.getType())
|
||||
.setProductScope(PromotionProductScopeEnum.SPU.getScope()).setProductScopeValues(singletonList(3L))
|
||||
.setRules(asList(new RewardActivityMatchRespDTO.Rule().setLimit(1).setDiscountPrice(10)
|
||||
.setGivePoint(true).setPoint(50).setFreeDelivery(false),
|
||||
new RewardActivityMatchRespDTO.Rule().setLimit(2).setDiscountPrice(60).setGivePoint(true)
|
||||
.setPoint(50).setFreeDelivery(false),
|
||||
new RewardActivityMatchRespDTO.Rule().setLimit(2).setDiscountPrice(60)
|
||||
.setPoint(100).setFreeDelivery(false), // 最大可满足,因为是 4 个
|
||||
new RewardActivityMatchRespDTO.Rule().setLimit(10).setDiscountPrice(100)
|
||||
.setGivePoint(false).setFreeDelivery(false))))
|
||||
.setFreeDelivery(false))))
|
||||
));
|
||||
|
||||
// 调用
|
||||
|
Reference in New Issue
Block a user