还是接着上一节来 ant design 的 tree 如何作为角色中的权限选择之一
这里先放一下全部代码:
import { useIntl } from '@umijs/max';
import React, { Key, useState } from 'react';
import { ProForm, ProFormText } from '@ant-design/pro-components';
import { Form, Input, Spin, Tree } from 'antd';
import useQueryList from '@/hooks/useQueryList';
import { FormInstance } from 'antd/es/form';
import { Permission } from '@/apiDataStructures/ApiDataStructure';
interface Props {
form?: FormInstance<any>;
newRecord?: boolean;
onFinish: (formData: any) => Promise<void>;
values?: any;
}
const BasicForm: React.FC<Props> = ({ newRecord, onFinish, values }) => {
const intl = useIntl();
const { items: permissionGroups, loading } = useQueryList('/permission-groups/list');
const [expandedKeys, setExpandedKeys] = useState<Key[]>([]);
const [autoExpandParent, setAutoExpandParent] = useState<boolean>(true);
const [checkedKeys, setCheckedKeys] = useState<Key[] | { checked: Key[]; halfChecked: Key[] }>(
values.permissions?.map((permission: Permission) => `${permission._id}`) ?? [],
);
const [selectedKeys, setSelectedKeys] = useState<Key[]>([]);
const onExpand = (expandedKeysValue: Key[]) => {
setExpandedKeys(expandedKeysValue);
setAutoExpandParent(false);
};
const onCheck = (checkedKeysValue: Key[] | { checked: Key[]; halfChecked: Key[] }) => {
setCheckedKeys(checkedKeysValue);
console.log('checkedKeysValue', checkedKeysValue);
};
const onSelect = (selectedKeysValue: Key[]) => {
setSelectedKeys(selectedKeysValue);
};
return (
<ProForm
initialValues={{
...values,
permissions: values?.permissions?.map((permission: Permission) => permission._id),
}}
onFinish={async (values) => {
await onFinish({
...values,
permissions: checkedKeys,
});
}}
>
<ProForm.Group>
<ProFormText
rules={[{ required: true, message: intl.formatMessage({ id: 'enter_name' }) }]}
width="md"
label={intl.formatMessage({ id: 'name' })}
name="name"
/>
<ProForm.Item name="permissions" label={intl.formatMessage({ id: 'permission_choose' })}>
<Spin spinning={loading}>
<Tree
checkable
onExpand={onExpand}
expandedKeys={expandedKeys}
autoExpandParent={autoExpandParent}
onCheck={onCheck}
checkedKeys={checkedKeys}
onSelect={onSelect}
selectedKeys={selectedKeys}
treeData={permissionGroups} // Use filtered top-level groups
fieldNames={{ title: 'name', key: '_id', children: 'children' }}
/>
</Spin>
</ProForm.Item>
</ProForm.Group>
{!newRecord && (
<Form.Item name="_id" label={false}>
<Input type="hidden" />
</Form.Item>
)}
</ProForm>
);
};
export default BasicForm;
const { items: permissionGroups, loading } = useQueryList('/permission-groups/list');
这一部分的源码也放出来:
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;
为什么编辑的时候会填充上选中的状态?
<ProForm
initialValues={{
...values,
permissions: values?.permissions?.map((permission: Permission) => permission._id),
}}
onFinish={async (values) => {
await onFinish({
...values,
permissions: checkedKeys,
});
}}
>
主要是这个 initialValues ,permissions 是 那个 name ,对上了就好。
但是提交的时候要把 permissions 带上。
后端的话可以参考我的设计,
我是权限组是有层级的,然后权限组下面有权限
import mongoose, { Document } from 'mongoose';
export interface IPermissionGroup extends Document {
name: string;
parent?: IPermissionGroup;
children?: IPermissionGroup[];
createdAt?: Date;
updatedAt?: Date;
}
const permissionGroupSchema = new mongoose.Schema(
{
name: { type: String, required: true, unique: true },
parent: { type: mongoose.Schema.Types.ObjectId, ref: 'PermissionGroup' },
},
{ timestamps: true },
);
const PermissionGroup = mongoose.model<IPermissionGroup>(
'PermissionGroup',
permissionGroupSchema,
);
export default PermissionGroup;
import mongoose, { Document } from 'mongoose';
import { IPermissionGroup } from './permissionGroup';
export interface IPermission extends Document {
name: string;
path: string;
action: string;
permissionGroup: IPermissionGroup;
createdAt?: Date;
updatedAt?: Date;
}
const permissionSchema = new mongoose.Schema({
name: { type: String, required: true },
path: { type: String, required: true },
action: { type: String, required: true },
permissionGroup: { type: mongoose.Schema.Types.ObjectId, ref: 'PermissionGroup' },
}, { timestamps: true });
const Permission = mongoose.model<IPermission>('Permission', permissionSchema);
export default Permission;
大约是这样的情况,希望对大家有所帮助
我的网站