|
@@ -4,10 +4,12 @@ import cn.hutool.core.collection.CollectionUtil;
|
|
|
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.date.LocalDateTimeUtils;
|
|
|
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.api.seckill.dto.SeckillValidateJoinRespDTO;
|
|
|
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;
|
|
@@ -15,10 +17,10 @@ import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.Sec
|
|
|
import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityPageReqVO;
|
|
|
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.SeckillConfigDO;
|
|
|
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 +62,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 +131,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 +156,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 +248,7 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
|
|
|
|
|
|
@Override
|
|
|
public SeckillActivityDO getSeckillActivity(Long id) {
|
|
|
- return validateSeckillActivityExists(id);
|
|
|
+ return seckillActivityMapper.selectById(id);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -261,12 +266,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),
|
|
@@ -281,16 +280,46 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
|
|
|
|
|
|
@Override
|
|
|
public List<SeckillProductDO> getSeckillActivityProductList(Long id, Collection<Long> skuIds) {
|
|
|
- // 1、校验秒杀活动是否存在
|
|
|
- validateSeckillActivityExists(id);
|
|
|
+
|
|
|
// 2、校验活动商品是否存在
|
|
|
List<SeckillProductDO> productList = filterList(seckillProductMapper.selectListByActivityId(id),
|
|
|
item -> skuIds.contains(item.getSkuId()));
|
|
|
if (CollectionUtil.isEmpty(productList)) {
|
|
|
throw exception(SKU_NOT_EXISTS);
|
|
|
}
|
|
|
-
|
|
|
return productList;
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public SeckillValidateJoinRespDTO validateJoinSeckill(Long activityId, Long skuId, Integer count) {
|
|
|
+ // 1.1 校验秒杀活动是否存在
|
|
|
+ SeckillActivityDO activity = validateSeckillActivityExists(activityId);
|
|
|
+ if (ObjectUtil.notEqual(activity.getStatus(), CommonStatusEnum.ENABLE.getStatus())) {
|
|
|
+ throw exception(SECKILL_JOIN_ACTIVITY_STATUS_CLOSED);
|
|
|
+ }
|
|
|
+ // 1.2 是否在活动时间范围内
|
|
|
+ if (!LocalDateTimeUtils.isBetween(activity.getStartTime(), activity.getEndTime())) {
|
|
|
+ throw exception(SECKILL_JOIN_ACTIVITY_TIME_ERROR);
|
|
|
+ }
|
|
|
+ SeckillConfigDO config = seckillConfigService.getCurrentSeckillConfig();
|
|
|
+ if (config == null || !CollectionUtil.contains(activity.getConfigIds(), config.getId())) {
|
|
|
+ throw exception(SECKILL_JOIN_ACTIVITY_TIME_ERROR);
|
|
|
+ }
|
|
|
+ // 1.3 超过单次购买限制
|
|
|
+ if (count > activity.getSingleLimitCount()) {
|
|
|
+ throw exception(SECKILL_JOIN_ACTIVITY_SINGLE_LIMIT_COUNT_EXCEED);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2.1 校验秒杀商品是否存在
|
|
|
+ SeckillProductDO product = seckillProductMapper.selectByActivityIdAndSkuId(activityId, skuId);
|
|
|
+ if (product == null) {
|
|
|
+ throw exception(SECKILL_JOIN_ACTIVITY_PRODUCT_NOT_EXISTS);
|
|
|
+ }
|
|
|
+ // 2.2 校验库存是否充足
|
|
|
+ if (count > product.getStock()) {
|
|
|
+ throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL);
|
|
|
+ }
|
|
|
+ return SeckillActivityConvert.INSTANCE.convert02(activity, product);
|
|
|
+ }
|
|
|
+
|
|
|
}
|