RoleEdit.tsx 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. import { userApi } from "@/api";
  2. import { FormPageFooter, PageContainer } from "@/components";
  3. import { PermItemType } from "@/types";
  4. import { getAuthorizedIds } from "@/utils";
  5. import { DageLoading } from "@dage/pc-components";
  6. import { Form, Input, Tree } from "antd";
  7. import { FC, Key, useEffect, useMemo, useState } from "react";
  8. import { useNavigate, useParams } from "react-router-dom";
  9. const { TextArea } = Input;
  10. const getCheckedIds = (treeData: PermItemType[], checkedIds: number[]) => {
  11. const fullyCheckedIds: number[] = [];
  12. const halfCheckedIds: number[] = [];
  13. const checkNode = (node: PermItemType): boolean => {
  14. let allChildrenChecked = true;
  15. let someChildrenChecked = false;
  16. if (node.children && node.children.length > 0) {
  17. for (const child of node.children) {
  18. const isChildChecked = checkNode(child);
  19. if (!isChildChecked) allChildrenChecked = false;
  20. if (isChildChecked) someChildrenChecked = true;
  21. }
  22. }
  23. const isNodeExplicitlyChecked = checkedIds.includes(node.id);
  24. if (
  25. isNodeExplicitlyChecked &&
  26. (allChildrenChecked || node.children?.length === 0)
  27. ) {
  28. fullyCheckedIds.push(node.id);
  29. return true;
  30. }
  31. if (
  32. (someChildrenChecked && !isNodeExplicitlyChecked) ||
  33. (isNodeExplicitlyChecked && !allChildrenChecked)
  34. ) {
  35. halfCheckedIds.push(node.id);
  36. return true;
  37. }
  38. return isNodeExplicitlyChecked;
  39. };
  40. treeData.forEach((node) => checkNode(node));
  41. return { fullyCheckedIds, halfCheckedIds };
  42. };
  43. const RoleEditPage: FC = () => {
  44. const [form] = Form.useForm();
  45. const params = useParams();
  46. const navigate = useNavigate();
  47. const isEdit = useMemo(() => location.href.indexOf("edit") > -1, [location]);
  48. const [permTree, setPermTree] = useState<PermItemType[]>([]);
  49. const [checkedKeys, setCheckedKeys] = useState<Key[]>([]);
  50. const [halfCheckedKeys, setHalfCheckedKeys] = useState<Key[]>([]);
  51. const [loading, setLoading] = useState(false);
  52. const getTree = async () => {
  53. const data = await userApi.getPermTree();
  54. setPermTree(data);
  55. };
  56. const getDetail = async () => {
  57. try {
  58. setLoading(true);
  59. const data = await userApi.getRole(params.id as string);
  60. form.setFieldsValue({
  61. roleName: data.role.roleName,
  62. roleDesc: data.role.roleDesc,
  63. });
  64. const idsRes = getCheckedIds(permTree, getAuthorizedIds(data.permission));
  65. setCheckedKeys(idsRes.fullyCheckedIds);
  66. setHalfCheckedKeys(idsRes.halfCheckedIds);
  67. } finally {
  68. setLoading(false);
  69. }
  70. };
  71. const handleSubmit = async () => {
  72. if (!(await form.validateFields())) return;
  73. const val = form.getFieldsValue();
  74. await userApi.saveRole({
  75. ...val,
  76. resources: [...checkedKeys, ...halfCheckedKeys],
  77. id: params.id,
  78. });
  79. navigate(-1);
  80. };
  81. useEffect(() => {
  82. getTree();
  83. }, []);
  84. useEffect(() => {
  85. if (params.id && permTree.length) getDetail();
  86. }, [permTree]);
  87. return (
  88. <PageContainer title={isEdit ? "编辑角色" : "新增角色"}>
  89. {loading && <DageLoading />}
  90. <Form labelCol={{ span: 4 }} form={form}>
  91. <Form.Item
  92. label="角色名称"
  93. name="roleName"
  94. required
  95. rules={[{ required: true, message: "请输入内容" }]}
  96. >
  97. <Input
  98. className="w450"
  99. showCount
  100. maxLength={10}
  101. placeholder="请输入内容,最多10字;不能重复"
  102. />
  103. </Form.Item>
  104. <Form.Item label="角色说明" name="roleDesc">
  105. <TextArea
  106. className="w450"
  107. showCount
  108. style={{ height: 200 }}
  109. maxLength={200}
  110. placeholder="请输入内容,最多200字;不能重复"
  111. />
  112. </Form.Item>
  113. <Form.Item label="用户权限">
  114. <div className="w450">
  115. <Tree
  116. checkable
  117. // @ts-ignore
  118. treeData={permTree}
  119. checkedKeys={{
  120. checked: checkedKeys,
  121. halfChecked: halfCheckedKeys,
  122. }}
  123. fieldNames={{ title: "name", key: "id" }}
  124. onCheck={(keys, halfKeys) => {
  125. setCheckedKeys(keys as number[]);
  126. if (halfKeys.halfCheckedKeys) {
  127. setHalfCheckedKeys(halfKeys.halfCheckedKeys as number[]);
  128. }
  129. }}
  130. />
  131. </div>
  132. </Form.Item>
  133. </Form>
  134. <FormPageFooter onSubmit={handleSubmit} onCancel={() => navigate(-1)} />
  135. </PageContainer>
  136. );
  137. };
  138. export default RoleEditPage;