feat: RBAC

This commit is contained in:
2025-03-12 11:38:34 +08:00
parent e06d00feff
commit fb3686968d
17 changed files with 144 additions and 98 deletions

View File

@@ -1,9 +1,17 @@
import request from '@/utils/request';
export function grantPermission(id: string, menuIds: string[]) {
return request.put(`/permission/roles/${id}/resources`, { menuIds });
export function assignMenus(id: string, menuIds: string[]) {
return request.put(`/permission/roles/${id}/menus`, { menuIds });
}
export function getRoleMenuIds(id: string) {
return request.get(`/permission/roles/${id}/resources`);
export function getMenus(id: string) {
return request.get(`/permission/roles/${id}/menus`);
}
export function assignResources(id: string, resourceIds: string[]) {
return request.put(`/permission/roles/${id}/menus`, { resourceIds });
}
export function getResources(id: string) {
return request.get(`/permission/roles/${id}/menus`);
}

View File

@@ -12,8 +12,6 @@ export const enum TableOptions {
DELETE = 'delete',
}
export function getColumns(callback: (type: TableOptions, record: any) => Promise<void>): TableColumnProps[] {
return [
{
@@ -28,7 +26,7 @@ export function getColumns(callback: (type: TableOptions, record: any) => Promis
},
{
title: '权限字符',
dataIndex: 'permission',
dataIndex: 'permissionKey',
align: 'center',
},
{

View File

@@ -88,7 +88,7 @@ export default function FormComponent(props: Props) {
<Form.Item label="权限名称" field="name" rules={[{required: true}]}>
<Input placeholder="请输入权限名称"/>
</Form.Item>
<Form.Item label="权限字符" field="permission" rules={[{required: true}]}>
<Form.Item label="权限字符" field="permissionKey" rules={[{required: true}]}>
<Input placeholder="请输入权限字符"/>
</Form.Item>
<Form.Item label="排序" field="sort">

View File

@@ -1,13 +1,18 @@
import React, { useEffect, useState } from 'react';
import { Modal, Form, Input, Message, Tree } from '@arco-design/web-react';
import { getTreeMenu } from '@/api/menu';
import { getRoleMenuIds, grantPermission } from '@/api/permission';
import {
getMenus,
getResources,
assignMenus,
assignResources,
} from '@/api/permission';
interface Props {
record: { [key: string]: any } | null,
visible: boolean,
handleConfirm: () => void,
handleCancel: () => void
record: { [key: string]: any } | null;
visible: boolean;
handleConfirm: () => void;
handleCancel: () => void;
}
function GrantPermission(props: Props) {
@@ -20,7 +25,7 @@ function GrantPermission(props: Props) {
try {
setConfirmLoading(true);
const values = await form.validate();
await grantPermission(values.id, checkedKeys);
await assignMenus(values.id, checkedKeys);
Message.success(`操作成功!`);
handleConfirm();
} catch (e) {
@@ -33,12 +38,12 @@ function GrantPermission(props: Props) {
const [form] = Form.useForm();
useEffect(() => {
record && form.setFieldsValue({
...record
});
record &&
form.setFieldsValue({
...record,
});
}, [record]);
const [handleFinished, setHandleFinished] = useState(false);
const handleMenuAndKeys = (menu, menuIds) => {
let newMenuIds = menuIds.map((menuId) => menuId);
@@ -49,8 +54,8 @@ function GrantPermission(props: Props) {
item.parentId = item.id;
if (item.children?.length > 0) {
if (item.children.some(child => !newMenuIds.includes(child.id))) {
newMenuIds = newMenuIds.filter(id => id !== item.id);
if (item.children.some((child) => !newMenuIds.includes(child.id))) {
newMenuIds = newMenuIds.filter((id) => id !== item.id);
}
handleMenu(item.children);
}
@@ -72,7 +77,7 @@ function GrantPermission(props: Props) {
if (visible) {
const fetchTreeMenu = async () => {
const { data } = await getTreeMenu();
const { data: menuIds } = await getRoleMenuIds(record.id);
const { data: menuIds } = await getMenus(record.id);
handleMenuAndKeys(data, menuIds);
};
fetchTreeMenu();
@@ -98,8 +103,8 @@ function GrantPermission(props: Props) {
<Input />
</Form.Item>
<Form.Item label="菜单权限">
{
handleFinished && <Tree
{handleFinished && (
<Tree
checkable
checkedKeys={checkedKeys}
autoExpandParent={true}
@@ -109,10 +114,10 @@ function GrantPermission(props: Props) {
treeData={treeData}
fieldNames={{
key: 'id',
title: 'name'
title: 'name',
}}
></Tree>
}
)}
</Form.Item>
</Form>
</Modal>

View File

@@ -14,7 +14,7 @@ import Form from './form';
import {IconPlus} from '@arco-design/web-react/icon';
import {getColumns, TableOptions} from './constants';
import {getRole,deleteRole} from "@/api/role";
import GrantRolesForm from "./grantPerm";
import AssignMenusForm from "./grantPerm";
import SearchForm from "./searchForm";
@@ -24,7 +24,7 @@ function UserManage() {
const reactQueryKey = useHistory().location.pathname
const [visible, setVisible] = useState(false);
const [visibleAssignRoles, setVisibleAssignRoles] = useState(false);
const [visibleAssignMenus, setVisibleAssignMenus] = useState(false);
const [record, setRecord] = useState(null);
const [pagination, setPagination] = useState<PaginationProps>({
sizeCanChange: true,
@@ -40,11 +40,15 @@ function UserManage() {
pageSize: pagination.pageSize,
});
const showAssignRolesModal = (payload) => {
const showAssignMenusModal = (payload) => {
setRecord(payload);
setVisibleAssignRoles(true);
setVisibleAssignMenus(true);
};
const showAssignResourcesModal = () => {
}
const showModal = (payload?) => {
payload && setRecord(payload);
setVisible(true);
@@ -65,7 +69,10 @@ function UserManage() {
await onDelete(record);
break
case TableOptions.ASSIGN_MENUS:
showAssignRolesModal(record);
showAssignMenusModal(record);
break
case TableOptions.ASSIGN_RESOURCES:
showAssignResourcesModal(record);
break
}
}
@@ -108,14 +115,14 @@ function UserManage() {
const handleConfirm = async () => {
setRecord(null);
setVisible(false);
setVisibleAssignRoles(false);
setVisibleAssignMenus(false);
await refetch();
};
const handleCancel = () => {
setRecord(null);
setVisible(false);
setVisibleAssignRoles(false);
setVisibleAssignMenus(false);
};
useEffect(() => {
@@ -135,10 +142,10 @@ function UserManage() {
visible={visible}
record={record}
/>
<GrantRolesForm
<AssignMenusForm
handleConfirm={handleConfirm}
handleCancel={handleCancel}
visible={visibleAssignRoles}
visible={visibleAssignMenus}
record={record}
/>
<Title heading={6}></Title>