diff --git a/Touchkebao/src/store/module/dataCenter/index.data.ts b/Touchkebao/src/store/module/dataCenter/index.data.ts new file mode 100644 index 00000000..29a1f2d6 --- /dev/null +++ b/Touchkebao/src/store/module/dataCenter/index.data.ts @@ -0,0 +1,113 @@ +import { ChatRecord, ContractData, weChatGroup } from "@/pages/pc/ckbox/data"; +import { + CommentItem, + likeListItem, + FriendsCircleItem, +} from "@/pages/pc/ckbox/weChat/components/SidebarMenu/FriendsCicle/index.data"; + +/** + * 微信聊天状态管理接口定义 + * 包含聊天消息、联系人管理、朋友圈等功能的状态和方法 + */ +export interface WeChatState { + showChatRecordModel: boolean; + updateShowChatRecordModel: (show: boolean) => void; + aiQuoteMessageContent: number; + updateAiQuoteMessageContent: (message: number) => void; + quoteMessageContent: string; + updateQuoteMessageContent: (value: string) => void; + // ==================== Transmit Module =========Start=========== + /** 选中的聊天记录列表 */ + selectedChatRecords: ChatRecord[]; + /** 更新选中的聊天记录 */ + updateSelectedChatRecords: (message: ChatRecord[]) => void; + + /** 选中的联系人或群组列表 */ + selectedTransmitContact: ContractData[] | weChatGroup[]; + /** 更新选中的联系人或群组 */ + updateSelectedTransmitContact: ( + contact: ContractData[] | weChatGroup[], + ) => void; + + /** 转发弹窗开启状态 */ + openTransmitModal: boolean; + /** 更新转发弹窗状态 */ + updateTransmitModal: (open: boolean) => void; + // ==================== Transmit Module =========END=========== + + // ==================== 当前联系人管理 ==================== + /** 当前选中的联系人/群组 */ + currentContract: ContractData | weChatGroup | null; + /** 清空当前联系人 */ + clearCurrentContact: () => void; + /** 设置当前联系人 */ + setCurrentContact: ( + contract: ContractData | weChatGroup, + isExist?: boolean, + ) => void; + + // ==================== 聊天消息管理 ==================== + /** 当前聊天的消息列表 */ + currentMessages: ChatRecord[]; + /** 添加新消息 */ + addMessage: (message: ChatRecord) => void; + /** 更新指定消息 */ + updateMessage: (messageId: number, updates: Partial) => void; + /** 撤回指定消息 */ + recallMessage: (messageId: number) => void; + /** 消息加载状态 */ + messagesLoading: boolean; + /** 数据初始化加载状态 */ + isLoadingData: boolean; + /** 当前群组成员列表 */ + currentGroupMembers: any[]; + + // ==================== 界面状态管理 ==================== + /** 是否显示复选框 */ + showCheckbox: boolean; + /** 更新复选框显示状态 */ + updateShowCheckbox: (show: boolean) => void; + /** 进入模块类型 (common | multipleForwarding) */ + EnterModule: string; + /** 更新进入模块类型 */ + updateEnterModule: (module: string) => void; + + // ==================== 朋友圈相关 ==================== + /** 朋友圈数据列表 */ + MomentCommon: FriendsCircleItem[]; + /** 朋友圈数据加载状态 */ + MomentCommonLoading: boolean; + /** 清空朋友圈数据 */ + clearMomentCommon: () => void; + /** 添加朋友圈数据 */ + addMomentCommon: (moment: FriendsCircleItem[]) => void; + /** 更新朋友圈数据 */ + updateMomentCommon: (moments: FriendsCircleItem[]) => void; + /** 更新朋友圈加载状态 */ + updateMomentCommonLoading: (loading: boolean) => void; + /** 更新朋友圈点赞 */ + updateLikeMoment: (snsId: string, likeList: likeListItem[]) => void; + /** 更新朋友圈评论 */ + updateComment: (snsId: string, commentList: CommentItem[]) => void; + + // ==================== 消息加载方法 ==================== + /** 加载聊天消息 */ + loadChatMessages: (Init: boolean, To?: number) => Promise; + /** 搜索消息 */ + SearchMessage: (params: { + From: number; + To: number; + keyword: string; + Count?: number; + }) => Promise; + + // ==================== 视频消息处理 ==================== + /** 设置视频消息加载状态 */ + setVideoLoading: (messageId: number, isLoading: boolean) => void; + /** 设置视频消息URL */ + setVideoUrl: (messageId: number, videoUrl: string) => void; + + // ==================== 消息接收处理 ==================== + /** 接收新消息处理 */ + receivedMsg: (message: ChatRecord) => void; +} diff --git a/Touchkebao/src/store/module/dataCenter/index.ts b/Touchkebao/src/store/module/dataCenter/index.ts new file mode 100644 index 00000000..dcfd4b61 --- /dev/null +++ b/Touchkebao/src/store/module/dataCenter/index.ts @@ -0,0 +1,479 @@ +import { create } from "zustand"; +import { persist } from "zustand/middleware"; +import { + getChatMessages, + getChatroomMessages, + getGroupMembers, +} from "@/pages/pc/ckbox/api"; +import { WeChatState } from "./index.data"; + +import { + likeListItem, + CommentItem, +} from "@/pages/pc/ckbox/weChat/components/SidebarMenu/FriendsCicle/index.data"; +import { + clearUnreadCount1, + clearUnreadCount2, + updateConfig, + getFriendInjectConfig, +} from "@/pages/pc/ckbox/api"; +import { ChatRecord, ContractData, weChatGroup } from "@/pages/pc/ckbox/data"; +import { weChatGroupService, contractService } from "@/utils/db"; +import { + addChatSession, + updateChatSession, + useCkChatStore, + pinChatSessionToTop, +} from "@/store/module/ckchat/ckchat"; + +/** + * 微信聊天状态管理 Store + * 使用 Zustand 管理微信聊天相关的状态和操作 + */ +export const useWeChatStore = create()( + persist( + (set, get) => ({ + showChatRecordModel: false, + updateShowChatRecordModel: (show: boolean) => { + set({ showChatRecordModel: show }); + }, + //当前用户的ai接管状态 + aiQuoteMessageContent: 0, + updateAiQuoteMessageContent: (message: number) => { + set({ aiQuoteMessageContent: message }); + }, + quoteMessageContent: "", + updateQuoteMessageContent: (message: string) => { + set({ quoteMessageContent: message }); + }, + // ==================== Transmit Module =========Start=========== + /** 选中的聊天记录列表 */ + selectedChatRecords: [], + /** 更新选中的聊天记录 */ + updateSelectedChatRecords: (message: ChatRecord[]) => { + set({ selectedChatRecords: message }); + }, + + /** 选中的联系人或群组列表 */ + selectedTransmitContact: [], + /** 更新选中的联系人或群组 */ + updateSelectedTransmitContact: ( + contact: ContractData[] | weChatGroup[], + ) => { + set({ selectedTransmitContact: contact }); + }, + + /** 转发弹窗开启状态 */ + openTransmitModal: false, + /** 更新转发弹窗状态 */ + updateTransmitModal: (open: boolean) => { + set({ openTransmitModal: open }); + }, + // ==================== Transmit Module =========END=========== + + // ==================== 当前联系人管理状态 ==================== + /** 当前选中的联系人/群组 */ + currentContract: null, + /** 当前聊天的消息列表 */ + currentMessages: [], + + // ==================== 聊天消息管理方法 ==================== + /** 添加新消息到当前聊天 */ + addMessage: message => { + const { wechatChatroomId, wechatFriendId } = message; + const currentContract = get().currentContract; + if (currentContract) { + if ( + currentContract.id === wechatFriendId || + currentContract.id === wechatChatroomId + ) { + set(state => ({ + currentMessages: [...state.currentMessages, message], + })); + } + } + }, + /** 更新指定消息内容 */ + updateMessage: (messageId, updates) => { + set(state => ({ + currentMessages: state.currentMessages.map(msg => + msg.id === messageId ? { ...msg, ...updates } : msg, + ), + })); + }, + /** 撤回指定消息 */ + recallMessage: (messageId: number) => { + set(state => ({ + currentMessages: state.currentMessages.filter( + msg => msg.id !== messageId, + ), + })); + }, + + // ==================== 加载状态管理 ==================== + /** 消息加载状态 */ + messagesLoading: false, + /** 数据初始化加载状态 */ + isLoadingData: false, + /** 当前群组成员列表 */ + currentGroupMembers: [], + + // ==================== 界面状态管理 ==================== + /** 是否显示复选框 */ + showCheckbox: false, + /** 更新复选框显示状态 */ + updateShowCheckbox: (show: boolean) => { + set({ showCheckbox: show }); + }, + /** 进入模块类型 (common | multipleForwarding) */ + EnterModule: "common", + /** 更新进入模块类型 */ + updateEnterModule: (module: string) => { + set({ EnterModule: module }); + }, + + // ==================== 朋友圈相关状态 ==================== + /** 朋友圈数据列表 */ + MomentCommon: [], + /** 朋友圈数据加载状态 */ + MomentCommonLoading: false, + /** 更新朋友圈加载状态 */ + updateMomentCommonLoading: (loading: boolean) => { + set({ MomentCommonLoading: loading }); + }, + + // ==================== 当前联系人管理方法 ==================== + /** 清空当前联系人和消息 */ + clearCurrentContact: () => { + set({ currentContract: null, currentMessages: [] }); + }, + /** 设置当前联系人并加载相关数据 */ + setCurrentContact: ( + contract: ContractData | weChatGroup, + isExist?: boolean, + ) => { + const state = useWeChatStore.getState(); + // 切换联系人时清空当前消息,等待重新加载 + set({ currentMessages: [], openTransmitModal: false }); + + const params: any = {}; + + if (!contract.chatroomId) { + params.wechatFriendId = contract.id; + } else { + params.wechatChatroomId = contract.id; + } + //重置动作 + set({ showChatRecordModel: false }); + clearUnreadCount1(params); + clearUnreadCount2([contract.id]); + getFriendInjectConfig({ + friendId: contract.id, + wechatAccountId: contract.wechatAccountId, + }).then(result => { + set({ aiQuoteMessageContent: result }); + }); + if (isExist) { + updateChatSession({ + ...contract, + config: { 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: 20, + 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) }); + }, + + // ==================== 消息接收处理 ==================== + /** 接收新消息处理 */ + 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 { + // 更新其他聊天的未读消息数 + const chatSessions = useCkChatStore.getState().chatSessions; + const session = chatSessions.find(item => item.id == getMessageId); + if (session) { + session.config.unreadCount = Number(session.config.unreadCount) + 1; + updateChatSession(session); + // 将接收到新消息的会话置顶到列表顶部 + pinChatSessionToTop(getMessageId); + } else { + // 如果会话不存在,创建新会话 + if (isWechatGroup) { + const [group] = await weChatGroupService.findByIds(getMessageId); + if (group) { + addChatSession({ + ...group, + config: { unreadCount: 1 }, + }); + // 新创建的会话会自动添加到列表顶部,无需额外置顶 + } + } else { + const [user] = await contractService.findByIds(getMessageId); + addChatSession({ + ...user, + config: { unreadCount: 1 }, + }); + // 新创建的会话会自动添加到列表顶部,无需额外置顶 + } + } + } + }, + + // ==================== 便捷选择器方法 ==================== + /** 获取当前联系人 */ + 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; + }), + })); + }, + + /** 设置视频消息URL */ + 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, + }); + }, + + // ==================== 朋友圈管理方法 ==================== + /** 清空朋友圈数据 */ + clearMomentCommon: () => { + set({ MomentCommon: [] }); + }, + + /** 添加朋友圈数据 */ + addMomentCommon: moment => { + set(state => ({ + MomentCommon: [...state.MomentCommon, ...moment], + })); + }, + + /** 更新朋友圈数据 */ + updateMomentCommon: moments => { + set({ MomentCommon: moments }); + }, + + /** 更新朋友圈点赞 */ + updateLikeMoment: (snsId: string, likeList: likeListItem[]) => { + set(state => ({ + MomentCommon: state.MomentCommon.map(moment => + moment.snsId === snsId ? { ...moment, likeList } : moment, + ), + })); + }, + + /** 更新朋友圈评论 */ + updateComment: (snsId: string, commentList: CommentItem[]) => { + set(state => ({ + MomentCommon: state.MomentCommon.map(moment => + moment.snsId === snsId ? { ...moment, commentList } : moment, + ), + })); + }, + }), + { + name: "wechat-storage", + partialize: state => ({ + // currentContract 不做持久化,登录和页面刷新时直接清空 + }), + }, + ), +); + +// ==================== 便捷选择器导出 ==================== +/** 获取当前联系人的 Hook */ +export const useCurrentContact = () => + useWeChatStore(state => state.currentContract); +/** 获取当前消息列表的 Hook */ +export const useCurrentMessages = () => + useWeChatStore(state => state.currentMessages); +/** 获取消息加载状态的 Hook */ +export const useMessagesLoading = () => + useWeChatStore(state => state.messagesLoading); +/** 获取复选框显示状态的 Hook */ +export const useShowCheckbox = () => + useWeChatStore(state => state.showCheckbox);