From 6636ee7420dcc55025d5d97d7e975b88936b63cd Mon Sep 17 00:00:00 2001 From: puhui999 Date: Sat, 7 Oct 2023 18:46:19 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8B=BC=E5=9B=A2=E8=AE=B0=E5=BD=95(APP)?= =?UTF-8?q?=EF=BC=9A=E6=96=B0=E5=A2=9E=E4=B8=80=E4=B8=AA=E5=8F=96=E6=B6=88?= =?UTF-8?q?=E6=8B=BC=E5=9B=A2=E7=9A=84=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../util/collection/CollectionUtils.java | 8 +++ .../AppCombinationRecordController.java | 31 ++++++-- .../combination/CombinationRecordMapper.java | 16 ----- .../combination/CombinationRecordService.java | 24 ++++++- .../CombinationRecordServiceImpl.java | 70 +++++++++++++++++-- .../module/trade/api/order/TradeOrderApi.java | 8 +++ .../trade/api/order/TradeOrderApiImpl.java | 5 ++ .../order/TradeOrderUpdateService.java | 8 +++ .../order/TradeOrderUpdateServiceImpl.java | 11 +++ 9 files changed, 152 insertions(+), 29 deletions(-) diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/collection/CollectionUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/collection/CollectionUtils.java index 12d18dc951..5d9613de77 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/collection/CollectionUtils.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/collection/CollectionUtils.java @@ -25,6 +25,14 @@ public class CollectionUtils { return Arrays.stream(collections).anyMatch(CollectionUtil::isEmpty); } + public static > List sortedAsc( + Collection from, Function keyExtractor) { + // 按照升序排序 + return from.stream() + .sorted(Comparator.comparing(keyExtractor)) + .collect(Collectors.toList()); + } + public static boolean anyMatch(Collection from, Predicate predicate) { return from.stream().anyMatch(predicate); } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationRecordController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationRecordController.java index ded52759c8..f22065193a 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationRecordController.java +++ b/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 import cn.iocoder.yudao.module.promotion.controller.app.combination.vo.record.AppCombinationRecordSummaryRespVO; import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert; import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationRecordDO; +import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum; import cn.iocoder.yudao.module.promotion.service.combination.CombinationRecordService; +import cn.iocoder.yudao.module.trade.api.order.TradeOrderApi; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameters; import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.context.annotation.Lazy; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -35,6 +38,9 @@ public class AppCombinationRecordController { @Resource private CombinationRecordService combinationRecordService; + @Resource + @Lazy + private TradeOrderApi tradeOrderApi; @GetMapping("/get-summary") @Operation(summary = "获得拼团记录的概要信息", description = "用于小程序首页") @@ -96,9 +102,26 @@ public class AppCombinationRecordController { return success(CombinationActivityConvert.INSTANCE.convert(getLoginUserId(), headRecord, memberRecords)); } - // TODO @puhui:新增一个取消拼团的接口,cancel - // 1. 需要先校验拼团记录未完成; - // 2. 在 Order 那增加一个 cancelPaidOrder 接口,用于取消已支付的订单 - // 3. order 完成后,取消拼团记录。另外,如果它是团长,则顺序(下单时间)继承 + @GetMapping("/cancel") + @Operation(summary = "取消拼团") + @Parameter(name = "id", description = "拼团记录编号", required = true, example = "1024") + public CommonResult cancelCombinationRecord(@RequestParam("id") Long id) { + Long userId = getLoginUserId(); + // 1、查找这条拼团记录 + CombinationRecordDO record = combinationRecordService.getCombinationRecordByIdAndUser(userId, id); + if (record == null) { + return success(Boolean.FALSE); + } + // 1.1、需要先校验拼团记录未完成; + if (!CombinationRecordStatusEnum.isInProgress(record.getStatus())) { + return success(Boolean.FALSE); + } + + // 2. 取消已支付的订单 + tradeOrderApi.cancelPaidOrder(userId, record.getOrderId()); + // 3. 取消拼团记录 + combinationRecordService.cancelCombinationRecord(userId, record.getId(), record.getHeadId()); + return success(Boolean.TRUE); + } } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/CombinationRecordMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/CombinationRecordMapper.java index 6226cb2eba..8e3e47251c 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/CombinationRecordMapper.java +++ b/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 selectList(Long activityId, Long headId) { - return selectList(new LambdaQueryWrapperX() - .eq(CombinationRecordDO::getActivityId, activityId) - .eq(CombinationRecordDO::getHeadId, headId) - .or() - .eq(CombinationRecordDO::getId, headId)); - - } - } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordService.java index 3e8a97c0ea..3baf69529a 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordService.java +++ b/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 { * 【拼团活动】获得拼团记录数量 Map * * @param activityIds 活动记录编号数组 - * @param status 拼团状态,允许空 - * @param headId 团长编号,允许空。目的 headId 设置为 {@link CombinationRecordDO#HEAD_ID_GROUP} 时,可以设置 + * @param status 拼团状态,允许空 + * @param headId 团长编号,允许空。目的 headId 设置为 {@link CombinationRecordDO#HEAD_ID_GROUP} 时,可以设置 * @return 拼团记录数量 Map */ Map getCombinationRecordCountMapByActivity(Collection activityIds, @Nullable Integer status, @Nullable Long headId); + + /** + * 获取拼团记录 + * + * @param userId 用户编号 + * @param id 拼团记录编号 + * @return 拼团记录 + */ + CombinationRecordDO getCombinationRecordByIdAndUser(Long userId, Long id); + + /** + * 取消拼团 + * + * @param userId 用户编号 + * @param id 拼团记录编号 + * @param headId 团长编号 + */ + void cancelCombinationRecord(Long userId, Long id, Long headId); + + } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java index cbf2440f78..183fda97b1 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java +++ b/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; import javax.annotation.Nullable; import javax.annotation.Resource; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; +import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; @@ -180,7 +177,7 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { recordMapper.insert(recordDO); // 3、如果是团长需要设置 headId 为 CombinationRecordDO#HEAD_ID_GROUP - if (reqDTO.getHeadId() == null) { + if (ObjUtil.equal(CombinationRecordDO.HEAD_ID_GROUP, reqDTO.getHeadId())) { recordMapper.updateById(new CombinationRecordDO().setId(recordDO.getId()).setHeadId(CombinationRecordDO.HEAD_ID_GROUP)); return; } @@ -212,13 +209,17 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { * @param headId 团长编号 */ private void updateCombinationRecords(CombinationActivityDO activity, Long headId) { - List records = recordMapper.selectList(CombinationRecordDO::getHeadId, headId); + // 团长 + CombinationRecordDO recordHead = recordMapper.selectById(headId); + // 团员 + List records = getCombinationRecordListByHeadId(headId); + // 需要更新的记录 List updateRecords = new ArrayList<>(); if (CollUtil.isEmpty(records)) { return; } - + records.add(recordHead); // 加入团长,团长也需要更新 boolean isEqual = ObjUtil.equal(records.size(), activity.getUserSize()); records.forEach(item -> { CombinationRecordDO recordDO = new CombinationRecordDO(); @@ -305,4 +306,59 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { return recordMapper.selectCombinationRecordCountMapByActivityIdAndStatusAndHeadId(activityIds, status, headId); } + @Override + public CombinationRecordDO getCombinationRecordByIdAndUser(Long userId, Long id) { + return recordMapper.selectOne(CombinationRecordDO::getUserId, userId, CombinationRecordDO::getId, id); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void cancelCombinationRecord(Long userId, Long id, Long headId) { + // 删除记录 + recordMapper.deleteById(id); + + // 需要更新的记录 + List updateRecords = new ArrayList<>(); + // 如果它是团长,则顺序(下单时间)继承 + if (Objects.equals(headId, CombinationRecordDO.HEAD_ID_GROUP)) { // 情况一:团长 + // 团员 + List list = getCombinationRecordListByHeadId(id); + if (CollUtil.isEmpty(list)) { + return; + } + // 按照创建时间升序排序 + List recordsSort = sortedAsc(list, CombinationRecordDO::getCreateTime); + CombinationRecordDO newHead = recordsSort.get(0); // 新团长继位 + recordsSort.forEach(item -> { + CombinationRecordDO recordDO = new CombinationRecordDO(); + recordDO.setId(item.getId()); + if (ObjUtil.equal(item.getId(), newHead.getId())) { // 新团长 + recordDO.setHeadId(CombinationRecordDO.HEAD_ID_GROUP); + } else { + recordDO.setHeadId(newHead.getId()); + } + recordDO.setUserCount(recordsSort.size()); + updateRecords.add(recordDO); + }); + } else { // 情况二:团员 + // 团长 + CombinationRecordDO recordHead = recordMapper.selectById(headId); + // 团员 + List records = getCombinationRecordListByHeadId(headId); + if (CollUtil.isEmpty(records)) { + return; + } + records.add(recordHead); // 加入团长,团长数据也需要更新 + records.forEach(item -> { + CombinationRecordDO recordDO = new CombinationRecordDO(); + recordDO.setId(item.getId()); + recordDO.setUserCount(records.size()); + updateRecords.add(recordDO); + }); + } + + // 更新拼团记录 + recordMapper.updateBatch(updateRecords); + } + } diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/order/TradeOrderApi.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/order/TradeOrderApi.java index 0d72a75e86..91298874c6 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/order/TradeOrderApi.java +++ b/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 { */ void updateOrderCombinationInfo(Long orderId, Long activityId, Long combinationRecordId, Long headId); + /** + * 取消支付订单 + * + * @param userId 用户编号 + * @param orderId 订单编号 + */ + void cancelPaidOrder(Long userId, Long orderId); + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/order/TradeOrderApiImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/order/TradeOrderApiImpl.java index ed1ee1f26b..1013ae71fc 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/order/TradeOrderApiImpl.java +++ b/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 { tradeOrderUpdateService.updateOrderCombinationInfo(orderId, activityId, combinationRecordId, headId); } + @Override + public void cancelPaidOrder(Long userId, Long orderId) { + tradeOrderUpdateService.cancelPaidOrder(userId, orderId); + } + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateService.java index bc8413b3d5..2916805782 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateService.java +++ b/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 { */ void updateOrderCombinationInfo(Long orderId, Long activityId, Long combinationRecordId, Long headId); + /** + * 取消支付订单 + * + * @param userId 用户编号 + * @param orderId 订单编号 + */ + void cancelPaidOrder(Long userId, Long orderId); + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java index 7c5ed91b32..a34859f0b9 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java +++ b/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 { .setCombinationRecordId(combinationRecordId).setCombinationHeadId(headId)); } + @Override + @Transactional(rollbackFor = Exception.class) + public void cancelPaidOrder(Long userId, Long orderId) { + TradeOrderDO order = tradeOrderMapper.selectOrderByIdAndUserId(orderId, userId); + if (order == null) { + throw exception(ORDER_NOT_FOUND); + } + + cancelOrder0(order, TradeOrderCancelTypeEnum.MEMBER_CANCEL); + } + /** * 创建单个订单的评论 *