Sfoglia il codice sorgente

fix:修复 mall review @puhui999

puhui999 1 anno fa
parent
commit
e7d8643665
38 ha cambiato i file con 207 aggiunte e 244 eliminazioni
  1. 21 1
      yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java
  2. 1 1
      yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java
  3. 0 13
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentBaseVO.java
  4. 1 2
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentPageReqVO.java
  5. 12 0
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java
  6. 0 5
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java
  7. 0 5
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuCreateReqVO.java
  8. 0 6
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java
  9. 0 5
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExportReqVO.java
  10. 0 5
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java
  11. 0 5
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java
  12. 0 5
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSimpleRespVO.java
  13. 0 5
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java
  14. 0 5
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateStatusReqVO.java
  15. 7 21
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppProductCommentController.java
  16. 0 5
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentRespVO.java
  17. 25 5
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java
  18. 2 2
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java
  19. 1 1
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java
  20. 8 14
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java
  21. 4 5
      yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java
  22. 0 5
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillConfigController.java
  23. 0 5
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityRespVO.java
  24. 19 3
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigBaseVO.java
  25. 0 6
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigPageReqVO.java
  26. 3 10
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/product/SeckillProductCreateReqVO.java
  27. 4 6
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/product/SeckillProductRespVO.java
  28. 0 5
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/product/SeckillProductUpdateReqVO.java
  29. 13 8
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillconfig/SeckillConfigDO.java
  30. 7 0
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillconfig/SeckillConfigMapper.java
  31. 29 40
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillconfig/SeckillConfigServiceImpl.java
  32. 2 0
      yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java
  33. 2 26
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java
  34. 0 5
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/item/AppTradeOrderItemCommentCreateReqVO.java
  35. 0 1
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java
  36. 11 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderService.java
  37. 29 2
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java
  38. 6 6
      yudao-module-member/yudao-module-member-biz/src/test/java/cn/iocoder/yudao/module/member/service/address/AddressServiceImplTest.java

+ 21 - 1
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java

@@ -4,6 +4,7 @@ import cn.hutool.core.date.LocalDateTimeUtil;
 
 import java.time.Duration;
 import java.time.LocalDateTime;
+import java.time.LocalTime;
 
 /**
  * 时间工具类,用于 {@link java.time.LocalDateTime}
@@ -50,7 +51,7 @@ public class LocalDateTimeUtils {
      * 判断当前时间是否在该时间范围内
      *
      * @param startTime 开始时间
-     * @param endTime 结束时间
+     * @param endTime   结束时间
      * @return 是否
      */
     public static boolean isBetween(LocalDateTime startTime, LocalDateTime endTime) {
@@ -60,4 +61,23 @@ public class LocalDateTimeUtils {
         return LocalDateTimeUtil.isIn(LocalDateTime.now(), startTime, endTime);
     }
 
+    /**
+     * 检查时间重叠 不包含日期
+     *
+     * @param startTime1 需要校验的开始时间
+     * @param endTime1   需要校验的结束时间
+     * @param startTime2 校验所需的开始时间
+     * @param endTime2   校验所需的结束时间
+     * @return 是否重叠
+     */
+    public static boolean checkTimeOverlap(LocalTime startTime1, LocalTime endTime1, LocalTime startTime2, LocalTime endTime2) {
+        // 判断时间是否重叠
+        // 开始时间在已配置时段的结束时间之前 且 结束时间在已配置时段的开始时间之后 []
+        return startTime1.isBefore(endTime2) && endTime1.isAfter(startTime2)
+                // 开始时间在已配置时段的开始时间之前 且 结束时间在已配置时段的开始时间之后 (] 或 ()
+                || startTime1.isBefore(startTime2) && endTime1.isAfter(startTime2)
+                // 开始时间在已配置时段的结束时间之前 且 结束时间在已配值时段的结束时间之后 [) 或 ()
+                || startTime1.isBefore(endTime2) && endTime1.isAfter(endTime2);
+    }
+
 }

+ 1 - 1
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java

