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