| import React, { useEffect, useState } from 'react'; |
| import { Row, Col, Pagination, Input, Carousel, Menu, Card, message, Button } from 'antd'; |
| import { SearchOutlined, AuditOutlined } from '@ant-design/icons'; |
| import { getPostList, getPromotionPosts } from '@/services/post'; |
| import PostCard from '../PostCenter/PostCard'; |
| import styles from './index.module.css'; |
| import { Post } from '../PostCenter/types'; |
| import { useNavigate } from 'react-router-dom'; |
| import { useModel } from 'umi'; |
| |
| const { Search } = Input; |
| |
| const PostCenter: React.FC = () => { |
| const [posts, setPosts] = useState<Post[]>([]); |
| const [promotionPosts, setPromotionPosts] = useState<Post[]>([]); |
| const [total, setTotal] = useState<number>(0); |
| const [page, setPage] = useState<number>(1); |
| const [loading, setLoading] = useState<boolean>(false); |
| const [selectedCategory, setSelectedCategory] = useState<string>('all'); |
| const [searchKeyword, setSearchKeyword] = useState<string>(''); |
| const pageSize = 12; |
| const navigate = useNavigate(); |
| const { initialState } = useModel('@@initialState'); |
| |
| // 检查是否为管理员 - 用户名包含admin |
| const isAdmin = initialState?.currentUser?.userName?.toLowerCase().includes('admin') || false; |
| |
| const fetchPosts = async (current: number = 1, category?: string, searchTitle?: string) => { |
| try { |
| setLoading(true); |
| const params: any = { |
| pageNum: current, |
| pageSize: pageSize, |
| status: '1', // 只查询正常状态的帖子 |
| }; |
| |
| // 根据分类筛选 |
| if (category && category !== 'all') { |
| params.tags = category; |
| } |
| |
| // 搜索关键词 |
| if (searchTitle) { |
| params.title = searchTitle; |
| } |
| |
| const response = await getPostList(params); |
| |
| if (response.code === 200) { |
| // 确保返回的数据符合 Post 类型 |
| const formattedPosts = (response.rows || []).map((post: API.Post.PostInfo) => ({ |
| ...post, |
| id: post.postId, // 确保id字段映射正确 |
| tags: post.tags ? post.tags.split(',') : [], |
| views: post.views || 0, |
| comments: post.comments || 0, |
| favorites: post.favorites || 0, |
| likes: post.likes || 0, |
| coverImage: post.coverImage || '/images/404.png', // 使用本地默认图片 |
| isPromoted: post.promotionPlanId != null && post.promotionPlanId > 0, // 添加推广标识 |
| })); |
| setPosts(formattedPosts); |
| setTotal(response.total || 0); |
| } else { |
| message.error(response.msg || '获取帖子列表失败'); |
| setPosts([]); |
| setTotal(0); |
| } |
| } catch (error) { |
| console.error('获取帖子失败:', error); |
| message.error('获取帖子列表失败,请稍后重试'); |
| setPosts([]); |
| setTotal(0); |
| } finally { |
| setLoading(false); |
| } |
| }; |
| |
| const fetchPromotionPosts = async () => { |
| try { |
| const response = await getPromotionPosts(); |
| if (response.code === 200) { |
| const formattedPosts = (response.data || []).map((post: API.Post.PostInfo) => ({ |
| ...post, |
| id: post.postId, |
| tags: post.tags ? post.tags.split(',') : [], |
| views: post.views || 0, |
| comments: post.comments || 0, |
| favorites: post.favorites || 0, |
| likes: post.likes || 0, |
| coverImage: post.coverImage || '/images/404.png', |
| isPromoted: post.promotionPlanId != null && post.promotionPlanId > 0, // 添加推广标识 |
| })); |
| setPromotionPosts(formattedPosts); |
| } |
| } catch (error) { |
| console.error('获取推广帖子失败:', error); |
| } |
| }; |
| |
| useEffect(() => { |
| fetchPosts(page, selectedCategory, searchKeyword); |
| fetchPromotionPosts(); |
| }, [page, selectedCategory]); |
| |
| const handleSearch = (value: string) => { |
| console.log('搜索:', value); |
| setSearchKeyword(value); |
| setPage(1); // 重置页码 |
| fetchPosts(1, selectedCategory, value); |
| }; |
| |
| const handlePageChange = (newPage: number) => { |
| setPage(newPage); |
| fetchPosts(newPage, selectedCategory, searchKeyword); |
| }; |
| |
| const handleCategoryChange = (category: string) => { |
| setSelectedCategory(category); |
| setPage(1); // 重置页码 |
| setSearchKeyword(''); // 清空搜索 |
| fetchPosts(1, category, ''); |
| }; |
| |
| return ( |
| <div className={styles.postCenterContainer}> |
| {/* 顶部导航 */} |
| <div className={styles.headerNav}> |
| <div className={styles.categoryMenu}> |
| <Button |
| type={selectedCategory === 'all' ? 'primary' : 'text'} |
| onClick={() => handleCategoryChange('all')} |
| className={styles.categoryButton} |
| > |
| 首页 |
| </Button> |
| <Button |
| type={selectedCategory === '日剧' ? 'primary' : 'text'} |
| onClick={() => handleCategoryChange('日剧')} |
| className={styles.categoryButton} |
| > |
| 日剧 |
| </Button> |
| <Button |
| type={selectedCategory === '电影' ? 'primary' : 'text'} |
| onClick={() => handleCategoryChange('电影')} |
| className={styles.categoryButton} |
| > |
| 电影 |
| </Button> |
| <Button |
| type={selectedCategory === '音乐' ? 'primary' : 'text'} |
| onClick={() => handleCategoryChange('音乐')} |
| className={styles.categoryButton} |
| > |
| 音乐 |
| </Button> |
| <Button |
| type={selectedCategory === '合集' ? 'primary' : 'text'} |
| onClick={() => handleCategoryChange('合集')} |
| className={styles.categoryButton} |
| > |
| 合集 |
| </Button> |
| <Button |
| type={selectedCategory === '动漫' ? 'primary' : 'text'} |
| onClick={() => handleCategoryChange('动漫')} |
| className={styles.categoryButton} |
| > |
| 动漫 |
| </Button> |
| <Button |
| type={selectedCategory === '游戏' ? 'primary' : 'text'} |
| onClick={() => handleCategoryChange('游戏')} |
| className={styles.categoryButton} |
| > |
| 游戏 |
| </Button> |
| </div> |
| |
| <div className={styles.searchContainer}> |
| <Search |
| placeholder="搜索帖子..." |
| onSearch={handleSearch} |
| style={{ width: 300 }} |
| enterButton={<SearchOutlined />} |
| value={searchKeyword} |
| onChange={(e) => setSearchKeyword(e.target.value)} |
| /> |
| </div> |
| |
| <div className={styles.userCenter}> |
| {isAdmin && ( |
| <Button |
| icon={<AuditOutlined />} |
| onClick={() => navigate('/post-review')} |
| style={{ marginRight: 16 }} |
| > |
| 帖子审核 |
| </Button> |
| )} |
| <Button |
| type="primary" |
| onClick={() => navigate('/user-center')} |
| > |
| 个人中心 |
| </Button> |
| </div> |
| </div> |
| |
| {/* 轮播推荐图 */} |
| <div className={styles.carouselContainer}> |
| <Carousel autoplay> |
| {promotionPosts.length > 0 ? ( |
| promotionPosts.map((post) => ( |
| <div key={post.id} onClick={() => navigate(`/post-detail/${post.id}`)}> |
| <div |
| className={styles.carouselSlide} |
| style={{ |
| backgroundImage: `linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4)), url(${post.coverImage})`, |
| backgroundSize: 'cover', |
| backgroundPosition: 'center', |
| height: '300px', |
| position: 'relative', |
| cursor: 'pointer' |
| }} |
| > |
| <div className={styles.carouselOverlay}> |
| <h2 className={styles.carouselTitle}>{post.title}</h2> |
| <p className={styles.carouselSummary}>{post.summary}</p> |
| <div className={styles.carouselMeta}> |
| <span>作者: {post.author}</span> |
| <span>浏览: {post.views}</span> |
| <span>点赞: {post.likes}</span> |
| </div> |
| </div> |
| </div> |
| </div> |
| )) |
| ) : ( |
| // 默认轮播图 |
| <> |
| <div> |
| <div |
| className={styles.carouselSlide} |
| style={{ |
| backgroundImage: `url(/images/flower.jpg)`, |
| backgroundSize: 'cover', |
| backgroundPosition: 'center', |
| height: '300px', |
| }} |
| > |
| <div className={styles.carouselOverlay}> |
| <h2 className={styles.carouselTitle}>欢迎来到ThunderHub</h2> |
| <p className={styles.carouselSummary}>发现精彩内容,分享美好时光</p> |
| </div> |
| </div> |
| </div> |
| </> |
| )} |
| </Carousel> |
| </div> |
| |
| {/* 卡片帖子区 */} |
| <div className={styles.postsSection}> |
| {selectedCategory !== 'all' && ( |
| <div className={styles.categoryTitle}> |
| <h2>{selectedCategory} 分类</h2> |
| <p>共找到 {total} 篇相关帖子</p> |
| </div> |
| )} |
| |
| <Row gutter={[24, 24]} className={styles.postsRow}> |
| {posts.map((post) => ( |
| <Col xs={24} sm={12} lg={8} xl={6} key={post.id} className={styles.postCol}> |
| <PostCard post={post} /> |
| </Col> |
| ))} |
| </Row> |
| |
| {posts.length === 0 && !loading && ( |
| <div className={styles.emptyState}> |
| <p>暂无相关帖子</p> |
| </div> |
| )} |
| |
| <div className={styles.paginationContainer}> |
| <Pagination |
| current={page} |
| pageSize={pageSize} |
| total={total} |
| onChange={handlePageChange} |
| showTotal={(total) => `共 ${total} 条帖子`} |
| /> |
| </div> |
| </div> |
| </div> |
| ); |
| }; |
| |
| export default PostCenter; |