@@ -46,7 +46,7 @@ public interface ErrorCodeConstants {
 
     // ========== 商品 评价 1008007000 ==========
     ErrorCode COMMENT_NOT_EXISTS = new ErrorCode(1008007000, "商品 评价 不存在");
-    ErrorCode ORDER_SPU_COMMENT_EXISTS = new ErrorCode(1008007001, "订单 商品评价 已存在");
+    ErrorCode ORDER_SKU_COMMENT_EXISTS = new ErrorCode(1008007001, "订单 商品评价 已存在");
     ErrorCode COMMENT_ERROR_OPT = new ErrorCode(1008007002, "商品评价非法操作");
     ErrorCode COMMENT_ADDITIONAL_EXISTS  = new ErrorCode(1008007003, "商品追加评价已存在");
 

+ 0 - 13
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentBaseVO.java

@@ -26,23 +26,10 @@ public class ProductCommentBaseVO {
     @NotNull(message = "评价人头像不能为空")
     private String userAvatar;
 
-    // TODO @puhui:spuId、spuName 是不是只有 ProductCommentRespVO 有呀。
-    @Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "清凉丝滑透气小短袖")
-    @NotNull(message = "商品 SPU 编号不能为空")
-    private Long spuId;
-
-    @Schema(description = "商品 SPU 名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
-    @NotNull(message = "商品 SPU 名称不能为空")
-    private String spuName;
-
     @Schema(description = "商品 SKU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
     @NotNull(message = "商品 SKU 编号不能为空")
     private Long skuId;
 
-    @Schema(description = "评分星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
-    @NotNull(message = "评分星级不能为空")
-    private Integer scores;
-
     @Schema(description = "描述星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
     @NotNull(message = "描述星级不能为空")
     private Integer descriptionScores;

+ 1 - 2
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentPageReqVO.java

@@ -35,9 +35,8 @@ public class ProductCommentPageReqVO extends PageParam {
     @InEnum(ProductCommentScoresEnum.class)
     private Integer scores;
 
-    // TODO @puhui999:replyStatus 哈
     @Schema(description = "商家是否回复", example = "true")
-    private Boolean replied;
+    private Boolean replyStatus;
 
     @Schema(description = "创建时间")
     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)

+ 12 - 0
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java

@@ -5,6 +5,7 @@ import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.ToString;
 
+import javax.validation.constraints.NotNull;
 import java.time.LocalDateTime;
 
 @Schema(description = "管理后台 - 商品评价 Response VO")
@@ -40,4 +41,15 @@ public class ProductCommentRespVO extends ProductCommentBaseVO {
     @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
     private LocalDateTime createTime;
 
+    @Schema(description = "评分星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
+    private Integer scores;
+
+    @Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "清凉丝滑透气小短袖")
+    @NotNull(message = "商品 SPU 编号不能为空")
+    private Long spuId;
+
+    @Schema(description = "商品 SPU 名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
+    @NotNull(message = "商品 SPU 名称不能为空")
+    private String spuName;
+
 }

+ 0 - 5
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java

@@ -30,11 +30,6 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;
 
-/**
- * 商品 SPU 相关接口
- *
- * @author HUIHUI
- */
 @Tag(name = "管理后台 - 商品 SPU")
 @RestController
 @RequestMapping("/product/spu")

+ 0 - 5
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuCreateReqVO.java

@@ -9,11 +9,6 @@ import lombok.ToString;
 import javax.validation.Valid;
 import java.util.List;
 
-/**
- * 商品 SPU 创建 Request VO
- *
- * @author HUIHUI
- */
 @Schema(description = "管理后台 - 商品 SPU 创建 Request VO")
 @Data
 @EqualsAndHashCode(callSuper = true)

+ 0 - 6
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java

@@ -8,12 +8,6 @@ import lombok.ToString;
 
 import java.util.List;
 
-/**
- * 商品 SPU 详细 Response VO
- * 包括关联的 SKU 等信息
- *
- * @author HUIHUI
- */
 @Schema(description = "管理后台 - 商品 SPU 详细 Response VO")
 @Data
 @EqualsAndHashCode(callSuper = true)

+ 0 - 5
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExportReqVO.java

@@ -10,11 +10,6 @@ import java.time.LocalDateTime;
 
 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
 
-/**
- * 商品Spu导出 Request VO,参数和 ProductSpuPageReqVO 是一致的
- *
- * @author HUIHUI
- */
 @Schema(description = "管理后台 - 商品Spu导出 Request VO,参数和 ProductSpuPageReqVO 是一致的")
 @Data
 @NoArgsConstructor

+ 0 - 5
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java

@@ -11,11 +11,6 @@ import java.time.LocalDateTime;
 
 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
 
-/**
- * 商品 SPU 分页 Request VO
- *
- * @author HUIHUI
- */
 @Schema(description = "管理后台 - 商品 SPU 分页 Request VO")
 @Data
 @EqualsAndHashCode(callSuper = true)

+ 0 - 5
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java

@@ -7,11 +7,6 @@ import lombok.ToString;
 
 import java.time.LocalDateTime;
 
-/**
- * 商品 SPU Response VO
- *
- * @author HUIHUI
- */
 @Schema(description = "管理后台 - 商品 SPU Response VO")
 @Data
 @EqualsAndHashCode(callSuper = true)

+ 0 - 5
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSimpleRespVO.java

@@ -4,11 +4,6 @@ import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 import lombok.ToString;
 
-/**
- * 商品 SPU 精简 Response VO
- *  TODO 商品 SPU 精简 VO 暂时没有使用到,用到的时候再按需添加\修改属性
- * @author HUIHUI
- */
 @Schema(description = "管理后台 - 商品 SPU 精简 Response VO")
 @Data
 @ToString(callSuper = true)

+ 0 - 5
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java

@@ -12,11 +12,6 @@ import javax.validation.Valid;
 import javax.validation.constraints.NotNull;
 import java.util.List;
 
-/**
- * 商品 SPU 更新 Request VO
- *
- * @author HUIHUI
- */
 @Schema(description = "管理后台 - 商品 SPU 更新 Request VO")
 @Data
 @EqualsAndHashCode(callSuper = true)

+ 0 - 5
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateStatusReqVO.java

@@ -7,11 +7,6 @@ import lombok.Data;
 
 import javax.validation.constraints.NotNull;
 
-/**
- * 商品 SPU Status 更新 Request VO
- *
- * @author HUIHUI
- */
 @Schema(description = "管理后台 - 商品 SPU Status 更新 Request VO")
 @Data
 public class ProductSpuUpdateStatusReqVO{

+ 7 - 21
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppProductCommentController.java

@@ -1,18 +1,18 @@
 package cn.iocoder.yudao.module.product.controller.app.comment;
 
 import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.util.ObjectUtil;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO;
 import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentStatisticsRespVO;
 import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppProductCommentRespVO;
-import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProductPropertyValueDetailRespVO;
 import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert;
 import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO;
 import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
 import cn.iocoder.yudao.module.product.service.comment.ProductCommentService;
 import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
+import com.google.common.collect.Maps;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.Parameters;
@@ -26,11 +26,9 @@ import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
 import javax.validation.Valid;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.stream.Collectors;
 
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 
@@ -61,26 +59,14 @@ public class AppProductCommentController {
     @GetMapping("/page")
     @Operation(summary = "获得商品评价分页")
     public CommonResult<PageResult<AppProductCommentRespVO>> getCommentPage(@Valid AppCommentPageReqVO pageVO) {
-        PageResult<AppProductCommentRespVO> page = productCommentService.getCommentPage(pageVO, Boolean.TRUE);
-        // TODO @puhui CollUtils 有简化 convertmap 和 list 的方法
-        Set<Long> skuIds = page.getList().stream().map(AppProductCommentRespVO::getSkuId).collect(Collectors.toSet());
+        PageResult<ProductCommentDO> commentDOPage = productCommentService.getCommentPage(pageVO, Boolean.TRUE);
+        Set<Long> skuIds = CollectionUtils.convertSet(commentDOPage.getList(), ProductCommentDO::getSkuId);
         List<ProductSkuDO> skuList = productSkuService.getSkuList(skuIds);
-        Map<Long, ProductSkuDO> skuDOMap = new HashMap<>(skuIds.size());
+        Map<Long, ProductSkuDO> skuDOMap = Maps.newLinkedHashMapWithExpectedSize(skuIds.size());
         if (CollUtil.isNotEmpty(skuList)) {
-            skuDOMap.putAll(skuList.stream().collect(Collectors.toMap(ProductSkuDO::getId, c -> c)));
+            skuDOMap.putAll(CollectionUtils.convertMap(skuList, ProductSkuDO::getId, c -> c));
         }
-        // TODO @puihui999:下面也可以放到 convert 里哈
-        page.getList().forEach(item -> {
-            // 判断用户是否选择匿名
-            if (ObjectUtil.equal(item.getAnonymous(), true)) {
-                item.setUserNickname(ProductCommentDO.NICKNAME_ANONYMOUS);
-            }
-            ProductSkuDO productSkuDO = skuDOMap.get(item.getSkuId());
-            if (productSkuDO != null) {
-                List<AppProductPropertyValueDetailRespVO> skuProperties = ProductCommentConvert.INSTANCE.convertList01(productSkuDO.getProperties());
-                item.setSkuProperties(skuProperties);
-            }
-        });
+        PageResult<AppProductCommentRespVO> page = ProductCommentConvert.INSTANCE.convertPage02(commentDOPage, skuDOMap);
         return success(page);
     }
 

+ 0 - 5
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentRespVO.java

@@ -10,11 +10,6 @@ import javax.validation.constraints.Size;
 import java.time.LocalDateTime;
 import java.util.List;
 
-/**
- * 用户 App - 商品评价详情 Response VO
- *
- * @author HUIHUI
- */
 @Schema(description = "用户 App - 商品评价详情 Response VO")
 @Data
 @ToString(callSuper = true)

+ 25 - 5
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java

@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.module.product.convert.comment;
 
+import cn.hutool.core.util.ObjectUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
 import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
@@ -19,6 +20,7 @@ import org.mapstruct.factory.Mappers;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.util.List;
+import java.util.Map;
 
 /**
  * 商品评价 Convert
@@ -32,10 +34,12 @@ public interface ProductCommentConvert {
 
     ProductCommentRespVO convert(ProductCommentDO bean);
 
-    // TODO @puhui999:这里貌似字段对上,就不用 mapping 了;可以测试下看看哈
-    @Mapping(target = "goodCount", source = "goodCount")
-    @Mapping(target = "mediocreCount", source = "mediocreCount")
-    @Mapping(target = "negativeCount", source = "negativeCount")
+    @Named("calculateOverallScore")
+    default double calculateOverallScore(long goodCount, long mediocreCount, long negativeCount) {
+        return (goodCount * 5 + mediocreCount * 3 + negativeCount) / (double) (goodCount + mediocreCount + negativeCount);
+    }
+
+    @Mapping(target = "scores", expression = "java(calculateOverallScore(goodCount, mediocreCount, negativeCount))")
     AppCommentStatisticsRespVO convert(Long goodCount, Long mediocreCount, Long negativeCount);
 
     List<ProductCommentRespVO> convertList(List<ProductCommentDO> list);
@@ -44,7 +48,23 @@ public interface ProductCommentConvert {
 
     PageResult<ProductCommentRespVO> convertPage(PageResult<ProductCommentDO> page);
 
-    PageResult<AppProductCommentRespVO> convertPage02(PageResult<ProductCommentDO> pageResult);
+    PageResult<AppProductCommentRespVO> convertPage01(PageResult<ProductCommentDO> pageResult);
+
+    default PageResult<AppProductCommentRespVO> convertPage02(PageResult<ProductCommentDO> pageResult, Map<Long, ProductSkuDO> skuDOMap) {
+        PageResult<AppProductCommentRespVO> page = convertPage01(pageResult);
+        page.getList().forEach(item -> {
+            // 判断用户是否选择匿名
+            if (ObjectUtil.equal(item.getAnonymous(), true)) {
+                item.setUserNickname(ProductCommentDO.NICKNAME_ANONYMOUS);
+            }
+            ProductSkuDO productSkuDO = skuDOMap.get(item.getSkuId());
+            if (productSkuDO != null) {
+                List<AppProductPropertyValueDetailRespVO> skuProperties = ProductCommentConvert.INSTANCE.convertList01(productSkuDO.getProperties());
+                item.setSkuProperties(skuProperties);
+            }
+        });
+        return page;
+    }
 
     /**
      * 计算综合评分

+ 2 - 2
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java

@@ -51,11 +51,11 @@ public interface ProductCommentMapper extends BaseMapperX<ProductCommentDO> {
         return selectPage(reqVO, queryWrapper);
     }
 
-    default ProductCommentDO selectByUserIdAndOrderItemIdAndSpuId(Long userId, Long orderItemId, Long spuId) {
+    default ProductCommentDO selectByUserIdAndOrderItemIdAndSpuId(Long userId, Long orderItemId, Long skuId) {
         return selectOne(new LambdaQueryWrapperX<ProductCommentDO>()
                 .eq(ProductCommentDO::getUserId, userId)
                 .eq(ProductCommentDO::getOrderItemId, orderItemId)
-                .eq(ProductCommentDO::getSpuId, spuId));
+                .eq(ProductCommentDO::getSpuId, skuId));
     }
 
     default Long selectCountBySpuId(Long spuId, Boolean visible, Integer type) {

+ 1 - 1
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java

@@ -54,7 +54,7 @@ public interface ProductCommentService {
      * @param visible 是否可见
      * @return 商品评价分页
      */
-    PageResult<AppProductCommentRespVO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible);
+    PageResult<ProductCommentDO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible);
 
     /**
      * 创建商品评论

+ 8 - 14
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java

@@ -81,7 +81,7 @@ public class ProductCommentServiceImpl implements ProductCommentService {
     @Transactional(rollbackFor = Exception.class)
     public void createComment(ProductCommentCreateReqVO createReqVO) {
         // 校验评论
-        validateComment(createReqVO.getSpuId(), createReqVO.getUserId(), createReqVO.getOrderItemId());
+        validateComment(createReqVO.getSkuId(), createReqVO.getUserId(), createReqVO.getOrderItemId());
 
         ProductCommentDO commentDO = ProductCommentConvert.INSTANCE.convert(createReqVO);
         productCommentMapper.insert(commentDO);
@@ -108,11 +108,11 @@ public class ProductCommentServiceImpl implements ProductCommentService {
         return commentDO.getId();
     }
 
-    private void validateComment(Long spuId, Long userId, Long orderItemId) {
+    private void validateComment(Long skuId, Long userId, Long orderItemId) {
         // 判断当前订单的当前商品用户是否评价过
-        ProductCommentDO exist = productCommentMapper.selectByUserIdAndOrderItemIdAndSpuId(userId, orderItemId, spuId);
+        ProductCommentDO exist = productCommentMapper.selectByUserIdAndOrderItemIdAndSpuId(userId, orderItemId, skuId);
         if (null != exist) {
-            throw exception(ORDER_SPU_COMMENT_EXISTS);
+            throw exception(ORDER_SKU_COMMENT_EXISTS);
         }
     }
 
@@ -141,23 +141,17 @@ public class ProductCommentServiceImpl implements ProductCommentService {
                 productCommentMapper.selectCountBySpuId(spuId, visible, AppCommentPageReqVO.MEDIOCRE_COMMENT),
                 // 查询商品 id = spuId 的所有差评数量
                 productCommentMapper.selectCountBySpuId(spuId, visible, AppCommentPageReqVO.NEGATIVE_COMMENT)
-        ).setScores(3.0); // TODO @puhui999:这里要实现下;;
+        );
     }
 
     @Override
     public List<AppProductCommentRespVO> getCommentList(Long spuId, Integer count) {
-        // 校验商品 spu 是否存在
-        // TODO @puhui 这里校验可以去掉哈。
-        ProductSpuDO spuDO = validateSpu(spuId);
-        return ProductCommentConvert.INSTANCE.convertList02(productCommentMapper.selectCommentList(spuDO.getId(), count).getList());
+        return ProductCommentConvert.INSTANCE.convertList02(productCommentMapper.selectCommentList(spuId, count).getList());
     }
 
-    // TODO @puhui 可以放到 controller 去 convert 哈
     @Override
-    public PageResult<AppProductCommentRespVO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible) {
-        // TODO @puhui 可以放到 controller 去 convert 哈
-        return ProductCommentConvert.INSTANCE.convertPage02(
-                productCommentMapper.selectPage(pageVO, visible));
+    public PageResult<ProductCommentDO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible) {
+        return productCommentMapper.selectPage(pageVO, visible);
     }
 
     @Override

+ 4 - 5
yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java

@@ -10,7 +10,6 @@ import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommen
 import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO;
 import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO;
 import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentStatisticsRespVO;
-import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppProductCommentRespVO;
 import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert;
 import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO;
 import cn.iocoder.yudao.module.product.dal.mysql.comment.ProductCommentMapper;
@@ -128,7 +127,7 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest {
         productCommentPageReqVO.setSpuId(spuId);
         productCommentPageReqVO.setSpuName("感冒药");
         productCommentPageReqVO.setScores(ProductCommentScoresEnum.FOUR.getScores());
-        productCommentPageReqVO.setReplied(Boolean.TRUE);
+        productCommentPageReqVO.setReplyStatus(Boolean.TRUE);
 
         PageResult<ProductCommentDO> commentPage = productCommentService.getCommentPage(productCommentPageReqVO);
         PageResult<ProductCommentRespVO> result = ProductCommentConvert.INSTANCE.convertPage(productCommentMapper.selectPage(productCommentPageReqVO));
@@ -138,15 +137,15 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest {
         assertEquals(8, all.getTotal());
 
         // 测试获取所有商品分页评论数据
-        PageResult<AppProductCommentRespVO> result1 = productCommentService.getCommentPage(new AppCommentPageReqVO(), Boolean.TRUE);
+        PageResult<ProductCommentDO> result1 = productCommentService.getCommentPage(new AppCommentPageReqVO(), Boolean.TRUE);
         assertEquals(7, result1.getTotal());
 
         // 测试获取所有商品分页中评数据
-        PageResult<AppProductCommentRespVO> result2 = productCommentService.getCommentPage(new AppCommentPageReqVO().setType(AppCommentPageReqVO.MEDIOCRE_COMMENT), Boolean.TRUE);
+        PageResult<ProductCommentDO> result2 = productCommentService.getCommentPage(new AppCommentPageReqVO().setType(AppCommentPageReqVO.MEDIOCRE_COMMENT), Boolean.TRUE);
         assertEquals(2, result2.getTotal());
 
         // 测试获取指定 spuId 商品分页中评数据
-        PageResult<AppProductCommentRespVO> result3 = productCommentService.getCommentPage(new AppCommentPageReqVO().setSpuId(spuId).setType(AppCommentPageReqVO.MEDIOCRE_COMMENT), Boolean.TRUE);
+        PageResult<ProductCommentDO> result3 = productCommentService.getCommentPage(new AppCommentPageReqVO().setSpuId(spuId).setType(AppCommentPageReqVO.MEDIOCRE_COMMENT), Boolean.TRUE);
         assertEquals(2, result3.getTotal());
 
         // 测试分页 tab count

+ 0 - 5
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillConfigController.java

@@ -19,11 +19,6 @@ import java.util.List;
 
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 
-/**
- * 管理后台 - 秒杀时段相关接口
- *
- * @author HUIHUI
- */
 @Tag(name = "管理后台 - 秒杀时段")
 @RestController
 @RequestMapping("/promotion/seckill-config")

+ 0 - 5
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityRespVO.java

@@ -9,11 +9,6 @@ import lombok.ToString;
 import java.time.LocalDateTime;
 import java.util.List;
 
-/**
- * 管理后台 - 秒杀活动 Response VO
- *
- * @author HUIHUI
- */
 @Schema(description = "管理后台 - 秒杀活动 Response VO")
 @Data
 @EqualsAndHashCode(callSuper = true)

+ 19 - 3
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigBaseVO.java

@@ -1,9 +1,13 @@
 package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config;
 
+import com.fasterxml.jackson.annotation.JsonIgnore;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
+import javax.validation.constraints.AssertTrue;
 import javax.validation.constraints.NotNull;
+import java.time.LocalTime;
+import java.util.List;
 
 /**
  * 秒杀时段 Base VO,提供给添加、修改、详细的子 VO 使用
@@ -26,12 +30,24 @@ public class SeckillConfigBaseVO {
     @NotNull(message = "结束时间点不能为空")
     private String endTime;
 
-    @Schema(description = "秒杀图", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn")
-    @NotNull(message = "秒杀图不能为空")
-    private String picUrl;
+    @Schema(description = "秒杀轮播图", requiredMode = Schema.RequiredMode.REQUIRED, example = "[https://www.iocoder.cn/xx.png]")
+    @NotNull(message = "秒杀轮播图不能为空")
+    private List<String> sliderPicUrls;
 
     @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
     @NotNull(message = "状态不能为空")
     private Integer status;
 
+    @AssertTrue(message = "秒杀时段开始时间和结束时间不能相等")
+    @JsonIgnore
+    public boolean isValidStartTimeValid() {
+        return !LocalTime.parse(startTime).equals(LocalTime.parse(endTime));
+    }
+
+    @AssertTrue(message = "秒杀时段开始时间不能在结束时间之后")
+    @JsonIgnore
+    public boolean isValidEndTimeValid() {
+        return !LocalTime.parse(startTime).isAfter(LocalTime.parse(endTime));
+    }
+
 }

+ 0 - 6
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigPageReqVO.java

@@ -6,12 +6,6 @@ import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.ToString;
 
-// TODO @puhui:VO 上不写注释,已经有注解啦。
-/**
- * 管理后台 - 秒杀时段分页 Request VO
- *
- * @author HUIHUI
- */
 @Schema(description = "管理后台 - 秒杀时段分页 Request VO")
 @Data
 @EqualsAndHashCode(callSuper = true)

+ 3 - 10
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/product/SeckillProductCreateReqVO.java

@@ -1,16 +1,9 @@
 package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product;
 
-import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductBaseVO;
-import lombok.*;
-import java.util.*;
 import io.swagger.v3.oas.annotations.media.Schema;
-import javax.validation.constraints.*;
-
-/**
- * 管理后台 - 秒杀参与商品创建 Request VO
- *
- * @author HUIHUI
- */
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
 @Schema(description = "管理后台 - 秒杀参与商品创建 Request VO")
 @Data
 @EqualsAndHashCode(callSuper = true)

+ 4 - 6
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/product/SeckillProductRespVO.java

@@ -1,14 +1,12 @@
 package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product;
 
 import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
 import java.time.LocalDateTime;
 
-/**
- * 管理后台 - 秒杀参与商品 Response VO
- *
- * @author HUIHUI
- */
 @Schema(description = "管理后台 - 秒杀参与商品 Response VO")
 @Data
 @EqualsAndHashCode(callSuper = true)

+ 0 - 5
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/product/SeckillProductUpdateReqVO.java

@@ -5,11 +5,6 @@ import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.ToString;
 
-/**
- * 管理后台 - 秒杀参与商品更新 Request VO
- *
- * @author HUIHUI
- */
 @Schema(description = "管理后台 - 秒杀参与商品更新 Request VO")
 @Data
 @EqualsAndHashCode(callSuper = true)

+ 13 - 8
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillconfig/SeckillConfigDO.java

@@ -3,22 +3,27 @@ package cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig;
 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
 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.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
+import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
+import lombok.*;
+
+import java.util.List;
 
 /**
  * 秒杀时段 DO
  *
  * @author 芋道源码
  */
-@TableName("promotion_seckill_config")
+@TableName(value = "promotion_seckill_config", autoResultMap = true)
 @KeySequence("promotion_seckill_config_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
 @Data
 @EqualsAndHashCode(callSuper = true)
 @ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
 public class SeckillConfigDO extends BaseDO {
 
     /**
@@ -38,14 +43,14 @@ public class SeckillConfigDO extends BaseDO {
      * 结束时间点
      */
     private String endTime;
-    // TODO puhui999:应该是轮播图;    private List<String> sliderPicUrls;
     /**
-     * 秒杀
+     * 秒杀轮播
      */
-    private String picUrl;
+    @TableField(typeHandler = JacksonTypeHandler.class)
+    private List<String> sliderPicUrls;
     /**
      * 状态
-     *
+     * <p>
      * 枚举 {@link CommonStatusEnum 对应的类}
      */
     private Integer status;

+ 7 - 0
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillconfig/SeckillConfigMapper.java

@@ -7,6 +7,8 @@ import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.Seck
 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO;
 import org.apache.ibatis.annotations.Mapper;
 
+import java.util.List;
+
 @Mapper
 public interface SeckillConfigMapper extends BaseMapperX<SeckillConfigDO> {
 
@@ -17,4 +19,9 @@ public interface SeckillConfigMapper extends BaseMapperX<SeckillConfigDO> {
                 .orderByDesc(SeckillConfigDO::getId));
     }
 
+    default List<SeckillConfigDO> selectListByStatus(Integer status) {
+        return selectList(SeckillConfigDO::getStatus, status);
+    }
+
+
 }

+ 29 - 40
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillconfig/SeckillConfigServiceImpl.java

@@ -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.PageResult;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
+import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigCreateReqVO;
 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigPageReqVO;
 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigUpdateReqVO;
@@ -12,14 +13,13 @@ import cn.iocoder.yudao.module.promotion.convert.seckill.seckillconfig.SeckillCo
 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO;
 import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillconfig.SeckillConfigMapper;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
 import java.time.LocalTime;
 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.promotion.enums.ErrorCodeConstants.*;
@@ -37,9 +37,10 @@ public class SeckillConfigServiceImpl implements SeckillConfigService {
     private SeckillConfigMapper seckillConfigMapper;
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public Long createSeckillConfig(SeckillConfigCreateReqVO createReqVO) {
         // 校验时间段是否冲突
-        validateSeckillConfigConflict(createReqVO.getStartTime(), createReqVO.getEndTime());
+        validateSeckillConfigConflict(createReqVO.getStartTime(), createReqVO.getEndTime(), null);
 
         // 插入
         SeckillConfigDO seckillConfig = SeckillConfigConvert.INSTANCE.convert(createReqVO);
@@ -49,18 +50,30 @@ public class SeckillConfigServiceImpl implements SeckillConfigService {
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public void updateSeckillConfig(SeckillConfigUpdateReqVO updateReqVO) {
         // 校验存在
         validateSeckillConfigExists(updateReqVO.getId());
         // 校验时间段是否冲突
-        validateSeckillConfigConflict(updateReqVO.getStartTime(), updateReqVO.getEndTime());
+        validateSeckillConfigConflict(updateReqVO.getStartTime(), updateReqVO.getEndTime(), updateReqVO.getId());
 
         // 更新
         SeckillConfigDO updateObj = SeckillConfigConvert.INSTANCE.convert(updateReqVO);
         seckillConfigMapper.updateById(updateObj);
     }
 
+    // TODO  @puhui999: 这个要不合并到更新操作里? 不单独有个操作咧; 更新状态不用那么多必须的参数,更新的时候需要校验时间段
     @Override
+    public void updateSeckillConfigStatus(Long id, Integer status) {
+        // 校验秒杀时段是否存在
+        validateSeckillConfigExists(id);
+
+        // 更新状态
+        seckillConfigMapper.updateById(new SeckillConfigDO().setId(id).setStatus(status));
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
     public void deleteSeckillConfig(Long id) {
         // 校验存在
         validateSeckillConfigExists(id);
@@ -81,39 +94,29 @@ public class SeckillConfigServiceImpl implements SeckillConfigService {
      * @param startTime 开始时间
      * @param endTime   结束时间
      */
-    private void validateSeckillConfigConflict(String startTime, String endTime) {
+    private void validateSeckillConfigConflict(String startTime, String endTime, Long seckillConfigId) {
         LocalTime startTime1 = LocalTime.parse(startTime);
         LocalTime endTime1 = LocalTime.parse(endTime);
-        // TODO @puhui999: 这个可以用 validator 里的 assertTrue 去做哈;
-        // 检查选择的时间是否相等
-        if (startTime1.equals(endTime1)) {
-            throw exception(SECKILL_TIME_EQUAL);
-        }
-        // 检查开始时间是否在结束时间之前
-        if (startTime1.isAfter(endTime1)) {
-            throw exception(SECKILL_START_TIME_BEFORE_END_TIME);
-        }
         // 查询出所有的时段配置
         List<SeckillConfigDO> configDOs = seckillConfigMapper.selectList();
+        // 更新时排除自己
+        if (seckillConfigId != null) {
+            configDOs.removeIf(item -> ObjectUtil.equal(item.getId(), seckillConfigId));
+        }
         // 过滤出重叠的时段 ids
-        // TODO @puhui999:感觉 findOne 就可以了?
-        Set<Long> ids = configDOs.stream().filter((config) -> {
+        boolean hasConflict = configDOs.stream().anyMatch(config -> {
             LocalTime startTime2 = LocalTime.parse(config.getStartTime());
             LocalTime endTime2 = LocalTime.parse(config.getEndTime());
             // 判断时间是否重叠
-            // 开始时间在已配置时段的结束时间之前 且 结束时间在已配置时段的开始时间之后 []
-            // todo @puhui999:LocalDateUtils 可以写个工具类?是否是有重叠的时间?感觉别的场景,可能也会有需要
-            return startTime1.isBefore(endTime2) && endTime1.isAfter(startTime2)
-                    // 开始时间在已配置时段的开始时间之前 且 结束时间在已配置时段的开始时间之后 (] 或 ()
-                    || startTime1.isBefore(startTime2) && endTime1.isAfter(startTime2)
-                    // 开始时间在已配置时段的结束时间之前 且 结束时间在已配值时段的结束时间之后 [) 或 ()
-                    || startTime1.isBefore(endTime2) && endTime1.isAfter(endTime2);
-        }).map(SeckillConfigDO::getId).collect(Collectors.toSet());
-        if (CollUtil.isNotEmpty(ids)) {
+            return LocalDateTimeUtils.checkTimeOverlap(startTime1, endTime1, startTime2, endTime2);
+        });
+
+        if (hasConflict) {
             throw exception(SECKILL_TIME_CONFLICTS);
         }
     }
 
+
     @Override
     public SeckillConfigDO getSeckillConfig(Long id) {
         return seckillConfigMapper.selectById(id);
@@ -148,23 +151,9 @@ public class SeckillConfigServiceImpl implements SeckillConfigService {
         return seckillConfigMapper.selectPage(pageVO);
     }
 
-    // TODO  @puhui999:写个查询状态的; 尽可能通用哈
     @Override
     public List<SeckillConfigDO> getListAllSimple() {
-        return seckillConfigMapper.selectList(SeckillConfigDO::getStatus, CommonStatusEnum.ENABLE.getStatus());
-    }
-
-    // TODO  @puhui999: 这个要不合并到更新操作里? 不单独有个操作咧;
-    @Override
-    public void updateSeckillConfigStatus(Long id, Integer status) {
-        // 校验秒杀时段是否存在
-        validateSeckillConfigExists(id);
-
-        SeckillConfigDO seckillConfigDO = new SeckillConfigDO();
-        seckillConfigDO.setId(id);
-        seckillConfigDO.setStatus(status);
-        // 更新状态
-        seckillConfigMapper.updateById(seckillConfigDO);
+        return seckillConfigMapper.selectListByStatus(CommonStatusEnum.ENABLE.getStatus());
     }
 
 }

+ 2 - 0
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java

@@ -27,6 +27,8 @@ public interface ErrorCodeConstants {
     ErrorCode ORDER_UPDATE_PAID_FAIL_PAY_PRICE_NOT_MATCH = new ErrorCode(1011000016, "交易订单更新支付状态失败,支付单金额不匹配");
     ErrorCode ORDER_DELIVERY_FAIL_STATUS_NOT_UNDELIVERED = new ErrorCode(1011000017, "交易订单发货失败,订单不是【待发货】状态");
     ErrorCode ORDER_RECEIVE_FAIL_STATUS_NOT_DELIVERED = new ErrorCode(1011000018, "交易订单收货失败,订单不是【待收货】状态");
+    ErrorCode ORDER_COMMENT_FAIL_STATUS_NOT_COMPLETED = new ErrorCode(1011000019, "创建交易订单项的评价失败,订单不是【已完成】状态");
+    ErrorCode ORDER_COMMENT_STATUS_NOT_FALSE = new ErrorCode(1011000019, "创建交易订单项的评价失败,订单已评价");
 
     // ==========  After Sale 模块 1011000100 ==========
     ErrorCode AFTER_SALE_NOT_FOUND = new ErrorCode(1011000100, "售后单不存在");

+ 2 - 26
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java

@@ -4,8 +4,6 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
 import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO;
-import cn.iocoder.yudao.module.product.api.comment.ProductCommentApi;
-import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
 import cn.iocoder.yudao.module.product.api.property.ProductPropertyValueApi;
 import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
 import cn.iocoder.yudao.module.trade.controller.app.order.vo.*;
@@ -30,13 +28,10 @@ import javax.validation.Valid;
 import java.util.List;
 import java.util.Map;
 
-import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
 import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
-import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_ITEM_NOT_FOUND;
-import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_NOT_FOUND;
 
 @Tag(name = "用户 App - 交易订单")
 @RestController
@@ -47,12 +42,8 @@ public class AppTradeOrderController {
 
     @Resource
     private TradeOrderService tradeOrderService;
-
     @Resource
     private ProductPropertyValueApi productPropertyValueApi;
-    @Resource
-    private ProductCommentApi productCommentApi;
-
     @Resource
     private TradeOrderProperties tradeOrderProperties;
 
@@ -121,7 +112,7 @@ public class AppTradeOrderController {
         // 待发货
         orderCount.put("undeliveredCount", tradeOrderService.getOrderCount(getLoginUserId(), TradeOrderStatusEnum.UNDELIVERED.getStatus(), null));
         // 待收货
-        orderCount.put("deliveredCount", tradeOrderService.getOrderCount(getLoginUserId(),  TradeOrderStatusEnum.DELIVERED.getStatus(), null));
+        orderCount.put("deliveredCount", tradeOrderService.getOrderCount(getLoginUserId(), TradeOrderStatusEnum.DELIVERED.getStatus(), null));
         // 待评价
         orderCount.put("uncommentedCount", tradeOrderService.getOrderCount(getLoginUserId(), TradeOrderStatusEnum.COMPLETED.getStatus(), false));
         return success(orderCount);
@@ -164,22 +155,7 @@ public class AppTradeOrderController {
     @PostMapping("/item/create-comment")
     @Operation(summary = "创建交易订单项的评价")
     public CommonResult<Long> createOrderItemComment(@RequestBody AppTradeOrderItemCommentCreateReqVO createReqVO) {
-        // TODO @puhui999:这个逻辑,最好写到 service 哈;
-        Long loginUserId = getLoginUserId();
-        // 先通过订单项 ID 查询订单项是否存在
-        TradeOrderItemDO orderItemDO = tradeOrderService.getOrderItemByIdAndUserId(createReqVO.getOrderItemId(), loginUserId);
-        if (orderItemDO == null) {
-            throw exception(ORDER_ITEM_NOT_FOUND);
-        }
-        // 校验订单
-        TradeOrderDO orderDO = tradeOrderService.getOrderByIdAndUserId(orderItemDO.getOrderId(), loginUserId);
-        if (orderDO == null) {
-            throw exception(ORDER_NOT_FOUND);
-        }
-        // TODO @puhui999:要校验订单已完成,但是未评价;
-
-        ProductCommentCreateReqDTO productCommentCreateReqDTO = TradeOrderConvert.INSTANCE.convert04(createReqVO, orderItemDO);
-        return success(productCommentApi.createComment(productCommentCreateReqDTO));
+        return success(tradeOrderService.createOrderItemComment(createReqVO));
     }
 
 }

+ 0 - 5
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/item/AppTradeOrderItemCommentCreateReqVO.java

@@ -19,11 +19,6 @@ public class AppTradeOrderItemCommentCreateReqVO {
     @NotNull(message = "交易订单项编号不能为空")
     private Long orderItemId;
 
-    // TODO @puhui999:貌似不用这个字段哈;
-    @Schema(description = "评分星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
-    @NotNull(message = "评分星级 1-5 分不能为空")
-    private Integer scores;
-
     @Schema(description = "描述星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
     @NotNull(message = "描述星级 1-5 分不能为空")
     private Integer descriptionScores;

+ 0 - 1
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java

@@ -270,7 +270,6 @@ public interface TradeOrderConvert {
     @Mapping(target = "skuId", source = "tradeOrderItemDO.skuId")
     @Mapping(target = "orderId", source = "tradeOrderItemDO.orderId")
     @Mapping(target = "orderItemId", source = "tradeOrderItemDO.id")
-    @Mapping(target = "scores", source = "createReqVO.scores")
     @Mapping(target = "descriptionScores", source = "createReqVO.descriptionScores")
     @Mapping(target = "benefitScores", source = "createReqVO.benefitScores")
     @Mapping(target = "content", source = "createReqVO.content")

+ 11 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderService.java

@@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreate
 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageReqVO;
 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementReqVO;
 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementRespVO;
+import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO;
 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
 
@@ -177,4 +178,14 @@ public interface TradeOrderService {
      * @return 得到订单
      */
     TradeOrderDO getOrderByIdAndUserId(Long orderId, Long loginUserId);
+
+    /**
+     * 创建订单项评论
+     * 创建交易订单项的评价
+     *
+     * @param createReqVO 创建请求
+     * @return 得到评价 id
+     */
+    Long createOrderItemComment(AppTradeOrderItemCommentCreateReqVO createReqVO);
+
 }

+ 29 - 2
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java

@@ -17,19 +17,21 @@ import cn.iocoder.yudao.module.pay.api.order.PayOrderApi;
 import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
 import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO;
 import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum;
+import cn.iocoder.yudao.module.product.api.comment.ProductCommentApi;
+import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
 import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
 import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi;
 import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO;
 import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
 import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO;
-import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
 import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO;
 import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageReqVO;
 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO;
 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageReqVO;
 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementReqVO;
 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementRespVO;
+import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO;
 import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert;
 import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO;
 import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO;
@@ -57,6 +59,7 @@ import java.util.*;
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue;
+import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.PAY_ORDER_NOT_FOUND;
 import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
 
@@ -93,7 +96,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
     @Resource
     private MemberUserApi memberUserApi;
     @Resource
-    private AdminUserApi adminUserApi;
+    private ProductCommentApi productCommentApi;
     @Resource
     private NotifyMessageSendApi notifyMessageSendApi;
 
@@ -556,6 +559,30 @@ public class TradeOrderServiceImpl implements TradeOrderService {
         return tradeOrderMapper.selectOrderByIdAndUserId(orderId, loginUserId);
     }
 
+    @Override
+    public Long createOrderItemComment(AppTradeOrderItemCommentCreateReqVO createReqVO) {
+        Long loginUserId = getLoginUserId();
+        // 先通过订单项 ID 查询订单项是否存在
+        TradeOrderItemDO orderItemDO = getOrderItemByIdAndUserId(createReqVO.getOrderItemId(), loginUserId);
+        if (orderItemDO == null) {
+            throw exception(ORDER_ITEM_NOT_FOUND);
+        }
+        // 校验订单
+        TradeOrderDO orderDO = getOrderByIdAndUserId(orderItemDO.getOrderId(), loginUserId);
+        if (orderDO == null) {
+            throw exception(ORDER_NOT_FOUND);
+        }
+        if (ObjectUtil.notEqual(orderDO.getStatus(), TradeOrderStatusEnum.COMPLETED.getStatus())) {
+            throw exception(ORDER_COMMENT_FAIL_STATUS_NOT_COMPLETED);
+        }
+        if (ObjectUtil.notEqual(orderDO.getCommentStatus(), Boolean.FALSE)) {
+            throw exception(ORDER_COMMENT_STATUS_NOT_FALSE);
+        }
+
+        ProductCommentCreateReqDTO productCommentCreateReqDTO = TradeOrderConvert.INSTANCE.convert04(createReqVO, orderItemDO);
+        return productCommentApi.createComment(productCommentCreateReqDTO);
+    }
+
     /**
      * 判断指定订单的所有订单项,是不是都售后成功
      *

+ 6 - 6
yudao-module-member/yudao-module-member-biz/src/test/java/cn/iocoder/yudao/module/member/service/address/AddressServiceImplTest.java

@@ -19,10 +19,10 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertNull;
 
 /**
-* {@link AddressServiceImpl} 的单元测试类
-*
-* @author 芋道源码
-*/
+ * {@link AddressServiceImpl} 的单元测试类
+ *
+ * @author 芋道源码
+ */
 @Import(AddressServiceImpl.class)
 public class AddressServiceImplTest extends BaseDbUnitTest {
 
@@ -82,8 +82,8 @@ public class AddressServiceImplTest extends BaseDbUnitTest {
 
         // 调用
         addressService.deleteAddress(dbAddress.getUserId(), id);
-       // 校验数据不存在了
-       assertNull(addressMapper.selectById(id));
+        // 校验数据不存在了
+        assertNull(addressMapper.selectById(id));
     }
 
     @Test