fix-send-message
Change-Id: I43a2f333a56eea499c960b057cd796b1621c771b
diff --git a/src/pages/UserCenter/UserFriends.jsx b/src/pages/UserCenter/UserFriends.jsx
index e69de29..3aaec44 100644
--- a/src/pages/UserCenter/UserFriends.jsx
+++ b/src/pages/UserCenter/UserFriends.jsx
@@ -0,0 +1,209 @@
+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;