Commit e6496af9ae0bb17d69e7fb68c90aec0194b8eeaa
Merge branch 'develop' of https://gitee.com/zhijiantianya/ruoyi-vue-pro into master-jdk17
Showing
26 changed files
with
496 additions
and
19 deletions
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/point/PointActivityApi.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.promotion.api.point; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.promotion.api.point.dto.PointValidateJoinRespDTO; | |
| 4 | + | |
| 5 | +/** | |
| 6 | + * 积分商城活动 API 接口 | |
| 7 | + * | |
| 8 | + * @author HUIHUI | |
| 9 | + */ | |
| 10 | +public interface PointActivityApi { | |
| 11 | + | |
| 12 | + /** | |
| 13 | + * 【下单前】校验是否参与积分商城活动 | |
| 14 | + * | |
| 15 | + * 如果校验失败,则抛出业务异常 | |
| 16 | + * | |
| 17 | + * @param activityId 活动编号 | |
| 18 | + * @param skuId SKU 编号 | |
| 19 | + * @param count 数量 | |
| 20 | + * @return 积分商城商品信息 | |
| 21 | + */ | |
| 22 | + PointValidateJoinRespDTO validateJoinPointActivity(Long activityId, Long skuId, Integer count); | |
| 23 | + | |
| 24 | + /** | |
| 25 | + * 更新积分商城商品库存(减少) | |
| 26 | + * | |
| 27 | + * @param id 活动编号 | |
| 28 | + * @param skuId sku 编号 | |
| 29 | + * @param count 数量(正数) | |
| 30 | + */ | |
| 31 | + void updatePointStockDecr(Long id, Long skuId, Integer count); | |
| 32 | + | |
| 33 | + /** | |
| 34 | + * 更新积分商城商品库存(增加) | |
| 35 | + * | |
| 36 | + * @param id 活动编号 | |
| 37 | + * @param skuId sku 编号 | |
| 38 | + * @param count 数量(正数) | |
| 39 | + */ | |
| 40 | + void updatePointStockIncr(Long id, Long skuId, Integer count); | |
| 41 | + | |
| 42 | +} | ... | ... |
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/point/dto/PointValidateJoinRespDTO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.promotion.api.point.dto; | |
| 2 | + | |
| 3 | +import lombok.Data; | |
| 4 | + | |
| 5 | +/** | |
| 6 | + * 校验参与积分商城 Response DTO | |
| 7 | + */ | |
| 8 | +@Data | |
| 9 | +public class PointValidateJoinRespDTO { | |
| 10 | + | |
| 11 | + /** | |
| 12 | + * 可兑换次数 | |
| 13 | + */ | |
| 14 | + private Integer count; | |
| 15 | + /** | |
| 16 | + * 所需兑换积分 | |
| 17 | + */ | |
| 18 | + private Integer point; | |
| 19 | + /** | |
| 20 | + * 所需兑换金额,单位:分 | |
| 21 | + */ | |
| 22 | + private Integer price; | |
| 23 | + | |
| 24 | +} | ... | ... |
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 { |
| 50 | 50 | ErrorCode POINT_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1_013_007_002, "积分商城活动已关闭,不能修改"); |
| 51 | 51 | ErrorCode POINT_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1_013_007_003, "积分商城活动未关闭或未结束,不能删除"); |
| 52 | 52 | ErrorCode POINT_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1_013_007_004, "积分商城活动已关闭,不能重复关闭"); |
| 53 | + ErrorCode POINT_ACTIVITY_JOIN_ACTIVITY_STATUS_CLOSED = new ErrorCode(1_013_007_005, "积分商品兑换失败,原因:积分商城活动已关闭"); | |
| 54 | + ErrorCode POINT_ACTIVITY_JOIN_ACTIVITY_SINGLE_LIMIT_COUNT_EXCEED = new ErrorCode(1_013_007_006, "积分商品兑换失败,原因:单次限购超出"); | |
| 55 | + ErrorCode POINT_ACTIVITY_JOIN_ACTIVITY_PRODUCT_NOT_EXISTS = new ErrorCode(1_013_007_007, "积分商品兑换失败,原因:商品不存在"); | |
| 56 | + ErrorCode POINT_ACTIVITY_UPDATE_STOCK_FAIL = new ErrorCode(1_013_007_008, "积分商品兑换失败,原因:积分商品库存不足"); | |
| 53 | 57 | |
| 54 | 58 | // ========== 秒杀活动 1-013-008-000 ========== |
| 55 | 59 | ErrorCode SECKILL_ACTIVITY_NOT_EXISTS = new ErrorCode(1_013_008_000, "秒杀活动不存在"); | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/point/PointActivityApiImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.promotion.api.point; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.promotion.api.point.dto.PointValidateJoinRespDTO; | |
| 4 | +import cn.iocoder.yudao.module.promotion.service.point.PointActivityService; | |
| 5 | +import jakarta.annotation.Resource; | |
| 6 | +import org.springframework.stereotype.Service; | |
| 7 | +import org.springframework.validation.annotation.Validated; | |
| 8 | + | |
| 9 | +/** | |
| 10 | + * 积分商城活动 Api 接口实现类 | |
| 11 | + * | |
| 12 | + * @author HUIHUI | |
| 13 | + */ | |
| 14 | +@Service | |
| 15 | +@Validated | |
| 16 | +public class PointActivityApiImpl implements PointActivityApi { | |
| 17 | + | |
| 18 | + @Resource | |
| 19 | + private PointActivityService pointActivityService; | |
| 20 | + | |
| 21 | + @Override | |
| 22 | + public PointValidateJoinRespDTO validateJoinPointActivity(Long activityId, Long skuId, Integer count) { | |
| 23 | + return pointActivityService.validateJoinPointActivity(activityId, skuId, count); | |
| 24 | + } | |
| 25 | + | |
| 26 | + @Override | |
| 27 | + public void updatePointStockDecr(Long id, Long skuId, Integer count) { | |
| 28 | + pointActivityService.updatePointStockDecr(id, skuId, count); | |
| 29 | + } | |
| 30 | + | |
| 31 | + @Override | |
| 32 | + public void updatePointStockIncr(Long id, Long skuId, Integer count) { | |
| 33 | + pointActivityService.updatePointStockIncr(id, skuId, count); | |
| 34 | + } | |
| 35 | + | |
| 36 | +} | ... | ... |
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 { |
| 76 | 76 | |
| 77 | 77 | // 2. 拼接数据 |
| 78 | 78 | List<PointProductDO> products = pointActivityService.getPointProductListByActivityIds(Collections.singletonList(id)); |
| 79 | - AppPointActivityDetailRespVO respVO = BeanUtils.toBean(activity, AppPointActivityDetailRespVO.class); | |
| 80 | - respVO.setProducts(BeanUtils.toBean(products, AppPointActivityDetailRespVO.Product.class)); | |
| 79 | + PointProductDO minProduct = getMinObject(products, PointProductDO::getPoint); | |
| 80 | + assert minProduct != null; | |
| 81 | + AppPointActivityDetailRespVO respVO = BeanUtils.toBean(activity, AppPointActivityDetailRespVO.class) | |
| 82 | + .setProducts(BeanUtils.toBean(products, AppPointActivityDetailRespVO.Product.class)) | |
| 83 | + .setPoint(minProduct.getPoint()).setPrice(minProduct.getPrice()); | |
| 81 | 84 | return success(respVO); |
| 82 | 85 | } |
| 83 | 86 | ... | ... |
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 { |
| 30 | 30 | @Schema(description = "商品信息数组", requiredMode = Schema.RequiredMode.REQUIRED) |
| 31 | 31 | private List<Product> products; |
| 32 | 32 | |
| 33 | + //======================= 显示所需兑换积分最少的 SKU 信息 ======================= | |
| 34 | + | |
| 35 | + @Schema(description = "兑换积分", requiredMode = Schema.RequiredMode.REQUIRED) | |
| 36 | + private Integer point; | |
| 37 | + | |
| 38 | + @Schema(description = "兑换金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "15860") | |
| 39 | + private Integer price; | |
| 40 | + | |
| 33 | 41 | @Schema(description = "商品信息") |
| 34 | 42 | @Data |
| 35 | 43 | public static class Product { | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/point/PointActivityMapper.java
| 1 | 1 | package cn.iocoder.yudao.module.promotion.dal.mysql.point; |
| 2 | 2 | |
| 3 | +import cn.hutool.core.lang.Assert; | |
| 3 | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | 5 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| 5 | 6 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| 6 | 7 | import cn.iocoder.yudao.module.promotion.controller.admin.point.vo.activity.PointActivityPageReqVO; |
| 7 | 8 | import cn.iocoder.yudao.module.promotion.dal.dataobject.point.PointActivityDO; |
| 9 | +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; | |
| 8 | 10 | import org.apache.ibatis.annotations.Mapper; |
| 9 | 11 | |
| 10 | 12 | /** |
| ... | ... | @@ -25,4 +27,33 @@ public interface PointActivityMapper extends BaseMapperX<PointActivityDO> { |
| 25 | 27 | .orderByDesc(PointActivityDO::getId)); |
| 26 | 28 | } |
| 27 | 29 | |
| 30 | + /** | |
| 31 | + * 更新活动库存(减少) | |
| 32 | + * | |
| 33 | + * @param id 活动编号 | |
| 34 | + * @param count 扣减的库存数量(正数) | |
| 35 | + * @return 影响的行数 | |
| 36 | + */ | |
| 37 | + default int updateStockDecr(Long id, int count) { | |
| 38 | + Assert.isTrue(count > 0); | |
| 39 | + return update(null, new LambdaUpdateWrapper<PointActivityDO>() | |
| 40 | + .eq(PointActivityDO::getId, id) | |
| 41 | + .ge(PointActivityDO::getStock, count) | |
| 42 | + .setSql("stock = stock - " + count)); | |
| 43 | + } | |
| 44 | + | |
| 45 | + /** | |
| 46 | + * 更新活动库存(增加) | |
| 47 | + * | |
| 48 | + * @param id 活动编号 | |
| 49 | + * @param count 增加的库存数量(正数) | |
| 50 | + * @return 影响的行数 | |
| 51 | + */ | |
| 52 | + default int updateStockIncr(Long id, int count) { | |
| 53 | + Assert.isTrue(count > 0); | |
| 54 | + return update(null, new LambdaUpdateWrapper<PointActivityDO>() | |
| 55 | + .eq(PointActivityDO::getId, id) | |
| 56 | + .setSql("stock = stock + " + count)); | |
| 57 | + } | |
| 58 | + | |
| 28 | 59 | } |
| 29 | 60 | \ No newline at end of file | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/point/PointProductMapper.java
| 1 | 1 | package cn.iocoder.yudao.module.promotion.dal.mysql.point; |
| 2 | 2 | |
| 3 | +import cn.hutool.core.lang.Assert; | |
| 3 | 4 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| 4 | 5 | import cn.iocoder.yudao.module.promotion.dal.dataobject.point.PointProductDO; |
| 5 | 6 | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| ... | ... | @@ -29,4 +30,37 @@ public interface PointProductMapper extends BaseMapperX<PointProductDO> { |
| 29 | 30 | .eq(PointProductDO::getActivityId, pointProductDO.getActivityId())); |
| 30 | 31 | } |
| 31 | 32 | |
| 33 | + default PointProductDO selectListByActivityIdAndSkuId(Long activityId, Long skuId) { | |
| 34 | + return selectOne(PointProductDO::getActivityId, activityId, | |
| 35 | + PointProductDO::getSkuId, skuId); | |
| 36 | + } | |
| 37 | + | |
| 38 | + /** | |
| 39 | + * 更新活动库存(减少) | |
| 40 | + * | |
| 41 | + * @param id 活动编号 | |
| 42 | + * @param count 扣减的库存数量(减少库存) | |
| 43 | + * @return 影响的行数 | |
| 44 | + */ | |
| 45 | + default int updateStockDecr(Long id, int count) { | |
| 46 | + Assert.isTrue(count > 0); | |
| 47 | + return update(null, new LambdaUpdateWrapper<PointProductDO>() | |
| 48 | + .eq(PointProductDO::getId, id) | |
| 49 | + .ge(PointProductDO::getStock, count) | |
| 50 | + .setSql("stock = stock - " + count)); | |
| 51 | + } | |
| 52 | + | |
| 53 | + /** | |
| 54 | + * 更新活动库存(增加) | |
| 55 | + * | |
| 56 | + * @param id 活动编号 | |
| 57 | + * @param count 需要增加的库存(增加库存) | |
| 58 | + * @return 影响的行数 | |
| 59 | + */ | |
| 60 | + default int updateStockIncr(Long id, int count) { | |
| 61 | + Assert.isTrue(count > 0); | |
| 62 | + return update(null, new LambdaUpdateWrapper<PointProductDO>() | |
| 63 | + .eq(PointProductDO::getId, id) | |
| 64 | + .setSql("stock = stock + " + count)); | |
| 65 | + } | |
| 32 | 66 | } |
| 33 | 67 | \ No newline at end of file | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/point/PointActivityService.java
| 1 | 1 | package cn.iocoder.yudao.module.promotion.service.point; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | +import cn.iocoder.yudao.module.promotion.api.point.dto.PointValidateJoinRespDTO; | |
| 4 | 5 | import cn.iocoder.yudao.module.promotion.controller.admin.point.vo.activity.PointActivityPageReqVO; |
| 5 | 6 | import cn.iocoder.yudao.module.promotion.controller.admin.point.vo.activity.PointActivitySaveReqVO; |
| 6 | 7 | import cn.iocoder.yudao.module.promotion.dal.dataobject.point.PointActivityDO; |
| ... | ... | @@ -33,6 +34,24 @@ public interface PointActivityService { |
| 33 | 34 | void updatePointActivity(@Valid PointActivitySaveReqVO updateReqVO); |
| 34 | 35 | |
| 35 | 36 | /** |
| 37 | + * 更新积分商城商品库存(减少) | |
| 38 | + * | |
| 39 | + * @param id 活动编号 | |
| 40 | + * @param skuId sku 编号 | |
| 41 | + * @param count 数量(正数) | |
| 42 | + */ | |
| 43 | + void updatePointStockDecr(Long id, Long skuId, Integer count); | |
| 44 | + | |
| 45 | + /** | |
| 46 | + * 更新积分商城商品库存(增加) | |
| 47 | + * | |
| 48 | + * @param id 活动编号 | |
| 49 | + * @param skuId sku 编号 | |
| 50 | + * @param count 数量(正数) | |
| 51 | + */ | |
| 52 | + void updatePointStockIncr(Long id, Long skuId, Integer count); | |
| 53 | + | |
| 54 | + /** | |
| 36 | 55 | * 关闭积分商城活动 |
| 37 | 56 | * |
| 38 | 57 | * @param id 编号 |
| ... | ... | @@ -78,4 +97,16 @@ public interface PointActivityService { |
| 78 | 97 | */ |
| 79 | 98 | List<PointProductDO> getPointProductListByActivityIds(Collection<Long> activityIds); |
| 80 | 99 | |
| 100 | + /** | |
| 101 | + * 【下单前】校验是否参与积分商城活动 | |
| 102 | + * | |
| 103 | + * 如果校验失败,则抛出业务异常 | |
| 104 | + * | |
| 105 | + * @param activityId 活动编号 | |
| 106 | + * @param skuId SKU 编号 | |
| 107 | + * @param count 数量 | |
| 108 | + * @return 积分商城商品信息 | |
| 109 | + */ | |
| 110 | + PointValidateJoinRespDTO validateJoinPointActivity(Long activityId, Long skuId, Integer count); | |
| 111 | + | |
| 81 | 112 | } |
| 82 | 113 | \ No newline at end of file | ... | ... |
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; |
| 8 | 8 | import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; |
| 9 | 9 | import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; |
| 10 | 10 | import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; |
| 11 | +import cn.iocoder.yudao.module.promotion.api.point.dto.PointValidateJoinRespDTO; | |
| 11 | 12 | import cn.iocoder.yudao.module.promotion.controller.admin.point.vo.activity.PointActivityPageReqVO; |
| 12 | 13 | import cn.iocoder.yudao.module.promotion.controller.admin.point.vo.activity.PointActivitySaveReqVO; |
| 13 | 14 | import cn.iocoder.yudao.module.promotion.controller.admin.point.vo.product.PointProductSaveReqVO; |
| ... | ... | @@ -104,6 +105,43 @@ public class PointActivityServiceImpl implements PointActivityService { |
| 104 | 105 | |
| 105 | 106 | @Override |
| 106 | 107 | @Transactional(rollbackFor = Exception.class) |
| 108 | + public void updatePointStockDecr(Long id, Long skuId, Integer count) { | |
| 109 | + // 1.1 校验活动库存是否充足 | |
| 110 | + PointActivityDO activity = validatePointActivityExists(id); | |
| 111 | + if (count > activity.getStock()) { | |
| 112 | + throw exception(POINT_ACTIVITY_UPDATE_STOCK_FAIL); | |
| 113 | + } | |
| 114 | + // 1.2 校验商品库存是否充足 | |
| 115 | + PointProductDO product = pointProductMapper.selectListByActivityIdAndSkuId(id, skuId); | |
| 116 | + if (product == null || count > product.getStock()) { | |
| 117 | + throw exception(POINT_ACTIVITY_UPDATE_STOCK_FAIL); | |
| 118 | + } | |
| 119 | + | |
| 120 | + // 2.1 更新活动商品库存 | |
| 121 | + int updateCount = pointProductMapper.updateStockDecr(product.getId(), count); | |
| 122 | + if (updateCount == 0) { | |
| 123 | + throw exception(POINT_ACTIVITY_UPDATE_STOCK_FAIL); | |
| 124 | + } | |
| 125 | + | |
| 126 | + // 2.2 更新活动库存 | |
| 127 | + updateCount = pointActivityMapper.updateStockDecr(id, count); | |
| 128 | + if (updateCount == 0) { | |
| 129 | + throw exception(POINT_ACTIVITY_UPDATE_STOCK_FAIL); | |
| 130 | + } | |
| 131 | + } | |
| 132 | + | |
| 133 | + @Override | |
| 134 | + @Transactional(rollbackFor = Exception.class) | |
| 135 | + public void updatePointStockIncr(Long id, Long skuId, Integer count) { | |
| 136 | + PointProductDO product = pointProductMapper.selectListByActivityIdAndSkuId(id, skuId); | |
| 137 | + // 更新活动商品库存 | |
| 138 | + pointProductMapper.updateStockIncr(product.getId(), count); | |
| 139 | + // 更新活动库存 | |
| 140 | + pointActivityMapper.updateStockIncr(id, count); | |
| 141 | + } | |
| 142 | + | |
| 143 | + @Override | |
| 144 | + @Transactional(rollbackFor = Exception.class) | |
| 107 | 145 | public void closePointActivity(Long id) { |
| 108 | 146 | // 校验存在 |
| 109 | 147 | PointActivityDO pointActivity = validatePointActivityExists(id); |
| ... | ... | @@ -244,4 +282,28 @@ public class PointActivityServiceImpl implements PointActivityService { |
| 244 | 282 | return pointProductMapper.selectListByActivityId(activityIds); |
| 245 | 283 | } |
| 246 | 284 | |
| 285 | + @Override | |
| 286 | + public PointValidateJoinRespDTO validateJoinPointActivity(Long activityId, Long skuId, Integer count) { | |
| 287 | + // 1. 校验积分商城活动是否存在 | |
| 288 | + PointActivityDO activity = validatePointActivityExists(activityId); | |
| 289 | + if (CommonStatusEnum.isDisable(activity.getStatus())) { | |
| 290 | + throw exception(POINT_ACTIVITY_JOIN_ACTIVITY_STATUS_CLOSED); | |
| 291 | + } | |
| 292 | + | |
| 293 | + // 2.1 校验积分商城商品是否存在 | |
| 294 | + PointProductDO product = pointProductMapper.selectListByActivityIdAndSkuId(activityId, skuId); | |
| 295 | + if (product == null) { | |
| 296 | + throw exception(POINT_ACTIVITY_JOIN_ACTIVITY_PRODUCT_NOT_EXISTS); | |
| 297 | + } | |
| 298 | + // 2.2 超过单次购买限制 | |
| 299 | + if (count > product.getCount()) { | |
| 300 | + throw exception(POINT_ACTIVITY_JOIN_ACTIVITY_SINGLE_LIMIT_COUNT_EXCEED); | |
| 301 | + } | |
| 302 | + // 2.2 校验库存是否充足 | |
| 303 | + if (count > product.getStock()) { | |
| 304 | + throw exception(POINT_ACTIVITY_UPDATE_STOCK_FAIL); | |
| 305 | + } | |
| 306 | + return BeanUtils.toBean(product, PointValidateJoinRespDTO.class); | |
| 307 | + } | |
| 308 | + | |
| 247 | 309 | } |
| 248 | 310 | \ No newline at end of file | ... | ... |
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 { |
| 160 | 160 | public void updateSeckillStockDecr(Long id, Long skuId, Integer count) { |
| 161 | 161 | // 1.1 校验活动库存是否充足 |
| 162 | 162 | SeckillActivityDO seckillActivity = validateSeckillActivityExists(id); |
| 163 | - if (count > seckillActivity.getTotalStock()) { | |
| 163 | + if (count > seckillActivity.getStock()) { | |
| 164 | 164 | throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL); |
| 165 | 165 | } |
| 166 | 166 | // 1.2 校验商品库存是否充足 | ... | ... |
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 { |
| 58 | 58 | |
| 59 | 59 | // ========== Price 相关 1-011-003-000 ============ |
| 60 | 60 | ErrorCode PRICE_CALCULATE_PAY_PRICE_ILLEGAL = new ErrorCode(1_011_003_000, "支付价格计算异常,原因:价格小于等于 0"); |
| 61 | - ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_TEMPLATE_NOT_FOUND = new ErrorCode(1_011_003_002, "计算快递运费异常,找不到对应的运费模板"); | |
| 62 | - ErrorCode PRICE_CALCULATE_COUPON_NOT_MATCH_NORMAL_ORDER = new ErrorCode(1_011_003_004, "参与秒杀、拼团、砍价的营销商品,无法使用优惠劵"); | |
| 63 | - ErrorCode PRICE_CALCULATE_SECKILL_TOTAL_LIMIT_COUNT = new ErrorCode(1_011_003_005, "参与秒杀的商品,超过了秒杀总限购数量"); | |
| 64 | - ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_TYPE_ILLEGAL = new ErrorCode(1_011_003_006, "计算快递运费异常,配送方式不匹配"); | |
| 65 | - ErrorCode PRICE_CALCULATE_COUPON_CAN_NOT_USE = new ErrorCode(1_011_003_007, "该优惠劵无法使用,原因:{}」"); | |
| 61 | + ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_TEMPLATE_NOT_FOUND = new ErrorCode(1_011_003_001, "计算快递运费异常,找不到对应的运费模板"); | |
| 62 | + ErrorCode PRICE_CALCULATE_COUPON_NOT_MATCH_NORMAL_ORDER = new ErrorCode(1_011_003_002, "参与秒杀、拼团、砍价的营销商品,无法使用优惠劵"); | |
| 63 | + ErrorCode PRICE_CALCULATE_SECKILL_TOTAL_LIMIT_COUNT = new ErrorCode(1_011_003_003, "参与秒杀的商品,超过了秒杀总限购数量"); | |
| 64 | + ErrorCode PRICE_CALCULATE_POINT_TOTAL_LIMIT_COUNT = new ErrorCode(1_011_003_004, "参与积分活动的商品,超过了积分活动商品总限购数量"); | |
| 65 | + ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_TYPE_ILLEGAL = new ErrorCode(1_011_003_005, "计算快递运费异常,配送方式不匹配"); | |
| 66 | + ErrorCode PRICE_CALCULATE_COUPON_CAN_NOT_USE = new ErrorCode(1_011_003_006, "该优惠劵无法使用,原因:{}」"); | |
| 66 | 67 | |
| 67 | 68 | // ========== 物流 Express 模块 1-011-004-000 ========== |
| 68 | 69 | ErrorCode EXPRESS_NOT_EXISTS = new ErrorCode(1_011_004_000, "快递公司不存在"); | ... | ... |
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 { |
| 20 | 20 | SECKILL(1, "秒杀订单"), |
| 21 | 21 | BARGAIN(2, "砍价订单"), |
| 22 | 22 | COMBINATION(3, "拼团订单"), |
| 23 | + POINT(4, "积分商城"), | |
| 23 | 24 | ; |
| 24 | 25 | |
| 25 | 26 | public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeOrderTypeEnum::getType).toArray(); |
| ... | ... | @@ -54,4 +55,8 @@ public enum TradeOrderTypeEnum implements IntArrayValuable { |
| 54 | 55 | return ObjectUtil.equal(type, COMBINATION.getType()); |
| 55 | 56 | } |
| 56 | 57 | |
| 58 | + public static boolean isPoint(Integer type) { | |
| 59 | + return ObjectUtil.equal(type, POINT.getType()); | |
| 60 | + } | |
| 61 | + | |
| 57 | 62 | } | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java
| ... | ... | @@ -6,13 +6,13 @@ import cn.iocoder.yudao.framework.common.validation.Mobile; |
| 6 | 6 | import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum; |
| 7 | 7 | import com.fasterxml.jackson.annotation.JsonIgnore; |
| 8 | 8 | import io.swagger.v3.oas.annotations.media.Schema; |
| 9 | -import lombok.Data; | |
| 10 | - | |
| 11 | 9 | import jakarta.validation.Valid; |
| 12 | 10 | import jakarta.validation.constraints.AssertTrue; |
| 13 | 11 | import jakarta.validation.constraints.Min; |
| 14 | 12 | import jakarta.validation.constraints.NotEmpty; |
| 15 | 13 | import jakarta.validation.constraints.NotNull; |
| 14 | +import lombok.Data; | |
| 15 | + | |
| 16 | 16 | import java.util.List; |
| 17 | 17 | |
| 18 | 18 | @Schema(description = "用户 App - 交易订单结算 Request VO") |
| ... | ... | @@ -62,6 +62,10 @@ public class AppTradeOrderSettlementReqVO { |
| 62 | 62 | @Schema(description = "砍价记录编号", example = "123") |
| 63 | 63 | private Long bargainRecordId; |
| 64 | 64 | |
| 65 | + // ========== 积分商城活动相关字段 ========== | |
| 66 | + @Schema(description = "积分商城活动编号", example = "123") | |
| 67 | + private Long pointActivityId; | |
| 68 | + | |
| 65 | 69 | @AssertTrue(message = "活动商品每次只能购买一种规格") |
| 66 | 70 | @JsonIgnore |
| 67 | 71 | public boolean isValidActivityItems() { | ... | ... |
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 { |
| 219 | 219 | .setSeckillActivityId(settlementReqVO.getSeckillActivityId()) |
| 220 | 220 | .setBargainRecordId(settlementReqVO.getBargainRecordId()) |
| 221 | 221 | .setCombinationActivityId(settlementReqVO.getCombinationActivityId()) |
| 222 | - .setCombinationHeadId(settlementReqVO.getCombinationHeadId()); | |
| 222 | + .setCombinationHeadId(settlementReqVO.getCombinationHeadId()) | |
| 223 | + .setPointActivityId(settlementReqVO.getPointActivityId()); | |
| 223 | 224 | // 商品项的构建 |
| 224 | 225 | Map<Long, CartDO> cartMap = convertMap(cartList, CartDO::getId); |
| 225 | 226 | for (AppTradeOrderSettlementReqVO.Item item : settlementReqVO.getItems()) { | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java
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 { |
| 42 | 42 | /** |
| 43 | 43 | * 获得指定用户,指定活动,指定状态的交易订单 |
| 44 | 44 | * |
| 45 | - * @param userId 用户编号 | |
| 45 | + * @param userId 用户编号 | |
| 46 | 46 | * @param combinationActivityId 活动编号 |
| 47 | - * @param status 订单状态 | |
| 47 | + * @param status 订单状态 | |
| 48 | 48 | * @return 交易订单 |
| 49 | 49 | */ |
| 50 | 50 | TradeOrderDO getOrderByUserIdAndStatusAndCombination(Long userId, Long combinationActivityId, Integer status); | ... | ... |
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 { |
| 245 | 245 | } |
| 246 | 246 | |
| 247 | 247 | // 3. 生成预支付 |
| 248 | - createPayOrder(order, orderItems); | |
| 248 | + // 特殊情况:积分兑换时,可能支付金额为零 | |
| 249 | + if (order.getPayPrice() > 0) { | |
| 250 | + createPayOrder(order, orderItems); | |
| 251 | + } | |
| 249 | 252 | |
| 250 | 253 | // 4. 插入订单日志 |
| 251 | 254 | TradeOrderLogUtils.setOrderInfo(order.getId(), null, order.getStatus()); | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradePointOrderHandler.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.trade.service.order.handler; | |
| 2 | + | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 4 | +import cn.hutool.core.lang.Assert; | |
| 5 | +import cn.iocoder.yudao.module.promotion.api.point.PointActivityApi; | |
| 6 | +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; | |
| 7 | +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; | |
| 8 | +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; | |
| 9 | +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; | |
| 10 | +import jakarta.annotation.Resource; | |
| 11 | +import org.springframework.stereotype.Component; | |
| 12 | + | |
| 13 | +import java.util.List; | |
| 14 | +import java.util.Objects; | |
| 15 | + | |
| 16 | +/** | |
| 17 | + * 积分商城活动订单的 {@link TradeOrderHandler} 实现类 | |
| 18 | + * | |
| 19 | + * @author HUIHUI | |
| 20 | + */ | |
| 21 | +@Component | |
| 22 | +public class TradePointOrderHandler implements TradeOrderHandler { | |
| 23 | + | |
| 24 | + @Resource | |
| 25 | + private PointActivityApi pointActivityApi; | |
| 26 | + | |
| 27 | + @Override | |
| 28 | + public void beforeOrderCreate(TradeOrderDO order, List<TradeOrderItemDO> orderItems) { | |
| 29 | + if (!TradeOrderTypeEnum.isPoint(order.getType())) { | |
| 30 | + return; | |
| 31 | + } | |
| 32 | + // 明确校验一下 | |
| 33 | + Assert.isTrue(orderItems.size() == 1, "积分商城活动兑换商品兑换时,只允许选择一个商品"); | |
| 34 | + | |
| 35 | + // 扣减积分商城活动的库存 | |
| 36 | + pointActivityApi.updatePointStockDecr(order.getPointActivityId(), | |
| 37 | + orderItems.get(0).getSkuId(), orderItems.get(0).getCount()); | |
| 38 | + | |
| 39 | + // 如果支付金额为 0,则直接设置为已支付 | |
| 40 | + if (Objects.equals(order.getPayPrice(), 0)) { | |
| 41 | + order.setPayStatus(true).setStatus(TradeOrderStatusEnum.UNDELIVERED.getStatus()); | |
| 42 | + } | |
| 43 | + } | |
| 44 | + | |
| 45 | + @Override | |
| 46 | + public void afterCancelOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) { | |
| 47 | + if (!TradeOrderTypeEnum.isPoint(order.getType())) { | |
| 48 | + return; | |
| 49 | + } | |
| 50 | + // 明确校验一下 | |
| 51 | + Assert.isTrue(orderItems.size() == 1, "积分商城活动兑换商品兑换时,只允许选择一个商品"); | |
| 52 | + | |
| 53 | + // 售后的订单项,已经在 afterCancelOrderItem 回滚库存,所以这里不需要重复回滚 | |
| 54 | + orderItems = filterOrderItemListByNoneAfterSale(orderItems); | |
| 55 | + if (CollUtil.isEmpty(orderItems)) { | |
| 56 | + return; | |
| 57 | + } | |
| 58 | + afterCancelOrderItem(order, orderItems.get(0)); | |
| 59 | + } | |
| 60 | + | |
| 61 | + @Override | |
| 62 | + public void afterCancelOrderItem(TradeOrderDO order, TradeOrderItemDO orderItem) { | |
| 63 | + if (!TradeOrderTypeEnum.isPoint(order.getType())) { | |
| 64 | + return; | |
| 65 | + } | |
| 66 | + // 恢复积分商城活动的库存 | |
| 67 | + pointActivityApi.updatePointStockIncr(order.getPointActivityId(), | |
| 68 | + orderItem.getSkuId(), orderItem.getCount()); | |
| 69 | + } | |
| 70 | + | |
| 71 | +} | ... | ... |
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 { |
| 69 | 69 | .buildCalculateResp(calculateReqBO, spuList, skuList); |
| 70 | 70 | priceCalculators.forEach(calculator -> calculator.calculate(calculateReqBO, calculateRespBO)); |
| 71 | 71 | // 2.2 如果最终支付金额小于等于 0,则抛出业务异常 |
| 72 | - if (calculateRespBO.getPrice().getPayPrice() <= 0) { | |
| 72 | + if (calculateReqBO.getPointActivityId() == null // 积分订单,允许支付金额为 0 | |
| 73 | + && calculateRespBO.getPrice().getPayPrice() <= 0) { | |
| 73 | 74 | log.error("[calculatePrice][价格计算不正确,请求 calculateReqDTO({}),结果 priceCalculate({})]", |
| 74 | 75 | calculateReqBO, calculateRespBO); |
| 75 | 76 | throw exception(PRICE_CALCULATE_PAY_PRICE_ILLEGAL); | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java
| 1 | 1 | package cn.iocoder.yudao.module.trade.service.price.bo; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum; |
| 4 | -import lombok.Data; | |
| 5 | - | |
| 6 | 4 | import jakarta.validation.Valid; |
| 7 | 5 | import jakarta.validation.constraints.Min; |
| 8 | 6 | import jakarta.validation.constraints.NotNull; |
| 7 | +import lombok.Data; | |
| 8 | + | |
| 9 | 9 | import java.util.List; |
| 10 | 10 | |
| 11 | 11 | /** |
| ... | ... | @@ -84,6 +84,12 @@ public class TradePriceCalculateReqBO { |
| 84 | 84 | */ |
| 85 | 85 | private Long bargainRecordId; |
| 86 | 86 | |
| 87 | + // ========== 积分商城活动相关字段 ========== | |
| 88 | + /** | |
| 89 | + * 积分商城活动编号 | |
| 90 | + */ | |
| 91 | + private Long pointActivityId; | |
| 92 | + | |
| 87 | 93 | /** |
| 88 | 94 | * 商品 SKU |
| 89 | 95 | */ | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointActivityPriceCalculator.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.trade.service.price.calculator; | |
| 2 | + | |
| 3 | +import cn.hutool.core.lang.Assert; | |
| 4 | +import cn.hutool.core.util.ObjectUtil; | |
| 5 | +import cn.hutool.core.util.StrUtil; | |
| 6 | +import cn.iocoder.yudao.module.member.api.user.MemberUserApi; | |
| 7 | +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; | |
| 8 | +import cn.iocoder.yudao.module.promotion.api.point.PointActivityApi; | |
| 9 | +import cn.iocoder.yudao.module.promotion.api.point.dto.PointValidateJoinRespDTO; | |
| 10 | +import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum; | |
| 11 | +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; | |
| 12 | +import cn.iocoder.yudao.module.trade.service.order.TradeOrderQueryService; | |
| 13 | +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; | |
| 14 | +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; | |
| 15 | +import jakarta.annotation.Resource; | |
| 16 | +import lombok.extern.slf4j.Slf4j; | |
| 17 | +import org.springframework.core.annotation.Order; | |
| 18 | +import org.springframework.stereotype.Component; | |
| 19 | + | |
| 20 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | |
| 21 | +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.PRICE_CALCULATE_POINT_TOTAL_LIMIT_COUNT; | |
| 22 | + | |
| 23 | +/** | |
| 24 | + * 积分商城的 {@link TradePriceCalculator} 实现类 | |
| 25 | + * | |
| 26 | + * @author owen | |
| 27 | + */ | |
| 28 | +@Component | |
| 29 | +@Order(TradePriceCalculator.ORDER_POINT_ACTIVITY) | |
| 30 | +@Slf4j | |
| 31 | +public class TradePointActivityPriceCalculator implements TradePriceCalculator { | |
| 32 | + | |
| 33 | + @Resource | |
| 34 | + private PointActivityApi pointActivityApi; | |
| 35 | + @Resource | |
| 36 | + private MemberUserApi memberUserApi; | |
| 37 | + | |
| 38 | + @Resource | |
| 39 | + private TradeOrderQueryService tradeOrderQueryService; | |
| 40 | + | |
| 41 | + @Override | |
| 42 | + public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) { | |
| 43 | + // 1.1 判断订单类型是否为积分商城活动 | |
| 44 | + if (ObjectUtil.notEqual(result.getType(), TradeOrderTypeEnum.POINT.getType())) { | |
| 45 | + return; | |
| 46 | + } | |
| 47 | + // 1.2 初始化积分 | |
| 48 | + MemberUserRespDTO user = memberUserApi.getUser(param.getUserId()); | |
| 49 | + result.setTotalPoint(user.getPoint()).setUsePoint(0); | |
| 50 | + | |
| 51 | + // 1.3 校验用户积分余额 | |
| 52 | + if (user.getPoint() == null || user.getPoint() <= 0) { | |
| 53 | + return; | |
| 54 | + } | |
| 55 | + | |
| 56 | + Assert.isTrue(param.getItems().size() == 1, "积分商城兑换商品时,只允许选择一个商品"); | |
| 57 | + // 2. 校验是否可以参与积分商城活动 | |
| 58 | + TradePriceCalculateRespBO.OrderItem orderItem = result.getItems().get(0); | |
| 59 | + PointValidateJoinRespDTO activity = validateJoinSeckill( | |
| 60 | + param.getUserId(), param.getPointActivityId(), | |
| 61 | + orderItem.getSkuId(), orderItem.getCount()); | |
| 62 | + | |
| 63 | + // 3.1 记录优惠明细 | |
| 64 | + int discountPrice = orderItem.getPayPrice(); // 情况一:单使用积分兑换 | |
| 65 | + Assert.isTrue(activity.getPoint() >= 1, "积分商城商品兑换积分必须大于 1"); | |
| 66 | + result.setUsePoint(activity.getPoint() * orderItem.getCount()); | |
| 67 | + orderItem.setUsePoint(activity.getPoint() * orderItem.getCount()); | |
| 68 | + if (activity.getPrice() != null && activity.getPrice() > 0) { // 情况二:积分 + 金额 | |
| 69 | + discountPrice = orderItem.getPayPrice() - activity.getPrice() * orderItem.getCount(); | |
| 70 | + } | |
| 71 | + // 3.2 记录优惠明细 | |
| 72 | + TradePriceCalculatorHelper.addPromotion(result, orderItem, | |
| 73 | + param.getPointActivityId(), "积分商城活动", PromotionTypeEnum.POINT.getType(), | |
| 74 | + StrUtil.format("积分商城活动:省 {} 元", TradePriceCalculatorHelper.formatPrice(discountPrice)), | |
| 75 | + discountPrice); | |
| 76 | + | |
| 77 | + // 3.3 更新 SKU 优惠金额 | |
| 78 | + orderItem.setDiscountPrice(orderItem.getDiscountPrice() + discountPrice); | |
| 79 | + TradePriceCalculatorHelper.recountPayPrice(orderItem); | |
| 80 | + TradePriceCalculatorHelper.recountAllPrice(result); | |
| 81 | + } | |
| 82 | + | |
| 83 | + private PointValidateJoinRespDTO validateJoinSeckill(Long userId, Long activityId, Long skuId, Integer count) { | |
| 84 | + // 1. 校验是否可以参与积分商城活动 | |
| 85 | + PointValidateJoinRespDTO pointValidateJoinRespDTO = pointActivityApi.validateJoinPointActivity(activityId, skuId, count); | |
| 86 | + // 2. 校验总限购数量,目前只有 trade 有具体下单的数据,需要交给 trade 价格计算使用 | |
| 87 | + int activityProductCount = tradeOrderQueryService.getSeckillProductCount(userId, activityId); | |
| 88 | + if (activityProductCount + count > pointValidateJoinRespDTO.getCount()) { | |
| 89 | + throw exception(PRICE_CALCULATE_POINT_TOTAL_LIMIT_COUNT); | |
| 90 | + } | |
| 91 | + return pointValidateJoinRespDTO; | |
| 92 | + } | |
| 93 | + | |
| 94 | +} | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointUsePriceCalculator.java
| 1 | 1 | package cn.iocoder.yudao.module.trade.service.price.calculator; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.util.BooleanUtil; |
| 4 | +import cn.hutool.core.util.ObjectUtil; | |
| 4 | 5 | import cn.hutool.core.util.StrUtil; |
| 5 | 6 | import cn.iocoder.yudao.module.member.api.config.MemberConfigApi; |
| 6 | 7 | import cn.iocoder.yudao.module.member.api.config.dto.MemberConfigRespDTO; |
| 7 | 8 | import cn.iocoder.yudao.module.member.api.user.MemberUserApi; |
| 8 | 9 | import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; |
| 9 | 10 | import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum; |
| 11 | +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; | |
| 10 | 12 | import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; |
| 11 | 13 | import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; |
| 12 | 14 | import jakarta.annotation.Resource; |
| ... | ... | @@ -37,6 +39,10 @@ public class TradePointUsePriceCalculator implements TradePriceCalculator { |
| 37 | 39 | |
| 38 | 40 | @Override |
| 39 | 41 | public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) { |
| 42 | + // 判断订单类型是否不为积分商城活动 | |
| 43 | + if (ObjectUtil.equal(result.getType(), TradeOrderTypeEnum.POINT.getType())) { | |
| 44 | + return; | |
| 45 | + } | |
| 40 | 46 | // 0. 初始化积分 |
| 41 | 47 | MemberUserRespDTO user = memberUserApi.getUser(param.getUserId()); |
| 42 | 48 | result.setTotalPoint(user.getPoint()).setUsePoint(0); | ... | ... |
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 { |
| 16 | 16 | int ORDER_SECKILL_ACTIVITY = 8; |
| 17 | 17 | int ORDER_BARGAIN_ACTIVITY = 8; |
| 18 | 18 | int ORDER_COMBINATION_ACTIVITY = 8; |
| 19 | + int ORDER_POINT_ACTIVITY = 8; | |
| 19 | 20 | |
| 20 | 21 | int ORDER_DISCOUNT_ACTIVITY = 10; |
| 21 | 22 | int ORDER_REWARD_ACTIVITY = 20; | ... | ... |
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 { |
| 90 | 90 | if (param.getBargainRecordId() != null) { |
| 91 | 91 | return TradeOrderTypeEnum.BARGAIN.getType(); |
| 92 | 92 | } |
| 93 | + if (param.getPointActivityId() != null) { | |
| 94 | + return TradeOrderTypeEnum.POINT.getType(); | |
| 95 | + } | |
| 93 | 96 | return TradeOrderTypeEnum.NORMAL.getType(); |
| 94 | 97 | } |
| 95 | 98 | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeSeckillActivityPriceCalculator.java
| ... | ... | @@ -8,11 +8,10 @@ import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum; |
| 8 | 8 | import cn.iocoder.yudao.module.trade.service.order.TradeOrderQueryService; |
| 9 | 9 | import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; |
| 10 | 10 | import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; |
| 11 | +import jakarta.annotation.Resource; | |
| 11 | 12 | import org.springframework.core.annotation.Order; |
| 12 | 13 | import org.springframework.stereotype.Component; |
| 13 | 14 | |
| 14 | -import jakarta.annotation.Resource; | |
| 15 | - | |
| 16 | 15 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 17 | 16 | import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.PRICE_CALCULATE_SECKILL_TOTAL_LIMIT_COUNT; |
| 18 | 17 | ... | ... |