update: 优化ProLayout
This commit is contained in:
parent
34d3ff7419
commit
3b04286842
|
@ -8,10 +8,13 @@
|
||||||
:breadcrumb="{ routes: breadcrumb }"
|
:breadcrumb="{ routes: breadcrumb }"
|
||||||
>
|
>
|
||||||
<template #breadcrumbRender="slotProps">
|
<template #breadcrumbRender="slotProps">
|
||||||
<a v-if="slotProps.route.index !== 0">{{
|
<a
|
||||||
slotProps.route.breadcrumbName
|
v-if="slotProps.route.index !== 0 && !slotProps.route.isLast"
|
||||||
}}</a>
|
@click='() => jumpPage(slotProps.route.path)'
|
||||||
<span v-else>{{ slotProps.route.breadcrumbName }}</span>
|
>
|
||||||
|
{{ slotProps.route.breadcrumbName }}
|
||||||
|
</a>
|
||||||
|
<span v-else >{{ slotProps.route.breadcrumbName }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #rightContentRender>
|
<template #rightContentRender>
|
||||||
<div class="right-content">
|
<div class="right-content">
|
||||||
|
@ -32,6 +35,7 @@ import Notice from './components/Notice.vue';
|
||||||
import DefaultSetting from '../../../config/config';
|
import DefaultSetting from '../../../config/config';
|
||||||
import { useMenuStore } from '@/store/menu';
|
import { useMenuStore } from '@/store/menu';
|
||||||
import { clearMenuItem } from 'jetlinks-ui-components/es/ProLayout/util';
|
import { clearMenuItem } from 'jetlinks-ui-components/es/ProLayout/util';
|
||||||
|
import { AccountMenu } from '@/router/menu'
|
||||||
|
|
||||||
type StateType = {
|
type StateType = {
|
||||||
collapsed: boolean;
|
collapsed: boolean;
|
||||||
|
@ -50,7 +54,8 @@ 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: clearMenuItem(menu.siderMenus),
|
menuData: [...clearMenuItem(menu.siderMenus), AccountMenu],
|
||||||
|
// menuData: menu.siderMenus,
|
||||||
splitMenus: true,
|
splitMenus: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -61,26 +66,49 @@ const state = reactive<StateType>({
|
||||||
selectedKeys: [],
|
selectedKeys: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const findRouteMeta = (code: string) => {
|
||||||
|
let meta = []
|
||||||
|
let menuItem: any = menu.menus[code]
|
||||||
|
while (menuItem) {
|
||||||
|
meta.unshift(menuItem)
|
||||||
|
if (menuItem.parentName) {
|
||||||
|
menuItem = menu.menus[menuItem.parentName]
|
||||||
|
} else {
|
||||||
|
menuItem = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return meta
|
||||||
|
}
|
||||||
|
|
||||||
|
const jumpPage = (path: string) => {
|
||||||
|
console.log(path)
|
||||||
|
router.push(path)
|
||||||
|
}
|
||||||
|
|
||||||
const breadcrumb = computed(() =>
|
const breadcrumb = computed(() =>
|
||||||
router.currentRoute.value.matched.concat().map((item, index) => {
|
{
|
||||||
return {
|
const paths = router.currentRoute.value.name as string
|
||||||
index,
|
const metas = findRouteMeta(paths)
|
||||||
path: item.path,
|
return metas.map((item, index) => {
|
||||||
breadcrumbName: item.meta.title || '',
|
return {
|
||||||
};
|
index,
|
||||||
}),
|
isLast: index === (metas.length - 1),
|
||||||
|
path: item.path,
|
||||||
|
breadcrumbName: item.title || '',
|
||||||
|
};
|
||||||
|
})
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
if (router.currentRoute) {
|
if (router.currentRoute) {
|
||||||
const matched = router.currentRoute.value.matched.concat();
|
const paths = router.currentRoute.value.name as string
|
||||||
state.selectedKeys = matched.map((r) => r.path);
|
if (paths) {
|
||||||
state.openKeys = matched
|
const _metas = findRouteMeta(paths)
|
||||||
.filter((r) => r.path !== router.currentRoute.value.path)
|
state.selectedKeys = _metas.map(item => item.path)
|
||||||
.map((r) => r.path);
|
state.openKeys = _metas.filter((r) => r !== router.currentRoute.value.path).map(item => item.path)
|
||||||
console.log(state.selectedKeys);
|
}
|
||||||
}
|
}
|
||||||
// TODO 获取当前路由中参数,用于控制pure
|
|
||||||
});
|
});
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
|
|
|
@ -5,6 +5,7 @@ export const AccountMenu = {
|
||||||
component: () => import('@/components/Layout/BasicLayoutPage.vue'),
|
component: () => import('@/components/Layout/BasicLayoutPage.vue'),
|
||||||
redirect: '/account/center',
|
redirect: '/account/center',
|
||||||
name: 'account',
|
name: 'account',
|
||||||
|
code: 'account',
|
||||||
meta: {
|
meta: {
|
||||||
title: '个人中心',
|
title: '个人中心',
|
||||||
icon: '',
|
icon: '',
|
||||||
|
@ -14,6 +15,7 @@ export const AccountMenu = {
|
||||||
{
|
{
|
||||||
path: '/account/center',
|
path: '/account/center',
|
||||||
name: 'account/center',
|
name: 'account/center',
|
||||||
|
code: 'account/center',
|
||||||
meta: {
|
meta: {
|
||||||
title: '基本设置',
|
title: '基本设置',
|
||||||
icon: '',
|
icon: '',
|
||||||
|
@ -24,6 +26,7 @@ export const AccountMenu = {
|
||||||
{
|
{
|
||||||
path: '/account/NotificationSubscription',
|
path: '/account/NotificationSubscription',
|
||||||
name: 'account/NotificationSubscription',
|
name: 'account/NotificationSubscription',
|
||||||
|
code: 'account/NotificationSubscription',
|
||||||
meta: {
|
meta: {
|
||||||
title: '通知订阅',
|
title: '通知订阅',
|
||||||
icon: '',
|
icon: '',
|
||||||
|
@ -34,6 +37,7 @@ export const AccountMenu = {
|
||||||
{
|
{
|
||||||
path: '/account/NotificationRecord',
|
path: '/account/NotificationRecord',
|
||||||
name: 'account/NotificationRecord',
|
name: 'account/NotificationRecord',
|
||||||
|
code: 'account/NotificationRecord',
|
||||||
meta: {
|
meta: {
|
||||||
title: '通知记录',
|
title: '通知记录',
|
||||||
icon: '',
|
icon: '',
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import { queryOwnThree } from '@/api/system/menu'
|
import { queryOwnThree } from '@/api/system/menu'
|
||||||
import { filterAsnycRouter, MenuItem } from '@/utils/menu'
|
import { filterAsyncRouter, findCodeRoute, MenuItem } from '@/utils/menu'
|
||||||
import { isArray } from 'lodash-es'
|
import { isArray } from 'lodash-es'
|
||||||
import { usePermissionStore } from './permission'
|
import { usePermissionStore } from './permission'
|
||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
|
@ -33,6 +33,8 @@ type MenuStateType = {
|
||||||
menus: {
|
menus: {
|
||||||
[key: string]: {
|
[key: string]: {
|
||||||
buttons?: string[]
|
buttons?: string[]
|
||||||
|
title: string
|
||||||
|
parentName: string
|
||||||
path: string
|
path: string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,24 +100,15 @@ export const useMenuStore = defineStore({
|
||||||
if (resp.success) {
|
if (resp.success) {
|
||||||
const permission = usePermissionStore()
|
const permission = usePermissionStore()
|
||||||
permission.permissions = {}
|
permission.permissions = {}
|
||||||
const { menusData, silderMenus } = filterAsnycRouter(resp.result)
|
const { menusData, silderMenus } = filterAsyncRouter(resp.result)
|
||||||
this.menus = {}
|
this.menus = findCodeRoute([...resp.result, AccountMenu])
|
||||||
const handleMenuItem = (menu: any) => {
|
Object.keys(this.menus).forEach((item) => {
|
||||||
if (isArray(menu)) {
|
const _item = this.menus[item]
|
||||||
menu.forEach(menuItem => {
|
if (_item.buttons?.length) {
|
||||||
this.menus[menuItem.name] = {
|
permission.permissions[item] = _item.buttons
|
||||||
path: menuItem.path,
|
|
||||||
buttons: menuItem.meta.buttons
|
|
||||||
}
|
|
||||||
permission.permissions[menuItem.name] = menuItem.meta.buttons
|
|
||||||
if (menuItem.children && menuItem.children.length) {
|
|
||||||
handleMenuItem(menuItem.children)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
|
|
||||||
handleMenuItem(menusData)
|
|
||||||
menusData.push({
|
menusData.push({
|
||||||
path: '/',
|
path: '/',
|
||||||
redirect: menusData[0]?.path,
|
redirect: menusData[0]?.path,
|
||||||
|
@ -124,10 +117,7 @@ export const useMenuStore = defineStore({
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
menusData.push(AccountMenu)
|
menusData.push(AccountMenu)
|
||||||
silderMenus.push(AccountMenu)
|
|
||||||
this.siderMenus = silderMenus
|
this.siderMenus = silderMenus
|
||||||
console.log('menusData', menusData)
|
|
||||||
console.log('silderMenus', silderMenus)
|
|
||||||
res(menusData)
|
res(menusData)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -3,11 +3,12 @@ import { defineStore } from "pinia";
|
||||||
export const usePermissionStore = defineStore({
|
export const usePermissionStore = defineStore({
|
||||||
id: 'permission',
|
id: 'permission',
|
||||||
state: () => ({
|
state: () => ({
|
||||||
permissions: {} as {[key: string]: string},
|
permissions: {} as {[key: string]: string[]},
|
||||||
}),
|
}),
|
||||||
getters: {
|
getters: {
|
||||||
check(state) {
|
check(state) {
|
||||||
return (permissionCode: string) => {
|
return (permissionCode: string) => {
|
||||||
|
|
||||||
if (!permissionCode) {
|
if (!permissionCode) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -16,6 +17,7 @@ export const usePermissionStore = defineStore({
|
||||||
}
|
}
|
||||||
const code = permissionCode.split(":")[0]
|
const code = permissionCode.split(":")[0]
|
||||||
const value = permissionCode.split(":")[1]
|
const value = permissionCode.split(":")[1]
|
||||||
|
|
||||||
const _buttonArray = state.permissions[code]
|
const _buttonArray = state.permissions[code]
|
||||||
if (!_buttonArray) {
|
if (!_buttonArray) {
|
||||||
return false
|
return false
|
||||||
|
|
|
@ -151,7 +151,6 @@ const extraRouteObj = {
|
||||||
const resolveComponent = (name: any) => {
|
const resolveComponent = (name: any) => {
|
||||||
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?`)
|
|
||||||
return undefined
|
return undefined
|
||||||
} else {
|
} else {
|
||||||
const res = () => importPage()
|
const res = () => importPage()
|
||||||
|
@ -201,7 +200,52 @@ const findDetailRoutes = (routes: any[]): any[] => {
|
||||||
return newRoutes
|
return newRoutes
|
||||||
}
|
}
|
||||||
|
|
||||||
export function filterAsnycRouter(asyncRouterMap: any, parentCode = '', level = 1): { menusData: any, silderMenus: any } {
|
export const findCodeRoute = (asyncRouterMap: any[]) => {
|
||||||
|
const routeMeta = {}
|
||||||
|
|
||||||
|
function findChildren (data: any[], code: string = '') {
|
||||||
|
data.forEach(route => {
|
||||||
|
routeMeta[route.code] = {
|
||||||
|
path: route.url || route.path,
|
||||||
|
title: route.meta?.title || route.name,
|
||||||
|
parentName: code,
|
||||||
|
buttons: route.buttons?.map((b: any) => b.id) || []
|
||||||
|
}
|
||||||
|
const detail = findDetailRouteItem(route.code, route.url)
|
||||||
|
if (detail) {
|
||||||
|
routeMeta[(detail as MenuItem).code] = {
|
||||||
|
path: detail.url,
|
||||||
|
title: detail.name,
|
||||||
|
parentName: route.code,
|
||||||
|
buttons: detail.buttons?.map((b: any) => b.id) || []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const otherRoutes = extraRouteObj[route.code]
|
||||||
|
if (otherRoutes) {
|
||||||
|
otherRoutes.children.map((item: any) => {
|
||||||
|
const _code = `${route.code}/${item.code}`
|
||||||
|
routeMeta[_code] = {
|
||||||
|
path: `${route.url}/${item.code}`,
|
||||||
|
title: item.name,
|
||||||
|
parentName: route.code,
|
||||||
|
buttons: item.buttons?.map((b: any) => b.id) || []
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (route.children) {
|
||||||
|
findChildren(route.children, route.code)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
findChildren(asyncRouterMap)
|
||||||
|
|
||||||
|
return routeMeta
|
||||||
|
}
|
||||||
|
|
||||||
|
export function filterAsyncRouter(asyncRouterMap: any, parentCode = '', level = 1): { menusData: any, silderMenus: any} {
|
||||||
const _asyncRouterMap = cloneDeep(asyncRouterMap)
|
const _asyncRouterMap = cloneDeep(asyncRouterMap)
|
||||||
const menusData: any[] = []
|
const menusData: any[] = []
|
||||||
const silderMenus: any[] = []
|
const silderMenus: any[] = []
|
||||||
|
@ -224,7 +268,7 @@ export function filterAsnycRouter(asyncRouterMap: any, parentCode = '', level =
|
||||||
route.children = findDetailRoutes(route.children)
|
route.children = findDetailRoutes(route.children)
|
||||||
if (route.children && route.children.length) {
|
if (route.children && route.children.length) {
|
||||||
// TODO 查看是否具有详情页
|
// TODO 查看是否具有详情页
|
||||||
const { menusData: _menusData, silderMenus: _silderMenus } = filterAsnycRouter(route.children, `${parentCode}/${route.code}`, level + 1)
|
const { menusData: _menusData, silderMenus: _silderMenus } = filterAsyncRouter(route.children, `${parentCode}/${route.code}`, level + 1)
|
||||||
_route.children = _menusData
|
_route.children = _menusData
|
||||||
silder.children = _silderMenus
|
silder.children = _silderMenus
|
||||||
const showChildren = _route.children.some((r: any) => !r.meta.hideInMenu)
|
const showChildren = _route.children.some((r: any) => !r.meta.hideInMenu)
|
||||||
|
@ -251,6 +295,6 @@ export function filterAsnycRouter(asyncRouterMap: any, parentCode = '', level =
|
||||||
})
|
})
|
||||||
return {
|
return {
|
||||||
menusData,
|
menusData,
|
||||||
silderMenus
|
silderMenus,
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -95,6 +95,7 @@ import { queryFlow, list } from '@/api/iot-card/home';
|
||||||
import * as echarts from 'echarts';
|
import * as echarts from 'echarts';
|
||||||
import { useMenuStore } from '@/store/menu';
|
import { useMenuStore } from '@/store/menu';
|
||||||
import { usePermissionStore } from '@/store/permission';
|
import { usePermissionStore } from '@/store/permission';
|
||||||
|
import { message } from 'jetlinks-ui-components'
|
||||||
|
|
||||||
const { proxy } = <any>getCurrentInstance();
|
const { proxy } = <any>getCurrentInstance();
|
||||||
|
|
||||||
|
@ -178,11 +179,10 @@ const pieChartData = ref<any[]>([
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const jumpPage = (data: GuideItemProps) => {
|
const jumpPage = (data: GuideItemProps) => {
|
||||||
// if (data.url && data.auth) {
|
if (!data.auth){
|
||||||
// router.push({ path: `${data.url}`, ...data.param });
|
message.warning('暂无权限,请联系管理员');
|
||||||
// } else {
|
return
|
||||||
// message.warning('暂无权限,请联系管理员');
|
}
|
||||||
// }
|
|
||||||
if (data.key === 'EQUIPMENT') {
|
if (data.key === 'EQUIPMENT') {
|
||||||
menuStory.jumpPage(data.url, { id: 'add' });
|
menuStory.jumpPage(data.url, { id: 'add' });
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue