Skip to content

Commit d33a8a4

Browse files
authored
Merge pull request #1989 from bypanghu/main
fix: 添加内部 iframe 展示网页,优化 permission.js 逻辑
2 parents 9c7abf7 + 0682000 commit d33a8a4

File tree

11 files changed

+323
-131
lines changed

11 files changed

+323
-131
lines changed

web/src/components/commandMenu/index.vue

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@
5454
const options = reactive([])
5555
const deepMenus = (menus) => {
5656
const arr = []
57-
menus.forEach((menu) => {
57+
menus?.forEach((menu) => {
58+
if (!menu?.children) return
5859
if (menu.children && menu.children.length > 0) {
5960
arr.push(...deepMenus(menu.children))
6061
} else {
@@ -77,7 +78,7 @@
7778
label: '跳转',
7879
children: []
7980
}
80-
const menus = deepMenus(routerStore.asyncRouters[0].children)
81+
const menus = deepMenus(routerStore.asyncRouters[0]?.children || [])
8182
option.children.push(...menus)
8283
options.push(option)
8384
}

web/src/pathInfo.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"/src/view/layout/aside/normalMode.vue": "GvaAside",
2828
"/src/view/layout/header/index.vue": "Index",
2929
"/src/view/layout/header/tools.vue": "Tools",
30+
"/src/view/layout/iframe.vue": "GvaLayoutIframe",
3031
"/src/view/layout/index.vue": "GvaLayout",
3132
"/src/view/layout/screenfull/index.vue": "Screenfull",
3233
"/src/view/layout/search/search.vue": "BtnBox",

web/src/permission.js

Lines changed: 102 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -4,134 +4,143 @@ import getPageTitle from '@/utils/page'
44
import router from '@/router'
55
import Nprogress from 'nprogress'
66
import 'nprogress/nprogress.css'
7-
Nprogress.configure({ showSpinner: false, ease: 'ease', speed: 500 })
87

9-
const whiteList = ['Login', 'Init']
8+
// 配置 NProgress
9+
Nprogress.configure({
10+
showSpinner: false,
11+
ease: 'ease',
12+
speed: 500
13+
})
1014

11-
const getRouter = async (userStore) => {
12-
const routerStore = useRouterStore()
13-
await routerStore.SetAsyncRouter()
14-
await userStore.GetUserInfo()
15-
const asyncRouters = routerStore.asyncRouters
16-
asyncRouters.forEach((asyncRouter) => {
17-
router.addRoute(asyncRouter)
18-
})
15+
// 白名单路由
16+
const WHITE_LIST = ['Login', 'Init', 'Iframe']
17+
18+
// 处理路由加载
19+
const setupRouter = async (userStore) => {
20+
try {
21+
const routerStore = useRouterStore()
22+
await Promise.all([routerStore.SetAsyncRouter(), userStore.GetUserInfo()])
23+
24+
routerStore.asyncRouters.forEach((route) => router.addRoute(route))
25+
return true
26+
} catch (error) {
27+
console.error('Setup router failed:', error)
28+
return false
29+
}
1930
}
2031

32+
// 移除加载动画
2133
const removeLoading = () => {
2234
const element = document.getElementById('gva-loading-box')
23-
if (element) {
24-
element.remove()
25-
}
35+
element?.remove()
2636
}
2737

28-
async function handleKeepAlive(to) {
29-
if (to.matched.some((item) => item.meta.keepAlive)) {
30-
if (to.matched && to.matched.length > 2) {
31-
for (let i = 1; i < to.matched.length; i++) {
32-
const element = to.matched[i - 1]
33-
if (element.name === 'layout') {
34-
to.matched.splice(i, 1)
35-
await handleKeepAlive(to)
36-
}
37-
// 如果没有按需加载完成则等待加载
38-
if (typeof element.components.default === 'function') {
39-
await element.components.default()
40-
await handleKeepAlive(to)
41-
}
38+
// 处理组件缓存
39+
const handleKeepAlive = async (to) => {
40+
if (!to.matched.some((item) => item.meta.keepAlive)) return
41+
42+
if (to.matched?.length > 2) {
43+
for (let i = 1; i < to.matched.length; i++) {
44+
const element = to.matched[i - 1]
45+
46+
if (element.name === 'layout') {
47+
to.matched.splice(i, 1)
48+
await handleKeepAlive(to)
49+
continue
50+
}
51+
52+
if (typeof element.components.default === 'function') {
53+
await element.components.default()
54+
await handleKeepAlive(to)
4255
}
4356
}
4457
}
4558
}
4659

60+
// 处理路由重定向
61+
const handleRedirect = (to, userStore) => {
62+
if (router.hasRoute(userStore.userInfo.authority.defaultRouter)) {
63+
return { ...to, replace: true }
64+
}
65+
return { path: '/layout/404' }
66+
}
67+
68+
// 路由守卫
4769
router.beforeEach(async (to, from) => {
70+
const userStore = useUserStore()
4871
const routerStore = useRouterStore()
72+
const token = userStore.token
73+
4974
Nprogress.start()
50-
const userStore = useUserStore()
75+
76+
// 处理元数据和缓存
5177
to.meta.matched = [...to.matched]
52-
handleKeepAlive(to)
53-
const token = userStore.token
54-
// 在白名单中的判断情况
78+
await handleKeepAlive(to)
79+
80+
// 设置页面标题
5581
document.title = getPageTitle(to.meta.title, to)
82+
5683
if (to.meta.client) {
5784
return true
5885
}
59-
if (whiteList.indexOf(to.name) > -1) {
60-
if (token) {
61-
if (!routerStore.asyncRouterFlag && whiteList.indexOf(from.name) < 0) {
62-
await getRouter(userStore)
63-
}
64-
// token 可以解析但是却是不存在的用户 id 或角色 id 会导致无限调用
65-
if (userStore.userInfo?.authority?.defaultRouter != null) {
66-
if (router.hasRoute(userStore.userInfo.authority.defaultRouter)) {
67-
return { name: userStore.userInfo.authority.defaultRouter }
68-
} else {
69-
return { path: '/layout/404' }
70-
}
71-
} else {
72-
// 强制退出账号
73-
userStore.ClearStorage()
74-
return {
75-
name: 'Login',
76-
query: {
77-
redirect: document.location.hash
78-
}
79-
}
80-
}
81-
} else {
82-
return true
86+
87+
// 白名单路由处理
88+
if (WHITE_LIST.includes(to.name)) {
89+
if (
90+
token &&
91+
!routerStore.asyncRouterFlag &&
92+
!WHITE_LIST.includes(from.name)
93+
) {
94+
await setupRouter(userStore)
8395
}
84-
} else {
85-
// 不在白名单中并且已经登录的时候
86-
if (token) {
87-
if (sessionStorage.getItem('needToHome') === 'true') {
88-
sessionStorage.removeItem('needToHome')
89-
return { path: '/' }
90-
}
91-
// 添加flag防止多次获取动态路由和栈溢出
92-
if (!routerStore.asyncRouterFlag && whiteList.indexOf(from.name) < 0) {
93-
await getRouter(userStore)
94-
if (userStore.token) {
95-
if (router.hasRoute(userStore.userInfo.authority.defaultRouter)) {
96-
return { ...to, replace: true }
97-
} else {
98-
return { path: '/layout/404' }
99-
}
100-
} else {
101-
return {
102-
name: 'Login',
103-
query: { redirect: to.href }
104-
}
105-
}
106-
} else {
107-
if (to.matched.length) {
108-
return true
109-
} else {
110-
return { path: '/layout/404' }
111-
}
112-
}
96+
return true
97+
}
98+
99+
// 需要登录的路由处理
100+
if (token) {
101+
// 处理需要跳转到首页的情况
102+
if (sessionStorage.getItem('needToHome') === 'true') {
103+
sessionStorage.removeItem('needToHome')
104+
return { path: '/' }
113105
}
114-
// 不在白名单中并且未登录的时候
115-
if (!token) {
106+
107+
// 处理异步路由
108+
if (!routerStore.asyncRouterFlag && !WHITE_LIST.includes(from.name)) {
109+
const setupSuccess = await setupRouter(userStore)
110+
111+
if (setupSuccess && userStore.token) {
112+
return handleRedirect(to, userStore)
113+
}
114+
116115
return {
117116
name: 'Login',
118-
query: {
119-
redirect: document.location.hash
120-
}
117+
query: { redirect: to.href }
121118
}
122119
}
120+
121+
return to.matched.length ? true : { path: '/layout/404' }
122+
}
123+
124+
// 未登录跳转登录页
125+
return {
126+
name: 'Login',
127+
query: {
128+
redirect: document.location.hash
129+
}
123130
}
124131
})
125132

133+
// 路由加载完成
126134
router.afterEach(() => {
127-
// 路由加载完成后关闭进度条
128-
document.getElementsByClassName('main-cont main-right')[0]?.scrollTo(0, 0)
135+
document.querySelector('.main-cont.main-right')?.scrollTo(0, 0)
129136
Nprogress.done()
130137
})
131138

132-
router.onError(() => {
133-
// 路由发生错误后销毁进度条
139+
// 路由错误处理
140+
router.onError((error) => {
141+
console.error('Router error:', error)
134142
Nprogress.remove()
135143
})
136144

145+
// 移除初始加载动画
137146
removeLoading()

web/src/router/index.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ const routes = [
2121
closeTab: true
2222
},
2323
component: () => import('@/view/error/index.vue')
24+
},
25+
{
26+
path: '/iframe',
27+
name: 'Iframe',
28+
component: () => import('@/view/layout/iframe.vue')
2429
}
2530
]
2631

web/src/view/dashboard/index.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@
22
<div
33
class="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-7 py-2 gap-4 md:gap-2 gva-container2"
44
>
5-
<gva-card custom-class="col-span-1 lg:col-span-2 h-32">
5+
<gva-card custom-class="col-span-1 lg:col-span-2 ">
66
<gva-chart :type="1" title="访问人数" />
77
</gva-card>
8-
<gva-card custom-class="col-span-1 lg:col-span-2 h-32 ">
8+
<gva-card custom-class="col-span-1 lg:col-span-2 ">
99
<gva-chart :type="2" title="新增客户" />
1010
</gva-card>
11-
<gva-card custom-class="col-span-1 lg:col-span-2 h-32">
11+
<gva-card custom-class="col-span-1 lg:col-span-2 ">
1212
<gva-chart :type="3" title="解决数量" />
1313
</gva-card>
1414
<gva-card
1515
title="快捷功能"
1616
show-action
17-
custom-class="col-start-1 md:col-start-3 lg:col-start-7 row-span-2 h-38"
17+
custom-class="col-start-1 md:col-start-3 lg:col-start-7 row-span-2 "
1818
>
1919
<gva-quick-link />
2020
</gva-card>

web/src/view/layout/aside/combinationMode.vue

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@
9797
})
9898
9999
watchEffect(() => {
100+
if (route.name === 'Iframe') {
101+
active.value = decodeURIComponent(route.query.url)
102+
return
103+
}
100104
active.value = route.meta.activeName || route.name
101105
})
102106
@@ -123,7 +127,18 @@
123127
})
124128
if (index === route.name) return
125129
if (index.indexOf('http://') > -1 || index.indexOf('https://') > -1) {
126-
window.open(index)
130+
if (index === 'Iframe') {
131+
query.url = decodeURIComponent(index)
132+
router.push({
133+
name: 'Iframe',
134+
query,
135+
params
136+
})
137+
return
138+
} else {
139+
window.open(index, '_blank')
140+
return
141+
}
127142
} else {
128143
if (!top) {
129144
router.push({ name: index, query, params })

web/src/view/layout/aside/headMode.vue

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@
4040
const isCollapse = ref(false)
4141
const active = ref('')
4242
watchEffect(() => {
43+
if (route.name === 'Iframe') {
44+
active.value = decodeURIComponent(route.query.url)
45+
return
46+
}
4347
active.value = route.meta.activeName || route.name
4448
})
4549
@@ -66,7 +70,18 @@
6670
})
6771
if (index === route.name) return
6872
if (index.indexOf('http://') > -1 || index.indexOf('https://') > -1) {
69-
window.open(index)
73+
if (index === 'Iframe') {
74+
query.url = decodeURIComponent(index)
75+
router.push({
76+
name: 'Iframe',
77+
query,
78+
params
79+
})
80+
return
81+
} else {
82+
window.open(index, '_blank')
83+
return
84+
}
7085
} else {
7186
router.push({ name: index, query, params })
7287
}

0 commit comments

Comments
 (0)