初始化

This commit is contained in:
2026-03-03 09:53:54 +08:00
commit 3f349a35a4
437 changed files with 65639 additions and 0 deletions

View File

@@ -0,0 +1,10 @@
/**
* 路由和导航相关工具函数统一导出
*
* @module utils/navigation/index
* @author Art Design Pro Team
*/
export * from './jump'
export * from './worktab'
export * from './route'

View File

@@ -0,0 +1,62 @@
/**
* 导航跳转工具模块
*
* 提供统一的页面跳转和导航功能
*
* ## 主要功能
*
* - 外部链接打开(新窗口)
* - 菜单项跳转处理(支持内部路由和外部链接)
* - iframe 页面跳转支持
* - 递归查找并跳转到第一个可见的子菜单
* - 智能判断跳转目标类型(外部链接/内部路由)
*
* @module utils/navigation/jump
* @author Art Design Pro Team
*/
import { AppRouteRecord } from '@/types/router'
import { router } from '@/router'
// 打开外部链接
export const openExternalLink = (link: string) => {
window.open(link, '_blank')
}
/**
* 菜单跳转
* @param item 菜单项
* @param jumpToFirst 是否跳转到第一个子菜单
* @returns
*/
export const handleMenuJump = (item: AppRouteRecord, jumpToFirst: boolean = false) => {
// 处理外部链接
const { link, isIframe } = item.meta
if (link && !isIframe) {
return openExternalLink(link)
}
// 如果不需要跳转到第一个子菜单,或者没有子菜单,直接跳转当前路径
if (!jumpToFirst || !item.children?.length) {
return router.push(item.path)
}
// 递归查找第一个可见的叶子节点菜单
const findFirstLeafMenu = (items: AppRouteRecord[]): AppRouteRecord => {
for (const child of items) {
if (!child.meta.isHide) {
return child.children?.length ? findFirstLeafMenu(child.children) : child
}
}
return items[0]
}
const firstChild = findFirstLeafMenu(item.children)
// 如果第一个子菜单是外部链接则打开新窗口
if (firstChild.meta?.link) {
return openExternalLink(firstChild.meta.link)
}
// 跳转到子菜单路径
router.push(firstChild.path)
}

View File

@@ -0,0 +1,78 @@
/**
* 路由工具模块
*
* 提供路由处理和菜单路径相关的工具函数
*
* ## 主要功能
*
* - iframe 路由检测,判断是否为外部嵌入页面
* - 菜单项有效性验证,过滤隐藏和无效菜单
* - 路径标准化处理,统一路径格式
* - 递归查找菜单树中第一个有效路径
* - 支持多级嵌套菜单的路径解析
*
* ## 使用场景
*
* - 系统初始化时获取默认跳转路径
* - 菜单权限过滤后获取首个可访问页面
* - 路由重定向逻辑处理
* - iframe 页面特殊处理
*
* @module utils/navigation/route
* @author Art Design Pro Team
*/
import { AppRouteRecord } from '@/types'
// 检查是否为 iframe 路由
export function isIframe(url: string): boolean {
return url.startsWith('/outside/iframe/')
}
/**
* 验证菜单项是否有效
* @param menuItem 菜单项
* @returns 是否为有效菜单项
*/
const isValidMenuItem = (menuItem: AppRouteRecord): boolean => {
return !!(menuItem.path && menuItem.path.trim() && !menuItem.meta?.isHide)
}
/**
* 标准化路径格式
* @param path 路径
* @returns 标准化后的路径
*/
const normalizePath = (path: string): string => {
return path.startsWith('/') ? path : `/${path}`
}
/**
* 递归获取菜单的第一个有效路径
* @param menuList 菜单列表
* @returns 第一个有效路径,如果没有找到则返回空字符串
*/
export const getFirstMenuPath = (menuList: AppRouteRecord[]): string => {
if (!Array.isArray(menuList) || menuList.length === 0) {
return ''
}
for (const menuItem of menuList) {
if (!isValidMenuItem(menuItem)) {
continue
}
// 如果有子菜单,优先查找子菜单
if (menuItem.children?.length) {
const childPath = getFirstMenuPath(menuItem.children)
if (childPath) {
return childPath
}
}
// 返回当前菜单项的标准化路径
return normalizePath(menuItem.path!)
}
return ''
}

View File

@@ -0,0 +1,67 @@
/**
* 工作标签页管理模块
*
* 提供工作标签页Worktab的自动管理功能
*
* ## 主要功能
*
* - 根据路由导航自动创建和更新工作标签页
* - iframe 页面标签页特殊处理
* - 标签页信息提取(标题、路径、缓存状态等)
* - 固定标签页支持
* - 根据系统设置控制标签页显示
* - 首页标签页特殊处理
*
* ## 使用场景
*
* - 路由守卫中自动创建标签页
* - 页面切换时更新标签页状态
* - 多标签页导航系统
*
* @module utils/navigation/worktab
* @author Art Design Pro Team
*/
import { useWorktabStore } from '@/store/modules/worktab'
import { RouteLocationNormalized } from 'vue-router'
import { isIframe } from './route'
import { useSettingStore } from '@/store/modules/setting'
import { IframeRouteManager } from '@/router/core'
import { useCommon } from '@/hooks/core/useCommon'
/**
* 根据当前路由信息设置工作标签页worktab
* @param to 当前路由对象
*/
export const setWorktab = (to: RouteLocationNormalized): void => {
const worktabStore = useWorktabStore()
const { meta, path, name, params, query } = to
if (!meta.isHideTab) {
// 如果是 iframe 页面,则特殊处理工作标签页
if (isIframe(path)) {
const iframeRoute = IframeRouteManager.getInstance().findByPath(to.path)
if (iframeRoute?.meta) {
worktabStore.openTab({
title: iframeRoute.meta.title,
icon: meta.icon as string,
path,
name: name as string,
keepAlive: meta.keepAlive as boolean,
params,
query
})
}
} else if (useSettingStore().showWorkTab || path === useCommon().homePath.value) {
worktabStore.openTab({
title: meta.title as string,
icon: meta.icon as string,
path,
name: name as string,
keepAlive: meta.keepAlive as boolean,
params,
query,
fixedTab: meta.fixedTab as boolean
})
}
}
}