no message
This commit is contained in:
parent
b98f835ab1
commit
9cdee03753
@ -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);
|
||||||
|
|||||||
@ -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) {
|
||||||
// 合并后端群组详细信息(已包含格式化和排序)
|
// 合并后端群组详细信息(已包含格式化和排序)
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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...')
|
||||||
|
try {
|
||||||
await this.waitForSDKReady(IM_CONNECTION_CONFIG.SDK_READY_TIMEOUT)
|
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
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user