mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-22 07:11:52 +08:00
fix:完善 mall seckill 相关 ②
This commit is contained in:
parent
b44ad3a0f7
commit
ab30ff6480
@ -1,7 +1,7 @@
|
||||
package cn.iocoder.yudao.module.product.api.sku;
|
||||
|
||||
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
|
||||
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
|
||||
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@ -30,6 +30,14 @@ public interface ProductSkuApi {
|
||||
*/
|
||||
List<ProductSkuRespDTO> getSkuList(Collection<Long> ids);
|
||||
|
||||
/**
|
||||
* 批量查询 SKU 数组
|
||||
*
|
||||
* @param spuIds SPU 编号列表
|
||||
* @return SKU 数组
|
||||
*/
|
||||
List<ProductSkuRespDTO> getSkuListBySpuId(List<Long> spuIds);
|
||||
|
||||
/**
|
||||
* 更新 SKU 库存
|
||||
*
|
||||
|
@ -42,6 +42,15 @@ public class ProductSkuApiImpl implements ProductSkuApi {
|
||||
return ProductSkuConvert.INSTANCE.convertList04(skus);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProductSkuRespDTO> getSkuListBySpuId(List<Long> spuIds) {
|
||||
if (CollUtil.isEmpty(spuIds)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<ProductSkuDO> skus = productSkuService.getSkuListBySpuId(spuIds);
|
||||
return ProductSkuConvert.INSTANCE.convertList04(skus);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSkuStock(ProductSkuUpdateStockReqDTO updateStockReqDTO) {
|
||||
productSkuService.updateSkuStock(updateStockReqDTO);
|
||||
|
@ -1,6 +1,6 @@
|
||||
package cn.iocoder.yudao.module.product.api.spu;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
|
||||
import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
|
||||
@ -14,7 +14,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* TODO LeeYan9: 类注释;
|
||||
* 商品 SPU API 接口实现类
|
||||
*
|
||||
* @author LeeYan9
|
||||
* @since 2022-09-06
|
||||
@ -28,11 +28,12 @@ public class ProductSpuApiImpl implements ProductSpuApi {
|
||||
|
||||
@Override
|
||||
public List<ProductSpuRespDTO> getSpuList(Collection<Long> spuIds) {
|
||||
// TODO TODO LeeYan9: AllEmpty?
|
||||
if (CollectionUtils.isAnyEmpty(spuIds)) {
|
||||
// TODO 需不需要判断集合中是否有 null 值
|
||||
if (CollectionUtil.isEmpty(spuIds)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<ProductSpuDO> productSpuDOList = productSpuMapper.selectBatchIds(spuIds);
|
||||
return ProductSpuConvert.INSTANCE.convertList2(productSpuDOList);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ public interface ProductSkuService {
|
||||
* 批量创建 SKU
|
||||
*
|
||||
* @param spuId 商品 SPU 编号
|
||||
* @param list SKU 对象集合
|
||||
* @param list SKU 对象集合
|
||||
*/
|
||||
void createSkuList(Long spuId, List<ProductSkuCreateOrUpdateReqVO> list);
|
||||
|
||||
@ -63,13 +63,13 @@ public interface ProductSkuService {
|
||||
* 根据 SPU 编号,批量更新它的 SKU 信息
|
||||
*
|
||||
* @param spuId SPU 编码
|
||||
* @param skus SKU 的集合
|
||||
* @param skus SKU 的集合
|
||||
*/
|
||||
void updateSkuList(Long spuId, List<ProductSkuCreateOrUpdateReqVO> skus);
|
||||
|
||||
/**
|
||||
* 更新 SKU 库存(增量)
|
||||
*
|
||||
* <p>
|
||||
* 如果更新的库存不足,会抛出异常
|
||||
*
|
||||
* @param updateStockReqDTO 更行请求
|
||||
@ -88,7 +88,7 @@ public interface ProductSkuService {
|
||||
* 获得 spu 对应的 SKU 集合
|
||||
*
|
||||
* @param spuIds spu 编码集合
|
||||
* @return 商品 sku 集合
|
||||
* @return 商品 sku 集合
|
||||
*/
|
||||
List<ProductSkuDO> getSkuListBySpuId(List<Long> spuIds);
|
||||
|
||||
@ -123,4 +123,5 @@ public interface ProductSkuService {
|
||||
* @return int 影响的行数
|
||||
*/
|
||||
int updateSkuPropertyValue(Long propertyValueId, String propertyValueName);
|
||||
|
||||
}
|
||||
|
@ -1,17 +1,14 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* 秒杀活动基地签证官
|
||||
@ -23,18 +20,14 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DE
|
||||
@Data
|
||||
public class SeckillActivityBaseVO {
|
||||
|
||||
@Schema(description = "秒杀活动商品", requiredMode = Schema.RequiredMode.REQUIRED, example = "121")
|
||||
@Schema(description = "秒杀活动商品id", requiredMode = Schema.RequiredMode.REQUIRED, example = "[121,1212]")
|
||||
@NotNull(message = "秒杀活动商品不能为空")
|
||||
private Long spuId;
|
||||
private List<Long> spuIds;
|
||||
|
||||
@Schema(description = "秒杀活动名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "618大促")
|
||||
@NotNull(message = "秒杀活动名称不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "活动状态 开启:0 禁用:1", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
|
||||
@NotNull(message = "活动状态 开启:0 禁用:1不能为空")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "备注", example = "清仓大甩卖割韭菜")
|
||||
private String remark;
|
||||
|
||||
@ -52,8 +45,8 @@ public class SeckillActivityBaseVO {
|
||||
@NotNull(message = "排序不能为空")
|
||||
private Integer sort;
|
||||
|
||||
@Schema(description = "秒杀时段id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "秒杀时段id不能为空")
|
||||
@Schema(description = "秒杀时段id", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1,2,3]")
|
||||
@NotNull(message = "秒杀时段不能为空")
|
||||
private List<Long> configIds;
|
||||
|
||||
@Schema(description = "总限购数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "12877")
|
||||
|
@ -6,7 +6,6 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -24,8 +23,10 @@ public class SeckillActivityRespVO extends SeckillActivityBaseVO {
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "秒杀商品", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<SeckillProductRespVO> products;
|
||||
private List<SeckillProductRespVO> products; // TODO puhui: 考虑是否去除
|
||||
|
||||
@Schema(description = "活动状态 开启:0 禁用:1", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
|
||||
private Integer status;
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,12 +1,9 @@
|
||||
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;
|
||||
import javax.validation.constraints.*;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import lombok.Data;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 秒杀参与商品 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
@ -17,15 +14,7 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
|
||||
@Data
|
||||
public class SeckillProductBaseVO {
|
||||
|
||||
@Schema(description = "秒杀活动id", requiredMode = Schema.RequiredMode.REQUIRED, example = "20173")
|
||||
@NotNull(message = "秒杀活动id不能为空")
|
||||
private Long activityId;
|
||||
|
||||
@Schema(description = "秒杀时段id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "秒杀时段id不能为空")
|
||||
private String configIds;
|
||||
|
||||
@Schema(description = "商品spu_id", requiredMode = Schema.RequiredMode.REQUIRED, example = "10290")
|
||||
@Schema(description = "商品spu_id", requiredMode = Schema.RequiredMode.REQUIRED, example = "30563")
|
||||
@NotNull(message = "商品spu_id不能为空")
|
||||
private Long spuId;
|
||||
|
||||
@ -41,18 +30,5 @@ public class SeckillProductBaseVO {
|
||||
@NotNull(message = "秒杀库存不能为空")
|
||||
private Integer stock;
|
||||
|
||||
@Schema(description = "秒杀商品状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "秒杀商品状态不能为空")
|
||||
private Integer activityStatus;
|
||||
|
||||
@Schema(description = "活动开始时间点", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "活动开始时间点不能为空")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime activityStartTime;
|
||||
|
||||
@Schema(description = "活动结束时间点", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "活动结束时间点不能为空")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime activityEndTime;
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
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.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityDetailRespVO;
|
||||
@ -12,6 +13,7 @@ import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -47,7 +49,7 @@ public interface SeckillActivityConvert {
|
||||
* @return 是否匹配
|
||||
*/
|
||||
default boolean isEquals(SeckillProductDO productDO, SeckillProductCreateReqVO productVO) {
|
||||
return ObjectUtil.equals(productDO.getSpuId(), productVO.getSpuId())
|
||||
return ObjectUtil.equals(productDO.getSpuId(), 1) // TODO puhui:再看看
|
||||
&& ObjectUtil.equals(productDO.getSkuId(), productVO.getSkuId())
|
||||
&& ObjectUtil.equals(productDO.getSeckillPrice(), productVO.getSeckillPrice());
|
||||
//&& ObjectUtil.equals(productDO.getQuota(), productVO.getQuota())
|
||||
@ -65,9 +67,25 @@ public interface SeckillActivityConvert {
|
||||
return ObjectUtil.equals(productDO.getSpuId(), productVO.getSpuId())
|
||||
&& ObjectUtil.equals(productDO.getSkuId(), productVO.getSkuId())
|
||||
&& ObjectUtil.equals(productDO.getSeckillPrice(), productVO.getSeckillPrice());
|
||||
//&& ObjectUtil.equals(productDO.getQuota(), productVO.getQuota())
|
||||
//&& ObjectUtil.equals(productDO.getLimitCount(), productVO.getLimitCount());
|
||||
//&& ObjectUtil.equals(productDO.getQuota(), productVO.getQuota())
|
||||
//&& ObjectUtil.equals(productDO.getLimitCount(), productVO.getLimitCount());
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ 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;
|
||||
@ -35,7 +34,8 @@ public class SeckillActivityDO extends BaseDO {
|
||||
/**
|
||||
* 秒杀活动商品
|
||||
*/
|
||||
private Long spuId;
|
||||
@TableField(typeHandler = LongListTypeHandler.class)
|
||||
private List<Long> spuIds;
|
||||
/**
|
||||
* 秒杀活动名称
|
||||
*/
|
||||
|
@ -1,9 +1,16 @@
|
||||
package cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity;
|
||||
|
||||
import lombok.*;
|
||||
import java.time.LocalDateTime;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
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.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
|
||||
@ -32,7 +39,8 @@ public class SeckillProductDO extends BaseDO {
|
||||
/**
|
||||
* 秒杀时段 id
|
||||
*/
|
||||
private String configIds;
|
||||
@TableField(typeHandler = LongListTypeHandler.class)
|
||||
private List<Long> configIds;
|
||||
/**
|
||||
* 商品 spu_id
|
||||
*/
|
||||
@ -51,6 +59,7 @@ public class SeckillProductDO extends BaseDO {
|
||||
private Integer stock;
|
||||
/**
|
||||
* 秒杀商品状态
|
||||
* 枚举 {@link CommonStatusEnum 对应的类}
|
||||
*/
|
||||
private Integer activityStatus;
|
||||
/**
|
||||
|
@ -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
|
||||
*
|
||||
@ -23,4 +25,9 @@ public interface SeckillActivityMapper extends BaseMapperX<SeckillActivityDO> {
|
||||
.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));
|
||||
}
|
||||
}
|
||||
|
@ -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,16 +1,19 @@
|
||||
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.controller.admin.seckill.vo.product.SeckillProductCreateReqVO;
|
||||
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;
|
||||
@ -25,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;
|
||||
|
||||
@ -45,40 +52,94 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
|
||||
private SeckillProductMapper seckillProductMapper;
|
||||
@Resource
|
||||
private SeckillConfigService seckillConfigService;
|
||||
@Resource
|
||||
private ProductSpuApi productSpuApi;
|
||||
@Resource
|
||||
private ProductSkuApi productSkuApi;
|
||||
|
||||
@Override
|
||||
public Long createSeckillActivity(SeckillActivityCreateReqVO createReqVO) {
|
||||
// 校验商品是否冲突
|
||||
validateSeckillActivityProductConflicts(null, createReqVO.getProducts());
|
||||
// 校验秒杀时段是否存在
|
||||
seckillConfigService.validateSeckillConfigExists(createReqVO.getConfigIds());
|
||||
// 校验商品秒秒杀时段是否冲突
|
||||
validateProductSpuSeckillConflict(createReqVO.getConfigIds(), createReqVO.getSpuIds());
|
||||
// 校验商品 sku 是否存在
|
||||
validateProductSkuExistence(createReqVO.getSpuIds(), createReqVO.getProducts());
|
||||
|
||||
// 插入秒杀活动 TODO 活动日期拼接上秒杀时段 -> 2023-06-08 09:00:00
|
||||
// 插入秒杀活动
|
||||
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);
|
||||
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);
|
||||
//updateSeckillProduct(updateReqVO);
|
||||
}
|
||||
|
||||
|
||||
@ -92,10 +153,11 @@ 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)));
|
||||
@ -116,37 +178,6 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
|
||||
seckillProductMapper.updateTimeIdsByActivityId(updateReqVO.getId(), updateReqVO.getConfigIds());
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验商品是否冲突
|
||||
*
|
||||
* @param id 秒杀活动编号
|
||||
* @param products 商品列表
|
||||
*/
|
||||
private <T extends SeckillProductBaseVO> void validateSeckillActivityProductConflicts(Long id, List<T> products) {
|
||||
if (CollUtil.isEmpty(products)) {
|
||||
return;
|
||||
}
|
||||
// 校验秒杀商品是否存在
|
||||
List<SeckillProductDO> seckillProductDOs = seckillProductMapper
|
||||
.selectListBySkuIds(CollectionUtils.convertSet(products, T::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()));
|
||||
}
|
||||
// 排除关闭了的活动
|
||||
seckillActivityDOs.removeIf(item -> ObjectUtil.equal(item.getStatus(), CommonStatusEnum.DISABLE.getStatus()));
|
||||
// 如果非空,则说明冲突
|
||||
if (CollUtil.isNotEmpty(seckillActivityDOs)) {
|
||||
throw exception(SECKILL_ACTIVITY_SPU_CONFLICTS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeSeckillActivity(Long id) {
|
||||
// 校验存在
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user