fix chatmodel
This commit is contained in:
@@ -49,14 +49,14 @@ export interface IChatPanelCallback {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 聊天控制器类 (MVP中的Presenter) - 单例模式
|
* 聊天控制器类 (MVP中的Presenter) - 单例模式
|
||||||
*
|
*
|
||||||
* 负责处理聊天相关的业务逻辑协调,包括:
|
* 负责处理聊天相关的业务逻辑协调,包括:
|
||||||
* - 协调Model和View之间的交互
|
* - 协调Model和View之间的交互
|
||||||
* - 处理用户交互和业务逻辑
|
* - 处理用户交互和业务逻辑
|
||||||
* - 管理AI服务调用
|
* - 管理AI服务调用
|
||||||
* - 处理情绪状态更新
|
* - 处理情绪状态更新
|
||||||
* - 错误处理和状态管理
|
* - 错误处理和状态管理
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```typescript
|
* ```typescript
|
||||||
* const controller = ChatController.Instance;
|
* const controller = ChatController.Instance;
|
||||||
@@ -115,12 +115,14 @@ export class ChatController {
|
|||||||
* 初始化聊天控制器
|
* 初始化聊天控制器
|
||||||
* @param roleId 角色ID
|
* @param roleId 角色ID
|
||||||
*/
|
*/
|
||||||
public initialize(roleId: number): void {
|
public initialize(categoryId: string, roleId: number): void {
|
||||||
this.dialogManager = DialogManager.getInstance();
|
this.dialogManager = DialogManager.getInstance();
|
||||||
|
|
||||||
// 初始化或切换到指定角色
|
// 初始化或切换到指定角色
|
||||||
if (!this.chatModel.initializeRole(roleId)) {
|
if (!this.chatModel.initializeRole(categoryId, roleId)) {
|
||||||
const error = new Error(`Failed to initialize ChatModel with roleId: ${roleId}`);
|
const error = new Error(
|
||||||
|
`Failed to initialize ChatModel with roleId: ${roleId}`
|
||||||
|
);
|
||||||
this.handleError(error);
|
this.handleError(error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -128,13 +130,13 @@ export class ChatController {
|
|||||||
// 设置当前聊天的角色ID到AI服务
|
// 设置当前聊天的角色ID到AI服务
|
||||||
if (roleId && roleId > 0) {
|
if (roleId && roleId > 0) {
|
||||||
ChatAIService.Instance.setCurrentRole(roleId);
|
ChatAIService.Instance.setCurrentRole(roleId);
|
||||||
|
|
||||||
// 从ChatHistoryManager加载对话记录到ChatModel中
|
// 从ChatHistoryManager加载对话记录到ChatModel中
|
||||||
this.loadDialogsFromHistory(roleId);
|
this.loadDialogsFromHistory(roleId);
|
||||||
|
|
||||||
// 同步到DialogManager
|
// 同步到DialogManager
|
||||||
this.syncDialogData();
|
this.syncDialogData();
|
||||||
|
|
||||||
console.log(`ChatController initialized with role ${roleId}`);
|
console.log(`ChatController initialized with role ${roleId}`);
|
||||||
} else {
|
} else {
|
||||||
const error = new Error(`Invalid roleId: ${roleId}`);
|
const error = new Error(`Invalid roleId: ${roleId}`);
|
||||||
@@ -147,21 +149,21 @@ export class ChatController {
|
|||||||
* @param roleId 角色ID
|
* @param roleId 角色ID
|
||||||
* @returns 是否切换成功
|
* @returns 是否切换成功
|
||||||
*/
|
*/
|
||||||
public switchRole(roleId: number): boolean {
|
public switchRole(categoryId: string, roleId: number): boolean {
|
||||||
if (!this.chatModel.switchToRole(roleId)) {
|
if (!this.chatModel.switchToRole(categoryId, roleId)) {
|
||||||
console.error(`Failed to switch to role ${roleId}`);
|
console.error(`Failed to switch to role ${roleId}`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新AI服务的当前角色
|
// 更新AI服务的当前角色
|
||||||
ChatAIService.Instance.setCurrentRole(roleId);
|
ChatAIService.Instance.setCurrentRole(roleId);
|
||||||
|
|
||||||
// 从ChatHistoryManager加载对话记录到ChatModel中
|
// 从ChatHistoryManager加载对话记录到ChatModel中
|
||||||
this.loadDialogsFromHistory(roleId);
|
this.loadDialogsFromHistory(roleId);
|
||||||
|
|
||||||
// 同步对话数据到DialogManager
|
// 同步对话数据到DialogManager
|
||||||
this.syncDialogData();
|
this.syncDialogData();
|
||||||
|
|
||||||
console.log(`ChatController switched to role ${roleId}`);
|
console.log(`ChatController switched to role ${roleId}`);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -205,12 +207,15 @@ export class ChatController {
|
|||||||
console.log(`Sending message to role ${roleId}: ${message}`);
|
console.log(`Sending message to role ${roleId}: ${message}`);
|
||||||
|
|
||||||
// 发送消息给AI服务
|
// 发送消息给AI服务
|
||||||
const response = await ChatAIService.Instance.sendMessage(roleId, message);
|
const response = await ChatAIService.Instance.sendMessage(
|
||||||
|
roleId,
|
||||||
|
message
|
||||||
|
);
|
||||||
|
|
||||||
if (response) {
|
if (response) {
|
||||||
// 移除加载中的对话
|
// 移除加载中的对话
|
||||||
this.dialogManager?.removeLoadingDialog();
|
this.dialogManager?.removeLoadingDialog();
|
||||||
|
|
||||||
// 添加AI回复到模型 (保持完整消息)
|
// 添加AI回复到模型 (保持完整消息)
|
||||||
this.chatModel.addDialog(false, response);
|
this.chatModel.addDialog(false, response);
|
||||||
|
|
||||||
@@ -222,7 +227,7 @@ export class ChatController {
|
|||||||
this.callback?.onMessageReceived(response);
|
this.callback?.onMessageReceived(response);
|
||||||
|
|
||||||
// 增加聊天次数计数
|
// 增加聊天次数计数
|
||||||
this.chatModel.incrementChatCount();
|
//this.chatModel.incrementChatCount();
|
||||||
|
|
||||||
// 注意:情绪状态将通过异步事件更新,不在这里同步获取
|
// 注意:情绪状态将通过异步事件更新,不在这里同步获取
|
||||||
|
|
||||||
@@ -231,7 +236,7 @@ export class ChatController {
|
|||||||
} else {
|
} else {
|
||||||
// 移除加载中的对话
|
// 移除加载中的对话
|
||||||
this.dialogManager?.removeLoadingDialog();
|
this.dialogManager?.removeLoadingDialog();
|
||||||
|
|
||||||
const error = new Error("AI返回了空响应");
|
const error = new Error("AI返回了空响应");
|
||||||
this.handleError(error);
|
this.handleError(error);
|
||||||
return false;
|
return false;
|
||||||
@@ -239,11 +244,15 @@ export class ChatController {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
// 移除加载中的对话
|
// 移除加载中的对话
|
||||||
this.dialogManager?.removeLoadingDialog();
|
this.dialogManager?.removeLoadingDialog();
|
||||||
|
|
||||||
ErrorHandler.Instance.handleApiError(error, "ChatController.sendMessage", {
|
ErrorHandler.Instance.handleApiError(
|
||||||
roleId: this.chatModel.getCurrentRoleId(),
|
error,
|
||||||
message: message.substring(0, 100) + "..."
|
"ChatController.sendMessage",
|
||||||
});
|
{
|
||||||
|
roleId: this.chatModel.getCurrentRoleId(),
|
||||||
|
message: message.substring(0, 100) + "...",
|
||||||
|
}
|
||||||
|
);
|
||||||
this.handleError(error as Error);
|
this.handleError(error as Error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -257,27 +266,6 @@ export class ChatController {
|
|||||||
return this.chatModel.getCurrentEmotion();
|
return this.chatModel.getCurrentEmotion();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取当前角色数据
|
|
||||||
* @returns 角色数据对象,失败时返回null
|
|
||||||
*/
|
|
||||||
public getRoleData(): any {
|
|
||||||
if (!this.chatModel.validate()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
return {
|
|
||||||
basic: this.chatModel.getRoleData(),
|
|
||||||
detail: this.chatModel.getRoleDetail()
|
|
||||||
};
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`Failed to get role data:`, error);
|
|
||||||
this.handleError(error as Error);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 清除当前角色的聊天历史
|
* 清除当前角色的聊天历史
|
||||||
*/
|
*/
|
||||||
@@ -291,10 +279,10 @@ export class ChatController {
|
|||||||
try {
|
try {
|
||||||
// 清除AI服务中的历史记录
|
// 清除AI服务中的历史记录
|
||||||
ChatAIService.Instance.clearChatHistory(roleId);
|
ChatAIService.Instance.clearChatHistory(roleId);
|
||||||
|
|
||||||
// 清除模型中的对话记录
|
// 清除模型中的对话记录
|
||||||
this.chatModel.clearDialogs();
|
this.chatModel.clearDialogs();
|
||||||
|
|
||||||
console.log(`Chat history cleared for role ${roleId}`);
|
console.log(`Chat history cleared for role ${roleId}`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to clear chat history:", error);
|
console.error("Failed to clear chat history:", error);
|
||||||
@@ -310,10 +298,10 @@ export class ChatController {
|
|||||||
try {
|
try {
|
||||||
// 清除AI服务中的历史记录
|
// 清除AI服务中的历史记录
|
||||||
ChatAIService.Instance.clearChatHistory(roleId);
|
ChatAIService.Instance.clearChatHistory(roleId);
|
||||||
|
|
||||||
// 清除模型中的对话记录
|
// 清除模型中的对话记录
|
||||||
this.chatModel.clearDialogs(roleId);
|
this.chatModel.clearDialogs(roleId);
|
||||||
|
|
||||||
console.log(`Chat history cleared for role ${roleId}`);
|
console.log(`Chat history cleared for role ${roleId}`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Failed to clear chat history for role ${roleId}:`, error);
|
console.error(`Failed to clear chat history for role ${roleId}:`, error);
|
||||||
@@ -387,18 +375,20 @@ export class ChatController {
|
|||||||
|
|
||||||
// 从ChatHistoryManager加载聊天记录
|
// 从ChatHistoryManager加载聊天记录
|
||||||
const chatHistory = ChatHistoryManager.Instance.loadHistory(targetRoleId);
|
const chatHistory = ChatHistoryManager.Instance.loadHistory(targetRoleId);
|
||||||
|
|
||||||
// 清空ChatModel中的对话记录
|
// 清空ChatModel中的对话记录
|
||||||
this.chatModel.clearDialogs(targetRoleId);
|
this.chatModel.clearDialogs(targetRoleId);
|
||||||
|
|
||||||
// 将ChatHistoryManager的记录转换为Dialog格式并添加到ChatModel
|
// 将ChatHistoryManager的记录转换为Dialog格式并添加到ChatModel
|
||||||
chatHistory.forEach(message => {
|
chatHistory.forEach((message) => {
|
||||||
const isPlayer = message.role === "user";
|
const isPlayer = message.role === "user";
|
||||||
const content = message.parts.map(part => part.text).join("");
|
const content = message.parts.map((part) => part.text).join("");
|
||||||
this.chatModel.addDialog(isPlayer, content, targetRoleId);
|
this.chatModel.addDialog(isPlayer, content, targetRoleId);
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(`Loaded ${chatHistory.length} messages from ChatHistoryManager for role ${targetRoleId}`);
|
console.log(
|
||||||
|
`Loaded ${chatHistory.length} messages from ChatHistoryManager for role ${targetRoleId}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -407,13 +397,17 @@ export class ChatController {
|
|||||||
*/
|
*/
|
||||||
public syncDialogData(): void {
|
public syncDialogData(): void {
|
||||||
if (!this.dialogManager || !this.chatModel.validate()) {
|
if (!this.dialogManager || !this.chatModel.validate()) {
|
||||||
console.warn("Cannot sync dialog data: missing DialogManager or invalid ChatModel");
|
console.warn(
|
||||||
|
"Cannot sync dialog data: missing DialogManager or invalid ChatModel"
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const dialogs = this.chatModel.getDialogs();
|
const dialogs = this.chatModel.getDialogs();
|
||||||
this.dialogManager.syncFromChatModel(dialogs);
|
this.dialogManager.syncFromChatModel(dialogs);
|
||||||
console.log(`Synced ${dialogs.length} dialogs from ChatModel to DialogManager`);
|
console.log(
|
||||||
|
`Synced ${dialogs.length} dialogs from ChatModel to DialogManager`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -430,7 +424,7 @@ export class ChatController {
|
|||||||
roleId: targetRoleId,
|
roleId: targetRoleId,
|
||||||
dialogCount: this.chatModel.getDialogCount(targetRoleId),
|
dialogCount: this.chatModel.getDialogCount(targetRoleId),
|
||||||
lastDialog: this.chatModel.getLastDialog(targetRoleId),
|
lastDialog: this.chatModel.getLastDialog(targetRoleId),
|
||||||
currentEmotion: this.chatModel.getCurrentEmotion(targetRoleId)
|
currentEmotion: this.chatModel.getCurrentEmotion(targetRoleId),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -442,7 +436,7 @@ export class ChatController {
|
|||||||
const stats = {
|
const stats = {
|
||||||
totalCachedRoles: this.chatModel.getCachedRoleCount(),
|
totalCachedRoles: this.chatModel.getCachedRoleCount(),
|
||||||
currentRoleId: this.chatModel.getCurrentRoleId(),
|
currentRoleId: this.chatModel.getCurrentRoleId(),
|
||||||
roles: {} as any
|
roles: {} as any,
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const roleId of allRoleIds) {
|
for (const roleId of allRoleIds) {
|
||||||
@@ -452,14 +446,6 @@ export class ChatController {
|
|||||||
return stats;
|
return stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 检查是否有指定角色的数据
|
|
||||||
* @param roleId 角色ID
|
|
||||||
*/
|
|
||||||
public hasRoleData(roleId: number): boolean {
|
|
||||||
return this.chatModel.hasRoleData(roleId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 清除指定角色的所有数据
|
* 清除指定角色的所有数据
|
||||||
* @param roleId 角色ID
|
* @param roleId 角色ID
|
||||||
@@ -468,10 +454,10 @@ export class ChatController {
|
|||||||
try {
|
try {
|
||||||
// 清除AI服务中的历史记录
|
// 清除AI服务中的历史记录
|
||||||
ChatAIService.Instance.clearChatHistory(roleId);
|
ChatAIService.Instance.clearChatHistory(roleId);
|
||||||
|
|
||||||
// 清除模型中的角色数据
|
// 清除模型中的角色数据
|
||||||
this.chatModel.clearRoleData(roleId);
|
this.chatModel.clearRoleData(roleId);
|
||||||
|
|
||||||
console.log(`All data cleared for role ${roleId}`);
|
console.log(`All data cleared for role ${roleId}`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Failed to clear all data for role ${roleId}:`, error);
|
console.error(`Failed to clear all data for role ${roleId}:`, error);
|
||||||
@@ -479,6 +465,14 @@ export class ChatController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查是否有指定角色的数据
|
||||||
|
* @param roleId 角色ID
|
||||||
|
*/
|
||||||
|
public hasRoleData(categoryId:string,roleId: number): boolean {
|
||||||
|
return this.chatModel.hasRoleData(roleId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置最大缓存角色数量
|
* 设置最大缓存角色数量
|
||||||
* @param maxCount 最大缓存数量
|
* @param maxCount 最大缓存数量
|
||||||
@@ -487,14 +481,6 @@ export class ChatController {
|
|||||||
this.chatModel.setMaxCachedRoles(maxCount);
|
this.chatModel.setMaxCachedRoles(maxCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取模型状态摘要
|
|
||||||
* @param roleId 角色ID,不传则获取全局摘要
|
|
||||||
*/
|
|
||||||
public getModelSummary(roleId?: number): any {
|
|
||||||
return this.chatModel.getStateSummary(roleId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查是否可以发送消息(基于聊天次数限制)
|
* 检查是否可以发送消息(基于聊天次数限制)
|
||||||
* @returns 是否可以发送消息
|
* @returns 是否可以发送消息
|
||||||
@@ -503,39 +489,6 @@ export class ChatController {
|
|||||||
return this.chatModel.canChat();
|
return this.chatModel.canChat();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取当前角色剩余聊天次数
|
|
||||||
* @returns 剩余聊天次数
|
|
||||||
*/
|
|
||||||
public getRemainingChats(): number {
|
|
||||||
return this.chatModel.getRemainingChatCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取当前角色已使用的聊天次数
|
|
||||||
* @returns 已使用的聊天次数
|
|
||||||
*/
|
|
||||||
public getUsedChats(): number {
|
|
||||||
return this.chatModel.getRoleChatCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取当前角色的聊天次数限制
|
|
||||||
* @returns 聊天次数限制
|
|
||||||
*/
|
|
||||||
public getChatLimit(): number {
|
|
||||||
return this.chatModel.getRoleChatLimit();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 重置当前角色的聊天次数
|
|
||||||
*/
|
|
||||||
public resetChatCount(): void {
|
|
||||||
this.chatModel.resetChatCount();
|
|
||||||
console.log("ChatController: Chat count reset for current role");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理情绪更新事件
|
* 处理情绪更新事件
|
||||||
* @param data 情绪更新数据 { roleId: number, emotion: VideoEmotion }
|
* @param data 情绪更新数据 { roleId: number, emotion: VideoEmotion }
|
||||||
@@ -547,14 +500,16 @@ export class ChatController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { roleId, emotion } = data;
|
const { roleId, emotion } = data;
|
||||||
|
|
||||||
// 只处理当前角色的情绪更新
|
// 只处理当前角色的情绪更新
|
||||||
if (roleId === this.chatModel.getCurrentRoleId()) {
|
if (roleId === this.chatModel.getCurrentRoleId()) {
|
||||||
console.log(`ChatController: Emotion updated for role ${roleId}: ${VideoEmotion[emotion]}`);
|
console.log(
|
||||||
|
`ChatController: Emotion updated for role ${roleId}: ${VideoEmotion[emotion]}`
|
||||||
|
);
|
||||||
|
|
||||||
// 更新模型中的情绪状态
|
// 更新模型中的情绪状态
|
||||||
this.chatModel.setCurrentEmotion(emotion);
|
this.chatModel.setCurrentEmotion(emotion);
|
||||||
|
|
||||||
// 通知界面情绪更新
|
// 通知界面情绪更新
|
||||||
this.callback?.onEmotionUpdated(emotion);
|
this.callback?.onEmotionUpdated(emotion);
|
||||||
}
|
}
|
||||||
@@ -568,4 +523,4 @@ export class ChatController {
|
|||||||
console.error("ChatController error:", error);
|
console.error("ChatController error:", error);
|
||||||
this.callback?.onError(error);
|
this.callback?.onError(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,18 @@
|
|||||||
import { VideoEmotion, purchase } from "../../schema/schema";
|
import { VideoEmotion, purchase } from "../../schema/schema";
|
||||||
import { Dialog } from "./DialogData";
|
import { Dialog } from "./DialogData";
|
||||||
import { ConfigManager } from "../manager/ConfigManager";
|
import { ConfigManager } from "../manager/ConfigManager";
|
||||||
|
import { DataId, DataManager } from "./DataManager";
|
||||||
|
import { GirlData } from "./GirlData";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 单个角色的聊天数据结构
|
* 单个角色的聊天数据结构
|
||||||
*/
|
*/
|
||||||
export interface RoleChatData {
|
export interface RoleChatData {
|
||||||
roleId: number;
|
categoryId: string;
|
||||||
roleData: any;
|
girlId: number;
|
||||||
roleDetail: any;
|
|
||||||
dialogs: Dialog[];
|
dialogs: Dialog[];
|
||||||
currentEmotion: VideoEmotion;
|
currentEmotion: VideoEmotion;
|
||||||
commercialVideos: purchase.CommercialVideo[];
|
|
||||||
nameKey: string;
|
|
||||||
lastActiveTime: Date;
|
lastActiveTime: Date;
|
||||||
isInitialized: boolean;
|
|
||||||
chatCount: number;
|
|
||||||
maxChatCount: number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -36,93 +32,99 @@ export class ChatModel {
|
|||||||
private rolesData: Map<number, RoleChatData> = new Map();
|
private rolesData: Map<number, RoleChatData> = new Map();
|
||||||
|
|
||||||
// 当前活跃的角色ID
|
// 当前活跃的角色ID
|
||||||
private currentRoleId: number | null = null;
|
private currentGirlId: number | null = null;
|
||||||
|
|
||||||
// 最大缓存角色数量(内存管理)
|
// 最大缓存角色数量(内存管理)
|
||||||
private maxCachedRoles: number = 10;
|
private maxCachedRoles: number = 10;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化或切换到指定角色
|
* 初始化或切换到指定角色
|
||||||
* @param roleId 角色ID
|
* @param girlId 角色ID
|
||||||
* @returns 是否成功
|
* @returns 是否成功
|
||||||
*/
|
*/
|
||||||
public initializeRole(roleId: number): boolean {
|
public initializeRole(categoryId: string, girlId: number): boolean {
|
||||||
if (roleId <= 0) {
|
if (girlId <= 0) {
|
||||||
console.error("ChatModel: Invalid roleId provided");
|
console.error("ChatModel: Invalid roleId provided");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果角色数据已存在,直接切换
|
// 如果角色数据已存在,直接切换
|
||||||
if (this.rolesData.has(roleId)) {
|
if (this.rolesData.has(girlId)) {
|
||||||
this.currentRoleId = roleId;
|
this.currentGirlId = girlId;
|
||||||
this.updateLastActiveTime(roleId);
|
this.updateLastActiveTime(girlId);
|
||||||
console.log(`ChatModel: Switched to existing role ${roleId}`);
|
console.log(`ChatModel: Switched to existing role ${girlId}`);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建新的角色数据
|
// 创建新的角色数据
|
||||||
const newRoleData = this.createRoleData(roleId);
|
const newRoleData = this.createRoleData(categoryId, girlId);
|
||||||
if (newRoleData) {
|
if (newRoleData) {
|
||||||
// 内存管理:如果超过最大缓存数量,清理最久未使用的角色
|
// 内存管理:如果超过最大缓存数量,清理最久未使用的角色
|
||||||
this.manageMemory();
|
this.manageMemory();
|
||||||
|
|
||||||
this.rolesData.set(roleId, newRoleData);
|
this.rolesData.set(girlId, newRoleData);
|
||||||
this.currentRoleId = roleId;
|
this.currentGirlId = girlId;
|
||||||
console.log(`ChatModel: Initialized new role ${roleId}`);
|
console.log(`ChatModel: Initialized new role ${girlId}`);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查是否有指定角色的数据
|
||||||
|
* @param roleId 角色ID
|
||||||
|
*/
|
||||||
|
public hasRoleData(roleId: number): boolean {
|
||||||
|
return this.rolesData.has(roleId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 切换到指定角色(不存在则初始化)
|
* 切换到指定角色(不存在则初始化)
|
||||||
* @param roleId 角色ID
|
* @param roleId 角色ID
|
||||||
* @returns 是否成功
|
* @returns 是否成功
|
||||||
*/
|
*/
|
||||||
public switchToRole(roleId: number): boolean {
|
public switchToRole(categoryId: string, roleId: number): boolean {
|
||||||
return this.initializeRole(roleId);
|
return this.initializeRole(categoryId, roleId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建新的角色数据
|
* 创建新的角色数据
|
||||||
* @param roleId 角色ID
|
* @param girlId 角色ID
|
||||||
* @returns 角色数据对象
|
* @returns 角色数据对象
|
||||||
*/
|
*/
|
||||||
private createRoleData(roleId: number): RoleChatData | null {
|
private createRoleData(
|
||||||
|
categoryId: string,
|
||||||
|
girlId: number
|
||||||
|
): RoleChatData | null {
|
||||||
try {
|
try {
|
||||||
// 加载角色基础数据
|
// 加载角色基础数据
|
||||||
const roleData = ConfigManager.tables.TbGirls.get(roleId);
|
|
||||||
const roleDetail = ConfigManager.tables.TbGirlsDetail.get(roleId);
|
|
||||||
|
|
||||||
if (!roleData) {
|
const girlData = DataManager.I.getDataById<GirlData>(DataId.Girl);
|
||||||
console.error(`ChatModel: Role data not found for roleId ${roleId}`);
|
const chatTotalCount = girlData.getChatTotalCount(categoryId, girlId);
|
||||||
|
|
||||||
|
//const roleData = ConfigManager.tables.TbGirls.get(roleId);
|
||||||
|
//const roleDetail = ConfigManager.tables.TbGirlsDetail.get(roleId);
|
||||||
|
|
||||||
|
if (!girlData) {
|
||||||
|
console.error(`ChatModel: Role data not found for roleId ${girlId}`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Todo:未接入后端数据 待补充
|
//Todo:未接入后端数据 待补充
|
||||||
// 创建角色数据对象
|
// 创建角色数据对象
|
||||||
const newRoleData: RoleChatData = {
|
const newRoleData: RoleChatData = {
|
||||||
roleId: roleId,
|
girlId: girlId,
|
||||||
roleData: roleData,
|
categoryId: categoryId,
|
||||||
roleDetail: roleDetail,
|
|
||||||
nameKey: roleData.nameKey || "",
|
|
||||||
dialogs: [],
|
dialogs: [],
|
||||||
currentEmotion: VideoEmotion.calm_down,
|
currentEmotion: VideoEmotion.calm_down,
|
||||||
commercialVideos:
|
|
||||||
roleDetail && roleDetail.commercialVideos
|
|
||||||
? roleDetail.commercialVideos
|
|
||||||
: [],
|
|
||||||
lastActiveTime: new Date(),
|
lastActiveTime: new Date(),
|
||||||
isInitialized: true,
|
|
||||||
chatCount: 0,
|
|
||||||
maxChatCount: this.getDefaultChatLimit(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return newRoleData;
|
return newRoleData;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(
|
console.error(
|
||||||
`ChatModel: Failed to create role data for ${roleId}:`,
|
`ChatModel: Failed to create role data for ${girlId}:`,
|
||||||
error
|
error
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
@@ -169,67 +171,17 @@ export class ChatModel {
|
|||||||
* 获取当前活跃角色ID
|
* 获取当前活跃角色ID
|
||||||
*/
|
*/
|
||||||
public getCurrentRoleId(): number | null {
|
public getCurrentRoleId(): number | null {
|
||||||
return this.currentRoleId;
|
return this.currentGirlId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前角色数据
|
* 获取当前角色数据
|
||||||
*/
|
*/
|
||||||
public getCurrentRoleData(): RoleChatData | null {
|
public getCurrentRoleData(): RoleChatData | null {
|
||||||
if (!this.currentRoleId) {
|
if (!this.currentGirlId) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return this.rolesData.get(this.currentRoleId) || null;
|
return this.rolesData.get(this.currentGirlId) || null;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取指定角色数据
|
|
||||||
* @param roleId 角色ID,不传则使用当前角色
|
|
||||||
*/
|
|
||||||
public getRoleData(roleId?: number): any {
|
|
||||||
const targetRoleId = roleId || this.currentRoleId;
|
|
||||||
if (!targetRoleId) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const roleData = this.rolesData.get(targetRoleId);
|
|
||||||
return roleData ? roleData.roleData : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取指定角色详细数据
|
|
||||||
* @param roleId 角色ID,不传则使用当前角色
|
|
||||||
*/
|
|
||||||
public getRoleDetail(roleId?: number): any {
|
|
||||||
const targetRoleId = roleId || this.currentRoleId;
|
|
||||||
if (!targetRoleId) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const roleData = this.rolesData.get(targetRoleId);
|
|
||||||
return roleData ? roleData.roleDetail : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取角色名称键值
|
|
||||||
* @param roleId 角色ID,不传则使用当前角色
|
|
||||||
*/
|
|
||||||
public getNameKey(roleId?: number): string {
|
|
||||||
const targetRoleId = roleId || this.currentRoleId;
|
|
||||||
if (!targetRoleId) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
const roleData = this.rolesData.get(targetRoleId);
|
|
||||||
return roleData ? roleData.nameKey : "";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 检查是否有指定角色的数据
|
|
||||||
* @param roleId 角色ID
|
|
||||||
*/
|
|
||||||
public hasRoleData(roleId: number): boolean {
|
|
||||||
return this.rolesData.has(roleId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -237,7 +189,7 @@ export class ChatModel {
|
|||||||
* @param roleId 角色ID,不传则使用当前角色
|
* @param roleId 角色ID,不传则使用当前角色
|
||||||
*/
|
*/
|
||||||
public getDialogs(roleId?: number): Dialog[] {
|
public getDialogs(roleId?: number): Dialog[] {
|
||||||
const targetRoleId = roleId || this.currentRoleId;
|
const targetRoleId = roleId || this.currentGirlId;
|
||||||
if (!targetRoleId) {
|
if (!targetRoleId) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@@ -253,7 +205,7 @@ export class ChatModel {
|
|||||||
* @param roleId 角色ID,不传则使用当前角色
|
* @param roleId 角色ID,不传则使用当前角色
|
||||||
*/
|
*/
|
||||||
public addDialog(isPlayer: boolean, content: string, roleId?: number): void {
|
public addDialog(isPlayer: boolean, content: string, roleId?: number): void {
|
||||||
const targetRoleId = roleId || this.currentRoleId;
|
const targetRoleId = roleId || this.currentGirlId;
|
||||||
if (!targetRoleId) {
|
if (!targetRoleId) {
|
||||||
console.warn("ChatModel: Cannot add dialog - no active role");
|
console.warn("ChatModel: Cannot add dialog - no active role");
|
||||||
return;
|
return;
|
||||||
@@ -287,7 +239,7 @@ export class ChatModel {
|
|||||||
* @param roleId 角色ID,不传则使用当前角色
|
* @param roleId 角色ID,不传则使用当前角色
|
||||||
*/
|
*/
|
||||||
public clearDialogs(roleId?: number): void {
|
public clearDialogs(roleId?: number): void {
|
||||||
const targetRoleId = roleId || this.currentRoleId;
|
const targetRoleId = roleId || this.currentGirlId;
|
||||||
if (!targetRoleId) {
|
if (!targetRoleId) {
|
||||||
console.warn("ChatModel: Cannot clear dialogs - no active role");
|
console.warn("ChatModel: Cannot clear dialogs - no active role");
|
||||||
return;
|
return;
|
||||||
@@ -306,7 +258,7 @@ export class ChatModel {
|
|||||||
* @param roleId 角色ID,不传则使用当前角色
|
* @param roleId 角色ID,不传则使用当前角色
|
||||||
*/
|
*/
|
||||||
public getCurrentEmotion(roleId?: number): VideoEmotion {
|
public getCurrentEmotion(roleId?: number): VideoEmotion {
|
||||||
const targetRoleId = roleId || this.currentRoleId;
|
const targetRoleId = roleId || this.currentGirlId;
|
||||||
if (!targetRoleId) {
|
if (!targetRoleId) {
|
||||||
return VideoEmotion.calm_down;
|
return VideoEmotion.calm_down;
|
||||||
}
|
}
|
||||||
@@ -321,7 +273,7 @@ export class ChatModel {
|
|||||||
* @param roleId 角色ID,不传则使用当前角色
|
* @param roleId 角色ID,不传则使用当前角色
|
||||||
*/
|
*/
|
||||||
public setCurrentEmotion(emotion: VideoEmotion, roleId?: number): void {
|
public setCurrentEmotion(emotion: VideoEmotion, roleId?: number): void {
|
||||||
const targetRoleId = roleId || this.currentRoleId;
|
const targetRoleId = roleId || this.currentGirlId;
|
||||||
if (!targetRoleId) {
|
if (!targetRoleId) {
|
||||||
console.warn("ChatModel: Cannot set emotion - no active role");
|
console.warn("ChatModel: Cannot set emotion - no active role");
|
||||||
return;
|
return;
|
||||||
@@ -343,31 +295,14 @@ export class ChatModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取商业视频配置
|
|
||||||
* @param roleId 角色ID,不传则使用当前角色
|
|
||||||
*/
|
|
||||||
public getCommercialVideos(roleId?: number): purchase.CommercialVideo[] {
|
|
||||||
const targetRoleId = roleId || this.currentRoleId;
|
|
||||||
if (!targetRoleId) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
const roleData = this.rolesData.get(targetRoleId);
|
|
||||||
return roleData ? [...roleData.commercialVideos] : []; // 返回副本避免外部修改
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据情绪获取对应的视频(如果有多个视频,随机返回一个)
|
* 根据情绪获取对应的视频(如果有多个视频,随机返回一个)
|
||||||
* @param emotion 目标情绪
|
* @param emotion 目标情绪
|
||||||
* @param roleId 角色ID,不传则使用当前角色
|
* @param roleId 角色ID,不传则使用当前角色
|
||||||
* @returns 匹配的视频对象,没找到则返回null
|
* @returns 匹配的视频url
|
||||||
*/
|
*/
|
||||||
public getVideoByEmotion(
|
public getVideoByEmotion(emotion: VideoEmotion, roleId?: number): string {
|
||||||
emotion: VideoEmotion,
|
const targetRoleId = roleId || this.currentGirlId;
|
||||||
roleId?: number
|
|
||||||
): purchase.CommercialVideo | null {
|
|
||||||
const targetRoleId = roleId || this.currentRoleId;
|
|
||||||
if (!targetRoleId) {
|
if (!targetRoleId) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -376,46 +311,81 @@ export class ChatModel {
|
|||||||
if (!roleData) {
|
if (!roleData) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
const girlData = DataManager.I.getDataById<GirlData>(DataId.Girl);
|
||||||
// 获取所有匹配该情绪的视频
|
const allvideoIDs = girlData.getAllDisplayGrilVideoId(
|
||||||
const matchingVideos = roleData.commercialVideos.filter(
|
roleData.categoryId,
|
||||||
(video) => video.emotion === emotion
|
roleData.girlId
|
||||||
);
|
);
|
||||||
|
let targetIds: number[] = [];
|
||||||
|
for (let i = 0; i < allvideoIDs.length; i++) {
|
||||||
|
const element = allvideoIDs[i];
|
||||||
|
if (
|
||||||
|
girlData.getGrilVideoEmotion(
|
||||||
|
roleData.categoryId,
|
||||||
|
roleData.girlId,
|
||||||
|
element
|
||||||
|
) === emotion
|
||||||
|
) {
|
||||||
|
targetIds.push(allvideoIDs[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (matchingVideos.length === 0) {
|
if (targetIds.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果只有一个匹配的视频,直接返回
|
// 如果只有一个匹配的视频,直接返回
|
||||||
if (matchingVideos.length === 1) {
|
if (targetIds.length === 1) {
|
||||||
return matchingVideos[0];
|
return girlData.getGrilVideoPath(
|
||||||
|
roleData.categoryId,
|
||||||
|
roleData.girlId,
|
||||||
|
targetIds[0]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果有多个匹配的视频,随机选择一个
|
// 如果有多个匹配的视频,随机选择一个
|
||||||
const randomIndex = Math.floor(Math.random() * matchingVideos.length);
|
const randomIndex = Math.floor(Math.random() * targetIds.length);
|
||||||
return matchingVideos[randomIndex];
|
return girlData.getGrilVideoPath(
|
||||||
|
roleData.categoryId,
|
||||||
|
roleData.girlId,
|
||||||
|
targetIds[randomIndex]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取默认视频(第一个视频或平静状态视频)
|
* 获取默认视频(第一个视频或平静状态视频)
|
||||||
* @param roleId 角色ID,不传则使用当前角色
|
* @param girlId 角色ID,不传则使用当前角色
|
||||||
*/
|
*/
|
||||||
public getDefaultVideo(roleId?: number): purchase.CommercialVideo | null {
|
public getDefaultVideo(): string {
|
||||||
const targetRoleId = roleId || this.currentRoleId;
|
const girlData = DataManager.I.getDataById<GirlData>(DataId.Girl);
|
||||||
if (!targetRoleId) {
|
const roleData = this.rolesData.get(this.currentGirlId);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const roleData = this.rolesData.get(targetRoleId);
|
const allvideoIDs = girlData.getAllDisplayGrilVideoId(
|
||||||
if (!roleData || roleData.commercialVideos.length === 0) {
|
roleData.categoryId,
|
||||||
return null;
|
roleData.girlId
|
||||||
}
|
|
||||||
|
|
||||||
// 优先返回平静状态的视频
|
|
||||||
const calmVideo = roleData.commercialVideos.find(
|
|
||||||
(video) => video.emotion === VideoEmotion.calm_down
|
|
||||||
);
|
);
|
||||||
return calmVideo || roleData.commercialVideos[0];
|
let targetId: number = -1;
|
||||||
|
for (let i = 0; i < allvideoIDs.length; i++) {
|
||||||
|
const element = allvideoIDs[i];
|
||||||
|
if (
|
||||||
|
girlData.getGrilVideoEmotion(
|
||||||
|
roleData.categoryId,
|
||||||
|
roleData.girlId,
|
||||||
|
element
|
||||||
|
) === VideoEmotion.calm_down
|
||||||
|
) {
|
||||||
|
targetId = element;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (targetId == -1) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return girlData.getGrilVideoPath(
|
||||||
|
roleData.categoryId,
|
||||||
|
roleData.girlId,
|
||||||
|
targetId
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -423,7 +393,7 @@ export class ChatModel {
|
|||||||
* @param roleId 角色ID,不传则使用当前角色
|
* @param roleId 角色ID,不传则使用当前角色
|
||||||
*/
|
*/
|
||||||
public getDialogCount(roleId?: number): number {
|
public getDialogCount(roleId?: number): number {
|
||||||
const targetRoleId = roleId || this.currentRoleId;
|
const targetRoleId = roleId || this.currentGirlId;
|
||||||
if (!targetRoleId) {
|
if (!targetRoleId) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -437,7 +407,7 @@ export class ChatModel {
|
|||||||
* @param roleId 角色ID,不传则使用当前角色
|
* @param roleId 角色ID,不传则使用当前角色
|
||||||
*/
|
*/
|
||||||
public getLastDialog(roleId?: number): Dialog | null {
|
public getLastDialog(roleId?: number): Dialog | null {
|
||||||
const targetRoleId = roleId || this.currentRoleId;
|
const targetRoleId = roleId || this.currentGirlId;
|
||||||
if (!targetRoleId) {
|
if (!targetRoleId) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -450,26 +420,12 @@ export class ChatModel {
|
|||||||
return roleData.dialogs[roleData.dialogs.length - 1];
|
return roleData.dialogs[roleData.dialogs.length - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 检查当前角色是否已初始化
|
|
||||||
* @param roleId 角色ID,不传则使用当前角色
|
|
||||||
*/
|
|
||||||
public isInitialized(roleId?: number): boolean {
|
|
||||||
const targetRoleId = roleId || this.currentRoleId;
|
|
||||||
if (!targetRoleId) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const roleData = this.rolesData.get(targetRoleId);
|
|
||||||
return roleData ? roleData.isInitialized : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重置所有数据到初始状态
|
* 重置所有数据到初始状态
|
||||||
*/
|
*/
|
||||||
public reset(): void {
|
public reset(): void {
|
||||||
this.rolesData.clear();
|
this.rolesData.clear();
|
||||||
this.currentRoleId = null;
|
this.currentGirlId = null;
|
||||||
console.log(
|
console.log(
|
||||||
"ChatModel: All role data cleared and model reset to initial state"
|
"ChatModel: All role data cleared and model reset to initial state"
|
||||||
);
|
);
|
||||||
@@ -484,8 +440,8 @@ export class ChatModel {
|
|||||||
this.rolesData.delete(roleId);
|
this.rolesData.delete(roleId);
|
||||||
|
|
||||||
// 如果删除的是当前角色,清空当前角色ID
|
// 如果删除的是当前角色,清空当前角色ID
|
||||||
if (this.currentRoleId === roleId) {
|
if (this.currentGirlId === roleId) {
|
||||||
this.currentRoleId = null;
|
this.currentGirlId = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`ChatModel: Role ${roleId} data cleared`);
|
console.log(`ChatModel: Role ${roleId} data cleared`);
|
||||||
@@ -497,7 +453,7 @@ export class ChatModel {
|
|||||||
* @param roleId 角色ID,不传则使用当前角色
|
* @param roleId 角色ID,不传则使用当前角色
|
||||||
*/
|
*/
|
||||||
public validate(roleId?: number): boolean {
|
public validate(roleId?: number): boolean {
|
||||||
const targetRoleId = roleId || this.currentRoleId;
|
const targetRoleId = roleId || this.currentGirlId;
|
||||||
if (!targetRoleId) {
|
if (!targetRoleId) {
|
||||||
console.error("ChatModel: No active role");
|
console.error("ChatModel: No active role");
|
||||||
return false;
|
return false;
|
||||||
@@ -508,17 +464,6 @@ export class ChatModel {
|
|||||||
console.error(`ChatModel: Role data not found for ${targetRoleId}`);
|
console.error(`ChatModel: Role data not found for ${targetRoleId}`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!roleData.isInitialized) {
|
|
||||||
console.error(`ChatModel: Role ${targetRoleId} not initialized`);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!roleData.roleData) {
|
|
||||||
console.error(`ChatModel: Role ${targetRoleId} data not loaded`);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -565,45 +510,6 @@ export class ChatModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取模型状态摘要(用于调试)
|
|
||||||
* @param roleId 角色ID,不传则返回当前角色摘要
|
|
||||||
*/
|
|
||||||
public getStateSummary(roleId?: number): any {
|
|
||||||
const targetRoleId = roleId || this.currentRoleId;
|
|
||||||
|
|
||||||
if (!targetRoleId) {
|
|
||||||
return {
|
|
||||||
currentRoleId: null,
|
|
||||||
totalCachedRoles: this.rolesData.size,
|
|
||||||
maxCachedRoles: this.maxCachedRoles,
|
|
||||||
allRoleIds: this.getAllRoleIds(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const roleData = this.rolesData.get(targetRoleId);
|
|
||||||
if (!roleData) {
|
|
||||||
return {
|
|
||||||
roleId: targetRoleId,
|
|
||||||
error: "Role data not found",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
roleId: targetRoleId,
|
|
||||||
nameKey: roleData.nameKey,
|
|
||||||
dialogCount: roleData.dialogs.length,
|
|
||||||
currentEmotion: VideoEmotion[roleData.currentEmotion],
|
|
||||||
videoCount: roleData.commercialVideos.length,
|
|
||||||
lastActiveTime: roleData.lastActiveTime,
|
|
||||||
isInitialized: roleData.isInitialized,
|
|
||||||
chatCount: roleData.chatCount,
|
|
||||||
maxChatCount: roleData.maxChatCount,
|
|
||||||
remainingChats: roleData.maxChatCount - roleData.chatCount,
|
|
||||||
totalCachedRoles: this.rolesData.size,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取默认聊天次数限制
|
* 获取默认聊天次数限制
|
||||||
* TODO: 以后从后端获取,目前默认返回10
|
* TODO: 以后从后端获取,目前默认返回10
|
||||||
@@ -613,105 +519,17 @@ export class ChatModel {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取角色的聊天次数限制
|
|
||||||
* @param roleId 角色ID,不传则使用当前角色
|
|
||||||
* @returns 聊天次数限制,未找到角色则返回0
|
|
||||||
*/
|
|
||||||
public getRoleChatLimit(roleId?: number): number {
|
|
||||||
const targetRoleId = roleId || this.currentRoleId;
|
|
||||||
if (!targetRoleId) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const roleData = this.rolesData.get(targetRoleId);
|
|
||||||
return roleData ? roleData.maxChatCount : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取角色已使用的聊天次数
|
|
||||||
* @param roleId 角色ID,不传则使用当前角色
|
|
||||||
* @returns 已使用的聊天次数
|
|
||||||
*/
|
|
||||||
public getRoleChatCount(roleId?: number): number {
|
|
||||||
const targetRoleId = roleId || this.currentRoleId;
|
|
||||||
if (!targetRoleId) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const roleData = this.rolesData.get(targetRoleId);
|
|
||||||
return roleData ? roleData.chatCount : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取角色剩余聊天次数
|
|
||||||
* @param roleId 角色ID,不传则使用当前角色
|
|
||||||
* @returns 剩余聊天次数
|
|
||||||
*/
|
|
||||||
public getRemainingChatCount(roleId?: number): number {
|
|
||||||
const targetRoleId = roleId || this.currentRoleId;
|
|
||||||
if (!targetRoleId) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const roleData = this.rolesData.get(targetRoleId);
|
|
||||||
return roleData
|
|
||||||
? Math.max(0, roleData.maxChatCount - roleData.chatCount)
|
|
||||||
: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查角色是否还有剩余聊天次数
|
* 检查角色是否还有剩余聊天次数
|
||||||
* @param roleId 角色ID,不传则使用当前角色
|
* @param roleId 角色ID,不传则使用当前角色
|
||||||
* @returns 是否可以继续聊天
|
* @returns 是否可以继续聊天
|
||||||
*/
|
*/
|
||||||
public canChat(roleId?: number): boolean {
|
public canChat(roleId?: number): boolean {
|
||||||
return this.getRemainingChatCount(roleId) > 0;
|
const girlData = DataManager.I.getDataById<GirlData>(DataId.Girl);
|
||||||
}
|
const roleData = this.rolesData.get(this.currentGirlId);
|
||||||
|
|
||||||
/**
|
return (
|
||||||
* 增加角色聊天次数计数
|
girlData.getChatRemainCount(roleData.categoryId, roleData.girlId) > 0
|
||||||
* @param roleId 角色ID,不传则使用当前角色
|
|
||||||
*/
|
|
||||||
public incrementChatCount(roleId?: number): void {
|
|
||||||
const targetRoleId = roleId || this.currentRoleId;
|
|
||||||
if (!targetRoleId) {
|
|
||||||
console.warn("ChatModel: Cannot increment chat count - no active role");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const roleData = this.rolesData.get(targetRoleId);
|
|
||||||
if (!roleData) {
|
|
||||||
console.warn(`ChatModel: Role data not found for roleId ${targetRoleId}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
roleData.chatCount++;
|
|
||||||
this.updateLastActiveTime(targetRoleId);
|
|
||||||
console.log(
|
|
||||||
`ChatModel: Chat count incremented for role ${targetRoleId}, current: ${roleData.chatCount}/${roleData.maxChatCount}`
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 重置角色聊天次数
|
|
||||||
* @param roleId 角色ID,不传则使用当前角色
|
|
||||||
*/
|
|
||||||
public resetChatCount(roleId?: number): void {
|
|
||||||
const targetRoleId = roleId || this.currentRoleId;
|
|
||||||
if (!targetRoleId) {
|
|
||||||
console.warn("ChatModel: Cannot reset chat count - no active role");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const roleData = this.rolesData.get(targetRoleId);
|
|
||||||
if (!roleData) {
|
|
||||||
console.warn(`ChatModel: Role data not found for roleId ${targetRoleId}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
roleData.chatCount = 0;
|
|
||||||
this.updateLastActiveTime(targetRoleId);
|
|
||||||
console.log(`ChatModel: Chat count reset for role ${targetRoleId}`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ export class NavigationManager {
|
|||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
public navigateToChatWithTransition(
|
public navigateToChatWithTransition(
|
||||||
|
categoryId: string,
|
||||||
roleId: number,
|
roleId: number,
|
||||||
currentPanel?: any
|
currentPanel?: any
|
||||||
): void {
|
): void {
|
||||||
@@ -99,6 +100,7 @@ export class NavigationManager {
|
|||||||
ViewManager.I.openBundlesView(
|
ViewManager.I.openBundlesView(
|
||||||
"ChatPanel",
|
"ChatPanel",
|
||||||
{
|
{
|
||||||
|
categoryId: categoryId,
|
||||||
roleId: roleId,
|
roleId: roleId,
|
||||||
withSlideTransition: true,
|
withSlideTransition: true,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ import LanguageUtils from "../../../Main/Common/LanguageUtils";
|
|||||||
import { UITransitionHelper } from "../../utils/UITransitionHelper";
|
import { UITransitionHelper } from "../../utils/UITransitionHelper";
|
||||||
import { VideoEmotion, purchase } from "../../../schema/schema";
|
import { VideoEmotion, purchase } from "../../../schema/schema";
|
||||||
import { PayToTalkSubpanel } from "./PayToTalkSubpanel";
|
import { PayToTalkSubpanel } from "./PayToTalkSubpanel";
|
||||||
|
import { DataId, DataManager } from "../../data/DataManager";
|
||||||
|
import { GirlData } from "../../data/GirlData";
|
||||||
const { ccclass, property } = _decorator;
|
const { ccclass, property } = _decorator;
|
||||||
|
|
||||||
@ccclass("ChatPanel")
|
@ccclass("ChatPanel")
|
||||||
@@ -53,6 +55,7 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback {
|
|||||||
@property(ImagePopup)
|
@property(ImagePopup)
|
||||||
popUpImage: ImagePopup = null;
|
popUpImage: ImagePopup = null;
|
||||||
|
|
||||||
|
categoryId: string;
|
||||||
id: number;
|
id: number;
|
||||||
private _nodeTab: any = {};
|
private _nodeTab: any = {};
|
||||||
|
|
||||||
@@ -76,7 +79,7 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback {
|
|||||||
const isRoleSwitch = this.id && this.id !== newRoleId;
|
const isRoleSwitch = this.id && this.id !== newRoleId;
|
||||||
|
|
||||||
this.id = newRoleId;
|
this.id = newRoleId;
|
||||||
|
this.categoryId = data.categoryId;
|
||||||
// 如果标记了需要滑入动画,则执行动画
|
// 如果标记了需要滑入动画,则执行动画
|
||||||
if (withAnimation && this.node && this.node.isValid) {
|
if (withAnimation && this.node && this.node.isValid) {
|
||||||
// 延迟一帧执行动画,确保节点已正确加载到场景中
|
// 延迟一帧执行动画,确保节点已正确加载到场景中
|
||||||
@@ -91,18 +94,21 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback {
|
|||||||
|
|
||||||
// 初始化或切换ChatController
|
// 初始化或切换ChatController
|
||||||
if (this.id && this.id > 0) {
|
if (this.id && this.id > 0) {
|
||||||
if (isRoleSwitch && this.chatController.hasRoleData(this.id)) {
|
if (
|
||||||
|
isRoleSwitch &&
|
||||||
|
this.chatController.hasRoleData(this.categoryId, this.id)
|
||||||
|
) {
|
||||||
// 如果是角色切换且有缓存数据,使用switchRole
|
// 如果是角色切换且有缓存数据,使用switchRole
|
||||||
console.log(
|
console.log(
|
||||||
`ChatPanel: Switching from role ${this.chatController.getCurrentRoleId()} to role ${
|
`ChatPanel: Switching from role ${this.chatController.getCurrentRoleId()} to role ${
|
||||||
this.id
|
this.id
|
||||||
}`
|
}`
|
||||||
);
|
);
|
||||||
this.chatController.switchRole(this.id);
|
this.chatController.switchRole(this.categoryId, this.id);
|
||||||
} else {
|
} else {
|
||||||
// 首次初始化或没有缓存数据,使用initialize
|
// 首次初始化或没有缓存数据,使用initialize
|
||||||
console.log(`ChatPanel: Initializing role ${this.id}`);
|
console.log(`ChatPanel: Initializing role ${this.id}`);
|
||||||
this.chatController.initialize(this.id);
|
this.chatController.initialize(this.categoryId, this.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -111,7 +117,7 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback {
|
|||||||
Utils.parseNode(this.node, this._nodeTab);
|
Utils.parseNode(this.node, this._nodeTab);
|
||||||
|
|
||||||
this.register();
|
this.register();
|
||||||
this.refresh(this.id);
|
this.refresh();
|
||||||
this.payToTalkPanel.node.active = false;
|
this.payToTalkPanel.node.active = false;
|
||||||
// Add video loaded event callback
|
// Add video loaded event callback
|
||||||
if (this.girlVideo) {
|
if (this.girlVideo) {
|
||||||
@@ -176,18 +182,19 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback {
|
|||||||
this.chatController = null;
|
this.chatController = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
refresh(id: number) {
|
refresh() {
|
||||||
this.id = id;
|
//this.id = id;
|
||||||
|
|
||||||
// 通过ChatController获取角色数据
|
// 通过ChatController获取角色数据
|
||||||
const roleData = this.chatController.getRoleData();
|
//const roleData = this.chatController.getRoleData();
|
||||||
if (!roleData || !roleData.basic) return;
|
//if (!roleData || !roleData.basic) return;
|
||||||
|
|
||||||
const data = roleData.basic;
|
//const data = roleData.basic;
|
||||||
const dataDetail = roleData.detail;
|
//const dataDetail = roleData.detail;
|
||||||
|
const girlData = DataManager.I.getDataById<GirlData>(DataId.Girl);
|
||||||
|
|
||||||
this.nameKey = data.nameKey;
|
this.nameKey = girlData.getGrilName(this.categoryId, this.id);
|
||||||
this.girlName.string = LanguageUtils.getText(data.nameKey);
|
this.girlName.string = LanguageUtils.getText(this.nameKey);
|
||||||
// ResManager.I.changeBundleSpriteFrame(
|
// ResManager.I.changeBundleSpriteFrame(
|
||||||
// this.girlImg,
|
// this.girlImg,
|
||||||
// data.avatarPath,
|
// data.avatarPath,
|
||||||
@@ -204,45 +211,30 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback {
|
|||||||
|
|
||||||
// 通过ChatController获取商业视频数据
|
// 通过ChatController获取商业视频数据
|
||||||
const chatModel = this.chatController.getChatModel();
|
const chatModel = this.chatController.getChatModel();
|
||||||
const commercialVideos = chatModel.getCommercialVideos();
|
|
||||||
this.commercialVideos = commercialVideos;
|
|
||||||
|
|
||||||
if (commercialVideos.length > 0) {
|
// Load initial video based on current emotion
|
||||||
|
if (this.girlVideo) {
|
||||||
|
// Get current emotion from ChatController
|
||||||
|
const currentEmotion = this.chatController.getCurrentEmotion();
|
||||||
console.log(
|
console.log(
|
||||||
`Loaded ${commercialVideos.length} videos for role ${this.id}`
|
`Current emotion for role ${this.id}: ${VideoEmotion[currentEmotion]}`
|
||||||
);
|
);
|
||||||
|
|
||||||
// Load initial video based on current emotion
|
// Get appropriate video from ChatModel
|
||||||
if (this.girlVideo) {
|
const initialVideo =
|
||||||
// Get current emotion from ChatController
|
chatModel.getVideoByEmotion(currentEmotion) ||
|
||||||
const currentEmotion = this.chatController.getCurrentEmotion();
|
chatModel.getDefaultVideo();
|
||||||
|
|
||||||
|
if (initialVideo) {
|
||||||
console.log(
|
console.log(
|
||||||
`Current emotion for role ${this.id}: ${VideoEmotion[currentEmotion]}`
|
`Loading initial video: ${initialVideo} (emotion: ${VideoEmotion[initialVideo]})`
|
||||||
);
|
);
|
||||||
|
|
||||||
// Get appropriate video from ChatModel
|
// Set current emotion to the loaded video's emotion
|
||||||
const initialVideo =
|
this.currentEmotion = this.chatController.getCurrentEmotion();
|
||||||
chatModel.getVideoByEmotion(currentEmotion) ||
|
ResManager.I.changeBundleVideo(this.girlVideo, initialVideo, "Girls");
|
||||||
chatModel.getDefaultVideo();
|
// Also immediately try to adjust scale (in case already loaded)
|
||||||
|
this.adjustVideoScale();
|
||||||
if (initialVideo) {
|
|
||||||
console.log(
|
|
||||||
`Loading initial video: ${initialVideo.path} (emotion: ${
|
|
||||||
VideoEmotion[initialVideo.emotion]
|
|
||||||
})`
|
|
||||||
);
|
|
||||||
|
|
||||||
// Set current emotion to the loaded video's emotion
|
|
||||||
this.currentEmotion = initialVideo.emotion;
|
|
||||||
|
|
||||||
ResManager.I.changeBundleVideo(
|
|
||||||
this.girlVideo,
|
|
||||||
initialVideo.path,
|
|
||||||
"Girls"
|
|
||||||
);
|
|
||||||
// Also immediately try to adjust scale (in case already loaded)
|
|
||||||
this.adjustVideoScale();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.commercialVideos = [];
|
this.commercialVideos = [];
|
||||||
@@ -302,12 +294,6 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback {
|
|||||||
}
|
}
|
||||||
// Get video data from ChatModel through ChatController
|
// Get video data from ChatModel through ChatController
|
||||||
const chatModel = this.chatController.getChatModel();
|
const chatModel = this.chatController.getChatModel();
|
||||||
const commercialVideos = chatModel.getCommercialVideos();
|
|
||||||
|
|
||||||
if (commercialVideos.length === 0) {
|
|
||||||
console.warn("Cannot switch video: no commercialVideos data");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if emotion has changed
|
// Check if emotion has changed
|
||||||
if (this.currentEmotion === emotion) {
|
if (this.currentEmotion === emotion) {
|
||||||
@@ -322,9 +308,9 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback {
|
|||||||
|
|
||||||
if (matchingVideo) {
|
if (matchingVideo) {
|
||||||
console.log(
|
console.log(
|
||||||
`Switching to video for emotion ${VideoEmotion[emotion]}: ${
|
`Switching to video for emotion ${
|
||||||
matchingVideo.path
|
VideoEmotion[emotion]
|
||||||
} (from ${
|
}: ${matchingVideo} (from ${
|
||||||
this.currentEmotion !== null
|
this.currentEmotion !== null
|
||||||
? VideoEmotion[this.currentEmotion]
|
? VideoEmotion[this.currentEmotion]
|
||||||
: "null"
|
: "null"
|
||||||
@@ -332,11 +318,7 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Load the new video
|
// Load the new video
|
||||||
ResManager.I.changeBundleVideo(
|
ResManager.I.changeBundleVideo(this.girlVideo, matchingVideo, "Girls");
|
||||||
this.girlVideo,
|
|
||||||
matchingVideo.path,
|
|
||||||
"Girls"
|
|
||||||
);
|
|
||||||
|
|
||||||
// Update current emotion state
|
// Update current emotion state
|
||||||
this.currentEmotion = emotion;
|
this.currentEmotion = emotion;
|
||||||
@@ -353,20 +335,17 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback {
|
|||||||
const fallbackVideo = chatModel.getDefaultVideo();
|
const fallbackVideo = chatModel.getDefaultVideo();
|
||||||
if (fallbackVideo) {
|
if (fallbackVideo) {
|
||||||
console.log(
|
console.log(
|
||||||
`Loading fallback video: ${fallbackVideo.path} (emotion: ${
|
`Loading fallback video: ${fallbackVideo} (emotion: ${VideoEmotion[fallbackVideo]})`
|
||||||
VideoEmotion[fallbackVideo.emotion]
|
|
||||||
})`
|
|
||||||
);
|
);
|
||||||
|
|
||||||
ResManager.I.changeBundleVideo(
|
ResManager.I.changeBundleVideo(
|
||||||
this.girlVideo,
|
this.girlVideo,
|
||||||
fallbackVideo.path,
|
fallbackVideo,
|
||||||
"Chat18x"
|
"Chat18x"
|
||||||
);
|
);
|
||||||
|
|
||||||
// Update current emotion state to the fallback video's emotion
|
// Update current emotion state to the fallback video's emotion
|
||||||
this.currentEmotion = fallbackVideo.emotion;
|
this.currentEmotion = this.chatController.getCurrentEmotion();
|
||||||
|
|
||||||
this.adjustVideoScale();
|
this.adjustVideoScale();
|
||||||
this.setVideoEnable(true);
|
this.setVideoEnable(true);
|
||||||
}
|
}
|
||||||
@@ -452,7 +431,7 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onChatLimitReached(): void {
|
onChatLimitReached(): void {
|
||||||
this.payToTalkPanel.show();
|
this.payToTalkPanel.show(this.categoryId,this.id);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 情绪状态更新回调 (实现IChatPanelCallback接口)
|
* 情绪状态更新回调 (实现IChatPanelCallback接口)
|
||||||
@@ -502,22 +481,6 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback {
|
|||||||
ViewManager.I.openBundlesView("RecordPanel", this.id);
|
ViewManager.I.openBundlesView("RecordPanel", this.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取当前聊天状态信息(用于调试)
|
|
||||||
*/
|
|
||||||
public getChatStatus(): any {
|
|
||||||
if (!this.chatController) {
|
|
||||||
return { error: "ChatController not initialized" };
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
currentPanelRoleId: this.id,
|
|
||||||
controllerStats: this.chatController.getDialogStats(),
|
|
||||||
modelSummary: this.chatController.getModelSummary(),
|
|
||||||
allRolesStats: this.chatController.getAllRolesStats(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 手动清除指定角色的数据(调试用)
|
* 手动清除指定角色的数据(调试用)
|
||||||
* @param roleId 角色ID,不传则清除当前角色
|
* @param roleId 角色ID,不传则清除当前角色
|
||||||
|
|||||||
@@ -241,7 +241,11 @@ export class GirlDetailPanel extends li_BaseView {
|
|||||||
|
|
||||||
OnClickChatBtn() {
|
OnClickChatBtn() {
|
||||||
// 使用带过渡动画的导航方法
|
// 使用带过渡动画的导航方法
|
||||||
NavigationManager.Instance.navigateToChatWithTransition(this.id, this);
|
NavigationManager.Instance.navigateToChatWithTransition(
|
||||||
|
this.category.toString(),
|
||||||
|
this.id,
|
||||||
|
this
|
||||||
|
);
|
||||||
// 注意:不在这里直接调用onClose,而是在动画完成后由NavigationManager调用
|
// 注意:不在这里直接调用onClose,而是在动画完成后由NavigationManager调用
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export class PayToTalkSubpanel extends Component {
|
|||||||
this.base = this.getComponent(UIOpacity);
|
this.base = this.getComponent(UIOpacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
show() {
|
show(categoryId: string, girlId: number) {
|
||||||
this.node.active = true;
|
this.node.active = true;
|
||||||
this.base.opacity = 0;
|
this.base.opacity = 0;
|
||||||
tween(this.base).to(0.3, { opacity: 255 }).start();
|
tween(this.base).to(0.3, { opacity: 255 }).start();
|
||||||
@@ -53,7 +53,7 @@ export class PayToTalkSubpanel extends Component {
|
|||||||
|
|
||||||
onClick_BuyTime() {
|
onClick_BuyTime() {
|
||||||
//购买次数
|
//购买次数
|
||||||
ChatController.Instance.resetChatCount();
|
//ChatController.Instance.resetChatCount();
|
||||||
this.hide();
|
this.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7451,7 +7451,6 @@
|
|||||||
"girlName": {
|
"girlName": {
|
||||||
"__id__": 24
|
"__id__": 24
|
||||||
},
|
},
|
||||||
"girlImg": null,
|
|
||||||
"girlVideo": {
|
"girlVideo": {
|
||||||
"__id__": 123
|
"__id__": 123
|
||||||
},
|
},
|
||||||
|
|||||||
+1
-1
Submodule proto_cs updated: 9ec1d4f077...f055100cf0
Reference in New Issue
Block a user