Переглянути джерело

秒杀时段新增修改时间段冲突校验。
秒杀活动新增,修改,删除时对秒杀时段的秒杀活动数量进行修改

halfninety 2 роки тому
батько
коміт
54baad165d
13 змінених файлів з 180 додано та 175 видалено
  1. 10 6
      yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java
  2. 15 33
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/SeckillTimeController.java
  3. 0 37
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/vo/SeckillTimeExcelVO.java
  4. 0 30
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/vo/SeckillTimeExportReqVO.java
  5. 2 2
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/vo/SeckillTimeRespVO.java
  6. 0 1
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckilltime/SeckillTimeConvert.java
  7. 6 5
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckilltime/SeckillTimeDO.java
  8. 40 17
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckilltime/SeckillTimeMapper.java
  9. 39 9
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckillactivity/SeckillActivityServiceImpl.java
  10. 15 16
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckilltime/SeckillTimeService.java
  11. 41 7
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckilltime/SeckillTimeServiceImpl.java
  12. 11 11
      yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckilltime/SeckillTimeServiceImplTest.java
  13. 1 1
      yudao-ui-admin/src/views/promotion/seckillTime/index.vue

+ 10 - 6
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 {
 
     // ========== 秒杀活动 1003008000 ==========
     ErrorCode SECKILL_ACTIVITY_NOT_EXISTS = new ErrorCode(1003008000, "秒杀活动不存在");
-    ErrorCode SECKILL_TIME_NOT_EXISTS = new ErrorCode(1003008001, "秒杀时段不存在");
-    ErrorCode SECKILL_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1003008001, "存在商品参加了其它秒杀活动");
-    ErrorCode SECKILL_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1003006002, "秒杀活动已关闭,不能修改");
-    ErrorCode SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED = new ErrorCode(1003006003, "秒杀活动未关闭,不能删除");
-    ErrorCode SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1003006004, "秒杀活动已关闭,不能重复关闭");
-    ErrorCode SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_END = new ErrorCode(1003006004, "秒杀活动已结束,不能关闭");
+    ErrorCode SECKILL_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1003008002, "存在商品参加了其它秒杀活动");
+    ErrorCode SECKILL_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1003008003, "秒杀活动已关闭,不能修改");
+    ErrorCode SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1003008004, "秒杀活动未关闭或未结束,不能删除");
+    ErrorCode SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1003008005, "秒杀活动已关闭,不能重复关闭");
+    ErrorCode SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_END = new ErrorCode(1003008006, "秒杀活动已结束,不能关闭");
+
+    // ========== 秒杀时段 1003009000 ==========
+    ErrorCode SECKILL_TIME_NOT_EXISTS = new ErrorCode(1003009000, "秒杀时段不存在");
+    ErrorCode SECKILL_TIME_CONFLICTS = new ErrorCode(1003009001, "秒杀时段冲突");
+
 }

+ 15 - 33
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/SeckillTimeController.java

@@ -1,31 +1,25 @@
 package cn.iocoder.yudao.module.promotion.controller.admin.seckilltime;
 
-import org.springframework.web.bind.annotation.*;
-import javax.annotation.Resource;
-import org.springframework.validation.annotation.Validated;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo.SeckillTimeCreateReqVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo.SeckillTimeRespVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo.SeckillTimeUpdateReqVO;
+import cn.iocoder.yudao.module.promotion.convert.seckilltime.SeckillTimeConvert;
+import cn.iocoder.yudao.module.promotion.dal.dataobject.seckilltime.SeckillTimeDO;
+import cn.iocoder.yudao.module.promotion.service.seckilltime.SeckillTimeService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
 import org.springframework.security.access.prepost.PreAuthorize;
-import io.swagger.annotations.*;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
 
-import javax.validation.constraints.*;
-import javax.validation.*;
-import javax.servlet.http.*;
-import java.util.*;
-import java.io.IOException;
+import javax.annotation.Resource;
+import javax.validation.Valid;
+import java.util.List;
 
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 
-import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
-
-import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
-import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*;
-
-import cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo.*;
-import cn.iocoder.yudao.module.promotion.dal.dataobject.seckilltime.SeckillTimeDO;
-import cn.iocoder.yudao.module.promotion.convert.seckilltime.SeckillTimeConvert;
-import cn.iocoder.yudao.module.promotion.service.seckilltime.SeckillTimeService;
-
 @Api(tags = "管理后台 - 秒杀时段")
 @RestController
 @RequestMapping("/promotion/seckill-time")
