- ant design pro 如何去保存颜色
- ant design pro v6 如何做好角色管理
- ant design 的 tree 如何作为角色中的权限选择之一
- ant design 的 tree 如何作为角色中的权限选择之二
- ant design pro access.ts 是如何控制多角色的权限的
看上面的图片
当创建或编辑一个用户时,如何让它可以选择多个角色呢?
创建时简单,找到相应的组件放上去即可。
但是角色的数据是从后端拉取的。
所以首先第一步是要准备好一个角色列表的 api 的。
我这里已经有的:
数据格式是这样的:
javascript
{
"success": true,
"data": [
{
"_id": "66b6d773b9ad87dfa985f6ef",
"name": "运营员",
"permissions": [
{
"_id": "66b6d7a5b9ad87dfa985f749",
"name": "添加材料类目",
"path": "/material-categories",
"action": "POST",
"permissionGroup": "66adec30d647a4fde5546b1c",
"createdAt": "2024-08-10T02:59:49.106Z",
"updatedAt": "2024-08-10T07:36:39.702Z",
"__v": 0
},
{
"_id": "66b6d7b4b9ad87dfa985f75c",
"name": "删除材料类目",
"path": "/material-categories",
"action": "DELETE",
"permissionGroup": "66adec30d647a4fde5546b1c",
"createdAt": "2024-08-10T03:00:04.930Z",
"updatedAt": "2024-08-10T07:36:36.183Z",
"__v": 0
},
{
"_id": "66b6d7c4b9ad87dfa985f76f",
"name": "更新材料类目",
"path": "/material-categories/:id",
"action": "PUT",
"permissionGroup": "66adec30d647a4fde5546b1c",
"createdAt": "2024-08-10T03:00:20.075Z",
"updatedAt": "2024-08-10T07:36:32.789Z",
"__v": 0
},
{
"_id": "66b6d7d0b9ad87dfa985f782",
"name": "查看材料类目",
"path": "/material-categories",
"action": "GET",
"permissionGroup": "66adec30d647a4fde5546b1c",
"createdAt": "2024-08-10T03:00:32.932Z",
"updatedAt": "2024-08-10T08:02:59.634Z",
"__v": 0
}
],
"dataPermissions": [],
"createdAt": "2024-08-10T02:58:59.814Z",
"updatedAt": "2024-08-12T05:27:45.204Z",
"__v": 0
},
{
"_id": "66b6d74eb9ad87dfa985f6b1",
"name": "管理员",
"permissions": [
{
"_id": "66adee8cd22d6d5b1ce00780",
"name": "更新权限",
"path": "/permissions/:id",
"action": "PUT",
"permissionGroup": "66b1b00bb5d937a0aef34034",
"createdAt": "2024-08-03T08:47:08.777Z",
"updatedAt": "2024-08-10T02:38:15.837Z",
"__v": 0
},
{
"_id": "66b1a12b0e10340bd8bbeba0",
"name": "删除权限",
"path": "/permissions",
"action": "DELETE",
"createdAt": "2024-08-06T04:06:03.752Z",
"updatedAt": "2024-08-10T02:31:07.287Z",
"__v": 0,
"permissionGroup": "66b1b00bb5d937a0aef34034"
},
{
"_id": "66b1c55141364c27c464f858",
"name": "查看权限",
"path": "/permissions",
"action": "GET",
"permissionGroup": "66b1b00bb5d937a0aef34034",
"createdAt": "2024-08-06T06:40:17.991Z",
"updatedAt": "2024-08-10T08:03:27.245Z",
"__v": 0
},
{
"_id": "66b6cf51aa92a3526285b14d",
"name": "添加权限",
"path": "/permissions",
"action": "POST",
"createdAt": "2024-08-10T02:24:17.940Z",
"updatedAt": "2024-08-10T02:30:22.189Z",
"__v": 0,
"permissionGroup": "66b1b00bb5d937a0aef34034"
},
{
"_id": "66b6d339b9ad87dfa985f3dd",
"name": "添加用户",
"path": "/users",
"action": "POST",
"permissionGroup": "66b6d2c9b9ad87dfa985f34f",
"createdAt": "2024-08-10T02:40:57.583Z",
"updatedAt": "2024-08-10T02:41:30.112Z",
"__v": 0
},
{
"_id": "66b6d352b9ad87dfa985f3f0",
"name": "查看用户",
"path": "/users",
"action": "GET",
"permissionGroup": "66b6d2c9b9ad87dfa985f34f",
"createdAt": "2024-08-10T02:41:22.895Z",
"updatedAt": "2024-08-10T08:03:22.477Z",
"__v": 0
},
{
"_id": "66b6d368b9ad87dfa985f416",
"name": "删除用户",
"path": "/users",
"action": "DELETE",
"permissionGroup": "66b6d2c9b9ad87dfa985f34f",
"createdAt": "2024-08-10T02:41:44.912Z",
"updatedAt": "2024-08-10T02:41:44.912Z",
"__v": 0
},
{
"_id": "66b6d37bb9ad87dfa985f429",
"name": "更新用户",
"path": "/users/:id",
"action": "PUT",
"permissionGroup": "66b6d2c9b9ad87dfa985f34f",
"createdAt": "2024-08-10T02:42:03.242Z",
"updatedAt": "2024-08-10T02:45:40.000Z",
"__v": 0
},
{
"_id": "66b6d440b9ad87dfa985f488",
"name": "添加菜单",
"path": "/menus",
"action": "POST",
"permissionGroup": "66b6d2ddb9ad87dfa985f362",
"createdAt": "2024-08-10T02:45:20.021Z",
"updatedAt": "2024-08-10T02:45:20.021Z",
"__v": 0
},
{
"_id": "66b6d46cb9ad87dfa985f4c1",
"name": "删除菜单",
"path": "/menus",
"action": "DELETE",
"permissionGroup": "66b6d2ddb9ad87dfa985f362",
"createdAt": "2024-08-10T02:46:04.896Z",
"updatedAt": "2024-08-10T02:46:04.896Z",
"__v": 0
},
{
"_id": "66b6d47db9ad87dfa985f4d4",
"name": "更新菜单",
"path": "/menus/:id",
"action": "PUT",
"permissionGroup": "66b6d2ddb9ad87dfa985f362",
"createdAt": "2024-08-10T02:46:21.612Z",
"updatedAt": "2024-08-10T02:46:52.140Z",
"__v": 0
},
{
"_id": "66b6d48bb9ad87dfa985f4e7",
"name": "查看菜单",
"path": "/menus",
"action": "GET",
"permissionGroup": "66b6d2ddb9ad87dfa985f362",
"createdAt": "2024-08-10T02:46:35.896Z",
"updatedAt": "2024-08-10T08:03:13.698Z",
"__v": 0
},
{
"_id": "66b6d39eb9ad87dfa985f43c",
"name": "添加角色",
"path": "/roles",
"action": "POST",
"permissionGroup": "66b6d2e9b9ad87dfa985f377",
"createdAt": "2024-08-10T02:42:38.531Z",
"updatedAt": "2024-08-10T02:42:38.531Z",
"__v": 0
},
{
"_id": "66b6d3dfb9ad87dfa985f44f",
"name": "删除角色",
"path": "/roles",
"action": "DELETE",
"permissionGroup": "66b6d2e9b9ad87dfa985f377",
"createdAt": "2024-08-10T02:43:43.882Z",
"updatedAt": "2024-08-10T02:43:43.882Z",
"__v": 0
},
{
"_id": "66b6d3fab9ad87dfa985f462",
"name": "更新角色",
"path": "/roles/:id",
"action": "PUT",
"permissionGroup": "66b6d2e9b9ad87dfa985f377",
"createdAt": "2024-08-10T02:44:10.845Z",
"updatedAt": "2024-08-10T02:45:31.647Z",
"__v": 0
},
{
"_id": "66b6d40db9ad87dfa985f475",
"name": "查看角色",
"path": "/roles",
"action": "GET",
"permissionGroup": "66b6d2e9b9ad87dfa985f377",
"createdAt": "2024-08-10T02:44:29.797Z",
"updatedAt": "2024-08-10T08:03:18.669Z",
"__v": 0
},
{
"_id": "66b6d544b9ad87dfa985f559",
"name": "添加数据权限",
"path": "/data-permissions",
"action": "POST",
"permissionGroup": "66b6d2fdb9ad87dfa985f38e",
"createdAt": "2024-08-10T02:49:40.379Z",
"updatedAt": "2024-08-10T02:49:40.379Z",
"__v": 0
},
{
"_id": "66b6d559b9ad87dfa985f56c",
"name": "删除数据权限",
"path": "/data-permissions",
"action": "DELETE",
"permissionGroup": "66b6d2fdb9ad87dfa985f38e",
"createdAt": "2024-08-10T02:50:01.137Z",
"updatedAt": "2024-08-10T02:50:01.137Z",
"__v": 0
},
{
"_id": "66b6d578b9ad87dfa985f57f",
"name": "更新数据权限",
"path": "/data-permissions/:id",
"action": "PUT",
"permissionGroup": "66b6d2fdb9ad87dfa985f38e",
"createdAt": "2024-08-10T02:50:32.533Z",
"updatedAt": "2024-08-10T02:50:32.533Z",
"__v": 0
},
{
"_id": "66b6d586b9ad87dfa985f592",
"name": "查看数据权限",
"path": "/data-permissions",
"action": "GET",
"permissionGroup": "66b6d2fdb9ad87dfa985f38e",
"createdAt": "2024-08-10T02:50:46.780Z",
"updatedAt": "2024-08-10T08:03:04.925Z",
"__v": 0
},
{
"_id": "66b9ad528554e602536acc84",
"name": "授权管理菜单",
"path": "/auth",
"action": "GET",
"permissionGroup": "66b9ad348554e602536acc67",
"createdAt": "2024-08-12T06:36:02.754Z",
"updatedAt": "2024-08-12T06:36:02.754Z",
"__v": 0
},
{
"_id": "66b6d4bdb9ad87dfa985f50d",
"name": "添加权限组",
"path": "/permission-groups",
"action": "POST",
"permissionGroup": "66b6d314b9ad87dfa985f3a7",
"createdAt": "2024-08-10T02:47:25.139Z",
"updatedAt": "2024-08-10T02:47:25.139Z",
"__v": 0
},
{
"_id": "66b6d500b9ad87dfa985f520",
"name": "删除权限组",
"path": "/permission-groups",
"action": "DELETE",
"permissionGroup": "66b6d314b9ad87dfa985f3a7",
"createdAt": "2024-08-10T02:48:32.481Z",
"updatedAt": "2024-08-10T02:48:32.481Z",
"__v": 0
},
{
"_id": "66b6d519b9ad87dfa985f533",
"name": "更新权限组",
"path": "/permission-groups/:id",
"action": "PUT",
"permissionGroup": "66b6d314b9ad87dfa985f3a7",
"createdAt": "2024-08-10T02:48:57.720Z",
"updatedAt": "2024-08-10T02:48:57.720Z",
"__v": 0
},
{
"_id": "66b6d52cb9ad87dfa985f546",
"name": "查看权限组",
"path": "/permission-groups",
"action": "GET",
"permissionGroup": "66b6d314b9ad87dfa985f3a7",
"createdAt": "2024-08-10T02:49:16.624Z",
"updatedAt": "2024-08-10T08:03:09.517Z",
"__v": 0
}
],
"dataPermissions": [],
"createdAt": "2024-08-10T02:58:22.168Z",
"updatedAt": "2024-08-12T06:57:27.434Z",
"__v": 0
}
]
}
也就是说是个数组,数组中的对象,要有 name 和 _id.
name 是显示出来的,_id 才是最终传给后端的
我们看下代码:
javascript
<ProFormCheckbox.Group
name="roles"
layout="horizontal"
label={intl.formatMessage({ id: 'role_choose' })}
options={roles?.map((role: { name: string; _id: string }) => ({
label: role.name,
value: role._id,
}))}
fieldProps={{
disabled: loading, // 确保在 loading 时禁用复选框
}}
/>
</ProForm.Group>
这个是可有 可无的:
fieldProps={{
disabled: loading, // 确保在 loading 时禁用复选框
}}
主要还是 roles 的数据。
const { items: roles, loading } = useQueryList('/roles');
我后端请求得到的。之前有分享过 useQueryList 的源码的。
javascript
import { useEffect, useState } from 'react';
import { queryList } from '@/services/ant-design-pro/api';
const useQueryList = (url: string, hasPermission = true) => {
const [items, setItems] = useState([]);
const [loading, setLoading] = useState(false);
const query = async () => {
setLoading(true);
// Only proceed with the API call if the user has permission
if (hasPermission) {
const response = (await queryList(url, { pageSize: 10000 })) as any;
if (response.success) {
setItems(response.data);
}
}
setLoading(false);
};
useEffect(() => {
query().catch(console.error);
}, [hasPermission]); // Adding `hasPermission` to the dependency array to re-run the effect if it changes
return { items, setItems, loading };
};
export default useQueryList;
最完整的表单代码是这样的:
javascript
import { useIntl } from '@umijs/max';
import React from 'react';
import { ProForm, ProFormText, ProFormCheckbox } from '@ant-design/pro-components';
import { Form, Input } from 'antd';
import useQueryList from '@/hooks/useQueryList';
interface Props {
newRecord?: boolean;
onFinish: (formData: any) => Promise<void>;
values?: any;
}
const BasicForm: React.FC<Props> = ({ newRecord, onFinish, values }) => {
const intl = useIntl();
const { items: roles, loading } = useQueryList('/roles');
return (
<ProForm
initialValues={{
...values,
roles: values?.roles?.map((role: { _id: string }) => role._id),
}}
onFinish={async (values) => {
await onFinish({
...values,
});
}}
>
<ProForm.Group>
<ProFormText
rules={[{ required: true, message: intl.formatMessage({ id: 'enter_name' }) }]}
width="md"
label={intl.formatMessage({ id: 'name' })}
name="name"
/>
<ProFormText
rules={[{ required: true, message: intl.formatMessage({ id: 'enter_email' }) }]}
width="md"
label={intl.formatMessage({ id: 'email' })}
name="email"
/>
<ProFormText
rules={[{ required: newRecord, message: intl.formatMessage({ id: 'enter_password' }) }]}
width="md"
label={intl.formatMessage({ id: 'password' })}
name="password"
/>
<ProFormCheckbox.Group
name="roles"
layout="horizontal"
label={intl.formatMessage({ id: 'role_choose' })}
options={roles?.map((role: { name: string; _id: string }) => ({
label: role.name,
value: role._id,
}))}
fieldProps={{
disabled: loading, // 确保在 loading 时禁用复选框
}}
/>
</ProForm.Group>
{!newRecord && (
<Form.Item name="_id" label={false}>
<Input type="hidden" />
</Form.Item>
)}
</ProForm>
);
};
export default BasicForm;
要让编辑的时候选中。
initialValues={{
...values,
roles: values?.roles?.map((role: { _id: string }) => role._id),
}}
就是这里的代码发挥的作用
name="roles"
你只要填充好默认值即可。是个数组,由 _id 组成。
所以你的用户列表,一定要有 roles.