page.tsx 29 KB

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