diff --git a/pages/case/archive-detail.vue b/pages/case/archive-detail.vue index 628ef24..4be1445 100644 --- a/pages/case/archive-detail.vue +++ b/pages/case/archive-detail.vue @@ -119,10 +119,10 @@ /> - - @@ -262,6 +262,7 @@ const archive = ref({ creator: '', createdByDoctor: true, hasBindWechat: false, + chatGroupId: '', notes: '', groupIds: [] }); @@ -283,6 +284,17 @@ function getCorpId() { return String(d.corpId || a.corpId || team.corpId || '') || ''; } +function getCurrentTeamId() { + const team = uni.getStorageSync(CURRENT_TEAM_STORAGE_KEY) || {}; + return String(team?.teamId || team?._id || team?.id || '') || ''; +} + +function normalizeGroupId(v) { + const s = String(v || '').trim(); + if (!s) return ''; + return s.startsWith('GROUP') ? s.slice(5) : s; +} + function normalizeArchiveFromApi(raw) { const r = raw && typeof raw === 'object' ? raw : {}; const next = { @@ -302,6 +314,7 @@ function normalizeArchiveFromApi(raw) { creator: r.creator || '', notes: r.notes || r.remark || '', groupIds: Array.isArray(r.groupIds) ? r.groupIds : [], + chatGroupId: normalizeGroupId(r.chatGroupId || r.groupId || r.groupID || r.imGroupId || r.imGroupID || r.consultGroupId || ''), }; return next; } @@ -330,6 +343,23 @@ async function fetchArchive() { saveToStorage(); loadTeamMembers(); await fetchTeamGroups(true); + chatGroupId.value = normalizeGroupId(archive.value.chatGroupId || ''); + if (!chatGroupId.value) { + refreshChatRoom(); + } else { + const meta = await getChatRoomMeta(chatGroupId.value); + const ok = isChatRoomForArchive(meta, archiveId.value); + const currentTeamId = getCurrentTeamId(); + const metaTeamId = String(meta?.teamId || meta?.team?.teamId || meta?.team?._id || ''); + if (!ok || (currentTeamId && metaTeamId && metaTeamId !== currentTeamId)) { + chatGroupId.value = ''; + archive.value.chatGroupId = ''; + refreshChatRoom(); + } else { + archive.value.chatGroupId = chatGroupId.value; + } + } + saveToStorage(); // 档案信息刷新后,tabs 的位置可能变化,重新测量 nextTick(() => setTimeout(measureTabsTop, 30)); } catch (e) { @@ -473,16 +503,20 @@ onLoad((options) => { fromChat.value = options?.fromChat === 'true' || options?.fromChat === true; const cached = uni.getStorageSync(STORAGE_KEY); - if (cached && typeof cached === 'object') { + const cachedObj = cached && typeof cached === 'object' ? cached : null; + const cachedId = cachedObj ? String(cachedObj._id || cachedObj.id || '') : ''; + const canUseCached = Boolean(cachedObj && (!cachedId || !archiveId.value || cachedId === archiveId.value)); + if (canUseCached) { archive.value = { ...archive.value, ...cached, groupIds: Array.isArray(cached.groupIds) ? cached.groupIds : archive.value.groupIds }; + chatGroupId.value = normalizeGroupId(archive.value.chatGroupId || ''); } if (!archive.value.mobile) { - const mobiles = cached && Array.isArray(cached.mobiles) ? cached.mobiles : []; + const mobiles = canUseCached && cachedObj && Array.isArray(cachedObj.mobiles) ? cachedObj.mobiles : []; if (mobiles.length) archive.value.mobile = String(mobiles[0]); } @@ -512,12 +546,14 @@ onReady(() => { onShow(() => { const cached = uni.getStorageSync(STORAGE_KEY); - if (cached && typeof cached === 'object') { + const cachedId = cached && typeof cached === 'object' ? String(cached._id || cached.id || '') : ''; + if (cached && typeof cached === 'object' && (!cachedId || !archiveId.value || cachedId === archiveId.value)) { archive.value = { ...archive.value, ...cached, groupIds: Array.isArray(cached.groupIds) ? cached.groupIds : archive.value.groupIds, }; + chatGroupId.value = normalizeGroupId(archive.value.chatGroupId || ''); } setTimeout(measureTabsTop, 30); fetchArchive(); @@ -560,8 +596,10 @@ const createText = computed(() => { return ''; }); -const showBindWechat = computed(() => Boolean(archive.value.createdByDoctor && !archive.value.hasBindWechat)); -const floatingBottom = computed(() => (showBindWechat.value ? 90 : 16)); +const chatGroupId = ref(''); +const currentChatGroupId = computed(() => normalizeGroupId(chatGroupId.value || '')); +const showGoChat = computed(() => Boolean(currentChatGroupId.value)); +const floatingBottom = computed(() => (showGoChat.value ? 90 : 16)); // const contactTitle = computed(() => (archive.value.mobile ? '联系方式' : '添加联系电话')); // const notesTitle = computed(() => (archive.value.notes ? '备注' : '添加备注')); @@ -575,10 +613,140 @@ const goEdit = () => { uni.navigateTo({ url: `/pages/case/archive-edit?archiveId=${encodeURIComponent(archiveId.value || '')}` }); }; -const bindWechat = () => { - uni.showToast({ title: '关联患者微信功能待接入', icon: 'none' }); +const goChat = async () => { + let gid = normalizeGroupId(currentChatGroupId.value || ''); + if (!gid) { + await refreshChatRoom(); + gid = normalizeGroupId(currentChatGroupId.value || ''); + } + if (!gid) { + toast('暂无可进入的会话'); + return; + } + + const meta = await getChatRoomMeta(gid); + const ok = isChatRoomForArchive(meta, archiveId.value); + const currentTeamId = getCurrentTeamId(); + const metaTeamId = String(meta?.teamId || meta?.team?.teamId || meta?.team?._id || ''); + if (!ok || (currentTeamId && metaTeamId && metaTeamId !== currentTeamId)) { + chatGroupId.value = ''; + archive.value.chatGroupId = ''; + saveToStorage(); + await refreshChatRoom(); + gid = normalizeGroupId(currentChatGroupId.value || ''); + } + if (!gid) { + toast('暂无可进入的会话'); + return; + } + + const conversationID = `GROUP${gid}`; + uni.navigateTo({ + url: `/pages/message/index?conversationID=${encodeURIComponent(conversationID)}&groupID=${encodeURIComponent(gid)}&fromCase=true`, + }); }; +const isRefreshingChatRoom = ref(false); +let lastRefreshChatRoomAt = 0; + +function isChatRoomForArchive(meta, customerId) { + const cid = String(meta?.customerId || ''); + const pid = String(meta?.patientId || ''); + const id = String(customerId || ''); + if (!meta || !id) return false; + return (cid && cid === id) || (pid && pid === id); +} + +async function getChatRoomMeta(groupId) { + const gid = normalizeGroupId(groupId || ''); + if (!gid) return null; + try { + const res = await api('getGroupListByGroupId', { groupId: gid }, false); + if (!res?.success || !res?.data) return null; + return res.data; + } catch (e) { + return null; + } +} + +function parseAnyTimeMs(v) { + if (v === null || v === undefined) return 0; + if (typeof v === 'number') return v; + const s = String(v).trim(); + if (!s) return 0; + if (/^\d{10,13}$/.test(s)) return Number(s.length === 10 ? `${s}000` : s); + const d = dayjs(s); + return d.isValid() ? d.valueOf() : 0; +} + +async function refreshChatRoom() { + const customerId = String(archiveId.value || ''); + if (!customerId) return; + if (isRefreshingChatRoom.value) return; + const now = Date.now(); + if (now - lastRefreshChatRoomAt < 5000) return; + lastRefreshChatRoomAt = now; + + isRefreshingChatRoom.value = true; + try { + const corpId = getCorpId(); + const teamId = getCurrentTeamId(); + + const baseQuery = { + corpId, + customerId, + page: 1, + pageSize: 50, + }; + + const queryWithTeam = teamId ? { ...baseQuery, teamId } : baseQuery; + let detailRes = await api('getGroupList', queryWithTeam, false); + let details = Array.isArray(detailRes?.data?.list) ? detailRes.data.list : []; + + if (!details.length && teamId) { + detailRes = await api('getGroupList', baseQuery, false); + details = Array.isArray(detailRes?.data?.list) ? detailRes.data.list : []; + } + + if (!detailRes?.success || !details.length) { + chatGroupId.value = ''; + archive.value.chatGroupId = ''; + return; + } + + const currentTeamId = getCurrentTeamId(); + const detailsForCurrentTeam = currentTeamId + ? details.filter((g) => String(g?.teamId || g?.team?._id || g?.team?.teamId || '') === currentTeamId) + : []; + const candidates = detailsForCurrentTeam.length ? detailsForCurrentTeam : details; + + const statusRank = (s) => (s === 'processing' ? 3 : s === 'pending' ? 2 : 1); + candidates.sort((a, b) => { + const ra = statusRank(String(a?.orderStatus || '')); + const rb = statusRank(String(b?.orderStatus || '')); + if (rb !== ra) return rb - ra; + const ta = parseAnyTimeMs(a?.updatedAt) || parseAnyTimeMs(a?.createdAt); + const tb = parseAnyTimeMs(b?.updatedAt) || parseAnyTimeMs(b?.createdAt); + return tb - ta; + }); + + const best = candidates[0] || {}; + const gid = normalizeGroupId(best.groupId || best.groupID || best.group_id || ''); + if (gid) { + chatGroupId.value = String(gid); + archive.value.chatGroupId = chatGroupId.value; + saveToStorage(); + } else { + chatGroupId.value = ''; + archive.value.chatGroupId = ''; + } + } catch (e) { + // ignore + } finally { + isRefreshingChatRoom.value = false; + } +} + const makeCall = () => { if (archive.value.mobile) { uni.makePhoneCall({ phoneNumber: archive.value.mobile }); diff --git a/pages/home/message-home.vue b/pages/home/message-home.vue index 654726d..48566e9 100644 --- a/pages/home/message-home.vue +++ b/pages/home/message-home.vue @@ -467,11 +467,11 @@ console.log("已清空本地未读数:", conversation.name); } - // 跳转到聊天页面 - uni.navigateTo({ - url: `/pages/message/index?conversationID=${conversation.conversationID}&groupID=${conversation.groupID}`, - }); - }; + // 跳转到聊天页面 + uni.navigateTo({ + url: `/pages/message/index?conversationID=${encodeURIComponent(conversation.conversationID)}&groupID=${encodeURIComponent(conversation.groupID)}`, + }); + }; // 加载更多 const handleLoadMore = () => { @@ -693,4 +693,4 @@ font-size: 24rpx; color: #999; } - \ No newline at end of file + diff --git a/pages/message/index.vue b/pages/message/index.vue index 2dcb4b8..8fe4adf 100644 --- a/pages/message/index.vue +++ b/pages/message/index.vue @@ -358,23 +358,35 @@ function getBubbleClass(message) { return message.flow === "out" ? "user-bubble" : "doctor-bubble"; } -// 页面加载 -onLoad((options) => { - groupId.value = options.groupID || ""; - messageList.value = []; - isLoading.value = false; - if (options.conversationID) { - chatInfo.value.conversationID = options.conversationID; - timChatManager.setConversationID(options.conversationID); - console.log("设置当前会话ID:", options.conversationID); - } - if (options.userID) { - chatInfo.value.userID = options.userID; - } - - checkLoginAndInitTIM(); - updateNavigationTitle(); -}); +// 页面加载 +onLoad((options) => { + const decodeQueryValue = (v) => { + const s = typeof v === "string" ? v : String(v || ""); + if (!s) return ""; + try { + return decodeURIComponent(s); + } catch (e) { + return s; + } + }; + + const rawGroupId = decodeQueryValue(options.groupID || ""); + groupId.value = rawGroupId.startsWith("GROUP") ? rawGroupId.replace(/^GROUP/, "") : rawGroupId; + messageList.value = []; + isLoading.value = false; + if (options.conversationID) { + const cid = decodeQueryValue(options.conversationID); + chatInfo.value.conversationID = cid; + timChatManager.setConversationID(cid); + console.log("设置当前会话ID:", cid); + } + if (options.userID) { + chatInfo.value.userID = decodeQueryValue(options.userID); + } + + checkLoginAndInitTIM(); + updateNavigationTitle(); +}); // 检查登录状态并初始化IM const checkLoginAndInitTIM = async () => { diff --git a/pages/message/message.vue b/pages/message/message.vue index 6309e1a..6a0eb3f 100644 --- a/pages/message/message.vue +++ b/pages/message/message.vue @@ -467,11 +467,11 @@ console.log("已清空本地未读数:", conversation.name); } - // 跳转到聊天页面 - uni.navigateTo({ - url: `/pages/message/index?conversationID=${conversation.conversationID}&groupID=${conversation.groupID}`, - }); - }; + // 跳转到聊天页面 + uni.navigateTo({ + url: `/pages/message/index?conversationID=${encodeURIComponent(conversation.conversationID)}&groupID=${encodeURIComponent(conversation.groupID)}`, + }); + }; // 加载更多 const handleLoadMore = () => { @@ -693,4 +693,4 @@ font-size: 24rpx; color: #999; } - \ No newline at end of file +