import { computed, ref, watch } from "vue"; import { defineStore } from "pinia"; import { loadDataApi } from "@/services/api"; import { useAuthStore } from "./auth"; export const usePermissionStore = defineStore("permissions", () => { const authStore = useAuthStore(); const loadedPrincipalKey = ref(""); const modules = ref([]); const grantedPageIds = ref([]); const moduleCodes = ref([]); const powerCodes = ref([]); let loadingPromise = null; let loadingPrincipalKey = ""; let loadVersion = 0; const moduleByCode = computed( () => new Map(modules.value.map((module) => [String(module.b_code || ""), module])), ); 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 || ""); 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("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, 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; loadingPrincipalKey = ""; }); loadingPromise = request; return request; } 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 ""; } 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 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}`)) ); } function clear() { loadVersion++; loadingPromise = null; loadingPrincipalKey = ""; loadedPrincipalKey.value = ""; modules.value = []; grantedPageIds.value = []; moduleCodes.value = []; powerCodes.value = []; } watch( () => [authStore.orgId, authStore.user?.id, authStore.user?.account, authStore.token], clear, ); return { load, canAccess, canPower, clear, modules, grantedPageIds, moduleCodes, powerCodes, isG3soft, }; });