page.tsx 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887
  1. "use client";
  2. import { fetchApi } from "@/app/_modules/func";
  3. import {
  4. DeleteOutlined,
  5. ExclamationCircleFilled,
  6. PlusOutlined,
  7. ReloadOutlined,
  8. } from "@ant-design/icons";
  9. import type {
  10. ActionType,
  11. ProColumns,
  12. ProFormInstance,
  13. } from "@ant-design/pro-components";
  14. import {
  15. ModalForm,
  16. PageContainer,
  17. ProForm,
  18. ProFormDigit,
  19. ProFormRadio,
  20. ProFormSelect,
  21. ProFormText,
  22. ProFormTreeSelect,
  23. ProTable,
  24. } from "@ant-design/pro-components";
  25. import { Button, message, Modal, Space, Tag } from "antd";
  26. import { useRouter } from "next/navigation";
  27. import {
  28. faArrowsUpDown,
  29. faCheck,
  30. faPenToSquare,
  31. faToggleOff,
  32. faToggleOn,
  33. faXmark,
  34. } from "@fortawesome/free-solid-svg-icons";
  35. import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
  36. import { IconMap } from "@/app/_modules/definies";
  37. import { useRef, useState } from "react";
  38. //查询表格数据API
  39. const queryAPI = "/api/system/menu/list";
  40. //新建数据API
  41. const newAPI = "/api/system/menu";
  42. //修改数据API
  43. const modifyAPI = "/api/system/menu";
  44. //查询详情数据API
  45. const queryDetailAPI = "/api/system/menu";
  46. //删除API
  47. const deleteAPI = "/api/system/menu";
  48. export default function Menu() {
  49. const { push } = useRouter();
  50. //表格列定义
  51. const columns: ProColumns[] = [
  52. {
  53. title: "菜单名称",
  54. fieldProps: {
  55. placeholder: "请输入菜单名称",
  56. },
  57. dataIndex: "menuName",
  58. order: 2,
  59. },
  60. {
  61. title: "图标",
  62. dataIndex: "icon",
  63. search: false,
  64. },
  65. {
  66. title: "排序",
  67. dataIndex: "orderNum",
  68. search: false,
  69. },
  70. {
  71. title: "权限标识",
  72. dataIndex: "perms",
  73. ellipsis: true,
  74. search: false,
  75. },
  76. {
  77. title: "状态",
  78. fieldProps: {
  79. placeholder: "请选择菜单状态",
  80. },
  81. dataIndex: "status",
  82. valueType: "select",
  83. render: (_, record) => {
  84. return (
  85. <Space>
  86. <Tag
  87. color={record.status === "0" ? "green" : "red"}
  88. icon={
  89. record.status == 0 ? (
  90. <FontAwesomeIcon icon={faCheck} />
  91. ) : (
  92. <FontAwesomeIcon icon={faXmark} />
  93. )
  94. }
  95. >
  96. {_}
  97. </Tag>
  98. </Space>
  99. );
  100. },
  101. valueEnum: {
  102. 0: {
  103. text: "正常",
  104. status: "0",
  105. },
  106. 1: {
  107. text: "停用",
  108. status: "1",
  109. },
  110. },
  111. order: 1,
  112. },
  113. {
  114. title: "创建时间",
  115. dataIndex: "createTime",
  116. valueType: "dateTime",
  117. search: false,
  118. },
  119. {
  120. title: "操作",
  121. key: "option",
  122. search: false,
  123. render: (_, record) => [
  124. <Button
  125. key="modifyBtn"
  126. type="link"
  127. icon={<FontAwesomeIcon icon={faPenToSquare} />}
  128. onClick={() => onClickShowRowModifyModal(record)}
  129. >
  130. 修改
  131. </Button>,
  132. <Button
  133. key="newBtn"
  134. type="link"
  135. icon={<PlusOutlined />}
  136. onClick={() => onClickAdd(record)}
  137. >
  138. 新建
  139. </Button>,
  140. <Button
  141. key="deleteBtn"
  142. type="link"
  143. danger
  144. icon={<DeleteOutlined />}
  145. onClick={() => onClickDeleteRow(record)}
  146. >
  147. 删除
  148. </Button>,
  149. ],
  150. },
  151. ];
  152. //0.查询表格数据
  153. //原始的可展开的所有行的 id
  154. const [defaultExpandKeys, setDefaultExpandKeys] = useState<any[]>([]);
  155. //控制行展开的数据
  156. const [expandKeys, setExpandKeys] = useState<any[]>([]);
  157. const queryTableData = async (params: any, sorter: any, filter: any) => {
  158. const searchParams = {
  159. ...params,
  160. };
  161. const queryParams = new URLSearchParams(searchParams);
  162. Object.keys(sorter).forEach((key) => {
  163. queryParams.append("orderByColumn", key);
  164. if (sorter[key] === "ascend") {
  165. queryParams.append("isAsc", "ascending");
  166. } else {
  167. queryParams.append("isAsc", "descending");
  168. }
  169. });
  170. const body = await fetchApi(`${queryAPI}?${queryParams}`, push);
  171. const firstLevel = getFirstLevel(body.data);
  172. firstLevel.forEach((first) => {
  173. getChildren(body.data, first);
  174. });
  175. const newExpandedKeys: any[] = [];
  176. const render = (treeDatas: any[]) => {
  177. // 获取到所有可展开的父节点
  178. treeDatas.map((item) => {
  179. if (item.children) {
  180. newExpandedKeys.push(item.menuId);
  181. render(item.children);
  182. }
  183. });
  184. return newExpandedKeys;
  185. };
  186. const keys = render(firstLevel);
  187. setDefaultExpandKeys(keys);
  188. setExpandKeys([]);
  189. return firstLevel;
  190. };
  191. const getFirstLevel = (data: any[]) => {
  192. const firstLevel: any[] = [];
  193. for (let index = 0; index < data.length; index++) {
  194. const item = data[index];
  195. if (item.parentId === 0) {
  196. firstLevel.push(item);
  197. }
  198. }
  199. return firstLevel;
  200. };
  201. const getChildren = (data: any[], parentNode: any) => {
  202. for (let index = 0; index < data.length; index++) {
  203. const item = data[index];
  204. if (item.parentId === parentNode.menuId) {
  205. parentNode.children.push(item);
  206. getChildren(data, item);
  207. }
  208. }
  209. if (parentNode.children.length == 0) {
  210. delete parentNode.children;
  211. }
  212. };
  213. //1.新建
  214. const [showAddModal, setShowAddModal] = useState(false);
  215. //新建表单是否带有父节点id
  216. const [rowParentId, setRowParentId] = useState(0);
  217. //点击新建,如果从行点击新建,给定父节点
  218. const onClickAdd = (record?: any) => {
  219. setRowParentId(record.menuId);
  220. setShowAddModal(true);
  221. };
  222. const cancelAddModal = () => {
  223. setShowAddModal(false);
  224. setRowParentId(0);
  225. };
  226. //确定新建数据
  227. const executeAddData = async (values: any) => {
  228. const body = await fetchApi(newAPI, push, {
  229. method: "POST",
  230. headers: {
  231. "Content-Type": "application/json",
  232. },
  233. body: JSON.stringify(values),
  234. });
  235. if (body != undefined) {
  236. if (body.code == 200) {
  237. message.success(body.msg);
  238. if (actionTableRef.current) {
  239. actionTableRef.current.reload();
  240. }
  241. setShowAddModal(false);
  242. return true;
  243. }
  244. message.error(body.msg);
  245. return false;
  246. }
  247. return false;
  248. };
  249. //2.修改
  250. //是否展示修改对话框
  251. const [isShowModifyDataModal, setIsShowModifyDataModal] = useState(false);
  252. //展示修改对话框
  253. const onClickShowRowModifyModal = (record: any) => {
  254. queryRowData(record);
  255. setIsShowModifyDataModal(true);
  256. };
  257. //修改数据表单引用
  258. const modifyFormRef = useRef<ProFormInstance>();
  259. //操作当前数据的附加数据
  260. const [operatRowData, setOperateRowData] = useState<{
  261. [key: string]: any;
  262. }>({});
  263. //查询并加载待修改数据的详细信息
  264. const queryRowData = async (record: any) => {
  265. const menuId = record.menuId;
  266. operatRowData["menuId"] = menuId;
  267. setOperateRowData(operatRowData);
  268. if (menuId !== undefined) {
  269. const body = await fetchApi(`${queryDetailAPI}/${menuId}`, push);
  270. if (body !== undefined) {
  271. if (body.code == 200) {
  272. modifyFormRef?.current?.setFieldsValue({
  273. //需要加载到修改表单中的数据
  274. parentId: body.data.parentId,
  275. menuName: body.data.menuName,
  276. orderNum: body.data.orderNum,
  277. path: body.data.path,
  278. isFrame: body.data.isFrame,
  279. menuType: body.data.menuType,
  280. perms: body.data.perms,
  281. icon: body.data.icon,
  282. visible: body.data.visible,
  283. status: body.data.status,
  284. });
  285. setIsCatalog(body.data.menuType === "M");
  286. setIsMenu(body.data.menuType === "C");
  287. setIsButton(body.data.menuType === "F");
  288. }
  289. }
  290. }
  291. };
  292. //确认修改数据
  293. const executeModifyData = async (values: any) => {
  294. values["menuId"] = operatRowData["menuId"];
  295. const body = await fetchApi(modifyAPI, push, {
  296. method: "PUT",
  297. headers: {
  298. "Content-Type": "application/json",
  299. },
  300. body: JSON.stringify(values),
  301. });
  302. if (body !== undefined) {
  303. if (body.code == 200) {
  304. message.success(body.msg);
  305. //刷新列表
  306. if (actionTableRef.current) {
  307. actionTableRef.current.reload();
  308. }
  309. setIsShowModifyDataModal(false);
  310. return true;
  311. }
  312. message.error(body.msg);
  313. return false;
  314. }
  315. };
  316. //3.展开/折叠
  317. //点击展开/折叠按钮
  318. const onClickExpandRow = () => {
  319. if (expandKeys.length > 0) {
  320. setExpandKeys([]);
  321. } else {
  322. setExpandKeys(defaultExpandKeys);
  323. }
  324. };
  325. //处理行的展开/折叠逻辑
  326. const handleExpand = (expanded: boolean, record: any) => {
  327. console.log("has keys:", expandKeys);
  328. let keys = [...expandKeys];
  329. if (expanded) {
  330. keys.push(record.menuId);
  331. } else {
  332. keys = keys.filter((key: number) => key !== record.menuId);
  333. }
  334. console.log("now keys:", keys);
  335. setExpandKeys(keys);
  336. };
  337. //4.导出
  338. //5.选择行
  339. //搜索栏显示状态
  340. const [showSearch, setShowSearch] = useState(true);
  341. //action对象引用
  342. const actionTableRef = useRef<ActionType>();
  343. //搜索表单对象引用
  344. const searchTableFormRef = useRef<ProFormInstance>();
  345. const getMenuList = async () => {
  346. const body = await fetchApi(queryAPI, push);
  347. if (body !== undefined) {
  348. const firstLevel = getFirstLevel(body.data);
  349. firstLevel.forEach((first) => {
  350. getChildren(body.data, first);
  351. });
  352. const root: any = {
  353. menuId: 0,
  354. menuName: "根目录",
  355. children: [],
  356. };
  357. firstLevel.forEach((first: any) => {
  358. root.children.push(first as never);
  359. });
  360. return [root];
  361. }
  362. return [];
  363. };
  364. //点击删除按钮
  365. const onClickDeleteRow = (record: any) => {
  366. Modal.confirm({
  367. title: "系统提示",
  368. icon: <ExclamationCircleFilled />,
  369. content: `确定删除菜单名称为“${record.menuName}”的数据项?`,
  370. onOk() {
  371. executeDeleteRow(record.menuId);
  372. },
  373. onCancel() {},
  374. });
  375. };
  376. //确定删除选中的菜单
  377. const executeDeleteRow = async (menuId: any) => {
  378. const body = await fetchApi(`${deleteAPI}/${menuId}`, push, {
  379. method: "DELETE",
  380. });
  381. if (body !== undefined) {
  382. if (body.code == 200) {
  383. message.success("删除成功");
  384. //刷新列表
  385. if (actionTableRef.current) {
  386. actionTableRef.current.reload();
  387. }
  388. } else {
  389. message.error(body.msg);
  390. }
  391. }
  392. };
  393. const [isCatalog, setIsCatalog] = useState(true);
  394. const [isMenu, setIsMenu] = useState(false);
  395. const [isButton, setIsButton] = useState(false);
  396. const onChangeType = (e: any) => {
  397. const type = e.target.value;
  398. setIsCatalog(type === "M");
  399. setIsMenu(type === "C");
  400. setIsButton(type === "F");
  401. };
  402. const IconData = () => {
  403. const iconData = { ...IconMap };
  404. Object.keys(iconData).forEach((key) => {
  405. iconData[key] = (
  406. <>
  407. <span style={{ marginRight: 8 }}>{iconData[key]}</span>
  408. {key}
  409. </>
  410. );
  411. });
  412. return iconData;
  413. };
  414. return (
  415. <PageContainer title={false}>
  416. <ProTable
  417. formRef={searchTableFormRef}
  418. rowKey="menuId"
  419. columns={columns}
  420. expandable={{
  421. expandedRowKeys: expandKeys,
  422. onExpand: handleExpand,
  423. }}
  424. request={async (params: any, sorter: any, filter: any) => {
  425. // 表单搜索项会从 params 传入,传递给后端接口。
  426. const data = await queryTableData(params, sorter, filter);
  427. if (data !== undefined) {
  428. return Promise.resolve({
  429. data: data,
  430. success: true,
  431. total: data.length,
  432. });
  433. }
  434. return Promise.resolve({
  435. data: [],
  436. success: true,
  437. });
  438. }}
  439. pagination={false}
  440. search={
  441. showSearch
  442. ? {
  443. defaultCollapsed: false,
  444. searchText: "搜索",
  445. }
  446. : false
  447. }
  448. dateFormatter="string"
  449. actionRef={actionTableRef}
  450. toolbar={{
  451. actions: [
  452. <ModalForm
  453. key="addmodal"
  454. title="添加菜单"
  455. open={showAddModal}
  456. trigger={
  457. <Button icon={<PlusOutlined />} type="primary">
  458. 新建
  459. </Button>
  460. }
  461. autoFocusFirstInput
  462. modalProps={{
  463. destroyOnHidden: true,
  464. onCancel: () => {
  465. cancelAddModal();
  466. },
  467. }}
  468. submitTimeout={2000}
  469. onFinish={executeAddData}
  470. >
  471. <ProForm.Group>
  472. <ProFormTreeSelect
  473. width="md"
  474. name="parentId"
  475. initialValue={rowParentId}
  476. label="上级菜单"
  477. placeholder="请选择上级菜单"
  478. rules={[{ required: true, message: "请选择上级菜单" }]}
  479. request={getMenuList}
  480. fieldProps={{
  481. filterTreeNode: true,
  482. showSearch: true,
  483. treeNodeFilterProp: "label",
  484. fieldNames: {
  485. label: "menuName",
  486. value: "menuId",
  487. },
  488. }}
  489. />
  490. </ProForm.Group>
  491. <ProForm.Group>
  492. <ProFormRadio.Group
  493. name="menuType"
  494. width="md"
  495. label="类型"
  496. initialValue="M"
  497. fieldProps={{
  498. onChange: (e: any) => onChangeType(e),
  499. }}
  500. options={[
  501. {
  502. label: "目录",
  503. value: "M",
  504. },
  505. {
  506. label: "菜单",
  507. value: "C",
  508. },
  509. {
  510. label: "按钮",
  511. value: "F",
  512. },
  513. ]}
  514. />
  515. </ProForm.Group>
  516. {(isCatalog || isMenu) && (
  517. <ProForm.Group>
  518. <ProFormSelect
  519. width="md"
  520. name="icon"
  521. label="菜单图标"
  522. fieldProps={{
  523. showSearch,
  524. }}
  525. valueEnum={IconData}
  526. placeholder="请选择菜单图标"
  527. rules={[{ required: true, message: "请选择菜单图标" }]}
  528. />
  529. </ProForm.Group>
  530. )}
  531. <ProForm.Group>
  532. <ProFormText
  533. width="md"
  534. name="menuName"
  535. label="菜单名称"
  536. placeholder="请输入菜单名称"
  537. rules={[{ required: true, message: "请输入菜单名称" }]}
  538. />
  539. <ProFormDigit
  540. fieldProps={{ precision: 0 }}
  541. width="md"
  542. name="orderNum"
  543. initialValue="1"
  544. label="排序"
  545. placeholder="请输入排序"
  546. rules={[{ required: true, message: "请输入排序" }]}
  547. />
  548. </ProForm.Group>
  549. {(isCatalog || isMenu) && (
  550. <ProForm.Group>
  551. <ProFormText
  552. width="md"
  553. name="path"
  554. label="路由地址"
  555. placeholder="请输入路由地址"
  556. rules={[{ required: true, message: "请输入路由地址" }]}
  557. />
  558. <ProFormRadio.Group
  559. name="isFrame"
  560. width="md"
  561. label="是否外链"
  562. initialValue="1"
  563. options={[
  564. {
  565. label: "是",
  566. value: "0",
  567. },
  568. {
  569. label: "否",
  570. value: "1",
  571. },
  572. ]}
  573. />
  574. </ProForm.Group>
  575. )}
  576. {isMenu && (
  577. <ProForm.Group>
  578. <ProFormText
  579. width="md"
  580. name="perms"
  581. label="权限字符"
  582. placeholder="请输入权限字符"
  583. />
  584. </ProForm.Group>
  585. )}
  586. <ProForm.Group>
  587. <ProFormRadio.Group
  588. name="visible"
  589. width="md"
  590. label="显示状态"
  591. initialValue="0"
  592. options={[
  593. {
  594. label: "显示",
  595. value: "0",
  596. },
  597. {
  598. label: "隐藏",
  599. value: "1",
  600. },
  601. ]}
  602. />
  603. <ProFormRadio.Group
  604. name="status"
  605. width="md"
  606. label="菜单状态"
  607. initialValue="0"
  608. options={[
  609. {
  610. label: "正常",
  611. value: "0",
  612. },
  613. {
  614. label: "停用",
  615. value: "1",
  616. },
  617. ]}
  618. />
  619. </ProForm.Group>
  620. </ModalForm>,
  621. <Button
  622. key="expand"
  623. icon={<FontAwesomeIcon icon={faArrowsUpDown} />}
  624. onClick={() => onClickExpandRow()}
  625. >
  626. 折叠/展开
  627. </Button>,
  628. ],
  629. settings: [
  630. {
  631. key: "switch",
  632. icon: showSearch ? (
  633. <FontAwesomeIcon icon={faToggleOn} />
  634. ) : (
  635. <FontAwesomeIcon icon={faToggleOff} />
  636. ),
  637. tooltip: showSearch ? "隐藏搜索栏" : "显示搜索栏",
  638. onClick: (key: string | undefined) => {
  639. setShowSearch(!showSearch);
  640. },
  641. },
  642. {
  643. key: "refresh",
  644. tooltip: "刷新",
  645. icon: <ReloadOutlined />,
  646. onClick: (key: string | undefined) => {
  647. if (actionTableRef.current) {
  648. actionTableRef.current.reload();
  649. }
  650. },
  651. },
  652. ],
  653. }}
  654. />
  655. <ModalForm
  656. key="modifymodal"
  657. title="修改菜单"
  658. formRef={modifyFormRef}
  659. open={isShowModifyDataModal}
  660. autoFocusFirstInput
  661. modalProps={{
  662. destroyOnHidden: true,
  663. onCancel: () => {
  664. setIsShowModifyDataModal(false);
  665. },
  666. }}
  667. submitTimeout={2000}
  668. onFinish={executeModifyData}
  669. >
  670. <ProForm.Group>
  671. <ProFormTreeSelect
  672. width="md"
  673. name="parentId"
  674. initialValue={rowParentId}
  675. label="上级菜单"
  676. placeholder="请选择上级菜单"
  677. rules={[{ required: true, message: "请选择上级菜单" }]}
  678. request={getMenuList}
  679. fieldProps={{
  680. filterTreeNode: true,
  681. showSearch: true,
  682. treeNodeFilterProp: "label",
  683. fieldNames: {
  684. label: "menuName",
  685. value: "menuId",
  686. },
  687. }}
  688. />
  689. </ProForm.Group>
  690. <ProForm.Group>
  691. <ProFormRadio.Group
  692. name="menuType"
  693. width="md"
  694. label="类型"
  695. fieldProps={{
  696. onChange: (e: any) => onChangeType(e),
  697. }}
  698. options={[
  699. {
  700. label: "目录",
  701. value: "M",
  702. },
  703. {
  704. label: "菜单",
  705. value: "C",
  706. },
  707. {
  708. label: "按钮",
  709. value: "F",
  710. },
  711. ]}
  712. />
  713. </ProForm.Group>
  714. {(isCatalog || isMenu) && (
  715. <ProForm.Group>
  716. <ProFormSelect
  717. width="md"
  718. name="icon"
  719. label="菜单图标"
  720. fieldProps={{
  721. showSearch,
  722. }}
  723. valueEnum={IconData}
  724. placeholder="请选择菜单图标"
  725. rules={[{ required: true, message: "请选择菜单图标" }]}
  726. />
  727. </ProForm.Group>
  728. )}
  729. <ProForm.Group>
  730. <ProFormText
  731. width="md"
  732. name="menuName"
  733. label="菜单名称"
  734. placeholder="请输入菜单名称"
  735. rules={[{ required: true, message: "请输入菜单名称" }]}
  736. />
  737. <ProFormDigit
  738. fieldProps={{ precision: 0 }}
  739. width="md"
  740. name="orderNum"
  741. initialValue="1"
  742. label="排序"
  743. placeholder="请输入排序"
  744. rules={[{ required: true, message: "请输入排序" }]}
  745. />
  746. </ProForm.Group>
  747. {(isCatalog || isMenu) && (
  748. <ProForm.Group>
  749. <ProFormText
  750. width="md"
  751. name="path"
  752. label="路由地址"
  753. placeholder="请输入路由地址"
  754. rules={[{ required: true, message: "请输入路由地址" }]}
  755. />
  756. <ProFormRadio.Group
  757. name="isFrame"
  758. width="md"
  759. label="是否外链"
  760. initialValue="1"
  761. options={[
  762. {
  763. label: "是",
  764. value: "0",
  765. },
  766. {
  767. label: "否",
  768. value: "1",
  769. },
  770. ]}
  771. />
  772. </ProForm.Group>
  773. )}
  774. {isMenu && (
  775. <ProForm.Group>
  776. <ProFormText
  777. width="md"
  778. name="perms"
  779. label="权限字符"
  780. placeholder="请输入权限字符"
  781. />
  782. </ProForm.Group>
  783. )}
  784. <ProForm.Group>
  785. <ProFormRadio.Group
  786. name="visible"
  787. width="md"
  788. label="显示状态"
  789. initialValue="0"
  790. options={[
  791. {
  792. label: "显示",
  793. value: "0",
  794. },
  795. {
  796. label: "隐藏",
  797. value: "1",
  798. },
  799. ]}
  800. />
  801. <ProFormRadio.Group
  802. name="status"
  803. width="md"
  804. label="菜单状态"
  805. initialValue="0"
  806. options={[
  807. {
  808. label: "正常",
  809. value: "0",
  810. },
  811. {
  812. label: "停用",
  813. value: "1",
  814. },
  815. ]}
  816. />
  817. </ProForm.Group>
  818. </ModalForm>
  819. ,
  820. </PageContainer>
  821. );
  822. }