blob: b81efb0cd3cde1f6e3ddc9518e6bb109c175b944 [file] [log] [blame]
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;