完成新增网站功能
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import Request from '@/utils/request'
|
import Request from '@/utils/request'
|
||||||
import { Web } from '@/types/web'
|
import { Web, LinkType } from '@/types/web'
|
||||||
|
|
||||||
// 新增网站
|
// 新增网站
|
||||||
export const addLinkDataAPI = (data: Web) => Request<Web>("POST", "/link", data)
|
export const addLinkDataAPI = (data: Web) => Request<Web>("POST", "/link", data)
|
||||||
@@ -22,3 +22,8 @@ export const getLinkListAPI = (pagination?: Page) => {
|
|||||||
return Request<Web[]>("GET", `/link/all`);
|
return Request<Web[]>("GET", `/link/all`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 获取网站类型列表
|
||||||
|
export const getLinkTypeListAPI = () => {
|
||||||
|
return Request<LinkType[]>("GET", `/link/type`);
|
||||||
|
};
|
||||||
|
|||||||
@@ -2,8 +2,7 @@ import React, { useState, useEffect, useRef } from 'react';
|
|||||||
import { Cate } from '@/types/cate';
|
import { Cate } from '@/types/cate';
|
||||||
import { addCateDataAPI, delCateDataAPI, editCateDataAPI, getCateDataAPI, getCateListAPI } from '@/api/Cate';
|
import { addCateDataAPI, delCateDataAPI, editCateDataAPI, getCateDataAPI, getCateListAPI } from '@/api/Cate';
|
||||||
import { DownOutlined } from '@ant-design/icons';
|
import { DownOutlined } from '@ant-design/icons';
|
||||||
import { titleSty } from '@/styles/sty';
|
import { Form, Input, Button, Tree, Modal, Spin, Dropdown, Card, MenuProps, Popconfirm, message } from 'antd';
|
||||||
import { Form, Input, Button, Tree, Modal, notification, Spin, Dropdown, Card, MenuProps, Popconfirm } from 'antd';
|
|
||||||
import "./index.scss"
|
import "./index.scss"
|
||||||
import Title from '@/components/Title';
|
import Title from '@/components/Title';
|
||||||
|
|
||||||
@@ -42,10 +41,10 @@ const CateManager: React.FC = () => {
|
|||||||
.then(async (values: any) => {
|
.then(async (values: any) => {
|
||||||
if (cate.id) {
|
if (cate.id) {
|
||||||
await editCateDataAPI({ ...cate, ...values });
|
await editCateDataAPI({ ...cate, ...values });
|
||||||
notification.success({ message: '🎉 修改分类成功' });
|
message.success('🎉 修改分类成功');
|
||||||
} else {
|
} else {
|
||||||
await addCateDataAPI({ ...cate, ...values });
|
await addCateDataAPI({ ...cate, ...values });
|
||||||
notification.success({ message: '🎉 新增分类成功' });
|
message.success('🎉 新增分类成功');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化表单状态
|
// 初始化表单状态
|
||||||
@@ -62,7 +61,7 @@ const CateManager: React.FC = () => {
|
|||||||
|
|
||||||
const delCateData = async (id: number) => {
|
const delCateData = async (id: number) => {
|
||||||
await delCateDataAPI(id);
|
await delCateDataAPI(id);
|
||||||
notification.success({ message: '🎉 删除分类成功' });
|
message.success('🎉 删除分类成功');
|
||||||
getCateList();
|
getCateList();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -149,7 +148,7 @@ const CateManager: React.FC = () => {
|
|||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item label="链接(选填)" name="url">
|
<Form.Item label="链接(选填)" name="url">
|
||||||
<Input placeholder="https://liuyuyang.net/" />
|
<Input placeholder="https://blog.liuyuyang.net/" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item className='!mb-0 flex justify-end'>
|
<Form.Item className='!mb-0 flex justify-end'>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { Tabs, Spin, Card, message, Table, Popconfirm, Button, Tag, Modal } from 'antd';
|
import { Spin, Card, message, Table, Popconfirm, Button, Tag, Modal } from 'antd';
|
||||||
import { getCommentListAPI } from '@/api/Comment';
|
import { getCommentListAPI } from '@/api/Comment';
|
||||||
import { auditCommentDataAPI, delCommentDataAPI } from '@/api/Comment';
|
import { auditCommentDataAPI, delCommentDataAPI } from '@/api/Comment';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
@@ -8,8 +8,6 @@ import { titleSty } from '@/styles/sty';
|
|||||||
import Title from '@/components/Title';
|
import Title from '@/components/Title';
|
||||||
import { Comment } from '@/types/comment'
|
import { Comment } from '@/types/comment'
|
||||||
|
|
||||||
const { TabPane } = Tabs;
|
|
||||||
|
|
||||||
const CommentPage = () => {
|
const CommentPage = () => {
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [comment, setComment] = useState<Comment>();
|
const [comment, setComment] = useState<Comment>();
|
||||||
@@ -107,13 +105,18 @@ const CommentPage = () => {
|
|||||||
fixed: 'right',
|
fixed: 'right',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
render: (text: string, record: Comment) => (
|
render: (text: string, record: Comment) => (
|
||||||
<div className='flex space-x-2'>
|
<div className='flex justify-center space-x-2'>
|
||||||
{!record.auditStatus && <Button type='primary' onClick={() => auditCommentData(1)}>审核</Button>}
|
{
|
||||||
|
!record.auditStatus
|
||||||
<Button onClick={() => {
|
? <Button type='primary' onClick={() => {
|
||||||
setComment(record)
|
setComment(record)
|
||||||
setIsModalOpen(true)
|
setIsModalOpen(true)
|
||||||
}}>查看</Button>
|
}}>审核</Button>
|
||||||
|
: <Button onClick={() => {
|
||||||
|
setComment(record)
|
||||||
|
setIsModalOpen(true)
|
||||||
|
}}>查看</Button>
|
||||||
|
}
|
||||||
|
|
||||||
<Popconfirm title="警告" description="你确定要删除吗" okText="确定" cancelText="取消" onConfirm={() => delCommentData(record.id)}>
|
<Popconfirm title="警告" description="你确定要删除吗" okText="确定" cancelText="取消" onConfirm={() => delCommentData(record.id)}>
|
||||||
<Button type="primary" danger>删除</Button>
|
<Button type="primary" danger>删除</Button>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import React, { useState, useEffect, useRef } from 'react';
|
import React, { useState, useEffect, useRef } from 'react';
|
||||||
import { Tabs, Input, Button, Form, notification, Row, Spin, Empty, Card, Popconfirm } from 'antd';
|
import { Tabs, Input, Button, Form, Spin, Empty, Card, Popconfirm, Select, message } from 'antd';
|
||||||
import { SearchOutlined } from '@ant-design/icons';
|
import { SearchOutlined } from '@ant-design/icons';
|
||||||
import { getLinkListAPI, addLinkDataAPI, editLinkDataAPI, delLinkDataAPI } from '@/api/Web';
|
import { getLinkListAPI, addLinkDataAPI, editLinkDataAPI, delLinkDataAPI, getLinkTypeListAPI } from '@/api/Web';
|
||||||
import { Web } from '@/types/web'
|
import { LinkType, Web } from '@/types/web'
|
||||||
import Title from '@/components/Title';
|
import Title from '@/components/Title';
|
||||||
import "./index.scss"
|
import "./index.scss"
|
||||||
const LinkManager: React.FC = () => {
|
const LinkManager: React.FC = () => {
|
||||||
@@ -10,13 +10,14 @@ const LinkManager: React.FC = () => {
|
|||||||
const [tab, setTab] = useState<string>('list');
|
const [tab, setTab] = useState<string>('list');
|
||||||
const [list, setList] = useState<Web[]>([]);
|
const [list, setList] = useState<Web[]>([]);
|
||||||
const [listTemp, setListTemp] = useState<Web[]>([]);
|
const [listTemp, setListTemp] = useState<Web[]>([]);
|
||||||
|
const [typeList, setTypeList] = useState<LinkType[]>([]);
|
||||||
const [search, setSearch] = useState<string>('');
|
const [search, setSearch] = useState<string>('');
|
||||||
const [link, setLink] = useState<Web>({} as Web);
|
const [link, setLink] = useState<Web>({} as Web);
|
||||||
|
|
||||||
const formRef = useRef<any>(null);
|
const formRef = useRef<any>(null);
|
||||||
|
|
||||||
|
// 获取网站列表
|
||||||
const getLinkList = async () => {
|
const getLinkList = async () => {
|
||||||
setLoading(true);
|
|
||||||
const { data } = await getLinkListAPI();
|
const { data } = await getLinkListAPI();
|
||||||
|
|
||||||
setList(data as Web[]);
|
setList(data as Web[]);
|
||||||
@@ -24,8 +25,16 @@ const LinkManager: React.FC = () => {
|
|||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 获取网站类型列表
|
||||||
|
const getLinkTypeList = async () => {
|
||||||
|
const { data } = await getLinkTypeListAPI();
|
||||||
|
setTypeList(data)
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
setLoading(true);
|
||||||
getLinkList();
|
getLinkList();
|
||||||
|
getLinkTypeList()
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -37,8 +46,9 @@ const LinkManager: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const deleteLink = async (id: number) => {
|
const deleteLink = async (id: number) => {
|
||||||
|
setLoading(true);
|
||||||
await delLinkDataAPI(id);
|
await delLinkDataAPI(id);
|
||||||
notification.success({ message: '删除网站成功' });
|
message.success('🎉 删除网站成功');
|
||||||
getLinkList();
|
getLinkList();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -49,12 +59,14 @@ const LinkManager: React.FC = () => {
|
|||||||
|
|
||||||
const submit = async () => {
|
const submit = async () => {
|
||||||
formRef.current.validateFields().then(async (values: Web) => {
|
formRef.current.validateFields().then(async (values: Web) => {
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
if (link.id) {
|
if (link.id) {
|
||||||
await editLinkDataAPI({ ...link, ...values });
|
await editLinkDataAPI({ ...link, ...values });
|
||||||
notification.success({ message: '编辑网站成功' });
|
message.success('🎉 编辑网站成功');
|
||||||
} else {
|
} else {
|
||||||
await addLinkDataAPI(values);
|
await addLinkDataAPI(values);
|
||||||
notification.success({ message: '新增网站成功' });
|
message.success('🎉 新增网站成功');
|
||||||
}
|
}
|
||||||
formRef.current.resetFields();
|
formRef.current.resetFields();
|
||||||
getLinkList();
|
getLinkList();
|
||||||
@@ -62,6 +74,8 @@ const LinkManager: React.FC = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const { Option } = Select;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Title value="网站管理" />
|
<Title value="网站管理" />
|
||||||
@@ -111,32 +125,47 @@ const LinkManager: React.FC = () => {
|
|||||||
</Tabs.TabPane>
|
</Tabs.TabPane>
|
||||||
|
|
||||||
<Tabs.TabPane tab={link.id ? '编辑网站' : '新增网站'} key="operate">
|
<Tabs.TabPane tab={link.id ? '编辑网站' : '新增网站'} key="operate">
|
||||||
<Row className="form-container">
|
<h2 className="text-xl pb-4 text-center">{link.id ? '编辑网站' : '新增网站'}</h2>
|
||||||
<h2 className="form-title">{link.id ? '编辑网站' : '新增网站'}</h2>
|
|
||||||
<Form ref={formRef} layout="vertical" initialValues={link} onFinish={submit}>
|
<div className='w-5/12 mx-auto'>
|
||||||
<Form.Item label="标题" name="title" rules={[{ required: true, message: '网站标题不能为空' }, { min: 2, max: 30, message: '网站标题限制在2 ~ 30个字符' }]}>
|
<Form ref={formRef} layout="vertical" size='large' initialValues={link} onFinish={submit}>
|
||||||
|
<Form.Item label="网站标题" name="title" rules={[{ required: true, message: '网站标题不能为空' }]}>
|
||||||
<Input placeholder="Thrive" />
|
<Input placeholder="Thrive" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="描述" name="description" rules={[{ required: true, message: '网站描述不能为空' }, { min: 2, max: 100, message: '网站描述限制在2 ~ 100个字符' }]}>
|
|
||||||
|
<Form.Item label="网站描述" name="description" rules={[{ required: true, message: '网站描述不能为空' }]}>
|
||||||
<Input placeholder="记录前端、Python、Java点点滴滴" />
|
<Input placeholder="记录前端、Python、Java点点滴滴" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="邮箱" name="email" rules={[{ required: true, message: '网站邮箱不能为空' }]}>
|
|
||||||
|
<Form.Item label="站长邮箱" name="email">
|
||||||
<Input placeholder="3311118881@qq.com" />
|
<Input placeholder="3311118881@qq.com" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="头像" name="image" rules={[{ required: true, message: '网站图标不能为空' }]}>
|
|
||||||
<Input placeholder="https://liuyuyang.net/logo.png" />
|
<Form.Item label="网站图标" name="image" rules={[{ required: true, message: '网站图标不能为空' }]}>
|
||||||
|
<Input placeholder="https://blog.liuyuyang.net/logo.png" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="链接" name="url" rules={[{ required: true, message: '网站链接不能为空' }]}>
|
|
||||||
<Input placeholder="https://liuyuyang.net/" />
|
<Form.Item label="网站链接" name="url">
|
||||||
|
<Input placeholder="https://blog.liuyuyang.net/" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="类型" name="type" rules={[{ required: true, message: '网站类型不能为空' }, { min: 2, max: 10, message: '网站类型限制在2 ~ 10个字符' }]}>
|
|
||||||
<Input placeholder="技术类" />
|
<Form.Item name="typeId" label="网站类型" rules={[{ required: true, message: '网站类型不能为空' }]}>
|
||||||
|
<Select
|
||||||
|
placeholder="请选择网站类型"
|
||||||
|
onChange={(value: string) => {
|
||||||
|
console.log(value);
|
||||||
|
}}
|
||||||
|
allowClear
|
||||||
|
>
|
||||||
|
{typeList.map(item => <Option key={item.id} value={item.id}>{item.name}</Option>)}
|
||||||
|
</Select>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item>
|
<Form.Item>
|
||||||
<Button type="primary" htmlType="submit">{link.id ? '编辑网站' : '新增网站'}</Button>
|
<Button type="primary" htmlType="submit" className='w-full'>{link.id ? '编辑网站' : '新增网站'}</Button>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
</Row>
|
</div>
|
||||||
</Tabs.TabPane>
|
</Tabs.TabPane>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
2
src/types/web.d.ts
vendored
2
src/types/web.d.ts
vendored
@@ -1,4 +1,4 @@
|
|||||||
interface LinkType {
|
export interface LinkType {
|
||||||
id: number,
|
id: number,
|
||||||
name: string
|
name: string
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user