Browse Source

拼团记录(APP):新增一个取消拼团的接口

puhui999 1 year ago
parent
commit
6636ee7420

+ 8 - 0
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 <T, U extends Comparable<? super U>> List<T> sortedAsc(
+            Collection<T> from, Function<? super T, ? extends U> keyExtractor) {
+        // 按照升序排序
+        return from.stream()
+                .sorted(Comparator.comparing(keyExtractor))
+                .collect(Collectors.toList());
+    }
+
     public static <T> boolean anyMatch(Collection<T> from, Predicate<T> predicate) {
         return from.stream().anyMatch(predicate);
     }

+ 27 - 4
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<Boolean> 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);
+    }
 
 }

+ 0 - 16
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
                 .betweenIfPresent(CombinationRecordDO::getCreateTime, builderQueryTime(dateType)));
     }
 
-    /**
-     * 查询指定团长的拼团记录(包括团长)
-     *
-     * @param activityId 活动编号
-     * @param headId     团长编号
-     * @return 拼团记录
-     */
-    default List<CombinationRecordDO> selectList(Long activityId, Long headId) {
-        return selectList(new LambdaQueryWrapperX<CombinationRecordDO>()
-                .eq(CombinationRecordDO::getActivityId, activityId)
-                .eq(CombinationRecordDO::getHeadId, headId)
-                .or()
-                .eq(CombinationRecordDO::getId, headId));
-
-    }
-
 }

+ 22 - 2
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<Long, Integer> getCombinationRecordCountMapByActivity(Collection<Long> 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);
+
+
 }

+ 63 - 7
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<CombinationRecordDO> records = recordMapper.selectList(CombinationRecordDO::getHeadId, headId);
+        // 团长
+        CombinationRecordDO recordHead = recordMapper.selectById(headId);
+        // 团员
+        List<CombinationRecordDO> records = getCombinationRecordListByHeadId(headId);
+        // 需要更新的记录
         List<CombinationRecordDO> 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<CombinationRecordDO> updateRecords = new ArrayList<>();
+        // 如果它是团长,则顺序(下单时间)继承
+        if (Objects.equals(headId, CombinationRecordDO.HEAD_ID_GROUP)) { // 情况一:团长
+            // 团员
+            List<CombinationRecordDO> list = getCombinationRecordListByHeadId(id);
+            if (CollUtil.isEmpty(list)) {
+                return;
+            }
+            // 按照创建时间升序排序
+            List<CombinationRecordDO> 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<CombinationRecordDO> 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);
+    }
+
 }

+ 8 - 0
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);
+
 }

+ 5 - 0
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);
+    }
+
 }

+ 8 - 0
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);
+
 }

+ 11 - 0
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);
+    }
+
     /**
      * 创建单个订单的评论
      *