Skip to content

Commit de69353

Browse files
author
bestGao
committed
feat(m): 列表
1 parent 02d7c0c commit de69353

File tree

9 files changed

+269
-20
lines changed

9 files changed

+269
-20
lines changed

src/constants/commonTypes.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
const articleTypes = [
2+
{
3+
label: "大前端",
4+
value: "FE",
5+
},
6+
{
7+
label: "后端",
8+
value: "BE",
9+
},
10+
{
11+
label: "人工智能",
12+
value: "AI",
13+
},
14+
{
15+
label: "系统架构设计",
16+
value: "Architecture",
17+
},
18+
];
19+
20+
export { articleTypes };

src/constants/menus.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const menuItems: MenuItem[] = [
2626
{
2727
key: "Architecture",
2828
icon: <KubernetesOutlined />,
29-
label: <Link to="/system_architecture">系统架构</Link>,
29+
label: <Link to="/system_architecture">系统架构设计</Link>,
3030
},
3131
];
3232

src/pages/ai/index.module.less

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
.aiContainer {
2-
height: 100%;
3-
display: flex;
4-
5-
flex-direction: column;
6-
justify-content: space-between;
72
.title {
83
height: 64px;
94
}
105
}
116
.bigMe {
12-
flex: 1;
7+
position: absolute;
8+
bottom: 0;
9+
right: 16px;
10+
width: 200px;
11+
height: 100px;
1312
background-repeat: no-repeat;
1413
background-image: url("../../assets/me.png");
1514
background-size: 100%;

src/pages/ai/index.tsx

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,37 @@
1+
import { useEffect } from "react";
2+
import { List } from "antd";
3+
import { post } from "@/utils/request";
14
import style from "./index.module.less";
5+
import useCustomReducer from "@/hooks/useCusReducer";
6+
import { Link } from "react-router-dom";
27
export default function AI() {
8+
const [state, dispatch] = useCustomReducer({
9+
article: [],
10+
});
11+
12+
useEffect(() => {
13+
async function getList() {
14+
const res: any = await post("/user/posts", { articleType: "AI" });
15+
if (res) {
16+
dispatch("article", res.articles);
17+
}
18+
}
19+
getList();
20+
}, []);
321
return (
422
<div className={style.aiContainer}>
5-
<div className={style.title}>人工智能</div>
23+
<List
24+
size="large"
25+
bordered
26+
dataSource={state.article}
27+
renderItem={(item: any) => (
28+
<List.Item>
29+
<Link target="_blank" to={item.link}>
30+
{item.title}
31+
</Link>
32+
</List.Item>
33+
)}
34+
/>
635
<div className={style.bigMe} />
736
</div>
837
);

src/pages/arch/index.tsx

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,37 @@
1-
export default function BE() {
2-
return <div>后端</div>;
1+
import { useEffect } from "react";
2+
import { List } from "antd";
3+
import style from "./index.module.less";
4+
import { post } from "@/utils/request";
5+
import useCustomReducer from "@/hooks/useCusReducer";
6+
import { Link } from "react-router-dom";
7+
export default function BFE() {
8+
const [state, dispatch] = useCustomReducer({
9+
article: [],
10+
});
11+
12+
useEffect(() => {
13+
async function getList() {
14+
const res: any = await post("/user/posts", { articleType: "Architecture" });
15+
if (res) {
16+
dispatch("article", res.articles);
17+
}
18+
}
19+
getList();
20+
}, []);
21+
return (
22+
<div>
23+
<List
24+
size="large"
25+
bordered
26+
dataSource={state.article}
27+
renderItem={(item: any) => (
28+
<List.Item>
29+
<Link target="_blank" to={item.link}>
30+
{item.title}
31+
</Link>
32+
</List.Item>
33+
)}
34+
/>
35+
</div>
36+
);
337
}

src/pages/be/index.tsx

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,37 @@
1-
export default function BE() {
2-
return <div>后端</div>;
1+
import { useEffect } from "react";
2+
import { List } from "antd";
3+
import style from "./index.module.less";
4+
import { post } from "@/utils/request";
5+
import useCustomReducer from "@/hooks/useCusReducer";
6+
import { Link } from "react-router-dom";
7+
export default function BFE() {
8+
const [state, dispatch] = useCustomReducer({
9+
article: [],
10+
});
11+
12+
useEffect(() => {
13+
async function getList() {
14+
const res: any = await post("/user/posts", { articleType: "BE" });
15+
if (res) {
16+
dispatch("article", res.articles);
17+
}
18+
}
19+
getList();
20+
}, []);
21+
return (
22+
<div>
23+
<List
24+
size="large"
25+
bordered
26+
dataSource={state.article}
27+
renderItem={(item: any) => (
28+
<List.Item>
29+
<Link target="_blank" to={item.link}>
30+
{item.title}
31+
</Link>
32+
</List.Item>
33+
)}
34+
/>
35+
</div>
36+
);
337
}

src/pages/bfe/index.tsx

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,37 @@
1+
import { useEffect } from "react";
2+
import { List } from "antd";
3+
import style from "./index.module.less";
4+
import { post } from "@/utils/request";
5+
import useCustomReducer from "@/hooks/useCusReducer";
6+
import { Link } from "react-router-dom";
17
export default function BFE() {
2-
return <div>大前端</div>;
8+
const [state, dispatch] = useCustomReducer({
9+
article: [],
10+
});
11+
12+
useEffect(() => {
13+
async function getList() {
14+
const res: any = await post("/user/posts", { articleType: "FE" });
15+
if (res) {
16+
dispatch("article", res.articles);
17+
}
18+
}
19+
getList();
20+
}, []);
21+
return (
22+
<div>
23+
<List
24+
size="large"
25+
bordered
26+
dataSource={state.article}
27+
renderItem={(item: any) => (
28+
<List.Item>
29+
<Link target="_blank" to={item.link}>
30+
{item.title}
31+
</Link>
32+
</List.Item>
33+
)}
34+
/>
35+
</div>
36+
);
337
}

src/pages/user/write/index.tsx

Lines changed: 99 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,30 @@ import { useEffect, useState } from "react";
22
import Vditor from "vditor";
33
import style from "./index.module.less";
44
import "vditor/dist/index.css";
5-
import { Button } from "antd";
5+
import { post } from "@/utils/request";
6+
import {
7+
Button,
8+
Modal,
9+
Form,
10+
Input,
11+
Select,
12+
List,
13+
Typography,
14+
message,
15+
} from "antd";
16+
import axios from "axios";
17+
import { articleTypes } from "@/constants/commonTypes";
18+
import { useNavigate } from "react-router-dom";
619

7-
const App = () => {
20+
const { Option } = Select;
21+
const { Title } = Typography;
22+
23+
const Write = () => {
824
const [vd, setVd] = useState<Vditor>();
25+
const [isModalVisible, setIsModalVisible] = useState(false);
26+
const navigate = useNavigate();
27+
const [form] = Form.useForm();
28+
929
useEffect(() => {
1030
const vditor = new Vditor("vditor", {
1131
mode: "sv",
@@ -14,20 +34,95 @@ const App = () => {
1434
setVd(vditor);
1535
},
1636
});
37+
1738
// Clear the effect
1839
return () => {
1940
vd?.destroy();
2041
setVd(undefined);
2142
};
2243
}, []);
44+
45+
const handlePublish = () => {
46+
setIsModalVisible(true);
47+
};
48+
49+
// 定义 ValidationError 类型
50+
51+
const handleOk = async () => {
52+
// 验证表单字段,如果有错误会抛出异常
53+
await form.validateFields();
54+
55+
// 获取所有字段的值
56+
const values = form.getFieldsValue();
57+
// 获取富文本编辑器的内容
58+
const content = vd?.getValue();
59+
60+
if (!content) {
61+
return;
62+
}
63+
64+
// 发送请求
65+
const response: any = await post("/user/write", {
66+
category: values.category,
67+
title: values.title,
68+
content: content,
69+
});
70+
71+
// 根据响应显示成功或错误模态框
72+
if (response?.success) {
73+
message.success("文章已成功发布");
74+
// 成功后可以关闭弹窗并重置表单
75+
setIsModalVisible(false);
76+
form.resetFields();
77+
setTimeout(() => {
78+
navigate("/");
79+
}, 0);
80+
}
81+
};
82+
83+
const handleCancel = () => {
84+
setIsModalVisible(false);
85+
form.resetFields();
86+
};
87+
2388
return (
2489
<div className={style.writeWP}>
2590
<div className={style.operaBtns}>
26-
<Button type="primary">发布</Button>
91+
<Button type="primary" onClick={handlePublish}>
92+
发布
93+
</Button>
2794
</div>
2895
<div id="vditor" className="vditor" />
96+
<Modal
97+
title="发布文章"
98+
open={isModalVisible}
99+
onOk={handleOk}
100+
onCancel={handleCancel}
101+
okText="确定"
102+
cancelText="取消"
103+
>
104+
<Form form={form} layout="vertical">
105+
<Form.Item
106+
name="category"
107+
label="文章分类"
108+
rules={[{ required: true, message: "请选择文章分类" }]}
109+
>
110+
<Select
111+
placeholder="请选择文章分类"
112+
options={articleTypes}
113+
></Select>
114+
</Form.Item>
115+
<Form.Item
116+
name="title"
117+
label="文章标题"
118+
rules={[{ required: true, message: "请输入文章标题" }]}
119+
>
120+
<Input placeholder="请输入文章标题" />
121+
</Form.Item>
122+
</Form>
123+
</Modal>
29124
</div>
30125
);
31126
};
32127

33-
export default App;
128+
export default Write;

src/utils/request.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ service.interceptors.response.use(
4444
break;
4545
case 401:
4646
console.log(`response`, error.response.data);
47-
message.error(error.response.data.message)
47+
message.error(error.response.data.message);
4848
break;
4949
case 403:
5050
console.log("Forbidden");
@@ -53,10 +53,14 @@ service.interceptors.response.use(
5353
console.log("Not Found");
5454
break;
5555
case 500:
56-
console.log("Internal Server Error");
56+
if (error.response.data.message) {
57+
message.error(error.response.data.message);
58+
} else {
59+
console.log(error);
60+
}
5761
break;
5862
default:
59-
message.error(error.response.data.message)
63+
message.error(error.response.data.message);
6064
console.log(`Unexpected error: ${error.response.status}`);
6165
}
6266
} else if (error.request) {

0 commit comments

Comments
 (0)