153 lines
5.2 KiB
JavaScript
153 lines
5.2 KiB
JavaScript
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,
|
|
};
|
|
});
|