From 26f9fe2a2093a08d90d779b7531514863646242b Mon Sep 17 00:00:00 2001
From: chen-xin-zhi <3588068430@qq.com>
Date: Wed, 14 May 2025 10:40:17 +0800
Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E4=BA=86=E7=AC=AC=E4=B8=80?=
 =?UTF-8?q?=E7=89=88?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../project/ProjectDetailController.java      | 64 +++++++++----------
 .../userInfo/UserInfoController.java          | 15 +++++
 .../promotion/mapper/UserInfoMapper.java      |  9 +++
 .../dto/userInfo/UserInfoAddRequest.java      | 18 ------
 .../dto/userInfo/UserInfoUpdateRequest.java   |  6 --
 .../promotion/model/entity/UserInfo.java      |  5 --
 .../model/vo/userInfo/UserInfoVO.java         |  6 --
 .../service/userInfo/UserInfoService.java     |  8 +++
 .../userInfo/impl/UserInfoServiceImpl.java    | 47 +++++++++++++-
 .../resources/mapper/PromoCodeApplyMapper.xml |  2 -
 src/main/resources/mapper/UserInfoMapper.xml  | 22 +++++++
 11 files changed, 129 insertions(+), 73 deletions(-)

diff --git a/src/main/java/com/greenorange/promotion/controller/project/ProjectDetailController.java b/src/main/java/com/greenorange/promotion/controller/project/ProjectDetailController.java
index 5f88101..c02f258 100644
--- a/src/main/java/com/greenorange/promotion/controller/project/ProjectDetailController.java
+++ b/src/main/java/com/greenorange/promotion/controller/project/ProjectDetailController.java
@@ -2,6 +2,7 @@ package com.greenorange.promotion.controller.project;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
 import com.greenorange.promotion.annotation.RequiresPermission;
 import com.greenorange.promotion.annotation.SysLog;
 import com.greenorange.promotion.common.BaseResponse;
