diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/point/PointActivityApi.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/point/PointActivityApi.java new file mode 100644 index 000000000..87393d336 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/point/PointActivityApi.java @@ -0,0 +1,54 @@ +package cn.iocoder.yudao.module.promotion.api.point; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.promotion.api.point.dto.PointValidateJoinRespDTO; +import cn.iocoder.yudao.module.promotion.enums.ApiConstants; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestParam; + +@FeignClient(name = ApiConstants.NAME) // TODO 芋艿:fallbackFactory = +@Tag(name = "RPC 服务 - 秒杀活动") +public interface PointActivityApi { + + String PREFIX = ApiConstants.PREFIX + "/point-activity"; + + @GetMapping(PREFIX + "/validate-join") + @Operation(summary = "【下单前】校验是否参与积分商城活动") + @Parameters({ + @Parameter(name = "activityId", description = "活动编号", required = true, example = "1"), + @Parameter(name = "skuId", description = "SKU 编号", required = true, example = "2"), + @Parameter(name = "count", description = "数量", required = true, example = "3"), + }) + CommonResult validateJoinPointActivity(@RequestParam("activityId") Long activityId, + @RequestParam("skuId") Long skuId, + @RequestParam("count")Integer count); + + @PutMapping(PREFIX + "/update-stock-decr") + @Operation(summary = "更新积分商品库存(减少)") + @Parameters({ + @Parameter(name = "id", description = "活动编号", required = true, example = "1"), + @Parameter(name = "skuId", description = "SKU 编号", required = true, example = "2"), + @Parameter(name = "count", description = "数量", required = true, example = "3"), + }) + CommonResult updatePointStockDecr(@RequestParam("id") Long id, + @RequestParam("skuId") Long skuId, + @RequestParam("count")Integer count); + + @PutMapping(PREFIX + "/update-stock-incr") + @Operation(summary = "更新积分商城商品库存(增加)") + @Parameters({ + @Parameter(name = "id", description = "活动编号", required = true, example = "1"), + @Parameter(name = "skuId", description = "SKU 编号", required = true, example = "2"), + @Parameter(name = "count", description = "数量", required = true, example = "3"), + }) + CommonResult updatePointStockIncr(@RequestParam("id") Long id, + @RequestParam("skuId") Long skuId, + @RequestParam("count")Integer count); + +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/point/dto/PointValidateJoinRespDTO.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/point/dto/PointValidateJoinRespDTO.java new file mode 100644 index 000000000..e3b993461 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/point/dto/PointValidateJoinRespDTO.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.promotion.api.point.dto; + +import lombok.Data; + +/** + * 校验参与积分商城 Response DTO + */ +@Data +public class PointValidateJoinRespDTO { + + /** + * 可兑换次数 + */ + private Integer count; + /** + * 所需兑换积分 + */ + private Integer point; + /** + * 所需兑换金额,单位:分 + */ + private Integer price; + +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/SeckillActivityApi.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/SeckillActivityApi.java index e077d0544..bb485eb6b 100644 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/SeckillActivityApi.java +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/SeckillActivityApi.java @@ -40,7 +40,7 @@ public interface SeckillActivityApi { @RequestParam("skuId") Long skuId, @RequestParam("count")Integer count); - @GetMapping("/validate-join") + @GetMapping(PREFIX + "/validate-join") @Operation(summary = "【下单前】校验是否参与秒杀活动") // 如果校验失败,则抛出业务异常 @Parameters({ @Parameter(name = "activityId", description = "活动编号", required = true, example = "1"), diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java index af8206d2d..514cb27af 100644 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java @@ -50,6 +50,10 @@ public interface ErrorCodeConstants { ErrorCode POINT_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1_013_007_002, "积分商城活动已关闭,不能修改"); ErrorCode POINT_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1_013_007_003, "积分商城活动未关闭或未结束,不能删除"); ErrorCode POINT_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1_013_007_004, "积分商城活动已关闭,不能重复关闭"); + ErrorCode POINT_ACTIVITY_JOIN_ACTIVITY_STATUS_CLOSED = new ErrorCode(1_013_007_005, "积分商品兑换失败,原因:积分商城活动已关闭"); + ErrorCode POINT_ACTIVITY_JOIN_ACTIVITY_SINGLE_LIMIT_COUNT_EXCEED = new ErrorCode(1_013_007_006, "积分商品兑换失败,原因:单次限购超出"); + ErrorCode POINT_ACTIVITY_JOIN_ACTIVITY_PRODUCT_NOT_EXISTS = new ErrorCode(1_013_007_007, "积分商品兑换失败,原因:商品不存在"); + ErrorCode POINT_ACTIVITY_UPDATE_STOCK_FAIL = new ErrorCode(1_013_007_008, "积分商品兑换失败,原因:积分商品库存不足"); // ========== 秒杀活动 1-013-008-000 ========== ErrorCode SECKILL_ACTIVITY_NOT_EXISTS = new ErrorCode(1_013_008_000, "秒杀活动不存在"); diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/point/PointActivityApiImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/point/PointActivityApiImpl.java new file mode 100644 index 000000000..1cf556b14 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/point/PointActivityApiImpl.java @@ -0,0 +1,41 @@ +package cn.iocoder.yudao.module.promotion.api.point; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.promotion.api.point.dto.PointValidateJoinRespDTO; +import cn.iocoder.yudao.module.promotion.service.point.PointActivityService; +import jakarta.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.RestController; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +/** + * 积分商城活动 Api 接口实现类 + * + * @author HUIHUI + */ +@RestController // 提供 RESTful API 接口,给 Feign 调用 +@Validated +public class PointActivityApiImpl implements PointActivityApi { + + @Resource + private PointActivityService pointActivityService; + + @Override + public CommonResult validateJoinPointActivity(Long activityId, Long skuId, Integer count) { + return success(pointActivityService.validateJoinPointActivity(activityId, skuId, count)); + } + + @Override + public CommonResult updatePointStockDecr(Long id, Long skuId, Integer count) { + pointActivityService.updatePointStockDecr(id, skuId, count); + return success(true); + } + + @Override + public CommonResult updatePointStockIncr(Long id, Long skuId, Integer count) { + pointActivityService.updatePointStockIncr(id, skuId, count); + return success(true); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/point/AppPointActivityController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/point/AppPointActivityController.java index 533ac8ede..c364b64f2 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/point/AppPointActivityController.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/point/AppPointActivityController.java @@ -76,8 +76,11 @@ public class AppPointActivityController { // 2. 拼接数据 List products = pointActivityService.getPointProductListByActivityIds(Collections.singletonList(id)); - AppPointActivityDetailRespVO respVO = BeanUtils.toBean(activity, AppPointActivityDetailRespVO.class); - respVO.setProducts(BeanUtils.toBean(products, AppPointActivityDetailRespVO.Product.class)); + PointProductDO minProduct = getMinObject(products, PointProductDO::getPoint); + assert minProduct != null; + AppPointActivityDetailRespVO respVO = BeanUtils.toBean(activity, AppPointActivityDetailRespVO.class) + .setProducts(BeanUtils.toBean(products, AppPointActivityDetailRespVO.Product.class)) + .setPoint(minProduct.getPoint()).setPrice(minProduct.getPrice()); return success(respVO); } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/point/vo/AppPointActivityDetailRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/point/vo/AppPointActivityDetailRespVO.java index 8253e4fe2..2e02f107a 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/point/vo/AppPointActivityDetailRespVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/point/vo/AppPointActivityDetailRespVO.java @@ -30,6 +30,14 @@ public class AppPointActivityDetailRespVO { @Schema(description = "商品信息数组", requiredMode = Schema.RequiredMode.REQUIRED) private List products; + //======================= 显示所需兑换积分最少的 SKU 信息 ======================= + + @Schema(description = "兑换积分", requiredMode = Schema.RequiredMode.REQUIRED) + private Integer point; + + @Schema(description = "兑换金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "15860") + private Integer price; + @Schema(description = "商品信息") @Data public static class Product { diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/point/PointActivityMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/point/PointActivityMapper.java index 46db5841e..d724c32ee 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/point/PointActivityMapper.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/point/PointActivityMapper.java @@ -1,10 +1,12 @@ 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.mybatis.core.mapper.BaseMapperX; 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.dal.dataobject.point.PointActivityDO; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import org.apache.ibatis.annotations.Mapper; /** @@ -25,4 +27,33 @@ public interface PointActivityMapper extends BaseMapperX { .orderByDesc(PointActivityDO::getId)); } + /** + * 更新活动库存(减少) + * + * @param id 活动编号 + * @param count 扣减的库存数量(正数) + * @return 影响的行数 + */ + default int updateStockDecr(Long id, int count) { + Assert.isTrue(count > 0); + return update(null, new LambdaUpdateWrapper() + .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() + .eq(PointActivityDO::getId, id) + .setSql("stock = stock + " + count)); + } + } \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/point/PointProductMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/point/PointProductMapper.java index cfa10a515..3c6d469a2 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/point/PointProductMapper.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/point/PointProductMapper.java @@ -1,5 +1,6 @@ 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.module.promotion.dal.dataobject.point.PointProductDO; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; @@ -29,4 +30,37 @@ public interface PointProductMapper extends BaseMapperX { .eq(PointProductDO::getActivityId, pointProductDO.getActivityId())); } + default PointProductDO selectListByActivityIdAndSkuId(Long activityId, Long skuId) { + return selectOne(PointProductDO::getActivityId, activityId, + PointProductDO::getSkuId, skuId); + } + + /** + * 更新活动库存(减少) + * + * @param id 活动编号 + * @param count 扣减的库存数量(减少库存) + * @return 影响的行数 + */ + default int updateStockDecr(Long id, int count) { + Assert.isTrue(count > 0); + return update(null, new LambdaUpdateWrapper() + .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() + .eq(PointProductDO::getId, id) + .setSql("stock = stock + " + count)); + } } \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/point/PointActivityService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/point/PointActivityService.java index 24facb182..b2b039570 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/point/PointActivityService.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/point/PointActivityService.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.promotion.service.point; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.promotion.api.point.dto.PointValidateJoinRespDTO; import cn.iocoder.yudao.module.promotion.controller.admin.point.vo.activity.PointActivityPageReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.point.vo.activity.PointActivitySaveReqVO; import cn.iocoder.yudao.module.promotion.dal.dataobject.point.PointActivityDO; @@ -32,6 +33,24 @@ public interface PointActivityService { */ 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); + /** * 关闭积分商城活动 * @@ -78,4 +97,16 @@ public interface PointActivityService { */ List getPointProductListByActivityIds(Collection activityIds); + /** + * 【下单前】校验是否参与积分商城活动 + * + * 如果校验失败,则抛出业务异常 + * + * @param activityId 活动编号 + * @param skuId SKU 编号 + * @param count 数量 + * @return 积分商城商品信息 + */ + PointValidateJoinRespDTO validateJoinPointActivity(Long activityId, Long skuId, Integer count); + } \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/point/PointActivityServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/point/PointActivityServiceImpl.java index da8d233e5..a0506b8f6 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/point/PointActivityServiceImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/point/PointActivityServiceImpl.java @@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; +import cn.iocoder.yudao.module.promotion.api.point.dto.PointValidateJoinRespDTO; import cn.iocoder.yudao.module.promotion.controller.admin.point.vo.activity.PointActivityPageReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.point.vo.activity.PointActivitySaveReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.point.vo.product.PointProductSaveReqVO; @@ -102,6 +103,43 @@ public class PointActivityServiceImpl implements PointActivityService { 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 @Transactional(rollbackFor = Exception.class) public void closePointActivity(Long id) { @@ -244,4 +282,28 @@ public class PointActivityServiceImpl implements PointActivityService { return pointProductMapper.selectListByActivityId(activityIds); } + @Override + public PointValidateJoinRespDTO validateJoinPointActivity(Long activityId, Long skuId, Integer count) { + // 1. 校验积分商城活动是否存在 + PointActivityDO activity = validatePointActivityExists(activityId); + if (CommonStatusEnum.isDisable(activity.getStatus())) { + throw exception(POINT_ACTIVITY_JOIN_ACTIVITY_STATUS_CLOSED); + } + + // 2.1 校验积分商城商品是否存在 + PointProductDO product = pointProductMapper.selectListByActivityIdAndSkuId(activityId, skuId); + if (product == null) { + throw exception(POINT_ACTIVITY_JOIN_ACTIVITY_PRODUCT_NOT_EXISTS); + } + // 2.2 超过单次购买限制 + if (count > product.getCount()) { + throw exception(POINT_ACTIVITY_JOIN_ACTIVITY_SINGLE_LIMIT_COUNT_EXCEED); + } + // 2.2 校验库存是否充足 + if (count > product.getStock()) { + throw exception(POINT_ACTIVITY_UPDATE_STOCK_FAIL); + } + return BeanUtils.toBean(product, PointValidateJoinRespDTO.class); + } + } \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityServiceImpl.java index 8b525e225..35df3ef25 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityServiceImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityServiceImpl.java @@ -160,7 +160,7 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { public void updateSeckillStockDecr(Long id, Long skuId, Integer count) { // 1.1 校验活动库存是否充足 SeckillActivityDO seckillActivity = validateSeckillActivityExists(id); - if (count > seckillActivity.getTotalStock()) { + if (count > seckillActivity.getStock()) { throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL); } // 1.2 校验商品库存是否充足 diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java index 2ab726ec4..be0ef51ae 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java @@ -58,11 +58,12 @@ public interface ErrorCodeConstants { // ========== Price 相关 1-011-003-000 ============ ErrorCode PRICE_CALCULATE_PAY_PRICE_ILLEGAL = new ErrorCode(1_011_003_000, "支付价格计算异常,原因:价格小于等于 0"); - ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_TEMPLATE_NOT_FOUND = new ErrorCode(1_011_003_002, "计算快递运费异常,找不到对应的运费模板"); - ErrorCode PRICE_CALCULATE_COUPON_NOT_MATCH_NORMAL_ORDER = new ErrorCode(1_011_003_004, "参与秒杀、拼团、砍价的营销商品,无法使用优惠劵"); - ErrorCode PRICE_CALCULATE_SECKILL_TOTAL_LIMIT_COUNT = new ErrorCode(1_011_003_005, "参与秒杀的商品,超过了秒杀总限购数量"); - ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_TYPE_ILLEGAL = new ErrorCode(1_011_003_006, "计算快递运费异常,配送方式不匹配"); - ErrorCode PRICE_CALCULATE_COUPON_CAN_NOT_USE = new ErrorCode(1_011_003_007, "该优惠劵无法使用,原因:{}」"); + ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_TEMPLATE_NOT_FOUND = new ErrorCode(1_011_003_001, "计算快递运费异常,找不到对应的运费模板"); + ErrorCode PRICE_CALCULATE_COUPON_NOT_MATCH_NORMAL_ORDER = new ErrorCode(1_011_003_002, "参与秒杀、拼团、砍价的营销商品,无法使用优惠劵"); + ErrorCode PRICE_CALCULATE_SECKILL_TOTAL_LIMIT_COUNT = new ErrorCode(1_011_003_003, "参与秒杀的商品,超过了秒杀总限购数量"); + ErrorCode PRICE_CALCULATE_POINT_TOTAL_LIMIT_COUNT = new ErrorCode(1_011_003_004, "参与积分活动的商品,超过了积分活动商品总限购数量"); + ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_TYPE_ILLEGAL = new ErrorCode(1_011_003_005, "计算快递运费异常,配送方式不匹配"); + ErrorCode PRICE_CALCULATE_COUPON_CAN_NOT_USE = new ErrorCode(1_011_003_006, "该优惠劵无法使用,原因:{}」"); // ========== 物流 Express 模块 1-011-004-000 ========== ErrorCode EXPRESS_NOT_EXISTS = new ErrorCode(1_011_004_000, "快递公司不存在"); diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderTypeEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderTypeEnum.java index f82071206..0fccebb47 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderTypeEnum.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderTypeEnum.java @@ -20,6 +20,7 @@ public enum TradeOrderTypeEnum implements IntArrayValuable { SECKILL(1, "秒杀订单"), BARGAIN(2, "砍价订单"), COMBINATION(3, "拼团订单"), + POINT(4, "积分商城"), ; public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeOrderTypeEnum::getType).toArray(); @@ -54,4 +55,8 @@ public enum TradeOrderTypeEnum implements IntArrayValuable { return ObjectUtil.equal(type, COMBINATION.getType()); } + public static boolean isPoint(Integer type) { + return ObjectUtil.equal(type, POINT.getType()); + } + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java index ea20b7b42..7188bc17c 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java @@ -62,6 +62,10 @@ public class AppTradeOrderSettlementReqVO { @Schema(description = "砍价记录编号", example = "123") private Long bargainRecordId; + // ========== 积分商城活动相关字段 ========== + @Schema(description = "积分商城活动编号", example = "123") + private Long pointActivityId; + @AssertTrue(message = "活动商品每次只能购买一种规格") @JsonIgnore public boolean isValidActivityItems() { diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java index 60b81057f..45462a5be 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java @@ -219,7 +219,8 @@ public interface TradeOrderConvert { .setSeckillActivityId(settlementReqVO.getSeckillActivityId()) .setBargainRecordId(settlementReqVO.getBargainRecordId()) .setCombinationActivityId(settlementReqVO.getCombinationActivityId()) - .setCombinationHeadId(settlementReqVO.getCombinationHeadId()); + .setCombinationHeadId(settlementReqVO.getCombinationHeadId()) + .setPointActivityId(settlementReqVO.getPointActivityId()); // 商品项的构建 Map cartMap = convertMap(cartList, CartDO::getId); for (AppTradeOrderSettlementReqVO.Item item : settlementReqVO.getItems()) { diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java index 399b692ed..4c06c8013 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java @@ -353,4 +353,11 @@ public class TradeOrderDO extends BaseDO { */ private Long combinationRecordId; + /** + * 积分商城活动的编号 + * + * 关联 PointActivityDO 的 id 字段 + */ + private Long pointActivityId; + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/rpc/config/RpcConfiguration.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/rpc/config/RpcConfiguration.java index f51be2735..88aab7450 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/rpc/config/RpcConfiguration.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/rpc/config/RpcConfiguration.java @@ -16,6 +16,7 @@ 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.discount.DiscountActivityApi; +import cn.iocoder.yudao.module.promotion.api.point.PointActivityApi; import cn.iocoder.yudao.module.promotion.api.reward.RewardActivityApi; import cn.iocoder.yudao.module.promotion.api.seckill.SeckillActivityApi; import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi; @@ -26,7 +27,7 @@ import org.springframework.context.annotation.Configuration; @Configuration(proxyBeanMethods = false) @EnableFeignClients(clients = { BargainActivityApi.class, BargainRecordApi.class, CombinationRecordApi.class, - CouponApi.class, DiscountActivityApi.class, RewardActivityApi.class, SeckillActivityApi.class, + CouponApi.class, DiscountActivityApi.class, RewardActivityApi.class, SeckillActivityApi.class, PointActivityApi.class, MemberUserApi.class, MemberPointApi.class, MemberLevelApi.class, MemberAddressApi.class, MemberConfigApi.class, ProductSpuApi.class, ProductSkuApi.class, ProductCommentApi.class, ProductCategoryApi.class, PayOrderApi.class, PayRefundApi.class, diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryService.java index 445792232..5e436d959 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryService.java @@ -42,9 +42,9 @@ public interface TradeOrderQueryService { /** * 获得指定用户,指定活动,指定状态的交易订单 * - * @param userId 用户编号 + * @param userId 用户编号 * @param combinationActivityId 活动编号 - * @param status 订单状态 + * @param status 订单状态 * @return 交易订单 */ TradeOrderDO getOrderByUserIdAndStatusAndCombination(Long userId, Long combinationActivityId, Integer status); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java index f99b4ebf5..a199011ba 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java @@ -245,7 +245,10 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { } // 3. 生成预支付 - createPayOrder(order, orderItems); + // 特殊情况:积分兑换时,可能支付金额为零 + if (order.getPayPrice() > 0) { + createPayOrder(order, orderItems); + } // 4. 插入订单日志 TradeOrderLogUtils.setOrderInfo(order.getId(), null, order.getStatus()); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradePointOrderHandler.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradePointOrderHandler.java new file mode 100644 index 000000000..7bd5e8784 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradePointOrderHandler.java @@ -0,0 +1,71 @@ +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.TradeOrderStatusEnum; +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Objects; + +/** + * 积分商城活动订单的 {@link TradeOrderHandler} 实现类 + * + * @author HUIHUI + */ +@Component +public class TradePointOrderHandler implements TradeOrderHandler { + + @Resource + private PointActivityApi pointActivityApi; + + @Override + public void beforeOrderCreate(TradeOrderDO order, List orderItems) { + if (!TradeOrderTypeEnum.isPoint(order.getType())) { + return; + } + // 明确校验一下 + Assert.isTrue(orderItems.size() == 1, "积分商城活动兑换商品兑换时,只允许选择一个商品"); + + // 扣减积分商城活动的库存 + pointActivityApi.updatePointStockDecr(order.getPointActivityId(), + orderItems.get(0).getSkuId(), orderItems.get(0).getCount()).getCheckedData(); + + // 如果支付金额为 0,则直接设置为已支付 + if (Objects.equals(order.getPayPrice(), 0)) { + order.setPayStatus(true).setStatus(TradeOrderStatusEnum.UNDELIVERED.getStatus()); + } + } + + @Override + public void afterCancelOrder(TradeOrderDO order, List 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()).getCheckedData(); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImpl.java index 7a496d28b..bb64e689e 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImpl.java @@ -69,7 +69,8 @@ public class TradePriceServiceImpl implements TradePriceService { .buildCalculateResp(calculateReqBO, spuList, skuList); priceCalculators.forEach(calculator -> calculator.calculate(calculateReqBO, calculateRespBO)); // 2.2 如果最终支付金额小于等于 0,则抛出业务异常 - if (calculateRespBO.getPrice().getPayPrice() <= 0) { + if (calculateReqBO.getPointActivityId() == null // 积分订单,允许支付金额为 0 + && calculateRespBO.getPrice().getPayPrice() <= 0) { log.error("[calculatePrice][价格计算不正确,请求 calculateReqDTO({}),结果 priceCalculate({})]", calculateReqBO, calculateRespBO); throw exception(PRICE_CALCULATE_PAY_PRICE_ILLEGAL); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java index ce9949027..ada677f36 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java @@ -84,6 +84,12 @@ public class TradePriceCalculateReqBO { */ private Long bargainRecordId; + // ========== 积分商城活动相关字段 ========== + /** + * 积分商城活动编号 + */ + private Long pointActivityId; + /** * 商品 SKU */ diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointActivityPriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointActivityPriceCalculator.java new file mode 100644 index 000000000..0a5498428 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointActivityPriceCalculator.java @@ -0,0 +1,94 @@ +package cn.iocoder.yudao.module.trade.service.price.calculator; + +import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.module.member.api.user.MemberUserApi; +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; +import cn.iocoder.yudao.module.promotion.api.point.PointActivityApi; +import cn.iocoder.yudao.module.promotion.api.point.dto.PointValidateJoinRespDTO; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum; +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; +import cn.iocoder.yudao.module.trade.service.order.TradeOrderQueryService; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.PRICE_CALCULATE_POINT_TOTAL_LIMIT_COUNT; + +/** + * 积分商城的 {@link TradePriceCalculator} 实现类 + * + * @author owen + */ +@Component +@Order(TradePriceCalculator.ORDER_POINT_ACTIVITY) +@Slf4j +public class TradePointActivityPriceCalculator implements TradePriceCalculator { + + @Resource + private PointActivityApi pointActivityApi; + @Resource + private MemberUserApi memberUserApi; + + @Resource + private TradeOrderQueryService tradeOrderQueryService; + + @Override + public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) { + // 1.1 判断订单类型是否为积分商城活动 + if (ObjectUtil.notEqual(result.getType(), TradeOrderTypeEnum.POINT.getType())) { + return; + } + // 1.2 初始化积分 + MemberUserRespDTO user = memberUserApi.getUser(param.getUserId()).getCheckedData(); + result.setTotalPoint(user.getPoint()).setUsePoint(0); + + // 1.3 校验用户积分余额 + if (user.getPoint() == null || user.getPoint() <= 0) { + return; + } + + Assert.isTrue(param.getItems().size() == 1, "积分商城兑换商品时,只允许选择一个商品"); + // 2. 校验是否可以参与积分商城活动 + TradePriceCalculateRespBO.OrderItem orderItem = result.getItems().get(0); + PointValidateJoinRespDTO activity = validateJoinSeckill( + param.getUserId(), param.getPointActivityId(), + orderItem.getSkuId(), orderItem.getCount()); + + // 3.1 记录优惠明细 + int discountPrice = orderItem.getPayPrice(); // 情况一:单使用积分兑换 + Assert.isTrue(activity.getPoint() >= 1, "积分商城商品兑换积分必须大于 1"); + result.setUsePoint(activity.getPoint() * orderItem.getCount()); + orderItem.setUsePoint(activity.getPoint() * orderItem.getCount()); + if (activity.getPrice() != null && activity.getPrice() > 0) { // 情况二:积分 + 金额 + discountPrice = orderItem.getPayPrice() - activity.getPrice() * orderItem.getCount(); + } + // 3.2 记录优惠明细 + TradePriceCalculatorHelper.addPromotion(result, orderItem, + param.getPointActivityId(), "积分商城活动", PromotionTypeEnum.POINT.getType(), + StrUtil.format("积分商城活动:省 {} 元", TradePriceCalculatorHelper.formatPrice(discountPrice)), + discountPrice); + + // 3.3 更新 SKU 优惠金额 + orderItem.setDiscountPrice(orderItem.getDiscountPrice() + discountPrice); + TradePriceCalculatorHelper.recountPayPrice(orderItem); + TradePriceCalculatorHelper.recountAllPrice(result); + } + + private PointValidateJoinRespDTO validateJoinSeckill(Long userId, Long activityId, Long skuId, Integer count) { + // 1. 校验是否可以参与积分商城活动 + PointValidateJoinRespDTO pointValidateJoinRespDTO = pointActivityApi.validateJoinPointActivity(activityId, skuId, count).getCheckedData(); + // 2. 校验总限购数量,目前只有 trade 有具体下单的数据,需要交给 trade 价格计算使用 + int activityProductCount = tradeOrderQueryService.getSeckillProductCount(userId, activityId); + if (activityProductCount + count > pointValidateJoinRespDTO.getCount()) { + throw exception(PRICE_CALCULATE_POINT_TOTAL_LIMIT_COUNT); + } + return pointValidateJoinRespDTO; + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointUsePriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointUsePriceCalculator.java index 3940d40db..ba381e1a2 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointUsePriceCalculator.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointUsePriceCalculator.java @@ -1,12 +1,14 @@ package cn.iocoder.yudao.module.trade.service.price.calculator; import cn.hutool.core.util.BooleanUtil; +import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.module.member.api.config.MemberConfigApi; import cn.iocoder.yudao.module.member.api.config.dto.MemberConfigRespDTO; import cn.iocoder.yudao.module.member.api.user.MemberUserApi; import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum; +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; import jakarta.annotation.Resource; @@ -37,6 +39,10 @@ public class TradePointUsePriceCalculator implements TradePriceCalculator { @Override public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) { + // 判断订单类型是否不为积分商城活动 + if (ObjectUtil.equal(result.getType(), TradeOrderTypeEnum.POINT.getType())) { + return; + } // 0. 初始化积分 MemberUserRespDTO user = memberUserApi.getUser(param.getUserId()).getCheckedData(); result.setTotalPoint(user.getPoint()).setUsePoint(0); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculator.java index 9ed7d9a2f..a37048b3b 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculator.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculator.java @@ -16,6 +16,7 @@ public interface TradePriceCalculator { int ORDER_SECKILL_ACTIVITY = 8; int ORDER_BARGAIN_ACTIVITY = 8; int ORDER_COMBINATION_ACTIVITY = 8; + int ORDER_POINT_ACTIVITY = 8; int ORDER_DISCOUNT_ACTIVITY = 10; int ORDER_REWARD_ACTIVITY = 20; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java index 323b50e93..0b24e2ea0 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java @@ -90,6 +90,9 @@ public class TradePriceCalculatorHelper { if (param.getBargainRecordId() != null) { return TradeOrderTypeEnum.BARGAIN.getType(); } + if (param.getPointActivityId() != null) { + return TradeOrderTypeEnum.POINT.getType(); + } return TradeOrderTypeEnum.NORMAL.getType(); }