Files
2026-11-03 11:13:59 +08:00

102 lines
3.5 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 子系统数据获取(共享逻辑)
*
* 三个子系统页面(概览 / 功能 / 待办)都需要:
* 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<string>} 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 }
}