Browse Source

add:添加系统聊天

master
tiantian 7 months ago
parent
commit
c7d3651964
  1. 5
      frontend/src/components/chat/Chat.vue
  2. 102
      frontend/src/components/chat/ChatBox.vue
  3. 10
      frontend/src/components/chat/ChatMsgList.vue
  4. 10
      frontend/src/components/chat/chatUserInfo.vue
  5. 103
      frontend/src/stores/chat.ts
  6. 6
      frontend/src/stores/db.ts
  7. 3
      frontend/src/stores/upgrade.ts

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

@ -18,7 +18,8 @@
const data = ref(generateData()); const data = ref(generateData());
// users any[] // users any[]
const users = ref<any[]>([]); let users = ref<any[]>([]);
const myTransfer = ref()
watchEffect(() => { watchEffect(() => {
if (store.allUserList.length > 0) { if (store.allUserList.length > 0) {
@ -133,7 +134,9 @@
style="height: 250px" style="height: 250px"
filter-placeholder="搜索用户名" filter-placeholder="搜索用户名"
:props="{ key: 'key', label: 'label', avatar: 'avatar' }" :props="{ key: 'key', label: 'label', avatar: 'avatar' }"
:left-default-checked="[]"
class="transfer-container" class="transfer-container"
ref="myTransfer"
> >
<!-- 自定义穿梭框列表项模板 --> <!-- 自定义穿梭框列表项模板 -->
<template #default="{ option }"> <template #default="{ option }">

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

@ -52,7 +52,7 @@
<ChatGroupMember /> <ChatGroupMember />
<div <div
class="chatbox-main" class="chatbox-main"
v-if="store.targetChatId" v-if="store.targetChatType==='user'||store.targetChatType==='group'"
> >
<!--聊天顶部区--> <!--聊天顶部区-->
<el-header class="chat-header"> <el-header class="chat-header">
@ -67,7 +67,6 @@
class="header-title-name" class="header-title-name"
>{{ store.targetGroupInfo.displayName }}</span >{{ store.targetGroupInfo.displayName }}</span
> >
<div <div
v-if=" v-if="
store.targetGroupInfo && store.targetGroupInfo &&
@ -147,7 +146,6 @@
</div> </div>
</div> </div>
</el-header> </el-header>
<!--聊天主体区--> <!--聊天主体区-->
<el-main class="msg-main"> <el-main class="msg-main">
<!-- 聊天消息滚动区域 --> <!-- 聊天消息滚动区域 -->
@ -199,7 +197,60 @@
</div> </div>
</el-footer> </el-footer>
</div> </div>
<div class="chatbox-main" v-if="store.targetChatType==='system'">
<!--聊天顶部区-->
<el-header class="chat-header">
<div class="header-title">
<span
v-if="store.systemInfo"
class="header-title-name"
>系统消息</span
>
<div
style="
height: 50px;
display: flex;
align-items: center;
justify-content: center;
"
>
<el-dropdown>
<el-icon
style="
cursor: pointer;
color: black;
font-size: 15px;
"
><More
/></el-icon>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="clearMessages('system')"
>清空记录</el-dropdown-item
>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
</el-header>
<!--聊天主体区-->
<el-main class="system-main">
<div class="msg-container">
<el-scrollbar ref="scrollbarRef">
<div ref="innerRef" >
<div class="msg-card" v-for="item in store.systemInfo" :key="item.id">
<div class="msg-time">{{ formatTime(item.time) }}</div>
<el-card class="box-card">
{{ item.previewMessage}}
</el-card>
</div>
</div>
</el-scrollbar>
</div>
</el-main>
</div>
<div <div
style=" style="
width: 100%; width: 100%;
@ -209,7 +260,7 @@
align-items: center; align-items: center;
justify-content: center; justify-content: center;
" "
v-else v-if="!store.targetChatType"
> >
<el-empty description="请选择一个用户或群聊" /> <el-empty description="请选择一个用户或群聊" />
</div> </div>
@ -227,6 +278,17 @@
const scrollbarRef = ref(null); const scrollbarRef = ref(null);
const innerRef = ref(null); const innerRef = ref(null);
function formatTime(timestamp:number) {
const date=new Date(timestamp)
const year = date.getFullYear();
const month = (date.getMonth() + 1).toString().padStart(2, '0');
const day = date.getDate().toString().padStart(2, '0');
const hours = date.getHours().toString().padStart(2, '0');
const minutes = date.getMinutes().toString().padStart(2, '0');
const seconds = date.getSeconds().toString().padStart(2, '0');
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
}
// //
const clearMessages = (type: string) => { const clearMessages = (type: string) => {
// //
@ -245,6 +307,8 @@
} }
} else if (type === "group") { } else if (type === "group") {
store.clearGroupMessages(); store.clearGroupMessages();
} else if(type==='system'){
store.clearSystemMessages()
} }
}; };
@ -341,6 +405,36 @@
</script> </script>
<style scoped> <style scoped>
.system-main {
width: 100%;
/* 占据整个宽度 */
height: 90%;
padding: 0;
border-top: 1px solid #edebeb;
display: flex;
justify-content: space-between;
}
.msg-card{
display: flex;
flex-direction: column;
align-items: center;
}
.msg-time{
text-align: center;
font-size: 12px;
color: #656a72;
padding: 15px 0;
}
.box-card{
width: 80%;
border: 0;
border-radius: 10px;
}
.el-card .el-card__body{
padding: 0;
}
.msg-main { .msg-main {
width: 100%; width: 100%;

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

@ -48,6 +48,14 @@
" "
></div> ></div>
</el-avatar> </el-avatar>
<el-avatar
v-else-if="item.type == 'system'"
shape="square"
:size="40"
class="avatar"
icon="el-icon-message"
>
</el-avatar>
</el-col> </el-col>
<!-- 在线状态 --> <!-- 在线状态 -->
@ -90,7 +98,7 @@
</div> </div>
<div class="previewTime"> <div class="previewTime">
{{ formatTime(item.item) }} {{ formatTime(item.time) }}
</div> </div>
</div> </div>

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

@ -13,11 +13,11 @@
> >
<div class="user-details"> <div class="user-details">
<h2>{{ store.targetUserInfo.displayName }}</h2> <h2>{{ store.targetUserInfo.displayName }}</h2>
<p>工号{{ targetUserInfo.jobNumber }}</p> <p>工号{{ store.targetUserInfo.jobNumber||'暂未设置' }}</p>
<p>岗位{{ targetUserInfo.desc }}</p> <p>岗位{{ store.targetUserInfo.desc ||'暂未设置'}}</p>
<p>邮箱{{ targetUserInfo.email }}</p> <p>邮箱{{ store.targetUserInfo.email||'暂未设置' }}</p>
<p>电话{{ targetUserInfo.phone }}</p> <p>电话{{ store.targetUserInfo.phone ||'暂未设置'}}</p>
<p>入职日期{{ targetUserInfo.hiredDate }}</p> <p>入职日期{{ store.targetUserInfo.hiredDate ||'暂未设置'}}</p>
</div> </div>
<div class="avatar"> <div class="avatar">
<el-avatar <el-avatar

103
frontend/src/stores/chat.ts

@ -73,7 +73,7 @@ export const useChatStore = defineStore('chatStore', () => {
// 添加成员 // 添加成员
const addMemberDialogVisible = ref(false) const addMemberDialogVisible = ref(false)
// 聊天列表 // 聊天列表
const chatList: any = ref([]); const chatList = ref<any[]>([]);
// 聊天消息记录列表 // 聊天消息记录列表
const chatHistory: any = ref([]); const chatHistory: any = ref([]);
@ -93,7 +93,7 @@ export const useChatStore = defineStore('chatStore', () => {
const message: any = ref(''); const message: any = ref('');
const targetUserInfo: any = ref({}); const targetUserInfo: any = ref({});
const targetChatId = ref(); const targetChatId = ref();
const searchList = ref([]); const searchList = ref<any[]>([]);
const groups: any = ref([]) const groups: any = ref([])
const searchInput = ref(''); const searchInput = ref('');
// 定义消息发送、接受的状态用于控制滚动条的滚动 // 定义消息发送、接受的状态用于控制滚动条的滚动
@ -200,19 +200,26 @@ export const useChatStore = defineStore('chatStore', () => {
const uniqueUserSessionList = userSessionList.filter((item: any, index: number, self: any[]) => const uniqueUserSessionList = userSessionList.filter((item: any, index: number, self: any[]) =>
index === self.findIndex((t: any) => t.chatId === item.chatId) index === self.findIndex((t: any) => t.chatId === item.chatId)
); );
// 获取所有系统消息列表
// 确保groupList已加载 const systemSessionList = await db.getAll("systemChatRecord");
if (groupList.value.length > 0) { // 取最后一条消息
// 合并两个数组 const latestSysSession=systemSessionList.pop()
if(latestSysSession){
chatList.value = [latestSysSession,...uniqueUserSessionList, ...groupList.value];
}else{
chatList.value = [...uniqueUserSessionList, ...groupList.value]; chatList.value = [...uniqueUserSessionList, ...groupList.value];
} else {
// 如果groupList为空,只使用userSessionList
chatList.value = [...uniqueUserSessionList];
} }
console.log('!!!!1',chatList.value)
chatList.value.sort((a,b)=>{
return b.time - a.time
})
}; };
const setCurrentNavId = (id: number) => { const setCurrentNavId = (id: number) => {
currentNavId.value = id; currentNavId.value = id;
targetChatType.value=''
targetChatId.value = ''
}; };
const sendMessage = async (messageType: string) => { const sendMessage = async (messageType: string) => {
@ -477,6 +484,7 @@ export const useChatStore = defineStore('chatStore', () => {
const sessionList = await db.getByField("workbenchSessionList", "chatId", targetUserInfo.value.chatId) const sessionList = await db.getByField("workbenchSessionList", "chatId", targetUserInfo.value.chatId)
await db.update("workbenchSessionList", sessionList[0].id, { await db.update("workbenchSessionList", sessionList[0].id, {
previewMessage: message, previewMessage: message,
time: Date.now(),
previewTimeFormat: formatTime(Date.now()) previewTimeFormat: formatTime(Date.now())
}) })
@ -704,13 +712,13 @@ export const useChatStore = defineStore('chatStore', () => {
// groupConversation添加到groupSessionList // groupConversation添加到groupSessionList
await db.addOne("groupSessionList", groupConversation) await db.addOne("groupSessionList", groupConversation)
departmentName.value=''
// 更新会话列表 // 更新会话列表
initChatList() initChatList()
// 关闭对话弹窗 // 关闭对话弹窗
setGroupChatInvitedDialogVisible(false) setGroupChatInvitedDialogVisible(false)
// 更新群组列表 // 更新群组列表
// await getAllList() await getAllList()
getGroupList() getGroupList()
notifySuccess('创建群聊成功') notifySuccess('创建群聊成功')
}; };
@ -817,8 +825,8 @@ export const useChatStore = defineStore('chatStore', () => {
// 从groupSessionList中获取群信息 // 从groupSessionList中获取群信息
const groupSessionList = await db.getAll("groupSessionList") const groupSessionList = await db.getAll("groupSessionList")
console.log('aaaaaa',groupSessionList)
// 合并查找和封装逻辑到一个循环中 // 合并,查找和封装逻辑到一个循环中
const formattedGroups = list.data.groups.map((group: any) => { const formattedGroups = list.data.groups.map((group: any) => {
const groupSession = groupSessionList.find((item: { chatId: string; }) => item.chatId === group.id); const groupSession = groupSessionList.find((item: { chatId: string; }) => item.chatId === group.id);
return { return {
@ -831,6 +839,8 @@ export const useChatStore = defineStore('chatStore', () => {
previewMessage: groupSession ? groupSession.previewMessage : "", // 如果找到对应的会话则使用其预览消息,否则为空 previewMessage: groupSession ? groupSession.previewMessage : "", // 如果找到对应的会话则使用其预览消息,否则为空
}; };
}); });
groupList.value = formattedGroups; groupList.value = formattedGroups;
// 将群成员添加到数据库 // 将群成员添加到数据库
@ -990,6 +1000,7 @@ export const useChatStore = defineStore('chatStore', () => {
// 清空聊天记录 // 清空聊天记录
chatHistory.value = [] chatHistory.value = []
targetChatId.value = chatId targetChatId.value = chatId
targetChatType.value = type
if (type === 'user') { if (type === 'user') {
console.log("user") console.log("user")
@ -1011,6 +1022,10 @@ export const useChatStore = defineStore('chatStore', () => {
await setTargetGrouprInfo(chatId); await setTargetGrouprInfo(chatId);
messageSendStatus.value = true messageSendStatus.value = true
} }
else if(type === 'system'){
await getSystemInfo()
messageSendStatus.value = true
}
}; };
const getHistory = async (sendUserId: string, toUserId: string, type: string) => { const getHistory = async (sendUserId: string, toUserId: string, type: string) => {
@ -1085,7 +1100,7 @@ export const useChatStore = defineStore('chatStore', () => {
userId: data.userId, userId: data.userId,
groupId: data.to_groupid, groupId: data.to_groupid,
content_type: data.content_type, content_type: data.content_type,
time: data.time, time: Date.now(),
type: data.type, type: data.type,
chatId: data.to_groupid, chatId: data.to_groupid,
isMe: false, isMe: false,
@ -1126,6 +1141,10 @@ export const useChatStore = defineStore('chatStore', () => {
// 更改聊天记录 // 更改聊天记录
chatHistory.value.push(messageRecord) chatHistory.value.push(messageRecord)
// 找到群会话列表,更新对于id的数据。
await updateRecipientGroupSessionList(messageRecord.previewMessage, data.to_groupid)
messageReceiveStatus.value = true messageReceiveStatus.value = true
}; };
@ -1160,12 +1179,14 @@ export const useChatStore = defineStore('chatStore', () => {
// 从groupList中删除 // 从groupList中删除
groupList.value = groupList.value.filter((group: any) => group.group_id !== group_id) groupList.value = groupList.value.filter((group: any) => group.group_id !== group_id)
await db.deleteByField("workbenchGroupUserList", "group_id", group_id) await db.deleteByField("workbenchGroupUserList", "group_id", group_id)
await getAllList()
// 获取群列表 // 获取群列表
await getGroupList() await getGroupList()
// 初始化聊天列表 // 初始化聊天列表
initChatList() initChatList()
targetGroupInfo.value = {} targetGroupInfo.value = {}
targetChatId.value = '' targetChatId.value = ''
targetChatType.value =''
notifySuccess("退出群聊成功") notifySuccess("退出群聊成功")
} }
@ -1285,6 +1306,15 @@ export const useChatStore = defineStore('chatStore', () => {
item.previewMessage = "快开始打招呼吧!"; item.previewMessage = "快开始打招呼吧!";
} }
}); });
const res:any = await db.getByField("workbenchSessionList","chatId",targetChatId.value)
console.log(',kmmim',res)
await db.update('workbenchSessionList',res[0].id,{
previewMessage:"快开始打招呼吧",
})
return true return true
} else { } else {
return false return false
@ -1324,14 +1354,55 @@ export const useChatStore = defineStore('chatStore', () => {
item.previewMessage = "快开始打招呼吧!"; item.previewMessage = "快开始打招呼吧!";
} }
}); });
const res = await db.getByField("groupSessionList","chatId",targetChatId.value)
await db.update('groupSessionList',res[0].id,{
previewMessage:"快开始打招呼吧",
})
notifySuccess("删除成功"); notifySuccess("删除成功");
} else { } else {
notifyError("删除失败"); notifyError("删除失败");
} }
} }
// 系统消息模块
const targetChatType=ref()
const systemInfo=ref<any[]>([])
// 收到系统消息触发
const systemMessage = async (data: {
type: string;
data: string;
time: number;
}) => {
const systemMsg = {
type: "system",
chatId: 'system',
displayName: "系统消息",
time: Date.now(),
previewTimeFormat: formatTime(Date.now()),
previewMessage: data.data,
};
await db.addOne("systemChatRecord", systemMsg);
initChatList()
await getSystemInfo()
messageSendStatus.value=true
};
// 获取系统消息数组
const getSystemInfo=async()=>{
systemInfo.value=await db.getAll('systemChatRecord')
}
// 清空系统聊天记录
const clearSystemMessages=async()=>{
await db.clear('systemChatRecord')
notifySuccess("删除成功")
chatList.value=chatList.value.filter(item=>item.type!=='system')
initChatList()
systemInfo.value=[]
targetChatType.value=''
}
return { return {
clearSystemMessages,
systemInfo,
targetChatType,
systemMessage,
emojiList, emojiList,
groupSystemMessage, groupSystemMessage,
onlineUserList, onlineUserList,

6
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' | 'workbenchGroupInviteMessage'; export type ChatTable = 'chatuser' | 'chatmsg' |'systemChatRecord'| '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({
@ -18,6 +18,8 @@ dbInit.version(1).stores({
workbenchGroupUserList: '++id, group_id, createdAt, userIdArray', workbenchGroupUserList: '++id, group_id, createdAt, userIdArray',
// 群组邀请信息消息 // 群组邀请信息消息
workbenchGroupInviteMessage: '++id, group_id,userId, message, createdAt', workbenchGroupInviteMessage: '++id, group_id,userId, message, createdAt',
//系统聊天记录表
systemChatRecord: '++id,chatId,message,time,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',
@ -29,11 +31,13 @@ dbInit.version(1).stores({
workbenchGroupInviteMessage: any; workbenchGroupInviteMessage: any;
groupSessionList: any; groupSessionList: any;
workbenchChatRecord: any; workbenchChatRecord: any;
systemChatRecord: any;
}) => { }) => {
// 手动添加索引 // 手动添加索引
tx.groupSessionList.addIndex('chatId', (obj: { chatId: any; }) => obj.chatId); tx.groupSessionList.addIndex('chatId', (obj: { chatId: any; }) => obj.chatId);
tx.workbenchSessionList.addIndex('chatId', (obj: { chatId: any; }) => obj.chatId); tx.workbenchSessionList.addIndex('chatId', (obj: { chatId: any; }) => obj.chatId);
tx.workbenchChatRecord.addIndex('toUserId', (obj: { toUserId: any; }) => obj.toUserId); tx.workbenchChatRecord.addIndex('toUserId', (obj: { toUserId: any; }) => obj.toUserId);
tx.systemChatRecord.addIndex('chatId', (obj: { chatId: any; }) => obj.chatId);
// 添加复合索引 // 添加复合索引
tx.workbenchChatRecord.addIndex('[toUserId+userId]', (obj: { toUserId: any; userId: any; }) => [obj.toUserId, obj.userId]); tx.workbenchChatRecord.addIndex('[toUserId+userId]', (obj: { toUserId: any; userId: any; }) => [obj.toUserId, obj.userId]);
tx.workbenchGroupChatRecord.addIndex('chatId', (obj: { chatId: any; }) => obj.chatId); tx.workbenchGroupChatRecord.addIndex('chatId', (obj: { chatId: any; }) => obj.chatId);

3
frontend/src/stores/upgrade.ts

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

Loading…
Cancel
Save