Browse Source

add:新增创建群会推送消息

master
qiutianhong 7 months ago
parent
commit
f8fb00cadd
  1. 3
      frontend/components.d.ts
  2. 21
      frontend/src/components/chat/Chat.vue
  3. 27
      frontend/src/components/chat/ChatBox.vue
  4. 11
      frontend/src/components/chat/ChatMsgList.vue
  5. 6
      frontend/src/components/chat/ChatUserList.vue
  6. 10
      frontend/src/components/chat/chatUserInfo.vue
  7. 94
      frontend/src/stores/chat.ts

3
frontend/components.d.ts

@ -61,6 +61,9 @@ declare module 'vue' {
ElContainer: typeof import('element-plus/es')['ElContainer'] ElContainer: typeof import('element-plus/es')['ElContainer']
ElDialog: typeof import('element-plus/es')['ElDialog'] ElDialog: typeof import('element-plus/es')['ElDialog']
ElDrawer: typeof import('element-plus/es')['ElDrawer'] 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'] ElEmpty: typeof import('element-plus/es')['ElEmpty']
ElFooter: typeof import('element-plus/es')['ElFooter'] ElFooter: typeof import('element-plus/es')['ElFooter']
ElForm: typeof import('element-plus/es')['ElForm'] ElForm: typeof import('element-plus/es')['ElForm']

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

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

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

@ -3,7 +3,6 @@
class="chatbox-main" class="chatbox-main"
v-if="store.targetChatId" v-if="store.targetChatId"
> >
<!--聊天顶部区--> <!--聊天顶部区-->
<el-header class="chat-header"> <el-header class="chat-header">
<div class="header-title"> <div class="header-title">
@ -15,10 +14,13 @@
<span <span
v-else-if="store.targetGroupInfo.displayName" v-else-if="store.targetGroupInfo.displayName"
class="header-title-name" class="header-title-name"
>{{ store.targetGroupInfo.displayName }}{{ 1 }}</span >{{ store.targetGroupInfo.displayName }}</span
> >
<div @click="store.drawerVisible = true"> <div
v-if="store.targetGroupInfo.value && Object.keys(store.targetGroupInfo.value).length > 0"
@click="store.drawerVisible = true"
>
<el-icon><Tools /></el-icon> <el-icon><Tools /></el-icon>
<!-- 抽屉 --> <!-- 抽屉 -->
<el-drawer <el-drawer
@ -83,6 +85,17 @@
</el-drawer> </el-drawer>
</div> </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 <el-dialog
v-model="store.inviteFriendDialogVisible" v-model="store.inviteFriendDialogVisible"
@ -251,6 +264,14 @@
</script> </script>
<style scoped> <style scoped>
:deep(.el-drawer__header) {
color: #000000;
}
:deep(.el-drawer__body) {
margin-top: -40px; /* 根据需要调整这个值 */
}
.group-name { .group-name {
font-size: 16px; font-size: 16px;
border-top: 1px solid #edebeb; border-top: 1px solid #edebeb;

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

@ -1,5 +1,4 @@
<template> <template>
<div <div
v-if=" v-if="
(store.searchList.length > 0 ? store.searchList : store.chatList) (store.searchList.length > 0 ? store.searchList : store.chatList)
@ -37,6 +36,14 @@
></el-avatar ></el-avatar
> >
</el-col> </el-col>
<el-icon
v-if="item.online"
style="position: absolute; left: 40px; bottom: 5px;"
>
<CircleCheckFilled />
</el-icon>
<el-col <el-col
:span="18" :span="18"
class="preview" class="preview"
@ -50,6 +57,7 @@
<div class="previewName"> <div class="previewName">
{{ item.displayName }} {{ item.displayName }}
</div> </div>
<div class="previewTime"> <div class="previewTime">
{{ item.previewTimeFormat }} {{ item.previewTimeFormat }}
</div> </div>
@ -69,7 +77,6 @@
</el-row> </el-row>
</div> </div>
</div> </div>
<div <div
v-else v-else
class="emptyChat" class="emptyChat"

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

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

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

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

94
frontend/src/stores/chat.ts

@ -149,7 +149,7 @@ export const useChatStore = defineStore('chatStore', () => {
// 新增代码:提取部门成员并去重,按指定字段保存 // 新增代码:提取部门成员并去重,按指定字段保存
const uniqueUsers = new Set(); const uniqueUsers = new Set();
console.log(data.data.users)
data.data.users.forEach((department: { users: any[]; }) => { data.data.users.forEach((department: { users: any[]; }) => {
department.users?.forEach(async (user) => { department.users?.forEach(async (user) => {
if (!uniqueUsers.has(user.user_id)) { if (!uniqueUsers.has(user.user_id)) {
@ -179,6 +179,7 @@ export const useChatStore = defineStore('chatStore', () => {
// 初始化用户列表 // 初始化用户列表
const initChatList = async () => { const initChatList = async () => {
console.log("收到消息被刷新了!!!!")
const userSessionList = await db.getAll("workbenchSessionList"); const userSessionList = await db.getAll("workbenchSessionList");
// 确保groupList已加载 // 确保groupList已加载
if (groupList.value.length > 0) { if (groupList.value.length > 0) {
@ -242,11 +243,11 @@ export const useChatStore = defineStore('chatStore', () => {
return; return;
} }
Message.message = await getImageSrc(Message.message)
// 封装成消息历史记录 // 封装成消息历史记录
const messageHistory = { const messageHistory = {
...Message, ...Message,
isMe: true, isMe: true,
message: await getImageSrc(Message.message),
previewTimeFormat: formatTime(Date.now()), previewTimeFormat: formatTime(Date.now()),
displayName: userInfo.value.nickname, displayName: userInfo.value.nickname,
chatId: Message.type === 'group' ? targetGroupInfo.value.chatId : targetUserInfo.value.chatId, chatId: Message.type === 'group' ? targetGroupInfo.value.chatId : targetUserInfo.value.chatId,
@ -356,7 +357,6 @@ export const useChatStore = defineStore('chatStore', () => {
Message.userInfo = {} Message.userInfo = {}
} }
console.log("token", config.userInfo.token)
// 发送消息 // 发送消息
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) {
@ -413,6 +413,7 @@ export const useChatStore = defineStore('chatStore', () => {
toUserId: data.toUserId, toUserId: data.toUserId,
chatId: data.userId, chatId: data.userId,
type: data.type, type: data.type,
online: data.online,
messages: data.message, messages: data.message,
displayName: data.userInfo.nickname, displayName: data.userInfo.nickname,
nickname: data.userInfo.nickname, nickname: data.userInfo.nickname,
@ -472,6 +473,7 @@ export const useChatStore = defineStore('chatStore', () => {
chatId: user.id, chatId: user.id,
nickname: user.nickname, nickname: user.nickname,
avatar: user.avatar, avatar: user.avatar,
online: user.online,
toUserId: userInfo.value.id, toUserId: userInfo.value.id,
previewMessage: message.value || "快开始打招呼吧!", previewMessage: message.value || "快开始打招呼吧!",
previewTimeFormat: formatTime(Date.now()), previewTimeFormat: formatTime(Date.now()),
@ -487,6 +489,7 @@ export const useChatStore = defineStore('chatStore', () => {
username: user.username, username: user.username,
nickname: user.nickname, nickname: user.nickname,
avatar: user.avatar, avatar: user.avatar,
online: user.online,
toUserId: userInfo.value.id, toUserId: userInfo.value.id,
previewMessage: message.value || "快开始打招呼吧!", previewMessage: message.value || "快开始打招呼吧!",
previewTimeFormat: formatTime(Date.now()), previewTimeFormat: formatTime(Date.now()),
@ -526,15 +529,14 @@ export const useChatStore = defineStore('chatStore', () => {
// 获取用户表中所有用户 // 获取用户表中所有用户
const getAllUser = async () => { 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[]) => { const createGroupChat = async (userIds: number[]) => {
console.log(userIds)
if (userIds.length === 0) { if (userIds.length === 0) {
notifyError('请选择用户') notifyError('请选择用户')
return false return false
@ -566,6 +568,10 @@ export const useChatStore = defineStore('chatStore', () => {
// 群数据 // 群数据
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,
@ -574,7 +580,7 @@ export const useChatStore = defineStore('chatStore', () => {
chatId: group_id, chatId: group_id,
type: "group", type: "group",
displayName: departmentName.value, displayName: departmentName.value,
previewMessage: "快来和大家一起交流吧!", previewMessage: message.value,
previewTimeFormat: formatTime(Date.now()), previewTimeFormat: formatTime(Date.now()),
createdAt: new Date() createdAt: new Date()
} }
@ -582,8 +588,15 @@ export const useChatStore = defineStore('chatStore', () => {
initChatList() initChatList()
// 关闭对话弹窗 // 关闭对话弹窗
setGroupChatInvitedDialogVisible(false) setGroupChatInvitedDialogVisible(false)
notifySuccess('创建群聊成功')
await getAllList() await getAllList()
// 创建群之后发送一条初始消息
// 设置targetGroupInfo
setTargetGrouprInfo(group_id)
// 发送消息
await sendMessage("text")
targetUserInfo.value = {};
notifySuccess('创建群聊成功')
}; };
// 处理用户消息 // 处理用户消息
@ -703,12 +716,18 @@ export const useChatStore = defineStore('chatStore', () => {
} }
}; };
const onlineUserData = async (data: OnlineUserInfoType[]) => { const onlineUserData = async (data: OnlineUserInfoType[]) => {
if (data.length === 0) { if (data.length === 0) {
onlineUserList.value = [] onlineUserList.value = []
// 更新会话列表用户在线状态
chatList.value = chatList.value.map((chat: { type: string; }) => {
if (chat.type === 'user') {
return { ...chat, online: false };
}
return chat;
});
return return
} }
@ -723,6 +742,7 @@ export const useChatStore = defineStore('chatStore', () => {
username: item.username, username: item.username,
nickname: item.nickname nickname: item.nickname
})).filter(item => item.id && item.login_ip); // 确保所有项都有有效的id和ip })).filter(item => item.id && item.login_ip); // 确保所有项都有有效的id和ip
// 更新在线用户列表,只添加不存在的用户 // 更新在线用户列表,只添加不存在的用户
updatedOnlineUsers.forEach(newUser => { updatedOnlineUsers.forEach(newUser => {
if (!onlineUserList.value.some(existingUser => existingUser.id === newUser.id)) { if (!onlineUserList.value.some(existingUser => existingUser.id === newUser.id)) {
@ -732,6 +752,19 @@ export const useChatStore = defineStore('chatStore', () => {
// 更新数据库中的用户信息 // 更新数据库中的用户信息
await updateOrAddUsers(updatedOnlineUsers); 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[]) => { const updateOrAddUsers = async (users: OnlineUserInfoType[]) => {
@ -858,7 +891,6 @@ export const useChatStore = defineStore('chatStore', () => {
// 设置目标群信息 // 设置目标群信息
const setTargetGrouprInfo = async (id: string) => { const setTargetGrouprInfo = async (id: string) => {
for (const group of groupList.value) { for (const group of groupList.value) {
console.log(group)
if (group.group_id === id) { if (group.group_id === id) {
targetGroupInfo.value = group; targetGroupInfo.value = group;
targetUserInfo.value = {}; targetUserInfo.value = {};
@ -872,7 +904,19 @@ export const useChatStore = defineStore('chatStore', () => {
}; };
const groupChatMessage = async (data: any) => { const groupChatMessage = async (data: any) => {
const messageRecord = {
// 检查groupList中是否存在当前群组
const groupExists = groupList.value.some((group: { group_id: string; }) => group.group_id === data.to_groupid);
// 如果不存在,则获取群聊列表
if (!groupExists) {
await getGroupList();
// 合并groupList到chatList
chatList.value = [...chatList.value, ...groupList.value]
}
// 构建消息记录
const messageRecord: any = {
userId: data.userId, userId: data.userId,
groupId: data.to_groupid, groupId: data.to_groupid,
content_type: data.content_type, content_type: data.content_type,
@ -881,7 +925,7 @@ export const useChatStore = defineStore('chatStore', () => {
chatId: data.to_groupid, chatId: data.to_groupid,
isMe: false, isMe: false,
previewTimeFormat: formatTime(Date.now()), previewTimeFormat: formatTime(Date.now()),
displayName: data.userInfo.nickname, displayName: data.userInfo.nickname, // 发送者昵称
avatar: data.userInfo.avatar, avatar: data.userInfo.avatar,
role_id: data.userInfo.role_id, role_id: data.userInfo.role_id,
createdAt: Date.now(), createdAt: Date.now(),
@ -889,20 +933,26 @@ export const useChatStore = defineStore('chatStore', () => {
if (data.content_type === 'image') { if (data.content_type === 'image') {
messageRecord.message = await getImageSrc(data.message) messageRecord.message = await getImageSrc(data.message)
messageRecord.previewMessage = "[图片消息]"
} else if (data.content_type === 'text') { } else if (data.content_type === 'text') {
messageRecord.message = data.message messageRecord.message = data.message
messageRecord.previewMessage = data.message
} else if (data.content_type === 'file') { } else if (data.content_type === 'file') {
messageRecord.message = data.message messageRecord.message = data.message
messageRecord.previewMessage = "[文件消息]"
} }
// 判断当前消息是否是自己发送的 // 判断接受的消息是否是自己发送的
if (messageRecord.userId === userInfo.value.id) { if (messageRecord.userId === userInfo.value.id) {
return; return;
} }
console.log(messageRecord)
// 将消息记录添加到数据库 // 将消息记录添加到数据库
const res = await db.addOne("workbenchGroupChatRecord", messageRecord); await db.addOne("workbenchGroupChatRecord", messageRecord);
console.log(res) // // push进groupList
// groupList.value.push(messageRecord)
// 更改聊天记录 // 更改聊天记录
chatHistory.value.push(messageRecord) chatHistory.value.push(messageRecord)
}; };
@ -924,13 +974,12 @@ export const useChatStore = defineStore('chatStore', () => {
console.log(await res.json()) console.log(await res.json())
// 从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)
const a = await db.deleteByField("workbenchGroupUserList", "group_id", group_id) await db.deleteByField("workbenchGroupUserList", "group_id", group_id)
console.log(a)
initChatList() initChatList()
notifySuccess("退出群聊成功")
targetGroupInfo.value = {} targetGroupInfo.value = {}
targetChatId.value = '' targetChatId.value = ''
drawerVisible.value = false
notifySuccess("退出群聊成功")
} }
// 获取群成员 // 获取群成员
@ -963,7 +1012,6 @@ export const useChatStore = defineStore('chatStore', () => {
if (!imageMessage.startsWith('/')) { if (!imageMessage.startsWith('/')) {
imageMessage = '/' + imageMessage; imageMessage = '/' + imageMessage;
} }
console.log("地址:-----------", imageMessage)
const path = userInfo.value.url + "/chat/image/view?path=" + imageMessage; const path = userInfo.value.url + "/chat/image/view?path=" + imageMessage;
const response = await fetchGet(path); const response = await fetchGet(path);

Loading…
Cancel
Save