diff --git a/src/views/message/components/GroupSetting.vue b/src/views/message/components/GroupSetting.vue index cd4d822..809ee4a 100644 --- a/src/views/message/components/GroupSetting.vue +++ b/src/views/message/components/GroupSetting.vue @@ -142,13 +142,13 @@ export default { props: { chat: Object, + groupInfo: Object, }, data() { return { visible: false, isSearchVisible: false, - groupInfo: {}, isAdmin: false, showDeleteBtn: null, currentUserId: this.$store.state.user.userInfo?.id, @@ -162,18 +162,6 @@ export default { methods: { async loadGroupInfo() { this.visible = true; - if (this.chat) { - if (!this.chat?.id) return; - try { - const res = await getMultiChatInfo({ multi_chat_id: this.chat.id }); - this.groupInfo = { - ...res.data, - user_list: res.data.user_list.sort((a, b) => a.id - b.id), - }; - } catch (e) { - console.error("获取群信息失败", e); - } - } }, editGroupName() { diff --git a/src/views/message/components/MessageDisplay.vue b/src/views/message/components/MessageDisplay.vue index 1571182..dd0b3c4 100644 --- a/src/views/message/components/MessageDisplay.vue +++ b/src/views/message/components/MessageDisplay.vue @@ -4,8 +4,8 @@
{{ currentChat.name }} - - ({{ currentChat.user_num }}) + + ({{ currentChat.user_num - 1 }})
@@ -13,12 +13,13 @@ type="text" icon="el-icon-chat-line-round" @click="handleSearchRecord" + v-if="currentChat && currentChat.scene != ContactsScene.NOTIFY" />
@@ -41,90 +42,122 @@
- -
- {{ formatMessageTime(msg.create_time) }} -
-
- {{ - currentChat.user_num > 0 - ? `${currentChat.source_name || "成员"}邀请了${ - currentChat.user_num - }人加入群聊` - : `${currentChat.source_name || "成员"}加入了群聊` - }} -
-
- {{ msg.source_name || "成员" }}退出了群聊 -
+
- - - -
- -
- {{ msg.sender_name || msg.source_name || "未知用户" }} -
- -
- -
- - +
+ {{ formatMessageTime(msg.update_time) }} +
+
+ {{ + (msg.source_name || "成员") + + (JSON.parse(msg.content).invited_user_ids.length > 0 + ? `邀请了${ + JSON.parse(msg.content).invited_user_ids.length || 0 + }人加入群聊` + : "加入了群聊") + }} +
+
+ + + +
+
+ {{ formatMessageTime(msg.update_time) }} +
+
+ {{ + (msg.sender_name || msg.source_name || "未知用户") + + `修改了群名为"${JSON.parse(msg.content).name || ""}"` + }} +
+
+ + +
+
+ {{ formatMessageTime(msg.update_time) }} +
+
+ + + +
+
- + +
+ +
-
- - +
+ +
+ + + - - + - -
-
-
- -
-
-
{{ msg.file_name }}
-
- {{ formatFileSize(msg.file_size) }} + +
+
+
+
-
- - 打开 - - - 打开目录 - +
+
{{ msg.file_name }}
+
+ {{ formatFileSize(msg.file_size) }} +
+
+ + 打开 + + + 打开目录 + +
-
- -
- 病例分享: 姓名:{{ JSON.parse(msg.content).name }}, 年龄:{{ - JSON.parse(msg.content).age - }}, 性别:{{ JSON.parse(msg.content).sex }}, - +
- 病例ID:{{ JSON.parse(msg.content).report_id }} - -
+ 病例分享: 姓名:{{ JSON.parse(msg.content).name }}, 年龄:{{ + JSON.parse(msg.content).age + }}, 性别:{{ JSON.parse(msg.content).sex }}, + + 病例ID:{{ JSON.parse(msg.content).report_id }} + +
- -
- 知识库分享: - +
- 资源名称:{{ JSON.parse(msg.content).file_name }} - -
-
- 视讯邀请:{{ JSON.parse(msg.content).name }}邀请您参加会诊 - + 资源名称:{{ JSON.parse(msg.content).file_name }} + +
+
- 会诊口令:{{ JSON.parse(msg.content).room_id }} - -
- -
-
-
-
- 标题:{{ JSON.parse(msg.content).title }} -
-
- 内容:{{ JSON.parse(msg.content).content }} -
-
- - 进入阅读 - + 视讯邀请:{{ JSON.parse(msg.content).name }}邀请您参加会诊 + + 会诊口令:{{ JSON.parse(msg.content).room_id }} + +
+ +
+
+
+
+ 标题:{{ JSON.parse(msg.content).title }} +
+
+ 内容:{{ JSON.parse(msg.content).content }} +
+
+ + 进入阅读 + +
-
- -
- 发送中... - 失败 - - 已读 - - {{ - currentChat.scene === 4 - ? msg.unread_count - ? msg.unread_count + "人未读" - : "未读" - : "对方未读" - }} + +
+ 发送中... + 失败 + + + {{ currentChat.user_num - msg.read_user_ids.length }}人未读 + + + 未读 + +
@@ -323,12 +365,15 @@ export default { data() { return { MessageType, + ContactsScene, loadingHistory: false, hasMoreHistory: true, loadingNewer: false, hasMoreNewer: true, + scrollDebounceHistory: false, + scrollDebounceNewer: false, baseMessageId: 0, - pageSize: 4, + pageSize: 10, previewVisible: false, previewImageUrl: "", isNearBottom: true, @@ -380,12 +425,47 @@ export default { this.setMessages({ key, messages: [] }); // 默认 base_message_id 为 0,加载最新消息 await this.loadMessages({ up: 1, baseMessageId: 0 }); + + // 自动加载历史消息直到填满可视区域 + await this.$nextTick(); + await this.preloadHistoryMessages(); + this.$nextTick(() => { this.scrollToBottom(); }); this.markAsRead(); }, + async preloadHistoryMessages() { + const container = this.$refs.messageContainer; + if (!container) return; + + const containerHeight = container.clientHeight; + let contentHeight = container.scrollHeight; + let prevHeight = 0; + let loadCount = 0; + const maxLoadCount = 10; // 最多加载10次,防止无限循环 + + // 如果内容高度小于容器高度,说明消息不够,需要加载更多历史 + while ( + contentHeight < containerHeight && + this.hasMoreHistory && + !this.loadingHistory && + loadCount < maxLoadCount + ) { + prevHeight = contentHeight; + await this.loadMessages({ up: 1 }); + await this.$nextTick(); + contentHeight = container.scrollHeight; + loadCount++; + + // 高度没有变化,说明没有更多数据了 + if (contentHeight === prevHeight) { + break; + } + } + }, + // 通用消息加载方法 // up: 0 表示加载更新消息(向下滚动),1 表示加载历史消息(向上滚动) async loadMessages({ up, baseMessageId }) { @@ -424,7 +504,7 @@ export default { base_message_id: currentBaseMessageId, page: 1, size: this.pageSize, - up: up, + up: 1, target_id: this.currentChat.id, }; @@ -453,12 +533,17 @@ export default { const processed = list.map((m) => this.processMessage(m)); let merged; + // 创建已存在消息ID的集合用于去重 + const existingIds = new Set(existing.map(m => m.message_id || m.id)); + if (up === 0) { // 加载更新消息:追加到尾部 - merged = [...existing, ...processed]; + const newMessages = processed.filter(m => !existingIds.has(m.message_id || m.id)); + merged = [...existing, ...newMessages]; } else { // 加载历史消息:插入到头部 - merged = [...processed, ...existing]; + const newMessages = processed.filter(m => !existingIds.has(m.message_id || m.id)); + merged = [...newMessages, ...existing]; } this.setMessages({ key, messages: merged }); @@ -486,25 +571,30 @@ export default { handleScroll(e) { const el = e.target; const scrollTop = el.scrollTop; - const clientHeight = el.clientHeight; const scrollHeight = el.scrollHeight; - const isNearBottom = scrollTop + clientHeight >= scrollHeight - 50; const isNearTop = scrollTop <= 30; - // 向下滚动到底部 → 加载更新消息(最新的数据) - if (isNearBottom && this.hasMoreNewer && !this.loadingNewer) { - this.loadMessages({ up: 1 }); - } - // 向上滚动到顶部 → 加载历史消息(更早的消息) - if (isNearTop && this.hasMoreHistory && !this.loadingHistory) { + if ( + isNearTop && + this.hasMoreHistory && + !this.loadingHistory && + !this.scrollDebounceHistory + ) { + this.scrollDebounceHistory = true; const oldHeight = scrollHeight; - this.loadMessages({ up: 1 }).then(() => { - this.$nextTick(() => { - const newHeight = el.scrollHeight; - el.scrollTop = newHeight - oldHeight; + this.loadMessages({ up: 1 }) + .then(() => { + this.$nextTick(() => { + const newHeight = el.scrollHeight; + el.scrollTop = newHeight - oldHeight; + }); + }) + .finally(() => { + setTimeout(() => { + this.scrollDebounceHistory = false; + }, 1000); }); - }); } }, @@ -645,7 +735,11 @@ export default { // 下载文件 handleDownload(item) { if (item.file_path) { - window.open(this.$store.state.user.netConfig.MINIO_ENDPOINT_HTTPS + item.file_path, "_blank"); + window.open( + this.$store.state.user.netConfig.MINIO_ENDPOINT_HTTPS + + item.file_path, + "_blank" + ); } else { this.$message.warning("文件链接不可用"); } @@ -656,7 +750,9 @@ export default { this.$modal.msg("浏览器安全限制:请下载文件后在下载列表中打开文件夹"); // 先触发下载 const a = document.createElement("a"); - a.href = this.$store.state.user.netConfig.MINIO_ENDPOINT_HTTPS + item.file_path; + a.href = + this.$store.state.user.netConfig.MINIO_ENDPOINT_HTTPS + + item.file_path; a.download = item.file_name; a.target = "_blank"; document.body.appendChild(a); @@ -680,10 +776,11 @@ export default { }, handleOpenKnowledge(msg) { - const knowledgeId = msg.payload.knowledge_id; - if (knowledgeId) { - this.$router.push(`/knowledge-base?id=${knowledgeId}`); - } + window.open( + this.$store.state.user.netConfig.MINIO_ENDPOINT_HTTPS + + JSON.parse(msg.content).file_path, + "_blank" + ); }, handleOpenConsultationInvite(msg) { this.$router.push({ @@ -754,6 +851,7 @@ export default { }); } this.$emit("clear-unread", this.currentChat.id, scene); + this.$emit("refresh-list"); } catch (e) { console.error("标记已读失败", e); } diff --git a/src/views/message/components/MessageEditor.vue b/src/views/message/components/MessageEditor.vue index 1a65c72..be7970c 100644 --- a/src/views/message/components/MessageEditor.vue +++ b/src/views/message/components/MessageEditor.vue @@ -2,195 +2,144 @@
- + - - - - + + - + + + + A + + 10px + 11px + 12px + 13px + 14px + + + + + @ + + +
+ + 所有人 +
+
+ +
+ + {{ item.name }} +
+
+ {{ item.role_name }} +
+
+
+
+ + - - + + - - @ - - - - - A - - - - -
-
- {{ size }}px -
-
- - Enter 发送 / Ctrl+Enter 换行 -
- - -
-
- - - - -
-
选择要@的成员
- -
-
+
+
+ +
+ - - {{ user.name }} -
-
- 无匹配成员 -
+ 发送 + + + + {{ sendModeLabel }} + + + + Enter发送 + Ctrl+Enter发送 + +
- - + - - - - -
-
- -
-
-
{{ currentChat.name || '通话中' }}
-
{{ callStatus }}
-
-
- {{ formatCallTime(callDuration) }} -
-
- - {{ videoEnabled ? '关闭摄像头' : '开启摄像头' }} - - - {{ micEnabled ? '静音' : '取消静音' }} - - - 结束通话 - -
-
-