Kaynağa Gözat

!571 完善订单发货逻辑、重构砍价活动、完善拼团记录创建逻辑
Merge pull request !571 from puhui999/feature/mall_product

芋道源码 1 yıl önce
ebeveyn
işleme
60171ce7e4
37 değiştirilmiş dosya ile 383 ekleme ve 493 silme
  1. 10 1
      yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainRecordApi.java
  2. 24 2
      yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApi.java
  3. 46 0
      yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/dto/CombinationRecordRespDTO.java
  4. 6 5
      yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java
  5. 24 0
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainRecordApiImpl.java
  6. 15 2
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApiImpl.java
  7. 7 22
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/BargainActivityController.java
  8. 17 1
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/BargainActivityBaseVO.java
  9. 1 14
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/BargainActivityPageReqVO.java
  10. 3 9
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/BargainActivityRespVO.java
  11. 1 8
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/BargainActivityUpdateReqVO.java
  12. 0 22
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/activity/BargainActivityCreateReqVO.java
  13. 0 35
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/product/BargainProductBaseVO.java
  14. 0 22
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/product/BargainProductRespVO.java
  15. 1 13
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityPageReqVO.java
  16. 4 63
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/bargain/BargainActivityConvert.java
  17. 14 10
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/combination/CombinationActivityConvert.java
  18. 17 17
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillactivity/SeckillActivityConvert.java
  19. 22 8
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/bargain/BargainActivityDO.java
  20. 0 71
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/bargain/BargainProductDO.java
  21. 2 1
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/bargain/BargainActivityMapper.java
  22. 0 22
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/bargain/BargainProductMapper.java
  23. 0 2
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/CombinationActivityMapper.java
  24. 20 6
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/CombinationRecordMapper.java
  25. 4 14
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityService.java
  26. 26 70
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityServiceImpl.java
  27. 1 1
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainRecordService.java
  28. 14 0
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainRecordServiceImpl.java
  29. 21 0
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordService.java
  30. 34 4
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java
  31. 0 3
      yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImplTest.java
  32. 1 4
      yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java
  33. 0 2
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderDeliveryReqVO.java
  34. 2 3
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java
  35. 6 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderItemMapper.java
  36. 3 2
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderService.java
  37. 37 34
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java

+ 10 - 1
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainRecordApi.java

@@ -14,10 +14,19 @@ import javax.validation.Valid;
 public interface BargainRecordApi {
 
     /**
-     * 创建开团记录
+     * 创建砍价记录
      *
      * @param reqDTO 请求 DTO
      */
     void createRecord(@Valid BargainRecordCreateReqDTO reqDTO);
 
+    /**
+     * 查询砍价是否成功
+     *
+     * @param userId  用户编号
+     * @param orderId 订单编号
+     * @return 砍价是否成功
+     */
+    boolean validateRecordSuccess(Long userId, Long orderId);
+
 }

+ 24 - 2
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApi.java

@@ -1,11 +1,14 @@
 package cn.iocoder.yudao.module.promotion.api.combination;
 
 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
+import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO;
 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordUpdateStatusReqDTO;
 
 import javax.validation.Valid;
+import java.util.List;
 
 // TODO @芋艿:后面也再撸撸这几个接口
+
 /**
  * 拼团记录 API 接口
  *
@@ -18,7 +21,7 @@ public interface CombinationRecordApi {
      *
      * @param reqDTO 请求 DTO
      */
-    void createCombinationRecord(@Valid CombinationRecordCreateReqDTO reqDTO);
+    void createRecord(@Valid CombinationRecordCreateReqDTO reqDTO);
 
     /**
      * 查询拼团记录是否成功
@@ -27,7 +30,26 @@ public interface CombinationRecordApi {
      * @param orderId 订单编号
      * @return 拼团是否成功
      */
-    boolean isCombinationRecordSuccess(Long userId, Long orderId);
+    boolean validateRecordSuccess(Long userId, Long orderId);
+
+    /**
+     * 获取拼团记录
+     *
+     * @param userId     用户编号
+     * @param activityId 活动编号
+     * @return 拼团记录列表
+     */
+    List<CombinationRecordRespDTO> getRecordListByUserIdAndActivityId(Long userId, Long activityId);
+
+    /**
+     * 验证组合限制数
+     * 校验是否满足限购要求
+     *
+     * @param count      本次购买数量
+     * @param sumCount   已购买数量合计
+     * @param activityId 活动编号
+     */
+    void validateCombinationLimitCount(Long activityId, Integer count, Integer sumCount);
 
     // TODO @puhui999:是不是搞成具体的方法,拼团成功,拼团失败,这种方法;
 

+ 46 - 0
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/dto/CombinationRecordRespDTO.java

@@ -0,0 +1,46 @@
+package cn.iocoder.yudao.module.promotion.api.combination.dto;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * 拼团记录 Response DTO
+ *
+ * @author HUIHUI
+ */
+@Data
+public class CombinationRecordRespDTO {
+
+    /**
+     * 拼团活动编号
+     */
+    @NotNull(message = "拼团活动编号不能为空")
+    private Long activityId;
+    /**
+     * spu 编号
+     */
+    @NotNull(message = "spu 编号不能为空")
+    private Long spuId;
+    /**
+     * sku 编号
+     */
+    @NotNull(message = "sku 编号不能为空")
+    private Long skuId;
+    /**
+     * 用户编号
+     */
+    @NotNull(message = "用户编号不能为空")
+    private Long userId;
+    /**
+     * 订单编号
+     */
+    @NotNull(message = "订单编号不能为空")
+    private Long orderId;
+    /**
+     * 开团状态:正在开团 拼团成功 拼团失败
+     */
+    @NotNull(message = "开团状态不能为空")
+    private Integer status;
+
+}

+ 6 - 5
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java

@@ -64,17 +64,18 @@ public interface ErrorCodeConstants {
     ErrorCode COMBINATION_RECORD_NOT_EXISTS = new ErrorCode(1013010004, "拼团不存在");
     ErrorCode COMBINATION_RECORD_EXISTS = new ErrorCode(1013010005, "拼团失败,已参与过该拼团");
     ErrorCode COMBINATION_RECORD_HEAD_NOT_EXISTS = new ErrorCode(1013010006, "拼团失败,父拼团不存在");
-    ErrorCode COMBINATION_RECORD_USER_FULL = new ErrorCode(1013010006, "拼团失败,拼团人数已满");
+    ErrorCode COMBINATION_RECORD_USER_FULL = new ErrorCode(1013010007, "拼团失败,拼团人数已满");
+    ErrorCode COMBINATION_RECORD_FAILED_HAVE_JOINED = new ErrorCode(1013010008, "拼团失败,已参与其它拼团");
+    ErrorCode COMBINATION_RECORD_FAILED_TIME_END = new ErrorCode(1013010009, "拼团失败,活动已经结束");
+    ErrorCode COMBINATION_RECORD_FAILED_SINGLE_LIMIT_COUNT_EXCEED = new ErrorCode(1013010010, "拼团失败,单次限购超出");
+    ErrorCode COMBINATION_RECORD_FAILED_TOTAL_LIMIT_COUNT_EXCEED = new ErrorCode(1013010011, "拼团失败,单次限购超出");
 
     // ========== 砍价活动 1013011000 ==========
     ErrorCode BARGAIN_ACTIVITY_NOT_EXISTS = new ErrorCode(1013011000, "砍价活动不存在");
     ErrorCode BARGAIN_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1013011001, "存在商品参加了其它砍价活动");
     ErrorCode BARGAIN_ACTIVITY_STATUS_DISABLE = new ErrorCode(1013011002, "砍价活动已关闭不能修改");
     ErrorCode BARGAIN_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1013011003, "砍价活动未关闭或未结束,不能删除");
-
-    // TODO @puhui999:拆分成砍价记录
-
-    ErrorCode BARGAIN_RECORD_NOT_EXISTS = new ErrorCode(1013011004, "砍价不存在");
+    ErrorCode BARGAIN_RECORD_NOT_EXISTS = new ErrorCode(1013011004, "砍价记录不存在");
     ErrorCode BARGAIN_RECORD_EXISTS = new ErrorCode(1013011005, "砍价失败,已参与过该砍价");
     ErrorCode BARGAIN_RECORD_HEAD_NOT_EXISTS = new ErrorCode(1013011006, "砍价失败,父砍价不存在");
     ErrorCode BARGAIN_RECORD_USER_FULL = new ErrorCode(1013011007, "砍价失败,砍价人数已满");

