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

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

@ -52,7 +52,7 @@
<ChatGroupMember />
<div
class="chatbox-main"
v-if="store.targetChatId"
v-if="store.targetChatType==='user'||store.targetChatType==='group'"
>
<!--聊天顶部区-->
<el-header class="chat-header">
@ -67,7 +67,6 @@
class="header-title-name"
>{{ store.targetGroupInfo.displayName }}</span
>
<div
v-if="
store.targetGroupInfo &&
@ -147,7 +146,6 @@
</div>
</div>
</el-header>
<!--聊天主体区-->
<el-main class="msg-main">
<!-- 聊天消息滚动区域 -->
@ -199,7 +197,60 @@
</div>
</el-footer>
</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
style="
width: 100%;
@ -209,7 +260,7 @@
align-items: center;
justify-content: center;
"
v-else
v-if="!store.targetChatType"
>
<el-empty description="请选择一个用户或群聊" />
</div>
@ -227,6 +278,17 @@
const scrollbarRef = 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) => {
//
@ -245,6 +307,8 @@
}
} else if (type === "group") {
store.clearGroupMessages();
} else if(type==='system'){
store.clearSystemMessages()
}
};
@ -341,6 +405,36 @@
</script>
<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 {
width: 100%;

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

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

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

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

101
frontend/src/stores/chat.ts

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

6
frontend/src/stores/db.ts

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

Loading…
Cancel
Save