xiangyixiangqin/miniapp/store/chat.js
2026-01-21 19:36:36 +08:00

292 lines
7.6 KiB
JavaScript

/**
* 聊天状态管理模块
* 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<ChatSession>} 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<ChatMessage>} 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
}
}
})