package jnpf.dmsPermission;
|
|
import jnpf.dmsEntity.permission.model.DmsSubjectSet;
|
import jnpf.permission.OrganizeApi;
|
import jnpf.permission.PositionApi;
|
import jnpf.permission.entity.OrganizeEntity;
|
import jnpf.permission.entity.PositionEntity;
|
import lombok.RequiredArgsConstructor;
|
import org.springframework.stereotype.Component;
|
|
import java.util.ArrayList;
|
import java.util.Collection;
|
import java.util.LinkedHashMap;
|
import java.util.LinkedHashSet;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.Set;
|
|
@Component
|
@RequiredArgsConstructor
|
public class DmsSubjectHierarchyResolver {
|
private static final String ROOT_PARENT_ID = "-1";
|
private static final String LEGACY_ROOT_PARENT_ID = "0";
|
|
private final OrganizeApi organizeApi;
|
private final PositionApi positionApi;
|
|
public void resolve(Collection<DmsSubjectSet> subjects) {
|
resolve(subjects, false);
|
}
|
|
public void resolveStrict(Collection<DmsSubjectSet> subjects) {
|
resolve(subjects, true);
|
}
|
|
private void resolve(Collection<DmsSubjectSet> subjects, boolean strict) {
|
if (subjects == null || subjects.isEmpty()) {
|
return;
|
}
|
resolvePositions(subjects, strict);
|
resolveOrganizations(subjects, strict);
|
}
|
|
private void resolveOrganizations(Collection<DmsSubjectSet> subjects, boolean strict) {
|
Set<String> directIds = collectDirectIds(subjects, true);
|
if (directIds.isEmpty()) {
|
return;
|
}
|
for (DmsSubjectSet subject : subjects) {
|
if (subject != null) {
|
subject.getAncestorOrgIds().addAll(subject.getDirectOrgIds());
|
}
|
}
|
|
Map<String, OrganizeEntity> entitiesById = new LinkedHashMap<>();
|
List<OrganizeEntity> entities = organizeApi.getListByIds(new ArrayList<>(directIds));
|
if (entities != null) {
|
for (OrganizeEntity entity : entities) {
|
String id = entity == null ? null : normalizeId(entity.getId());
|
if (id != null && directIds.contains(id)) {
|
entitiesById.putIfAbsent(id, entity);
|
}
|
}
|
}
|
rejectMissing(directIds, entitiesById.keySet(), "直属组织", strict);
|
|
for (DmsSubjectSet subject : subjects) {
|
if (subject == null) {
|
continue;
|
}
|
for (String directId : subject.getDirectOrgIds()) {
|
OrganizeEntity entity = entitiesById.get(directId);
|
if (entity == null) {
|
continue;
|
}
|
List<String> hierarchy = parseHierarchy(entity.getOrganizeIdTree(), directId);
|
subject.getAncestorOrgIds().addAll(hierarchy);
|
addImmediateParent(subject.getImmediateParentOrgIds(), subject.getAncestorOrgIds(),
|
entity.getParentId(), hierarchy, directId);
|
}
|
}
|
}
|
|
private void resolvePositions(Collection<DmsSubjectSet> subjects, boolean strict) {
|
Set<String> directIds = collectDirectIds(subjects, false);
|
if (directIds.isEmpty()) {
|
return;
|
}
|
for (DmsSubjectSet subject : subjects) {
|
if (subject != null) {
|
subject.getAncestorPositionIds().addAll(subject.getPositionIds());
|
}
|
}
|
|
Map<String, PositionEntity> entitiesById = new LinkedHashMap<>();
|
List<PositionEntity> entities = positionApi.getListByIds(new ArrayList<>(directIds));
|
if (entities != null) {
|
for (PositionEntity entity : entities) {
|
String id = entity == null ? null : normalizeId(entity.getId());
|
if (id != null && directIds.contains(id)) {
|
entitiesById.putIfAbsent(id, entity);
|
}
|
}
|
}
|
rejectMissing(directIds, entitiesById.keySet(), "直属岗位", strict);
|
|
for (DmsSubjectSet subject : subjects) {
|
if (subject == null) {
|
continue;
|
}
|
for (String directId : subject.getPositionIds()) {
|
PositionEntity entity = entitiesById.get(directId);
|
if (entity == null) {
|
continue;
|
}
|
String organizationId = normalizeId(entity.getOrganizeId());
|
if (organizationId != null) {
|
subject.getDirectOrgIds().add(organizationId);
|
}
|
List<String> hierarchy = parseHierarchy(entity.getPositionIdTree(), directId);
|
subject.getAncestorPositionIds().addAll(hierarchy);
|
addImmediateParent(subject.getImmediateParentPositionIds(),
|
subject.getAncestorPositionIds(), entity.getParentId(), hierarchy, directId);
|
}
|
}
|
}
|
|
private Set<String> collectDirectIds(Collection<DmsSubjectSet> subjects, boolean organization) {
|
Set<String> directIds = new LinkedHashSet<>();
|
for (DmsSubjectSet subject : subjects) {
|
if (subject == null) {
|
continue;
|
}
|
Set<String> source = organization ? subject.getDirectOrgIds() : subject.getPositionIds();
|
Set<String> normalized = new LinkedHashSet<>();
|
if (source != null) {
|
for (String id : source) {
|
String value = normalizeId(id);
|
if (value != null) {
|
normalized.add(value);
|
}
|
}
|
source.clear();
|
source.addAll(normalized);
|
}
|
directIds.addAll(normalized);
|
}
|
return directIds;
|
}
|
|
private List<String> parseHierarchy(String idTree, String directId) {
|
Set<String> hierarchy = new LinkedHashSet<>();
|
if (idTree != null) {
|
for (String id : idTree.split(",")) {
|
String value = normalizeId(id);
|
if (value != null) {
|
hierarchy.add(value);
|
}
|
}
|
}
|
hierarchy.add(directId);
|
return new ArrayList<>(hierarchy);
|
}
|
|
private void addImmediateParent(Set<String> parentIds, Set<String> ancestorIds,
|
String entityParentId, List<String> hierarchy, String directId) {
|
String parentId = normalizeId(entityParentId);
|
if (parentId == null) {
|
int directIndex = hierarchy.indexOf(directId);
|
if (directIndex > 0) {
|
parentId = hierarchy.get(directIndex - 1);
|
}
|
}
|
if (parentId != null && !parentId.equals(directId)) {
|
parentIds.add(parentId);
|
ancestorIds.add(parentId);
|
}
|
}
|
|
private void rejectMissing(Set<String> requestedIds, Set<String> foundIds, String subjectType,
|
boolean strict) {
|
Set<String> missingIds = new LinkedHashSet<>(requestedIds);
|
missingIds.removeAll(foundIds);
|
if (strict && !missingIds.isEmpty()) {
|
throw DmsPermissionException.of(DmsPermissionError.PRINCIPAL_NOT_FOUND,
|
subjectType + "主体不存在或主体服务不可用: " + missingIds);
|
}
|
}
|
|
private String normalizeId(String id) {
|
if (id == null) {
|
return null;
|
}
|
String value = id.trim();
|
return value.isEmpty() || ROOT_PARENT_ID.equals(value) || LEGACY_ROOT_PARENT_ID.equals(value)
|
? null : value;
|
}
|
}
|