@@ -84,16 +78,4 @@ public class SeckillTimeController {
 //        return success(SeckillTimeConvert.INSTANCE.convertPage(pageResult));
 //    }
 
-    @GetMapping("/export-excel")
-    @ApiOperation("导出秒杀时段 Excel")
-    @PreAuthorize("@ss.hasPermission('promotion:seckill-time:export')")
-    @OperateLog(type = EXPORT)
-    public void exportSeckillTimeExcel(@Valid SeckillTimeExportReqVO exportReqVO,
-              HttpServletResponse response) throws IOException {
-        List<SeckillTimeDO> list = seckillTimeService.getSeckillTimeList(exportReqVO);
-        // 导出 Excel
-        List<SeckillTimeExcelVO> datas = SeckillTimeConvert.INSTANCE.convertList02(list);
-        ExcelUtils.write(response, "秒杀时段.xls", "数据", SeckillTimeExcelVO.class, datas);
-    }
-
 }

+ 0 - 37
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/vo/SeckillTimeExcelVO.java

@@ -1,37 +0,0 @@
-package cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo;
-
-import lombok.*;
-
-import java.time.LocalTime;
-import java.util.*;
-import io.swagger.annotations.*;
-
-import com.alibaba.excel.annotation.ExcelProperty;
-
-/**
- * 秒杀时段 Excel VO
- *
- * @author 芋道源码
- */
-@Data
-public class SeckillTimeExcelVO {
-
-    @ExcelProperty("编号")
-    private Long id;
-
-    @ExcelProperty("秒杀时段名称")
-    private String name;
-
-    @ExcelProperty("开始时间点")
-    private LocalTime startTime;
-
-    @ExcelProperty("结束时间点")
-    private LocalTime endTime;
-
-    @ExcelProperty("商品数量")
-    private Integer productCount;
-
-    @ExcelProperty("创建时间")
-    private Date createTime;
-
-}

+ 0 - 30
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/vo/SeckillTimeExportReqVO.java

@@ -1,30 +0,0 @@
-package cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo;
-
-import lombok.*;
-
-import java.time.LocalTime;
-import java.util.*;
-import io.swagger.annotations.*;
-import cn.iocoder.yudao.framework.common.pojo.PageParam;
-import org.springframework.format.annotation.DateTimeFormat;
-
-import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
-
-@ApiModel(value = "管理后台 - 秒杀时段 Excel 导出 Request VO", description = "参数和 SeckillTimePageReqVO 是一致的")
-@Data
-public class SeckillTimeExportReqVO {
-
-    @ApiModelProperty(value = "秒杀时段名称")
-    private String name;
-
-    @ApiModelProperty(value = "开始时间点")
-    private LocalTime[] startTime;
-
-    @ApiModelProperty(value = "结束时间点")
-    private LocalTime[] endTime;
-
-    @ApiModelProperty(value = "创建时间")
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    private Date[] createTime;
-
-}

+ 2 - 2
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 {
     @ApiModelProperty(value = "编号", required = true)
     private Long id;
 
-    @ApiModelProperty(value = "商品数量", required = true)
-    private Integer productCount;
+    @ApiModelProperty(value = "秒杀活动数量", required = true)
+    private Integer seckillActivityCount;
 
     @ApiModelProperty(value = "创建时间", required = true)
     private Date createTime;

+ 0 - 1
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 {
 
     PageResult<SeckillTimeRespVO> convertPage(PageResult<SeckillTimeDO> page);
 
-    List<SeckillTimeExcelVO> convertList02(List<SeckillTimeDO> list);
 }

+ 6 - 5
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckilltime/SeckillTimeDO.java

@@ -1,11 +1,12 @@
 package cn.iocoder.yudao.module.promotion.dal.dataobject.seckilltime;
 
+import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.*;
 
 import java.time.LocalTime;
-import java.util.*;
-import com.baomidou.mybatisplus.annotation.*;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
 
 /**
  * 秒杀时段 DO
@@ -40,8 +41,8 @@ public class SeckillTimeDO extends BaseDO {
      */
     private LocalTime endTime;
     /**
-     * 商品数量
+     * 秒杀活动数量
      */
-    private Integer productCount;
+    private Integer seckillActivityCount;
 
 }

+ 40 - 17
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckilltime/SeckillTimeMapper.java

@@ -1,11 +1,17 @@
 package cn.iocoder.yudao.module.promotion.dal.mysql.seckilltime;
 
