2025-09-03 14:52:32 +08:00
|
|
|
|
import { create } from "zustand";
|
|
|
|
|
|
import { persist } from "zustand/middleware";
|
|
|
|
|
|
import { getChatMessages } 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";
|
2025-09-03 17:47:43 +08:00
|
|
|
|
import {
|
|
|
|
|
|
addChatSession,
|
|
|
|
|
|
updateChatSession,
|
2025-09-03 18:33:05 +08:00
|
|
|
|
useCkChatStore,
|
2025-09-03 17:47:43 +08:00
|
|
|
|
} from "@/store/module/ckchat/ckchat";
|
2025-09-03 16:06:12 +08:00
|
|
|
|
|
2025-09-03 14:52:32 +08:00
|
|
|
|
export const useWeChatStore = create<WeChatState>()(
|
|
|
|
|
|
persist(
|
|
|
|
|
|
(set, get) => ({
|
|
|
|
|
|
// 初始状态
|
|
|
|
|
|
currentContract: null,
|
|
|
|
|
|
currentMessages: [],
|
|
|
|
|
|
messagesLoading: false,
|
|
|
|
|
|
|
|
|
|
|
|
// Actions
|
2025-09-03 18:33:05 +08:00
|
|
|
|
setCurrentContact: (
|
|
|
|
|
|
contract: ContractData | weChatGroup,
|
|
|
|
|
|
isExist?: boolean,
|
|
|
|
|
|
) => {
|
2025-09-03 14:52:32 +08:00
|
|
|
|
const state = useWeChatStore.getState();
|
|
|
|
|
|
// 切换联系人时清空当前消息,等待重新加载
|
|
|
|
|
|
set({ currentMessages: [] });
|
|
|
|
|
|
clearUnreadCount([contract.id]).then(() => {
|
2025-09-03 18:33:05 +08:00
|
|
|
|
if (isExist) {
|
|
|
|
|
|
updateChatSession({ ...contract, unreadCount: 0 });
|
|
|
|
|
|
} else {
|
|
|
|
|
|
addChatSession(contract);
|
|
|
|
|
|
}
|
2025-09-03 14:52:32 +08:00
|
|
|
|
set({ currentContract: contract });
|
|
|
|
|
|
updateConfig({
|
|
|
|
|
|
id: contract.id,
|
|
|
|
|
|
config: { chat: true },
|
|
|
|
|
|
});
|
|
|
|
|
|
state.loadChatMessages(contract);
|
|
|
|
|
|
});
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
loadChatMessages: async contact => {
|
|
|
|
|
|
set({ messagesLoading: true });
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
const params: any = {
|
|
|
|
|
|
wechatAccountId: contact.wechatAccountId,
|
|
|
|
|
|
From: 1,
|
|
|
|
|
|
To: 4704624000000,
|
|
|
|
|
|
Count: 10,
|
|
|
|
|
|
olderData: true,
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
if ("chatroomId" in contact && contact.chatroomId) {
|
2025-09-04 15:00:29 +08:00
|
|
|
|
params.wechatChatroomId = contact.id;
|
2025-09-03 14:52:32 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
params.wechatFriendId = contact.id;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const messages = await getChatMessages(params);
|
2025-09-04 10:47:57 +08:00
|
|
|
|
set({ currentMessages: messages || [] });
|
2025-09-03 14:52:32 +08:00
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error("获取聊天消息失败:", error);
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
set({ messagesLoading: false });
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
setMessageLoading: loading => {
|
2025-09-03 15:08:29 +08:00
|
|
|
|
set({ messagesLoading: Boolean(loading) });
|
2025-09-03 14:52:32 +08:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
addMessage: message => {
|
|
|
|
|
|
set(state => ({
|
|
|
|
|
|
currentMessages: [...state.currentMessages, message],
|
|
|
|
|
|
}));
|
|
|
|
|
|
},
|
|
|
|
|
|
|
2025-09-03 17:47:43 +08:00
|
|
|
|
receivedMsg: message => {
|
|
|
|
|
|
const currentContract = useWeChatStore.getState().currentContract;
|
|
|
|
|
|
if (
|
|
|
|
|
|
currentContract &&
|
|
|
|
|
|
currentContract.wechatAccountId == message.wechatAccountId &&
|
|
|
|
|
|
currentContract.id == message.wechatFriendId
|
|
|
|
|
|
) {
|
|
|
|
|
|
set(state => ({
|
|
|
|
|
|
currentMessages: [...state.currentMessages, message],
|
|
|
|
|
|
}));
|
|
|
|
|
|
} else {
|
|
|
|
|
|
//更新消息列表unread数值,根据接收的++1 这样
|
2025-09-03 18:33:05 +08:00
|
|
|
|
const chatSessions = useCkChatStore.getState().chatSessions;
|
2025-09-03 17:47:43 +08:00
|
|
|
|
const session = chatSessions.find(
|
|
|
|
|
|
item => item.id == message.wechatFriendId,
|
|
|
|
|
|
);
|
2025-09-03 18:33:05 +08:00
|
|
|
|
if (session) {
|
|
|
|
|
|
session.unreadCount = Number(session.unreadCount) + 1;
|
|
|
|
|
|
updateChatSession(session);
|
|
|
|
|
|
}
|
2025-09-03 17:47:43 +08:00
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
2025-09-03 14:52:32 +08:00
|
|
|
|
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,
|
|
|
|
|
|
|
2025-09-03 16:06:12 +08:00
|
|
|
|
// 视频消息处理方法
|
|
|
|
|
|
setVideoLoading: (messageId: number, isLoading: boolean) => {
|
2025-09-03 15:08:29 +08:00
|
|
|
|
set(state => ({
|
|
|
|
|
|
currentMessages: state.currentMessages.map(msg => {
|
2025-09-03 16:06:12 +08:00
|
|
|
|
if (msg.id === messageId) {
|
2025-09-03 15:08:29 +08:00
|
|
|
|
try {
|
2025-09-03 16:06:12 +08:00
|
|
|
|
const content = JSON.parse(msg.content);
|
|
|
|
|
|
// 更新加载状态
|
|
|
|
|
|
const updatedContent = { ...content, isLoading };
|
2025-09-03 15:08:29 +08:00
|
|
|
|
return {
|
|
|
|
|
|
...msg,
|
2025-09-03 16:06:12 +08:00
|
|
|
|
content: JSON.stringify(updatedContent),
|
2025-09-03 15:08:29 +08:00
|
|
|
|
};
|
|
|
|
|
|
} catch (e) {
|
2025-09-03 16:06:12 +08:00
|
|
|
|
console.error("更新视频加载状态失败:", e);
|
|
|
|
|
|
return msg;
|
2025-09-03 15:08:29 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return msg;
|
|
|
|
|
|
}),
|
|
|
|
|
|
}));
|
|
|
|
|
|
},
|
|
|
|
|
|
|
2025-09-03 16:06:12 +08:00
|
|
|
|
setVideoUrl: (messageId: number, videoUrl: string) => {
|
2025-09-03 15:08:29 +08:00
|
|
|
|
set(state => ({
|
|
|
|
|
|
currentMessages: state.currentMessages.map(msg => {
|
2025-09-03 16:06:12 +08:00
|
|
|
|
if (msg.id === messageId) {
|
2025-09-03 15:08:29 +08:00
|
|
|
|
try {
|
2025-09-03 16:06:12 +08:00
|
|
|
|
const content = JSON.parse(msg.content);
|
|
|
|
|
|
// 检查视频是否已经下载完毕,避免重复更新
|
|
|
|
|
|
if (content.videoUrl && content.videoUrl === videoUrl) {
|
|
|
|
|
|
console.log("视频已下载,跳过重复更新:", messageId);
|
|
|
|
|
|
return msg;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 设置视频URL并清除加载状态
|
|
|
|
|
|
const updatedContent = {
|
|
|
|
|
|
...content,
|
|
|
|
|
|
videoUrl,
|
|
|
|
|
|
isLoading: false,
|
|
|
|
|
|
};
|
2025-09-03 15:08:29 +08:00
|
|
|
|
return {
|
|
|
|
|
|
...msg,
|
2025-09-03 16:06:12 +08:00
|
|
|
|
content: JSON.stringify(updatedContent),
|
2025-09-03 15:08:29 +08:00
|
|
|
|
};
|
|
|
|
|
|
} catch (e) {
|
2025-09-03 16:06:12 +08:00
|
|
|
|
console.error("更新视频URL失败:", e);
|
|
|
|
|
|
return msg;
|
2025-09-03 15:08:29 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return msg;
|
|
|
|
|
|
}),
|
|
|
|
|
|
}));
|
|
|
|
|
|
},
|
2025-09-03 14:52:32 +08:00
|
|
|
|
clearAllData: () => {
|
|
|
|
|
|
set({
|
|
|
|
|
|
currentContract: null,
|
|
|
|
|
|
currentMessages: [],
|
|
|
|
|
|
messagesLoading: false,
|
|
|
|
|
|
});
|
|
|
|
|
|
},
|
|
|
|
|
|
}),
|
|
|
|
|
|
{
|
|
|
|
|
|
name: "wechat-storage",
|
|
|
|
|
|
partialize: state => ({
|
2025-09-03 16:49:45 +08:00
|
|
|
|
// currentContract 不做持久化,登录和页面刷新时直接清空
|
2025-09-03 14:52:32 +08:00
|
|
|
|
}),
|
|
|
|
|
|
},
|
|
|
|
|
|
),
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
// 导出便捷的选择器函数
|
|
|
|
|
|
export const useCurrentContact = () =>
|
|
|
|
|
|
useWeChatStore(state => state.currentContract);
|
|
|
|
|
|
export const useCurrentMessages = () =>
|
|
|
|
|
|
useWeChatStore(state => state.currentMessages);
|
|
|
|
|
|
export const useMessagesLoading = () =>
|
|
|
|
|
|
useWeChatStore(state => state.messagesLoading);
|