Browse Source

add:完成群组列表

master
qiutianhong 7 months ago
parent
commit
cac16fa86f
  1. 2
      frontend/components.d.ts
  2. 36
      frontend/src/components/chat/Chat.vue
  3. 2
      frontend/src/components/chat/ChatMsgList.vue
  4. 151
      frontend/src/stores/chat.ts
  5. 10
      frontend/src/stores/db.ts

2
frontend/components.d.ts

@ -57,6 +57,8 @@ declare module 'vue' {
ElCarouselItem: typeof import('element-plus/es')['ElCarouselItem'] ElCarouselItem: typeof import('element-plus/es')['ElCarouselItem']
ElCheckbox: typeof import('element-plus/es')['ElCheckbox'] ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
ElCol: typeof import('element-plus/es')['ElCol'] ElCol: typeof import('element-plus/es')['ElCol']
ElCollapse: typeof import('element-plus/es')['ElCollapse']
ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
ElColorPicker: typeof import('element-plus/es')['ElColorPicker'] ElColorPicker: typeof import('element-plus/es')['ElColorPicker']
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']

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

@ -8,28 +8,9 @@
store.initChat(); store.initChat();
}); });
const userList = ref([
{
id: 2,
nickname: "朋友2",
avatar: "/logo.png",
previewTimeFormat: "昨天",
previewType: 1,
previewMessage: "测试消息",
},
{
id: 3,
nickname: "朋友3",
avatar: "/logo.png",
previewTimeFormat: "昨天",
previewType: 1,
previewMessage: "测试消息",
},
]);
// el-transfer // el-transfer
const generateData = () => { const generateData = () => {
return userList.value.map((user) => ({ return store.allUserList.map((user) => ({
key: user.id, key: user.id,
label: user.nickname, label: user.nickname,
avatar: user.avatar, // avatar: user.avatar, //
@ -38,6 +19,12 @@
const data = ref(generateData()); const data = ref(generateData());
const users = ref([]); const users = ref([]);
watchEffect(() => {
if (store.allUserList.length > 0) {
data.value = generateData();
}
});
</script> </script>
<template> <template>
<el-container class="container"> <el-container class="container">
@ -104,6 +91,11 @@
width="80%" width="80%"
> >
<div class="dialog-body"> <div class="dialog-body">
<!-- 添加输入部门名的输入框 -->
<el-input
v-model="store.departmentName"
placeholder="请输入群聊名称"
></el-input>
<el-transfer <el-transfer
v-model="users" v-model="users"
:data="data" :data="data"
@ -126,7 +118,9 @@
<el-button @click="store.groupChatInvitedDialogVisible = false" <el-button @click="store.groupChatInvitedDialogVisible = false"
>取消</el-button >取消</el-button
> >
<el-button @click="store.createGroupChat()" <el-button
type="primary"
@click="store.createGroupChat(users)"
>确定</el-button >确定</el-button
> >
</span> </span>

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

@ -19,7 +19,7 @@
<el-col :span="18" class="preview"> <el-col :span="18" class="preview">
<el-row class="preview-content"> <el-row class="preview-content">
<el-col :span="18" class="preview-left"> <el-col :span="18" class="preview-left">
<div class="previewName">{{ item.nickname }}</div> <div class="previewName">{{ item.nickname || item.name }}</div>
<div class="previewChat"> <div class="previewChat">
<span>{{ item.previewMessage }}</span> <span>{{ item.previewMessage }}</span>

151
frontend/src/stores/chat.ts

@ -1,6 +1,5 @@
import emojiList from "@/assets/emoji.json"; import emojiList from "@/assets/emoji.json";
import { fetchGet, fetchPost, getSystemConfig } from '@/system/config'; import { fetchGet, fetchPost, getSystemConfig } from '@/system/config';
import { notifyError } from "@/util/msg";
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
import { db } from "./db"; import { db } from "./db";
@ -29,6 +28,7 @@ export const useChatStore = defineStore('chatStore', () => {
const groupInfoSettingDrawerVisible = ref(false); const groupInfoSettingDrawerVisible = ref(false);
// 设置群聊邀请对话框状态 // 设置群聊邀请对话框状态
const setGroupChatInvitedDialogVisible = (visible: boolean) => { const setGroupChatInvitedDialogVisible = (visible: boolean) => {
getAllUser()
groupChatInvitedDialogVisible.value = visible; groupChatInvitedDialogVisible.value = visible;
}; };
// 设置群信息抽屉状态 // 设置群信息抽屉状态
@ -36,6 +36,9 @@ export const useChatStore = defineStore('chatStore', () => {
groupInfoSettingDrawerVisible.value = visible groupInfoSettingDrawerVisible.value = visible
} }
// 群名
const departmentName = ref('');
// 定义用户类型 // 定义用户类型
type User = { type User = {
id: number; id: number;
@ -77,12 +80,18 @@ export const useChatStore = defineStore('chatStore', () => {
const targetUserInfo: any = ref({}); const targetUserInfo: any = ref({});
const targetUserId = ref(); const targetUserId = ref();
const search = ref(''); const search = ref('');
// 目标群组id
const targetGroupId = ref(0);
// 所有用户列表
const allUserList = ref([])
// 部门列表 // 部门列表
const departmentList = ref([ const departmentList = ref([
]) ])
const contextMenu = ref({ const contextMenu = ref({
visible: false, visible: false,
chatMessageId: 0, chatMessageId: 0,
@ -95,6 +104,8 @@ export const useChatStore = defineStore('chatStore', () => {
}); });
const initChat = () => { const initChat = () => {
if (config.userInfo.avatar == '') { if (config.userInfo.avatar == '') {
config.userInfo.avatar = '/logo.png'; config.userInfo.avatar = '/logo.png';
@ -117,10 +128,15 @@ export const useChatStore = defineStore('chatStore', () => {
departmentList.value = data.data.users; departmentList.value = data.data.users;
} }
} }
// 初始化用户列表 // 初始化用户列表
const initChatList = async () => { const initChatList = async () => {
chatList.value = await db.getAll('conversationList'); const userchatList = await db.getAll('conversationList');
console.log(chatList.value); // 获取群数据
const groupChatListawait = await db.getAll("groupChatList")
// 合并两个数组
chatList.value = [...userchatList, ...groupChatListawait];
}; };
const setCurrentNavId = (id: number) => { const setCurrentNavId = (id: number) => {
@ -165,7 +181,6 @@ export const useChatStore = defineStore('chatStore', () => {
await setScrollToBottom(); await setScrollToBottom();
return; return;
} }
notifyError("消息发送失败");
}; };
// 更新聊天和聊天记录 // 更新聊天和聊天记录
@ -219,49 +234,58 @@ export const useChatStore = defineStore('chatStore', () => {
} }
}; };
const changeChatListAndGetChatHistory = async (userId: number) => { const changeChatListAndGetChatHistory = async (userId: number) => {
// 将当前的chatlist存到map中id为key,如果userId能在map中找到就不添加。
// 将当前的 chatList 存到 map 中,id 为 key
const chatListMap = new Map<number, any>();
// value可设置为空 // todo 优化,需要加唯一标识
chatList.value.forEach((chat: { userId: number; }) => { console.log(chatList.value);
chatListMap.set(chat.userId, ""); let userExists = false;
}); // 检查 chatList 中是否存在 userId
for (let i = 0; i < chatList.value.length; i++) {
// 检查 userId 是否在 map 中 console.log(chatList);
if (chatListMap.has(userId)) { if (chatList.value[i].id === userId) {
// 如果存在获取聊天记录添加到historyList userExists = true;
// console.log(getHistory(userId, userInfo.value.id)) break;
chatHistory.value = await getHistory(userId, userInfo.value.id) }
}
// 检查 userId 是否已经存
if (userExists) {
// 如果存在,获取聊天记录添加到 historyList
console.log("存在");
chatHistory.value = await getHistory(userId, userInfo.value.id);
return; return;
} else { } else {
// 如果不在chatlist中表示没有聊天记录。那么去用户表中获取该用户的基本信息 // 如果不存在,则从用户表中获取该用户的基本信息
const user = await db.getOne("workbenchusers", userId) const user = await db.getOne("workbenchusers", userId);
if (user) {
// 将新用户信息添加到 chatList
chatList.value.push({ chatList.value.push({
id: user.id, id: user.id,
type: "user",
nickname: user.nickname, nickname: user.nickname,
avatar: user.avatar, avatar: user.avatar,
previewTimeFormat: formatTime(Date.now()), previewTimeFormat: formatTime(Date.now()),
previewMessage: "", previewMessage: "",
}) });
// 持久化 // 持久化
await db.addOne("conversationList", { await db.addOne("conversationList", {
userId: user.id, userId: user.id,
type: "user",
username: user.username, username: user.username,
nickname: user.nickname, nickname: user.nickname,
avatar: user.avatar, avatar: user.avatar,
toUserId: userInfo.value.id, toUserId: userInfo.value.id,
time: Date.now(), time: Date.now(),
previewMessage: "", previewMessage: "",
createdAt: Date.now() createdAt: Date.now(),
}) });
} else {
console.warn("User not found in workbenchusers with userId:", userId);
}
} }
}; };
const formatTime = (timestamp: number): string => { const formatTime = (timestamp: number): string => {
const now = new Date(); const now = new Date();
const createdAt = new Date(timestamp); const createdAt = new Date(timestamp);
@ -287,24 +311,78 @@ export const useChatStore = defineStore('chatStore', () => {
}; };
// 获取用户表中所有用户
const getAllUser = async () => {
allUserList.value = await db.getAll("workbenchusers");
console.log(allUserList.value)
};
// 创建群聊 // 创建群聊
const createGroupChat = async (groupName?: string, userIds?: number[]) => { const createGroupChat = async (userIds: number[]) => {
try { try {
const currUserId = userInfo.value.id;
// 将当前用户的 ID 添加到 user_ids 数组中
const newUserIds = [currUserId, ...userIds]
const data = { const data = {
name: groupName, name: departmentName.value,
user_ids: userIds user_ids: newUserIds
} }
const url = config.userInfo.url + "/chat/group"; const url = config.userInfo.url + "/chat/group";
const res = await fetchPost(url, JSON.stringify(data)); const res = await fetchPost(url, JSON.stringify(data));
console.log(res)
if (!res.ok) { if (!res.ok) {
return false; return false;
} }
const groupData = await res.json(); const groupData = await res.json();
console.log(groupData) console.log(groupData)
// 构建数据入库
// 群数据
const group_id = groupData.data.group_id
const gourpData = {
name: departmentName.value,
avatar: "./logo.png",
groupId: group_id,
creator: currUserId,
createdAt: new Date()
}
// 群成员数据
const groupMembers = {
userId: currUserId,
groupId: group_id,
createdAt: new Date()
}
// 添加数据库
db.addOne("group", gourpData)
db.addOne("groupMembers", groupMembers)
// 添加到会话列表中
const groupConversation = {
group_id: group_id,
name: departmentName.value,
avatar: "./logo.png",
messages: "",
type: "group",
previewMessage: "",
previewTimeFormat: formatTime(Date.now()),
createdAt: new Date()
}
//
db.addOne("groupChatList", groupConversation)
chatList.value.push(groupConversation)
// 关闭对话弹窗
setGroupChatInvitedDialogVisible(false)
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} }
}; };
// 处理用户消息 // 处理用户消息
@ -527,16 +605,18 @@ export const useChatStore = defineStore('chatStore', () => {
}; };
const changeChatList = async (userId: number) => { const changeChatList = async (id) => {
// 设置 targetUserId // 设置 targetUserId
targetUserId.value = userId; console.log(id)
targetUserId.value = id
// 获取当前用户和目标用户的聊天记录 // 获取当前用户和目标用户的聊天记录
const history = await getHistory(userId, userInfo.value.id) const history = await getHistory(id, userInfo.value.id)
chatHistory.value = history; chatHistory.value = history;
// 设置目标用户的信息 // 设置目标用户的信息
await setTargetUserInfo(userId); await setTargetUserInfo(id);
}; };
const getHistory = async (userId: any, toUserId: any) => { const getHistory = async (userId: any, toUserId: any) => {
@ -590,6 +670,8 @@ export const useChatStore = defineStore('chatStore', () => {
groupInfoSettingDrawerVisible, groupInfoSettingDrawerVisible,
targetNickname, targetNickname,
departmentList, departmentList,
allUserList,
departmentName,
initChat, initChat,
showContextMenu, showContextMenu,
setCurrentNavId, setCurrentNavId,
@ -604,6 +686,7 @@ export const useChatStore = defineStore('chatStore', () => {
createGroupChat, createGroupChat,
userChatMessage, userChatMessage,
initOnlineUserList, initOnlineUserList,
getDepartmentList getDepartmentList,
getAllUser
}; };
}); });

10
frontend/src/stores/db.ts

@ -1,6 +1,6 @@
import Dexie from 'dexie'; import Dexie from 'dexie';
export type ChatTable = 'chatuser' | 'chatmsg' | 'chatmessage' | 'groupmessage' | 'chatRecord' | 'workbenchusers' | 'conversationList' | 'group'; export type ChatTable = 'chatuser' | 'chatmsg' | 'chatmessage' | 'groupmessage' | 'chatRecord' | 'workbenchusers' | 'conversationList' | 'group' | 'groupMembers' | 'groupChatList';
export const dbInit: any = new Dexie('GodoOSDatabase'); export const dbInit: any = new Dexie('GodoOSDatabase');
dbInit.version(1).stores({ dbInit.version(1).stores({
@ -15,9 +15,11 @@ dbInit.version(1).stores({
chatmessage: '++id,userId,toUserId,senderInfo,isMe,isRead,content,type,readAt,createdAt', chatmessage: '++id,userId,toUserId,senderInfo,isMe,isRead,content,type,readAt,createdAt',
groupmessage: '++id,userId,groupId,senderInfo,isMe,isRead,content,type,readAt,createdAt', groupmessage: '++id,userId,groupId,senderInfo,isMe,isRead,content,type,readAt,createdAt',
// 群组表 // 群组表
group: '++id,name,creator,createdAt', group: '++id,avatar,name,groupId,creator,createdAt',
// 群成员表 // 群成员表
group_members: '++id,userId,groupId,createdAt', groupMembers: '++id,userId,groupTableId,groupId,createdAt',
// 群会话列表
groupChatList: '++id,groupId,name,message,previewMessage,avatar,createdAt',
}).upgrade((tx: { }).upgrade((tx: {
conversationList: any; conversationList: any;
@ -27,7 +29,7 @@ dbInit.version(1).stores({
// 手动添加索引 // 手动添加索引
tx.conversationList.addIndex('userId', (obj: { userId: any; }) => obj.userId); tx.conversationList.addIndex('userId', (obj: { userId: any; }) => obj.userId);
tx.chatRecord.addIndex('toUserId', (obj: { toUserId: any; }) => obj.toUserId); tx.chatRecord.addIndex('toUserId', (obj: { toUserId: any; }) => obj.toUserId);
tx.group.addIndex('owner_id', (obj: { owner_id: any }) => obj.owner_id); // 添加索引: 群主 ID tx.group.addIndex('groupId', (obj: { groupId: any }) => obj.groupId); // 添加索引: 群主 ID
}); });
export const db = { export const db = {

Loading…
Cancel
Save