From 9cdee037530e80cea04a0cc21180e242ee4da6c4 Mon Sep 17 00:00:00 2001 From: wangdongbo <949818794@qq.com> Date: Sun, 8 Feb 2026 15:03:47 +0800 Subject: [PATCH] no message --- .../archive-detail/follow-up-manage-tab.vue | 38 ++++++-- pages/message/message.vue | 96 ++++++++++++++++++- store/account.js | 22 ++++- utils/tim-chat.js | 78 +++++++++++---- 4 files changed, 199 insertions(+), 35 deletions(-) diff --git a/pages/case/components/archive-detail/follow-up-manage-tab.vue b/pages/case/components/archive-detail/follow-up-manage-tab.vue index 792688a..be97c5c 100644 --- a/pages/case/components/archive-detail/follow-up-manage-tab.vue +++ b/pages/case/components/archive-detail/follow-up-manage-tab.vue @@ -526,6 +526,7 @@ async function sendFollowUp(todo) { content: todo.sendContent, }); } + console.log("==============>fileList", todo.fileList); // 2. 处理文件列表(图片、宣教文章、问卷) if (Array.isArray(todo.fileList)) { @@ -537,20 +538,21 @@ async function sendFollowUp(todo) { content: file.URL, name: file.file?.name || file.name || "图片", }); - } else if (file.type === "article" && file.file?.url) { - // 发送宣教文章 + } else if (file.file.type === "article" && file.file?.url) { + // 发送宣教文章 - 从 URL 中解析 id + const articleId = extractIdFromUrl(file.file.url); messages.push({ type: "article", content: { - _id: file.file?._id || file._id, - title: file.file?.name || file.name || "宣教文章", + _id: articleId, + title: file.file?.name || "宣教文章", url: file.file?.url || file.URL, subtitle: file.file?.subtitle || "", cover: file.file?.cover || "", - articleId: file.file?._id || file._id, + articleId: articleId, }, }); - } else if (file.type === "questionnaire" && file.file?.surveryId) { + } else if (file.file.type === "questionnaire" && file.file?.surveryId) { // 发送问卷 messages.push({ type: "questionnaire", @@ -580,6 +582,30 @@ async function sendFollowUp(todo) { } } +/** + * 从 URL 中提取 id 参数 + * @param {string} url - 完整的 URL + * @returns {string} 提取出的 id 值 + */ +function extractIdFromUrl(url) { + if (!url) return ""; + try { + // 处理格式: https://www.youcan365.com/patientDeploy/#/pages/article/index?id=267epkhd3xbklcnbf0f45gzp1769567841991&corpId=... + const urlObj = new URL(url); + const id = urlObj.searchParams.get("id"); + if (id) return id; + + // 备用方案:使用正则表达式提取 + const match = url.match(/[?&]id=([^&]+)/); + return match ? decodeURIComponent(match[1]) : ""; + } catch (error) { + console.error("解析 URL 失败:", error); + // 备用方案:使用正则表达式提取 + const match = url.match(/[?&]id=([^&]+)/); + return match ? decodeURIComponent(match[1]) : ""; + } +} + // ---- filter popup ---- const filterPopupRef = ref(null); const state = ref(null); diff --git a/pages/message/message.vue b/pages/message/message.vue index 6309e1a..7debcb6 100644 --- a/pages/message/message.vue +++ b/pages/message/message.vue @@ -164,9 +164,18 @@ uni.hideLoading(); if (!success) { - uni.showToast({ - title: "IM连接失败,请重试", - icon: "none", + // 显示重试提示 + uni.showModal({ + title: "IM连接失败", + content: "连接失败,请检查网络后重试。如果IM连接失败,请重新登陆IM再连接", + confirmText: "重新登陆", + cancelText: "取消", + success: (res) => { + if (res.confirm) { + // 重新登陆 + handleReloginIM(); + } + } }); return false; } @@ -178,21 +187,100 @@ uni.hideLoading(); if (!reconnected) { + // 显示重试提示 + uni.showModal({ + title: "IM连接失败", + content: "连接失败,请检查网络后重试。如果IM连接失败,请重新登陆IM再连接", + confirmText: "重新登陆", + cancelText: "取消", + success: (res) => { + if (res.confirm) { + // 重新登陆 + handleReloginIM(); + } + } + }); return false; } } return true; }; + // 重新登陆IM + const handleReloginIM = async () => { + try { + uni.showLoading({ + title: "重新登陆中...", + }); + + // 清理旧的IM实例 + if (globalTimChatManager) { + await globalTimChatManager.cleanupOldInstance(); + } + + // 重新初始化IM + const { initIMAfterLogin } = useAccountStore(); + const success = await initIMAfterLogin(); + uni.hideLoading(); + + if (success) { + uni.showToast({ + title: "IM连接成功", + icon: "success", + }); + // 重新加载会话列表 + await loadConversationList(); + setupConversationListener(); + } else { + uni.showToast({ + title: "IM连接失败,请检查网络", + icon: "none", + }); + } + } catch (error) { + uni.hideLoading(); + console.error("重新登陆IM失败:", error); + uni.showToast({ + title: "重新登陆失败", + icon: "none", + }); + } + }; + // 加载会话列表 const loadConversationList = async () => { if (loading.value) return; loading.value = true; try { console.log("开始加载群聊列表"); - if (!globalTimChatManager || !globalTimChatManager.getGroupList) { + + // 确保 IM 已连接 + if (!globalTimChatManager) { throw new Error("IM管理器未初始化"); } + + // 检查 TIM 实例是否存在 + if (!globalTimChatManager.tim) { + console.warn("TIM实例不存在,尝试重新初始化IM"); + const reinitialized = await initIMAfterLogin(); + if (!reinitialized) { + throw new Error("IM重新初始化失败"); + } + } + + // 检查是否已登录 + if (!globalTimChatManager.isLoggedIn) { + console.warn("IM未登录,尝试重新连接"); + const reconnected = await globalTimChatManager.ensureIMConnection(); + if (!reconnected) { + throw new Error("IM重新连接失败"); + } + } + + if (!globalTimChatManager.getGroupList) { + throw new Error("IM管理器方法不可用"); + } + const result = await globalTimChatManager.getGroupList(); if (result && result.success && result.groupList) { // 合并后端群组详细信息(已包含格式化和排序) diff --git a/store/account.js b/store/account.js index d8fd3fc..eb46acb 100644 --- a/store/account.js +++ b/store/account.js @@ -108,16 +108,30 @@ export default defineStore("accountStore", () => { } async function initIMAfterLogin() { if (isIMInitialized.value) return true; - if (!doctorInfo.value) return; + if (!doctorInfo.value) { + console.error('医生信息未获取,无法初始化IM'); + return false; + } try { - const userID = doctorInfo.value.userid; - if (!userID) await getDoctorInfo(); - await initGlobalTIM(userID); + if (!userID) { + await getDoctorInfo(); + if (!doctorInfo.value?.userid) { + throw new Error('无法获取用户ID'); + } + } + + const success = await initGlobalTIM(userID); + if (!success) { + console.error('initGlobalTIM 返回失败'); + return false; + } + isIMInitialized.value = true; return true; } catch (error) { console.error('IM初始化失败:', error); + isIMInitialized.value = false; return false; } } diff --git a/utils/tim-chat.js b/utils/tim-chat.js index 000962b..cd88a20 100644 --- a/utils/tim-chat.js +++ b/utils/tim-chat.js @@ -20,16 +20,16 @@ if (!TIM_CONFIG.SDKAppID || isNaN(TIM_CONFIG.SDKAppID)) { // IM连接配置常量 const IM_CONNECTION_CONFIG = { - MAX_RECONNECT_ATTEMPTS: 10, // 最大重连次数 - RECONNECT_DELAYS: [2000, 4000, 8000, 16000, 30000], // 重连延迟(指数退避) - LOGIN_COOLDOWN: 5000, // 登录冷却时间 - SDK_READY_TIMEOUT: 15000, // SDK就绪超时时间 + MAX_RECONNECT_ATTEMPTS: 15, // 增加最大重连次数到15次 + RECONNECT_DELAYS: [1000, 2000, 4000, 8000, 16000, 30000], // 重连延迟(指数退避) + LOGIN_COOLDOWN: 3000, // 降低登录冷却时间到3秒 + SDK_READY_TIMEOUT: 20000, // 增加SDK就绪超时时间到20秒 LOGIN_CHECK_INTERVAL_STABLE: 60000, // 稳定状态检查间隔 - LOGIN_CHECK_INTERVAL_UNSTABLE: 15000, // 不稳定状态检查间隔 - LOGIN_CHECK_FIRST_DELAY: 30000, // 首次检查延迟 + LOGIN_CHECK_INTERVAL_UNSTABLE: 10000, // 降低不稳定状态检查间隔到10秒 + LOGIN_CHECK_FIRST_DELAY: 20000, // 降低首次检查延迟到20秒 HEARTBEAT_INTERVAL: 60000, // 心跳间隔(毫秒)60秒 - HEARTBEAT_MAX_FAIL: 3, // 心跳最大失败次数 - NETWORK_RECONNECT_DELAY: 2000, // 网络恢复后延迟重连 + HEARTBEAT_MAX_FAIL: 2, // 降低心跳最大失败次数到2次 + NETWORK_RECONNECT_DELAY: 1000, // 降低网络恢复后延迟重连到1秒 MESSAGE_BATCH_COUNT: 20, // 每批消息数量 MAX_MESSAGE_REQUESTS: 50, // 最大消息请求次数 MAX_CACHE_SIZE: 1000, // 最大缓存消息数 @@ -191,7 +191,12 @@ class TimChatManager { // 等待SDK Ready console.log('等待SDK Ready...') - await this.waitForSDKReady(IM_CONNECTION_CONFIG.SDK_READY_TIMEOUT) + try { + await this.waitForSDKReady(IM_CONNECTION_CONFIG.SDK_READY_TIMEOUT) + } catch (timeoutError) { + // SDK Ready 超时,但不一定是致命错误,继续进行 + console.warn('SDK Ready 超时,但继续进行:', timeoutError.message) + } console.log('=== IM初始化完成 ===') return true @@ -264,7 +269,7 @@ class TimChatManager { waitForSDKReady(timeout = IM_CONNECTION_CONFIG.SDK_READY_TIMEOUT) { return new Promise((resolve, reject) => { const startTime = Date.now() - const checkInterval = 1000 // 每秒检查一次 + const checkInterval = 500 // 每500ms检查一次,更快响应 let checkCount = 0 const checkSDKReady = () => { @@ -277,8 +282,8 @@ class TimChatManager { } else if (elapsed > timeout) { const error = new Error(`等待SDK Ready超时(${timeout}ms)`) console.error('✗', error.message) - // 超时不算致命错误,尝试继续 - resolve() + // 超时时拒绝而不是继续,让调用者知道出错了 + reject(error) } else { console.log(`等待SDK Ready... ${Math.floor(elapsed / 1000)}/${Math.floor(timeout / 1000)}秒`) setTimeout(checkSDKReady, checkInterval) @@ -838,16 +843,16 @@ class TimChatManager { } if (netState === TIM.TYPES.NET_STATE_CONNECTED) { - console.log('✓ 网络已连接,延迟检查IM状态以确保稳定') + console.log('✓ 网络已连接,立即检查IM状态') - // 网络恢复后延迟再检查,避免网络还不稳定时立即重连 + // 网络恢复后立即检查,不再延迟 const delay = IM_CONNECTION_CONFIG.NETWORK_RECONNECT_DELAY this.networkReconnectTimer = setTimeout(() => { if (this.tim && !this.isLoggedIn && !this.isLoggingIn) { - console.log('🔄 网络已稳定,开始重连') + console.log('🔄 网络已恢复,开始重连') this.ensureIMConnection() } else if (this.isLoggedIn) { - console.log('✓ 网络已稳定,IM连接正常') + console.log('✓ 网络已恢复,IM连接正常') } this.networkReconnectTimer = null }, delay) @@ -855,7 +860,7 @@ class TimChatManager { // 重置重连次数(网络恢复后给更多机会) if (this.reconnectAttempts > 0) { console.log(`重置重连次数(之前: ${this.reconnectAttempts})`) - this.reconnectAttempts = 0 + this.reconnectAttempts = Math.max(0, this.reconnectAttempts - 3) // 减少重连次数,给更多机会 } } else if (netState === TIM.TYPES.NET_STATE_CONNECTING) { @@ -1025,8 +1030,31 @@ class TimChatManager { // 获取群聊列表 getGroupList() { return new Promise((resolve, reject) => { + // 如果 TIM 实例不存在,等待初始化 if (!this.tim) { - reject(new Error('TIM实例不存在')) + console.log('TIM实例不存在,等待初始化...') + let waitTime = 0 + const maxWaitTime = 30000 // 最多等待30秒 + const checkInterval = 500 // 每500ms检查一次 + let timeoutHandle = null + + const checkTIMReady = () => { + if (this.tim && this.isLoggedIn) { + console.log('TIM实例已就绪,开始获取群聊列表') + if (timeoutHandle) clearTimeout(timeoutHandle) + this.getGroupListInternal().then(resolve).catch(reject) + } else if (waitTime >= maxWaitTime) { + console.error('等待TIM实例就绪超时') + if (timeoutHandle) clearTimeout(timeoutHandle) + reject(new Error('IM连接失败,请检查网络连接或重新登陆')) + } else { + waitTime += checkInterval + console.log(`等待TIM实例就绪... (${Math.floor(waitTime / 1000)}/${Math.floor(maxWaitTime / 1000)}秒)`) + timeoutHandle = setTimeout(checkTIMReady, checkInterval) + } + } + + checkTIMReady() return } @@ -1034,7 +1062,7 @@ class TimChatManager { console.log('SDK未ready,等待SDK初始化...') let waitTime = 0 const maxWaitTime = 30000 // 最多等待30秒 - const checkInterval = 1000 // 每秒检查一次 + const checkInterval = 500 // 每500ms检查一次 let timeoutHandle = null const checkSDKReady = () => { @@ -2847,7 +2875,11 @@ const initGlobalTIM = async (userID, forceReinit = false) => { console.log('强制重新初始化:TIM登出成功') } - await globalTimChatManager.initTIM(userID) + const success = await globalTimChatManager.initTIM(userID) + if (!success) { + console.error('强制重新初始化失败') + return false + } console.log('强制重新初始化完成') return true } @@ -2857,7 +2889,11 @@ const initGlobalTIM = async (userID, forceReinit = false) => { return true } - await globalTimChatManager.initTIM(userID) + const success = await globalTimChatManager.initTIM(userID) + if (!success) { + console.error('全局IM初始化失败') + return false + } console.log('全局IM初始化成功') return true }