diff --git a/src/pages/News/Detail.tsx b/src/pages/News/Detail.tsx index 77f4ad5..186489f 100644 --- a/src/pages/News/Detail.tsx +++ b/src/pages/News/Detail.tsx @@ -4,39 +4,40 @@ import React, { useEffect, useState } from 'react' import { useParams, Link } from 'react-router-dom' -import { Breadcrumb, Spin, Empty, Tag, Space, Typography, Divider } from 'antd' +import { Breadcrumb, Spin, Empty, Tag, Space, Typography, Divider, Card } from 'antd' import { HomeOutlined, EyeOutlined, - HeartOutlined, + LikeOutlined, CalendarOutlined, UserOutlined, } from '@ant-design/icons' -import { getNewsById } from '@services/api' -import type { NewsArticle } from '@/types' +import dayjs from 'dayjs' +import { getNewsDetail } from '@services/newsApi' +import FavoriteButton from '@components/FavoriteButton' +import LikeButton from '@components/LikeButton' +import CommentSection from '@components/CommentSection' +import type { NewsDetail } from '@/types' import './Detail.css' const { Title, Paragraph, Text } = Typography +// 后端分类映射:news、activity、notice const categoryLabels: Record = { - exhibition: '展览', + news: '新闻', activity: '活动', - policy: '政策', - research: '研究', - story: '故事', + notice: '通知', } const categoryColors: Record = { - exhibition: 'purple', - activity: 'blue', - policy: 'red', - research: 'green', - story: 'orange', + news: 'blue', + activity: 'green', + notice: 'red', } -const NewsDetail: React.FC = () => { +const NewsDetailPage: React.FC = () => { const { id } = useParams<{ id: string }>() - const [data, setData] = useState(null) + const [data, setData] = useState(null) const [loading, setLoading] = useState(true) useEffect(() => { @@ -48,7 +49,7 @@ const NewsDetail: React.FC = () => { const fetchData = async (newsId: string) => { setLoading(true) try { - const result = await getNewsById(newsId) + const result = await getNewsDetail(newsId) setData(result) } catch (error) { console.error('Failed to fetch news detail:', error) @@ -73,6 +74,9 @@ const NewsDetail: React.FC = () => { ) } + // 处理标签字符串 + const tagArray = data?.tags ? data.tags.split(',').filter(tag => tag.trim()) : [] + return (
{/* 面包屑导航 */} @@ -93,8 +97,8 @@ const NewsDetail: React.FC = () => {
{/* 封面图 */} - {data.cover && ( -
+ {data.coverImage && ( +
)} @@ -102,63 +106,96 @@ const NewsDetail: React.FC = () => { {/* 详情内容 */}
-
- {/* 头部信息 */} -
- - {categoryLabels[data.category]} - - - {data.title} - - {data.subtitle && ( - {data.subtitle} +
+ {/* 主要内容 */} +
+ {/* 头部信息 */} +
+ + {categoryLabels[data.category] || data.category} + + + {data.title} + +
+ + + + 作者:{data.author} + + + 来源:{data.source} + + + + 发布时间:{dayjs(data.publishTime).format('YYYY-MM-DD HH:mm')} + + + + {data.viewCount.toLocaleString()} 浏览 + + + + {data.likeCount.toLocaleString()} 点赞 + + +
+
+ + + + {/* 摘要 */} +
+ {data.summary} +
+ + {/* 正文内容 - 使用 dangerouslySetInnerHTML 渲染 HTML */} +
+ + {/* 标签 */} + {tagArray.length > 0 && ( +
+ + 标签: + {tagArray.map((tag, index) => ( + {tag} + ))} + +
)} -
- - - - 作者:{data.author} - - - - 发布时间:{data.publishDate} - - - - {data.viewCount.toLocaleString()} 浏览 - - - - {data.likeCount.toLocaleString()} 点赞 - - + + + + {/* 评论区 */} +
+
- - - {/* 摘要 */} -
- {data.summary} -
- - {/* 正文内容 */} -
- {data.content} -
- - {/* 标签 */} - {data.tags && data.tags.length > 0 && ( -
- - 标签: - {data.tags.map((tag) => ( - {tag} - ))} + {/* 侧边栏 */} +
+ {/* 操作按钮 */} + + + + -
- )} + +
@@ -166,4 +203,4 @@ const NewsDetail: React.FC = () => { ) } -export default NewsDetail +export default NewsDetailPage diff --git a/src/pages/News/index.tsx b/src/pages/News/index.tsx index 618174f..afa0c0e 100644 --- a/src/pages/News/index.tsx +++ b/src/pages/News/index.tsx @@ -8,54 +8,43 @@ import { FileTextOutlined, CalendarOutlined } from '@ant-design/icons' import NewsCard from '@components/NewsCard' import EventCard from '@components/EventCard' import CustomPagination from '@components/CustomPagination' -import { getNewsList, getEventList } from '@services/api' -import type { NewsArticle, Event, PaginationResult } from '@/types' +import { getNewsList } from '@services/newsApi' +import { getEventList } from '@services/eventApi' +import type { NewsListItem, EventListItem, IPage, NewsCategory, EventStatus } from '@/types' import './index.css' const { TabPane } = Tabs -// 资讯分类选项 +// 资讯分类选项(匹配后端 category 字段:news、activity、notice) const newsCategoryOptions = [ { label: '全部', value: '' }, - { label: '展览', value: 'exhibition' }, - { label: '活动', value: 'activity' }, - { label: '政策', value: 'policy' }, - { label: '研究', value: 'research' }, - { label: '故事', value: 'story' }, + { label: '新闻资讯', value: 'news' }, + { label: '活动动态', value: 'activity' }, + { label: '通知公告', value: 'notice' }, ] -// 活动类型选项 -const eventTypeOptions = [ - { label: '全部', value: '' }, - { label: '展览', value: 'exhibition' }, - { label: '工作坊', value: 'workshop' }, - { label: '演出', value: 'performance' }, - { label: '讲座', value: 'lecture' }, - { label: '节日', value: 'festival' }, -] - -// 活动状态选项 +// 活动状态选项(匹配后端 status 字段:upcoming、ongoing、finished、cancelled) const eventStatusOptions = [ { label: '全部', value: '' }, { label: '即将开始', value: 'upcoming' }, { label: '进行中', value: 'ongoing' }, { label: '已结束', value: 'finished' }, + { label: '已取消', value: 'cancelled' }, ] const NewsPage: React.FC = () => { const [activeTab, setActiveTab] = useState('news') - const [newsData, setNewsData] = useState | null>(null) - const [eventsData, setEventsData] = useState | null>(null) + const [newsData, setNewsData] = useState | null>(null) + const [eventsData, setEventsData] = useState | null>(null) const [loading, setLoading] = useState(true) // 资讯筛选条件 - const [newsCategory, setNewsCategory] = useState('') + const [newsCategory, setNewsCategory] = useState('') const [newsPage, setNewsPage] = useState(1) const [newsPageSize, setNewsPageSize] = useState(12) // 活动筛选条件 - const [eventType, setEventType] = useState('') - const [eventStatus, setEventStatus] = useState('') + const [eventStatus, setEventStatus] = useState('') const [eventPage, setEventPage] = useState(1) const [eventPageSize, setEventPageSize] = useState(12) @@ -64,9 +53,9 @@ const NewsPage: React.FC = () => { setLoading(true) try { const result = await getNewsList({ - category: (newsCategory || undefined) as any, - page: newsPage, + pageNum: newsPage, pageSize: newsPageSize, + category: newsCategory || undefined, }) setNewsData(result) } catch (error) { @@ -81,10 +70,9 @@ const NewsPage: React.FC = () => { setLoading(true) try { const result = await getEventList({ - type: eventType || undefined, - status: eventStatus || undefined, - page: eventPage, + pageNum: eventPage, pageSize: eventPageSize, + status: eventStatus || undefined, }) setEventsData(result) } catch (error) { @@ -100,7 +88,7 @@ const NewsPage: React.FC = () => { } else { fetchEvents() } - }, [activeTab, newsCategory, newsPage, newsPageSize, eventType, eventStatus, eventPage, eventPageSize]) + }, [activeTab, newsCategory, newsPage, newsPageSize, eventStatus, eventPage, eventPageSize]) const handleTabChange = (key: string) => { setActiveTab(key) @@ -165,10 +153,10 @@ const NewsPage: React.FC = () => {
- ) : newsData && newsData.data.length > 0 ? ( + ) : newsData && newsData.records.length > 0 ? ( <> - {newsData.data.map((item) => ( + {newsData.records.map((item) => ( @@ -199,13 +187,6 @@ const NewsPage: React.FC = () => { {/* 活动筛选 */}
- 活动类型: - {
- ) : eventsData && eventsData.data.length > 0 ? ( + ) : eventsData && eventsData.records.length > 0 ? ( <> - {eventsData.data.map((item) => ( + {eventsData.records.map((item) => (