优化AI消息处理逻辑,区分AI辅助模式与AI接管模式,确保在接管模式下直接发送消息而不经过MessageEnter组件。同时,调整相关组件的状态管理,提升代码可读性和维护性。

This commit is contained in:
超级老白兔
2025-11-27 15:07:34 +08:00
parent 65da14032b
commit a5cc4e5e18
4 changed files with 183 additions and 35 deletions

View File

@@ -176,19 +176,21 @@ const MessageEnter: React.FC<MessageEnterProps> = ({ contract }) => {
updateQuoteMessageContent(""); updateQuoteMessageContent("");
}; };
// AI 消息处理 // AI 消息处理 - 只处理AI辅助模式
// AI接管模式已经在weChat.ts中直接发送不经过此组件
// 快捷语填充:当 quoteMessageContent 更新时,填充到输入框
useEffect(() => { useEffect(() => {
if (quoteMessageContent) { if (quoteMessageContent) {
if (isAiAssist) { if (isAiAssist) {
// AI辅助模式直接填充输入框
setInputValue(quoteMessageContent);
} else {
// 快捷语模式:直接填充输入框(用户主动点击快捷语,应该替换当前内容)
setInputValue(quoteMessageContent); setInputValue(quoteMessageContent);
}
if (isAiTakeover) {
handleSend(quoteMessageContent);
} }
} }
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [quoteMessageContent, aiQuoteMessageContent, isAiAssist, isAiTakeover]); }, [quoteMessageContent, aiQuoteMessageContent, isAiAssist]);
const handleKeyPress = (e: React.KeyboardEvent) => { const handleKeyPress = (e: React.KeyboardEvent) => {
if (e.key === "Enter" && !e.shiftKey && !e.ctrlKey) { if (e.key === "Enter" && !e.shiftKey && !e.ctrlKey) {

View File

@@ -18,6 +18,7 @@ import {
getFriendInjectConfig, getFriendInjectConfig,
} from "@/pages/pc/ckbox/api"; } from "@/pages/pc/ckbox/api";
import { ChatRecord, ContractData, weChatGroup } from "@/pages/pc/ckbox/data"; import { ChatRecord, ContractData, weChatGroup } from "@/pages/pc/ckbox/data";
import { useWebSocketStore } from "@/store/module/websocket/websocket";
/** /**
* AI请求防抖管理 * AI请求防抖管理
@@ -392,13 +393,73 @@ export const manualTriggerAi = async () => {
return false; return false;
} }
// 更新AI回复内容 // 获取当前接待类型
state.updateQuoteMessageContent(messageContent?.content || ""); const aiType = (currentContract as any)?.aiType || 0; // 0=人工, 1=AI辅助, 2=AI接管
state.updateIsLoadingAiChat(false); const aiResponseContent = messageContent?.content || "";
console.log( const isWechatGroup = !!(currentContract as any)?.chatroomId;
`✅ 手动AI回复成功 [${generationId}]:`,
messageContent?.content, // 根据接待类型处理AI回复
); if (aiType === 2 && aiResponseContent) {
// AI接管模式直接发送消息不经过MessageEnter组件
const messageId = +Date.now();
// 构造本地消息对象
const localMessage: ChatRecord = {
id: messageId,
wechatAccountId: currentContract.wechatAccountId,
wechatFriendId: isWechatGroup ? 0 : currentContract.id,
wechatChatroomId: isWechatGroup ? currentContract.id : 0,
tenantId: 0,
accountId: 0,
synergyAccountId: 0,
content: aiResponseContent,
msgType: 1,
msgSubType: 0,
msgSvrId: "",
isSend: true,
createTime: new Date().toISOString(),
isDeleted: false,
deleteTime: "",
sendStatus: 1,
wechatTime: Date.now(),
origin: 0,
msgId: 0,
recalled: false,
seq: messageId,
};
// 添加到消息列表
state.addMessage(localMessage);
// 直接发送消息
const { sendCommand } = useWebSocketStore.getState();
sendCommand("CmdSendMessage", {
wechatAccountId: currentContract.wechatAccountId,
wechatChatroomId: isWechatGroup ? currentContract.id : 0,
wechatFriendId: isWechatGroup ? 0 : currentContract.id,
msgSubType: 0,
msgType: 1,
content: aiResponseContent,
seq: messageId,
});
state.updateIsLoadingAiChat(false);
console.log(
`✅ 手动AI接管模式直接发送消息 [${generationId}]:`,
aiResponseContent,
);
} else if (aiType === 1) {
// AI辅助模式设置quoteMessageContent让MessageEnter组件填充输入框
state.updateQuoteMessageContent(aiResponseContent);
state.updateIsLoadingAiChat(false);
console.log(
`✅ 手动AI辅助模式填充输入框 [${generationId}]:`,
aiResponseContent,
);
} else {
// 其他情况
state.updateIsLoadingAiChat(false);
}
// 清除当前生成ID // 清除当前生成ID
currentAiGenerationId = null; currentAiGenerationId = null;
@@ -837,15 +898,85 @@ export const useWeChatStore = create<WeChatState>()(
return; return;
} }
// 附加生成ID到回复内容 // 获取当前接待类型
set(() => ({ const aiType = (currentContract as any)?.aiType || 0; // 0=人工, 1=AI辅助, 2=AI接管
quoteMessageContent: messageContent?.content || "", const aiResponseContent = messageContent?.content || "";
isLoadingAiChat: false,
})); // 根据接待类型处理AI回复
console.log( if (aiType === 2 && aiResponseContent) {
`✅ AI回复成功 [${generationId}]:`, // AI接管模式直接发送消息不经过MessageEnter组件
messageContent?.content, const messageId = +Date.now();
);
// 构造本地消息对象
const localMessage: ChatRecord = {
id: messageId,
wechatAccountId: currentContract.wechatAccountId,
wechatFriendId: isWechatGroup ? 0 : currentContract.id,
wechatChatroomId: isWechatGroup
? currentContract.id
: 0,
tenantId: 0,
accountId: 0,
synergyAccountId: 0,
content: aiResponseContent,
msgType: 1,
msgSubType: 0,
msgSvrId: "",
isSend: true,
createTime: new Date().toISOString(),
isDeleted: false,
deleteTime: "",
sendStatus: 1,
wechatTime: Date.now(),
origin: 0,
msgId: 0,
recalled: false,
seq: messageId,
};
// 添加到消息列表
set(state => ({
currentMessages: [
...state.currentMessages,
localMessage,
],
isLoadingAiChat: false,
}));
// 直接发送消息
const { sendCommand } = useWebSocketStore.getState();
sendCommand("CmdSendMessage", {
wechatAccountId: currentContract.wechatAccountId,
wechatChatroomId: isWechatGroup
? currentContract.id
: 0,
wechatFriendId: isWechatGroup ? 0 : currentContract.id,
msgSubType: 0,
msgType: 1,
content: aiResponseContent,
seq: messageId,
});
console.log(
`✅ AI接管模式直接发送消息 [${generationId}]:`,
aiResponseContent,
);
} else if (aiType === 1) {
// AI辅助模式设置quoteMessageContent让MessageEnter组件填充输入框
set(() => ({
quoteMessageContent: aiResponseContent,
isLoadingAiChat: false,
}));
console.log(
`✅ AI辅助模式填充输入框 [${generationId}]:`,
aiResponseContent,
);
} else {
// 其他情况
set(() => ({
isLoadingAiChat: false,
}));
}
// 清除当前生成ID // 清除当前生成ID
currentAiGenerationId = null; currentAiGenerationId = null;

View File

@@ -8,17 +8,23 @@ import { Modal } from "antd";
import { useCustomerStore, updateCustomerList } from "../weChat/customer"; import { useCustomerStore, updateCustomerList } from "../weChat/customer";
// 消息处理器类型定义 // 消息处理器类型定义
type MessageHandler = (message: WebSocketMessage) => void; type MessageHandler = (message: WebSocketMessage) => void;
const addMessage = useWeChatStore.getState().addMessage;
const recallMessage = useWeChatStore.getState().recallMessage; // 延迟获取 store 方法,避免循环依赖问题
const receivedMsg = useWeChatStore.getState().receivedMsg; const getWeChatStoreMethods = () => {
const findMessageBySeq = useWeChatStore.getState().findMessageBySeq; const state = useWeChatStore.getState();
const findMessageById = useWeChatStore.getState().findMessageById; return {
const updateMessage = useWeChatStore.getState().updateMessage; addMessage: state.addMessage,
const updateMomentCommonLoading = recallMessage: state.recallMessage,
useWeChatStore.getState().updateMomentCommonLoading; receivedMsg: state.receivedMsg,
const addMomentCommon = useWeChatStore.getState().addMomentCommon; findMessageBySeq: state.findMessageBySeq,
const setFileDownloadUrl = useWeChatStore.getState().setFileDownloadUrl; findMessageById: state.findMessageById,
const setFileDownloading = useWeChatStore.getState().setFileDownloading; updateMessage: state.updateMessage,
updateMomentCommonLoading: state.updateMomentCommonLoading,
addMomentCommon: state.addMomentCommon,
setFileDownloadUrl: state.setFileDownloadUrl,
setFileDownloading: state.setFileDownloading,
};
};
// 消息处理器映射 // 消息处理器映射
const messageHandlers: Record<string, MessageHandler> = { const messageHandlers: Record<string, MessageHandler> = {
// 微信账号存活状态响应 // 微信账号存活状态响应
@@ -46,6 +52,7 @@ const messageHandlers: Record<string, MessageHandler> = {
}, },
// 发送消息响应 // 发送消息响应
CmdSendMessageResp: message => { CmdSendMessageResp: message => {
const { findMessageBySeq, updateMessage } = getWeChatStoreMethods();
const msg = findMessageBySeq(message.seq); const msg = findMessageBySeq(message.seq);
if (msg) { if (msg) {
updateMessage(message.seq, { updateMessage(message.seq, {
@@ -55,6 +62,7 @@ const messageHandlers: Record<string, MessageHandler> = {
} }
}, },
CmdSendMessageResult: message => { CmdSendMessageResult: message => {
const { updateMessage } = getWeChatStoreMethods();
updateMessage(message.friendMessageId || message.chatroomMessageId, { updateMessage(message.friendMessageId || message.chatroomMessageId, {
sendStatus: 0, sendStatus: 0,
}); });
@@ -68,6 +76,7 @@ const messageHandlers: Record<string, MessageHandler> = {
//收到消息 //收到消息
CmdNewMessage: (message: Messages) => { CmdNewMessage: (message: Messages) => {
// 处理消息本身 // 处理消息本身
const { receivedMsg } = getWeChatStoreMethods();
receivedMsg(message.friendMessage || message.chatroomMessage); receivedMsg(message.friendMessage || message.chatroomMessage);
// 触发会话列表更新事件 // 触发会话列表更新事件
@@ -107,6 +116,7 @@ const messageHandlers: Record<string, MessageHandler> = {
// setVideoUrl(message.friendMessageId, message.url); // setVideoUrl(message.friendMessageId, message.url);
}, },
CmdDownloadFileResult: message => { CmdDownloadFileResult: message => {
const { setFileDownloadUrl, setFileDownloading } = getWeChatStoreMethods();
const messageId = message.friendMessageId || message.chatroomMessageId; const messageId = message.friendMessageId || message.chatroomMessageId;
if (!messageId) { if (!messageId) {
@@ -124,6 +134,8 @@ const messageHandlers: Record<string, MessageHandler> = {
}, },
CmdFetchMomentResult: message => { CmdFetchMomentResult: message => {
const { addMomentCommon, updateMomentCommonLoading } =
getWeChatStoreMethods();
addMomentCommon(message.result); addMomentCommon(message.result);
updateMomentCommonLoading(false); updateMomentCommonLoading(false);
}, },
@@ -162,16 +174,18 @@ const messageHandlers: Record<string, MessageHandler> = {
//撤回消息 //撤回消息
CmdMessageRecalled: message => { CmdMessageRecalled: message => {
const { recallMessage } = getWeChatStoreMethods();
const MessageId = message.friendMessageId || message.chatroomMessageId; const MessageId = message.friendMessageId || message.chatroomMessageId;
recallMessage(MessageId); recallMessage(MessageId);
}, },
CmdVoiceToTextResult: message => { CmdVoiceToTextResult: message => {
const { findMessageById, updateMessage } = getWeChatStoreMethods();
const msg = findMessageById( const msg = findMessageById(
message.friendMessageId || message.chatroomMessageId, message.friendMessageId || message.chatroomMessageId,
); );
const content = JSON.parse(msg.content);
if (msg) { if (msg) {
const content = JSON.parse(msg.content);
updateMessage(msg.id, { updateMessage(msg.id, {
content: JSON.stringify({ content: JSON.stringify({
...content, ...content,

View File

@@ -2,7 +2,6 @@ import { createPersistStore } from "@/store/createPersistStore";
import { useUserStore } from "../user"; import { useUserStore } from "../user";
import { useCkChatStore } from "@/store/module/ckchat/ckchat"; import { useCkChatStore } from "@/store/module/ckchat/ckchat";
import { useCustomerStore } from "@/store/module/weChat/customer"; import { useCustomerStore } from "@/store/module/weChat/customer";
const { getAccountId } = useCkChatStore.getState();
import { msgManageCore } from "./msgManage"; import { msgManageCore } from "./msgManage";
// WebSocket消息类型 // WebSocket消息类型
export interface WebSocketMessage { export interface WebSocketMessage {
@@ -141,6 +140,7 @@ export const useWebSocketStore = createPersistStore<WebSocketState>(
} }
// 构建WebSocket URL // 构建WebSocket URL
const { getAccountId } = useCkChatStore.getState();
const params = new URLSearchParams({ const params = new URLSearchParams({
client: fullConfig.client.toString(), client: fullConfig.client.toString(),
accountId: getAccountId().toString(), accountId: getAccountId().toString(),
@@ -330,6 +330,7 @@ export const useWebSocketStore = createPersistStore<WebSocketState>(
// console.log("WebSocket连接成功"); // console.log("WebSocket连接成功");
const { token2 } = useUserStore.getState(); const { token2 } = useUserStore.getState();
const { getAccountId } = useCkChatStore.getState();
// 发送登录命令 // 发送登录命令
if (currentState.config) { if (currentState.config) {
currentState.sendCommand("CmdSignIn", { currentState.sendCommand("CmdSignIn", {