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 c9a977f..0623253 100644
--- a/frontend/components.d.ts
+++ b/frontend/components.d.ts
@@ -53,7 +53,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([]);
@@ -47,7 +63,7 @@
@@ -57,7 +73,6 @@
-
@@ -81,29 +96,44 @@
-
+
+
-
-
-
+
+
+
+
+
+
+ {{ option.label }}
+
+
+
+
+
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 {
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