blob: 3aaec44eb4106bf0ba467ccbac0a8183445beb36 [file] [log] [blame]
import React, { useEffect, useState } from 'react';
import axios from 'axios';
import UserNav from './UserNav';
import Header from '../../components/Header';
import './UserFriends.css';
import { useUser } from '../../context/UserContext';
const UserFriends = () => {
const { user, loading } = useUser();
const [friends, setFriends] = useState([]);
const [error, setError] = useState(null);
// 私信相关状态
const [chatOpen, setChatOpen] = useState(false);
const [chatFriend, setChatFriend] = useState(null);
const [messageContent, setMessageContent] = useState('');
const [sendingStatus, setSendingStatus] = useState(null);
// 新增:聊天记录
const [chatMessages, setChatMessages] = useState([]);
const [loadingMessages, setLoadingMessages] = useState(false);
const [messagesError, setMessagesError] = useState(null);
useEffect(() => {
if (loading) return;
const fetchFriends = async () => {
if (!user || !user.userId) {
setError('未登录或用户信息缺失');
return;
}
try {
const res = await axios.get(`/echo/user/${user.userId}/friends`);
setFriends(res.data || []);
setError(null);
} catch (err) {
setError('加载好友失败,请稍后再试');
}
};
fetchFriends();
}, [user, loading]);
// 打开聊天框时加载聊天记录
const openChat = async (friend) => {
setChatFriend(friend);
setMessageContent('');
setSendingStatus(null);
setChatMessages([]);
setMessagesError(null);
setChatOpen(true);
if (!user || !user.userId) return;
setLoadingMessages(true);
try {
const res = await axios.get(`/echo/message/${user.userId}/getUserMessages`);
if (res.data.status === 'success') {
// 过滤出和这个好友的聊天消息(发或收都算)
const allMessages = res.data.messages || [];
const related = allMessages.filter(m =>
(m.sender_id === user.userId && m.receiver_id === friend.id) ||
(m.sender_id === friend.id && m.receiver_id === user.userId)
);
// 按时间排序(升序)
related.sort((a, b) => new Date(a.timestamp) - new Date(b.timestamp));
setChatMessages(related);
} else {
setMessagesError('无法加载聊天记录');
}
} catch (err) {
setMessagesError('加载聊天记录失败,请稍后再试');
} finally {
setLoadingMessages(false);
}
};
const closeChat = () => {
setChatOpen(false);
setChatFriend(null);
setMessageContent('');
setSendingStatus(null);
setChatMessages([]);
setMessagesError(null);
};
const sendMessage = async () => {
if (!messageContent.trim()) {
setSendingStatus('消息不能为空');
return;
}
setSendingStatus('发送中...');
try {
const res = await axios.post('/echo/message/sendMessages', {
sender_id: user.userId,
receiver_id: chatFriend.id,
content: messageContent.trim(),
});
if (res.data.status === 'success') {
setSendingStatus('发送成功');
setMessageContent('');
// 发送成功后,将这条消息追加到聊天记录
const newMsg = {
message_id: res.data.message_id,
sender_id: user.userId,
sender_username: user.username || '我',
receiver_id: chatFriend.id,
receiver_username: chatFriend.nickname,
content: messageContent.trim(),
timestamp: new Date().toISOString(),
};
setChatMessages(prev => [...prev, newMsg]);
} else {
setSendingStatus(res.data.message || '发送失败');
}
} catch (err) {
setSendingStatus('发送失败,请稍后再试');
}
};
if (loading) return <p>正在加载...</p>;
if (error) return <p className="error">{error}</p>;
return (
<div className="user-friends-container">
<Header />
<div className="user-center">
<div className="user-nav-container">
<UserNav />
</div>
<div className="common-card">
<h2>我的好友</h2>
<div className="friends-list">
{friends.length === 0 && <p>暂无好友</p>}
{friends.map((friend) => (
<div key={friend.id} className="friend-card">
<img src={friend.avatar} alt={friend.nickname} className="friend-avatar" />
<div className="friend-info">
<p><strong>{friend.nickname}</strong></p>
<p>{friend.email}</p>
<button
className="send-message-btn"
onClick={() => openChat(friend)}
>
发送私信
</button>
</div>
</div>
))}
</div>
</div>
</div>
{/* 私信弹窗 */}
{chatOpen && (
<div className="chat-modal">
<div className="chat-modal-content">
<h3> {chatFriend.nickname} 发送私信</h3>
<div className="chat-messages" style={{height: '250px', overflowY: 'auto', border: '1px solid #ccc', padding: '8px', marginBottom: '8px'}}>
{loadingMessages && <p>加载聊天记录中...</p>}
{messagesError && <p className="error">{messagesError}</p>}
{!loadingMessages && chatMessages.length === 0 && <p>暂无聊天记录</p>}
{chatMessages.map(msg => (
<div
key={msg.message_id}
style={{
textAlign: msg.sender_id === user.userId ? 'right' : 'left',
marginBottom: '8px'
}}
>
<div style={{
display: 'inline-block',
backgroundColor: msg.sender_id === user.userId ? '#409eff' : '#f0f0f0',
color: msg.sender_id === user.userId ? 'white' : 'black',
borderRadius: '10px',
padding: '6px 12px',
maxWidth: '70%',
wordBreak: 'break-word'
}}>
<p style={{margin: 0}}>{msg.content}</p>
<small style={{fontSize: '10px', opacity: 0.7}}>
{new Date(msg.timestamp).toLocaleString()}
</small>
</div>
</div>
))}
</div>
<textarea
rows="3"
value={messageContent}
onChange={(e) => setMessageContent(e.target.value)}
placeholder="输入消息内容"
style={{width: '100%', marginBottom: '8px'}}
/>
<div className="chat-actions">
<button onClick={sendMessage}>发送</button>
<button onClick={closeChat}>关闭</button>
</div>
{sendingStatus && <p className="status-msg">{sendingStatus}</p>}
</div>
<div className="chat-modal-backdrop" onClick={closeChat}></div>
</div>
)}
</div>
);
};
export default UserFriends;