update: 1.优化动态路由,处理路由数据格式;优化layout样式

This commit is contained in:
xieyonghong 2023-01-31 17:50:47 +08:00
parent de3a57ce91
commit 8e2e0de679
9 changed files with 220 additions and 90 deletions

View File

@ -21,6 +21,7 @@
import { ProLayout } from '@/components/Layout' import { ProLayout } from '@/components/Layout'
import DefaultSetting from '../../../config/config' import DefaultSetting from '../../../config/config'
import { useMenuStore } from '@/store/menu' import { useMenuStore } from '@/store/menu'
import { clearMenuItem } from 'components/Layout/utils'
type StateType = { type StateType = {
collapsed: boolean collapsed: boolean
@ -39,7 +40,7 @@ const layoutConf = reactive({
siderWidth: DefaultSetting.layout.siderWidth, siderWidth: DefaultSetting.layout.siderWidth,
logo: DefaultSetting.layout.logo, logo: DefaultSetting.layout.logo,
title: DefaultSetting.layout.title, title: DefaultSetting.layout.title,
menuData: menu.menus, menuData: clearMenuItem(menu.siderMenus),
}); });
const state = reactive<StateType>({ const state = reactive<StateType>({

View File

@ -32,7 +32,7 @@ export const HeaderView = defineComponent({
height: `${headerHeight.value}px`, height: `${headerHeight.value}px`,
lineHeight: `${headerHeight.value}px`, lineHeight: `${headerHeight.value}px`,
width: `100%`, width: `100%`,
background: 'transparent'
}} }}
/> />
<Layout.Header <Layout.Header

View File

@ -13,4 +13,8 @@
flex-direction: column; flex-direction: column;
height: 100%; height: 100%;
} }
.ant-menu-inline {
background: transparent;
}
} }

View File

@ -8,7 +8,7 @@ import 'ant-design-vue/es/notification/style/css';
const app = createApp(App) const app = createApp(App)
app.use(router) app.use(store)
.use(store) .use(router)
.use(components) .use(components)
.mount('#app') .mount('#app')

View File

