page.tsx 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998
  1. "use client";
  2. import { fetchApi, fetchFile } from "@/app/_modules/func";
  3. import {
  4. CaretDownOutlined,
  5. CheckOutlined,
  6. CloseOutlined,
  7. DeleteOutlined,
  8. ExclamationCircleFilled,
  9. KeyOutlined,
  10. PlusOutlined,
  11. ReloadOutlined,
  12. } from "@ant-design/icons";
  13. import type {
  14. ActionType,
  15. ProColumns,
  16. ProFormInstance,
  17. } from "@ant-design/pro-components";
  18. import {
  19. ModalForm,
  20. PageContainer,
  21. ProForm,
  22. ProFormDigit,
  23. ProFormRadio,
  24. ProFormText,
  25. ProFormTextArea,
  26. ProFormTreeSelect,
  27. ProTable,
  28. } from "@ant-design/pro-components";
  29. import type { GetProp, UploadProps } from "antd";
  30. import {
  31. Button,
  32. Dropdown,
  33. Form,
  34. Input,
  35. message,
  36. Modal,
  37. Select,
  38. Space,
  39. Switch,
  40. Upload,
  41. } from "antd";
  42. import { useRouter } from "next/navigation";
  43. import {
  44. faDownload,
  45. faPenToSquare,
  46. faToggleOff,
  47. faToggleOn,
  48. faUsers,
  49. } from "@fortawesome/free-solid-svg-icons";
  50. import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
  51. import { TreeSelect } from "@/node_modules/antd/es/index";
  52. import { useRef, useState } from "react";
  53. type FileType = Parameters<GetProp<UploadProps, "beforeUpload">>[0];
  54. const { Dragger } = Upload;
  55. export type OptionType = {
  56. label: string;
  57. value: string | number;
  58. };
  59. export default function Role() {
  60. const { push } = useRouter();
  61. //控制行的状态值的恢复
  62. const [rowStatusMap, setRowStatusMap] = useState<{ [key: number]: boolean }>(
  63. {}
  64. );
  65. //表格列定义
  66. //表格列定义
  67. const columns: ProColumns[] = [
  68. {
  69. title: "角色编号",
  70. dataIndex: "roleId",
  71. search: false,
  72. },
  73. {
  74. title: "角色名称",
  75. fieldProps: {
  76. placeholder: "请输入角色名称",
  77. },
  78. dataIndex: "roleName",
  79. ellipsis: true,
  80. sorter: true,
  81. order: 4,
  82. },
  83. {
  84. title: "权限字符",
  85. fieldProps: {
  86. placeholder: "请输入权限字符",
  87. },
  88. dataIndex: "roleKey",
  89. ellipsis: true,
  90. sorter: true,
  91. order: 3,
  92. },
  93. {
  94. title: "角色排序",
  95. dataIndex: "roleSort",
  96. search: false,
  97. sorter: true,
  98. },
  99. {
  100. title: "状态",
  101. fieldProps: {
  102. placeholder: "请选择角色状态",
  103. },
  104. dataIndex: "status",
  105. valueType: "select",
  106. order: 2,
  107. valueEnum: {
  108. 0: {
  109. text: "正常",
  110. status: "0",
  111. },
  112. 1: {
  113. text: "停用",
  114. status: "1",
  115. },
  116. },
  117. render: (text, record) => {
  118. return (
  119. <Space>
  120. <Switch
  121. checkedChildren={<CheckOutlined />}
  122. unCheckedChildren={<CloseOutlined />}
  123. defaultChecked={record.status === "0"}
  124. checked={rowStatusMap[record.roleId]}
  125. disabled={record.roleId == 1}
  126. onChange={(checked, event) => {
  127. showSwitchRoleStatusModal(checked, record);
  128. }}
  129. />
  130. </Space>
  131. );
  132. },
  133. },
  134. {
  135. title: "创建时间",
  136. dataIndex: "createTime",
  137. valueType: "dateTime",
  138. search: false,
  139. sorter: true,
  140. },
  141. {
  142. title: "创建时间",
  143. fieldProps: {
  144. placeholder: ["开始日期", "结束日期"],
  145. },
  146. dataIndex: "createTimeRange",
  147. valueType: "dateRange",
  148. hideInTable: true,
  149. order: 1,
  150. search: {
  151. transform: (value) => {
  152. return {
  153. "params[beginTime]": `${value[0]} 00:00:00`,
  154. "params[endTime]": `${value[1]} 23:59:59`,
  155. };
  156. },
  157. },
  158. },
  159. {
  160. title: "操作",
  161. key: "option",
  162. search: false,
  163. render: (_, record) => {
  164. if (record.roleId != 1)
  165. return [
  166. <Button
  167. key="modifyBtn"
  168. type="link"
  169. icon={<FontAwesomeIcon icon={faPenToSquare} />}
  170. onClick={() => showRowModifyModal(record)}
  171. >
  172. 修改
  173. </Button>,
  174. <Button
  175. key="deleteBtn"
  176. type="link"
  177. danger
  178. icon={<DeleteOutlined />}
  179. onClick={() => onClickDeleteRow(record)}
  180. >
  181. 删除
  182. </Button>,
  183. <Dropdown
  184. key="moreDrop"
  185. menu={{
  186. items: [
  187. {
  188. key: "1",
  189. label: (
  190. <a
  191. onClick={() => {
  192. modifyRolePermission(record);
  193. }}
  194. >
  195. 数据权限
  196. </a>
  197. ),
  198. icon: <KeyOutlined />,
  199. },
  200. {
  201. key: "2",
  202. label: (
  203. <a
  204. onClick={() =>
  205. push(`/system/role/auth/${record.roleId}`)
  206. }
  207. >
  208. 分配用户
  209. </a>
  210. ),
  211. icon: <FontAwesomeIcon icon={faUsers} />,
  212. },
  213. ],
  214. }}
  215. >
  216. <a onClick={(e) => e.preventDefault()}>
  217. <Space>
  218. 更多
  219. <CaretDownOutlined />
  220. </Space>
  221. </a>
  222. </Dropdown>,
  223. ];
  224. },
  225. },
  226. ];
  227. //是否展示修改角色对话框
  228. const [showModifyRoleModal, setShowModifyRoleModal] = useState(false);
  229. //展示修改用户对话框
  230. const showRowModifyModal = (record?: any) => {
  231. queryRoleInfo(record);
  232. setShowModifyRoleModal(true);
  233. queryRolePermissionData(record);
  234. };
  235. //是否展示修改角色权限
  236. const [showModifyRolePermissionModal, setShowModifyRolePermissionModal] =
  237. useState(false);
  238. //重置密码表单引用
  239. const [scopeFormRef] = Form.useForm();
  240. //打开修改角色权限范围对话框
  241. const modifyRolePermission = (record: any) => {
  242. attachRowdata["roleId"] = record.roleId;
  243. attachRowdata["roleName"] = record.roleName;
  244. setAttachRowdata(attachRowdata);
  245. setShowModifyRolePermissionModal(true);
  246. queryRoleScope(record.roleId);
  247. queryRoleDeptTree(record.roleId);
  248. };
  249. //查询用户相关权限范围
  250. const queryRoleScope = async (roleId: number) => {
  251. const body = await fetchApi(`/api/system/role/${roleId}`, push);
  252. if (body !== undefined) {
  253. if (body.code == 200) {
  254. scopeFormRef.setFieldsValue({
  255. roleName: body.data.roleName,
  256. roleKey: body.data.roleKey,
  257. dataScope: body.data.dataScope,
  258. });
  259. if (body.data.dataScope === "2") {
  260. setShowDept(true);
  261. }
  262. }
  263. }
  264. };
  265. //角色权限范围的部门树
  266. const [roleDeptTree, setRoleDeptTree] = useState([]);
  267. //查询角色权限范围的部门树
  268. const queryRoleDeptTree = async (roleId: number) => {
  269. const body = await fetchApi(`/api/system/role/deptTree/${roleId}`, push);
  270. if (body !== undefined) {
  271. if (body.code == 200) {
  272. setRoleDeptTree(body.depts);
  273. scopeFormRef.setFieldsValue({
  274. deptIds: body.checkedKeys,
  275. });
  276. }
  277. }
  278. };
  279. //是否展示部门列表
  280. const [showDept, setShowDept] = useState(false);
  281. //选择权限范围
  282. const onSelectScope = (value: number) => {
  283. setShowDept(value == 2);
  284. };
  285. //确认修改角色权限范围
  286. const confirmModifyRolePermission = () => {
  287. scopeFormRef.submit();
  288. setShowDept(false);
  289. };
  290. //取消修改角色权限范围
  291. const cancelModifyRolePermission = () => {
  292. setShowModifyRolePermissionModal(false);
  293. setShowDept(false);
  294. };
  295. //执行修改分配权限范围
  296. const executeModifyRolePermissionScope = async (values: any) => {
  297. setShowModifyRolePermissionModal(false);
  298. values["roleId"] = attachRowdata["roleId"];
  299. if (!values.hasOwnProperty("deptIds")) {
  300. values["deptIds"] = [];
  301. }
  302. console.log("depts:", values);
  303. const body = await fetchApi("/api/system/role/dataScope", push, {
  304. method: "PUT",
  305. headers: {
  306. "Content-Type": "application/json",
  307. },
  308. body: JSON.stringify(values),
  309. });
  310. if (body != undefined) {
  311. if (body.code == 200) {
  312. message.success(`修改${attachRowdata["roleName"]}权限范围成功`);
  313. } else {
  314. message.error(body.msg);
  315. }
  316. }
  317. scopeFormRef.resetFields();
  318. };
  319. //查询用户数据
  320. const getList = async (params: any, sorter: any, filter: any) => {
  321. const searchParams = {
  322. pageNum: params.current,
  323. ...params,
  324. };
  325. delete searchParams.current;
  326. const queryParams = new URLSearchParams(searchParams);
  327. Object.keys(sorter).forEach((key) => {
  328. queryParams.append("orderByColumn", key);
  329. if (sorter[key] === "ascend") {
  330. queryParams.append("isAsc", "ascending");
  331. } else {
  332. queryParams.append("isAsc", "descending");
  333. }
  334. });
  335. const body = await fetchApi(`/api/system/role/list?${queryParams}`, push);
  336. if (body !== undefined) {
  337. body.rows.forEach((row: any) => {
  338. setRowStatusMap({ ...rowStatusMap, [row.roleId]: row.status === "0" });
  339. });
  340. }
  341. return body;
  342. };
  343. //展示切换角色状态对话框
  344. const showSwitchRoleStatusModal = (checked: boolean, record: any) => {
  345. setRowStatusMap({ ...rowStatusMap, [record.roleId]: checked });
  346. Modal.confirm({
  347. title: "系统提示",
  348. icon: <ExclamationCircleFilled />,
  349. content: `确认要${checked ? "启用" : "停用"}"${record.roleName}"角色吗?`,
  350. onOk() {
  351. executeSwitchStatus(checked, record.roleId, () => {
  352. setRowStatusMap({ ...rowStatusMap, [record.roleId]: !checked });
  353. });
  354. },
  355. onCancel() {
  356. setRowStatusMap({ ...rowStatusMap, [record.roleId]: !checked });
  357. },
  358. });
  359. };
  360. //确认变更角色状态
  361. const executeSwitchStatus = async (
  362. checked: boolean,
  363. roleId: string,
  364. erroCallback: () => void
  365. ) => {
  366. const modifyData = {
  367. roleId: roleId,
  368. status: checked ? "0" : "1",
  369. };
  370. const body = await fetchApi(`/api/system/role/changeStatus`, push, {
  371. method: "PUT",
  372. headers: {
  373. "Content-Type": "application/json",
  374. },
  375. body: JSON.stringify(modifyData),
  376. });
  377. if (body !== undefined) {
  378. if (body.code == 200) {
  379. message.success(body.msg);
  380. } else {
  381. message.error(body.msg);
  382. erroCallback();
  383. }
  384. }
  385. };
  386. //删除按钮是否可用,选中行时才可用
  387. const [rowCanDelete, setRowCanDelete] = useState(false);
  388. //选中行操作
  389. const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
  390. const [selectedRow, setSelectedRow] = useState(undefined as any);
  391. //修改按钮是否可用
  392. const [rowCanModify, setRowCanModify] = useState(false);
  393. const rowSelection = {
  394. onChange: (newSelectedRowKeys: React.Key[], selectedRows: any[]) => {
  395. setSelectedRowKeys(newSelectedRowKeys);
  396. setRowCanDelete(newSelectedRowKeys && newSelectedRowKeys.length > 0);
  397. if (newSelectedRowKeys && newSelectedRowKeys.length == 1) {
  398. setSelectedRow(selectedRows[0]);
  399. setRowCanModify(true);
  400. } else {
  401. setRowCanModify(false);
  402. setSelectedRow(undefined);
  403. }
  404. },
  405. getCheckboxProps: (record: any) => ({
  406. disabled: record.roleId == 1,
  407. }),
  408. };
  409. //确定新建角色
  410. const executeAddRole = async (values: any) => {
  411. const body = await fetchApi("/api/system/role", push, {
  412. method: "POST",
  413. headers: {
  414. "Content-Type": "application/json",
  415. },
  416. body: JSON.stringify(values),
  417. });
  418. if (body != undefined) {
  419. if (body.code == 200) {
  420. message.success(body.msg);
  421. if (actionRef.current) {
  422. actionRef.current.reload();
  423. }
  424. return true;
  425. }
  426. message.error(body.msg);
  427. return false;
  428. }
  429. return false;
  430. };
  431. //修改角色表单引用
  432. const modifyFormRef = useRef<ProFormInstance>();
  433. //操作角色的附加数据
  434. const [attachRowdata, setAttachRowdata] = useState<{ [key: string]: any }>(
  435. {}
  436. );
  437. //查询用户信息
  438. const queryRoleInfo = async (record?: any) => {
  439. const roleId = record !== undefined ? record.roleId : selectedRow.roleId;
  440. const roleName =
  441. record !== undefined ? record.roleName : selectedRow.roleName;
  442. attachRowdata["roleId"] = roleId;
  443. attachRowdata["roleName"] = roleName;
  444. setAttachRowdata(attachRowdata);
  445. if (roleId !== undefined) {
  446. const body = await fetchApi(`/api/system/role/${roleId}`, push);
  447. if (body !== undefined) {
  448. if (body.code == 200) {
  449. modifyFormRef?.current?.setFieldsValue({
  450. roleName: body.data.roleName,
  451. roleKey: body.data.roleKey,
  452. roleSort: body.data.roleSort,
  453. status: body.data.status,
  454. menuIds: body.menuIds,
  455. remark: body.data.remark,
  456. });
  457. }
  458. }
  459. }
  460. };
  461. //待修改角色选中的权限数据
  462. const [roleSelectedPermission, setRoleSelectedPermission] = useState([]);
  463. //修改角色框中权限树数据
  464. const [rolePermissionTree, setRolePermissionTree] = useState([]);
  465. //查询修改角色时权限树,并获取角色选中权限数据
  466. const queryRolePermissionData = async (record?: any) => {
  467. const roleId = record !== undefined ? record.roleId : selectedRow.roleId;
  468. const body = await fetchApi(
  469. `/api/system/menu/roleMenuTreeselect/${roleId}`,
  470. push
  471. );
  472. if (body !== undefined) {
  473. if (body.code == 200) {
  474. setRolePermissionTree(body.menus);
  475. //绑定角色已选择的权限
  476. modifyFormRef?.current?.setFieldsValue({
  477. menuIds: body.checkedKeys,
  478. });
  479. }
  480. }
  481. };
  482. //确认修改角色
  483. const executeModifyRole = async (values: any) => {
  484. values["roleId"] = attachRowdata["roleId"];
  485. const body = await fetchApi("/api/system/role", push, {
  486. method: "PUT",
  487. headers: {
  488. "Content-Type": "application/json",
  489. },
  490. body: JSON.stringify(values),
  491. });
  492. if (body !== undefined) {
  493. setShowModifyRoleModal(false);
  494. if (body.code == 200) {
  495. message.success(body.msg);
  496. //刷新列表
  497. if (actionRef.current) {
  498. actionRef.current.reload();
  499. }
  500. return true;
  501. }
  502. message.error(body.msg);
  503. return false;
  504. }
  505. };
  506. //点击删除按钮
  507. const onClickDeleteRow = (record?: any) => {
  508. const roleId =
  509. record != undefined ? record.roleId : selectedRowKeys.join(",");
  510. Modal.confirm({
  511. title: "系统提示",
  512. icon: <ExclamationCircleFilled />,
  513. content: `确定删除角色编号为“${roleId}”的数据项?`,
  514. onOk() {
  515. executeDeleteRow(roleId);
  516. },
  517. onCancel() {},
  518. });
  519. };
  520. //确定删除选中的角色
  521. const executeDeleteRow = async (roleId: any) => {
  522. const body = await fetchApi(`/api/system/role/${roleId}`, push, {
  523. method: "DELETE",
  524. });
  525. if (body !== undefined) {
  526. if (body.code == 200) {
  527. message.success("删除成功");
  528. //修改按钮变回不可点击
  529. setRowCanModify(false);
  530. //删除按钮变回不可点击
  531. setRowCanDelete(false);
  532. //选中行数据重置为空
  533. setSelectedRowKeys([]);
  534. //刷新列表
  535. if (actionRef.current) {
  536. actionRef.current.reload();
  537. }
  538. } else {
  539. message.error(body.msg);
  540. }
  541. }
  542. };
  543. //搜索栏显示状态
  544. const [showSearch, setShowSearch] = useState(true);
  545. //action对象引用
  546. const actionRef = useRef<ActionType>();
  547. //表单对象引用
  548. const formRef = useRef<ProFormInstance>();
  549. //当前页数和每页条数
  550. const [page, setPage] = useState(1);
  551. const defaultPageSize = 10;
  552. const [pageSize, setPageSize] = useState(defaultPageSize);
  553. const pageChange = (page: number, pageSize: number) => {
  554. setPage(page);
  555. setPageSize(pageSize);
  556. };
  557. //导出用户
  558. const exportTable = async () => {
  559. if (formRef.current) {
  560. const formData = new FormData();
  561. const data = {
  562. pageNum: page,
  563. pageSize: pageSize,
  564. ...formRef.current.getFieldsValue(),
  565. };
  566. Object.keys(data).forEach((key) => {
  567. if (data[key] !== undefined) {
  568. formData.append(key, data[key]);
  569. }
  570. });
  571. await fetchFile(
  572. "/api/system/role/export",
  573. push,
  574. {
  575. method: "POST",
  576. body: formData,
  577. },
  578. `role_${new Date().getTime()}.xlsx`
  579. );
  580. }
  581. };
  582. //查询所有权限树
  583. const getPermissionTree = async () => {
  584. const body = await fetchApi("/api/system/menu/treeselect", push);
  585. if (body !== undefined) {
  586. if (body.code == 200) {
  587. return body.data;
  588. }
  589. }
  590. return [];
  591. };
  592. return (
  593. <PageContainer title={false}>
  594. <ProTable
  595. formRef={formRef}
  596. rowKey="roleId"
  597. rowSelection={{
  598. selectedRowKeys,
  599. ...rowSelection,
  600. }}
  601. columns={columns}
  602. request={async (params: any, sorter: any, filter: any) => {
  603. // 表单搜索项会从 params 传入,传递给后端接口。
  604. const data = await getList(params, sorter, filter);
  605. if (data !== undefined) {
  606. return Promise.resolve({
  607. data: data.rows,
  608. success: true,
  609. total: data.total,
  610. });
  611. }
  612. return Promise.resolve({
  613. data: [],
  614. success: true,
  615. });
  616. }}
  617. pagination={{
  618. defaultPageSize: defaultPageSize,
  619. showQuickJumper: true,
  620. showSizeChanger: true,
  621. onChange: pageChange,
  622. }}
  623. search={
  624. showSearch
  625. ? {
  626. defaultCollapsed: false,
  627. searchText: "搜索",
  628. }
  629. : false
  630. }
  631. dateFormatter="string"
  632. actionRef={actionRef}
  633. toolbar={{
  634. actions: [
  635. <ModalForm
  636. key="addmodal"
  637. title="添加角色"
  638. trigger={
  639. <Button icon={<PlusOutlined />} type="primary">
  640. 新建
  641. </Button>
  642. }
  643. autoFocusFirstInput
  644. modalProps={{
  645. destroyOnHidden: true,
  646. }}
  647. submitTimeout={2000}
  648. onFinish={executeAddRole}
  649. >
  650. <ProForm.Group>
  651. <ProFormText
  652. width="md"
  653. name="roleName"
  654. label="角色名称"
  655. placeholder="请输入角色名称"
  656. rules={[{ required: true, message: "请输入角色名称" }]}
  657. />
  658. <ProFormText
  659. width="md"
  660. name="roleKey"
  661. label="权限字符"
  662. placeholder="请输入权限字符"
  663. rules={[{ required: true, message: "请输入权限字符" }]}
  664. />
  665. </ProForm.Group>
  666. <ProForm.Group>
  667. <ProFormDigit
  668. fieldProps={{ precision: 0 }}
  669. width="md"
  670. name="roleSort"
  671. initialValue="0"
  672. label="角色排序"
  673. placeholder="请输入角色排序"
  674. rules={[{ required: true, message: "请输入角色排序" }]}
  675. />
  676. <ProFormRadio.Group
  677. name="status"
  678. width="sm"
  679. label="状态"
  680. initialValue="0"
  681. options={[
  682. {
  683. label: "正常",
  684. value: "0",
  685. },
  686. {
  687. label: "停用",
  688. value: "1",
  689. },
  690. ]}
  691. />
  692. </ProForm.Group>
  693. <ProFormTreeSelect
  694. width="md"
  695. name="menuIds"
  696. label="菜单权限"
  697. request={async () => {
  698. return getPermissionTree();
  699. }}
  700. fieldProps={{
  701. placement: "topRight",
  702. filterTreeNode: true,
  703. showSearch: true,
  704. multiple: true,
  705. treeCheckable: true,
  706. treeNodeFilterProp: "label",
  707. fieldNames: {
  708. label: "label",
  709. value: "id",
  710. },
  711. }}
  712. />
  713. <ProFormTextArea
  714. name="remark"
  715. width={688}
  716. label="备注"
  717. placeholder="请输入内容"
  718. />
  719. </ModalForm>,
  720. <ModalForm
  721. key="modifymodal"
  722. title="修改角色"
  723. formRef={modifyFormRef}
  724. trigger={
  725. <Button
  726. icon={<FontAwesomeIcon icon={faPenToSquare} />}
  727. disabled={!rowCanModify}
  728. onClick={() => showRowModifyModal()}
  729. >
  730. 修改
  731. </Button>
  732. }
  733. open={showModifyRoleModal}
  734. autoFocusFirstInput
  735. modalProps={{
  736. destroyOnHidden: true,
  737. onCancel: () => {
  738. setShowModifyRoleModal(false);
  739. },
  740. }}
  741. submitTimeout={2000}
  742. onFinish={executeModifyRole}
  743. >
  744. <ProForm.Group>
  745. <ProFormText
  746. width="md"
  747. name="roleName"
  748. label="角色名称"
  749. placeholder="请输入角色名称"
  750. rules={[{ required: true, message: "请输入角色名称" }]}
  751. />
  752. <ProFormText
  753. width="md"
  754. name="roleKey"
  755. label="权限字符"
  756. placeholder="请输入权限字符"
  757. rules={[{ required: true, message: "请输入权限字符" }]}
  758. />
  759. </ProForm.Group>
  760. <ProForm.Group>
  761. <ProFormDigit
  762. fieldProps={{ precision: 0 }}
  763. width="md"
  764. name="roleSort"
  765. initialValue="0"
  766. label="角色排序"
  767. placeholder="请输入角色排序"
  768. rules={[{ required: true, message: "请输入角色排序" }]}
  769. />
  770. <ProFormRadio.Group
  771. name="status"
  772. width="sm"
  773. label="状态"
  774. initialValue="0"
  775. options={[
  776. {
  777. label: "正常",
  778. value: "0",
  779. },
  780. {
  781. label: "停用",
  782. value: "1",
  783. },
  784. ]}
  785. />
  786. </ProForm.Group>
  787. <ProFormTreeSelect
  788. width="md"
  789. name="menuIds"
  790. label="菜单权限"
  791. initialValue={roleSelectedPermission}
  792. request={async () => {
  793. return rolePermissionTree;
  794. }}
  795. fieldProps={{
  796. placement: "topRight",
  797. filterTreeNode: true,
  798. showSearch: true,
  799. multiple: true,
  800. treeCheckable: true,
  801. treeNodeFilterProp: "label",
  802. fieldNames: {
  803. label: "label",
  804. value: "id",
  805. },
  806. }}
  807. />
  808. <ProFormTextArea
  809. name="remark"
  810. width={688}
  811. label="备注"
  812. placeholder="请输入内容"
  813. />
  814. </ModalForm>,
  815. <Button
  816. key="danger"
  817. danger
  818. icon={<DeleteOutlined />}
  819. disabled={!rowCanDelete}
  820. onClick={() => onClickDeleteRow()}
  821. >
  822. 删除
  823. </Button>,
  824. <Button
  825. key="export"
  826. type="primary"
  827. icon={<FontAwesomeIcon icon={faDownload} />}
  828. onClick={exportTable}
  829. >
  830. 导出
  831. </Button>,
  832. ],
  833. settings: [
  834. {
  835. key: "switch",
  836. icon: showSearch ? (
  837. <FontAwesomeIcon icon={faToggleOn} />
  838. ) : (
  839. <FontAwesomeIcon icon={faToggleOff} />
  840. ),
  841. tooltip: showSearch ? "隐藏搜索栏" : "显示搜索栏",
  842. onClick: (key: string | undefined) => {
  843. setShowSearch(!showSearch);
  844. },
  845. },
  846. {
  847. key: "refresh",
  848. tooltip: "刷新",
  849. icon: <ReloadOutlined />,
  850. onClick: (key: string | undefined) => {
  851. if (actionRef.current) {
  852. actionRef.current.reload();
  853. }
  854. },
  855. },
  856. ],
  857. }}
  858. />
  859. <Modal
  860. title={`分配数据权限`}
  861. open={showModifyRolePermissionModal}
  862. onOk={confirmModifyRolePermission}
  863. onCancel={cancelModifyRolePermission}
  864. >
  865. <Form
  866. layout="horizontal"
  867. form={scopeFormRef}
  868. onFinish={executeModifyRolePermissionScope}
  869. >
  870. <Form.Item name="roleName" label="角色名称">
  871. <Input disabled />
  872. </Form.Item>
  873. <Form.Item name="roleKey" label="权限字符">
  874. <Input disabled />
  875. </Form.Item>
  876. <Form.Item name="dataScope" label="权限范围" initialValue="1">
  877. <Select
  878. placeholder="选择权限范围"
  879. onChange={onSelectScope}
  880. options={[
  881. {
  882. label: "全部数据权限",
  883. value: "1",
  884. },
  885. {
  886. label: "自定义数据权限",
  887. value: "2",
  888. },
  889. {
  890. label: "本部门数据权限",
  891. value: "3",
  892. },
  893. {
  894. label: "本部门及以下权限",
  895. value: "4",
  896. },
  897. {
  898. label: "仅本人数据权限",
  899. value: "5",
  900. },
  901. ]}
  902. ></Select>
  903. </Form.Item>
  904. {showDept && (
  905. <Form.Item name="deptIds" label="数据权限">
  906. <TreeSelect
  907. treeData={roleDeptTree}
  908. allowClear
  909. multiple={true}
  910. showCheckedStrategy={TreeSelect.SHOW_ALL}
  911. treeCheckable={true}
  912. fieldNames={{
  913. label: "label",
  914. value: "id",
  915. }}
  916. />
  917. </Form.Item>
  918. )}
  919. </Form>
  920. </Modal>
  921. </PageContainer>
  922. );
  923. }