From 7bc1ae5f35e3e095a0950020658772421b701cc8 Mon Sep 17 00:00:00 2001 From: halfninety <690534687@qq.com> Date: Mon, 28 Nov 2022 20:45:54 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=92=E6=9D=80=E6=B4=BB=E5=8A=A8=E5=A2=9E?= =?UTF-8?q?=E5=88=A0=E6=94=B9=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../promotion/enums/ErrorCodeConstants.java | 5 + .../SeckillActivityController.java | 65 ++++---- .../vo/SeckillActivityBaseVO.java | 53 +++++-- .../vo/SeckillActivityCreateReqVO.java | 24 ++- .../vo/SeckillActivityDetailRespVO.java | 21 +++ .../vo/SeckillActivityExcelVO.java | 46 ------ .../vo/SeckillActivityExportReqVO.java | 28 ---- .../vo/SeckillActivityPageReqVO.java | 15 +- .../vo/SeckillActivityRespVO.java | 21 ++- .../vo/SeckillActivityUpdateReqVO.java | 21 ++- .../SeckillActivityConvert.java | 55 ++++++- .../seckillactivity/SeckillActivityDO.java | 18 ++- .../seckillactivity/SeckillProductDO.java | 60 ++++++++ .../SeckillActivityMapper.java | 20 +-- .../seckillactivity/SeckillProductMapper.java | 21 +++ .../SeckillActivityService.java | 17 +- .../SeckillActivityServiceImpl.java | 145 +++++++++++++++--- .../SeckillActivityServiceImplTest.java | 56 ++++--- .../src/api/promotion/seckillActivity.js | 18 +-- 19 files changed, 473 insertions(+), 236 deletions(-) create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckillactivity/vo/SeckillActivityDetailRespVO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckillactivity/vo/SeckillActivityExcelVO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckillactivity/vo/SeckillActivityExportReqVO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckillactivity/SeckillProductDO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckillactivity/SeckillProductMapper.java 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 4f25810d3..5e21b568c 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 @@ -48,4 +48,9 @@ public interface ErrorCodeConstants { // ========== 秒杀活动 1003008000 ========== ErrorCode SECKILL_ACTIVITY_NOT_EXISTS = new ErrorCode(1003008000, "秒杀活动不存在"); ErrorCode SECKILL_TIME_NOT_EXISTS = new ErrorCode(1003008001, "秒杀时段不存在"); + ErrorCode SECKILL_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1003008001, "存在商品参加了其它秒杀活动"); + ErrorCode SECKILL_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1003006002, "秒杀活动已关闭,不能修改"); + ErrorCode SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED = new ErrorCode(1003006003, "秒杀活动未关闭,不能删除"); + ErrorCode SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1003006004, "秒杀活动已关闭,不能重复关闭"); + ErrorCode SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_END = new ErrorCode(1003006004, "秒杀活动已结束,不能关闭"); } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckillactivity/SeckillActivityController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckillactivity/SeckillActivityController.java index 419ae8e61..a6434a501 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckillactivity/SeckillActivityController.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckillactivity/SeckillActivityController.java @@ -1,35 +1,26 @@ package cn.iocoder.yudao.module.promotion.controller.admin.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.seckillactivity.vo.*; +import cn.iocoder.yudao.module.promotion.convert.seckillactivity.SeckillActivityConvert; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckillactivity.SeckillActivityDO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckillactivity.SeckillProductDO; +import cn.iocoder.yudao.module.promotion.service.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 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 javax.validation.Valid; +import java.util.Collection; +import java.util.List; 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.seckillactivity.vo.*; -import cn.iocoder.yudao.module.promotion.dal.dataobject.seckillactivity.SeckillActivityDO; -import cn.iocoder.yudao.module.promotion.convert.seckillactivity.SeckillActivityConvert; -import cn.iocoder.yudao.module.promotion.service.seckillactivity.SeckillActivityService; - @Api(tags = "管理后台 - 秒杀活动") @RestController @RequestMapping("/promotion/seckill-activity") @@ -54,6 +45,15 @@ public class SeckillActivityController { return success(true); } + @PutMapping("/close") + @ApiOperation("关闭秒杀活动") + @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @PreAuthorize("@ss.hasPermission('promotion:seckill-activity:close')") + public CommonResult closeSeckillActivity(@RequestParam("id") Long id) { + seckillActivityService.closeSeckillActivity(id); + return success(true); + } + @DeleteMapping("/delete") @ApiOperation("删除秒杀活动") @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) @@ -67,12 +67,13 @@ public class SeckillActivityController { @ApiOperation("获得秒杀活动") @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) @PreAuthorize("@ss.hasPermission('promotion:seckill-activity:query')") - public CommonResult getSeckillActivity(@RequestParam("id") Long id) { + public CommonResult getSeckillActivity(@RequestParam("id") Long id) { SeckillActivityDO seckillActivity = seckillActivityService.getSeckillActivity(id); if (seckillActivity == null) { return success(null); } - return success(SeckillActivityConvert.INSTANCE.convert(seckillActivity)); + List seckillProducts = seckillActivityService.getSeckillProductListByActivityId(id); + return success(SeckillActivityConvert.INSTANCE.convert(seckillActivity,seckillProducts)); } @GetMapping("/list") @@ -92,16 +93,4 @@ public class SeckillActivityController { return success(SeckillActivityConvert.INSTANCE.convertPage(pageResult)); } - @GetMapping("/export-excel") - @ApiOperation("导出秒杀活动 Excel") - @PreAuthorize("@ss.hasPermission('promotion:seckill-activity:export')") - @OperateLog(type = EXPORT) - public void exportSeckillActivityExcel(@Valid SeckillActivityExportReqVO exportReqVO, - HttpServletResponse response) throws IOException { - List list = seckillActivityService.getSeckillActivityList(exportReqVO); - // 导出 Excel - List datas = SeckillActivityConvert.INSTANCE.convertList02(list); - ExcelUtils.write(response, "秒杀活动.xls", "数据", SeckillActivityExcelVO.class, datas); - } - } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckillactivity/vo/SeckillActivityBaseVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckillactivity/vo/SeckillActivityBaseVO.java index 88f0d2cc7..62ed1fa2d 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckillactivity/vo/SeckillActivityBaseVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckillactivity/vo/SeckillActivityBaseVO.java @@ -1,13 +1,17 @@ package cn.iocoder.yudao.module.promotion.controller.admin.seckillactivity.vo; -import lombok.*; -import java.util.*; -import java.math.BigDecimal; -import io.swagger.annotations.*; -import javax.validation.constraints.*; +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 使用 @@ -20,22 +24,43 @@ public class SeckillActivityBaseVO { @NotNull(message = "秒杀活动名称不能为空") private String name; - @ApiModelProperty(value = "活动状态", required = true, example = "进行中") - @NotNull(message = "活动状态不能为空") - private Integer status; - @ApiModelProperty(value = "活动开始时间", required = true) @NotNull(message = "活动开始时间不能为空") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private Date startTime; + @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) - private Date endTime; + @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) + private LocalDateTime endTime; - @ApiModelProperty(value = "订单实付金额,单位:分", required = true) - @NotNull(message = "订单实付金额,单位:分不能为空") - private BigDecimal totalPrice; + + @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/seckillactivity/vo/SeckillActivityCreateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckillactivity/vo/SeckillActivityCreateReqVO.java index e397bd57c..2cd21af9e 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckillactivity/vo/SeckillActivityCreateReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckillactivity/vo/SeckillActivityCreateReqVO.java @@ -1,9 +1,16 @@ package cn.iocoder.yudao.module.promotion.controller.admin.seckillactivity.vo; -import lombok.*; -import java.util.*; -import io.swagger.annotations.*; -import javax.validation.constraints.*; +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 @@ -19,7 +26,14 @@ public class SeckillActivityCreateReqVO extends SeckillActivityBaseVO { private Integer sort; @ApiModelProperty(value = "秒杀时段id", required = true) - @NotNull(message = "秒杀时段id不能为空") + @NotBlank(message = "参与场次不能为空") private String timeId; + /** + * 商品列表 + */ + @NotEmpty(message = "商品列表不能为空") + @Valid + private List products; + } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckillactivity/vo/SeckillActivityDetailRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckillactivity/vo/SeckillActivityDetailRespVO.java new file mode 100644 index 000000000..97da65df8 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckillactivity/vo/SeckillActivityDetailRespVO.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.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 products; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckillactivity/vo/SeckillActivityExcelVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckillactivity/vo/SeckillActivityExcelVO.java deleted file mode 100644 index ea0d5f49f..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckillactivity/vo/SeckillActivityExcelVO.java +++ /dev/null @@ -1,46 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.seckillactivity.vo; - -import lombok.*; -import java.util.*; -import java.math.BigDecimal; -import io.swagger.annotations.*; - -import com.alibaba.excel.annotation.ExcelProperty; -import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; -import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; - - -/** - * 秒杀活动 Excel VO - * - * @author 芋道源码 - */ -@Data -public class SeckillActivityExcelVO { - - @ExcelProperty("秒杀活动名称") - private String name; - - @ExcelProperty(value = "活动状态", converter = DictConvert.class) - @DictFormat("promotion_activity_status") // TODO 代码优化:建议设置到对应的 XXXDictTypeConstants 枚举类中 - private Integer status; - - @ExcelProperty("活动开始时间") - private Date startTime; - - @ExcelProperty("活动结束时间") - private Date endTime; - - @ExcelProperty("付款订单数") - private Integer orderCount; - - @ExcelProperty("付款人数") - private Integer userCount; - - @ExcelProperty("订单实付金额,单位:分") - private BigDecimal totalPrice; - - @ExcelProperty("创建时间") - private Date createTime; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckillactivity/vo/SeckillActivityExportReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckillactivity/vo/SeckillActivityExportReqVO.java deleted file mode 100644 index e8a5e459b..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckillactivity/vo/SeckillActivityExportReqVO.java +++ /dev/null @@ -1,28 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.seckillactivity.vo; - -import lombok.*; -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 = "参数和 SeckillActivityPageReqVO 是一致的") -@Data -public class SeckillActivityExportReqVO { - - @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) - private Date[] createTime; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckillactivity/vo/SeckillActivityPageReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckillactivity/vo/SeckillActivityPageReqVO.java index ebfb9bb2a..102877d2b 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckillactivity/vo/SeckillActivityPageReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckillactivity/vo/SeckillActivityPageReqVO.java @@ -1,12 +1,18 @@ package cn.iocoder.yudao.module.promotion.controller.admin.seckillactivity.vo; -import lombok.*; -import java.util.*; -import io.swagger.annotations.*; 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 @@ -25,6 +31,7 @@ public class SeckillActivityPageReqVO extends PageParam { @ApiModelProperty(value = "创建时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private Date[] createTime; + @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/seckillactivity/vo/SeckillActivityRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckillactivity/vo/SeckillActivityRespVO.java index 3e75f5c16..91db8565b 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckillactivity/vo/SeckillActivityRespVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckillactivity/vo/SeckillActivityRespVO.java @@ -1,10 +1,12 @@ package cn.iocoder.yudao.module.promotion.controller.admin.seckillactivity.vo; -import lombok.*; -import java.util.*; -import io.swagger.annotations.*; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; -import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; @ApiModel("管理后台 - 秒杀活动 Response VO") @Data @@ -22,9 +24,18 @@ public class SeckillActivityRespVO extends SeckillActivityBaseVO { private Integer userCount; @ApiModelProperty(value = "创建时间", required = true) - private Date createTime; + 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/seckillactivity/vo/SeckillActivityUpdateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckillactivity/vo/SeckillActivityUpdateReqVO.java index f75a5294a..d8471594c 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckillactivity/vo/SeckillActivityUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckillactivity/vo/SeckillActivityUpdateReqVO.java @@ -1,9 +1,15 @@ package cn.iocoder.yudao.module.promotion.controller.admin.seckillactivity.vo; -import lombok.*; -import java.util.*; -import io.swagger.annotations.*; -import javax.validation.constraints.*; +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 @@ -26,4 +32,11 @@ public class SeckillActivityUpdateReqVO extends SeckillActivityBaseVO { @NotNull(message = "秒杀时段id不能为空") private String timeId; + /** + * 商品列表 + */ + @NotEmpty(message = "商品列表不能为空") + @Valid + private List products; + } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckillactivity/SeckillActivityConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckillactivity/SeckillActivityConvert.java index 8e416aef4..90db545c2 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckillactivity/SeckillActivityConvert.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckillactivity/SeckillActivityConvert.java @@ -1,13 +1,16 @@ package cn.iocoder.yudao.module.promotion.convert.seckillactivity; -import java.util.*; - +import cn.hutool.core.util.ObjectUtil; 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.seckillactivity.vo.*; import cn.iocoder.yudao.module.promotion.dal.dataobject.seckillactivity.SeckillActivityDO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckillactivity.SeckillProductDO; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Mappings; +import org.mapstruct.factory.Mappers; + +import java.util.List; /** * 秒杀活动 Convert @@ -19,8 +22,15 @@ 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); @@ -29,6 +39,39 @@ public interface SeckillActivityConvert { PageResult convertPage(PageResult page); - List convertList02(List list); + @Mappings({@Mapping(target = "products",source = "seckillProducts")}) + SeckillActivityDetailRespVO convert(SeckillActivityDO seckillActivity,List 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/dal/dataobject/seckillactivity/SeckillActivityDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckillactivity/SeckillActivityDO.java index 69edb1ff6..2ff3b1b4c 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckillactivity/SeckillActivityDO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckillactivity/SeckillActivityDO.java @@ -1,10 +1,14 @@ package cn.iocoder.yudao.module.promotion.dal.dataobject.seckillactivity; -import lombok.*; -import java.util.*; -import java.math.BigDecimal; -import com.baomidou.mybatisplus.annotation.*; 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 @@ -33,7 +37,7 @@ public class SeckillActivityDO extends BaseDO { /** * 活动状态 * - * 枚举 {@link TODO promotion_activity_status 对应的类} + * 枚举 {@link PromotionActivityStatusEnum 对应的类} */ private Integer status; /** @@ -43,11 +47,11 @@ public class SeckillActivityDO extends BaseDO { /** * 活动开始时间 */ - private Date startTime; + private LocalDateTime startTime; /** * 活动结束时间 */ - private Date endTime; + private LocalDateTime endTime; /** * 排序 */ diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckillactivity/SeckillProductDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckillactivity/SeckillProductDO.java new file mode 100644 index 000000000..e6e8f6a9f --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckillactivity/SeckillProductDO.java @@ -0,0 +1,60 @@ +package cn.iocoder.yudao.module.promotion.dal.dataobject.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/mysql/seckillactivity/SeckillActivityMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckillactivity/SeckillActivityMapper.java index 6b3319361..12cc179b3 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckillactivity/SeckillActivityMapper.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckillactivity/SeckillActivityMapper.java @@ -1,13 +1,11 @@ package cn.iocoder.yudao.module.promotion.dal.mysql.seckillactivity; -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.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.promotion.controller.admin.seckillactivity.vo.SeckillActivityPageReqVO; import cn.iocoder.yudao.module.promotion.dal.dataobject.seckillactivity.SeckillActivityDO; import org.apache.ibatis.annotations.Mapper; -import cn.iocoder.yudao.module.promotion.controller.admin.seckillactivity.vo.*; /** * 秒杀活动 Mapper @@ -16,21 +14,13 @@ import cn.iocoder.yudao.module.promotion.controller.admin.seckillactivity.vo.*; */ @Mapper public interface SeckillActivityMapper extends BaseMapperX { - +// TODO: 2022/11/28 halfninety 秒杀活动通过场次查询使用like会出现问题,查询活动场次编号为1,则活动场次编号为 1,11,......的都会被查出来 default PageResult selectPage(SeckillActivityPageReqVO reqVO) { return selectPage(reqVO, new LambdaQueryWrapperX() .likeIfPresent(SeckillActivityDO::getName, reqVO.getName()) .eqIfPresent(SeckillActivityDO::getStatus, reqVO.getStatus()) - .eqIfPresent(SeckillActivityDO::getTimeId, reqVO.getTimeId()) - .betweenIfPresent(SeckillActivityDO::getCreateTime, reqVO.getCreateTime()) - .orderByDesc(SeckillActivityDO::getId)); - } - - default List selectList(SeckillActivityExportReqVO reqVO) { - return selectList(new LambdaQueryWrapperX() - .likeIfPresent(SeckillActivityDO::getName, reqVO.getName()) - .eqIfPresent(SeckillActivityDO::getStatus, reqVO.getStatus()) - .eqIfPresent(SeckillActivityDO::getTimeId, reqVO.getTimeId()) + .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/seckillactivity/SeckillProductMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckillactivity/SeckillProductMapper.java new file mode 100644 index 000000000..d1d609982 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckillactivity/SeckillProductMapper.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.promotion.dal.mysql.seckillactivity; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckillactivity.SeckillProductDO; +import org.apache.ibatis.annotations.Mapper; + +import java.util.Collection; +import java.util.List; + +@Mapper +public interface SeckillProductMapper extends BaseMapperX { + + default List selectListByActivityId(Long id){ + return selectList(SeckillProductDO::getActivityId,id); + } + + default List selectListBySkuIds(Collection skuIds){ + return selectList(SeckillProductDO::getSkuId,skuIds); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckillactivity/SeckillActivityService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckillactivity/SeckillActivityService.java index 6ff337fe4..1b3060d52 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckillactivity/SeckillActivityService.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckillactivity/SeckillActivityService.java @@ -5,6 +5,7 @@ import javax.validation.*; import cn.iocoder.yudao.module.promotion.controller.admin.seckillactivity.vo.*; import cn.iocoder.yudao.module.promotion.dal.dataobject.seckillactivity.SeckillActivityDO; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckillactivity.SeckillProductDO; /** * 秒杀活动 Service 接口 @@ -28,6 +29,12 @@ public interface SeckillActivityService { */ void updateSeckillActivity(@Valid SeckillActivityUpdateReqVO updateReqVO); + /** + * 关闭秒杀活动 + * @param id 编号 + */ + void closeSeckillActivity(Long id); + /** * 删除秒杀活动 * @@ -60,11 +67,9 @@ public interface SeckillActivityService { PageResult getSeckillActivityPage(SeckillActivityPageReqVO pageReqVO); /** - * 获得秒杀活动列表, 用于 Excel 导出 - * - * @param exportReqVO 查询条件 - * @return 秒杀活动列表 + * 通过活动编号获取活动商品 + * @param id 活动编号 + * @return 活动商品列表 */ - List getSeckillActivityList(SeckillActivityExportReqVO exportReqVO); - + List getSeckillProductListByActivityId(Long id); } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckillactivity/SeckillActivityServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckillactivity/SeckillActivityServiceImpl.java index 9e23e0e29..63c1bd13d 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckillactivity/SeckillActivityServiceImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckillactivity/SeckillActivityServiceImpl.java @@ -1,19 +1,29 @@ package cn.iocoder.yudao.module.promotion.service.seckillactivity; +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.promotion.controller.admin.seckillactivity.vo.SeckillActivityBaseVO; +import cn.iocoder.yudao.module.promotion.controller.admin.seckillactivity.vo.SeckillActivityCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.seckillactivity.vo.SeckillActivityPageReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.seckillactivity.vo.SeckillActivityUpdateReqVO; +import cn.iocoder.yudao.module.promotion.convert.seckillactivity.SeckillActivityConvert; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckillactivity.SeckillActivityDO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckillactivity.SeckillProductDO; +import cn.iocoder.yudao.module.promotion.dal.mysql.seckillactivity.SeckillActivityMapper; +import cn.iocoder.yudao.module.promotion.dal.mysql.seckillactivity.SeckillProductMapper; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; +import cn.iocoder.yudao.module.promotion.util.PromotionUtils; 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.seckillactivity.vo.*; -import cn.iocoder.yudao.module.promotion.dal.dataobject.seckillactivity.SeckillActivityDO; -import cn.iocoder.yudao.framework.common.pojo.PageResult; - -import cn.iocoder.yudao.module.promotion.convert.seckillactivity.SeckillActivityConvert; -import cn.iocoder.yudao.module.promotion.dal.mysql.seckillactivity.SeckillActivityMapper; +import javax.annotation.Resource; +import java.util.Collection; +import java.util.List; 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 实现类 @@ -27,11 +37,24 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { @Resource private SeckillActivityMapper seckillActivityMapper; + @Resource + private SeckillProductMapper seckillProductMapper; + @Override public Long createSeckillActivity(SeckillActivityCreateReqVO createReqVO) { - // 插入 - SeckillActivityDO seckillActivity = SeckillActivityConvert.INSTANCE.convert(createReqVO); +// validateSeckillActivityProductConflicts(null,createReqVO.getProducts()); + List statuses = asList(PromotionActivityStatusEnum.WAIT.getStatus(), PromotionActivityStatusEnum.RUN.getStatus()); + // 校验商品是否冲突 + validateSeckillActivityProductConflicts(null, createReqVO.getProducts()); + // 插入秒杀活动 + SeckillActivityDO seckillActivity = SeckillActivityConvert.INSTANCE.convert(createReqVO) + .setStatus(PromotionUtils.calculateActivityStatus(createReqVO.getStartTime(), createReqVO.getEndTime()));; seckillActivityMapper.insert(seckillActivity); + + // 插入商品 + List productDOS = CollectionUtils.convertList(createReqVO.getProducts(), + product -> SeckillActivityConvert.INSTANCE.convert(product).setActivityId(seckillActivity.getId())); + seckillProductMapper.insertBatch(productDOS); // 返回 return seckillActivity.getId(); } @@ -39,24 +62,110 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { @Override public void updateSeckillActivity(SeckillActivityUpdateReqVO updateReqVO) { // 校验存在 - this.validateSeckillActivityExists(updateReqVO.getId()); - // 更新 - SeckillActivityDO updateObj = SeckillActivityConvert.INSTANCE.convert(updateReqVO); + SeckillActivityDO seckillActivity = this.validateSeckillActivityExists(updateReqVO.getId()); + if (PromotionActivityStatusEnum.CLOSE.getStatus().equals(seckillActivity.getStatus())) { + throw exception(SECKILL_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED); + } + List statuses = asList(PromotionActivityStatusEnum.WAIT.getStatus(), PromotionActivityStatusEnum.RUN.getStatus()); + // 校验商品是否冲突 + validateSeckillActivityProductConflicts(updateReqVO.getId(), updateReqVO.getProducts()); + // 更新活动 + SeckillActivityDO updateObj = SeckillActivityConvert.INSTANCE.convert(updateReqVO) + .setStatus(PromotionUtils.calculateActivityStatus(updateReqVO.getStartTime(), updateReqVO.getEndTime())); seckillActivityMapper.updateById(updateObj); + // 更新商品 + updateSeckillProduct(updateReqVO); + } + + /** + * 更新秒杀商品 + */ + private void updateSeckillProduct(SeckillActivityUpdateReqVO updateReqVO) { + List seckillProductDOS = seckillProductMapper.selectListByActivityId(updateReqVO.getId()); + List products = updateReqVO.getProducts(); + //对后台查出的数据和前台查出的数据进行遍历, + //1.对前台数据进行遍历:如果不存在于后台的sku中需要新增 + //2.对后台数据进行遍历:如果不存在于前台的sku中需要删除 + //计算需要删除的数据 + List deleteIds = CollectionUtils.convertList(seckillProductDOS, SeckillProductDO::getId, + seckillProductDO -> products.stream() + .noneMatch(product -> SeckillActivityConvert.INSTANCE.isEquals(seckillProductDO, product))); + if (CollUtil.isNotEmpty(deleteIds)) { + seckillProductMapper.deleteBatchIds(deleteIds); + } + //计算需要新增的数据 + List 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 商品列表 + */ + public void validateSeckillActivityProductConflicts(Long id, List products) { + if (CollUtil.isEmpty(products)) { + return; + } + List seckillProductDOS = seckillProductMapper + .selectListBySkuIds(CollectionUtils.convertSet(products, SeckillActivityBaseVO.Product::getSkuId)); + if (CollUtil.isEmpty(seckillProductDOS)) { + return; + } + List seckillActivityDOS = seckillActivityMapper + .selectBatchIds(CollectionUtils.convertSet(seckillProductDOS, SeckillProductDO::getActivityId)); + if (id != null) {// 排除自己这个活动 + seckillActivityDOS.removeIf(item -> id.equals(item.getId())); + } + // 排除不满足status的活动 + List 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) { // 校验存在 - this.validateSeckillActivityExists(id); + SeckillActivityDO seckillActivity = this.validateSeckillActivityExists(id); + if (!PromotionActivityStatusEnum.CLOSE.getStatus().equals(seckillActivity.getStatus())) { + throw exception(SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED); + } // 删除 seckillActivityMapper.deleteById(id); } - private void validateSeckillActivityExists(Long id) { - if (seckillActivityMapper.selectById(id) == null) { + private SeckillActivityDO validateSeckillActivityExists(Long id) { + SeckillActivityDO seckillActivity = seckillActivityMapper.selectById(id); + if (seckillActivity == null) { throw exception(SECKILL_ACTIVITY_NOT_EXISTS); } + return seckillActivity; } @Override @@ -75,8 +184,8 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { } @Override - public List getSeckillActivityList(SeckillActivityExportReqVO exportReqVO) { - return seckillActivityMapper.selectList(exportReqVO); + public List getSeckillProductListByActivityId(Long id) { + return seckillProductMapper.selectListByActivityId(id); } } 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 index b95c8a0e4..2492fb0ac 100644 --- 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 @@ -1,30 +1,26 @@ package cn.iocoder.yudao.module.promotion.service.seckillactivity; -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.common.pojo.PageResult; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; - -import cn.iocoder.yudao.module.promotion.controller.admin.seckillactivity.vo.*; +import cn.iocoder.yudao.module.promotion.controller.admin.seckillactivity.vo.SeckillActivityCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.seckillactivity.vo.SeckillActivityPageReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.seckillactivity.vo.SeckillActivityUpdateReqVO; import cn.iocoder.yudao.module.promotion.dal.dataobject.seckillactivity.SeckillActivityDO; import cn.iocoder.yudao.module.promotion.dal.mysql.seckillactivity.SeckillActivityMapper; -import cn.iocoder.yudao.framework.common.pojo.PageResult; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.springframework.context.annotation.Import; import javax.annotation.Resource; -import org.springframework.context.annotation.Import; -import java.util.*; +import java.time.LocalDateTime; -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 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.*; -import static org.mockito.Mockito.*; /** * {@link SeckillActivityServiceImpl} 的单元测试类 @@ -127,7 +123,7 @@ public class SeckillActivityServiceImplTest extends BaseDbUnitTest { reqVO.setName(null); reqVO.setStatus(null); reqVO.setTimeId(null); - reqVO.setCreateTime((new Date[]{})); + reqVO.setCreateTime((new LocalDateTime[]{})); // 调用 PageResult pageResult = seckillActivityService.getSeckillActivityPage(reqVO); @@ -157,17 +153,17 @@ public class SeckillActivityServiceImplTest extends BaseDbUnitTest { // 测试 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 list = seckillActivityService.getSeckillActivityList(reqVO); - // 断言 - assertEquals(1, list.size()); - assertPojoEquals(dbSeckillActivity, list.get(0)); +// SeckillActivityExportReqVO reqVO = new SeckillActivityExportReqVO(); +// reqVO.setName(null); +// reqVO.setStatus(null); +// reqVO.setTimeId(null); +// reqVO.setCreateTime((new Date[]{})); +// +// // 调用 +// List list = seckillActivityService.getSeckillActivityList(reqVO); +// // 断言 +// assertEquals(1, list.size()); +// assertPojoEquals(dbSeckillActivity, list.get(0)); } } diff --git a/yudao-ui-admin/src/api/promotion/seckillActivity.js b/yudao-ui-admin/src/api/promotion/seckillActivity.js index 9b74081c0..fa67a739c 100644 --- a/yudao-ui-admin/src/api/promotion/seckillActivity.js +++ b/yudao-ui-admin/src/api/promotion/seckillActivity.js @@ -18,6 +18,14 @@ export function updateSeckillActivity(data) { }) } +// 关闭限时折扣活动 +export function closeSeckillActivity(id) { + return request({ + url: '/promotion/seckill-activity/close?id=' + id, + method: 'put' + }) +} + // 删除秒杀活动 export function deleteSeckillActivity(id) { return request({ @@ -42,13 +50,3 @@ export function getSeckillActivityPage(query) { params: query }) } - -// 导出秒杀活动 Excel -export function exportSeckillActivityExcel(query) { - return request({ - url: '/promotion/seckill-activity/export-excel', - method: 'get', - params: query, - responseType: 'blob' - }) -}