prr 8 months ago
parent
commit
30bd47e5d5
  1. 3
      frontend/components.d.ts
  2. 21
      frontend/src/components/chat/Chat.vue
  3. 60
      frontend/src/components/chat/ChatBox.vue
  4. 27
      frontend/src/components/chat/ChatMessage.vue
  5. 29
      frontend/src/components/chat/ChatMsgList.vue
  6. 6
      frontend/src/components/chat/ChatUserList.vue
  7. 10
      frontend/src/components/chat/chatUserInfo.vue
  8. 235
      frontend/src/stores/chat.ts
  9. 11
      frontend/src/stores/db.ts
  10. 3
      frontend/src/stores/upgrade.ts
  11. 10
      frontend/src/system/initBuiltin.ts

3
frontend/components.d.ts

@ -61,6 +61,9 @@ declare module 'vue' {
ElContainer: typeof import('element-plus/es')['ElContainer']
ElDialog: typeof import('element-plus/es')['ElDialog']
ElDrawer: typeof import('element-plus/es')['ElDrawer']
ElDropdown: typeof import('element-plus/es')['ElDropdown']
ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu']
ElEmpty: typeof import('element-plus/es')['ElEmpty']
ElFooter: typeof import('element-plus/es')['ElFooter']
ElForm: typeof import('element-plus/es')['ElForm']

21
frontend/src/components/chat/Chat.vue

@ -132,6 +132,10 @@
:data="data"
:titles="['可选项', '已选项']"
filterable
:style="{
height: store.groupTitle === '创建群聊' ? '250px' : '350px',
}"
filter-placeholder="搜索用户名"
:props="{ key: 'key', label: 'label', avatar: 'avatar' }"
class="transfer-container"
>
@ -169,22 +173,25 @@
display: flex;
flex-direction: row; /* 将布局方向设置为横向 */
width: 550px; /* 让穿梭框占满宽度 */
justify-content: center;
align-items: center;
.el-transfer__buttons {
display: flex;
justify-content: space-evenly;
align-items: center;
width: 160px;
width: 120px;
padding: 0 0 !important;
.el-button {
width: 50px !important;
width: 40px !important;
height: 30px !important;
background-color: #0078d4;
color: #fff;
}
}
}
.el-transfer {
display: flex;
flex-direction: row; /* 将布局方向设置为横向 */
width: 550px; /* 让穿梭框占满宽度 */
height: 250px;
::v-deep .el-dialog .el-dialog__header {
border: none !important;
}
::v-deep .el-transfer-panel {

60
frontend/src/components/chat/ChatBox.vue

@ -3,7 +3,6 @@
class="chatbox-main"
v-if="store.targetChatId"
>
<!--聊天顶部区-->
<el-header class="chat-header">
<div class="header-title">
@ -15,10 +14,16 @@
<span
v-else-if="store.targetGroupInfo.displayName"
class="header-title-name"
>{{ store.targetGroupInfo.displayName }}{{ 1 }}</span
>{{ store.targetGroupInfo.displayName }}</span
>
<div @click="store.drawerVisible = true">
<div
v-if="
store.targetGroupInfo &&
Object.keys(store.targetGroupInfo).length > 0
"
@click="store.drawerVisible = true"
>
<el-icon><Tools /></el-icon>
<!-- 抽屉 -->
<el-drawer
@ -83,6 +88,17 @@
</el-drawer>
</div>
<div v-else>
<el-dropdown>
<el-icon><Tools /></el-icon>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item>删除好友</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
<!-- 邀请好友对话框 -->
<el-dialog
v-model="store.inviteFriendDialogVisible"
@ -117,8 +133,8 @@
<!--聊天主体区-->
<el-main class="msg-main">
<el-scrollbar ref="store.scrollbarRef">
<div ref="store.innerRef">
<el-scrollbar ref="scrollbarRef">
<div ref="innerRef">
<ChatMessage />
</div>
</el-scrollbar>
@ -201,6 +217,32 @@
const choose = useChooseStore();
const imgExt = ["png", "jpg", "jpeg", "gif", "bmp", "webp", "svg"];
const choosetype = ref("");
const scrollbarRef = ref(null);
const innerRef = ref(null);
function scrollToBottom() {
store.setScrollToBottom(innerRef, scrollbarRef);
}
// storemessageSendStatus.value = truescrollToBottom
watch(
() => store.messageSendStatus,
(newVal, _) => {
if (newVal) {
scrollToBottom();
}
}
);
// storemessageReceiveStatusscrollToBottom
watch(
() => store.messageReceiveStatus,
(newVal, _) => {
if (newVal) {
scrollToBottom();
}
}
);
// store.drawerVisible
watch(
@ -251,6 +293,14 @@
</script>
<style scoped>
:deep(.el-drawer__header) {
color: #000000;
}
:deep(.el-drawer__body) {
margin-top: -40px; /* 根据需要调整这个值 */
}
.group-name {
font-size: 16px;
border-top: 1px solid #edebeb;

27
frontend/src/components/chat/ChatMessage.vue

@ -5,6 +5,16 @@
style="margin-top: 10px"
:key="item.chatId"
>
<div
v-if="item.content_type == 'invite_group_message'"
class="system-message"
>
{{ item.message }}
<!-- <span v-if="item.isMe">{{ item.message }}</span>
<span v-else>{{ item.message }}</span> -->
</div>
<div v-else>
<div
v-if="item.isMe"
class="chat-item"
@ -35,6 +45,7 @@
<!-- 文件消息展示 -->
<div
@click="sys.openFile(item.message)"
v-else-if="item.content_type == 'file'"
:class="['chat-item-file', 'file-me']"
>
@ -153,7 +164,7 @@
</el-row>
</div>
</div>
</div>
<!-- 悬浮菜单 -->
<div
class="context-menu"
@ -180,10 +191,24 @@
<script setup lang="ts">
import { useChatStore } from "@/stores/chat";
import { System } from "@/system";
const store = useChatStore();
const sys: any = inject<System>("system");
</script>
<style scoped>
.system-message {
background-color: #e8e8e8; /* 设置背景颜色 */
color: #333; /* 设置文字颜色 */
font-size: 12px; /* 设置文字大小 */
padding: 2px 20px; /* 设置内边距 */
font-family: Arial, sans-serif;
border-radius: 10px; /* 设置边角为圆角 */
text-align: center; /* 文本居中显示 */
margin: 10px auto; /* 上下外边距为10px,左右自动(居中) */
max-width: 60%; /* 最大宽度为80% */
}
.bubble-me,
.bubble-other {
display: flex;

29
frontend/src/components/chat/ChatMsgList.vue

@ -1,5 +1,4 @@
<template>
<div
v-if="
(store.searchList.length > 0 ? store.searchList : store.chatList)
@ -37,6 +36,32 @@
></el-avatar
>
</el-col>
<!-- 在线状态 -->
<el-icon
v-if="item.online"
style="
position: absolute;
left: 40px;
bottom: 5px;
color: #0078d4;
"
>
<CircleCheckFilled />
</el-icon>
<!-- 离线状态 -->
<el-icon
v-else
style="
position: absolute;
left: 40px;
bottom: 5px;
color: #999999;
"
>
<CircleCloseFilled />
</el-icon>
<el-col
:span="18"
class="preview"
@ -50,6 +75,7 @@
<div class="previewName">
{{ item.displayName }}
</div>
<div class="previewTime">
{{ item.previewTimeFormat }}
</div>
@ -69,7 +95,6 @@
</el-row>
</div>
</div>
<div
v-else
class="emptyChat"

6
frontend/src/components/chat/ChatUserList.vue

@ -93,12 +93,6 @@
<el-col>
<div class="previewName">
{{ item.nickname }}
<el-icon
class="online-icon"
v-if="item.isOnline"
>
<CircleCheckFilled />
</el-icon>
</div>
</el-col>
<el-col :span="6">

10
frontend/src/components/chat/chatUserInfo.vue

@ -15,7 +15,13 @@
v-else
class="user-info-container"
>
<div class="user-details">
<div
class="user-details"
v-if="
store.targetUserInfo &&
Object.keys(store.targetUserInfo).length > 0
"
>
<p>昵称: {{ store.targetUserInfo.displayName }}</p>
<p>邮箱: {{ store.targetUserInfo.email }}</p>
<p>电话: {{ store.targetUserInfo.phone }}</p>
@ -25,7 +31,7 @@
<p>入职日期: {{ store.targetUserInfo.hiredDate }}</p>
</div>
<el-button
type="primary"
style="background-color: #0078d4; color: #fff"
@click="sendMessage(store.targetChatId)"
>发送消息</el-button
>

235
frontend/src/stores/chat.ts

@ -95,6 +95,9 @@ export const useChatStore = defineStore('chatStore', () => {
const searchList = ref([]);
const groups: any = ref([])
const searchInput = ref('');
// 定义消息发送、接受的状态用于控制滚动条的滚动
const messageSendStatus = ref(false)
const messageReceiveStatus = ref(false)
// 群成员列表
const groupMemberList = ref<any[]>([])
@ -108,6 +111,9 @@ export const useChatStore = defineStore('chatStore', () => {
// groupTitle
const groupTitle = ref('')
// 群组信息系统消息
const groupSystemMessage = ref('')
// 邀请好友
const inviteFriendDialogVisible = ref(false)
const contextMenu = ref({
@ -149,7 +155,7 @@ export const useChatStore = defineStore('chatStore', () => {
// 新增代码:提取部门成员并去重,按指定字段保存
const uniqueUsers = new Set();
console.log(data.data.users)
data.data.users.forEach((department: { users: any[]; }) => {
department.users?.forEach(async (user) => {
if (!uniqueUsers.has(user.user_id)) {
@ -179,6 +185,7 @@ export const useChatStore = defineStore('chatStore', () => {
// 初始化用户列表
const initChatList = async () => {
console.log("收到消息被刷新了!!!!")
const userSessionList = await db.getAll("workbenchSessionList");
// 确保groupList已加载
if (groupList.value.length > 0) {
@ -196,21 +203,33 @@ export const useChatStore = defineStore('chatStore', () => {
const sendMessage = async (messageType: string) => {
console.log("群聊消息类型", messageType)
if (messageType == 'text') {
await sendTextMessage()
}
if (messageType == 'image') {
await sendImageMessage()
console.log("messageType", messageType)
if (messageType == "text" && message.value.trim() == '') {
return
}
messageSendStatus.value = false
console.log(messageType)
if (messageType == 'applyfile') {
// 根据文件扩展名调整消息类型
const fileExtension = sendInfo.value[0]?.split('.').pop().toLowerCase(); // 确保扩展名比较时不区分大小写
if (['png', 'jpg', 'jpeg', 'gif', 'bmp'].includes(fileExtension)) {
messageType = 'image';
} else if (['txt', 'doc', 'pdf', 'xls', 'xlsx', 'ppt', 'pptx'].includes(fileExtension)) {
messageType = 'applyfile';
}
}
if (messageType == 'text') {
await sendTextMessage()
} else if (messageType == 'image') {
await sendImageMessage()
} else if (messageType == 'applyfile') {
await sendFileMessage()
}
}
// 发送图片消息
const sendImageMessage = async () => {
@ -234,7 +253,7 @@ export const useChatStore = defineStore('chatStore', () => {
Message.to_groupid = targetGroupInfo.value?.group_id || '';
Message.userInfo = {};
}
console.log(Message)
// 发送文件消息
const res = await fetchPost(config.userInfo.url + '/chat/send', JSON.stringify(Message));
if (!res.ok) {
@ -242,11 +261,11 @@ export const useChatStore = defineStore('chatStore', () => {
return;
}
Message.message = await getImageSrc(Message.message)
// 封装成消息历史记录
const messageHistory = {
...Message,
isMe: true,
message: await getImageSrc(Message.message),
previewTimeFormat: formatTime(Date.now()),
displayName: userInfo.value.nickname,
chatId: Message.type === 'group' ? targetGroupInfo.value.chatId : targetUserInfo.value.chatId,
@ -265,6 +284,8 @@ export const useChatStore = defineStore('chatStore', () => {
fileSendActive.value = true;
notifySuccess('文件发送成功');
messageSendStatus.value = true
// 两秒后关闭
setTimeout(() => {
fileSendActive.value = false;
@ -289,7 +310,7 @@ export const useChatStore = defineStore('chatStore', () => {
Message.content_type = 'file';
Message.userId = userInfo.value.id;
Message.toUserId = targetChatId.value;
Message.message = sendInfo.value[0];
Message.message = "data/userData/1"+sendInfo.value[0];
Message.to_groupid = targetGroupInfo.value?.group_id || '';
Message.userInfo = {};
}
@ -315,6 +336,7 @@ export const useChatStore = defineStore('chatStore', () => {
createdAt: Date.now()
};
// 添加到聊天记录
if (Message.type === 'group') {
await db.addOne("workbenchGroupChatRecord", messageHistory);
@ -325,6 +347,7 @@ export const useChatStore = defineStore('chatStore', () => {
fileSendActive.value = true;
notifySuccess('文件发送成功');
messageSendStatus.value = true
// 两秒后关闭
setTimeout(() => {
fileSendActive.value = false;
@ -356,7 +379,6 @@ export const useChatStore = defineStore('chatStore', () => {
Message.userInfo = {}
}
console.log("token", config.userInfo.token)
// 发送消息
const res = await fetchPost(config.userInfo.url + '/chat/send', JSON.stringify(Message));
if (res.ok) {
@ -393,8 +415,7 @@ export const useChatStore = defineStore('chatStore', () => {
// 清空输入框
clearMessage();
// 聊天框滚动到底部
await setScrollToBottom();
messageSendStatus.value = true
}
}
@ -413,10 +434,11 @@ export const useChatStore = defineStore('chatStore', () => {
toUserId: data.toUserId,
chatId: data.userId,
type: data.type,
online: data.online,
messages: data.message,
displayName: data.userInfo.nickname,
nickname: data.userInfo.nickname,
time: Date.now().toString,
time: Date.now(),
previewMessage: data.message,
previewTimeFormat: formatTime(Date.now()), // 时间格式化函数
createdAt: Date.now(),
@ -435,7 +457,7 @@ export const useChatStore = defineStore('chatStore', () => {
nickname: data.userInfo.nickname,
displayName: data.userInfo.nickname,
previewMessage: data.message,
time: data.time || Date.now().toString,
time: Date.now(),
previewTimeFormat: formatTime(Date.now())
});
@ -472,6 +494,7 @@ export const useChatStore = defineStore('chatStore', () => {
chatId: user.id,
nickname: user.nickname,
avatar: user.avatar,
online: user.online,
toUserId: userInfo.value.id,
previewMessage: message.value || "快开始打招呼吧!",
previewTimeFormat: formatTime(Date.now()),
@ -487,6 +510,7 @@ export const useChatStore = defineStore('chatStore', () => {
username: user.username,
nickname: user.nickname,
avatar: user.avatar,
online: user.online,
toUserId: userInfo.value.id,
previewMessage: message.value || "快开始打招呼吧!",
previewTimeFormat: formatTime(Date.now()),
@ -526,14 +550,13 @@ export const useChatStore = defineStore('chatStore', () => {
// 获取用户表中所有用户
const getAllUser = async () => {
allUserList.value = await db.getAll("workbenchChatUser");
const users = await db.getAll("workbenchChatUser");
// 过滤掉当前用户
allUserList.value = users.filter((user: { id: any; }) => user.id !== userInfo.value.id);
};
// 创建群聊
const createGroupChat = async (userIds: number[]) => {
console.log(userIds)
const createGroupChat = async (userIds: string[]) => {
if (userIds.length === 0) {
notifyError('请选择用户')
@ -561,7 +584,6 @@ export const useChatStore = defineStore('chatStore', () => {
}
const groupData = await res.json();
console.log(groupData)
// 构建数据入库
// 群数据
const group_id = groupData.data.group_id
@ -570,20 +592,38 @@ export const useChatStore = defineStore('chatStore', () => {
const groupConversation = {
group_id: group_id,
avatar: "./logo.png",
messages: "",
messages: message.value,
chatId: group_id,
type: "group",
displayName: departmentName.value,
previewMessage: "快来和大家一起交流吧!",
previewMessage: message.value,
previewTimeFormat: formatTime(Date.now()),
createdAt: new Date()
}
groupList.value.push(groupConversation)
// 这里的message是群主发送的邀请信息,需要根据userIds去拿到被邀请用户的nickname
const userList = await db.getByIds("workbenchChatUser", userIds)
const inviteUserName = userList.map((user: { nickname: string; }) => user.nickname).join(',')
// 封装邀请信息
const groupInviteMessage = {
content_type: "invite_group_message",
isMe: true,
chatId: group_id,
message: `你邀请 ${inviteUserName} 加入群聊`,
createdAt: Date.now()
}
// 添加到数据库
await db.addOne("workbenchGroupChatRecord", groupInviteMessage)
// 更新会话列表
initChatList()
// 关闭对话弹窗
setGroupChatInvitedDialogVisible(false)
notifySuccess('创建群聊成功')
// 更新群组列表
await getAllList()
notifySuccess('创建群聊成功')
};
// 处理用户消息
@ -593,6 +633,9 @@ export const useChatStore = defineStore('chatStore', () => {
// 更新会话列表数据库
// 更新chatlist
// 更新聊天记录
console.log(data)
messageReceiveStatus.value = false
// 判断是否是自己发的消息
if (data.userId === userInfo.value.id) {
@ -604,9 +647,6 @@ export const useChatStore = defineStore('chatStore', () => {
return
}
// 添加消息记录
const addMessageHistory = {
type: data.type,
@ -640,25 +680,27 @@ export const useChatStore = defineStore('chatStore', () => {
changeChatListAndChatHistory(data)
// 更改聊天记录
chatHistory.value.push(addMessageHistory)
messageReceiveStatus.value = true
};
const setScrollToBottom = async () => {
// await nextTick(); // 确保 DOM 已经更新完毕
// 接收 innerRef 和 scrollbarRef 作为参数
const setScrollToBottom = async (innerRef: any, scrollbarRef: any) => {
await nextTick(); // 确保 DOM 已经更新完毕
// // 检查 innerRef 是否存在
// if (!innerRef.value) {
// console.warn('innerRef is not defined.');
// return;
// }
// 检查 innerRef 是否存在
if (!innerRef.value) {
console.warn('innerRef is not defined.');
return;
}
// // 设置滚动条到底部
// const max = innerRef.value.clientHeight;
// if (scrollbarRef.value) {
// scrollbarRef.value.setScrollTop(max);
// } else {
// console.warn('scrollbarRef is not defined.');
// }
// 设置滚动条到底部
const max = innerRef.value.clientHeight;
if (scrollbarRef.value) {
scrollbarRef.value.setScrollTop(max);
} else {
console.warn('scrollbarRef is not defined.');
}
};
// 获取群列表信息
const getGroupList = async () => {
@ -703,15 +745,20 @@ export const useChatStore = defineStore('chatStore', () => {
}
};
const onlineUserData = async (data: OnlineUserInfoType[]) => {
if (data.length === 0) {
onlineUserList.value = []
return
// 更新会话列表用户在线状态
chatList.value = chatList.value.map((chat: { type: string; }) => {
if (chat.type === 'user') {
return { ...chat, online: false };
}
return chat;
});
return
}
// 创建一个新的用户数组,用于更新在线用户列表
const updatedOnlineUsers = data.map(item => ({
id: item.id,
@ -723,6 +770,7 @@ export const useChatStore = defineStore('chatStore', () => {
username: item.username,
nickname: item.nickname
})).filter(item => item.id && item.login_ip); // 确保所有项都有有效的id和ip
// 更新在线用户列表,只添加不存在的用户
updatedOnlineUsers.forEach(newUser => {
if (!onlineUserList.value.some(existingUser => existingUser.id === newUser.id)) {
@ -730,8 +778,26 @@ export const useChatStore = defineStore('chatStore', () => {
}
});
// 新增代码:从onlineUserList中移除不在data中的用户
onlineUserList.value = onlineUserList.value.filter(user =>
data.some(newUser => newUser.id === user.id)
);
// 更新数据库中的用户信息
await updateOrAddUsers(updatedOnlineUsers);
// 更新会话列表用户在线状态
const updateOnlineStatus = async (data: any[]) => {
const updatedChats = chatList.value.map((chat: { type: string; chatId: any; }) => {
if (chat.type === 'user') {
const isOnline = data.some(user => user.id === chat.chatId);
return { ...chat, online: isOnline };
}
return chat;
});
return updatedChats;
};
chatList.value = await updateOnlineStatus(updatedOnlineUsers);
};
const updateOrAddUsers = async (users: OnlineUserInfoType[]) => {
@ -817,6 +883,7 @@ export const useChatStore = defineStore('chatStore', () => {
// 获取当前用户和目标用户的聊天记录
console.log(userInfo.value.id, chatId, type)
const history = await getHistory(userInfo.value.id, chatId, type)
// await getGroupInviteMessage(chatId)
chatHistory.value = history;
// 设置目标用户的信息
await setTargetGrouprInfo(chatId);
@ -858,7 +925,6 @@ export const useChatStore = defineStore('chatStore', () => {
// 设置目标群信息
const setTargetGrouprInfo = async (id: string) => {
for (const group of groupList.value) {
console.log(group)
if (group.group_id === id) {
targetGroupInfo.value = group;
targetUserInfo.value = {};
@ -872,7 +938,12 @@ export const useChatStore = defineStore('chatStore', () => {
};
const groupChatMessage = async (data: any) => {
const messageRecord = {
messageReceiveStatus.value = false
console.log("接受消息", data)
// 构建消息记录
const messageRecord: any = {
userId: data.userId,
groupId: data.to_groupid,
content_type: data.content_type,
@ -881,7 +952,7 @@ export const useChatStore = defineStore('chatStore', () => {
chatId: data.to_groupid,
isMe: false,
previewTimeFormat: formatTime(Date.now()),
displayName: data.userInfo.nickname,
displayName: data.userInfo.nickname, // 发送者昵称
avatar: data.userInfo.avatar,
role_id: data.userInfo.role_id,
createdAt: Date.now(),
@ -889,22 +960,29 @@ export const useChatStore = defineStore('chatStore', () => {
if (data.content_type === 'image') {
messageRecord.message = await getImageSrc(data.message)
messageRecord.previewMessage = "[图片消息]"
} else if (data.content_type === 'text') {
messageRecord.message = data.message
messageRecord.previewMessage = data.message
} else if (data.content_type === 'file') {
messageRecord.message = data.message
messageRecord.previewMessage = "[文件消息]"
}
// 判断当前消息是否是自己发送的
// 判断接受的消息是否是自己发送的
if (messageRecord.userId === userInfo.value.id) {
return;
}
console.log(messageRecord)
// 将消息记录添加到数据库
const res = await db.addOne("workbenchGroupChatRecord", messageRecord);
console.log(res)
await db.addOne("workbenchGroupChatRecord", messageRecord);
// // push进groupList
// groupList.value.push(messageRecord)
// 更改聊天记录
chatHistory.value.push(messageRecord)
messageReceiveStatus.value = true
};
const showContextMenu = (event: any, id: number) => {
@ -924,13 +1002,12 @@ export const useChatStore = defineStore('chatStore', () => {
console.log(await res.json())
// 从groupList中删除
groupList.value = groupList.value.filter((group: any) => group.group_id !== group_id)
const a = await db.deleteByField("workbenchGroupUserList", "group_id", group_id)
console.log(a)
await db.deleteByField("workbenchGroupUserList", "group_id", group_id)
initChatList()
notifySuccess("退出群聊成功")
targetGroupInfo.value = {}
targetChatId.value = ''
drawerVisible.value = false
notifySuccess("退出群聊成功")
}
// 获取群成员
@ -963,7 +1040,6 @@ export const useChatStore = defineStore('chatStore', () => {
if (!imageMessage.startsWith('/')) {
imageMessage = '/' + imageMessage;
}
console.log("地址:-----------", imageMessage)
const path = userInfo.value.url + "/chat/image/view?path=" + imageMessage;
const response = await fetchGet(path);
@ -976,15 +1052,51 @@ export const useChatStore = defineStore('chatStore', () => {
const reader = new FileReader();
reader.onloadend = () => {
const base64data = reader.result; // 转换为 base64
console.log(base64data);
resolve(base64data);
};
reader.readAsDataURL(blob);
});
}
// 设置群组信息(todo:如果群的系统消息更新,则更新群组信息)
const groupInviteMessage = async (data: any) => {
const groupInviteMessage = {
group_id: data.group_id,
message: data.message,
chatId: data.group_id,
isMe: false,
content_type: "invite_group_message",
createdAt: Date.now()
};
await db.addOne("workbenchGroupChatRecord", groupInviteMessage)
const groupExists = groupList.value.some((group: { group_id: string; }) => group.group_id === data.group_id);
// 如果不存在,则获取群聊列表
if (!groupExists) {
await getGroupList();
// 合并groupList到chatList,同时去重
const existingGroupIds = new Set(chatList.value.map((item: { chatId: string }) => item.chatId));
const newGroups = groupList.value.filter((group: { chatId: string }) => !existingGroupIds.has(group.chatId));
chatList.value = [...chatList.value, ...newGroups];
}
}
// 获取群组系统消息
const getGroupInviteMessage = async (group_id: string) => {
groupSystemMessage.value = ""
// 邀请群信息
const message = await db.getByField("workbenchGroupInviteMessage", "group_id", group_id)
groupSystemMessage.value = message[0].Message
}
return {
emojiList,
groupSystemMessage,
onlineUserList,
chatList,
groupList,
@ -1018,6 +1130,8 @@ export const useChatStore = defineStore('chatStore', () => {
addMemberDialogVisible,
groupTitle,
inviteUserList,
messageSendStatus,
messageReceiveStatus,
initChat,
showContextMenu,
setCurrentNavId,
@ -1038,6 +1152,9 @@ export const useChatStore = defineStore('chatStore', () => {
inviteFriend,
getGroupMember,
addMember,
getImageSrc
getImageSrc,
groupInviteMessage,
getGroupInviteMessage,
setScrollToBottom
};
});

11
frontend/src/stores/db.ts

@ -1,6 +1,6 @@
import Dexie from 'dexie';
export type ChatTable = 'chatuser' | 'chatmsg' | 'workbenchChatRecord' | 'workbenchChatUser' | 'workbenchSessionList' | 'groupSessionList' | 'workbenchGroupChatRecord' | 'workbenchGroupUserList';
export type ChatTable = 'chatuser' | 'chatmsg' | 'workbenchChatRecord' | 'workbenchChatUser' | 'workbenchSessionList' | 'groupSessionList' | 'workbenchGroupChatRecord' | 'workbenchGroupUserList' | 'workbenchGroupInviteMessage';
export const dbInit: any = new Dexie('GodoOSDatabase');
dbInit.version(1).stores({
@ -16,6 +16,8 @@ dbInit.version(1).stores({
workbenchGroupChatRecord: '++id,chatId,userId,to_groupid,messageType,userInfo,message,time,type,createdAt',
// 群用户列表
workbenchGroupUserList: '++id, group_id, createdAt, userIdArray',
// 群组邀请信息消息
workbenchGroupInviteMessage: '++id, group_id,userId, message, createdAt',
// 用户列表
chatuser: '++id,ip,hostname,userName,avatar,mobile,nickName,isOnline,updatedAt,createdAt',
chatmsg: '++id,toUserId,targetIp,senderInfo,reciperInfo,previewMessage,content,type,status,isRead,isMe,readAt,createdAt',
@ -24,6 +26,7 @@ dbInit.version(1).stores({
workbenchChatUser: any;
workbenchGroupChatRecord: any;
workbenchGroupUserList: any;
workbenchGroupInviteMessage: any;
workbenchChatRecord: { addIndex: (arg0: string, arg1: (obj: { toUserId: any; }) => any) => void; };
}) => {
// 手动添加索引
@ -32,6 +35,7 @@ dbInit.version(1).stores({
tx.workbenchChatUser.addIndex('chatId', (obj: { chatId: any; }) => obj.chatId);
tx.workbenchGroupChatRecord.addIndex('chatId', (obj: { chatId: any; }) => obj.chatId);
tx.workbenchGroupUserList.addIndex('group_id', (obj: { group_id: any; }) => obj.group_id);
tx.workbenchGroupInviteMessage.addIndex('group_id', (obj: { group_id: any; }) => obj.group_id);
});
export const db = {
@ -110,6 +114,11 @@ export const db = {
return row[fName]
},
// 写一个根据id数组的in方法
async getByIds(tableName: ChatTable, ids: string[]) {
return dbInit[tableName].where("id").anyOf(ids).toArray()
},
async getByField(tableName: ChatTable, fieldName: string, val: any) {
return dbInit[tableName].where(fieldName).equals(val).toArray()
},

3
frontend/src/stores/upgrade.ts

@ -87,6 +87,9 @@ export const useUpgradeStore = defineStore('upgradeStore', () => {
console.log(message)
chatChatStore.groupChatMessage(message.data);
break;
case 'update_group':
chatChatStore.groupInviteMessage(message.data)
break;
default:
console.warn('Unknown message type:', message.type);
}

10
frontend/src/system/initBuiltin.ts

@ -1,14 +1,14 @@
import { t } from "@/i18n";
import type { System } from "./index";
import { BrowserWindow } from "./window/BrowserWindow";
import { t } from "@/i18n";
import { dealIcon } from "../util/Icon";
import { basename } from "./core/Path";
import { Dialog } from "./window/Dialog";
import { Tray } from "./menu/Tary";
import { appList } from "./applist.ts";
import { getSystemConfig } from './config'
import { getSystemConfig } from './config';
import { basename } from "./core/Path";
import { memberList } from "./member.ts";
import { Tray } from "./menu/Tary";
import { Dialog } from "./window/Dialog";
const unknownIcon = "unknown";
export function initBuiltinApp(system: System) {
const config = getSystemConfig();

Loading…
Cancel
Save