优化AI消息处理逻辑,区分AI辅助模式与AI接管模式,确保在接管模式下直接发送消息而不经过MessageEnter组件。同时,调整相关组件的状态管理,提升代码可读性和维护性。
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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", {
|
||||
|
||||
Reference in New Issue
Block a user