212 lines
6.0 KiB
JavaScript
212 lines
6.0 KiB
JavaScript
import { defineStore } from "pinia"
|
|
import { ref, computed } from "vue"
|
|
import { chatDB } from "@/utils/db"
|
|
|
|
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 initDB = async () => {
|
|
try {
|
|
await chatDB.init()
|
|
console.log("数据库初始化成功")
|
|
} catch (error) {
|
|
console.error("数据库初始化失败:", error)
|
|
}
|
|
}
|
|
|
|
// 加载好友列表
|
|
const loadFriends = async (presetUsers, currentUserId) => {
|
|
try {
|
|
// 从数据库获取好友列表
|
|
let friendList = await chatDB.getFriends(currentUserId)
|
|
|
|
// 如果数据库中没有好友,使用预设用户初始化
|
|
if (friendList.length === 0) {
|
|
friendList = presetUsers.filter((user) => user.id !== currentUserId)
|
|
|
|
// 保存到数据库
|
|
for (const friend of friendList) {
|
|
await chatDB.saveFriend(
|
|
{
|
|
...friend,
|
|
lastMessage: "",
|
|
unreadCount: 0,
|
|
},
|
|
currentUserId,
|
|
)
|
|
}
|
|
}
|
|
|
|
friends.value = friendList
|
|
} catch (error) {
|
|
console.error("加载好友列表失败:", error)
|
|
// 降级到预设用户
|
|
const friendList = presetUsers.filter((user) => user.id !== currentUserId)
|
|
friendList.forEach((friend) => {
|
|
friend.lastMessage = ""
|
|
friend.unreadCount = 0
|
|
})
|
|
friends.value = friendList
|
|
}
|
|
}
|
|
|
|
// 设置当前好友 - 新增方法
|
|
const setCurrentFriend = (friend) => {
|
|
currentFriend.value = friend
|
|
// 清除未读消息计数
|
|
if (friend) {
|
|
friend.unreadCount = 0
|
|
}
|
|
}
|
|
|
|
// 切换当前聊天好友
|
|
const switchFriend = async (friend, currentUserId) => {
|
|
currentFriend.value = friend
|
|
|
|
// 清空未读消息计数
|
|
friend.unreadCount = 0
|
|
await chatDB.clearUnreadCount(friend.id)
|
|
|
|
// 加载聊天记录
|
|
try {
|
|
const chatHistory = await chatDB.getChatHistory(currentUserId, friend.id)
|
|
messages.value = chatHistory.sort((a, b) => a.timestamp - b.timestamp)
|
|
} catch (error) {
|
|
console.error("加载聊天记录失败:", error)
|
|
messages.value = []
|
|
}
|
|
}
|
|
|
|
// 添加消息
|
|
const addMessage = async (message, currentUserId) => {
|
|
messages.value.push(message)
|
|
|
|
if (currentFriend.value) {
|
|
try {
|
|
// 保存到数据库
|
|
await chatDB.saveMessage(message, currentUserId, currentFriend.value.id)
|
|
|
|
// 更新好友列表中的最后消息
|
|
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
|
|
|
|
// 更新数据库中的好友信息
|
|
await chatDB.updateFriendLastMessage(friend.id, currentUserId, friend.lastMessage, 0)
|
|
}
|
|
} catch (error) {
|
|
console.error("保存消息失败:", error)
|
|
}
|
|
}
|
|
}
|
|
|
|
// 处理接收到的消息
|
|
const handleIncomingMessage = async (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,
|
|
timestamp: Date.now(),
|
|
}
|
|
|
|
try {
|
|
// 保存消息到数据库
|
|
await chatDB.saveMessage(newMessage, currentUserId, senderId)
|
|
|
|
// 如果消息来自当前聊天用户,直接显示
|
|
if (currentFriend.value && senderId == currentFriend.value.id) {
|
|
newMessage.read = true
|
|
messages.value.push(newMessage)
|
|
} 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
|
|
|
|
// 更新数据库
|
|
await chatDB.updateFriendLastMessage(friend.id, currentUserId, lastMessage, friend.unreadCount)
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.error("处理接收消息失败:", error)
|
|
}
|
|
}
|
|
|
|
// 根据消息类型编号获取类型字符串
|
|
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,
|
|
initDB,
|
|
loadFriends,
|
|
setCurrentFriend,
|
|
switchFriend,
|
|
addMessage,
|
|
handleIncomingMessage,
|
|
}
|
|
})
|