Commit 342c25c0dd96c0796eeab8a32837fde1edf26ab3
1 parent
51fdbb81
【代码优化】商城: 完善积分商城
Showing
9 changed files
with
183 additions
and
93 deletions
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java
| @@ -46,7 +46,10 @@ public interface ErrorCodeConstants { | @@ -46,7 +46,10 @@ public interface ErrorCodeConstants { | ||
| 46 | 46 | ||
| 47 | // ========== 积分商城活动 1-013-007-000 ========== | 47 | // ========== 积分商城活动 1-013-007-000 ========== |
| 48 | ErrorCode POINT_ACTIVITY_NOT_EXISTS = new ErrorCode(1_013_007_000, "积分商城活动不存在"); | 48 | ErrorCode POINT_ACTIVITY_NOT_EXISTS = new ErrorCode(1_013_007_000, "积分商城活动不存在"); |
| 49 | - ErrorCode POINT_PRODUCT_NOT_EXISTS = new ErrorCode(1_013_007_100, "积分商城商品不存在"); | 49 | + ErrorCode POINT_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1_013_007_001, "存在商品参加了其它积分商城活动"); |
| 50 | + ErrorCode POINT_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1_013_007_002, "积分商城活动已关闭,不能修改"); | ||
| 51 | + ErrorCode POINT_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1_013_007_003, "积分商城活动未关闭或未结束,不能删除"); | ||
| 52 | + ErrorCode POINT_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1_013_007_004, "积分商城活动已关闭,不能重复关闭"); | ||
| 50 | 53 | ||
| 51 | // ========== 秒杀活动 1-013-008-000 ========== | 54 | // ========== 秒杀活动 1-013-008-000 ========== |
| 52 | ErrorCode SECKILL_ACTIVITY_NOT_EXISTS = new ErrorCode(1_013_008_000, "秒杀活动不存在"); | 55 | 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/controller/admin/point/PointActivityController.java
| @@ -51,6 +51,15 @@ public class PointActivityController { | @@ -51,6 +51,15 @@ public class PointActivityController { | ||
| 51 | return success(true); | 51 | return success(true); |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | + @PutMapping("/close") | ||
| 55 | + @Operation(summary = "关闭积分商城活动") | ||
| 56 | + @Parameter(name = "id", description = "编号", required = true) | ||
| 57 | + @PreAuthorize("@ss.hasPermission('promotion:point-activity:close')") | ||
| 58 | + public CommonResult<Boolean> closeSeckillActivity(@RequestParam("id") Long id) { | ||
| 59 | + pointActivityService.closePointActivity(id); | ||
| 60 | + return success(true); | ||
| 61 | + } | ||
| 62 | + | ||
| 54 | @DeleteMapping("/delete") | 63 | @DeleteMapping("/delete") |
| 55 | @Operation(summary = "删除积分商城活动") | 64 | @Operation(summary = "删除积分商城活动") |
| 56 | @Parameter(name = "id", description = "编号", required = true) | 65 | @Parameter(name = "id", description = "编号", required = true) |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/point/vo/product/PointProductSaveReqVO.java
| @@ -25,7 +25,7 @@ public class PointProductSaveReqVO { | @@ -25,7 +25,7 @@ public class PointProductSaveReqVO { | ||
| 25 | 25 | ||
| 26 | @Schema(description = "可兑换数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "3926") | 26 | @Schema(description = "可兑换数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "3926") |
| 27 | @NotNull(message = "可兑换数量不能为空") | 27 | @NotNull(message = "可兑换数量不能为空") |
| 28 | - private Integer maxCount; | 28 | + private Integer count; |
| 29 | 29 | ||
| 30 | @Schema(description = "兑换积分", requiredMode = Schema.RequiredMode.REQUIRED) | 30 | @Schema(description = "兑换积分", requiredMode = Schema.RequiredMode.REQUIRED) |
| 31 | @NotNull(message = "兑换积分不能为空") | 31 | @NotNull(message = "兑换积分不能为空") |
| @@ -35,9 +35,9 @@ public class PointProductSaveReqVO { | @@ -35,9 +35,9 @@ public class PointProductSaveReqVO { | ||
| 35 | @NotNull(message = "兑换金额,单位:分不能为空") | 35 | @NotNull(message = "兑换金额,单位:分不能为空") |
| 36 | private Integer price; | 36 | private Integer price; |
| 37 | 37 | ||
| 38 | - @Schema(description = "兑换类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") | ||
| 39 | - @NotNull(message = "兑换类型不能为空") | ||
| 40 | - private Integer type; | 38 | + @Schema(description = "积分商城商品库存", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") |
| 39 | + @NotNull(message = "积分商城商品不能为空") | ||
| 40 | + private Integer stock; | ||
| 41 | 41 | ||
| 42 | @Schema(description = "积分商城商品状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") | 42 | @Schema(description = "积分商城商品状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") |
| 43 | @NotNull(message = "积分商城商品状态不能为空") | 43 | @NotNull(message = "积分商城商品状态不能为空") |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/point/PointActivityDO.java
| @@ -45,4 +45,13 @@ public class PointActivityDO extends BaseDO { | @@ -45,4 +45,13 @@ public class PointActivityDO extends BaseDO { | ||
| 45 | */ | 45 | */ |
| 46 | private Integer sort; | 46 | private Integer sort; |
| 47 | 47 | ||
| 48 | + /** | ||
| 49 | + * 积分商城活动库存(剩余库存积分兑换时扣减) | ||
| 50 | + */ | ||
| 51 | + private Integer stock; | ||
| 52 | + /** | ||
| 53 | + * 积分商城活动总库存 | ||
| 54 | + */ | ||
| 55 | + private Integer totalStock; | ||
| 56 | + | ||
| 48 | } | 57 | } |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/point/PointProductDO.java
| @@ -42,24 +42,21 @@ public class PointProductDO extends BaseDO { | @@ -42,24 +42,21 @@ public class PointProductDO extends BaseDO { | ||
| 42 | */ | 42 | */ |
| 43 | private Long skuId; | 43 | private Long skuId; |
| 44 | /** | 44 | /** |
| 45 | - * 可兑换数量 | 45 | + * 可兑换次数 |
| 46 | */ | 46 | */ |
| 47 | - private Integer maxCount; | 47 | + private Integer count; |
| 48 | /** | 48 | /** |
| 49 | - * 兑换积分 | 49 | + * 所需兑换积分 |
| 50 | */ | 50 | */ |
| 51 | private Integer point; | 51 | private Integer point; |
| 52 | /** | 52 | /** |
| 53 | - * 兑换金额,单位:分 | 53 | + * 所需兑换金额,单位:分 |
| 54 | */ | 54 | */ |
| 55 | private Integer price; | 55 | private Integer price; |
| 56 | /** | 56 | /** |
| 57 | - * 兑换类型 | ||
| 58 | - * 1. 积分 | ||
| 59 | - * 2. 积分 + 钱 | ||
| 60 | - * 3. 直接购买 | 57 | + * 积分商城商品库存 |
| 61 | */ | 58 | */ |
| 62 | - private Integer type; | 59 | + private Integer stock; |
| 63 | /** | 60 | /** |
| 64 | * 积分商城商品状态 | 61 | * 积分商城商品状态 |
| 65 | * | 62 | * |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/pointproduct/PointProductDO.java deleted
| 1 | -package cn.iocoder.yudao.module.promotion.dal.dataobject.pointproduct; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | ||
| 4 | -import com.baomidou.mybatisplus.annotation.KeySequence; | ||
| 5 | -import com.baomidou.mybatisplus.annotation.TableId; | ||
| 6 | -import com.baomidou.mybatisplus.annotation.TableName; | ||
| 7 | -import lombok.*; | ||
| 8 | - | ||
| 9 | -/** | ||
| 10 | - * 积分商城商品 DO | ||
| 11 | - * | ||
| 12 | - * @author HUIHUI | ||
| 13 | - */ | ||
| 14 | -@TableName("promotion_point_product") | ||
| 15 | -@KeySequence("promotion_point_product_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 | ||
| 16 | -@Data | ||
| 17 | -@EqualsAndHashCode(callSuper = true) | ||
| 18 | -@ToString(callSuper = true) | ||
| 19 | -@Builder | ||
| 20 | -@NoArgsConstructor | ||
| 21 | -@AllArgsConstructor | ||
| 22 | -public class PointProductDO extends BaseDO { | ||
| 23 | - | ||
| 24 | - /** | ||
| 25 | - * 积分商城商品编号 | ||
| 26 | - */ | ||
| 27 | - @TableId | ||
| 28 | - private Long id; | ||
| 29 | - /** | ||
| 30 | - * 积分商城活动 id | ||
| 31 | - */ | ||
| 32 | - private Long activityId; | ||
| 33 | - /** | ||
| 34 | - * 商品 SPU 编号 | ||
| 35 | - */ | ||
| 36 | - private Long spuId; | ||
| 37 | - /** | ||
| 38 | - * 商品 SKU 编号 | ||
| 39 | - */ | ||
| 40 | - private Long skuId; | ||
| 41 | - /** | ||
| 42 | - * 可兑换数量 | ||
| 43 | - */ | ||
| 44 | - private Integer maxCount; | ||
| 45 | - /** | ||
| 46 | - * 兑换积分 | ||
| 47 | - */ | ||
| 48 | - private Integer point; | ||
| 49 | - /** | ||
| 50 | - * 兑换金额,单位:分 | ||
| 51 | - */ | ||
| 52 | - private Integer price; | ||
| 53 | - /** | ||
| 54 | - * 兑换类型 | ||
| 55 | - */ | ||
| 56 | - private Integer type; | ||
| 57 | - /** | ||
| 58 | - * 积分商城商品状态 | ||
| 59 | - */ | ||
| 60 | - private Integer activityStatus; | ||
| 61 | - | ||
| 62 | -} | ||
| 63 | \ No newline at end of file | 0 | \ 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
| @@ -4,9 +4,13 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; | @@ -4,9 +4,13 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 4 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | 4 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| 5 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | 5 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| 6 | import cn.iocoder.yudao.module.promotion.controller.admin.point.vo.product.PointProductPageReqVO; | 6 | import cn.iocoder.yudao.module.promotion.controller.admin.point.vo.product.PointProductPageReqVO; |
| 7 | -import cn.iocoder.yudao.module.promotion.dal.dataobject.pointproduct.PointProductDO; | 7 | +import cn.iocoder.yudao.module.promotion.dal.dataobject.point.PointProductDO; |
| 8 | +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; | ||
| 8 | import org.apache.ibatis.annotations.Mapper; | 9 | import org.apache.ibatis.annotations.Mapper; |
| 9 | 10 | ||
| 11 | +import java.util.Collection; | ||
| 12 | +import java.util.List; | ||
| 13 | + | ||
| 10 | /** | 14 | /** |
| 11 | * 积分商城商品 Mapper | 15 | * 积分商城商品 Mapper |
| 12 | * | 16 | * |
| @@ -20,13 +24,24 @@ public interface PointProductMapper extends BaseMapperX<PointProductDO> { | @@ -20,13 +24,24 @@ public interface PointProductMapper extends BaseMapperX<PointProductDO> { | ||
| 20 | .eqIfPresent(PointProductDO::getActivityId, reqVO.getActivityId()) | 24 | .eqIfPresent(PointProductDO::getActivityId, reqVO.getActivityId()) |
| 21 | .eqIfPresent(PointProductDO::getSpuId, reqVO.getSpuId()) | 25 | .eqIfPresent(PointProductDO::getSpuId, reqVO.getSpuId()) |
| 22 | .eqIfPresent(PointProductDO::getSkuId, reqVO.getSkuId()) | 26 | .eqIfPresent(PointProductDO::getSkuId, reqVO.getSkuId()) |
| 23 | - .eqIfPresent(PointProductDO::getMaxCount, reqVO.getMaxCount()) | ||
| 24 | .eqIfPresent(PointProductDO::getPoint, reqVO.getPoint()) | 27 | .eqIfPresent(PointProductDO::getPoint, reqVO.getPoint()) |
| 25 | .eqIfPresent(PointProductDO::getPrice, reqVO.getPrice()) | 28 | .eqIfPresent(PointProductDO::getPrice, reqVO.getPrice()) |
| 26 | - .eqIfPresent(PointProductDO::getType, reqVO.getType()) | ||
| 27 | .eqIfPresent(PointProductDO::getActivityStatus, reqVO.getActivityStatus()) | 29 | .eqIfPresent(PointProductDO::getActivityStatus, reqVO.getActivityStatus()) |
| 28 | .betweenIfPresent(PointProductDO::getCreateTime, reqVO.getCreateTime()) | 30 | .betweenIfPresent(PointProductDO::getCreateTime, reqVO.getCreateTime()) |
| 29 | .orderByDesc(PointProductDO::getId)); | 31 | .orderByDesc(PointProductDO::getId)); |
| 30 | } | 32 | } |
| 31 | 33 | ||
| 34 | + default List<PointProductDO> selectListByActivityId(Collection<Long> activityIds) { | ||
| 35 | + return selectList(PointProductDO::getActivityId, activityIds); | ||
| 36 | + } | ||
| 37 | + | ||
| 38 | + default List<PointProductDO> selectListByActivityId(Long activityId) { | ||
| 39 | + return selectList(PointProductDO::getActivityId, activityId); | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + default void updateByActivityId(PointProductDO pointProductDO) { | ||
| 43 | + update(pointProductDO, new LambdaUpdateWrapper<PointProductDO>() | ||
| 44 | + .eq(PointProductDO::getActivityId, pointProductDO.getActivityId())); | ||
| 45 | + } | ||
| 46 | + | ||
| 32 | } | 47 | } |
| 33 | \ No newline at end of file | 48 | \ 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
| @@ -29,6 +29,13 @@ public interface PointActivityService { | @@ -29,6 +29,13 @@ public interface PointActivityService { | ||
| 29 | void updatePointActivity(@Valid PointActivitySaveReqVO updateReqVO); | 29 | void updatePointActivity(@Valid PointActivitySaveReqVO updateReqVO); |
| 30 | 30 | ||
| 31 | /** | 31 | /** |
| 32 | + * 关闭积分商城活动 | ||
| 33 | + * | ||
| 34 | + * @param id 编号 | ||
| 35 | + */ | ||
| 36 | + void closePointActivity(Long id); | ||
| 37 | + | ||
| 38 | + /** | ||
| 32 | * 删除积分商城活动 | 39 | * 删除积分商城活动 |
| 33 | * | 40 | * |
| 34 | * @param id 编号 | 41 | * @param id 编号 |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/point/PointActivityServiceImpl.java
| 1 | package cn.iocoder.yudao.module.promotion.service.point; | 1 | package cn.iocoder.yudao.module.promotion.service.point; |
| 2 | 2 | ||
| 3 | +import cn.hutool.core.util.ObjectUtil; | ||
| 4 | +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | 6 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 5 | import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; | 7 | import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; |
| @@ -10,6 +12,7 @@ import cn.iocoder.yudao.module.promotion.controller.admin.point.vo.activity.Poin | @@ -10,6 +12,7 @@ import cn.iocoder.yudao.module.promotion.controller.admin.point.vo.activity.Poin | ||
| 10 | import cn.iocoder.yudao.module.promotion.controller.admin.point.vo.activity.PointActivitySaveReqVO; | 12 | import cn.iocoder.yudao.module.promotion.controller.admin.point.vo.activity.PointActivitySaveReqVO; |
| 11 | import cn.iocoder.yudao.module.promotion.controller.admin.point.vo.product.PointProductSaveReqVO; | 13 | import cn.iocoder.yudao.module.promotion.controller.admin.point.vo.product.PointProductSaveReqVO; |
| 12 | import cn.iocoder.yudao.module.promotion.dal.dataobject.point.PointActivityDO; | 14 | import cn.iocoder.yudao.module.promotion.dal.dataobject.point.PointActivityDO; |
| 15 | +import cn.iocoder.yudao.module.promotion.dal.dataobject.point.PointProductDO; | ||
| 13 | import cn.iocoder.yudao.module.promotion.dal.mysql.point.PointActivityMapper; | 16 | import cn.iocoder.yudao.module.promotion.dal.mysql.point.PointActivityMapper; |
| 14 | import cn.iocoder.yudao.module.promotion.dal.mysql.point.PointProductMapper; | 17 | import cn.iocoder.yudao.module.promotion.dal.mysql.point.PointProductMapper; |
| 15 | import jakarta.annotation.Resource; | 18 | import jakarta.annotation.Resource; |
| @@ -19,15 +22,16 @@ import org.springframework.validation.annotation.Validated; | @@ -19,15 +22,16 @@ import org.springframework.validation.annotation.Validated; | ||
| 19 | import java.util.List; | 22 | import java.util.List; |
| 20 | import java.util.Map; | 23 | import java.util.Map; |
| 21 | 24 | ||
| 25 | +import static cn.hutool.core.collection.CollUtil.intersectionDistinct; | ||
| 26 | +import static cn.hutool.core.collection.CollUtil.isNotEmpty; | ||
| 22 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 27 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 23 | -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; | 28 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; |
| 29 | +import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; | ||
| 24 | import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS; | 30 | import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS; |
| 25 | import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS; | 31 | import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS; |
| 26 | -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.POINT_ACTIVITY_NOT_EXISTS; | 32 | +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; |
| 27 | import static java.util.Collections.singletonList; | 33 | import static java.util.Collections.singletonList; |
| 28 | 34 | ||
| 29 | -// TODO @puhui999: 下次提交完善 | ||
| 30 | - | ||
| 31 | /** | 35 | /** |
| 32 | * 积分商城活动 Service 实现类 | 36 | * 积分商城活动 Service 实现类 |
| 33 | * | 37 | * |
| @@ -47,13 +51,27 @@ public class PointActivityServiceImpl implements PointActivityService { | @@ -47,13 +51,27 @@ public class PointActivityServiceImpl implements PointActivityService { | ||
| 47 | @Resource | 51 | @Resource |
| 48 | private ProductSkuApi productSkuApi; | 52 | private ProductSkuApi productSkuApi; |
| 49 | 53 | ||
| 54 | + private static List<PointProductDO> buildPointProductDO(PointActivityDO pointActivity, List<PointProductSaveReqVO> products) { | ||
| 55 | + return BeanUtils.toBean(products, PointProductDO.class, product -> { | ||
| 56 | + product.setActivityId(pointActivity.getId()).setActivityStatus(pointActivity.getStatus()); | ||
| 57 | + }); | ||
| 58 | + } | ||
| 59 | + | ||
| 50 | @Override | 60 | @Override |
| 51 | public Long createPointActivity(PointActivitySaveReqVO createReqVO) { | 61 | public Long createPointActivity(PointActivitySaveReqVO createReqVO) { |
| 52 | - // 1. 校验商品是否存在 | 62 | + // 1.1 校验商品是否存在 |
| 53 | validateProductExists(createReqVO.getSpuId(), createReqVO.getProducts()); | 63 | validateProductExists(createReqVO.getSpuId(), createReqVO.getProducts()); |
| 54 | - // 插入 | ||
| 55 | - PointActivityDO pointActivity = BeanUtils.toBean(createReqVO, PointActivityDO.class); | 64 | + // 1.2 校验商品是否已经参加别的活动 |
| 65 | + validatePointActivityProductConflicts(null, createReqVO.getProducts()); | ||
| 66 | + | ||
| 67 | + // 2.1 插入积分商城活动 | ||
| 68 | + PointActivityDO pointActivity = BeanUtils.toBean(createReqVO, PointActivityDO.class) | ||
| 69 | + .setStatus(CommonStatusEnum.ENABLE.getStatus()) | ||
| 70 | + .setStock(getSumValue(createReqVO.getProducts(), PointProductSaveReqVO::getStock, Integer::sum)); | ||
| 71 | + pointActivity.setTotalStock(pointActivity.getStock()); | ||
| 56 | pointActivityMapper.insert(pointActivity); | 72 | pointActivityMapper.insert(pointActivity); |
| 73 | + // 2.2 插入积分商城活动商品 | ||
| 74 | + pointProductMapper.insertBatch(buildPointProductDO(pointActivity, createReqVO.getProducts())); | ||
| 57 | // 返回 | 75 | // 返回 |
| 58 | return pointActivity.getId(); | 76 | return pointActivity.getId(); |
| 59 | } | 77 | } |
| @@ -61,27 +79,92 @@ public class PointActivityServiceImpl implements PointActivityService { | @@ -61,27 +79,92 @@ public class PointActivityServiceImpl implements PointActivityService { | ||
| 61 | @Override | 79 | @Override |
| 62 | public void updatePointActivity(PointActivitySaveReqVO updateReqVO) { | 80 | public void updatePointActivity(PointActivitySaveReqVO updateReqVO) { |
| 63 | // 1.1 校验存在 | 81 | // 1.1 校验存在 |
| 64 | - validatePointActivityExists(updateReqVO.getId()); | 82 | + PointActivityDO activity = validatePointActivityExists(updateReqVO.getId()); |
| 83 | + if (CommonStatusEnum.DISABLE.getStatus().equals(activity.getStatus())) { | ||
| 84 | + throw exception(POINT_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED); | ||
| 85 | + } | ||
| 65 | // 1.2 校验商品是否存在 | 86 | // 1.2 校验商品是否存在 |
| 66 | validateProductExists(updateReqVO.getSpuId(), updateReqVO.getProducts()); | 87 | validateProductExists(updateReqVO.getSpuId(), updateReqVO.getProducts()); |
| 88 | + // 1.3 校验商品是否已经参加别的活动 | ||
| 89 | + validatePointActivityProductConflicts(updateReqVO.getId(), updateReqVO.getProducts()); | ||
| 90 | + | ||
| 91 | + // 2.1 更新积分商城活动 | ||
| 92 | + PointActivityDO updateObj = BeanUtils.toBean(updateReqVO, PointActivityDO.class) | ||
| 93 | + .setStock(getSumValue(updateReqVO.getProducts(), PointProductSaveReqVO::getStock, Integer::sum)); | ||
| 94 | + if (updateObj.getStock() > activity.getTotalStock()) { // 如果更新的库存大于原来的库存,则更新总库存 | ||
| 95 | + updateObj.setTotalStock(updateObj.getStock()); | ||
| 96 | + } | ||
| 97 | + pointActivityMapper.updateById(updateObj); | ||
| 98 | + // 2.2 更新商品 | ||
| 99 | + updateSeckillProduct(updateObj, updateReqVO.getProducts()); | ||
| 100 | + } | ||
| 101 | + | ||
| 102 | + @Override | ||
| 103 | + public void closePointActivity(Long id) { | ||
| 104 | + // 校验存在 | ||
| 105 | + PointActivityDO pointActivity = validatePointActivityExists(id); | ||
| 106 | + if (CommonStatusEnum.DISABLE.getStatus().equals(pointActivity.getStatus())) { | ||
| 107 | + throw exception(POINT_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED); | ||
| 108 | + } | ||
| 67 | 109 | ||
| 68 | // 更新 | 110 | // 更新 |
| 69 | - PointActivityDO updateObj = BeanUtils.toBean(updateReqVO, PointActivityDO.class); | ||
| 70 | - pointActivityMapper.updateById(updateObj); | 111 | + pointActivityMapper.updateById(new PointActivityDO().setId(id).setStatus(CommonStatusEnum.DISABLE.getStatus())); |
| 112 | + // 更新活动商品状态 | ||
| 113 | + pointProductMapper.updateByActivityId(new PointProductDO().setActivityId(id).setActivityStatus( | ||
| 114 | + CommonStatusEnum.DISABLE.getStatus())); | ||
| 115 | + } | ||
| 116 | + | ||
| 117 | + /** | ||
| 118 | + * 更新秒杀商品 | ||
| 119 | + * | ||
| 120 | + * @param activity 秒杀活动 | ||
| 121 | + * @param products 该活动的最新商品配置 | ||
| 122 | + */ | ||
| 123 | + private void updateSeckillProduct(PointActivityDO activity, List<PointProductSaveReqVO> products) { | ||
| 124 | + // 第一步,对比新老数据,获得添加、修改、删除的列表 | ||
| 125 | + List<PointProductDO> newList = buildPointProductDO(activity, products); | ||
| 126 | + List<PointProductDO> oldList = pointProductMapper.selectListByActivityId(activity.getId()); | ||
| 127 | + List<List<PointProductDO>> diffList = diffList(oldList, newList, (oldVal, newVal) -> { | ||
| 128 | + boolean same = ObjectUtil.equal(oldVal.getSkuId(), newVal.getSkuId()); | ||
| 129 | + if (same) { | ||
| 130 | + newVal.setId(oldVal.getId()); | ||
| 131 | + } | ||
| 132 | + return same; | ||
| 133 | + }); | ||
| 134 | + | ||
| 135 | + // 第二步,批量添加、修改、删除 | ||
| 136 | + if (isNotEmpty(diffList.get(0))) { | ||
| 137 | + pointProductMapper.insertBatch(diffList.get(0)); | ||
| 138 | + } | ||
| 139 | + if (isNotEmpty(diffList.get(1))) { | ||
| 140 | + pointProductMapper.updateBatch(diffList.get(1)); | ||
| 141 | + } | ||
| 142 | + if (isNotEmpty(diffList.get(2))) { | ||
| 143 | + pointProductMapper.deleteByIds(convertList(diffList.get(2), PointProductDO::getId)); | ||
| 144 | + } | ||
| 71 | } | 145 | } |
| 72 | 146 | ||
| 73 | @Override | 147 | @Override |
| 74 | public void deletePointActivity(Long id) { | 148 | public void deletePointActivity(Long id) { |
| 75 | // 校验存在 | 149 | // 校验存在 |
| 76 | - validatePointActivityExists(id); | ||
| 77 | - // 删除 | 150 | + PointActivityDO pointActivity = validatePointActivityExists(id); |
| 151 | + if (CommonStatusEnum.ENABLE.getStatus().equals(pointActivity.getStatus())) { | ||
| 152 | + throw exception(POINT_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END); | ||
| 153 | + } | ||
| 154 | + | ||
| 155 | + // 删除商城活动 | ||
| 78 | pointActivityMapper.deleteById(id); | 156 | pointActivityMapper.deleteById(id); |
| 157 | + // 删除活动商品 | ||
| 158 | + List<PointProductDO> products = pointProductMapper.selectListByActivityId(id); | ||
| 159 | + pointProductMapper.deleteByIds(convertSet(products, PointProductDO::getId)); | ||
| 79 | } | 160 | } |
| 80 | 161 | ||
| 81 | - private void validatePointActivityExists(Long id) { | ||
| 82 | - if (pointActivityMapper.selectById(id) == null) { | 162 | + private PointActivityDO validatePointActivityExists(Long id) { |
| 163 | + PointActivityDO pointActivityDO = pointActivityMapper.selectById(id); | ||
| 164 | + if (pointActivityDO == null) { | ||
| 83 | throw exception(POINT_ACTIVITY_NOT_EXISTS); | 165 | throw exception(POINT_ACTIVITY_NOT_EXISTS); |
| 84 | } | 166 | } |
| 167 | + return pointActivityDO; | ||
| 85 | } | 168 | } |
| 86 | 169 | ||
| 87 | /** | 170 | /** |
| @@ -107,6 +190,35 @@ public class PointActivityServiceImpl implements PointActivityService { | @@ -107,6 +190,35 @@ public class PointActivityServiceImpl implements PointActivityService { | ||
| 107 | }); | 190 | }); |
| 108 | } | 191 | } |
| 109 | 192 | ||
| 193 | + /** | ||
| 194 | + * 校验商品是否冲突 | ||
| 195 | + * | ||
| 196 | + * @param id 编号 | ||
| 197 | + * @param products 商品列表 | ||
| 198 | + */ | ||
| 199 | + private void validatePointActivityProductConflicts(Long id, List<PointProductSaveReqVO> products) { | ||
| 200 | + // 1.1 查询所有开启的积分商城活动 | ||
| 201 | + List<PointActivityDO> activityList = pointActivityMapper.selectList(PointActivityDO::getStatus, | ||
| 202 | + CommonStatusEnum.ENABLE.getStatus()); | ||
| 203 | + if (id != null) { // 更新时排除自己 | ||
| 204 | + activityList.removeIf(item -> ObjectUtil.equal(item.getId(), id)); | ||
| 205 | + } | ||
| 206 | + // 1.2 查询活动下的所有商品 | ||
| 207 | + List<PointProductDO> productList = pointProductMapper.selectListByActivityId( | ||
| 208 | + convertList(activityList, PointActivityDO::getId)); | ||
| 209 | + Map<Long, List<PointProductDO>> productListMap = convertMultiMap(productList, PointProductDO::getActivityId); | ||
| 210 | + | ||
| 211 | + // 2. 校验商品是否冲突 | ||
| 212 | + activityList.forEach(item -> { | ||
| 213 | + findAndThen(productListMap, item.getId(), discountProducts -> { | ||
| 214 | + if (!intersectionDistinct(convertList(discountProducts, PointProductDO::getSpuId), | ||
| 215 | + convertList(products, PointProductSaveReqVO::getSpuId)).isEmpty()) { | ||
| 216 | + throw exception(POINT_ACTIVITY_SPU_CONFLICTS); | ||
| 217 | + } | ||
| 218 | + }); | ||
| 219 | + }); | ||
| 220 | + } | ||
| 221 | + | ||
| 110 | @Override | 222 | @Override |
| 111 | public PointActivityDO getPointActivity(Long id) { | 223 | public PointActivityDO getPointActivity(Long id) { |
| 112 | return pointActivityMapper.selectById(id); | 224 | return pointActivityMapper.selectById(id); |