Commit 54baad165de937ac4853bd4470ca92205b62dd1d

Authored by halfninety
1 parent 7bc1ae5f

秒杀时段新增修改时间段冲突校验。

秒杀活动新增,修改,删除时对秒杀时段的秒杀活动数量进行修改
Showing 13 changed files with 180 additions and 175 deletions
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java
@@ -47,10 +47,14 @@ public interface ErrorCodeConstants { @@ -47,10 +47,14 @@ public interface ErrorCodeConstants {
47 47
48 // ========== 秒杀活动 1003008000 ========== 48 // ========== 秒杀活动 1003008000 ==========
49 ErrorCode SECKILL_ACTIVITY_NOT_EXISTS = new ErrorCode(1003008000, "秒杀活动不存在"); 49 ErrorCode SECKILL_ACTIVITY_NOT_EXISTS = new ErrorCode(1003008000, "秒杀活动不存在");
50 - ErrorCode SECKILL_TIME_NOT_EXISTS = new ErrorCode(1003008001, "秒杀时段不存在");  
51 - ErrorCode SECKILL_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1003008001, "存在商品参加了其它秒杀活动");  
52 - ErrorCode SECKILL_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1003006002, "秒杀活动已关闭,不能修改");  
53 - ErrorCode SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED = new ErrorCode(1003006003, "秒杀活动未关闭,不能删除");  
54 - ErrorCode SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1003006004, "秒杀活动已关闭,不能重复关闭");  
55 - ErrorCode SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_END = new ErrorCode(1003006004, "秒杀活动已结束,不能关闭"); 50 + ErrorCode SECKILL_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1003008002, "存在商品参加了其它秒杀活动");
  51 + ErrorCode SECKILL_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1003008003, "秒杀活动已关闭,不能修改");
  52 + ErrorCode SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1003008004, "秒杀活动未关闭或未结束,不能删除");
  53 + ErrorCode SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1003008005, "秒杀活动已关闭,不能重复关闭");
  54 + ErrorCode SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_END = new ErrorCode(1003008006, "秒杀活动已结束,不能关闭");
  55 +
  56 + // ========== 秒杀时段 1003009000 ==========
  57 + ErrorCode SECKILL_TIME_NOT_EXISTS = new ErrorCode(1003009000, "秒杀时段不存在");
  58 + ErrorCode SECKILL_TIME_CONFLICTS = new ErrorCode(1003009001, "秒杀时段冲突");
  59 +
56 } 60 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/SeckillTimeController.java
1 package cn.iocoder.yudao.module.promotion.controller.admin.seckilltime; 1 package cn.iocoder.yudao.module.promotion.controller.admin.seckilltime;
2 2
3 -import org.springframework.web.bind.annotation.*;  
4 -import javax.annotation.Resource;  
5 -import org.springframework.validation.annotation.Validated; 3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo.SeckillTimeCreateReqVO;
  5 +import cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo.SeckillTimeRespVO;
  6 +import cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo.SeckillTimeUpdateReqVO;
  7 +import cn.iocoder.yudao.module.promotion.convert.seckilltime.SeckillTimeConvert;
  8 +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckilltime.SeckillTimeDO;
  9 +import cn.iocoder.yudao.module.promotion.service.seckilltime.SeckillTimeService;
  10 +import io.swagger.annotations.Api;
  11 +import io.swagger.annotations.ApiImplicitParam;
  12 +import io.swagger.annotations.ApiOperation;
6 import org.springframework.security.access.prepost.PreAuthorize; 13 import org.springframework.security.access.prepost.PreAuthorize;
7 -import io.swagger.annotations.*; 14 +import org.springframework.validation.annotation.Validated;
  15 +import org.springframework.web.bind.annotation.*;
8 16
9 -import javax.validation.constraints.*;  
10 -import javax.validation.*;  
11 -import javax.servlet.http.*;  
12 -import java.util.*;  
13 -import java.io.IOException; 17 +import javax.annotation.Resource;
  18 +import javax.validation.Valid;
  19 +import java.util.List;
