20260804223152

This commit is contained in:
oneao committed 2026-08-04 22:31:52 +08:00
1 parent 75b1ccaa6d
commit 7c9761a4fc
71 files changed
+5534 -9113

No files matched your search

+94 -119
View File
@@ -1,82 +1,83 @@
import { computed, ref, watch } from "vue";
import { defineStore } from "pinia";
import { loadDataApi } from "@/services/api";
import { hasPageComponent } from "@/router/pageComponents";
import { useAuthStore } from "./auth";
export const usePermissionStore = defineStore("permissions", () => {
const authStore = useAuthStore();
const loadedPrincipalKey = ref("");
const modules = ref([]);
const functionNodes = ref([]);
const pageNodes = ref([]);
const actions = ref([]);
const grantedFunctionNodeIds = ref([]);
const grantedPageNodeIds = ref([]);
const grantedActionIds = ref([]);
const grantedPageIds = ref([]);
const moduleCodes = ref([]);
const powerCodes = ref([]);
let loadingPromise = null;
let loadingPrincipalKey = "";
let loadVersion = 0;
const functionNodeById = computed(
() => new Map(functionNodes.value.map((node) => [String(node.b_id), node])),
const moduleByCode = computed(
() => new Map(modules.value.map((module) => [String(module.b_code || ""), module])),
);
const grantedFunctionSet = computed(() => new Set(grantedFunctionNodeIds.value));
const grantedPageSet = computed(() => new Set(grantedPageNodeIds.value));
const grantedActionSet = computed(() => new Set(grantedActionIds.value));
const isSystemUser = computed(
() => String(authStore.user?.account || "").toLowerCase() === "g3soft",
const moduleById = computed(
() => new Map(modules.value.map((module) => [String(module.b_id || ""), module])),
);
const grantedPageSet = computed(() => new Set(grantedPageIds.value));
const powerSet = computed(() => new Set(powerCodes.value));
const isG3soft = computed(() => {
return (
String(authStore.user?.account || "")
.trim()
.toLowerCase() === "g3soft"
);
});
async function load() {
const userId = String(authStore.user?.id || "");
if (!/^\d+$/.test(userId)) throw new Error("登录用户 ID 无效,请重新登录");
const principalKey = `${String(authStore.orgId || "")}:${userId}`;
if (isG3soft.value) {
const elevatedKey = `g3soft:${principalKey}`;
if (loadedPrincipalKey.value === elevatedKey) return;
loadVersion++;
loadingPromise = null;
loadingPrincipalKey = "";
loadedPrincipalKey.value = elevatedKey;
modules.value = [];
grantedPageIds.value = [];
moduleCodes.value = [];
powerCodes.value = [];
return;
}
if (!/^\d+$/.test(userId)) throw new Error("登录用户 ID 无效,请重新登录");
if (loadedPrincipalKey.value === principalKey) return;
if (loadingPromise && loadingPrincipalKey === principalKey) return loadingPromise;
const requestVersion = ++loadVersion;
loadingPrincipalKey = principalKey;
const request = Promise.all([
loadDataApi("v_s_module_runtime", "b_canuse = 1", "b_module_id ASC, b_profile_id ASC"),
loadDataApi("v_s_function_node", "b_canuse = 1", "b_xh ASC, b_id ASC"),
loadDataApi("v_s_page_node", "b_canuse = 1", "b_xh ASC, b_id ASC"),
loadDataApi("v_s_module_action", "b_canuse = 1", "b_xh ASC, b_id ASC"),
loadDataApi(
"v_s_user_function_permission",
`b_user_id = ${userId}`,
"b_function_node_id ASC",
),
loadDataApi("v_s_user_page_permission", `b_user_id = ${userId}`, "b_page_node_id ASC"),
loadDataApi("v_s_user_action_permission", `b_user_id = ${userId}`, "b_action_id ASC"),
loadDataApi("s_module", "b_canuse = 1", "b_id ASC"),
loadDataApi("b_user_module", `b_user_id = ${userId}`, "b_id ASC"),
loadDataApi("b_user_power", `b_user_id = ${userId}`, "b_id ASC"),
loadDataApi("s_module_power", "b_canuse = 1", "b_id ASC"),
])
.then(
([
moduleResponse,
functionResponse,
pageResponse,
actionResponse,
functionGrants,
pageGrants,
actionGrants,
]) => {
if (requestVersion !== loadVersion) return;
modules.value = moduleResponse.data || [];
functionNodes.value = functionResponse.data || [];
pageNodes.value = pageResponse.data || [];
actions.value = actionResponse.data || [];
grantedFunctionNodeIds.value = (functionGrants.data || []).map((item) =>
String(item.b_function_node_id),
);
grantedPageNodeIds.value = (pageGrants.data || []).map((item) =>
String(item.b_page_node_id),
);
grantedActionIds.value = (actionGrants.data || []).map((item) =>
String(item.b_action_id),
);
loadedPrincipalKey.value = principalKey;
},
)
.then(([moduleResponse, userModules, userPowers, powers]) => {
if (requestVersion !== loadVersion) return;
const activeModules = moduleResponse.data || [];
const moduleById = new Map(activeModules.map((module) => [String(module.b_id), module]));
const powerById = new Map(powers.data.map((power) => [String(power.b_id), power]));
const pageIds = userModules.data
.map((item) => String(item.b_module_id || ""))
.filter(Boolean);
modules.value = activeModules;
grantedPageIds.value = pageIds;
moduleCodes.value = userModules.data
.map((item) => moduleById.get(String(item.b_module_id))?.b_code)
.filter(Boolean);
powerCodes.value = userPowers.data
.map((item) => powerById.get(String(item.b_power_id)))
.filter(Boolean)
.map((power) => `${String(power.b_module_id)}.${power.b_code}`)
.filter(Boolean);
loadedPrincipalKey.value = principalKey;
})
.finally(() => {
if (requestVersion !== loadVersion) return;
loadingPromise = null;
@@ -86,58 +87,39 @@ export const usePermissionStore = defineStore("permissions", () => {
return request;
}
function hasGrantedDescendant(nodeId) {
const ancestorIds = new Set();
for (const grantedId of grantedFunctionSet.value) {
let current = functionNodeById.value.get(grantedId);
while (current?.b_parent_id != null) {
const parentId = String(current.b_parent_id);
ancestorIds.add(parentId);
current = functionNodeById.value.get(parentId);
}
function resolvePageId(code) {
let module = moduleByCode.value.get(String(code || ""));
const visited = new Set();
while (module) {
const moduleId = String(module.b_id || "");
if (!moduleId || visited.has(moduleId)) return "";
visited.add(moduleId);
if (module.b_module_type === "page") return moduleId;
const parentId = String(module.b_parent_id || "");
module = parentId ? moduleById.value.get(parentId) : null;
}
return ancestorIds.has(String(nodeId));
return "";
}
function canAccessFunctionNode(nodeId) {
const id = String(nodeId || "");
if (!id) return false;
const node = functionNodeById.value.get(id);
if (!node) return false;
if (isSystemUser.value) {
if (node.b_node_type === "directory") return true;
if (node.b_page_mode === "custom" && !hasPageComponent(node.b_component_key)) return false;
return true;
}
if (node.b_node_type === "directory") return hasGrantedDescendant(id);
if (node.b_page_mode === "custom" && !hasPageComponent(node.b_component_key)) return false;
return grantedFunctionSet.value.has(id);
function canAccess(moduleCode) {
if (isG3soft.value || !moduleCode) return true;
const module = moduleByCode.value.get(String(moduleCode));
if (!module) return false;
const moduleId = String(module.b_id || "");
const pageId = resolvePageId(moduleCode);
return grantedPageSet.value.has(moduleId) || (!!pageId && grantedPageSet.value.has(pageId));
}
function canAccessRoute(path) {
if (path === "/dashboard") return true;
if (isSystemUser.value) return true;
const node = functionNodes.value.find(
(item) => item.b_node_type === "entry" && String(item.b_route || "") === String(path || ""),
function canPower(scopeCode, powerCode) {
if (isG3soft.value) return true;
const module = moduleByCode.value.get(String(scopeCode || ""));
if (!module || !canAccess(scopeCode)) return false;
const moduleId = String(module.b_id || "");
const pageId = resolvePageId(scopeCode);
return (
powerSet.value.has(`${moduleId}.${powerCode}`) ||
(!!pageId && powerSet.value.has(`${pageId}.${powerCode}`))
);
return node ? canAccessFunctionNode(node.b_id) : false;
}
function canViewPageNode(nodeId, permissionRequired = true) {
if (!permissionRequired) return true;
if (isSystemUser.value) return true;
return grantedPageSet.value.has(String(nodeId || ""));
}
function canAction(moduleIdOrCode, actionCode) {
if (isSystemUser.value) return true;
const action = actions.value.find(
(item) =>
(String(item.b_module_id) === String(moduleIdOrCode) ||
String(item.b_module_code) === String(moduleIdOrCode)) &&
String(item.b_code) === String(actionCode),
);
return action ? grantedActionSet.value.has(String(action.b_id)) : false;
}
function clear() {
@@ -146,32 +128,25 @@ export const usePermissionStore = defineStore("permissions", () => {
loadingPrincipalKey = "";
loadedPrincipalKey.value = "";
modules.value = [];
functionNodes.value = [];
pageNodes.value = [];
actions.value = [];
grantedFunctionNodeIds.value = [];
grantedPageNodeIds.value = [];
grantedActionIds.value = [];
grantedPageIds.value = [];
moduleCodes.value = [];
powerCodes.value = [];
}
watch(() => [authStore.orgId, authStore.user?.id, authStore.token], clear);
watch(
() => [authStore.orgId, authStore.user?.id, authStore.user?.account, authStore.token],
clear,
);
return {
load,
canAccess,
canPower,
clear,
canAccessFunctionNode,
canAccessRoute,
canViewPageNode,
canAction,
canAccess: canAccessRoute,
canPower: canAction,
isSystemUser,
modules,
functionNodes,
pageNodes,
actions,
grantedFunctionNodeIds,
grantedPageNodeIds,
grantedActionIds,
grantedPageIds,
moduleCodes,
powerCodes,
isG3soft,
};
});