feat(service): 完善服务层和状态管理
- 更新API服务配置(api/login.ts) - 优化HTTP服务配置(http/alova.ts, config.ts, handle.ts) - 完善认证状态管理(store/auth.ts) - 优化路由状态管理(store/router/) 加强服务层架构和状态管理机制
This commit is contained in:
parent
c239a15840
commit
567e68234b
@ -1,25 +1,84 @@
|
|||||||
import { request } from '../http'
|
import { request } from '../http'
|
||||||
|
|
||||||
interface Ilogin {
|
interface LoginRequest {
|
||||||
userName: string
|
loginName: string
|
||||||
password: string
|
password: string
|
||||||
|
codeKey: string
|
||||||
|
securityCode: string
|
||||||
|
rememberMe?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fetchLogin(data: Ilogin) {
|
interface RegisterRequest {
|
||||||
const methodInstance = request.Post<Service.ResponseResult<Api.Login.Info>>('/login', data)
|
loginName: string
|
||||||
|
password: string
|
||||||
|
userName: string
|
||||||
|
codeKey: string
|
||||||
|
securityCode: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface LoginResponse {
|
||||||
|
tokenName: string
|
||||||
|
tokenValue: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CaptchaResponse {
|
||||||
|
codeKey: string
|
||||||
|
captchaPicture: string
|
||||||
|
captchaText?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export function fetchLogin(data: LoginRequest) {
|
||||||
|
const methodInstance = request.Post<Service.ResponseResult<LoginResponse>>('/auth/login', data)
|
||||||
methodInstance.meta = {
|
methodInstance.meta = {
|
||||||
authRole: null,
|
authRole: null,
|
||||||
}
|
}
|
||||||
return methodInstance
|
return methodInstance
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function fetchLogout() {
|
||||||
|
return request.Get<Service.ResponseResult<string>>('/auth/logout')
|
||||||
|
}
|
||||||
|
|
||||||
|
export function fetchRegister(data: RegisterRequest) {
|
||||||
|
const methodInstance = request.Post<Service.ResponseResult<string>>('/auth/register', data)
|
||||||
|
methodInstance.meta = {
|
||||||
|
authRole: null,
|
||||||
|
}
|
||||||
|
return methodInstance
|
||||||
|
}
|
||||||
|
|
||||||
export function fetchUpdateToken(data: any) {
|
export function fetchUpdateToken(data: any) {
|
||||||
const method = request.Post<Service.ResponseResult<Api.Login.Info>>('/updateToken', data)
|
const method = request.Post<Service.ResponseResult<LoginResponse>>('/updateToken', data)
|
||||||
method.meta = {
|
method.meta = {
|
||||||
authRole: 'refreshToken',
|
authRole: 'refreshToken',
|
||||||
}
|
}
|
||||||
return method
|
return method
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fetchUserRoutes(params: { id: number }) {
|
export function fetchUserRoutesOld(params: { id: number }) {
|
||||||
return request.Get<Service.ResponseResult<AppRoute.RowRoute[]>>('/getUserRoutes', { params })
|
return request.Get<Service.ResponseResult<AppRoute.RowRoute[]>>('/getUserRoutes', { params })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function fetchLoginUserInfo() {
|
||||||
|
return request.Get<Service.ResponseResult<Api.Login.Info>>('/coder/sysLoginUser/getLoginUserInformation')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证码相关接口
|
||||||
|
|
||||||
|
// 获取PNG格式验证码
|
||||||
|
export function fetchCaptchaPng() {
|
||||||
|
const methodInstance = request.Get<Service.ResponseResult<CaptchaResponse>>('/captcha/png')
|
||||||
|
methodInstance.meta = {
|
||||||
|
authRole: null,
|
||||||
|
}
|
||||||
|
return methodInstance
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取GIF格式验证码
|
||||||
|
export function fetchCaptchaGif() {
|
||||||
|
const methodInstance = request.Get<Service.ResponseResult<CaptchaResponse>>('/captcha/gif')
|
||||||
|
methodInstance.meta = {
|
||||||
|
authRole: null,
|
||||||
|
}
|
||||||
|
return methodInstance
|
||||||
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { local } from '@/utils'
|
import { local } from '@/utils'
|
||||||
|
import { coiMsgWarning } from '@/utils/coi'
|
||||||
import { createAlova } from 'alova'
|
import { createAlova } from 'alova'
|
||||||
import { createServerTokenAuthentication } from 'alova/client'
|
import { createServerTokenAuthentication } from 'alova/client'
|
||||||
import adapterFetch from 'alova/fetch'
|
import adapterFetch from 'alova/fetch'
|
||||||
@ -89,7 +90,7 @@ export function createAlovaInstance(
|
|||||||
},
|
},
|
||||||
onError: (error, method) => {
|
onError: (error, method) => {
|
||||||
const tip = `[${method.type}] - [${method.url}] - ${error.message}`
|
const tip = `[${method.type}] - [${method.url}] - ${error.message}`
|
||||||
window.$message?.warning(tip)
|
coiMsgWarning(tip)
|
||||||
},
|
},
|
||||||
|
|
||||||
onComplete: async (_method) => {
|
onComplete: async (_method) => {
|
||||||
|
|||||||
@ -10,8 +10,8 @@ export const DEFAULT_ALOVA_OPTIONS = {
|
|||||||
export const DEFAULT_BACKEND_OPTIONS = {
|
export const DEFAULT_BACKEND_OPTIONS = {
|
||||||
codeKey: 'code',
|
codeKey: 'code',
|
||||||
dataKey: 'data',
|
dataKey: 'data',
|
||||||
msgKey: 'message',
|
msgKey: 'msg',
|
||||||
successCode: 200,
|
successCode: 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 请求不成功各种状态的错误 */
|
/** 请求不成功各种状态的错误 */
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { fetchUpdateToken } from '@/service'
|
import { fetchUpdateToken } from '@/service'
|
||||||
import { useAuthStore } from '@/store'
|
import { useAuthStore } from '@/store'
|
||||||
import { local } from '@/utils'
|
import { local } from '@/utils'
|
||||||
|
import { coiMsgError } from '@/utils/coi'
|
||||||
import {
|
import {
|
||||||
ERROR_NO_TIP_STATUS,
|
ERROR_NO_TIP_STATUS,
|
||||||
ERROR_STATUS,
|
ERROR_STATUS,
|
||||||
@ -94,5 +95,5 @@ export function showError(error: Service.RequestError) {
|
|||||||
if (ERROR_NO_TIP_STATUS.includes(code))
|
if (ERROR_NO_TIP_STATUS.includes(code))
|
||||||
return
|
return
|
||||||
|
|
||||||
window.$message.error(error.message)
|
coiMsgError(error.message)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { router } from '@/router'
|
import { router } from '@/router'
|
||||||
import { fetchLogin } from '@/service'
|
import { fetchLogin, fetchLoginUserInfo } from '@/service'
|
||||||
import { local } from '@/utils'
|
import { local } from '@/utils'
|
||||||
import { useRouteStore } from './router'
|
import { useRouteStore } from './router'
|
||||||
import { useTabStore } from './tab'
|
import { useTabStore } from './tab'
|
||||||
@ -52,14 +52,28 @@ export const useAuthStore = defineStore('auth-store', {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/* 用户登录 */
|
/* 用户登录 */
|
||||||
async login(userName: string, password: string) {
|
async login(loginName: string, password: string, codeKey: string, securityCode: string, rememberMe = false) {
|
||||||
try {
|
try {
|
||||||
const { isSuccess, data } = await fetchLogin({ userName, password })
|
const { isSuccess, data } = await fetchLogin({ loginName, password, codeKey, securityCode, rememberMe })
|
||||||
if (!isSuccess)
|
if (!isSuccess)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
// 保存Token
|
||||||
|
local.set('accessToken', data.tokenValue)
|
||||||
|
this.token = data.tokenValue
|
||||||
|
|
||||||
|
// 获取用户信息
|
||||||
|
const userInfoResult = await fetchLoginUserInfo()
|
||||||
|
if (!userInfoResult.isSuccess)
|
||||||
|
return
|
||||||
|
|
||||||
// 处理登录信息
|
// 处理登录信息
|
||||||
await this.handleLoginInfo(data)
|
const userInfo = {
|
||||||
|
...userInfoResult.data,
|
||||||
|
accessToken: data.tokenValue,
|
||||||
|
refreshToken: data.tokenValue, // 如果后端没有单独的refreshToken,暂时使用相同值
|
||||||
|
}
|
||||||
|
await this.handleLoginInfo(userInfo as Api.Login.Info)
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
console.warn('[Login Error]:', e)
|
console.warn('[Login Error]:', e)
|
||||||
|
|||||||
@ -1,14 +1,36 @@
|
|||||||
import type { MenuOption } from 'naive-ui'
|
import type { MenuOption } from 'naive-ui'
|
||||||
import type { RouteRecordRaw } from 'vue-router'
|
import type { RouteRecordRaw } from 'vue-router'
|
||||||
|
import { h } from 'vue'
|
||||||
import { usePermission } from '@/hooks'
|
import { usePermission } from '@/hooks'
|
||||||
import Layout from '@/layouts/index.vue'
|
import Layout from '@/layouts/index.vue'
|
||||||
import { $t, arrayToTree, renderIcon } from '@/utils'
|
import { arrayToTree, renderIcon } from '@/utils'
|
||||||
import { clone, min, omit, pick } from 'radash'
|
import { clone, min, omit, pick } from 'radash'
|
||||||
import { RouterLink } from 'vue-router'
|
import { RouterLink } from 'vue-router'
|
||||||
|
|
||||||
const metaFields: AppRoute.MetaKeys[]
|
const metaFields: AppRoute.MetaKeys[]
|
||||||
= ['title', 'icon', 'requiresAuth', 'roles', 'keepAlive', 'hide', 'order', 'href', 'activeMenu', 'withoutTab', 'pinTab', 'menuType']
|
= ['title', 'icon', 'requiresAuth', 'roles', 'keepAlive', 'hide', 'order', 'href', 'activeMenu', 'withoutTab', 'pinTab', 'menuType']
|
||||||
|
|
||||||
|
// 将后端菜单数据转换为前端路由数据
|
||||||
|
function transformBackendToRoute(backendRoute: AppRoute.BackendRoute): AppRoute.RowRoute {
|
||||||
|
return {
|
||||||
|
id: backendRoute.menuId,
|
||||||
|
pid: backendRoute.parentId === 0 ? null : backendRoute.parentId,
|
||||||
|
name: backendRoute.name,
|
||||||
|
path: backendRoute.path,
|
||||||
|
componentPath: backendRoute.component || null,
|
||||||
|
redirect: backendRoute.redirect || undefined,
|
||||||
|
title: backendRoute.menuName,
|
||||||
|
icon: backendRoute.icon,
|
||||||
|
requiresAuth: true, // 动态路由都需要认证
|
||||||
|
hide: backendRoute.isHide === '0', // 0-隐藏 1-显示
|
||||||
|
keepAlive: backendRoute.isKeepAlive === '0', // 0-是 1-否
|
||||||
|
pinTab: backendRoute.isAffix === '0', // 0-是 1-否
|
||||||
|
activeMenu: backendRoute.activeMenu || undefined,
|
||||||
|
menuType: backendRoute.menuType as AppRoute.MenuType,
|
||||||
|
href: backendRoute.isLink === '0' ? backendRoute.path : undefined, // 如果是外链
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function standardizedRoutes(route: AppRoute.RowRoute[]) {
|
function standardizedRoutes(route: AppRoute.RowRoute[]) {
|
||||||
return clone(route).map((i) => {
|
return clone(route).map((i) => {
|
||||||
const route = omit(i, metaFields)
|
const route = omit(i, metaFields)
|
||||||
@ -18,9 +40,20 @@ function standardizedRoutes(route: AppRoute.RowRoute[]) {
|
|||||||
}) as AppRoute.Route[]
|
}) as AppRoute.Route[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createRoutes(routes: AppRoute.RowRoute[]) {
|
// 处理路由数据的主函数 - 支持动态和静态路由以及混合模式
|
||||||
|
export function createRoutes(routeData: (AppRoute.BackendRoute | AppRoute.RowRoute)[]) {
|
||||||
const { hasPermission } = usePermission()
|
const { hasPermission } = usePermission()
|
||||||
|
|
||||||
|
// 处理混合数据:分别处理后端数据和前端数据
|
||||||
|
const backendRoutes = routeData.filter(item => 'menuId' in item) as AppRoute.BackendRoute[]
|
||||||
|
const frontendRoutes = routeData.filter(item => !('menuId' in item)) as AppRoute.RowRoute[]
|
||||||
|
|
||||||
|
// 转换后端路由数据
|
||||||
|
const transformedBackendRoutes = backendRoutes.map(transformBackendToRoute)
|
||||||
|
|
||||||
|
// 合并所有路由
|
||||||
|
const routes = [...frontendRoutes, ...transformedBackendRoutes]
|
||||||
|
|
||||||
// Structure the meta field
|
// Structure the meta field
|
||||||
let resultRouter = standardizedRoutes(routes)
|
let resultRouter = standardizedRoutes(routes)
|
||||||
|
|
||||||
@ -30,8 +63,43 @@ export function createRoutes(routes: AppRoute.RowRoute[]) {
|
|||||||
// Generate routes, no need to import files for those with redirect
|
// Generate routes, no need to import files for those with redirect
|
||||||
const modules = import.meta.glob('@/views/**/*.vue')
|
const modules = import.meta.glob('@/views/**/*.vue')
|
||||||
resultRouter = resultRouter.map((item: AppRoute.Route) => {
|
resultRouter = resultRouter.map((item: AppRoute.Route) => {
|
||||||
if (item.componentPath && !item.redirect)
|
if (item.componentPath && !item.redirect) {
|
||||||
item.component = modules[`/src/views${item.componentPath}`]
|
// 对于动态路由,只有菜单类型才需要组件;对于静态路由,都需要组件
|
||||||
|
const needComponent = item.meta.menuType === '2' || !item.meta.menuType
|
||||||
|
if (needComponent) {
|
||||||
|
// 处理组件路径,确保正确的路径格式
|
||||||
|
let componentPath = item.componentPath
|
||||||
|
// 确保路径以 / 开头
|
||||||
|
if (!componentPath.startsWith('/')) {
|
||||||
|
componentPath = `/${componentPath}`
|
||||||
|
}
|
||||||
|
// 确保路径以 .vue 结尾
|
||||||
|
if (!componentPath.endsWith('.vue')) {
|
||||||
|
componentPath = `${componentPath}.vue`
|
||||||
|
}
|
||||||
|
const fullPath = `/src/views${componentPath}`
|
||||||
|
item.component = modules[fullPath]
|
||||||
|
|
||||||
|
// 如果组件未找到,输出调试信息并提供默认组件
|
||||||
|
if (!item.component) {
|
||||||
|
console.warn(`组件未找到: ${fullPath}`)
|
||||||
|
console.warn('可用组件路径:', Object.keys(modules).slice(0, 10)) // 只显示前10个避免日志过长
|
||||||
|
|
||||||
|
// 为找不到组件的页面提供一个默认的空页面组件
|
||||||
|
item.component = () => h('div', { class: 'p-4' }, [
|
||||||
|
h('div', { class: 'text-center text-gray-500' }, [
|
||||||
|
h('h3', '页面开发中'),
|
||||||
|
h('p', `组件路径: ${fullPath}`),
|
||||||
|
h('p', '请联系开发人员创建对应的页面组件'),
|
||||||
|
]),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (item.meta.menuType === '1') {
|
||||||
|
// 目录类型不需要组件,但需要确保有children
|
||||||
|
item.component = undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
return item
|
return item
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -41,7 +109,7 @@ export function createRoutes(routes: AppRoute.RowRoute[]) {
|
|||||||
const appRootRoute: RouteRecordRaw = {
|
const appRootRoute: RouteRecordRaw = {
|
||||||
path: '/appRoot',
|
path: '/appRoot',
|
||||||
name: 'appRoot',
|
name: 'appRoot',
|
||||||
redirect: import.meta.env.VITE_HOME_PATH,
|
redirect: import.meta.env.VITE_HOME_PATH || '/dashboard/monitor',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
meta: {
|
meta: {
|
||||||
title: '',
|
title: '',
|
||||||
@ -91,11 +159,21 @@ function setRedirect(routes: AppRoute.Route[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 生成侧边菜单的数据 */
|
/* 生成侧边菜单的数据 */
|
||||||
export function createMenus(userRoutes: AppRoute.RowRoute[]) {
|
export function createMenus(routeData: (AppRoute.BackendRoute | AppRoute.RowRoute)[]) {
|
||||||
|
// 处理混合数据:分别处理后端数据和前端数据
|
||||||
|
const backendRoutes = routeData.filter(item => 'menuId' in item) as AppRoute.BackendRoute[]
|
||||||
|
const frontendRoutes = routeData.filter(item => !('menuId' in item)) as AppRoute.RowRoute[]
|
||||||
|
|
||||||
|
// 转换后端路由数据
|
||||||
|
const transformedBackendRoutes = backendRoutes.map(transformBackendToRoute)
|
||||||
|
|
||||||
|
// 合并所有路由
|
||||||
|
const userRoutes = [...frontendRoutes, ...transformedBackendRoutes]
|
||||||
|
|
||||||
const resultMenus = standardizedRoutes(userRoutes)
|
const resultMenus = standardizedRoutes(userRoutes)
|
||||||
|
|
||||||
// filter menus that do not need to be displayed
|
// filter menus that do not need to be displayed
|
||||||
const visibleMenus = resultMenus.filter(route => !route.meta.hide)
|
const visibleMenus = resultMenus.filter(route => !route.meta.hide && route.meta.menuType !== '3') // 过滤按钮类型
|
||||||
|
|
||||||
// generate side menu
|
// generate side menu
|
||||||
return arrayToTree(transformAuthRoutesToMenus(visibleMenus))
|
return arrayToTree(transformAuthRoutesToMenus(visibleMenus))
|
||||||
@ -123,7 +201,7 @@ function transformAuthRoutesToMenus(userRoutes: AppRoute.Route[]) {
|
|||||||
id: item.id,
|
id: item.id,
|
||||||
pid: item.pid,
|
pid: item.pid,
|
||||||
label:
|
label:
|
||||||
(!item.meta.menuType || item.meta.menuType === 'page')
|
(!item.meta.menuType || item.meta.menuType === '2')
|
||||||
? () =>
|
? () =>
|
||||||
h(
|
h(
|
||||||
RouterLink,
|
RouterLink,
|
||||||
@ -132,9 +210,9 @@ function transformAuthRoutesToMenus(userRoutes: AppRoute.Route[]) {
|
|||||||
path: item.path,
|
path: item.path,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ default: () => $t(`route.${String(item.name)}`, item.meta.title) },
|
{ default: () => item.meta.title },
|
||||||
)
|
)
|
||||||
: () => $t(`route.${String(item.name)}`, item.meta.title),
|
: () => item.meta.title,
|
||||||
key: item.path,
|
key: item.path,
|
||||||
icon: item.meta.icon ? renderIcon(item.meta.icon) : undefined,
|
icon: item.meta.icon ? renderIcon(item.meta.icon) : undefined,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,14 +2,15 @@ import type { MenuOption } from 'naive-ui'
|
|||||||
import { router } from '@/router'
|
import { router } from '@/router'
|
||||||
import { staticRoutes } from '@/router/routes.static'
|
import { staticRoutes } from '@/router/routes.static'
|
||||||
import { fetchUserRoutes } from '@/service'
|
import { fetchUserRoutes } from '@/service'
|
||||||
import { useAuthStore } from '@/store/auth'
|
import { $t } from '@/utils'
|
||||||
import { $t, local } from '@/utils'
|
import { coiMsgError } from '@/utils/coi'
|
||||||
import { createMenus, createRoutes, generateCacheRoutes } from './helper'
|
import { createMenus, createRoutes, generateCacheRoutes } from './helper'
|
||||||
|
|
||||||
interface RoutesStatus {
|
interface RoutesStatus {
|
||||||
isInitAuthRoute: boolean
|
isInitAuthRoute: boolean
|
||||||
menus: MenuOption[]
|
menus: MenuOption[]
|
||||||
rowRoutes: AppRoute.RowRoute[]
|
rowRoutes: AppRoute.RowRoute[]
|
||||||
|
backendRoutes: AppRoute.BackendRoute[]
|
||||||
activeMenu: string | null
|
activeMenu: string | null
|
||||||
cacheRoutes: string[]
|
cacheRoutes: string[]
|
||||||
}
|
}
|
||||||
@ -20,6 +21,7 @@ export const useRouteStore = defineStore('route-store', {
|
|||||||
activeMenu: null,
|
activeMenu: null,
|
||||||
menus: [],
|
menus: [],
|
||||||
rowRoutes: [],
|
rowRoutes: [],
|
||||||
|
backendRoutes: [],
|
||||||
cacheRoutes: [],
|
cacheRoutes: [],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -38,50 +40,94 @@ export const useRouteStore = defineStore('route-store', {
|
|||||||
},
|
},
|
||||||
|
|
||||||
async initRouteInfo() {
|
async initRouteInfo() {
|
||||||
|
// 始终加载静态路由(仪表盘等基础路由)
|
||||||
|
const allRoutes = [...staticRoutes]
|
||||||
|
|
||||||
if (import.meta.env.VITE_ROUTE_LOAD_MODE === 'dynamic') {
|
if (import.meta.env.VITE_ROUTE_LOAD_MODE === 'dynamic') {
|
||||||
const userInfo = local.get('userInfo')
|
try {
|
||||||
|
// 获取动态路由并合并
|
||||||
|
const { isSuccess, data } = await fetchUserRoutes()
|
||||||
|
|
||||||
if (!userInfo || !userInfo.id) {
|
if (isSuccess && data) {
|
||||||
const authStore = useAuthStore()
|
// 将动态路由添加到静态路由中
|
||||||
authStore.logout()
|
const dynamicRoutes = Array.isArray(data) ? data : []
|
||||||
return
|
console.warn('成功获取动态路由:', dynamicRoutes.length, '个')
|
||||||
}
|
|
||||||
|
|
||||||
// Get user's route
|
// 保持动态路由的原始ID关系,不需要修改ID,因为静态路由和动态路由可以共存
|
||||||
const { data } = await fetchUserRoutes({
|
const processedDynamicRoutes = dynamicRoutes
|
||||||
id: userInfo.id,
|
|
||||||
})
|
|
||||||
|
|
||||||
if (!data)
|
return [...allRoutes, ...processedDynamicRoutes]
|
||||||
return
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.rowRoutes = staticRoutes
|
console.warn('动态路由获取失败,只使用静态路由')
|
||||||
return staticRoutes
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.error('动态路由获取异常,只使用静态路由:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return allRoutes
|
||||||
},
|
},
|
||||||
async initAuthRoute() {
|
async initAuthRoute() {
|
||||||
this.isInitAuthRoute = false
|
this.isInitAuthRoute = false
|
||||||
|
|
||||||
// Initialize route information
|
// Initialize route information
|
||||||
const rowRoutes = await this.initRouteInfo()
|
const routeData = await this.initRouteInfo()
|
||||||
if (!rowRoutes) {
|
if (!routeData) {
|
||||||
window.$message.error($t(`app.getRouteError`))
|
coiMsgError($t(`app.getRouteError`))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.rowRoutes = rowRoutes
|
|
||||||
|
// 检查是否包含动态路由数据(通过是否有menuId字段判断)
|
||||||
|
const hasDynamicRoutes = routeData.some(item => 'menuId' in item)
|
||||||
|
|
||||||
|
if (hasDynamicRoutes) {
|
||||||
|
// 混合模式:分离静态路由和动态路由
|
||||||
|
const staticRouteData = routeData.filter(item => !('menuId' in item)) as AppRoute.RowRoute[]
|
||||||
|
const dynamicRouteData = routeData.filter(item => 'menuId' in item) as AppRoute.BackendRoute[]
|
||||||
|
|
||||||
|
// 保存动态路由原始数据
|
||||||
|
this.backendRoutes = dynamicRouteData
|
||||||
|
|
||||||
|
// 转换动态路由为前端格式
|
||||||
|
const transformedDynamicRoutes = dynamicRouteData.map(item => ({
|
||||||
|
id: item.menuId,
|
||||||
|
pid: item.parentId === 0 ? null : item.parentId,
|
||||||
|
name: item.name,
|
||||||
|
path: item.path,
|
||||||
|
componentPath: item.component || null,
|
||||||
|
redirect: item.redirect || undefined,
|
||||||
|
title: item.menuName,
|
||||||
|
icon: item.icon,
|
||||||
|
requiresAuth: true,
|
||||||
|
hide: item.isHide === '0',
|
||||||
|
keepAlive: item.isKeepAlive === '0',
|
||||||
|
pinTab: item.isAffix === '0',
|
||||||
|
activeMenu: item.activeMenu || undefined,
|
||||||
|
menuType: item.menuType as AppRoute.MenuType,
|
||||||
|
href: item.isLink === '0' ? item.path : undefined,
|
||||||
|
} as AppRoute.RowRoute))
|
||||||
|
|
||||||
|
// 合并静态路由和转换后的动态路由
|
||||||
|
this.rowRoutes = [...staticRouteData, ...transformedDynamicRoutes]
|
||||||
|
this.cacheRoutes = generateCacheRoutes(this.rowRoutes)
|
||||||
|
|
||||||
|
console.warn('混合路由模式 - 静态路由:', staticRouteData.length, '动态路由:', transformedDynamicRoutes.length)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// 纯静态路由模式
|
||||||
|
this.rowRoutes = routeData as AppRoute.RowRoute[]
|
||||||
|
this.cacheRoutes = generateCacheRoutes(this.rowRoutes)
|
||||||
|
console.warn('静态路由模式 - 路由数量:', this.rowRoutes.length)
|
||||||
|
}
|
||||||
|
|
||||||
// Generate actual route and insert
|
// Generate actual route and insert
|
||||||
const routes = createRoutes(rowRoutes)
|
const routes = createRoutes(routeData)
|
||||||
router.addRoute(routes)
|
router.addRoute(routes)
|
||||||
|
|
||||||
// Generate side menu
|
// Generate side menu
|
||||||
this.menus = createMenus(rowRoutes)
|
this.menus = createMenus(routeData)
|
||||||
|
|
||||||
// Generate the route cache
|
|
||||||
this.cacheRoutes = generateCacheRoutes(rowRoutes)
|
|
||||||
|
|
||||||
this.isInitAuthRoute = true
|
this.isInitAuthRoute = true
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user