刘嘉昕 | 9cdeca2 | 2025-06-03 16:54:30 +0800 | [diff] [blame^] | 1 | import React, { useState, useEffect, useRef } from 'react'; |
| 2 | import { getMessagesByUserIds, sendMessage } from '../api/chat'; // 替换为新API |
| 3 | |
| 4 | const ChatBox = ({ senderId, receiverId }) => { // 不再接收relationId |
| 5 | const [messages, setMessages] = useState([]); |
| 6 | const [inputContent, setInputContent] = useState(''); |
| 7 | const messagesEndRef = useRef(null); |
| 8 | |
| 9 | // 加载历史消息(改为通过用户ID获取) |
| 10 | const loadMessages = async () => { |
| 11 | try { |
| 12 | if (!senderId || !receiverId) return; |
| 13 | const data = await getMessagesByUserIds(senderId, receiverId); |
| 14 | |
| 15 | // 格式化消息:同时处理friend1(chatimformation1)和friend2(chatimformation2)的消息 |
| 16 | const formattedMessages = data.flatMap(msg => { |
| 17 | const messages = []; |
| 18 | // 处理friend1的消息(chatimformation1) |
| 19 | if (msg.chatimformation1) { |
| 20 | messages.push({ |
| 21 | content: msg.chatimformation1, |
| 22 | isSelf: msg.friend1 === senderId, // 发送方是friend1,判断是否是当前用户 |
| 23 | talkTime: msg.talkTime // 保留时间用于排序和唯一key |
| 24 | }); |
| 25 | } |
| 26 | // 处理friend2的消息(chatimformation2) |
| 27 | if (msg.chatimformation2) { |
| 28 | messages.push({ |
| 29 | content: msg.chatimformation2, |
| 30 | isSelf: msg.friend2 === senderId, // 发送方是friend2,判断是否是当前用户 |
| 31 | talkTime: msg.talkTime // 保留时间用于排序和唯一key |
| 32 | }); |
| 33 | } |
| 34 | return messages; |
| 35 | }).sort((a, b) => new Date(a.talkTime) - new Date(b.talkTime)); // 按时间升序排列 |
| 36 | |
| 37 | setMessages(formattedMessages); |
| 38 | } catch (error) { |
| 39 | console.error('加载消息失败:', error.message); |
| 40 | } |
| 41 | }; |
| 42 | |
| 43 | // 发送消息(不再需要relationId) |
| 44 | const handleSend = async () => { |
| 45 | if (!inputContent.trim()) return; |
| 46 | if (!senderId || !receiverId) { // 新增:校验用户ID有效性 |
| 47 | console.error('未获取到有效的用户ID'); |
| 48 | return; |
| 49 | } |
| 50 | |
| 51 | try { |
| 52 | const newMessage = await sendMessage({ |
| 53 | senderId, |
| 54 | receiverId, |
| 55 | content: inputContent |
| 56 | }); |
| 57 | setMessages(prev => [...prev, { content: inputContent, isSelf: true }]); |
| 58 | setInputContent(''); |
| 59 | scrollToBottom(); |
| 60 | } catch (error) { |
| 61 | console.error('发送消息失败:', error.message); |
| 62 | } |
| 63 | }; |
| 64 | |
| 65 | // 依赖改为用户ID变化时重新加载 |
| 66 | useEffect(() => { |
| 67 | if (senderId && receiverId) loadMessages(); |
| 68 | }, [senderId, receiverId]); |
| 69 | |
| 70 | const scrollToBottom = () => { |
| 71 | messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' }); |
| 72 | }; |
| 73 | |
| 74 | return ( |
| 75 | <div className="chat-box" style={{ |
| 76 | width: '400px', |
| 77 | height: '600px', |
| 78 | border: '1px solid #e5e7eb', |
| 79 | borderRadius: '8px', |
| 80 | display: 'flex', |
| 81 | flexDirection: 'column' |
| 82 | }}> |
| 83 | {/* 消息列表 */} |
| 84 | <div style={{ |
| 85 | flex: 1, |
| 86 | padding: '16px', |
| 87 | overflowY: 'auto', |
| 88 | backgroundColor: '#f3f4f6' |
| 89 | }}> |
| 90 | {/* 消息列表渲染(使用数据库唯一ID作为key) */} |
| 91 | {messages.map((msg) => ( |
| 92 | <div |
| 93 | key={msg.informationid} |
| 94 | style={{ |
| 95 | marginBottom: '12px', |
| 96 | display: 'flex', |
| 97 | justifyContent: msg.isSelf ? 'flex-end' : 'flex-start' |
| 98 | }} |
| 99 | > |
| 100 | <div |
| 101 | style={{ |
| 102 | maxWidth: '70%', |
| 103 | padding: '8px 12px', |
| 104 | borderRadius: '12px', |
| 105 | backgroundColor: msg.isSelf ? '#2563eb' : '#ffffff', |
| 106 | color: msg.isSelf ? 'white' : 'black' |
| 107 | }} |
| 108 | > |
| 109 | {msg.content} |
| 110 | </div> |
| 111 | </div> |
| 112 | ))} |
| 113 | <div ref={messagesEndRef} /> |
| 114 | </div> |
| 115 | |
| 116 | {/* 输入区域 */} |
| 117 | <div style={{ |
| 118 | padding: '16px', |
| 119 | display: 'flex', |
| 120 | gap: '8px', |
| 121 | borderTop: '1px solid #e5e7eb' |
| 122 | }}> |
| 123 | <input |
| 124 | type="text" |
| 125 | value={inputContent} |
| 126 | onChange={(e) => setInputContent(e.target.value)} |
| 127 | onKeyPress={(e) => e.key === 'Enter' && handleSend()} |
| 128 | placeholder="输入消息..." |
| 129 | style={{ |
| 130 | flex: 1, |
| 131 | padding: '8px 12px', |
| 132 | borderRadius: '6px', |
| 133 | border: '1px solid #d1d5db', |
| 134 | fontSize: '14px' |
| 135 | }} |
| 136 | /> |
| 137 | <button |
| 138 | onClick={handleSend} |
| 139 | style={{ |
| 140 | padding: '8px 16px', |
| 141 | backgroundColor: '#2563eb', |
| 142 | color: 'white', |
| 143 | border: 'none', |
| 144 | borderRadius: '6px', |
| 145 | cursor: 'pointer' |
| 146 | }} |
| 147 | > |
| 148 | 发送 |
| 149 | </button> |
| 150 | </div> |
| 151 | </div> |
| 152 | ); |
| 153 | }; |
| 154 | |
| 155 | export default ChatBox; |