diff --git a/src/family/pages/InteractionHistory.tsx b/src/family/pages/InteractionHistory.tsx new file mode 100644 index 0000000..a082807 --- /dev/null +++ b/src/family/pages/InteractionHistory.tsx @@ -0,0 +1,258 @@ +import React, { useState, useEffect } from 'react'; +import { Bot, User, RefreshCw } from 'lucide-react'; + +/** + * 聊天记录页面 + * 展示老人与数字人的聊天对话内容 + */ + +interface ChatMessage { + username: string; + is_adopted: number; + type: 'fay' | 'member'; + way: string; + content: string; + createtime: number; + timetext: string; +} + +const API_BASE_URL = 'http://127.0.0.1:5000'; + +export const InteractionHistory: React.FC = () => { + const [messages, setMessages] = useState([]); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + const username = 'User'; // 实际使用时从用户上下文获取 + + // 加载聊天记录 + const loadChatHistory = async () => { + try { + setLoading(true); + setError(null); + + const response = await fetch(`${API_BASE_URL}/api/get-msg`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ username, limit: 100 }), + }); + + if (!response.ok) { + throw new Error('获取聊天记录失败'); + } + + const data = await response.json(); + // 按时间倒序排列,最新的在前面 + const sortedMessages = (data.list || []).sort( + (a: ChatMessage, b: ChatMessage) => b.createtime - a.createtime + ); + setMessages(sortedMessages); + } catch (err) { + console.error('加载聊天记录失败:', err); + setError('无法连接到数字人服务'); + } finally { + setLoading(false); + } + }; + + useEffect(() => { + loadChatHistory(); + // 每30秒刷新一次 + const interval = setInterval(loadChatHistory, 30000); + return () => clearInterval(interval); + }, []); + + // 格式化时间戳 + const formatTime = (timestamp: number) => { + const date = new Date(timestamp * 1000); + const now = new Date(); + const isToday = date.toDateString() === now.toDateString(); + + const timeStr = date.toLocaleTimeString('zh-CN', { + hour: '2-digit', + minute: '2-digit', + }); + + if (isToday) { + return timeStr; + } + + const yesterday = new Date(now); + yesterday.setDate(yesterday.getDate() - 1); + if (date.toDateString() === yesterday.toDateString()) { + return `昨天 ${timeStr}`; + } + + return date.toLocaleDateString('zh-CN', { + month: '2-digit', + day: '2-digit', + }) + ' ' + timeStr; + }; + + // 按日期分组消息 + const groupMessagesByDate = (msgs: ChatMessage[]) => { + const groups: { [key: string]: ChatMessage[] } = {}; + + msgs.forEach(msg => { + const date = new Date(msg.createtime * 1000); + const now = new Date(); + const isToday = date.toDateString() === now.toDateString(); + + const yesterday = new Date(now); + yesterday.setDate(yesterday.getDate() - 1); + const isYesterday = date.toDateString() === yesterday.toDateString(); + + let dateKey: string; + if (isToday) { + dateKey = '今天'; + } else if (isYesterday) { + dateKey = '昨天'; + } else { + dateKey = date.toLocaleDateString('zh-CN', { + month: '2-digit', + day: '2-digit', + }); + } + + if (!groups[dateKey]) { + groups[dateKey] = []; + } + groups[dateKey].push(msg); + }); + + return groups; + }; + + const groupedMessages = groupMessagesByDate(messages); + + // 显示加载状态 + if (loading && messages.length === 0) { + return ( +
+
+
+

正在加载聊天记录...

+
+
+ ); + } + + return ( +
+
+ {/* 顶部标题和刷新按钮 */} +
+

聊天记录

+ +
+ + {/* 统计卡片 */} +
+
+
{messages.length}
+
消息总数
+
+
+
+ {messages.filter(m => m.type === 'member').length} +
+
老人发言
+
+
+ + {/* 错误提示 */} + {error && ( +
+

{error}

+
+ )} + + {/* 聊天记录列表 */} + {Object.keys(groupedMessages).length > 0 ? ( + Object.entries(groupedMessages).map(([dateKey, msgs]) => ( +
+ {/* 日期分隔 */} +
+ + {dateKey} + +
+ + {/* 消息列表 - 按时间正序显示 */} +
+ {[...msgs].reverse().map((msg, index) => ( +
+ {/* 头像 */} +
+ {msg.type === 'fay' ? ( + + ) : ( + + )} +
+ + {/* 消息气泡 */} +
+
+

+ {msg.content} +

+
+
+ + {formatTime(msg.createtime)} + +
+
+
+ ))} +
+
+ )) + ) : ( +
+ +

暂无聊天记录

+
+ )} +
+
+ ); +};