Files
cunkebao_v3/Cunkebao/src/store/module/weChat/weChat.ts
超级老白兔 51b1918f72 feat(微信聊天): 添加聊天记录搜索和客户转接功能
- 在微信聊天界面新增聊天记录搜索组件,支持按时间和关键词搜索
- 添加客户转接功能组件,支持选择目标客服和添加附言
- 实现一键转回功能
- 添加相关API接口和状态管理
- 配置antd中文语言环境和dayjs本地化
2025-09-10 16:52:28 +08:00

285 lines
8.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { create } from "zustand";
import { persist } from "zustand/middleware";
import {
getChatMessages,
getChatroomMessages,
getGroupMembers,
} from "@/pages/pc/ckbox/api";
import { WeChatState } from "./weChat.data";
import { clearUnreadCount, updateConfig } from "@/pages/pc/ckbox/api";
import { ContractData, weChatGroup } from "@/pages/pc/ckbox/data";
import { weChatGroupService, contractService } from "@/utils/db";
import {
addChatSession,
updateChatSession,
useCkChatStore,
} from "@/store/module/ckchat/ckchat";
export const useWeChatStore = create<WeChatState>()(
persist(
(set, get) => ({
// 初始状态
currentContract: null,
currentMessages: [],
messagesLoading: false,
isLoadingData: false,
currentGroupMembers: [],
// Actions
setCurrentContact: (
contract: ContractData | weChatGroup,
isExist?: boolean,
) => {
const state = useWeChatStore.getState();
// 切换联系人时清空当前消息,等待重新加载
set({ currentMessages: [] });
clearUnreadCount([contract.id]).then(() => {
if (isExist) {
updateChatSession({ ...contract, unreadCount: 0 });
} else {
addChatSession(contract);
}
set({ currentContract: contract });
updateConfig({
id: contract.id,
config: { chat: true },
});
state.loadChatMessages(true, 4704624000000);
});
},
loadChatMessages: async (Init: boolean, To?: number) => {
const state = useWeChatStore.getState();
const contact = state.currentContract;
set({ messagesLoading: true });
set({ isLoadingData: Init });
try {
const params: any = {
wechatAccountId: contact.wechatAccountId,
From: 1,
To: To || +new Date(),
Count: 5,
olderData: true,
};
if ("chatroomId" in contact && contact.chatroomId) {
params.wechatChatroomId = contact.id;
const messages = await getChatroomMessages(params);
const currentGroupMembers = await getGroupMembers({
id: contact.id,
});
if (Init) {
set({ currentMessages: messages || [], currentGroupMembers });
} else {
set({
currentMessages: [
...(messages || []),
...state.currentMessages,
],
});
}
} else {
params.wechatFriendId = contact.id;
const messages = await getChatMessages(params);
if (Init) {
set({ currentMessages: messages || [] });
} else {
set({
currentMessages: [
...(messages || []),
...state.currentMessages,
],
});
}
}
set({ messagesLoading: false });
} catch (error) {
console.error("获取聊天消息失败:", error);
} finally {
set({ messagesLoading: false });
}
},
SearchMessage: async ({
From = 1,
To = 4704624000000,
keyword = "",
Count = 20,
}: {
From: number;
To: number;
keyword: string;
Count?: number;
}) => {
const state = useWeChatStore.getState();
const contact = state.currentContract;
set({ messagesLoading: true });
try {
const params: any = {
wechatAccountId: contact.wechatAccountId,
From,
To,
keyword,
Count,
olderData: true,
};
if ("chatroomId" in contact && contact.chatroomId) {
params.wechatChatroomId = contact.id;
const messages = await getChatroomMessages(params);
const currentGroupMembers = await getGroupMembers({
id: contact.id,
});
set({ currentMessages: messages || [], currentGroupMembers });
} else {
params.wechatFriendId = contact.id;
const messages = await getChatMessages(params);
set({ currentMessages: messages || [] });
}
set({ messagesLoading: false });
} catch (error) {
console.error("获取聊天消息失败:", error);
} finally {
set({ messagesLoading: false });
}
},
setMessageLoading: loading => {
set({ messagesLoading: Boolean(loading) });
},
addMessage: message => {
set(state => ({
currentMessages: [...state.currentMessages, message],
}));
},
receivedMsg: async message => {
const currentContract = useWeChatStore.getState().currentContract;
//判断群还是好友
const getMessageId =
message?.wechatChatroomId || message.wechatFriendId;
const isWechatGroup = message?.wechatChatroomId;
//当前选中聊天的群或好友
if (currentContract && currentContract.id == getMessageId) {
set(state => ({
currentMessages: [...state.currentMessages, message],
}));
} else {
//更新消息列表unread数值根据接收的++1 这样
const chatSessions = useCkChatStore.getState().chatSessions;
const session = chatSessions.find(item => item.id == getMessageId);
if (session) {
session.unreadCount = Number(session.unreadCount) + 1;
updateChatSession(session);
} else {
if (isWechatGroup) {
const [group] = await weChatGroupService.findByIds(getMessageId);
if (group) {
addChatSession({
...group,
unreadCount: 1,
});
}
} else {
const [user] = await contractService.findByIds(getMessageId);
addChatSession({
...user,
unreadCount: 1,
});
}
}
}
},
updateMessage: (messageId, updates) => {
set(state => ({
currentMessages: state.currentMessages.map(msg =>
msg.id === messageId ? { ...msg, ...updates } : msg,
),
}));
},
// 便捷选择器
getCurrentContact: () => get().currentContract,
getCurrentMessages: () => get().currentMessages,
getMessagesLoading: () => get().messagesLoading,
// 视频消息处理方法
setVideoLoading: (messageId: number, isLoading: boolean) => {
set(state => ({
currentMessages: state.currentMessages.map(msg => {
if (msg.id === messageId) {
try {
const content = JSON.parse(msg.content);
// 更新加载状态
const updatedContent = { ...content, isLoading };
return {
...msg,
content: JSON.stringify(updatedContent),
};
} catch (e) {
console.error("更新视频加载状态失败:", e);
return msg;
}
}
return msg;
}),
}));
},
setVideoUrl: (messageId: number, videoUrl: string) => {
set(state => ({
currentMessages: state.currentMessages.map(msg => {
if (msg.id === messageId) {
try {
const content = JSON.parse(msg.content);
// 检查视频是否已经下载完毕,避免重复更新
if (content.videoUrl && content.videoUrl === videoUrl) {
console.log("视频已下载,跳过重复更新:", messageId);
return msg;
}
// 设置视频URL并清除加载状态
const updatedContent = {
...content,
videoUrl,
isLoading: false,
};
return {
...msg,
content: JSON.stringify(updatedContent),
};
} catch (e) {
console.error("更新视频URL失败:", e);
return msg;
}
}
return msg;
}),
}));
},
clearAllData: () => {
set({
currentContract: null,
currentMessages: [],
messagesLoading: false,
});
},
}),
{
name: "wechat-storage",
partialize: state => ({
// currentContract 不做持久化,登录和页面刷新时直接清空
}),
},
),
);
// 导出便捷的选择器函数
export const useCurrentContact = () =>
useWeChatStore(state => state.currentContract);
export const useCurrentMessages = () =>
useWeChatStore(state => state.currentMessages);
export const useMessagesLoading = () =>
useWeChatStore(state => state.messagesLoading);