| import React, { useEffect, useState } from 'react'; |
| import { |
| Table, Button, Modal, Image, message, Tag, |
| Space, Input, Tooltip, Form, Upload |
| } from 'antd'; |
| import { |
| ExclamationCircleOutlined, SearchOutlined, UploadOutlined |
| } from '@ant-design/icons'; |
| import { |
| getAllActivities, |
| searchActivitiesByTitle, |
| deleteActivity, |
| createActivity, |
| updateActivity |
| } from '../api/activity'; |
| |
| const { confirm } = Modal; |
| |
| const ActivityAdminPanel = () => { |
| const [activities, setActivities] = useState([]); |
| const [loading, setLoading] = useState(false); |
| const [keyword, setKeyword] = useState(''); |
| const [modalVisible, setModalVisible] = useState(false); |
| const [editMode, setEditMode] = useState(false); |
| const [currentActivity, setCurrentActivity] = useState(null); |
| const [form] = Form.useForm(); |
| |
| const fetchActivities = async () => { |
| setLoading(true); |
| try { |
| const data = keyword.trim() |
| ? await searchActivitiesByTitle(keyword.trim()) |
| : await getAllActivities(); |
| setActivities(data.data || []); |
| } catch (error) { |
| message.error('获取公告失败'); |
| } finally { |
| setLoading(false); |
| } |
| }; |
| |
| useEffect(() => { |
| fetchActivities(); |
| }, []); |
| |
| const handleSearch = () => { |
| fetchActivities(); |
| }; |
| |
| const handleDelete = (activityid) => { |
| confirm({ |
| title: '确认删除该公告吗?', |
| icon: <ExclamationCircleOutlined />, |
| okText: '删除', |
| okType: 'danger', |
| cancelText: '取消', |
| onOk: async () => { |
| try { |
| const res = await deleteActivity(activityid); |
| if (res.data === true) { |
| message.success('删除成功'); |
| fetchActivities(); |
| } else { |
| message.error('删除失败'); |
| } |
| } catch { |
| message.error('删除请求失败'); |
| } |
| }, |
| }); |
| }; |
| |
| const openEditModal = (record) => { |
| setEditMode(true); |
| setCurrentActivity(record); |
| form.setFieldsValue({ |
| activityid: record.activityid, |
| title: record.title, |
| content: record.content, |
| isShow: record.is_show, |
| }); |
| setModalVisible(true); |
| }; |
| |
| const openCreateModal = () => { |
| setEditMode(false); |
| form.resetFields(); |
| setModalVisible(true); |
| }; |
| |
| const handleModalOk = async () => { |
| try { |
| const values = await form.validateFields(); |
| const formData = new FormData(); |
| Object.keys(values).forEach(key => { |
| if (key !== 'photo' && values[key] !== undefined) { |
| formData.append(key, values[key]); |
| } |
| }); |
| if (values.photo && values.photo.file) { |
| formData.append('photo', values.photo.file); |
| } |
| |
| const res = editMode |
| ? await updateActivity(formData) |
| : await createActivity(formData); |
| |
| if (res.data === true) { |
| message.success(editMode ? '修改成功' : '创建成功'); |
| setModalVisible(false); |
| fetchActivities(); |
| } else { |
| message.error('提交失败'); |
| } |
| } catch (error) { |
| message.error('提交失败,请检查表单'); |
| } |
| }; |
| |
| const columns = [ |
| { |
| title: 'ID', |
| dataIndex: 'activityid', |
| key: 'activityid', |
| width: 80, |
| }, |
| { |
| title: '标题', |
| dataIndex: 'title', |
| key: 'title', |
| width: 200, |
| ellipsis: true, |
| }, |
| { |
| title: '内容', |
| dataIndex: 'content', |
| key: 'content', |
| ellipsis: { showTitle: false }, |
| render: (text) => ( |
| <Tooltip placement="topLeft" title={text}> |
| {text} |
| </Tooltip> |
| ), |
| }, |
| { |
| title: '图片', |
| dataIndex: 'photo', |
| key: 'photo', |
| width: 100, |
| render: (url) => |
| url ? ( |
| <Image |
| src={`http://localhost:8080${url}`} |
| width={80} |
| height={80} |
| style={{ objectFit: 'cover' }} |
| /> |
| ) : ( |
| <Tag color="default">无</Tag> |
| ), |
| }, |
| { |
| title: '展示状态', |
| dataIndex: 'is_show', |
| key: 'is_show', |
| width: 100, |
| render: (val) => |
| val === 0 ? <Tag color="green">展示</Tag> : <Tag color="red">隐藏</Tag>, |
| }, |
| { |
| title: '发布时间', |
| dataIndex: 'time', |
| key: 'time', |
| width: 180, |
| render: (time) => |
| time ? new Date(time).toLocaleString() : <Tag color="default">暂无</Tag>, |
| }, |
| { |
| title: '操作', |
| key: 'action', |
| width: 180, |
| render: (_, record) => ( |
| <Space size="middle"> |
| <Button type="primary" onClick={() => openEditModal(record)}> |
| 修改 |
| </Button> |
| <Button danger onClick={() => handleDelete(record.activityid)}> |
| 删除 |
| </Button> |
| </Space> |
| ), |
| }, |
| ]; |
| |
| return ( |
| <div style={{ padding: 20 }}> |
| <h2 style={{ marginBottom: 20 }}>公告管理面板</h2> |
| <Space style={{ marginBottom: 16 }}> |
| <Input |
| placeholder="请输入标题关键词" |
| value={keyword} |
| onChange={(e) => setKeyword(e.target.value)} |
| style={{ width: 300 }} |
| /> |
| <Button type="primary" icon={<SearchOutlined />} onClick={handleSearch}> |
| 搜索 |
| </Button> |
| <Button onClick={() => { setKeyword(''); fetchActivities(); }}> |
| 重置 |
| </Button> |
| <Button type="primary" onClick={openCreateModal}> |
| 新建公告 |
| </Button> |
| </Space> |
| <Table |
| rowKey="activityid" |
| columns={columns} |
| dataSource={activities} |
| loading={loading} |
| scroll={{ x: 1200 }} |
| pagination={{ pageSize: 8 }} |
| bordered |
| size="middle" |
| /> |
| |
| <Modal |
| title={editMode ? '修改公告' : '新建公告'} |
| open={modalVisible} |
| onOk={handleModalOk} |
| onCancel={() => setModalVisible(false)} |
| okText="提交" |
| cancelText="取消" |
| destroyOnClose |
| > |
| <Form form={form} layout="vertical" preserve={false}> |
| {editMode && ( |
| <Form.Item name="activityid" hidden> |
| <Input /> |
| </Form.Item> |
| )} |
| <Form.Item |
| name="title" |
| label="标题" |
| rules={[{ required: true, message: '请输入标题' }]} |
| > |
| <Input /> |
| </Form.Item> |
| <Form.Item |
| name="content" |
| label="内容" |
| rules={[{ required: true, message: '请输入内容' }]} |
| > |
| <Input.TextArea rows={4} /> |
| </Form.Item> |
| <Form.Item name="isShow" label="是否展示"> |
| <Input placeholder="0 表示展示,1 表示隐藏" /> |
| </Form.Item> |
| <Form.Item name="photo" label="上传图片"> |
| <Upload beforeUpload={() => false} maxCount={1}> |
| <Button icon={<UploadOutlined />}>选择文件</Button> |
| </Upload> |
| </Form.Item> |
| </Form> |
| </Modal> |
| </div> |
| ); |
| }; |
| |
| export default ActivityAdminPanel; |