+import java.time.LocalTime;
 import java.util.*;
 
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckilltime.SeckillTimeDO;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
+import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper;
 import org.apache.ibatis.annotations.Mapper;
 import cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo.*;
 
@@ -16,25 +22,42 @@ import cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo.*;
  */
 @Mapper
 public interface SeckillTimeMapper extends BaseMapperX<SeckillTimeDO> {
+    default List<SeckillTimeDO> selectListWithTime(LocalTime time){
+        if (time == null) {
+            return Collections.emptyList();
+        }
+        return selectList(new LambdaQueryWrapper<SeckillTimeDO>()
+                .le(SeckillTimeDO::getStartTime,time)
+                .ge(SeckillTimeDO::getEndTime,time));
+    }
+    
+    default List<SeckillTimeDO> selectListWithTime(LocalTime startTime, LocalTime endTime){
+        if (startTime == null && endTime == null) {
+            return Collections.emptyList();
+        }
+        return selectList(new LambdaQueryWrapper<SeckillTimeDO>()
+                .ge(SeckillTimeDO::getStartTime,startTime)
+                .le(SeckillTimeDO::getEndTime,endTime));
+    }
 
-//    default PageResult<SeckillTimeDO> selectPage(SeckillTimePageReqVO reqVO) {
-//        return selectPage(reqVO, new LambdaQueryWrapperX<SeckillTimeDO>()
-//                .likeIfPresent(SeckillTimeDO::getName, reqVO.getName())
-//                .geIfPresent(SeckillTimeDO::getStartTime, reqVO.getStartTime())
-//                .leIfPresent(SeckillTimeDO::getEndTime, reqVO.getEndTime())
-////                .betweenIfPresent(SeckillTimeDO::getStartTime, reqVO.getStartTime())
-////                .betweenIfPresent(SeckillTimeDO::getEndTime, reqVO.getEndTime())
-////                .betweenIfPresent(SeckillTimeDO::getCreateTime, reqVO.getCreateTime())
-//                .orderByDesc(SeckillTimeDO::getId));
-//    }
+    default void sekillActivityCountAdd(List<Long> ids){
+        if (CollUtil.isEmpty(ids)){
+            return;
+        }
+        new LambdaUpdateChainWrapper<SeckillTimeDO>(this)
+                .in(SeckillTimeDO::getId,ids)
+                .setSql("`seckill_activity_count` = `seckill_activity_count` + 1 ")
+                .update();
+    }
 
-    default List<SeckillTimeDO> selectList(SeckillTimeExportReqVO reqVO) {
-        return selectList(new LambdaQueryWrapperX<SeckillTimeDO>()
-                .likeIfPresent(SeckillTimeDO::getName, reqVO.getName())
-                .betweenIfPresent(SeckillTimeDO::getStartTime, reqVO.getStartTime())
-                .betweenIfPresent(SeckillTimeDO::getEndTime, reqVO.getEndTime())
-                .betweenIfPresent(SeckillTimeDO::getCreateTime, reqVO.getCreateTime())
-                .orderByDesc(SeckillTimeDO::getId));
+    default void sekillActivityCountReduce(List<Long> ids){
+        if (CollUtil.isEmpty(ids)){
+            return;
+        }
+        new LambdaUpdateChainWrapper<SeckillTimeDO>(this)
+                .in(SeckillTimeDO::getId,ids)
+                .setSql("`seckill_activity_count` = `seckill_activity_count` - 1 ")
+                .update();
     }
 
 }

+ 39 - 9
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;
 import cn.hutool.core.collection.CollUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
+import cn.iocoder.yudao.framework.common.util.string.StrUtils;
 import cn.iocoder.yudao.module.promotion.controller.admin.seckillactivity.vo.SeckillActivityBaseVO;
 import cn.iocoder.yudao.module.promotion.controller.admin.seckillactivity.vo.SeckillActivityCreateReqVO;
 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
 import cn.iocoder.yudao.module.promotion.dal.mysql.seckillactivity.SeckillActivityMapper;
 import cn.iocoder.yudao.module.promotion.dal.mysql.seckillactivity.SeckillProductMapper;
 import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum;
+import cn.iocoder.yudao.module.promotion.service.seckilltime.SeckillTimeService;
 import cn.iocoder.yudao.module.promotion.util.PromotionUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
@@ -20,6 +22,7 @@ import org.springframework.validation.annotation.Validated;
 import javax.annotation.Resource;
 import java.util.Collection;
 import java.util.List;
+import java.util.stream.Collectors;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
@@ -40,22 +43,24 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
     @Resource
     private SeckillProductMapper seckillProductMapper;
 
+    @Resource
+    private SeckillTimeService seckillTimeService;
+
     @Override
     public Long createSeckillActivity(SeckillActivityCreateReqVO createReqVO) {
-//        validateSeckillActivityProductConflicts(null,createReqVO.getProducts());
         List<Integer> statuses = asList(PromotionActivityStatusEnum.WAIT.getStatus(), PromotionActivityStatusEnum.RUN.getStatus());
         // 校验商品是否冲突
         validateSeckillActivityProductConflicts(null, createReqVO.getProducts());
+        // 更新秒杀时段的秒杀活动数量
+        seckillTimeService.sekillActivityCountAdd(StrUtils.splitToLong(createReqVO.getTimeId(),","));
         // 插入秒杀活动
         SeckillActivityDO seckillActivity = SeckillActivityConvert.INSTANCE.convert(createReqVO)
-                .setStatus(PromotionUtils.calculateActivityStatus(createReqVO.getStartTime(), createReqVO.getEndTime()));;
+                .setStatus(PromotionUtils.calculateActivityStatus(createReqVO.getStartTime(), createReqVO.getEndTime()));
         seckillActivityMapper.insert(seckillActivity);
-
         // 插入商品
         List<SeckillProductDO> productDOS = CollectionUtils.convertList(createReqVO.getProducts(),
                 product -> SeckillActivityConvert.INSTANCE.convert(product).setActivityId(seckillActivity.getId()));
         seckillProductMapper.insertBatch(productDOS);
-        // 返回
         return seckillActivity.getId();
     }
 
@@ -66,9 +71,10 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
         if (PromotionActivityStatusEnum.CLOSE.getStatus().equals(seckillActivity.getStatus())) {
             throw exception(SECKILL_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED);
         }
-        List<Integer> statuses = asList(PromotionActivityStatusEnum.WAIT.getStatus(), PromotionActivityStatusEnum.RUN.getStatus());
         // 校验商品是否冲突
         validateSeckillActivityProductConflicts(updateReqVO.getId(), updateReqVO.getProducts());
+        // 更新秒杀时段的秒杀活动数量
+        updateSeckillTimeActivityCount(updateReqVO.getId(), updateReqVO.getTimeId());
         // 更新活动
         SeckillActivityDO updateObj = SeckillActivityConvert.INSTANCE.convert(updateReqVO)
                 .setStatus(PromotionUtils.calculateActivityStatus(updateReqVO.getStartTime(), updateReqVO.getEndTime()));
@@ -77,6 +83,28 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
         updateSeckillProduct(updateReqVO);
     }
 