+ 24 - 0
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainRecordApiImpl.java

@@ -0,0 +1,24 @@
+package cn.iocoder.yudao.module.promotion.api.bargain;
+
+import cn.iocoder.yudao.module.promotion.api.bargain.dto.BargainRecordCreateReqDTO;
+import org.springframework.stereotype.Service;
+
+/**
+ * 砍价活动 API 实现类 TODO @puhui999
+ *
+ * @author HUIHUI
+ */
+@Service
+public class BargainRecordApiImpl implements BargainRecordApi {
+
+    @Override
+    public void createRecord(BargainRecordCreateReqDTO reqDTO) {
+
+    }
+
+    @Override
+    public boolean validateRecordSuccess(Long userId, Long orderId) {
+        return false;
+    }
+
+}

+ 15 - 2
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApiImpl.java

@@ -1,12 +1,15 @@
 package cn.iocoder.yudao.module.promotion.api.combination;
 
 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
+import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO;
 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordUpdateStatusReqDTO;
+import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert;
 import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
 import cn.iocoder.yudao.module.promotion.service.combination.CombinationRecordService;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
+import java.util.List;
 
 /**
  * 拼团活动 API 实现类
@@ -20,15 +23,25 @@ public class CombinationRecordApiImpl implements CombinationRecordApi {
     private CombinationRecordService recordService;
 
     @Override
-    public void createCombinationRecord(CombinationRecordCreateReqDTO reqDTO) {
+    public void createRecord(CombinationRecordCreateReqDTO reqDTO) {
         recordService.createCombinationRecord(reqDTO);
     }
 
     @Override
-    public boolean isCombinationRecordSuccess(Long userId, Long orderId) {
+    public boolean validateRecordSuccess(Long userId, Long orderId) {
         return CombinationRecordStatusEnum.isSuccess(recordService.getCombinationRecord(userId, orderId).getStatus());
     }
 
+    @Override
+    public List<CombinationRecordRespDTO> getRecordListByUserIdAndActivityId(Long userId, Long activityId) {
+        return CombinationActivityConvert.INSTANCE.convert(recordService.getRecordListByUserIdAndActivityId(userId, activityId));
+    }
+
+    @Override
+    public void validateCombinationLimitCount(Long activityId, Integer count, Integer sumCount) {
+        recordService.validateCombinationLimitCount(activityId, count, sumCount);
+    }
+
     @Override
     public void updateCombinationRecordStatus(CombinationRecordUpdateStatusReqDTO reqDTO) {
         if (null == reqDTO.getStartTime()) {

+ 7 - 22
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/BargainActivityController.java

@@ -4,14 +4,12 @@ import cn.hutool.core.collection.CollUtil;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 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.bargain.vo.activity.BargainActivityCreateReqVO;
-import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.BargainActivityPageReqVO;
-import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.BargainActivityRespVO;
-import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.BargainActivityUpdateReqVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityBaseVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityPageReqVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityRespVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityUpdateReqVO;
 import cn.iocoder.yudao.module.promotion.convert.bargain.BargainActivityConvert;
 import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO;
-import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainProductDO;
 import cn.iocoder.yudao.module.promotion.service.bargain.BargainActivityService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
@@ -22,12 +20,8 @@ import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
 import javax.validation.Valid;
-import java.util.Collections;
-import java.util.List;
 
-import static cn.hutool.core.collection.CollectionUtil.newArrayList;
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
 
 @Tag(name = "管理后台 - 砍价活动")
 @RestController
@@ -44,7 +38,7 @@ public class BargainActivityController {
     @PostMapping("/create")
     @Operation(summary = "创建砍价活动")
     @PreAuthorize("@ss.hasPermission('promotion:bargain-activity:create')")
-    public CommonResult<Long> createBargainActivity(@Valid @RequestBody BargainActivityCreateReqVO createReqVO) {
+    public CommonResult<Long> createBargainActivity(@Valid @RequestBody BargainActivityBaseVO createReqVO) {
         return success(activityService.createBargainActivity(createReqVO));
     }
 
@@ -70,9 +64,7 @@ public class BargainActivityController {
     @Parameter(name = "id", description = "编号", required = true, example = "1024")
     @PreAuthorize("@ss.hasPermission('promotion:bargain-activity:query')")
     public CommonResult<BargainActivityRespVO> getBargainActivity(@RequestParam("id") Long id) {
-        BargainActivityDO activity = activityService.getBargainActivity(id);
-        List<BargainProductDO> products = activityService.getBargainProductsByActivityIds(newArrayList(id));
-        return success(BargainActivityConvert.INSTANCE.convert(activity, products));
+        return success(BargainActivityConvert.INSTANCE.convert(activityService.getBargainActivity(id)));
     }
 
     @GetMapping("/page")
@@ -85,14 +77,7 @@ public class BargainActivityController {
         if (CollUtil.isEmpty(pageResult.getList())) {
             return success(PageResult.empty(pageResult.getTotal()));
         }
-
-        // 拼接数据
-//        List<BargainProductDO> products = activityService.getBargainProductsByActivityIds(
-//                convertSet(pageResult.getList(), BargainActivityDO::getId));
-        List<BargainProductDO> products = Collections.emptyList();
-        List<ProductSpuRespDTO> spus = productSpuApi.getSpuList(
-                convertSet(pageResult.getList(), BargainActivityDO::getSpuId));
-        return success(BargainActivityConvert.INSTANCE.convertPage(pageResult, products, spus));
+        return success(BargainActivityConvert.INSTANCE.convertPage(activityService.getBargainActivityPage(pageVO)));
     }
 
 }

+ 17 - 1
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/activity/BargainActivityBaseVO.java → yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/BargainActivityBaseVO.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity;
+package cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo;
 
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
@@ -26,6 +26,22 @@ public class BargainActivityBaseVO {
     @NotNull(message = "砍价商品不能为空")
     private Long spuId;
 
+    @Schema(description = "商品 skuId", requiredMode = Schema.RequiredMode.REQUIRED, example = "23")
+    @NotNull(message = "商品 skuId 不能为空")
+    private Long skuId;
+
+    @Schema(description = "砍价起始价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "23")
+    @NotNull(message = "砍价起始价格不能为空")
+    private Integer bargainFirstPrice;
+
+    @Schema(description = "砍价底价", requiredMode = Schema.RequiredMode.REQUIRED, example = "23")
+    @NotNull(message = "砍价底价不能为空")
+    private Integer bargainPrice;
+
+    @Schema(description = "活动库存", requiredMode = Schema.RequiredMode.REQUIRED, example = "23")
+    @NotNull(message = "活动库存不能为空")
+    private Integer stock;
+
     @Schema(description = "总限购数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "16218")
     @NotNull(message = "总限购数量不能为空")
     private Integer totalLimitCount;

+ 1 - 14
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/activity/BargainActivityPageReqVO.java → yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/BargainActivityPageReqVO.java

@@ -1,15 +1,10 @@
-package cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity;
+package cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo;
 
 import cn.iocoder.yudao.framework.common.pojo.PageParam;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.ToString;
-import org.springframework.format.annotation.DateTimeFormat;
-
-import java.time.LocalDateTime;
-
-import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
 
 @Schema(description = "管理后台 - 砍价活动分页 Request VO")
 @Data
@@ -20,14 +15,6 @@ public class BargainActivityPageReqVO extends PageParam {
     @Schema(description = "砍价名称", example = "赵六")
     private String name;
 
-    @Schema(description = "开始时间")
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    private LocalDateTime[] startTime;
-
-    @Schema(description = "结束时间")
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    private LocalDateTime[] endTime;
-
     @Schema(description = "活动状态:0开启 1关闭", example = "0")
     private Integer status;
 

+ 3 - 9
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/activity/BargainActivityRespVO.java → yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/BargainActivityRespVO.java

@@ -1,6 +1,5 @@
-package cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity;
+package cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo;
 
-import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.product.BargainProductRespVO;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
@@ -8,8 +7,6 @@ import lombok.ToString;
 
 import javax.validation.constraints.NotNull;
 import java.time.LocalDateTime;
-import java.util.List;
-
 @Schema(description = "管理后台 - 砍价活动 Response VO")
 @Data
 @EqualsAndHashCode(callSuper = true)
@@ -25,17 +22,14 @@ public class BargainActivityRespVO extends BargainActivityBaseVO {
     @Schema(description = "活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22901")
     private Long id;
 
-    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2022-07-01 23:59:59")
     private LocalDateTime createTime;
 
-    @Schema(description = "砍价成功数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "888")
+    @Schema(description = "砍价成功数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "999")
     private Integer successCount;
 
     @Schema(description = "活动状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
     @NotNull(message = "活动状态不能为空")
     private Integer status;
 
-    @Schema(description = "砍价商品", requiredMode = Schema.RequiredMode.REQUIRED)
-    private List<BargainProductRespVO> products;
-
 }

+ 1 - 8
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/activity/BargainActivityUpdateReqVO.java → yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/BargainActivityUpdateReqVO.java

@@ -1,14 +1,11 @@
-package cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity;
+package cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo;
 
-import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.product.BargainProductBaseVO;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.ToString;
 
-import javax.validation.Valid;
 import javax.validation.constraints.NotNull;
-import java.util.List;
 
 @Schema(description = "管理后台 - 砍价活动更新 Request VO")
 @Data
@@ -20,8 +17,4 @@ public class BargainActivityUpdateReqVO extends BargainActivityBaseVO {
     @NotNull(message = "活动编号不能为空")
     private Long id;
 
-    @Schema(description = "砍价商品", requiredMode = Schema.RequiredMode.REQUIRED)
-    @Valid
-    private List<BargainProductBaseVO> products;
-
 }

+ 0 - 22
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/activity/BargainActivityCreateReqVO.java

@@ -1,22 +0,0 @@
-package cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity;
-
-import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.product.BargainProductBaseVO;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
-
-import javax.validation.Valid;
-import java.util.List;
-
-@Schema(description = "管理后台 - 砍价活动创建 Request VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class BargainActivityCreateReqVO extends BargainActivityBaseVO {
-
-    @Schema(description = "砍价商品", requiredMode = Schema.RequiredMode.REQUIRED)
-    @Valid
-    private List<BargainProductBaseVO> products;
-
-}

+ 0 - 35
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/product/BargainProductBaseVO.java

@@ -1,35 +0,0 @@
-package cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.product;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-import javax.validation.constraints.NotNull;
-
-/**
- * 砍价商品 Base VO,提供给添加、修改、详细的子 VO 使用
- * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
- */
-@Data
-public class BargainProductBaseVO {
-
-    @Schema(description = "商品 spuId", requiredMode = Schema.RequiredMode.REQUIRED, example = "123")
-    @NotNull(message = "商品 spuId 不能为空")
-    private Long spuId;
-
-    @Schema(description = "商品 skuId", requiredMode = Schema.RequiredMode.REQUIRED, example = "44")
-    @NotNull(message = "商品 skuId 不能为空")
-    private Long skuId;
-
-    @Schema(description = "砍价起始价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "33")
-    @NotNull(message = "砍价起始价格不能为空")
-    private Integer bargainFirstPrice;
-
-    @Schema(description = "砍价底价", requiredMode = Schema.RequiredMode.REQUIRED, example = "22")
-    @NotNull(message = "砍价底价不能为空")
-    private Integer bargainPrice;
-
-    @Schema(description = "活动库存", requiredMode = Schema.RequiredMode.REQUIRED, example = "11")
-    @NotNull(message = "活动库存不能为空")
-    private Integer stock;
-
-}

+ 0 - 22
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/product/BargainProductRespVO.java

@@ -1,22 +0,0 @@
-package cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.product;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
-
-import java.time.LocalDateTime;
-
-@Schema(description = "管理后台 - 砍价商品 Response VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class BargainProductRespVO extends BargainProductBaseVO {
-
-    @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "28322")
-    private Long id;
-
-    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
-    private LocalDateTime createTime;
-
-}

+ 1 - 13
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityPageReqVO.java

@@ -5,11 +5,6 @@ import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.ToString;
-import org.springframework.format.annotation.DateTimeFormat;
-
-import java.time.LocalDateTime;
-
-import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
 
 @Schema(description = "管理后台 - 拼团活动分页 Request VO")
 @Data
@@ -20,15 +15,8 @@ public class CombinationActivityPageReqVO extends PageParam {
     @Schema(description = "拼团名称", example = "赵六")
     private String name;
 
-    @Schema(description = "开始时间")
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    private LocalDateTime[] startTime;
-
-    @Schema(description = "结束时间")
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    private LocalDateTime[] endTime;
-
     @Schema(description = "活动状态:0开启 1关闭", example = "0")
     private Integer status;
 
+
 }

+ 4 - 63
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/bargain/BargainActivityConvert.java

@@ -1,25 +1,14 @@
 package cn.iocoder.yudao.module.promotion.convert.bargain;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
-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.controller.admin.bargain.vo.activity.BargainActivityCreateReqVO;
-import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.BargainActivityRespVO;
-import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.BargainActivityUpdateReqVO;
-import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.product.BargainProductBaseVO;
-import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.product.BargainProductRespVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityBaseVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityRespVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityUpdateReqVO;
 import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO;
-import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainProductDO;
 import org.mapstruct.Mapper;
-import org.mapstruct.Mapping;
-import org.mapstruct.Mappings;
 import org.mapstruct.factory.Mappers;
 
 import java.util.List;
