Browse Source

add:完善文件聊天消息展示

master
qiutianhong 7 months ago
parent
commit
10b136810f
  1. 35
      frontend/src/components/chat/ChatBox.vue
  2. 287
      frontend/src/components/chat/ChatMessage.vue
  3. 20
      frontend/src/components/chat/ChatMsgList.vue
  4. 181
      frontend/src/stores/chat.ts
  5. 11
      frontend/src/stores/db.ts
  6. 3
      frontend/src/stores/upgrade.ts
  7. 14
      frontend/src/system/initBuiltin.ts

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

@ -18,7 +18,10 @@
> >
<div <div
v-if="store.targetGroupInfo.value && Object.keys(store.targetGroupInfo.value).length > 0" v-if="
store.targetGroupInfo &&
Object.keys(store.targetGroupInfo).length > 0
"
@click="store.drawerVisible = true" @click="store.drawerVisible = true"
> >
<el-icon><Tools /></el-icon> <el-icon><Tools /></el-icon>
@ -130,8 +133,8 @@
<!--聊天主体区--> <!--聊天主体区-->
<el-main class="msg-main"> <el-main class="msg-main">
<el-scrollbar ref="store.scrollbarRef"> <el-scrollbar ref="scrollbarRef">
<div ref="store.innerRef"> <div ref="innerRef">
<ChatMessage /> <ChatMessage />
</div> </div>
</el-scrollbar> </el-scrollbar>
@ -214,6 +217,32 @@
const choose = useChooseStore(); const choose = useChooseStore();
const imgExt = ["png", "jpg", "jpeg", "gif", "bmp", "webp", "svg"]; const imgExt = ["png", "jpg", "jpeg", "gif", "bmp", "webp", "svg"];
const choosetype = ref(""); 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 // store.drawerVisible
watch( watch(

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

@ -6,154 +6,165 @@
:key="item.chatId" :key="item.chatId"
> >
<div <div
v-if="item.isMe" v-if="item.content_type == 'invite_group_message'"
class="chat-item" class="system-message"
> >
<el-row> {{ item.message }}
<el-col :span="8" /> <!-- <span v-if="item.isMe">{{ item.message }}</span>
<el-col :span="14"> <span v-else>{{ item.message }}</span> -->
<el-row> </div>
<el-col :span="24">
<div class="chat-name-me">
{{ store.userInfo.nickname }}
</div>
</el-col>
</el-row>
<div
class="bubble-me"
@contextmenu.prevent="
store.showContextMenu($event, item.chatId)
"
>
<!-- 文本消息展示 -->
<div
v-if="item.content_type == 'text'"
class="chat-font"
>
{{ item.message }}
</div>
<!-- 文件消息展示 --> <div v-else>
<div
v-if="item.isMe"
class="chat-item"
>
<el-row>
<el-col :span="8" />
<el-col :span="14">
<el-row>
<el-col :span="24">
<div class="chat-name-me">
{{ store.userInfo.nickname }}
</div>
</el-col>
</el-row>
<div <div
v-else-if="item.content_type == 'file'" class="bubble-me"
:class="['chat-item-file', 'file-me']" @contextmenu.prevent="
store.showContextMenu($event, item.chatId)
"
> >
<div class="chat-item-file-icon"> <!-- 文本消息展示 -->
<el-icon <div
size="30" v-if="item.content_type == 'text'"
color="#303133" class="chat-font"
><Document >
/></el-icon>
</div>
<div class="chat-item-file-name">
{{ item.message }} {{ item.message }}
</div> </div>
</div>
<!-- 图片消息展示 --> <!-- 文件消息展示 -->
<div <div
v-else-if="item.content_type == 'image'" @click="sys.openFile(item.message)"
class="chat-item-image" v-else-if="item.content_type == 'file'"
> :class="['chat-item-file', 'file-me']"
<el-image >
fit="cover" <div class="chat-item-file-icon">
loading="lazy" <el-icon
:preview-src-list="[item.message]" size="30"
:src="item.message" color="#303133"
><Document
/></el-icon>
</div>
<div class="chat-item-file-name">
{{ item.message }}
</div>
</div>
<!-- 图片消息展示 -->
<div
v-else-if="item.content_type == 'image'"
class="chat-item-image"
>
<el-image
fit="cover"
loading="lazy"
:preview-src-list="[item.message]"
:src="item.message"
/>
</div>
</div>
<!-- 发送时间展示在消息框外部的下方 -->
<div class="chat-time-me-outer">
{{ item.previewTimeFormat }}
</div>
</el-col>
<el-col :span="2">
<div class="chat-avatar">
<el-avatar
shape="square"
style="margin: 0; float: left"
:size="32"
class="userAvatar"
:src="item.avatar"
/> />
</div> </div>
</div> </el-col>
<!-- 发送时间展示在消息框外部的下方 --> </el-row>
<div class="chat-time-me-outer"> </div>
{{ item.previewTimeFormat }} <div
</div> v-else
</el-col> class="chat-item"
<el-col :span="2"> >
<div class="chat-avatar"> <el-row>
<el-avatar <el-col :span="2">
shape="square" <div class="chat-avatar">
style="margin: 0; float: left" <el-avatar
:size="32" shape="square"
class="userAvatar" style="margin: 0; float: right"
:src="item.avatar" :size="32"
/> class="userAvatar"
</div> :src="item.avatar"
</el-col> />
</el-row>
</div>
<div
v-else
class="chat-item"
>
<el-row>
<el-col :span="2">
<div class="chat-avatar">
<el-avatar
shape="square"
style="margin: 0; float: right"
:size="32"
class="userAvatar"
:src="item.avatar"
/>
</div>
</el-col>
<el-col :span="14">
<el-row>
<el-col :span="24">
<div class="chat-name-other">
{{ item.displayName }}
</div>
</el-col>
</el-row>
<div class="bubble-other">
<!-- 文本消息展示 -->
<div
v-if="item.content_type == 'text'"
class="chat-font"
>
{{ item.message }}
</div> </div>
</el-col>
<el-col :span="14">
<el-row>
<el-col :span="24">
<div class="chat-name-other">
{{ item.displayName }}
</div>
</el-col>
</el-row>
<div class="bubble-other">
<!-- 文本消息展示 -->
<div
v-if="item.content_type == 'text'"
class="chat-font"
>
{{ item.message }}
</div>
<!-- 文件消息展示 --> <!-- 文件消息展示 -->
<div <div
v-else-if="item.content_type == 'file'" v-else-if="item.content_type == 'file'"
:class="['chat-item-file', 'file-other']" :class="['chat-item-file', 'file-other']"
> >
<div class="chat-item-file-icon"> <div class="chat-item-file-icon">
<el-icon <el-icon
size="30" size="30"
color="#303133" color="#303133"
><Document ><Document
/></el-icon> /></el-icon>
</div>
<div class="chat-item-file-name">
{{ item.message }}
</div>
</div> </div>
<div class="chat-item-file-name">
{{ item.message }} <!-- 图片消息展示 -->
<div
v-else-if="item.content_type == 'image'"
class="chat-item-image"
>
<el-image
fit="cover"
loading="lazy"
:preview-src-list="[item.message]"
:src="item.message"
/>
</div> </div>
</div> </div>
<!-- 发送时间展示在消息框外部的下方 -->
<!-- 图片消息展示 --> <div class="chat-time-other-outer">
<div {{ item.previewTimeFormat }}
v-else-if="item.content_type == 'image'"
class="chat-item-image"
>
<el-image
fit="cover"
loading="lazy"
:preview-src-list="[item.message]"
:src="item.message"
/>
</div> </div>
</div> </el-col>
<!-- 发送时间展示在消息框外部的下方 --> <el-col :span="8" />
<div class="chat-time-other-outer"> </el-row>
{{ item.previewTimeFormat }} </div>
</div>
</el-col>
<el-col :span="8" />
</el-row>
</div> </div>
</div> </div>
<!-- 悬浮菜单 --> <!-- 悬浮菜单 -->
<div <div
class="context-menu" class="context-menu"
@ -180,10 +191,24 @@
<script setup lang="ts"> <script setup lang="ts">
import { useChatStore } from "@/stores/chat"; import { useChatStore } from "@/stores/chat";
import { System } from "@/system";
const store = useChatStore(); const store = useChatStore();
const sys: any = inject<System>("system");
</script> </script>
<style scoped> <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-me,
.bubble-other { .bubble-other {
display: flex; display: flex;

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

@ -37,12 +37,30 @@
> >
</el-col> </el-col>
<!-- 在线状态 -->
<el-icon <el-icon
v-if="item.online" v-if="item.online"
style="position: absolute; left: 40px; bottom: 5px;" style="
position: absolute;
left: 40px;
bottom: 5px;
color: #0078d4;
"
> >
<CircleCheckFilled /> <CircleCheckFilled />
</el-icon> </el-icon>
<!-- 离线状态 -->
<el-icon
v-else
style="
position: absolute;
left: 40px;
bottom: 5px;
color: #999999;
"
>
<CircleCloseFilled />
</el-icon>
<el-col <el-col
:span="18" :span="18"

181
frontend/src/stores/chat.ts

@ -95,6 +95,9 @@ export const useChatStore = defineStore('chatStore', () => {
const searchList = ref([]); const searchList = ref([]);
const groups: any = ref([]) const groups: any = ref([])
const searchInput = ref(''); const searchInput = ref('');
// 定义消息发送、接受的状态用于控制滚动条的滚动
const messageSendStatus = ref(false)
const messageReceiveStatus = ref(false)
// 群成员列表 // 群成员列表
const groupMemberList = ref<any[]>([]) const groupMemberList = ref<any[]>([])
@ -108,6 +111,9 @@ export const useChatStore = defineStore('chatStore', () => {
// groupTitle // groupTitle
const groupTitle = ref('') const groupTitle = ref('')
// 群组信息系统消息
const groupSystemMessage = ref('')
// 邀请好友 // 邀请好友
const inviteFriendDialogVisible = ref(false) const inviteFriendDialogVisible = ref(false)
const contextMenu = ref({ const contextMenu = ref({
@ -197,21 +203,33 @@ export const useChatStore = defineStore('chatStore', () => {
const sendMessage = async (messageType: string) => { const sendMessage = async (messageType: string) => {
console.log("群聊消息类型", messageType)
if (messageType == 'text') { console.log("messageType", messageType)
await sendTextMessage() if (messageType == "text" && message.value.trim() == '') {
} return
if (messageType == 'image') {
await sendImageMessage()
} }
messageSendStatus.value = false
console.log(messageType)
if (messageType == 'applyfile') { 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() await sendFileMessage()
} }
} }
// 发送图片消息 // 发送图片消息
const sendImageMessage = async () => { const sendImageMessage = async () => {
@ -235,7 +253,7 @@ export const useChatStore = defineStore('chatStore', () => {
Message.to_groupid = targetGroupInfo.value?.group_id || ''; Message.to_groupid = targetGroupInfo.value?.group_id || '';
Message.userInfo = {}; Message.userInfo = {};
} }
console.log(Message)
// 发送文件消息 // 发送文件消息
const res = await fetchPost(config.userInfo.url + '/chat/send', JSON.stringify(Message)); const res = await fetchPost(config.userInfo.url + '/chat/send', JSON.stringify(Message));
if (!res.ok) { if (!res.ok) {
@ -266,6 +284,8 @@ export const useChatStore = defineStore('chatStore', () => {
fileSendActive.value = true; fileSendActive.value = true;
notifySuccess('文件发送成功'); notifySuccess('文件发送成功');
messageSendStatus.value = true
// 两秒后关闭 // 两秒后关闭
setTimeout(() => { setTimeout(() => {
fileSendActive.value = false; fileSendActive.value = false;
@ -290,7 +310,7 @@ export const useChatStore = defineStore('chatStore', () => {
Message.content_type = 'file'; Message.content_type = 'file';
Message.userId = userInfo.value.id; Message.userId = userInfo.value.id;
Message.toUserId = targetChatId.value; 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.to_groupid = targetGroupInfo.value?.group_id || '';
Message.userInfo = {}; Message.userInfo = {};
} }
@ -316,6 +336,7 @@ export const useChatStore = defineStore('chatStore', () => {
createdAt: Date.now() createdAt: Date.now()
}; };
// 添加到聊天记录 // 添加到聊天记录
if (Message.type === 'group') { if (Message.type === 'group') {
await db.addOne("workbenchGroupChatRecord", messageHistory); await db.addOne("workbenchGroupChatRecord", messageHistory);
@ -326,6 +347,7 @@ export const useChatStore = defineStore('chatStore', () => {
fileSendActive.value = true; fileSendActive.value = true;
notifySuccess('文件发送成功'); notifySuccess('文件发送成功');
messageSendStatus.value = true
// 两秒后关闭 // 两秒后关闭
setTimeout(() => { setTimeout(() => {
fileSendActive.value = false; fileSendActive.value = false;
@ -393,8 +415,7 @@ export const useChatStore = defineStore('chatStore', () => {
// 清空输入框 // 清空输入框
clearMessage(); clearMessage();
// 聊天框滚动到底部 messageSendStatus.value = true
await setScrollToBottom();
} }
} }
@ -417,7 +438,7 @@ export const useChatStore = defineStore('chatStore', () => {
messages: data.message, messages: data.message,
displayName: data.userInfo.nickname, displayName: data.userInfo.nickname,
nickname: data.userInfo.nickname, nickname: data.userInfo.nickname,
time: Date.now().toString, time: Date.now(),
previewMessage: data.message, previewMessage: data.message,
previewTimeFormat: formatTime(Date.now()), // 时间格式化函数 previewTimeFormat: formatTime(Date.now()), // 时间格式化函数
createdAt: Date.now(), createdAt: Date.now(),
@ -436,7 +457,7 @@ export const useChatStore = defineStore('chatStore', () => {
nickname: data.userInfo.nickname, nickname: data.userInfo.nickname,
displayName: data.userInfo.nickname, displayName: data.userInfo.nickname,
previewMessage: data.message, previewMessage: data.message,
time: data.time || Date.now().toString, time: Date.now(),
previewTimeFormat: formatTime(Date.now()) previewTimeFormat: formatTime(Date.now())
}); });
@ -535,7 +556,7 @@ export const useChatStore = defineStore('chatStore', () => {
}; };
// 创建群聊 // 创建群聊
const createGroupChat = async (userIds: number[]) => { const createGroupChat = async (userIds: string[]) => {
if (userIds.length === 0) { if (userIds.length === 0) {
notifyError('请选择用户') notifyError('请选择用户')
@ -563,20 +584,15 @@ export const useChatStore = defineStore('chatStore', () => {
} }
const groupData = await res.json(); const groupData = await res.json();
console.log(groupData)
// 构建数据入库 // 构建数据入库
// 群数据 // 群数据
const group_id = groupData.data.group_id const group_id = groupData.data.group_id
// 设置message
message.value = "大家好,我是" + userInfo.value.nickname
// 添加到会话列表中 // 添加到会话列表中
const groupConversation = { const groupConversation = {
group_id: group_id, group_id: group_id,
avatar: "./logo.png", avatar: "./logo.png",
messages: "", messages: message.value,
chatId: group_id, chatId: group_id,
type: "group", type: "group",
displayName: departmentName.value, displayName: departmentName.value,
@ -585,17 +601,28 @@ export const useChatStore = defineStore('chatStore', () => {
createdAt: new Date() createdAt: new Date()
} }
groupList.value.push(groupConversation) 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() initChatList()
// 关闭对话弹窗 // 关闭对话弹窗
setGroupChatInvitedDialogVisible(false) setGroupChatInvitedDialogVisible(false)
// 更新群组列表
await getAllList() await getAllList()
// 创建群之后发送一条初始消息
// 设置targetGroupInfo
setTargetGrouprInfo(group_id)
// 发送消息
await sendMessage("text")
targetUserInfo.value = {};
notifySuccess('创建群聊成功') notifySuccess('创建群聊成功')
}; };
@ -606,6 +633,9 @@ export const useChatStore = defineStore('chatStore', () => {
// 更新会话列表数据库 // 更新会话列表数据库
// 更新chatlist // 更新chatlist
// 更新聊天记录 // 更新聊天记录
console.log(data)
messageReceiveStatus.value = false
// 判断是否是自己发的消息 // 判断是否是自己发的消息
if (data.userId === userInfo.value.id) { if (data.userId === userInfo.value.id) {
@ -617,9 +647,6 @@ export const useChatStore = defineStore('chatStore', () => {
return return
} }
// 添加消息记录 // 添加消息记录
const addMessageHistory = { const addMessageHistory = {
type: data.type, type: data.type,
@ -653,25 +680,27 @@ export const useChatStore = defineStore('chatStore', () => {
changeChatListAndChatHistory(data) changeChatListAndChatHistory(data)
// 更改聊天记录 // 更改聊天记录
chatHistory.value.push(addMessageHistory) chatHistory.value.push(addMessageHistory)
messageReceiveStatus.value = true
}; };
const setScrollToBottom = async () => { // 接收 innerRef 和 scrollbarRef 作为参数
// await nextTick(); // 确保 DOM 已经更新完毕 const setScrollToBottom = async (innerRef: any, scrollbarRef: any) => {
await nextTick(); // 确保 DOM 已经更新完毕
// // 检查 innerRef 是否存在 // 检查 innerRef 是否存在
// if (!innerRef.value) { if (!innerRef.value) {
// console.warn('innerRef is not defined.'); console.warn('innerRef is not defined.');
// return; return;
// } }
// // 设置滚动条到底部 // 设置滚动条到底部
// const max = innerRef.value.clientHeight; const max = innerRef.value.clientHeight;
// if (scrollbarRef.value) { if (scrollbarRef.value) {
// scrollbarRef.value.setScrollTop(max); scrollbarRef.value.setScrollTop(max);
// } else { } else {
// console.warn('scrollbarRef is not defined.'); console.warn('scrollbarRef is not defined.');
// } }
}; };
// 获取群列表信息 // 获取群列表信息
const getGroupList = async () => { const getGroupList = async () => {
@ -730,7 +759,6 @@ export const useChatStore = defineStore('chatStore', () => {
return return
} }
// 创建一个新的用户数组,用于更新在线用户列表 // 创建一个新的用户数组,用于更新在线用户列表
const updatedOnlineUsers = data.map(item => ({ const updatedOnlineUsers = data.map(item => ({
id: item.id, id: item.id,
@ -750,6 +778,11 @@ export const useChatStore = defineStore('chatStore', () => {
} }
}); });
// 新增代码:从onlineUserList中移除不在data中的用户
onlineUserList.value = onlineUserList.value.filter(user =>
data.some(newUser => newUser.id === user.id)
);
// 更新数据库中的用户信息 // 更新数据库中的用户信息
await updateOrAddUsers(updatedOnlineUsers); await updateOrAddUsers(updatedOnlineUsers);
@ -850,6 +883,7 @@ export const useChatStore = defineStore('chatStore', () => {
// 获取当前用户和目标用户的聊天记录 // 获取当前用户和目标用户的聊天记录
console.log(userInfo.value.id, chatId, type) console.log(userInfo.value.id, chatId, type)
const history = await getHistory(userInfo.value.id, chatId, type) const history = await getHistory(userInfo.value.id, chatId, type)
// await getGroupInviteMessage(chatId)
chatHistory.value = history; chatHistory.value = history;
// 设置目标用户的信息 // 设置目标用户的信息
await setTargetGrouprInfo(chatId); await setTargetGrouprInfo(chatId);
@ -905,15 +939,8 @@ export const useChatStore = defineStore('chatStore', () => {
const groupChatMessage = async (data: any) => { const groupChatMessage = async (data: any) => {
// 检查groupList中是否存在当前群组 messageReceiveStatus.value = false
const groupExists = groupList.value.some((group: { group_id: string; }) => group.group_id === data.to_groupid); console.log("接受消息", data)
// 如果不存在,则获取群聊列表
if (!groupExists) {
await getGroupList();
// 合并groupList到chatList
chatList.value = [...chatList.value, ...groupList.value]
}
// 构建消息记录 // 构建消息记录
const messageRecord: any = { const messageRecord: any = {
@ -955,6 +982,7 @@ export const useChatStore = defineStore('chatStore', () => {
// 更改聊天记录 // 更改聊天记录
chatHistory.value.push(messageRecord) chatHistory.value.push(messageRecord)
messageReceiveStatus.value = true
}; };
const showContextMenu = (event: any, id: number) => { const showContextMenu = (event: any, id: number) => {
@ -1024,15 +1052,51 @@ export const useChatStore = defineStore('chatStore', () => {
const reader = new FileReader(); const reader = new FileReader();
reader.onloadend = () => { reader.onloadend = () => {
const base64data = reader.result; // 转换为 base64 const base64data = reader.result; // 转换为 base64
console.log(base64data);
resolve(base64data); resolve(base64data);
}; };
reader.readAsDataURL(blob); 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 { return {
emojiList, emojiList,
groupSystemMessage,
onlineUserList, onlineUserList,
chatList, chatList,
groupList, groupList,
@ -1066,6 +1130,8 @@ export const useChatStore = defineStore('chatStore', () => {
addMemberDialogVisible, addMemberDialogVisible,
groupTitle, groupTitle,
inviteUserList, inviteUserList,
messageSendStatus,
messageReceiveStatus,
initChat, initChat,
showContextMenu, showContextMenu,
setCurrentNavId, setCurrentNavId,
@ -1086,6 +1152,9 @@ export const useChatStore = defineStore('chatStore', () => {
inviteFriend, inviteFriend,
getGroupMember, getGroupMember,
addMember, addMember,
getImageSrc getImageSrc,
groupInviteMessage,
getGroupInviteMessage,
setScrollToBottom
}; };
}); });

11
frontend/src/stores/db.ts

@ -1,6 +1,6 @@
import Dexie from 'dexie'; 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'); export const dbInit: any = new Dexie('GodoOSDatabase');
dbInit.version(1).stores({ dbInit.version(1).stores({
@ -16,6 +16,8 @@ dbInit.version(1).stores({
workbenchGroupChatRecord: '++id,chatId,userId,to_groupid,messageType,userInfo,message,time,type,createdAt', workbenchGroupChatRecord: '++id,chatId,userId,to_groupid,messageType,userInfo,message,time,type,createdAt',
// 群用户列表 // 群用户列表
workbenchGroupUserList: '++id, group_id, createdAt, userIdArray', workbenchGroupUserList: '++id, group_id, createdAt, userIdArray',
// 群组邀请信息消息
workbenchGroupInviteMessage: '++id, group_id,userId, message, createdAt',
// 用户列表 // 用户列表
chatuser: '++id,ip,hostname,userName,avatar,mobile,nickName,isOnline,updatedAt,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', chatmsg: '++id,toUserId,targetIp,senderInfo,reciperInfo,previewMessage,content,type,status,isRead,isMe,readAt,createdAt',
@ -24,6 +26,7 @@ dbInit.version(1).stores({
workbenchChatUser: any; workbenchChatUser: any;
workbenchGroupChatRecord: any; workbenchGroupChatRecord: any;
workbenchGroupUserList: any; workbenchGroupUserList: any;
workbenchGroupInviteMessage: any;
workbenchChatRecord: { addIndex: (arg0: string, arg1: (obj: { toUserId: any; }) => any) => void; }; 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.workbenchChatUser.addIndex('chatId', (obj: { chatId: any; }) => obj.chatId);
tx.workbenchGroupChatRecord.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.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 = { export const db = {
@ -110,6 +114,11 @@ export const db = {
return row[fName] 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) { async getByField(tableName: ChatTable, fieldName: string, val: any) {
return dbInit[tableName].where(fieldName).equals(val).toArray() 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) console.log(message)
chatChatStore.groupChatMessage(message.data); chatChatStore.groupChatMessage(message.data);
break; break;
case 'update_group':
chatChatStore.groupInviteMessage(message.data)
break;
default: default:
console.warn('Unknown message type:', message.type); console.warn('Unknown message type:', message.type);
} }

14
frontend/src/system/initBuiltin.ts

@ -1,20 +1,20 @@
import { t } from "@/i18n";
import type { System } from "./index"; import type { System } from "./index";
import { BrowserWindow } from "./window/BrowserWindow"; import { BrowserWindow } from "./window/BrowserWindow";
import { t } from "@/i18n";
import { dealIcon } from "../util/Icon"; 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 { appList } from "./applist.ts";
import { getSystemConfig } from './config' import { getSystemConfig } from './config';
import { basename } from "./core/Path";
import { memberList } from "./member.ts"; import { memberList } from "./member.ts";
import { Tray } from "./menu/Tary";
import { Dialog } from "./window/Dialog";
const unknownIcon = "unknown"; const unknownIcon = "unknown";
export function initBuiltinApp(system: System) { export function initBuiltinApp(system: System) {
const config = getSystemConfig(); const config = getSystemConfig();
let sysList = appList; let sysList = appList;
if(config.userType == 'member') { if (config.userType == 'member') {
sysList = [...appList,...memberList] sysList = [...appList, ...memberList]
} }
sysList.forEach((d: any) => { sysList.forEach((d: any) => {

Loading…
Cancel
Save