deploy-ease-platform/frontend/src/pages/System/User/components/RoleModal.tsx
2024-11-28 09:57:54 +08:00

108 lines
2.7 KiB
TypeScript

import React, { useEffect, useState } from 'react';
import { Modal, Transfer, message, Spin } from 'antd';
import type { TransferDirection, TransferProps } from 'antd/es/transfer';
import { getRoles } from '../../Role/service';
import { getUserRoleIds, updateUserRoles } from '../service';
import type { RoleDTO } from '../../Role/types';
interface RoleModalProps {
userId: number;
visible: boolean;
onCancel: () => void;
onSuccess: () => void;
}
interface RoleTransferItem {
key: string;
title: string;
description: string;
disabled?: boolean;
}
const RoleModal: React.FC<RoleModalProps> = ({
userId,
visible,
onCancel,
onSuccess
}) => {
const [roles, setRoles] = useState<RoleDTO[]>([]);
const [selectedKeys, setSelectedKeys] = useState<string[]>([]);
const [loading, setLoading] = useState(false);
const fetchData = async () => {
try {
setLoading(true);
const [allRoles, userRoleIds] = await Promise.all([
getRoles(),
getUserRoleIds(userId)
]);
setRoles(allRoles);
setSelectedKeys(userRoleIds.map(String));
} catch (error) {
message.error('获取角色数据失败');
} finally {
setLoading(false);
}
};
useEffect(() => {
if (visible) {
fetchData();
}
}, [visible, userId]);
const handleChange: TransferProps<RoleTransferItem>['onChange'] = (nextTargetKeys) => {
setSelectedKeys(nextTargetKeys as string[]);
};
const handleOk = async () => {
try {
setLoading(true);
await updateUserRoles(userId, selectedKeys.map(Number));
message.success('角色分配成功');
onSuccess();
} catch (error) {
message.error('角色分配失败');
} finally {
setLoading(false);
}
};
return (
<Modal
title="分配角色"
open={visible}
onOk={handleOk}
onCancel={onCancel}
width={600}
confirmLoading={loading}
destroyOnClose
>
<Spin spinning={loading}>
<Transfer<RoleTransferItem>
dataSource={roles.map(role => ({
key: role.id.toString(),
title: role.name,
description: role.code,
disabled: role.code === 'ROLE_ADMIN'
}))}
titles={['未选择', '已选择']}
targetKeys={selectedKeys}
onChange={handleChange}
render={item => item.title}
listStyle={{
width: 250,
height: 400,
}}
showSearch
filterOption={(inputValue, item) =>
(item.title?.toLowerCase().indexOf(inputValue.toLowerCase()) !== -1) ||
(item.description?.toLowerCase().indexOf(inputValue.toLowerCase()) !== -1)
}
/>
</Spin>
</Modal>
);
};
export default RoleModal;