import { sys } from "cc"; export interface ChatMessage { role: "user" | "model"; parts: { text: string }[]; timestamp?: number; } export interface ChatHistory { roleId: number; messages: ChatMessage[]; createdAt: number; updatedAt: number; } /** * 聊天历史管理器 * 负责聊天记录的本地存储、加载和管理 */ export class ChatHistoryManager { private static _instance: ChatHistoryManager; public static get Instance(): ChatHistoryManager { if (!this._instance) { this._instance = new ChatHistoryManager(); } return this._instance; } private constructor() {} /** * 保存聊天历史到本地 * @param roleId 角色ID * @param messages 消息列表 */ public saveHistory(roleId: number, messages: ChatMessage[]): void { const key = `chat_history_${roleId}`; try { const history: ChatHistory = { roleId: roleId, messages: messages, createdAt: Date.now(), updatedAt: Date.now() }; sys.localStorage.setItem(key, JSON.stringify(history)); console.log(`Saved chat history for role ${roleId}, ${messages.length} messages`); } catch (error) { console.error(`Failed to save chat history for role ${roleId}:`, error); } } /** * 从本地加载聊天历史 * @param roleId 角色ID * @returns 消息列表,如果没有历史记录则返回空数组 */ public loadHistory(roleId: number): ChatMessage[] { const key = `chat_history_${roleId}`; try { const data = sys.localStorage.getItem(key); if (data) { const history: ChatHistory = JSON.parse(data); console.log(`Loaded chat history for role ${roleId}: ${history.messages.length} messages`); return history.messages; } } catch (error) { console.error(`Failed to load chat history for role ${roleId}:`, error); // 如果数据损坏,清除错误的数据 this.clearHistory(roleId); } return []; } /** * 清除指定角色的聊天历史 * @param roleId 角色ID */ public clearHistory(roleId: number): void { const key = `chat_history_${roleId}`; sys.localStorage.removeItem(key); console.log(`Cleared chat history for role ${roleId}`); } /** * 追加消息到历史记录 * @param roleId 角色ID * @param message 消息对象 */ public appendMessage(roleId: number, message: ChatMessage): void { const history = this.loadHistory(roleId); // 添加时间戳 message.timestamp = Date.now(); history.push(message); // 限制历史长度,保留最近100条消息 if (history.length > 100) { history.splice(0, history.length - 100); console.log(`Trimmed chat history for role ${roleId} to 100 messages`); } this.saveHistory(roleId, history); } /** * 获取指定角色的消息数量 * @param roleId 角色ID * @returns 消息数量 */ public getMessageCount(roleId: number): number { const history = this.loadHistory(roleId); return history.length; } /** * 获取最近的N条消息 * @param roleId 角色ID * @param count 消息数量 * @returns 最近的消息列表 */ public getRecentMessages(roleId: number, count: number = 10): ChatMessage[] { const history = this.loadHistory(roleId); return history.slice(-count); } /** * 清除所有聊天历史 */ public clearAllHistory(): void { // 查找所有chat_history_开头的key const keysToRemove: string[] = []; for (let i = 0; i < sys.localStorage.length; i++) { const key = sys.localStorage.key(i); if (key && key.startsWith('chat_history_')) { keysToRemove.push(key); } } // 删除找到的所有聊天历史 keysToRemove.forEach(key => { sys.localStorage.removeItem(key); }); console.log(`Cleared all chat histories, ${keysToRemove.length} records removed`); } /** * 获取所有有历史记录的角色ID列表 * @returns 角色ID数组 */ public getAllHistoryRoleIds(): number[] { const roleIds: number[] = []; for (let i = 0; i < sys.localStorage.length; i++) { const key = sys.localStorage.key(i); if (key && key.startsWith('chat_history_')) { const roleId = parseInt(key.replace('chat_history_', '')); if (!isNaN(roleId)) { roleIds.push(roleId); } } } return roleIds; } /** * 准备上传到远程服务器(预留接口) * @param roleId 角色ID */ public async syncToRemote(roleId: number): Promise { const history = this.loadHistory(roleId); if (history.length === 0) { console.log(`No history to sync for role ${roleId}`); return; } try { // TODO: 调用 HttpUnit.ins.api 上传到服务器 // await HttpUnit.ins.api("chat/save_history", { // role_id: roleId, // messages: history // }, "POST"); console.log(`Ready to sync ${history.length} messages for role ${roleId} to remote server`); } catch (error) { console.error(`Failed to sync history for role ${roleId}:`, error); } } /** * 从远程服务器下载历史(预留接口) * @param roleId 角色ID */ public async syncFromRemote(roleId: number): Promise { try { // TODO: 调用 HttpUnit.ins.api 从服务器获取历史 // const response = await HttpUnit.ins.api("chat/get_history", { // role_id: roleId // }, "GET"); // if (response && response.messages) { // this.saveHistory(roleId, response.messages); // console.log(`Synced ${response.messages.length} messages from remote for role ${roleId}`); // } console.log(`Ready to sync history from remote server for role ${roleId}`); } catch (error) { console.error(`Failed to sync from remote for role ${roleId}:`, error); } } }