/** * 子系统数据获取(共享逻辑) * * 三个子系统页面(概览 / 功能 / 待办)都需要: * 1. 该子系统的配置(config/subsystems.js) * 2. 该子系统下的菜单(/api/home → menus 按 module 归组) * 这里统一封装,避免三个页面各写一遍。 */ import { ref, computed } from 'vue' import { fetchHome, fetchPublicMenus } from '@/api/workspace.js' import { isLoggedIn } from '@/utils/auth.js' import { getSubsystem } from '@/config/subsystems.js' /** * 游客(未登录)菜单源:公开接口 /api/menus/public(菜单级 require_login=0)。 * 免登录控制按菜单粒度在 Platform 菜单管理配置,后端下发什么游客就能用什么; * 多个 Sub 组件共享一次拉取(会话级缓存,失败不缓存以便重试)。 */ let guestMenusPromise = null function loadGuestMenus() { if (!guestMenusPromise) { guestMenusPromise = fetchPublicMenus() .then((list) => (Array.isArray(list) ? list : [])) .catch((e) => { guestMenusPromise = null console.error('[subsystem] public menus failed:', e) return [] }) } return guestMenusPromise } /** * @param {string} slug 子系统目录名(crm / erp / oa / cms / tools) * @param {import('vue').Ref} currentTab 当前 tab,用于按需拉数据 */ export function useSubsystem(slug) { const sub = getSubsystem(slug) const loading = ref(true) const loadError = ref('') const user = ref({}) const menus = ref([]) const moduleMeta = ref(null) // 用户自定义「常用功能」菜单 ID(有序);为空表示未自定义,前端回落默认 const quickMenuIds = ref([]) /** 该子系统下所有菜单(含目录);小程序端不支持的功能在此隐藏 */ const MP_HIDDEN_TITLES = ['文档图谱'] const allMenus = computed(() => menus.value.filter( (m) => m.module === sub.module && !MP_HIDDEN_TITLES.includes(String(m.title || '').trim()) ) ) /** 可直接跳转的叶子菜单,未开通/锁定的排除 */ const leafMenus = computed(() => allMenus.value.filter((m) => m.leaf !== false && !m.locked) ) /** 目录(有下级,不能直接跳) */ const dirMenus = computed(() => allMenus.value.filter((m) => m.leaf === false)) /** 是否已被租户套餐开通 */ const enabled = ref(true) async function load(force = false) { loading.value = true // 游客(未登录)不拉需鉴权的 /api/home,避免 401 触发登出回环; // 改用公开菜单接口,按 module 归组后渲染免登录入口(菜单级 require_login 控制)。 if (!isLoggedIn()) { try { menus.value = await loadGuestMenus() } catch (e) { menus.value = [] } loading.value = false return } try { const data = await fetchHome(force) user.value = data.user || {} menus.value = Array.isArray(data.menus) ? data.menus : [] quickMenuIds.value = Array.isArray(data.quick_menu_ids) ? data.quick_menu_ids : [] const hit = (Array.isArray(data.modules) ? data.modules : []).find( (m) => String(m.code || '').toLowerCase() === String(sub.module).toLowerCase() ) moduleMeta.value = hit || null enabled.value = hit ? hit.enabled !== false : true loadError.value = '' } catch (e) { console.error('[subsystem] load failed:', e) loadError.value = (e && e.message) || '接口请求失败' } finally { loading.value = false } } return { sub, loading, loadError, user, menus, moduleMeta, enabled, allMenus, leafMenus, dirMenus, quickMenuIds, load } }