@ -37,12 +37,12 @@ router.beforeEach((to, from, next) => {
menuData.forEach(r => { menuData.forEach(r => {
router.addRoute('base', r) router.addRoute('base', r)
}) })
router.addRoute('base',{ router.addRoute('base',{
path: '/:pathMatch(.*)*', path: '/:pathMatch(.*)',
name: 'error',
component: () => NotFindPage component: () => NotFindPage
}) })
console.log(to)
next({ ...to, replace: true }) next({ ...to, replace: true })
}) })
}).catch(() => { }).catch(() => {

View File

@ -18,7 +18,7 @@ export default [
// path: '/initsetting', // path: '/initsetting',
// component: () => import('@/view/Login/initSet.vue') // component: () => import('@/view/Login/initSet.vue')
// } // }
{ path: '/*', redirect: '/'},
// start: 测试用, 可删除 // start: 测试用, 可删除
{ {
path: '/login', path: '/login',

View File

@ -1,12 +1,14 @@
import { defineStore } from "pinia"; import { defineStore } from "pinia";
import { queryOwnThree } from '@/api/system/menu' import { queryOwnThree } from '@/api/system/menu'
import { filterAsnycRouter } from '@/utils/menu' import { filterAsnycRouter } from '@/utils/menu'
import { cloneDeep } from 'lodash-es'
export const useMenuStore = defineStore({ export const useMenuStore = defineStore({
id: 'menu', id: 'menu',
state: () => ({ state: () => ({
menus: {}, menus: {},
menuData: [], menuData: [],
siderMenus: [],
menusKey: [] menusKey: []
}), }),
getters: { getters: {
@ -52,7 +54,8 @@ export const useMenuStore = defineStore({
]; ];
const resp = await queryOwnThree({ paging: false, terms: params }) const resp = await queryOwnThree({ paging: false, terms: params })
if (resp.success) { if (resp.success) {
const menus = filterAsnycRouter(resp.result) const silderMenus = filterAsnycRouter(cloneDeep(resp.result))
const menus = filterAsnycRouter(cloneDeep(resp.result))
menus.push({ menus.push({
path: '/', path: '/',
redirect: menus[0]?.path, redirect: menus[0]?.path,
@ -61,6 +64,8 @@ export const useMenuStore = defineStore({
} }
}) })
this.menuData = menus this.menuData = menus
this.siderMenus = silderMenus
console.log('silderMenus', silderMenus)
res(menus) res(menus)
} }
}) })

View File

@ -1,11 +1,99 @@
const pagesComponent = import.meta.glob('../views/**/*.vue', { eager: true }); const pagesComponent = import.meta.glob('../views/**/*.vue', { eager: true });
import { BlankLayoutPage, BasicLayoutPage } from 'components/Layout' import { BlankLayoutPage, BasicLayoutPage } from 'components/Layout'
type ExtraRouteItem = { /**
code: string *
name: string */
url?: string export type PermissionInfo = {
} permission: string;
actions: string[];
};
/**
*
*/
export type MenuButtonInfo = {
id: string;
name: string;
permissions: PermissionInfo;
createTime: number;
describe?: string;
options: Record<string, any>;
};
export type MenuItem = {
id: string;
/**
*
*/
name: string;
/**
*
*/
code: string;
/**
*
*/
application: string;
/**
*
*/
describe: string;
/**
* url
*/
url: string;
/**
*
*/
icon: string;
/**
* , 01
*/
status: number;
/**
*
*/
permissions: PermissionInfo[];
/**
*
*/
buttons: MenuButtonInfo[];
/**
*
*/
options: Record<string, any>;
/**
* ID
*/
parentId: string;
/**
*
*/
path: string;
/**
*
*/
sortIndex: number;
/**
*
*/
level: number;
createTime: number;
redirect?: string;
children?: MenuItem[];
accessSupport?: { text: string; value: string };
appId?: string; //应用id
isShow?: boolean;
meta?: {
title?: string
icon?: string
[key: string]: any
},
component?: any
};
// 额外子级路由 // 额外子级路由
const extraRouteObj = { const extraRouteObj = {
'media/Cascade': { 'media/Cascade': {
@ -59,51 +147,82 @@ const extraRouteObj = {
const resolveComponent = (name: any) => { const resolveComponent = (name: any) => {
// TODO 暂时用system进行测试
const importPage = pagesComponent[`../views/${name}/index.vue`]; const importPage = pagesComponent[`../views/${name}/index.vue`];
if (!importPage) { if (!importPage) {
console.warn(`Unknown page ${name}. Is it located under Pages with a .vue extension?`) console.warn(`Unknown page ${name}. Is it located under Pages with a .vue extension?`)
} }
//@ts-ignore //@ts-ignore
return !!importPage ? importPage.default : BlankLayoutPage return !!importPage ? importPage.default : undefined
} }
const findChildrenRoute = (code: string, url: string): ExtraRouteItem[] => { const findChildrenRoute = (code: string, url: string): MenuItem[] => {
if (extraRouteObj[code]) { if (extraRouteObj[code]) {
return extraRouteObj[code].children.map((route: ExtraRouteItem) => { return extraRouteObj[code].children.map((route: MenuItem) => {
return { return {
url: `${url}/${route.code}`, url: `${url}/${route.code}`,
code: route.code, code: route.code,
name: route.name name: route.name,
isShow: false
} }
}) })
} }
return [] return []
} }
const findDetailRouteItem = (code: string, url: string): Partial<MenuItem> | null => {
const detailComponent = resolveComponent(`${code}/Detail`)
if (detailComponent) {
return {
url: `${url}/Detail/:id`,
component: detailComponent,
name: '详情信息',
isShow: false
}
}
return null
}
const findDetailRoutes = (routes: any[]): any[] => {
const newRoutes: any[] = []
routes.forEach((route: any) => {
newRoutes.push(route)
const detail = findDetailRouteItem(route.code, route.url)
if (detail) {
newRoutes.push(detail)
}
})
return newRoutes
}
export function filterAsnycRouter(asyncRouterMap: any, parentCode = '', level = 1) { export function filterAsnycRouter(asyncRouterMap: any, parentCode = '', level = 1) {
return asyncRouterMap.map((route: any) => { return asyncRouterMap.map((route: any) => {
console.log(route.name, route)
route.path = `${route.url}` route.path = `${route.url}`
route.meta = { route.meta = {
icon: route.icon, icon: route.icon,
title: route.name title: route.name,
hideInMenu: route.isShow === false
} }
// 查看是否有隐藏子路由 // 查看是否有隐藏子路由
const extraChildren = findChildrenRoute(route.code, route.url) const extraChildren = findChildrenRoute(route.code, route.url)
route.children = route.children && route.children.length ? [...route.children, ...extraChildren] : extraChildren route.children = route.children && route.children.length ? [...route.children, ...extraChildren] : extraChildren
route.children = findDetailRoutes(route.children)
// TODO 查看是否具有详情页
// route.children = [...route.children, ]
if (route.children && route.children.length) { if (route.children && route.children.length) {
route.component = () => level === 1 ? BasicLayoutPage : BlankLayoutPage // TODO 查看是否具有详情页
route.children = filterAsnycRouter(route.children, `${parentCode}/${route.code}`, level + 1) route.children = filterAsnycRouter(route.children, `${parentCode}/${route.code}`, level + 1)
route.redirect = route.children[0].url const showChildren = route.children.some((r: any) => !r.meta.hideInMenu)
if (showChildren) {
route.component = () => level === 1 ? BasicLayoutPage : BlankLayoutPage
route.redirect = route.children[0].url
} else {
route.component = resolveComponent(route.code) || BlankLayoutPage;
}
} else { } else {
route.component = resolveComponent(route.code); route.component = resolveComponent(route.code) || BlankLayoutPage;
} }
delete route.name
return route return route
}) })
} }

View File

@ -1,79 +1,80 @@
<template> <template>
<div class="container"> <page-container>
<div class="header"></div> <InitHome v-if="currentView === 'init'" @refresh='setCurrentView' />
<div class="left"></div> <DeviceHome v-else-if="currentView === 'device'" />
<div class="content iot-home-container" v-loading="loading"> <DevOpsHome v-else-if="currentView === 'ops'" />
<InitHome v-if="currentView === 'init'" @refresh="setCurrentView" /> <ComprehensiveHome v-else-if="currentView === 'comprehensive'" />
<DeviceHome v-else-if="currentView === 'device'" /> </page-container>
<DevOpsHome v-else-if="currentView === 'ops'" />
<ComprehensiveHome v-else-if="currentView === 'comprehensive'" />
</div>
</div>
</template> </template>
<script lang="ts" setup> <script lang='ts' setup name='IotHome'>
import InitHome from './components/InitHome/index.vue'; import InitHome from './components/InitHome/index.vue'
import DeviceHome from './components/DeviceHome/index.vue'; import DeviceHome from './components/DeviceHome/index.vue'
import DevOpsHome from './components/DevOpsHome/index.vue'; import DevOpsHome from './components/DevOpsHome/index.vue'
import ComprehensiveHome from './components/ComprehensiveHome/index.vue'; import ComprehensiveHome from './components/ComprehensiveHome/index.vue'
import PageContainer from 'components/Layout/components/PageContainer'
import { isNoCommunity } from '@/utils/utils'
import { getMe_api, getView_api } from '@/api/home'
import { isNoCommunity } from '@/utils/utils'; const router = useRouter()
import { getMe_api, getView_api } from '@/api/home';
const router = useRouter(); const currentView = ref<string>('')
const loading = ref<boolean>(true)
const currentView = ref<string>('');
const loading = ref<boolean>(true);
// //
const setCurrentView = () => { const setCurrentView = () => {
getView_api().then((resp: any) => { getView_api().then((resp: any) => {
if (resp.status === 200) { if (resp.status === 200) {
if (resp.result) currentView.value = resp.result?.content; if (resp.result) currentView.value = resp.result?.content
else if (resp.result.username === 'admin') { else if (resp.result.username === 'admin') {
currentView.value = 'comprehensive'; currentView.value = 'comprehensive'
} else currentView.value = 'init'; } else currentView.value = 'init'
} }
}); })
}; }
if (isNoCommunity) { if (isNoCommunity) {
// api // api
getMe_api().then((resp: any) => { getMe_api().then((resp: any) => {
if (resp && resp.status === 200) { if (resp && resp.status === 200) {
const isApiUser = resp.result.dimensions.find( const isApiUser = resp.result.dimensions.find(
(item: any) => (item: any) =>
item.type === 'api-client' || item.type.id === 'api-client', item.type === 'api-client' || item.type.id === 'api-client'
); )
isApiUser ? router.push('/system/api') : setCurrentView()
}
})
} else setCurrentView()
isApiUser ? router.push('/system/api') : setCurrentView();
}
});
}else setCurrentView()
</script> </script>
<style lang="less" scoped> <style lang='less' scoped>
.container { .container {
background: #f0f2f5; background: #f0f2f5;
width: 100vw;
min-height: 100vh;
display: flex;
flex-wrap: wrap;
.header {
height: 48px;
background: #7e1c1c;
width: 100vw; width: 100vw;
min-height: 100vh; }
display: flex;
flex-wrap: wrap; .left {
.header { background: #352d85;
height: 48px; width: 210px;
background: #7e1c1c; min-height: calc(100vh - 48px);
width: 100vw; }
}
.left { .content {
background: #352d85; margin: 24px;
width: 210px; width: calc(100vw - 280px);
min-height: calc(100vh - 48px); overflow: hidden;
} min-height: calc(100vh - 96px);
.content { }
margin: 24px;
width: calc(100vw - 280px);
overflow: hidden;
min-height: calc(100vh - 96px);
}
} }
</style> </style>