Skip to content
This repository has been archived by the owner on Mar 25, 2024. It is now read-only.

Commit

Permalink
feat: 新增按钮权限
Browse files Browse the repository at this point in the history
  • Loading branch information
buqiyuan committed Dec 14, 2021
1 parent 6aec46a commit 5538d38
Show file tree
Hide file tree
Showing 27 changed files with 331 additions and 232 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@

安装项目根目录.vscode 推荐的插件,再安装 Volar,并禁用 Vetur,重启 vscode 即可。

> 使用了 Vue3.0 全家桶、ant-design-vue2.0 和 typescript4.0,实践 vue3.0 的新特性以及玩法,不得不说 vue3.0 的 Composition API 相比于 vue2.0 的 Options API 灵活很多,让我们可以灵活地组合组件逻辑,我们可以很轻松的使用 hooks 的形式去代替以前 mixins 等的写法。更多 hooks 可以参考[vueuse](https://vueuse.org/functions.html)
> 使用了 Vue3.x 全家桶、ant-design-vue3.x 和 typescript4.x,实践 vue3.x 的新特性以及玩法,不得不说 vue3.x 的 Composition API 相比于 vue2.x 的 Options API 灵活很多,让我们可以灵活地组合组件逻辑,我们可以很轻松的使用 hooks 的形式去代替以前 mixins 等的写法。更多 hooks 可以参考[vueuse](https://vueuse.org/functions.html)
## 项目简要说明

`rootadmin` 默认开放多点登录,其他新建的账号默认都是单点登录。建议自己拉后端代码到本地跑,避免多人同时操作时产生冲突和误解。

## Project setup

Expand Down
14 changes: 7 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@
"@commitlint/config-conventional": "^15.0.0",
"@types/lodash": "^4.14.178",
"@types/node": "^16.11.12",
"@typescript-eslint/eslint-plugin": "^5.6.0",
"@typescript-eslint/parser": "^5.6.0",
"@typescript-eslint/eslint-plugin": "^5.7.0",
"@typescript-eslint/parser": "^5.7.0",
"@vitejs/plugin-legacy": "^1.6.4",
"@vitejs/plugin-vue": "^2.0.0",
"@vitejs/plugin-vue-jsx": "^1.3.1",
"@vitejs/plugin-vue": "^2.0.1",
"@vitejs/plugin-vue-jsx": "^1.3.2",
"@vue/compiler-sfc": "^3.2.26",
"commitizen": "^4.2.4",
"cross-env": "^7.0.3",
Expand All @@ -62,9 +62,9 @@
"stylelint-config-recommended": "^6.0.0",
"stylelint-config-standard": "^24.0.0",
"stylelint-order": "^5.0.0",
"typescript": "^4.5.3",
"unplugin-vue-components": "^0.17.8",
"vite": "^2.7.1",
"typescript": "^4.5.4",
"unplugin-vue-components": "^0.17.9",
"vite": "^2.7.2",
"vite-plugin-svg-icons": "^1.0.5",
"vite-plugin-windicss": "^1.5.4",
"vue-eslint-parser": "^8.0.1",
Expand Down
2 changes: 1 addition & 1 deletion src/api/system/user/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { request } from '@/utils/request';
import Api from '@/core/permission/modules/sys/user';
import { generatePermCode } from '@/core/permission';
import { generatePermCode } from '@/core/permission/modules';

export function getUserListPage(data: API.PageParams<{ departmentIds: number[] }>) {
return request<API.TableListResult<API.UserListPageResult>>(
Expand Down
36 changes: 33 additions & 3 deletions src/components/dynamic-table/components/table-action.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<template v-for="(actionItem, index) in actions" :key="`${index}-${actionItem.label}`">
<template v-for="(actionItem, index) in actionFilters" :key="`${index}-${actionItem.label}`">
<component
:title="actionItem.title"
:is="actionItem.popConfirm ? Popconfirm : 'span'"
Expand All @@ -14,14 +14,44 @@

<script lang="ts" setup>
import { Popconfirm } from 'ant-design-vue';
import { PropType } from 'vue';
import type { PropType } from 'vue';
import { computed } from 'vue';
import type { ActionItem } from '../types/tableAction';
import { verifyAuth } from '@/core/permission/';
import { isString, isObject } from '@/utils/is';
defineProps({
const props = defineProps({
actions: {
// 表格行动作
type: Array as PropType<ActionItem[]>,
default: () => [],
},
});
const actionFilters = computed(() => {
return props.actions.filter((item) => {
const auth = item.auth;
if (Object.is(auth, undefined)) {
return true;
}
if (isString(auth)) {
const isValid = verifyAuth(auth);
item.disabled = !isValid;
if (item.disabled) {
item.title = '对不起,您没有该操作权限!';
}
return isValid;
}
if (isObject(auth)) {
const isValid = verifyAuth(auth.perm);
const isDisable = auth.effect !== 'delete';
item.disabled = !isValid && isDisable;
if (item.disabled) {
item.title = '对不起,您没有该操作权限!';
}
return isValid || isDisable;
}
});
});
</script>
8 changes: 8 additions & 0 deletions src/components/dynamic-table/types/tableAction.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { PopconfirmProps } from 'ant-design-vue/es/popconfirm';
import type { ButtonProps, TooltipProps } from 'ant-design-vue/lib/components';
import { ColumnParams } from '../typing';
import type { PermissionType } from '@/core/permission/modules/types';

export interface ActionItem extends Omit<ButtonProps, 'onClick'> {
onClick?: Fn<ColumnParams, any>;
Expand All @@ -15,6 +16,13 @@ export interface ActionItem extends Omit<ButtonProps, 'onClick'> {
// 业务控制是否显示
ifShow?: boolean | ((action: ActionItem) => boolean);
tooltip?: string | TooltipProps;
/** 设置按钮权限, effect不传默认为disable */
auth?:
| PermissionType
| {
perm: PermissionType;
effect?: 'delete' | 'disable';
};
}

export interface PopConfirm extends PopconfirmProps {
Expand Down
62 changes: 21 additions & 41 deletions src/core/permission/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,49 +8,13 @@
// import type { DataNode } from 'rc-tree-select/lib/interface'

import type { TreeSelectProps } from 'ant-design-vue';
import type { App } from 'vue';
import { permissions } from './modules/';
import type { PermissionType } from './modules/types';
import { useUserStore } from '@/store/modules/user';

type DataNode = NonNullable<TreeSelectProps['treeData']>[number];

interface Permissions {
[key: string]: {
[key: string]: string;
};
}

const modulesPermissionFiles = import.meta.globEager('./modules/**/*.ts');
/**
* 根据接口路径生成接口权限码, eg: sys/user/add => sys:user:add
* @param str 接口路径
* @returns {string}
*/
export const generatePermCode = (str: string) => str.replace(/\//g, ':');

/**
* @description 权限列表
*/
export const permissions: Permissions = Object.keys(modulesPermissionFiles).reduce(
(modules, modulePath) => {
// set './app.js' => 'app'
// set './sys/app.js' => 'sysApp'
const moduleName = modulePath
.replace(/^\.\/(.*)\.\w+$/, '$1')
.replace(/[-_/][a-z]/gi, (s) => s.substring(1).toUpperCase());
const value = modulesPermissionFiles[modulePath].default;

// pass sys/user/add => sys:user:add
const permissionModule = Object.keys(value).reduce((obj, key) => {
obj[key] = generatePermCode(value[key]);
return obj;
}, {});

modules[moduleName] = permissionModule;
// console.log('permissions modules', modules);
return modules;
},
{},
);
// console.log('permissions', permissions);

/**
* @description 将权限列表转成级联选择器要求的数据格式
*/
Expand Down Expand Up @@ -99,4 +63,20 @@ export const formarPermsToCascader = () => {
// }
// }
// })
export default permissions;
/**
* 验证权限
* @param {PermissionType} perm 权限码
* @returns {boolean} true | false
*/
export const verifyAuth = (perm: PermissionType) => {
const permCode = perm.split('/').join(':');
const permissionList = useUserStore().perms;

return permissionList.some((n) => n === permCode);
};

export default {
install(app: App) {
app.config.globalProperties.$auth = verifyAuth;
},
};
42 changes: 42 additions & 0 deletions src/core/permission/modules/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
interface Permissions {
[key: string]: {
[key: string]: string;
};
}

const modulesPermissionFiles = import.meta.globEager('./**/*.ts');
/**
* 根据接口路径生成接口权限码, eg: sys/user/add => sys:user:add
* @param str 接口路径
* @returns {string}
*/
export const generatePermCode = (str: string) => str.replace(/\//g, ':');

const filterDirs = ['/index.ts', './types.ts'];

/**
* @description 权限列表
*/
export const permissions: Permissions = Object.keys(modulesPermissionFiles).reduce(
(modules, modulePath) => {
if (filterDirs.some((n) => modulePath.includes(n))) return modules;
// set './app.js' => 'app'
// set './sys/app.js' => 'sysApp'
const moduleName = modulePath
.replace(/^\.\/(.*)\.\w+$/, '$1')
.replace(/[-_/][a-z]/gi, (s) => s.substring(1).toUpperCase());
const value = modulesPermissionFiles[modulePath].default;

// pass sys/user/add => sys:user:add
const permissionModule = Object.keys(value).reduce((obj, key) => {
obj[key] = generatePermCode(value[key]);
return obj;
}, {});

modules[moduleName] = permissionModule;
// console.log('permissions modules', modules);
return modules;
},
{},
);
console.log('permissions', permissions);
3 changes: 3 additions & 0 deletions src/core/permission/modules/netdisk/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import type { NetdiskMangePerms } from './manage';

export type NetdiskPermissionType = NetdiskMangePerms;
10 changes: 8 additions & 2 deletions src/core/permission/modules/netdisk/manage.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export default {
export const netdiskMange = {
list: 'netdisk/manage/list',
mkdir: 'netdisk/manage/mkdir',
token: 'netdisk/manage/token',
Expand All @@ -10,4 +10,10 @@ export default {
mark: 'netdisk/manage/mark',
cut: 'netdisk/manage/cut',
copy: 'netdisk/manage/copy',
};
} as const;

export const values = Object.values(netdiskMange);

export type NetdiskMangePerms = typeof values[number];

export default netdiskMange;
13 changes: 11 additions & 2 deletions src/core/permission/modules/sys/dept.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
export default {
export const sysDept = {
/** 获取部门列表 */
list: 'sys/dept/list',
/** 移动部门 */
move: 'sys/dept/move',
/** 更新部门 */
update: 'sys/dept/update',
delete: 'sys/dept/delete',
add: 'sys/dept/add',
info: 'sys/dept/info',
transfer: 'sys/dept/transfer',
};
} as const;

export const values = Object.values(sysDept);

export type SysDeptPerms = typeof values[number];

export default sysDept;
16 changes: 16 additions & 0 deletions src/core/permission/modules/sys/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { SysLogPerms } from './log';
import { SysDeptPerms } from './dept';
import { SysMenuPerms } from './menu';
import { SysOnlinePerms } from './online';
import { SysRolePerms } from './role';
import { SysTaskPerms } from './task';
import { SysUserPerms } from './user';

export type SysPermissionType =
| SysLogPerms
| SysDeptPerms
| SysMenuPerms
| SysOnlinePerms
| SysRolePerms
| SysTaskPerms
| SysUserPerms;
10 changes: 8 additions & 2 deletions src/core/permission/modules/sys/log.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
export default {
export const sysLog = {
req: 'sys/log/req/page',
login: 'sys/log/login/page',
task: 'sys/log/task/page',
};
} as const;

export const values = Object.values(sysLog);

export type SysLogPerms = typeof values[number];

export default sysLog;
10 changes: 8 additions & 2 deletions src/core/permission/modules/sys/menu.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
export default {
export const sysMenu = {
list: 'sys/menu/list',
add: 'sys/menu/add',
update: 'sys/menu/update',
info: 'sys/menu/info',
delete: 'sys/menu/delete',
};
} as const;

export const deptValues = Object.values(sysMenu);

export type SysMenuPerms = typeof deptValues[number];

export default sysMenu;
10 changes: 8 additions & 2 deletions src/core/permission/modules/sys/online.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
export default {
export const sysOnline = {
list: 'sys/online/list',
kick: 'sys/online/kick',
};
} as const;

export const values = Object.values(sysOnline);

export type SysOnlinePerms = typeof values[number];

export default sysOnline;
10 changes: 8 additions & 2 deletions src/core/permission/modules/sys/role.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
export default {
export const sysRole = {
list: 'sys/role/list',
page: 'sys/role/page',
add: 'sys/role/add',
update: 'sys/role/update',
delete: 'sys/role/delete',
info: 'sys/role/info',
};
} as const;

export const values = Object.values(sysRole);

export type SysRolePerms = typeof values[number];

export default sysRole;
10 changes: 8 additions & 2 deletions src/core/permission/modules/sys/task.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export default {
export const sysTask = {
page: 'sys/task/page',
add: 'sys/task/add',
update: 'sys/task/update',
Expand All @@ -7,4 +7,10 @@ export default {
start: 'sys/task/start',
stop: 'sys/task/stop',
info: 'sys/task/info',
};
} as const;

export const values = Object.values(sysTask);

export type SysTaskPerms = typeof values[number];

export default sysTask;
10 changes: 8 additions & 2 deletions src/core/permission/modules/sys/user.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
export default {
export const sysUser = {
add: 'sys/user/add',
page: 'sys/user/page',
info: 'sys/user/info',
update: 'sys/user/update',
delete: 'sys/user/delete',
password: 'sys/user/password',
};
} as const;

export const values = Object.values(sysUser);

export type SysUserPerms = typeof values[number];

export default sysUser;
Loading

0 comments on commit 5538d38

Please sign in to comment.