-import java.util.Map;
-
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
 
 /**
  * 拼团活动 Convert
@@ -31,62 +20,14 @@ public interface BargainActivityConvert {
 
     BargainActivityConvert INSTANCE = Mappers.getMapper(BargainActivityConvert.class);
 
-    BargainActivityDO convert(BargainActivityCreateReqVO bean);
+    BargainActivityDO convert(BargainActivityBaseVO bean);
 
     BargainActivityDO convert(BargainActivityUpdateReqVO bean);
 
     BargainActivityRespVO convert(BargainActivityDO bean);
 
-    BargainProductRespVO convert(BargainProductDO bean);
-
-    default BargainActivityRespVO convert(BargainActivityDO activity,
-                                          List<BargainProductDO> products) {
-        return convert(activity).setProducts(convertList2(products));
-    }
-
     List<BargainActivityRespVO> convertList(List<BargainActivityDO> list);
 
     PageResult<BargainActivityRespVO> convertPage(PageResult<BargainActivityDO> page);
 
-    default PageResult<BargainActivityRespVO> convertPage(PageResult<BargainActivityDO> page,
-                                                          List<BargainProductDO> productList,
-                                                          List<ProductSpuRespDTO> spuList) {
-        PageResult<BargainActivityRespVO> pageResult = convertPage(page);
-        // 拼接商品
-        Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId);
-        pageResult.getList().forEach(item -> {
-            item.setProducts(convertList2(productList));
-            MapUtils.findAndThen(spuMap, item.getSpuId(),
-                    spu -> item.setSpuName(spu.getName()).setPicUrl(spu.getPicUrl()));
-        });
-        return pageResult;
-    }
-
-    List<BargainProductRespVO> convertList2(List<BargainProductDO> productDOs);
-
-    @Mappings({
-            @Mapping(target = "id", ignore = true),
-            @Mapping(target = "activityId", source = "activity.id"),
-            @Mapping(target = "spuId", source = "activity.spuId"),
-            @Mapping(target = "skuId", source = "product.skuId"),
-            @Mapping(target = "bargainFirstPrice", source = "product.bargainFirstPrice"),
-            @Mapping(target = "bargainPrice", source = "product.bargainPrice"),
-            @Mapping(target = "stock", source = "product.stock"),
-            @Mapping(target = "activityStartTime", source = "activity.startTime"),
-            @Mapping(target = "activityEndTime", source = "activity.endTime")
-    })
-    BargainProductDO convert(BargainActivityDO activity, BargainProductBaseVO product);
-
-    default List<BargainProductDO> convertList(List<? extends BargainProductBaseVO> products, BargainActivityDO activityDO) {
-        return CollectionUtils.convertList(products, item -> convert(activityDO, item).setActivityStatus(activityDO.getStatus()));
-    }
-
-    default List<BargainProductDO> convertList(List<BargainProductBaseVO> updateProductVOs,
-                                               List<BargainProductDO> products, BargainActivityDO activity) {
-        Map<Long, Long> productMap = convertMap(products, BargainProductDO::getSkuId, BargainProductDO::getId);
-        return CollectionUtils.convertList(updateProductVOs, updateProductVO -> convert(activity, updateProductVO)
-                .setId(productMap.get(updateProductVO.getSkuId()))
-                .setActivityStatus(activity.getStatus()));
-    }
-
 }

+ 14 - 10
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/combination/CombinationActivityConvert.java

@@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 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.combination.dto.CombinationRecordCreateReqDTO;
+import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO;
 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityCreateReqVO;
 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityRespVO;
 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO;
@@ -41,9 +42,8 @@ public interface CombinationActivityConvert {
 
     CombinationProductRespVO convert(CombinationProductDO bean);
 
-    default CombinationActivityRespVO convert(CombinationActivityDO activity,
-                                              List<CombinationProductDO> products) {
-        return convert(activity).setProducts(convertList2(products));
+    default CombinationActivityRespVO convert(CombinationActivityDO bean, List<CombinationProductDO> productDOs) {
+        return convert(bean).setProducts(convertList2(productDOs));
     }
 
     List<CombinationActivityRespVO> convertList(List<CombinationActivityDO> list);
@@ -53,22 +53,20 @@ public interface CombinationActivityConvert {
     default PageResult<CombinationActivityRespVO> convertPage(PageResult<CombinationActivityDO> page,
                                                               List<CombinationProductDO> productList,
                                                               List<ProductSpuRespDTO> spuList) {
-        PageResult<CombinationActivityRespVO> pageResult = convertPage(page);
-        // 拼接商品
         Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId);
+        PageResult<CombinationActivityRespVO> pageResult = convertPage(page);
         pageResult.getList().forEach(item -> {
+            MapUtils.findAndThen(spuMap, item.getSpuId(), spu -> {
+                item.setSpuName(spu.getName());
+                item.setPicUrl(spu.getPicUrl());
+            });
             item.setProducts(convertList2(productList));
-            MapUtils.findAndThen(spuMap, item.getSpuId(),
-                    spu -> item.setSpuName(spu.getName()).setPicUrl(spu.getPicUrl()));
         });
         return pageResult;
     }
 
     List<CombinationProductRespVO> convertList2(List<CombinationProductDO> productDOs);
 
-    default List<CombinationProductDO> convertList(List<? extends CombinationProductBaseVO> products, CombinationActivityDO activityDO) {
-        return CollectionUtils.convertList(products, item -> convert(activityDO, item).setActivityStatus(activityDO.getStatus()));
-    }
     @Mappings({
             @Mapping(target = "id", ignore = true),
             @Mapping(target = "activityId", source = "activity.id"),
@@ -80,6 +78,10 @@ public interface CombinationActivityConvert {
     })
     CombinationProductDO convert(CombinationActivityDO activity, CombinationProductBaseVO product);
 
+    default List<CombinationProductDO> convertList(List<? extends CombinationProductBaseVO> products, CombinationActivityDO activity) {
+        return CollectionUtils.convertList(products, item -> convert(activity, item).setActivityStatus(activity.getStatus()));
+    }
+
     default List<CombinationProductDO> convertList(List<CombinationProductBaseVO> updateProductVOs,
                                                    List<CombinationProductDO> products, CombinationActivityDO activity) {
         Map<Long, Long> productMap = convertMap(products, CombinationProductDO::getSkuId, CombinationProductDO::getId);
@@ -90,4 +92,6 @@ public interface CombinationActivityConvert {
 
     CombinationRecordDO convert(CombinationRecordCreateReqDTO reqDTO);
 
+    List<CombinationRecordRespDTO> convert(List<CombinationRecordDO> bean);
+
 }

+ 17 - 17
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillactivity/SeckillActivityConvert.java

@@ -20,8 +20,6 @@ import org.mapstruct.factory.Mappers;
 import java.util.List;
 import java.util.Map;
 
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
-
 /**
  * 秒杀活动 Convert
  *
@@ -40,32 +38,28 @@ public interface SeckillActivityConvert {
 
     List<SeckillActivityRespVO> convertList(List<SeckillActivityDO> list);
 
-    default PageResult<SeckillActivityRespVO> convertPage(PageResult<SeckillActivityDO> page,
-                                                          List<SeckillProductDO> seckillProducts,
-                                                          List<ProductSpuRespDTO> spuList) {
+    PageResult<SeckillActivityRespVO> convertPage(PageResult<SeckillActivityDO> page);
+
+    default PageResult<SeckillActivityRespVO> convertPage(PageResult<SeckillActivityDO> page, List<SeckillProductDO> seckillProducts, List<ProductSpuRespDTO> spuList) {
+        Map<Long, ProductSpuRespDTO> spuMap = CollectionUtils.convertMap(spuList, ProductSpuRespDTO::getId);
         PageResult<SeckillActivityRespVO> pageResult = convertPage(page);
-        // 拼接商品
-        Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId);
         pageResult.getList().forEach(item -> {
+            MapUtils.findAndThen(spuMap, item.getSpuId(), spu -> {
+                item.setSpuName(spu.getName());
+                item.setPicUrl(spu.getPicUrl());
+            });
+
             item.setProducts(convertList2(seckillProducts));
-            MapUtils.findAndThen(spuMap, item.getSpuId(),
-                    spu -> item.setSpuName(spu.getName()).setPicUrl(spu.getPicUrl()));
         });
         return pageResult;
     }
-    PageResult<SeckillActivityRespVO> convertPage(PageResult<SeckillActivityDO> page);
 
     SeckillActivityDetailRespVO convert1(SeckillActivityDO seckillActivity);
 
-    default SeckillActivityDetailRespVO convert(SeckillActivityDO activity,
-                                                List<SeckillProductDO> products) {
-        return convert1(activity).setProducts(convertList2(products));
+    default SeckillActivityDetailRespVO convert(SeckillActivityDO seckillActivity, List<SeckillProductDO> seckillProducts) {
+        return convert1(seckillActivity).setProducts(convertList2(seckillProducts));
     }
-    List<SeckillProductRespVO> convertList2(List<SeckillProductDO> productDOs);
 
-    default List<SeckillProductDO> convertList(List<? extends SeckillProductBaseVO> products, SeckillActivityDO activityDO) {
-        return CollectionUtils.convertList(products, item -> convert(activityDO, item).setActivityStatus(activityDO.getStatus()));
-    }
     @Mappings({
             @Mapping(target = "id", ignore = true),
             @Mapping(target = "activityId", source = "activity.id"),
@@ -79,4 +73,10 @@ public interface SeckillActivityConvert {
     })
     SeckillProductDO convert(SeckillActivityDO activity, SeckillProductBaseVO product);
 
+    default List<SeckillProductDO> convertList(List<? extends SeckillProductBaseVO> products, SeckillActivityDO activity) {
+        return CollectionUtils.convertList(products, item -> convert(activity, item).setActivityStatus(activity.getStatus()));
+    }
+
+    List<SeckillProductRespVO> convertList2(List<SeckillProductDO> productDOs);
+
 }

+ 22 - 8
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/bargain/BargainActivityDO.java

@@ -1,6 +1,5 @@
 package cn.iocoder.yudao.module.promotion.dal.dataobject.bargain;
 
-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.TableId;
@@ -29,6 +28,7 @@ public class BargainActivityDO extends BaseDO {
      */
     @TableId
     private Long id;
+
     /**
      * 砍价活动名称
      */