+    /**
+     * 更新秒杀时段的秒杀活动数量
+     *
+     * @param id
+     * @param timeId
+     */
+    private void updateSeckillTimeActivityCount(Long id, String timeId) {
+        List<Long> updateTimeIds = StrUtils.splitToLong(timeId, ",");
+        // 查出自己的timeIds
+        SeckillActivityDO seckillActivityDO = seckillActivityMapper.selectById(id);
+        List<Long> existsTimeIds = StrUtils.splitToLong(seckillActivityDO.getTimeId(), ",");
+        //需要减少的时间段
+        List<Long> reduceIds = existsTimeIds.stream()
+                .filter(existsTimeId -> !updateTimeIds.contains(existsTimeId))
+                .collect(Collectors.toList());
+        //需要添加的时间段
+        updateTimeIds.removeIf(updateTimeId -> existsTimeIds.contains(updateTimeId));
+        //更新减少时间段和增加时间段
+        seckillTimeService.sekillActivityCountAdd(updateTimeIds);
+        seckillTimeService.sekillActivityCountReduce(reduceIds);
+    }
+
     /**
      * 更新秒杀商品
      */
@@ -109,7 +137,7 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
      * @param id       秒杀活动编号
      * @param products 商品列表
      */
-    public void validateSeckillActivityProductConflicts(Long id, List<SeckillActivityBaseVO.Product> products) {
+    private void validateSeckillActivityProductConflicts(Long id, List<SeckillActivityBaseVO.Product> products) {
         if (CollUtil.isEmpty(products)) {
             return;
         }
@@ -146,16 +174,18 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
         // 更新
         SeckillActivityDO updateObj = new SeckillActivityDO().setId(id).setStatus(PromotionActivityStatusEnum.CLOSE.getStatus());
         seckillActivityMapper.updateById(updateObj);
-
     }
 
     @Override
     public void deleteSeckillActivity(Long id) {
         // 校验存在
         SeckillActivityDO seckillActivity = this.validateSeckillActivityExists(id);
-        if (!PromotionActivityStatusEnum.CLOSE.getStatus().equals(seckillActivity.getStatus())) {
-            throw exception(SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED);
+        List<Integer> statuses = asList(PromotionActivityStatusEnum.CLOSE.getStatus(), PromotionActivityStatusEnum.END.getStatus());
+        if (!statuses.contains(seckillActivity.getStatus())) {
+            throw exception(SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END);
         }
+        // 更新秒杀时段的秒杀活动数量
+        seckillTimeService.sekillActivityCountReduce(StrUtils.splitToLong(seckillActivity.getTimeId(),","));
         // 删除
         seckillActivityMapper.deleteById(id);
     }

+ 15 - 16
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckilltime/SeckillTimeService.java

@@ -1,10 +1,11 @@
 package cn.iocoder.yudao.module.promotion.service.seckilltime;
 
-import java.util.*;
-import javax.validation.*;
-import cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo.*;
+import cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo.SeckillTimeCreateReqVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo.SeckillTimeUpdateReqVO;
 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckilltime.SeckillTimeDO;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
+
+import javax.validation.Valid;
+import java.util.List;
 
 /**
  * 秒杀时段 Service 接口
@@ -50,20 +51,18 @@ public interface SeckillTimeService {
      */
     List<SeckillTimeDO> getSeckillTimeList();
 
-//    /**
-//     * 获得秒杀时段分页
-//     *
-//     * @param pageReqVO 分页查询
-//     * @return 秒杀时段分页
-//     */
-//    PageResult<SeckillTimeDO> getSeckillTimePage(SeckillTimePageReqVO pageReqVO);
-
     /**
-     * 获得秒杀时段列表, 用于 Excel 导出
+     * 秒杀时段列表的秒杀活动数量加 1
      *
-     * @param exportReqVO 查询条件
-     * @return 秒杀时段列表
+     * @param ids 秒杀时段id列表
      */
-    List<SeckillTimeDO> getSeckillTimeList(SeckillTimeExportReqVO exportReqVO);
+    void sekillActivityCountAdd(List<Long> ids);
+
 
+    /**
+     * 秒杀时段列表的秒杀活动数量减 1
+     *
+     * @param ids 秒杀时段id列表
+     */
+    void sekillActivityCountReduce(List<Long> ids);
 }

+ 41 - 7
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckilltime/SeckillTimeServiceImpl.java

@@ -1,13 +1,17 @@
 package cn.iocoder.yudao.module.promotion.service.seckilltime;
 
+import cn.hutool.core.collection.CollUtil;
 import org.springframework.stereotype.Service;
+
 import javax.annotation.Resource;
+
 import org.springframework.validation.annotation.Validated;
 
+import java.time.LocalTime;
 import java.util.*;
+
 import cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo.*;
 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckilltime.SeckillTimeDO;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
 
 import cn.iocoder.yudao.module.promotion.convert.seckilltime.SeckillTimeConvert;
 import cn.iocoder.yudao.module.promotion.dal.mysql.seckilltime.SeckillTimeMapper;
@@ -24,11 +28,14 @@ import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
 @Validated
 public class SeckillTimeServiceImpl implements SeckillTimeService {
 
+
     @Resource
     private SeckillTimeMapper seckillTimeMapper;
 
     @Override
     public Long createSeckillTime(SeckillTimeCreateReqVO createReqVO) {
+        // 校验时间段是否冲突
+        validateSeckillTimeConflict(null,createReqVO.getStartTime(), createReqVO.getEndTime());
         // 插入
         SeckillTimeDO seckillTime = SeckillTimeConvert.INSTANCE.convert(createReqVO);
         seckillTimeMapper.insert(seckillTime);
@@ -40,6 +47,8 @@ public class SeckillTimeServiceImpl implements SeckillTimeService {
     public void updateSeckillTime(SeckillTimeUpdateReqVO updateReqVO) {
         // 校验存在
         this.validateSeckillTimeExists(updateReqVO.getId());
+        // 校验时间段是否冲突
+        validateSeckillTimeConflict(updateReqVO.getId(), updateReqVO.getStartTime(), updateReqVO.getEndTime());
         // 更新
         SeckillTimeDO updateObj = SeckillTimeConvert.INSTANCE.convert(updateReqVO);
         seckillTimeMapper.updateById(updateObj);
@@ -59,6 +68,31 @@ public class SeckillTimeServiceImpl implements SeckillTimeService {
         }
     }
 
+    /**
+     * 校验时间是否存在冲突
+     *
+     * @param startTime 开始时间
+     * @param endTime   结束时间
+     */
+    private void validateSeckillTimeConflict(Long id, LocalTime startTime, LocalTime endTime) {
+        //查询开始时间,结束时间,是否在别人的时间段内
+        List<SeckillTimeDO> startTimeList = seckillTimeMapper.selectListWithTime(startTime);
+        List<SeckillTimeDO> endTimeList = seckillTimeMapper.selectListWithTime(endTime);
+        //查询自己时间段内是否有时间段
+        List<SeckillTimeDO> startEndTimeList = seckillTimeMapper.selectListWithTime(startTime, endTime);
+        if (id != null) {
+            //移除自己
+            startTimeList.removeIf(seckillTime -> Objects.equals(seckillTime.getId(), id));
+            endTimeList.removeIf(seckillTime -> Objects.equals(seckillTime.getId(), id));
+            startEndTimeList.removeIf(seckillTime -> Objects.equals(seckillTime.getId(), id));
+        }
+        if (CollUtil.isNotEmpty(startTimeList) || CollUtil.isNotEmpty(endTimeList)
+                || CollUtil.isNotEmpty(startEndTimeList)) {
+            throw exception(SECKILL_TIME_CONFLICTS);
+        }
+    }
+
+
     @Override
     public SeckillTimeDO getSeckillTime(Long id) {
         return seckillTimeMapper.selectById(id);
@@ -69,14 +103,14 @@ public class SeckillTimeServiceImpl implements SeckillTimeService {
         return seckillTimeMapper.selectList();
     }
 
-//    @Override
-//    public PageResult<SeckillTimeDO> getSeckillTimePage(SeckillTimePageReqVO pageReqVO) {
-//        return seckillTimeMapper.selectPage(pageReqVO);
-//    }
+    @Override
+    public void sekillActivityCountAdd(List<Long> ids) {
+        seckillTimeMapper.sekillActivityCountAdd(ids);
+    }
 
     @Override
-    public List<SeckillTimeDO> getSeckillTimeList(SeckillTimeExportReqVO exportReqVO) {
-        return seckillTimeMapper.selectList(exportReqVO);
+    public void sekillActivityCountReduce(List<Long> ids) {
+        seckillTimeMapper.sekillActivityCountReduce(ids);
     }
 
 }

+ 11 - 11
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 {
        // 测试 createTime 不匹配
        seckillTimeMapper.insert(cloneIgnoreId(dbSeckillTime, o -> o.setCreateTime(null)));
        // 准备参数
-       SeckillTimeExportReqVO reqVO = new SeckillTimeExportReqVO();
-       reqVO.setName(null);
-       reqVO.setStartTime((new LocalTime[]{}));
-       reqVO.setEndTime((new LocalTime[]{}));
-       reqVO.setCreateTime((new Date[]{}));
-
-       // 调用
-       List<SeckillTimeDO> list = seckillTimeService.getSeckillTimeList(reqVO);
-       // 断言
-       assertEquals(1, list.size());
-       assertPojoEquals(dbSeckillTime, list.get(0));
+//       SeckillTimeExportReqVO reqVO = new SeckillTimeExportReqVO();
+//       reqVO.setName(null);
+//       reqVO.setStartTime((new LocalTime[]{}));
+//       reqVO.setEndTime((new LocalTime[]{}));
+//       reqVO.setCreateTime((new Date[]{}));
+//
+//       // 调用
+//       List<SeckillTimeDO> list = seckillTimeService.getSeckillTimeList(reqVO);
+//       // 断言
+//       assertEquals(1, list.size());
+//       assertPojoEquals(dbSeckillTime, list.get(0));
     }
 
 }

+ 1 - 1
yudao-ui-admin/src/views/promotion/seckillTime/index.vue

@@ -47,7 +47,7 @@
           <span>{{ scope.row.endTime }}</span>
         </template>
       </el-table-column>
-      <el-table-column label="商品数量" align="center" prop="productCount" />
+      <el-table-column label="秒杀活动数量" align="center" prop="seckillActivityCount" />
       <el-table-column label="创建时间" align="center" prop="createTime" width="180">
         <template slot-scope="scope">
           <span>{{ parseTime(scope.row.createTime) }}</span>