14 20
15 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
16 -import cn.iocoder.yudao.framework.common.pojo.CommonResult;  
17 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 21 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
18 22
19 -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;  
20 -  
21 -import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;  
22 -import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*;  
23 -  
24 -import cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo.*;  
25 -import cn.iocoder.yudao.module.promotion.dal.dataobject.seckilltime.SeckillTimeDO;  
26 -import cn.iocoder.yudao.module.promotion.convert.seckilltime.SeckillTimeConvert;  
27 -import cn.iocoder.yudao.module.promotion.service.seckilltime.SeckillTimeService;  
28 -  
29 @Api(tags = "管理后台 - 秒杀时段") 23 @Api(tags = "管理后台 - 秒杀时段")
30 @RestController 24 @RestController
31 @RequestMapping("/promotion/seckill-time") 25 @RequestMapping("/promotion/seckill-time")
@@ -84,16 +78,4 @@ public class SeckillTimeController { @@ -84,16 +78,4 @@ public class SeckillTimeController {
84 // return success(SeckillTimeConvert.INSTANCE.convertPage(pageResult)); 78 // return success(SeckillTimeConvert.INSTANCE.convertPage(pageResult));
85 // } 79 // }
86 80
87 - @GetMapping("/export-excel")  
88 - @ApiOperation("导出秒杀时段 Excel")  
89 - @PreAuthorize("@ss.hasPermission('promotion:seckill-time:export')")  
90 - @OperateLog(type = EXPORT)  
91 - public void exportSeckillTimeExcel(@Valid SeckillTimeExportReqVO exportReqVO,  
92 - HttpServletResponse response) throws IOException {  
93 - List<SeckillTimeDO> list = seckillTimeService.getSeckillTimeList(exportReqVO);  
94 - // 导出 Excel  
95 - List<SeckillTimeExcelVO> datas = SeckillTimeConvert.INSTANCE.convertList02(list);  
96 - ExcelUtils.write(response, "秒杀时段.xls", "数据", SeckillTimeExcelVO.class, datas);  
97 - }  
98 -  
99 } 81 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/vo/SeckillTimeExcelVO.java deleted
1 -package cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo;  
2 -  
3 -import lombok.*;  
4 -  
5 -import java.time.LocalTime;  
6 -import java.util.*;  
7 -import io.swagger.annotations.*;  
8 -  
9 -import com.alibaba.excel.annotation.ExcelProperty;  
10 -  
11 -/**  
12 - * 秒杀时段 Excel VO  
13 - *  
14 - * @author 芋道源码  
15 - */  
16 -@Data  
17 -public class SeckillTimeExcelVO {  
18 -  
19 - @ExcelProperty("编号")  
20 - private Long id;  
21 -  
22 - @ExcelProperty("秒杀时段名称")  
23 - private String name;  
24 -  
25 - @ExcelProperty("开始时间点")  
26 - private LocalTime startTime;  
27 -  
28 - @ExcelProperty("结束时间点")  
29 - private LocalTime endTime;  
30 -  
31 - @ExcelProperty("商品数量")  
32 - private Integer productCount;  
33 -  
34 - @ExcelProperty("创建时间")  
35 - private Date createTime;  
36 -  
37 -}  
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/vo/SeckillTimeExportReqVO.java deleted
1 -package cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo;  
2 -  
3 -import lombok.*;  
4 -  
5 -import java.time.LocalTime;  
6 -import java.util.*;  
7 -import io.swagger.annotations.*;  
8 -import cn.iocoder.yudao.framework.common.pojo.PageParam;  
9 -import org.springframework.format.annotation.DateTimeFormat;  
10 -  
11 -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;  
12 -  
13 -@ApiModel(value = "管理后台 - 秒杀时段 Excel 导出 Request VO", description = "参数和 SeckillTimePageReqVO 是一致的")  
14 -@Data  
15 -public class SeckillTimeExportReqVO {  
16 -  
17 - @ApiModelProperty(value = "秒杀时段名称")  
18 - private String name;  
19 -  
20 - @ApiModelProperty(value = "开始时间点")  
21 - private LocalTime[] startTime;  
22 -  
23 - @ApiModelProperty(value = "结束时间点")  
24 - private LocalTime[] endTime;  
25 -  
26 - @ApiModelProperty(value = "创建时间")  
27 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
28 - private Date[] createTime;  
29 -  
30 -}  
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/vo/SeckillTimeRespVO.java
@@ -13,8 +13,8 @@ public class SeckillTimeRespVO extends SeckillTimeBaseVO { @@ -13,8 +13,8 @@ public class SeckillTimeRespVO extends SeckillTimeBaseVO {
13 @ApiModelProperty(value = "编号", required = true) 13 @ApiModelProperty(value = "编号", required = true)
14 private Long id; 14 private Long id;
15 15
16 - @ApiModelProperty(value = "商品数量", required = true)  
17 - private Integer productCount; 16 + @ApiModelProperty(value = "秒杀活动数量", required = true)
  17 + private Integer seckillActivityCount;
18 18
19 @ApiModelProperty(value = "创建时间", required = true) 19 @ApiModelProperty(value = "创建时间", required = true)
20 private Date createTime; 20 private Date createTime;
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckilltime/SeckillTimeConvert.java
@@ -29,5 +29,4 @@ public interface SeckillTimeConvert { @@ -29,5 +29,4 @@ public interface SeckillTimeConvert {
29 29
30 PageResult<SeckillTimeRespVO> convertPage(PageResult<SeckillTimeDO> page); 30 PageResult<SeckillTimeRespVO> convertPage(PageResult<SeckillTimeDO> page);
31 31
32 - List<SeckillTimeExcelVO> convertList02(List<SeckillTimeDO> list);  
33 } 32 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckilltime/SeckillTimeDO.java
1 package cn.iocoder.yudao.module.promotion.dal.dataobject.seckilltime; 1 package cn.iocoder.yudao.module.promotion.dal.dataobject.seckilltime;
2 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;
3 import lombok.*; 7 import lombok.*;
4 8
5 import java.time.LocalTime; 9 import java.time.LocalTime;
6 -import java.util.*;  
7 -import com.baomidou.mybatisplus.annotation.*;  
8 -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;  
9 10
10 /** 11 /**
11 * 秒杀时段 DO 12 * 秒杀时段 DO
@@ -40,8 +41,8 @@ public class SeckillTimeDO extends BaseDO { @@ -40,8 +41,8 @@ public class SeckillTimeDO extends BaseDO {
40 */ 41 */
41 private LocalTime endTime; 42 private LocalTime endTime;
42 /** 43 /**
43 - * 商品数量 44 + * 秒杀活动数量
44 */ 45 */
45 - private Integer productCount; 46 + private Integer seckillActivityCount;
46 47
47 } 48 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckilltime/SeckillTimeMapper.java
1 package cn.iocoder.yudao.module.promotion.dal.mysql.seckilltime; 1 package cn.iocoder.yudao.module.promotion.dal.mysql.seckilltime;
2 2
  3 +import java.time.LocalTime;
3 import java.util.*; 4 import java.util.*;
4 5
  6 +import cn.hutool.core.collection.CollUtil;
  7 +import cn.hutool.core.util.ObjectUtil;
5 import cn.iocoder.yudao.framework.common.pojo.PageResult; 8 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; 9 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
7 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 10 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
8 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckilltime.SeckillTimeDO; 11 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckilltime.SeckillTimeDO;
  12 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  13 +import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
  14 +import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper;
9 import org.apache.ibatis.annotations.Mapper; 15 import org.apache.ibatis.annotations.Mapper;
10 import cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo.*; 16 import cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo.*;
11 17
@@ -16,25 +22,42 @@ import cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo.*; @@ -16,25 +22,42 @@ import cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo.*;
16 */ 22 */
17 @Mapper 23 @Mapper
18 public interface SeckillTimeMapper extends BaseMapperX<SeckillTimeDO> { 24 public interface SeckillTimeMapper extends BaseMapperX<SeckillTimeDO> {
  25 + default List<SeckillTimeDO> selectListWithTime(LocalTime time){
  26 + if (time == null) {
  27 + return Collections.emptyList();
  28 + }
  29 + return selectList(new LambdaQueryWrapper<SeckillTimeDO>()
  30 + .le(SeckillTimeDO::getStartTime,time)
  31 + .ge(SeckillTimeDO::getEndTime,time));
  32 + }
  33 +
  34 + default List<SeckillTimeDO> selectListWithTime(LocalTime startTime, LocalTime endTime){
  35 + if (startTime == null && endTime == null) {
  36 + return Collections.emptyList();
  37 + }
  38 + return selectList(new LambdaQueryWrapper<SeckillTimeDO>()
  39 + .ge(SeckillTimeDO::getStartTime,startTime)
  40 + .le(SeckillTimeDO::getEndTime,endTime));
  41 + }
19 42
20 -// default PageResult<SeckillTimeDO> selectPage(SeckillTimePageReqVO reqVO) {  
21 -// return selectPage(reqVO, new LambdaQueryWrapperX<SeckillTimeDO>()  
22 -// .likeIfPresent(SeckillTimeDO::getName, reqVO.getName())  
23 -// .geIfPresent(SeckillTimeDO::getStartTime, reqVO.getStartTime())  
24 -// .leIfPresent(SeckillTimeDO::getEndTime, reqVO.getEndTime())  
25 -//// .betweenIfPresent(SeckillTimeDO::getStartTime, reqVO.getStartTime())  
26 -//// .betweenIfPresent(SeckillTimeDO::getEndTime, reqVO.getEndTime())  
27 -//// .betweenIfPresent(SeckillTimeDO::getCreateTime, reqVO.getCreateTime())  
28 -// .orderByDesc(SeckillTimeDO::getId));  
29 -// } 43 + default void sekillActivityCountAdd(List<Long> ids){
  44 + if (CollUtil.isEmpty(ids)){
  45 + return;
  46 + }
  47 + new LambdaUpdateChainWrapper<SeckillTimeDO>(this)
  48 + .in(SeckillTimeDO::getId,ids)
  49 + .setSql("`seckill_activity_count` = `seckill_activity_count` + 1 ")
  50 + .update();
  51 + }
30 52
31 - default List<SeckillTimeDO> selectList(SeckillTimeExportReqVO reqVO) {  
32 - return selectList(new LambdaQueryWrapperX<SeckillTimeDO>()  
33 - .likeIfPresent(SeckillTimeDO::getName, reqVO.getName())  
34 - .betweenIfPresent(SeckillTimeDO::getStartTime, reqVO.getStartTime())  
35 - .betweenIfPresent(SeckillTimeDO::getEndTime, reqVO.getEndTime())  
36 - .betweenIfPresent(SeckillTimeDO::getCreateTime, reqVO.getCreateTime())  
37 - .orderByDesc(SeckillTimeDO::getId)); 53 + default void sekillActivityCountReduce(List<Long> ids){
  54 + if (CollUtil.isEmpty(ids)){
  55 + return;
  56 + }
  57 + new LambdaUpdateChainWrapper<SeckillTimeDO>(this)
  58 + .in(SeckillTimeDO::getId,ids)
  59 + .setSql("`seckill_activity_count` = `seckill_activity_count` - 1 ")
  60 + .update();
38 } 61 }
39 62
40 } 63 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckillactivity/SeckillActivityServiceImpl.java
@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.promotion.service.seckillactivity; @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.promotion.service.seckillactivity;
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; 5 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  6 +import cn.iocoder.yudao.framework.common.util.string.StrUtils;
6 import cn.iocoder.yudao.module.promotion.controller.admin.seckillactivity.vo.SeckillActivityBaseVO; 7 import cn.iocoder.yudao.module.promotion.controller.admin.seckillactivity.vo.SeckillActivityBaseVO;
7 import cn.iocoder.yudao.module.promotion.controller.admin.seckillactivity.vo.SeckillActivityCreateReqVO; 8 import cn.iocoder.yudao.module.promotion.controller.admin.seckillactivity.vo.SeckillActivityCreateReqVO;
8 import cn.iocoder.yudao.module.promotion.controller.admin.seckillactivity.vo.SeckillActivityPageReqVO; 9 import cn.iocoder.yudao.module.promotion.controller.admin.seckillactivity.vo.SeckillActivityPageReqVO;
@@ -13,6 +14,7 @@ import cn.iocoder.yudao.module.promotion.dal.dataobject.seckillactivity.SeckillP @@ -13,6 +14,7 @@ import cn.iocoder.yudao.module.promotion.dal.dataobject.seckillactivity.SeckillP
13 import cn.iocoder.yudao.module.promotion.dal.mysql.seckillactivity.SeckillActivityMapper; 14 import cn.iocoder.yudao.module.promotion.dal.mysql.seckillactivity.SeckillActivityMapper;
14 import cn.iocoder.yudao.module.promotion.dal.mysql.seckillactivity.SeckillProductMapper; 15 import cn.iocoder.yudao.module.promotion.dal.mysql.seckillactivity.SeckillProductMapper;
15 import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; 16 import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum;
  17 +import cn.iocoder.yudao.module.promotion.service.seckilltime.SeckillTimeService;
16 import cn.iocoder.yudao.module.promotion.util.PromotionUtils; 18 import cn.iocoder.yudao.module.promotion.util.PromotionUtils;
17 import org.springframework.stereotype.Service; 19 import org.springframework.stereotype.Service;
18 import org.springframework.validation.annotation.Validated; 20 import org.springframework.validation.annotation.Validated;
@@ -20,6 +22,7 @@ import org.springframework.validation.annotation.Validated; @@ -20,6 +22,7 @@ import org.springframework.validation.annotation.Validated;
20 import javax.annotation.Resource; 22 import javax.annotation.Resource;
21 import java.util.Collection; 23 import java.util.Collection;
22 import java.util.List; 24 import java.util.List;
  25 +import java.util.stream.Collectors;
23 26
24 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 27 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
25 import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; 28 import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
@@ -40,22 +43,24 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { @@ -40,22 +43,24 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
40 @Resource 43 @Resource
41 private SeckillProductMapper seckillProductMapper; 44 private SeckillProductMapper seckillProductMapper;
42 45
  46 + @Resource
  47 + private SeckillTimeService seckillTimeService;
  48 +
43 @Override 49 @Override
44 public Long createSeckillActivity(SeckillActivityCreateReqVO createReqVO) { 50 public Long createSeckillActivity(SeckillActivityCreateReqVO createReqVO) {
45 -// validateSeckillActivityProductConflicts(null,createReqVO.getProducts());  
46 List<Integer> statuses = asList(PromotionActivityStatusEnum.WAIT.getStatus(), PromotionActivityStatusEnum.RUN.getStatus()); 51 List<Integer> statuses = asList(PromotionActivityStatusEnum.WAIT.getStatus(), PromotionActivityStatusEnum.RUN.getStatus());
47 // 校验商品是否冲突 52 // 校验商品是否冲突
48 validateSeckillActivityProductConflicts(null, createReqVO.getProducts()); 53 validateSeckillActivityProductConflicts(null, createReqVO.getProducts());
  54 + // 更新秒杀时段的秒杀活动数量
  55 + seckillTimeService.sekillActivityCountAdd(StrUtils.splitToLong(createReqVO.getTimeId(),","));
49 // 插入秒杀活动 56 // 插入秒杀活动
50 SeckillActivityDO seckillActivity = SeckillActivityConvert.INSTANCE.convert(createReqVO) 57 SeckillActivityDO seckillActivity = SeckillActivityConvert.INSTANCE.convert(createReqVO)
51 - .setStatus(PromotionUtils.calculateActivityStatus(createReqVO.getStartTime(), createReqVO.getEndTime()));; 58 + .setStatus(PromotionUtils.calculateActivityStatus(createReqVO.getStartTime(), createReqVO.getEndTime()));
52 seckillActivityMapper.insert(seckillActivity); 59 seckillActivityMapper.insert(seckillActivity);
53 -  
54 // 插入商品 60 // 插入商品
55 List<SeckillProductDO> productDOS = CollectionUtils.convertList(createReqVO.getProducts(), 61 List<SeckillProductDO> productDOS = CollectionUtils.convertList(createReqVO.getProducts(),
56 product -> SeckillActivityConvert.INSTANCE.convert(product).setActivityId(seckillActivity.getId())); 62 product -> SeckillActivityConvert.INSTANCE.convert(product).setActivityId(seckillActivity.getId()));
57 seckillProductMapper.insertBatch(productDOS); 63 seckillProductMapper.insertBatch(productDOS);
58 - // 返回  
59 return seckillActivity.getId(); 64 return seckillActivity.getId();
60 } 65 }
61 66
@@ -66,9 +71,10 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { @@ -66,9 +71,10 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
66 if (PromotionActivityStatusEnum.CLOSE.getStatus().equals(seckillActivity.getStatus())) { 71 if (PromotionActivityStatusEnum.CLOSE.getStatus().equals(seckillActivity.getStatus())) {
67 throw exception(SECKILL_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED); 72 throw exception(SECKILL_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED);
68 } 73 }
69 - List<Integer> statuses = asList(PromotionActivityStatusEnum.WAIT.getStatus(), PromotionActivityStatusEnum.RUN.getStatus());  
70 // 校验商品是否冲突 74 // 校验商品是否冲突
71 validateSeckillActivityProductConflicts(updateReqVO.getId(), updateReqVO.getProducts()); 75 validateSeckillActivityProductConflicts(updateReqVO.getId(), updateReqVO.getProducts());
  76 + // 更新秒杀时段的秒杀活动数量
  77 + updateSeckillTimeActivityCount(updateReqVO.getId(), updateReqVO.getTimeId());
72 // 更新活动 78 // 更新活动
73 SeckillActivityDO updateObj = SeckillActivityConvert.INSTANCE.convert(updateReqVO) 79 SeckillActivityDO updateObj = SeckillActivityConvert.INSTANCE.convert(updateReqVO)
74 .setStatus(PromotionUtils.calculateActivityStatus(updateReqVO.getStartTime(), updateReqVO.getEndTime())); 80 .setStatus(PromotionUtils.calculateActivityStatus(updateReqVO.getStartTime(), updateReqVO.getEndTime()));
@@ -78,6 +84,28 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { @@ -78,6 +84,28 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
78 } 84 }
79 85
80 /** 86 /**
  87 + * 更新秒杀时段的秒杀活动数量
  88 + *
  89 + * @param id
  90 + * @param timeId
  91 + */
  92 + private void updateSeckillTimeActivityCount(Long id, String timeId) {
  93 + List<Long> updateTimeIds = StrUtils.splitToLong(timeId, ",");
  94 + // 查出自己的timeIds
  95 + SeckillActivityDO seckillActivityDO = seckillActivityMapper.selectById(id);
  96 + List<Long> existsTimeIds = StrUtils.splitToLong(seckillActivityDO.getTimeId(), ",");
  97 + //需要减少的时间段
  98 + List<Long> reduceIds = existsTimeIds.stream()
  99 + .filter(existsTimeId -> !updateTimeIds.contains(existsTimeId))
  100 + .collect(Collectors.toList());
  101 + //需要添加的时间段
  102 + updateTimeIds.removeIf(updateTimeId -> existsTimeIds.contains(updateTimeId));
  103 + //更新减少时间段和增加时间段
  104 + seckillTimeService.sekillActivityCountAdd(updateTimeIds);
  105 + seckillTimeService.sekillActivityCountReduce(reduceIds);
  106 + }
  107 +
  108 + /**
81 * 更新秒杀商品 109 * 更新秒杀商品
82 */ 110 */
83 private void updateSeckillProduct(SeckillActivityUpdateReqVO updateReqVO) { 111 private void updateSeckillProduct(SeckillActivityUpdateReqVO updateReqVO) {
@@ -109,7 +137,7 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { @@ -109,7 +137,7 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
109 * @param id 秒杀活动编号 137 * @param id 秒杀活动编号
110 * @param products 商品列表 138 * @param products 商品列表
111 */ 139 */
112 - public void validateSeckillActivityProductConflicts(Long id, List<SeckillActivityBaseVO.Product> products) { 140 + private void validateSeckillActivityProductConflicts(Long id, List<SeckillActivityBaseVO.Product> products) {
113 if (CollUtil.isEmpty(products)) { 141 if (CollUtil.isEmpty(products)) {
114 return; 142 return;
115 } 143 }
@@ -146,16 +174,18 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { @@ -146,16 +174,18 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
146 // 更新 174 // 更新
147 SeckillActivityDO updateObj = new SeckillActivityDO().setId(id).setStatus(PromotionActivityStatusEnum.CLOSE.getStatus()); 175 SeckillActivityDO updateObj = new SeckillActivityDO().setId(id).setStatus(PromotionActivityStatusEnum.CLOSE.getStatus());
148 seckillActivityMapper.updateById(updateObj); 176 seckillActivityMapper.updateById(updateObj);
149 -  
150 } 177 }
151 178
152 @Override 179 @Override
153 public void deleteSeckillActivity(Long id) { 180 public void deleteSeckillActivity(Long id) {
154 // 校验存在 181 // 校验存在
155 SeckillActivityDO seckillActivity = this.validateSeckillActivityExists(id); 182 SeckillActivityDO seckillActivity = this.validateSeckillActivityExists(id);
156 - if (!PromotionActivityStatusEnum.CLOSE.getStatus().equals(seckillActivity.getStatus())) {  
157 - throw exception(SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED); 183 + List<Integer> statuses = asList(PromotionActivityStatusEnum.CLOSE.getStatus(), PromotionActivityStatusEnum.END.getStatus());
  184 + if (!statuses.contains(seckillActivity.getStatus())) {
  185 + throw exception(SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END);
158 } 186 }
  187 + // 更新秒杀时段的秒杀活动数量
  188 + seckillTimeService.sekillActivityCountReduce(StrUtils.splitToLong(seckillActivity.getTimeId(),","));
159 // 删除 189 // 删除
160 seckillActivityMapper.deleteById(id); 190 seckillActivityMapper.deleteById(id);
161 } 191 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckilltime/SeckillTimeService.java
1 package cn.iocoder.yudao.module.promotion.service.seckilltime; 1 package cn.iocoder.yudao.module.promotion.service.seckilltime;
2 2
3 -import java.util.*;  
4 -import javax.validation.*;  
5 -import cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo.*; 3 +import cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo.SeckillTimeCreateReqVO;
  4 +import cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo.SeckillTimeUpdateReqVO;
6 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckilltime.SeckillTimeDO; 5 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckilltime.SeckillTimeDO;
7 -import cn.iocoder.yudao.framework.common.pojo.PageResult; 6 +
  7 +import javax.validation.Valid;
  8 +import java.util.List;
8 9
9 /** 10 /**
10 * 秒杀时段 Service 接口 11 * 秒杀时段 Service 接口
@@ -50,20 +51,18 @@ public interface SeckillTimeService { @@ -50,20 +51,18 @@ public interface SeckillTimeService {
50 */ 51 */
51 List<SeckillTimeDO> getSeckillTimeList(); 52 List<SeckillTimeDO> getSeckillTimeList();
52 53
53 -// /**  
54 -// * 获得秒杀时段分页  
55 -// *  
56 -// * @param pageReqVO 分页查询  
57 -// * @return 秒杀时段分页  
58 -// */  
59 -// PageResult<SeckillTimeDO> getSeckillTimePage(SeckillTimePageReqVO pageReqVO);  
60 -  
61 /** 54 /**
62 - * 获得秒杀时段列表, 用于 Excel 导出 55 + * 秒杀时段列表的秒杀活动数量加 1
63 * 56 *
64 - * @param exportReqVO 查询条件  
65 - * @return 秒杀时段列表 57 + * @param ids 秒杀时段id列表
66 */ 58 */
67 - List<SeckillTimeDO> getSeckillTimeList(SeckillTimeExportReqVO exportReqVO); 59 + void sekillActivityCountAdd(List<Long> ids);
  60 +
68 61
  62 + /**
  63 + * 秒杀时段列表的秒杀活动数量减 1
  64 + *
  65 + * @param ids 秒杀时段id列表
  66 + */
  67 + void sekillActivityCountReduce(List<Long> ids);
69 } 68 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckilltime/SeckillTimeServiceImpl.java
1 package cn.iocoder.yudao.module.promotion.service.seckilltime; 1 package cn.iocoder.yudao.module.promotion.service.seckilltime;
2 2
  3 +import cn.hutool.core.collection.CollUtil;
3 import org.springframework.stereotype.Service; 4 import org.springframework.stereotype.Service;
  5 +
4 import javax.annotation.Resource; 6 import javax.annotation.Resource;
  7 +
5 import org.springframework.validation.annotation.Validated; 8 import org.springframework.validation.annotation.Validated;
6 9
  10 +import java.time.LocalTime;
7 import java.util.*; 11 import java.util.*;
  12 +
8 import cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo.*; 13 import cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo.*;
9 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckilltime.SeckillTimeDO; 14 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckilltime.SeckillTimeDO;
10 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
11 15
12 import cn.iocoder.yudao.module.promotion.convert.seckilltime.SeckillTimeConvert; 16 import cn.iocoder.yudao.module.promotion.convert.seckilltime.SeckillTimeConvert;
13 import cn.iocoder.yudao.module.promotion.dal.mysql.seckilltime.SeckillTimeMapper; 17 import cn.iocoder.yudao.module.promotion.dal.mysql.seckilltime.SeckillTimeMapper;
@@ -24,11 +28,14 @@ import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; @@ -24,11 +28,14 @@ import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
24 @Validated 28 @Validated
25 public class SeckillTimeServiceImpl implements SeckillTimeService { 29 public class SeckillTimeServiceImpl implements SeckillTimeService {
26 30
  31 +
27 @Resource 32 @Resource
28 private SeckillTimeMapper seckillTimeMapper; 33 private SeckillTimeMapper seckillTimeMapper;
29 34
30 @Override 35 @Override
31 public Long createSeckillTime(SeckillTimeCreateReqVO createReqVO) { 36 public Long createSeckillTime(SeckillTimeCreateReqVO createReqVO) {
  37 + // 校验时间段是否冲突
  38 + validateSeckillTimeConflict(null,createReqVO.getStartTime(), createReqVO.getEndTime());
32 // 插入 39 // 插入
33 SeckillTimeDO seckillTime = SeckillTimeConvert.INSTANCE.convert(createReqVO); 40 SeckillTimeDO seckillTime = SeckillTimeConvert.INSTANCE.convert(createReqVO);
34 seckillTimeMapper.insert(seckillTime); 41 seckillTimeMapper.insert(seckillTime);
@@ -40,6 +47,8 @@ public class SeckillTimeServiceImpl implements SeckillTimeService { @@ -40,6 +47,8 @@ public class SeckillTimeServiceImpl implements SeckillTimeService {
40 public void updateSeckillTime(SeckillTimeUpdateReqVO updateReqVO) { 47 public void updateSeckillTime(SeckillTimeUpdateReqVO updateReqVO) {
41 // 校验存在 48 // 校验存在
42 this.validateSeckillTimeExists(updateReqVO.getId()); 49 this.validateSeckillTimeExists(updateReqVO.getId());
  50 + // 校验时间段是否冲突
  51 + validateSeckillTimeConflict(updateReqVO.getId(), updateReqVO.getStartTime(), updateReqVO.getEndTime());
43 // 更新 52 // 更新
44 SeckillTimeDO updateObj = SeckillTimeConvert.INSTANCE.convert(updateReqVO); 53 SeckillTimeDO updateObj = SeckillTimeConvert.INSTANCE.convert(updateReqVO);
45 seckillTimeMapper.updateById(updateObj); 54 seckillTimeMapper.updateById(updateObj);
@@ -59,6 +68,31 @@ public class SeckillTimeServiceImpl implements SeckillTimeService { @@ -59,6 +68,31 @@ public class SeckillTimeServiceImpl implements SeckillTimeService {
59 } 68 }
60 } 69 }
61 70
  71 + /**
  72 + * 校验时间是否存在冲突
  73 + *
  74 + * @param startTime 开始时间
  75 + * @param endTime 结束时间
  76 + */
  77 + private void validateSeckillTimeConflict(Long id, LocalTime startTime, LocalTime endTime) {
  78 + //查询开始时间,结束时间,是否在别人的时间段内
  79 + List<SeckillTimeDO> startTimeList = seckillTimeMapper.selectListWithTime(startTime);
  80 + List<SeckillTimeDO> endTimeList = seckillTimeMapper.selectListWithTime(endTime);
  81 + //查询自己时间段内是否有时间段
  82 + List<SeckillTimeDO> startEndTimeList = seckillTimeMapper.selectListWithTime(startTime, endTime);
  83 + if (id != null) {
  84 + //移除自己
  85 + startTimeList.removeIf(seckillTime -> Objects.equals(seckillTime.getId(), id));
  86 + endTimeList.removeIf(seckillTime -> Objects.equals(seckillTime.getId(), id));
  87 + startEndTimeList.removeIf(seckillTime -> Objects.equals(seckillTime.getId(), id));
  88 + }
  89 + if (CollUtil.isNotEmpty(startTimeList) || CollUtil.isNotEmpty(endTimeList)
  90 + || CollUtil.isNotEmpty(startEndTimeList)) {
  91 + throw exception(SECKILL_TIME_CONFLICTS);
  92 + }
  93 + }
  94 +
  95 +
62 @Override 96 @Override
63 public SeckillTimeDO getSeckillTime(Long id) { 97 public SeckillTimeDO getSeckillTime(Long id) {
64 return seckillTimeMapper.selectById(id); 98 return seckillTimeMapper.selectById(id);
@@ -69,14 +103,14 @@ public class SeckillTimeServiceImpl implements SeckillTimeService { @@ -69,14 +103,14 @@ public class SeckillTimeServiceImpl implements SeckillTimeService {
69 return seckillTimeMapper.selectList(); 103 return seckillTimeMapper.selectList();
70 } 104 }
71 105
72 -// @Override  
73 -// public PageResult<SeckillTimeDO> getSeckillTimePage(SeckillTimePageReqVO pageReqVO) {  
74 -// return seckillTimeMapper.selectPage(pageReqVO);  
75 -// } 106 + @Override
  107 + public void sekillActivityCountAdd(List<Long> ids) {
  108 + seckillTimeMapper.sekillActivityCountAdd(ids);
  109 + }
76 110
77 @Override 111 @Override
78 - public List<SeckillTimeDO> getSeckillTimeList(SeckillTimeExportReqVO exportReqVO) {  
79 - return seckillTimeMapper.selectList(exportReqVO); 112 + public void sekillActivityCountReduce(List<Long> ids) {
  113 + seckillTimeMapper.sekillActivityCountReduce(ids);
80 } 114 }
81 115
82 } 116 }
yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckilltime/SeckillTimeServiceImplTest.java
@@ -180,17 +180,17 @@ public class SeckillTimeServiceImplTest extends BaseDbUnitTest { @@ -180,17 +180,17 @@ public class SeckillTimeServiceImplTest extends BaseDbUnitTest {
180 // 测试 createTime 不匹配 180 // 测试 createTime 不匹配
181 seckillTimeMapper.insert(cloneIgnoreId(dbSeckillTime, o -> o.setCreateTime(null))); 181 seckillTimeMapper.insert(cloneIgnoreId(dbSeckillTime, o -> o.setCreateTime(null)));
182 // 准备参数 182 // 准备参数
183 - SeckillTimeExportReqVO reqVO = new SeckillTimeExportReqVO();  
184 - reqVO.setName(null);  
185 - reqVO.setStartTime((new LocalTime[]{}));  
186 - reqVO.setEndTime((new LocalTime[]{}));  
187 - reqVO.setCreateTime((new Date[]{}));  
188 -  
189 - // 调用  
190 - List<SeckillTimeDO> list = seckillTimeService.getSeckillTimeList(reqVO);  
191 - // 断言  
192 - assertEquals(1, list.size());  
193 - assertPojoEquals(dbSeckillTime, list.get(0)); 183 +// SeckillTimeExportReqVO reqVO = new SeckillTimeExportReqVO();
  184 +// reqVO.setName(null);
  185 +// reqVO.setStartTime((new LocalTime[]{}));
  186 +// reqVO.setEndTime((new LocalTime[]{}));
  187 +// reqVO.setCreateTime((new Date[]{}));
  188 +//
  189 +// // 调用
  190 +// List<SeckillTimeDO> list = seckillTimeService.getSeckillTimeList(reqVO);
  191 +// // 断言
  192 +// assertEquals(1, list.size());
  193 +// assertPojoEquals(dbSeckillTime, list.get(0));
194 } 194 }
195 195
196 } 196 }
yudao-ui-admin/src/views/promotion/seckillTime/index.vue
@@ -47,7 +47,7 @@ @@ -47,7 +47,7 @@
47 <span>{{ scope.row.endTime }}</span> 47 <span>{{ scope.row.endTime }}</span>
48 </template> 48 </template>
49 </el-table-column> 49 </el-table-column>
50 - <el-table-column label="商品数量" align="center" prop="productCount" /> 50 + <el-table-column label="秒杀活动数量" align="center" prop="seckillActivityCount" />
51 <el-table-column label="创建时间" align="center" prop="createTime" width="180"> 51 <el-table-column label="创建时间" align="center" prop="createTime" width="180">
52 <template slot-scope="scope"> 52 <template slot-scope="scope">
53 <span>{{ parseTime(scope.row.createTime) }}</span> 53 <span>{{ parseTime(scope.row.createTime) }}</span>