Commit 53e67c0437a634407322c1f6dc98a4fd5bda0f54

Authored by puhui999
1 parent 7b727d5c

拼团活动:完善 review 提到的问题

Showing 14 changed files with 106 additions and 48 deletions
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApi.java
1 package cn.iocoder.yudao.module.promotion.api.combination; 1 package cn.iocoder.yudao.module.promotion.api.combination;
2 2
  3 +import cn.iocoder.yudao.framework.common.core.KeyValue;
3 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; 4 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
4 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationValidateJoinRespDTO; 5 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationValidateJoinRespDTO;
5 6
@@ -29,9 +30,9 @@ public interface CombinationRecordApi { @@ -29,9 +30,9 @@ public interface CombinationRecordApi {
29 * 创建开团记录 30 * 创建开团记录
30 * 31 *
31 * @param reqDTO 请求 DTO 32 * @param reqDTO 请求 DTO
32 - * @return 开团记录编号 33 + * @return key 开团记录编号 value 团长编号
33 */ 34 */
34 - Long createCombinationRecord(@Valid CombinationRecordCreateReqDTO reqDTO); 35 + KeyValue<Long, Long> createCombinationRecord(@Valid CombinationRecordCreateReqDTO reqDTO);
35 36
36 /** 37 /**
37 * 查询拼团记录是否成功 38 * 查询拼团记录是否成功
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApiImpl.java
1 package cn.iocoder.yudao.module.promotion.api.combination; 1 package cn.iocoder.yudao.module.promotion.api.combination;
2 2
  3 +import cn.iocoder.yudao.framework.common.core.KeyValue;
3 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; 4 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
4 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationValidateJoinRespDTO; 5 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationValidateJoinRespDTO;
5 import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationRecordDO; 6 import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationRecordDO;
@@ -29,7 +30,7 @@ public class CombinationRecordApiImpl implements CombinationRecordApi { @@ -29,7 +30,7 @@ public class CombinationRecordApiImpl implements CombinationRecordApi {
29 } 30 }
30 31
31 @Override 32 @Override
32 - public Long createCombinationRecord(CombinationRecordCreateReqDTO reqDTO) { 33 + public KeyValue<Long, Long> createCombinationRecord(CombinationRecordCreateReqDTO reqDTO) {
33 return recordService.createCombinationRecord(reqDTO); 34 return recordService.createCombinationRecord(reqDTO);
34 } 35 }
35 36
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/CombinationRecordController.java
@@ -54,10 +54,11 @@ public class CombinationRecordController { @@ -54,10 +54,11 @@ public class CombinationRecordController {
54 @PreAuthorize("@ss.hasPermission('promotion:combination-record:query')") 54 @PreAuthorize("@ss.hasPermission('promotion:combination-record:query')")
55 public CommonResult<CombinationRecordSummaryVO> getCombinationRecordSummary() { 55 public CommonResult<CombinationRecordSummaryVO> getCombinationRecordSummary() {
56 CombinationRecordSummaryVO summaryVO = new CombinationRecordSummaryVO(); 56 CombinationRecordSummaryVO summaryVO = new CombinationRecordSummaryVO();
57 - summaryVO.setUserCount(combinationRecordService.getCombinationRecordCount(null, null)); // 获取所有拼团记录 57 + summaryVO.setUserCount(combinationRecordService.getCombinationRecordCount(null, null, null)); // 获取拼团用户参与数量
58 summaryVO.setSuccessCount(combinationRecordService.getCombinationRecordCount( // 获取成团记录 58 summaryVO.setSuccessCount(combinationRecordService.getCombinationRecordCount( // 获取成团记录
59 - CombinationRecordStatusEnum.SUCCESS.getStatus(), null));  
60 - summaryVO.setVirtualGroupCount(combinationRecordService.getCombinationRecordCount(null, Boolean.TRUE));// 获取虚拟成团记录 59 + CombinationRecordStatusEnum.SUCCESS.getStatus(), null, CombinationRecordDO.HEAD_ID_GROUP));
  60 + summaryVO.setVirtualGroupCount(combinationRecordService.getCombinationRecordCount(// 获取虚拟成团记录
  61 + null, Boolean.TRUE, CombinationRecordDO.HEAD_ID_GROUP));
61 return success(summaryVO); 62 return success(summaryVO);
62 } 63 }
63 64
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationRecordController.java
@@ -46,8 +46,8 @@ public class AppCombinationRecordController { @@ -46,8 +46,8 @@ public class AppCombinationRecordController {
46 @Operation(summary = "获得拼团记录的概要信息", description = "用于小程序首页") 46 @Operation(summary = "获得拼团记录的概要信息", description = "用于小程序首页")
47 public CommonResult<AppCombinationRecordSummaryRespVO> getCombinationRecordSummary() { 47 public CommonResult<AppCombinationRecordSummaryRespVO> getCombinationRecordSummary() {
48 AppCombinationRecordSummaryRespVO summary = new AppCombinationRecordSummaryRespVO(); 48 AppCombinationRecordSummaryRespVO summary = new AppCombinationRecordSummaryRespVO();
49 - // 1. 获得拼团记录数量  
50 - Long count = combinationRecordService.getCombinationRecordCount(null, null); 49 + // 1. 获得拼团参与用户数量
  50 + Long count = combinationRecordService.getCombinationRecordCount(null, null, null);
51 if (count == 0) { 51 if (count == 0) {
52 summary.setAvatars(Collections.emptyList()); 52 summary.setAvatars(Collections.emptyList());
53 summary.setUserCount(count); 53 summary.setUserCount(count);
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/combination/CombinationActivityConvert.java
@@ -28,7 +28,6 @@ import org.mapstruct.Mapping; @@ -28,7 +28,6 @@ import org.mapstruct.Mapping;
28 import org.mapstruct.Mappings; 28 import org.mapstruct.Mappings;
29 import org.mapstruct.factory.Mappers; 29 import org.mapstruct.factory.Mappers;
30 30
31 -import java.time.LocalDateTime;  
32 import java.util.List; 31 import java.util.List;
33 import java.util.Map; 32 import java.util.Map;
34 33
@@ -114,9 +113,6 @@ public interface CombinationActivityConvert { @@ -114,9 +113,6 @@ public interface CombinationActivityConvert {
114 ProductSpuRespDTO spu, ProductSkuRespDTO sku) { 113 ProductSpuRespDTO spu, ProductSkuRespDTO sku) {
115 return convert(reqDTO).setVirtualGroup(false) 114 return convert(reqDTO).setVirtualGroup(false)
116 .setStatus(CombinationRecordStatusEnum.IN_PROGRESS.getStatus()) // 创建后默认状态为进行中 115 .setStatus(CombinationRecordStatusEnum.IN_PROGRESS.getStatus()) // 创建后默认状态为进行中
117 - .setStartTime(LocalDateTime.now()) // TODO @puhui999:想了下,这个 startTime 应该是团长的;  
118 - // TODO @puhui999:有团长的情况下,expireTime 应该是团长的;  
119 - .setExpireTime(activity.getStartTime().plusHours(activity.getLimitDuration()))  
120 .setUserSize(activity.getUserSize()).setUserCount(1) // 默认就是 1 插入后会接着更新一次所有的拼团记录 116 .setUserSize(activity.getUserSize()).setUserCount(1) // 默认就是 1 插入后会接着更新一次所有的拼团记录
121 // 用户信息 117 // 用户信息
122 .setNickname(user.getNickname()).setAvatar(user.getAvatar()) 118 .setNickname(user.getNickname()).setAvatar(user.getAvatar())
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/CombinationRecordMapper.java
@@ -100,13 +100,21 @@ public interface CombinationRecordMapper extends BaseMapperX&lt;CombinationRecordDO @@ -100,13 +100,21 @@ public interface CombinationRecordMapper extends BaseMapperX&lt;CombinationRecordDO
100 .betweenIfPresent(CombinationRecordDO::getCreateTime, pageVO.getCreateTime())); 100 .betweenIfPresent(CombinationRecordDO::getCreateTime, pageVO.getCreateTime()));
101 } 101 }
102 102
103 - // TODO @puhui999:这个最好把 headId 也作为一个参数;因为有个要求 userCount,它要 DISTINCT 下;整体可以参考 selectCombinationRecordCountMapByActivityIdAndStatusAndHeadId  
104 - default Long selectCountByHeadAndStatusAndVirtualGroup(Integer status, Boolean virtualGroup) {  
105 - return selectCount(new LambdaQueryWrapperX<CombinationRecordDO>()  
106 - .eq(status != null || virtualGroup != null,  
107 - CombinationRecordDO::getHeadId, CombinationRecordDO.HEAD_ID_GROUP) // 统计团信息则指定团长  
108 - .eqIfPresent(CombinationRecordDO::getStatus, status)  
109 - .eqIfPresent(CombinationRecordDO::getVirtualGroup, virtualGroup)); 103 + /**
  104 + * 查询指定条件的记录数
  105 + * 如果参数都为 null 时则查询用户拼团记录(DISTINCT 去重),也就是说查询会员表中的用户有多少人参与过拼团活动每个人只统计一次
  106 + *
  107 + * @param status 状态,可为 null
  108 + * @param virtualGroup 是否虚拟成团,可为 null
  109 + * @param headId 团长编号,可为 null
  110 + * @return 记录数
  111 + */
  112 + default Long selectCountByHeadAndStatusAndVirtualGroup(Integer status, Boolean virtualGroup, Long headId) {
  113 + return selectCount(new QueryWrapper<CombinationRecordDO>()
  114 + .select(status == null && virtualGroup == null && headId == null, "COUNT(DISTINCT(user_id))")
  115 + .eq(status != null, "status", status)
  116 + .eq(virtualGroup != null, "virtual_group", virtualGroup)
  117 + .eq(headId != null, "head_id", headId));
110 } 118 }
111 119
112 } 120 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordService.java
@@ -49,9 +49,9 @@ public interface CombinationRecordService { @@ -49,9 +49,9 @@ public interface CombinationRecordService {
49 * 创建拼团记录 49 * 创建拼团记录
50 * 50 *
51 * @param reqDTO 创建信息 51 * @param reqDTO 创建信息
52 - * @return 开团记录编号 52 + * @return key 开团记录编号 value 团长编号
53 */ 53 */
54 - Long createCombinationRecord(CombinationRecordCreateReqDTO reqDTO); 54 + KeyValue<Long, Long> createCombinationRecord(CombinationRecordCreateReqDTO reqDTO);
55 55
56 /** 56 /**
57 * 获得拼团记录 57 * 获得拼团记录
@@ -90,9 +90,10 @@ public interface CombinationRecordService { @@ -90,9 +90,10 @@ public interface CombinationRecordService {
90 * 90 *
91 * @param status 状态-允许为空 91 * @param status 状态-允许为空
92 * @param virtualGroup 是否虚拟成团-允许为空 92 * @param virtualGroup 是否虚拟成团-允许为空
  93 + * @param headId 团长编号,允许空。目的 headId 设置为 {@link CombinationRecordDO#HEAD_ID_GROUP} 时,可以设置
93 * @return 记录数 94 * @return 记录数
94 */ 95 */
95 - Long getCombinationRecordCount(@Nullable Integer status, @Nullable Boolean virtualGroup); 96 + Long getCombinationRecordCount(@Nullable Integer status, @Nullable Boolean virtualGroup, @Nullable Long headId);
96 97
97 /** 98 /**
98 * 获取最近的 count 条拼团记录 99 * 获取最近的 count 条拼团记录
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java
@@ -20,7 +20,6 @@ import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationP @@ -20,7 +20,6 @@ import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationP
20 import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationRecordDO; 20 import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationRecordDO;
21 import cn.iocoder.yudao.module.promotion.dal.mysql.combination.CombinationRecordMapper; 21 import cn.iocoder.yudao.module.promotion.dal.mysql.combination.CombinationRecordMapper;
22 import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum; 22 import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
23 -import cn.iocoder.yudao.module.trade.api.order.TradeOrderApi;  
24 import org.springframework.context.annotation.Lazy; 23 import org.springframework.context.annotation.Lazy;
25 import org.springframework.stereotype.Service; 24 import org.springframework.stereotype.Service;
26 import org.springframework.transaction.annotation.Transactional; 25 import org.springframework.transaction.annotation.Transactional;
@@ -28,6 +27,7 @@ import org.springframework.validation.annotation.Validated; @@ -28,6 +27,7 @@ import org.springframework.validation.annotation.Validated;
28 27
29 import javax.annotation.Nullable; 28 import javax.annotation.Nullable;
30 import javax.annotation.Resource; 29 import javax.annotation.Resource;
  30 +import java.time.LocalDateTime;
31 import java.util.*; 31 import java.util.*;
32 32
33 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 33 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -62,8 +62,6 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { @@ -62,8 +62,6 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
62 @Resource 62 @Resource
63 @Lazy 63 @Lazy
64 private ProductSkuApi productSkuApi; 64 private ProductSkuApi productSkuApi;
65 - @Resource  
66 - private TradeOrderApi tradeOrderApi;  
67 65
68 // TODO @芋艿:在详细预览下; 66 // TODO @芋艿:在详细预览下;
69 @Override 67 @Override
@@ -164,32 +162,36 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { @@ -164,32 +162,36 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
164 162
165 @Override 163 @Override
166 @Transactional(rollbackFor = Exception.class) 164 @Transactional(rollbackFor = Exception.class)
167 - public Long createCombinationRecord(CombinationRecordCreateReqDTO reqDTO) {  
168 - // 1. 校验拼团活动 165 + public KeyValue<Long, Long> createCombinationRecord(CombinationRecordCreateReqDTO reqDTO) {
  166 + // 1.校验拼团活动
169 KeyValue<CombinationActivityDO, CombinationProductDO> keyValue = validateCombinationRecord(reqDTO.getUserId(), 167 KeyValue<CombinationActivityDO, CombinationProductDO> keyValue = validateCombinationRecord(reqDTO.getUserId(),
170 reqDTO.getActivityId(), reqDTO.getHeadId(), reqDTO.getSkuId(), reqDTO.getCount()); 168 reqDTO.getActivityId(), reqDTO.getHeadId(), reqDTO.getSkuId(), reqDTO.getCount());
171 169
172 - // 2.1 组合数据创建拼团记录 170 + // 2.组合数据创建拼团记录
173 MemberUserRespDTO user = memberUserApi.getUser(reqDTO.getUserId()); 171 MemberUserRespDTO user = memberUserApi.getUser(reqDTO.getUserId());
174 ProductSpuRespDTO spu = productSpuApi.getSpu(reqDTO.getSpuId()); 172 ProductSpuRespDTO spu = productSpuApi.getSpu(reqDTO.getSpuId());
175 ProductSkuRespDTO sku = productSkuApi.getSku(reqDTO.getSkuId()); 173 ProductSkuRespDTO sku = productSkuApi.getSku(reqDTO.getSkuId());
176 CombinationRecordDO record = CombinationActivityConvert.INSTANCE.convert(reqDTO, keyValue.getKey(), user, spu, sku); 174 CombinationRecordDO record = CombinationActivityConvert.INSTANCE.convert(reqDTO, keyValue.getKey(), user, spu, sku);
177 - // 2.2 如果是团长需要设置 headId 为 CombinationRecordDO#HEAD_ID_GROUP 175 + // 2.1.如果是团长需要设置 headId 为 CombinationRecordDO#HEAD_ID_GROUP
178 if (record.getHeadId() == null) { 176 if (record.getHeadId() == null) {
179 - record.setHeadId(CombinationRecordDO.HEAD_ID_GROUP); 177 + record.setStartTime(LocalDateTime.now())
  178 + .setExpireTime(keyValue.getKey().getStartTime().plusHours(keyValue.getKey().getLimitDuration()))
  179 + .setHeadId(CombinationRecordDO.HEAD_ID_GROUP);
  180 + } else {
  181 + // 2.2.有团长的情况下需要设置开始时间和过期时间为团长的
  182 + CombinationRecordDO headRecord = recordMapper.selectByHeadId(record.getHeadId(),
  183 + CombinationRecordStatusEnum.IN_PROGRESS.getStatus()); // 查询进行中的父拼团
  184 + record.setStartTime(headRecord.getStartTime()).setExpireTime(headRecord.getExpireTime());
180 } 185 }
181 recordMapper.insert(record); 186 recordMapper.insert(record);
182 187
183 if (ObjUtil.equal(CombinationRecordDO.HEAD_ID_GROUP, record.getHeadId())) { 188 if (ObjUtil.equal(CombinationRecordDO.HEAD_ID_GROUP, record.getHeadId())) {
184 - return record.getId(); 189 + return new KeyValue<>(record.getId(), record.getHeadId());
185 } 190 }
186 191
187 - // TODO @puhui:是不是这里的更新,放到 order 模块那;支付完成后;  
188 - // 4、更新拼团相关信息到订单  
189 - tradeOrderApi.updateOrderCombinationInfo(record.getOrderId(), record.getActivityId(), record.getId(), record.getHeadId());  
190 - // 4、更新拼团记录 192 + // 3、更新拼团记录
191 updateCombinationRecordWhenCreate(reqDTO.getHeadId(), keyValue.getKey()); 193 updateCombinationRecordWhenCreate(reqDTO.getHeadId(), keyValue.getKey());
192 - return record.getId(); 194 + return new KeyValue<>(record.getId(), record.getHeadId());
193 } 195 }
194 196
195 /** 197 /**
@@ -241,8 +243,8 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { @@ -241,8 +243,8 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
241 } 243 }
242 244
243 @Override 245 @Override
244 - public Long getCombinationRecordCount(@Nullable Integer status, @Nullable Boolean virtualGroup) {  
245 - return recordMapper.selectCountByHeadAndStatusAndVirtualGroup(status, virtualGroup); 246 + public Long getCombinationRecordCount(@Nullable Integer status, @Nullable Boolean virtualGroup, @Nullable Long headId) {
  247 + return recordMapper.selectCountByHeadAndStatusAndVirtualGroup(status, virtualGroup, headId);
246 } 248 }
247 249
248 @Override 250 @Override
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java
@@ -33,7 +33,8 @@ public interface ErrorCodeConstants { @@ -33,7 +33,8 @@ public interface ErrorCodeConstants {
33 ErrorCode ORDER_UPDATE_PRICE_FAIL_PRICE_ERROR = new ErrorCode(1_011_000_028, "支付订单调价失败,原因:调整后支付价格不能小于 0.01 元"); 33 ErrorCode ORDER_UPDATE_PRICE_FAIL_PRICE_ERROR = new ErrorCode(1_011_000_028, "支付订单调价失败,原因:调整后支付价格不能小于 0.01 元");
34 ErrorCode ORDER_DELETE_FAIL_STATUS_NOT_CANCEL = new ErrorCode(1_011_000_029, "交易订单删除失败,订单不是【已取消】状态"); 34 ErrorCode ORDER_DELETE_FAIL_STATUS_NOT_CANCEL = new ErrorCode(1_011_000_029, "交易订单删除失败,订单不是【已取消】状态");
35 ErrorCode ORDER_RECEIVE_FAIL_DELIVERY_TYPE_NOT_PICK_UP = new ErrorCode(1_011_000_030, "交易订单自提失败,收货方式不是【用户自提】"); 35 ErrorCode ORDER_RECEIVE_FAIL_DELIVERY_TYPE_NOT_PICK_UP = new ErrorCode(1_011_000_030, "交易订单自提失败,收货方式不是【用户自提】");
36 - ErrorCode ORDER_UPDATE_ADDRESS_FAIL_STATUS_NOT_DELIVERED = new ErrorCode(1_011_000_031, "交易订单修改收货地址失败,原因:订单已发货"); 36 + ErrorCode ORDER_UPDATE_ADDRESS_FAIL_STATUS_NOT_DELIVERED = new ErrorCode(1_011_000_031, "交易订单修改收货地址失败,原因:订单不是【待发货】状态");
  37 + ErrorCode ORDER_CREATE_FAIL_EXIST_UNPAID = new ErrorCode(1_011_000_032, "交易订单创建失败,原因:存在未付款订单");
37 38
38 // ========== After Sale 模块 1-011-000-100 ========== 39 // ========== After Sale 模块 1-011-000-100 ==========
39 ErrorCode AFTER_SALE_NOT_FOUND = new ErrorCode(1_011_000_100, "售后单不存在"); 40 ErrorCode AFTER_SALE_NOT_FOUND = new ErrorCode(1_011_000_100, "售后单不存在");
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderMapper.java
@@ -110,4 +110,16 @@ public interface TradeOrderMapper extends BaseMapperX&lt;TradeOrderDO&gt; { @@ -110,4 +110,16 @@ public interface TradeOrderMapper extends BaseMapperX&lt;TradeOrderDO&gt; {
110 return selectOne(TradeOrderDO::getPickUpVerifyCode, pickUpVerifyCode); 110 return selectOne(TradeOrderDO::getPickUpVerifyCode, pickUpVerifyCode);
111 } 111 }
112 112
  113 + default TradeOrderDO selectByUserIdAndActivityIdAndStatus(Long userId, Long activityId, Integer status) {
  114 + return selectOne(new LambdaQueryWrapperX<TradeOrderDO>()
  115 + .and(q -> q.eq(TradeOrderDO::getUserId, userId)
  116 + .eq(TradeOrderDO::getStatus, status))
  117 + .and(q -> q.eq(TradeOrderDO::getCombinationActivityId, activityId)
  118 + .or()
  119 + .eq(TradeOrderDO::getSeckillActivityId, activityId)
  120 + .or()
  121 + .eq(TradeOrderDO::getBargainActivityId, activityId))
  122 + );
  123 + }
  124 +
113 } 125 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryService.java
@@ -41,6 +41,16 @@ public interface TradeOrderQueryService { @@ -41,6 +41,16 @@ public interface TradeOrderQueryService {
41 TradeOrderDO getOrder(Long userId, Long id); 41 TradeOrderDO getOrder(Long userId, Long id);
42 42
43 /** 43 /**
  44 + * 获得指定用户,指定活动,指定状态的交易订单
  45 + *
  46 + * @param userId 用户编号
  47 + * @param activityId 活动编号
  48 + * @param status 订单状态
  49 + * @return 交易订单
  50 + */
  51 + TradeOrderDO getActivityOrderByUserIdAndActivityIdAndStatus(Long userId, Long activityId, Integer status);
  52 +
  53 + /**
44 * 获得订单列表 54 * 获得订单列表
45 * 55 *
46 * @param ids 订单编号数组 56 * @param ids 订单编号数组
@@ -95,7 +105,7 @@ public interface TradeOrderQueryService { @@ -95,7 +105,7 @@ public interface TradeOrderQueryService {
95 /** 105 /**
96 * 【会员】在指定秒杀活动下,用户购买的商品数量 106 * 【会员】在指定秒杀活动下,用户购买的商品数量
97 * 107 *
98 - * @param userId 用户编号 108 + * @param userId 用户编号
99 * @param activityId 活动编号 109 * @param activityId 活动编号
100 * @return 秒杀商品数量 110 * @return 秒杀商品数量
101 */ 111 */
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryServiceImpl.java
@@ -73,6 +73,11 @@ public class TradeOrderQueryServiceImpl implements TradeOrderQueryService { @@ -73,6 +73,11 @@ public class TradeOrderQueryServiceImpl implements TradeOrderQueryService {
73 } 73 }
74 74
75 @Override 75 @Override
  76 + public TradeOrderDO getActivityOrderByUserIdAndActivityIdAndStatus(Long userId, Long activityId, Integer status) {
  77 + return tradeOrderMapper.selectByUserIdAndActivityIdAndStatus(userId, activityId, status);
  78 + }
  79 +
  80 + @Override
76 public List<TradeOrderDO> getOrderList(Collection<Long> ids) { 81 public List<TradeOrderDO> getOrderList(Collection<Long> ids) {
77 if (CollUtil.isEmpty(ids)) { 82 if (CollUtil.isEmpty(ids)) {
78 return Collections.emptyList(); 83 return Collections.emptyList();
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java
@@ -742,9 +742,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { @@ -742,9 +742,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
742 public void updateOrderAddress(TradeOrderUpdateAddressReqVO reqVO) { 742 public void updateOrderAddress(TradeOrderUpdateAddressReqVO reqVO) {
743 // 校验交易订单 743 // 校验交易订单
744 TradeOrderDO order = validateOrderExists(reqVO.getId()); 744 TradeOrderDO order = validateOrderExists(reqVO.getId());
745 - // 发货后,不允许修改;  
746 - // TODO @puhui999:只有待发货,可以执行 update  
747 - if (TradeOrderStatusEnum.isDelivered(order.getStatus())) { 745 + // 只有待发货状态才可以修改订单收货地址;
  746 + if (!TradeOrderStatusEnum.isUndelivered(order.getStatus())) {
748 throw exception(ORDER_UPDATE_ADDRESS_FAIL_STATUS_NOT_DELIVERED); 747 throw exception(ORDER_UPDATE_ADDRESS_FAIL_STATUS_NOT_DELIVERED);
749 } 748 }
750 749
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeCombinationHandler.java
1 package cn.iocoder.yudao.module.trade.service.order.handler; 1 package cn.iocoder.yudao.module.trade.service.order.handler;
2 2
3 import cn.hutool.core.lang.Assert; 3 import cn.hutool.core.lang.Assert;
  4 +import cn.iocoder.yudao.framework.common.core.KeyValue;
4 import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi; 5 import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi;
5 import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; 6 import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert;
6 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; 7 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
7 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; 8 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
  9 +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum;
8 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; 10 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
  11 +import cn.iocoder.yudao.module.trade.service.order.TradeOrderQueryService;
  12 +import cn.iocoder.yudao.module.trade.service.order.TradeOrderUpdateService;
9 import org.springframework.stereotype.Component; 13 import org.springframework.stereotype.Component;
10 14
11 import javax.annotation.Resource; 15 import javax.annotation.Resource;
12 import java.util.List; 16 import java.util.List;
13 17
  18 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  19 +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_CREATE_FAIL_EXIST_UNPAID;
  20 +
14 /** 21 /**
15 * 拼团订单 handler 接口实现类 22 * 拼团订单 handler 接口实现类
16 * 23 *
@@ -20,6 +27,11 @@ import java.util.List; @@ -20,6 +27,11 @@ import java.util.List;
20 public class TradeCombinationHandler implements TradeOrderHandler { 27 public class TradeCombinationHandler implements TradeOrderHandler {
21 28
22 @Resource 29 @Resource
  30 + private TradeOrderQueryService orderQueryService;
  31 + @Resource
  32 + private TradeOrderUpdateService orderUpdateService;
  33 +
  34 + @Resource
23 private CombinationRecordApi combinationRecordApi; 35 private CombinationRecordApi combinationRecordApi;
24 36
25 @Override 37 @Override
@@ -34,21 +46,30 @@ public class TradeCombinationHandler implements TradeOrderHandler { @@ -34,21 +46,30 @@ public class TradeCombinationHandler implements TradeOrderHandler {
34 TradeOrderItemDO item = orderItems.get(0); 46 TradeOrderItemDO item = orderItems.get(0);
35 combinationRecordApi.validateCombinationRecord(order.getUserId(), order.getCombinationActivityId(), 47 combinationRecordApi.validateCombinationRecord(order.getUserId(), order.getCombinationActivityId(),
36 order.getCombinationHeadId(), item.getSkuId(), item.getCount()); 48 order.getCombinationHeadId(), item.getSkuId(), item.getCount());
37 - // TODO @puhui999:这里还要限制下,是不是已经 createOrder;就是还没支付的时候,重复下单了;需要校验下;不然的话,一个拼团可以下多个单子了; 49 + // 校验该用户是否存在未支付的拼团活动订单;就是还没支付的时候,重复下单了;需要校验下;不然的话,一个拼团可以下多个单子了;
  50 + TradeOrderDO activityOrder = orderQueryService.getActivityOrderByUserIdAndActivityIdAndStatus(
  51 + order.getUserId(), order.getCombinationActivityId(), TradeOrderStatusEnum.UNPAID.getStatus());
  52 + if (activityOrder != null) {
  53 + throw exception(ORDER_CREATE_FAIL_EXIST_UNPAID);
  54 + }
38 } 55 }
39 56
40 @Override 57 @Override
41 public void afterPayOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) { 58 public void afterPayOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
42 - // 如果不是拼团订单则结束 59 + // 1.如果不是拼团订单则结束
43 if (TradeOrderTypeEnum.isCombination(order.getType())) { 60 if (TradeOrderTypeEnum.isCombination(order.getType())) {
44 return; 61 return;
45 } 62 }
46 Assert.isTrue(orderItems.size() == 1, "拼团时,只允许选择一个商品"); 63 Assert.isTrue(orderItems.size() == 1, "拼团时,只允许选择一个商品");
47 64
48 - // 获取商品信息 65 + // 2.获取商品信息
49 TradeOrderItemDO item = orderItems.get(0); 66 TradeOrderItemDO item = orderItems.get(0);
50 - // 创建拼团记录  
51 - combinationRecordApi.createCombinationRecord(TradeOrderConvert.INSTANCE.convert(order, item)); 67 + // 2.1.创建拼团记录
  68 + KeyValue<Long, Long> recordIdAndHeadId = combinationRecordApi.createCombinationRecord(
  69 + TradeOrderConvert.INSTANCE.convert(order, item));
  70 + // 3.更新拼团相关信息到订单
  71 + orderUpdateService.updateOrderCombinationInfo(order.getId(), order.getCombinationActivityId(),
  72 + recordIdAndHeadId.getKey(), recordIdAndHeadId.getValue());
52 } 73 }
53 74
54 @Override 75 @Override