Browse Source

style:优化群成员样式。

master
qiutianhong 7 months ago
parent
commit
0f8227e09c
  1. 80
      frontend/src/components/chat/ChatBox.vue
  2. 12
      frontend/src/components/chat/ChatMessage.vue
  3. 20
      frontend/src/components/chat/ChatMsgList.vue
  4. 96
      frontend/src/components/chat/chatGroupMember.vue
  5. 12
      frontend/src/components/chat/chatUserInfo.vue
  6. 60
      frontend/src/stores/chat.ts
  7. 7
      frontend/src/stores/db.ts
  8. 2
      frontend/src/system/member.ts

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

@ -48,6 +48,8 @@
>
</div>
</el-dialog>
<!-- 群成员抽屉 -->
<ChatGroupMember />
<div
class="chatbox-main"
v-if="store.targetChatId"
@ -87,6 +89,13 @@
/></el-icon>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item
@click="
store.groupMemberDrawerVisible = true
"
>群成员</el-dropdown-item
>
<el-dropdown-item
@click="openInviteGroupDialog()"
>邀请群聊</el-dropdown-item
@ -99,7 +108,10 @@
"
>退出群聊</el-dropdown-item
>
<el-dropdown-item>清空记录</el-dropdown-item>
<el-dropdown-item
@click="clearMessages('group')"
>清空记录</el-dropdown-item
>
</el-dropdown-menu>
</template>
</el-dropdown>
@ -126,7 +138,7 @@
/></el-icon>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="store.clearChatRecord()"
<el-dropdown-item @click="clearMessages('user')"
>清空记录</el-dropdown-item
>
</el-dropdown-menu>
@ -147,14 +159,6 @@
</div>
</el-scrollbar>
</div>
<!-- 群成员滚动区域 -->
<div class="member-container">
<el-scrollbar ref="memberScrollbarRef">
<div ref="memberInnerRef">
<ChatGroupMember />
</div>
</el-scrollbar>
</div>
</el-main>
<!--聊天输入区和发送按钮等-->
@ -207,28 +211,14 @@
"
v-else
>
<el-icon
:size="180"
color="#0078d7"
>
<ChatDotSquare />
</el-icon>
<p
style="
font-size: 18px;
font-weight: 600;
margin-top: 10px;
color: #333;
"
>
欢迎使用GodoOS
</p>
<el-empty description="请选择一个用户或群聊" />
</div>
</template>
<script setup lang="ts">
import { useChatStore } from "@/stores/chat";
import { useChooseStore } from "@/stores/choose";
import { notifyError, notifySuccess } from "@/util/msg";
const store: any = useChatStore();
const choose = useChooseStore();
@ -237,6 +227,27 @@
const scrollbarRef = ref(null);
const innerRef = ref(null);
//
const clearMessages = (type: string) => {
//
if (type === "user") {
if (store.clearSentMessages()) {
if (store.clearReceivedMessages()) {
notifySuccess("删除成功");
store.getSessionInfo(store.targetChatId, type);
} else {
notifyError("删除失败");
}
} else if (store.clearReceivedMessages()) {
notifySuccess("删除成功");
} else {
notifyError("删除失败");
}
} else if (type === "group") {
store.clearGroupMessages();
}
};
const openInviteGroupDialog = () => {
store.inviteFriendDialogVisible = true;
store.getInviteUserList();
@ -292,11 +303,6 @@
}
);
function openDrawer() {
store.drawerVisible = true;
// store.getGroupMemberList(store.targetGroupInfo.group_id);
}
// store.drawerVisible
watch(
() => store.drawerVisible,
@ -348,14 +354,14 @@
/* 聊天消息滚动区域 */
.msg-container {
width: calc(100% - 150px);
width: 100%;
height: 100%;
}
/* 群成员滚动区域 */
.member-container {
border-left: 1px solid #edebeb;
width: 140px;
height: 100%;
height: calc(100% - 10px);
}
.input-main {
@ -388,14 +394,6 @@
margin-bottom: 10px; /* 每个成员之间的间距 */
}
:deep(.el-drawer__header) {
color: #000000;
}
:deep(.el-drawer__body) {
margin-top: -40px; /* 根据需要调整这个值 */
}
.group-name {
font-size: 16px;
border-top: 1px solid #edebeb;

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

@ -76,7 +76,7 @@
</div>
<!-- 发送时间展示在消息框外部的下方 -->
<div class="chat-time-me-outer">
{{ item.previewTimeFormat }}
{{ formatTime(item.createdAt) }}
</div>
</el-col>
<el-col :span="2">
@ -160,7 +160,7 @@
</div>
<!-- 发送时间展示在消息框外部的下方 -->
<div class="chat-time-other-outer">
{{ item.previewTimeFormat }}
{{ item.time }}
</div>
</el-col>
<el-col :span="8" />
@ -230,6 +230,14 @@
const currUserId = ref();
//
function formatTime(timestamp) {
const date = new Date(timestamp);
const month = date.getMonth() + 1; // 0
const day = date.getDate();
return `${month}-${day}`;
}
const showUserInfo = (chatId: string) => {
console.log(chatId);
currUserId.value = chatId;

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

@ -33,7 +33,7 @@
:size="40"
class="avatar"
style="
background-color: #165DFF;
background-color: #165dff;
display: flex;
align-items: center;
justify-content: center;
@ -90,7 +90,7 @@
</div>
<div class="previewTime">
{{ item.previewTimeFormat }}
{{ formatTime(item.time) }}
</div>
</div>
@ -129,6 +129,14 @@
const store = useChatStore();
const id = ref("1");
//
function formatTime(timestamp) {
const date = new Date(timestamp);
const month = date.getMonth() + 1; // 0
const day = date.getDate();
return `${month}-${day}`;
}
// store
const filteredMessages = computed(() => {
return store.search
@ -152,11 +160,11 @@
margin-bottom: 5px;
overflow: hidden;
margin-top: 5px;
background-color: #FFF;
background-color: #fff;
}
.list-item:hover {
background-color: #E8F3FF;
background-color: #e8f3ff;
}
.avatar {
@ -201,7 +209,7 @@
.previewTime {
font-size: 12px;
color: #86909C;
color: #86909c;
}
.preview-left {
@ -218,7 +226,7 @@
margin-left: 10px;
font-size: 12px;
font-family: Arial, sans-serif;
color: #86909C;
color: #86909c;
overflow: hidden; /* 隐藏超出部分 */
text-overflow: ellipsis; /* 显示为省略号 */
white-space: nowrap; /* 不换行 */

96
frontend/src/components/chat/chatGroupMember.vue

@ -1,44 +1,73 @@
<template>
<div class="group-member-container">
<el-drawer
v-model="store.groupMemberDrawerVisible"
direction="rtl"
title="群成员"
:with-header="true"
:show-close="true"
size="250px"
>
<!-- 群成员列表 -->
<div
class="member-list"
v-for="item in groupMembers"
:key="item.userId"
>
<!-- 头像和昵称 -->
<div class="member-item">
<div class="avatar-container">
<el-avatar
style="width: 100%; height: 100%;"
:src="item.avatar"
/>
<div class="group-member-container">
<div
class="member-list"
v-for="item in store.groupMembers"
:key="item.id"
>
<div class="member-item">
<!-- 头像和昵称 -->
<div class="avatar-container">
<el-avatar
style="width: 100%; height: 100%"
:src="item.avatar"
/>
</div>
<span>{{ item.nickname }}</span>
</div>
<span>{{ item.nickname }}</span>
</div>
</div>
</div>
</el-drawer>
</template>
<script setup lang="ts">
import { useChatStore } from "@/stores/chat";
const store = useChatStore();
// 使
// true
watch(
() => store.groupMemberDrawerVisible,
(newVal) => {
if (newVal) {
store.getGroupMemberList(store.targetGroupInfo.group_id);
}
}
);
// 使40
const groupMembers = ref(
Array.from({ length: 40 }, (v, i) => ({
userId: `${i + 1}`,
avatar: `path/to/avatar${i + 1}.jpg`,
nickname: `用户1111111111111111${i + 1}`,
}))
//
watch(
() => store.drawerVisible,
(newVal) => {
if (newVal) {
store.getGroupMemberList(store.targetGroupInfo.group_id);
}
}
);
</script>
<style scoped>
:deep(.el-drawer__header) {
background-color: red;
padding: 0px 20px;
height: 50px;
color: #000000;
margin-bottom: 0px;
}
:deep(.el-drawer__title) {
font-size: 20px;
}
.group-member-container {
margin: 10px 0;
width: 100%;
height: 100%;
overflow-y: auto; /* 添加滚动条 */
}
.member-item {
@ -48,19 +77,18 @@
}
.avatar-container {
width: 25px;
height: 25px;
margin-right: 5px;
width: 30px;
height: 30px;
margin-right: 10px;
}
.member-item span {
width: 90px;
width: 150px;
margin-left: 10px;
font-size: 12px;
color: #86909C;
overflow: hidden; /* 防止内容溢出 */
white-space: nowrap; /* 保持文本在一行 */
text-overflow: ellipsis; /* 文本溢出显示省略号 */
max-width: 150px; /* 最大宽度,根据需要调整 */
font-size: 12px;
color: #86909c;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
</style>

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

@ -74,7 +74,9 @@
</el-button>
</div>
</div>
<div v-else>1</div>
<div v-else class="empty-container">
<el-empty description="请选择一个用户或群聊" />
</div>
</template>
<script lang="ts" setup>
@ -107,6 +109,14 @@
</script>
<style scoped>
.empty-container {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.chat-user-info {
display: flex;
flex-direction: column;

60
frontend/src/stores/chat.ts

@ -99,6 +99,8 @@ export const useChatStore = defineStore('chatStore', () => {
// 定义消息发送、接受的状态用于控制滚动条的滚动
const messageSendStatus = ref(false)
const messageReceiveStatus = ref(false)
// 群成员列表抽屉是否显示
const groupMemberDrawerVisible = ref(false)
// 群成员列表
const groupMemberList = ref<any[]>([])
@ -1260,43 +1262,66 @@ export const useChatStore = defineStore('chatStore', () => {
};
// 清空聊天记录
// 清空聊天记录
const clearChatRecord = async () => {
// 删除我发送给对方的记录
// 清空发送的聊天记录
const clearSentMessages = async () => {
const whereObjSent = {
toUserId: targetChatId.value,
userId: userInfo.value.id
};
const resSent = await db.deleteByWhere("workbenchChatRecord", whereObjSent);
if (resSent >= 0) {
// 更新chatList中的预览消息
chatList.value.forEach((item: any) => {
if (item.chatId === targetChatId.value) {
item.previewMessage = "快开始打招呼吧!";
}
});
return true
} else {
return false
}
};
// 删除对方发送给我的记录
// 清空接收的聊天记录
const clearReceivedMessages = async () => {
const whereObjReceived = {
userId: targetChatId.value,
toUserId: userInfo.value.id
};
const resReceived = await db.deleteByWhere("workbenchChatRecord", whereObjReceived);
if (resReceived >= 0) {
// 检查两个删除操作是否都成功
if (resSent == 1 && resReceived == 1) {
// 更新chatHistory,移除相关记录
chatHistory.value = chatHistory.value.filter((item: any) =>
!(item.toUserId === targetChatId.value && item.userId === userInfo.value.id) &&
!(item.userId === targetChatId.value && item.toUserId === userInfo.value.id)
);
// 更新chatList中的预览消息
chatList.value.forEach((item: any) => {
if (item.chatId === targetChatId.value) {
item.previewMessage = "快开始打招呼吧!";
}
});
return true
} else {
return false
}
};
// 清空群消息
const clearGroupMessages = async () => {
const res = await db.deleteByField("workbenchGroupChatRecord", "chatId", targetChatId.value);
if (res >= 0) {
// 还需要找到
getSessionInfo(targetChatId.value, "group")
// 更新chatList中的预览消息
chatList.value.forEach((item: any) => {
if (item.chatId === targetChatId.value) {
item.previewMessage = "快开始打招呼吧!";
}
});
notifySuccess("清空成功");
return;
notifySuccess("删除成功");
} else {
notifyError("删除失败");
}
notifyError("清空失败");
}
return {
emojiList,
groupSystemMessage,
@ -1334,6 +1359,7 @@ export const useChatStore = defineStore('chatStore', () => {
messageSendStatus,
messageReceiveStatus,
groupMembers,
groupMemberDrawerVisible,
initChat,
showContextMenu,
setCurrentNavId,
@ -1358,6 +1384,8 @@ export const useChatStore = defineStore('chatStore', () => {
setScrollToBottom,
getGroupMemberList,
getInviteUserList,
clearChatRecord,
clearReceivedMessages,
clearSentMessages,
clearGroupMessages
};
});

7
frontend/src/stores/db.ts

@ -9,7 +9,7 @@ dbInit.version(1).stores({
// 会话列表
workbenchSessionList: '++id,avatar,chatId,username,nickname,userId,toUserId,previewMessage,messages,time,createdAt',
// 聊天记录
workbenchChatRecord: '++id,toUserId,messages,messageType,time,createdAt,userInfo',
workbenchChatRecord: '++id,[toUserId+userId], [userId+toUserId],toUserId,messages,messageType,time,createdAt,userInfo',
// 群组会话列表
groupSessionList: '++id,groupId,chatId,name,message,previewMessage,avatar,createdAt',
// 群组聊天记录
@ -28,13 +28,14 @@ dbInit.version(1).stores({
workbenchGroupUserList: any;
workbenchGroupInviteMessage: any;
groupSessionList: any;
workbenchChatRecord: { addIndex: (arg0: string, arg1: (obj: { toUserId: any; }) => any) => void; };
workbenchChatRecord: 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.workbenchChatUser.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);
tx.workbenchGroupUserList.addIndex('group_id', (obj: { group_id: any; }) => obj.group_id);
tx.workbenchGroupInviteMessage.addIndex('group_id', (obj: { group_id: any; }) => obj.group_id);

2
frontend/src/system/member.ts

@ -4,7 +4,7 @@ export const memberList = [
appIcon: "chat",
content:"Chat",
frame: true,
width: 1000,
width: 900,
height: 650,
center: true,
resizable: true,

Loading…
Cancel
Save