!522 mall seckill

Merge pull request !522 from puhui999/feature/mall_product
This commit is contained in:
芋道源码
2023-06-23 06:04:47 +00:00
committed by Gitee
111 changed files with 1960 additions and 1506 deletions

View File

@@ -0,0 +1,99 @@
package cn.iocoder.yudao.module.promotion.controller.admin.seckill;
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.vo.config.*;
import cn.iocoder.yudao.module.promotion.convert.seckill.seckillconfig.SeckillConfigConvert;
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO;
import cn.iocoder.yudao.module.promotion.service.seckill.seckillconfig.SeckillConfigService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
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;
/**
* 管理后台 - 秒杀时段相关接口
*
* @author HUIHUI
*/
@Tag(name = "管理后台 - 秒杀时段")
@RestController
@RequestMapping("/promotion/seckill-config")
@Validated
public class SeckillConfigController {
@Resource
private SeckillConfigService seckillConfigService;
@PostMapping("/create")
@Operation(summary = "创建秒杀时段")
@PreAuthorize("@ss.hasPermission('promotion:seckill-config:create')")
public CommonResult<Long> createSeckillConfig(@Valid @RequestBody SeckillConfigCreateReqVO createReqVO) {
return success(seckillConfigService.createSeckillConfig(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新秒杀时段")
@PreAuthorize("@ss.hasPermission('promotion:seckill-config:update')")
public CommonResult<Boolean> updateSeckillConfig(@Valid @RequestBody SeckillConfigUpdateReqVO updateReqVO) {
seckillConfigService.updateSeckillConfig(updateReqVO);
return success(true);
}
@PutMapping("/update-status")
@Operation(summary = "修改时段配置状态")
@PreAuthorize("@ss.hasPermission('system:seckill-config:update')")
public CommonResult<Boolean> updateSeckillConfigStatus(@Valid @RequestBody SeckillConfigUpdateStatusReqVo reqVO) {
seckillConfigService.updateSeckillConfigStatus(reqVO.getId(), reqVO.getStatus());
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除秒杀时段")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('promotion:seckill-config:delete')")
public CommonResult<Boolean> deleteSeckillConfig(@RequestParam("id") Long id) {
seckillConfigService.deleteSeckillConfig(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得秒杀时段")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('promotion:seckill-config:query')")
public CommonResult<SeckillConfigRespVO> getSeckillConfig(@RequestParam("id") Long id) {
SeckillConfigDO seckillConfig = seckillConfigService.getSeckillConfig(id);
return success(SeckillConfigConvert.INSTANCE.convert(seckillConfig));
}
@GetMapping("/list")
@Operation(summary = "获得所有秒杀时段列表")
@PreAuthorize("@ss.hasPermission('promotion:seckill-config:query')")
public CommonResult<List<SeckillConfigRespVO>> getSeckillConfigList() {
List<SeckillConfigDO> list = seckillConfigService.getSeckillConfigList();
return success(SeckillConfigConvert.INSTANCE.convertList(list));
}
@GetMapping("/list-all-simple")
@Operation(summary = "获得所有开启状态的秒杀时段精简列表", description = "主要用于前端的下拉选项")
public CommonResult<List<SeckillConfigSimpleRespVO>> getListAllSimple() {
List<SeckillConfigDO> list = seckillConfigService.getListAllSimple();
return success(SeckillConfigConvert.INSTANCE.convertList1(list));
}
@GetMapping("/page")
@Operation(summary = "获得秒杀活动分页")
@PreAuthorize("@ss.hasPermission('promotion:seckill-config:query')")
public CommonResult<PageResult<SeckillConfigRespVO>> getSeckillActivityPage(@Valid SeckillConfigPageReqVO pageVO) {
PageResult<SeckillConfigDO> pageResult = seckillConfigService.getSeckillConfigPage(pageVO);
return success(SeckillConfigConvert.INSTANCE.convertPage(pageResult));
}
}

View File

@@ -1,72 +0,0 @@
package cn.iocoder.yudao.module.promotion.controller.admin.seckill;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeCreateReqVO;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeRespVO;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.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.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
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;
@Tag(name = "管理后台 - 秒杀时段")
@RestController
@RequestMapping("/promotion/seckill-time")
@Validated
public class SeckillTimeController {
@Resource
private SeckillTimeService seckillTimeService;
@PostMapping("/create")
@Operation(summary = "创建秒杀时段")
@PreAuthorize("@ss.hasPermission('promotion:seckill-time:create')")
public CommonResult<Long> createSeckillTime(@Valid @RequestBody SeckillTimeCreateReqVO createReqVO) {
return success(seckillTimeService.createSeckillTime(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新秒杀时段")
@PreAuthorize("@ss.hasPermission('promotion:seckill-time:update')")
public CommonResult<Boolean> updateSeckillTime(@Valid @RequestBody SeckillTimeUpdateReqVO updateReqVO) {
seckillTimeService.updateSeckillTime(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除秒杀时段")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('promotion:seckill-time:delete')")
public CommonResult<Boolean> deleteSeckillTime(@RequestParam("id") Long id) {
seckillTimeService.deleteSeckillTime(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得秒杀时段")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@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")
@Operation(summary = "获得所有秒杀时段列表")
@PreAuthorize("@ss.hasPermission('promotion:seckill-time:query')")
public CommonResult<List<SeckillTimeRespVO>> getSeckillTimeList() {
List<SeckillTimeDO> list = seckillTimeService.getSeckillTimeList();
return success(SeckillTimeConvert.INSTANCE.convertList(list));
}
}

View File

@@ -1,65 +1,61 @@
package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import java.util.List;
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 文档生成
*
* @author HUIHUI
*/
@Data
public class SeckillActivityBaseVO {
@Schema(description = "秒杀活动名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "晚九点限时秒杀")
@Schema(description = "秒杀活动商品id", requiredMode = Schema.RequiredMode.REQUIRED, example = "[121,1212]")
@NotNull(message = "秒杀活动商品不能为空")
private List<Long> spuIds;
@Schema(description = "秒杀活动名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "618大促")
@NotNull(message = "秒杀活动名称不能为空")
private String name;
@Schema(description = "备注", example = "清仓大甩卖割韭菜")
private String remark;
@Schema(description = "活动开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
@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;
@Schema(description = "活动结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
@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;
@Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "排序不能为空")
private Integer sort;
@Schema(description = "商品")
@Data
public static class Product {
@Schema(description = "秒杀时段id", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1,2,3]")
@NotNull(message = "秒杀时段不能为空")
private List<Long> configIds;
@Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "商品 SPU 编号不能为空")
private Long spuId;
@Schema(description = "总限购数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "12877")
private Integer totalLimitCount;
@Schema(description = "商品 SKU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "商品 SKU 编号不能为空")
private Long skuId;
@Schema(description = "单次限够数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "31683")
private Integer singleLimitCount;
@Schema(description = "秒杀金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "12.00")
@NotNull(message = "秒杀金额不能为空")
private Integer seckillPrice;
@Schema(description = "秒杀库存", example = "80")
@Min(value = 0, message = "秒杀库存需要大于等于 0")
private Integer stock;
@Schema(description = "每人限购", example = "10") // 如果为 0 则不限购
@Min(value = 0, message = "每人限购需要大于等于 0")
private Integer limitCount;
}
@Schema(description = "秒杀总库存", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
private Integer totalStock;
}

View File

@@ -1,37 +1,26 @@
package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductCreateReqVO;
import io.swagger.v3.oas.annotations.media.Schema;
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;
/**
* 管理后台 - 秒杀活动创建 Request VO
*
* @author HUIHUI
*/
@Schema(description = "管理后台 - 秒杀活动创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class SeckillActivityCreateReqVO extends SeckillActivityBaseVO {
@Schema(description = "备注", example = "限时秒杀活动")
private String remark;
@Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "排序不能为空")
private Integer sort;
@Schema(description = "秒杀时段id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1,3")
@NotEmpty(message = "参与场次不能为空")
private List<Long> timeIds;
/**
* 商品列表
*/
@NotEmpty(message = "商品列表不能为空")
@Valid
private List<Product> products;
@Schema(description = "秒杀商品", requiredMode = Schema.RequiredMode.REQUIRED)
private List<SeckillProductCreateReqVO> products;
}

View File

@@ -1,21 +1,26 @@
package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductRespVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.List;
/**
* 管理后台 - 秒杀活动的详细 Response VO
*
* @author HUIHUI
*/
@Schema(description = "管理后台 - 秒杀活动的详细 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class SeckillActivityDetailRespVO extends SeckillActivityRespVO {
public class SeckillActivityDetailRespVO extends SeckillActivityBaseVO{
/**
* 商品列表
*/
private List<Product> products;
@Schema(description = "秒杀活动id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long id;
@Schema(description = "秒杀商品", requiredMode = Schema.RequiredMode.REQUIRED)
private List<SeckillProductRespVO> products;
}

View File

@@ -26,7 +26,7 @@ public class SeckillActivityPageReqVO extends PageParam {
private Integer status;
@Schema(description = "秒杀时段id", example = "1")
private Long timeId;
private Long configId;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)

View File

@@ -1,13 +1,18 @@
package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductRespVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.time.LocalDateTime;
import java.util.List;
/**
* 管理后台 - 秒杀活动 Response VO
*
* @author HUIHUI
*/
@Schema(description = "管理后台 - 秒杀活动 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@@ -17,25 +22,11 @@ public class SeckillActivityRespVO extends SeckillActivityBaseVO {
@Schema(description = "秒杀活动id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long id;
@Schema(description = "付款订单数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer orderCount;
@Schema(description = "秒杀商品", requiredMode = Schema.RequiredMode.REQUIRED)
private List<SeckillProductRespVO> products; // TODO puhui: 考虑是否去除
@Schema(description = "付款人数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer userCount;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
@Schema(description = "秒杀时段id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1,3")
private List<Long> timeIds;
@Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer sort;
@Schema(description = "备注", example = "限时秒杀活动")
private String remark;
@Schema(description = "活动状态", example = "进行中")
@Schema(description = "活动状态 开启0 禁用1", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
private Integer status;
}

View File

@@ -1,5 +1,7 @@
package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductRespVO;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductUpdateReqVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -10,32 +12,22 @@ import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* 管理后台 - 秒杀活动更新 Request VO
*
* @author HUIHUI
*/
@Schema(description = "管理后台 - 秒杀活动更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class SeckillActivityUpdateReqVO extends SeckillActivityBaseVO {
@Schema(description = "秒杀活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "224")
@NotNull(message = "秒杀活动编号不能为空")
@Schema(description = "秒杀活动id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long id;
@Schema(description = "备注", example = "限时秒杀活动")
private String remark;
@Schema(description = "秒杀商品", requiredMode = Schema.RequiredMode.REQUIRED)
private List<SeckillProductUpdateReqVO> products;
@Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "排序不能为空")
private Integer sort;
@Schema(description = "秒杀时段id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1,3")
@NotEmpty(message = "秒杀时段id不能为空")
private List<Long> timeIds;
/**
* 商品列表
*/
@NotEmpty(message = "商品列表不能为空")
@Valid
private List<Product> products;
}

View File

@@ -1,28 +1,37 @@
package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time;
package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.time.LocalTime;
/**
* 秒杀时段 Base VO提供给添加修改详细的子 VO 使用
* 如果子 VO 存在差异的字段请不要添加到这里影响 Swagger 文档生成
*
* @author HUIHUI
*/
@Data
public class SeckillTimeBaseVO {
public class SeckillConfigBaseVO {
@Schema(description = "秒杀时段名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "")
@Schema(description = "秒杀时段名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "上场")
@NotNull(message = "秒杀时段名称不能为空")
private String name;
@Schema(description = "开始时间点", requiredMode = Schema.RequiredMode.REQUIRED, example = "16:30:40")
@Schema(description = "开始时间点", requiredMode = Schema.RequiredMode.REQUIRED, example = "09:00:00")
@NotNull(message = "开始时间点不能为空")
private LocalTime startTime;
private String startTime;
@Schema(description = "结束时间点", requiredMode = Schema.RequiredMode.REQUIRED, example = "16:30:40")
@Schema(description = "结束时间点", requiredMode = Schema.RequiredMode.REQUIRED, example = "16:00:00")
@NotNull(message = "结束时间点不能为空")
private LocalTime endTime;
private String endTime;
@Schema(description = "秒杀主图", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn")
@NotNull(message = "秒杀主图不能为空")
private String picUrl;
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
@NotNull(message = "状态不能为空")
private Integer status;
}

View File

@@ -1,14 +1,19 @@
package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time;
package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
/**
* 管理后台 秒杀时段创建 Request VO
*
* @author HUIHUI
*/
@Schema(description = "管理后台 - 秒杀时段创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class SeckillTimeCreateReqVO extends SeckillTimeBaseVO {
public class SeckillConfigCreateReqVO extends SeckillConfigBaseVO {
}

View File

@@ -1,29 +1,26 @@
package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time;
package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalTime;
/**
* 管理后台 - 秒杀时段分页 Request VO
*
* @author HUIHUI
*/
@Schema(description = "管理后台 - 秒杀时段分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class SeckillTimePageReqVO extends PageParam {
public class SeckillConfigPageReqVO extends PageParam {
@Schema(description = "秒杀时段名称", example = "上午场")
private String name;
@Schema(description = "开始时间点", example = "16:30:40")
@DateTimeFormat(pattern = "HH:mm:ss")
private LocalTime startTime;
@Schema(description = "结束时间点", example = "16:30:40")
@DateTimeFormat(pattern = "HH:mm:ss")
private LocalTime endTime;
@Schema(description = "状态", example = "0")
private Integer status;
}

View File

@@ -1,25 +1,34 @@
package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time;
package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config;
import io.swagger.v3.oas.annotations.media.Schema;
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;
/**
* 管理后台 - 秒杀时段 Response VO
*
* @author HUIHUI
*/
@Schema(description = "管理后台 - 秒杀时段 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class SeckillTimeRespVO extends SeckillTimeBaseVO {
public class SeckillConfigRespVO extends SeckillConfigBaseVO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long id;
@Schema(description = "秒杀活动数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@Schema(description = "秒杀活动数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
private Integer seckillActivityCount;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime createTime;
}

View File

@@ -0,0 +1,29 @@
package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotNull;
/**
* 管理后台 - 秒杀时段配置精简信息 Response VO
*
* @author HUIHUI
*/
@Schema(description = "管理后台 - 秒杀时段配置精简信息 Response VO")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class SeckillConfigSimpleRespVO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "编号不能为空")
private Long id;
@Schema(description = "秒杀时段名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "早上场")
@NotNull(message = "秒杀时段名称不能为空")
private String name;
}

View File

@@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time;
package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@@ -7,11 +7,16 @@ import lombok.ToString;
import javax.validation.constraints.NotNull;
/**
* 管理后台 - 秒杀时段更新 Request VO
*
* @author HUIHUI
*/
@Schema(description = "管理后台 - 秒杀时段更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class SeckillTimeUpdateReqVO extends SeckillTimeBaseVO {
public class SeckillConfigUpdateReqVO extends SeckillConfigBaseVO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "编号不能为空")

View File

@@ -0,0 +1,28 @@
package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* 管理后台 - 修改时段配置状态 Request VO
*
* @author HUIHUI
*/
@Schema(description = "管理后台 - 修改时段配置状态 Request VO")
@Data
public class SeckillConfigUpdateStatusReqVo {
@Schema(description = "时段配置编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@NotNull(message = "时段配置编号不能为空")
private Long id;
@Schema(description = "状态,见 CommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "状态不能为空")
@InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}")
private Integer status;
}

View File

@@ -0,0 +1,34 @@
package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* 秒杀参与商品 Base VO提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*
* @author HUIHUI
*/
@Data
public class SeckillProductBaseVO {
@Schema(description = "商品spu_id", requiredMode = Schema.RequiredMode.REQUIRED, example = "30563")
@NotNull(message = "商品spu_id不能为空")
private Long spuId;
@Schema(description = "商品sku_id", requiredMode = Schema.RequiredMode.REQUIRED, example = "30563")
@NotNull(message = "商品sku_id不能为空")
private Long skuId;
@Schema(description = "秒杀金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "6689")
@NotNull(message = "秒杀金额,单位:分不能为空")
private Integer seckillPrice;
@Schema(description = "秒杀库存", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "秒杀库存不能为空")
private Integer stock;
}

View File

@@ -0,0 +1,20 @@
package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductBaseVO;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import javax.validation.constraints.*;
/**
* 管理后台 - 秒杀参与商品创建 Request VO
*
* @author HUIHUI
*/
@Schema(description = "管理后台 - 秒杀参与商品创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class SeckillProductCreateReqVO extends SeckillProductBaseVO {
}

View File

@@ -0,0 +1,24 @@
package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.time.LocalDateTime;
/**
* 管理后台 - 秒杀参与商品 Response VO
*
* @author HUIHUI
*/
@Schema(description = "管理后台 - 秒杀参与商品 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class SeckillProductRespVO extends SeckillProductBaseVO {
@Schema(description = "秒杀参与商品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "256")
private Long id;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
}

View File

@@ -0,0 +1,22 @@
package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import javax.validation.constraints.*;
/**
* 管理后台 - 秒杀参与商品更新 Request VO
*
* @author HUIHUI
*/
@Schema(description = "管理后台 - 秒杀参与商品更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class SeckillProductUpdateReqVO extends SeckillProductBaseVO {
@Schema(description = "秒杀参与商品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "256")
@NotNull(message = "秒杀参与商品编号不能为空")
private Long id;
}

View File

@@ -9,19 +9,20 @@ import java.time.LocalDateTime;
@Data
public class AppActivityRespVO {
@Schema(description = "活动编号", required = true, example = "1024")
@Schema(description = "活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long id;
@Schema(description = "活动类型", required = true, example = "1") // 对应 PromotionTypeEnum 枚举
@Schema(description = "活动类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
// 对应 PromotionTypeEnum 枚举
private Integer type;
@Schema(description = "活动名称", required = true, example = "618 大促")
@Schema(description = "活动名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "618 大促")
private String name;
@Schema(description = "活动开始时间", required = true)
@Schema(description = "活动开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime startTime;
@Schema(description = "活动结束时间", required = true)
@Schema(description = "活动结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime endTime;
}

View File

@@ -10,28 +10,28 @@ import java.util.List;
@Data
public class AppCombinationActivityDetailRespVO {
@Schema(description = "拼团活动编号", required = true, example = "1024")
@Schema(description = "拼团活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long id;
@Schema(description = "拼团活动名称", required = true, example = "618 大拼团")
@Schema(description = "拼团活动名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "618 大拼团")
private String name;
@Schema(description = "活动状态", required = true, example = "1")
@Schema(description = "活动状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer status;
@Schema(description = "活动开始时间", required = true)
@Schema(description = "活动开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime startTime;
@Schema(description = "活动结束时间", required = true)
@Schema(description = "活动结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime endTime;
@Schema(description = "拼团人数", required = true, example = "3")
@Schema(description = "拼团人数", requiredMode = Schema.RequiredMode.REQUIRED, example = "3")
private Integer userSize;
@Schema(description = "成功的拼团数量", required = true, example = "100")
@Schema(description = "成功的拼团数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
private Integer successCount;
@Schema(description = "商品 SPU 编号", required = true, example = "2048")
@Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048")
private Long spuId;
@Schema(description = "总共限购数量", example = "10")
@@ -40,17 +40,17 @@ public class AppCombinationActivityDetailRespVO {
@Schema(description = "单次限购数量", example = "5")
private Integer singleLimitCount;
@Schema(description = "商品信息数组", required = true)
@Schema(description = "商品信息数组", requiredMode = Schema.RequiredMode.REQUIRED)
private List<Product> products;
@Schema(description = "商品信息")
@Data
public static class Product {
@Schema(description = "商品 SKU 编号", required = true, example = "4096")
@Schema(description = "商品 SKU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "4096")
private Long skuId;
@Schema(description = "拼团金额,单位:分", required = true, example = "100")
@Schema(description = "拼团金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
private Integer combinationPrice;
}

View File

@@ -7,25 +7,28 @@ import lombok.Data;
@Data
public class AppCombinationActivityRespVO {
@Schema(description = "拼团活动编号", required = true, example = "1024")
@Schema(description = "拼团活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long id;
@Schema(description = "拼团活动名称", required = true, example = "618 大拼团")
@Schema(description = "拼团活动名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "618 大拼团")
private String name;
@Schema(description = "拼团人数", required = true, example = "3")
@Schema(description = "拼团人数", requiredMode = Schema.RequiredMode.REQUIRED, example = "3")
private Integer userSize;
@Schema(description = "商品 SPU 编号", required = true, example = "2048")
@Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048")
private Long spuId;
@Schema(description = "商品图片", required = true, example = "4096") // 从 SPU 的 picUrl 读取
@Schema(description = "商品图片", requiredMode = Schema.RequiredMode.REQUIRED, example = "4096")
// 从 SPU 的 picUrl 读取
private String picUrl;
@Schema(description = "商品市场价,单位:分", required = true, example = "50") // 从 SPU 的 marketPrice 读取
@Schema(description = "商品市场价,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "50")
// 从 SPU 的 marketPrice 读取
private Integer marketPrice;
@Schema(description = "拼团金额,单位:分", required = true, example = "100") // 从拼团商品里取最低价
@Schema(description = "拼团金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
// 从拼团商品里取最低价
private Integer combinationPrice;
}

View File

@@ -9,13 +9,14 @@ import java.util.List;
@Data
public class AppCombinationRecordDetailRespVO {
@Schema(description = "团长的拼团记录", required = true)
@Schema(description = "团长的拼团记录", requiredMode = Schema.RequiredMode.REQUIRED)
private AppCombinationRecordRespVO headRecord;
@Schema(description = "成员的拼团记录", required = true)
@Schema(description = "成员的拼团记录", requiredMode = Schema.RequiredMode.REQUIRED)
private List<AppCombinationRecordRespVO> memberRecords;
@Schema(description = "当前用户参团记录对应的订单编号", required = true, example = "1024") // 如果没参团,返回 null
@Schema(description = "当前用户参团记录对应的订单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
// 如果没参团,返回 null
private Long orderId;
}

View File

@@ -9,37 +9,37 @@ import java.util.Date;
@Data
public class AppCombinationRecordRespVO {
@Schema(description = "拼团记录编号", required = true, example = "1024")
@Schema(description = "拼团记录编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long id;
@Schema(description = "拼团活动编号", required = true, example = "1024")
@Schema(description = "拼团活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long activityId;
@Schema(description = "用户昵称", required = true, example = "1024")
@Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private String nickname;
@Schema(description = "用户头像", required = true, example = "1024")
@Schema(description = "用户头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private String avatar;
@Schema(description = "过期时间", required = true)
@Schema(description = "过期时间", requiredMode = Schema.RequiredMode.REQUIRED)
private Date expireTime;
@Schema(description = "可参团人数", required = true, example = "10")
@Schema(description = "可参团人数", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
private Integer userSize;
@Schema(description = "已参团人数", required = true, example = "5")
@Schema(description = "已参团人数", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
private Integer userCount;
@Schema(description = "拼团状态", required = true, example = "1")
@Schema(description = "拼团状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer status;
@Schema(description = "商品名字", required = true, example = "我是大黄豆")
@Schema(description = "商品名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "我是大黄豆")
private String spuName;
@Schema(description = "商品图片", required = true, example = "https://www.iocoder.cn/1.png")
@Schema(description = "商品图片", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/1.png")
private String picUrl;
@Schema(description = "拼团金额,单位:分", required = true, example = "100")
@Schema(description = "拼团金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
private Integer combinationPrice;
}

View File

@@ -9,10 +9,10 @@ import java.util.List;
@Data
public class AppCombinationRecordSummaryRespVO {
@Schema(description = "拼团用户数量", required = true, example = "1024")
@Schema(description = "拼团用户数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Integer userCount;
@Schema(description = "拼团用户头像列表", required = true) // 只返回最近的 7 个
@Schema(description = "拼团用户头像列表", requiredMode = Schema.RequiredMode.REQUIRED) // 只返回最近的 7 个
private List<String> avatars;
}

View File

@@ -10,27 +10,28 @@ import java.time.LocalDateTime;
@Data
public class AppCouponTemplateRespVO {
@Schema(description = "优惠劵模板编号", required = true, example = "1")
@Schema(description = "优惠劵模板编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long id;
@Schema(description = "优惠劵名", required = true, example = "春节送送送")
@Schema(description = "优惠劵名", requiredMode = Schema.RequiredMode.REQUIRED, example = "春节送送送")
private String name;
@Schema(description = "每人限领个数", required = true, example = "66") // -1 - 则表示不限制
@Schema(description = "每人限领个数", requiredMode = Schema.RequiredMode.REQUIRED, example = "66") // -1 - 则表示不限制
private Integer takeLimitCount;
@Schema(description = "是否设置满多少金额可用", required = true, example = "100") // 单位0 - 不限制
@Schema(description = "是否设置满多少金额可用", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
// 单位0 - 不限制
private Integer usePrice;
// TODO 芋艿:这两要改的
// @Schema(description = "商品范围", required = true, example = "1")
// @Schema(description = "商品范围", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
// @InEnum(PromotionProductScopeEnum.class)
// private Integer productScope;
//
// @Schema(description = "商品 SPU 编号的数组", example = "1,3")
// private List<Long> productSpuIds;
@Schema(description = "生效日期类型", required = true, example = "1")
@Schema(description = "生效日期类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer validityType;
@Schema(description = "固定日期 - 生效开始时间")
@@ -47,7 +48,7 @@ public class AppCouponTemplateRespVO {
@Min(value = 1L, message = "开始天数必须大于 1")
private Integer fixedEndTerm;
@Schema(description = "优惠类型", required = true, example = "1")
@Schema(description = "优惠类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer discountType;
@Schema(description = "折扣百分比", example = "80") // 例如说80% 为 80
@@ -62,7 +63,7 @@ public class AppCouponTemplateRespVO {
// ========== 用户相关字段 ==========
@Schema(description = "是否已领取", required = true, example = "true")
@Schema(description = "是否已领取", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
private Boolean takeStatus;
}

View File

@@ -10,24 +10,24 @@ import java.util.List;
@Data
public class AppSeckillActivityDetailRespVO {
@Schema(description = "秒杀活动编号", required = true, example = "1024")
@Schema(description = "秒杀活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long id;
@Schema(description = "秒杀活动名称", required = true, example = "晚九点限时秒杀")
@Schema(description = "秒杀活动名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "晚九点限时秒杀")
private String name;
@Schema(description = "活动状态", required = true, example = "1")
@Schema(description = "活动状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer status;
// TODO @芋艿:开始时间、结束时间,要和场次结合起来;就是要算到当前场次,是几点哈;
@Schema(description = "活动开始时间", required = true)
@Schema(description = "活动开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime startTime;
@Schema(description = "活动结束时间", required = true)
@Schema(description = "活动结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime endTime;
@Schema(description = "商品 SPU 编号", required = true, example = "2048")
@Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048")
private Long spuId;
@Schema(description = "总共限购数量", example = "10")
@@ -36,26 +36,26 @@ public class AppSeckillActivityDetailRespVO {
@Schema(description = "单次限购数量", example = "5")
private Integer singleLimitCount;
@Schema(description = "秒杀库存(剩余)", required = true, example = "50")
@Schema(description = "秒杀库存(剩余)", requiredMode = Schema.RequiredMode.REQUIRED, example = "50")
private Integer stock;
@Schema(description = "秒杀库存(总计)", required = true, example = "100")
@Schema(description = "秒杀库存(总计)", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
private Integer totalStock;
@Schema(description = "商品信息数组", required = true)
@Schema(description = "商品信息数组", requiredMode = Schema.RequiredMode.REQUIRED)
private List<Product> products;
@Schema(description = "商品信息")
@Data
public static class Product {
@Schema(description = "商品 SKU 编号", required = true, example = "4096")
@Schema(description = "商品 SKU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "4096")
private Long skuId;
@Schema(description = "秒杀金额,单位:分", required = true, example = "100")
@Schema(description = "秒杀金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
private Integer seckillPrice;
@Schema(description = "秒杀限量库存", required = true, example = "50")
@Schema(description = "秒杀限量库存", requiredMode = Schema.RequiredMode.REQUIRED, example = "50")
private Integer stock;
}

View File

@@ -10,10 +10,10 @@ import java.util.List;
@Data
public class AppSeckillActivityNowRespVO {
@Schema(description = "秒杀时间段", required = true)
@Schema(description = "秒杀时间段", requiredMode = Schema.RequiredMode.REQUIRED)
private AppSeckillConfigRespVO config;
@Schema(description = "秒杀活动数组", required = true)
@Schema(description = "秒杀活动数组", requiredMode = Schema.RequiredMode.REQUIRED)
private List<AppSeckillActivityRespVO> activities;
}

View File

@@ -7,28 +7,31 @@ import lombok.Data;
@Data
public class AppSeckillActivityRespVO {
@Schema(description = "秒杀活动编号", required = true, example = "1024")
@Schema(description = "秒杀活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long id;
@Schema(description = "秒杀活动名称", required = true, example = "晚九点限时秒杀")
@Schema(description = "秒杀活动名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "晚九点限时秒杀")
private String name;
@Schema(description = "商品 SPU 编号", required = true, example = "2048")
@Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048")
private Long spuId;
@Schema(description = "商品图片", required = true, example = "4096") // 从 SPU 的 picUrl 读取
@Schema(description = "商品图片", requiredMode = Schema.RequiredMode.REQUIRED, example = "4096")
// 从 SPU 的 picUrl 读取
private String picUrl;
@Schema(description = "单位名", requiredMode = Schema.RequiredMode.REQUIRED, example = "")
private String unitName;
@Schema(description = "商品市场价,单位:分", required = true, example = "50") // 从 SPU 的 marketPrice 读取
@Schema(description = "商品市场价,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "50")
// 从 SPU 的 marketPrice 读取
private Integer marketPrice;
@Schema(description = "秒杀库存(剩余)", required = true, example = "100")
@Schema(description = "秒杀库存(剩余)", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
private Integer stock;
@Schema(description = "秒杀库存(总共)", required = true, example = "200")
@Schema(description = "秒杀库存(总共)", requiredMode = Schema.RequiredMode.REQUIRED, example = "200")
private Integer totalStock;
@Schema(description = "秒杀金额,单位:分", required = true, example = "100") // 从秒杀商品里取最低价
@Schema(description = "秒杀金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
// 从秒杀商品里取最低价
private Integer seckillPrice;
}

View File

@@ -9,15 +9,15 @@ import java.util.List;
@Data
public class AppSeckillConfigRespVO {
@Schema(description = "秒杀时间段编号", required = true, example = "1024")
@Schema(description = "秒杀时间段编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long id;
@Schema(description = "开始时间点", required = true, example = "09:00")
@Schema(description = "开始时间点", requiredMode = Schema.RequiredMode.REQUIRED, example = "09:00")
private String startTime;
@Schema(description = "结束时间点", required = true, example = "09:59")
@Schema(description = "结束时间点", requiredMode = Schema.RequiredMode.REQUIRED, example = "09:59")
private String endTime;
@Schema(description = "轮播图", required = true)
@Schema(description = "轮播图", requiredMode = Schema.RequiredMode.REQUIRED)
private List<String> sliderPicUrls;
}

View File

@@ -1,16 +1,19 @@
package cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
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.seckill.vo.activity.*;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityDetailRespVO;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityRespVO;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductCreateReqVO;
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.ArrayList;
import java.util.List;
/**
@@ -23,15 +26,10 @@ public interface SeckillActivityConvert {
SeckillActivityConvert INSTANCE = Mappers.getMapper(SeckillActivityConvert.class);
SeckillProductDO convert(SeckillActivityBaseVO.Product product);
SeckillProductDO convert(SeckillProductCreateReqVO product);
SeckillActivityDO convert(SeckillActivityCreateReqVO bean);
default String map(Long[] value) {
return value.toString();
}
SeckillActivityDO convert(SeckillActivityUpdateReqVO bean);
SeckillActivityRespVO convert(SeckillActivityDO bean);
@@ -40,7 +38,6 @@ public interface SeckillActivityConvert {
PageResult<SeckillActivityRespVO> convertPage(PageResult<SeckillActivityDO> page);
@Mappings({@Mapping(target = "products", source = "seckillProducts")})
SeckillActivityDetailRespVO convert(SeckillActivityDO seckillActivity, List<SeckillProductDO> seckillProducts);
@@ -51,12 +48,12 @@ public interface SeckillActivityConvert {
* @param productVO 前端传入的商品
* @return 是否匹配
*/
default boolean isEquals(SeckillProductDO productDO, SeckillActivityBaseVO.Product productVO) {
return ObjectUtil.equals(productDO.getSpuId(), productVO.getSpuId())
default boolean isEquals(SeckillProductDO productDO, SeckillProductCreateReqVO productVO) {
return ObjectUtil.equals(productDO.getSpuId(), 1) // TODO puhui再看看
&& ObjectUtil.equals(productDO.getSkuId(), productVO.getSkuId())
&& ObjectUtil.equals(productDO.getSeckillPrice(), productVO.getSeckillPrice())
&& ObjectUtil.equals(productDO.getStock(), productVO.getStock())
&& ObjectUtil.equals(productDO.getLimitCount(), productVO.getLimitCount());
&& ObjectUtil.equals(productDO.getSeckillPrice(), productVO.getSeckillPrice());
//&& ObjectUtil.equals(productDO.getQuota(), productVO.getQuota())
//&& ObjectUtil.equals(productDO.getLimitCount(), productVO.getLimitCount());
}
/**
@@ -69,15 +66,26 @@ public interface SeckillActivityConvert {
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.getLimitCount(), productVO.getLimitCount());
&& ObjectUtil.equals(productDO.getSeckillPrice(), productVO.getSeckillPrice());
//&& ObjectUtil.equals(productDO.getQuota(), productVO.getQuota())
//&& ObjectUtil.equals(productDO.getLimitCount(), productVO.getLimitCount());
}
default List<SeckillProductDO> convertList(List<SeckillActivityBaseVO.Product> products, SeckillActivityDO seckillActivity) {
return CollectionUtils.convertList(products, product -> convert(product)
.setActivityId(seckillActivity.getId()).setTimeIds(seckillActivity.getTimeIds()));
default List<SeckillProductDO> convertList(SeckillActivityDO seckillActivity, List<SeckillProductCreateReqVO> products) {
List<SeckillProductDO> list = new ArrayList<>();
products.forEach(sku -> {
SeckillProductDO productDO = new SeckillProductDO();
productDO.setActivityId(seckillActivity.getId());
productDO.setConfigIds(seckillActivity.getConfigIds());
productDO.setSpuId(sku.getSpuId());
productDO.setSkuId(sku.getSkuId());
productDO.setSeckillPrice(sku.getSeckillPrice());
productDO.setStock(sku.getStock());
productDO.setActivityStatus(CommonStatusEnum.ENABLE.getStatus());
productDO.setActivityStartTime(seckillActivity.getStartTime());
productDO.setActivityEndTime(seckillActivity.getEndTime());
});
return list;
}
}

View File

@@ -0,0 +1,36 @@
package cn.iocoder.yudao.module.promotion.convert.seckill.seckillconfig;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigCreateReqVO;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigRespVO;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigSimpleRespVO;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigUpdateReqVO;
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
/**
* 秒杀时段 Convert
*
* @author 芋道源码
*/
@Mapper
public interface SeckillConfigConvert {
SeckillConfigConvert INSTANCE = Mappers.getMapper(SeckillConfigConvert.class);
SeckillConfigDO convert(SeckillConfigCreateReqVO bean);
SeckillConfigDO convert(SeckillConfigUpdateReqVO bean);
SeckillConfigRespVO convert(SeckillConfigDO bean);
List<SeckillConfigRespVO> convertList(List<SeckillConfigDO> list);
List<SeckillConfigSimpleRespVO> convertList1(List<SeckillConfigDO> list);
PageResult<SeckillConfigRespVO> convertPage(PageResult<SeckillConfigDO> page);
}

View File

@@ -1,34 +0,0 @@
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.vo.time.SeckillTimeCreateReqVO;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeRespVO;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.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);
}

View File

@@ -1,8 +1,8 @@
package cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler;
import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
@@ -31,6 +31,11 @@ public class SeckillActivityDO extends BaseDO {
*/
@TableId
private Long id;
/**
* 秒杀活动商品
*/
@TableField(typeHandler = LongListTypeHandler.class)
private List<Long> spuIds;
/**
* 秒杀活动名称
*/
@@ -38,7 +43,7 @@ public class SeckillActivityDO extends BaseDO {
/**
* 活动状态
*
* 枚举 {@link PromotionActivityStatusEnum 对应的类}
* 枚举 {@link CommonStatusEnum 对应的类}
*/
private Integer status;
/**
@@ -61,9 +66,9 @@ public class SeckillActivityDO extends BaseDO {
* 秒杀时段 id
*/
@TableField(typeHandler = LongListTypeHandler.class)
private List<Long> timeIds;
private List<Long> configIds;
/**
* 付款订单数
* 新增订单数
*/
private Integer orderCount;
/**
@@ -74,5 +79,21 @@ public class SeckillActivityDO extends BaseDO {
* 订单实付金额,单位:分
*/
private Long totalPrice;
/**
* 总限购数量
*/
private Integer totalLimitCount;
/**
* 单次限够数量
*/
private Integer singleLimitCount;
/**
* 秒杀库存
*/
private Integer stock;
/**
* 秒杀总库存
*/
private Integer totalStock;
}

View File

@@ -1,67 +1,74 @@
package cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import java.time.LocalDateTime;
import java.util.List;
/**
* 秒杀参与商品
* 秒杀参与商品 DO
*
* @author halfninety
* @TableName promotion_seckill_product
* @author HUIHUI
*/
@TableName(value = "promotion_seckill_product", autoResultMap = true)
@TableName("promotion_seckill_product")
@KeySequence("promotion_seckill_product_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SeckillProductDO extends BaseDO {
/**
* 秒杀参与商品编号
*/
@TableId(type = IdType.AUTO)
@TableId
private Long id;
/**
* 秒杀活动id
* 秒杀活动 id
*/
private Long activityId;
/**
* 秒杀时段id
* 秒杀时段 id
*/
@TableField(typeHandler = LongListTypeHandler.class)
private List<Long> timeIds;
private List<Long> configIds;
/**
* 商品id
* 商品 spu_id
*/
private Long spuId;
/**
* 商品sku_id
* 商品 sku_id
*/
private Long skuId;
/**
* 秒杀金额
* 秒杀金额,单位:分
*/
private Integer seckillPrice;
// TODO @芋艿:改成 quota 限量库存;每次购买时,需要减小;
/**
* 秒杀库存
*/
private Integer stock;
/**
* 每人限购
* 秒杀商品状态
* 枚举 {@link CommonStatusEnum 对应的类}
*/
private Integer limitCount;
private Integer activityStatus;
/**
* 活动开始时间点
*/
private LocalDateTime activityStartTime;
/**
* 活动结束时间点
*/
private LocalDateTime activityEndTime;
}

View File

@@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckilltime;
package cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
@@ -8,19 +9,17 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.time.LocalTime;
/**
* 秒杀时段 DO
*
* @author 芋道源码
*/
@TableName("promotion_seckill_time")
@KeySequence("promotion_seckill_time_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@TableName("promotion_seckill_config")
@KeySequence("promotion_seckill_config_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class SeckillTimeDO extends BaseDO {
public class SeckillConfigDO extends BaseDO {
/**
* 编号
@@ -34,14 +33,20 @@ public class SeckillTimeDO extends BaseDO {
/**
* 开始时间点
*/
private LocalTime startTime;
private String startTime;
/**
* 结束时间点
*/
private LocalTime endTime;
private String endTime;
/**
* 秒杀活动数量
* 秒杀主图
*/
private Integer seckillActivityCount;
private String picUrl;
/**
* 状态 开启0 禁用1
* <p>
* 枚举 {@link CommonStatusEnum 对应的类}
*/
private Integer status;
}

View File

@@ -8,6 +8,8 @@ import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.Se
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* 秒杀活动 Mapper
*
@@ -20,7 +22,12 @@ public interface SeckillActivityMapper extends BaseMapperX<SeckillActivityDO> {
.likeIfPresent(SeckillActivityDO::getName, reqVO.getName())
.eqIfPresent(SeckillActivityDO::getStatus, reqVO.getStatus())
.betweenIfPresent(SeckillActivityDO::getCreateTime, reqVO.getCreateTime())
.apply(ObjectUtil.isNotNull(reqVO.getTimeId()),"FIND_IN_SET(" + reqVO.getTimeId() + ",time_ids) > 0")
.apply(ObjectUtil.isNotNull(reqVO.getConfigId()), "FIND_IN_SET(" + reqVO.getConfigId() + ",time_ids) > 0")
.orderByDesc(SeckillActivityDO::getId));
}
default List<SeckillActivityDO> selectListByStatus(Integer status) {
return selectList(new LambdaQueryWrapperX<SeckillActivityDO>()
.eqIfPresent(SeckillActivityDO::getStatus, status));
}
}

View File

@@ -27,7 +27,7 @@ public interface SeckillProductMapper extends BaseMapperX<SeckillProductDO> {
default void updateTimeIdsByActivityId(Long id, List<Long> timeIds) {
new LambdaUpdateChainWrapper<>(this)
.set(SeckillProductDO::getTimeIds, CollUtil.join(timeIds, ","))
.set(SeckillProductDO::getConfigIds, CollUtil.join(timeIds, ","))
.eq(SeckillProductDO::getActivityId, id)
.update();
}

View File

@@ -0,0 +1,20 @@
package cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillconfig;
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.vo.config.SeckillConfigPageReqVO;
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface SeckillConfigMapper extends BaseMapperX<SeckillConfigDO> {
default PageResult<SeckillConfigDO> selectPage(SeckillConfigPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<SeckillConfigDO>()
.likeIfPresent(SeckillConfigDO::getName, reqVO.getName())
.eqIfPresent(SeckillConfigDO::getStatus, reqVO.getStatus())
.orderByDesc(SeckillConfigDO::getId));
}
}

View File

@@ -1,32 +0,0 @@
package cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckilltime;
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;
import java.time.LocalTime;
import java.util.Collection;
import java.util.List;
@Mapper
public interface SeckillTimeMapper extends BaseMapperX<SeckillTimeDO> {
default List<SeckillTimeDO> selectListByTime(LocalTime time) {
return selectList(SeckillTimeDO::getStartTime, SeckillTimeDO::getEndTime, time);
}
default List<SeckillTimeDO> selectListByTime(LocalTime startTime, LocalTime endTime) {
return selectList(new LambdaQueryWrapper<SeckillTimeDO>()
.ge(SeckillTimeDO::getStartTime, startTime)
.le(SeckillTimeDO::getEndTime, endTime));
}
default void updateActivityCount(Collection<Long> ids, String type, Integer count) {
new LambdaUpdateChainWrapper<>(this)
.in(SeckillTimeDO::getId, ids)
.setSql("`seckill_activity_count` = `seckill_activity_count` " + type + count)
.update();
}
}

View File

@@ -52,7 +52,7 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
// 插入活动
DiscountActivityDO discountActivity = DiscountActivityConvert.INSTANCE.convert(createReqVO)
.setStatus(PromotionUtils.calculateActivityStatus(createReqVO.getStartTime(), createReqVO.getEndTime()));
.setStatus(PromotionUtils.calculateActivityStatus(createReqVO.getEndTime()));
discountActivityMapper.insert(discountActivity);
// 插入商品
List<DiscountProductDO> discountProducts = convertList(createReqVO.getProducts(),
@@ -74,7 +74,7 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
// 更新活动
DiscountActivityDO updateObj = DiscountActivityConvert.INSTANCE.convert(updateReqVO)
.setStatus(PromotionUtils.calculateActivityStatus(updateReqVO.getStartTime(), updateReqVO.getEndTime()));
.setStatus(PromotionUtils.calculateActivityStatus(updateReqVO.getEndTime()));
discountActivityMapper.updateById(updateObj);
// 更新商品
updateDiscountProduct(updateReqVO);

View File

@@ -41,7 +41,7 @@ public class RewardActivityServiceImpl implements RewardActivityService {
// 插入
RewardActivityDO rewardActivity = RewardActivityConvert.INSTANCE.convert(createReqVO)
.setStatus(PromotionUtils.calculateActivityStatus(createReqVO.getStartTime(), createReqVO.getEndTime()));
.setStatus(PromotionUtils.calculateActivityStatus(createReqVO.getEndTime()));
rewardActivityMapper.insert(rewardActivity);
// 返回
return rewardActivity.getId();
@@ -59,7 +59,7 @@ public class RewardActivityServiceImpl implements RewardActivityService {
// 更新
RewardActivityDO updateObj = RewardActivityConvert.INSTANCE.convert(updateReqVO)
.setStatus(PromotionUtils.calculateActivityStatus(updateReqVO.getStartTime(), updateReqVO.getEndTime()));
.setStatus(PromotionUtils.calculateActivityStatus(updateReqVO.getEndTime()));
rewardActivityMapper.updateById(updateObj);
}

View File

@@ -1,15 +1,16 @@
package cn.iocoder.yudao.module.promotion.service.seckill.seckillactivity;
import java.util.*;
import javax.validation.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.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;
import javax.validation.Valid;
import java.util.Collection;
import java.util.List;
/**
* 秒杀活动 Service 接口
*
@@ -77,4 +78,5 @@ public interface SeckillActivityService {
* @return 活动商品列表
*/
List<SeckillProductDO> getSeckillProductListByActivityId(Long id);
}

View File

@@ -1,19 +1,26 @@
package cn.iocoder.yudao.module.promotion.service.seckill.seckillactivity;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
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.seckill.vo.activity.SeckillActivityBaseVO;
import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductBaseVO;
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.service.seckill.seckillconfig.SeckillConfigService;
import cn.iocoder.yudao.module.promotion.util.PromotionUtils;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
@@ -21,8 +28,12 @@ import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS;
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;
import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
import static java.util.Arrays.asList;
@@ -34,75 +45,104 @@ import static java.util.Arrays.asList;
@Service
@Validated
public class SeckillActivityServiceImpl implements SeckillActivityService {
@Resource
private SeckillActivityMapper seckillActivityMapper;
@Resource
private SeckillProductMapper seckillProductMapper;
@Resource
private SeckillTimeService seckillTimeService;
private SeckillConfigService seckillConfigService;
@Resource
private ProductSpuApi productSpuApi;
@Resource
private ProductSkuApi productSkuApi;
@Override
public Long createSeckillActivity(SeckillActivityCreateReqVO createReqVO) {
// 校验商品是否冲突
validateSeckillActivityProductConflicts(null, createReqVO.getProducts());
// 校验秒杀时段是否存在
seckillTimeService.validateSeckillTimeExists(createReqVO.getTimeIds());
// 校验商品秒秒杀时段是否冲突
validateProductSpuSeckillConflict(createReqVO.getConfigIds(), createReqVO.getSpuIds());
// 校验商品 sku 是否存在
validateProductSkuExistence(createReqVO.getSpuIds(), createReqVO.getProducts());
// 插入秒杀活动
SeckillActivityDO seckillActivity = SeckillActivityConvert.INSTANCE.convert(createReqVO)
.setStatus(PromotionUtils.calculateActivityStatus(createReqVO.getStartTime(), createReqVO.getEndTime()));
.setStatus(PromotionUtils.calculateActivityStatus(createReqVO.getEndTime()));
seckillActivityMapper.insert(seckillActivity);
// 插入商品
List<SeckillProductDO> productDOS = SeckillActivityConvert.INSTANCE.convertList(createReqVO.getProducts(), seckillActivity);
seckillProductMapper.insertBatch(productDOS);
// 更新秒杀时段的秒杀活动数量
seckillTimeService.sekillActivityCountIncr(createReqVO.getTimeIds());
List<SeckillProductDO> productDOs = SeckillActivityConvert.INSTANCE.convertList(seckillActivity, createReqVO.getProducts());
seckillProductMapper.insertBatch(productDOs);
return seckillActivity.getId();
}
private <T extends SeckillProductBaseVO> void validateProductSkuExistence(List<Long> spuIds, List<T> products) {
Set<Long> convertedSpuIds = CollectionUtils.convertSet(products, T::getSpuId);
// 校验 spu 个数是否相等
if (ObjectUtil.notEqual(spuIds.size(), convertedSpuIds.size())) {
throw exception(SKU_NOT_EXISTS);
}
// 获取所选 spu下的所有 sku
List<ProductSkuRespDTO> skuRespDTOs = productSkuApi.getSkuListBySpuId(spuIds);
// 校验 sku 个数是否一致
Set<Long> skuIdsSet = CollectionUtils.convertSet(products, T::getSkuId);
Set<Long> skuIdsSet1 = CollectionUtils.convertSet(skuRespDTOs, ProductSkuRespDTO::getId);
if (ObjectUtil.notEqual(skuIdsSet.size(), skuIdsSet1.size())) {
throw exception(SKU_NOT_EXISTS);
}
// 校验 skuId 是否存在
if (!skuIdsSet1.containsAll(skuIdsSet) || !skuIdsSet.containsAll(skuIdsSet1)) {
throw exception(SKU_NOT_EXISTS);
}
}
private void validateProductSpuSeckillConflict(List<Long> configIds, List<Long> spuIds) {
// 校验秒杀时段是否存在
seckillConfigService.validateSeckillConfigExists(configIds);
// 校验商品 spu 是否存在
List<ProductSpuRespDTO> spuList = productSpuApi.getSpuList(spuIds);
if (ObjectUtil.notEqual(spuIds.size(), spuList.size())) {
throw exception(SPU_NOT_EXISTS);
}
// 查询所有开启的秒杀活动
List<SeckillActivityDO> activityDOs = seckillActivityMapper.selectListByStatus(CommonStatusEnum.ENABLE.getStatus());
// 过滤出所有 spuIds 有交集的活动
List<SeckillActivityDO> doList = activityDOs.stream().filter(s -> {
// 判断 spu 是否有交集
List<Long> spuIdsClone = ArrayUtil.clone(s.getSpuIds());
spuIdsClone.retainAll(spuIds);
if (CollUtil.isEmpty(spuIdsClone)) {
return false;
}
// 判断秒杀时段是否有交集
List<Long> configIdsClone = ArrayUtil.clone(s.getConfigIds());
configIdsClone.retainAll(configIds);
return CollUtil.isNotEmpty(configIdsClone);
}).collect(Collectors.toList());
if (CollUtil.isNotEmpty(doList)) {
throw exception(SECKILL_ACTIVITY_SPU_CONFLICTS);
}
}
@Override
public void updateSeckillActivity(SeckillActivityUpdateReqVO updateReqVO) {
// 校验存在
SeckillActivityDO seckillActivity = validateSeckillActivityExists(updateReqVO.getId());
if (PromotionActivityStatusEnum.CLOSE.getStatus().equals(seckillActivity.getStatus())) {
if (CommonStatusEnum.ENABLE.getStatus().equals(seckillActivity.getStatus())) {
throw exception(SECKILL_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED);
}
// 校验商品是否冲突
validateSeckillActivityProductConflicts(updateReqVO.getId(), updateReqVO.getProducts());
validateProductSpuSeckillConflict(updateReqVO.getConfigIds(), updateReqVO.getSpuIds());
// 校验商品 sku 是否存在
validateProductSkuExistence(updateReqVO.getSpuIds(), updateReqVO.getProducts());
// 更新活动
SeckillActivityDO updateObj = SeckillActivityConvert.INSTANCE.convert(updateReqVO)
.setStatus(PromotionUtils.calculateActivityStatus(updateReqVO.getStartTime(), updateReqVO.getEndTime()));
.setStatus(PromotionUtils.calculateActivityStatus(updateReqVO.getEndTime()));
seckillActivityMapper.updateById(updateObj);
// 更新商品
updateSeckillProduct(updateReqVO);
// 更新秒杀时段的秒杀活动数量
updateSeckillTimeActivityCount(seckillActivity, updateReqVO.getTimeIds());
//updateSeckillProduct(updateReqVO);
}
/**
* 更新秒杀时段的秒杀活动数量
*
* @param seckillActivity 查询出的秒杀活动
* @param updateTimeIds 更新后的秒杀时段id列表
*/
private void updateSeckillTimeActivityCount(SeckillActivityDO seckillActivity, List<Long> updateTimeIds) {
// 查询出 timeIds
List<Long> existsTimeIds = seckillActivity.getTimeIds();
// 需要减少的时间段
Collection<Long> reduceIds = CollUtil.filterNew(existsTimeIds, existsTimeId -> !updateTimeIds.contains(existsTimeId));
// 需要添加的时间段
updateTimeIds.removeIf(existsTimeIds::contains);
// 更新减少时间段和增加时间段
if (CollUtil.isNotEmpty(updateTimeIds)) {
seckillTimeService.sekillActivityCountIncr(updateTimeIds);
}
if (CollUtil.isNotEmpty(reduceIds)) {
seckillTimeService.sekillActivityCountDecr(reduceIds);
}
}
/**
* 更新秒杀商品
* 后台查出的数据和前台查出的数据进行遍历,
@@ -113,57 +153,29 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
* @param updateReqVO 更新的请求VO
*/
private void updateSeckillProduct(SeckillActivityUpdateReqVO updateReqVO) {
List<SeckillProductDO> seckillProductDOS = seckillProductMapper.selectListByActivityId(updateReqVO.getId());
List<SeckillActivityBaseVO.Product> products = updateReqVO.getProducts();
// TODO puhui999后续完善
//List<SeckillProductDO> seckillProductDOs = seckillProductMapper.selectListByActivityId(updateReqVO.getId());
//List<SeckillProductUpdateReqVO> products = updateReqVO.getProducts();
// 计算需要删除的数据
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);
}
////计算需要删除的数据
//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);
//}
//全量更新当前活动商品的秒杀时段id列表timeIds
seckillProductMapper.updateTimeIdsByActivityId(updateReqVO.getId(), updateReqVO.getTimeIds());
}
/**
* 校验商品是否冲突
*
* @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);
}
seckillProductMapper.updateTimeIdsByActivityId(updateReqVO.getId(), updateReqVO.getConfigIds());
}
@Override
@@ -189,8 +201,7 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
if (!statuses.contains(seckillActivity.getStatus())) {
throw exception(SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END);
}
// 更新秒杀时段的秒杀活动数量
seckillTimeService.sekillActivityCountDecr(seckillActivity.getTimeIds());
// 删除
seckillActivityMapper.deleteById(id);
}

View File

@@ -0,0 +1,87 @@
package cn.iocoder.yudao.module.promotion.service.seckill.seckillconfig;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigCreateReqVO;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigPageReqVO;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigUpdateReqVO;
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO;
import javax.validation.Valid;
import java.util.Collection;
import java.util.List;
/**
* 秒杀时段 Service 接口
*
* @author halfninety
*/
public interface SeckillConfigService {
/**
* 创建秒杀时段
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createSeckillConfig(@Valid SeckillConfigCreateReqVO createReqVO);
/**
* 更新秒杀时段
*
* @param updateReqVO 更新信息
*/
void updateSeckillConfig(@Valid SeckillConfigUpdateReqVO updateReqVO);
/**
* 删除秒杀时段
*
* @param id 编号
*/
void deleteSeckillConfig(Long id);
/**
* 获得秒杀时段
*
* @param id 编号
* @return 秒杀时段
*/
SeckillConfigDO getSeckillConfig(Long id);
/**
* 获得所有秒杀时段列表
*
* @return 所有秒杀时段列表
*/
List<SeckillConfigDO> getSeckillConfigList();
/**
* 校验秒杀时段是否存在
*
* @param timeIds 秒杀时段id集合
*/
void validateSeckillConfigExists(Collection<Long> timeIds);
/**
* 获得秒杀时间段配置分页数据
*
* @param pageVO 分页请求参数
* @return 秒杀时段分页列表
*/
PageResult<SeckillConfigDO> getSeckillConfigPage(SeckillConfigPageReqVO pageVO);
/**
* 获得所有正常状态的时段配置列表
*
* @return 秒杀时段列表
*/
List<SeckillConfigDO> getListAllSimple();
/**
* 更新秒杀时段配置状态
*
* @param id id
* @param status 状态
*/
void updateSeckillConfigStatus(Long id, Integer status);
}

View File

@@ -0,0 +1,154 @@
package cn.iocoder.yudao.module.promotion.service.seckill.seckillconfig;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigCreateReqVO;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigPageReqVO;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigUpdateReqVO;
import cn.iocoder.yudao.module.promotion.convert.seckill.seckillconfig.SeckillConfigConvert;
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO;
import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillconfig.SeckillConfigMapper;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.time.LocalTime;
import java.util.Collection;
import java.util.List;
import java.util.Set;
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.*;
/**
* 秒杀时段 Service 实现类
*
* @author halfninety
*/
@Service
@Validated
public class SeckillConfigServiceImpl implements SeckillConfigService {
@Resource
private SeckillConfigMapper seckillConfigMapper;
@Override
public Long createSeckillConfig(SeckillConfigCreateReqVO createReqVO) {
// 校验时间段是否冲突
validateSeckillConfigConflict(createReqVO.getStartTime(), createReqVO.getEndTime());
// 插入
SeckillConfigDO seckillConfig = SeckillConfigConvert.INSTANCE.convert(createReqVO);
seckillConfigMapper.insert(seckillConfig);
// 返回
return seckillConfig.getId();
}
@Override
public void updateSeckillConfig(SeckillConfigUpdateReqVO updateReqVO) {
// 校验存在
validateSeckillConfigExists(updateReqVO.getId());
// 校验时间段是否冲突
validateSeckillConfigConflict(updateReqVO.getStartTime(), updateReqVO.getEndTime());
// 更新
SeckillConfigDO updateObj = SeckillConfigConvert.INSTANCE.convert(updateReqVO);
seckillConfigMapper.updateById(updateObj);
}
@Override
public void deleteSeckillConfig(Long id) {
// 校验存在
validateSeckillConfigExists(id);
// 删除
seckillConfigMapper.deleteById(id);
}
private void validateSeckillConfigExists(Long id) {
if (seckillConfigMapper.selectById(id) == null) {
throw exception(SECKILL_TIME_NOT_EXISTS);
}
}
/**
* 校验时间是否存在冲突
*
* @param startTime 开始时间
* @param endTime 结束时间
*/
private void validateSeckillConfigConflict(String startTime, String endTime) {
LocalTime startTime1 = LocalTime.parse(startTime);
LocalTime endTime1 = LocalTime.parse(endTime);
// 检查选择的时间是否相等
if (startTime1.equals(endTime1)) {
throw exception(SECKILL_TIME_EQUAL);
}
// 检查开始时间是否在结束时间之前
if (startTime1.isAfter(endTime1)) {
throw exception(SECKILL_START_TIME_BEFORE_END_TIME);
}
// 查询出所有的时段配置
List<SeckillConfigDO> configDOs = seckillConfigMapper.selectList();
// 过滤出重叠的时段 ids
Set<Long> ids = configDOs.stream().filter((config) -> {
LocalTime startTime2 = LocalTime.parse(config.getStartTime());
LocalTime endTime2 = LocalTime.parse(config.getEndTime());
// 判断时间是否重叠
// 开始时间在已配置时段的结束时间之前 且 结束时间在已配置时段的开始时间之后 []
return startTime1.isBefore(endTime2) && endTime1.isAfter(startTime2)
// 开始时间在已配置时段的开始时间之前 且 结束时间在已配置时段的开始时间之后 (] 或 ()
|| startTime1.isBefore(startTime2) && endTime1.isAfter(startTime2)
// 开始时间在已配置时段的结束时间之前 且 结束时间在已配值时段的结束时间之后 [) 或 ()
|| startTime1.isBefore(endTime2) && endTime1.isAfter(endTime2);
}).map(SeckillConfigDO::getId).collect(Collectors.toSet());
if (CollUtil.isNotEmpty(ids)) {
throw exception(SECKILL_TIME_CONFLICTS);
}
}
@Override
public SeckillConfigDO getSeckillConfig(Long id) {
return seckillConfigMapper.selectById(id);
}
@Override
public List<SeckillConfigDO> getSeckillConfigList() {
return seckillConfigMapper.selectList();
}
@Override
public void validateSeckillConfigExists(Collection<Long> configIds) {
if (CollUtil.isEmpty(configIds)) {
throw exception(SECKILL_TIME_NOT_EXISTS);
}
if (seckillConfigMapper.selectBatchIds(configIds).size() != configIds.size()) {
throw exception(SECKILL_TIME_NOT_EXISTS);
}
}
@Override
public PageResult<SeckillConfigDO> getSeckillConfigPage(SeckillConfigPageReqVO pageVO) {
return seckillConfigMapper.selectPage(pageVO);
}
@Override
public List<SeckillConfigDO> getListAllSimple() {
return seckillConfigMapper.selectList(SeckillConfigDO::getStatus, CommonStatusEnum.ENABLE.getStatus());
}
@Override
public void updateSeckillConfigStatus(Long id, Integer status) {
// 校验秒杀时段是否存在
validateSeckillConfigExists(id);
SeckillConfigDO seckillConfigDO = new SeckillConfigDO();
seckillConfigDO.setId(id);
seckillConfigDO.setStatus(status);
// 更新状态
seckillConfigMapper.updateById(seckillConfigDO);
}
}

View File

@@ -1,76 +0,0 @@
package cn.iocoder.yudao.module.promotion.service.seckill.seckilltime;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeCreateReqVO;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeUpdateReqVO;
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckilltime.SeckillTimeDO;
import javax.validation.Valid;
import java.util.Collection;
import java.util.List;
/**
* 秒杀时段 Service 接口
*
* @author halfninety
*/
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();
/**
* 校验秒杀时段是否存在
*
* @param timeIds 秒杀时段id集合
*/
void validateSeckillTimeExists(Collection<Long> timeIds);
/**
* 秒杀时段列表的秒杀活动数量加 1
*
* @param ids 秒杀时段id列表
*/
void sekillActivityCountIncr(Collection<Long> ids);
/**
* 秒杀时段列表的秒杀活动数量减 1
*
* @param ids 秒杀时段id列表
*/
void sekillActivityCountDecr(Collection<Long> ids);
}

View File

@@ -1,124 +0,0 @@
package cn.iocoder.yudao.module.promotion.service.seckill.seckilltime;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeCreateReqVO;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.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.dal.mysql.seckill.seckilltime.SeckillTimeMapper;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.time.LocalTime;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.SECKILL_TIME_CONFLICTS;
import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.SECKILL_TIME_NOT_EXISTS;
/**
* 秒杀时段 Service 实现类
*
* @author halfninety
*/
@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.selectListByTime(startTime);
List<SeckillTimeDO> endTimeList = seckillTimeMapper.selectListByTime(endTime);
//查询自己时间段内是否有时间段
List<SeckillTimeDO> startEndTimeList = seckillTimeMapper.selectListByTime(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 validateSeckillTimeExists(Collection<Long> timeIds) {
if (CollUtil.isEmpty(timeIds)) {
throw exception(SECKILL_TIME_NOT_EXISTS);
}
if (seckillTimeMapper.selectBatchIds(timeIds).size() != timeIds.size()) {
throw exception(SECKILL_TIME_NOT_EXISTS);
}
}
@Override
public void sekillActivityCountIncr(Collection<Long> ids) {
seckillTimeMapper.updateActivityCount(ids, "+", 1);
}
@Override
public void sekillActivityCountDecr(Collection<Long> ids) {
seckillTimeMapper.updateActivityCount(ids, "-", 1);
}
}

View File

@@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.promotion.util;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum;
import java.time.LocalDateTime;
@@ -15,18 +15,11 @@ public class PromotionUtils {
/**
* 根据时间,计算活动状态
*
* @param startTime 开始时间
* @param endTime 结束时间
* @return 活动状态
*/
public static Integer calculateActivityStatus(LocalDateTime startTime, LocalDateTime endTime) {
if (LocalDateTimeUtils.beforeNow(endTime)) {
return PromotionActivityStatusEnum.END.getStatus();
}
if (LocalDateTimeUtils.afterNow(startTime)) {
return PromotionActivityStatusEnum.WAIT.getStatus();
}
return PromotionActivityStatusEnum.RUN.getStatus();
public static Integer calculateActivityStatus(LocalDateTime endTime) {
return LocalDateTimeUtils.beforeNow(endTime) ? CommonStatusEnum.DISABLE.getStatus() : CommonStatusEnum.ENABLE.getStatus();
}
}

View File

@@ -108,31 +108,31 @@ public class SeckillActivityServiceImplTest extends BaseDbUnitTest {
SeckillActivityDO dbSeckillActivity = randomPojo(SeckillActivityDO.class, o -> { // 等会查询到
o.setName(null);
o.setStatus(null);
o.setTimeIds(null);
o.setConfigIds(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.setTimeIds(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[]{}));
seckillActivityMapper.insert(cloneIgnoreId(dbSeckillActivity, o -> o.setName(null)));
// 测试 status 不匹配
seckillActivityMapper.insert(cloneIgnoreId(dbSeckillActivity, o -> o.setStatus(null)));
// 测试 timeId 不匹配
seckillActivityMapper.insert(cloneIgnoreId(dbSeckillActivity, o -> o.setConfigIds(null)));
// 测试 createTime 不匹配
seckillActivityMapper.insert(cloneIgnoreId(dbSeckillActivity, o -> o.setCreateTime(null)));
// 准备参数
SeckillActivityPageReqVO reqVO = new SeckillActivityPageReqVO();
reqVO.setName(null);
reqVO.setStatus(null);
reqVO.setConfigId(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));
// 调用
PageResult<SeckillActivityDO> pageResult = seckillActivityService.getSeckillActivityPage(reqVO);
// 断言
assertEquals(1, pageResult.getTotal());
assertEquals(1, pageResult.getList().size());
assertPojoEquals(dbSeckillActivity, pageResult.getList().get(0));
}
@Test
@@ -142,7 +142,7 @@ public class SeckillActivityServiceImplTest extends BaseDbUnitTest {
SeckillActivityDO dbSeckillActivity = randomPojo(SeckillActivityDO.class, o -> { // 等会查询到
o.setName(null);
o.setStatus(null);
o.setTimeIds(null);
o.setConfigIds(null);
o.setCreateTime(null);
});
seckillActivityMapper.insert(dbSeckillActivity);
@@ -151,7 +151,7 @@ public class SeckillActivityServiceImplTest extends BaseDbUnitTest {
// 测试 status 不匹配
seckillActivityMapper.insert(cloneIgnoreId(dbSeckillActivity, o -> o.setStatus(null)));
// 测试 timeId 不匹配
seckillActivityMapper.insert(cloneIgnoreId(dbSeckillActivity, o -> o.setTimeIds(null)));
seckillActivityMapper.insert(cloneIgnoreId(dbSeckillActivity, o -> o.setConfigIds(null)));
// 测试 createTime 不匹配
seckillActivityMapper.insert(cloneIgnoreId(dbSeckillActivity, o -> o.setCreateTime(null)));
// 准备参数

View File

@@ -0,0 +1,190 @@
package cn.iocoder.yudao.module.promotion.service.seckillconfig;
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigCreateReqVO;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigUpdateReqVO;
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO;
import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillconfig.SeckillConfigMapper;
import cn.iocoder.yudao.module.promotion.service.seckill.seckillconfig.SeckillConfigServiceImpl;
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.context.annotation.Import;
import javax.annotation.Resource;
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_TIME_NOT_EXISTS;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
/**
* {@link SeckillConfigServiceImpl} 的单元测试类
*
* @author 芋道源码
*/
@Import(SeckillConfigServiceImpl.class)
@Disabled // TODO 芋艿:未来开启
public class SeckillConfigServiceImplTest extends BaseDbUnitTest {
@Resource
private SeckillConfigServiceImpl SeckillConfigService;
@Resource
private SeckillConfigMapper seckillConfigMapper;
@Resource
private ObjectMapper objectMapper;
@Test
public void testJacksonSerializ() {
// 准备参数
SeckillConfigCreateReqVO reqVO = randomPojo(SeckillConfigCreateReqVO.class);
// ObjectMapper objectMapper = new ObjectMapper();
try {
String string = objectMapper.writeValueAsString(reqVO);
System.out.println(string);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
@Test
public void testCreateSeckillConfig_success() {
// 准备参数
SeckillConfigCreateReqVO reqVO = randomPojo(SeckillConfigCreateReqVO.class);
// 调用
Long SeckillConfigId = SeckillConfigService.createSeckillConfig(reqVO);
// 断言
assertNotNull(SeckillConfigId);
// 校验记录的属性是否正确
SeckillConfigDO SeckillConfig = seckillConfigMapper.selectById(SeckillConfigId);
assertPojoEquals(reqVO, SeckillConfig);
}
@Test
public void testUpdateSeckillConfig_success() {
// mock 数据
SeckillConfigDO dbSeckillConfig = randomPojo(SeckillConfigDO.class);
seckillConfigMapper.insert(dbSeckillConfig);// @Sql: 先插入出一条存在的数据
// 准备参数
SeckillConfigUpdateReqVO reqVO = randomPojo(SeckillConfigUpdateReqVO.class, o -> {
o.setId(dbSeckillConfig.getId()); // 设置更新的 ID
});
// 调用
SeckillConfigService.updateSeckillConfig(reqVO);
// 校验是否更新正确
SeckillConfigDO SeckillConfig = seckillConfigMapper.selectById(reqVO.getId()); // 获取最新的
assertPojoEquals(reqVO, SeckillConfig);
}
@Test
public void testUpdateSeckillConfig_notExists() {
// 准备参数
SeckillConfigUpdateReqVO reqVO = randomPojo(SeckillConfigUpdateReqVO.class);
// 调用, 并断言异常
assertServiceException(() -> SeckillConfigService.updateSeckillConfig(reqVO), SECKILL_TIME_NOT_EXISTS);
}
@Test
public void testDeleteSeckillConfig_success() {
// mock 数据
SeckillConfigDO dbSeckillConfig = randomPojo(SeckillConfigDO.class);
seckillConfigMapper.insert(dbSeckillConfig);// @Sql: 先插入出一条存在的数据
// 准备参数
Long id = dbSeckillConfig.getId();
// 调用
SeckillConfigService.deleteSeckillConfig(id);
// 校验数据不存在了
assertNull(seckillConfigMapper.selectById(id));
}
@Test
public void testDeleteSeckillConfig_notExists() {
// 准备参数
Long id = randomLongId();
// 调用, 并断言异常
assertServiceException(() -> SeckillConfigService.deleteSeckillConfig(id), SECKILL_TIME_NOT_EXISTS);
}
@Test
@Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
public void testGetSeckillConfigPage() {
// mock 数据
// SeckillConfigDO dbSeckillConfig = randomPojo(SeckillConfigDO.class, o -> { // 等会查询到
// o.setName(null);
// o.setStartTime(null);
// o.setEndTime(null);
// o.setCreateTime(null);
// });
// seckillConfigMapper.insert(dbSeckillConfig);
// // 测试 name 不匹配
// seckillConfigMapper.insert(cloneIgnoreId(dbSeckillConfig, o -> o.setName(null)));
// // 测试 startTime 不匹配
// seckillConfigMapper.insert(cloneIgnoreId(dbSeckillConfig, o -> o.setStartTime(null)));
// // 测试 endTime 不匹配
// seckillConfigMapper.insert(cloneIgnoreId(dbSeckillConfig, o -> o.setEndTime(null)));
// // 测试 createTime 不匹配
// seckillConfigMapper.insert(cloneIgnoreId(dbSeckillConfig, o -> o.setCreateTime(null)));
// // 准备参数
// SeckillConfigPageReqVO reqVO = new SeckillConfigPageReqVO();
// reqVO.setName(null);
//// reqVO.setStartTime((new LocalTime()));
//// reqVO.setEndTime((new LocalTime[]{}));
//// reqVO.setCreateTime((new Date[]{}));
//
// // 调用
// PageResult<SeckillConfigDO> pageResult = SeckillConfigService.getSeckillConfigPage(reqVO);
// // 断言
// assertEquals(1, pageResult.getTotal());
// assertEquals(1, pageResult.getList().size());
// assertPojoEquals(dbSeckillConfig, pageResult.getList().get(0));
}
@Test
@Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
public void testGetSeckillConfigList() {
// mock 数据
SeckillConfigDO dbSeckillConfig = randomPojo(SeckillConfigDO.class, o -> { // 等会查询到
o.setName(null);
o.setStartTime(null);
o.setEndTime(null);
o.setCreateTime(null);
});
seckillConfigMapper.insert(dbSeckillConfig);
// 测试 name 不匹配
seckillConfigMapper.insert(cloneIgnoreId(dbSeckillConfig, o -> o.setName(null)));
// 测试 startTime 不匹配
seckillConfigMapper.insert(cloneIgnoreId(dbSeckillConfig, o -> o.setStartTime(null)));
// 测试 endTime 不匹配
seckillConfigMapper.insert(cloneIgnoreId(dbSeckillConfig, o -> o.setEndTime(null)));
// 测试 createTime 不匹配
seckillConfigMapper.insert(cloneIgnoreId(dbSeckillConfig, o -> o.setCreateTime(null)));
// 准备参数
// SeckillConfigExportReqVO reqVO = new SeckillConfigExportReqVO();
// reqVO.setName(null);
// reqVO.setStartTime((new LocalTime[]{}));
// reqVO.setEndTime((new LocalTime[]{}));
// reqVO.setCreateTime((new Date[]{}));
//
// // 调用
// List<SeckillConfigDO> list = SeckillConfigService.getSeckillConfigList(reqVO);
// // 断言
// assertEquals(1, list.size());
// assertPojoEquals(dbSeckillConfig, list.get(0));
}
}

View File

@@ -1,190 +0,0 @@
package cn.iocoder.yudao.module.promotion.service.seckilltime;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeCreateReqVO;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.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)
@Disabled // TODO 芋艿:未来开启
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));
}
}

View File

@@ -4,3 +4,4 @@ DELETE FROM "promotion_coupon";
DELETE FROM "promotion_reward_activity";
DELETE FROM "promotion_discount_activity";
DELETE FROM "promotion_discount_product";
DELETE FROM "promotion_seckill_config";

View File

@@ -107,18 +107,45 @@ CREATE TABLE IF NOT EXISTS "promotion_discount_activity" (
PRIMARY KEY ("id")
) COMMENT '限时折扣活动';
CREATE TABLE IF NOT EXISTS "promotion_discount_product" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"activity_id" bigint NOT NULL,
"spu_id" bigint NOT NULL,
"sku_id" bigint NOT NULL,
"discount_type" int NOT NULL,
"discount_percent" int,
"discount_price" int,
"creator" varchar DEFAULT '',
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar DEFAULT '',
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
PRIMARY KEY ("id")
) COMMENT '限时折扣活动';
-- 将该建表 SQL 语句添加到 yudao-module-promotion-biz 模块的 test/resources/sql/create_tables.sql 文件里
CREATE TABLE IF NOT EXISTS "promotion_seckill_activity" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"spu_id" bigint NOT NULL,
"name" varchar NOT NULL,
"status" int NOT NULL,
"remark" varchar,
"start_time" varchar NOT NULL,
"end_time" varchar NOT NULL,
"sort" int NOT NULL,
"config_ids" varchar NOT NULL,
"order_count" int NOT NULL,
"user_count" int NOT NULL,
"total_price" int NOT NULL,
"total_limit_count" int,
"single_limit_count" int,
"stock" int,
"total_stock" int,
"creator" varchar DEFAULT '',
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar DEFAULT '',
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
"tenant_id" bigint NOT NULL,
PRIMARY KEY ("id")
) COMMENT '秒杀活动';
CREATE TABLE IF NOT EXISTS "promotion_seckill_config" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"name" varchar NOT NULL,
"start_time" varchar NOT NULL,
"end_time" varchar NOT NULL,
"pic_url" varchar NOT NULL,
"status" int NOT NULL,
"creator" varchar DEFAULT '',
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar DEFAULT '',
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
"tenant_id" bigint NOT NULL,
PRIMARY KEY ("id")
) COMMENT '秒杀时段配置';