Skip to content

Commit

Permalink
Fixes bug 动态路由配置重构
Browse files Browse the repository at this point in the history
  • Loading branch information
jekip committed Aug 10, 2021
1 parent 737f967 commit 9c51200
Show file tree
Hide file tree
Showing 23 changed files with 179 additions and 98 deletions.
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
# CHANGELOG

## 1.5.4 (2021-08-10)

### 🐛 Bug Fixes

- `暗色模式下多页签背景问题 ` 合并 [#23](https://github.com/jekip/naive-ui-admin/pull/23) 感谢 [@Dishone](https://github.com/Dishone)
- `表格设置列,重复添加action列样式错乱问题` 合并 [#24](https://github.com/jekip/naive-ui-admin/pull/24) 感谢 [@CasbaL](https://github.com/CasbaL)

- ### ✨ Features
-(破坏性更新)
- 优化 `动态路由配置` 取消`constantRouterComponents.ts`,中组件映射配置,更名为 `router-icons.ts`
- 优化 `admin_info接口结构`,roles 更名为:permissions,roles.roleName,更名为:label
- 优化 多级路由,当没有配置时,`redirect``redirect` 默认为第一个子路由,配置则优先按配置
- 依赖升级

# 1.5.3 (2021-08-09)
### 🐛 Bug Fixes
- 修复顶部菜单,选中联动
Expand Down
8 changes: 4 additions & 4 deletions mock/user/menus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const menusList = [
{
path: '/dashboard',
name: 'Dashboard',
component: 'Layout',
component: 'LAYOUT',
redirect: '/dashboard/console',
meta: {
icon: 'DashboardOutlined',
Expand All @@ -14,23 +14,23 @@ const menusList = [
{
path: 'console',
name: 'dashboard_console',
component: 'DashboardConsole',
component: '/dashboard/console/console',
meta: {
title: '主控台',
},
},
{
path: 'monitor',
name: 'dashboard_monitor',
component: 'DashboardMonitor',
component: '/dashboard/monitor/monitor',
meta: {
title: '监控页',
},
},
{
path: 'workplace',
name: 'dashboard_workplace',
component: 'DashboardWorkplace',
component: '/dashboard/workplace/workplace',
meta: {
hidden: true,
title: '工作台',
Expand Down
12 changes: 6 additions & 6 deletions mock/user/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,25 @@ const adminInfo = {
desc: 'manager',
password: Random.string('upper', 4, 16),
token,
roles: [
permissions: [
{
roleName: '主控台',
label: '主控台',
value: 'dashboard_console',
},
{
roleName: '监控页',
label: '监控页',
value: 'dashboard_monitor',
},
{
roleName: '工作台',
label: '工作台',
value: 'dashboard_workplace',
},
{
roleName: '基础列表',
label: '基础列表',
value: 'basic_list',
},
{
roleName: '基础列表删除',
label: '基础列表删除',
value: 'basic_list_delete',
},
],
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "naive-ui-admin",
"version": "1.5.3",
"version": "1.5.4",
"author": {
"name": "Ahjung",
"email": "[email protected]",
Expand Down Expand Up @@ -87,7 +87,7 @@
"stylelint-scss": "^3.19.0",
"tailwindcss": "^2.2.7",
"typescript": "^4.3.5",
"vite": "2.3.6",
"vite": "2.4.4",
"vite-plugin-compression": "^0.3.1",
"vite-plugin-html": "^2.0.7",
"vite-plugin-mock": "^2.9.3",
Expand Down
4 changes: 2 additions & 2 deletions src/components/Table/src/types/tableAction.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @ts-ignore
import { NButton } from 'naive-ui';
import { RoleEnum } from '@/enums/roleEnum';
import { PermissionsEnum } from '@/enums/permissionsEnum';
// @ts-ignore
export interface ActionItem extends NButton.props {
onClick?: Fn;
Expand All @@ -11,7 +11,7 @@ export interface ActionItem extends NButton.props {
disabled?: boolean;
divider?: boolean;
// 权限编码控制是否显示
auth?: RoleEnum | RoleEnum[] | string | string[];
auth?: PermissionsEnum | PermissionsEnum[] | string | string[];
// 业务控制是否显示
ifShow?: boolean | ((action: ActionItem) => boolean);
}
Expand Down
14 changes: 7 additions & 7 deletions src/hooks/web/usePermission.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ export function usePermission() {
* 检查权限
* @param accesses
*/
function _someRoles(accesses: string[]) {
return userStore.getRoles.some((item) => {
function _somePermissions(accesses: string[]) {
return userStore.getPermissions.some((item) => {
const { value }: any = item;
return accesses.includes(value);
});
Expand All @@ -20,17 +20,17 @@ export function usePermission() {
* */
function hasPermission(accesses: string[]): boolean {
if (!accesses || !accesses.length) return true;
return _someRoles(accesses);
return _somePermissions(accesses);
}

/**
* 是否包含指定的所有权限
* @param accesses
*/
function hasEveryPermission(accesses: string[]): boolean {
const rolesList = userStore.getRoles;
const permissionsList = userStore.getPermissions;
if (Array.isArray(accesses)) {
return accesses.every((access) => !!rolesList[access]);
return accesses.every((access) => !!permissionsList[access]);
}
throw new Error(`[hasEveryPermission]: ${accesses} should be a array !`);
}
Expand All @@ -41,9 +41,9 @@ export function usePermission() {
* @param accessMap
*/
function hasSomePermission(accesses: string[]): boolean {
const rolesList = userStore.getRoles;
const permissionsList = userStore.getPermissions;
if (Array.isArray(accesses)) {
return accesses.some((access) => !!rolesList[access]);
return accesses.some((access) => !!permissionsList[access]);
}
throw new Error(`[hasSomePermission]: ${accesses} should be a array !`);
}
Expand Down
2 changes: 1 addition & 1 deletion src/router/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const ErrorPageRoute: AppRouteRecordRaw = {
children: [
{
path: '/:path(.*)*',
name: 'ErrorPage',
name: 'ErrorPageSon',
component: ErrorPage,
meta: {
title: 'ErrorPage',
Expand Down
16 changes: 0 additions & 16 deletions src/router/constantRouterComponents.ts

This file was deleted.

75 changes: 69 additions & 6 deletions src/router/generator-routers.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import { adminMenus } from '@/api/system/menu';
import { constantRouterComponents, constantRouterIcon } from './constantRouterComponents';
import { constantRouterIcon } from './router-icons';
import router from '@/router/index';
import { constantRouter } from '@/router/index';
import { RouteRecordRaw } from 'vue-router';
import { Layout, ParentLayout } from '@/router/constant';
import type { AppRouteRecordRaw } from '@/router/types';

const Iframe = () => import('@/views/iframe/index.vue');
const LayoutMap = new Map<string, () => Promise<typeof import('*.vue')>>();

LayoutMap.set('LAYOUT', Layout);
LayoutMap.set('IFRAME', Iframe);

/**
* 格式化 后端 结构信息并递归生成层级路由表
*
* @param routerMap
* @param parent
* @returns {*}
Expand All @@ -19,21 +26,24 @@ export const routerGenerator = (routerMap, parent?): any[] => {
// 路由名称,建议唯一
name: item.name || '',
// 该路由对应页面的 组件
component: constantRouterComponents[item.component],
component: item.component,
// meta: 页面标题, 菜单图标, 页面权限(供指令权限用,可去掉)
meta: {
...item.meta,
label: item.meta.title,
icon: constantRouterIcon[item.meta.icon] || null,
permission: item.meta.permission || null,
permissions: item.meta.permissions || null,
},
};

// 为了防止出现后端返回结果不规范,处理有可能出现拼接出两个 反斜杠
currentRouter.path = currentRouter.path.replace('//', '/');
// 重定向
item.redirect && (currentRouter.redirect = item.redirect);
// 是否有子菜单,并递归处理
if (item.children && item.children.length > 0) {
//如果未定义 redirect 默认第一个子路由为 redirect
!item.redirect && (currentRouter.redirect = `${item.path}/${item.children[0].path}`);
// Recursion
currentRouter.children = routerGenerator(item.children, currentRouter);
}
Expand All @@ -43,15 +53,15 @@ export const routerGenerator = (routerMap, parent?): any[] => {

/**
* 动态生成菜单
* @param token
* @returns {Promise<Router>}
*/
export const generatorDynamicRouter = (): Promise<RouteRecordRaw[]> => {
return new Promise((resolve, reject) => {
adminMenus()
.then((result) => {
const routeList = routerGenerator(result);
const asyncRoutesList = [...constantRouter, ...routeList];
asyncImportRoute(routeList);
const asyncRoutesList = [...routeList, ...constantRouter];
asyncRoutesList.forEach((item) => {
router.addRoute(item);
});
Expand All @@ -62,3 +72,56 @@ export const generatorDynamicRouter = (): Promise<RouteRecordRaw[]> => {
});
});
};

/**
* 查找views中对应的组件文件
* */
let viewsModules: Record<string, () => Promise<Recordable>>;
export const asyncImportRoute = (routes: AppRouteRecordRaw[] | undefined): void => {
viewsModules = viewsModules || import.meta.glob('../views/**/*.{vue,tsx}');
if (!routes) return;
routes.forEach((item) => {
if (!item.component && item.meta?.frameSrc) {
item.component = 'IFRAME';
}
const { component, name } = item;
const { children } = item;
if (component) {
const layoutFound = LayoutMap.get(component as string);
if (layoutFound) {
item.component = layoutFound;
} else {
item.component = dynamicImport(viewsModules, component as string);
}
} else if (name) {
item.component = ParentLayout;
}
children && asyncImportRoute(children);
});
};

/**
* 动态导入
* */
export const dynamicImport = (
viewsModules: Record<string, () => Promise<Recordable>>,
component: string
) => {
const keys = Object.keys(viewsModules);
const matchKeys = keys.filter((key) => {
let k = key.replace('../views', '');
const lastIndex = k.lastIndexOf('.');
k = k.substring(0, lastIndex);
return k === component;
});
if (matchKeys?.length === 1) {
const matchKey = matchKeys[0];
return viewsModules[matchKey];
}
if (matchKeys?.length > 1) {
console.warn(
'Please do not create `.vue` and `.TSX` files with the same file name in the same hierarchical directory under the views folder. This will cause dynamic introduction failure'
);
return;
}
};
4 changes: 2 additions & 2 deletions src/router/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { App } from 'vue';
import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router';
import { ErrorPageRoute, RedirectRoute } from '@/router/base';
import { RedirectRoute } from '@/router/base';
import { PageEnum } from '@/enums/pageEnum';
import { createRouterGuards } from './router-guards';

Expand Down Expand Up @@ -40,7 +40,7 @@ export const LoginRoute: RouteRecordRaw = {
};

//需要验证权限
export const asyncRoutes = [ErrorPageRoute, ...routeModuleList];
export const asyncRoutes = [...routeModuleList];

//普通路由 无需验证权限
export const constantRouter: any[] = [LoginRoute, RootRoute, RedirectRoute];
Expand Down
8 changes: 4 additions & 4 deletions src/router/modules/dashboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const routes: Array<RouteRecordRaw> = [
meta: {
title: 'Dashboard',
icon: renderIcon(DashboardOutlined),
permission: ['dashboard_console', 'dashboard_console', 'dashboard_workplace'],
permissions: ['dashboard_console', 'dashboard_console', 'dashboard_workplace'],
sort: 0,
},
children: [
Expand All @@ -33,7 +33,7 @@ const routes: Array<RouteRecordRaw> = [
name: `${routeName}_console`,
meta: {
title: '主控台',
permission: ['dashboard_console'],
permissions: ['dashboard_console'],
},
component: () => import('@/views/dashboard/console/console.vue'),
},
Expand All @@ -42,7 +42,7 @@ const routes: Array<RouteRecordRaw> = [
// name: `${ routeName }_monitor`,
// meta: {
// title: '监控页',
// permission: ['dashboard_monitor']
// permissions: ['dashboard_monitor']
// },
// component: () => import('@/views/dashboard/monitor/monitor.vue')
// },
Expand All @@ -52,7 +52,7 @@ const routes: Array<RouteRecordRaw> = [
meta: {
title: '工作台',
keepAlive: true,
permission: ['dashboard_workplace'],
permissions: ['dashboard_workplace'],
},
component: () => import('@/views/dashboard/workplace/workplace.vue'),
},
Expand Down
Loading

1 comment on commit 9c51200

@vercel
Copy link

@vercel vercel bot commented on 9c51200 Aug 10, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.