diff --git a/pages/case/archive-detail.vue b/pages/case/archive-detail.vue index 628ef24..e8a8a0f 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(); @@ -556,12 +592,16 @@ const createText = computed(() => { const creatorId = ['-', '—', '--'].includes(rawCreator.trim()) ? '' : rawCreator.trim(); const creatorName = creatorId ? resolveUserName(creatorId) : ''; if (time && creatorName) return `${time} ${creatorName}创建`; + if (time && !rawCreator.trim()) return `${time} 患者创建`; if (time) return `${time} 创建`; + if (!rawCreator.trim()) return '患者创建'; 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 +615,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/case/group-manage.vue b/pages/case/group-manage.vue index 5af53c5..1fefe3d 100644 --- a/pages/case/group-manage.vue +++ b/pages/case/group-manage.vue @@ -2,7 +2,7 @@ - + + +