274 lines
8.6 KiB
TypeScript
274 lines
8.6 KiB
TypeScript
//消息管理器
|
|
import { useWeChatStore } from "../weChat/weChat";
|
|
import { WebSocketMessage } from "./websocket";
|
|
import { deepCopy } from "@/utils/common";
|
|
import { Messages } from "./msg.data";
|
|
import { db } from "@/utils/db";
|
|
import { Modal } from "antd";
|
|
import { useCustomerStore, updateCustomerList } from "../weChat/customer";
|
|
import { dataProcessing, asyncMessageStatus } from "@/api/ai";
|
|
// 消息处理器类型定义
|
|
type MessageHandler = (message: WebSocketMessage) => void;
|
|
|
|
// 延迟获取 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> = {
|
|
// 微信账号存活状态响应
|
|
CmdRequestWechatAccountsAliveStatusResp: message => {
|
|
// console.log("微信账号存活状态响应", message);
|
|
// 获取客服列表
|
|
const customerList = deepCopy(useCustomerStore.getState().customerList);
|
|
const wechatAccountsAliveStatus = message.wechatAccountsAliveStatus || {};
|
|
|
|
// 遍历客服列表,更新在线状态
|
|
const updatedCustomerList = customerList.map(customer => ({
|
|
...customer,
|
|
isOnline: wechatAccountsAliveStatus[customer.id] || false,
|
|
}));
|
|
|
|
// 按在线状态排序,在线的排在前面
|
|
updatedCustomerList.sort((a, b) => {
|
|
if (a.isOnline && !b.isOnline) return -1;
|
|
if (!a.isOnline && b.isOnline) return 1;
|
|
return 0;
|
|
});
|
|
|
|
// 更新客服列表
|
|
updateCustomerList(updatedCustomerList);
|
|
},
|
|
// 发送消息响应
|
|
CmdSendMessageResp: (message: Messages) => {
|
|
const { findMessageBySeq, updateMessage } = getWeChatStoreMethods();
|
|
const msg = findMessageBySeq(message.seq);
|
|
|
|
//异步传新消息给数据库
|
|
goAsyncServiceData(message);
|
|
asyncMessageStatus({
|
|
messageId: message.friendMessage?.id || message.chatroomMessage?.id,
|
|
wechatFriendId: message.friendMessage?.wechatFriendId,
|
|
wechatChatroomId: message.chatroomMessage?.wechatChatroomId,
|
|
wechatAccountId:
|
|
message.friendMessage?.wechatAccountId ||
|
|
message.chatroomMessage?.wechatAccountId,
|
|
}).then(res => {
|
|
if (msg) {
|
|
console.log("CmdSendMessageResp 发送消息响应", res);
|
|
updateMessage(message.seq, {
|
|
sendStatus: 0,
|
|
id: message.friendMessage?.id || message.chatroomMessage?.id,
|
|
});
|
|
}
|
|
});
|
|
},
|
|
CmdSendMessageResult: message => {
|
|
console.log("CmdSendMessageResult 发送消息结果", message);
|
|
dataProcessing({
|
|
chatroomMessageId: message.chatroomMessageId,
|
|
friendMessageId: message.friendMessageId,
|
|
sendStatus: message.sendStatus,
|
|
type: "CmdSendMessageResult",
|
|
wechatAccountId: 1,
|
|
wechatTime: message?.wechatTime,
|
|
});
|
|
},
|
|
// 接收消息响应
|
|
CmdReceiveMessageResp: message => {
|
|
console.log("CmdReceiveMessageResp 接收消息响应", message);
|
|
// addMessage(message.friendMessage || message.chatroomMessage);
|
|
// 在这里添加具体的处理逻辑
|
|
},
|
|
//收到消息
|
|
CmdNewMessage: (message: Messages) => {
|
|
// 处理消息本身
|
|
const { receivedMsg } = getWeChatStoreMethods();
|
|
receivedMsg(message.friendMessage || message.chatroomMessage);
|
|
//异步传新消息给数据库
|
|
goAsyncServiceData(message);
|
|
// 触发会话列表更新事件
|
|
const msgData = message.friendMessage || message.chatroomMessage;
|
|
if (msgData) {
|
|
const sessionId = message.friendMessage
|
|
? message.friendMessage.wechatFriendId
|
|
: message.chatroomMessage?.wechatChatroomId;
|
|
const type = message.friendMessage ? "friend" : "group";
|
|
|
|
// 发送自定义事件通知MessageList组件
|
|
window.dispatchEvent(
|
|
new CustomEvent("chatMessageReceived", {
|
|
detail: {
|
|
message: msgData,
|
|
sessionId,
|
|
type,
|
|
},
|
|
}),
|
|
);
|
|
}
|
|
},
|
|
CmdFriendInfoChanged: () => {
|
|
// console.log("好友信息变更", message);
|
|
// 在这里添加具体的处理逻辑
|
|
},
|
|
|
|
// 登录响应
|
|
CmdSignInResp: message => {
|
|
console.log("登录响应", message);
|
|
// 在这里添加具体的处理逻辑
|
|
},
|
|
|
|
CmdDownloadVideoResult: message => {
|
|
// 在这里添加具体的处理逻辑
|
|
console.log("视频下载结果:", message);
|
|
// setVideoUrl(message.friendMessageId, message.url);
|
|
},
|
|
CmdDownloadFileResult: message => {
|
|
const { setFileDownloadUrl, setFileDownloading } = getWeChatStoreMethods();
|
|
const messageId = message.friendMessageId || message.chatroomMessageId;
|
|
|
|
if (!messageId) {
|
|
console.warn("文件下载结果缺少消息ID:", message);
|
|
return;
|
|
}
|
|
|
|
if (!message.url) {
|
|
console.warn("文件下载结果缺少URL:", message);
|
|
setFileDownloading(messageId, false);
|
|
return;
|
|
}
|
|
|
|
setFileDownloadUrl(messageId, message.url);
|
|
},
|
|
|
|
CmdFetchMomentResult: message => {
|
|
const { addMomentCommon, updateMomentCommonLoading } =
|
|
getWeChatStoreMethods();
|
|
addMomentCommon(message.result);
|
|
updateMomentCommonLoading(false);
|
|
},
|
|
|
|
CmdNotify: async (message: WebSocketMessage) => {
|
|
console.log("通知消息", message);
|
|
// 在这里添加具体的处理逻辑
|
|
if (["Auth failed", "Kicked out"].includes(message.notify)) {
|
|
// 避免重复弹窗
|
|
if ((window as any).__CKB_AUTH_FAILED_SHOWN__) {
|
|
return;
|
|
}
|
|
(window as any).__CKB_AUTH_FAILED_SHOWN__ = true;
|
|
|
|
Modal.warning({
|
|
title: "登录失效",
|
|
content: "认证已失效或账号在其他设备登录,请重新登录。",
|
|
okText: "重新登录",
|
|
onOk: async () => {
|
|
try {
|
|
// 被踢出时删除所有缓存数据
|
|
localStorage.clear();
|
|
await db.chatSessions.clear();
|
|
await db.contactsUnified.clear();
|
|
await db.contactLabelMap.clear();
|
|
await db.userLoginRecords.clear();
|
|
} finally {
|
|
(window as any).__CKB_AUTH_FAILED_SHOWN__ = false;
|
|
window.location.href = "/login";
|
|
}
|
|
},
|
|
});
|
|
return;
|
|
}
|
|
},
|
|
|
|
//撤回消息
|
|
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,
|
|
);
|
|
if (msg) {
|
|
const content = JSON.parse(msg.content);
|
|
updateMessage(msg.id, {
|
|
content: JSON.stringify({
|
|
...content,
|
|
text: message.text,
|
|
}),
|
|
});
|
|
}
|
|
},
|
|
};
|
|
//消息异步同步
|
|
const goAsyncServiceData = (message: Messages) => {
|
|
const chatroomMessages = message.chatroomMessage
|
|
? [message.chatroomMessage]
|
|
: null;
|
|
const friendMessages = message.friendMessage ? [message.friendMessage] : null;
|
|
dataProcessing({
|
|
chatroomMessage: chatroomMessages,
|
|
friendMessage: friendMessages,
|
|
type: "CmdNewMessage",
|
|
wechatAccountId:
|
|
message.friendMessage?.wechatAccountId ||
|
|
message.chatroomMessage?.wechatAccountId,
|
|
});
|
|
};
|
|
|
|
// 默认处理器
|
|
const defaultHandler: MessageHandler = message => {
|
|
console.log("未知消息类型", message.cmdType, message);
|
|
};
|
|
|
|
// 注册新的消息处理器
|
|
export const registerMessageHandler = (
|
|
cmdType: string,
|
|
handler: MessageHandler,
|
|
) => {
|
|
messageHandlers[cmdType] = handler;
|
|
};
|
|
|
|
// 移除消息处理器
|
|
export const unregisterMessageHandler = (cmdType: string) => {
|
|
delete messageHandlers[cmdType];
|
|
};
|
|
|
|
// 获取所有已注册的消息类型
|
|
export const getRegisteredMessageTypes = (): string[] => {
|
|
return Object.keys(messageHandlers);
|
|
};
|
|
|
|
// 消息管理核心函数
|
|
export const msgManageCore = (message: WebSocketMessage) => {
|
|
const cmdType = message.cmdType;
|
|
if (!cmdType) {
|
|
console.warn("消息缺少cmdType字段", message);
|
|
return;
|
|
}
|
|
|
|
// 获取对应的处理器,如果没有则使用默认处理器
|
|
const handler = messageHandlers[cmdType] || defaultHandler;
|
|
|
|
try {
|
|
handler(message);
|
|
} catch (error) {
|
|
console.error(`处理消息类型 ${cmdType} 时发生错误:`, error);
|
|
}
|
|
};
|