edit.tsx 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. import Icon from '@ant-design/icons';
  2. import {
  3. Col,
  4. Form,
  5. Input,
  6. InputNumber,
  7. message,
  8. Modal,
  9. Radio,
  10. Row,
  11. Select,
  12. TreeSelect,
  13. } from 'antd';
  14. import React, { useEffect, useState } from 'react';
  15. import IconSelector from '@/components/IconSelecter';
  16. import { createMenu, editMenu, queryMenu } from '@/services/menu';
  17. interface editPros {
  18. visible: boolean;
  19. editCallback: () => void;
  20. params: any;
  21. }
  22. /**
  23. * 菜单管理 - 编辑
  24. * @param props
  25. * @constructor
  26. */
  27. const Edit: React.FC<editPros> = (props) => {
  28. const { params, visible, editCallback } = props;
  29. const [iconSelectorVisible, setIconSelectorVisible] = useState(false);
  30. const [form] = Form.useForm();
  31. const { getFieldValue, setFieldsValue } = form;
  32. const iconType = getFieldValue('icon') || (params ? params.icon : '');
  33. // 菜单树列表数据
  34. const [treeData, setTreeData] = useState([]);
  35. useEffect(() => {
  36. // 获取树结构的菜单列表数据
  37. queryMenu({ q: 'tree', query_all: 1 }).then((res) => {
  38. if (res && res.code === 0) {
  39. setTreeData(res.data.list);
  40. }
  41. });
  42. }, []);
  43. // 确认弹框
  44. const onOk = () => {
  45. form.validateFields().then((values) => {
  46. if (values) {
  47. const data = { ...values };
  48. if (params) {
  49. data.record_id = params.record_id;
  50. editMenu(data)
  51. .then((res) => {
  52. if (res.code === 0) {
  53. message.success('编辑成功');
  54. editCallback();
  55. } else {
  56. message.error(res?.message);
  57. editCallback();
  58. }
  59. })
  60. .catch((e) => {
  61. message.error(e?.message);
  62. editCallback();
  63. });
  64. } else {
  65. createMenu(data)
  66. .then((res) => {
  67. if (res.code === 0) {
  68. message.success('新增成功');
  69. editCallback();
  70. } else {
  71. message.error(res?.message);
  72. editCallback();
  73. }
  74. })
  75. .catch((e) => {
  76. message.error(e?.message);
  77. editCallback();
  78. });
  79. }
  80. }
  81. });
  82. };
  83. // 取消
  84. const onCancel = () => {
  85. editCallback();
  86. };
  87. // 打开图标选择框
  88. const openIconSelector = () => {
  89. setIconSelectorVisible(true);
  90. };
  91. // 上级菜单 树选择
  92. const toTreeSelect = (data: any) => {
  93. if (!data) {
  94. return [];
  95. }
  96. const newData = [];
  97. for (let i = 0; i < data.length; i += 1) {
  98. const item = {
  99. ...data[i],
  100. title: data[i].name,
  101. value: data[i].record_id,
  102. };
  103. if (item.children && item.children.length > 0) {
  104. item.children = toTreeSelect(item.children);
  105. }
  106. newData.push(item);
  107. }
  108. return newData;
  109. };
  110. // 选中图标后
  111. const onIconSelected = (item: any) => {
  112. if (item && typeof item === 'string') {
  113. setFieldsValue({ icon: item });
  114. }
  115. setIconSelectorVisible(false);
  116. };
  117. const formItemLayout = {
  118. labelCol: {
  119. span: 6,
  120. },
  121. wrapperCol: {
  122. span: 18,
  123. },
  124. };
  125. const formItemLayout24 = {
  126. labelCol: { span: 3 },
  127. wrapperCol: { span: 21 },
  128. };
  129. return (
  130. <Modal
  131. title={`${params ? '编辑' : '新增'}`}
  132. open={visible}
  133. onOk={onOk}
  134. onCancel={onCancel}
  135. width={800}
  136. >
  137. <Form form={form}>
  138. <Row>
  139. <Col span={12}>
  140. <Form.Item
  141. {...formItemLayout}
  142. name="name"
  143. label="菜单名称"
  144. rules={[{ required: true, message: '请输入菜单名称' }]}
  145. initialValue={params?.name}
  146. >
  147. <Input placeholder="请输入菜单名称" />
  148. </Form.Item>
  149. </Col>
  150. <Col span={12}>
  151. <Form.Item
  152. {...formItemLayout}
  153. name="parent_id"
  154. label="上级菜单"
  155. rules={[{ required: false, message: '请选择上级菜单' }]}
  156. initialValue={params?.parent_id}
  157. >
  158. <TreeSelect
  159. allowClear
  160. showSearch
  161. treeNodeFilterProp="title"
  162. style={{ width: '100%' }}
  163. dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
  164. treeData={toTreeSelect(treeData)}
  165. placeholder="请选择"
  166. />
  167. </Form.Item>
  168. </Col>
  169. <Col span={12}>
  170. <Form.Item
  171. {...formItemLayout}
  172. name="tag"
  173. label="菜单标签"
  174. rules={[{ required: true, message: '请选择菜单标签' }]}
  175. initialValue={params?.tag}
  176. >
  177. <Select placeholder="请选择菜单标签">
  178. <Select.Option key="api" value="api">
  179. api
  180. </Select.Option>
  181. <Select.Option key="web" value="web">
  182. web
  183. </Select.Option>
  184. </Select>
  185. </Form.Item>
  186. </Col>
  187. <Col span={12}>
  188. <Form.Item
  189. {...formItemLayout}
  190. name="sequence"
  191. label="排序值"
  192. rules={[{ required: true, message: '请输入排序值' }]}
  193. initialValue={params?.sequence}
  194. >
  195. <InputNumber placeholder="请输入排序值" style={{ width: '280px' }} />
  196. </Form.Item>
  197. </Col>
  198. <Col span={12}>
  199. <Form.Item
  200. {...formItemLayout}
  201. name="icon"
  202. label="图标"
  203. rules={[{ required: true, message: '请选择图标' }]}
  204. initialValue={params?.icon}
  205. >
  206. <Input
  207. placeholder="请输入"
  208. readOnly
  209. onClick={openIconSelector}
  210. suffix={iconType ? <Icon type={iconType} /> : null}
  211. />
  212. </Form.Item>
  213. </Col>
  214. <Col span={12}>
  215. <Form.Item
  216. {...formItemLayout}
  217. name="hidden"
  218. label="状态"
  219. rules={[{ required: true, message: '请选择状态' }]}
  220. initialValue={params?.hidden}
  221. >
  222. <Radio.Group>
  223. <Radio value={0}>显示</Radio>
  224. <Radio value={1}>隐藏</Radio>
  225. </Radio.Group>
  226. </Form.Item>
  227. </Col>
  228. <Col span={24}>
  229. <Form.Item
  230. {...formItemLayout24}
  231. name="router"
  232. label="访问路由"
  233. rules={[{ required: true, message: '请输入访问路由' }]}
  234. initialValue={params?.router}
  235. >
  236. <Input placeholder="请输入访问路由" />
  237. </Form.Item>
  238. </Col>
  239. </Row>
  240. </Form>
  241. {iconSelectorVisible && (
  242. <IconSelector visible={iconSelectorVisible} onSelected={onIconSelected} />
  243. )}
  244. </Modal>
  245. );
  246. };
  247. export default Edit;