import { defineStore } from 'pinia' import { getOrganizationTreeApi, type OrganizationNode } from '@/api/organization' import { useUserStore } from '@/stores/user' const CACHE_MAX_AGE = 24 * 60 * 60 * 1000 const CACHE_SCHEMA_VERSION = 1 let requestPromise: Promise | null = null /** * 机构树共享缓存。 * * 只持久化精简后的 code/name/children,并按登录账号隔离, * 避免不同账号共用可能存在权限差异的机构数据。 */ export const useOrganizationStore = defineStore( 'organization', () => { const tree = ref([]) const cachedAt = ref(0) const cacheOwner = ref('') const schemaVersion = ref(CACHE_SCHEMA_VERSION) const loading = ref(false) const hasCache = computed(() => tree.value.length > 0) const organizationNameMap = computed(() => { const nameMap = new Map() const nodes = [...tree.value] while (nodes.length) { const node = nodes.pop() if (!node) continue nameMap.set(node.code, node.name) if (node.children?.length) nodes.push(...node.children) } return nameMap }) /** 根据机构号从缓存的机构树中获取机构名称。 */ function getOrganizationName(code?: string) { const organizationCode = code?.trim() return organizationCode ? organizationNameMap.value.get(organizationCode) || '' : '' } async function ensureOrganizationTree(force = false) { const owner = useUserStore().username.trim() if (cacheOwner.value !== owner || schemaVersion.value !== CACHE_SCHEMA_VERSION) { clearOrganizationCache() } const cacheFresh = Date.now() - cachedAt.value < CACHE_MAX_AGE if (!force && hasCache.value && cacheFresh) return tree.value if (requestPromise) return requestPromise loading.value = true requestPromise = getOrganizationTreeApi() .then((result) => { if (!result.length) throw new Error('机构树数据为空') tree.value = result cachedAt.value = Date.now() cacheOwner.value = owner schemaVersion.value = CACHE_SCHEMA_VERSION return tree.value }) .catch((error) => { // 过期缓存仍可作为断网降级数据,首次加载失败则交给页面展示重试。 if (hasCache.value) return tree.value throw error }) .finally(() => { loading.value = false requestPromise = null }) return requestPromise } function refreshOrganizationTree() { return ensureOrganizationTree(true) } function clearOrganizationCache() { tree.value = [] cachedAt.value = 0 cacheOwner.value = '' schemaVersion.value = CACHE_SCHEMA_VERSION } return { tree, cachedAt, cacheOwner, schemaVersion, loading, hasCache, getOrganizationName, ensureOrganizationTree, refreshOrganizationTree, clearOrganizationCache, } }, { persist: { key: 'mini2_organization_cache', pick: ['tree', 'cachedAt', 'cacheOwner', 'schemaVersion'], }, }, )