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

View File

@@ -18,6 +18,7 @@ import {
getFriendInjectConfig,
} from "@/pages/pc/ckbox/api";
import { ChatRecord, ContractData, weChatGroup } from "@/pages/pc/ckbox/data";
import { useWebSocketStore } from "@/store/module/websocket/websocket";
/**
* AI请求防抖管理
@@ -392,13 +393,73 @@ export const manualTriggerAi = async () => {
return false;
}
// 更新AI回复内容
state.updateQuoteMessageContent(messageContent?.content || "");
state.updateIsLoadingAiChat(false);
console.log(
`✅ 手动AI回复成功 [${generationId}]:`,
messageContent?.content,
);
// 获取当前接待类型
const aiType = (currentContract as any)?.aiType || 0; // 0=人工, 1=AI辅助, 2=AI接管
const aiResponseContent = messageContent?.content || "";
const isWechatGroup = !!(currentContract as any)?.chatroomId;
// 根据接待类型处理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
currentAiGenerationId = null;
@@ -837,15 +898,85 @@ export const useWeChatStore = create<WeChatState>()(
return;
}
// 附加生成ID到回复内容
set(() => ({
quoteMessageContent: messageContent?.content || "",
isLoadingAiChat: false,
}));
console.log(
`✅ AI回复成功 [${generationId}]:`,
messageContent?.content,
);
// 获取当前接待类型
const aiType = (currentContract as any)?.aiType || 0; // 0=人工, 1=AI辅助, 2=AI接管
const aiResponseContent = 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,
};
// 添加到消息列表
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
currentAiGenerationId = null;

View File

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

View File

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