import { ChatAIService } from "./ChatAIService"; import { EmotionAIService } from "./EmotionAIService"; import { DialogManager } from "../manager/DialogManager"; import { VideoEmotion } from "../../schema/schema"; import ConfigManager from "../manager/ConfigManager"; import { ErrorHandler, ErrorType } from "../utils/ErrorHandler"; /** * 聊天控制器接口 - 定义Panel和Controller之间的通信协议 */ export interface IChatPanelCallback { /** * 消息发送开始回调 * @param message 用户发送的消息 */ onMessageSent(message: string): void; /** * 接收到AI回复回调 * @param response AI的回复内容 */ onMessageReceived(response: string): void; /** * 情绪状态更新回调 * @param emotion 更新后的情绪状态 */ onEmotionUpdated(emotion: VideoEmotion): void; /** * 对话更新回调 */ onDialogUpdated(): void; /** * 错误处理回调 * @param error 错误信息 */ onError(error: Error): void; } /** * 聊天控制器类 * * 负责处理聊天相关的所有业务逻辑,包括: * - 角色数据管理 * - 消息发送和接收 * - 情绪状态管理 * - 与AI服务的交互 * - 对话历史管理 * * @example * ```typescript * const controller = new ChatController(); * controller.initialize(10001, panelCallback); * const response = await controller.sendMessage("Hello"); * ``` */ export class ChatController { private roleId: number | null = null; private callback: IChatPanelCallback | null = null; private dialogManager: DialogManager | null = null; /** * 初始化聊天控制器 * @param roleId 角色ID * @param callback 回调接口实现 */ public initialize(roleId: number, callback: IChatPanelCallback): void { this.roleId = roleId; this.callback = callback; this.dialogManager = DialogManager.getInstance(); // 设置当前聊天的角色ID if (roleId && roleId > 0) { ChatAIService.Instance.setCurrentRole(roleId); console.log(`ChatController initialized with role ${roleId}`); } else { const error = new Error(`Invalid roleId: ${roleId}`); this.handleError(error); } } /** * 发送消息给AI并处理回复 * @param message 用户消息内容 * @returns Promise AI的回复,失败时返回null */ public async sendMessage(message: string): Promise { if (!this.validateSendMessage(message)) { return null; } try { // 通知界面消息发送开始 this.callback?.onMessageSent(message); // 更新对话显示 - 用户消息 this.dialogManager?.updateDialog(true, message, true); this.callback?.onDialogUpdated(); console.log(`Sending message to role ${this.roleId}: ${message}`); // 发送消息给AI服务 const response = await ChatAIService.Instance.sendMessage(this.roleId!, message); if (response) { // 更新对话显示 - AI回复 this.dialogManager?.updateDialog(false, response); this.callback?.onDialogUpdated(); // 通知界面收到回复 this.callback?.onMessageReceived(response); // 获取更新后的情绪状态 try { const currentEmotion = EmotionAIService.Instance.getCurrentEmotion(this.roleId!); console.log(`Current emotion for role ${this.roleId}: ${VideoEmotion[currentEmotion]}`); // 通知界面情绪更新 this.callback?.onEmotionUpdated(currentEmotion); } catch (emotionError) { console.warn("Failed to get current emotion:", emotionError); // 情绪获取失败不影响聊天功能 } console.log(`Response received from role ${this.roleId}: ${response}`); return response; } else { const error = new Error("AI返回了空响应"); this.handleError(error); return null; } } catch (error) { ErrorHandler.Instance.handleApiError(error, "ChatController.sendMessage", { roleId: this.roleId, message: message.substring(0, 100) + "..." }); this.handleError(error as Error); return null; } } /** * 获取当前角色的情绪状态 * @returns VideoEmotion 当前情绪状态 */ public getCurrentEmotion(): VideoEmotion { if (!this.roleId) { return VideoEmotion.calm_down; } return EmotionAIService.Instance.getCurrentEmotion(this.roleId); } /** * 获取当前角色数据 * @returns 角色数据对象,失败时返回null */ public getRoleData(): any { if (!this.roleId) { return null; } try { const roleData = ConfigManager.tables.TbGirls.get(this.roleId); const roleDetail = ConfigManager.tables.TbGirlsDetail.get(this.roleId); return { basic: roleData, detail: roleDetail }; } catch (error) { console.error(`Failed to get role data for ${this.roleId}:`, error); this.handleError(error as Error); return null; } } /** * 清除当前角色的聊天历史 */ public clearChatHistory(): void { if (!this.roleId) { console.warn("Cannot clear history: roleId is null"); return; } try { ChatAIService.Instance.clearChatHistory(this.roleId); console.log(`Chat history cleared for role ${this.roleId}`); } catch (error) { console.error("Failed to clear chat history:", error); this.handleError(error as Error); } } /** * 获取当前角色ID * @returns 当前角色ID */ public getCurrentRoleId(): number | null { return this.roleId; } /** * 销毁控制器,清理资源 */ public destroy(): void { this.roleId = null; this.callback = null; this.dialogManager = null; console.log("ChatController destroyed"); } /** * 验证发送消息的参数 * @param message 消息内容 * @returns 验证是否通过 */ private validateSendMessage(message: string): boolean { if (!this.roleId || this.roleId <= 0) { const error = new Error("角色ID无效"); this.handleError(error); return false; } if (!message || message.trim() === "") { const error = new Error("消息内容不能为空"); this.handleError(error); return false; } if (!this.callback) { const error = new Error("回调接口未设置"); this.handleError(error); return false; } return true; } /** * 统一错误处理 * @param error 错误对象 */ private handleError(error: Error): void { console.error("ChatController error:", error); this.callback?.onError(error); } }