promotion:完善秒杀的 uniapp 接口
This commit is contained in:
parent
ac55a9657c
commit
a1e9bedf34
@ -79,7 +79,8 @@ public class LocalDateTimeUtils {
|
||||
return false;
|
||||
}
|
||||
LocalDate nowDate = LocalDate.now();
|
||||
return LocalDateTimeUtil.isIn(LocalDateTime.now(), LocalDateTime.of(nowDate, LocalTime.parse(startTime)),
|
||||
return LocalDateTimeUtil.isIn(LocalDateTime.now(),
|
||||
LocalDateTime.of(nowDate, LocalTime.parse(startTime)),
|
||||
LocalDateTime.of(nowDate, LocalTime.parse(endTime)));
|
||||
}
|
||||
|
||||
@ -98,46 +99,6 @@ public class LocalDateTimeUtils {
|
||||
LocalDateTime.of(nowDate, startTime2), LocalDateTime.of(nowDate, endTime2));
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建日期时间 TODO 后面有需要的话再继续扩展
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
public static class BuilderDateTime {
|
||||
|
||||
/**
|
||||
* 日期;2023-10-01
|
||||
*/
|
||||
private String localDate;
|
||||
/**
|
||||
* 时间;10:01:00
|
||||
*/
|
||||
private String localTime;
|
||||
|
||||
public BuilderDateTime() {
|
||||
}
|
||||
|
||||
public BuilderDateTime withDate(String date) {
|
||||
this.localDate = date;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BuilderDateTime withDate(LocalDateTime date) {
|
||||
this.localDate = LocalDateTimeUtil.format(date, "yyyy-MM-dd");
|
||||
return this;
|
||||
}
|
||||
|
||||
public BuilderDateTime withTime(String time) {
|
||||
this.localTime = time;
|
||||
return this;
|
||||
}
|
||||
|
||||
public LocalDateTime build() {
|
||||
return LocalDateTimeUtil.parse(this.localDate + " " + this.localTime, "yyyy-MM-dd HH:mm:ss");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定日期所在的月份的开始时间
|
||||
* 例如:2023-09-30 00:00:00,000
|
||||
|
@ -5,6 +5,7 @@ import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
|
||||
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.app.seckill.vo.activity.AppSeckillActivityDetailRespVO;
|
||||
@ -13,10 +14,12 @@ import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppS
|
||||
import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityRespVO;
|
||||
import cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity.SeckillActivityConvert;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillProductDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillConfigDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillProductDO;
|
||||
import cn.iocoder.yudao.module.promotion.service.seckill.SeckillActivityService;
|
||||
import cn.iocoder.yudao.module.promotion.service.seckill.SeckillConfigService;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
@ -28,16 +31,37 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.cache.CacheUtils.buildAsyncReloadingCache;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.findFirst;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.isBetween;
|
||||
|
||||
@Tag(name = "用户 App - 秒杀活动")
|
||||
@RestController
|
||||
@RequestMapping("/promotion/seckill-activity")
|
||||
@Validated
|
||||
public class AppSeckillActivityController {
|
||||
|
||||
/**
|
||||
* {@link AppSeckillActivityNowRespVO} 缓存,通过它异步刷新 {@link #getNowSeckillActivity()} 所要的首页数据
|
||||
*/
|
||||
private final LoadingCache<String, AppSeckillActivityNowRespVO> nowSeckillActivityCache = buildAsyncReloadingCache(Duration.ofSeconds(10L),
|
||||
new CacheLoader<String, AppSeckillActivityNowRespVO>() {
|
||||
|
||||
@Override
|
||||
public AppSeckillActivityNowRespVO load(String key) {
|
||||
return getNowSeckillActivity0();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@Resource
|
||||
private SeckillActivityService activityService;
|
||||
@Resource
|
||||
@ -47,21 +71,25 @@ public class AppSeckillActivityController {
|
||||
@Resource
|
||||
private ProductSpuApi spuApi;
|
||||
|
||||
// TODO 芋艿:需要增加 spring cache
|
||||
@GetMapping("/get-now")
|
||||
@Operation(summary = "获得当前秒杀活动", description = "获取当前正在进行的活动,提供给首页使用")
|
||||
public CommonResult<AppSeckillActivityNowRespVO> getNowSeckillActivity() {
|
||||
return success(nowSeckillActivityCache.getUnchecked(""));
|
||||
}
|
||||
|
||||
private AppSeckillActivityNowRespVO getNowSeckillActivity0() {
|
||||
// 1. 获取当前时间处在哪个秒杀阶段
|
||||
SeckillConfigDO configList = configService.getSeckillConfigListByStatusOnCurrentTime(CommonStatusEnum.ENABLE.getStatus());
|
||||
if (configList == null) { // 时段不存在直接返回 null
|
||||
return success(null);
|
||||
SeckillConfigDO config = configService.getCurrentSeckillConfig();
|
||||
if (config == null) { // 时段不存在直接返回 null
|
||||
return new AppSeckillActivityNowRespVO();
|
||||
}
|
||||
|
||||
// 2. 查询满足当前阶段的活动
|
||||
List<SeckillActivityDO> activityList = activityService.getSeckillActivityListByConfigIdAndStatus(configList.getId(), CommonStatusEnum.ENABLE.getStatus());
|
||||
// 3 获取 spu 信息
|
||||
// 2.1 查询满足当前阶段的活动
|
||||
List<SeckillActivityDO> activityList = activityService.getSeckillActivityListByConfigIdAndStatus(config.getId(), CommonStatusEnum.ENABLE.getStatus());
|
||||
List<SeckillProductDO> productList = activityService.getSeckillProductListByActivityId(convertList(activityList, SeckillActivityDO::getId));
|
||||
// 2.2 获取 spu 信息
|
||||
List<ProductSpuRespDTO> spuList = spuApi.getSpuList(convertList(activityList, SeckillActivityDO::getSpuId));
|
||||
return success(SeckillActivityConvert.INSTANCE.convert(configList, activityList, spuList));
|
||||
return SeckillActivityConvert.INSTANCE.convert(config, activityList, productList, spuList);
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@ -72,31 +100,52 @@ public class AppSeckillActivityController {
|
||||
if (CollUtil.isEmpty(pageResult.getList())) {
|
||||
return success(PageResult.empty(pageResult.getTotal()));
|
||||
}
|
||||
List<SeckillProductDO> productList = activityService.getSeckillProductListByActivityId(
|
||||
convertList(pageResult.getList(), SeckillActivityDO::getId));
|
||||
|
||||
// 2. 拼接数据
|
||||
List<ProductSpuRespDTO> spuList = spuApi.getSpuList(convertList(pageResult.getList(), SeckillActivityDO::getSpuId));
|
||||
return success(SeckillActivityConvert.INSTANCE.convertPage(pageResult, spuList));
|
||||
return success(SeckillActivityConvert.INSTANCE.convertPage02(pageResult, productList, spuList));
|
||||
}
|
||||
|
||||
@GetMapping("/get-detail")
|
||||
@Operation(summary = "获得秒杀活动明细")
|
||||
@Parameter(name = "id", description = "活动编号", required = true, example = "1024")
|
||||
public CommonResult<AppSeckillActivityDetailRespVO> getSeckillActivity(@RequestParam("id") Long id) {
|
||||
// 1. 获取当前时间处在哪个秒杀阶段
|
||||
SeckillConfigDO configList = configService.getSeckillConfigListByStatusOnCurrentTime(CommonStatusEnum.ENABLE.getStatus());
|
||||
if (configList == null) { // 时段不存在直接返回 null
|
||||
// 1. 获取活动
|
||||
SeckillActivityDO activity = activityService.getSeckillActivity(id);
|
||||
if (activity == null
|
||||
|| ObjectUtil.equal(activity.getStatus(), CommonStatusEnum.DISABLE.getStatus())) {
|
||||
return success(null);
|
||||
}
|
||||
|
||||
// 2. 获取活动
|
||||
SeckillActivityDO seckillActivity = activityService.getSeckillActivity(id);
|
||||
if (seckillActivity == null
|
||||
|| ObjectUtil.equal(seckillActivity.getStatus(), CommonStatusEnum.DISABLE.getStatus())) {
|
||||
return success(null);
|
||||
// 2. 获取时间段
|
||||
List<SeckillConfigDO> configs = configService.getSeckillConfigListByStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
configs.removeIf(config -> !CollUtil.contains(activity.getConfigIds(), config.getId()));
|
||||
// 2.1 优先使用当前时间段
|
||||
SeckillConfigDO config = findFirst(configs, config0 -> isBetween(config0.getStartTime(), config0.getEndTime()));
|
||||
// 2.2 如果没有,则获取最后一个,因为倾向优先展示“未开始” > “已结束”
|
||||
if (config == null) {
|
||||
config = CollUtil.getLast(configs);
|
||||
}
|
||||
if (config == null) {
|
||||
return null;
|
||||
}
|
||||
// 3. 计算开始时间、结束时间
|
||||
LocalDate nowDate;
|
||||
// 3.1 如果在活动日期范围内,则以今天为 nowDate
|
||||
if (LocalDateTimeUtils.isBetween(activity.getStartTime(), activity.getEndTime())) {
|
||||
nowDate = LocalDate.now();
|
||||
} else {
|
||||
// 3.2 如果不在活动时间范围内,则直接以活动的 endTime 作为 nowDate,因为还是倾向优先展示“未开始” > “已结束”
|
||||
nowDate = activity.getEndTime().toLocalDate();
|
||||
}
|
||||
LocalDateTime startTime = LocalDateTime.of(nowDate, LocalTime.parse(config.getStartTime()));
|
||||
LocalDateTime endTime = LocalDateTime.of(nowDate, LocalTime.parse(config.getEndTime()));
|
||||
|
||||
// 3. 拼接数据
|
||||
List<SeckillProductDO> productList = activityService.getSeckillProductListByActivityId(seckillActivity.getId());
|
||||
return success(SeckillActivityConvert.INSTANCE.convert3(seckillActivity, productList, configList));
|
||||
// 4. 拼接数据
|
||||
List<SeckillProductDO> productList = activityService.getSeckillProductListByActivityId(activity.getId());
|
||||
return success(SeckillActivityConvert.INSTANCE.convert3(activity, productList, startTime, endTime));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.config.AppSeckillConfigRespVO;
|
||||
import cn.iocoder.yudao.module.promotion.convert.seckill.seckillconfig.SeckillConfigConvert;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillConfigDO;
|
||||
import cn.iocoder.yudao.module.promotion.service.seckill.SeckillConfigService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
@ -28,8 +29,8 @@ public class AppSeckillConfigController {
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "获得秒杀时间段列表")
|
||||
public CommonResult<List<AppSeckillConfigRespVO>> getSeckillConfigList() {
|
||||
return success(SeckillConfigConvert.INSTANCE.convertList2(
|
||||
configService.getSeckillConfigListByStatus(CommonStatusEnum.ENABLE.getStatus())));
|
||||
List<SeckillConfigDO> list = configService.getSeckillConfigListByStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
return success(SeckillConfigConvert.INSTANCE.convertList2(list));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,8 +19,6 @@ public class AppSeckillActivityDetailRespVO {
|
||||
@Schema(description = "活动状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer status;
|
||||
|
||||
// TODO @芋艿:开始时间、结束时间,要和场次结合起来;就是要算到当前场次,是几点哈;
|
||||
|
||||
@Schema(description = "活动开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime startTime;
|
||||
|
||||
|
@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
|
||||
import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;
|
||||
import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
|
||||
import cn.iocoder.yudao.module.product.enums.DictTypeConstants;
|
||||
@ -19,17 +18,18 @@ import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppS
|
||||
import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityRespVO;
|
||||
import cn.iocoder.yudao.module.promotion.convert.seckill.seckillconfig.SeckillConfigConvert;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillProductDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillConfigDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillProductDO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.Mappings;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
|
||||
|
||||
/**
|
||||
@ -93,16 +93,19 @@ public interface SeckillActivityConvert {
|
||||
|
||||
List<AppSeckillActivityRespVO> convertList3(List<SeckillActivityDO> activityList);
|
||||
|
||||
default AppSeckillActivityNowRespVO convert(SeckillConfigDO filteredConfig, List<SeckillActivityDO> activityList, List<ProductSpuRespDTO> spuList) {
|
||||
default AppSeckillActivityNowRespVO convert(SeckillConfigDO filteredConfig, List<SeckillActivityDO> activityList,
|
||||
List<SeckillProductDO> productList, List<ProductSpuRespDTO> spuList) {
|
||||
AppSeckillActivityNowRespVO respVO = new AppSeckillActivityNowRespVO();
|
||||
respVO.setConfig(SeckillConfigConvert.INSTANCE.convert1(filteredConfig));
|
||||
Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId);
|
||||
Map<Long, List<SeckillProductDO>> productMap = convertMultiMap(productList, SeckillProductDO::getActivityId);
|
||||
respVO.setActivities(CollectionUtils.convertList(convertList3(activityList), item -> {
|
||||
findAndThen(spuMap, item.getSpuId(), spu -> {
|
||||
item.setPicUrl(spu.getPicUrl())
|
||||
.setMarketPrice(spu.getMarketPrice())
|
||||
.setUnitName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.PRODUCT_UNIT, spu.getUnit()));
|
||||
});
|
||||
// product 信息
|
||||
item.setSeckillPrice(getMinValue(productMap.get(item.getId()), SeckillProductDO::getSeckillPrice));
|
||||
// spu 信息
|
||||
findAndThen(spuMap, item.getSpuId(), spu ->
|
||||
item.setPicUrl(spu.getPicUrl()).setMarketPrice(spu.getMarketPrice())
|
||||
.setUnitName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.PRODUCT_UNIT, spu.getUnit())));
|
||||
return item;
|
||||
}));
|
||||
return respVO;
|
||||
@ -110,10 +113,14 @@ public interface SeckillActivityConvert {
|
||||
|
||||
PageResult<AppSeckillActivityRespVO> convertPage1(PageResult<SeckillActivityDO> pageResult);
|
||||
|
||||
default PageResult<AppSeckillActivityRespVO> convertPage(PageResult<SeckillActivityDO> pageResult, List<ProductSpuRespDTO> spuList) {
|
||||
default PageResult<AppSeckillActivityRespVO> convertPage02(PageResult<SeckillActivityDO> pageResult, List<SeckillProductDO> productList, List<ProductSpuRespDTO> spuList) {
|
||||
PageResult<AppSeckillActivityRespVO> result = convertPage1(pageResult);
|
||||
Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId);
|
||||
Map<Long, List<SeckillProductDO>> productMap = convertMultiMap(productList, SeckillProductDO::getActivityId);
|
||||
List<AppSeckillActivityRespVO> list = CollectionUtils.convertList(result.getList(), item -> {
|
||||
// product 信息
|
||||
item.setSeckillPrice(getMinValue(productMap.get(item.getId()), SeckillProductDO::getSeckillPrice));
|
||||
// spu 信息
|
||||
findAndThen(spuMap, item.getSpuId(), spu -> item.setPicUrl(spu.getPicUrl()).setMarketPrice(spu.getMarketPrice())
|
||||
.setUnitName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.PRODUCT_UNIT, spu.getUnit())));
|
||||
return item;
|
||||
@ -126,17 +133,11 @@ public interface SeckillActivityConvert {
|
||||
|
||||
List<AppSeckillActivityDetailRespVO.Product> convertList1(List<SeckillProductDO> products);
|
||||
|
||||
default AppSeckillActivityDetailRespVO convert3(SeckillActivityDO seckillActivity, List<SeckillProductDO> products, SeckillConfigDO filteredConfig) {
|
||||
return convert2(seckillActivity)
|
||||
default AppSeckillActivityDetailRespVO convert3(SeckillActivityDO activity, List<SeckillProductDO> products,
|
||||
LocalDateTime startTime, LocalDateTime endTime) {
|
||||
return convert2(activity)
|
||||
.setProducts(convertList1(products))
|
||||
.setStartTime(new LocalDateTimeUtils.BuilderDateTime()
|
||||
.withDate(seckillActivity.getStartTime())
|
||||
.withTime(filteredConfig.getStartTime())
|
||||
.build())// 活动开始日期和时段结合
|
||||
.setEndTime(new LocalDateTimeUtils.BuilderDateTime()
|
||||
.withDate(seckillActivity.getEndTime())
|
||||
.withTime(filteredConfig.getEndTime())
|
||||
.build()); // 活动结束日期和时段结合
|
||||
.setStartTime(startTime).setEndTime(endTime);
|
||||
}
|
||||
|
||||
List<SeckillActivityProductRespDTO> convertList4(List<SeckillProductDO> seckillActivityProductList);
|
||||
|
@ -66,18 +66,7 @@ public class SeckillActivityDO extends BaseDO {
|
||||
*/
|
||||
@TableField(typeHandler = LongListTypeHandler.class)
|
||||
private List<Long> configIds;
|
||||
/**
|
||||
* 新增订单数
|
||||
*/
|
||||
private Integer orderCount;
|
||||
/**
|
||||
* 付款人数
|
||||
*/
|
||||
private Integer userCount;
|
||||
/**
|
||||
* 订单实付金额,单位:分
|
||||
*/
|
||||
private Long totalPrice;
|
||||
|
||||
/**
|
||||
* 总限购数量
|
||||
*/
|
||||
@ -86,6 +75,7 @@ public class SeckillActivityDO extends BaseDO {
|
||||
* 单次限够数量
|
||||
*/
|
||||
private Integer singleLimitCount;
|
||||
|
||||
/**
|
||||
* 秒杀库存(剩余库存秒杀时扣减)
|
||||
*/
|
||||
|
@ -89,14 +89,6 @@ public interface SeckillActivityService {
|
||||
*/
|
||||
List<SeckillProductDO> getSeckillProductListByActivityId(Collection<Long> activityIds);
|
||||
|
||||
/**
|
||||
* 通过活动时段获取秒杀活动
|
||||
*
|
||||
* @param ids 时段配置编号
|
||||
* @return 秒杀活动列表
|
||||
*/
|
||||
List<SeckillActivityDO> getSeckillActivityListByConfigIds(Collection<Long> ids);
|
||||
|
||||
/**
|
||||
* 通过活动时段编号获取指定 status 的秒杀活动
|
||||
*
|
||||
|
@ -18,7 +18,6 @@ import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillActivityD
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.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.util.PromotionUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
@ -60,17 +59,18 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long createSeckillActivity(SeckillActivityCreateReqVO createReqVO) {
|
||||
// 校验商品秒杀时段是否冲突
|
||||
// 1.1 校验商品秒杀时段是否冲突
|
||||
validateProductConflict(createReqVO.getConfigIds(), createReqVO.getSpuId(), null);
|
||||
// 校验商品是否存在
|
||||
// 1.2 校验商品是否存在
|
||||
validateProductExists(createReqVO.getSpuId(), createReqVO.getProducts());
|
||||
|
||||
// 插入秒杀活动
|
||||
// 2.1 插入秒杀活动
|
||||
SeckillActivityDO activity = SeckillActivityConvert.INSTANCE.convert(createReqVO)
|
||||
.setStatus(PromotionUtils.calculateActivityStatus(createReqVO.getEndTime()))
|
||||
.setTotalStock(getSumValue(createReqVO.getProducts(), SeckillProductBaseVO::getStock, Integer::sum));
|
||||
.setStatus(CommonStatusEnum.ENABLE.getStatus())
|
||||
.setStock(getSumValue(createReqVO.getProducts(), SeckillProductBaseVO::getStock, Integer::sum));
|
||||
activity.setTotalStock(activity.getStock());
|
||||
seckillActivityMapper.insert(activity);
|
||||
// 插入商品
|
||||
// 2.2 插入商品
|
||||
List<SeckillProductDO> products = SeckillActivityConvert.INSTANCE.convertList(createReqVO.getProducts(), activity);
|
||||
seckillProductMapper.insertBatch(products);
|
||||
return activity.getId();
|
||||
@ -128,22 +128,24 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateSeckillActivity(SeckillActivityUpdateReqVO updateReqVO) {
|
||||
// 校验存在
|
||||
SeckillActivityDO seckillActivity = validateSeckillActivityExists(updateReqVO.getId());
|
||||
if (CommonStatusEnum.DISABLE.getStatus().equals(seckillActivity.getStatus())) {
|
||||
// 1.1 校验存在
|
||||
SeckillActivityDO activity = validateSeckillActivityExists(updateReqVO.getId());
|
||||
if (CommonStatusEnum.DISABLE.getStatus().equals(activity.getStatus())) {
|
||||
throw exception(SECKILL_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED);
|
||||
}
|
||||
// 校验商品是否冲突
|
||||
// 1.2 校验商品是否冲突
|
||||
validateProductConflict(updateReqVO.getConfigIds(), updateReqVO.getSpuId(), updateReqVO.getId());
|
||||
// 校验商品是否存在
|
||||
// 1.3 校验商品是否存在
|
||||
validateProductExists(updateReqVO.getSpuId(), updateReqVO.getProducts());
|
||||
|
||||
// 更新活动
|
||||
// 2.1 更新活动
|
||||
SeckillActivityDO updateObj = SeckillActivityConvert.INSTANCE.convert(updateReqVO)
|
||||
.setStatus(PromotionUtils.calculateActivityStatus(updateReqVO.getEndTime()))
|
||||
.setTotalStock(getSumValue(updateReqVO.getProducts(), SeckillProductBaseVO::getStock, Integer::sum));
|
||||
.setStock(getSumValue(updateReqVO.getProducts(), SeckillProductBaseVO::getStock, Integer::sum));
|
||||
if (updateObj.getStock() > activity.getTotalStock()) { // 如果更新的库存大于原来的库存,则更新总库存
|
||||
updateObj.setTotalStock(updateObj.getStock());
|
||||
}
|
||||
seckillActivityMapper.updateById(updateObj);
|
||||
// 更新商品
|
||||
// 2.2 更新商品
|
||||
updateSeckillProduct(updateObj, updateReqVO.getProducts());
|
||||
}
|
||||
|
||||
@ -151,7 +153,7 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateSeckillStock(Long id, Long skuId, Integer count) {
|
||||
// 1.1 校验活动库存是否充足
|
||||
SeckillActivityDO seckillActivity = getSeckillActivity(id);
|
||||
SeckillActivityDO seckillActivity = validateSeckillActivityExists(id);
|
||||
if (count > seckillActivity.getTotalStock()) {
|
||||
throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL);
|
||||
}
|
||||
@ -243,7 +245,7 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
|
||||
|
||||
@Override
|
||||
public SeckillActivityDO getSeckillActivity(Long id) {
|
||||
return validateSeckillActivityExists(id);
|
||||
return seckillActivityMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -261,12 +263,6 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
|
||||
return seckillProductMapper.selectListByActivityId(activityIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SeckillActivityDO> getSeckillActivityListByConfigIds(Collection<Long> ids) {
|
||||
return filterList(seckillActivityMapper.selectList(),
|
||||
item -> anyMatch(item.getConfigIds(), ids::contains));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SeckillActivityDO> getSeckillActivityListByConfigIdAndStatus(Long configId, Integer status) {
|
||||
return filterList(seckillActivityMapper.selectList(SeckillActivityDO::getStatus, status),
|
||||
@ -289,7 +285,6 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
|
||||
if (CollectionUtil.isEmpty(productList)) {
|
||||
throw exception(SKU_NOT_EXISTS);
|
||||
}
|
||||
|
||||
return productList;
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,6 @@ public interface SeckillConfigService {
|
||||
*/
|
||||
List<SeckillConfigDO> getSeckillConfigList();
|
||||
|
||||
|
||||
/**
|
||||
* 校验秒杀时段是否存在
|
||||
*
|
||||
@ -87,11 +86,12 @@ public interface SeckillConfigService {
|
||||
void updateSeckillConfigStatus(Long id, Integer status);
|
||||
|
||||
/**
|
||||
* 获取当前日期时间处于的秒杀时段且状态为 status
|
||||
* 获得当前的秒杀时段
|
||||
*
|
||||
* 要求必须处于开启状态、且在当前时间段内
|
||||
*
|
||||
* @param status 状态
|
||||
* @return 时段
|
||||
*/
|
||||
SeckillConfigDO getSeckillConfigListByStatusOnCurrentTime(Integer status);
|
||||
SeckillConfigDO getCurrentSeckillConfig();
|
||||
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ import org.springframework.validation.annotation.Validated;
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalTime;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
@ -70,9 +71,9 @@ public class SeckillConfigServiceImpl implements SeckillConfigService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public SeckillConfigDO getSeckillConfigListByStatusOnCurrentTime(Integer status) {
|
||||
return findFirst(seckillConfigMapper.selectList(SeckillConfigDO::getStatus, status),
|
||||
config -> isBetween(config.getStartTime(), config.getEndTime()));
|
||||
public SeckillConfigDO getCurrentSeckillConfig() {
|
||||
List<SeckillConfigDO> list = seckillConfigMapper.selectList(SeckillConfigDO::getStatus, CommonStatusEnum.ENABLE.getStatus());
|
||||
return findFirst(list, config -> isBetween(config.getStartTime(), config.getEndTime()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -151,7 +152,9 @@ public class SeckillConfigServiceImpl implements SeckillConfigService {
|
||||
|
||||
@Override
|
||||
public List<SeckillConfigDO> getSeckillConfigListByStatus(Integer status) {
|
||||
return seckillConfigMapper.selectListByStatus(status);
|
||||
List<SeckillConfigDO> list = seckillConfigMapper.selectListByStatus(status);
|
||||
list.sort(Comparator.comparing(SeckillConfigDO::getStartTime));
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user