mirror of
https://gitee.com/hhyykk/ipms-sjy.git
synced 2025-08-23 06:31:52 +08:00
!522 mall seckill
Merge pull request !522 from puhui999/feature/mall_product
This commit is contained in:
@@ -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));
|
||||
}
|
||||
}
|
@@ -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));
|
||||
}
|
||||
}
|
@@ -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;
|
||||
|
||||
}
|
||||
|
@@ -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;
|
||||
|
||||
}
|
||||
|
@@ -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;
|
||||
|
||||
}
|
||||
|
@@ -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)
|
||||
|
@@ -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;
|
||||
|
||||
|
||||
}
|
||||
|
@@ -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;
|
||||
|
||||
}
|
||||
|
@@ -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;
|
||||
|
||||
}
|
@@ -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 {
|
||||
|
||||
}
|
@@ -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;
|
||||
|
||||
}
|
@@ -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;
|
||||
|
||||
}
|
@@ -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;
|
||||
|
||||
}
|
@@ -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 = "编号不能为空")
|
@@ -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;
|
||||
|
||||
}
|
@@ -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;
|
||||
|
||||
|
||||
}
|
@@ -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 {
|
||||
|
||||
}
|
@@ -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;
|
||||
|
||||
}
|
@@ -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;
|
||||
|
||||
}
|
@@ -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;
|
||||
|
||||
}
|
||||
|
@@ -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;
|
||||
|
||||
}
|
||||
|
@@ -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;
|
||||
|
||||
}
|
||||
|
@@ -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;
|
||||
|
||||
}
|
||||
|
@@ -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;
|
||||
|
||||
}
|
||||
|
@@ -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;
|
||||
|
||||
}
|
||||
|
@@ -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;
|
||||
|
||||
}
|
||||
|
@@ -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;
|
||||
|
||||
}
|
||||
|
@@ -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;
|
||||
|
||||
}
|
||||
|
@@ -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;
|
||||
|
||||
}
|
||||
|
@@ -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;
|
||||
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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);
|
||||
|
||||
}
|
@@ -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);
|
||||
|
||||
}
|
@@ -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;
|
||||
|
||||
}
|
||||
|
@@ -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;
|
||||
|
||||
}
|
||||
|
@@ -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") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@TableName("promotion_seckill_config")
|
||||
@KeySequence("promotion_seckill_config_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 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;
|
||||
|
||||
}
|
@@ -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));
|
||||
}
|
||||
}
|
||||
|
@@ -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();
|
||||
}
|
||||
|
@@ -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));
|
||||
}
|
||||
|
||||
}
|
@@ -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();
|
||||
}
|
||||
}
|
@@ -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);
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
@@ -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);
|
||||
}
|
||||
|
||||
}
|
@@ -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);
|
||||
}
|
@@ -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);
|
||||
}
|
||||
|
||||
}
|
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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)));
|
||||
// 准备参数
|
||||
|
@@ -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));
|
||||
}
|
||||
|
||||
}
|
@@ -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));
|
||||
}
|
||||
|
||||
}
|
@@ -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";
|
||||
|
@@ -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 '秒杀时段配置';
|
||||
|
Reference in New Issue
Block a user