Files
18xchat/assets/Scripts/chat18x/core/ChatController.ts
T

250 lines
6.6 KiB
TypeScript
Raw Normal View History

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<string | null> AI的回复,失败时返回null
*/
public async sendMessage(message: string): Promise<string | null> {
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);
}
}