import { useState, useEffect } from 'react'; import { Tabs, Input, Button, Form, Spin, Empty, Card, Popconfirm, Select, message } from 'antd'; import { SearchOutlined } from '@ant-design/icons'; import { getLinkListAPI, addLinkDataAPI, editLinkDataAPI, delLinkDataAPI, getWebTypeListAPI, getLinkDataAPI } from '@/api/Web'; import { WebType, Web } from '@/types/app/web'; import Title from '@/components/Title'; import { RuleObject } from 'antd/es/form'; import group from "./assets/svg/group.svg" import './index.scss'; export default () => { const [loading, setLoading] = useState(false); const [btnLoading, setBtnLoading] = useState(false) const [editLoading, setEditLoading] = useState(false) const [form] = Form.useForm(); const [tab, setTab] = useState('list'); const [list, setList] = useState<{ [key: string]: Web[] }>({}); const [listTemp, setListTemp] = useState([]); const [typeList, setTypeList] = useState([]); const [search, setSearch] = useState(''); const [link, setLink] = useState({} as Web); // 区分新增或编辑 const [isMethod, setIsMethod] = useState<"create" | "edit">("create"); // 获取网站列表 const getLinkList = async () => { try { setLoading(true); const { data } = await getLinkListAPI(); data.sort((a, b) => a.order - b.order) data.sort((a, b) => a.type.order - b.type.order) const grouped = data.reduce((acc, item) => { const groupName = item.type.name; if (!acc[groupName]) { acc[groupName] = []; } acc[groupName].push(item); return acc; }, {} as { [key: string]: Web[] }); setList(grouped); setListTemp(data); setLoading(false) } catch (error) { setLoading(false); } }; // 获取网站类型列表 const getWebTypeList = async () => { const { data } = await getWebTypeListAPI(); setTypeList(data); }; useEffect(() => { getLinkList(); getWebTypeList(); }, []); useEffect(() => { // 过滤出符合搜索条件的网站 const filteredList = listTemp.filter(item => item.title.includes(search) || item.description.includes(search) ); // 按类型分组 const grouped = filteredList.reduce((acc, item) => { const groupName = item.type.name; if (!acc[groupName]) { acc[groupName] = []; } acc[groupName].push(item); return acc; }, {} as { [key: string]: Web[] }); setList(grouped); }, [search, listTemp]); const deleteLinkData = async (id: number) => { try { setLoading(true); await delLinkDataAPI(id); await getLinkList(); message.success('🎉 删除网站成功'); } catch (error) { setLoading(false) } }; const editLinkData = async (record: Web) => { try { setEditLoading(true) setTab('operate'); setIsMethod("edit"); const { data } = await getLinkDataAPI(record.id) setLink(data); form.setFieldsValue(data); setEditLoading(false) } catch (error) { setEditLoading(false) } }; // 做一些初始化的事情 const reset = () => { form.resetFields(); // 重置表单字段 setLink({} as Web); setIsMethod("create"); } // 校验网站链接 const validateURL = (_: RuleObject, value: string) => { return !value || /^(https?:\/\/)/.test(value) ? Promise.resolve() : Promise.reject(new Error('请输入有效的链接')); }; const submit = async () => { try { setBtnLoading(true) form.validateFields().then(async (values: Web) => { if (isMethod === "edit") { await editLinkDataAPI({ ...link, ...values }); message.success('🎉 编辑网站成功'); } else { await addLinkDataAPI({ ...values, createTime: new Date().getTime().toString() }); message.success('🎉 新增网站成功'); } await getLinkList(); reset() setTab('list'); }); setBtnLoading(false) } catch (error) { setBtnLoading(false) } }; const { Option } = Select; const handleTabChange = (key: string) => { setTab(key); reset() }; const toHref = (url: string) => { window.open(url, '_blank'); }; const tabItems = [ { label: '网站列表', key: 'list', children: (
} value={search} onChange={e => setSearch(e.target.value)} className='w-[400px]' />
{ Object.keys(list).map((key) => (
分组图标 {key} { Object.values(list[key]).length ? (
{ Object.values(list[key]).map(item => (
{item.title}
{item.description}
{item.type.name}
editLinkData(item)} className="edit">修改
deleteLinkData(item.id!)}>
删除
toHref(item.url)} className="headFor">前往该网站 →
)) }
) : }
)) }
), }, { label: isMethod === "edit" ? '编辑网站' : '新增网站', key: 'operate', children: (

{isMethod === "edit" ? '编辑网站' : '新增网站'}

), }, ]; return (
<Card className="WebPage mt-2 min-h-[calc(100vh-180px)]"> <Tabs activeKey={tab} tabPosition="top" onChange={handleTabChange} items={tabItems} /> </Card> </div> ); };