| import React, { useState, useEffect, useRef } from 'react'; |
| import { getMessagesByUserIds, sendMessage } from '../api/chat'; // 替换为新API |
| |
| const ChatBox = ({ senderId, receiverId }) => { // 不再接收relationId |
| const [messages, setMessages] = useState([]); |
| const [inputContent, setInputContent] = useState(''); |
| const messagesEndRef = useRef(null); |
| |
| // 加载历史消息(改为通过用户ID获取) |
| const loadMessages = async () => { |
| try { |
| if (!senderId || !receiverId) return; |
| const data = await getMessagesByUserIds(senderId, receiverId); |
| |
| // 格式化消息:同时处理friend1(chatimformation1)和friend2(chatimformation2)的消息 |
| const formattedMessages = data.flatMap(msg => { |
| const messages = []; |
| // 处理friend1的消息(chatimformation1) |
| if (msg.chatimformation1) { |
| messages.push({ |
| content: msg.chatimformation1, |
| isSelf: msg.friend1 === senderId, // 发送方是friend1,判断是否是当前用户 |
| talkTime: msg.talkTime // 保留时间用于排序和唯一key |
| }); |
| } |
| // 处理friend2的消息(chatimformation2) |
| if (msg.chatimformation2) { |
| messages.push({ |
| content: msg.chatimformation2, |
| isSelf: msg.friend2 === senderId, // 发送方是friend2,判断是否是当前用户 |
| talkTime: msg.talkTime // 保留时间用于排序和唯一key |
| }); |
| } |
| return messages; |
| }).sort((a, b) => new Date(a.talkTime) - new Date(b.talkTime)); // 按时间升序排列 |
| |
| setMessages(formattedMessages); |
| } catch (error) { |
| console.error('加载消息失败:', error.message); |
| } |
| }; |
| |
| // 发送消息(不再需要relationId) |
| const handleSend = async () => { |
| if (!inputContent.trim()) return; |
| if (!senderId || !receiverId) { // 新增:校验用户ID有效性 |
| console.error('未获取到有效的用户ID'); |
| return; |
| } |
| |
| try { |
| const newMessage = await sendMessage({ |
| senderId, |
| receiverId, |
| content: inputContent |
| }); |
| setMessages(prev => [...prev, { content: inputContent, isSelf: true }]); |
| setInputContent(''); |
| scrollToBottom(); |
| } catch (error) { |
| console.error('发送消息失败:', error.message); |
| } |
| }; |
| |
| // 依赖改为用户ID变化时重新加载 |
| useEffect(() => { |
| if (senderId && receiverId) loadMessages(); |
| }, [senderId, receiverId]); |
| |
| const scrollToBottom = () => { |
| messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' }); |
| }; |
| |
| return ( |
| <div className="chat-box" style={{ |
| width: '400px', |
| height: '600px', |
| border: '1px solid #e5e7eb', |
| borderRadius: '8px', |
| display: 'flex', |
| flexDirection: 'column' |
| }}> |
| {/* 消息列表 */} |
| <div style={{ |
| flex: 1, |
| padding: '16px', |
| overflowY: 'auto', |
| backgroundColor: '#f3f4f6' |
| }}> |
| {/* 消息列表渲染(使用数据库唯一ID作为key) */} |
| {messages.map((msg) => ( |
| <div |
| key={msg.informationid} |
| style={{ |
| marginBottom: '12px', |
| display: 'flex', |
| justifyContent: msg.isSelf ? 'flex-end' : 'flex-start' |
| }} |
| > |
| <div |
| style={{ |
| maxWidth: '70%', |
| padding: '8px 12px', |
| borderRadius: '12px', |
| backgroundColor: msg.isSelf ? '#2563eb' : '#ffffff', |
| color: msg.isSelf ? 'white' : 'black' |
| }} |
| > |
| {msg.content} |
| </div> |
| </div> |
| ))} |
| <div ref={messagesEndRef} /> |
| </div> |
| |
| {/* 输入区域 */} |
| <div style={{ |
| padding: '16px', |
| display: 'flex', |
| gap: '8px', |
| borderTop: '1px solid #e5e7eb' |
| }}> |
| <input |
| type="text" |
| value={inputContent} |
| onChange={(e) => setInputContent(e.target.value)} |
| onKeyPress={(e) => e.key === 'Enter' && handleSend()} |
| placeholder="输入消息..." |
| style={{ |
| flex: 1, |
| padding: '8px 12px', |
| borderRadius: '6px', |
| border: '1px solid #d1d5db', |
| fontSize: '14px' |
| }} |
| /> |
| <button |
| onClick={handleSend} |
| style={{ |
| padding: '8px 16px', |
| backgroundColor: '#2563eb', |
| color: 'white', |
| border: 'none', |
| borderRadius: '6px', |
| cursor: 'pointer' |
| }} |
| > |
| 发送 |
| </button> |
| </div> |
| </div> |
| ); |
| }; |
| |
| export default ChatBox; |