@@ -38,6 +38,7 @@ public class BargainActivityDO extends BaseDO {
      * 活动开始时间
      */
     private LocalDateTime startTime;
+
     /**
      * 活动结束时间
      */
@@ -45,8 +46,6 @@ public class BargainActivityDO extends BaseDO {
 
     /**
      * 活动状态
-     *
-     * 枚举 {@link CommonStatusEnum}
      */
     private Integer status;
 
@@ -55,35 +54,50 @@ public class BargainActivityDO extends BaseDO {
      */
     private Long spuId;
     /**
-     * 砍价库存
+     * 商品 SKU 编号
      */
-    private Integer stock;
-
+    private Long skuId;
+    /**
+     * 砍价起始价格,单位分
+     */
+    private Integer bargainFirstPrice;
+    /**
+     * 砍价底价,单位:分
+     */
+    private Integer bargainPrice;
     /**
      * 达到该人数,才能砍到低价
      */
     private Integer userSize;
+
     /**
      * 最大帮砍次数
      */
     private Integer bargainCount;
+
     /**
      * 总限购数量
      */
     private Integer totalLimitCount;
+
+    /**
+     * 砍价活动库存
+     */
+    private Integer stock;
+
     /**
      * 用户每次砍价的最小金额,单位:分
      */
     private Integer randomMinPrice;
+
     /**
      * 用户每次砍价的最大金额,单位:分
      */
     private Integer randomMaxPrice;
+
     /**
      * 砍价成功数量
      */
     private Integer successCount;
 
-    // TODO @puhui999:把 BargainProductDO 字段融合过来;
-
 }

+ 0 - 71
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/bargain/BargainProductDO.java

@@ -1,71 +0,0 @@
-package cn.iocoder.yudao.module.promotion.dal.dataobject.bargain;
-
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
-import com.baomidou.mybatisplus.annotation.KeySequence;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.*;
-
-import java.time.LocalDateTime;
-
-/**
- * 砍价商品 DO
- *
- * @author HUIHUI
- */
-@Deprecated // 应该融合到 BargainActivityDO 表
-@TableName("promotion_bargain_product")
-@KeySequence("promotion_bargain_product_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-@Builder
-@NoArgsConstructor
-@AllArgsConstructor
-public class BargainProductDO extends BaseDO {
-
-    /**
-     * 编号
-     */
-    @TableId
-    private Long id;
-    /**
-     * 砍价活动编号
-     */
-    private Long activityId;
-    /**
-     * 商品 SPU 编号
-     */
-    private Long spuId;
-    /**
-     * 商品 SKU 编号
-     */
-    private Long skuId;
-    /**
-     * 砍价商品状态
-     *
-     * 关联 {@link BargainActivityDO#getStatus()}
-     */
-    private Integer activityStatus;
-    /**
-     * 活动开始时间点
-     */
-    private LocalDateTime activityStartTime;
-    /**
-     * 活动结束时间点
-     */
-    private LocalDateTime activityEndTime;
-    /**
-     * 砍价起始价格,单位分
-     */
-    private Integer bargainFirstPrice;
-    /**
-     * 砍价底价,单位:分
-     */
-    private Integer bargainPrice;
-    /**
-     * 活动库存
-     */
-    private Integer stock;
-
-}

+ 2 - 1
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/bargain/BargainActivityMapper.java

@@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.promotion.dal.mysql.bargain;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
-import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.BargainActivityPageReqVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityPageReqVO;
 import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO;
 import org.apache.ibatis.annotations.Mapper;
 
@@ -20,6 +20,7 @@ public interface BargainActivityMapper extends BaseMapperX<BargainActivityDO> {
     default PageResult<BargainActivityDO> selectPage(BargainActivityPageReqVO reqVO) {
         return selectPage(reqVO, new LambdaQueryWrapperX<BargainActivityDO>()
                 .likeIfPresent(BargainActivityDO::getName, reqVO.getName())
+                .eqIfPresent(BargainActivityDO::getStatus, reqVO.getStatus())
                 .orderByDesc(BargainActivityDO::getId));
     }
 

+ 0 - 22
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/bargain/BargainProductMapper.java

@@ -1,22 +0,0 @@
-package cn.iocoder.yudao.module.promotion.dal.mysql.bargain;
-
-import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
-import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainProductDO;
-import org.apache.ibatis.annotations.Mapper;
-
-import java.util.Collection;
-import java.util.List;
-
-/**
- * 砍价商品 Mapper
- *
- * @author HUIHUI
- */
-@Mapper
-public interface BargainProductMapper extends BaseMapperX<BargainProductDO> {
-
-    default List<BargainProductDO> selectListByActivityIds(Collection<Long> ids) {
-        return selectList(BargainProductDO::getActivityId, ids);
-    }
-
-}

+ 0 - 2
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/CombinationActivityMapper.java

@@ -20,8 +20,6 @@ public interface CombinationActivityMapper extends BaseMapperX<CombinationActivi
     default PageResult<CombinationActivityDO> selectPage(CombinationActivityPageReqVO reqVO) {
         return selectPage(reqVO, new LambdaQueryWrapperX<CombinationActivityDO>()
                 .likeIfPresent(CombinationActivityDO::getName, reqVO.getName())
-                .betweenIfPresent(CombinationActivityDO::getStartTime, reqVO.getStartTime())
-                .betweenIfPresent(CombinationActivityDO::getEndTime, reqVO.getEndTime())
                 .eqIfPresent(CombinationActivityDO::getStatus, reqVO.getStatus())
                 .orderByDesc(CombinationActivityDO::getId));
     }

+ 20 - 6
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/CombinationRecordMapper.java

@@ -20,18 +20,20 @@ public interface CombinationRecordMapper extends BaseMapperX<CombinationRecordDO
                 CombinationRecordDO::getOrderId, orderId);
     }
 
-    // TODO @puhui999 selectByUserIdAndActivityId
+    default List<CombinationRecordDO> selectListByUserIdAndStatus(Long userId, Integer status) {
+        return selectList(new LambdaQueryWrapperX<CombinationRecordDO>()
+                .eq(CombinationRecordDO::getUserId, userId)
+                .eq(CombinationRecordDO::getStatus, status));
+    }
     /**
      * 查询拼团记录
      *
-     * @param headId     团长编号
-     * @param activityId 活动编号
+     * @param headId 团长编号
      * @return 拼团记录
      */
-    default CombinationRecordDO selectRecordByHeadId(Long headId, Long activityId, Integer status) {
+    default CombinationRecordDO selectOneByHeadId(Long headId, Integer status) {
         return selectOne(new LambdaQueryWrapperX<CombinationRecordDO>()
-                .eq(CombinationRecordDO::getUserId, headId)
-                .eq(CombinationRecordDO::getActivityId, activityId)
+                .eq(CombinationRecordDO::getId, headId)
                 .eq(CombinationRecordDO::getStatus, status));
     }
 
@@ -45,4 +47,16 @@ public interface CombinationRecordMapper extends BaseMapperX<CombinationRecordDO
         return selectList(CombinationRecordDO::getStatus, status);
     }
 
+    /**
+     * 查询拼团记录
+     *
+     * @param userId     用户 id
+     * @param activityId 活动 id
+     * @return 拼团记录
+     */
+    default List<CombinationRecordDO> selectListByUserIdAndActivityId(Long userId, Long activityId) {
+        return selectList(new LambdaQueryWrapperX<CombinationRecordDO>()
+                .eq(CombinationRecordDO::getUserId, userId)
+                .eq(CombinationRecordDO::getActivityId, activityId));
+    }
 }

+ 4 - 14
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityService.java

@@ -1,15 +1,12 @@
 package cn.iocoder.yudao.module.promotion.service.bargain;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.BargainActivityCreateReqVO;
-import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.BargainActivityPageReqVO;
-import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.BargainActivityUpdateReqVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityBaseVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityPageReqVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityUpdateReqVO;
 import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO;
-import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainProductDO;
 
 import javax.validation.Valid;
-import java.util.Collection;
-import java.util.List;
 
 /**
  * 砍价活动 Service 接口
@@ -24,7 +21,7 @@ public interface BargainActivityService {
      * @param createReqVO 创建信息
      * @return 编号
      */
-    Long createBargainActivity(@Valid BargainActivityCreateReqVO createReqVO);
+    Long createBargainActivity(@Valid BargainActivityBaseVO createReqVO);
 
     /**
      * 更新砍价活动
@@ -56,12 +53,5 @@ public interface BargainActivityService {
      */
     PageResult<BargainActivityDO> getBargainActivityPage(BargainActivityPageReqVO pageReqVO);
 
-    /**
-     * 获得砍价活动商品列表
-     *
-     * @param activityIds 砍价活动 ids
-     * @return 砍价活动的商品列表
-     */
-    List<BargainProductDO> getBargainProductsByActivityIds(Collection<Long> activityIds);
 
 }

+ 26 - 70
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityServiceImpl.java

@@ -10,29 +10,25 @@ import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
 import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
 import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
-import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.BargainActivityCreateReqVO;
-import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.BargainActivityPageReqVO;
-import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.BargainActivityUpdateReqVO;
-import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.product.BargainProductBaseVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityBaseVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityPageReqVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityUpdateReqVO;
 import cn.iocoder.yudao.module.promotion.convert.bargain.BargainActivityConvert;
 import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO;
-import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainProductDO;
 import cn.iocoder.yudao.module.promotion.dal.mysql.bargain.BargainActivityMapper;
-import cn.iocoder.yudao.module.promotion.dal.mysql.bargain.BargainProductMapper;
+import cn.iocoder.yudao.module.promotion.dal.mysql.bargain.BargainRecordMapper;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
-import java.util.Collection;
 import java.util.List;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.anyMatch;
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue;
+import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS;
 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;
 import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
-import static cn.iocoder.yudao.module.promotion.util.PromotionUtils.validateProductSkuAllExists;
 
 /**
  * 砍价活动 Service 实现类
@@ -43,42 +39,43 @@ import static cn.iocoder.yudao.module.promotion.util.PromotionUtils.validateProd
 @Validated
 public class BargainActivityServiceImpl implements BargainActivityService {
 
+
     @Resource
     private BargainActivityMapper bargainActivityMapper;
     @Resource
-    private BargainProductMapper bargainProductMapper;
-
+    private BargainRecordMapper recordMapper;
     @Resource
     private ProductSpuApi productSpuApi;
     @Resource
     private ProductSkuApi productSkuApi;
 
+    private static void validateSku(Long skuId, List<ProductSkuRespDTO> skus) {
+        // 校验商品 sku 是否存在
+        if (!CollectionUtils.convertSet(skus, ProductSkuRespDTO::getId).contains(skuId)) {
+            throw exception(SKU_NOT_EXISTS);
+        }
+    }
+
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public Long createBargainActivity(BargainActivityCreateReqVO createReqVO) {
+    public Long createBargainActivity(BargainActivityBaseVO createReqVO) {
         // 校验商品 SPU 是否存在是否参加的别的活动
-        validateProductBargainConflict(createReqVO.getSpuId(), null);
+        validateBargainConflict(createReqVO.getSpuId(), null);
         // 获取所选 spu下的所有 sku
         List<ProductSkuRespDTO> skus = productSkuApi.getSkuListBySpuId(CollectionUtil.newArrayList(createReqVO.getSpuId()));
-        // 校验商品 sku 是否存在
-        validateProductSkuAllExists(skus, createReqVO.getProducts(), BargainProductBaseVO::getSkuId);
+        validateSku(createReqVO.getSkuId(), skus);
 
         // 插入砍价活动
-        BargainActivityDO activity = BargainActivityConvert.INSTANCE.convert(createReqVO);
+        BargainActivityDO activityDO = BargainActivityConvert.INSTANCE.convert(createReqVO);
         // TODO 营销相关属性初始化 砍价成功更新相关属性
-        activity.setSuccessCount(0);
-        // 活动总库存
-        activity.setStock(getSumValue(createReqVO.getProducts(), BargainProductBaseVO::getStock, Integer::sum));
-        activity.setStatus(CommonStatusEnum.ENABLE.getStatus());
-        bargainActivityMapper.insert(activity);
-        // 插入商品
-        List<BargainProductDO> productDOs = BargainActivityConvert.INSTANCE.convertList(createReqVO.getProducts(), activity);
-        bargainProductMapper.insertBatch(productDOs);
+        activityDO.setSuccessCount(0);
+        activityDO.setStatus(CommonStatusEnum.ENABLE.getStatus());
+        bargainActivityMapper.insert(activityDO);
         // 返回
-        return activity.getId();
+        return activityDO.getId();
     }
 
-    private void validateProductBargainConflict(Long spuId, Long activityId) {
+    private void validateBargainConflict(Long spuId, Long activityId) {
         // 校验商品 spu 是否存在
         List<ProductSpuRespDTO> spuList = productSpuApi.getSpuList(CollUtil.newArrayList(spuId));
         if (CollUtil.isEmpty(spuList)) {
@@ -106,52 +103,16 @@ public class BargainActivityServiceImpl implements BargainActivityService {
             throw exception(BARGAIN_ACTIVITY_STATUS_DISABLE);
         }
         // 校验商品冲突
-        validateProductBargainConflict(updateReqVO.getSpuId(), updateReqVO.getId());
+        validateBargainConflict(updateReqVO.getSpuId(), updateReqVO.getId());
         // 获取所选 spu下的所有 sku
         List<ProductSkuRespDTO> skus = productSkuApi.getSkuListBySpuId(CollectionUtil.newArrayList(updateReqVO.getSpuId()));
         // 校验商品 sku 是否存在
-        validateProductSkuAllExists(skus, updateReqVO.getProducts(), BargainProductBaseVO::getSkuId);
+        validateSku(updateReqVO.getSkuId(), skus);
 
         // 更新
         BargainActivityDO updateObj = BargainActivityConvert.INSTANCE.convert(updateReqVO);
-        // 更新活动库存
-        updateObj.setStock(getSumValue(updateReqVO.getProducts(), BargainProductBaseVO::getStock, Integer::sum));
         bargainActivityMapper.updateById(updateObj);
-        // 更新商品
-        updateBargainProduct(updateObj, updateReqVO.getProducts());
-    }
 
-    /**
-     * 更新砍价商品
-     *
-     * @param updateObj 更新的活动
-     * @param products  商品配置
-     */
-    private void updateBargainProduct(BargainActivityDO updateObj, List<BargainProductBaseVO> products) {
-        // 默认全部新增
-        List<BargainProductDO> defaultNewList = BargainActivityConvert.INSTANCE.convertList(products, updateObj);
-        // 数据库中的老数据
-        List<BargainProductDO> oldList = bargainProductMapper.selectListByActivityIds(CollUtil.newArrayList(updateObj.getId()));
-        List<List<BargainProductDO>> lists = CollectionUtils.diffList(oldList, defaultNewList, (oldVal, newVal) -> {
-            boolean same = ObjectUtil.equal(oldVal.getSkuId(), newVal.getSkuId());
-            if (same) {
-                newVal.setId(oldVal.getId());
-            }
-            return same;
-        });
-
-        // create
-        if (CollUtil.isNotEmpty(lists.get(0))) {
-            bargainProductMapper.insertBatch(lists.get(0));
-        }
-        // update
-        if (CollUtil.isNotEmpty(lists.get(1))) {
-            bargainProductMapper.updateBatch(lists.get(1));
-        }
-        // delete
-        if (CollUtil.isNotEmpty(lists.get(2))) {
-            bargainProductMapper.deleteBatchIds(CollectionUtils.convertList(lists.get(2), BargainProductDO::getId));
-        }
     }
 
     @Override
@@ -178,7 +139,7 @@ public class BargainActivityServiceImpl implements BargainActivityService {
 
     @Override
     public BargainActivityDO getBargainActivity(Long id) {
-        return bargainActivityMapper.selectById(id);
+        return validateBargainActivityExists(id);
     }
 
     @Override
@@ -186,9 +147,4 @@ public class BargainActivityServiceImpl implements BargainActivityService {
         return bargainActivityMapper.selectPage(pageReqVO);
     }
 
-    @Override
-    public List<BargainProductDO> getBargainProductsByActivityIds(Collection<Long> activityIds) {
-        return bargainProductMapper.selectListByActivityIds(activityIds);
-    }
-
 }

+ 1 - 1
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainRecordService.java

@@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.promotion.service.bargain;
 
 
 /**
- * 商品活动记录 service
+ * 砍价记录 service 接口
  *
  * @author HUIHUI
  */

+ 14 - 0
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainRecordServiceImpl.java

@@ -0,0 +1,14 @@
+package cn.iocoder.yudao.module.promotion.service.bargain;
+
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+
+/**
+ * 砍价记录 Service 实现类
+ *
+ * @author HUIHUI
+ */
+@Service
+@Validated
+public class BargainRecordServiceImpl implements BargainRecordService {
+}

+ 21 - 0
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordService.java

@@ -4,6 +4,8 @@ import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCr
 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordUpdateStatusReqDTO;
 import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationRecordDO;
 
+import java.util.List;
+
 /**
  * 拼团记录 Service 接口
  *
@@ -41,4 +43,23 @@ public interface CombinationRecordService {
      */
     CombinationRecordDO getCombinationRecord(Long userId, Long orderId);
 
+    /**
+     * 获取拼团记录
+     *
+     * @param userId     用户 id
+     * @param activityId 活动 id
+     * @return 拼团记录列表
+     */
+    List<CombinationRecordDO> getRecordListByUserIdAndActivityId(Long userId, Long activityId);
+
+    /**
+     * 验证组合限制数
+     * 校验是否满足限购要求
+     *
+     * @param count      本次购买数量
+     * @param sumCount   已购买数量合计
+     * @param activityId 活动编号
+     */
+    void validateCombinationLimitCount(Long activityId, Integer count, Integer sumCount);
+
 }

