公告用户前端以及管理员
Change-Id: I3ea4a7f62ae91ef97734d6d673cce28855d10eeb
diff --git a/src/components/ActivityBoard.jsx b/src/components/ActivityBoard.jsx
new file mode 100644
index 0000000..4cbfb52
--- /dev/null
+++ b/src/components/ActivityBoard.jsx
@@ -0,0 +1,98 @@
+// src/components/ActivityBoard.jsx
+import React, { useEffect, useState } from 'react';
+import { Card, Row, Col, Typography, Spin, message, Modal } from 'antd';
+import { getFullActivities } from '../api/activity';
+import './ActivityBoard.css';
+
+const { Paragraph, Text } = Typography;
+
+const ActivityBoard = () => {
+ const [activities, setActivities] = useState([]);
+ const [loading, setLoading] = useState(true);
+ const [modalVisible, setModalVisible] = useState(false);
+ const [selectedActivity, setSelectedActivity] = useState(null);
+
+ useEffect(() => {
+ getFullActivities()
+ .then((res) => {
+ setActivities(res.data);
+ setLoading(false);
+ })
+ .catch(() => {
+ message.error('获取公告失败');
+ setLoading(false);
+ });
+ }, []);
+
+ const showModal = (activity) => {
+ setSelectedActivity(activity);
+ setModalVisible(true);
+ };
+
+ const handleClose = () => {
+ setModalVisible(false);
+ setSelectedActivity(null);
+ };
+
+ return (
+ <>
+ {loading ? (
+ <div className="loading-container">
+ <Spin size="large" />
+ </div>
+ ) : (
+ <Row gutter={[24, 24]}>
+ {activities.map((activity) => (
+ <Col xs={24} sm={12} md={8} lg={6} key={activity.activityid}>
+ <Card
+ hoverable
+ className="activity-card"
+ cover={
+ <img
+ alt="活动图片"
+ src={`http://localhost:8080${activity.photo}`}
+ className="activity-photo"
+ onClick={() => showModal(activity)}
+ />
+ }
+ >
+ <Card.Meta
+ title={<div className="activity-title">{activity.title}</div>}
+ />
+ </Card>
+ </Col>
+ ))}
+ </Row>
+ )}
+
+ {/* 弹窗展示公告详情 */}
+ <Modal
+ open={modalVisible}
+ title={selectedActivity?.title}
+ footer={null}
+ onCancel={handleClose}
+ centered
+ width={700}
+ bodyStyle={{ padding: '24px', maxHeight: '80vh', overflowY: 'auto' }}
+ >
+ {selectedActivity && (
+ <div>
+ {selectedActivity.photo && (
+ <img
+ src={`http://localhost:8080${selectedActivity.photo}`}
+ alt="公告图片"
+ style={{ width: '100%', maxHeight: 400, objectFit: 'cover', borderRadius: 8, marginBottom: 20 }}
+ />
+ )}
+ <Paragraph style={{ fontSize: 16 }}>{selectedActivity.content}</Paragraph>
+ <Text type="secondary">
+ 发布时间:{new Date(selectedActivity.time).toLocaleString()}
+ </Text>
+ </div>
+ )}
+ </Modal>
+ </>
+ );
+};
+
+export default ActivityBoard;