Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
V
Vue-Dashboard
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
高源
Vue-Dashboard
Commits
07405b7b
Commit
07405b7b
authored
Jun 16, 2025
by
User
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
登录模块优化,路由验证优化
parent
70990881
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
199 additions
and
178 deletions
+199
-178
index.html
dist/index.html
+2
-2
router.ts
src/hooks/common/router.ts
+9
-1
main.ts
src/main.ts
+0
-65
route.ts
src/router/guard/route.ts
+29
-27
index.ts
src/router/routes/index.ts
+59
-32
index.ts
src/store/modules/auth/index.ts
+62
-47
index.ts
src/store/modules/route/index.ts
+38
-4
No files found.
dist/index.html
View file @
07405b7b
<!doctype html>
<!doctype html>
<html
lang=
"zh-cmn-Hans"
>
<html
lang=
"zh-cmn-Hans"
>
<head>
<head>
<meta
name=
"buildTime"
content=
"2025-06-1
0 20:28:50
"
>
<meta
name=
"buildTime"
content=
"2025-06-1
6 14:15:36
"
>
<meta
charset=
"UTF-8"
/>
<meta
charset=
"UTF-8"
/>
<link
rel=
"icon"
href=
"/favicon.svg"
/>
<link
rel=
"icon"
href=
"/favicon.svg"
/>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0"
/>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0"
/>
<meta
name=
"color-scheme"
content=
"light dark"
/>
<meta
name=
"color-scheme"
content=
"light dark"
/>
<title>
VueDashboard
</title>
<title>
VueDashboard
</title>
<script
type=
"module"
crossorigin
src=
"/Content/VueDashboardUi/VueDashboard1/assets/index-
B_dt3SP8
.js"
></script>
<script
type=
"module"
crossorigin
src=
"/Content/VueDashboardUi/VueDashboard1/assets/index-
C1MVrFI5
.js"
></script>
<link
rel=
"stylesheet"
crossorigin
href=
"/Content/VueDashboardUi/VueDashboard1/assets/index-BLjiwC98.css"
>
<link
rel=
"stylesheet"
crossorigin
href=
"/Content/VueDashboardUi/VueDashboard1/assets/index-BLjiwC98.css"
>
</head>
</head>
<body>
<body>
...
...
src/hooks/common/router.ts
View file @
07405b7b
...
@@ -124,7 +124,15 @@ export function useRouterPush(inSetup = true) {
...
@@ -124,7 +124,15 @@ export function useRouterPush(inSetup = true) {
const
redirect
=
route
.
value
.
query
?.
redirect
as
string
;
const
redirect
=
route
.
value
.
query
?.
redirect
as
string
;
if
(
redirect
)
{
if
(
redirect
)
{
routerPush
(
redirect
);
// 清理redirect参数,避免循环重定向
const
cleanRedirect
=
redirect
.
split
(
'?'
)[
0
];
// 只保留路径部分,去掉查询参数
// 确保不是回到登录页
if
(
cleanRedirect
!==
'/login'
)
{
routerPush
(
cleanRedirect
);
}
else
{
toHome
();
}
}
else
{
}
else
{
toHome
();
toHome
();
}
}
...
...
src/main.ts
View file @
07405b7b
...
@@ -5,8 +5,6 @@ import VueGridLayout from 'vue-grid-layout';
...
@@ -5,8 +5,6 @@ import VueGridLayout from 'vue-grid-layout';
import
MateChat
from
'@matechat/core'
;
import
MateChat
from
'@matechat/core'
;
import
'@devui-design/icons/icomoon/devui-icon.css'
;
import
'@devui-design/icons/icomoon/devui-icon.css'
;
import
'./plugins/assets'
;
import
'./plugins/assets'
;
import
{
localStg
}
from
'@/utils/storage'
;
// main.js or main.ts
import
'font-awesome/css/font-awesome.css'
;
import
'font-awesome/css/font-awesome.css'
;
// 引入 KaTeX 样式以支持数学公式渲染
// 引入 KaTeX 样式以支持数学公式渲染
import
'katex/dist/katex.min.css'
;
import
'katex/dist/katex.min.css'
;
...
@@ -16,46 +14,6 @@ import { setupRouter } from './router';
...
@@ -16,46 +14,6 @@ import { setupRouter } from './router';
import
{
setupI18n
}
from
'./locales'
;
import
{
setupI18n
}
from
'./locales'
;
import
App
from
'./App.vue'
;
import
App
from
'./App.vue'
;
// let timeoutHandle: string | number | NodeJS.Timeout | undefined;
// const INACTIVITY_TIMEOUT = 20 * 60 * 1000;
// function handleLogout(app: any) {
// localStg.remove('token');
// localStg.remove('refreshToken');
// localStg.remove('userInfo');
// app.config.globalProperties.$router.push('/login/pwd-login');
// }
// function checkLastActivity(app: any) {
// const lastActivity = localStorage.getItem('lastActivityTime');
// if (lastActivity) {
// const timeDiff = Date.now() - Number.parseInt(lastActivity, 10);
// if (timeDiff > INACTIVITY_TIMEOUT) {
// handleLogout(app);
// }
// }
// }
// function startInactivityTimer(app: any) {
// clearTimeout(timeoutHandle);
// localStorage.setItem('lastActivityTime', Date.now().toString());
// timeoutHandle = setTimeout(() => handleLogout(app), INACTIVITY_TIMEOUT);
// }
// function resetInactivityTimer(app: any) {
// startInactivityTimer(app);
// }
// 检查认证状态
// function checkAuthStatus(app: any) {
// if (window.uiGlobalConfig?.IsAuthenticated === false) {
// localStg.remove('token');
// localStg.remove('refreshToken');
// localStg.remove('userInfo');
// app.config.globalProperties.$router.push('/login/pwd-login');
// }
// }
async
function
setupApp
()
{
async
function
setupApp
()
{
setupLoading
();
setupLoading
();
setupNProgress
();
setupNProgress
();
...
@@ -66,37 +24,14 @@ async function setupApp() {
...
@@ -66,37 +24,14 @@ async function setupApp() {
setupStore
(
app
);
setupStore
(
app
);
await
setupRouter
(
app
);
await
setupRouter
(
app
);
setupI18n
(
app
);
setupI18n
(
app
);
// 检查认证状态
// checkAuthStatus(app);
// 检查上次活动时间
// checkLastActivity(app);
// 监听用户的操作
// window.addEventListener('mousemove', () => resetInactivityTimer(app));
// window.addEventListener('keydown', () => resetInactivityTimer(app));
// window.addEventListener('click', () => resetInactivityTimer(app));
// window.addEventListener('scroll', () => resetInactivityTimer(app));
// 启动计时器
// startInactivityTimer(app);
app
.
use
(
VueGridLayout
);
app
.
use
(
VueGridLayout
);
app
.
use
(
MateChat
);
app
.
use
(
MateChat
);
// 全局注册 wangeditor 组件
// 全局注册 wangeditor 组件
app
.
component
(
'WangEditor'
,
Editor
);
app
.
component
(
'WangEditor'
,
Editor
);
app
.
component
(
'WangToolbar'
,
Toolbar
);
app
.
component
(
'WangToolbar'
,
Toolbar
);
app
.
mount
(
'#app'
);
app
.
mount
(
'#app'
);
}
}
// 页面卸载时保存最后活动时间
// window.addEventListener('beforeunload', () => {
// localStorage.setItem('lastActivityTime', Date.now().toString());
// });
setTimeout
(()
=>
{
setTimeout
(()
=>
{
setupApp
();
setupApp
();
},
200
);
},
200
);
src/router/guard/route.ts
View file @
07405b7b
import
type
{
import
type
{
NavigationGuardNext
,
RouteLocationNormalized
,
RouteLocationRaw
,
Router
}
from
'vue-router'
;
LocationQueryRaw
,
NavigationGuardNext
,
RouteLocationNormalized
,
RouteLocationRaw
,
Router
}
from
'vue-router'
;
import
type
{
RouteKey
,
RoutePath
}
from
'@elegant-router/types'
;
import
type
{
RouteKey
,
RoutePath
}
from
'@elegant-router/types'
;
import
{
getRouteName
}
from
'@/router/elegant/transform'
;
import
{
useAuthStore
}
from
'@/store/modules/auth'
;
import
{
useAuthStore
}
from
'@/store/modules/auth'
;
import
{
useRouteStore
}
from
'@/store/modules/route'
;
import
{
useRouteStore
}
from
'@/store/modules/route'
;
import
{
localStg
}
from
'@/utils/storage'
;
import
{
localStg
}
from
'@/utils/storage'
;
...
@@ -27,20 +20,46 @@ export function createRouteGuard(router: Router) {
...
@@ -27,20 +20,46 @@ export function createRouteGuard(router: Router) {
const
authStore
=
useAuthStore
();
const
authStore
=
useAuthStore
();
const
rootRoute
:
RouteKey
=
'root'
;
const
loginRoute
:
RouteKey
=
'login'
;
const
loginRoute
:
RouteKey
=
'login'
;
const
noAuthorizationRoute
:
RouteKey
=
'403'
;
const
noAuthorizationRoute
:
RouteKey
=
'403'
;
const
isAuthenticated
=
window
.
uiGlobalConfig
?.
IsAuthenticated
!==
false
;
// IsAuthenticated 字段具有决定性权威
const
globalIsAuthenticated
=
window
.
uiGlobalConfig
?.
IsAuthenticated
;
const
hasLocalToken
=
Boolean
(
localStg
.
get
(
'token'
));
// 如果 IsAuthenticated 明确为 false,则必须跳转登录页
if
(
globalIsAuthenticated
===
false
)
{
// 清除所有本地认证数据
localStg
.
remove
(
'token'
);
localStg
.
remove
(
'refreshToken'
);
localStg
.
remove
(
'userInfo'
);
const
needLogin
=
!
to
.
meta
.
constant
;
if
(
needLogin
)
{
next
({
name
:
loginRoute
,
query
:
{
redirect
:
to
.
fullPath
}
});
return
;
}
}
// 如果 IsAuthenticated 为 true 或 undefined,则检查 token 状态
const
isAuthenticated
=
globalIsAuthenticated
===
true
||
(
globalIsAuthenticated
===
undefined
&&
hasLocalToken
);
const
needLogin
=
!
to
.
meta
.
constant
;
const
needLogin
=
!
to
.
meta
.
constant
;
const
routeRoles
=
to
.
meta
.
roles
||
[];
const
routeRoles
=
to
.
meta
.
roles
||
[];
const
hasRole
=
authStore
.
userInfo
.
roles
.
some
(
role
=>
routeRoles
.
includes
(
role
));
const
hasRole
=
authStore
.
userInfo
.
roles
.
some
(
role
=>
routeRoles
.
includes
(
role
));
const
hasAuth
=
authStore
.
isStaticSuper
||
!
routeRoles
.
length
||
hasRole
;
const
hasAuth
=
authStore
.
isStaticSuper
||
!
routeRoles
.
length
||
hasRole
;
// 如果有token但uiGlobalConfig未设置,则设置认证状态
if
(
hasLocalToken
&&
globalIsAuthenticated
===
undefined
&&
window
.
uiGlobalConfig
)
{
window
.
uiGlobalConfig
.
IsAuthenticated
=
true
;
}
// 如果未认证,清除token并跳转登录页
// 如果未认证,清除token并跳转登录页
if
(
!
isAuthenticated
&&
needLogin
)
{
if
(
!
isAuthenticated
&&
needLogin
)
{
localStg
.
remove
(
'token'
);
localStg
.
remove
(
'token'
);
localStg
.
remove
(
'refreshToken'
);
localStg
.
remove
(
'userInfo'
);
next
({
name
:
loginRoute
,
query
:
{
redirect
:
to
.
fullPath
}
});
next
({
name
:
loginRoute
,
query
:
{
redirect
:
to
.
fullPath
}
});
return
;
return
;
}
}
...
@@ -174,20 +193,3 @@ function handleRouteSwitch(to: RouteLocationNormalized, from: RouteLocationNorma
...
@@ -174,20 +193,3 @@ function handleRouteSwitch(to: RouteLocationNormalized, from: RouteLocationNorma
next
();
next
();
}
}
function
getRouteQueryOfLoginRoute
(
to
:
RouteLocationNormalized
,
routeHome
:
RouteKey
)
{
const
loginRoute
:
RouteKey
=
'login'
;
const
redirect
=
to
.
fullPath
;
const
[
redirectPath
,
redirectQuery
]
=
redirect
.
split
(
'?'
);
const
redirectName
=
getRouteName
(
redirectPath
as
RoutePath
);
const
isRedirectHome
=
routeHome
===
redirectName
;
const
query
:
LocationQueryRaw
=
to
.
name
!==
loginRoute
&&
!
isRedirectHome
?
{
redirect
}
:
{};
if
(
isRedirectHome
&&
redirectQuery
)
{
query
.
redirect
=
`/?
${
redirectQuery
}
`
;
}
return
query
;
}
src/router/routes/index.ts
View file @
07405b7b
/* eslint-disable no-plusplus */
/* eslint-disable no-plusplus */
import
{
truncate
}
from
'node:fs/promises'
;
import
type
{
ElegantConstRoute
}
from
'@elegant-router/types'
;
import
type
{
CustomRoute
,
ElegantConstRoute
,
ElegantRoute
}
from
'@elegant-router/types'
;
import
{
getRootMenu
}
from
'@/service/api'
;
import
{
getRootMenu
}
from
'@/service/api'
;
import
{
useRouteStore
}
from
'@/store/modules/route'
;
import
{
useRouteStore
}
from
'@/store/modules/route'
;
import
{
generatedRoutes
}
from
'../elegant/routes'
;
import
{
layouts
,
views
}
from
'../elegant/imports'
;
import
{
layouts
,
views
}
from
'../elegant/imports'
;
import
{
transformElegantRoutesToVueRoutes
}
from
'../elegant/transform'
;
import
{
transformElegantRoutesToVueRoutes
}
from
'../elegant/transform'
;
import
{
generatedRoutes
}
from
'../elegant/routes'
;
type
ElegantRoute
=
ElegantConstRoute
;
/**
/**
* custom routes
* custom routes
*
*
* @link https://github.com/soybeanjs/elegant-router?tab=readme-ov-file#custom-route
* @link https://github.com/soybeanjs/elegant-router?tab=readme-ov-file#custom-route
*/
*/
const
customRoutes
:
Custom
Route
[]
=
[
const
customRoutes
:
Elegant
Route
[]
=
[
// {
// {
// name: 'exception',
// name: 'exception',
// path: '/exception',
// path: '/exception',
...
@@ -56,8 +58,6 @@ const customRoutes: CustomRoute[] = [
...
@@ -56,8 +58,6 @@ const customRoutes: CustomRoute[] = [
// }
// }
// ]
// ]
// },
// },
// 以下是iframe-page的示例
// 以下是iframe-page的示例
// {
// {
// name: 'document',
// name: 'document',
...
@@ -186,37 +186,49 @@ const customRoutes: CustomRoute[] = [
...
@@ -186,37 +186,49 @@ const customRoutes: CustomRoute[] = [
// ]
// ]
// }
// }
];
];
/**
* Get MenuThree
*
* @param MenuThree MenuThree
*/
// 以下是获取菜单的示例
// ${window.uiGlobalConfig.InternalCode}
// const { data: menus } = await getRootMenu(`/Restful/Kivii.Basic.Entities.Menu/Show.json?RootInternalCode=dashboard`);
const
{
data
:
menus
}
=
await
getRootMenu
(
`/Restful/Kivii.Basic.Entities.Menu/Show.json?RootInternalCode=
${
window
.
uiGlobalConfig
.
InternalCode
}
`
);
const
MenuThree
=
await
getMenuThree
(
menus
?.
MenusMain
?.
Results
);
// 将动态菜单路由存储在全局变量中
const
MenuRoot
=
menus
?.
MenuRoot
;
let
dynamicMenuRoutes
:
ElegantRoute
[]
=
[];
// // console.log(MenuRoot);
// // 存储 MenuRoot 到 store
if
(
MenuRoot
)
{
// 动态获取菜单数据并生成路由
setTimeout
(()
=>
{
const
routeStore
=
useRouteStore
();
export
async
function
generateDynamicRoutes
()
{
routeStore
.
setMenuRoot
(
MenuRoot
);
try
{
},
1000
);
// 清空之前的动态路由
}
dynamicMenuRoutes
=
[];
if
(
!
window
.
uiGlobalConfig
?.
InternalCode
)
{
console
.
warn
(
'InternalCode not found, skipping dynamic route generation'
);
return
;
}
const
MenuThree2
=
generateRoutes
(
MenuThree
);
const
{
data
:
menus
}
=
await
getRootMenu
(
if
(
MenuThree2
.
length
>
0
)
{
`/Restful/Kivii.Basic.Entities.Menu/Show.json?RootInternalCode=
${
window
.
uiGlobalConfig
.
InternalCode
}
`
for
(
let
i
=
0
;
i
<
MenuThree2
.
length
;
i
++
)
{
);
customRoutes
.
push
(
MenuThree2
[
i
]);
const
MenuThree
=
getMenuThree
(
menus
?.
MenusMain
?.
Results
);
const
MenuRoot
=
menus
?.
MenuRoot
;
// 存储 MenuRoot 到 store
if
(
MenuRoot
)
{
setTimeout
(()
=>
{
const
routeStore
=
useRouteStore
();
routeStore
.
setMenuRoot
(
MenuRoot
);
},
100
);
}
const
MenuThree2
=
generateRoutes
(
MenuThree
);
if
(
MenuThree2
.
length
>
0
)
{
dynamicMenuRoutes
=
[...
MenuThree2
];
}
}
catch
(
error
)
{
console
.
error
(
'Failed to generate dynamic routes:'
,
error
);
}
}
}
}
function
getMenuThree
(
data
:
any
)
{
function
getMenuThree
(
data
:
any
)
{
if
(
!
data
||
!
Array
.
isArray
(
data
))
return
[];
const
cloneData
=
JSON
.
parse
(
JSON
.
stringify
(
data
));
// 对源数据深度克隆
const
cloneData
=
JSON
.
parse
(
JSON
.
stringify
(
data
));
// 对源数据深度克隆
return
cloneData
.
filter
((
father
:
{
Kvid
:
any
;
children
:
any
;
ParentKvid
:
undefined
})
=>
{
return
cloneData
.
filter
((
father
:
{
Kvid
:
any
;
children
:
any
;
ParentKvid
:
undefined
})
=>
{
const
branchArr
=
cloneData
.
filter
((
child
:
{
ParentKvid
:
any
})
=>
father
.
Kvid
===
child
.
ParentKvid
);
const
branchArr
=
cloneData
.
filter
((
child
:
{
ParentKvid
:
any
})
=>
father
.
Kvid
===
child
.
ParentKvid
);
...
@@ -226,7 +238,10 @@ function getMenuThree(data: any) {
...
@@ -226,7 +238,10 @@ function getMenuThree(data: any) {
return
father
.
ParentKvid
==
undefined
;
return
father
.
ParentKvid
==
undefined
;
});
});
}
}
function
generateRoutes
(
data
:
any
[])
{
function
generateRoutes
(
data
:
any
[])
{
if
(
!
data
||
!
Array
.
isArray
(
data
))
return
[];
return
data
.
map
(
item
=>
{
return
data
.
map
(
item
=>
{
const
route
:
any
=
{
const
route
:
any
=
{
name
:
item
.
Type
===
'System'
?
`
${
item
.
Type
}
`
:
item
.
Kvid
,
name
:
item
.
Type
===
'System'
?
`
${
item
.
Type
}
`
:
item
.
Kvid
,
...
@@ -270,11 +285,12 @@ function generateRoutes(data: any[]) {
...
@@ -270,11 +285,12 @@ function generateRoutes(data: any[]) {
return
route
;
return
route
;
});
});
}
}
export
function
createStaticRoutes
()
{
export
function
createStaticRoutes
()
{
const
constantRoutes
:
ElegantRoute
[]
=
[];
const
constantRoutes
:
ElegantRoute
[]
=
[];
const
authRoutes
:
ElegantRoute
[]
=
[];
const
authRoutes
:
ElegantRoute
[]
=
[];
[...
customRoutes
,
...
generatedRoutes
].
forEach
(
item
=>
{
[...
customRoutes
,
...
dynamicMenuRoutes
,
...
generatedRoutes
].
forEach
(
item
=>
{
if
(
item
.
meta
?.
constant
)
{
if
(
item
.
meta
?.
constant
)
{
constantRoutes
.
push
(
item
);
constantRoutes
.
push
(
item
);
}
else
{
}
else
{
...
@@ -296,3 +312,14 @@ export function createStaticRoutes() {
...
@@ -296,3 +312,14 @@ export function createStaticRoutes() {
export
function
getAuthVueRoutes
(
routes
:
ElegantConstRoute
[])
{
export
function
getAuthVueRoutes
(
routes
:
ElegantConstRoute
[])
{
return
transformElegantRoutesToVueRoutes
(
routes
,
layouts
,
views
);
return
transformElegantRoutesToVueRoutes
(
routes
,
layouts
,
views
);
}
}
// 初始化时生成一次动态路由(兼容性)
// 确保在浏览器环境且必要的全局配置已准备好时才执行
if
(
typeof
window
!==
'undefined'
&&
window
.
uiGlobalConfig
?.
InternalCode
)
{
// 使用 setTimeout 确保应用完全初始化后再执行
setTimeout
(()
=>
{
generateDynamicRoutes
().
catch
(
error
=>
{
console
.
warn
(
'Initial dynamic route generation failed:'
,
error
);
});
},
100
);
}
src/store/modules/auth/index.ts
View file @
07405b7b
import
{
json
}
from
'node:stream/consumers'
;
import
{
computed
,
reactive
,
ref
}
from
'vue'
;
import
{
computed
,
reactive
,
ref
}
from
'vue'
;
import
{
useRoute
}
from
'vue-router'
;
import
{
useRoute
}
from
'vue-router'
;
import
{
defineStore
}
from
'pinia'
;
import
{
defineStore
}
from
'pinia'
;
import
{
useLoading
}
from
'@sa/hooks'
;
import
{
useLoading
}
from
'@sa/hooks'
;
import
{
SetupStoreId
}
from
'@/enum'
;
import
{
SetupStoreId
}
from
'@/enum'
;
import
{
useRouterPush
}
from
'@/hooks/common/router'
;
import
{
useRouterPush
}
from
'@/hooks/common/router'
;
import
{
fetch
GetUserInfo
,
fetch
Login
,
fetchLogout
}
from
'@/service/api'
;
import
{
fetchLogin
,
fetchLogout
}
from
'@/service/api'
;
import
{
localStg
}
from
'@/utils/storage'
;
import
{
localStg
}
from
'@/utils/storage'
;
import
{
$t
}
from
'@/locales'
;
import
{
$t
}
from
'@/locales'
;
import
{
useRouteStore
}
from
'../route'
;
import
{
useRouteStore
}
from
'../route'
;
...
@@ -81,6 +80,42 @@ export const useAuthStore = defineStore(SetupStoreId.Auth, () => {
...
@@ -81,6 +80,42 @@ export const useAuthStore = defineStore(SetupStoreId.Auth, () => {
}
}
}
}
/** Handle successful login redirect */
async
function
handleLoginRedirect
()
{
try
{
await
redirectFromLogin
();
// 显示成功通知
window
.
$notification
?.
success
({
title
:
$t
(
'page.login.common.loginSuccess'
),
content
:
$t
(
'page.login.common.welcomeBack'
,
{
FullName
:
userInfo
.
FullName
}),
duration
:
4500
});
}
catch
(
redirectError
)
{
console
.
error
(
'Redirect error:'
,
redirectError
);
// 如果重定向失败,直接跳转到首页
window
.
location
.
href
=
'/home'
;
}
}
/** Initialize routes after login */
async
function
initializeAuthRoutes
(
redirect
:
boolean
)
{
await
routeStore
.
forceReloadAuthRoute
();
if
(
!
routeStore
.
isInitAuthRoute
)
{
console
.
error
(
'Failed to initialize auth routes'
);
throw
new
Error
(
'Route initialization failed'
);
}
// 确保菜单也更新了
await
routeStore
.
updateGlobalMenusByLocale
();
if
(
redirect
)
{
// 延迟执行重定向,确保路由完全加载
setTimeout
(()
=>
handleLoginRedirect
(),
300
);
}
}
/**
/**
* Login
* Login
*
*
...
@@ -91,37 +126,35 @@ export const useAuthStore = defineStore(SetupStoreId.Auth, () => {
...
@@ -91,37 +126,35 @@ export const useAuthStore = defineStore(SetupStoreId.Auth, () => {
async
function
login
(
userName
:
string
,
password
:
string
,
redirect
=
true
)
{
async
function
login
(
userName
:
string
,
password
:
string
,
redirect
=
true
)
{
startLoading
();
startLoading
();
const
{
data
:
loginToken
,
error
}
=
await
fetchLogin
(
userName
,
password
);
try
{
if
(
!
error
)
{
const
{
data
:
loginToken
,
error
}
=
await
fetchLogin
(
userName
,
password
);
if
(
error
)
{
resetStore
();
return
;
}
const
pass
=
await
loginByToken
(
loginToken
);
const
pass
=
await
loginByToken
(
loginToken
);
if
(
!
pass
)
{
resetStore
();
return
;
}
if
(
pass
)
{
// 设置认证状态为true
// 设置认证状态为true
if
(
window
.
uiGlobalConfig
)
{
if
(
window
.
uiGlobalConfig
)
{
window
.
uiGlobalConfig
.
IsAuthenticated
=
true
;
window
.
uiGlobalConfig
.
IsAuthenticated
=
true
;
}
}
// 初始化路由
try
{
await
routeStore
.
initAuthRoute
();
await
initializeAuthRoutes
(
redirect
);
}
catch
(
routeError
)
{
// 等待路由初始化完成
console
.
error
(
'Route loading error:'
,
routeError
);
if
(
routeStore
.
isInitAuthRoute
)
{
// 如果路由初始化失败,尝试刷新页面作为备用方案
if
(
redirect
)
{
setTimeout
(()
=>
{
// 先执行重定向
window
.
location
.
reload
();
await
redirectFromLogin
();
},
1000
);
// 延迟一下再刷新,确保重定向已完成
setTimeout
(()
=>
{
window
.
location
.
reload
();
window
.
$notification
?.
success
({
title
:
$t
(
'page.login.common.loginSuccess'
),
content
:
$t
(
'page.login.common.welcomeBack'
,
{
FullName
:
userInfo
.
FullName
}),
duration
:
4500
});
},
500
);
}
}
}
}
}
else
{
}
catch
(
loginError
)
{
console
.
error
(
'Login error:'
,
loginError
);
resetStore
();
resetStore
();
}
}
...
@@ -135,30 +168,12 @@ export const useAuthStore = defineStore(SetupStoreId.Auth, () => {
...
@@ -135,30 +168,12 @@ export const useAuthStore = defineStore(SetupStoreId.Auth, () => {
localStg
.
set
(
'userInfo'
,
JSON
.
stringify
(
loginToken
));
localStg
.
set
(
'userInfo'
,
JSON
.
stringify
(
loginToken
));
// 2. get user info
// 2. get user info
// const pass = await getUserInfo();
// if (pass) {
token
.
value
=
loginToken
.
FullName
;
token
.
value
=
loginToken
.
FullName
;
Object
.
assign
(
userInfo
,
loginToken
);
Object
.
assign
(
userInfo
,
loginToken
);
// return true;
// }
return
true
;
return
true
;
}
}
async
function
getUserInfo
()
{
const
{
data
:
info
,
error
}
=
await
fetchGetUserInfo
();
if
(
!
error
)
{
// update store
Object
.
assign
(
userInfo
,
info
);
return
true
;
}
return
false
;
}
async
function
initUserInfo
()
{
async
function
initUserInfo
()
{
const
hasToken
=
getToken
();
const
hasToken
=
getToken
();
const
userInfoStr
=
getLocalUserInfo
();
const
userInfoStr
=
getLocalUserInfo
();
...
...
src/store/modules/route/index.ts
View file @
07405b7b
...
@@ -5,7 +5,7 @@ import { useBoolean } from '@sa/hooks';
...
@@ -5,7 +5,7 @@ import { useBoolean } from '@sa/hooks';
import
type
{
CustomRoute
,
ElegantConstRoute
,
LastLevelRouteKey
,
RouteKey
,
RouteMap
}
from
'@elegant-router/types'
;
import
type
{
CustomRoute
,
ElegantConstRoute
,
LastLevelRouteKey
,
RouteKey
,
RouteMap
}
from
'@elegant-router/types'
;
import
{
SetupStoreId
}
from
'@/enum'
;
import
{
SetupStoreId
}
from
'@/enum'
;
import
{
router
}
from
'@/router'
;
import
{
router
}
from
'@/router'
;
import
{
createStaticRoutes
,
getAuthVueRoutes
}
from
'@/router/routes'
;
import
{
createStaticRoutes
,
ge
nerateDynamicRoutes
,
ge
tAuthVueRoutes
}
from
'@/router/routes'
;
import
{
ROOT_ROUTE
}
from
'@/router/routes/builtin'
;
import
{
ROOT_ROUTE
}
from
'@/router/routes/builtin'
;
import
{
getRouteName
,
getRoutePath
}
from
'@/router/elegant/transform'
;
import
{
getRouteName
,
getRoutePath
}
from
'@/router/elegant/transform'
;
import
{
fetchGetConstantRoutes
,
fetchGetUserRoutes
,
fetchIsRouteExist
}
from
'@/service/api'
;
import
{
fetchGetConstantRoutes
,
fetchGetUserRoutes
,
fetchIsRouteExist
}
from
'@/service/api'
;
...
@@ -227,6 +227,24 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => {
...
@@ -227,6 +227,24 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => {
tabStore
.
initHomeTab
();
tabStore
.
initHomeTab
();
}
}
/** Force reload auth route - 强制重新加载路由 */
async
function
forceReloadAuthRoute
()
{
// 重置路由状态
setIsInitAuthRoute
(
false
);
// 清除现有路由
resetVueRoutes
();
// 清除现有的auth routes
authRoutes
.
value
=
[];
// 重新生成动态路由数据
await
generateDynamicRoutes
();
// 重新初始化路由
await
initAuthRoute
();
}
/** Init static auth route */
/** Init static auth route */
function
initStaticAuthRoute
()
{
function
initStaticAuthRoute
()
{
const
{
authRoutes
:
staticAuthRoutes
}
=
createStaticRoutes
();
const
{
authRoutes
:
staticAuthRoutes
}
=
createStaticRoutes
();
...
@@ -246,9 +264,10 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => {
...
@@ -246,9 +264,10 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => {
/** Init dynamic auth route */
/** Init dynamic auth route */
async
function
initDynamicAuthRoute
()
{
async
function
initDynamicAuthRoute
()
{
// 首先尝试使用后端接口获取路由
const
{
data
,
error
}
=
await
fetchGetUserRoutes
();
const
{
data
,
error
}
=
await
fetchGetUserRoutes
();
if
(
!
error
)
{
if
(
!
error
&&
data
?.
routes
)
{
const
{
routes
,
home
}
=
data
;
const
{
routes
,
home
}
=
data
;
addAuthRoutes
(
routes
);
addAuthRoutes
(
routes
);
...
@@ -261,8 +280,22 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => {
...
@@ -261,8 +280,22 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => {
setIsInitAuthRoute
(
true
);
setIsInitAuthRoute
(
true
);
}
else
{
}
else
{
// if fetch user routes failed, reset store
// 如果后端接口获取失败,使用静态路由模式
authStore
.
resetStore
();
console
.
warn
(
'Dynamic route fetch failed, fallback to static routes'
);
// 重新创建静态路由(这会重新调用接口获取最新菜单数据)
const
{
authRoutes
:
staticAuthRoutes
}
=
createStaticRoutes
();
if
(
authStore
.
isStaticSuper
)
{
addAuthRoutes
(
staticAuthRoutes
);
}
else
{
const
filteredAuthRoutes
=
filterAuthRoutesByRoles
(
staticAuthRoutes
,
authStore
.
userInfo
.
roles
);
addAuthRoutes
(
filteredAuthRoutes
);
}
handleConstantAndAuthRoutes
();
setIsInitAuthRoute
(
true
);
}
}
}
}
...
@@ -381,6 +414,7 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => {
...
@@ -381,6 +414,7 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => {
initConstantRoute
,
initConstantRoute
,
isInitConstantRoute
,
isInitConstantRoute
,
initAuthRoute
,
initAuthRoute
,
forceReloadAuthRoute
,
isInitAuthRoute
,
isInitAuthRoute
,
setIsInitAuthRoute
,
setIsInitAuthRoute
,
getIsAuthRouteExist
,
getIsAuthRouteExist
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment