diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/DateUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/DateUtils.java
index b4cb94e1f..466dfb050 100644
--- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/DateUtils.java
+++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/DateUtils.java
@@ -25,6 +25,8 @@ public class DateUtils {
 
     public static final String FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND = "yyyy-MM-dd HH:mm:ss";
 
+    public static final String FORMAT_HOUR_MINUTE_SECOND = "HH:mm:ss";
+
     /**
      * 将 LocalDateTime 转换成 Date
      *
diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/jackson/config/YudaoJacksonAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/jackson/config/YudaoJacksonAutoConfiguration.java
index c44e770a1..f3cad8d79 100644
--- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/jackson/config/YudaoJacksonAutoConfiguration.java
+++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/jackson/config/YudaoJacksonAutoConfiguration.java
@@ -1,8 +1,9 @@
 package cn.iocoder.yudao.framework.jackson.config;
 
+import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
 import cn.iocoder.yudao.framework.jackson.core.databind.LocalDateTimeDeserializer;
 import cn.iocoder.yudao.framework.jackson.core.databind.LocalDateTimeSerializer;
-import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
+import cn.iocoder.yudao.framework.jackson.core.databind.LocalTimeJson;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.module.SimpleModule;
 import lombok.extern.slf4j.Slf4j;
@@ -12,6 +13,7 @@ import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
 import java.time.LocalDateTime;
+import java.time.LocalTime;
 
 @Configuration(proxyBeanMethods = false)
 @Slf4j
@@ -30,12 +32,15 @@ public class YudaoJacksonAutoConfiguration {
                 /*
                  * 1. 新增Long类型序列化规则,数值超过2^53-1,在JS会出现精度丢失问题,因此Long自动序列化为字符串类型
                  * 2. 新增LocalDateTime序列化、反序列化规则
+                 * 3. 新增LocalTime序列化、反序列化规则
                  */
                 simpleModule
 //                .addSerializer(Long.class, ToStringSerializer.instance)
 //                    .addSerializer(Long.TYPE, ToStringSerializer.instance)
                         .addSerializer(LocalDateTime.class, LocalDateTimeSerializer.INSTANCE)
-                        .addDeserializer(LocalDateTime.class, LocalDateTimeDeserializer.INSTANCE);
+                        .addDeserializer(LocalDateTime.class, LocalDateTimeDeserializer.INSTANCE)
+                        .addSerializer(LocalTime.class, LocalTimeJson.SERIALIZER)
+                        .addDeserializer(LocalTime.class, LocalTimeJson.DESERIALIZABLE);
 
                 objectMapper.registerModules(simpleModule);
 
diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/jackson/core/databind/LocalTimeJson.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/jackson/core/databind/LocalTimeJson.java
new file mode 100644
index 000000000..f9ff37511
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/jackson/core/databind/LocalTimeJson.java
@@ -0,0 +1,21 @@
+package cn.iocoder.yudao.framework.jackson.core.databind;
+
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
+
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_HOUR_MINUTE_SECOND;
+
+public class LocalTimeJson {
+
+    public static final LocalTimeSerializer SERIALIZER = new LocalTimeSerializer(DateTimeFormatter
+            .ofPattern(FORMAT_HOUR_MINUTE_SECOND)
+            .withZone(ZoneId.systemDefault()));
+
+    public static final LocalTimeDeserializer DESERIALIZABLE = new LocalTimeDeserializer(DateTimeFormatter
+            .ofPattern(FORMAT_HOUR_MINUTE_SECOND)
+            .withZone(ZoneId.systemDefault()));
+
+}
diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java
index 7e8fadede..47ce28b4b 100644
--- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java
+++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java
@@ -45,4 +45,16 @@ public interface ErrorCodeConstants {
     // ========== Price 相关 1003007000 ============
     ErrorCode PRICE_CALCULATE_PAY_PRICE_ILLEGAL = new ErrorCode(1003007000, "支付价格计算异常,原因:价格小于等于 0");
 
+    // ========== 秒杀活动 1003008000 ==========
+    ErrorCode SECKILL_ACTIVITY_NOT_EXISTS = new ErrorCode(1003008000, "秒杀活动不存在");
+    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, "秒杀时段冲突");
+
 }
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckillactivity/SeckillActivityController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckillactivity/SeckillActivityController.java
new file mode 100644
index 000000000..1efeb387e
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckillactivity/SeckillActivityController.java
@@ -0,0 +1,96 @@
+package cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckillactivity;
+
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckillactivity.vo.*;
+import cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity.SeckillActivityConvert;
+import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
+import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO;
+import cn.iocoder.yudao.module.promotion.service.seckill.seckillactivity.SeckillActivityService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+import java.util.Collection;
+import java.util.List;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+@Api(tags = "管理后台 - 秒杀活动")
+@RestController
+@RequestMapping("/promotion/seckill-activity")
+@Validated
+public class SeckillActivityController {
+
+    @Resource
+    private SeckillActivityService seckillActivityService;
+
+    @PostMapping("/create")
+    @ApiOperation("创建秒杀活动")
+    @PreAuthorize("@ss.hasPermission('promotion:seckill-activity:create')")
+    public CommonResult<Long> createSeckillActivity(@Valid @RequestBody SeckillActivityCreateReqVO createReqVO) {
+        return success(seckillActivityService.createSeckillActivity(createReqVO));
+    }
+
+    @PutMapping("/update")
+    @ApiOperation("更新秒杀活动")
+    @PreAuthorize("@ss.hasPermission('promotion:seckill-activity:update')")
+    public CommonResult<Boolean> updateSeckillActivity(@Valid @RequestBody SeckillActivityUpdateReqVO updateReqVO) {
+        seckillActivityService.updateSeckillActivity(updateReqVO);
+        return success(true);
+    }
+
+    @PutMapping("/close")
+    @ApiOperation("关闭秒杀活动")
+    @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
+    @PreAuthorize("@ss.hasPermission('promotion:seckill-activity:close')")
+    public CommonResult<Boolean> closeSeckillActivity(@RequestParam("id") Long id) {
+        seckillActivityService.closeSeckillActivity(id);
+        return success(true);
+    }
+
+    @DeleteMapping("/delete")
+    @ApiOperation("删除秒杀活动")
+    @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
+    @PreAuthorize("@ss.hasPermission('promotion:seckill-activity:delete')")
+    public CommonResult<Boolean> deleteSeckillActivity(@RequestParam("id") Long id) {
+        seckillActivityService.deleteSeckillActivity(id);
+        return success(true);
+    }
+
+    @GetMapping("/get")
+    @ApiOperation("获得秒杀活动")
+    @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
+    @PreAuthorize("@ss.hasPermission('promotion:seckill-activity:query')")
+    public CommonResult<SeckillActivityDetailRespVO> getSeckillActivity(@RequestParam("id") Long id) {
+        SeckillActivityDO seckillActivity = seckillActivityService.getSeckillActivity(id);
+        if (seckillActivity == null) {
+            return success(null);
+        }
+        List<SeckillProductDO> seckillProducts =  seckillActivityService.getSeckillProductListByActivityId(id);
+        return success(SeckillActivityConvert.INSTANCE.convert(seckillActivity,seckillProducts));
+    }
+
+    @GetMapping("/list")
+    @ApiOperation("获得秒杀活动列表")
+    @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
+    @PreAuthorize("@ss.hasPermission('promotion:seckill-activity:query')")
+    public CommonResult<List<SeckillActivityRespVO>> getSeckillActivityList(@RequestParam("ids") Collection<Long> ids) {
+        List<SeckillActivityDO> list = seckillActivityService.getSeckillActivityList(ids);
+        return success(SeckillActivityConvert.INSTANCE.convertList(list));
+    }
+
+    @GetMapping("/page")
+    @ApiOperation("获得秒杀活动分页")
+    @PreAuthorize("@ss.hasPermission('promotion:seckill-activity:query')")
+    public CommonResult<PageResult<SeckillActivityRespVO>> getSeckillActivityPage(@Valid SeckillActivityPageReqVO pageVO) {
+        PageResult<SeckillActivityDO> pageResult = seckillActivityService.getSeckillActivityPage(pageVO);
+        return success(SeckillActivityConvert.INSTANCE.convertPage(pageResult));
+    }
+
+}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckillactivity/vo/SeckillActivityBaseVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckillactivity/vo/SeckillActivityBaseVO.java
new file mode 100644
index 000000000..66128212a
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckillactivity/vo/SeckillActivityBaseVO.java
@@ -0,0 +1,66 @@
+package cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckillactivity.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import java.time.LocalDateTime;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DEFAULT;
+
+/**
+* 秒杀活动 Base VO,提供给添加、修改、详细的子 VO 使用
+* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
+*/
+@Data
+public class SeckillActivityBaseVO {
+
+    @ApiModelProperty(value = "秒杀活动名称", required = true, example = "晚九点限时秒杀")
+    @NotNull(message = "秒杀活动名称不能为空")
+    private String name;
+
+    @ApiModelProperty(value = "活动开始时间", required = true)
+    @NotNull(message = "活动开始时间不能为空")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
+    private LocalDateTime startTime;
+
+    @ApiModelProperty(value = "活动结束时间", required = true)
+    @NotNull(message = "活动结束时间不能为空")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
+    private LocalDateTime endTime;
+
+
+    @ApiModel("商品")
+    @Data
+    public static class Product {
+
+        @ApiModelProperty(value = "商品 SPU 编号", required = true, example = "1")
+        @NotNull(message = "商品 SPU 编号不能为空")
+        private Long spuId;
+
+        @ApiModelProperty(value = "商品 SKU 编号", required = true, example = "1")
+        @NotNull(message = "商品 SKU 编号不能为空")
+        private Long skuId;
+
+        @ApiModelProperty(value = "秒杀金额", required = true, example = "12.00")
+        @NotNull(message = "秒杀金额不能为空")
+        private Integer seckillPrice;
+
+        @ApiModelProperty(value = "秒杀库存", example = "80")
+        @Min(value = 0, message = "秒杀库存需要大于等于 0")
+        private Integer stock;
+
+        @ApiModelProperty(value = "每人限购", example = "10", notes = "如果为0则不限购")
+        @Min(value = 0, message = "每人限购需要大于等于 0")
+        private Integer limitBuyCount;
+
+    }
+
+}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckillactivity/vo/SeckillActivityCreateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckillactivity/vo/SeckillActivityCreateReqVO.java
new file mode 100644
index 000000000..1291da6c7
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckillactivity/vo/SeckillActivityCreateReqVO.java
@@ -0,0 +1,39 @@
+package cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckillactivity.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+@ApiModel("管理后台 - 秒杀活动创建 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class SeckillActivityCreateReqVO extends SeckillActivityBaseVO {
+
+    @ApiModelProperty(value = "备注", example = "限时秒杀活动")
+    private String remark;
+
+    @ApiModelProperty(value = "排序", required = true)
+    @NotNull(message = "排序不能为空")
+    private Integer sort;
+
+    @ApiModelProperty(value = "秒杀时段id", required = true)
+    @NotBlank(message = "参与场次不能为空")
+    private String timeId;
+
+    /**
+     * 商品列表
+     */
+    @NotEmpty(message = "商品列表不能为空")
+    @Valid
+    private List<Product> products;
+
+}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckillactivity/vo/SeckillActivityDetailRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckillactivity/vo/SeckillActivityDetailRespVO.java
new file mode 100644
index 000000000..aa6343137
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckillactivity/vo/SeckillActivityDetailRespVO.java
@@ -0,0 +1,21 @@
+package cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckillactivity.vo;
+
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+import java.util.List;
+
+@ApiModel("管理后台 - 秒杀活动的详细 Response VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class SeckillActivityDetailRespVO extends SeckillActivityRespVO{
+
+    /**
+     * 商品列表
+     */
+    private List<Product> products;
+
+}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckillactivity/vo/SeckillActivityPageReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckillactivity/vo/SeckillActivityPageReqVO.java
new file mode 100644
index 000000000..5aa32fac8
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckillactivity/vo/SeckillActivityPageReqVO.java
@@ -0,0 +1,37 @@
+package cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckillactivity.vo;
+
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDateTime;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DEFAULT;
+
+@ApiModel("管理后台 - 秒杀活动分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class SeckillActivityPageReqVO extends PageParam {
+
+    @ApiModelProperty(value = "秒杀活动名称", example = "晚九点限时秒杀")
+    private String name;
+
+    @ApiModelProperty(value = "活动状态", example = "进行中")
+    private Integer status;
+
+    @ApiModelProperty(value = "秒杀时段id")
+    private String timeId;
+
+    @ApiModelProperty(value = "创建时间")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
+    private LocalDateTime[] createTime;
+
+}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckillactivity/vo/SeckillActivityRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckillactivity/vo/SeckillActivityRespVO.java
new file mode 100644
index 000000000..220f4df6f
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckillactivity/vo/SeckillActivityRespVO.java
@@ -0,0 +1,41 @@
+package cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckillactivity.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+import java.time.LocalDateTime;
+
+@ApiModel("管理后台 - 秒杀活动 Response VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class SeckillActivityRespVO extends SeckillActivityBaseVO {
+
+    @ApiModelProperty(value = "秒杀活动id",  required = true, example = "1")
+    private Long id;
+
+    @ApiModelProperty(value = "付款订单数", required = true)
+    private Integer orderCount;
+
+    @ApiModelProperty(value = "付款人数", required = true)
+    private Integer userCount;
+
+    @ApiModelProperty(value = "创建时间", required = true)
+    private LocalDateTime createTime;
+
+    @ApiModelProperty(value = "秒杀时段id", required = true)
+    private String timeId;
+
+    @ApiModelProperty(value = "排序", required = true)
+    private Integer sort;
+
+    @ApiModelProperty(value = "备注", example = "限时秒杀活动")
+    private String remark;
+
+    @ApiModelProperty(value = "活动状态", example = "进行中")
+    private Integer status;
+
+}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckillactivity/vo/SeckillActivityUpdateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckillactivity/vo/SeckillActivityUpdateReqVO.java
new file mode 100644
index 000000000..f53bb50d8
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckillactivity/vo/SeckillActivityUpdateReqVO.java
@@ -0,0 +1,42 @@
+package cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckillactivity.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+@ApiModel("管理后台 - 秒杀活动更新 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class SeckillActivityUpdateReqVO extends SeckillActivityBaseVO {
+
+    @ApiModelProperty(value = "秒杀活动编号", required = true, example = "224")
+    @NotNull(message = "秒杀活动编号不能为空")
+    private Long id;
+
+    @ApiModelProperty(value = "备注", example = "限时秒杀活动")
+    private String remark;
+
+    @ApiModelProperty(value = "排序", required = true)
+    @NotNull(message = "排序不能为空")
+    private Integer sort;
+
+    @ApiModelProperty(value = "秒杀时段id", required = true)
+    @NotNull(message = "秒杀时段id不能为空")
+    private String timeId;
+
+    /**
+     * 商品列表
+     */
+    @NotEmpty(message = "商品列表不能为空")
+    @Valid
+    private List<Product> products;
+
+}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckilltime/SeckillTimeController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckilltime/SeckillTimeController.java
new file mode 100644
index 000000000..fad5300be
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckilltime/SeckillTimeController.java
@@ -0,0 +1,81 @@
+package cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckilltime;
+
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckilltime.vo.SeckillTimeCreateReqVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckilltime.vo.SeckillTimeRespVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckilltime.vo.SeckillTimeUpdateReqVO;
+import cn.iocoder.yudao.module.promotion.convert.seckill.seckilltime.SeckillTimeConvert;
+import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckilltime.SeckillTimeDO;
+import cn.iocoder.yudao.module.promotion.service.seckill.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 org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+import java.util.List;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+@Api(tags = "管理后台 - 秒杀时段")
+@RestController
+@RequestMapping("/promotion/seckill-time")
+@Validated
+public class SeckillTimeController {
+
+    @Resource
+    private SeckillTimeService seckillTimeService;
+
+    @PostMapping("/create")
+    @ApiOperation("创建秒杀时段")
+    @PreAuthorize("@ss.hasPermission('promotion:seckill-time:create')")
+    public CommonResult<Long> createSeckillTime(@Valid @RequestBody SeckillTimeCreateReqVO createReqVO) {
+        return success(seckillTimeService.createSeckillTime(createReqVO));
+    }
+
+    @PutMapping("/update")
+    @ApiOperation("更新秒杀时段")
+    @PreAuthorize("@ss.hasPermission('promotion:seckill-time:update')")
+    public CommonResult<Boolean> updateSeckillTime(@Valid @RequestBody SeckillTimeUpdateReqVO updateReqVO) {
+        seckillTimeService.updateSeckillTime(updateReqVO);
+        return success(true);
+    }
+
+    @DeleteMapping("/delete")
+    @ApiOperation("删除秒杀时段")
+    @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
+    @PreAuthorize("@ss.hasPermission('promotion:seckill-time:delete')")
+    public CommonResult<Boolean> deleteSeckillTime(@RequestParam("id") Long id) {
+        seckillTimeService.deleteSeckillTime(id);
+        return success(true);
+    }
+
+    @GetMapping("/get")
+    @ApiOperation("获得秒杀时段")
+    @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
+    @PreAuthorize("@ss.hasPermission('promotion:seckill-time:query')")
+    public CommonResult<SeckillTimeRespVO> getSeckillTime(@RequestParam("id") Long id) {
+        SeckillTimeDO seckillTime = seckillTimeService.getSeckillTime(id);
+        return success(SeckillTimeConvert.INSTANCE.convert(seckillTime));
+    }
+
+    @GetMapping("/list")
+    @ApiOperation("获得所有秒杀时段列表")
+//    @PreAuthorize("@ss.hasPermission('promotion:seckill-time:query')")
+    public CommonResult<List<SeckillTimeRespVO>> getSeckillTimeList() {
+        List<SeckillTimeDO> list = seckillTimeService.getSeckillTimeList();
+        return success(SeckillTimeConvert.INSTANCE.convertList(list));
+    }
+
+//    @GetMapping("/page")
+//    @ApiOperation("获得秒杀时段分页")
+//    @PreAuthorize("@ss.hasPermission('promotion:seckill-time:query')")
+//    public CommonResult<PageResult<SeckillTimeRespVO>> getSeckillTimePage(@Valid SeckillTimePageReqVO pageVO) {
+//        PageResult<SeckillTimeDO> pageResult = seckillTimeService.getSeckillTimePage(pageVO);
+//        return success(SeckillTimeConvert.INSTANCE.convertPage(pageResult));
+//    }
+
+}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckilltime/vo/SeckillTimeBaseVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckilltime/vo/SeckillTimeBaseVO.java
new file mode 100644
index 000000000..fd2ea5480
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckilltime/vo/SeckillTimeBaseVO.java
@@ -0,0 +1,32 @@
+package cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckilltime.vo;
+
+import lombok.*;
+
+import java.time.LocalTime;
+import java.util.*;
+import io.swagger.annotations.*;
+import javax.validation.constraints.*;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+/**
+* 秒杀时段 Base VO,提供给添加、修改、详细的子 VO 使用
+* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
+*/
+@Data
+public class SeckillTimeBaseVO {
+
+    @ApiModelProperty(value = "秒杀时段名称", required = true)
+    @NotNull(message = "秒杀时段名称不能为空")
+    private String name;
+
+    @ApiModelProperty(value = "开始时间点", required = true)
+    @NotNull(message = "开始时间点不能为空")
+    private LocalTime startTime;
+
+    @ApiModelProperty(value = "结束时间点", required = true)
+    @NotNull(message = "结束时间点不能为空")
+    private LocalTime endTime;
+
+}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckilltime/vo/SeckillTimeCreateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckilltime/vo/SeckillTimeCreateReqVO.java
new file mode 100644
index 000000000..e00ad7a63
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckilltime/vo/SeckillTimeCreateReqVO.java
@@ -0,0 +1,12 @@
+package cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckilltime.vo;
+
+import lombok.*;
+import io.swagger.annotations.*;
+
+@ApiModel("管理后台 - 秒杀时段创建 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class SeckillTimeCreateReqVO extends SeckillTimeBaseVO {
+
+}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckilltime/vo/SeckillTimePageReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckilltime/vo/SeckillTimePageReqVO.java
new file mode 100644
index 000000000..7fe5b07d5
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckilltime/vo/SeckillTimePageReqVO.java
@@ -0,0 +1,40 @@
+package cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckilltime.vo;
+
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalTime;
+
+@ApiModel("管理后台 - 秒杀时段分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class SeckillTimePageReqVO extends PageParam {
+
+    @ApiModelProperty(value = "秒杀时段名称")
+    private String name;
+
+    @ApiModelProperty(value = "开始时间点")
+    @DateTimeFormat(pattern = "HH:mm:ss")
+    private LocalTime startTime;
+
+    @ApiModelProperty(value = "结束时间点")
+    @DateTimeFormat(pattern = "HH:mm:ss")
+    private LocalTime endTime;
+
+
+
+
+
+
+
+//    @ApiModelProperty(value = "创建时间")
+//    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+//    private Date[] createTime;
+
+}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckilltime/vo/SeckillTimeRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckilltime/vo/SeckillTimeRespVO.java
new file mode 100644
index 000000000..c40f189d9
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckilltime/vo/SeckillTimeRespVO.java
@@ -0,0 +1,22 @@
+package cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckilltime.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+
+@ApiModel("管理后台 - 秒杀时段 Response VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class SeckillTimeRespVO extends SeckillTimeBaseVO {
+
+    @ApiModelProperty(value = "编号", required = true)
+    private Long id;
+
+    @ApiModelProperty(value = "秒杀活动数量", required = true)
+    private Integer seckillActivityCount;
+
+    @ApiModelProperty(value = "创建时间", required = true)
+    private Date createTime;
+
+}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckilltime/vo/SeckillTimeSimpleRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckilltime/vo/SeckillTimeSimpleRespVO.java
new file mode 100644
index 000000000..25714595f
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckilltime/vo/SeckillTimeSimpleRespVO.java
@@ -0,0 +1,4 @@
+package cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckilltime.vo;
+
+public class SeckillTimeSimpleRespVO {
+}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckilltime/vo/SeckillTimeUpdateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckilltime/vo/SeckillTimeUpdateReqVO.java
new file mode 100644
index 000000000..16b786c7d
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/seckilltime/vo/SeckillTimeUpdateReqVO.java
@@ -0,0 +1,21 @@
+package cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckilltime.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+import javax.validation.constraints.NotNull;
+
+@ApiModel("管理后台 - 秒杀时段更新 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class SeckillTimeUpdateReqVO extends SeckillTimeBaseVO {
+
+    @ApiModelProperty(value = "编号", required = true)
+    @NotNull(message = "编号不能为空")
+    private Long id;
+
+}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillactivity/SeckillActivityConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillactivity/SeckillActivityConvert.java
new file mode 100644
index 000000000..fda7b6e1d
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillactivity/SeckillActivityConvert.java
@@ -0,0 +1,77 @@
+package cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity;
+
+import cn.hutool.core.util.ObjectUtil;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckillactivity.vo.*;
+import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
+import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.Mappings;
+import org.mapstruct.factory.Mappers;
+
+import java.util.List;
+
+/**
+ * 秒杀活动 Convert
+ *
+ * @author 芋道源码
+ */
+@Mapper
+public interface SeckillActivityConvert {
+
+    SeckillActivityConvert INSTANCE = Mappers.getMapper(SeckillActivityConvert.class);
+
+    SeckillProductDO convert(SeckillActivityBaseVO.Product product);
+
+
+    SeckillActivityDO convert(SeckillActivityCreateReqVO bean);
+
+    default String map(Long[] value){
+        return value.toString();
+    }
+
+    SeckillActivityDO convert(SeckillActivityUpdateReqVO bean);
+
+    SeckillActivityRespVO convert(SeckillActivityDO bean);
+
+    List<SeckillActivityRespVO> convertList(List<SeckillActivityDO> list);
+
+    PageResult<SeckillActivityRespVO> convertPage(PageResult<SeckillActivityDO> page);
+
+    @Mappings({@Mapping(target = "products",source = "seckillProducts")})
+    SeckillActivityDetailRespVO convert(SeckillActivityDO seckillActivity, List<SeckillProductDO> seckillProducts);
+
+
+    /**
+     * 比较两个秒杀商品对象是否相等
+     *
+     * @param productDO 数据库中的商品
+     * @param productVO 前端传入的商品
+     * @return 是否匹配
+     */
+    default boolean isEquals(SeckillProductDO productDO, SeckillActivityBaseVO.Product productVO) {
+        return ObjectUtil.equals(productDO.getSpuId(), productVO.getSpuId())
+                && ObjectUtil.equals(productDO.getSkuId(), productVO.getSkuId())
+                && ObjectUtil.equals(productDO.getSeckillPrice(), productVO.getSeckillPrice())
+                && ObjectUtil.equals(productDO.getStock(), productVO.getStock())
+                && ObjectUtil.equals(productDO.getLimitBuyCount(), productVO.getLimitBuyCount());
+
+    }
+
+    /**
+     * 比较两个秒杀商品对象是否相等
+     *
+     * @param productDO 商品1
+     * @param productVO 商品2
+     * @return 是否匹配
+     */
+    default boolean isEquals(SeckillProductDO productDO, SeckillProductDO productVO) {
+        return ObjectUtil.equals(productDO.getSpuId(), productVO.getSpuId())
+                && ObjectUtil.equals(productDO.getSkuId(), productVO.getSkuId())
+                && ObjectUtil.equals(productDO.getSeckillPrice(), productVO.getSeckillPrice())
+                && ObjectUtil.equals(productDO.getStock(), productVO.getStock())
+                && ObjectUtil.equals(productDO.getLimitBuyCount(), productVO.getLimitBuyCount());
+
+    }
+}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckilltime/SeckillTimeConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckilltime/SeckillTimeConvert.java
new file mode 100644
index 000000000..dda7d2c9d
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckilltime/SeckillTimeConvert.java
@@ -0,0 +1,34 @@
+package cn.iocoder.yudao.module.promotion.convert.seckill.seckilltime;
+
+import java.util.*;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+
+import cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckilltime.vo.SeckillTimeCreateReqVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckilltime.vo.SeckillTimeRespVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckilltime.vo.SeckillTimeUpdateReqVO;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckilltime.SeckillTimeDO;
+
+/**
+ * 秒杀时段 Convert
+ *
+ * @author 芋道源码
+ */
+@Mapper
+public interface SeckillTimeConvert {
+
+    SeckillTimeConvert INSTANCE = Mappers.getMapper(SeckillTimeConvert.class);
+
+    SeckillTimeDO convert(SeckillTimeCreateReqVO bean);
+
+    SeckillTimeDO convert(SeckillTimeUpdateReqVO bean);
+
+    SeckillTimeRespVO convert(SeckillTimeDO bean);
+
+    List<SeckillTimeRespVO> convertList(List<SeckillTimeDO> list);
+
+    PageResult<SeckillTimeRespVO> convertPage(PageResult<SeckillTimeDO> page);
+
+}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillActivityDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillActivityDO.java
new file mode 100644
index 000000000..fc1341862
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillActivityDO.java
@@ -0,0 +1,76 @@
+package cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity;
+
+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 cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum;
+import lombok.*;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 秒杀活动 DO
+ *
+ * @author 芋道源码
+ */
+@TableName("promotion_seckill_activity")
+@KeySequence("promotion_seckill_activity_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class SeckillActivityDO extends BaseDO {
+
+    /**
+     * 秒杀活动编号
+     */
+    @TableId
+    private Long id;
+    /**
+     * 秒杀活动名称
+     */
+    private String name;
+    /**
+     * 活动状态
+     *
+     * 枚举 {@link PromotionActivityStatusEnum 对应的类}
+     */
+    private Integer status;
+    /**
+     * 备注
+     */
+    private String remark;
+    /**
+     * 活动开始时间
+     */
+    private LocalDateTime startTime;
+    /**
+     * 活动结束时间
+     */
+    private LocalDateTime endTime;
+    /**
+     * 排序
+     */
+    private Integer sort;
+    /**
+     * 秒杀时段id
+     */
+    private String timeId;
+    /**
+     * 付款订单数
+     */
+    private Integer orderCount;
+    /**
+     * 付款人数
+     */
+    private Integer userCount;
+    /**
+     * 订单实付金额,单位:分
+     */
+    private BigDecimal totalPrice;
+
+}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillProductDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillProductDO.java
new file mode 100644
index 000000000..3ed54efa4
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillProductDO.java
@@ -0,0 +1,60 @@
+package cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity;
+
+import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+import lombok.Data;
+
+/**
+ * 秒杀参与商品
+ * @TableName promotion_seckill_product
+ */
+@TableName(value ="promotion_seckill_product")
+@Data
+public class SeckillProductDO extends BaseDO {
+    /**
+     * 秒杀参与商品编号
+     */
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 秒杀活动id
+     */
+    private Long activityId;
+
+    /**
+     * 秒杀时段id
+     */
+    private Long timeId;
+
+    /**
+     * 商品id
+     */
+    private Long spuId;
+
+    /**
+     * 商品sku_id
+     */
+    private Long skuId;
+
+    /**
+     * 秒杀金额
+     */
+    private Integer seckillPrice;
+
+    /**
+     * 秒杀库存
+     */
+    private Integer stock;
+
+    /**
+     * 每人限购
+     */
+    private Integer limitBuyCount;
+}
\ No newline at end of file
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckilltime/SeckillTimeDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckilltime/SeckillTimeDO.java
new file mode 100644
index 000000000..56dc0eb93
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckilltime/SeckillTimeDO.java
@@ -0,0 +1,48 @@
+package cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.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;
+
+/**
+ * 秒杀时段 DO
+ *
+ * @author 芋道源码
+ */
+@TableName("promotion_seckill_time")
+@KeySequence("promotion_seckill_time_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class SeckillTimeDO extends BaseDO {
+
+    /**
+     * 编号
+     */
+    @TableId
+    private Long id;
+    /**
+     * 秒杀时段名称
+     */
+    private String name;
+    /**
+     * 开始时间点
+     */
+    private LocalTime startTime;
+    /**
+     * 结束时间点
+     */
+    private LocalTime endTime;
+    /**
+     * 秒杀活动数量
+     */
+    private Integer seckillActivityCount;
+
+}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillActivityMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillActivityMapper.java
new file mode 100644
index 000000000..41b7cafdc
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillActivityMapper.java
@@ -0,0 +1,28 @@
+package cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckillactivity.vo.SeckillActivityPageReqVO;
+import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 秒杀活动 Mapper
+ *
+ * @author 芋道源码
+ */
+@Mapper
+public interface SeckillActivityMapper extends BaseMapperX<SeckillActivityDO> {
+// TODO: 2022/11/28 halfninety 秒杀活动通过场次查询使用like会出现问题,查询活动场次编号为1,则活动场次编号为 1,11,......的都会被查出来
+    default PageResult<SeckillActivityDO> selectPage(SeckillActivityPageReqVO reqVO) {
+        return selectPage(reqVO, new LambdaQueryWrapperX<SeckillActivityDO>()
+                .likeIfPresent(SeckillActivityDO::getName, reqVO.getName())
+                .eqIfPresent(SeckillActivityDO::getStatus, reqVO.getStatus())
+                .likeIfPresent(SeckillActivityDO::getTimeId, reqVO.getTimeId())
+//                .like(StringUtils.hasText(reqVO.getTimeId()),SeckillActivityDO::getTimeId, reqVO.getTimeId() + ",")
+                .betweenIfPresent(SeckillActivityDO::getCreateTime, reqVO.getCreateTime())
+                .orderByDesc(SeckillActivityDO::getId));
+    }
+
+}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillProductMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillProductMapper.java
new file mode 100644
index 000000000..3c76b45df
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillProductMapper.java
@@ -0,0 +1,21 @@
+package cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity;
+
+import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.Collection;
+import java.util.List;
+
+@Mapper
+public interface SeckillProductMapper extends BaseMapperX<SeckillProductDO> {
+
+    default List<SeckillProductDO> selectListByActivityId(Long id){
+        return selectList(SeckillProductDO::getActivityId,id);
+    }
+
+    default List<SeckillProductDO> selectListBySkuIds(Collection<Long> skuIds){
+        return selectList(SeckillProductDO::getSkuId,skuIds);
+    }
+
+}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckilltime/SeckillTimeMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckilltime/SeckillTimeMapper.java
new file mode 100644
index 000000000..83242f18b
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckilltime/SeckillTimeMapper.java
@@ -0,0 +1,58 @@
+package cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckilltime;
+
+import java.time.LocalTime;
+import java.util.*;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckilltime.SeckillTimeDO;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 秒杀时段 Mapper
+ *
+ * @author 芋道源码
+ */
+@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 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 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();
+    }
+
+}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityService.java
new file mode 100644
index 000000000..6b45330ba
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityService.java
@@ -0,0 +1,78 @@
+package cn.iocoder.yudao.module.promotion.service.seckill.seckillactivity;
+
+import java.util.*;
+import javax.validation.*;
+
+import cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckillactivity.vo.SeckillActivityCreateReqVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckillactivity.vo.SeckillActivityPageReqVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckillactivity.vo.SeckillActivityUpdateReqVO;
+import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO;
+
+/**
+ * 秒杀活动 Service 接口
+ *
+ * @author 芋道源码
+ */
+public interface SeckillActivityService {
+
+    /**
+     * 创建秒杀活动
+     *
+     * @param createReqVO 创建信息
+     * @return 编号
+     */
+    Long createSeckillActivity(@Valid SeckillActivityCreateReqVO createReqVO);
+
+    /**
+     * 更新秒杀活动
+     *
+     * @param updateReqVO 更新信息
+     */
+    void updateSeckillActivity(@Valid SeckillActivityUpdateReqVO updateReqVO);
+
+    /**
+     * 关闭秒杀活动
+     * @param id 编号
+     */
+    void closeSeckillActivity(Long id);
+
+    /**
+     * 删除秒杀活动
+     *
+     * @param id 编号
+     */
+    void deleteSeckillActivity(Long id);
+
+    /**
+     * 获得秒杀活动
+     *
+     * @param id 编号
+     * @return 秒杀活动
+     */
+    SeckillActivityDO getSeckillActivity(Long id);
+
+    /**
+     * 获得秒杀活动列表
+     *
+     * @param ids 编号
+     * @return 秒杀活动列表
+     */
+    List<SeckillActivityDO> getSeckillActivityList(Collection<Long> ids);
+
+    /**
+     * 获得秒杀活动分页
+     *
+     * @param pageReqVO 分页查询
+     * @return 秒杀活动分页
+     */
+    PageResult<SeckillActivityDO> getSeckillActivityPage(SeckillActivityPageReqVO pageReqVO);
+
+    /**
+     * 通过活动编号获取活动商品
+     * @param id 活动编号
+     * @return 活动商品列表
+     */
+    List<SeckillProductDO> getSeckillProductListByActivityId(Long id);
+}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityServiceImpl.java
new file mode 100644
index 000000000..d10fd607f
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityServiceImpl.java
@@ -0,0 +1,221 @@
+package cn.iocoder.yudao.module.promotion.service.seckill.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.seckill.seckillactivity.vo.SeckillActivityBaseVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckillactivity.vo.SeckillActivityCreateReqVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckillactivity.vo.SeckillActivityPageReqVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckillactivity.vo.SeckillActivityUpdateReqVO;
+import cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity.SeckillActivityConvert;
+import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
+import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO;
+import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity.SeckillActivityMapper;
+import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity.SeckillProductMapper;
+import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum;
+import cn.iocoder.yudao.module.promotion.service.seckill.seckilltime.SeckillTimeService;
+import cn.iocoder.yudao.module.promotion.util.PromotionUtils;
+import org.springframework.stereotype.Service;
+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.*;
+import static java.util.Arrays.asList;
+
+/**
+ * 秒杀活动 Service 实现类
+ *
+ * @author 芋道源码
+ */
+@Service
+@Validated
+public class SeckillActivityServiceImpl implements SeckillActivityService {
+
+    @Resource
+    private SeckillActivityMapper seckillActivityMapper;
+
+    @Resource
+    private SeckillProductMapper seckillProductMapper;
+
+    @Resource
+    private SeckillTimeService seckillTimeService;
+
+    @Override
+    public Long createSeckillActivity(SeckillActivityCreateReqVO createReqVO) {
+        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()));
+        seckillActivityMapper.insert(seckillActivity);
+        // 插入商品
+        List<SeckillProductDO> productDOS = CollectionUtils.convertList(createReqVO.getProducts(),
+                product -> SeckillActivityConvert.INSTANCE.convert(product).setActivityId(seckillActivity.getId()));
+        seckillProductMapper.insertBatch(productDOS);
+        return seckillActivity.getId();
+    }
+
+    @Override
+    public void updateSeckillActivity(SeckillActivityUpdateReqVO updateReqVO) {
+        // 校验存在
+        SeckillActivityDO seckillActivity = this.validateSeckillActivityExists(updateReqVO.getId());
+        if (PromotionActivityStatusEnum.CLOSE.getStatus().equals(seckillActivity.getStatus())) {
+            throw exception(SECKILL_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED);
+        }
+        // 校验商品是否冲突
+        validateSeckillActivityProductConflicts(updateReqVO.getId(), updateReqVO.getProducts());
+        // 更新秒杀时段的秒杀活动数量
+        updateSeckillTimeActivityCount(updateReqVO.getId(), updateReqVO.getTimeId());
+        // 更新活动
+        SeckillActivityDO updateObj = SeckillActivityConvert.INSTANCE.convert(updateReqVO)
+                .setStatus(PromotionUtils.calculateActivityStatus(updateReqVO.getStartTime(), updateReqVO.getEndTime()));
+        seckillActivityMapper.updateById(updateObj);
+        // 更新商品
+        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);
+    }
+
+    /**
+     * 更新秒杀商品
+     */
+    private void updateSeckillProduct(SeckillActivityUpdateReqVO updateReqVO) {
+        List<SeckillProductDO> seckillProductDOS = seckillProductMapper.selectListByActivityId(updateReqVO.getId());
+        List<SeckillActivityBaseVO.Product> products = updateReqVO.getProducts();
+        //对后台查出的数据和前台查出的数据进行遍历,
+        //1.对前台数据进行遍历:如果不存在于后台的sku中需要新增
+        //2.对后台数据进行遍历:如果不存在于前台的sku中需要删除
+        //计算需要删除的数据
+        List<Long> deleteIds = CollectionUtils.convertList(seckillProductDOS, SeckillProductDO::getId,
+                seckillProductDO -> products.stream()
+                        .noneMatch(product -> SeckillActivityConvert.INSTANCE.isEquals(seckillProductDO, product)));
+        if (CollUtil.isNotEmpty(deleteIds)) {
+            seckillProductMapper.deleteBatchIds(deleteIds);
+        }
+        //计算需要新增的数据
+        List<SeckillProductDO> newSeckillProductDOs = CollectionUtils.convertList(products,
+                product -> SeckillActivityConvert.INSTANCE.convert(product).setActivityId(updateReqVO.getId()));
+        newSeckillProductDOs.removeIf(product -> seckillProductDOS.stream()
+                .anyMatch(seckillProduct -> SeckillActivityConvert.INSTANCE.isEquals(seckillProduct, product)));
+        if (CollUtil.isNotEmpty(newSeckillProductDOs)) {
+            seckillProductMapper.insertBatch(newSeckillProductDOs);
+        }
+    }
+
+    /**
+     * 校验商品是否冲突
+     *
+     * @param id       秒杀活动编号
+     * @param products 商品列表
+     */
+    private void validateSeckillActivityProductConflicts(Long id, List<SeckillActivityBaseVO.Product> products) {
+        if (CollUtil.isEmpty(products)) {
+            return;
+        }
+        List<SeckillProductDO> seckillProductDOS = seckillProductMapper
+                .selectListBySkuIds(CollectionUtils.convertSet(products, SeckillActivityBaseVO.Product::getSkuId));
+        if (CollUtil.isEmpty(seckillProductDOS)) {
+            return;
+        }
+        List<SeckillActivityDO> seckillActivityDOS = seckillActivityMapper
+                .selectBatchIds(CollectionUtils.convertSet(seckillProductDOS, SeckillProductDO::getActivityId));
+        if (id != null) {// 排除自己这个活动
+            seckillActivityDOS.removeIf(item -> id.equals(item.getId()));
+        }
+        // 排除不满足status的活动
+        List<Integer> statuses = asList(PromotionActivityStatusEnum.WAIT.getStatus(), PromotionActivityStatusEnum.RUN.getStatus());
+        seckillActivityDOS.removeIf(item -> !statuses.contains(item.getStatus()));
+        //如果非空,则说明冲突
+        if (CollUtil.isNotEmpty(seckillActivityDOS)) {
+            throw exception(SECKILL_ACTIVITY_SPU_CONFLICTS);
+        }
+
+    }
+
+    @Override
+    public void closeSeckillActivity(Long id) {
+        // 校验存在
+        SeckillActivityDO seckillActivity = this.validateSeckillActivityExists(id);
+        if (PromotionActivityStatusEnum.CLOSE.getStatus().equals(seckillActivity.getStatus())) {
+            throw exception(SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED);
+        }
+        if (PromotionActivityStatusEnum.END.getStatus().equals(seckillActivity.getStatus())) {
+            throw exception(SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_END);
+        }
+        // 更新
+        SeckillActivityDO updateObj = new SeckillActivityDO().setId(id).setStatus(PromotionActivityStatusEnum.CLOSE.getStatus());
+        seckillActivityMapper.updateById(updateObj);
+    }
+
+    @Override
+    public void deleteSeckillActivity(Long id) {
+        // 校验存在
+        SeckillActivityDO seckillActivity = this.validateSeckillActivityExists(id);
+        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);
+    }
+
+    private SeckillActivityDO validateSeckillActivityExists(Long id) {
+        SeckillActivityDO seckillActivity = seckillActivityMapper.selectById(id);
+        if (seckillActivity == null) {
+            throw exception(SECKILL_ACTIVITY_NOT_EXISTS);
+        }
+        return seckillActivity;
+    }
+
+    @Override
+    public SeckillActivityDO getSeckillActivity(Long id) {
+        return seckillActivityMapper.selectById(id);
+    }
+
+    @Override
+    public List<SeckillActivityDO> getSeckillActivityList(Collection<Long> ids) {
+        return seckillActivityMapper.selectBatchIds(ids);
+    }
+
+    @Override
+    public PageResult<SeckillActivityDO> getSeckillActivityPage(SeckillActivityPageReqVO pageReqVO) {
+        return seckillActivityMapper.selectPage(pageReqVO);
+    }
+
+    @Override
+    public List<SeckillProductDO> getSeckillProductListByActivityId(Long id) {
+        return seckillProductMapper.selectListByActivityId(id);
+    }
+
+}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckilltime/SeckillTimeService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckilltime/SeckillTimeService.java
new file mode 100644
index 000000000..0256c873a
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckilltime/SeckillTimeService.java
@@ -0,0 +1,68 @@
+package cn.iocoder.yudao.module.promotion.service.seckill.seckilltime;
+
+import cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckilltime.vo.SeckillTimeCreateReqVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckilltime.vo.SeckillTimeUpdateReqVO;
+import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckilltime.SeckillTimeDO;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * 秒杀时段 Service 接口
+ *
+ * @author 芋道源码
+ */
+public interface SeckillTimeService {
+
+    /**
+     * 创建秒杀时段
+     *
+     * @param createReqVO 创建信息
+     * @return 编号
+     */
+    Long createSeckillTime(@Valid SeckillTimeCreateReqVO createReqVO);
+
+    /**
+     * 更新秒杀时段
+     *
+     * @param updateReqVO 更新信息
+     */
+    void updateSeckillTime(@Valid SeckillTimeUpdateReqVO updateReqVO);
+
+    /**
+     * 删除秒杀时段
+     *
+     * @param id 编号
+     */
+    void deleteSeckillTime(Long id);
+
+    /**
+     * 获得秒杀时段
+     *
+     * @param id 编号
+     * @return 秒杀时段
+     */
+    SeckillTimeDO getSeckillTime(Long id);
+
+    /**
+     * 获得所有秒杀时段列表
+     *
+     * @return 所有秒杀时段列表
+     */
+    List<SeckillTimeDO> getSeckillTimeList();
+
+    /**
+     * 秒杀时段列表的秒杀活动数量加 1
+     *
+     * @param ids 秒杀时段id列表
+     */
+    void sekillActivityCountAdd(List<Long> ids);
+
+
+    /**
+     * 秒杀时段列表的秒杀活动数量减 1
+     *
+     * @param ids 秒杀时段id列表
+     */
+    void sekillActivityCountReduce(List<Long> ids);
+}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckilltime/SeckillTimeServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckilltime/SeckillTimeServiceImpl.java
new file mode 100644
index 000000000..44e959835
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckilltime/SeckillTimeServiceImpl.java
@@ -0,0 +1,117 @@
+package cn.iocoder.yudao.module.promotion.service.seckill.seckilltime;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckilltime.vo.SeckillTimeCreateReqVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckilltime.vo.SeckillTimeUpdateReqVO;
+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.dal.dataobject.seckill.seckilltime.SeckillTimeDO;
+
+import cn.iocoder.yudao.module.promotion.convert.seckill.seckilltime.SeckillTimeConvert;
+import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckilltime.SeckillTimeMapper;
+
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
+
+/**
+ * 秒杀时段 Service 实现类
+ *
+ * @author 芋道源码
+ */
+@Service
+@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);
+        // 返回
+        return seckillTime.getId();
+    }
+
+    @Override
+    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);
+    }
+
+    @Override
+    public void deleteSeckillTime(Long id) {
+        // 校验存在
+        this.validateSeckillTimeExists(id);
+        // 删除
+        seckillTimeMapper.deleteById(id);
+    }
+
+    private void validateSeckillTimeExists(Long id) {
+        if (seckillTimeMapper.selectById(id) == null) {
+            throw exception(SECKILL_TIME_NOT_EXISTS);
+        }
+    }
+
+    /**
+     * 校验时间是否存在冲突
+     *
+     * @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);
+    }
+
+    @Override
+    public List<SeckillTimeDO> getSeckillTimeList() {
+        return seckillTimeMapper.selectList();
+    }
+
+    @Override
+    public void sekillActivityCountAdd(List<Long> ids) {
+        seckillTimeMapper.sekillActivityCountAdd(ids);
+    }
+
+    @Override
+    public void sekillActivityCountReduce(List<Long> ids) {
+        seckillTimeMapper.sekillActivityCountReduce(ids);
+    }
+
+}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/seckillactivity/SeckillActivityMapper.xml b/yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/seckillactivity/SeckillActivityMapper.xml
new file mode 100644
index 000000000..0f0d7c6cf
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/seckillactivity/SeckillActivityMapper.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity.SeckillActivityMapper">
+
+    <!--
+        一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
+        无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
+        代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
+        文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
+     -->
+
+</mapper>
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/seckilltime/SeckillTimeMapper.xml b/yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/seckilltime/SeckillTimeMapper.xml
new file mode 100644
index 000000000..c15423798
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/seckilltime/SeckillTimeMapper.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckilltime.SeckillTimeMapper">
+
+    <!--
+        一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
+        无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
+        代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
+        文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
+     -->
+
+</mapper>
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckillactivity/SeckillActivityServiceImplTest.java b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckillactivity/SeckillActivityServiceImplTest.java
new file mode 100644
index 000000000..2ea767e97
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckillactivity/SeckillActivityServiceImplTest.java
@@ -0,0 +1,170 @@
+package cn.iocoder.yudao.module.promotion.service.seckillactivity;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
+import cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckillactivity.vo.SeckillActivityCreateReqVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckillactivity.vo.SeckillActivityPageReqVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckillactivity.vo.SeckillActivityUpdateReqVO;
+import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
+import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity.SeckillActivityMapper;
+import cn.iocoder.yudao.module.promotion.service.seckill.seckillactivity.SeckillActivityServiceImpl;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+import org.springframework.context.annotation.Import;
+
+import javax.annotation.Resource;
+import java.time.LocalDateTime;
+
+import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
+import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
+import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
+import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
+import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
+import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.SECKILL_ACTIVITY_NOT_EXISTS;
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+* {@link SeckillActivityServiceImpl} 的单元测试类
+*
+* @author 芋道源码
+*/
+@Import(SeckillActivityServiceImpl.class)
+public class SeckillActivityServiceImplTest extends BaseDbUnitTest {
+
+    @Resource
+    private SeckillActivityServiceImpl seckillActivityService;
+
+    @Resource
+    private SeckillActivityMapper seckillActivityMapper;
+
+    @Test
+    public void testCreateSeckillActivity_success() {
+        // 准备参数
+        SeckillActivityCreateReqVO reqVO = randomPojo(SeckillActivityCreateReqVO.class);
+
+        // 调用
+        Long seckillActivityId = seckillActivityService.createSeckillActivity(reqVO);
+        // 断言
+        assertNotNull(seckillActivityId);
+        // 校验记录的属性是否正确
+        SeckillActivityDO seckillActivity = seckillActivityMapper.selectById(seckillActivityId);
+        assertPojoEquals(reqVO, seckillActivity);
+    }
+
+    @Test
+    public void testUpdateSeckillActivity_success() {
+        // mock 数据
+        SeckillActivityDO dbSeckillActivity = randomPojo(SeckillActivityDO.class);
+        seckillActivityMapper.insert(dbSeckillActivity);// @Sql: 先插入出一条存在的数据
+        // 准备参数
+        SeckillActivityUpdateReqVO reqVO = randomPojo(SeckillActivityUpdateReqVO.class, o -> {
+            o.setId(dbSeckillActivity.getId()); // 设置更新的 ID
+        });
+
+        // 调用
+        seckillActivityService.updateSeckillActivity(reqVO);
+        // 校验是否更新正确
+        SeckillActivityDO seckillActivity = seckillActivityMapper.selectById(reqVO.getId()); // 获取最新的
+        assertPojoEquals(reqVO, seckillActivity);
+    }
+
+    @Test
+    public void testUpdateSeckillActivity_notExists() {
+        // 准备参数
+        SeckillActivityUpdateReqVO reqVO = randomPojo(SeckillActivityUpdateReqVO.class);
+
+        // 调用, 并断言异常
+        assertServiceException(() -> seckillActivityService.updateSeckillActivity(reqVO), SECKILL_ACTIVITY_NOT_EXISTS);
+    }
+
+    @Test
+    public void testDeleteSeckillActivity_success() {
+        // mock 数据
+        SeckillActivityDO dbSeckillActivity = randomPojo(SeckillActivityDO.class);
+        seckillActivityMapper.insert(dbSeckillActivity);// @Sql: 先插入出一条存在的数据
+        // 准备参数
+        Long id = dbSeckillActivity.getId();
+
+        // 调用
+        seckillActivityService.deleteSeckillActivity(id);
+       // 校验数据不存在了
+       assertNull(seckillActivityMapper.selectById(id));
+    }
+
+    @Test
+    public void testDeleteSeckillActivity_notExists() {
+        // 准备参数
+        Long id = randomLongId();
+
+        // 调用, 并断言异常
+        assertServiceException(() -> seckillActivityService.deleteSeckillActivity(id), SECKILL_ACTIVITY_NOT_EXISTS);
+    }
+
+    @Test
+    @Disabled  // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
+    public void testGetSeckillActivityPage() {
+       // mock 数据
+       SeckillActivityDO dbSeckillActivity = randomPojo(SeckillActivityDO.class, o -> { // 等会查询到
+           o.setName(null);
+           o.setStatus(null);
+           o.setTimeId(null);
+           o.setCreateTime(null);
+       });
+       seckillActivityMapper.insert(dbSeckillActivity);
+       // 测试 name 不匹配
+       seckillActivityMapper.insert(cloneIgnoreId(dbSeckillActivity, o -> o.setName(null)));
+       // 测试 status 不匹配
+       seckillActivityMapper.insert(cloneIgnoreId(dbSeckillActivity, o -> o.setStatus(null)));
+       // 测试 timeId 不匹配
+       seckillActivityMapper.insert(cloneIgnoreId(dbSeckillActivity, o -> o.setTimeId(null)));
+       // 测试 createTime 不匹配
+       seckillActivityMapper.insert(cloneIgnoreId(dbSeckillActivity, o -> o.setCreateTime(null)));
+       // 准备参数
+       SeckillActivityPageReqVO reqVO = new SeckillActivityPageReqVO();
+       reqVO.setName(null);
+       reqVO.setStatus(null);
+       reqVO.setTimeId(null);
+       reqVO.setCreateTime((new LocalDateTime[]{}));
+
+       // 调用
+       PageResult<SeckillActivityDO> pageResult = seckillActivityService.getSeckillActivityPage(reqVO);
+       // 断言
+       assertEquals(1, pageResult.getTotal());
+       assertEquals(1, pageResult.getList().size());
+       assertPojoEquals(dbSeckillActivity, pageResult.getList().get(0));
+    }
+
+    @Test
+    @Disabled  // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
+    public void testGetSeckillActivityList() {
+       // mock 数据
+       SeckillActivityDO dbSeckillActivity = randomPojo(SeckillActivityDO.class, o -> { // 等会查询到
+           o.setName(null);
+           o.setStatus(null);
+           o.setTimeId(null);
+           o.setCreateTime(null);
+       });
+       seckillActivityMapper.insert(dbSeckillActivity);
+       // 测试 name 不匹配
+       seckillActivityMapper.insert(cloneIgnoreId(dbSeckillActivity, o -> o.setName(null)));
+       // 测试 status 不匹配
+       seckillActivityMapper.insert(cloneIgnoreId(dbSeckillActivity, o -> o.setStatus(null)));
+       // 测试 timeId 不匹配
+       seckillActivityMapper.insert(cloneIgnoreId(dbSeckillActivity, o -> o.setTimeId(null)));
+       // 测试 createTime 不匹配
+       seckillActivityMapper.insert(cloneIgnoreId(dbSeckillActivity, o -> o.setCreateTime(null)));
+       // 准备参数
+//       SeckillActivityExportReqVO reqVO = new SeckillActivityExportReqVO();
+//       reqVO.setName(null);
+//       reqVO.setStatus(null);
+//       reqVO.setTimeId(null);
+//       reqVO.setCreateTime((new Date[]{}));
+//
+//       // 调用
+//       List<SeckillActivityDO> list = seckillActivityService.getSeckillActivityList(reqVO);
+//       // 断言
+//       assertEquals(1, list.size());
+//       assertPojoEquals(dbSeckillActivity, list.get(0));
+    }
+
+}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckilltime/SeckillTimeServiceImplTest.java b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckilltime/SeckillTimeServiceImplTest.java
new file mode 100644
index 000000000..439bcf03e
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckilltime/SeckillTimeServiceImplTest.java
@@ -0,0 +1,189 @@
+package cn.iocoder.yudao.module.promotion.service.seckilltime;
+
+import cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckilltime.vo.SeckillTimeCreateReqVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.seckill.seckilltime.vo.SeckillTimeUpdateReqVO;
+import cn.iocoder.yudao.module.promotion.service.seckill.seckilltime.SeckillTimeServiceImpl;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+
+import javax.annotation.Resource;
+
+import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
+
+import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckilltime.SeckillTimeDO;
+import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckilltime.SeckillTimeMapper;
+
+import org.springframework.context.annotation.Import;
+
+import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
+import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*;
+import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
+import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*;
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+* {@link SeckillTimeServiceImpl} 的单元测试类
+*
+* @author 芋道源码
+*/
+@Import(SeckillTimeServiceImpl.class)
+public class SeckillTimeServiceImplTest extends BaseDbUnitTest {
+
+    @Resource
+    private SeckillTimeServiceImpl seckillTimeService;
+
+    @Resource
+    private SeckillTimeMapper seckillTimeMapper;
+
+    @Resource
+    private ObjectMapper objectMapper;
+
+    @Test
+    public void testJacksonSerializ(){
+
+        // 准备参数
+        SeckillTimeCreateReqVO reqVO = randomPojo(SeckillTimeCreateReqVO.class);
+//        ObjectMapper objectMapper = new ObjectMapper();
+        try {
+            String string = objectMapper.writeValueAsString(reqVO);
+            System.out.println(string);
+        } catch (JsonProcessingException e) {
+            e.printStackTrace();
+        }
+
+
+    }
+
+    @Test
+    public void testCreateSeckillTime_success() {
+        // 准备参数
+        SeckillTimeCreateReqVO reqVO = randomPojo(SeckillTimeCreateReqVO.class);
+
+        // 调用
+        Long seckillTimeId = seckillTimeService.createSeckillTime(reqVO);
+        // 断言
+        assertNotNull(seckillTimeId);
+        // 校验记录的属性是否正确
+        SeckillTimeDO seckillTime = seckillTimeMapper.selectById(seckillTimeId);
+        assertPojoEquals(reqVO, seckillTime);
+    }
+
+    @Test
+    public void testUpdateSeckillTime_success() {
+        // mock 数据
+        SeckillTimeDO dbSeckillTime = randomPojo(SeckillTimeDO.class);
+        seckillTimeMapper.insert(dbSeckillTime);// @Sql: 先插入出一条存在的数据
+        // 准备参数
+        SeckillTimeUpdateReqVO reqVO = randomPojo(SeckillTimeUpdateReqVO.class, o -> {
+            o.setId(dbSeckillTime.getId()); // 设置更新的 ID
+        });
+
+        // 调用
+        seckillTimeService.updateSeckillTime(reqVO);
+        // 校验是否更新正确
+        SeckillTimeDO seckillTime = seckillTimeMapper.selectById(reqVO.getId()); // 获取最新的
+        assertPojoEquals(reqVO, seckillTime);
+    }
+
+    @Test
+    public void testUpdateSeckillTime_notExists() {
+        // 准备参数
+        SeckillTimeUpdateReqVO reqVO = randomPojo(SeckillTimeUpdateReqVO.class);
+
+        // 调用, 并断言异常
+        assertServiceException(() -> seckillTimeService.updateSeckillTime(reqVO), SECKILL_TIME_NOT_EXISTS);
+    }
+
+    @Test
+    public void testDeleteSeckillTime_success() {
+        // mock 数据
+        SeckillTimeDO dbSeckillTime = randomPojo(SeckillTimeDO.class);
+        seckillTimeMapper.insert(dbSeckillTime);// @Sql: 先插入出一条存在的数据
+        // 准备参数
+        Long id = dbSeckillTime.getId();
+
+        // 调用
+        seckillTimeService.deleteSeckillTime(id);
+       // 校验数据不存在了
+       assertNull(seckillTimeMapper.selectById(id));
+    }
+
+    @Test
+    public void testDeleteSeckillTime_notExists() {
+        // 准备参数
+        Long id = randomLongId();
+
+        // 调用, 并断言异常
+        assertServiceException(() -> seckillTimeService.deleteSeckillTime(id), SECKILL_TIME_NOT_EXISTS);
+    }
+
+    @Test
+    @Disabled  // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
+    public void testGetSeckillTimePage() {
+       // mock 数据
+//       SeckillTimeDO dbSeckillTime = randomPojo(SeckillTimeDO.class, o -> { // 等会查询到
+//           o.setName(null);
+//           o.setStartTime(null);
+//           o.setEndTime(null);
+//           o.setCreateTime(null);
+//       });
+//       seckillTimeMapper.insert(dbSeckillTime);
+//       // 测试 name 不匹配
+//       seckillTimeMapper.insert(cloneIgnoreId(dbSeckillTime, o -> o.setName(null)));
+//       // 测试 startTime 不匹配
+//       seckillTimeMapper.insert(cloneIgnoreId(dbSeckillTime, o -> o.setStartTime(null)));
+//       // 测试 endTime 不匹配
+//       seckillTimeMapper.insert(cloneIgnoreId(dbSeckillTime, o -> o.setEndTime(null)));
+//       // 测试 createTime 不匹配
+//       seckillTimeMapper.insert(cloneIgnoreId(dbSeckillTime, o -> o.setCreateTime(null)));
+//       // 准备参数
+//       SeckillTimePageReqVO reqVO = new SeckillTimePageReqVO();
+//       reqVO.setName(null);
+////       reqVO.setStartTime((new LocalTime()));
+////       reqVO.setEndTime((new LocalTime[]{}));
+////       reqVO.setCreateTime((new Date[]{}));
+//
+//       // 调用
+//       PageResult<SeckillTimeDO> pageResult = seckillTimeService.getSeckillTimePage(reqVO);
+//       // 断言
+//       assertEquals(1, pageResult.getTotal());
+//       assertEquals(1, pageResult.getList().size());
+//       assertPojoEquals(dbSeckillTime, pageResult.getList().get(0));
+    }
+
+    @Test
+    @Disabled  // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
+    public void testGetSeckillTimeList() {
+       // mock 数据
+       SeckillTimeDO dbSeckillTime = randomPojo(SeckillTimeDO.class, o -> { // 等会查询到
+           o.setName(null);
+           o.setStartTime(null);
+           o.setEndTime(null);
+           o.setCreateTime(null);
+       });
+       seckillTimeMapper.insert(dbSeckillTime);
+       // 测试 name 不匹配
+       seckillTimeMapper.insert(cloneIgnoreId(dbSeckillTime, o -> o.setName(null)));
+       // 测试 startTime 不匹配
+       seckillTimeMapper.insert(cloneIgnoreId(dbSeckillTime, o -> o.setStartTime(null)));
+       // 测试 endTime 不匹配
+       seckillTimeMapper.insert(cloneIgnoreId(dbSeckillTime, o -> o.setEndTime(null)));
+       // 测试 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));
+    }
+
+}
diff --git a/yudao-ui-admin/src/api/mall/promotion/seckillActivity.js b/yudao-ui-admin/src/api/mall/promotion/seckillActivity.js
new file mode 100644
index 000000000..fa67a739c
--- /dev/null
+++ b/yudao-ui-admin/src/api/mall/promotion/seckillActivity.js
@@ -0,0 +1,52 @@
+import request from '@/utils/request'
+
+// 创建秒杀活动
+export function createSeckillActivity(data) {
+  return request({
+    url: '/promotion/seckill-activity/create',
+    method: 'post',
+    data: data
+  })
+}
+
+// 更新秒杀活动
+export function updateSeckillActivity(data) {
+  return request({
+    url: '/promotion/seckill-activity/update',
+    method: 'put',
+    data: data
+  })
+}
+
+// 关闭限时折扣活动
+export function closeSeckillActivity(id) {
+  return request({
+    url: '/promotion/seckill-activity/close?id=' + id,
+    method: 'put'
+  })
+}
+
+// 删除秒杀活动
+export function deleteSeckillActivity(id) {
+  return request({
+    url: '/promotion/seckill-activity/delete?id=' + id,
+    method: 'delete'
+  })
+}
+
+// 获得秒杀活动
+export function getSeckillActivity(id) {
+  return request({
+    url: '/promotion/seckill-activity/get?id=' + id,
+    method: 'get'
+  })
+}
+
+// 获得秒杀活动分页
+export function getSeckillActivityPage(query) {
+  return request({
+    url: '/promotion/seckill-activity/page',
+    method: 'get',
+    params: query
+  })
+}
diff --git a/yudao-ui-admin/src/api/mall/promotion/seckillTime.js b/yudao-ui-admin/src/api/mall/promotion/seckillTime.js
new file mode 100644
index 000000000..ae3c8a8ca
--- /dev/null
+++ b/yudao-ui-admin/src/api/mall/promotion/seckillTime.js
@@ -0,0 +1,62 @@
+import request from '@/utils/request'
+
+// 创建秒杀时段
+export function createSeckillTime(data) {
+  return request({
+    url: '/promotion/seckill-time/create',
+    method: 'post',
+    data: data
+  })
+}
+
+// 更新秒杀时段
+export function updateSeckillTime(data) {
+  return request({
+    url: '/promotion/seckill-time/update',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除秒杀时段
+export function deleteSeckillTime(id) {
+  return request({
+    url: '/promotion/seckill-time/delete?id=' + id,
+    method: 'delete'
+  })
+}
+
+// 获得秒杀时段
+export function getSeckillTime(id) {
+  return request({
+    url: '/promotion/seckill-time/get?id=' + id,
+    method: 'get'
+  })
+}
+
+// 获得秒杀时段分页
+export function getSeckillTimePage(query) {
+  return request({
+    url: '/promotion/seckill-time/page',
+    method: 'get',
+    params: query
+  })
+}
+
+// 获取所有的秒杀时段
+export function getSeckillTimeList() {
+  return request({
+    url: '/promotion/seckill-time/list',
+    method: 'get'
+  })
+}
+
+// 导出秒杀时段 Excel
+export function exportSeckillTimeExcel(query) {
+  return request({
+    url: '/promotion/seckill-time/export-excel',
+    method: 'get',
+    params: query,
+    responseType: 'blob'
+  })
+}
diff --git a/yudao-ui-admin/src/views/mall/promotion/seckill/seckillActivity/index.vue b/yudao-ui-admin/src/views/mall/promotion/seckill/seckillActivity/index.vue
new file mode 100644
index 000000000..3805def34
--- /dev/null
+++ b/yudao-ui-admin/src/views/mall/promotion/seckill/seckillActivity/index.vue
@@ -0,0 +1,490 @@
+<template>
+    <div class="app-container">
+
+        <!-- 搜索工作栏 -->
+        <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch"
+            label-width="68px">
+            <el-form-item label="活动名称" prop="name">
+                <el-input v-model="queryParams.name" placeholder="请输入秒杀活动名称" clearable
+                    @keyup.enter.native="handleQuery" />
+            </el-form-item>
+            <el-form-item label="活动状态" prop="status">
+                <el-select v-model="queryParams.status" placeholder="请选择活动状态" clearable size="small">
+                    <el-option v-for="dict in this.getDictDatas(DICT_TYPE.PROMOTION_ACTIVITY_STATUS)" :key="dict.value"
+                        :label="dict.label" :value="dict.value" />
+                </el-select>
+            </el-form-item>
+            <el-form-item label="参与场次" prop="timeId">
+                <el-select v-model="queryParams.timeId" placeholder="请选择参与场次" clearable size="small">
+                    <el-option v-for="item in seckillTimeList" :key="item.id" :label="item.name" :value="item.id" />
+                </el-select>
+            </el-form-item>
+            <el-form-item label="创建时间" prop="createTime">
+                <el-date-picker v-model="queryParams.createTime" style="width: 240px" value-format="yyyy-MM-dd HH:mm:ss"
+                    type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"
+                    :default-time="['00:00:00', '23:59:59']" />
+            </el-form-item>
+            <el-form-item>
+                <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
+                <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
+            </el-form-item>
+        </el-form>
+
+        <!-- 操作工具栏 -->
+        <el-row :gutter="10" class="mb8">
+            <el-col :span="1.5">
+                <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
+                    v-hasPermi="['promotion:seckill-activity:create']">新增秒杀活动</el-button>
+            </el-col>
+            <el-col :span="1.5">
+                <el-button type="primary" plain icon="el-icon-menu" size="mini" @click="openSeckillTime"
+                    v-hasPermi="['promotion:seckill-activity:create']">管理参与场次</el-button>
+            </el-col>
+            <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+        </el-row>
+
+        <!-- 列表 -->
+        <el-table v-loading="loading" :data="list">
+            <el-table-column label="活动名称" align="center" prop="name" />
+            <el-table-column label="活动状态" align="center" prop="status">
+                <template slot-scope="scope">
+                    <dict-tag :type="DICT_TYPE.PROMOTION_ACTIVITY_STATUS" :value="scope.row.status" />
+                </template>
+            </el-table-column>
+            <el-table-column label="参与场次" prop="timeId" width="250">
+                <template slot-scope="scope">
+                    <span v-for="item in seckillTimeList" :key="item.id"
+                        v-if="scope.row.timeId.indexOf(item.id) !== -1">
+                        <el-tag style="margin:4px;" size="small">{{ item.name }}</el-tag>
+                    </span>
+                </template>
+            </el-table-column>
+            <el-table-column label="活动开始时间" align="center" prop="startTime" width="190">
+                <template slot-scope="scope">
+                    <span>{{ "开始: " + parseTime(scope.row.startTime) }}</span>
+                    <span>{{ "结束: " + parseTime(scope.row.endTime) }}</span>
+                </template>
+            </el-table-column>
+
+            <el-table-column label="付款订单数" align="center" prop="orderCount" />
+            <el-table-column label="付款人数" align="center" prop="userCount" />
+            <el-table-column label="创建时间" align="center" prop="createTime" width="180">
+                <template slot-scope="scope">
+                    <span>{{ parseTime(scope.row.createTime) }}</span>
+                </template>
+            </el-table-column>
+            <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+                <template slot-scope="scope">
+                    <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
+                        v-hasPermi="['promotion:seckill-activity:update']">修改</el-button>
+                    <el-button size="mini" type="text" icon="el-icon-close" @click="handleClose(scope.row)"
+                        v-hasPermi="['promotion:seckill-activity:delete']">关闭</el-button>
+                    <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
+                        v-hasPermi="['promotion:seckill-activity:delete']">删除</el-button>
+                </template>
+            </el-table-column>
+        </el-table>
+        <!-- 分页组件 -->
+        <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
+            @pagination="getList" />
+
+        <!-- 对话框(添加 / 修改) -->
+        <el-dialog :title="title" :visible.sync="open" width="1200px" v-dialogDrag append-to-body>
+            <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+                <el-form-item label="活动名称" prop="name">
+                    <el-input v-model="form.name" placeholder="请输入秒杀活动名称" />
+                </el-form-item>
+                <el-form-item label="活动时间" prop="startAndEndTime">
+                    <el-date-picker clearable v-model="form.startAndEndTime" type="datetimerange"
+                        value-format="timestamp" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期"
+                        style="width: 1080px" />
+                </el-form-item>
+                <el-form-item label="排序" prop="sort">
+                    <el-input-number v-model="form.sort" controls-position="right" :min="0" :max="10000">
+                    </el-input-number>
+                </el-form-item>
+                <el-form-item label="备注" prop="remark">
+                    <el-input type="textarea" v-model="form.remark" placeholder="请输入备注" />
+                </el-form-item>
+                <el-form-item label="场次选择">
+                    <el-select v-model="form.timeId" placeholder="请选择参与场次" clearable size="small" multiple filterable
+                        style="width: 880px">
+                        <el-option v-for="item in seckillTimeList" :key="item.id" :label="item.name" :value="item.id">
+                            <span style="float: left">{{ item.name + ': { ' }} {{ item.startTime }} -- {{ item.endTime +
+                                    ' }'
+                            }}</span>
+                            <span style="float: right; color: #8492a6; font-size: 13px"></span>
+                        </el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="商品选择">
+                    <el-select v-model="form.skuIds" placeholder="请选择活动商品" clearable size="small" multiple filterable
+                        style="width: 880px" @change="changeFormSku">
+                        <el-option v-for="item in productSkus" :key="item.id" :label="item.spuName + ' ' + item.name"
+                            :value="item.id">
+                            <span style="float: left">{{ item.spuName }} &nbsp; {{ item.name }}</span>
+                            <span style="float: right; color: #8492a6; font-size: 13px">¥{{ (item.price /
+                                    100.0).toFixed(2)
+                            }}</span>
+                        </el-option>
+                    </el-select>
+                    <el-row>
+                        <el-button type="primary" size="mini" @click="batchEditProduct('limitBuyCount')">限购</el-button>
+                        <el-button type="primary" size="mini" @click="batchEditProduct('seckillPrice')">秒杀价</el-button>
+                        <el-button type="primary" size="mini" @click="batchEditProduct('seckillStock')">秒杀库存</el-button>
+                    </el-row>
+                    <el-table v-loading="loading" ref="productsTable" :data="form.products">
+                        <el-table-column type="selection" width="55">
+                        </el-table-column>
+                        <el-table-column label="商品名称" align="center" width="200">
+                            <template slot-scope="scope">
+                                {{ scope.row.spuName }} &nbsp; {{ scope.row.name }}
+                            </template>
+                        </el-table-column>
+                        <el-table-column label="商品价格" align="center" prop="price">
+                            <template slot-scope="scope">
+                                ¥{{ (scope.row.price / 100.0).toFixed(2) }}
+                            </template>
+                        </el-table-column>
+                        <el-table-column label="库存" align="center" prop="productStock" />
+                        <el-table-column label="限购(0为不限购)" align="center" width="150">
+                            <template slot-scope="scope">
+                                <el-input-number v-model="scope.row.limitBuyCount" size="mini" :min="0" :max="10000">
+                                </el-input-number>
+                            </template>
+                        </el-table-column>
+                        <el-table-column label="秒杀价(元)" align="center" width="150">
+                            <template slot-scope="scope">
+                                <el-input-number v-model="scope.row.seckillPrice" size="mini" :precision="2" :min="0"
+                                    :max="10000">
+                                </el-input-number>
+                            </template>
+                        </el-table-column>
+                        <el-table-column label="秒杀库存" align="center" width="150" prop="seckillStock">
+                            <template slot-scope="scope">
+                                <el-input-number v-model="scope.row.seckillStock" size="mini" :min="0" :max="10000">
+                                </el-input-number>
+                            </template>
+                        </el-table-column>
+                        <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+                            <template slot-scope="scope">
+                                <el-button size="mini" type="text" icon="el-icon-delete"
+                                    @click="removeFormSku(scope.row.skuId)">删除
+                                </el-button>
+                            </template>
+                        </el-table-column>
+                    </el-table>
+                </el-form-item>
+            </el-form>
+            <div slot="footer" class="dialog-footer">
+                <el-button type="primary" @click="submitForm">确 定</el-button>
+                <el-button @click="cancel">取 消</el-button>
+            </div>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+import { getSkuOptionList } from "@/api/mall/product/sku";
+import { createSeckillActivity, updateSeckillActivity, closeSeckillActivity,deleteSeckillActivity, getSeckillActivity, getSeckillActivityPage, exportSeckillActivityExcel } from "@/api/mall/promotion/seckillActivity";
+import { getSeckillTimeList } from "@/api/mall/promotion/seckillTime";
+import { deepClone } from "@/utils";
+
+export default {
+    name: "SeckillActivity",
+    components: {
+    },
+    data() {
+        return {
+            // 遮罩层
+            loading: true,
+            // 显示搜索条件
+            showSearch: true,
+            // 总条数
+            total: 0,
+            // 秒杀活动列表
+            list: [],
+            // 秒杀场次列表
+            seckillTimeList: [],
+            // 弹出层标题
+            title: "",
+            // 是否显示弹出层
+            open: false,
+            // 查询参数
+            queryParams: {
+                pageNo: 1,
+                pageSize: 10,
+                name: null,
+                status: null,
+                timeId: null,
+                createTime: [],
+            },
+            // 表单参数
+            form: {
+                skuIds: [], // 选中的 SKU
+                products: [], // 商品信息
+                timeId: [], //选中的秒杀场次id
+            },
+            // 商品 SKU 列表
+            productSkus: [],
+            // 表单校验
+            rules: {
+                name: [{ required: true, message: "秒杀活动名称不能为空", trigger: "blur" }],
+                status: [{ required: true, message: "活动状态不能为空", trigger: "blur" }],
+                startAndEndTime: [{ required: true, message: "活动时间不能为空", trigger: "blur" }],
+                sort: [{ required: true, message: "排序不能为空", trigger: "blur" }],
+                timeId: [{ required: true, message: "秒杀场次不能为空", trigger: "blur" }],
+                totalPrice: [{ required: true, message: "订单实付金额,单位:分不能为空", trigger: "blur" }],
+            }
+        };
+    },
+    created() {
+        this.getList();
+    },
+    watch:{
+        $route: 'getList'
+    },
+    methods: {
+        /** 查询列表 */
+        getList() {
+            const timeId = this.$route.params && this.$route.params.timeId;
+            if (timeId) {
+                this.queryParams.timeId = timeId
+            }
+            this.loading = true;
+            // 执行查询
+            getSeckillActivityPage(this.queryParams).then(response => {
+                this.list = response.data.list;
+                this.total = response.data.total;
+                this.loading = false;
+            });
+            if (timeId) {
+                this.$route.params.timeId = undefined
+            }
+            // 获得 SKU 商品列表
+            getSkuOptionList().then(response => {
+                this.productSkus = response.data;
+            });
+            // 获取参与场次列表
+            getSeckillTimeList().then(response => {
+                this.seckillTimeList = response.data;
+            });
+        },
+        /** 取消按钮 */
+        cancel() {
+            this.open = false;
+            this.reset();
+        },
+        /** 表单重置 */
+        reset() {
+            this.form = {
+                id: undefined,
+                name: undefined,
+                status: undefined,
+                remark: undefined,
+                startTime: undefined,
+                endTime: undefined,
+                sort: undefined,
+                timeId: [],
+                totalPrice: undefined,
+                skuIds: [],
+                products: [],
+            };
+            this.resetForm("form");
+        },
+        /** 搜索按钮操作 */
+        handleQuery() {
+            this.queryParams.pageNo = 1;
+            this.getList();
+        },
+        /** 重置按钮操作 */
+        resetQuery() {
+            this.resetForm("queryForm");
+            this.handleQuery();
+        },
+        /**打开秒杀场次管理页面 */
+        openSeckillTime() {
+            this.$tab.openPage("秒杀场次管理", "/promotion/seckill-time");
+        },
+        /** 新增按钮操作 */
+        handleAdd() {
+            this.reset();
+            this.open = true;
+            this.title = "添加秒杀活动";
+        },
+        /** 修改按钮操作 */
+        handleUpdate(row) {
+            this.reset();
+            const id = row.id;
+            getSeckillActivity(id).then(response => {
+                var timeIdList = response.data.timeId.split(',')
+                this.form = response.data;
+                // 修改数据
+                this.form.startAndEndTime = [response.data.startTime, response.data.endTime];
+                this.form.timeId = timeIdList.map(item => parseInt(item))
+                this.form.skuIds = response.data.products.map(item => item.skuId);
+                this.form.products.forEach(product => {
+                    // 获得对应的 SKU 信息
+                    const sku = this.productSkus.find(item => item.id === product.skuId);
+                    if (!sku) {
+                        return;
+                    }
+                    // 设置商品信息
+                    product.name = sku.name;
+                    product.spuName = sku.spuName;
+                    product.price = sku.price;
+                    product.productStock = sku.stock;
+                    this.$set(product,'seckillStock',product.stock);
+                    product.seckillPrice = product.seckillPrice !== undefined ? product.seckillPrice / 100 : undefined;
+
+                });
+                // 打开弹窗
+                this.open = true;
+                this.title = "修改限时折扣活动";
+            })
+        },
+        /** 提交按钮 */
+        submitForm() {
+            this.$refs["form"].validate(valid => {
+                if (!valid) {
+                    return;
+                }
+                // 处理数据
+                const data = deepClone(this.form);
+                data.startTime = this.form.startAndEndTime[0];
+                data.endTime = this.form.startAndEndTime[1];
+                data.timeId = data.timeId.toString();
+                data.products.forEach(product => {
+                    product.stock = product.seckillStock;
+                    product.seckillPrice = product.seckillPrice !== undefined ? product.seckillPrice * 100 : undefined;
+                });
+                // 修改的提交
+                if (this.form.id != null) {
+                    updateSeckillActivity(data).then(response => {
+                        this.$modal.msgSuccess("修改成功");
+                        this.open = false;
+                        this.getList();
+                    });
+                    return;
+                }
+                // 添加的提交
+                createSeckillActivity(data).then(response => {
+                    this.$modal.msgSuccess("新增成功");
+                    this.open = false;
+                    this.getList();
+                });
+            });
+        },
+        /** 关闭按钮操作 */
+        handleClose(row) {
+            const id = row.id;
+            this.$modal.confirm('是否确认关闭秒杀活动编号为"' + id + '"的数据项?').then(function () {
+                return closeSeckillActivity(id);
+            }).then(() => {
+                this.getList();
+                this.$modal.msgSuccess("关闭成功");
+            }).catch(() => { });
+        },
+        /** 删除按钮操作 */
+        handleDelete(row) {
+            const id = row.id;
+            this.$modal.confirm('是否确认删除秒杀活动编号为"' + id + '"的数据项?').then(function () {
+                return deleteSeckillActivity(id);
+            }).then(() => {
+                this.getList();
+                this.$modal.msgSuccess("删除成功");
+            }).catch(() => { });
+        },
+        /** 批量修改商品秒杀价,秒杀库存,每人限购数量 */
+        batchEditProduct(editType) {
+            const selectProducts = this.$refs.productsTable.selection;
+            if (selectProducts.length === 0) {
+                this.$modal.msgError("请选择需要修改的商品");
+                return;
+            }
+            let promptTitle = '请输入';
+            let regularPattern = /^[\s\S]*.*[^\s][\s\S]*$/; // 判断非空,且非空格
+            //限购数
+            if (editType === 'limitBuyCount') {
+                promptTitle = '限购数';
+                regularPattern = /^[0-9]*$/; //数字
+            }
+            //秒杀价
+            if (editType === 'seckillPrice') {
+                promptTitle = '秒杀价(元)';
+                regularPattern = /^[0-9]+(\.[0-9]{1,2})?$/; // 有一位或两位小数的正数
+            }
+            //秒杀库存
+            if (editType === 'seckillStock') {
+                promptTitle = '秒杀库存';
+                regularPattern = /^[0-9]*$/; //数字
+            }
+
+            this.$prompt(promptTitle, '提示', {
+                confirmButtonText: '保存',
+                cancelButtonText: '取消',
+                inputPattern: regularPattern,
+                inputErrorMessage: promptTitle + '格式不正确'
+            }).then(({ value }) => {
+                if (editType === 'limitBuyCount') {
+                    selectProducts.forEach((item) => {
+                        item.limitBuyCount = value;
+                    })
+                }
+                if (editType === 'seckillPrice') {
+                    selectProducts.forEach((item) => {
+                        item.seckillPrice = value;
+                    })
+                }
+                if (editType === 'seckillStock') {
+                    selectProducts.forEach((item) => {
+                        item.seckillStock = value;
+                    })
+                }
+            }).catch();
+        },
+        /** 当 Form 的 SKU 发生变化时 */
+        changeFormSku(skuIds) {
+            // 处理【新增】
+            skuIds.forEach(skuId => {
+                // 获得对应的 SKU 信息
+                const sku = this.productSkus.find(item => item.id === skuId);
+                if (!sku) {
+                    return;
+                }
+                // 判断已存在,直接跳过
+                const product = this.form.products.find(item => item.skuId === skuId);
+                if (product) {
+                    return;
+                }
+                this.form.products.push({
+                    skuId: sku.id,
+                    name: sku.name,
+                    price: sku.price,
+                    productStock: sku.stock,
+                    spuId: sku.spuId,
+                    spuName: sku.spuName,
+                    limitBuyCount: 1,
+                    seckillStock: sku.stock,
+                    seckillPrice: sku.price,
+                });
+            });
+            // 处理【移除】
+            this.form.products.map((product, index) => {
+                if (!skuIds.includes(product.skuId)) {
+                    this.form.products.splice(index, 1);
+                }
+            });
+        },
+        /** 移除 Form 的 SKU */
+        removeFormSku(skuId) {
+            this.form.skuIds.map((id, index) => {
+                if (skuId === id) {
+                    this.form.skuIds.splice(index, 1);
+                }
+            });
+            this.changeFormSku(this.form.skuIds);
+        },
+    }
+};
+</script>
diff --git a/yudao-ui-admin/src/views/mall/promotion/seckill/seckillTime/index.vue b/yudao-ui-admin/src/views/mall/promotion/seckill/seckillTime/index.vue
new file mode 100644
index 000000000..aa7df7200
--- /dev/null
+++ b/yudao-ui-admin/src/views/mall/promotion/seckill/seckillTime/index.vue
@@ -0,0 +1,197 @@
+<template>
+  <div class="app-container">
+
+    <!-- 操作工具栏 -->
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
+          v-hasPermi="['promotion:seckill-time:create']">新增秒杀时段</el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <!-- 列表 -->
+    <el-table v-loading="loading" :data="list">
+      <el-table-column label="秒杀时段名称" align="center" prop="name" />
+      <el-table-column label="开始时间点" align="center" prop="startTime" width="180">
+        <template slot-scope="scope">
+          <span>{{ scope.row.startTime }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="结束时间点" align="center" prop="endTime" width="180">
+        <template slot-scope="scope">
+          <span>{{ scope.row.endTime }}</span>
+        </template>
+      </el-table-column>
+      <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>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button size="mini" type="text" icon="el-icon-view" @click="handleOpenSeckillActivity(scope.row)">
+            查看秒杀活动</el-button>
+          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
+            v-hasPermi="['promotion:seckill-time:update']">修改</el-button>
+          <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
+            v-hasPermi="['promotion:seckill-time:delete']">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <!-- 对话框(添加 / 修改) -->
+    <el-dialog :title="title" :visible.sync="open" width="600px" v-dialogDrag append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="140px">
+        <el-form-item label="秒杀场次名称" prop="name">
+          <el-input v-model="form.name" placeholder="请输入秒杀时段名称" clearable />
+        </el-form-item>
+        <el-form-item label="秒杀时间段" prop="startAndEndTime">
+          <el-time-picker is-range v-model="form.startAndEndTime" range-separator="至" start-placeholder="开始时间"
+            end-placeholder="结束时间" placeholder="选择时间范围" value-format="HH:mm:ss">
+          </el-time-picker>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { createSeckillTime, updateSeckillTime, deleteSeckillTime, getSeckillTime, getSeckillTimePage, exportSeckillTimeExcel, getSeckillTimeList } from "@/api/mall/promotion/seckillTime";
+import router from "@/router";
+import { deepClone } from "@/utils";
+
+export default {
+  name: "SeckillTime",
+  components: {
+  },
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 导出遮罩层
+      exportLoading: false,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      // total: 0,
+      // 秒杀时段列表
+      list: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        name: [{ required: true, message: "秒杀时段名称不能为空", trigger: "blur" }],
+        startAndEndTime: [{ required: true, message: "秒杀时间段不能为空", trigger: "blur" }],
+      }
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /** 查询列表 */
+    getList() {
+      this.loading = true;
+      // 执行查询
+      getSeckillTimeList().then(response => {
+        this.list = response.data;
+        this.loading = false;
+      });
+    },
+    /** 取消按钮 */
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    /** 表单重置 */
+    reset() {
+      this.form = {
+        id: undefined,
+        name: undefined,
+        startAndEndTime: undefined,
+        startTime: undefined,
+        endTime: undefined,
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    /**查看当前秒杀时段的秒杀活动 */
+    handleOpenSeckillActivity(row) {
+      router.push({ name: 'SeckillActivity', params: { timeId: row.id } })
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加秒杀时段";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id;
+      getSeckillTime(id).then(response => {
+        response.data.startAndEndTime = [response.data.startTime, response.data.endTime]
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改秒杀时段";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        console.log(valid, "是否通过");
+        if (!valid) {
+          return;
+        }
+        // 处理数据
+        const data = deepClone(this.form);
+        data.startTime = this.form.startAndEndTime[0];
+        data.endTime = this.form.startAndEndTime[1];
+        // 修改的提交
+        if (this.form.id != null) {
+          updateSeckillTime(data).then(response => {
+            this.$modal.msgSuccess("修改成功");
+            this.open = false;
+            this.getList();
+          });
+          return;
+        }
+        // 添加的提交
+        createSeckillTime(data).then(response => {
+          this.$modal.msgSuccess("新增成功");
+          this.open = false;
+          this.getList();
+        });
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const id = row.id;
+      this.$modal.confirm('是否确认删除秒杀时段编号为"' + id + '"的数据项?').then(function () {
+        return deleteSeckillTime(id);
+      }).then(() => {
+        this.getList();
+        this.$modal.msgSuccess("删除成功");
+      }).catch(() => { });
+    },
+  }
+};
+</script>