no message

This commit is contained in:
wangdongbo 2026-02-08 15:03:47 +08:00
parent b98f835ab1
commit 9cdee03753
4 changed files with 199 additions and 35 deletions

View File

@ -526,6 +526,7 @@ async function sendFollowUp(todo) {
content: todo.sendContent, content: todo.sendContent,
}); });
} }
console.log("==============>fileList", todo.fileList);
// 2. // 2.
if (Array.isArray(todo.fileList)) { if (Array.isArray(todo.fileList)) {
@ -537,20 +538,21 @@ async function sendFollowUp(todo) {
content: file.URL, content: file.URL,
name: file.file?.name || file.name || "图片", 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({ messages.push({
type: "article", type: "article",
content: { content: {
_id: file.file?._id || file._id, _id: articleId,
title: file.file?.name || file.name || "宣教文章", title: file.file?.name || "宣教文章",
url: file.file?.url || file.URL, url: file.file?.url || file.URL,
subtitle: file.file?.subtitle || "", subtitle: file.file?.subtitle || "",
cover: file.file?.cover || "", 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({ messages.push({
type: "questionnaire", 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 ---- // ---- filter popup ----
const filterPopupRef = ref(null); const filterPopupRef = ref(null);
const state = ref(null); const state = ref(null);

View File

@ -164,9 +164,18 @@
uni.hideLoading(); uni.hideLoading();
if (!success) { if (!success) {
uni.showToast({ //
title: "IM连接失败请重试", uni.showModal({
icon: "none", title: "IM连接失败",
content: "连接失败请检查网络后重试。如果IM连接失败请重新登陆IM再连接",
confirmText: "重新登陆",
cancelText: "取消",
success: (res) => {
if (res.confirm) {
//
handleReloginIM();
}
}
}); });
return false; return false;
} }
@ -178,21 +187,100 @@
uni.hideLoading(); uni.hideLoading();
if (!reconnected) { if (!reconnected) {
//
uni.showModal({
title: "IM连接失败",
content: "连接失败请检查网络后重试。如果IM连接失败请重新登陆IM再连接",
confirmText: "重新登陆",
cancelText: "取消",
success: (res) => {
if (res.confirm) {
//
handleReloginIM();
}
}
});
return false; return false;
} }
} }
return true; 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 () => { const loadConversationList = async () => {
if (loading.value) return; if (loading.value) return;
loading.value = true; loading.value = true;
try { try {
console.log("开始加载群聊列表"); console.log("开始加载群聊列表");
if (!globalTimChatManager || !globalTimChatManager.getGroupList) {
// IM
if (!globalTimChatManager) {
throw new Error("IM管理器未初始化"); 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(); const result = await globalTimChatManager.getGroupList();
if (result && result.success && result.groupList) { if (result && result.success && result.groupList) {
// //

View File

@ -108,16 +108,30 @@ export default defineStore("accountStore", () => {
} }
async function initIMAfterLogin() { async function initIMAfterLogin() {
if (isIMInitialized.value) return true; if (isIMInitialized.value) return true;
if (!doctorInfo.value) return; if (!doctorInfo.value) {
console.error('医生信息未获取无法初始化IM');
return false;
}
try { try {
const userID = doctorInfo.value.userid; const userID = doctorInfo.value.userid;
if (!userID) await getDoctorInfo(); if (!userID) {
await initGlobalTIM(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; isIMInitialized.value = true;
return true; return true;
} catch (error) { } catch (error) {
console.error('IM初始化失败:', error); console.error('IM初始化失败:', error);
isIMInitialized.value = false;
return false; return false;
} }
} }

View File

@ -20,16 +20,16 @@ if (!TIM_CONFIG.SDKAppID || isNaN(TIM_CONFIG.SDKAppID)) {
// IM连接配置常量 // IM连接配置常量
const IM_CONNECTION_CONFIG = { const IM_CONNECTION_CONFIG = {
MAX_RECONNECT_ATTEMPTS: 10, // 最大重连次数 MAX_RECONNECT_ATTEMPTS: 15, // 增加最大重连次数到15次
RECONNECT_DELAYS: [2000, 4000, 8000, 16000, 30000], // 重连延迟(指数退避) RECONNECT_DELAYS: [1000, 2000, 4000, 8000, 16000, 30000], // 重连延迟(指数退避)
LOGIN_COOLDOWN: 5000, // 登录冷却时间 LOGIN_COOLDOWN: 3000, // 降低登录冷却时间到3秒
SDK_READY_TIMEOUT: 15000, // SDK就绪超时时间 SDK_READY_TIMEOUT: 20000, // 增加SDK就绪超时时间到20秒
LOGIN_CHECK_INTERVAL_STABLE: 60000, // 稳定状态检查间隔 LOGIN_CHECK_INTERVAL_STABLE: 60000, // 稳定状态检查间隔
LOGIN_CHECK_INTERVAL_UNSTABLE: 15000, // 不稳定状态检查间隔 LOGIN_CHECK_INTERVAL_UNSTABLE: 10000, // 降低不稳定状态检查间隔到10秒
LOGIN_CHECK_FIRST_DELAY: 30000, // 首次检查延迟 LOGIN_CHECK_FIRST_DELAY: 20000, // 降低首次检查延迟到20秒
HEARTBEAT_INTERVAL: 60000, // 心跳间隔毫秒60秒 HEARTBEAT_INTERVAL: 60000, // 心跳间隔毫秒60秒
HEARTBEAT_MAX_FAIL: 3, // 心跳最大失败次数 HEARTBEAT_MAX_FAIL: 2, // 降低心跳最大失败次数到2次
NETWORK_RECONNECT_DELAY: 2000, // 网络恢复后延迟重连 NETWORK_RECONNECT_DELAY: 1000, // 降低网络恢复后延迟重连到1秒
MESSAGE_BATCH_COUNT: 20, // 每批消息数量 MESSAGE_BATCH_COUNT: 20, // 每批消息数量
MAX_MESSAGE_REQUESTS: 50, // 最大消息请求次数 MAX_MESSAGE_REQUESTS: 50, // 最大消息请求次数
MAX_CACHE_SIZE: 1000, // 最大缓存消息数 MAX_CACHE_SIZE: 1000, // 最大缓存消息数
@ -191,7 +191,12 @@ class TimChatManager {
// 等待SDK Ready // 等待SDK Ready
console.log('等待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初始化完成 ===') console.log('=== IM初始化完成 ===')
return true return true
@ -264,7 +269,7 @@ class TimChatManager {
waitForSDKReady(timeout = IM_CONNECTION_CONFIG.SDK_READY_TIMEOUT) { waitForSDKReady(timeout = IM_CONNECTION_CONFIG.SDK_READY_TIMEOUT) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const startTime = Date.now() const startTime = Date.now()
const checkInterval = 1000 // 每秒检查一次 const checkInterval = 500 // 每500ms检查一次更快响应
let checkCount = 0 let checkCount = 0
const checkSDKReady = () => { const checkSDKReady = () => {
@ -277,8 +282,8 @@ class TimChatManager {
} else if (elapsed > timeout) { } else if (elapsed > timeout) {
const error = new Error(`等待SDK Ready超时${timeout}ms`) const error = new Error(`等待SDK Ready超时${timeout}ms`)
console.error('✗', error.message) console.error('✗', error.message)
// 超时不算致命错误,尝试继续 // 超时时拒绝而不是继续,让调用者知道出错了
resolve() reject(error)
} else { } else {
console.log(`等待SDK Ready... ${Math.floor(elapsed / 1000)}/${Math.floor(timeout / 1000)}`) console.log(`等待SDK Ready... ${Math.floor(elapsed / 1000)}/${Math.floor(timeout / 1000)}`)
setTimeout(checkSDKReady, checkInterval) setTimeout(checkSDKReady, checkInterval)
@ -838,16 +843,16 @@ class TimChatManager {
} }
if (netState === TIM.TYPES.NET_STATE_CONNECTED) { if (netState === TIM.TYPES.NET_STATE_CONNECTED) {
console.log('✓ 网络已连接,延迟检查IM状态以确保稳定') console.log('✓ 网络已连接,立即检查IM状态')
// 网络恢复后延迟再检查,避免网络还不稳定时立即重连 // 网络恢复后立即检查,不再延迟
const delay = IM_CONNECTION_CONFIG.NETWORK_RECONNECT_DELAY const delay = IM_CONNECTION_CONFIG.NETWORK_RECONNECT_DELAY
this.networkReconnectTimer = setTimeout(() => { this.networkReconnectTimer = setTimeout(() => {
if (this.tim && !this.isLoggedIn && !this.isLoggingIn) { if (this.tim && !this.isLoggedIn && !this.isLoggingIn) {
console.log('🔄 网络已稳定,开始重连') console.log('🔄 网络已恢复,开始重连')
this.ensureIMConnection() this.ensureIMConnection()
} else if (this.isLoggedIn) { } else if (this.isLoggedIn) {
console.log('✓ 网络已稳定IM连接正常') console.log('✓ 网络已恢复IM连接正常')
} }
this.networkReconnectTimer = null this.networkReconnectTimer = null
}, delay) }, delay)
@ -855,7 +860,7 @@ class TimChatManager {
// 重置重连次数(网络恢复后给更多机会) // 重置重连次数(网络恢复后给更多机会)
if (this.reconnectAttempts > 0) { if (this.reconnectAttempts > 0) {
console.log(`重置重连次数(之前: ${this.reconnectAttempts}`) console.log(`重置重连次数(之前: ${this.reconnectAttempts}`)
this.reconnectAttempts = 0 this.reconnectAttempts = Math.max(0, this.reconnectAttempts - 3) // 减少重连次数,给更多机会
} }
} else if (netState === TIM.TYPES.NET_STATE_CONNECTING) { } else if (netState === TIM.TYPES.NET_STATE_CONNECTING) {
@ -1025,8 +1030,31 @@ class TimChatManager {
// 获取群聊列表 // 获取群聊列表
getGroupList() { getGroupList() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
// 如果 TIM 实例不存在,等待初始化
if (!this.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 return
} }
@ -1034,7 +1062,7 @@ class TimChatManager {
console.log('SDK未ready等待SDK初始化...') console.log('SDK未ready等待SDK初始化...')
let waitTime = 0 let waitTime = 0
const maxWaitTime = 30000 // 最多等待30秒 const maxWaitTime = 30000 // 最多等待30秒
const checkInterval = 1000 // 每秒检查一次 const checkInterval = 500 // 每500ms检查一次
let timeoutHandle = null let timeoutHandle = null
const checkSDKReady = () => { const checkSDKReady = () => {
@ -2847,7 +2875,11 @@ const initGlobalTIM = async (userID, forceReinit = false) => {
console.log('强制重新初始化TIM登出成功') console.log('强制重新初始化TIM登出成功')
} }
await globalTimChatManager.initTIM(userID) const success = await globalTimChatManager.initTIM(userID)
if (!success) {
console.error('强制重新初始化失败')
return false
}
console.log('强制重新初始化完成') console.log('强制重新初始化完成')
return true return true
} }
@ -2857,7 +2889,11 @@ const initGlobalTIM = async (userID, forceReinit = false) => {
return true return true
} }
await globalTimChatManager.initTIM(userID) const success = await globalTimChatManager.initTIM(userID)
if (!success) {
console.error('全局IM初始化失败')
return false
}
console.log('全局IM初始化成功') console.log('全局IM初始化成功')
return true return true
} }