From cd62c4d22094dddb9feb9bf3c9ae845d023c48ef Mon Sep 17 00:00:00 2001 From: halfninety <690534687@qq.com> Date: Sun, 20 Nov 2022 16:53:57 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=92=E6=9D=80=E6=97=B6=E6=AE=B5=E7=9B=B8?= =?UTF-8?q?=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../framework/common/util/date/DateUtils.java | 2 + .../databind/LocalTimeDeserializable.java | 16 ++ .../core/databind/LocalTimeSerializable.java | 17 ++ .../promotion/enums/ErrorCodeConstants.java | 2 +- .../seckilltime/SeckillTimeController.java | 99 +++++++ .../seckilltime/vo/SeckillTimeBaseVO.java | 32 +++ .../vo/SeckillTimeCreateReqVO.java | 14 + .../seckilltime/vo/SeckillTimeExcelVO.java | 37 +++ .../vo/SeckillTimeExportReqVO.java | 30 +++ .../seckilltime/vo/SeckillTimePageReqVO.java | 40 +++ .../seckilltime/vo/SeckillTimeRespVO.java | 22 ++ .../vo/SeckillTimeSimpleRespVO.java | 4 + .../vo/SeckillTimeUpdateReqVO.java | 21 ++ .../seckilltime/SeckillTimeConvert.java | 33 +++ .../dataobject/seckilltime/SeckillTimeDO.java | 47 ++++ .../mysql/seckilltime/SeckillTimeMapper.java | 40 +++ .../seckilltime/SeckillTimeService.java | 69 +++++ .../seckilltime/SeckillTimeServiceImpl.java | 82 ++++++ .../mapper/seckilltime/SeckillTimeMapper.xml | 12 + .../SeckillTimeServiceImplTest.java | 196 ++++++++++++++ .../src/api/promotion/seckillTime.js | 62 +++++ .../src/views/promotion/seckillTime/index.vue | 243 ++++++++++++++++++ 22 files changed, 1119 insertions(+), 1 deletion(-) create mode 100644 yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/jackson/core/databind/LocalTimeDeserializable.java create mode 100644 yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/jackson/core/databind/LocalTimeSerializable.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/SeckillTimeController.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/vo/SeckillTimeBaseVO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/vo/SeckillTimeCreateReqVO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/vo/SeckillTimeExcelVO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/vo/SeckillTimeExportReqVO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/vo/SeckillTimePageReqVO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/vo/SeckillTimeRespVO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/vo/SeckillTimeSimpleRespVO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/vo/SeckillTimeUpdateReqVO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckilltime/SeckillTimeConvert.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckilltime/SeckillTimeDO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckilltime/SeckillTimeMapper.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckilltime/SeckillTimeService.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckilltime/SeckillTimeServiceImpl.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/seckilltime/SeckillTimeMapper.xml create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckilltime/SeckillTimeServiceImplTest.java create mode 100644 yudao-ui-admin/src/api/promotion/seckillTime.js create mode 100644 yudao-ui-admin/src/views/promotion/seckillTime/index.vue 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/core/databind/LocalTimeDeserializable.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/jackson/core/databind/LocalTimeDeserializable.java new file mode 100644 index 000000000..9735438b1 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/jackson/core/databind/LocalTimeDeserializable.java @@ -0,0 +1,16 @@ +package cn.iocoder.yudao.framework.jackson.core.databind; + +import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; + +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 LocalTimeDeserializable { + // TODO: 2022/11/15 修改名字 + public static final LocalTimeDeserializer INSTANCE = new LocalTimeDeserializer(DateTimeFormatter + .ofPattern(FORMAT_HOUR_MINUTE_SECOND) + .withZone(ZoneId.systemDefault())); + +} diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/jackson/core/databind/LocalTimeSerializable.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/jackson/core/databind/LocalTimeSerializable.java new file mode 100644 index 000000000..d6eaed819 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/jackson/core/databind/LocalTimeSerializable.java @@ -0,0 +1,17 @@ +package cn.iocoder.yudao.framework.jackson.core.databind; + +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 LocalTimeSerializable { + // TODO: 2022/11/15 修改名称 + + public static final LocalTimeSerializer INSTANCE = new LocalTimeSerializer(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 b6ac66757..4f25810d3 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 @@ -47,5 +47,5 @@ public interface ErrorCodeConstants { // ========== 秒杀活动 1003008000 ========== ErrorCode SECKILL_ACTIVITY_NOT_EXISTS = new ErrorCode(1003008000, "秒杀活动不存在"); - + ErrorCode SECKILL_TIME_NOT_EXISTS = new ErrorCode(1003008001, "秒杀时段不存在"); } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/SeckillTimeController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/SeckillTimeController.java new file mode 100644 index 000000000..1f66fb1c6 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/SeckillTimeController.java @@ -0,0 +1,99 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.seckilltime; + +import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.security.access.prepost.PreAuthorize; +import io.swagger.annotations.*; + +import javax.validation.constraints.*; +import javax.validation.*; +import javax.servlet.http.*; +import java.util.*; +import java.io.IOException; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; + +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*; + +import cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo.*; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckilltime.SeckillTimeDO; +import cn.iocoder.yudao.module.promotion.convert.seckilltime.SeckillTimeConvert; +import cn.iocoder.yudao.module.promotion.service.seckilltime.SeckillTimeService; + +@Api(tags = "管理后台 - 秒杀时段") +@RestController +@RequestMapping("/promotion/seckill-time") +@Validated +public class SeckillTimeController { + + @Resource + private SeckillTimeService seckillTimeService; + + @PostMapping("/create") + @ApiOperation("创建秒杀时段") + @PreAuthorize("@ss.hasPermission('promotion:seckill-time:create')") + public CommonResult createSeckillTime(@Valid @RequestBody SeckillTimeCreateReqVO createReqVO) { + return success(seckillTimeService.createSeckillTime(createReqVO)); + } + + @PutMapping("/update") + @ApiOperation("更新秒杀时段") + @PreAuthorize("@ss.hasPermission('promotion:seckill-time:update')") + public CommonResult 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 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 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> getSeckillTimeList() { + List list = seckillTimeService.getSeckillTimeList(); + return success(SeckillTimeConvert.INSTANCE.convertList(list)); + } + +// @GetMapping("/page") +// @ApiOperation("获得秒杀时段分页") +// @PreAuthorize("@ss.hasPermission('promotion:seckill-time:query')") +// public CommonResult> getSeckillTimePage(@Valid SeckillTimePageReqVO pageVO) { +// PageResult pageResult = seckillTimeService.getSeckillTimePage(pageVO); +// return success(SeckillTimeConvert.INSTANCE.convertPage(pageResult)); +// } + + @GetMapping("/export-excel") + @ApiOperation("导出秒杀时段 Excel") + @PreAuthorize("@ss.hasPermission('promotion:seckill-time:export')") + @OperateLog(type = EXPORT) + public void exportSeckillTimeExcel(@Valid SeckillTimeExportReqVO exportReqVO, + HttpServletResponse response) throws IOException { + List list = seckillTimeService.getSeckillTimeList(exportReqVO); + // 导出 Excel + List datas = SeckillTimeConvert.INSTANCE.convertList02(list); + ExcelUtils.write(response, "秒杀时段.xls", "数据", SeckillTimeExcelVO.class, datas); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/vo/SeckillTimeBaseVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/vo/SeckillTimeBaseVO.java new file mode 100644 index 000000000..5d9e3e2b4 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/vo/SeckillTimeBaseVO.java @@ -0,0 +1,32 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.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/seckilltime/vo/SeckillTimeCreateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/vo/SeckillTimeCreateReqVO.java new file mode 100644 index 000000000..f69d5ab8c --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/vo/SeckillTimeCreateReqVO.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo; + +import lombok.*; +import java.util.*; +import io.swagger.annotations.*; +import javax.validation.constraints.*; + +@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/seckilltime/vo/SeckillTimeExcelVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/vo/SeckillTimeExcelVO.java new file mode 100644 index 000000000..4b7f436da --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/vo/SeckillTimeExcelVO.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo; + +import lombok.*; + +import java.time.LocalTime; +import java.util.*; +import io.swagger.annotations.*; + +import com.alibaba.excel.annotation.ExcelProperty; + +/** + * 秒杀时段 Excel VO + * + * @author 芋道源码 + */ +@Data +public class SeckillTimeExcelVO { + + @ExcelProperty("编号") + private Long id; + + @ExcelProperty("秒杀时段名称") + private String name; + + @ExcelProperty("开始时间点") + private LocalTime startTime; + + @ExcelProperty("结束时间点") + private LocalTime endTime; + + @ExcelProperty("商品数量") + private Integer productCount; + + @ExcelProperty("创建时间") + private Date createTime; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/vo/SeckillTimeExportReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/vo/SeckillTimeExportReqVO.java new file mode 100644 index 000000000..f364db21d --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/vo/SeckillTimeExportReqVO.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo; + +import lombok.*; + +import java.time.LocalTime; +import java.util.*; +import io.swagger.annotations.*; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import org.springframework.format.annotation.DateTimeFormat; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@ApiModel(value = "管理后台 - 秒杀时段 Excel 导出 Request VO", description = "参数和 SeckillTimePageReqVO 是一致的") +@Data +public class SeckillTimeExportReqVO { + + @ApiModelProperty(value = "秒杀时段名称") + private String name; + + @ApiModelProperty(value = "开始时间点") + private LocalTime[] startTime; + + @ApiModelProperty(value = "结束时间点") + private LocalTime[] endTime; + + @ApiModelProperty(value = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private Date[] createTime; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/vo/SeckillTimePageReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/vo/SeckillTimePageReqVO.java new file mode 100644 index 000000000..6fe13e0ed --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/vo/SeckillTimePageReqVO.java @@ -0,0 +1,40 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.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/seckilltime/vo/SeckillTimeRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/vo/SeckillTimeRespVO.java new file mode 100644 index 000000000..09c01da55 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/vo/SeckillTimeRespVO.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.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 productCount; + + @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/seckilltime/vo/SeckillTimeSimpleRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/vo/SeckillTimeSimpleRespVO.java new file mode 100644 index 000000000..ae8288a26 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/vo/SeckillTimeSimpleRespVO.java @@ -0,0 +1,4 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.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/seckilltime/vo/SeckillTimeUpdateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/vo/SeckillTimeUpdateReqVO.java new file mode 100644 index 000000000..84a5f0204 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckilltime/vo/SeckillTimeUpdateReqVO.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.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/seckilltime/SeckillTimeConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckilltime/SeckillTimeConvert.java new file mode 100644 index 000000000..a983485e5 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckilltime/SeckillTimeConvert.java @@ -0,0 +1,33 @@ +package cn.iocoder.yudao.module.promotion.convert.seckilltime; + +import java.util.*; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; +import cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo.*; +import cn.iocoder.yudao.module.promotion.dal.dataobject.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 convertList(List list); + + PageResult convertPage(PageResult page); + + List convertList02(List list); +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckilltime/SeckillTimeDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckilltime/SeckillTimeDO.java new file mode 100644 index 000000000..4e06151d5 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckilltime/SeckillTimeDO.java @@ -0,0 +1,47 @@ +package cn.iocoder.yudao.module.promotion.dal.dataobject.seckilltime; + +import lombok.*; + +import java.time.LocalTime; +import java.util.*; +import com.baomidou.mybatisplus.annotation.*; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; + +/** + * 秒杀时段 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 productCount; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckilltime/SeckillTimeMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckilltime/SeckillTimeMapper.java new file mode 100644 index 000000000..d9a902c01 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckilltime/SeckillTimeMapper.java @@ -0,0 +1,40 @@ +package cn.iocoder.yudao.module.promotion.dal.mysql.seckilltime; + +import java.util.*; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckilltime.SeckillTimeDO; +import org.apache.ibatis.annotations.Mapper; +import cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo.*; + +/** + * 秒杀时段 Mapper + * + * @author 芋道源码 + */ +@Mapper +public interface SeckillTimeMapper extends BaseMapperX { + +// default PageResult selectPage(SeckillTimePageReqVO reqVO) { +// return selectPage(reqVO, new LambdaQueryWrapperX() +// .likeIfPresent(SeckillTimeDO::getName, reqVO.getName()) +// .geIfPresent(SeckillTimeDO::getStartTime, reqVO.getStartTime()) +// .leIfPresent(SeckillTimeDO::getEndTime, reqVO.getEndTime()) +//// .betweenIfPresent(SeckillTimeDO::getStartTime, reqVO.getStartTime()) +//// .betweenIfPresent(SeckillTimeDO::getEndTime, reqVO.getEndTime()) +//// .betweenIfPresent(SeckillTimeDO::getCreateTime, reqVO.getCreateTime()) +// .orderByDesc(SeckillTimeDO::getId)); +// } + + default List selectList(SeckillTimeExportReqVO reqVO) { + return selectList(new LambdaQueryWrapperX() + .likeIfPresent(SeckillTimeDO::getName, reqVO.getName()) + .betweenIfPresent(SeckillTimeDO::getStartTime, reqVO.getStartTime()) + .betweenIfPresent(SeckillTimeDO::getEndTime, reqVO.getEndTime()) + .betweenIfPresent(SeckillTimeDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(SeckillTimeDO::getId)); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckilltime/SeckillTimeService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckilltime/SeckillTimeService.java new file mode 100644 index 000000000..5c5011dd0 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckilltime/SeckillTimeService.java @@ -0,0 +1,69 @@ +package cn.iocoder.yudao.module.promotion.service.seckilltime; + +import java.util.*; +import javax.validation.*; +import cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo.*; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckilltime.SeckillTimeDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; + +/** + * 秒杀时段 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 getSeckillTimeList(); + +// /** +// * 获得秒杀时段分页 +// * +// * @param pageReqVO 分页查询 +// * @return 秒杀时段分页 +// */ +// PageResult getSeckillTimePage(SeckillTimePageReqVO pageReqVO); + + /** + * 获得秒杀时段列表, 用于 Excel 导出 + * + * @param exportReqVO 查询条件 + * @return 秒杀时段列表 + */ + List getSeckillTimeList(SeckillTimeExportReqVO exportReqVO); + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckilltime/SeckillTimeServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckilltime/SeckillTimeServiceImpl.java new file mode 100644 index 000000000..de4becc15 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckilltime/SeckillTimeServiceImpl.java @@ -0,0 +1,82 @@ +package cn.iocoder.yudao.module.promotion.service.seckilltime; + +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; + +import java.util.*; +import cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo.*; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckilltime.SeckillTimeDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; + +import cn.iocoder.yudao.module.promotion.convert.seckilltime.SeckillTimeConvert; +import cn.iocoder.yudao.module.promotion.dal.mysql.seckilltime.SeckillTimeMapper; + +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) { + // 插入 + SeckillTimeDO seckillTime = SeckillTimeConvert.INSTANCE.convert(createReqVO); + seckillTimeMapper.insert(seckillTime); + // 返回 + return seckillTime.getId(); + } + + @Override + public void updateSeckillTime(SeckillTimeUpdateReqVO updateReqVO) { + // 校验存在 + this.validateSeckillTimeExists(updateReqVO.getId()); + // 更新 + 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); + } + } + + @Override + public SeckillTimeDO getSeckillTime(Long id) { + return seckillTimeMapper.selectById(id); + } + + @Override + public List getSeckillTimeList() { + return seckillTimeMapper.selectList(); + } + +// @Override +// public PageResult getSeckillTimePage(SeckillTimePageReqVO pageReqVO) { +// return seckillTimeMapper.selectPage(pageReqVO); +// } + + @Override + public List getSeckillTimeList(SeckillTimeExportReqVO exportReqVO) { + return seckillTimeMapper.selectList(exportReqVO); + } + +} 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..eef757f86 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/seckilltime/SeckillTimeMapper.xml @@ -0,0 +1,12 @@ + + + + + + + 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..d5379212d --- /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,196 @@ +package cn.iocoder.yudao.module.promotion.service.seckilltime; + +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 org.springframework.boot.test.mock.mockito.MockBean; + +import javax.annotation.Resource; + +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; + +import cn.iocoder.yudao.module.promotion.controller.admin.seckilltime.vo.*; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckilltime.SeckillTimeDO; +import cn.iocoder.yudao.module.promotion.dal.mysql.seckilltime.SeckillTimeMapper; +import cn.iocoder.yudao.framework.common.pojo.PageResult; + +import javax.annotation.Resource; +import org.springframework.context.annotation.Import; + +import java.time.LocalTime; +import java.util.*; + +import static cn.hutool.core.util.RandomUtil.*; +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 cn.iocoder.yudao.framework.common.util.date.DateUtils.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +/** +* {@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 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 list = seckillTimeService.getSeckillTimeList(reqVO); + // 断言 + assertEquals(1, list.size()); + assertPojoEquals(dbSeckillTime, list.get(0)); + } + +} diff --git a/yudao-ui-admin/src/api/promotion/seckillTime.js b/yudao-ui-admin/src/api/promotion/seckillTime.js new file mode 100644 index 000000000..ae3c8a8ca --- /dev/null +++ b/yudao-ui-admin/src/api/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/promotion/seckillTime/index.vue b/yudao-ui-admin/src/views/promotion/seckillTime/index.vue new file mode 100644 index 000000000..c41dba309 --- /dev/null +++ b/yudao-ui-admin/src/views/promotion/seckillTime/index.vue @@ -0,0 +1,243 @@ + + +