no message
This commit is contained in:
parent
91db27cca7
commit
62b03f8343
@ -15,7 +15,8 @@ $primary-color: #0877F1;
|
|||||||
|
|
||||||
/* 患者信息栏样式 */
|
/* 患者信息栏样式 */
|
||||||
.patient-info-bar {
|
.patient-info-bar {
|
||||||
position: relative;
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
border-bottom: 1rpx solid #f0f0f0;
|
border-bottom: 1rpx solid #f0f0f0;
|
||||||
padding: 20rpx 32rpx;
|
padding: 20rpx 32rpx;
|
||||||
@ -112,6 +113,7 @@ $primary-color: #0877F1;
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -524,6 +524,7 @@ const initTIMCallbacks = async () => {
|
|||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
console.log("✓ 收到新消息后已标记为已读");
|
console.log("✓ 收到新消息后已标记为已读");
|
||||||
|
// 标记为已读后,刷新 tabBar 徽章
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error("✗ 标记已读失败:", error);
|
console.error("✗ 标记已读失败:", error);
|
||||||
@ -677,6 +678,7 @@ const loadMessageList = async () => {
|
|||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
console.log("✓ 会话已标记为已读:", chatInfo.value.conversationID);
|
console.log("✓ 会话已标记为已读:", chatInfo.value.conversationID);
|
||||||
|
// 标记为已读后,刷新 tabBar 徽章
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error("✗ 标记会话已读失败:", error);
|
console.error("✗ 标记会话已读失败:", error);
|
||||||
@ -825,6 +827,12 @@ onShow(() => {
|
|||||||
checkLoginAndInitTIM();
|
checkLoginAndInitTIM();
|
||||||
} else if (timChatManager.tim && !timChatManager.isLoggedIn) {
|
} else if (timChatManager.tim && !timChatManager.isLoggedIn) {
|
||||||
timChatManager.ensureIMConnection();
|
timChatManager.ensureIMConnection();
|
||||||
|
} else if (timChatManager.tim && timChatManager.isLoggedIn && chatInfo.value.conversationID) {
|
||||||
|
|
||||||
|
messageList.value = [];
|
||||||
|
isCompleted.value = false;
|
||||||
|
lastFirstMessageId.value = "";
|
||||||
|
loadMessageList();
|
||||||
}
|
}
|
||||||
|
|
||||||
startIMMonitoring(30000);
|
startIMMonitoring(30000);
|
||||||
|
|||||||
@ -1,5 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="message-page">
|
<view class="message-page">
|
||||||
|
<!-- 标题栏 -->
|
||||||
|
<view class="message-header">
|
||||||
|
<text class="header-title">咨询</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
<!-- 消息列表 -->
|
<!-- 消息列表 -->
|
||||||
<scroll-view
|
<scroll-view
|
||||||
class="message-list"
|
class="message-list"
|
||||||
@ -49,7 +54,7 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="message-preview">
|
<view class="message-preview">
|
||||||
<text class="preview-text">{{
|
<text class="preview-text">{{
|
||||||
conversation.lastMessage || "暂无消息"
|
cleanMessageText(conversation.lastMessage) || "暂无消息"
|
||||||
}}</text>
|
}}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@ -75,7 +80,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from "vue";
|
import { ref, computed } from "vue";
|
||||||
import { onLoad, onShow, onHide } from "@dcloudio/uni-app";
|
import { onLoad, onShow, onHide } from "@dcloudio/uni-app";
|
||||||
import { storeToRefs } from "pinia";
|
import { storeToRefs } from "pinia";
|
||||||
import useAccountStore from "@/store/account.js";
|
import useAccountStore from "@/store/account.js";
|
||||||
@ -98,6 +103,57 @@ const refreshing = ref(false);
|
|||||||
// 群聊头像管理
|
// 群聊头像管理
|
||||||
const { loadGroupAvatars, getAvatarList } = useGroupAvatars();
|
const { loadGroupAvatars, getAvatarList } = useGroupAvatars();
|
||||||
|
|
||||||
|
// 计算总未读消息数
|
||||||
|
const totalUnreadCount = computed(() => {
|
||||||
|
return conversationList.value.reduce(
|
||||||
|
(sum, conv) => sum + (conv.unreadCount || 0),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 立即更新未读徽章
|
||||||
|
const updateUnreadBadgeImmediately = async () => {
|
||||||
|
try {
|
||||||
|
if (!globalTimChatManager || !globalTimChatManager.tim) {
|
||||||
|
console.warn("TIM实例不存在,无法更新徽章");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await globalTimChatManager.tim.getConversationList();
|
||||||
|
|
||||||
|
if (!response || !response.data || !response.data.conversationList) {
|
||||||
|
console.warn("获取会话列表返回数据异常");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算群聊总未读数
|
||||||
|
const totalUnreadCount = response.data.conversationList
|
||||||
|
.filter(
|
||||||
|
(conv) => conv.conversationID && conv.conversationID.startsWith("GROUP")
|
||||||
|
)
|
||||||
|
.reduce((sum, conv) => sum + (conv.unreadCount || 0), 0);
|
||||||
|
try {
|
||||||
|
if (totalUnreadCount > 0) {
|
||||||
|
uni.setTabBarBadge({
|
||||||
|
index: 1,
|
||||||
|
text: totalUnreadCount > 99 ? "99+" : String(totalUnreadCount),
|
||||||
|
});
|
||||||
|
console.log("已更新 tabBar 徽章:", totalUnreadCount);
|
||||||
|
} else {
|
||||||
|
uni.setTabBarBadge({
|
||||||
|
index: 1,
|
||||||
|
text: "",
|
||||||
|
});
|
||||||
|
console.log("已清除 tabBar 徽章");
|
||||||
|
}
|
||||||
|
} catch (badgeError) {
|
||||||
|
console.error("更新TabBar徽章失败:", badgeError);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("更新未读徽章失败:", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 初始化IM
|
// 初始化IM
|
||||||
const initIM = async () => {
|
const initIM = async () => {
|
||||||
console.log("=== message.vue initIM 开始 ===");
|
console.log("=== message.vue initIM 开始 ===");
|
||||||
@ -202,11 +258,9 @@ let updateTimer = null;
|
|||||||
// 设置会话列表监听,实时更新列表
|
// 设置会话列表监听,实时更新列表
|
||||||
const setupConversationListener = () => {
|
const setupConversationListener = () => {
|
||||||
if (!globalTimChatManager) return;
|
if (!globalTimChatManager) return;
|
||||||
|
|
||||||
// 监听会话列表更新事件
|
// 监听会话列表更新事件
|
||||||
globalTimChatManager.setCallback("onConversationListUpdated", (eventData) => {
|
globalTimChatManager.setCallback("onConversationListUpdated", (eventData) => {
|
||||||
console.log("会话列表更新事件:", eventData);
|
console.log("会话列表更新事件:", eventData);
|
||||||
|
|
||||||
// 处理单个会话更新(标记已读的情况)
|
// 处理单个会话更新(标记已读的情况)
|
||||||
if (eventData && !Array.isArray(eventData) && eventData.conversationID) {
|
if (eventData && !Array.isArray(eventData) && eventData.conversationID) {
|
||||||
const conversationID = eventData.conversationID;
|
const conversationID = eventData.conversationID;
|
||||||
@ -395,16 +449,13 @@ const formatMessageTime = (timestamp) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 点击会话
|
// 点击会话
|
||||||
const handleClickConversation = (conversation) => {
|
const handleClickConversation = async (conversation) => {
|
||||||
console.log("点击会话:", conversation);
|
console.log("点击会话:", conversation);
|
||||||
|
|
||||||
// 立即清空本地未读数(优化用户体验)
|
|
||||||
const conversationIndex = conversationList.value.findIndex(
|
const conversationIndex = conversationList.value.findIndex(
|
||||||
(conv) => conv.conversationID === conversation.conversationID
|
(conv) => conv.conversationID === conversation.conversationID
|
||||||
);
|
);
|
||||||
if (conversationIndex !== -1) {
|
if (conversationIndex !== -1) {
|
||||||
conversationList.value[conversationIndex].unreadCount = 0;
|
conversationList.value[conversationIndex].unreadCount = 0;
|
||||||
console.log("已清空本地未读数:", conversation.name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 跳转到聊天页面
|
// 跳转到聊天页面
|
||||||
@ -440,11 +491,15 @@ onLoad(() => {
|
|||||||
console.log("消息列表页面加载");
|
console.log("消息列表页面加载");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 清理消息文本(移除换行符)
|
||||||
|
const cleanMessageText = (text) => {
|
||||||
|
if (!text) return "";
|
||||||
|
return text.replace(/[\r\n]+/g, " ").trim();
|
||||||
|
};
|
||||||
|
|
||||||
// 页面显示
|
// 页面显示
|
||||||
onShow(async () => {
|
onShow(async () => {
|
||||||
try {
|
try {
|
||||||
console.log("消息列表页面显示,开始初始化");
|
|
||||||
|
|
||||||
// 初始化IM
|
// 初始化IM
|
||||||
const imReady = await initIM();
|
const imReady = await initIM();
|
||||||
if (!imReady) {
|
if (!imReady) {
|
||||||
@ -466,8 +521,6 @@ onHide(() => {
|
|||||||
clearTimeout(updateTimer);
|
clearTimeout(updateTimer);
|
||||||
updateTimer = null;
|
updateTimer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 移除消息监听
|
|
||||||
if (globalTimChatManager) {
|
if (globalTimChatManager) {
|
||||||
globalTimChatManager.setCallback("onConversationListUpdated", null);
|
globalTimChatManager.setCallback("onConversationListUpdated", null);
|
||||||
globalTimChatManager.setCallback("onMessageReceived", null);
|
globalTimChatManager.setCallback("onMessageReceived", null);
|
||||||
@ -480,11 +533,46 @@ onHide(() => {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
background-color: #f5f5f5;
|
background-color: #f5f5f5;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 24rpx 32rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
border-bottom: 1rpx solid #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-title {
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.total-unread-badge {
|
||||||
|
min-width: 40rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
padding: 0 12rpx;
|
||||||
|
background-color: #ff4d4f;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-text {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #fff;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.message-list {
|
.message-list {
|
||||||
|
flex: 1;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.loading-container,
|
.loading-container,
|
||||||
|
|||||||
135
utils/global-unread-listener.js
Normal file
135
utils/global-unread-listener.js
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
import { globalTimChatManager } from './tim-chat.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全局未读消息监听管理器
|
||||||
|
* 负责监听会话列表更新和消息接收事件,实时更新 tabBar 徽章
|
||||||
|
*/
|
||||||
|
class GlobalUnreadListenerManager {
|
||||||
|
constructor() {
|
||||||
|
this.isInitialized = false;
|
||||||
|
this.originalConversationListCallback = null;
|
||||||
|
this.originalMessageReceivedCallback = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化全局未读消息监听
|
||||||
|
* 监听会话列表更新、消息接收和消息已读事件
|
||||||
|
*/
|
||||||
|
setup() {
|
||||||
|
if (this.isInitialized) {
|
||||||
|
console.warn('全局未读消息监听已初始化,跳过重复初始化');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!globalTimChatManager) {
|
||||||
|
console.warn('globalTimChatManager 未初始化');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存原始回调(在覆盖前保存)
|
||||||
|
this.originalConversationListCallback = globalTimChatManager.callbacks.onConversationListUpdated;
|
||||||
|
this.originalMessageReceivedCallback = globalTimChatManager.callbacks.onMessageReceived;
|
||||||
|
|
||||||
|
console.log('保存原始回调:', {
|
||||||
|
hasConversationListCallback: !!this.originalConversationListCallback,
|
||||||
|
hasMessageReceivedCallback: !!this.originalMessageReceivedCallback
|
||||||
|
});
|
||||||
|
|
||||||
|
// 监听会话列表更新事件(包括消息接收和已读状态变化)
|
||||||
|
globalTimChatManager.setCallback('onConversationListUpdated', (eventData) => {
|
||||||
|
console.log('onConversationListUpdated 触发,调用原始回调');
|
||||||
|
// 调用原始回调(如果存在)
|
||||||
|
if (this.originalConversationListCallback && typeof this.originalConversationListCallback === 'function') {
|
||||||
|
this.originalConversationListCallback(eventData);
|
||||||
|
}
|
||||||
|
// 更新 tabBar 徽章
|
||||||
|
this.updateTabBarBadge();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 监听消息接收事件
|
||||||
|
globalTimChatManager.setCallback('onMessageReceived', (message) => {
|
||||||
|
console.log('onMessageReceived 触发,调用原始回调');
|
||||||
|
// 调用原始回调(如果存在)
|
||||||
|
if (this.originalMessageReceivedCallback && typeof this.originalMessageReceivedCallback === 'function') {
|
||||||
|
this.originalMessageReceivedCallback(message);
|
||||||
|
}
|
||||||
|
// 更新 tabBar 徽章
|
||||||
|
this.updateTabBarBadge();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.isInitialized = true;
|
||||||
|
console.log('全局未读消息监听已设置');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新 tabBar 徽章
|
||||||
|
* 获取所有群聊会话的未读数,并更新对应的 tabBar 徽章
|
||||||
|
*/
|
||||||
|
async updateTabBarBadge() {
|
||||||
|
try {
|
||||||
|
if (!globalTimChatManager || !globalTimChatManager.tim) {
|
||||||
|
console.warn('globalTimChatManager 或 tim 未初始化');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await globalTimChatManager.tim.getConversationList();
|
||||||
|
|
||||||
|
if (!response || !response.data || !response.data.conversationList) {
|
||||||
|
console.warn('获取会话列表返回数据异常');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const totalUnreadCount = this.calculateGroupUnreadCount(response.data.conversationList);
|
||||||
|
this.setTabBarBadge(totalUnreadCount);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('更新 tabBar 徽章失败:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算群聊会话的总未读数
|
||||||
|
* @param {Array} conversationList - 会话列表
|
||||||
|
* @returns {number} 总未读数
|
||||||
|
*/
|
||||||
|
calculateGroupUnreadCount(conversationList) {
|
||||||
|
return conversationList
|
||||||
|
.filter((conv) => conv.conversationID && conv.conversationID.startsWith('GROUP'))
|
||||||
|
.reduce((sum, conv) => sum + (conv.unreadCount || 0), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置 tabBar 徽章
|
||||||
|
* @param {number} count - 未读数
|
||||||
|
* @param {number} tabIndex - tabBar 索引,默认为 1(消息页)
|
||||||
|
*/
|
||||||
|
setTabBarBadge(count, tabIndex = 1) {
|
||||||
|
if (count > 0) {
|
||||||
|
uni.setTabBarBadge({
|
||||||
|
index: tabIndex,
|
||||||
|
text: count > 99 ? '99+' : String(count)
|
||||||
|
});
|
||||||
|
console.log(`已更新 tabBar 徽章(索引 ${tabIndex}):`, count);
|
||||||
|
} else {
|
||||||
|
// uni.removeTabBarBadge({
|
||||||
|
// index: tabIndex
|
||||||
|
// });
|
||||||
|
console.log(`已移除 tabBar 徽章(索引 ${tabIndex})`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async refreshBadge() {
|
||||||
|
console.log('手动刷新 tabBar 徽章');
|
||||||
|
await this.updateTabBarBadge();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除监听(可选)
|
||||||
|
*/
|
||||||
|
destroy() {
|
||||||
|
this.isInitialized = false;
|
||||||
|
console.log('全局未读消息监听已清除');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 导出单例
|
||||||
|
export const globalUnreadListenerManager = new GlobalUnreadListenerManager();
|
||||||
@ -2740,11 +2740,14 @@ class TimChatManager {
|
|||||||
conversationID: formattedConversationID,
|
conversationID: formattedConversationID,
|
||||||
unreadCount: 0
|
unreadCount: 0
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('✗ 标记会话已读异常:', error)
|
console.error('✗ 标记会话已读异常:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 更新会话列表
|
// 更新会话列表
|
||||||
updateConversationListOnNewMessage(message) {
|
updateConversationListOnNewMessage(message) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user