no message
This commit is contained in:
parent
0dfb05fe97
commit
00478235e7
@ -769,6 +769,13 @@ 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) {
|
||||||
|
// 页面从后台返回时,重新加载消息列表
|
||||||
|
console.log("页面从后台返回,重新加载消息列表");
|
||||||
|
messageList.value = [];
|
||||||
|
isCompleted.value = false;
|
||||||
|
lastFirstMessageId.value = "";
|
||||||
|
loadMessageList();
|
||||||
}
|
}
|
||||||
|
|
||||||
startIMMonitoring(30000);
|
startIMMonitoring(30000);
|
||||||
|
|||||||
@ -67,10 +67,7 @@
|
|||||||
<text class="empty-text">医生信息未获取,请稍后重试</text>
|
<text class="empty-text">医生信息未获取,请稍后重试</text>
|
||||||
</view>
|
</view>
|
||||||
<view
|
<view
|
||||||
v-else-if="
|
v-else-if="!loading && filteredConversationList.length === 0"
|
||||||
!loading &&
|
|
||||||
filteredConversationList.length === 0
|
|
||||||
"
|
|
||||||
class="empty-container"
|
class="empty-container"
|
||||||
>
|
>
|
||||||
<image class="empty-image" src="/static/empty.svg" mode="aspectFit" />
|
<image class="empty-image" src="/static/empty.svg" mode="aspectFit" />
|
||||||
@ -165,12 +162,78 @@ const handleAddPatient = withInfo(() => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 立即更新未读徽章
|
||||||
|
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);
|
||||||
|
|
||||||
|
// 更新 tabBar 徽章 - 添加错误处理,防止在非TabBar页面调用时出错
|
||||||
|
try {
|
||||||
|
if (totalUnreadCount > 0) {
|
||||||
|
uni.setTabBarBadge({
|
||||||
|
index: 1,
|
||||||
|
text: totalUnreadCount > 99 ? "99+" : String(totalUnreadCount),
|
||||||
|
});
|
||||||
|
console.log("已更新 tabBar 徽章:", totalUnreadCount);
|
||||||
|
} else {
|
||||||
|
uni.removeTabBarBadge({
|
||||||
|
index: 1,
|
||||||
|
});
|
||||||
|
console.log("已移除 tabBar 徽章");
|
||||||
|
}
|
||||||
|
} catch (badgeError) {
|
||||||
|
// 在非TabBar页面上调用时会出错,这是正常的,不需要处理
|
||||||
|
if (badgeError.errMsg && badgeError.errMsg.includes("not TabBar page")) {
|
||||||
|
console.log("当前不是TabBar页面,跳过徽章更新");
|
||||||
|
} else {
|
||||||
|
console.error("更新TabBar徽章失败:", badgeError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("更新未读徽章失败:", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 初始化IM
|
// 初始化IM
|
||||||
const initIM = async () => {
|
const initIM = async () => {
|
||||||
if (!isIMInitialized.value) {
|
// 关键修复:不仅检查 isIMInitialized,还要检查实际连接状态
|
||||||
|
const needsInit =
|
||||||
|
!isIMInitialized.value ||
|
||||||
|
!globalTimChatManager ||
|
||||||
|
!globalTimChatManager.isLoggedIn;
|
||||||
|
|
||||||
|
if (needsInit) {
|
||||||
uni.showLoading({
|
uni.showLoading({
|
||||||
title: "连接中...",
|
title: "连接中...",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 如果已初始化但连接断开,先清理旧实例
|
||||||
|
if (
|
||||||
|
isIMInitialized.value &&
|
||||||
|
globalTimChatManager &&
|
||||||
|
!globalTimChatManager.isLoggedIn
|
||||||
|
) {
|
||||||
|
console.log("IM已初始化但连接已断开,清理旧实例后重新初始化");
|
||||||
|
await globalTimChatManager.cleanupOldInstance();
|
||||||
|
}
|
||||||
|
|
||||||
const success = await initIMAfterLogin();
|
const success = await initIMAfterLogin();
|
||||||
uni.hideLoading();
|
uni.hideLoading();
|
||||||
|
|
||||||
@ -191,30 +254,6 @@ const initIM = async () => {
|
|||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (globalTimChatManager && !globalTimChatManager.isLoggedIn) {
|
|
||||||
uni.showLoading({
|
|
||||||
title: "重连中...",
|
|
||||||
});
|
|
||||||
const reconnected = await globalTimChatManager.ensureIMConnection();
|
|
||||||
uni.hideLoading();
|
|
||||||
|
|
||||||
if (!reconnected) {
|
|
||||||
// 显示重试提示
|
|
||||||
uni.showModal({
|
|
||||||
title: "IM连接失败",
|
|
||||||
content:
|
|
||||||
"连接失败,请检查网络后重试。如果IM连接失败,请重新登陆IM再连接",
|
|
||||||
confirmText: "重新登陆",
|
|
||||||
cancelText: "取消",
|
|
||||||
success: (res) => {
|
|
||||||
if (res.confirm) {
|
|
||||||
// 重新登陆
|
|
||||||
handleReloginIM();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
@ -281,7 +320,7 @@ const loadConversationList = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查是否已登录
|
// 检查是否已登录 - 这是关键检查
|
||||||
if (!globalTimChatManager.isLoggedIn) {
|
if (!globalTimChatManager.isLoggedIn) {
|
||||||
console.warn("IM未登录,尝试重新连接");
|
console.warn("IM未登录,尝试重新连接");
|
||||||
const reconnected = await globalTimChatManager.ensureIMConnection();
|
const reconnected = await globalTimChatManager.ensureIMConnection();
|
||||||
@ -294,7 +333,19 @@ const loadConversationList = async () => {
|
|||||||
throw new Error("IM管理器方法不可用");
|
throw new Error("IM管理器方法不可用");
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await globalTimChatManager.getGroupList();
|
// 添加超时控制,防止永久等待
|
||||||
|
const timeoutPromise = new Promise((_, reject) => {
|
||||||
|
setTimeout(
|
||||||
|
() => reject(new Error("加载会话列表超时,请检查网络连接")),
|
||||||
|
35000
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await Promise.race([
|
||||||
|
globalTimChatManager.getGroupList(),
|
||||||
|
timeoutPromise,
|
||||||
|
]);
|
||||||
|
|
||||||
if (result && result.success && result.groupList) {
|
if (result && result.success && result.groupList) {
|
||||||
// 合并后端群组详细信息(已包含格式化和排序)
|
// 合并后端群组详细信息(已包含格式化和排序)
|
||||||
conversationList.value = await mergeConversationWithGroupDetails(
|
conversationList.value = await mergeConversationWithGroupDetails(
|
||||||
@ -317,17 +368,26 @@ const loadConversationList = async () => {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
console.error("加载群聊列表失败:", result);
|
console.error("加载群聊列表失败:", result);
|
||||||
uni.showToast({
|
throw new Error(result?.message || "加载失败,请重试");
|
||||||
title: "加载失败,请重试",
|
|
||||||
icon: "none",
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("加载会话列表失败:", error);
|
console.error("加载会话列表失败:", error);
|
||||||
uni.showToast({
|
|
||||||
title: error.message || "加载失败,请重试",
|
// 如果是超时或连接错误,提示用户重试
|
||||||
icon: "none",
|
if (
|
||||||
});
|
error.message &&
|
||||||
|
(error.message.includes("超时") || error.message.includes("连接"))
|
||||||
|
) {
|
||||||
|
uni.showToast({
|
||||||
|
title: "网络连接不稳定,请重试",
|
||||||
|
icon: "none",
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: error.message || "加载失败,请重试",
|
||||||
|
icon: "none",
|
||||||
|
});
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
@ -605,7 +665,7 @@ onShow(async () => {
|
|||||||
// 加载团队列表
|
// 加载团队列表
|
||||||
await getTeams();
|
await getTeams();
|
||||||
|
|
||||||
// 初始化IM
|
// 初始化IM - 关键修复:确保IM连接状态正确
|
||||||
const imReady = await initIM();
|
const imReady = await initIM();
|
||||||
if (!imReady) {
|
if (!imReady) {
|
||||||
console.error("IM初始化失败");
|
console.error("IM初始化失败");
|
||||||
|
|||||||
@ -1,118 +1,141 @@
|
|||||||
<template>
|
<template>
|
||||||
<view v-if="team" class="flex flex-col justify-center h-full bg-white">
|
<view v-if="team" class="flex flex-col justify-center h-full bg-white">
|
||||||
<view>
|
<view>
|
||||||
<view class="text-dark text-lg font-semibold text-center mb-10">
|
<view class="text-dark text-lg font-semibold text-center mb-10">
|
||||||
{{ team.name }}
|
{{ team.name }}
|
||||||
</view>
|
</view>
|
||||||
<view class="mb-10 text-dark text-lg font-semibold text-center mb-10">
|
<view class="mb-10 text-dark text-lg font-semibold text-center mb-10">
|
||||||
成员邀请码
|
成员邀请码
|
||||||
</view>
|
</view>
|
||||||
<view class="flex justify-center overflow-hidden">
|
<view class="flex justify-center overflow-hidden">
|
||||||
<uqrcode canvas-id="qrcode" :value="qrcode" :options="options"></uqrcode>
|
<uqrcode canvas-id="qrcode" :value="qrcode" :options="options"></uqrcode>
|
||||||
</view>
|
</view>
|
||||||
<view class="mt-10 px-15 text-base text-dark leading-normal text-center">
|
<view class="mt-10 px-15 text-base text-dark leading-normal text-center">
|
||||||
微信扫一扫上面的二维码
|
微信扫一扫上面的二维码
|
||||||
</view>
|
</view>
|
||||||
<view class="mt-10 px-15 text-base text-dark leading-normal text-center">
|
<view class="mt-10 px-15 text-base text-dark leading-normal text-center">
|
||||||
加入我的团队,协同开展患者管理服务
|
加入我的团队,协同开展患者管理服务
|
||||||
</view>
|
</view>
|
||||||
<view class="mt-10 flex px-15 leading-normal text-center">
|
<view class="mt-10 flex px-15 leading-normal text-center">
|
||||||
<button class="mr-10 border-auto rounded py-5 text-base text-primary flex-grow" @click="saveImage('save')">
|
<button class="mr-10 border-auto rounded py-5 text-base text-primary flex-grow"
|
||||||
保存图片
|
@click="saveImage('save')">
|
||||||
</button>
|
保存图片
|
||||||
<button class="bg-primary rounded py-5 text-base text-white flex-grow" open-type="share">分享微信</button>
|
</button>
|
||||||
</view>
|
<button class="bg-primary rounded py-5 text-base text-white flex-grow" open-type="share">分享微信</button>
|
||||||
<view class="canvas-box">
|
</view>
|
||||||
<l-painter ref="painterRef" :board="poster" />
|
<view class="canvas-box">
|
||||||
</view>
|
<l-painter ref="painterRef" :board="poster" />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
</view>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, ref } from "vue";
|
import {
|
||||||
import { storeToRefs } from "pinia";
|
computed,
|
||||||
import { onLoad, onShareAppMessage } from "@dcloudio/uni-app";
|
ref
|
||||||
import useGuard from "@/hooks/useGuard.js";
|
} from "vue";
|
||||||
import useAccountStore from "@/store/account.js";
|
import {
|
||||||
import api from '@/utils/api';
|
storeToRefs
|
||||||
import { toast } from "@/utils/widget";
|
} from "pinia";
|
||||||
import { getInviteMatePoster } from './base-poster-data';
|
import {
|
||||||
|
onLoad,
|
||||||
|
onShareAppMessage
|
||||||
|
} from "@dcloudio/uni-app";
|
||||||
|
import useGuard from "@/hooks/useGuard.js";
|
||||||
|
import useAccountStore from "@/store/account.js";
|
||||||
|
import api from '@/utils/api';
|
||||||
|
import {
|
||||||
|
toast
|
||||||
|
} from "@/utils/widget";
|
||||||
|
import {
|
||||||
|
getInviteMatePoster
|
||||||
|
} from './base-poster-data';
|
||||||
|
|
||||||
const env = __VITE_ENV__;
|
const env = __VITE_ENV__;
|
||||||
const inviteQrcode = env.MP_INVITE_TEAMMATE_QRCODE;
|
const inviteQrcode = env.MP_INVITE_TEAMMATE_QRCODE;
|
||||||
|
|
||||||
const options = { margin: 10 };
|
const options = {
|
||||||
const team = ref(null);
|
margin: 10
|
||||||
const teamId = ref('');
|
};
|
||||||
const painterRef = ref()
|
const team = ref(null);
|
||||||
const poster = ref({})
|
const teamId = ref('');
|
||||||
|
const painterRef = ref()
|
||||||
|
const poster = ref({})
|
||||||
|
|
||||||
const { useLoad, useShow } = useGuard();
|
const {
|
||||||
const { account } = storeToRefs(useAccountStore());
|
useLoad,
|
||||||
|
useShow
|
||||||
|
} = useGuard();
|
||||||
|
const {
|
||||||
|
account
|
||||||
|
} = storeToRefs(useAccountStore());
|
||||||
|
|
||||||
const qrcode = computed(() => `${inviteQrcode}?type=inviteTeam&teamId=${teamId.value}`)
|
const qrcode = computed(() => `${inviteQrcode}?type=inviteTeam&teamId=${teamId.value}`)
|
||||||
|
|
||||||
async function getTeam() {
|
async function getTeam() {
|
||||||
const res = await api('getTeamData', { teamId: teamId.value, corpId: account.value.corpId });
|
const res = await api('getTeamData', {
|
||||||
if (res && res.data) {
|
teamId: teamId.value,
|
||||||
team.value = res.data;
|
corpId: account.value.corpId
|
||||||
} else {
|
});
|
||||||
toast(res?.message || '获取团队信息失败')
|
if (res && res.data) {
|
||||||
}
|
team.value = res.data;
|
||||||
}
|
} else {
|
||||||
|
toast(res?.message || '获取团队信息失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function saveImage(action = 'save') {
|
async function saveImage(action = 'save') {
|
||||||
const data = getInviteMatePoster(team.value.name, qrcode.value)
|
const data = getInviteMatePoster(team.value.name, qrcode.value)
|
||||||
try {
|
try {
|
||||||
await painterRef.value.render(data);
|
await painterRef.value.render(data);
|
||||||
painterRef.value.canvasToTempFilePathSync({
|
painterRef.value.canvasToTempFilePathSync({
|
||||||
fileType: "jpg",
|
fileType: "jpg",
|
||||||
// 如果返回的是base64是无法使用 saveImageToPhotosAlbum,需要设置 pathType为url
|
// 如果返回的是base64是无法使用 saveImageToPhotosAlbum,需要设置 pathType为url
|
||||||
pathType: 'url',
|
pathType: 'url',
|
||||||
quality: 1,
|
quality: 1,
|
||||||
success: (res) => {
|
success: (res) => {
|
||||||
console.log(res.tempFilePath);
|
console.log(res.tempFilePath);
|
||||||
if (action === 'save') {
|
if (action === 'save') {
|
||||||
uni.saveImageToPhotosAlbum({
|
uni.saveImageToPhotosAlbum({
|
||||||
filePath: res.tempFilePath,
|
filePath: res.tempFilePath,
|
||||||
success: function () {
|
success: function() {
|
||||||
console.log('save success');
|
console.log('save success');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (action === 'share') {
|
} else if (action === 'share') {
|
||||||
wx.showShareImageMenu({
|
wx.showShareImageMenu({
|
||||||
path: res.tempFilePath,
|
path: res.tempFilePath,
|
||||||
needShowEntrance: false
|
needShowEntrance: false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
toast(e?.message)
|
toast(e?.message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
useLoad(options => {
|
useLoad(options => {
|
||||||
teamId.value = options.teamId;
|
teamId.value = options.teamId;
|
||||||
})
|
})
|
||||||
|
|
||||||
useShow(() => {
|
useShow(() => {
|
||||||
getTeam()
|
getTeam()
|
||||||
});
|
});
|
||||||
|
|
||||||
onShareAppMessage(() => {
|
onShareAppMessage(() => {
|
||||||
return {
|
return {
|
||||||
title: '邀请团队成员',
|
title: '邀请团队成员',
|
||||||
path: `pages/login/redirect-page?type=inviteTeam&teamId=${teamId.value}`
|
path: `pages/login/redirect-page?type=inviteTeam&teamId=${teamId.value}`
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
.canvas-box {
|
.canvas-box {
|
||||||
top: 10000rpx;
|
top: 10000rpx;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@ -1032,6 +1032,8 @@ class TimChatManager {
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
// 检查userId是否存在,不存在则不需要初始化
|
// 检查userId是否存在,不存在则不需要初始化
|
||||||
if (!this.currentUserID) {
|
if (!this.currentUserID) {
|
||||||
|
console.error('currentUserID不存在,无法获取群聊列表')
|
||||||
|
reject(new Error('用户ID不存在'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1076,12 +1078,13 @@ class TimChatManager {
|
|||||||
if (timeoutHandle) clearTimeout(timeoutHandle)
|
if (timeoutHandle) clearTimeout(timeoutHandle)
|
||||||
this.getGroupListInternal().then(resolve).catch(reject)
|
this.getGroupListInternal().then(resolve).catch(reject)
|
||||||
} else if (waitTime >= maxWaitTime) {
|
} else if (waitTime >= maxWaitTime) {
|
||||||
console.error('等待SDK就绪超时')
|
console.error('等待SDK就绪超时,当前isLoggedIn:', this.isLoggedIn)
|
||||||
if (timeoutHandle) clearTimeout(timeoutHandle)
|
if (timeoutHandle) clearTimeout(timeoutHandle)
|
||||||
|
// 超时时返回错误而不是继续等待
|
||||||
reject(new Error('SDK初始化超时,请检查网络连接'))
|
reject(new Error('SDK初始化超时,请检查网络连接'))
|
||||||
} else {
|
} else {
|
||||||
waitTime += checkInterval
|
waitTime += checkInterval
|
||||||
console.log(`等待SDK就绪... (${Math.floor(waitTime / 1000)}/${Math.floor(maxWaitTime / 1000)}秒)`)
|
console.log(`等待SDK就绪... (${Math.floor(waitTime / 1000)}/${Math.floor(maxWaitTime / 1000)}秒, isLoggedIn: ${this.isLoggedIn})`)
|
||||||
timeoutHandle = setTimeout(checkSDKReady, checkInterval)
|
timeoutHandle = setTimeout(checkSDKReady, checkInterval)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2758,6 +2761,7 @@ class TimChatManager {
|
|||||||
|
|
||||||
// 标记会话为已读
|
// 标记会话为已读
|
||||||
markConversationAsRead(conversationID) {
|
markConversationAsRead(conversationID) {
|
||||||
|
|
||||||
if (!this.tim || !this.isLoggedIn) {
|
if (!this.tim || !this.isLoggedIn) {
|
||||||
console.log('⚠️ TIM未初始化或未登录,无法标记会话已读');
|
console.log('⚠️ TIM未初始化或未登录,无法标记会话已读');
|
||||||
return;
|
return;
|
||||||
@ -2777,6 +2781,7 @@ class TimChatManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 更新会话列表
|
// 更新会话列表
|
||||||
updateConversationListOnNewMessage(message) {
|
updateConversationListOnNewMessage(message) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user