2024-08-09 14:48:05 +08:00
|
|
|
import { useState, useEffect } from 'react';
|
2025-01-11 22:53:12 +08:00
|
|
|
import { Table, Button, Image, Form, Input, Tabs, Card, Popconfirm, message, Spin } from 'antd';
|
|
|
|
|
import { getSwiperListAPI, addSwiperDataAPI, editSwiperDataAPI, delSwiperDataAPI, getSwiperDataAPI } from '@/api/Swiper';
|
2024-08-15 15:28:58 +08:00
|
|
|
import { Swiper } from '@/types/app/swiper';
|
2024-08-08 13:46:28 +08:00
|
|
|
import Title from '@/components/Title';
|
|
|
|
|
import { ColumnsType } from 'antd/es/table';
|
2024-08-22 15:27:44 +08:00
|
|
|
import { CloudUploadOutlined, PictureOutlined } from '@ant-design/icons';
|
2024-08-22 14:39:18 +08:00
|
|
|
import FileUpload from '@/components/FileUpload';
|
2024-08-08 13:46:28 +08:00
|
|
|
|
2024-08-09 14:48:05 +08:00
|
|
|
const SwiperPage = () => {
|
2024-08-08 13:46:28 +08:00
|
|
|
const [loading, setLoading] = useState<boolean>(false);
|
2024-11-22 14:40:15 +08:00
|
|
|
const [btnLoading, setBtnLoading] = useState(false)
|
2025-01-11 22:53:12 +08:00
|
|
|
const [editLoading, setEditLoading] = useState(false)
|
|
|
|
|
|
|
|
|
|
const [form] = Form.useForm();
|
2024-11-22 14:40:15 +08:00
|
|
|
|
2024-08-08 13:46:28 +08:00
|
|
|
const [swiper, setSwiper] = useState<Swiper>({} as Swiper);
|
|
|
|
|
const [list, setList] = useState<Swiper[]>([]);
|
2024-08-22 14:39:18 +08:00
|
|
|
const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
|
2024-08-08 13:46:28 +08:00
|
|
|
const [tab, setTab] = useState<string>('list');
|
|
|
|
|
|
|
|
|
|
const columns: ColumnsType<Swiper> = [
|
2024-08-22 13:39:56 +08:00
|
|
|
{ title: 'ID', dataIndex: 'id', key: 'id', align: 'center' },
|
2024-08-08 13:46:28 +08:00
|
|
|
{
|
|
|
|
|
title: '图片', dataIndex: 'image', key: 'image', width: 200,
|
2024-08-22 14:56:09 +08:00
|
|
|
render: (url: string) => <Image width={200} src={url} className="w-full rounded cursor-pointer" />
|
2024-08-08 13:46:28 +08:00
|
|
|
},
|
|
|
|
|
{ title: '标题', dataIndex: 'title', key: 'title' },
|
2024-08-22 13:39:56 +08:00
|
|
|
{ title: '描述', dataIndex: 'description', key: 'description', width: 500, },
|
2024-08-08 13:46:28 +08:00
|
|
|
{
|
|
|
|
|
title: '操作', key: 'action', align: 'center',
|
|
|
|
|
render: (text: string, record: Swiper) => (
|
|
|
|
|
<>
|
|
|
|
|
<Button onClick={() => editSwiperData(record)}>修改</Button>
|
|
|
|
|
|
|
|
|
|
<Popconfirm title="警告" description="你确定要删除吗" okText="确定" cancelText="取消" onConfirm={() => delSwiperData(record.id!)}>
|
|
|
|
|
<Button type="primary" danger className="ml-2">删除</Button>
|
|
|
|
|
</Popconfirm>
|
|
|
|
|
</>
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
const getSwiperList = async () => {
|
2025-01-11 22:53:12 +08:00
|
|
|
try {
|
|
|
|
|
const { data } = await getSwiperListAPI();
|
|
|
|
|
setList(data as Swiper[]);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
setLoading(false);
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-08 13:46:28 +08:00
|
|
|
setLoading(false);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
setLoading(true);
|
|
|
|
|
getSwiperList();
|
|
|
|
|
}, []);
|
|
|
|
|
|
2025-01-11 22:53:12 +08:00
|
|
|
const editSwiperData = async (record: Swiper) => {
|
|
|
|
|
setEditLoading(true);
|
2024-08-08 13:46:28 +08:00
|
|
|
setTab('operate');
|
2025-01-11 22:53:12 +08:00
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const { data } = await getSwiperDataAPI(record.id)
|
|
|
|
|
setSwiper(data);
|
|
|
|
|
form.setFieldsValue(record);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
setEditLoading(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setEditLoading(false);
|
2024-08-08 13:46:28 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const delSwiperData = async (id: number) => {
|
2025-01-11 22:53:12 +08:00
|
|
|
setBtnLoading(true);
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
await delSwiperDataAPI(id);
|
|
|
|
|
await getSwiperList();
|
|
|
|
|
message.success('🎉 删除轮播图成功');
|
|
|
|
|
} catch (error) {
|
|
|
|
|
setBtnLoading(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setBtnLoading(false);
|
2024-08-08 13:46:28 +08:00
|
|
|
};
|
|
|
|
|
|
2024-08-13 16:57:31 +08:00
|
|
|
const onSubmit = async () => {
|
2024-11-22 14:40:15 +08:00
|
|
|
setBtnLoading(true)
|
|
|
|
|
|
2025-01-11 22:53:12 +08:00
|
|
|
try {
|
|
|
|
|
form.validateFields().then(async (values: Swiper) => {
|
|
|
|
|
if (swiper.id) {
|
|
|
|
|
await editSwiperDataAPI({ ...swiper, ...values });
|
|
|
|
|
message.success('🎉 编辑轮播图成功');
|
|
|
|
|
} else {
|
|
|
|
|
await addSwiperDataAPI({ ...swiper, ...values });
|
|
|
|
|
message.success('🎉 新增轮播图成功');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await getSwiperList();
|
|
|
|
|
setTab('list');
|
|
|
|
|
form.resetFields();
|
|
|
|
|
setSwiper({} as Swiper);
|
|
|
|
|
})
|
|
|
|
|
} catch (error) {
|
|
|
|
|
setBtnLoading(false)
|
|
|
|
|
}
|
2024-08-08 13:46:28 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleTabChange = (key: string) => {
|
|
|
|
|
setTab(key);
|
|
|
|
|
form.resetFields();
|
|
|
|
|
setSwiper({} as Swiper);
|
|
|
|
|
};
|
|
|
|
|
|
2024-08-22 13:39:56 +08:00
|
|
|
// 文件上传
|
|
|
|
|
const UploadBtn = () => (
|
2024-08-22 14:39:18 +08:00
|
|
|
<CloudUploadOutlined className='text-xl cursor-pointer' onClick={() => setIsModalOpen(true)} />
|
2024-08-22 13:39:56 +08:00
|
|
|
)
|
|
|
|
|
|
2024-08-08 13:46:28 +08:00
|
|
|
const tabItems = [
|
|
|
|
|
{
|
|
|
|
|
label: '轮播图列表',
|
|
|
|
|
key: 'list',
|
|
|
|
|
children: (
|
|
|
|
|
<Table
|
|
|
|
|
rowKey="id"
|
|
|
|
|
dataSource={list}
|
|
|
|
|
columns={columns}
|
|
|
|
|
scroll={{ x: 'max-content' }}
|
|
|
|
|
pagination={{
|
|
|
|
|
position: ['bottomCenter'],
|
|
|
|
|
pageSize: 8
|
|
|
|
|
}}
|
|
|
|
|
loading={loading}
|
|
|
|
|
className="w-full"
|
|
|
|
|
/>
|
|
|
|
|
)
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: swiper.id ? '编辑轮播图' : '新增轮播图',
|
|
|
|
|
key: 'operate',
|
|
|
|
|
children: (
|
2025-01-11 22:53:12 +08:00
|
|
|
<Spin spinning={editLoading}>
|
2024-08-08 13:46:28 +08:00
|
|
|
<h2 className="text-xl pb-4 text-center">{swiper.id ? '编辑轮播图' : '新增轮播图'}</h2>
|
|
|
|
|
|
|
|
|
|
<Form
|
|
|
|
|
form={form}
|
|
|
|
|
layout="vertical"
|
|
|
|
|
initialValues={swiper}
|
2024-08-13 16:57:31 +08:00
|
|
|
onFinish={onSubmit}
|
2024-08-08 13:46:28 +08:00
|
|
|
size='large'
|
|
|
|
|
className="max-w-md mx-auto"
|
|
|
|
|
>
|
|
|
|
|
<Form.Item label="标题" name="title" rules={[{ required: true, message: '轮播图标题不能为空' }]}>
|
|
|
|
|
<Input placeholder="要么沉沦 要么巅峰!" />
|
|
|
|
|
</Form.Item>
|
|
|
|
|
|
|
|
|
|
<Form.Item label="描述" name="description">
|
|
|
|
|
<Input placeholder="Either sink or peak!" />
|
|
|
|
|
</Form.Item>
|
|
|
|
|
|
|
|
|
|
<Form.Item label="链接" name="url">
|
2024-11-08 12:17:37 +08:00
|
|
|
<Input placeholder="https://liuyuyang.net/" />
|
2024-08-08 13:46:28 +08:00
|
|
|
</Form.Item>
|
|
|
|
|
|
|
|
|
|
<Form.Item label="图片" name="image" rules={[{ required: true, message: '轮播图不能为空' }]}>
|
2024-11-08 12:17:37 +08:00
|
|
|
<Input placeholder="https://liuyuyang.net/swiper.jpg" prefix={<PictureOutlined />} addonAfter={<UploadBtn />} className='customizeAntdInputAddonAfter' />
|
2024-08-08 13:46:28 +08:00
|
|
|
</Form.Item>
|
|
|
|
|
|
|
|
|
|
<Form.Item>
|
2024-11-22 14:40:15 +08:00
|
|
|
<Button type="primary" htmlType="submit" loading={btnLoading} className="w-full">{swiper.id ? '编辑轮播图' : '新增轮播图'}</Button>
|
2024-08-08 13:46:28 +08:00
|
|
|
</Form.Item>
|
|
|
|
|
</Form>
|
2025-01-11 22:53:12 +08:00
|
|
|
</Spin>
|
2024-08-08 13:46:28 +08:00
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
<Title value="轮播图管理" />
|
|
|
|
|
|
2024-11-12 19:55:24 +08:00
|
|
|
<Card className="[&>.ant-card-body]:!pt-0 mt-2 min-h-[calc(100vh-180px)]">
|
2024-08-08 13:46:28 +08:00
|
|
|
<Tabs activeKey={tab} onChange={handleTabChange} items={tabItems} />
|
|
|
|
|
</Card>
|
|
|
|
|
|
2024-08-22 14:39:18 +08:00
|
|
|
<FileUpload
|
|
|
|
|
dir="swiper"
|
|
|
|
|
open={isModalOpen}
|
2024-10-12 12:55:39 +08:00
|
|
|
onSuccess={(url: string[]) => form.setFieldValue("image", url.join("\n"))}
|
2024-08-22 14:39:18 +08:00
|
|
|
onCancel={() => setIsModalOpen(false)}
|
|
|
|
|
/>
|
2024-08-08 13:46:28 +08:00
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default SwiperPage;
|