/** * 聊天状态管理模块 * Requirements: 7.1, 7.2, 13.5 */ import { defineStore } from 'pinia' /** * 消息类型枚举 * 与后端 MessageType 枚举保持一致 */ export const MessageType = { TEXT: 1, // 文本消息 VOICE: 2, // 语音消息 IMAGE: 3, // 图片消息 EXCHANGE_WECHAT: 4, // 交换微信请求 EXCHANGE_WECHAT_RESULT: 5, // 交换微信结果 EXCHANGE_PHOTO: 6, // 交换照片请求 EXCHANGE_PHOTO_RESULT: 7 // 交换照片结果 } /** * 消息状态枚举 */ export const MessageStatus = { SENDING: 0, // 发送中 SENT: 1, // 已发送 DELIVERED: 2, // 已送达 READ: 3, // 已读 FAILED: 4 // 发送失败 } /** * 聊天会话定义 * @typedef {Object} ChatSession * @property {number} sessionId - 会话ID * @property {number} targetUserId - 对方用户ID * @property {string} targetNickname - 对方昵称 * @property {string} targetAvatar - 对方头像 * @property {string} lastMessage - 最后一条消息 * @property {string} lastMessageTime - 最后消息时间 * @property {number} unreadCount - 未读消息数 */ /** * 聊天消息定义 * @typedef {Object} ChatMessage * @property {number} id - 消息ID * @property {number} sessionId - 会话ID * @property {number} senderId - 发送者ID * @property {number} receiverId - 接收者ID * @property {number} messageType - 消息类型 * @property {string} content - 消息内容 * @property {number} status - 消息状态 * @property {string} createTime - 创建时间 * @property {boolean} isMine - 是否是自己发送的 */ export const useChatStore = defineStore('chat', { state: () => ({ // 会话列表 sessions: [], // 当前会话的消息列表 (按sessionId分组) messagesBySession: {}, // 当前活跃的会话ID currentSessionId: null, // 总未读消息数 totalUnreadCount: 0 }), getters: { /** * 获取当前会话的消息列表 */ currentMessages: (state) => { if (!state.currentSessionId) return [] return state.messagesBySession[state.currentSessionId] || [] }, /** * 是否有未读消息 * Property 22: Unread Badge Display - 未读消息数 > 0 时显示红点 */ hasUnreadMessages: (state) => state.totalUnreadCount > 0, /** * 获取指定会话的未读数 */ getSessionUnreadCount: (state) => (sessionId) => { const session = state.sessions.find(s => s.sessionId === sessionId) return session ? session.unreadCount : 0 }, /** * 判断是否应该显示未读徽章 * Property 22: Unread Badge Display * @param {number} unreadCount - 未读消息数 * @returns {boolean} */ shouldShowUnreadBadge: () => (unreadCount) => { return unreadCount > 0 } }, actions: { /** * 设置会话列表 * @param {Array} sessions - 会话列表 */ setSessions(sessions) { this.sessions = sessions this.updateTotalUnreadCount() }, /** * 更新总未读消息数 */ updateTotalUnreadCount() { this.totalUnreadCount = this.sessions.reduce( (total, session) => total + (session.unreadCount || 0), 0 ) }, /** * 设置当前会话 * @param {number} sessionId - 会话ID */ setCurrentSession(sessionId) { this.currentSessionId = sessionId }, /** * 设置会话的消息列表 * @param {number} sessionId - 会话ID * @param {Array} messages - 消息列表 */ setMessages(sessionId, messages) { this.messagesBySession[sessionId] = messages }, /** * 添加新消息到会话 * @param {number} sessionId - 会话ID * @param {ChatMessage} message - 消息 */ addMessage(sessionId, message) { if (!this.messagesBySession[sessionId]) { this.messagesBySession[sessionId] = [] } this.messagesBySession[sessionId].push(message) // 更新会话的最后消息 this.updateSessionLastMessage(sessionId, message) }, /** * 更新会话的最后消息 * @param {number} sessionId - 会话ID * @param {ChatMessage} message - 消息 */ updateSessionLastMessage(sessionId, message) { const session = this.sessions.find(s => s.sessionId === sessionId) if (session) { session.lastMessage = this.getMessagePreview(message) session.lastMessageTime = message.createTime } }, /** * 获取消息预览文本 * @param {ChatMessage} message - 消息 * @returns {string} */ getMessagePreview(message) { switch (message.messageType) { case MessageType.TEXT: return message.content case MessageType.VOICE: return '[语音]' case MessageType.IMAGE: return '[图片]' case MessageType.EXCHANGE_WECHAT: return '[交换微信请求]' case MessageType.EXCHANGE_PHOTO: return '[交换照片请求]' default: return message.content || '' } }, /** * 接收新消息 * @param {ChatMessage} message - 消息 */ receiveMessage(message) { const { sessionId } = message // 添加消息到列表 this.addMessage(sessionId, message) // 如果不是当前会话,增加未读数 if (sessionId !== this.currentSessionId) { this.incrementUnreadCount(sessionId) } }, /** * 增加会话未读数 * @param {number} sessionId - 会话ID */ incrementUnreadCount(sessionId) { const session = this.sessions.find(s => s.sessionId === sessionId) if (session) { session.unreadCount = (session.unreadCount || 0) + 1 this.updateTotalUnreadCount() } }, /** * 标记会话已读 * @param {number} sessionId - 会话ID */ markSessionAsRead(sessionId) { const session = this.sessions.find(s => s.sessionId === sessionId) if (session && session.unreadCount > 0) { session.unreadCount = 0 this.updateTotalUnreadCount() } }, /** * 发送消息(本地状态更新) * @param {number} sessionId - 会话ID * @param {Object} messageData - 消息数据 * @returns {ChatMessage} 创建的消息对象 */ sendMessage(sessionId, messageData) { const message = { id: Date.now(), // 临时ID sessionId, senderId: messageData.senderId, receiverId: messageData.receiverId, messageType: messageData.messageType || MessageType.TEXT, content: messageData.content, status: MessageStatus.SENDING, createTime: new Date().toISOString(), isMine: true } this.addMessage(sessionId, message) return message }, /** * 更新消息状态 * @param {number} sessionId - 会话ID * @param {number} messageId - 消息ID * @param {number} status - 新状态 */ updateMessageStatus(sessionId, messageId, status) { const messages = this.messagesBySession[sessionId] if (messages) { const message = messages.find(m => m.id === messageId) if (message) { message.status = status } } }, /** * 清空当前会话 */ clearCurrentSession() { this.currentSessionId = null }, /** * 重置聊天状态 */ reset() { this.sessions = [] this.messagesBySession = {} this.currentSessionId = null this.totalUnreadCount = 0 } } })