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
33d487e1
Commit
33d487e1
authored
Feb 20, 2025
by
高源
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
默认首页功能支持
parent
50789fd1
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
186 additions
and
43 deletions
+186
-43
index.html
dist/index.html
+2
-2
index.ts
src/router/routes/index.ts
+19
-7
rootMenu.ts
src/service/api/rootMenu.ts
+6
-0
index.ts
src/store/modules/route/index.ts
+17
-1
api.d.ts
src/typings/api.d.ts
+8
-0
global.d.ts
src/typings/global.d.ts
+4
-0
[url].vue
src/views/_builtin/iframe-page/[url].vue
+44
-16
index.vue
src/views/home/index.vue
+86
-17
No files found.
dist/index.html
View file @
33d487e1
<!doctype html>
<html
lang=
"zh-cmn-Hans"
>
<head>
<meta
name=
"buildTime"
content=
"2025-02-
07 10:12:47
"
>
<meta
name=
"buildTime"
content=
"2025-02-
20 09:28:58
"
>
<meta
charset=
"UTF-8"
/>
<link
rel=
"icon"
href=
"/favicon.svg"
/>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0"
/>
<meta
name=
"color-scheme"
content=
"light dark"
/>
<title>
VueDashboard
</title>
<script
type=
"module"
crossorigin
src=
"/Content/VueDashboardUi/VueDashboard1/assets/index-
CPk3udR2
.js"
></script>
<script
type=
"module"
crossorigin
src=
"/Content/VueDashboardUi/VueDashboard1/assets/index-
u5iQYcYA
.js"
></script>
<link
rel=
"stylesheet"
crossorigin
href=
"/Content/VueDashboardUi/VueDashboard1/assets/index-9k_B1ZU8.css"
>
</head>
<body>
...
...
src/router/routes/index.ts
View file @
33d487e1
/* eslint-disable no-plusplus */
import
{
truncate
}
from
'node:fs/promises'
;
import
type
{
CustomRoute
,
ElegantConstRoute
,
ElegantRoute
}
from
'@elegant-router/types'
;
import
{
getRootMenu
}
from
'@/service/api'
;
import
{
useRouteStore
}
from
'@/store/modules/route'
;
import
{
generatedRoutes
}
from
'../elegant/routes'
;
import
{
layouts
,
views
}
from
'../elegant/imports'
;
import
{
transformElegantRoutesToVueRoutes
}
from
'../elegant/transform'
;
import
{
truncate
}
from
'fs/promises'
;
/**
* custom routes
*
...
...
@@ -53,7 +54,6 @@ const customRoutes: CustomRoute[] = [
// icon: 'ic:baseline-wifi-off'
// }
// },
// ]
// }
// {
...
...
@@ -187,13 +187,24 @@ const customRoutes: CustomRoute[] = [
* @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 { 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 rootMenu =getRootMenu('/Restful/Kivii.Basic.Entities.Menu/Show.json?RootInternalCode=Dashboard');
const
MenuThree
=
await
getMenuThree
(
menus
?.
MenusMain
?.
Results
);
const
MenuRoot
=
menus
?.
MenuRoot
;
console
.
log
(
MenuRoot
);
// 存储 MenuRoot 到 store
if
(
MenuRoot
)
{
setTimeout
(()
=>
{
const
routeStore
=
useRouteStore
();
routeStore
.
setMenuRoot
(
MenuRoot
);
},
1000
);
}
const
MenuThree2
=
generateRoutes
(
MenuThree
);
if
(
MenuThree2
.
length
>
0
)
{
for
(
let
i
=
0
;
i
<
MenuThree2
.
length
;
i
++
)
{
...
...
@@ -248,7 +259,8 @@ function generateRoutes(data: any[]) {
type
:
'iframe'
}
};
});
}
);
}
return
route
;
...
...
src/service/api/rootMenu.ts
View file @
33d487e1
...
...
@@ -12,3 +12,9 @@ export function getSelectMenu(urlValue: string) {
method
:
'post'
});
}
export
function
getDefaultMenu
(
urlValue
:
string
)
{
return
request
<
Api
.
RootMenu
.
Selectmenu
>
({
url
:
urlValue
,
method
:
'post'
});
}
src/store/modules/route/index.ts
View file @
33d487e1
...
...
@@ -354,6 +354,20 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => {
return
getSelectedMenuKeyPathByKey
(
selectedKey
,
menus
.
value
);
}
// 添加MenuRoot存储
const
menuRoot
=
ref
<
Api
.
Menu
.
MenuRoot
|
null
>
(
null
);
/** 设置MenuRoot 如果数据不包含Kvid字段则返回不存储 */
function
setMenuRoot
(
data
:
Api
.
Menu
.
MenuRoot
)
{
if
(
!
data
.
Kvid
)
{
console
.
log
(
'MenuRoot数据不包含Kvid字段,不进行存储'
);
return
;
}
menuRoot
.
value
=
data
;
console
.
log
(
'MenuRoot数据:'
,
data
);
}
return
{
resetStore
,
routeHome
,
...
...
@@ -370,6 +384,8 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => {
isInitAuthRoute
,
setIsInitAuthRoute
,
getIsAuthRouteExist
,
getSelectedMenuKeyPath
getSelectedMenuKeyPath
,
menuRoot
,
setMenuRoot
};
});
src/typings/api.d.ts
View file @
33d487e1
...
...
@@ -72,6 +72,7 @@ declare namespace Api {
MenusMain
:
{
Results
:
any
;
};
MenuRoot
:
any
;
};
// 这里定义 menu 为一个空对象类型
export
type
Selectmenu
=
{
Data
:
{
...
...
@@ -99,4 +100,11 @@ declare namespace Api {
home
:
import
(
'@elegant-router/types'
).
LastLevelRouteKey
;
}
}
namespace
Menu
{
interface
MenuRoot
{
Kvid
:
string
;
// ... 其他字段
}
}
}
src/typings/global.d.ts
View file @
33d487e1
...
...
@@ -12,6 +12,10 @@ declare global {
$message
?:
import
(
'naive-ui'
).
MessageProviderInst
;
/** Notification instance */
$notification
?:
import
(
'naive-ui'
).
NotificationProviderInst
;
uiGlobalConfig
:
{
InternalCode
:
string
;
[
key
:
string
]:
any
;
}
}
interface
ViewTransition
{
...
...
src/views/_builtin/iframe-page/[url].vue
View file @
33d487e1
<!-- eslint-disable no-console -->
<!-- eslint-disable @typescript-eslint/no-shadow -->
<
script
setup
lang=
"ts"
>
import
{
onActivated
,
onMounted
,
ref
,
shallowRef
}
from
'vue'
;
import
{
nextTick
,
onActivated
,
onMounted
,
ref
,
shallowRef
,
watch
}
from
'vue'
;
import
{
loadModule
}
from
'vue3-sfc-loader'
;
import
{
getSelectMenu
}
from
'@/service/api'
;
import
NotFound
from
'@/views/_builtin/404/index.vue'
;
// 引入 404 组件
...
...
@@ -14,7 +14,6 @@ interface Props {
kvid
:
string
;
type
:
string
;
}
// 定义响应式变量
const
asyncComponent
=
shallowRef
<
any
>
(
null
);
const
{
url
,
kvid
,
type
}
=
defineProps
<
Props
>
();
...
...
@@ -57,20 +56,15 @@ const loadExternalComponent = async (url: string) => {
});
};
onMounted
(()
=>
{
// console.log('mounted');
const
origin
=
window
.
location
.
origin
;
origin
.
split
(
'/'
).
slice
(
0
,
3
).
join
(
'/'
);
// loadExternalComponent(`${origin}/codet/testComponent.vue`);
// loadExternalComponent(`localhost:8081//src/views/_builtin/iframe-page/extJs.vue`);
});
// 将处理逻辑抽取为函数
const
handleMenuAccess
=
async
()
=>
{
if
(
!
type
||
!
kvid
)
return
;
onActivated
(
async
()
=>
{
// console.log('activated');
const
origin
=
window
.
location
.
origin
;
origin
.
split
(
'/'
).
slice
(
0
,
3
).
join
(
'/'
);
// 确保 DOM 已准备好
await
nextTick
();
// const origin = 'http://localhost:80';
console
.
log
(
'Processing:'
,
{
url
,
kvid
,
type
});
const
origin
=
window
.
location
.
origin
;
if
(
type
===
'System'
)
{
console
.
log
(
url
);
...
...
@@ -84,14 +78,25 @@ onActivated(async () => {
}
else
{
selectTag
.
value
=
`
${
origin
}
/
${
url
}
`
;
}
console
.
log
(
'url1:'
,
url
);
console
.
log
(
'kvid1:'
,
kvid
);
console
.
log
(
'type1:'
,
type
);
}
else
{
console
.
log
(
'url2:'
,
url
);
console
.
log
(
'kvid2:'
,
kvid
);
console
.
log
(
'type2:'
,
type
);
try
{
const
{
data
:
selectMenu
}
=
await
getSelectMenu
(
`/Restful/Kivii.Basic.Entities.Function/Access.json?MenuKvids=
${
kvid
}
`
);
if
(
selectMenu
?.
Results
!==
undefined
&&
selectMenu
?.
Results
.
length
>
0
)
{
if
(
selectMenu
?.
Results
?.
length
>
0
)
{
const
handler
=
selectMenu
.
Results
[
0
].
Handler
;
if
(
handler
.
slice
(
0
,
1
)
===
'/'
)
{
// 确保在设置 extTag 之前 DOM 已准备好
if
(
!
handler
.
startsWith
(
'/'
)
&&
!
handler
.
endsWith
(
'.vue'
))
{
await
nextTick
();
extTag
.
value
=
handler
;
}
else
if
(
handler
.
slice
(
0
,
1
)
===
'/'
)
{
// 先判断是否以/开头
if
(
handler
.
endsWith
(
'.vue'
))
{
// 如果以.vue结尾
...
...
@@ -108,9 +113,32 @@ onActivated(async () => {
hasError
.
value
=
true
;
}
}
catch
(
error
)
{
console
.
error
(
'Menu access error:'
,
error
);
hasError
.
value
=
true
;
}
}
};
// 监听 props 变化
watch
(
[()
=>
type
,
()
=>
kvid
,
()
=>
url
],
()
=>
{
handleMenuAccess
();
},
{
immediate
:
true
}
);
// onActivated 时也执行
onActivated
(()
=>
{
handleMenuAccess
();
});
onMounted
(()
=>
{
// console.log('mounted');
const
origin
=
window
.
location
.
origin
;
origin
.
split
(
'/'
).
slice
(
0
,
3
).
join
(
'/'
);
// loadExternalComponent(`${origin}/codet/testComponent.vue`);
// loadExternalComponent(`localhost:8081//src/views/_builtin/iframe-page/extJs.vue`);
});
</
script
>
...
...
src/views/home/index.vue
View file @
33d487e1
<
script
setup
lang=
"ts"
>
import
{
compu
ted
}
from
'vue'
;
import
{
onActivated
,
onDeactivated
,
computed
,
watch
,
ref
,
onMounted
,
onUnmoun
ted
}
from
'vue'
;
import
{
useAppStore
}
from
'@/store/modules/app'
;
import
{
useRouteStore
}
from
'@/store/modules/route'
;
import
HeaderBanner
from
'./modules/header-banner.vue'
;
import
CardData
from
'./modules/card-data.vue'
;
import
LineChart
from
'./modules/line-chart.vue'
;
import
PieChart
from
'./modules/pie-chart.vue'
;
import
ProjectNews
from
'./modules/project-news.vue'
;
import
CreativityBanner
from
'./modules/creativity-banner.vue'
;
import
IframePage
from
'@/views/_builtin/iframe-page/[url].vue'
;
import
{
getDefaultMenu
}
from
'@/service/api'
;
const
appStore
=
useAppStore
();
const
routeStore
=
useRouteStore
();
// 控制组件显示状态的变量
const
isActive
=
ref
(
true
);
const
extjsContainerId
=
`menuRoot-
${
Math
.
random
().
toString
(
36
).
substr
(
2
,
9
)}
`
;
// 获取 MenuRoot
const
menuRoot
=
computed
(()
=>
routeStore
.
menuRoot
);
// 添加状态管理自动启动项
const
autoStartProps
=
ref
({
type
:
''
,
kvid
:
''
,
url
:
''
});
// 添加 extjs-root 就绪状态
const
isExtjsRootReady
=
ref
(
false
);
// 检查 extjs-root 是否存在
const
checkExtjsRoot
=
()
=>
{
const
extjsRoot
=
document
.
getElementById
(
'extjs-root'
);
isExtjsRootReady
.
value
=
!!
extjsRoot
;
if
(
!
extjsRoot
)
{
setTimeout
(
checkExtjsRoot
,
100
);
// 继续检查
}
};
onMounted
(()
=>
{
checkExtjsRoot
();
isActive
.
value
=
true
;
});
onActivated
(()
=>
{
isActive
.
value
=
true
;
});
onDeactivated
(()
=>
{
isActive
.
value
=
false
;
});
// 监听 MenuRoot 变化
watch
(
menuRoot
,
async
(
newValue
)
=>
{
console
.
log
(
'MenuRoot updated:'
,
newValue
);
if
(
newValue
)
{
const
{
data
}
=
await
getDefaultMenu
(
`/Restful/Kivii.Basic.Entities.Menu/Query.json?ParentKvid=
${
newValue
.
Kvid
}
&isRelateFunction=true`
);
console
.
log
(
'Menu data:'
,
data
);
if
(
data
?.
Results
&&
data
?.
Results
.
length
>
0
)
{
const
autoStartItem
=
data
?.
Results
.
find
(
item
=>
{
try
{
const
params
=
JSON
.
parse
(
item
.
Parameters
||
'{}'
);
return
params
.
AutoStartup
===
'true'
;
}
catch
(
error
)
{
console
.
error
(
'Parameters parse error:'
,
error
);
return
false
;
}
});
if
(
autoStartItem
)
{
// 设置 iframe 属性
autoStartProps
.
value
=
{
type
:
autoStartItem
.
Type
,
kvid
:
autoStartItem
.
Kvid
,
url
:
''
};
console
.
log
(
'autoStartProps:'
,
autoStartProps
.
value
);
}
}
}
},
{
immediate
:
true
});
const
gap
=
computed
(()
=>
(
appStore
.
isMobile
?
0
:
16
));
</
script
>
<
template
>
<NSpace
vertical
:size=
"16"
>
<!--
<NAlert
:title=
"$t('common.warning')"
type=
"warning"
>
{{
$t
(
'page.home.branchDesc'
)
}}
</NAlert>
-->
<HeaderBanner
/>
<!--
<CardData
/>
-->
<!--
<NGrid
:x-gap=
"gap"
:y-gap=
"16"
responsive=
"screen"
item-responsive
>
<NGi
span=
"24 s:24 m:14"
>
<NCard
:bordered=
"false"
class=
"card-wrapper"
>
<LineChart
/>
</NCard>
</NGi>
<NGi
span=
"24 s:24 m:10"
>
<NCard
:bordered=
"false"
class=
"card-wrapper"
>
<PieChart
/>
</NCard>
</NGi>
</NGrid>
-->
<NGrid
:x-gap=
"gap"
:y-gap=
"16"
responsive=
"screen"
item-responsive
>
<NGi
span=
"24 s:24 m:14"
>
<!--
<ProjectNews
/>
-->
...
...
@@ -40,6 +97,18 @@ const gap = computed(() => (appStore.isMobile ? 0 : 16));
<!--
<CreativityBanner
/>
-->
</NGi>
</NGrid>
<!-- 添加 IframePage 组件,增加 isExtjsRootReady 检查 -->
<template
v-if=
"isExtjsRootReady"
>
<div
v-show=
"isActive"
:id=
"extjsContainerId"
style=
"width: 100%; height: 100%"
>
<IframePage
v-if=
"autoStartProps.type"
:type=
"autoStartProps.type"
:kvid=
"autoStartProps.kvid"
:url=
"autoStartProps.url"
/>
</div>
</
template
>
</NSpace>
</template>
...
...
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