Commit 6636ee7420dcc55025d5d97d7e975b88936b63cd
1 parent
1a0fda23
拼团记录(APP):新增一个取消拼团的接口
Showing
9 changed files
with
152 additions
and
29 deletions
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/collection/CollectionUtils.java
| ... | ... | @@ -25,6 +25,14 @@ public class CollectionUtils { |
| 25 | 25 | return Arrays.stream(collections).anyMatch(CollectionUtil::isEmpty); |
| 26 | 26 | } |
| 27 | 27 | |
| 28 | + public static <T, U extends Comparable<? super U>> List<T> sortedAsc( | |
| 29 | + Collection<T> from, Function<? super T, ? extends U> keyExtractor) { | |
| 30 | + // 按照升序排序 | |
| 31 | + return from.stream() | |
| 32 | + .sorted(Comparator.comparing(keyExtractor)) | |
| 33 | + .collect(Collectors.toList()); | |
| 34 | + } | |
| 35 | + | |
| 28 | 36 | public static <T> boolean anyMatch(Collection<T> from, Predicate<T> predicate) { |
| 29 | 37 | return from.stream().anyMatch(predicate); |
| 30 | 38 | } | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationRecordController.java
| ... | ... | @@ -6,11 +6,14 @@ import cn.iocoder.yudao.module.promotion.controller.app.combination.vo.record.Ap |
| 6 | 6 | import cn.iocoder.yudao.module.promotion.controller.app.combination.vo.record.AppCombinationRecordSummaryRespVO; |
| 7 | 7 | import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert; |
| 8 | 8 | import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationRecordDO; |
| 9 | +import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum; | |
| 9 | 10 | import cn.iocoder.yudao.module.promotion.service.combination.CombinationRecordService; |
| 11 | +import cn.iocoder.yudao.module.trade.api.order.TradeOrderApi; | |
| 10 | 12 | import io.swagger.v3.oas.annotations.Operation; |
| 11 | 13 | import io.swagger.v3.oas.annotations.Parameter; |
| 12 | 14 | import io.swagger.v3.oas.annotations.Parameters; |
| 13 | 15 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 16 | +import org.springframework.context.annotation.Lazy; | |
| 14 | 17 | import org.springframework.validation.annotation.Validated; |
| 15 | 18 | import org.springframework.web.bind.annotation.GetMapping; |
| 16 | 19 | import org.springframework.web.bind.annotation.RequestMapping; |
| ... | ... | @@ -35,6 +38,9 @@ public class AppCombinationRecordController { |
| 35 | 38 | |
| 36 | 39 | @Resource |
| 37 | 40 | private CombinationRecordService combinationRecordService; |
| 41 | + @Resource | |
| 42 | + @Lazy | |
| 43 | + private TradeOrderApi tradeOrderApi; | |
| 38 | 44 | |
| 39 | 45 | @GetMapping("/get-summary") |
| 40 | 46 | @Operation(summary = "获得拼团记录的概要信息", description = "用于小程序首页") |
| ... | ... | @@ -96,9 +102,26 @@ public class AppCombinationRecordController { |
| 96 | 102 | return success(CombinationActivityConvert.INSTANCE.convert(getLoginUserId(), headRecord, memberRecords)); |
| 97 | 103 | } |
| 98 | 104 | |
| 99 | - // TODO @puhui:新增一个取消拼团的接口,cancel | |
| 100 | - // 1. 需要先校验拼团记录未完成; | |
| 101 | - // 2. 在 Order 那增加一个 cancelPaidOrder 接口,用于取消已支付的订单 | |
| 102 | - // 3. order 完成后,取消拼团记录。另外,如果它是团长,则顺序(下单时间)继承 | |
| 105 | + @GetMapping("/cancel") | |
| 106 | + @Operation(summary = "取消拼团") | |
| 107 | + @Parameter(name = "id", description = "拼团记录编号", required = true, example = "1024") | |
| 108 | + public CommonResult<Boolean> cancelCombinationRecord(@RequestParam("id") Long id) { | |
| 109 | + Long userId = getLoginUserId(); | |
| 110 | + // 1、查找这条拼团记录 | |
| 111 | + CombinationRecordDO record = combinationRecordService.getCombinationRecordByIdAndUser(userId, id); | |
| 112 | + if (record == null) { | |
| 113 | + return success(Boolean.FALSE); | |
| 114 | + } | |
| 115 | + // 1.1、需要先校验拼团记录未完成; | |
| 116 | + if (!CombinationRecordStatusEnum.isInProgress(record.getStatus())) { | |
| 117 | + return success(Boolean.FALSE); | |
| 118 | + } | |
| 119 | + | |
| 120 | + // 2. 取消已支付的订单 | |
| 121 | + tradeOrderApi.cancelPaidOrder(userId, record.getOrderId()); | |
| 122 | + // 3. 取消拼团记录 | |
| 123 | + combinationRecordService.cancelCombinationRecord(userId, record.getId(), record.getHeadId()); | |
| 124 | + return success(Boolean.TRUE); | |
| 125 | + } | |
| 103 | 126 | |
| 104 | 127 | } | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/CombinationRecordMapper.java
| ... | ... | @@ -159,20 +159,4 @@ public interface CombinationRecordMapper extends BaseMapperX<CombinationRecordDO |
| 159 | 159 | .betweenIfPresent(CombinationRecordDO::getCreateTime, builderQueryTime(dateType))); |
| 160 | 160 | } |
| 161 | 161 | |
| 162 | - /** | |
| 163 | - * 查询指定团长的拼团记录(包括团长) | |
| 164 | - * | |
| 165 | - * @param activityId 活动编号 | |
| 166 | - * @param headId 团长编号 | |
| 167 | - * @return 拼团记录 | |
| 168 | - */ | |
| 169 | - default List<CombinationRecordDO> selectList(Long activityId, Long headId) { | |
| 170 | - return selectList(new LambdaQueryWrapperX<CombinationRecordDO>() | |
| 171 | - .eq(CombinationRecordDO::getActivityId, activityId) | |
| 172 | - .eq(CombinationRecordDO::getHeadId, headId) | |
| 173 | - .or() | |
| 174 | - .eq(CombinationRecordDO::getId, headId)); | |
| 175 | - | |
| 176 | - } | |
| 177 | - | |
| 178 | 162 | } | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordService.java
| ... | ... | @@ -158,12 +158,32 @@ public interface CombinationRecordService { |
| 158 | 158 | * 【拼团活动】获得拼团记录数量 Map |
| 159 | 159 | * |
| 160 | 160 | * @param activityIds 活动记录编号数组 |
| 161 | - * @param status 拼团状态,允许空 | |
| 162 | - * @param headId 团长编号,允许空。目的 headId 设置为 {@link CombinationRecordDO#HEAD_ID_GROUP} 时,可以设置 | |
| 161 | + * @param status 拼团状态,允许空 | |
| 162 | + * @param headId 团长编号,允许空。目的 headId 设置为 {@link CombinationRecordDO#HEAD_ID_GROUP} 时,可以设置 | |
| 163 | 163 | * @return 拼团记录数量 Map |
| 164 | 164 | */ |
| 165 | 165 | Map<Long, Integer> getCombinationRecordCountMapByActivity(Collection<Long> activityIds, |
| 166 | 166 | @Nullable Integer status, |
| 167 | 167 | @Nullable Long headId); |
| 168 | 168 | |
| 169 | + | |
| 170 | + /** | |
| 171 | + * 获取拼团记录 | |
| 172 | + * | |
| 173 | + * @param userId 用户编号 | |
| 174 | + * @param id 拼团记录编号 | |
| 175 | + * @return 拼团记录 | |
| 176 | + */ | |
| 177 | + CombinationRecordDO getCombinationRecordByIdAndUser(Long userId, Long id); | |
| 178 | + | |
| 179 | + /** | |
| 180 | + * 取消拼团 | |
| 181 | + * | |
| 182 | + * @param userId 用户编号 | |
| 183 | + * @param id 拼团记录编号 | |
| 184 | + * @param headId 团长编号 | |
| 185 | + */ | |
| 186 | + void cancelCombinationRecord(Long userId, Long id, Long headId); | |
| 187 | + | |
| 188 | + | |
| 169 | 189 | } | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java
| ... | ... | @@ -28,10 +28,7 @@ import org.springframework.validation.annotation.Validated; |
| 28 | 28 | |
| 29 | 29 | import javax.annotation.Nullable; |
| 30 | 30 | import javax.annotation.Resource; |
| 31 | -import java.util.ArrayList; | |
| 32 | -import java.util.Collection; | |
| 33 | -import java.util.List; | |
| 34 | -import java.util.Map; | |
| 31 | +import java.util.*; | |
| 35 | 32 | |
| 36 | 33 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 37 | 34 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; |
| ... | ... | @@ -180,7 +177,7 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { |
| 180 | 177 | recordMapper.insert(recordDO); |
| 181 | 178 | |
| 182 | 179 | // 3、如果是团长需要设置 headId 为 CombinationRecordDO#HEAD_ID_GROUP |
| 183 | - if (reqDTO.getHeadId() == null) { | |
| 180 | + if (ObjUtil.equal(CombinationRecordDO.HEAD_ID_GROUP, reqDTO.getHeadId())) { | |
| 184 | 181 | recordMapper.updateById(new CombinationRecordDO().setId(recordDO.getId()).setHeadId(CombinationRecordDO.HEAD_ID_GROUP)); |
| 185 | 182 | return; |
| 186 | 183 | } |
| ... | ... | @@ -212,13 +209,17 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { |
| 212 | 209 | * @param headId 团长编号 |
| 213 | 210 | */ |
| 214 | 211 | private void updateCombinationRecords(CombinationActivityDO activity, Long headId) { |
| 215 | - List<CombinationRecordDO> records = recordMapper.selectList(CombinationRecordDO::getHeadId, headId); | |
| 212 | + // 团长 | |
| 213 | + CombinationRecordDO recordHead = recordMapper.selectById(headId); | |
| 214 | + // 团员 | |
| 215 | + List<CombinationRecordDO> records = getCombinationRecordListByHeadId(headId); | |
| 216 | + // 需要更新的记录 | |
| 216 | 217 | List<CombinationRecordDO> updateRecords = new ArrayList<>(); |
| 217 | 218 | |
| 218 | 219 | if (CollUtil.isEmpty(records)) { |
| 219 | 220 | return; |
| 220 | 221 | } |
| 221 | - | |
| 222 | + records.add(recordHead); // 加入团长,团长也需要更新 | |
| 222 | 223 | boolean isEqual = ObjUtil.equal(records.size(), activity.getUserSize()); |
| 223 | 224 | records.forEach(item -> { |
| 224 | 225 | CombinationRecordDO recordDO = new CombinationRecordDO(); |
| ... | ... | @@ -305,4 +306,59 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { |
| 305 | 306 | return recordMapper.selectCombinationRecordCountMapByActivityIdAndStatusAndHeadId(activityIds, status, headId); |
| 306 | 307 | } |
| 307 | 308 | |
| 309 | + @Override | |
| 310 | + public CombinationRecordDO getCombinationRecordByIdAndUser(Long userId, Long id) { | |
| 311 | + return recordMapper.selectOne(CombinationRecordDO::getUserId, userId, CombinationRecordDO::getId, id); | |
| 312 | + } | |
| 313 | + | |
| 314 | + @Override | |
| 315 | + @Transactional(rollbackFor = Exception.class) | |
| 316 | + public void cancelCombinationRecord(Long userId, Long id, Long headId) { | |
| 317 | + // 删除记录 | |
| 318 | + recordMapper.deleteById(id); | |
| 319 | + | |
| 320 | + // 需要更新的记录 | |
| 321 | + List<CombinationRecordDO> updateRecords = new ArrayList<>(); | |
| 322 | + // 如果它是团长,则顺序(下单时间)继承 | |
| 323 | + if (Objects.equals(headId, CombinationRecordDO.HEAD_ID_GROUP)) { // 情况一:团长 | |
| 324 | + // 团员 | |
| 325 | + List<CombinationRecordDO> list = getCombinationRecordListByHeadId(id); | |
| 326 | + if (CollUtil.isEmpty(list)) { | |
| 327 | + return; | |
| 328 | + } | |
| 329 | + // 按照创建时间升序排序 | |
| 330 | + List<CombinationRecordDO> recordsSort = sortedAsc(list, CombinationRecordDO::getCreateTime); | |
| 331 | + CombinationRecordDO newHead = recordsSort.get(0); // 新团长继位 | |
| 332 | + recordsSort.forEach(item -> { | |
| 333 | + CombinationRecordDO recordDO = new CombinationRecordDO(); | |
| 334 | + recordDO.setId(item.getId()); | |
| 335 | + if (ObjUtil.equal(item.getId(), newHead.getId())) { // 新团长 | |
| 336 | + recordDO.setHeadId(CombinationRecordDO.HEAD_ID_GROUP); | |
| 337 | + } else { | |
| 338 | + recordDO.setHeadId(newHead.getId()); | |
| 339 | + } | |
| 340 | + recordDO.setUserCount(recordsSort.size()); | |
| 341 | + updateRecords.add(recordDO); | |
| 342 | + }); | |
| 343 | + } else { // 情况二:团员 | |
| 344 | + // 团长 | |
| 345 | + CombinationRecordDO recordHead = recordMapper.selectById(headId); | |
| 346 | + // 团员 | |
| 347 | + List<CombinationRecordDO> records = getCombinationRecordListByHeadId(headId); | |
| 348 | + if (CollUtil.isEmpty(records)) { | |
| 349 | + return; | |
| 350 | + } | |
| 351 | + records.add(recordHead); // 加入团长,团长数据也需要更新 | |
| 352 | + records.forEach(item -> { | |
| 353 | + CombinationRecordDO recordDO = new CombinationRecordDO(); | |
| 354 | + recordDO.setId(item.getId()); | |
| 355 | + recordDO.setUserCount(records.size()); | |
| 356 | + updateRecords.add(recordDO); | |
| 357 | + }); | |
| 358 | + } | |
| 359 | + | |
| 360 | + // 更新拼团记录 | |
| 361 | + recordMapper.updateBatch(updateRecords); | |
| 362 | + } | |
| 363 | + | |
| 308 | 364 | } | ... | ... |
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/order/TradeOrderApi.java
| ... | ... | @@ -49,4 +49,12 @@ public interface TradeOrderApi { |
| 49 | 49 | */ |
| 50 | 50 | void updateOrderCombinationInfo(Long orderId, Long activityId, Long combinationRecordId, Long headId); |
| 51 | 51 | |
| 52 | + /** | |
| 53 | + * 取消支付订单 | |
| 54 | + * | |
| 55 | + * @param userId 用户编号 | |
| 56 | + * @param orderId 订单编号 | |
| 57 | + */ | |
| 58 | + void cancelPaidOrder(Long userId, Long orderId); | |
| 59 | + | |
| 52 | 60 | } | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/order/TradeOrderApiImpl.java
| ... | ... | @@ -47,4 +47,9 @@ public class TradeOrderApiImpl implements TradeOrderApi { |
| 47 | 47 | tradeOrderUpdateService.updateOrderCombinationInfo(orderId, activityId, combinationRecordId, headId); |
| 48 | 48 | } |
| 49 | 49 | |
| 50 | + @Override | |
| 51 | + public void cancelPaidOrder(Long userId, Long orderId) { | |
| 52 | + tradeOrderUpdateService.cancelPaidOrder(userId, orderId); | |
| 53 | + } | |
| 54 | + | |
| 50 | 55 | } | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateService.java
| ... | ... | @@ -180,4 +180,12 @@ public interface TradeOrderUpdateService { |
| 180 | 180 | */ |
| 181 | 181 | void updateOrderCombinationInfo(Long orderId, Long activityId, Long combinationRecordId, Long headId); |
| 182 | 182 | |
| 183 | + /** | |
| 184 | + * 取消支付订单 | |
| 185 | + * | |
| 186 | + * @param userId 用户编号 | |
| 187 | + * @param orderId 订单编号 | |
| 188 | + */ | |
| 189 | + void cancelPaidOrder(Long userId, Long orderId); | |
| 190 | + | |
| 183 | 191 | } | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java
| ... | ... | @@ -918,6 +918,17 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { |
| 918 | 918 | .setCombinationRecordId(combinationRecordId).setCombinationHeadId(headId)); |
| 919 | 919 | } |
| 920 | 920 | |
| 921 | + @Override | |
| 922 | + @Transactional(rollbackFor = Exception.class) | |
| 923 | + public void cancelPaidOrder(Long userId, Long orderId) { | |
| 924 | + TradeOrderDO order = tradeOrderMapper.selectOrderByIdAndUserId(orderId, userId); | |
| 925 | + if (order == null) { | |
| 926 | + throw exception(ORDER_NOT_FOUND); | |
| 927 | + } | |
| 928 | + | |
| 929 | + cancelOrder0(order, TradeOrderCancelTypeEnum.MEMBER_CANCEL); | |
| 930 | + } | |
| 931 | + | |
| 921 | 932 | /** |
| 922 | 933 | * 创建单个订单的评论 |
| 923 | 934 | * | ... | ... |