Skip to content

Commit 332d752

Browse files
committed
add menu
1 parent 7a2a61c commit 332d752

File tree

11 files changed

+393
-14
lines changed

11 files changed

+393
-14
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
import { list, save, del } from '@/services/api/menu';
2+
import { PlusOutlined } from '@ant-design/icons';
3+
import type { ActionType, ProColumns } from '@ant-design/pro-components';
4+
import { ModalForm, PageContainer, ProCard, ProFormDigit, ProFormText } from '@ant-design/pro-components';
5+
import { Button, Form, message, Popconfirm } from 'antd';
6+
import { MyTable } from 'coding-components';
7+
import React, { useRef, useState, useEffect } from 'react';
8+
import MenuTree from './tree';
9+
10+
const MenuPage: React.FC = () => {
11+
12+
const actionRef = useRef<ActionType>();
13+
const [form] = Form.useForm();
14+
const [parentId, setParentId] = useState<number>(1);
15+
const [createModalOpen, handleModalOpen] = useState<boolean>(false);
16+
17+
const handleAdd = async (fields: any) => {
18+
const hide = message.loading('正在添加');
19+
try {
20+
const parentId = fields.parentId;
21+
delete fields.parentId;
22+
const request = {
23+
...fields,
24+
parent: {
25+
id: parentId
26+
}
27+
}
28+
console.log(request);
29+
await save(request);
30+
hide();
31+
message.success('保存成功');
32+
return true;
33+
} catch (error) {
34+
hide();
35+
message.error('保存失败,请重试!');
36+
return false;
37+
}
38+
};
39+
40+
41+
const handleDel = async (id: string) => {
42+
const hide = message.loading('正在删除');
43+
try {
44+
await del({ id: id });
45+
hide();
46+
message.success('删除成功');
47+
if (actionRef.current) {
48+
actionRef.current.reload();
49+
}
50+
return true;
51+
} catch (error) {
52+
hide();
53+
message.error('删除失败,请重试!');
54+
return false;
55+
}
56+
};
57+
58+
const columns: ProColumns<any>[] = [
59+
{
60+
title: "编号",
61+
dataIndex: 'id',
62+
search: false,
63+
},
64+
{
65+
title: "名称",
66+
dataIndex: 'name',
67+
},
68+
{
69+
title: "图标",
70+
dataIndex: 'icon',
71+
search: false,
72+
},
73+
{
74+
title: "编码",
75+
dataIndex: 'code',
76+
search: false,
77+
},
78+
{
79+
title: "排序",
80+
dataIndex: 'sort',
81+
search: false,
82+
},
83+
{
84+
title: "操作",
85+
dataIndex: 'option',
86+
valueType: 'option',
87+
render: (_, record) => [
88+
<a
89+
key="config"
90+
onClick={() => {
91+
// eslint-disable-next-line guard-for-in
92+
for (let key in record) {
93+
form.setFieldValue(key, record[key])
94+
}
95+
handleModalOpen(true);
96+
}}
97+
>
98+
修改
99+
</a>,
100+
<Popconfirm
101+
key="delete"
102+
title="删除提示"
103+
description="确认要删除这条数据吗?"
104+
onConfirm={async () => {
105+
await handleDel(record.id);
106+
}}
107+
okText="确认"
108+
cancelText="取消"
109+
>
110+
<a key="delete">
111+
删除
112+
</a>
113+
</Popconfirm>
114+
],
115+
},
116+
];
117+
118+
useEffect(() => {
119+
if (actionRef.current) {
120+
actionRef.current.reload();
121+
}
122+
}, [parentId]);
123+
124+
return (
125+
<PageContainer>
126+
<ProCard gutter={8}>
127+
<ProCard colSpan="20%">
128+
<MenuTree
129+
onSelect={(selectedKeys) => {
130+
setParentId(Number(selectedKeys[0]));
131+
}}
132+
/>
133+
</ProCard>
134+
<ProCard>
135+
<MyTable
136+
headerTitle="菜单列表"
137+
actionRef={actionRef}
138+
rowKey="id"
139+
toolBarRender={() => [
140+
<Button
141+
type="primary"
142+
key="primary"
143+
onClick={() => {
144+
handleModalOpen(true);
145+
}}
146+
>
147+
<PlusOutlined /> 新建
148+
</Button>,
149+
]}
150+
request={async (params, sort, filter) => {
151+
const res = await list({
152+
...params,
153+
"parent.id": parentId
154+
});
155+
return {
156+
data: res.data.list,
157+
success: res.success,
158+
total: res.data.total
159+
};
160+
}
161+
}
162+
columns={columns}
163+
/>
164+
</ProCard>
165+
</ProCard>
166+
167+
168+
<ModalForm
169+
title="新建菜单"
170+
form={form}
171+
modalProps={{
172+
destroyOnClose: true,
173+
onCancel: () => {
174+
form.resetFields();
175+
},
176+
}}
177+
initialValues={{
178+
"parentId": parentId,
179+
}}
180+
open={createModalOpen}
181+
onOpenChange={handleModalOpen}
182+
onFinish={async (value) => {
183+
const success = await handleAdd(value);
184+
if (success) {
185+
handleModalOpen(false);
186+
if (actionRef.current) {
187+
actionRef.current.reload();
188+
}
189+
}
190+
}}
191+
>
192+
<ProFormText
193+
hidden={true}
194+
name="id"
195+
/>
196+
197+
<ProFormText
198+
hidden={true}
199+
name="parentId"
200+
/>
201+
202+
<ProFormText
203+
placeholder="请输入菜单名称"
204+
label="菜单名称"
205+
rules={[
206+
{
207+
required: true,
208+
message: "请输入菜单名称",
209+
},
210+
]}
211+
name="name"
212+
/>
213+
<ProFormText
214+
placeholder="请输入菜单编码"
215+
label="菜单编码"
216+
rules={[
217+
{
218+
required: true,
219+
message: "请输入菜单编码",
220+
},
221+
]}
222+
name="code"
223+
/>
224+
<ProFormText
225+
placeholder="请输入菜单图标"
226+
label="菜单图标"
227+
rules={[
228+
{
229+
required: true,
230+
message: "请输入菜单图标",
231+
},
232+
]}
233+
name="icon"
234+
/>
235+
<ProFormDigit
236+
min={0}
237+
fieldProps={
238+
{
239+
precision: 0
240+
}
241+
}
242+
placeholder="请输入菜单排序"
243+
label="菜单排序"
244+
rules={[
245+
{
246+
required: true,
247+
message: "请输入菜单排序",
248+
},
249+
]}
250+
name="sort"
251+
/>
252+
</ModalForm>
253+
254+
</PageContainer>
255+
);
256+
};
257+
258+
export default MenuPage;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import { Tree } from 'antd';
2+
import React, { useEffect, useState } from 'react';
3+
import { DownOutlined, HomeOutlined, TeamOutlined } from '@ant-design/icons';
4+
import { DataNode } from 'antd/es/tree';
5+
import { tree } from '@/services/api/menu';
6+
7+
interface MenuPageProps{
8+
onSelect?: (selectedKeys: React.Key[], info?: any) => void;
9+
}
10+
11+
const MenuTree: React.FC<MenuPageProps> = (props) => {
12+
13+
const [treeData, setTreeData] = useState<DataNode[]>([]);
14+
const [defaultKeys, setSelectedKeys] = useState<React.Key[]>([1]);
15+
16+
const refreshTree = () => {
17+
tree().then(res => {
18+
if (res['success']) {
19+
const data = res.data;
20+
const search = (data: any) => {
21+
data.title = data.name;
22+
data.key = data.id;
23+
data.icon = data.type === 'COMPANY' ? <HomeOutlined /> : <TeamOutlined />;
24+
data.children = data.children || [];
25+
data.children.forEach((item: any) => {
26+
search(item);
27+
});
28+
}
29+
search(data);
30+
setTreeData([data]);
31+
}
32+
});
33+
};
34+
35+
36+
useEffect(() => {
37+
refreshTree();
38+
}, []);
39+
40+
41+
const onSelect = (selectedKeys: React.Key[]) => {
42+
setSelectedKeys(selectedKeys);
43+
if (props.onSelect) {
44+
props.onSelect(selectedKeys);
45+
}
46+
};
47+
48+
return (
49+
<>
50+
{treeData && treeData.length > 0 && (
51+
<Tree
52+
showIcon
53+
blockNode
54+
defaultExpandAll
55+
autoExpandParent
56+
defaultExpandParent
57+
defaultSelectedKeys={defaultKeys}
58+
selectedKeys={defaultKeys}
59+
onSelect={onSelect}
60+
switcherIcon={<DownOutlined />}
61+
treeData={treeData}
62+
/>
63+
)}
64+
</>
65+
)
66+
67+
}
68+
69+
70+
export default MenuTree

antd-pro/src/services/api/menu.ts

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// @ts-ignore
2+
/* eslint-disable */
3+
import {get, post} from "@/services/api/index";
4+
5+
export async function list(
6+
params: {
7+
[key in string]: any;
8+
},
9+
) {
10+
return get('/api/menu/list', params);
11+
}
12+
13+
14+
export async function tree() {
15+
return get('/api/menu/tree');
16+
}
17+
18+
19+
export async function save(body: any) {
20+
return post('/api/menu/save', body);
21+
}
22+
23+
24+
export async function del(body: {
25+
id:string,
26+
}) {
27+
return post('/api/menu/delete', body);
28+
}

components-server/components/api/pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
<maven.compile.source>17</maven.compile.source>
3030
<maven.compile.target>17</maven.compile.target>
3131

32-
<codingapi.framework.version>3.1.7</codingapi.framework.version>
32+
<codingapi.framework.version>3.1.8.dev</codingapi.framework.version>
3333
</properties>
3434

3535
<dependencies>

0 commit comments

Comments
 (0)