code review:限时折扣活动
This commit is contained in:
parent
90fb2c62b8
commit
785fbeeb5b
6
pom.xml
6
pom.xml
@ -13,14 +13,14 @@
|
||||
<!-- Server 主项目 -->
|
||||
<module>yudao-server</module>
|
||||
<!-- 各种 module 拓展 -->
|
||||
<!-- <module>yudao-module-member</module>-->
|
||||
<module>yudao-module-member</module>
|
||||
<module>yudao-module-system</module>
|
||||
<module>yudao-module-infra</module>
|
||||
<!-- <module>yudao-module-bpm</module>-->
|
||||
<!-- <module>yudao-module-report</module>-->
|
||||
<!-- <module>yudao-module-mp</module>-->
|
||||
<!-- <module>yudao-module-pay</module>-->
|
||||
<!-- <module>yudao-module-mall</module>-->
|
||||
<module>yudao-module-pay</module>
|
||||
<module>yudao-module-mall</module>
|
||||
<!-- 示例项目 -->
|
||||
<module>yudao-example</module>
|
||||
</modules>
|
||||
|
@ -15,7 +15,6 @@ public interface ErrorCodeConstants {
|
||||
ErrorCode DISCOUNT_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1_013_001_002, "限时折扣活动已关闭,不能修改");
|
||||
ErrorCode DISCOUNT_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED = new ErrorCode(1_013_001_003, "限时折扣活动未关闭,不能删除");
|
||||
ErrorCode DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1_013_001_004, "限时折扣活动已关闭,不能重复关闭");
|
||||
ErrorCode DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_END = new ErrorCode(1_013_001_005, "限时折扣活动已结束,不能关闭");
|
||||
|
||||
// ========== Banner 相关 1-013-002-000 ============
|
||||
ErrorCode BANNER_NOT_EXISTS = new ErrorCode(1_013_002_000, "Banner 不存在");
|
||||
|
@ -7,11 +7,8 @@ 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.discount.vo.*;
|
||||
import cn.iocoder.yudao.module.promotion.convert.discount.DiscountActivityConvert;
|
||||
import cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity.SeckillActivityConvert;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO;
|
||||
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.service.discount.DiscountActivityService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
@ -23,8 +20,6 @@ import org.springframework.web.bind.annotation.*;
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
@ -94,7 +89,7 @@ public class DiscountActivityController {
|
||||
public CommonResult<PageResult<DiscountActivityRespVO>> getDiscountActivityPage(@Valid DiscountActivityPageReqVO pageVO) {
|
||||
PageResult<DiscountActivityDO> pageResult = discountActivityService.getDiscountActivityPage(pageVO);
|
||||
|
||||
if (CollUtil.isEmpty(pageResult.getList())) {
|
||||
if (CollUtil.isEmpty(pageResult.getList())) { // TODO @zhangshuai:方法里的空行,目的是让代码分块,可以更清晰;所以上面这个空格可以不要,而下面判断之后的,空格,其实加下比较好;类似的还有 spuList、以及后面的 convert
|
||||
return success(PageResult.empty(pageResult.getTotal()));
|
||||
}
|
||||
// 拼接数据
|
||||
|
@ -26,15 +26,16 @@ public class DiscountActivityRespVO extends DiscountActivityBaseVO {
|
||||
private LocalDateTime createTime;
|
||||
|
||||
|
||||
@Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048")
|
||||
@Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048") // TODO @zhangshuai:属性和属性之间,最多空一行噢;
|
||||
private Long spuId;
|
||||
|
||||
@Schema(description = "限时折扣商品", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<DiscountActivityBaseVO.Product> products;
|
||||
|
||||
|
||||
// ========== 商品字段 ==========
|
||||
|
||||
// TODO @zhangshuai:一个优惠活动,会关联多个商品,所以它不用返回 spuName 哈;
|
||||
// TODO 最终界面展示字段就:编号、活动名称、参与商品数、活动状态、开始时间、结束时间、操作
|
||||
@Schema(description = "商品名称", requiredMode = Schema.RequiredMode.REQUIRED, // 从 SPU 的 name 读取
|
||||
example = "618大促")
|
||||
private String spuName;
|
||||
@ -45,5 +46,4 @@ public class DiscountActivityRespVO extends DiscountActivityBaseVO {
|
||||
example = "50")
|
||||
private Integer marketPrice;
|
||||
|
||||
|
||||
}
|
||||
|
@ -7,11 +7,8 @@ import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
|
||||
import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
|
||||
import cn.iocoder.yudao.module.promotion.api.discount.dto.DiscountProductRespDTO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.*;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityRespVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductRespVO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillProductDO;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
@ -47,7 +44,7 @@ public interface DiscountActivityConvert {
|
||||
List<ProductSpuRespDTO> spuList) {
|
||||
PageResult<DiscountActivityRespVO> pageResult = convertPage(page);
|
||||
|
||||
// 拼接商品
|
||||
// 拼接商品 TODO @zhangshuai:类似空行的问题,也可以看看
|
||||
Map<Long, DiscountProductDO> discountActivityMap = CollectionUtils.convertMap(discountProductDOList, DiscountProductDO::getActivityId);
|
||||
Map<Long, ProductSpuRespDTO> spuMap = CollectionUtils.convertMap(spuList, ProductSpuRespDTO::getId);
|
||||
pageResult.getList().forEach(item -> {
|
||||
|
@ -34,7 +34,6 @@ public class DiscountProductDO extends BaseDO {
|
||||
*/
|
||||
private Long activityId;
|
||||
|
||||
|
||||
/**
|
||||
* 商品 SPU 编号
|
||||
*
|
||||
@ -67,7 +66,6 @@ public class DiscountProductDO extends BaseDO {
|
||||
*/
|
||||
private Integer discountPrice;
|
||||
|
||||
// TODO 芋艿:这几个字段,要新增下;
|
||||
/**
|
||||
* 活动状态
|
||||
*
|
||||
|
@ -28,6 +28,6 @@ public interface DiscountProductMapper extends BaseMapperX<DiscountProductDO> {
|
||||
return selectList(DiscountProductDO::getActivityId, activityIds);
|
||||
}
|
||||
|
||||
|
||||
// TODO @zhangshuai:逻辑里,尽量避免写 join 语句哈,你可以看看这个查询,有什么办法优化?目前的一个思路,是分 2 次查询,性能也是 ok 的
|
||||
List<DiscountProductDO> getMatchDiscountProductList(@Param("skuIds") Collection<Long> skuIds);
|
||||
}
|
||||
|
@ -36,6 +36,8 @@ public interface CombinationActivityService {
|
||||
*/
|
||||
void updateCombinationActivity(@Valid CombinationActivityUpdateReqVO updateReqVO);
|
||||
|
||||
// TODO @puhui999:这里少了一个关闭活动的接口;因为关闭的活动,才可以删除
|
||||
|
||||
/**
|
||||
* 删除拼团活动
|
||||
*
|
||||
|
@ -43,7 +43,7 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
|
||||
|
||||
@Override
|
||||
public List<DiscountProductDO> getMatchDiscountProductList(Collection<Long> skuIds) {
|
||||
// 芋艿:开启、满足 skuId、日期内
|
||||
// TODO @zhangshuai:这里是不是可以直接 return discountProductMapper.getMatchDiscountProductList(skuIds); 一般来说,如果 idea 报“黄色”的警告,尽量都处理下哈;原则是,一切警告,皆为异常(错误),这样可以写出更好的代码。
|
||||
List<DiscountProductDO> matchDiscountProductList = discountProductMapper.getMatchDiscountProductList(skuIds);
|
||||
return matchDiscountProductList;
|
||||
}
|
||||
@ -55,9 +55,11 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
|
||||
|
||||
// 插入活动
|
||||
DiscountActivityDO discountActivity = DiscountActivityConvert.INSTANCE.convert(createReqVO)
|
||||
// TODO @zhangshuai:这里的调用去掉哈,强制就是开启的;
|
||||
.setStatus(PromotionUtils.calculateActivityStatus(createReqVO.getEndTime()));
|
||||
discountActivityMapper.insert(discountActivity);
|
||||
// 插入商品
|
||||
// TODO @zhangshuai:activityStatus 最好代码里,也做下设置噢。
|
||||
List<DiscountProductDO> discountProducts = convertList(createReqVO.getProducts(),
|
||||
product -> DiscountActivityConvert.INSTANCE.convert(product).setActivityId(discountActivity.getId()));
|
||||
discountProductMapper.insertBatch(discountProducts);
|
||||
@ -84,6 +86,8 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
|
||||
}
|
||||
|
||||
private void updateDiscountProduct(DiscountActivityUpdateReqVO updateReqVO) {
|
||||
// TODO @zhangshuai:这里的逻辑,可以优化下哈;参考 CombinationActivityServiceImpl 的 updateCombinationProduct,主要是 CollectionUtils.diffList 的使用哈;
|
||||
// 然后原先是使用 DiscountActivityConvert.INSTANCE.isEquals 对比,现在看看是不是简化就基于 skuId 对比就完事了;之前写的太精细,意义不大;
|
||||
List<DiscountProductDO> dbDiscountProducts = discountProductMapper.selectListByActivityId(updateReqVO.getId());
|
||||
// 计算要删除的记录
|
||||
List<Long> deleteIds = convertList(dbDiscountProducts, DiscountProductDO::getId,
|
||||
@ -102,7 +106,6 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
|
||||
}
|
||||
}
|
||||
|
||||
// 芋艿:校验逻辑简化,只查询时间冲突的活动,开启状态的。
|
||||
/**
|
||||
* 校验商品是否冲突
|
||||
*
|
||||
@ -114,13 +117,11 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
|
||||
return;
|
||||
}
|
||||
// 查询商品参加的活动
|
||||
|
||||
// TODO @zhangshuai:下面 121 这个查询,是不是不用做呀;直接 convert 出 skuId 集合就 ok 啦;
|
||||
List<DiscountProductDO> list = discountProductMapper.selectListByActivityId(id);
|
||||
// TODO @zhangshuai:一般简单的 stream 方法,建议是使用 CollectionUtils,例如说这里是 convertList 对把。
|
||||
List<Long> skuIds = list.stream().map(item -> item.getSkuId()).collect(Collectors.toList());
|
||||
List<DiscountProductDO> matchDiscountProductList = getMatchDiscountProductList(skuIds);
|
||||
// getRewardProductListBySkuIds(
|
||||
// convertSet(products, DiscountActivityBaseVO.Product::getSkuId),
|
||||
// asList(PromotionActivityStatusEnum.WAIT.getStatus(), PromotionActivityStatusEnum.RUN.getStatus()));
|
||||
if (id != null) { // 排除自己这个活动
|
||||
matchDiscountProductList.removeIf(product -> id.equals(product.getActivityId()));
|
||||
}
|
||||
@ -133,15 +134,12 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
|
||||
@Override
|
||||
public void closeDiscountActivity(Long id) {
|
||||
// 校验存在
|
||||
DiscountActivityDO dbDiscountActivity = validateDiscountActivityExists(id);
|
||||
if (dbDiscountActivity.getStatus().equals(CommonStatusEnum.DISABLE.getStatus())) { // 已关闭的活动,不能关闭噢
|
||||
DiscountActivityDO activity = validateDiscountActivityExists(id);
|
||||
if (activity.getStatus().equals(CommonStatusEnum.DISABLE.getStatus())) { // 已关闭的活动,不能关闭噢
|
||||
throw exception(DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED);
|
||||
}
|
||||
if (dbDiscountActivity.getStatus().equals(CommonStatusEnum.DISABLE.getStatus())) { // 已关闭的活动,不能关闭噢
|
||||
throw exception(DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_END);
|
||||
}
|
||||
|
||||
// 更新为关闭。
|
||||
// 更新
|
||||
DiscountActivityDO updateObj = new DiscountActivityDO().setId(id).setStatus(PromotionActivityStatusEnum.CLOSE.getStatus());
|
||||
discountActivityMapper.updateById(updateObj);
|
||||
}
|
||||
@ -185,4 +183,5 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
|
||||
public List<DiscountProductDO> getDiscountProductsByActivityId(Collection<Long> activityIds) {
|
||||
return discountProductMapper.selectList("activity_id", activityIds);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -37,11 +37,11 @@
|
||||
</dependency>
|
||||
|
||||
<!-- 会员中心。默认注释,保证编译速度 -->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>cn.iocoder.boot</groupId>-->
|
||||
<!-- <artifactId>yudao-module-member-biz</artifactId>-->
|
||||
<!-- <version>${revision}</version>-->
|
||||
<!-- </dependency>-->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-module-member-biz</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 数据报表。默认注释,保证编译速度 -->
|
||||
<!-- <dependency>-->
|
||||
@ -56,40 +56,40 @@
|
||||
<!-- <version>${revision}</version>-->
|
||||
<!-- </dependency>-->
|
||||
<!-- 支付服务。默认注释,保证编译速度 -->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>cn.iocoder.boot</groupId>-->
|
||||
<!-- <artifactId>yudao-module-pay-biz</artifactId>-->
|
||||
<!-- <version>${revision}</version>-->
|
||||
<!-- </dependency>-->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-module-pay-biz</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 微信公众号模块。默认注释,保证编译速度 -->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>cn.iocoder.boot</groupId>-->
|
||||
<!-- <artifactId>yudao-module-mp-biz</artifactId>-->
|
||||
<!-- <version>${revision}</version>-->
|
||||
<!-- </dependency>-->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-module-mp-biz</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 商城相关模块。默认注释,保证编译速度 -->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>cn.iocoder.boot</groupId>-->
|
||||
<!-- <artifactId>yudao-module-promotion-biz</artifactId>-->
|
||||
<!-- <version>${revision}</version>-->
|
||||
<!-- </dependency>-->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>cn.iocoder.boot</groupId>-->
|
||||
<!-- <artifactId>yudao-module-product-biz</artifactId>-->
|
||||
<!-- <version>${revision}</version>-->
|
||||
<!-- </dependency>-->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>cn.iocoder.boot</groupId>-->
|
||||
<!-- <artifactId>yudao-module-trade-biz</artifactId>-->
|
||||
<!-- <version>${revision}</version>-->
|
||||
<!-- </dependency>-->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>cn.iocoder.boot</groupId>-->
|
||||
<!-- <artifactId>yudao-module-statistics-biz</artifactId>-->
|
||||
<!-- <version>${revision}</version>-->
|
||||
<!-- </dependency>-->
|
||||
<!-- 商城相关模块。默认注释,保证编译速度-->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-module-promotion-biz</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-module-product-biz</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-module-trade-biz</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-module-statistics-biz</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- spring boot 配置所需依赖 -->
|
||||
<dependency>
|
||||
|
Loading…
Reference in New Issue
Block a user