From 34981c30a78e8bbd7791131059a9210f9928b62c Mon Sep 17 00:00:00 2001
From: 刘光辉 <347230014@qq.com>
Date: 星期四, 17 九月 2026 09:24:09 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master' into master

---
 jnpf-dms/jnpf-dms-biz/src/main/java/jnpf/dmsPermission/DmsResourceResolver.java |  175 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 175 insertions(+), 0 deletions(-)

diff --git a/jnpf-dms/jnpf-dms-biz/src/main/java/jnpf/dmsPermission/DmsResourceResolver.java b/jnpf-dms/jnpf-dms-biz/src/main/java/jnpf/dmsPermission/DmsResourceResolver.java
new file mode 100644
index 0000000..290d90e
--- /dev/null
+++ b/jnpf-dms/jnpf-dms-biz/src/main/java/jnpf/dmsPermission/DmsResourceResolver.java
@@ -0,0 +1,175 @@
+package jnpf.dmsPermission;
+
+import jnpf.dmsEntity.permission.entity.DmsDocumentEntity;
+import jnpf.dmsEntity.permission.entity.DmsFileVersionEntity;
+import jnpf.dmsEntity.permission.entity.DmsPermissionResourceEntity;
+import jnpf.dmsEntity.permission.enums.DmsResourceType;
+import jnpf.dmsEntity.permission.form.PermissionDecisionForm;
+import jnpf.dmsEntity.permission.model.DmsFolderAncestorRow;
+import jnpf.dmsEntity.permission.model.DmsResourcePath;
+import jnpf.dmsMapper.DmsDocumentMapper;
+import jnpf.dmsMapper.DmsFileVersionMapper;
+import jnpf.dmsMapper.DmsFolderMapper;
+import jnpf.dmsMapper.DmsPermissionResourceMapper;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+@Component
+@RequiredArgsConstructor
+public class DmsResourceResolver {
+    private final DmsPermissionResourceMapper resourceMapper;
+    private final DmsFolderMapper folderMapper;
+    private final DmsDocumentMapper documentMapper;
+    private final DmsFileVersionMapper fileVersionMapper;
+
+    public DmsResourcePath resolve(String tenantId, DmsResourceType type, UUID id) {
+        PermissionDecisionForm request = new PermissionDecisionForm();
+        request.setResourceType(type);
+        request.setResourceId(id);
+        return resolveAll(tenantId, Collections.singletonList(request)).get(id);
+    }
+
+    public Map<UUID, DmsResourcePath> resolveAll(String tenantId, List<PermissionDecisionForm> requests) {
+        Set<UUID> allIds = requests.stream().map(PermissionDecisionForm::getResourceId)
+                .collect(Collectors.toCollection(LinkedHashSet::new));
+        Map<UUID, DmsPermissionResourceEntity> registry = byId(
+                resourceMapper.selectByTenantAndIds(tenantId, new ArrayList<>(allIds)),
+                DmsPermissionResourceEntity::getId);
+
+        Map<DmsResourceType, List<UUID>> idsByType = new EnumMap<>(DmsResourceType.class);
+        for (PermissionDecisionForm request : requests) {
+            DmsPermissionResourceEntity registered = registry.get(request.getResourceId());
+            if (registered == null || !request.getResourceType().name().equals(registered.getResourceType())) {
+                throw DmsPermissionException.of(DmsPermissionError.RESOURCE_NOT_FOUND,
+                        "鏉冮檺璧勬簮涓嶅瓨鍦ㄦ垨绫诲瀷涓嶄竴鑷�: " + request.getResourceId());
+            }
+            idsByType.computeIfAbsent(request.getResourceType(), key -> new ArrayList<>())
+                    .add(request.getResourceId());
+        }
+
+        Map<UUID, DmsFileVersionEntity> versions = byId(loadVersions(tenantId,
+                idsByType.get(DmsResourceType.FILE_VERSION)), DmsFileVersionEntity::getId);
+        Set<UUID> documentIds = new LinkedHashSet<>();
+        documentIds.addAll(orEmpty(idsByType.get(DmsResourceType.DOCUMENT)));
+        for (DmsFileVersionEntity version : versions.values()) {
+            documentIds.add(version.getDocumentId());
+        }
+        Map<UUID, DmsDocumentEntity> documents = byId(loadDocuments(tenantId, documentIds),
+                DmsDocumentEntity::getId);
+
+        Set<UUID> startFolderIds = new LinkedHashSet<>();
+        startFolderIds.addAll(orEmpty(idsByType.get(DmsResourceType.FOLDER)));
+        for (DmsDocumentEntity document : documents.values()) {
+            startFolderIds.add(document.getFolderId());
+        }
+        Map<UUID, List<UUID>> folderPaths = loadFolderPaths(tenantId, startFolderIds);
+
+        Map<UUID, DmsResourcePath> result = new LinkedHashMap<>();
+        for (PermissionDecisionForm request : requests) {
+            DmsResourcePath path = new DmsResourcePath();
+            path.setActualResourceId(request.getResourceId());
+            path.setActualResourceType(request.getResourceType().name());
+            if (request.getResourceType() == DmsResourceType.FOLDER) {
+                path.setDirectFolderId(request.getResourceId());
+                path.setFolderPath(requiredFolderPath(folderPaths, request.getResourceId()));
+            } else if (request.getResourceType() == DmsResourceType.DOCUMENT) {
+                DmsDocumentEntity document = requireDocument(documents, request.getResourceId());
+                path.setDocumentId(document.getId());
+                path.setDirectFolderId(document.getFolderId());
+                path.setFolderPath(requiredFolderPath(folderPaths, document.getFolderId()));
+            } else {
+                DmsFileVersionEntity version = versions.get(request.getResourceId());
+                if (version == null) {
+                    throw missingBusinessObject(request.getResourceId());
+                }
+                DmsDocumentEntity document = requireDocument(documents, version.getDocumentId());
+                path.setDocumentId(document.getId());
+                path.setDirectFolderId(document.getFolderId());
+                path.setFolderPath(requiredFolderPath(folderPaths, document.getFolderId()));
+            }
+            result.put(request.getResourceId(), path);
+        }
+        return result;
+    }
+
+    public List<UUID> candidateResourceIds(DmsResourcePath path) {
+        LinkedHashSet<UUID> ids = new LinkedHashSet<>();
+        ids.add(path.getActualResourceId());
+        if (path.getDocumentId() != null) {
+            ids.add(path.getDocumentId());
+        }
+        ids.addAll(path.getFolderPath());
+        return new ArrayList<>(ids);
+    }
+
+    private List<DmsFileVersionEntity> loadVersions(String tenantId, List<UUID> ids) {
+        return ids == null || ids.isEmpty()
+                ? Collections.<DmsFileVersionEntity>emptyList()
+                : fileVersionMapper.selectByTenantAndIds(tenantId, distinct(ids));
+    }
+
+    private List<DmsDocumentEntity> loadDocuments(String tenantId, Set<UUID> ids) {
+        return ids.isEmpty()
+                ? Collections.<DmsDocumentEntity>emptyList()
+                : documentMapper.selectByTenantAndIds(tenantId, new ArrayList<>(ids));
+    }
+
+    private Map<UUID, List<UUID>> loadFolderPaths(String tenantId, Set<UUID> folderIds) {
+        Map<UUID, List<UUID>> result = new LinkedHashMap<>();
+        if (folderIds.isEmpty()) {
+            return result;
+        }
+        List<DmsFolderAncestorRow> rows = folderMapper.selectAncestorRows(tenantId, new ArrayList<>(folderIds));
+        for (DmsFolderAncestorRow row : rows) {
+            result.computeIfAbsent(row.getStartFolderId(), key -> new ArrayList<>())
+                    .add(row.getAncestorFolderId());
+        }
+        return result;
+    }
+
+    private DmsDocumentEntity requireDocument(Map<UUID, DmsDocumentEntity> documents, UUID id) {
+        DmsDocumentEntity document = documents.get(id);
+        if (document == null) {
+            throw missingBusinessObject(id);
+        }
+        return document;
+    }
+
+    private List<UUID> requiredFolderPath(Map<UUID, List<UUID>> paths, UUID folderId) {
+        List<UUID> path = paths.get(folderId);
+        if (path == null || path.isEmpty()) {
+            throw missingBusinessObject(folderId);
+        }
+        return path;
+    }
+
+    private DmsPermissionException missingBusinessObject(UUID id) {
+        return DmsPermissionException.of(DmsPermissionError.RESOURCE_NOT_FOUND,
+                "鏉冮檺鐧昏瀵瑰簲鐨勪笟鍔¤祫婧愪笉瀛樺湪: " + id);
+    }
+
+    private List<UUID> distinct(List<UUID> ids) {
+        return new ArrayList<>(new LinkedHashSet<>(ids));
+    }
+
+    private List<UUID> orEmpty(List<UUID> ids) {
+        return ids == null ? Collections.<UUID>emptyList() : ids;
+    }
+
+    private <T> Map<UUID, T> byId(List<T> values, Function<T, UUID> idGetter) {
+        return values.stream().collect(Collectors.toMap(idGetter, Function.identity(), (left, right) -> left,
+                LinkedHashMap::new));
+    }
+}

--
Gitblit v1.8.0