From 3f2853f394ae222e31742d00e0accf552365fcab Mon Sep 17 00:00:00 2001 From: qiutianhong Date: Thu, 31 Oct 2024 09:59:39 +0800 Subject: [PATCH 1/2] =?UTF-8?q?add=EF=BC=9A=E5=AE=8C=E6=88=90=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E6=8E=A5=E5=8F=97=E6=B6=88=E6=81=AF=E5=8F=91=E9=80=81?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/auto-imports.d.ts | 3 +- frontend/components.d.ts | 1 - frontend/src/components/chat/Chat.vue | 106 +++-- frontend/src/components/chat/ChatBox.vue | 62 +-- frontend/src/components/chat/ChatMessage.vue | 127 ++---- frontend/src/components/chat/ChatMsgList.vue | 14 +- frontend/src/components/chat/ChatUserList.vue | 23 - frontend/src/components/chat/chatUserInfo.vue | 4 +- frontend/src/stores/chat.ts | 419 +++++++++++------- frontend/src/stores/db.ts | 23 +- frontend/src/stores/upgrade.ts | 18 + frontend/src/system/index.ts | 5 +- 12 files changed, 463 insertions(+), 342 deletions(-) diff --git a/frontend/auto-imports.d.ts b/frontend/auto-imports.d.ts index eab6be6..d0c217f 100644 --- a/frontend/auto-imports.d.ts +++ b/frontend/auto-imports.d.ts @@ -3,6 +3,7 @@ // @ts-nocheck // noinspection JSUnusedGlobalSymbols // Generated by unplugin-auto-import +// biome-ignore lint: disable export {} declare global { const EffectScope: typeof import('vue')['EffectScope'] @@ -70,6 +71,6 @@ declare global { // for type re-export declare global { // @ts-ignore - export type { Component, ComponentPublicInstance, ComputedRef, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, VNode, WritableComputedRef } from 'vue' + export type { Component, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue' import('vue') } diff --git a/frontend/components.d.ts b/frontend/components.d.ts index 37c6c26..d46e001 100644 --- a/frontend/components.d.ts +++ b/frontend/components.d.ts @@ -51,7 +51,6 @@ declare module 'vue' { ElAside: typeof import('element-plus/es')['ElAside'] ElAvatar: typeof import('element-plus/es')['ElAvatar'] ElBadge: typeof import('element-plus/es')['ElBadge'] - ElBu: typeof import('element-plus/es')['ElBu'] ElButton: typeof import('element-plus/es')['ElButton'] ElCard: typeof import('element-plus/es')['ElCard'] ElCarousel: typeof import('element-plus/es')['ElCarousel'] diff --git a/frontend/src/components/chat/Chat.vue b/frontend/src/components/chat/Chat.vue index 2f869ab..81f684f 100644 --- a/frontend/src/components/chat/Chat.vue +++ b/frontend/src/components/chat/Chat.vue @@ -7,21 +7,37 @@ onMounted(() => { store.initChat(); }); + + const userList = ref([ + { + id: 2, + nickname: "朋友2", + avatar: "/logo.png", + previewTimeFormat: "昨天", + previewType: 1, + previewMessage: "测试消息", + }, + { + id: 3, + nickname: "朋友3", + avatar: "/logo.png", + previewTimeFormat: "昨天", + previewType: 1, + previewMessage: "测试消息", + }, + ]); + // 将用户列表转换为 el-transfer 组件所需的数据格式 const generateData = () => { - const data = []; - for (let i = 1; i <= 15; i++) { - data.push({ - key: i, - label: ` ${i}`, - disabled: i % 4 === 0, - }); - } - return data; + return userList.value.map((user) => ({ + key: user.id, + label: user.nickname, + avatar: user.avatar, // 添加头像数据 + })); }; - - const data = generateData(); - const value = ref([]); + + const data = ref(generateData()); + const users = ref([]); + diff --git a/frontend/src/components/chat/ChatMsgList.vue b/frontend/src/components/chat/ChatMsgList.vue index 1a69f8f..242ec75 100644 --- a/frontend/src/components/chat/ChatMsgList.vue +++ b/frontend/src/components/chat/ChatMsgList.vue @@ -2,9 +2,9 @@
@@ -21,14 +21,8 @@
{{ item.nickname }}
- {{ item.previewMessage }} - - {{ - item.targetUserId === id - ? "你" - : '"' + item.nickname + '"' - }}撤回了一条消息 - + {{ item.previewMessage }} +
diff --git a/frontend/src/components/chat/ChatUserList.vue b/frontend/src/components/chat/ChatUserList.vue index b8655f8..6130a81 100644 --- a/frontend/src/components/chat/ChatUserList.vue +++ b/frontend/src/components/chat/ChatUserList.vue @@ -122,29 +122,6 @@ {{ group.name }}
- -
- {{ group.previewTimeFormat }} -
-
- - -
- {{ group.previewMessage }} -
-
- {{ - group.userId === id - ? "你" - : '"' + group.name + '"' - }}撤回了一条消息 -
diff --git a/frontend/src/components/chat/chatUserInfo.vue b/frontend/src/components/chat/chatUserInfo.vue index c6beb3e..07d2b3e 100644 --- a/frontend/src/components/chat/chatUserInfo.vue +++ b/frontend/src/components/chat/chatUserInfo.vue @@ -37,9 +37,9 @@ const store = useChatStore(); - const sendMessage = (id:number) => { + const sendMessage = (userId:number) => { store.currentNavId = 0; - store.updateConversationList(id) + store.changeChatListAndGetChatHistory(userId) }; diff --git a/frontend/src/stores/chat.ts b/frontend/src/stores/chat.ts index e356c73..e23fc27 100644 --- a/frontend/src/stores/chat.ts +++ b/frontend/src/stores/chat.ts @@ -3,71 +3,64 @@ import { fetchPost, getSystemConfig } from '@/system/config'; import { notifyError } from "@/util/msg"; import { defineStore } from 'pinia'; import { db } from "./db"; -import { useMessageStore } from "./message"; - -interface ChatMessage { - type: string; - createdAt: number; - content: any; - targetUserId: any; - previewType: 0 | 1; // 消息类型,0表示正常消息,1表示撤回消息 - previewMessage: any; - isMe: boolean; - isRead: boolean; - userInfo: { - id: any; - username: any; - avatar: any; - }; -} -// 发起群聊对话框显示 -const groupChatDialogVisible = ref(false); -// 设置发起群聊对话框状态 -const setGroupChatDialogVisible = (visible: boolean) => { - groupChatDialogVisible.value = visible; -}; + + export const useChatStore = defineStore('chatStore', () => { - // 用户列表 - const userList: any = ref([]); - // 定义聊天列表项的接口 - interface ChatListItem { + interface ChatMessage { + type: string; // 消息类型,0表示文字消息,1表示图片消息,2表示文件消息 + time: number; // 消息发送时间 + message: any; // 消息内容 + userId: any; // 发送者id + toUserId: any; // 接收者id + // receiver: any; // 消息接收者 + // to_groupid: any; // 群组id + userInfo: { // 发送者信息 + } + }; + + // 发起群聊对话框显示 + const groupChatInvitedDialogVisible = ref(false); + + // 群信息设置抽屉 + const groupInfoSettingDrawerVisible = ref(false); + // 设置群聊邀请对话框状态 + const setGroupChatInvitedDialogVisible = (visible: boolean) => { + groupChatInvitedDialogVisible.value = visible; + }; + + // 设置群信息抽屉状态 + const setGroupInfoDrawerVisible = (visible: boolean) => { + groupInfoSettingDrawerVisible.value = visible + } + + // 定义用户类型 + type User = { id: number; - nickname: string; + ip: string; + isOnline: boolean; avatar: string; - previewTimeFormat: string; - previewType: 0 | 1; // 消息类型,0表示正常消息,1表示撤回消息 - previewMessage: string; - } + nickname: string; + username: string; + updatedAt?: number; + }; - // 模拟数据 - 聊天列表 - const chatList = ref([ - { - id: 2, - nickname: '朋友2', - avatar: '/logo.png', - previewTimeFormat: "昨天", - previewType: 1, - previewMessage: "测试消息", - }, - { - id: 3, - nickname: '朋友2', - avatar: '/logo.png', - previewTimeFormat: "昨天", - previewType: 1, - previewMessage: "测试消息", - }, + // 将 userList 的类型设置为 User[] + const userList = ref([]); - ]); + // 聊天列表 + const chatList: any = ref([]); + + // 聊天消息记录列表 + const chatHistory: any = ref([]); + + const targetNickname: any = ref(''); - // 模拟数据 - 聊天消息列表 - const chatHistory = ref([]); // 群组数据 - const groupList = ref([ + const groupList: any = ref([ { id: 1, name: '群组1', @@ -107,8 +100,6 @@ export const useChatStore = defineStore('chatStore', () => { const targetUserInfo: any = ref({}); const targetUserId = ref(); const search = ref(''); - const messageStore = useMessageStore(); - const apiUrl = "http://192.168.1.10:8816"; const contextMenu = ref({ visible: false, @@ -127,35 +118,40 @@ export const useChatStore = defineStore('chatStore', () => { } userInfo.value = config.userInfo; getUserList() - initUserList() - initOnlineUserList() + // initUserList() + initChatList() + // initOnlineUserList() console.log(userList.value); }; + // 初始化用户列表 + const initChatList = async () => { + chatList.value = await db.getAll('conversationList'); + console.log(chatList.value); + }; + const setCurrentNavId = (id: number) => { currentNavId.value = id; }; const sendMessage = async () => { - const chatSendUrl = apiUrl + '/chat/send'; + const chatSendUrl = config.userInfo.url + '/chat/send'; + // 封装成消息历史记录 const messageHistory: ChatMessage = { - type: 'text', - createdAt: Date.now(), - content: message.value, - targetUserId: targetUserId.value, - previewType: 0, // 消息类型,0表示正常消息,1表示撤回消息 - previewMessage: message.value, - isMe: true, - isRead: false, + type: 'user', + time: Date.now(), + message: message.value, + userId: userInfo.value.userId, + toUserId: targetUserId.value, + // receiver: targetUserId.value, userInfo: { - id: config.userInfo.id, - username: config.userInfo.username, - avatar: config.userInfo.avatar, }, }; + // 发送消息 const res = await fetchPost(chatSendUrl, messageHistory); + console.log(res); if (res.ok) { // 本地存储一份聊天记录 await db.addOne('chatRecord', messageHistory); @@ -163,8 +159,10 @@ export const useChatStore = defineStore('chatStore', () => { // 更新聊天历史 chatHistory.value.push(messageHistory); + console.log(chatHistory.value); + // 更新 chatList 和 conversationList - await updateConversationList(targetUserId.value); + // await changeChatListAndGetChatHistory(targetUserId.value, messageHistory); // 清空输入框 clearMessage(); @@ -176,57 +174,97 @@ export const useChatStore = defineStore('chatStore', () => { notifyError("消息发送失败"); }; - const updateConversationList = async (id: number) => { - // 先判断是否已经存在该会话 - const res = await db.getRow('conversationList', 'id', id); + // 更新聊天和聊天记录 + const changeChatListAndChatHistory = async (data: any) => { + try { + // 从 conversationList 数据库中查找是否存在对应的会话 + const conversation = await db.getByField('conversationList', 'userId', data.userId); - if (res) { - // 更新现有会话 + // 准备会话更新数据 const updatedConversation = { - ...res, - previewMessage: message.value, - previewTimeFormat: formatTime(Date.now()), - previewType: 0, + userId: data.userId, + avatar: data.userInfo.avatar || "logo.png", // 如果没有头像使用默认图片 + toUserId: data.toUserId, + messages: data.message, + nickname: data.userInfo.nickname, + time: data.time || Date.now(), + previewMessage: data.message, + previewTimeFormat: formatTime(Date.now()), // 时间格式化函数 + createdAt: Date.now() }; - await db.update('conversationList', id, updatedConversation); - // 更新 chatList - const existingConversationIndex = chatList.value.findIndex(conversation => conversation.id === id); - if (existingConversationIndex !== -1) { - chatList.value[existingConversationIndex] = updatedConversation; - } else { + if (conversation.length === 0) { + // 如果会话不存在,则添加到数据库和 chatList + await db.addOne('conversationList', updatedConversation); + chatList.value.push(updatedConversation); + } else { + // 如果会话存在,则更新数据库和 chatList + // 只更新变化的字段,而非全部覆盖,以减少写入数据的量 + await db.update('conversationList', conversation[0].id, { + avatar: data.userInfo.avatar || "logo.png", + nickname: data.userInfo.nickname, + previewMessage: data.message, + time: data.time || Date.now(), + previewTimeFormat: formatTime(Date.now()) + }); + + + // 更新 chatList 中的对应项 + const existingConversationIndex = chatList.value.findIndex( + (conv: any) => conv.userId === data.userId + ); + if (existingConversationIndex !== -1) { + chatList.value[existingConversationIndex] = updatedConversation; + } else { + chatList.value.push(updatedConversation); + } } - } else { - const targetUser = await db.getOne('workbenchusers', id); - const lastMessage: any = messageStore; + } catch (error) { + console.error("更新聊天和聊天记录时出错:", error); + } + }; - const targetUserInfo = { - id: targetUser.id, - nickname: targetUser.nickname, - avatar: targetUser.avatar, - }; - // 计算时间差 - const now = new Date(); - const createdAt = new Date(lastMessage.createdAt); - const diffTime = Math.abs(now.getTime() - createdAt.getTime()); - console.log(diffTime); - // 根据时间差格式化时间 - const previewTimeFormat = formatTime(Date.now()); - - const newConversation = { - ...targetUserInfo, - previewTimeFormat, - previewMessage: lastMessage.content, - previewType: lastMessage.type, - }; + const changeChatListAndGetChatHistory = async (userId: number) => { + // 将当前的chatlist存到map中id为key,如果userId能在map中找到就不添加。 - // 添加到 conversationList - await db.addOne('conversationList', newConversation); + // 将当前的 chatList 存到 map 中,id 为 key + const chatListMap = new Map(); + + // value可设置为空 + chatList.value.forEach((chat: { userId: number; }) => { + chatListMap.set(chat.userId, ""); + }); + + // 检查 userId 是否在 map 中 + if (chatListMap.has(userId)) { + // 如果存在获取聊天记录添加到historyList + const data = await db.getByField("chatRecord", "userId", userId) + chatHistory.value = data + return; + } else { + // 如果不在chatlist中表示没有聊天记录。那么去用户表中获取该用户的基本信息 + const user = await db.getOne("workbenchusers", userId) + chatList.value.push({ + id: user.id, + nickname: user.nickname, + avatar: user.avatar, + previewTimeFormat: formatTime(Date.now()), + previewMessage: "", + }) + // 持久化 + await db.addOne("conversationList", { + userId: user.id, + username: user.username, + nickname: user.nickname, + avatar: user.avatar, + toUserId: userInfo.value.id, + time: Date.now(), + previewMessage: "", + createdAt: Date.now() + }) - // 添加到 chatList - chatList.value.push(newConversation); } }; @@ -255,6 +293,66 @@ export const useChatStore = defineStore('chatStore', () => { }; + // 创建群聊 + const createGroupChat = async (groupName?: string, userIds?: number[]) => { + try { + const data = { + name: groupName, + user_ids: userIds + } + const url = config.userInfo.url + "/chat/group"; + const res = await fetchPost(url, JSON.stringify(data)); + if (!res.ok) { + return false; + } + console.log(res) + const groupData = await res.json(); + console.log(groupData) + } catch (error) { + console.log(error); + } + + }; + + // 处理用户消息 + const userChatMessage = async (data: any) => { + // 先判断数据库是否有该用户 + // 更新聊天记录表 + // 更新会话列表数据库 + // 更新chatlist + const isPresence = await db.getByField('workbenchusers', 'id', data.userId) + if (isPresence[0].id !== data.userId) { + return + } + + // 添加消息记录 + const addMessageHistory = { + type: data.type, + time: data.time, + userId: data.userId, + message: data.message, + toUserId: data.toUserId, + createdAt: Date.now(), + // 用户信息 + userInfo: { + id: data.userId, + nickname: data.userInfo.nickname || "未知用户", + avatar: data.userInfo.avatar || "logo.png", // 使用默认头像。 + email: data.userInfo.email, + phone: data.userInfo.phone, + remark: data.userInfo.remark, + role_id: data.userInfo.role_id, + } + } + + await db.addOne('chatRecord', addMessageHistory) + + + // 更新 chatList 和 conversationList表 + changeChatListAndChatHistory(data) + }; + + const setScrollToBottom = async () => { // await nextTick(); // 确保 DOM 已经更新完毕 @@ -274,11 +372,8 @@ export const useChatStore = defineStore('chatStore', () => { }; const handleUserData = async (data: any[]) => { - ; - // 创建一个用户数组,将所有在线的用户提取出来 const users: any[] = []; - // 遍历每个数据项 data.forEach((item: any) => { if (item.id && item.login_ip) { @@ -292,7 +387,6 @@ export const useChatStore = defineStore('chatStore', () => { } }); - console.log(users); // 将提取到的用户数据传递给 setUserList if (users.length > 0) { @@ -301,6 +395,7 @@ export const useChatStore = defineStore('chatStore', () => { }; + const setUserList = async (data: any[]) => { if (data.length < 1) { return; @@ -308,8 +403,8 @@ export const useChatStore = defineStore('chatStore', () => { // 从当前用户列表中获取已有用户的 IP 和完整用户映射 const existingIps = new Set(userList.value.map((d: any) => d.ip)); - const userMap = new Map( - userList.value.map((user: any) => [user.ip, user]) + const userMap = new Map( + userList.value.map((user: User) => [user.ip, user]) ); const updates: any[] = []; @@ -324,8 +419,9 @@ export const useChatStore = defineStore('chatStore', () => { key: existingUser.id, changes: { isOnline: true, + avatar: d.avatar, nickname: d.nickname, - username: d.usernmae, + username: d.username, updatedAt: Date.now() } }); @@ -335,6 +431,7 @@ export const useChatStore = defineStore('chatStore', () => { id: d.id, ip: d.ip, isOnline: true, + avatar: d.avatar, nickname: d.nickname, username: d.usernmae, createdAt: Date.now(), @@ -343,8 +440,6 @@ export const useChatStore = defineStore('chatStore', () => { } }); - console.log(updates); - console.log(newEntries); // 批量更新和添加用户数据 if (updates.length > 0) { @@ -363,21 +458,20 @@ export const useChatStore = defineStore('chatStore', () => { try { // 从数据库中获取所有用户信息 const list = await db.getAll("workbenchusers"); - + console.log(list); // 创建一个 Map,用于存储每个用户的唯一 ID 地址 let uniqueIdMap = new Map(); // 遍历用户列表,将每个用户添加到 Map 中(基于 ID 去重) list.forEach((item: any) => { - uniqueIdMap.set(item.id, item); // 使用 ID 作为键,用户对象作为值 + uniqueIdMap.set(item.userId, item); // 使用 ID 作为键,用户对象作为值 }); // 将 Map 的值转换为数组(去重后的用户列表) const uniqueIdList = Array.from(uniqueIdMap.values()); // 按照 updatedAt 时间进行升序排序 - uniqueIdList.sort((a: any, b: any) => a.updatedAt - b.updatedAt); - + uniqueIdList.sort((a: any, b: any) => a.time - b.time); // 更新用户列表 userList.value = uniqueIdList; } catch (error) { @@ -387,25 +481,29 @@ export const useChatStore = defineStore('chatStore', () => { // 初始化统一用户列表状态 const initUserList = async () => { - // 检查用户列表是否为空 - if (userList.value.length > 0) { - // 收集需要更新的用户数据 - const updates = userList.value - .filter((d: any) => d.isOnline) // 过滤出在线的用户 - .map((d: any) => ({ - key: d.id, - changes: { - isOnline: false - } - })); - - // 批量更新用户状态 - if (updates.length > 0) { - await db.table('workbenchusers').bulkUpdate(updates); + console.log("初始化用户列表状态"); + console.log(userList.value); + if (!userList.value.length) return; + // 获取需要更新的用户数据(只选取在线的用户并设为离线状态) + const updates = userList.value.reduce((acc: any[], user: any) => { + console.log(user); + if (user.isOnline) { + console.log(user); + acc.push({ + key: user.id, + changes: { isOnline: false } + }); } + return acc; + }, []); + + // 如果有需要更新的用户,批量更新数据库状态 + if (updates.length) { + await db.table('workbenchusers').bulkUpdate(updates); } }; + const initOnlineUserList = async () => { const msgAll = await db.getAll('workbenchusers'); @@ -438,20 +536,37 @@ export const useChatStore = defineStore('chatStore', () => { }; - - - const changeChatList = async (id: number) => { + const changeChatList = async (userId: number) => { // 设置 targetUserId - targetUserId.value = id; + targetUserId.value = userId; // 获取当前用户和目标用户的聊天记录 - const messagesList = await db.getByField('chatRecord', 'targetUserId', id); + const messagesList = await db.getByField('chatRecord', 'userId', userId); + + // // 表示与该用户没有聊天记录,但是也需要初始化一些信息 + // if (messagesList.length == 0) { + // const userData:any = await db.getOne("workbenchusers", userId) + // console.log(userData) + // const data: any = { + // userId: userData.id, + // userInfo: { + // id: userData.id, + // avatar: userData.avatar, + // nickname: userData.nickname, + // } + // } + + // chatHistory.value.push(data) + // } else { chatHistory.value = messagesList; + // } // 设置目标用户的信息 - setTargetUserInfo(id); + await setTargetUserInfo(userId); }; + + const setTargetUserInfo = async (id: number) => { targetUserInfo.value = await db.getOne('workbenchusers', id); }; @@ -487,16 +602,22 @@ export const useChatStore = defineStore('chatStore', () => { message, contextMenu, activeNames, - groupChatDialogVisible, + groupChatInvitedDialogVisible, + groupInfoSettingDrawerVisible, + targetNickname, initChat, showContextMenu, setCurrentNavId, sendMessage, changeChatList, handleContextMenu, - updateConversationList, + changeChatListAndGetChatHistory, handleUserData, initUserList, - setGroupChatDialogVisible + setGroupChatInvitedDialogVisible, + setGroupInfoDrawerVisible, + createGroupChat, + userChatMessage, + initOnlineUserList }; }); \ No newline at end of file diff --git a/frontend/src/stores/db.ts b/frontend/src/stores/db.ts index 57779dd..5142006 100644 --- a/frontend/src/stores/db.ts +++ b/frontend/src/stores/db.ts @@ -1,22 +1,31 @@ import Dexie from 'dexie'; -export type ChatTable = 'chatuser' | 'chatmsg' | 'chatmessage' | 'groupmessage' | 'chatRecord' | 'workbenchusers' | 'conversationList'; +export type ChatTable = 'chatuser' | 'chatmsg' | 'chatmessage' | 'groupmessage' | 'chatRecord' | 'workbenchusers' | 'conversationList' | 'group'; export const dbInit: any = new Dexie('GodoOSDatabase'); dbInit.version(1).stores({ // 用户列表 workbenchusers: '++id,ip,userName,avatar,mobile,nickName,isOnline,updatedAt,createdAt', // 聊天记录 - chatRecord: '++id,userId,targetUserId,senderInfo,previewType,previewMessage,isMe,isRead,content,type,readAt,createdAt', + chatRecord: '++id,toUserId,messages,time,createdAt,userInfo', // 会话列表 - conversationList: '++id,userId,targetUserId,targetIp,senderInfo,previewMessage,previewType,isMe,isRead,content,type,createdAt', + conversationList: '++id,avatar,username,nickname,userId,toUserId,previewMessage,messages,time,createdAt', chatuser: '++id,ip,hostname,userName,avatar,mobile,nickName,isOnline,updatedAt,createdAt', - // chatmsg: '++id,targetUserId,targetIp,senderInfo,reciperInfo,previewMessage,previewType,content,type,status,isRead,isMe,readAt,createdAt', - chatmessage: '++id,userId,targetUserId,senderInfo,isMe,isRead,content,type,readAt,createdAt', + // chatmsg: '++id,toUserId,targetIp,senderInfo,reciperInfo,previewMessage,content,type,status,isRead,isMe,readAt,createdAt', + chatmessage: '++id,userId,toUserId,senderInfo,isMe,isRead,content,type,readAt,createdAt', groupmessage: '++id,userId,groupId,senderInfo,isMe,isRead,content,type,readAt,createdAt', -}).upgrade((tx: { chatRecord: { addIndex: (arg0: string, arg1: (obj: { targetUserId: any; }) => any) => void; }; }) => { + // 群组表 + group: '++id,name,description,owner_id,avatar_url,created_at,updated_at,member_count,max_members,is_public,join_policy,group_type,status' + +}).upgrade((tx: { + conversationList: any; + group: any; + chatRecord: { addIndex: (arg0: string, arg1: (obj: { toUserId: any; }) => any) => void; }; +}) => { // 手动添加索引 - tx.chatRecord.addIndex('targetUserId', (obj: { targetUserId: any; }) => obj.targetUserId); + tx.conversationList.addIndex('userId', (obj: { userId: any; }) => obj.userId); + tx.chatRecord.addIndex('toUserId', (obj: { toUserId: any; }) => obj.toUserId); + tx.group.addIndex('owner_id', (obj: { owner_id: any }) => obj.owner_id); // 添加索引: 群主 ID }); export const db = { diff --git a/frontend/src/stores/upgrade.ts b/frontend/src/stores/upgrade.ts index c752e2c..34b9f2c 100644 --- a/frontend/src/stores/upgrade.ts +++ b/frontend/src/stores/upgrade.ts @@ -67,6 +67,20 @@ export const useUpgradeStore = defineStore('upgradeStore', () => { }; } + // 获取用户聊天消息 + function userChatMessage() { + const url = getUrl('/chat/message', false) + const source = new EventSource(url); + + source.onmessage = function (event) { + const data = JSON.parse(event.data); + + handleMessage(data); + }; + source.onerror = function (event) { + console.error('EventSource error:', event); + }; + } async function handleMessage(message: any) { switch (message.type) { @@ -79,6 +93,9 @@ export const useUpgradeStore = defineStore('upgradeStore', () => { case 'online': chatChatStore.handleUserData(message.data) break; + case 'user': + chatChatStore.userChatMessage + break default: console.warn('Unknown message type:', message.type); } @@ -180,6 +197,7 @@ export const useUpgradeStore = defineStore('upgradeStore', () => { checkUpdate, systemMessage, onlineMessage, + userChatMessage, update } }) \ No newline at end of file diff --git a/frontend/src/system/index.ts b/frontend/src/system/index.ts index 1554c59..efa3241 100644 --- a/frontend/src/system/index.ts +++ b/frontend/src/system/index.ts @@ -14,7 +14,6 @@ import { } from './type/type'; import { BrowserWindow, BrowserWindowOption } from './window/BrowserWindow'; -import { useMessageStore } from '@/stores/message'; import { useUpgradeStore } from '@/stores/upgrade'; import { RestartApp } from '@/util/goutil'; import { notifyError } from '@/util/msg'; @@ -435,7 +434,7 @@ export class System { const fileContent = await this.fs.readShareFile(path) // console.log('阅读:', fileContent); if (fileContent !== false) { - const fileName = extname(arr[arr.length-1] || '') || 'link' + const fileName = extname(arr[arr.length - 1] || '') || 'link' this._flieOpenerMap .get(fileName) ?.func.call(this, path, fileContent || ''); @@ -461,7 +460,7 @@ export class System { ?.func.call(this, path, fileContent || ''); } } - + } // 插件系统 use(func: OsPlugin): void { From abfc92a7fa33cbfd599de91b0deceef385ff7552 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E5=AD=90=E6=97=BA?= <15039612+liu-ziwang123@user.noreply.gitee.com> Date: Thu, 31 Oct 2024 10:33:21 +0800 Subject: [PATCH 2/2] =?UTF-8?q?fix:=E4=BF=AE=E5=A4=8D=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E4=B8=8D=E5=88=B0=E9=93=BE=E6=8E=A5=E6=96=87=E4=BB=B6bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- godo/files/pwdfile.go | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/godo/files/pwdfile.go b/godo/files/pwdfile.go index 9ddcbad..e0bb6ba 100644 --- a/godo/files/pwdfile.go +++ b/godo/files/pwdfile.go @@ -6,14 +6,14 @@ import ( "godo/libs" "net/http" "strconv" + "strings" ) -// 加密读 func HandleReadFile(w http.ResponseWriter, r *http.Request) { // 初始值 path := r.URL.Query().Get("path") - fPwd := r.Header.Get("fPwd") + fPwd := r.Header.Get("filePwd") salt := GetSalt(r) hasPwd, err := GetPwdFlag() if err != nil { @@ -38,12 +38,14 @@ func HandleReadFile(w http.ResponseWriter, r *http.Request) { libs.HTTPError(w, http.StatusNotFound, err.Error()) return } - + fileData := string(fileContent) // 无加密情况 if !hasPwd { - // 直接base64编码原文返回 - data := base64.StdEncoding.EncodeToString(fileContent) - resp := libs.APIResponse{Message: "success", Data: data} + // 判断文件开头是否以link:开头 + if !strings.HasPrefix(fileData, "link::") { + fileData = base64.StdEncoding.EncodeToString(fileContent) + } + resp := libs.APIResponse{Message: "success", Data: fileData} json.NewEncoder(w).Encode(resp) return } @@ -63,10 +65,14 @@ func HandleReadFile(w http.ResponseWriter, r *http.Request) { } // 3. base64编码后返回 - content := base64.StdEncoding.EncodeToString(fileContent) + // 判断文件开头是否以link:开头 + fileData = string(fileContent) + if !strings.HasPrefix(fileData, "link::") { + fileData = base64.StdEncoding.EncodeToString(fileContent) + } // 初始响应 - res := libs.APIResponse{Code: 0, Message: "success", Data: content} + res := libs.APIResponse{Code: 0, Message: "success", Data: fileData} json.NewEncoder(w).Encode(res) } @@ -116,7 +122,11 @@ func HandleChangeFilePwd(w http.ResponseWriter, r *http.Request) { func HandleSetIsPwd(w http.ResponseWriter, r *http.Request) { isPwd := r.URL.Query().Get("ispwd") // 0非加密机器 1加密机器 - isPwdValue, _ := strconv.Atoi(isPwd) + isPwdValue, err := strconv.Atoi(isPwd) + if err != nil { + libs.HTTPError(w, http.StatusBadRequest, err.Error()) + return + } var isPwdBool bool if isPwdValue == 0 { isPwdBool = false