fix(产品需求): 解决测试后存在的一些问题。
This commit is contained in:
@@ -4,11 +4,16 @@ import com.njcn.rdms.framework.apilog.core.annotation.ApiAccessLog;
|
||||
import com.njcn.rdms.framework.common.pojo.CommonResult;
|
||||
import com.njcn.rdms.framework.common.util.object.BeanUtils;
|
||||
import com.njcn.rdms.framework.excel.core.util.ExcelUtils;
|
||||
import com.njcn.rdms.module.system.controller.admin.user.vo.user.UserSimpleRespVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.user.vo.userManagementRelation.UserManagementRelationQueryReqVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.user.vo.userManagementRelation.UserManagementRelationRespVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.user.vo.userManagementRelation.UserManagementRelationSaveReqVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.user.vo.userManagementRelation.UserManagementRelationTreeRespVO;
|
||||
import com.njcn.rdms.module.system.convert.user.UserConvert;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.dept.DeptDO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.user.AdminUserDO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.user.UserManagementRelationDO;
|
||||
import com.njcn.rdms.module.system.service.dept.DeptService;
|
||||
import com.njcn.rdms.module.system.service.user.UserManagementRelationService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
@@ -22,9 +27,11 @@ import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.njcn.rdms.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
|
||||
import static com.njcn.rdms.framework.common.pojo.CommonResult.success;
|
||||
import static com.njcn.rdms.framework.common.util.collection.CollectionUtils.convertList;
|
||||
|
||||
/**
|
||||
* 用户管理链路 Controller
|
||||
@@ -43,6 +50,9 @@ import static com.njcn.rdms.framework.common.pojo.CommonResult.success;
|
||||
@Validated
|
||||
public class UserManagementRelationController {
|
||||
|
||||
@Resource
|
||||
private DeptService deptService;
|
||||
|
||||
@Resource
|
||||
private UserManagementRelationService userManagementRelationService;
|
||||
|
||||
@@ -147,6 +157,19 @@ public class UserManagementRelationController {
|
||||
return success(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取未绑定直属上级的候选下级用户列表
|
||||
* @return 候选下级用户列表
|
||||
*/
|
||||
@GetMapping("/candidate-users")
|
||||
@Operation(summary = "获取未绑定直属上级的候选下级用户列表")
|
||||
@PreAuthorize("@ss.hasPermission('system:user-management-relation:query')")
|
||||
public CommonResult<List<UserSimpleRespVO>> getCandidateSubordinateUsers() {
|
||||
List<AdminUserDO> users = userManagementRelationService.getCandidateSubordinateUsers();
|
||||
Map<Long, DeptDO> deptMap = deptService.getDeptMap(convertList(users, AdminUserDO::getDeptId));
|
||||
return success(UserConvert.INSTANCE.convertSimpleList(users, deptMap));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户管理链路树形结构
|
||||
*
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.njcn.rdms.framework.common.util.collection.CollectionUtils;
|
||||
import com.njcn.rdms.module.system.controller.admin.user.vo.userManagementRelation.UserManagementRelationQueryReqVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.user.vo.userManagementRelation.UserManagementRelationSaveReqVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.user.vo.userManagementRelation.UserManagementRelationTreeRespVO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.user.AdminUserDO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.user.UserManagementRelationDO;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -99,6 +100,13 @@ public interface UserManagementRelationService {
|
||||
*/
|
||||
List<UserManagementRelationTreeRespVO> getRelationTree(UserManagementRelationQueryReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 获取还未绑定直属上级的候选下级用户列表
|
||||
*
|
||||
* @return 候选下级用户列表
|
||||
*/
|
||||
List<AdminUserDO> getCandidateSubordinateUsers();
|
||||
|
||||
/**
|
||||
* 获得用户管理链路 Map
|
||||
*
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.njcn.rdms.module.system.service.user;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.njcn.rdms.framework.common.enums.CommonStatusEnum;
|
||||
import com.njcn.rdms.framework.common.exception.ServiceException;
|
||||
import com.njcn.rdms.framework.common.util.object.BeanUtils;
|
||||
import com.njcn.rdms.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
@@ -243,7 +244,7 @@ public class UserManagementRelationServiceImpl implements UserManagementRelation
|
||||
|
||||
Long targetUserId = determineTargetUserId(reqVO, context);
|
||||
if (targetUserId == null) {
|
||||
return buildFullTree(context);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return buildTargetBranchTree(targetUserId, context);
|
||||
@@ -272,6 +273,32 @@ public class UserManagementRelationServiceImpl implements UserManagementRelation
|
||||
return userManagementRelationMapper.selectListBySubordinateUserId(subordinateUserId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取候选的下属用户列表
|
||||
* @return 候选的下属用户列表
|
||||
*/
|
||||
@Override
|
||||
public List<AdminUserDO> getCandidateSubordinateUsers() {
|
||||
List<AdminUserDO> users = adminUserService.getUserListByStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
if (CollUtil.isEmpty(users)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<UserManagementRelationDO> relations =
|
||||
userManagementRelationMapper.selectList(new UserManagementRelationQueryReqVO());
|
||||
Set<Long> boundSubordinateUserIds = relations.stream()
|
||||
.map(UserManagementRelationDO::getSubordinateUserId)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
return users.stream()
|
||||
.filter(adminUserService::isUserAvailable)
|
||||
.filter(user -> !boundSubordinateUserIds.contains(user.getId()))
|
||||
.sorted(Comparator.comparing(AdminUserDO::getDeptId, Comparator.nullsLast(Long::compareTo))
|
||||
.thenComparing(AdminUserDO::getNickname, Comparator.nullsLast(String::compareTo))
|
||||
.thenComparing(AdminUserDO::getId))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户管理链路树形结构
|
||||
* 业务逻辑:
|
||||
@@ -402,112 +429,50 @@ public class UserManagementRelationServiceImpl implements UserManagementRelation
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建目标用户相关的分支树形结构
|
||||
* 只包含目标用户的上级链和下级树,不包含同级节点
|
||||
* 构建目标用户相关的分支树形结构(搜索模式)
|
||||
* 只包含目标用户的上级链和目标用户本身,不显示下级
|
||||
* <p>
|
||||
* 构建逻辑:
|
||||
* 1. 从目标用户向上追溯到根节点,记录上级链
|
||||
* 2. 从根节点开始,只沿着包含目标用户的分支向下构建
|
||||
* 3. 构建目标用户的所有下级
|
||||
* 3. 目标用户节点不构建下级
|
||||
*
|
||||
* @param targetUserId 目标用户ID
|
||||
* @param context 树形结构上下文
|
||||
* @return 目标用户相关的分支树形结构列表
|
||||
*/
|
||||
private List<UserManagementRelationTreeRespVO> buildTargetBranchTree(Long targetUserId, TreeBuildContext context) {
|
||||
LinkedList<Long> pathToRoot = findPathToRoot(targetUserId, context);
|
||||
if (pathToRoot.isEmpty()) {
|
||||
AdminUserDO targetUser = context.getUserMap().get(targetUserId);
|
||||
if (targetUser == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
Long rootUserId = pathToRoot.getFirst();
|
||||
UserManagementRelationTreeRespVO rootNode = buildRootNode(rootUserId, context);
|
||||
if (rootNode == null) {
|
||||
UserManagementRelationDO targetRelation = context.getSubordinateToRelationMap().get(targetUserId);
|
||||
Long targetRelationId = targetRelation != null ? targetRelation.getId() : null;
|
||||
if (targetRelation == null || Objects.equals(targetRelation.getManagerUserId(), targetUserId)) {
|
||||
// 根节点搜索时只返回本人,不继续展示更高层级
|
||||
UserManagementRelationTreeRespVO targetNode =
|
||||
buildTreeNodeForSearch(targetRelationId, targetUserId, targetUserId, context);
|
||||
return targetNode == null ? Collections.emptyList() : Collections.singletonList(targetNode);
|
||||
}
|
||||
|
||||
Long managerUserId = targetRelation.getManagerUserId();
|
||||
UserManagementRelationDO managerRelation = context.getSubordinateToRelationMap().get(managerUserId);
|
||||
Long managerRelationId = managerRelation != null ? managerRelation.getId() : null;
|
||||
UserManagementRelationTreeRespVO managerNode =
|
||||
buildTreeNodeForSearch(managerRelationId, managerUserId, managerUserId, context);
|
||||
if (managerNode == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
if (pathToRoot.size() > 1) {
|
||||
buildBranchPath(rootNode, pathToRoot, context);
|
||||
UserManagementRelationTreeRespVO targetNode =
|
||||
buildTreeNodeForSearch(targetRelationId, targetUserId, managerUserId, context);
|
||||
if (targetNode == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return Collections.singletonList(rootNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从目标用户向上追溯到根节点,记录路径
|
||||
*
|
||||
* @param targetUserId 目标用户ID
|
||||
* @param context 树形结构上下文
|
||||
* @return 从根节点到目标用户的路径(包含根节点和目标用户)
|
||||
*/
|
||||
private LinkedList<Long> findPathToRoot(Long targetUserId, TreeBuildContext context) {
|
||||
LinkedList<Long> path = new LinkedList<>();
|
||||
Set<Long> visited = new HashSet<>();
|
||||
Long currentUserId = targetUserId;
|
||||
|
||||
while (currentUserId != null && !visited.contains(currentUserId)) {
|
||||
visited.add(currentUserId);
|
||||
path.addFirst(currentUserId);
|
||||
|
||||
if (!context.getHasManagerUserIds().contains(currentUserId)) {
|
||||
break;
|
||||
}
|
||||
|
||||
UserManagementRelationDO relation = context.getSubordinateToRelationMap().get(currentUserId);
|
||||
if (relation == null) {
|
||||
break;
|
||||
}
|
||||
|
||||
Long managerUserId = relation.getManagerUserId();
|
||||
if (managerUserId.equals(currentUserId)) {
|
||||
break;
|
||||
}
|
||||
currentUserId = managerUserId;
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* 沿着指定路径构建分支
|
||||
* 从根节点的下一层开始,只构建路径中包含的用户节点
|
||||
*
|
||||
* @param parentNode 父节点
|
||||
* @param pathToRoot 从根节点到目标用户的路径
|
||||
* @param context 树形结构上下文
|
||||
*/
|
||||
private void buildBranchPath(UserManagementRelationTreeRespVO parentNode, LinkedList<Long> pathToRoot, TreeBuildContext context) {
|
||||
if (pathToRoot.size() <= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
Long parentUserId = parentNode.getUserId();
|
||||
List<Long> subordinateIds = context.getManagerToSubordinatesMap().get(parentUserId);
|
||||
if (CollUtil.isEmpty(subordinateIds)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Long nextUserIdInPath = pathToRoot.get(1);
|
||||
for (Long subordinateId : subordinateIds) {
|
||||
if (subordinateId.equals(parentUserId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
UserManagementRelationDO childRelation = context.getSubordinateToRelationMap().get(subordinateId);
|
||||
Long childRelationId = childRelation != null ? childRelation.getId() : null;
|
||||
|
||||
if (subordinateId.equals(nextUserIdInPath)) {
|
||||
UserManagementRelationTreeRespVO childNode = buildTreeNode(childRelationId, subordinateId, parentUserId, context);
|
||||
if (childNode != null) {
|
||||
parentNode.setChildren(Collections.singletonList(childNode));
|
||||
if (pathToRoot.size() > 2) {
|
||||
LinkedList<Long> remainingPath = new LinkedList<>(pathToRoot.subList(1, pathToRoot.size()));
|
||||
buildBranchPath(childNode, remainingPath, context);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
managerNode.setChildren(Collections.singletonList(targetNode));
|
||||
return Collections.singletonList(managerNode);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -611,6 +576,40 @@ public class UserManagementRelationServiceImpl implements UserManagementRelation
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建树形节点(搜索模式)
|
||||
* 与buildTreeNode的区别:不构建下级节点,只返回当前节点信息
|
||||
*
|
||||
* @param relationId 关系记录主键ID
|
||||
* @param userId 当前用户ID
|
||||
* @param managerUserId 上级用户ID
|
||||
* @param context 树形结构上下文
|
||||
* @return 树形节点(无下级)
|
||||
*/
|
||||
private UserManagementRelationTreeRespVO buildTreeNodeForSearch(Long relationId, Long userId, Long managerUserId,
|
||||
TreeBuildContext context) {
|
||||
AdminUserDO user = context.getUserMap().get(userId);
|
||||
if (user == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
UserManagementRelationTreeRespVO node = new UserManagementRelationTreeRespVO();
|
||||
node.setId(relationId);
|
||||
node.setUserId(userId);
|
||||
node.setUserNickname(user.getNickname());
|
||||
node.setManagerUserId(managerUserId);
|
||||
|
||||
if (managerUserId != null) {
|
||||
AdminUserDO managerUser = context.getUserMap().get(managerUserId);
|
||||
if (managerUser != null) {
|
||||
node.setManagerNickname(managerUser.getNickname());
|
||||
}
|
||||
}
|
||||
|
||||
node.setChildren(Collections.emptyList());
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* 统一时间有效性过滤条件:
|
||||
* <p>
|
||||
|
||||
Reference in New Issue
Block a user