diff --git a/Touchkebao/src/pages/pc/ckbox/weChat/components/ChatWindow/components/MessageEnter/index.tsx b/Touchkebao/src/pages/pc/ckbox/weChat/components/ChatWindow/components/MessageEnter/index.tsx index 9135624f..e057a728 100644 --- a/Touchkebao/src/pages/pc/ckbox/weChat/components/ChatWindow/components/MessageEnter/index.tsx +++ b/Touchkebao/src/pages/pc/ckbox/weChat/components/ChatWindow/components/MessageEnter/index.tsx @@ -176,19 +176,21 @@ const MessageEnter: React.FC = ({ 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) { diff --git a/Touchkebao/src/store/module/weChat/weChat.ts b/Touchkebao/src/store/module/weChat/weChat.ts index 89a001a9..e06e27cd 100644 --- a/Touchkebao/src/store/module/weChat/weChat.ts +++ b/Touchkebao/src/store/module/weChat/weChat.ts @@ -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()( 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; diff --git a/Touchkebao/src/store/module/websocket/msgManage.ts b/Touchkebao/src/store/module/websocket/msgManage.ts index 2fcaceb3..a2f31d98 100644 --- a/Touchkebao/src/store/module/websocket/msgManage.ts +++ b/Touchkebao/src/store/module/websocket/msgManage.ts @@ -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 = { // 微信账号存活状态响应 @@ -46,6 +52,7 @@ const messageHandlers: Record = { }, // 发送消息响应 CmdSendMessageResp: message => { + const { findMessageBySeq, updateMessage } = getWeChatStoreMethods(); const msg = findMessageBySeq(message.seq); if (msg) { updateMessage(message.seq, { @@ -55,6 +62,7 @@ const messageHandlers: Record = { } }, CmdSendMessageResult: message => { + const { updateMessage } = getWeChatStoreMethods(); updateMessage(message.friendMessageId || message.chatroomMessageId, { sendStatus: 0, }); @@ -68,6 +76,7 @@ const messageHandlers: Record = { //收到消息 CmdNewMessage: (message: Messages) => { // 处理消息本身 + const { receivedMsg } = getWeChatStoreMethods(); receivedMsg(message.friendMessage || message.chatroomMessage); // 触发会话列表更新事件 @@ -107,6 +116,7 @@ const messageHandlers: Record = { // 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 = { }, CmdFetchMomentResult: message => { + const { addMomentCommon, updateMomentCommonLoading } = + getWeChatStoreMethods(); addMomentCommon(message.result); updateMomentCommonLoading(false); }, @@ -162,16 +174,18 @@ const messageHandlers: Record = { //撤回消息 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, diff --git a/Touchkebao/src/store/module/websocket/websocket.ts b/Touchkebao/src/store/module/websocket/websocket.ts index 57ed7f15..59a2fcf3 100644 --- a/Touchkebao/src/store/module/websocket/websocket.ts +++ b/Touchkebao/src/store/module/websocket/websocket.ts @@ -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( } // 构建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( // console.log("WebSocket连接成功"); const { token2 } = useUserStore.getState(); + const { getAccountId } = useCkChatStore.getState(); // 发送登录命令 if (currentState.config) { currentState.sendCommand("CmdSignIn", {