帖子分类
Change-Id: I17bafbfe3c1c8fd26c1e12499cb3c17cd1738e23
diff --git a/src/views/postDetail/postDetail.tsx b/src/views/postDetail/postDetail.tsx
new file mode 100644
index 0000000..a40fb68
--- /dev/null
+++ b/src/views/postDetail/postDetail.tsx
@@ -0,0 +1,114 @@
+import React, { useEffect, useState } from 'react';
+import { useParams } from 'react-router-dom';
+import styles from './PostDetail.module.css';
+import { Card, List, Typography, Button, Input, Spin, Empty } from 'antd';
+type CommentProps = {
+ children?: React.ReactNode;
+};
+import { getPostDetail } from '@/api/post';
+import { getPostComments } from '@/api/comment';
+import { useSearchParams } from 'react-router-dom';
+import request from '@/utils/request';
+import { useApi } from '@/hooks/request';
+import Navbar from '@/components/navbar/navbar';
+
+const { Title, Text, Paragraph } = Typography;
+const { TextArea } = Input;
+
+export interface PostResponse {
+ createdAt?: number;
+ hotScore?: number;
+ lastCalculated?: number;
+ postContent?: string;
+ postId?: number;
+ postTitle?: string;
+ postType?: string;
+ userId?: number;
+ viewCount?: number;
+ [property: string]: any;
+}
+
+export interface CommentResponse {
+ commentId?: number;
+ content?: string;
+ createdAt?: number;
+ parentCommentId?: number | null;
+ postId?: number;
+ replies?: CommentResponse[];
+ userId?: number;
+ [property: string]: any;
+}
+
+const PostDetail: React.FC = () => {
+ const [searchParams] = useSearchParams();
+ const postId = searchParams.get('postId');
+ const { refresh: getPostDetailRefresh } = useApi(() => request.get(getPostDetail + `/${postId}`), false);
+ const { refresh: getPostCommentsRefresh } = useApi(() => request.get(getPostComments + `/${postId}`), false);
+ const [post, setPost] = useState<PostResponse | null>(null);
+ const [comments, setComments] = useState<CommentResponse[]>([]);
+ const [newComment, setNewComment] = useState<string>('');
+ const [loading, setLoading] = useState<boolean>(true);
+
+ useEffect(() => {
+ console.log('postId', postId);
+ if (!postId) return;
+ const fetchData = async () => {
+ setLoading(true);
+ const res = await getPostDetailRefresh();
+ if (res == null || (res as any).error) {
+ setLoading(false);
+ return;
+ }
+ setPost(res as PostResponse);
+ await getPostCommentsRefresh();
+ setComments(res as CommentResponse[]);
+ setLoading(false);
+ };
+ fetchData();
+ }, [postId]);
+
+ if (loading) return <div className={styles.center}><Spin /></div>;
+ if (!post) return <div className={styles.center}><Empty description="未找到帖子" /></div>;
+
+ return (
+ <div className={styles.container}>
+ <div className={styles.nav}>
+ <Navbar current={post.postType} />
+ </div>
+ <div className={styles.content}>
+ <div className={styles.postDetail}>
+
+ </div >
+ <Card title={post.postTitle} className={styles.card}>
+ <Paragraph>{post.postContent}</Paragraph>
+ <div className={styles.actions}>
+ <Button type="primary" onClick={() => setNewComment('')}>评论</Button>
+ </div>
+ </Card>
+
+ <List
+ className={styles.commentList}
+ header={<Title level={4}>评论区</Title>}
+ dataSource={comments}
+ renderItem={(item) => (
+ <List.Item key={item.commentId}>
+ <List.Item.Meta
+ title={<Text strong>{item.userId}</Text>}
+ description={<Text>{item.content}</Text>}
+ />
+ </List.Item>
+ )}
+ />
+
+ <TextArea
+ rows={4}
+ value={newComment}
+ onChange={(e) => setNewComment(e.target.value)}
+ placeholder="写下你的评论..."
+ />
+ </div>
+ </div>
+ );
+};
+
+export default PostDetail;
\ No newline at end of file