+ 34 - 4
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java

@@ -14,11 +14,11 @@ import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
+import java.time.LocalDateTime;
 import java.util.List;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
-import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COMBINATION_RECORD_USER_FULL;
 
 // TODO 芋艿:等拼团记录做完,完整 review 下
 /**
@@ -37,6 +37,7 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
     private CombinationRecordMapper recordMapper;
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public void updateCombinationRecordStatusByUserIdAndOrderId(CombinationRecordUpdateStatusReqDTO reqDTO) {
         // 校验拼团是否存在
         CombinationRecordDO recordDO = validateCombinationRecord(reqDTO.getUserId(), reqDTO.getOrderId());
@@ -80,6 +81,7 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public void createCombinationRecord(CombinationRecordCreateReqDTO reqDTO) {
         // 1.1 校验拼团活动
         CombinationActivityDO activity = combinationActivityService.validateCombinationActivityExists(reqDTO.getActivityId());
@@ -88,9 +90,19 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
         if (recordDO != null) {
             throw exception(COMBINATION_RECORD_EXISTS);
         }
-        // 1.3 父拼团是否存在,是否已经满了
+        // 1.3 校验用户是否参加了其它拼团
+        List<CombinationRecordDO> recordDOList = recordMapper.selectListByUserIdAndStatus(reqDTO.getUserId(), CombinationRecordStatusEnum.IN_PROGRESS.getStatus());
+        if (CollUtil.isNotEmpty(recordDOList)) {
+            throw exception(COMBINATION_RECORD_FAILED_HAVE_JOINED);
+        }
+        // 1.4 校验当前活动是否过期
+        if (LocalDateTime.now().isAfter(activity.getEndTime())) {
+            throw exception(COMBINATION_RECORD_FAILED_TIME_END);
+        }
+        // 1.5 父拼团是否存在,是否已经满了
         if (reqDTO.getHeadId() != null) {
-            CombinationRecordDO recordDO1 = recordMapper.selectRecordByHeadId(reqDTO.getHeadId(), reqDTO.getActivityId(), CombinationRecordStatusEnum.IN_PROGRESS.getStatus());
+            // 查询进行中的父拼团
+            CombinationRecordDO recordDO1 = recordMapper.selectOneByHeadId(reqDTO.getHeadId(), CombinationRecordStatusEnum.IN_PROGRESS.getStatus());
             if (recordDO1 == null) {
                 throw exception(COMBINATION_RECORD_HEAD_NOT_EXISTS);
             }
@@ -99,7 +111,6 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
                 throw exception(COMBINATION_RECORD_USER_FULL);
             }
         }
-        // TODO @puhui999:应该还有一些校验,后续补噶;例如说,一个团,自己已经参与进去了,不能再参与进去;
 
         // 2. 创建拼团记录
         CombinationRecordDO record = CombinationActivityConvert.INSTANCE.convert(reqDTO);
@@ -115,6 +126,25 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
         return validateCombinationRecord(userId, orderId);
     }
 
+    @Override
+    public List<CombinationRecordDO> getRecordListByUserIdAndActivityId(Long userId, Long activityId) {
+        return recordMapper.selectListByUserIdAndActivityId(userId, activityId);
+    }
+
+    @Override
+    public void validateCombinationLimitCount(Long activityId, Integer count, Integer sumCount) {
+        // 1.1 校验拼团活动
+        CombinationActivityDO activity = combinationActivityService.validateCombinationActivityExists(activityId);
+        // 校验是否达到限购总限购标准
+        if ((sumCount + count) > activity.getTotalLimitCount()) {
+            throw exception(COMBINATION_RECORD_FAILED_TOTAL_LIMIT_COUNT_EXCEED);
+        }
+        // 单次购买是否达到限购标准
+        if (count > activity.getSingleLimitCount()) {
+            throw exception(COMBINATION_RECORD_FAILED_SINGLE_LIMIT_COUNT_EXCEED);
+        }
+    }
+
     /**
      * APP 端获取开团记录
      *

+ 0 - 3
yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImplTest.java

@@ -13,7 +13,6 @@ import org.springframework.context.annotation.Import;
 
 import javax.annotation.Resource;
 
-import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
 import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
@@ -152,8 +151,6 @@ public class CombinationActivityServiceImplTest extends BaseDbUnitTest {
         // 准备参数
         CombinationActivityPageReqVO reqVO = new CombinationActivityPageReqVO();
         reqVO.setName(null);
-        reqVO.setStartTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
-        reqVO.setEndTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
         reqVO.setStatus(null);
 
         // 调用

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

@@ -31,10 +31,7 @@ public interface ErrorCodeConstants {
     ErrorCode ORDER_COMMENT_STATUS_NOT_FALSE = new ErrorCode(1011000020, "创建交易订单项的评价失败,订单已评价");
     ErrorCode ORDER_DELIVERY_FAIL_REFUND_STATUS_NOT_NONE = new ErrorCode(1011000021, "交易订单发货失败,订单已退款或部分退款");
     ErrorCode ORDER_DELIVERY_FAIL_COMBINATION_RECORD_STATUS_NOT_SUCCESS = new ErrorCode(1011000022, "交易订单发货失败,拼团未成功");
-    // TODO 已移除订单单独发货
-    ErrorCode ORDER_DELIVERY_FAILED_ITEMS_NOT_EMPTY = new ErrorCode(1011000023, "订单发货失败,请选择发货商品");
-    ErrorCode ORDER_DELIVERY_FAILED_ITEM_NOT_EXISTS = new ErrorCode(1011000024, "订单发货失败,所选发货商品不存在");
-    ErrorCode ORDER_DELIVERY_FAILED_ITEM_ALREADY_DELIVERY = new ErrorCode(1011000025, "订单发货失败,所选商品已发货");
+    ErrorCode ORDER_DELIVERY_FAIL_BARGAIN_RECORD_STATUS_NOT_SUCCESS = new ErrorCode(1011000023, "交易订单发货失败,砍价未成功");
 
     // ==========  After Sale 模块 1011000100 ==========
     ErrorCode AFTER_SALE_NOT_FOUND = new ErrorCode(1011000100, "售后单不存在");

+ 0 - 2
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderDeliveryReqVO.java

@@ -29,7 +29,5 @@ public class TradeOrderDeliveryReqVO {
     @NotEmpty(message = "发货物流单号不能为空")
     private String logisticsNo;
 
-    // =============== 同城配送  ================
-    // TODO
 
 }

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

@@ -149,9 +149,8 @@ public class AppTradeOrderController {
     @PutMapping("/receive")
     @Operation(summary = "确认交易订单收货")
     @Parameter(name = "id", description = "交易订单编号")
-    public CommonResult<Boolean> receiveOrder(@RequestParam("id") Long id) {
-        tradeOrderService.receiveOrder(getLoginUserId(), id);
-        return success(true);
+    public CommonResult<Boolean> takeOrder(@RequestParam("id") Long id) {
+        return success(tradeOrderService.receiveOrder(getLoginUserId(), id));
     }
 
     @DeleteMapping("/cancel")

+ 6 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderItemMapper.java

@@ -25,6 +25,12 @@ public interface TradeOrderItemMapper extends BaseMapperX<TradeOrderItemDO> {
         return selectList(TradeOrderItemDO::getOrderId, orderIds);
     }
 
+    default List<TradeOrderItemDO> selectListByOrderIdAnSkuId(Collection<Long> orderIds, Collection<Long> skuIds) {
+        return selectList(new LambdaQueryWrapperX<TradeOrderItemDO>()
+                .in(TradeOrderItemDO::getOrderId, orderIds)
+                .eq(TradeOrderItemDO::getSkuId, skuIds));
+    }
+
     default TradeOrderItemDO selectOrderItemByIdAndUserId(Long orderItemId, Long loginUserId) {
         return selectOne(new LambdaQueryWrapperX<TradeOrderItemDO>()
                 .eq(TradeOrderItemDO::getId, orderItemId)

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

@@ -65,9 +65,10 @@ public interface TradeOrderService {
      * 【会员】收货交易订单
      *
      * @param userId 用户编号
-     * @param id 订单编号
+     * @param id     订单编号
+     * @return 成功/失败
      */
