【功能完善】商城: APP 完善积分商城活动下单
This commit is contained in:
parent
d7236068b9
commit
67809be46d
|
@ -21,5 +21,22 @@ public interface PointActivityApi {
|
||||||
*/
|
*/
|
||||||
PointValidateJoinRespDTO validateJoinPointActivity(Long activityId, Long skuId, Integer count);
|
PointValidateJoinRespDTO validateJoinPointActivity(Long activityId, Long skuId, Integer count);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新积分商城商品库存(减少)
|
||||||
|
*
|
||||||
|
* @param id 活动编号
|
||||||
|
* @param skuId sku 编号
|
||||||
|
* @param count 数量(正数)
|
||||||
|
*/
|
||||||
|
void updatePointStockDecr(Long id, Long skuId, Integer count);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新积分商城商品库存(增加)
|
||||||
|
*
|
||||||
|
* @param id 活动编号
|
||||||
|
* @param skuId sku 编号
|
||||||
|
* @param count 数量(正数)
|
||||||
|
*/
|
||||||
|
void updatePointStockIncr(Long id, Long skuId, Integer count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,4 +23,14 @@ public class PointActivityApiImpl implements PointActivityApi {
|
||||||
return pointActivityService.validateJoinPointActivity(activityId, skuId, count);
|
return pointActivityService.validateJoinPointActivity(activityId, skuId, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updatePointStockDecr(Long id, Long skuId, Integer count) {
|
||||||
|
pointActivityService.updatePointStockDecr(id, skuId, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updatePointStockIncr(Long id, Long skuId, Integer count) {
|
||||||
|
pointActivityService.updatePointStockIncr(id, skuId, count);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
package cn.iocoder.yudao.module.promotion.dal.mysql.point;
|
package cn.iocoder.yudao.module.promotion.dal.mysql.point;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
import cn.iocoder.yudao.module.promotion.controller.admin.point.vo.activity.PointActivityPageReqVO;
|
import cn.iocoder.yudao.module.promotion.controller.admin.point.vo.activity.PointActivityPageReqVO;
|
||||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.point.PointActivityDO;
|
import cn.iocoder.yudao.module.promotion.dal.dataobject.point.PointActivityDO;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,4 +27,33 @@ public interface PointActivityMapper extends BaseMapperX<PointActivityDO> {
|
||||||
.orderByDesc(PointActivityDO::getId));
|
.orderByDesc(PointActivityDO::getId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新活动库存(减少)
|
||||||
|
*
|
||||||
|
* @param id 活动编号
|
||||||
|
* @param count 扣减的库存数量(正数)
|
||||||
|
* @return 影响的行数
|
||||||
|
*/
|
||||||
|
default int updateStockDecr(Long id, int count) {
|
||||||
|
Assert.isTrue(count > 0);
|
||||||
|
return update(null, new LambdaUpdateWrapper<PointActivityDO>()
|
||||||
|
.eq(PointActivityDO::getId, id)
|
||||||
|
.ge(PointActivityDO::getStock, count)
|
||||||
|
.setSql("stock = stock - " + count));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新活动库存(增加)
|
||||||
|
*
|
||||||
|
* @param id 活动编号
|
||||||
|
* @param count 增加的库存数量(正数)
|
||||||
|
* @return 影响的行数
|
||||||
|
*/
|
||||||
|
default int updateStockIncr(Long id, int count) {
|
||||||
|
Assert.isTrue(count > 0);
|
||||||
|
return update(null, new LambdaUpdateWrapper<PointActivityDO>()
|
||||||
|
.eq(PointActivityDO::getId, id)
|
||||||
|
.setSql("stock = stock + " + count));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package cn.iocoder.yudao.module.promotion.dal.mysql.point;
|
package cn.iocoder.yudao.module.promotion.dal.mysql.point;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.point.PointProductDO;
|
import cn.iocoder.yudao.module.promotion.dal.dataobject.point.PointProductDO;
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
|
@ -34,4 +35,32 @@ public interface PointProductMapper extends BaseMapperX<PointProductDO> {
|
||||||
PointProductDO::getSkuId, skuId);
|
PointProductDO::getSkuId, skuId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新活动库存(减少)
|
||||||
|
*
|
||||||
|
* @param id 活动编号
|
||||||
|
* @param count 扣减的库存数量(减少库存)
|
||||||
|
* @return 影响的行数
|
||||||
|
*/
|
||||||
|
default int updateStockDecr(Long id, int count) {
|
||||||
|
Assert.isTrue(count > 0);
|
||||||
|
return update(null, new LambdaUpdateWrapper<PointProductDO>()
|
||||||
|
.eq(PointProductDO::getId, id)
|
||||||
|
.ge(PointProductDO::getStock, count)
|
||||||
|
.setSql("stock = stock - " + count));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新活动库存(增加)
|
||||||
|
*
|
||||||
|
* @param id 活动编号
|
||||||
|
* @param count 需要增加的库存(增加库存)
|
||||||
|
* @return 影响的行数
|
||||||
|
*/
|
||||||
|
default int updateStockIncr(Long id, int count) {
|
||||||
|
Assert.isTrue(count > 0);
|
||||||
|
return update(null, new LambdaUpdateWrapper<PointProductDO>()
|
||||||
|
.eq(PointProductDO::getId, id)
|
||||||
|
.setSql("stock = stock + " + count));
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -33,6 +33,24 @@ public interface PointActivityService {
|
||||||
*/
|
*/
|
||||||
void updatePointActivity(@Valid PointActivitySaveReqVO updateReqVO);
|
void updatePointActivity(@Valid PointActivitySaveReqVO updateReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新积分商城商品库存(减少)
|
||||||
|
*
|
||||||
|
* @param id 活动编号
|
||||||
|
* @param skuId sku 编号
|
||||||
|
* @param count 数量(正数)
|
||||||
|
*/
|
||||||
|
void updatePointStockDecr(Long id, Long skuId, Integer count);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新积分商城商品库存(增加)
|
||||||
|
*
|
||||||
|
* @param id 活动编号
|
||||||
|
* @param skuId sku 编号
|
||||||
|
* @param count 数量(正数)
|
||||||
|
*/
|
||||||
|
void updatePointStockIncr(Long id, Long skuId, Integer count);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 关闭积分商城活动
|
* 关闭积分商城活动
|
||||||
*
|
*
|
||||||
|
|
|
@ -103,6 +103,43 @@ public class PointActivityServiceImpl implements PointActivityService {
|
||||||
updateSeckillProduct(updateObj, updateReqVO.getProducts());
|
updateSeckillProduct(updateObj, updateReqVO.getProducts());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void updatePointStockDecr(Long id, Long skuId, Integer count) {
|
||||||
|
// 1.1 校验活动库存是否充足
|
||||||
|
PointActivityDO activity = validatePointActivityExists(id);
|
||||||
|
if (count > activity.getStock()) {
|
||||||
|
throw exception(POINT_ACTIVITY_UPDATE_STOCK_FAIL);
|
||||||
|
}
|
||||||
|
// 1.2 校验商品库存是否充足
|
||||||
|
PointProductDO product = pointProductMapper.selectListByActivityIdAndSkuId(id, skuId);
|
||||||
|
if (product == null || count > product.getStock()) {
|
||||||
|
throw exception(POINT_ACTIVITY_UPDATE_STOCK_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2.1 更新活动商品库存
|
||||||
|
int updateCount = pointProductMapper.updateStockDecr(product.getId(), count);
|
||||||
|
if (updateCount == 0) {
|
||||||
|
throw exception(POINT_ACTIVITY_UPDATE_STOCK_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2.2 更新活动库存
|
||||||
|
updateCount = pointActivityMapper.updateStockDecr(id, count);
|
||||||
|
if (updateCount == 0) {
|
||||||
|
throw exception(POINT_ACTIVITY_UPDATE_STOCK_FAIL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void updatePointStockIncr(Long id, Long skuId, Integer count) {
|
||||||
|
PointProductDO product = pointProductMapper.selectListByActivityIdAndSkuId(id, skuId);
|
||||||
|
// 更新活动商品库存
|
||||||
|
pointProductMapper.updateStockIncr(product.getId(), count);
|
||||||
|
// 更新活动库存
|
||||||
|
pointActivityMapper.updateStockIncr(id, count);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void closePointActivity(Long id) {
|
public void closePointActivity(Long id) {
|
||||||
|
|
|
@ -160,7 +160,7 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
|
||||||
public void updateSeckillStockDecr(Long id, Long skuId, Integer count) {
|
public void updateSeckillStockDecr(Long id, Long skuId, Integer count) {
|
||||||
// 1.1 校验活动库存是否充足
|
// 1.1 校验活动库存是否充足
|
||||||
SeckillActivityDO seckillActivity = validateSeckillActivityExists(id);
|
SeckillActivityDO seckillActivity = validateSeckillActivityExists(id);
|
||||||
if (count > seckillActivity.getTotalStock()) {
|
if (count > seckillActivity.getStock()) {
|
||||||
throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL);
|
throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL);
|
||||||
}
|
}
|
||||||
// 1.2 校验商品库存是否充足
|
// 1.2 校验商品库存是否充足
|
||||||
|
|
|
@ -55,4 +55,8 @@ public enum TradeOrderTypeEnum implements IntArrayValuable {
|
||||||
return ObjectUtil.equal(type, COMBINATION.getType());
|
return ObjectUtil.equal(type, COMBINATION.getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isPoint(Integer type) {
|
||||||
|
return ObjectUtil.equal(type, POINT.getType());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -353,4 +353,11 @@ public class TradeOrderDO extends BaseDO {
|
||||||
*/
|
*/
|
||||||
private Long combinationRecordId;
|
private Long combinationRecordId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 积分商城活动的编号
|
||||||
|
*
|
||||||
|
* 关联 PointActivityDO 的 id 字段
|
||||||
|
*/
|
||||||
|
private Long pointActivityId;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
package cn.iocoder.yudao.module.trade.service.order.handler;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.core.lang.Assert;
|
||||||
|
import cn.iocoder.yudao.module.promotion.api.point.PointActivityApi;
|
||||||
|
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 jakarta.annotation.Resource;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 积分商城活动订单的 {@link TradeOrderHandler} 实现类
|
||||||
|
*
|
||||||
|
* @author HUIHUI
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class TradePointOrderHandler implements TradeOrderHandler {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private PointActivityApi pointActivityApi;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeOrderCreate(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
|
||||||
|
if (!TradeOrderTypeEnum.isPoint(order.getType())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 明确校验一下
|
||||||
|
Assert.isTrue(orderItems.size() == 1, "积分商城活动兑换商品兑换时,只允许选择一个商品");
|
||||||
|
|
||||||
|
// 扣减积分商城活动的库存
|
||||||
|
pointActivityApi.updatePointStockDecr(order.getPointActivityId(),
|
||||||
|
orderItems.get(0).getSkuId(), orderItems.get(0).getCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterCancelOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
|
||||||
|
if (!TradeOrderTypeEnum.isPoint(order.getType())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 明确校验一下
|
||||||
|
Assert.isTrue(orderItems.size() == 1, "积分商城活动兑换商品兑换时,只允许选择一个商品");
|
||||||
|
|
||||||
|
// 售后的订单项,已经在 afterCancelOrderItem 回滚库存,所以这里不需要重复回滚
|
||||||
|
orderItems = filterOrderItemListByNoneAfterSale(orderItems);
|
||||||
|
if (CollUtil.isEmpty(orderItems)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
afterCancelOrderItem(order, orderItems.get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterCancelOrderItem(TradeOrderDO order, TradeOrderItemDO orderItem) {
|
||||||
|
if (!TradeOrderTypeEnum.isPoint(order.getType())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 恢复积分商城活动的库存
|
||||||
|
pointActivityApi.updatePointStockIncr(order.getPointActivityId(),
|
||||||
|
orderItem.getSkuId(), orderItem.getCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -63,15 +63,18 @@ public class TradePointActivityPriceCalculator implements TradePriceCalculator {
|
||||||
// 3.1 记录优惠明细
|
// 3.1 记录优惠明细
|
||||||
int discountPrice = orderItem.getPayPrice(); // 情况一:单使用积分兑换
|
int discountPrice = orderItem.getPayPrice(); // 情况一:单使用积分兑换
|
||||||
Assert.isTrue(activity.getPoint() >= 1, "积分商城商品兑换积分必须大于 1");
|
Assert.isTrue(activity.getPoint() >= 1, "积分商城商品兑换积分必须大于 1");
|
||||||
result.setUsePoint(activity.getPoint());
|
result.setUsePoint(activity.getPoint() * orderItem.getCount());
|
||||||
|
orderItem.setUsePoint(activity.getPoint() * orderItem.getCount());
|
||||||
if (activity.getPrice() != null && activity.getPrice() > 0) { // 情况二:积分 + 金额
|
if (activity.getPrice() != null && activity.getPrice() > 0) { // 情况二:积分 + 金额
|
||||||
discountPrice = orderItem.getPayPrice() - activity.getPrice() * orderItem.getCount();
|
discountPrice = orderItem.getPayPrice() - activity.getPrice() * orderItem.getCount();
|
||||||
}
|
}
|
||||||
|
// 3.2 记录优惠明细
|
||||||
TradePriceCalculatorHelper.addPromotion(result, orderItem,
|
TradePriceCalculatorHelper.addPromotion(result, orderItem,
|
||||||
param.getPointActivityId(), "积分商城活动", PromotionTypeEnum.POINT.getType(),
|
param.getPointActivityId(), "积分商城活动", PromotionTypeEnum.POINT.getType(),
|
||||||
StrUtil.format("积分商城活动:省 {} 元", TradePriceCalculatorHelper.formatPrice(discountPrice)),
|
StrUtil.format("积分商城活动:省 {} 元", TradePriceCalculatorHelper.formatPrice(discountPrice)),
|
||||||
discountPrice);
|
discountPrice);
|
||||||
// 3.2 更新 SKU 优惠金额
|
|
||||||
|
// 3.3 更新 SKU 优惠金额
|
||||||
orderItem.setDiscountPrice(orderItem.getDiscountPrice() + discountPrice);
|
orderItem.setDiscountPrice(orderItem.getDiscountPrice() + discountPrice);
|
||||||
TradePriceCalculatorHelper.recountPayPrice(orderItem);
|
TradePriceCalculatorHelper.recountPayPrice(orderItem);
|
||||||
TradePriceCalculatorHelper.recountAllPrice(result);
|
TradePriceCalculatorHelper.recountAllPrice(result);
|
||||||
|
|
Loading…
Reference in New Issue