Files
nl-im-pc/src/stores/chat.js
2025-07-02 16:54:52 +08:00

177 lines
5.3 KiB
JavaScript

import { defineStore } from "pinia"
import { ref, computed } from "vue"
export const useChatStore = defineStore("chat", () => {
const friends = ref([])
const currentFriend = ref(null)
const messages = ref([])
const connectionStatus = ref("disconnected")
const socket = ref(null)
// 计算属性
const isConnected = computed(() => connectionStatus.value === "connected")
const connectionStatusText = computed(() => {
switch (connectionStatus.value) {
case "connected":
return "已连接"
case "connecting":
return "连接中..."
case "disconnected":
return "已断开"
default:
return "未知状态"
}
})
const connectionStatusIcon = computed(() => {
switch (connectionStatus.value) {
case "connected":
return "wifi"
case "connecting":
return "loading"
case "disconnected":
return "disconnect"
default:
return "question"
}
})
// 获取聊天历史记录
const getChatHistory = (friendId, currentUserId) => {
const chatKey = `chat_${currentUserId}_${friendId}`
const chatData = localStorage.getItem(chatKey)
return chatData ? JSON.parse(chatData) : []
}
// 保存聊天历史记录
const saveChatHistory = (friendId, currentUserId, messageList) => {
const chatKey = `chat_${currentUserId}_${friendId}`
localStorage.setItem(chatKey, JSON.stringify(messageList))
}
// 加载好友列表
const loadFriends = (presetUsers, currentUserId) => {
const friendList = presetUsers.filter((user) => user.id !== currentUserId)
friendList.forEach((friend) => {
const chatHistory = getChatHistory(friend.id, currentUserId)
if (chatHistory.length > 0) {
const lastMsg = chatHistory[chatHistory.length - 1]
let lastMessage = lastMsg.content
if (lastMsg.type === "image") lastMessage = "[图片]"
if (lastMsg.type === "video") lastMessage = "[视频]"
if (lastMsg.type === "audio") lastMessage = "[语音]"
friend.lastMessage = lastMessage.length > 20 ? lastMessage.substring(0, 20) + "..." : lastMessage
}
friend.unreadCount = chatHistory.filter((msg) => msg.senderId === friend.id && !msg.read).length
})
friends.value = friendList
}
// 切换当前聊天好友
const switchFriend = (friend, currentUserId) => {
currentFriend.value = friend
friend.unreadCount = 0
// 加载聊天记录
const chatHistory = getChatHistory(friend.id, currentUserId)
chatHistory.forEach((msg) => {
if (msg.senderId !== currentUserId) {
msg.read = true
}
})
messages.value = chatHistory
saveChatHistory(friend.id, currentUserId, chatHistory)
}
// 添加消息
const addMessage = (message, currentUserId) => {
messages.value.push(message)
if (currentFriend.value) {
saveChatHistory(currentFriend.value.id, currentUserId, messages.value)
// 更新好友列表中的最后消息
const friend = friends.value.find((f) => f.id === currentFriend.value.id)
if (friend) {
let lastMessage = message.content
if (message.type === "image") lastMessage = "[图片]"
if (message.type === "video") lastMessage = "[视频]"
if (message.type === "audio") lastMessage = "[语音]"
friend.lastMessage = lastMessage.length > 20 ? lastMessage.substring(0, 20) + "..." : lastMessage
}
}
}
// 处理接收到的消息
const handleIncomingMessage = (messageData, currentUserId) => {
const senderId = messageData.sender_user_id
const receiverId = messageData.receiver_user_id
if (receiverId !== currentUserId) return
const newMessage = {
type: getMessageType(messageData.message_type),
content: messageData.content,
time: new Date().toLocaleTimeString().slice(0, 5),
senderId: senderId,
read: false,
duration: messageData.duration || 0,
}
// 保存消息到本地存储
const chatHistory = getChatHistory(senderId, currentUserId)
chatHistory.push(newMessage)
saveChatHistory(senderId, currentUserId, chatHistory)
// 如果消息来自当前聊天用户,直接显示
if (currentFriend.value && senderId == currentFriend.value.id) {
newMessage.read = true
messages.value.push(newMessage)
saveChatHistory(senderId, currentUserId, messages.value)
} else {
// 更新未读消息计数
const friend = friends.value.find((f) => f.id == senderId)
if (friend) {
friend.unreadCount = (friend.unreadCount || 0) + 1
// 更新最后消息
let lastMessage = newMessage.content
if (newMessage.type === "image") lastMessage = "[图片]"
if (newMessage.type === "video") lastMessage = "[视频]"
if (newMessage.type === "audio") lastMessage = "[语音]"
friend.lastMessage = lastMessage
}
}
}
// 根据消息类型编号获取类型字符串
const getMessageType = (type) => {
const types = ["text", "image", "audio", "video", "prescription", "medical-record", "video-call"]
return types[type] || "text"
}
return {
friends,
currentFriend,
messages,
connectionStatus,
socket,
isConnected,
connectionStatusText,
connectionStatusIcon,
getChatHistory,
saveChatHistory,
loadFriends,
switchFriend,
addMessage,
handleIncomingMessage,
}
})