BindRolesDrawer.tsx 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. import { fetchRoleList } from '@/services/role';
  2. import { fetchBindRoles, fetchUserDetail } from '@/services/user';
  3. import { Button, Checkbox, Drawer, Spin, message } from 'antd';
  4. import { useEffect, useState } from 'react';
  5. interface BindRolesDrawerProps {
  6. userId: number;
  7. productCode: string;
  8. open: boolean;
  9. onClose: () => void;
  10. }
  11. export const BindRolesDrawer = ({ userId, productCode, open, onClose }: BindRolesDrawerProps) => {
  12. const [loading, setLoading] = useState(false);
  13. const [saving, setSaving] = useState(false);
  14. const [roles, setRoles] = useState<API.RoleItem[]>([]);
  15. const [checkedIds, setCheckedIds] = useState<number[]>([]);
  16. useEffect(() => {
  17. if (!open) return;
  18. setLoading(true);
  19. Promise.all([fetchUserDetail({ id: userId }), fetchRoleList({ productCode, pageSize: 999 })])
  20. .then(([userRes, roleRes]) => {
  21. setRoles(roleRes.data ?? []);
  22. setCheckedIds(userRes.data?.roleIds ?? []);
  23. })
  24. .finally(() => setLoading(false));
  25. }, [open, userId, productCode]);
  26. const handleSave = async () => {
  27. setSaving(true);
  28. try {
  29. await fetchBindRoles({ userId, roleIds: checkedIds });
  30. message.success('保存成功');
  31. onClose();
  32. } finally {
  33. setSaving(false);
  34. }
  35. };
  36. const toggle = (id: number) =>
  37. setCheckedIds((prev) => (prev.includes(id) ? prev.filter((i) => i !== id) : [...prev, id]));
  38. return (
  39. <Drawer
  40. title="分配角色"
  41. open={open}
  42. onClose={onClose}
  43. width={400}
  44. extra={
  45. <Button type="primary" loading={saving} onClick={handleSave}>
  46. 保存
  47. </Button>
  48. }
  49. >
  50. <Spin spinning={loading}>
  51. <div className="flex flex-col gap-2">
  52. {roles.map((r) => (
  53. <Checkbox key={r.id} checked={checkedIds.includes(r.id)} onChange={() => toggle(r.id)}>
  54. <span>{r.name}</span>
  55. <span className="text-xs text-gray-400 ml-2">级别 {r.permsLevel}</span>
  56. </Checkbox>
  57. ))}
  58. {roles.length === 0 && !loading && (
  59. <span className="text-gray-400 text-sm">该产品暂无角色</span>
  60. )}
  61. </div>
  62. </Spin>
  63. </Drawer>
  64. );
  65. };