diff --git a/frontend/src/pages/ForumDetail.jsx b/frontend/src/pages/ForumDetail.jsx
index a944022..8b286ff 100644
--- a/frontend/src/pages/ForumDetail.jsx
+++ b/frontend/src/pages/ForumDetail.jsx
@@ -2,7 +2,7 @@ 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, Grid } from 'antd';
import { UserOutlined, ClockCircleOutlined, EyeOutlined, CheckCircleFilled, LeftOutlined, UploadOutlined, EditOutlined } from '@ant-design/icons';
-import { getTopicDetail, createReply, uploadMedia } from '../api';
+import { getTopicDetail, createReply, uploadMedia, getStarUsers } from '../api';
import { useAuth } from '../context/AuthContext';
import LoginModal from '../components/LoginModal';
import CreateTopicModal from '../components/CreateTopicModal';
@@ -41,6 +41,9 @@ const ForumDetail = () => {
const [replyUploading, setReplyUploading] = useState(false);
const [replyMediaIds, setReplyMediaIds] = useState([]);
+ // Star Users State
+ const [starUsers, setStarUsers] = useState([]);
+
const fetchTopic = async () => {
try {
const res = await getTopicDetail(id);
@@ -53,14 +56,31 @@ const ForumDetail = () => {
}
};
+ const fetchStarUsers = async () => {
+ try {
+ const res = await getStarUsers();
+ setStarUsers(res.data || []);
+ } catch (error) {
+ console.error('Fetch star users failed', error);
+ }
+ };
+
const hasFetched = React.useRef(false);
useEffect(() => {
if (!hasFetched.current) {
fetchTopic();
+ fetchStarUsers();
hasFetched.current = true;
}
}, [id]);
+ const handleReplyToUser = (nickname) => {
+ const mentionText = `@${nickname} `;
+ setReplyContent(prev => prev + mentionText);
+ // Focus logic if needed, but simple append works
+ message.info(`已添加 @${nickname}`);
+ };
+
const handleSubmitReply = async () => {
if (!user) {
setLoginModalVisible(true);
@@ -272,6 +292,14 @@ const ForumDetail = () => {
{reply.author_info?.nickname}
{new Date(reply.created_at).toLocaleString()}
+
#{index + 1}
@@ -308,6 +336,25 @@ const ForumDetail = () => {
placeholder="友善回复,分享你的见解... (支持 Markdown)"
style={{ marginBottom: 16, background: '#111', border: '1px solid #333', color: '#fff' }}
/>
+
+ {starUsers.length > 0 && (
+
+ @技术专家:
+
+ {starUsers.map(user => (
+ handleReplyToUser(user.nickname)}
+ >
+ {user.nickname}
+
+ ))}
+
+
+ )}
+
{
const [sending, setSending] = useState(false)
const [htmlContent, setHtmlContent] = useState('')
const [userInfo, setUserInfo] = useState(null)
+
+ // Star Users & Mention
+ const [starUsers, setStarUsers] = useState([])
+ const [showStarUsers, setShowStarUsers] = useState(false)
const fetchDetail = async () => {
try {
@@ -38,12 +42,24 @@ const ForumDetail = () => {
}
}
+ const fetchStarUsers = async () => {
+ try {
+ const res = await getStarUsers()
+ // API might return array directly or { data: [] }
+ const users = Array.isArray(res) ? res : (res.data || [])
+ setStarUsers(users)
+ } catch (error) {
+ console.error('Fetch star users failed', error)
+ }
+ }
+
useEffect(() => {
const info = Taro.getStorageSync('userInfo')
if (info) setUserInfo(info)
if (id) {
fetchDetail()
+ fetchStarUsers()
}
}, [id])
@@ -53,6 +69,12 @@ const ForumDetail = () => {
}
})
+ const handleReplyToUser = (nickname) => {
+ const mentionText = `@${nickname} `
+ setReplyContent(prev => prev + mentionText)
+ setShowStarUsers(false)
+ }
+
useShareAppMessage(() => {
return {
title: topic?.title || '技术社区',
@@ -199,7 +221,12 @@ const ForumDetail = () => {
{reply.author_info?.nickname}
#{idx + 1} • {new Date(reply.created_at).toLocaleDateString()}
-
+
+ handleReplyToUser(reply.author_info?.nickname)} style={{marginRight: 10, padding: '2px 6px', background: '#f0f0f0', borderRadius: 4}}>
+ 回复
+
+
+
{/* Simple markdown render for replies or just text if complex */}
@@ -216,6 +243,9 @@ const ForumDetail = () => {
+ setShowStarUsers(true)} style={{marginLeft: 0}}>
+
+
{
{sending ? : 发送}
+
+ setShowStarUsers(false)} onClose={() => setShowStarUsers(false)}>
+ {starUsers.map(user => (
+ handleReplyToUser(user.nickname)}>
+
+
+ {user.nickname}
+ ({user.title || '专家'})
+
+
+ ))}
+
)
}