Commit 2efdbf93cb0c9baba43b532595ab72b550f7ffe7
1 parent
b16632ea
mall + promotion:review 秒杀、评论代码
Showing
34 changed files
with
58 additions
and
139 deletions
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApi.java
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApiImpl.java
| ... | ... | @@ -28,7 +28,6 @@ public class ProductSpuApiImpl implements ProductSpuApi { |
| 28 | 28 | |
| 29 | 29 | @Override |
| 30 | 30 | public List<ProductSpuRespDTO> getSpuList(Collection<Long> spuIds) { |
| 31 | - // TODO 需不需要判断集合中是否有 null 值 | |
| 32 | 31 | if (CollectionUtil.isEmpty(spuIds)) { |
| 33 | 32 | return Collections.emptyList(); |
| 34 | 33 | } | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentBaseVO.java
| ... | ... | @@ -26,6 +26,7 @@ public class ProductCommentBaseVO { |
| 26 | 26 | @NotNull(message = "评价人头像不能为空") |
| 27 | 27 | private String userAvatar; |
| 28 | 28 | |
| 29 | + // TODO @puhui:spuId、spuName 是不是只有 ProductCommentRespVO 有呀。 | |
| 29 | 30 | @Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "清凉丝滑透气小短袖") |
| 30 | 31 | @NotNull(message = "商品 SPU 编号不能为空") |
| 31 | 32 | private Long spuId; |
| ... | ... | @@ -54,7 +55,7 @@ public class ProductCommentBaseVO { |
| 54 | 55 | @NotNull(message = "评论内容不能为空") |
| 55 | 56 | private String content; |
| 56 | 57 | |
| 57 | - @Schema(description = "评论图片地址数组,以逗号分隔最多上传 9 张", requiredMode = Schema.RequiredMode.REQUIRED, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]") | |
| 58 | + @Schema(description = "评论图片地址数组,以逗号分隔最多上传 9 张", requiredMode = Schema.RequiredMode.REQUIRED, example = "[https://www.iocoder.cn/xx.png]") | |
| 58 | 59 | @Size(max = 9, message = "评论图片地址数组长度不能超过 9 张") |
| 59 | 60 | private List<String> picUrls; |
| 60 | 61 | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentPageReqVO.java
| ... | ... | @@ -35,6 +35,7 @@ public class ProductCommentPageReqVO extends PageParam { |
| 35 | 35 | @InEnum(ProductCommentScoresEnum.class) |
| 36 | 36 | private Integer scores; |
| 37 | 37 | |
| 38 | + // TODO @puhui999:replyStatus 哈 | |
| 38 | 39 | @Schema(description = "商家是否回复", example = "true") |
| 39 | 40 | private Boolean replied; |
| 40 | 41 | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentReplyReqVO.java
| ... | ... | @@ -7,7 +7,7 @@ import lombok.ToString; |
| 7 | 7 | import javax.validation.constraints.NotEmpty; |
| 8 | 8 | import javax.validation.constraints.NotNull; |
| 9 | 9 | |
| 10 | -@Schema(description = "管理后台 - 商品评价可见修改 Request VO") | |
| 10 | +@Schema(description = "管理后台 - 商品评价的商家回复 Request VO") | |
| 11 | 11 | @Data |
| 12 | 12 | @ToString(callSuper = true) |
| 13 | 13 | public class ProductCommentReplyReqVO { | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppProductCommentController.java
| ... | ... | @@ -56,19 +56,20 @@ public class AppProductCommentController { |
| 56 | 56 | public CommonResult<List<AppProductCommentRespVO>> getCommentList(@RequestParam("spuId") Long spuId, |
| 57 | 57 | @RequestParam(value = "count", defaultValue = "10") Integer count) { |
| 58 | 58 | return success(productCommentService.getCommentList(spuId, count)); |
| 59 | - | |
| 60 | 59 | } |
| 61 | 60 | |
| 62 | 61 | @GetMapping("/page") |
| 63 | 62 | @Operation(summary = "获得商品评价分页") |
| 64 | 63 | public CommonResult<PageResult<AppProductCommentRespVO>> getCommentPage(@Valid AppCommentPageReqVO pageVO) { |
| 65 | 64 | PageResult<AppProductCommentRespVO> page = productCommentService.getCommentPage(pageVO, Boolean.TRUE); |
| 65 | + // TODO @puhui CollUtils 有简化 convertmap 和 list 的方法 | |
| 66 | 66 | Set<Long> skuIds = page.getList().stream().map(AppProductCommentRespVO::getSkuId).collect(Collectors.toSet()); |
| 67 | 67 | List<ProductSkuDO> skuList = productSkuService.getSkuList(skuIds); |
| 68 | 68 | Map<Long, ProductSkuDO> skuDOMap = new HashMap<>(skuIds.size()); |
| 69 | 69 | if (CollUtil.isNotEmpty(skuList)) { |
| 70 | 70 | skuDOMap.putAll(skuList.stream().collect(Collectors.toMap(ProductSkuDO::getId, c -> c))); |
| 71 | 71 | } |
| 72 | + // TODO @puihui999:下面也可以放到 convert 里哈 | |
| 72 | 73 | page.getList().forEach(item -> { |
| 73 | 74 | // 判断用户是否选择匿名 |
| 74 | 75 | if (ObjectUtil.equal(item.getAnonymous(), true)) { |
| ... | ... | @@ -83,6 +84,7 @@ public class AppProductCommentController { |
| 83 | 84 | return success(page); |
| 84 | 85 | } |
| 85 | 86 | |
| 87 | + // TODO 芋艿:需要搞下 | |
| 86 | 88 | @GetMapping("/getCommentStatistics") |
| 87 | 89 | @Operation(summary = "获得商品的评价统计") |
| 88 | 90 | public CommonResult<AppCommentStatisticsRespVO> getCommentStatistics(@Valid @RequestParam("spuId") Long spuId) { | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentCreateReqVO.java deleted
| 1 | -package cn.iocoder.yudao.module.product.controller.app.comment.vo; | |
| 2 | - | |
| 3 | -import io.swagger.v3.oas.annotations.media.Schema; | |
| 4 | -import lombok.Data; | |
| 5 | -import lombok.ToString; | |
| 6 | - | |
| 7 | -import javax.validation.constraints.NotNull; | |
| 8 | -import javax.validation.constraints.Size; | |
| 9 | -import java.util.List; | |
| 10 | - | |
| 11 | -@Schema(description = "用户 App - 商品评价创建 Request VO") | |
| 12 | -@Data | |
| 13 | -@ToString(callSuper = true) | |
| 14 | -public class AppProductCommentCreateReqVO { | |
| 15 | - | |
| 16 | - @Schema(description = "是否匿名", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") | |
| 17 | - @NotNull(message = "是否匿名不能为空") | |
| 18 | - private Boolean anonymous; | |
| 19 | - | |
| 20 | - @Schema(description = "交易订单项编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2312312") | |
| 21 | - @NotNull(message = "交易订单项编号不能为空") | |
| 22 | - private Long orderItemId; | |
| 23 | - | |
| 24 | - @Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "91192") | |
| 25 | - @NotNull(message = "商品SPU编号不能为空") | |
| 26 | - private Long spuId; | |
| 27 | - | |
| 28 | - @Schema(description = "商品 SPU 名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "清凉丝滑小短袖") | |
| 29 | - @NotNull(message = "商品SPU名称不能为空") | |
| 30 | - private String spuName; | |
| 31 | - | |
| 32 | - @Schema(description = "商品 SKU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "81192") | |
| 33 | - @NotNull(message = "商品SKU编号不能为空") | |
| 34 | - private Long skuId; | |
| 35 | - | |
| 36 | - @Schema(description = "评分星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5") | |
| 37 | - @NotNull(message = "评分星级 1-5 分不能为空") | |
| 38 | - private Integer scores; | |
| 39 | - | |
| 40 | - @Schema(description = "描述星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5") | |
| 41 | - @NotNull(message = "描述星级 1-5 分不能为空") | |
| 42 | - private Integer descriptionScores; | |
| 43 | - | |
| 44 | - @Schema(description = "服务星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5") | |
| 45 | - @NotNull(message = "服务星级 1-5 分不能为空") | |
| 46 | - private Integer benefitScores; | |
| 47 | - | |
| 48 | - @Schema(description = "评论内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "哇,真的很丝滑凉快诶,好评") | |
| 49 | - @NotNull(message = "评论内容不能为空") | |
| 50 | - private String content; | |
| 51 | - | |
| 52 | - @Schema(description = "评论图片地址数组,以逗号分隔最多上传 9 张", requiredMode = Schema.RequiredMode.REQUIRED, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]") | |
| 53 | - @Size(max = 9, message = "评论图片地址数组长度不能超过 9 张") | |
| 54 | - private List<String> picUrls; | |
| 55 | - | |
| 56 | -} |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentRespVO.java
| ... | ... | @@ -4,15 +4,12 @@ import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProdu |
| 4 | 4 | import io.swagger.v3.oas.annotations.media.Schema; |
| 5 | 5 | import lombok.Data; |
| 6 | 6 | import lombok.ToString; |
| 7 | -import org.springframework.format.annotation.DateTimeFormat; | |
| 8 | 7 | |
| 9 | 8 | import javax.validation.constraints.NotNull; |
| 10 | 9 | import javax.validation.constraints.Size; |
| 11 | 10 | import java.time.LocalDateTime; |
| 12 | 11 | import java.util.List; |
| 13 | 12 | |
| 14 | -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | |
| 15 | - | |
| 16 | 13 | /** |
| 17 | 14 | * 用户 App - 商品评价详情 Response VO |
| 18 | 15 | * |
| ... | ... | @@ -54,7 +51,6 @@ public class AppProductCommentRespVO { |
| 54 | 51 | private String replyContent; |
| 55 | 52 | |
| 56 | 53 | @Schema(description = "商家回复时间") |
| 57 | - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | |
| 58 | 54 | private LocalDateTime replyTime; |
| 59 | 55 | |
| 60 | 56 | @Schema(description = "追加评价内容", example = "穿了很久都很丝滑诶") |
| ... | ... | @@ -64,23 +60,21 @@ public class AppProductCommentRespVO { |
| 64 | 60 | private List<String> additionalPicUrls; |
| 65 | 61 | |
| 66 | 62 | @Schema(description = "追加评价时间") |
| 67 | - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | |
| 68 | 63 | private LocalDateTime additionalTime; |
| 69 | 64 | |
| 70 | 65 | @Schema(description = "创建时间") |
| 71 | - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | |
| 72 | 66 | private LocalDateTime createTime; |
| 73 | 67 | |
| 74 | - @Schema(description = "商品SPU编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "91192") | |
| 75 | - @NotNull(message = "商品SPU编号不能为空") | |
| 68 | + @Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "91192") | |
| 69 | + @NotNull(message = "商品 SPU 编号不能为空") | |
| 76 | 70 | private Long spuId; |
| 77 | 71 | |
| 78 | - @Schema(description = "商品SPU名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "清凉丝滑小短袖") | |
| 79 | - @NotNull(message = "商品SPU名称不能为空") | |
| 72 | + @Schema(description = "商品 SPU 名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "清凉丝滑小短袖") | |
| 73 | + @NotNull(message = "商品 SPU 名称不能为空") | |
| 80 | 74 | private String spuName; |
| 81 | 75 | |
| 82 | - @Schema(description = "商品SKU编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "81192") | |
| 83 | - @NotNull(message = "商品SKU编号不能为空") | |
| 76 | + @Schema(description = "商品 SKU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "81192") | |
| 77 | + @NotNull(message = "商品 SKU 编号不能为空") | |
| 84 | 78 | private Long skuId; |
| 85 | 79 | |
| 86 | 80 | @Schema(description = "商品 SKU 属性", requiredMode = Schema.RequiredMode.REQUIRED) |
| ... | ... | @@ -102,7 +96,7 @@ public class AppProductCommentRespVO { |
| 102 | 96 | @NotNull(message = "评论内容不能为空") |
| 103 | 97 | private String content; |
| 104 | 98 | |
| 105 | - @Schema(description = "评论图片地址数组,以逗号分隔最多上传 9 张", requiredMode = Schema.RequiredMode.REQUIRED, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]") | |
| 99 | + @Schema(description = "评论图片地址数组,以逗号分隔最多上传 9 张", requiredMode = Schema.RequiredMode.REQUIRED, example = "[https://www.iocoder.cn/xx.png]") | |
| 106 | 100 | @Size(max = 9, message = "评论图片地址数组长度不能超过 9 张") |
| 107 | 101 | private List<String> picUrls; |
| 108 | 102 | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java
| ... | ... | @@ -32,6 +32,7 @@ public interface ProductCommentConvert { |
| 32 | 32 | |
| 33 | 33 | ProductCommentRespVO convert(ProductCommentDO bean); |
| 34 | 34 | |
| 35 | + // TODO @puhui999:这里貌似字段对上,就不用 mapping 了;可以测试下看看哈 | |
| 35 | 36 | @Mapping(target = "allCount", source = "allCount") |
| 36 | 37 | @Mapping(target = "goodCount", source = "goodCount") |
| 37 | 38 | @Mapping(target = "mediocreCount", source = "mediocreCount") | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java
| ... | ... | @@ -25,7 +25,6 @@ public interface ProductCommentMapper extends BaseMapperX<ProductCommentDO> { |
| 25 | 25 | .orderByDesc(ProductCommentDO::getId)); |
| 26 | 26 | } |
| 27 | 27 | |
| 28 | - // TODO 芋艿:在看看这块 | |
| 29 | 28 | static void appendTabQuery(LambdaQueryWrapperX<ProductCommentDO> queryWrapper, Integer type) { |
| 30 | 29 | // 构建好评查询语句:好评计算 总评 >= 4 |
| 31 | 30 | if (ObjectUtil.equal(type, AppCommentPageReqVO.GOOD_COMMENT)) { | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java
| ... | ... | @@ -149,13 +149,15 @@ public class ProductCommentServiceImpl implements ProductCommentService { |
| 149 | 149 | @Override |
| 150 | 150 | public List<AppProductCommentRespVO> getCommentList(Long spuId, Integer count) { |
| 151 | 151 | // 校验商品 spu 是否存在 |
| 152 | + // TODO @puhui 这里校验可以去掉哈。 | |
| 152 | 153 | ProductSpuDO spuDO = validateSpu(spuId); |
| 153 | - | |
| 154 | 154 | return ProductCommentConvert.INSTANCE.convertList02(productCommentMapper.selectCommentList(spuDO.getId(), count).getList()); |
| 155 | 155 | } |
| 156 | 156 | |
| 157 | + // TODO @puhui 可以放到 controller 去 convert 哈 | |
| 157 | 158 | @Override |
| 158 | 159 | public PageResult<AppProductCommentRespVO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible) { |
| 160 | + // TODO @puhui 可以放到 controller 去 convert 哈 | |
| 159 | 161 | return ProductCommentConvert.INSTANCE.convertPage02( |
| 160 | 162 | productCommentMapper.selectPage(pageVO, visible)); |
| 161 | 163 | } | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityBaseVO.java
| ... | ... | @@ -20,6 +20,7 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ |
| 20 | 20 | @Data |
| 21 | 21 | public class SeckillActivityBaseVO { |
| 22 | 22 | |
| 23 | + // TODO @puhui999:对应单 spuId 哈 | |
| 23 | 24 | @Schema(description = "秒杀活动商品id", requiredMode = Schema.RequiredMode.REQUIRED, example = "[121,1212]") |
| 24 | 25 | @NotNull(message = "秒杀活动商品不能为空") |
| 25 | 26 | private List<Long> spuIds; |
| ... | ... | @@ -45,7 +46,7 @@ public class SeckillActivityBaseVO { |
| 45 | 46 | @NotNull(message = "排序不能为空") |
| 46 | 47 | private Integer sort; |
| 47 | 48 | |
| 48 | - @Schema(description = "秒杀时段id", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1,2,3]") | |
| 49 | + @Schema(description = "秒杀时段 id", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1,2,3]") | |
| 49 | 50 | @NotNull(message = "秒杀时段不能为空") |
| 50 | 51 | private List<Long> configIds; |
| 51 | 52 | |
| ... | ... | @@ -55,6 +56,7 @@ public class SeckillActivityBaseVO { |
| 55 | 56 | @Schema(description = "单次限够数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "31683") |
| 56 | 57 | private Integer singleLimitCount; |
| 57 | 58 | |
| 59 | + // TODO @puhui999:这个应该是计算出来的字段,只返回,create 和 update 不用哈 | |
| 58 | 60 | @Schema(description = "秒杀总库存", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") |
| 59 | 61 | private Integer totalStock; |
| 60 | 62 | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityCreateReqVO.java
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityDetailRespVO.java
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityRespVO.java
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityUpdateReqVO.java
| 1 | 1 | package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity; |
| 2 | 2 | |
| 3 | -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductRespVO; | |
| 4 | 3 | import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductUpdateReqVO; |
| 5 | 4 | import io.swagger.v3.oas.annotations.media.Schema; |
| 6 | 5 | import lombok.Data; |
| 7 | 6 | import lombok.EqualsAndHashCode; |
| 8 | 7 | import lombok.ToString; |
| 9 | 8 | |
| 10 | -import javax.validation.Valid; | |
| 11 | -import javax.validation.constraints.NotEmpty; | |
| 12 | -import javax.validation.constraints.NotNull; | |
| 13 | 9 | import java.util.List; |
| 14 | 10 | |
| 15 | -/** | |
| 16 | - * 管理后台 - 秒杀活动更新 Request VO | |
| 17 | - * | |
| 18 | - * @author HUIHUI | |
| 19 | - */ | |
| 20 | 11 | @Schema(description = "管理后台 - 秒杀活动更新 Request VO") |
| 21 | 12 | @Data |
| 22 | 13 | @EqualsAndHashCode(callSuper = true) |
| ... | ... | @@ -29,5 +20,4 @@ public class SeckillActivityUpdateReqVO extends SeckillActivityBaseVO { |
| 29 | 20 | @Schema(description = "秒杀商品", requiredMode = Schema.RequiredMode.REQUIRED) |
| 30 | 21 | private List<SeckillProductUpdateReqVO> products; |
| 31 | 22 | |
| 32 | - | |
| 33 | 23 | } | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigCreateReqVO.java
| ... | ... | @@ -5,11 +5,6 @@ import lombok.Data; |
| 5 | 5 | import lombok.EqualsAndHashCode; |
| 6 | 6 | import lombok.ToString; |
| 7 | 7 | |
| 8 | -/** | |
| 9 | - * 管理后台 秒杀时段创建 Request VO | |
| 10 | - * | |
| 11 | - * @author HUIHUI | |
| 12 | - */ | |
| 13 | 8 | @Schema(description = "管理后台 - 秒杀时段创建 Request VO") |
| 14 | 9 | @Data |
| 15 | 10 | @EqualsAndHashCode(callSuper = true) | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigPageReqVO.java
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigRespVO.java
| ... | ... | @@ -4,17 +4,9 @@ import io.swagger.v3.oas.annotations.media.Schema; |
| 4 | 4 | import lombok.Data; |
| 5 | 5 | import lombok.EqualsAndHashCode; |
| 6 | 6 | import lombok.ToString; |
| 7 | -import org.springframework.format.annotation.DateTimeFormat; | |
| 8 | 7 | |
| 9 | 8 | import java.time.LocalDateTime; |
| 10 | 9 | |
| 11 | -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | |
| 12 | - | |
| 13 | -/** | |
| 14 | - * 管理后台 - 秒杀时段 Response VO | |
| 15 | - * | |
| 16 | - * @author HUIHUI | |
| 17 | - */ | |
| 18 | 10 | @Schema(description = "管理后台 - 秒杀时段 Response VO") |
| 19 | 11 | @Data |
| 20 | 12 | @EqualsAndHashCode(callSuper = true) |
| ... | ... | @@ -28,7 +20,6 @@ public class SeckillConfigRespVO extends SeckillConfigBaseVO { |
| 28 | 20 | private Integer seckillActivityCount; |
| 29 | 21 | |
| 30 | 22 | @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) |
| 31 | - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | |
| 32 | 23 | private LocalDateTime createTime; |
| 33 | 24 | |
| 34 | 25 | } | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigSimpleRespVO.java
| ... | ... | @@ -7,11 +7,6 @@ import lombok.NoArgsConstructor; |
| 7 | 7 | |
| 8 | 8 | import javax.validation.constraints.NotNull; |
| 9 | 9 | |
| 10 | -/** | |
| 11 | - * 管理后台 - 秒杀时段配置精简信息 Response VO | |
| 12 | - * | |
| 13 | - * @author HUIHUI | |
| 14 | - */ | |
| 15 | 10 | @Schema(description = "管理后台 - 秒杀时段配置精简信息 Response VO") |
| 16 | 11 | @Data |
| 17 | 12 | @NoArgsConstructor | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigUpdateReqVO.java
| ... | ... | @@ -7,11 +7,6 @@ import lombok.ToString; |
| 7 | 7 | |
| 8 | 8 | import javax.validation.constraints.NotNull; |
| 9 | 9 | |
| 10 | -/** | |
| 11 | - * 管理后台 - 秒杀时段更新 Request VO | |
| 12 | - * | |
| 13 | - * @author HUIHUI | |
| 14 | - */ | |
| 15 | 10 | @Schema(description = "管理后台 - 秒杀时段更新 Request VO") |
| 16 | 11 | @Data |
| 17 | 12 | @EqualsAndHashCode(callSuper = true) | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigUpdateStatusReqVo.java
| ... | ... | @@ -7,11 +7,6 @@ import lombok.Data; |
| 7 | 7 | |
| 8 | 8 | import javax.validation.constraints.NotNull; |
| 9 | 9 | |
| 10 | -/** | |
| 11 | - * 管理后台 - 修改时段配置状态 Request VO | |
| 12 | - * | |
| 13 | - * @author HUIHUI | |
| 14 | - */ | |
| 15 | 10 | @Schema(description = "管理后台 - 修改时段配置状态 Request VO") |
| 16 | 11 | @Data |
| 17 | 12 | public class SeckillConfigUpdateStatusReqVo { |
| ... | ... | @@ -20,7 +15,7 @@ public class SeckillConfigUpdateStatusReqVo { |
| 20 | 15 | @NotNull(message = "时段配置编号不能为空") |
| 21 | 16 | private Long id; |
| 22 | 17 | |
| 23 | - @Schema(description = "状态,见 CommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | |
| 18 | + @Schema(description = "状态,见 CommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | |
| 24 | 19 | @NotNull(message = "状态不能为空") |
| 25 | 20 | @InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}") |
| 26 | 21 | private Integer status; | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/product/SeckillProductBaseVO.java
| ... | ... | @@ -14,6 +14,7 @@ import javax.validation.constraints.NotNull; |
| 14 | 14 | @Data |
| 15 | 15 | public class SeckillProductBaseVO { |
| 16 | 16 | |
| 17 | + // TODO @puhui:spuId 不用传递;因为一个秒杀活动只对应一个 SPU 哈; | |
| 17 | 18 | @Schema(description = "商品spu_id", requiredMode = Schema.RequiredMode.REQUIRED, example = "30563") |
| 18 | 19 | @NotNull(message = "商品spu_id不能为空") |
| 19 | 20 | private Long spuId; | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/activity/AppActivityController.java
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillactivity/SeckillActivityConvert.java
| ... | ... | @@ -69,7 +69,6 @@ public interface SeckillActivityConvert { |
| 69 | 69 | && ObjectUtil.equals(productDO.getSeckillPrice(), productVO.getSeckillPrice()); |
| 70 | 70 | //&& ObjectUtil.equals(productDO.getQuota(), productVO.getQuota()) |
| 71 | 71 | //&& ObjectUtil.equals(productDO.getLimitCount(), productVO.getLimitCount()); |
| 72 | - | |
| 73 | 72 | } |
| 74 | 73 | |
| 75 | 74 | default List<SeckillProductDO> convertList(SeckillActivityDO seckillActivity, List<SeckillProductCreateReqVO> products) { | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillProductDO.java
| ... | ... | @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity |
| 3 | 3 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; |
| 4 | 4 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 5 | 5 | import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler; |
| 6 | +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO; | |
| 6 | 7 | import com.baomidou.mybatisplus.annotation.KeySequence; |
| 7 | 8 | import com.baomidou.mybatisplus.annotation.TableField; |
| 8 | 9 | import com.baomidou.mybatisplus.annotation.TableId; |
| ... | ... | @@ -34,10 +35,14 @@ public class SeckillProductDO extends BaseDO { |
| 34 | 35 | private Long id; |
| 35 | 36 | /** |
| 36 | 37 | * 秒杀活动 id |
| 38 | + * | |
| 39 | + * 关联 {@link SeckillActivityDO#getId()} | |
| 37 | 40 | */ |
| 38 | 41 | private Long activityId; |
| 39 | 42 | /** |
| 40 | 43 | * 秒杀时段 id |
| 44 | + * | |
| 45 | + * 关联 {@link SeckillConfigDO#getId()} | |
| 41 | 46 | */ |
| 42 | 47 | @TableField(typeHandler = LongListTypeHandler.class) |
| 43 | 48 | private List<Long> configIds; |
| ... | ... | @@ -57,8 +62,10 @@ public class SeckillProductDO extends BaseDO { |
| 57 | 62 | * 秒杀库存 |
| 58 | 63 | */ |
| 59 | 64 | private Integer stock; |
| 65 | + | |
| 60 | 66 | /** |
| 61 | 67 | * 秒杀商品状态 |
| 68 | + * | |
| 62 | 69 | * 枚举 {@link CommonStatusEnum 对应的类} |
| 63 | 70 | */ |
| 64 | 71 | private Integer activityStatus; | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillconfig/SeckillConfigDO.java
| ... | ... | @@ -38,13 +38,14 @@ public class SeckillConfigDO extends BaseDO { |
| 38 | 38 | * 结束时间点 |
| 39 | 39 | */ |
| 40 | 40 | private String endTime; |
| 41 | + // TODO puhui999:应该是轮播图; private List<String> sliderPicUrls; | |
| 41 | 42 | /** |
| 42 | 43 | * 秒杀主图 |
| 43 | 44 | */ |
| 44 | 45 | private String picUrl; |
| 45 | 46 | /** |
| 46 | - * 状态 开启:0 禁用:1 | |
| 47 | - * <p> | |
| 47 | + * 状态 | |
| 48 | + * | |
| 48 | 49 | * 枚举 {@link CommonStatusEnum 对应的类} |
| 49 | 50 | */ |
| 50 | 51 | private Integer status; | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillActivityMapper.java
| ... | ... | @@ -17,6 +17,7 @@ import java.util.List; |
| 17 | 17 | */ |
| 18 | 18 | @Mapper |
| 19 | 19 | public interface SeckillActivityMapper extends BaseMapperX<SeckillActivityDO> { |
| 20 | + | |
| 20 | 21 | default PageResult<SeckillActivityDO> selectPage(SeckillActivityPageReqVO reqVO) { |
| 21 | 22 | return selectPage(reqVO, new LambdaQueryWrapperX<SeckillActivityDO>() |
| 22 | 23 | .likeIfPresent(SeckillActivityDO::getName, reqVO.getName()) |
| ... | ... | @@ -30,4 +31,5 @@ public interface SeckillActivityMapper extends BaseMapperX<SeckillActivityDO> { |
| 30 | 31 | return selectList(new LambdaQueryWrapperX<SeckillActivityDO>() |
| 31 | 32 | .eqIfPresent(SeckillActivityDO::getStatus, status)); |
| 32 | 33 | } |
| 34 | + | |
| 33 | 35 | } | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityServiceImpl.java
| ... | ... | @@ -65,22 +65,24 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { |
| 65 | 65 | validateProductSkuExistence(createReqVO.getSpuIds(), createReqVO.getProducts()); |
| 66 | 66 | |
| 67 | 67 | // 插入秒杀活动 |
| 68 | - SeckillActivityDO seckillActivity = SeckillActivityConvert.INSTANCE.convert(createReqVO) | |
| 68 | + SeckillActivityDO activity = SeckillActivityConvert.INSTANCE.convert(createReqVO) | |
| 69 | 69 | .setStatus(PromotionUtils.calculateActivityStatus(createReqVO.getEndTime())); |
| 70 | - seckillActivityMapper.insert(seckillActivity); | |
| 70 | + seckillActivityMapper.insert(activity); | |
| 71 | 71 | // 插入商品 |
| 72 | - List<SeckillProductDO> productDOs = SeckillActivityConvert.INSTANCE.convertList(seckillActivity, createReqVO.getProducts()); | |
| 73 | - seckillProductMapper.insertBatch(productDOs); | |
| 74 | - return seckillActivity.getId(); | |
| 72 | + List<SeckillProductDO> product = SeckillActivityConvert.INSTANCE.convertList(activity, createReqVO.getProducts()); | |
| 73 | + seckillProductMapper.insertBatch(product); | |
| 74 | + return activity.getId(); | |
| 75 | 75 | } |
| 76 | 76 | |
| 77 | 77 | private <T extends SeckillProductBaseVO> void validateProductSkuExistence(List<Long> spuIds, List<T> products) { |
| 78 | - Set<Long> convertedSpuIds = CollectionUtils.convertSet(products, T::getSpuId); | |
| 79 | 78 | // 校验 spu 个数是否相等 |
| 79 | + // TODO @puhui999:不用校验 SPU 哈,只校验 sku 对应的 spuId 是否一致; | |
| 80 | + Set<Long> convertedSpuIds = CollectionUtils.convertSet(products, T::getSpuId); | |
| 80 | 81 | if (ObjectUtil.notEqual(spuIds.size(), convertedSpuIds.size())) { |
| 81 | 82 | throw exception(SKU_NOT_EXISTS); |
| 82 | 83 | } |
| 83 | 84 | // 获取所选 spu下的所有 sku |
| 85 | + // TODO @puhui999:变量可以简单一点;skus | |
| 84 | 86 | List<ProductSkuRespDTO> skuRespDTOs = productSkuApi.getSkuListBySpuId(spuIds); |
| 85 | 87 | // 校验 sku 个数是否一致 |
| 86 | 88 | Set<Long> skuIdsSet = CollectionUtils.convertSet(products, T::getSkuId); |
| ... | ... | @@ -153,6 +155,7 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { |
| 153 | 155 | * @param updateReqVO 更新的请求VO |
| 154 | 156 | */ |
| 155 | 157 | private void updateSeckillProduct(SeckillActivityUpdateReqVO updateReqVO) { |
| 158 | + // TODO puhui999:要不这里简单一点;删除原本的,插入新增的;不做的这么细致 | |
| 156 | 159 | // TODO puhui999:后续完善 |
| 157 | 160 | //List<SeckillProductDO> seckillProductDOs = seckillProductMapper.selectListByActivityId(updateReqVO.getId()); |
| 158 | 161 | //List<SeckillProductUpdateReqVO> products = updateReqVO.getProducts(); | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillconfig/SeckillConfigServiceImpl.java
| ... | ... | @@ -82,6 +82,7 @@ public class SeckillConfigServiceImpl implements SeckillConfigService { |
| 82 | 82 | private void validateSeckillConfigConflict(String startTime, String endTime) { |
| 83 | 83 | LocalTime startTime1 = LocalTime.parse(startTime); |
| 84 | 84 | LocalTime endTime1 = LocalTime.parse(endTime); |
| 85 | + // TODO @puhui999: 这个可以用 validator 里的 assertTrue 去做哈; | |
| 85 | 86 | // 检查选择的时间是否相等 |
| 86 | 87 | if (startTime1.equals(endTime1)) { |
| 87 | 88 | throw exception(SECKILL_TIME_EQUAL); |
| ... | ... | @@ -93,11 +94,13 @@ public class SeckillConfigServiceImpl implements SeckillConfigService { |
| 93 | 94 | // 查询出所有的时段配置 |
| 94 | 95 | List<SeckillConfigDO> configDOs = seckillConfigMapper.selectList(); |
| 95 | 96 | // 过滤出重叠的时段 ids |
| 97 | + // TODO @puhui999:感觉 findOne 就可以了? | |
| 96 | 98 | Set<Long> ids = configDOs.stream().filter((config) -> { |
| 97 | 99 | LocalTime startTime2 = LocalTime.parse(config.getStartTime()); |
| 98 | 100 | LocalTime endTime2 = LocalTime.parse(config.getEndTime()); |
| 99 | 101 | // 判断时间是否重叠 |
| 100 | 102 | // 开始时间在已配置时段的结束时间之前 且 结束时间在已配置时段的开始时间之后 [] |
| 103 | + // todo @puhui999:LocalDateUtils 可以写个工具类?是否是有重叠的时间?感觉别的场景,可能也会有需要 | |
| 101 | 104 | return startTime1.isBefore(endTime2) && endTime1.isAfter(startTime2) |
| 102 | 105 | // 开始时间在已配置时段的开始时间之前 且 结束时间在已配置时段的开始时间之后 (] 或 () |
| 103 | 106 | || startTime1.isBefore(startTime2) && endTime1.isAfter(startTime2) |
| ... | ... | @@ -127,6 +130,7 @@ public class SeckillConfigServiceImpl implements SeckillConfigService { |
| 127 | 130 | if (seckillConfigMapper.selectBatchIds(configIds).size() != configIds.size()) { |
| 128 | 131 | throw exception(SECKILL_TIME_NOT_EXISTS); |
| 129 | 132 | } |
| 133 | + // TODO @puhui999:应该要校验个 status 哈;如果有禁用的,也不行 | |
| 130 | 134 | } |
| 131 | 135 | |
| 132 | 136 | @Override |
| ... | ... | @@ -134,11 +138,13 @@ public class SeckillConfigServiceImpl implements SeckillConfigService { |
| 134 | 138 | return seckillConfigMapper.selectPage(pageVO); |
| 135 | 139 | } |
| 136 | 140 | |
| 141 | + // TODO @puhui999:写个查询状态的; 尽可能通用哈 | |
| 137 | 142 | @Override |
| 138 | 143 | public List<SeckillConfigDO> getListAllSimple() { |
| 139 | 144 | return seckillConfigMapper.selectList(SeckillConfigDO::getStatus, CommonStatusEnum.ENABLE.getStatus()); |
| 140 | 145 | } |
| 141 | 146 | |
| 147 | + // TODO @puhui999: 这个要不合并到更新操作里? 不单独有个操作咧; | |
| 142 | 148 | @Override |
| 143 | 149 | public void updateSeckillConfigStatus(Long id, Integer status) { |
| 144 | 150 | // 校验秒杀时段是否存在 | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckillconfig/SeckillConfigServiceImplTest.java
| ... | ... | @@ -29,7 +29,7 @@ import static org.junit.jupiter.api.Assertions.assertNull; |
| 29 | 29 | * @author 芋道源码 |
| 30 | 30 | */ |
| 31 | 31 | @Import(SeckillConfigServiceImpl.class) |
| 32 | -@Disabled // TODO 芋艿:未来开启 | |
| 32 | +@Disabled // TODO 芋艿:未来开启;后续要 review 下 | |
| 33 | 33 | public class SeckillConfigServiceImplTest extends BaseDbUnitTest { |
| 34 | 34 | |
| 35 | 35 | @Resource | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/order/TradeOrderApiImpl.java
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java
| ... | ... | @@ -140,6 +140,7 @@ public class AppTradeOrderController { |
| 140 | 140 | @PostMapping("/item/create-comment") |
| 141 | 141 | @Operation(summary = "创建交易订单项的评价") |
| 142 | 142 | public CommonResult<Long> createOrderItemComment(@RequestBody AppTradeOrderItemCommentCreateReqVO createReqVO) { |
| 143 | + // TODO @puhui999:这个逻辑,最好写到 service 哈; | |
| 143 | 144 | Long loginUserId = getLoginUserId(); |
| 144 | 145 | // 先通过订单项 ID 查询订单项是否存在 |
| 145 | 146 | TradeOrderItemDO orderItemDO = tradeOrderService.getOrderItemByIdAndUserId(createReqVO.getOrderItemId(), loginUserId); |
| ... | ... | @@ -151,6 +152,7 @@ public class AppTradeOrderController { |
| 151 | 152 | if (orderDO == null) { |
| 152 | 153 | throw exception(ORDER_NOT_FOUND); |
| 153 | 154 | } |
| 155 | + // TODO @puhui999:要校验订单已完成,但是未评价; | |
| 154 | 156 | |
| 155 | 157 | ProductCommentCreateReqDTO productCommentCreateReqDTO = TradeOrderConvert.INSTANCE.convert04(createReqVO, orderItemDO); |
| 156 | 158 | return success(productCommentApi.createComment(productCommentCreateReqDTO)); | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/item/AppTradeOrderItemCommentCreateReqVO.java
| ... | ... | @@ -19,6 +19,7 @@ public class AppTradeOrderItemCommentCreateReqVO { |
| 19 | 19 | @NotNull(message = "交易订单项编号不能为空") |
| 20 | 20 | private Long orderItemId; |
| 21 | 21 | |
| 22 | + // TODO @puhui999:貌似不用这个字段哈; | |
| 22 | 23 | @Schema(description = "评分星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5") |
| 23 | 24 | @NotNull(message = "评分星级 1-5 分不能为空") |
| 24 | 25 | private Integer scores; |
| ... | ... | @@ -35,7 +36,7 @@ public class AppTradeOrderItemCommentCreateReqVO { |
| 35 | 36 | @NotNull(message = "评论内容不能为空") |
| 36 | 37 | private String content; |
| 37 | 38 | |
| 38 | - @Schema(description = "评论图片地址数组,以逗号分隔最多上传 9 张", requiredMode = Schema.RequiredMode.REQUIRED, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xx.png]") | |
| 39 | + @Schema(description = "评论图片地址数组,以逗号分隔最多上传 9 张", requiredMode = Schema.RequiredMode.REQUIRED, example = "[https://www.iocoder.cn/xx.png]") | |
| 39 | 40 | @Size(max = 9, message = "评论图片地址数组长度不能超过 9 张") |
| 40 | 41 | private List<String> picUrls; |
| 41 | 42 | ... | ... |