-    void receiveOrder(Long userId, Long id);
+    Boolean receiveOrder(Long userId, Long id);
 
     /**
      * 获得指定编号的交易订单

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

@@ -9,6 +9,7 @@ import cn.iocoder.yudao.framework.common.core.KeyValue;
 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.common.enums.TerminalEnum;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
 import cn.iocoder.yudao.module.member.api.address.AddressApi;
 import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO;
@@ -22,7 +23,9 @@ 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.bargain.BargainRecordApi;
 import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi;
+import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO;
 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordUpdateStatusReqDTO;
 import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi;
 import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO;
@@ -108,6 +111,9 @@ public class TradeOrderServiceImpl implements TradeOrderService {
     @Resource
     private CombinationRecordApi combinationRecordApi;
 
+    @Resource
+    private BargainRecordApi bargainRecordApi;
+
     // =================== Order ===================
 
     @Override
@@ -173,8 +179,18 @@ public class TradeOrderServiceImpl implements TradeOrderService {
         // 拼团
         if (Objects.equals(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) {
             MemberUserRespDTO user = memberUserApi.getUser(userId);
+            List<CombinationRecordRespDTO> recordRespDTOS = combinationRecordApi.getRecordListByUserIdAndActivityId(userId, createReqVO.getCombinationActivityId());
             // TODO 拼团一次应该只能选择一种规格的商品
-            combinationRecordApi.createCombinationRecord(TradeOrderConvert.INSTANCE.convert(order, orderItems.get(0), createReqVO, user));
+            TradeOrderItemDO orderItemDO = orderItems.get(0);
+            if (CollUtil.isNotEmpty(recordRespDTOS)) {
+                List<Long> skuIds = convertList(recordRespDTOS, CombinationRecordRespDTO::getSkuId, item -> ObjectUtil.equals(item.getStatus(), CombinationRecordStatusEnum.SUCCESS.getStatus()));
+                List<TradeOrderItemDO> tradeOrderItemDOS = tradeOrderItemMapper.selectListByOrderIdAnSkuId(convertList(recordRespDTOS,
+                        CombinationRecordRespDTO::getOrderId, item -> ObjectUtil.equals(item.getStatus(), CombinationRecordStatusEnum.SUCCESS.getStatus())), skuIds);
+                combinationRecordApi.validateCombinationLimitCount(createReqVO.getCombinationActivityId(),
+                        CollectionUtils.getSumValue(tradeOrderItemDOS, TradeOrderItemDO::getCount, Integer::sum), orderItemDO.getCount());
+            }
+
+            combinationRecordApi.createRecord(TradeOrderConvert.INSTANCE.convert(order, orderItemDO, createReqVO, user));
         }
         // TODO 秒杀扣减库存是下单就扣除还是等待订单支付成功再扣除
         if (Objects.equals(TradeOrderTypeEnum.SECKILL.getType(), order.getType())) {
@@ -382,33 +398,23 @@ public class TradeOrderServiceImpl implements TradeOrderService {
     public void deliveryOrder(Long userId, TradeOrderDeliveryReqVO deliveryReqVO) {
         // 1.1 校验并获得交易订单(可发货)
         TradeOrderDO order = validateOrderDeliverable(deliveryReqVO.getId());
-
-        /* TODO
-         * fix: 首先需要店铺设置配送方式如: 自提 、配送、物流-配送、物流-配送-自提、商家配送
-         * 1.如果店铺有设置配送方式用户只填写收货地址的情况下店家后台自己选择配送方式
-         * 2.如果店铺只支持到店自提那么下单后默认发货不需要物流
-         * 3.如果店铺支持 物流-配送-自提 的情况下后台不需要选择配送方式按前端用户选择的配送方式发货即可
-         */
         TradeOrderDO updateOrderObj = new TradeOrderDO();
         // 判断发货类型
         // 2.1 快递发货
         if (Objects.equals(deliveryReqVO.getType(), DeliveryTypeEnum.EXPRESS.getMode())) {
             // 校验快递公司
-            validateDeliveryExpress(deliveryReqVO);
-            updateOrderObj.setLogisticsId(deliveryReqVO.getLogisticsId()).setLogisticsNo(deliveryReqVO.getLogisticsNo());
-        }
-        // 2.2 用户自提
-        if (Objects.equals(deliveryReqVO.getType(), DeliveryTypeEnum.PICK_UP.getMode())) {
-            // TODO 校验自提门店是否存在
-            // 重置一下确保快递公司和快递单号为空
-            updateOrderObj.setLogisticsId(null).setLogisticsNo("");
+            DeliveryExpressDO deliveryExpress = deliveryExpressService.getDeliveryExpress(deliveryReqVO.getLogisticsId());
+            if (deliveryExpress == null) {
+                throw exception(EXPRESS_NOT_EXISTS);
+            }
+            if (deliveryExpress.getStatus().equals(CommonStatusEnum.DISABLE.getStatus())) {
+                throw exception(EXPRESS_STATUS_NOT_ENABLE);
+            }
+            updateOrderObj.setLogisticsId(deliveryReqVO.getLogisticsId()).setLogisticsNo(deliveryReqVO.getLogisticsNo()).setDeliveryType(DeliveryTypeEnum.EXPRESS.getMode());
         }
-        // 2.3 TODO 芋艿:如果无需发货,需要怎么存储?回复:需要把 deliverType 设置为 DeliveryTypeEnum.NULL
+        // 2.2 无需发货
         if (Objects.equals(deliveryReqVO.getType(), DeliveryTypeEnum.NULL.getMode())) {
-            // TODO 情况一:正常走发货逻辑和用户自提有点像 不同点:不需要自提门店只需要用户确认收货
-            // TODO 情况二:用户下单付款后直接确认收货或等待用户确认收货
-            // 重置一下确保快递公司和快递单号为空
-            updateOrderObj.setLogisticsId(null).setLogisticsNo("");
+            updateOrderObj.setLogisticsId(null).setLogisticsNo("").setDeliveryType(DeliveryTypeEnum.NULL.getMode());
         }
 
         // 更新 TradeOrderDO 状态为已发货,等待收货
@@ -427,16 +433,6 @@ public class TradeOrderServiceImpl implements TradeOrderService {
         // TODO 设计:lili:是不是发货后,才支持售后?
     }
 
-    private void validateDeliveryExpress(TradeOrderDeliveryReqVO deliveryReqVO) {
-        DeliveryExpressDO deliveryExpress = deliveryExpressService.getDeliveryExpress(deliveryReqVO.getLogisticsId());
-        if (deliveryExpress == null) {
-            throw exception(EXPRESS_NOT_EXISTS);
-        }
-        if (deliveryExpress.getStatus().equals(CommonStatusEnum.DISABLE.getStatus())) {
-            throw exception(EXPRESS_STATUS_NOT_ENABLE);
-        }
-    }
-
     /**
      * 校验交易订单满足被发货的条件
      *
@@ -462,17 +458,23 @@ public class TradeOrderServiceImpl implements TradeOrderService {
         // 订单类型:拼团
         if (Objects.equals(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) {
             // 校验订单拼团是否成功
-            if (combinationRecordApi.isCombinationRecordSuccess(order.getUserId(), order.getId())) {
+            if (combinationRecordApi.validateRecordSuccess(order.getUserId(), order.getId())) {
                 throw exception(ORDER_DELIVERY_FAIL_COMBINATION_RECORD_STATUS_NOT_SUCCESS);
             }
         }
-        // TODO puhui999: 校验订单砍价是否成功
+        // 订单类类型:砍价
+        if (Objects.equals(TradeOrderTypeEnum.BARGAIN.getType(), order.getType())) {
+            // 校验订单砍价是否成功
+            if (bargainRecordApi.validateRecordSuccess(order.getUserId(), order.getId())) {
+                throw exception(ORDER_DELIVERY_FAIL_BARGAIN_RECORD_STATUS_NOT_SUCCESS);
+            }
+        }
         return order;
     }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void receiveOrder(Long userId, Long id) {
+    public Boolean receiveOrder(Long userId, Long id) {
         // 校验并获得交易订单(可收货)
         TradeOrderDO order = validateOrderReceivable(userId, id);
 
@@ -487,6 +489,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
         // TODO 芋艿:lili 发送订单变化的消息
 
         // TODO 芋艿:lili 发送商品被购买完成的数据
+        return Boolean.TRUE;
     }
 
     /**