移动端
All checks were successful
Deploy to Server / deploy (push) Successful in 37s

This commit is contained in:
jeremygan2021
2026-02-24 16:09:07 +08:00
parent 76ce1225ec
commit fd33201793
6 changed files with 214 additions and 71 deletions

View File

@@ -1,6 +1,6 @@
import React, { useState, useEffect } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { Typography, Card, Avatar, Tag, Space, Button, Divider, Input, message, Upload, Tooltip } from 'antd';
import { Typography, Card, Avatar, Tag, Space, Button, Divider, Input, message, Upload, Tooltip, Grid } from 'antd';
import { UserOutlined, ClockCircleOutlined, EyeOutlined, CheckCircleFilled, LeftOutlined, UploadOutlined, EditOutlined } from '@ant-design/icons';
import { getTopicDetail, createReply, uploadMedia } from '../api';
import { useAuth } from '../context/AuthContext';
@@ -17,11 +17,14 @@ import 'katex/dist/katex.min.css';
const { Title, Text } = Typography;
const { TextArea } = Input;
const { useBreakpoint } = Grid;
const ForumDetail = () => {
const { id } = useParams();
const navigate = useNavigate();
const { user } = useAuth();
const screens = useBreakpoint();
const isMobile = !screens.md;
const [loading, setLoading] = useState(true);
const [topic, setTopic] = useState(null);
@@ -156,7 +159,7 @@ const ForumDetail = () => {
};
return (
<div style={{ padding: '80px 20px 40px', minHeight: '100vh', maxWidth: 1000, margin: '0 auto' }}>
<div style={{ padding: isMobile ? '60px 10px 20px' : '80px 20px 40px', minHeight: '100vh', maxWidth: 1000, margin: '0 auto' }}>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 20 }}>
<Button
type="text"
@@ -167,21 +170,15 @@ const ForumDetail = () => {
返回列表
</Button>
{/* Debug Info: Remove in production */}
{/* <div style={{ color: 'red', fontSize: 10 }}>
User ID: {user?.id} ({typeof user?.id})<br/>
Topic Author: {topic.author} ({typeof topic.author})<br/>
Match: {String(topic.author) === String(user?.id) ? 'Yes' : 'No'}
</div> */}
{user && String(topic.author) === String(user.id) && (
<Button
type="primary"
ghost
icon={<EditOutlined />}
onClick={() => setEditModalVisible(true)}
size={isMobile ? 'small' : 'middle'}
>
编辑帖子
{isMobile ? '编辑' : '编辑帖子'}
</Button>
)}
</div>
@@ -194,17 +191,17 @@ const ForumDetail = () => {
backdropFilter: 'blur(10px)',
marginBottom: 30
}}
styles={{ body: { padding: '30px' } }}
styles={{ body: { padding: isMobile ? '15px' : '30px' } }}
>
<div style={{ marginBottom: 20 }}>
{topic.is_pinned && <Tag color="red" style={{ marginRight: 10 }}>置顶</Tag>}
{topic.product_info && <Tag color="blue">{topic.product_info.name}</Tag>}
<Title level={2} style={{ color: '#fff', margin: '10px 0' }}>{topic.title}</Title>
<Title level={isMobile ? 3 : 2} style={{ color: '#fff', margin: '10px 0', wordBreak: 'break-word' }}>{topic.title}</Title>
<Space size="large" style={{ color: '#888', marginTop: 10 }}>
<Space size={isMobile ? 'small' : 'large'} style={{ color: '#888', marginTop: 10, flexWrap: 'wrap' }}>
<Space>
<Avatar src={topic.author_info?.avatar_url} icon={<UserOutlined />} />
<span style={{ color: '#ccc' }}>{topic.author_info?.nickname}</span>
<Avatar src={topic.author_info?.avatar_url} icon={<UserOutlined />} size={isMobile ? 'small' : 'default'} />
<span style={{ color: '#ccc', fontSize: isMobile ? 12 : 14 }}>{topic.author_info?.nickname}</span>
{topic.is_verified_owner && (
<Tooltip title="已验证购买过相关产品">
<CheckCircleFilled style={{ color: '#00b96b' }} />
@@ -213,11 +210,11 @@ const ForumDetail = () => {
</Space>
<Space>
<ClockCircleOutlined />
<span>{new Date(topic.created_at).toLocaleString()}</span>
<span style={{ fontSize: isMobile ? 12 : 14 }}>{new Date(topic.created_at).toLocaleString()}</span>
</Space>
<Space>
<EyeOutlined />
<span>{topic.view_count} 阅读</span>
<span style={{ fontSize: isMobile ? 12 : 14 }}>{topic.view_count} 阅读</span>
</Space>
</Space>
</div>
@@ -253,7 +250,7 @@ const ForumDetail = () => {
{/* Replies List */}
<div style={{ marginBottom: 30 }}>
<Title level={4} style={{ color: '#fff', marginBottom: 20 }}>
<Title level={isMobile ? 5 : 4} style={{ color: '#fff', marginBottom: 20 }}>
{topic.replies?.length || 0} 条回复
</Title>
@@ -266,18 +263,19 @@ const ForumDetail = () => {
marginBottom: 16,
borderRadius: 8
}}
styles={{ body: { padding: isMobile ? '15px' : '24px' } }}
>
<div style={{ display: 'flex', gap: 16 }}>
<Avatar src={reply.author_info?.avatar_url} icon={<UserOutlined />} />
<div style={{ display: 'flex', gap: isMobile ? 10 : 16 }}>
<Avatar src={reply.author_info?.avatar_url} icon={<UserOutlined />} size={isMobile ? 'small' : 'default'} />
<div style={{ flex: 1 }}>
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 8 }}>
<Space>
<Text style={{ color: '#aaa', fontWeight: 'bold' }}>{reply.author_info?.nickname}</Text>
<Space size={isMobile ? 'small' : 'middle'} align="center">
<Text style={{ color: '#aaa', fontWeight: 'bold', fontSize: isMobile ? 13 : 14 }}>{reply.author_info?.nickname}</Text>
<Text style={{ color: '#666', fontSize: 12 }}>{new Date(reply.created_at).toLocaleString()}</Text>
</Space>
<Text style={{ color: '#444' }}>#{index + 1}</Text>
<Text style={{ color: '#444', fontSize: 12 }}>#{index + 1}</Text>
</div>
<div style={{ color: '#eee' }}>
<div style={{ color: '#eee', fontSize: isMobile ? 14 : 16 }}>
<ReactMarkdown
remarkPlugins={[remarkMath, remarkGfm]}
rehypePlugins={[rehypeKatex, rehypeRaw]}
@@ -298,6 +296,7 @@ const ForumDetail = () => {
background: 'rgba(20,20,20,0.8)',
border: '1px solid rgba(255,255,255,0.1)'
}}
styles={{ body: { padding: isMobile ? '15px' : '24px' } }}
>
<Title level={5} style={{ color: '#fff', marginBottom: 16 }}>发表回复</Title>
{user ? (
@@ -309,7 +308,7 @@ const ForumDetail = () => {
placeholder="友善回复,分享你的见解... (支持 Markdown)"
style={{ marginBottom: 16, background: '#111', border: '1px solid #333', color: '#fff' }}
/>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<div style={{ display: 'flex', flexDirection: isMobile ? 'column' : 'row', justifyContent: 'space-between', alignItems: isMobile ? 'stretch' : 'center', gap: isMobile ? 10 : 0 }}>
<Upload
beforeUpload={handleReplyUpload}
showUploadList={false}
@@ -321,14 +320,15 @@ const ForumDetail = () => {
style={{
color: '#fff',
background: 'rgba(255,255,255,0.1)',
border: '1px solid rgba(255,255,255,0.2)'
border: '1px solid rgba(255,255,255,0.2)',
width: isMobile ? '100%' : 'auto'
}}
>
插入图片/视频
</Button>
</Upload>
<Button type="primary" onClick={handleSubmitReply} loading={submitting}>
<Button type="primary" onClick={handleSubmitReply} loading={submitting} style={{ width: isMobile ? '100%' : 'auto' }}>
提交回复
</Button>
</div>