package jnpf.dmsPermission; import jnpf.dmsEntity.permission.model.DmsSubjectSet; import jnpf.permission.RoleRelationApi; import jnpf.permission.UserApi; import jnpf.permission.UserRelationApi; import jnpf.permission.entity.RoleRelationEntity; import jnpf.permission.entity.UserEntity; import jnpf.permission.entity.UserRelationEntity; import jnpf.permission.model.rolerelaiton.RoleRelationModel; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; @Component @RequiredArgsConstructor public class DmsUserSubjectBatchResolver { private static final String ORGANIZE = "organize"; private static final String POSITION = "position"; private static final String GROUP = "group"; private static final String USER = "user"; private final UserApi userApi; private final UserRelationApi userRelationApi; private final RoleRelationApi roleRelationApi; private final DmsSubjectHierarchyResolver hierarchyResolver; public List resolve(String tenantId, List normalizedUserIds) { String normalizedTenantId = trimToNull(tenantId); if (normalizedTenantId == null) { throw invalidRequest("租户标识不能为空"); } List userIds = normalizeUserIds(normalizedUserIds); validateUsers(normalizedTenantId, userIds); Map subjectsByUserId = new LinkedHashMap<>(); for (String userId : userIds) { DmsSubjectSet subjects = new DmsSubjectSet(); subjects.setUserId(userId); subjectsByUserId.put(userId, subjects); } applyUserRelations(subjectsByUserId, userRelationApi.getListByUserIdAll(userIds)); hierarchyResolver.resolveStrict(subjectsByUserId.values()); applyRoles(subjectsByUserId); return new ArrayList<>(subjectsByUserId.values()); } private List normalizeUserIds(List normalizedUserIds) { if (normalizedUserIds == null || normalizedUserIds.isEmpty()) { throw invalidRequest("用户列表不能为空"); } Set uniqueUserIds = new LinkedHashSet<>(); for (String userId : normalizedUserIds) { String normalized = trimToNull(userId); if (normalized == null) { throw invalidRequest("用户标识不能为空"); } uniqueUserIds.add(normalized); } return new ArrayList<>(uniqueUserIds); } private void validateUsers(String tenantId, List userIds) { List users = userApi.getUserName(userIds); Set found = new LinkedHashSet<>(); if (users != null) { for (UserEntity user : users) { if (user == null) { continue; } String userId = trimToNull(user.getId()); String userTenantId = trimToNull(user.getTenantId()); if (userId != null && userIds.contains(userId) && tenantId.equals(userTenantId)) { found.add(userId); } } } Set missing = new LinkedHashSet<>(userIds); missing.removeAll(found); if (!missing.isEmpty()) { throw DmsPermissionException.of(DmsPermissionError.PRINCIPAL_NOT_FOUND, "USER 主体不存在、不属于当前租户或主体服务不可用: " + missing); } } private void applyUserRelations(Map subjectsByUserId, List relations) { if (relations == null) { return; } for (UserRelationEntity relation : relations) { if (relation == null) { continue; } DmsSubjectSet subjects = subjectsByUserId.get(trimToNull(relation.getUserId())); String objectId = trimToNull(relation.getObjectId()); String objectType = trimToNull(relation.getObjectType()); if (subjects == null || objectId == null || objectType == null) { continue; } if (ORGANIZE.equalsIgnoreCase(objectType)) { subjects.getDirectOrgIds().add(objectId); } else if (POSITION.equalsIgnoreCase(objectType)) { subjects.getPositionIds().add(objectId); } else if (GROUP.equalsIgnoreCase(objectType)) { subjects.getPlatformGroupIds().add(objectId); } } } private void applyRoles(Map subjectsByUserId) { Map> userIdsByObjectId = new LinkedHashMap<>(); for (DmsSubjectSet subject : subjectsByUserId.values()) { addRoleTarget(userIdsByObjectId, subject.getUserId(), subject.getUserId()); addRoleTargets(userIdsByObjectId, subject.getDirectOrgIds(), subject.getUserId()); addRoleTargets(userIdsByObjectId, subject.getPositionIds(), subject.getUserId()); } RoleRelationModel request = new RoleRelationModel( new ArrayList<>(userIdsByObjectId.keySet()), null); List relations = roleRelationApi.getListByObjectId(request); if (relations == null) { return; } for (RoleRelationEntity relation : relations) { if (relation == null) { continue; } String objectId = trimToNull(relation.getObjectId()); String roleId = trimToNull(relation.getRoleId()); String objectType = trimToNull(relation.getObjectType()); if (objectId == null || roleId == null) { continue; } for (String userId : userIdsByObjectId.getOrDefault(objectId, Collections.emptySet())) { DmsSubjectSet subjects = subjectsByUserId.get(userId); subjects.getRoleIds().add(roleId); if (userId.equals(objectId) && USER.equalsIgnoreCase(objectType)) { subjects.getDirectUserRoleIds().add(roleId); } } } } private void addRoleTargets(Map> userIdsByObjectId, Collection objectIds, String userId) { for (String objectId : objectIds) { addRoleTarget(userIdsByObjectId, objectId, userId); } } private void addRoleTarget(Map> userIdsByObjectId, String objectId, String userId) { String normalized = trimToNull(objectId); if (normalized != null) { userIdsByObjectId.computeIfAbsent(normalized, key -> new LinkedHashSet<>()).add(userId); } } private DmsPermissionException invalidRequest(String message) { return DmsPermissionException.of(DmsPermissionError.INVALID_REQUEST, message); } private String trimToNull(String value) { return value == null || value.trim().isEmpty() ? null : value.trim(); } }