@@ -84,10 +85,7 @@ public class ProjectDetailController {
         projectService.updateById(project);
 
         // 获取所有的小程序用户
-        LambdaQueryWrapper<UserInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
-        lambdaQueryWrapper.eq(UserInfo::getUserRole, UserConstant.DEFAULT_ROLE);
-        List<UserInfo> userInfoList = userInfoService.list(lambdaQueryWrapper);
-
+        List<UserInfo> userInfoList = commonService.findByFieldEqTargetField(UserInfo::getUserRole, UserConstant.DEFAULT_ROLE, userInfoService);
         // 获取参数信息
         List<ProjectCommissionAddRequest> projectCommissionAddRequestList = new ArrayList<>();
         Long projectDetailId = projectDetail.getId();
@@ -108,9 +106,9 @@ public class ProjectDetailController {
         projectCommissionService.saveBatch(projectCommissions);
 
         // 给所有用户添加一条下级项目明细抽佣表
-        userInfoList = userInfoList.stream().filter(userInfo -> userInfo.getParentUserId() != null).collect(Collectors.toList());
         List<SubUserProjectCommissionAddRequest> subUserProjectCommissionAddRequestList = new ArrayList<>();
         for (UserInfo userInfo : userInfoList) {
+            if (userInfo.getParentUserId() == 0) continue;
             SubUserProjectCommissionAddRequest  subUserProjectCommissionAddRequest = SubUserProjectCommissionAddRequest.builder()
                     .projectDetailId(projectDetailId)
                     .myUnitPrice(projectSettlementPrice)
@@ -141,13 +139,13 @@ public class ProjectDetailController {
         Long projectDetailId = projectDetailUpdateRequest.getId();
         ProjectDetail sourceProjectDetail = projectDetailService.getById(projectDetailId);
         ProjectDetail projectDetail = commonService.copyProperties(projectDetailUpdateRequest, ProjectDetail.class);
+        // 1.更新项目明细的结算价格
+        projectDetailService.updateById(projectDetail);
         // 更新项目的价格
         Long projectId = projectDetail.getProjectId();
         Project project = projectService.getById(projectId);
         project.setProjectPrice(project.getProjectPrice().subtract(sourceProjectDetail.getProjectSettlementPrice()).add(projectDetail.getProjectSettlementPrice()));
         projectService.updateById(project);
-        // 1.更新项目明细的结算价格
-        projectDetailService.updateById(projectDetail);
         // 2.更新抽佣比例(如果抽佣比例比原来小)
         LambdaQueryWrapper<SubUserProjectCommission> lambdaQueryWrapper = new LambdaQueryWrapper<>();
         lambdaQueryWrapper.eq(SubUserProjectCommission::getProjectDetailId, projectDetail.getId());
@@ -167,32 +165,31 @@ public class ProjectDetailController {
             commissionRateMap.put(key, currentCommissionRate);
         }
         // 获取所有的小程序用户
-        LambdaQueryWrapper<UserInfo> userInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
-        userInfoLambdaQueryWrapper.eq(UserInfo::getUserRole, UserConstant.DEFAULT_ROLE);
-        List<UserInfo> userInfoList = userInfoService.list(userInfoLambdaQueryWrapper);
+        List<UserInfo> userInfoList = commonService.findByFieldEqTargetField(UserInfo::getUserRole, UserConstant.DEFAULT_ROLE, userInfoService);
         // 用来存储每个用户的上级列表
-        Map<Long, List<Long>> userParentMap = new HashMap<>();
-        for (UserInfo userInfo : userInfoList) {
-            String superUserList = userInfo.getSuperUserList();
-            if (superUserList != null) userParentMap.put(userInfo.getId(), Arrays.stream(superUserList.split(",")).map(Long::parseLong).collect(Collectors.toList()));
-        }
+//        Map<Long, List<Long>> userParentMap = new HashMap<>();
+//        for (UserInfo userInfo : userInfoList) {
+//            String superUserList = userInfo.getSuperUserList();
+//            if (superUserList != null) userParentMap.put(userInfo.getId(), Arrays.stream(superUserList.split(",")).map(Long::parseLong).collect(Collectors.toList()));
+//        }
+//        userInfoService.findPathToRoot()
         // 4.更新所有用户的结算价格
-        for (SubUserProjectCommission subUserProjectCommission : subUserProjectCommissionList) {
-            Long userId = subUserProjectCommission.getUserId();
-            List<Long> parentIds = userParentMap.get(userId);
-            parentIds.add(userId);
-            BigDecimal totalRate = BigDecimal.ONE;
-            for (int i = 0; i < parentIds.size() - 1; i ++ ) {
-                String key = parentIds.get(i) + "-" + parentIds.get(i + 1);
-                BigDecimal commissionRate = commissionRateMap.get(key);
-                totalRate = totalRate.multiply(BigDecimal.ONE.subtract(commissionRate));
-            }
-            BigDecimal projectSettlementPrice = projectDetail.getProjectSettlementPrice();
-            BigDecimal projectMinSettlementPrice = projectDetail.getProjectMinSettlementPrice();
-            BigDecimal finallySettlementPrice = projectSettlementPrice.multiply(totalRate);
-            if (finallySettlementPrice.compareTo(projectMinSettlementPrice) < 0) finallySettlementPrice = projectMinSettlementPrice;
-            subUserProjectCommission.setMyUnitPrice(finallySettlementPrice);
-        }
+//        for (SubUserProjectCommission subUserProjectCommission : subUserProjectCommissionList) {
+//            Long userId = subUserProjectCommission.getUserId();
+//            List<Long> parentIds = userParentMap.get(userId);
+//            parentIds.add(userId);
+//            BigDecimal totalRate = BigDecimal.ONE;
+//            for (int i = 0; i < parentIds.size() - 1; i ++ ) {
+//                String key = parentIds.get(i) + "-" + parentIds.get(i + 1);
+//                BigDecimal commissionRate = commissionRateMap.get(key);
+//                totalRate = totalRate.multiply(BigDecimal.ONE.subtract(commissionRate));
+//            }
+//            BigDecimal projectSettlementPrice = projectDetail.getProjectSettlementPrice();
+//            BigDecimal projectMinSettlementPrice = projectDetail.getProjectMinSettlementPrice();
+//            BigDecimal finallySettlementPrice = projectSettlementPrice.multiply(totalRate);
+//            if (finallySettlementPrice.compareTo(projectMinSettlementPrice) < 0) finallySettlementPrice = projectMinSettlementPrice;
+//            subUserProjectCommission.setMyUnitPrice(finallySettlementPrice);
+//        }
         subUserProjectCommissionService.updateBatchById(subUserProjectCommissionList);
 
         return ResultUtils.success(true);
@@ -243,7 +240,6 @@ public class ProjectDetailController {
     public BaseResponse<ProjectDetailVO> queryProjectDetailById(@Valid @RequestBody CommonRequest commonRequest) {
         Long id = commonRequest.getId();
         ProjectDetail projectDetail = projectDetailService.getById(id);
-        ThrowUtils.throwIf(projectDetail == null, ErrorCode.OPERATION_ERROR, "当前项目明细不存在");
         ProjectDetailVO projectDetailVO = commonService.copyProperties(projectDetail, ProjectDetailVO.class);
         return ResultUtils.success(projectDetailVO);
     }
@@ -260,9 +256,7 @@ public class ProjectDetailController {
     @SysLog(title = "项目明细管理", content = "web端管理员根据项目id查询项目明细")
     public BaseResponse<List<ProjectDetailVO>> queryProjectDetailByPid(@Valid @RequestBody CommonRequest commonRequest) {
         Long id = commonRequest.getId();
-        LambdaQueryWrapper<ProjectDetail> lambdaQueryWrapper = new LambdaQueryWrapper<>();
-        lambdaQueryWrapper.eq(ProjectDetail::getProjectId, id);
-        List<ProjectDetail> projectDetailList = projectDetailService.list(lambdaQueryWrapper);
+        List<ProjectDetail> projectDetailList = commonService.findByFieldEqTargetField(ProjectDetail::getProjectId, id, projectDetailService);
         List<ProjectDetailVO> projectDetailVOS = commonService.convertList(projectDetailList, ProjectDetailVO.class);
         return ResultUtils.success(projectDetailVOS);
     }
diff --git a/src/main/java/com/greenorange/promotion/controller/userInfo/UserInfoController.java b/src/main/java/com/greenorange/promotion/controller/userInfo/UserInfoController.java
index b5657f3..a623898 100644
--- a/src/main/java/com/greenorange/promotion/controller/userInfo/UserInfoController.java
+++ b/src/main/java/com/greenorange/promotion/controller/userInfo/UserInfoController.java
@@ -390,6 +390,21 @@ public class UserInfoController {
     }
 
 
+    /**
+     * (小程序端)查询当前用户到根节点的userId路径
+     * @param commonRequest 用户id
+     * @return 用户表列表
+     */
+    @PostMapping("query/path")
+    @Operation(summary = "查询当前用户到根节点的userId路径", description = "参数:用户id,权限:管理员(boss, admin),方法名:findPathToRootUserIdList")
+    @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE)
+    @SysLog(title = "用户管理", content = "查询当前用户到根节点的userId路径")
+    public BaseResponse<List<Long>> findPathToRootUserIdList(@Valid @RequestBody CommonRequest commonRequest) {
+        Long userId = commonRequest.getId();
+        List<Long> pathToRoot = userInfoService.findPathToRoot(userId);
+        return ResultUtils.success(pathToRoot);
+    }
+
 
 
 
diff --git a/src/main/java/com/greenorange/promotion/mapper/UserInfoMapper.java b/src/main/java/com/greenorange/promotion/mapper/UserInfoMapper.java
index 8d64da1..7a6ffc0 100644
--- a/src/main/java/com/greenorange/promotion/mapper/UserInfoMapper.java
+++ b/src/main/java/com/greenorange/promotion/mapper/UserInfoMapper.java
@@ -3,6 +3,8 @@ package com.greenorange.promotion.mapper;
 import com.greenorange.promotion.model.entity.UserInfo;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 
+import java.util.List;
+
 /**
 * @author 35880
 * @description 针对表【user_info(用户基本信息表)】的数据库操作Mapper
@@ -11,6 +13,13 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 */
 public interface UserInfoMapper extends BaseMapper<UserInfo> {
 
+
+    /**
+     * 查询从 userId 一路到根节点的所有 id,按 depth 倒序(根先出)
+     */
+    List<Long> findPathToRoot(Long userId);
+
+
 }
 
 
diff --git a/src/main/java/com/greenorange/promotion/model/dto/userInfo/UserInfoAddRequest.java b/src/main/java/com/greenorange/promotion/model/dto/userInfo/UserInfoAddRequest.java
index 0faabed..8b87074 100644
--- a/src/main/java/com/greenorange/promotion/model/dto/userInfo/UserInfoAddRequest.java
+++ b/src/main/java/com/greenorange/promotion/model/dto/userInfo/UserInfoAddRequest.java
@@ -55,12 +55,6 @@ public class UserInfoAddRequest implements Serializable {
     @Schema(description = "密码(建议加密存储)", example = "qingcheng")
     private String userPassword;
 
-    /**
-     * 邀请码
-     */
-    @Schema(description = "邀请码", example = "666999")
-    private String invitationCode;
-
     /**
      * 用户角色
      */
@@ -68,18 +62,6 @@ public class UserInfoAddRequest implements Serializable {
     @Schema(description = "用户角色", example = "user")
     private String userRole;
 
-    /**
-     * 上级用户id
-     */
-    @Schema(description = "上级用户id", example = "1")
-    private Long parentUserId;
-
-    /**
-     * 上级用户列表(1,2,3)
-     */
-    @Schema(description = "上级用户列表(1,2,3)", example = "1,2,3")
-    private String superUserList;
-
 
     @Serial
     private static final long serialVersionUID = 1L;
diff --git a/src/main/java/com/greenorange/promotion/model/dto/userInfo/UserInfoUpdateRequest.java b/src/main/java/com/greenorange/promotion/model/dto/userInfo/UserInfoUpdateRequest.java
index 07614cf..aa2f35f 100644
--- a/src/main/java/com/greenorange/promotion/model/dto/userInfo/UserInfoUpdateRequest.java
+++ b/src/main/java/com/greenorange/promotion/model/dto/userInfo/UserInfoUpdateRequest.java
@@ -84,12 +84,6 @@ public class UserInfoUpdateRequest implements Serializable {
     @Schema(description = "上级用户id", example = "1")
     private Long parentUserId;
 
-    /**
-     * 上级用户列表(1,2,3)
-     */
-    @Schema(description = "上级用户列表(1,2,3)", example = "1,2,3")
-    private String superUserList;
-
 
     @Serial
     private static final long serialVersionUID = 1L;
diff --git a/src/main/java/com/greenorange/promotion/model/entity/UserInfo.java b/src/main/java/com/greenorange/promotion/model/entity/UserInfo.java
index 478367a..43d5b5f 100644
--- a/src/main/java/com/greenorange/promotion/model/entity/UserInfo.java
+++ b/src/main/java/com/greenorange/promotion/model/entity/UserInfo.java
@@ -65,11 +65,6 @@ public class UserInfo implements Serializable {
      */
     private Long parentUserId;
 
-    /**
-     * 上级用户列表(1,2,3)
-     */
-    private String superUserList;
-
     /**
      * 是否删除
      */
diff --git a/src/main/java/com/greenorange/promotion/model/vo/userInfo/UserInfoVO.java b/src/main/java/com/greenorange/promotion/model/vo/userInfo/UserInfoVO.java
index 91d28e8..4fb4e53 100644
--- a/src/main/java/com/greenorange/promotion/model/vo/userInfo/UserInfoVO.java
+++ b/src/main/java/com/greenorange/promotion/model/vo/userInfo/UserInfoVO.java
@@ -69,12 +69,6 @@ public class UserInfoVO implements Serializable {
     @Schema(description = "上级用户id", example = "1")
     private Long parentUserId;
 
-    /**
-     * 上级用户列表(1,2,3)
-     */
-    @Schema(description = "上级用户列表(1,2,3)", example = "1,2,3")
-    private String superUserList;
-
 
     @Serial
     private static final long serialVersionUID = 1L;
diff --git a/src/main/java/com/greenorange/promotion/service/userInfo/UserInfoService.java b/src/main/java/com/greenorange/promotion/service/userInfo/UserInfoService.java
index 3c0168e..413de6e 100644
--- a/src/main/java/com/greenorange/promotion/service/userInfo/UserInfoService.java
+++ b/src/main/java/com/greenorange/promotion/service/userInfo/UserInfoService.java
@@ -5,6 +5,8 @@ import com.greenorange.promotion.model.dto.userInfo.*;
 import com.greenorange.promotion.model.entity.UserInfo;
 import com.baomidou.mybatisplus.extension.service.IService;
 
+import java.util.List;
+
 /**
 * @author 35880
 * @description 针对表【user_info(用户基本信息表)】的数据库操作Service
@@ -53,4 +55,10 @@ public interface UserInfoService extends IService<UserInfo> {
      * 小程序用户获取验证码
      */
     String getVerificationCode(String phoneNumber);
+
+
+    /**
+     * 查询从 userId 一路到根节点的所有 id,按 depth 倒序(根先出)
+     */
+    List<Long> findPathToRoot(Long userId);
 }
diff --git a/src/main/java/com/greenorange/promotion/service/userInfo/impl/UserInfoServiceImpl.java b/src/main/java/com/greenorange/promotion/service/userInfo/impl/UserInfoServiceImpl.java
index 0368480..2f6a9d8 100644
--- a/src/main/java/com/greenorange/promotion/service/userInfo/impl/UserInfoServiceImpl.java
+++ b/src/main/java/com/greenorange/promotion/service/userInfo/impl/UserInfoServiceImpl.java
@@ -12,10 +12,14 @@ import com.greenorange.promotion.constant.UserConstant;
 import com.greenorange.promotion.exception.ThrowUtils;
 import com.greenorange.promotion.mapper.UserInfoMapper;
 import com.greenorange.promotion.model.dto.userInfo.*;
+import com.greenorange.promotion.model.entity.ProjectCommission;
+import com.greenorange.promotion.model.entity.SubUserProjectCommission;
 import com.greenorange.promotion.model.entity.UserInfo;
 import com.greenorange.promotion.model.entity.UserMainInfo;
 import com.greenorange.promotion.model.enums.UserRoleEnum;
 import com.greenorange.promotion.service.common.CommonService;
+import com.greenorange.promotion.service.project.ProjectCommissionService;
+import com.greenorange.promotion.service.project.SubUserProjectCommissionService;
 import com.greenorange.promotion.service.userInfo.UserInfoService;
 import com.greenorange.promotion.service.userInfo.UserMainInfoService;
 import com.greenorange.promotion.service.wechat.WechatGetQrcodeService;
@@ -29,7 +33,10 @@ import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
 
 import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
 
@@ -61,6 +68,15 @@ public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo>
     @Resource
     private WechatGetQrcodeService wechatGetQrcodeService;
 
+    @Resource
+    private ProjectCommissionService projectCommissionService;
+
+    @Resource
+    private SubUserProjectCommissionService subUserProjectCommissionService;
+
+    @Resource
+    private UserInfoMapper userInfoMapper;
+
 
     /**
      * 获取查询条件
@@ -127,13 +143,16 @@ public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo>
         UserInfo parentUserInfo = this.getOne(invitedLambdaQueryWrapper);
         ThrowUtils.throwIf(parentUserInfo == null, ErrorCode.OPERATION_ERROR, "邀请码错误");
 
+
         UserInfo myUserInfo = commonService.copyProperties(userInfoRegisterRequest, UserInfo.class);
+        // 判断当前用户是否是根节点
+        List<UserInfo> userInfoList = commonService.findByFieldEqTargetField(UserInfo::getUserRole, UserConstant.DEFAULT_ROLE, this);
+        if (userInfoList.isEmpty()) myUserInfo.setParentUserId(0L);
         myUserInfo.setParentUserId(parentUserInfo.getId());
         myUserInfo.setInvitationCode(RandomUtil.randomNumbers(6));
         myUserInfo.setUserAccount(phoneNumber);
         myUserInfo.setUserRole(UserConstant.DEFAULT_ROLE);
         myUserInfo.setUserAvatar(UserConstant.USER_DEFAULT_AVATAR);
-        myUserInfo.setSuperUserList(parentUserInfo.getSuperUserList() + "," + parentUserInfo.getId());
         this.save(myUserInfo);
         UserMainInfo userMainInfo = new UserMainInfo();
         userMainInfo.setUserId(myUserInfo.getId());
@@ -146,6 +165,24 @@ public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo>
             e.printStackTrace();
         }
         userMainInfoService.save(userMainInfo);
+
+
+        List<SubUserProjectCommission> subUserProjectCommissionList = commonService.findByFieldEqTargetField(SubUserProjectCommission::getSubUserId, parentUserInfo.getId(), subUserProjectCommissionService);
+        List<ProjectCommission> projectCommissionList = new ArrayList<>();
+        for (SubUserProjectCommission subUserProjectCommission : subUserProjectCommissionList) {
+            // 插入下级用户项目明细抽佣记录
+            subUserProjectCommission.setId(null);
+            subUserProjectCommission.setUserId(parentUserInfo.getId());
+            subUserProjectCommission.setSubUserId(myUserInfo.getId());
+            subUserProjectCommission.setMyUnitPrice(subUserProjectCommission.getMyUnitPrice().multiply(BigDecimal.ONE.subtract(subUserProjectCommission.getCurrentCommissionRate())));
+            // 插入用户项目明细抽佣记录
+            ProjectCommission projectCommission = commonService.copyProperties(subUserProjectCommission, ProjectCommission.class);
+            projectCommission.setId(null);
+            projectCommission.setCurrentCommissionRate(BigDecimal.ZERO);
+            projectCommission.setUserId(myUserInfo.getId());
+        }
+        subUserProjectCommissionService.saveBatch(subUserProjectCommissionList);
+        projectCommissionService.saveBatch(projectCommissionList);
     }
 
 
@@ -246,6 +283,14 @@ public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo>
     }
 
 
+    /**
+     * 查询从 userId 一路到根节点的所有 id,按 depth 倒序(根先出)
+     */
+    @Override
+    public List<Long> findPathToRoot(Long userId) {
+        return userInfoMapper.findPathToRoot(userId);
+    }
+
 
 }
 
diff --git a/src/main/resources/mapper/PromoCodeApplyMapper.xml b/src/main/resources/mapper/PromoCodeApplyMapper.xml
index 510ca85..ce42ee8 100644
--- a/src/main/resources/mapper/PromoCodeApplyMapper.xml
+++ b/src/main/resources/mapper/PromoCodeApplyMapper.xml
@@ -12,8 +12,6 @@
             <result property="promoCodeLink" column="promoCodeLink" jdbcType="VARCHAR"/>
             <result property="projectName" column="projectName" jdbcType="VARCHAR"/>
             <result property="projectImage" column="projectImage" jdbcType="VARCHAR"/>
-            <result property="maxProjectPrice" column="maxProjectPrice" jdbcType="DECIMAL"/>
-            <result property="minProjectPrice" column="minProjectPrice" jdbcType="DECIMAL"/>
             <result property="userId" column="userId" jdbcType="BIGINT"/>
             <result property="isDelete" column="isDelete" jdbcType="TINYINT"/>
             <result property="createTime" column="createTime" jdbcType="TIMESTAMP"/>
diff --git a/src/main/resources/mapper/UserInfoMapper.xml b/src/main/resources/mapper/UserInfoMapper.xml
index d9267fa..a18b984 100644
--- a/src/main/resources/mapper/UserInfoMapper.xml
+++ b/src/main/resources/mapper/UserInfoMapper.xml
@@ -25,4 +25,26 @@
         userRole,parentUserId,superUserList,
         isDelete,createTime,updateTime
     </sql>
+
+
+
+
+<!--    查询从 userId 一路到根节点的所有 id,按 depth 倒序(根先出)-->
+    <select id="findPathToRoot" resultType="java.lang.Long">
+        WITH RECURSIVE user_path AS (
+            SELECT id, parentUserId, 1 AS depth
+            FROM user_info
+            WHERE id = #{userId}
+
+            UNION ALL
+
+            SELECT u.id, u.parentUserId, up.depth + 1
+            FROM user_info u
+                     JOIN user_path up ON u.id = up.parentUserId
+            WHERE up.depth &lt; 50000
+        )
+        SELECT id
+        FROM user_path
+        ORDER BY depth DESC
+    </select>
 </mapper>