diff --git a/App.vue b/App.vue index ee4b590..ed352ff 100644 --- a/App.vue +++ b/App.vue @@ -2,7 +2,7 @@ import dbStore from "@/store/db"; import accountStore from "@/store/account"; import { globalUnreadListenerManager } from "@/utils/global-unread-listener.js"; -import { initApiContextFromAppOptions } from "@/utils/api-base-config"; +import { initApiContextFromAppOptions, normalizeCorpIdFields } from "@/utils/api-base-config"; export default { async onLaunch(options) { @@ -35,7 +35,9 @@ export default { // 如果有完整的账户信息,也恢复 if (storedAccount) { - account.account = storedAccount; + const normalizedAccount = normalizeCorpIdFields(storedAccount); + account.account = normalizedAccount; + uni.setStorageSync("account", normalizedAccount); } // 初始化 IM diff --git a/pages/home/home.vue b/pages/home/home.vue index 55e339b..0b5f4f3 100644 --- a/pages/home/home.vue +++ b/pages/home/home.vue @@ -31,7 +31,8 @@ import { onLoad, onShow, onShareAppMessage } from "@dcloudio/uni-app"; import useAccount from "@/store/account"; import api from "@/utils/api"; import { toast } from "@/utils/widget"; -import { get, remove } from "@/utils/cache"; +import { get, remove, set } from "@/utils/cache"; +import { normalizeCorpId } from "@/utils/api-base-config"; import FullPage from "@/components/full-page.vue"; import articleList from "./article-list.vue"; @@ -57,6 +58,7 @@ const consultRef = ref(null); const archiveRef = ref(null); const corpUserIds = ref({}); const referenceCustomerIds = ref({}); +const HOME_CURRENT_TEAM_CACHE_KEY = "home-current-team-info"; const corpId = computed(() => team.value?.corpId); @@ -68,23 +70,55 @@ function handleCustomersUpdate(newCustomers) { customers.value = newCustomers; } +function getTeamIdentity(source = {}) { + return { + teamId: source.teamId || "", + corpId: normalizeCorpId(source.corpId || ""), + }; +} + +function cacheCurrentTeam(currentTeam) { + if (!currentTeam || !currentTeam.teamId) return; + set(HOME_CURRENT_TEAM_CACHE_KEY, getTeamIdentity(currentTeam)); +} + +function isSameTeam(candidate, target = {}) { + const targetTeamId = target.teamId || ""; + if (!candidate || !candidate.teamId || candidate.teamId !== targetTeamId) return false; + + const targetCorpId = normalizeCorpId(target.corpId || ""); + if (!targetCorpId) return true; + + const teamCorpId = normalizeCorpId(candidate.corpId || ""); + return targetCorpId === teamCorpId; +} + async function changeTeam({ teamId, corpId, corpName }) { loading.value = true; const res = await api("getTeamData", { teamId, corpId }); loading.value = false; if (res && res.data) { - team.value = res.data; + team.value = { + ...res.data, + corpId: normalizeCorpId(res.data.corpId || corpId), + }; team.value.corpName = corpName; + cacheCurrentTeam(team.value); } else { toast(res?.message || "获取团队信息失败"); } } -async function getMatchTeams(inviteTeamId = '') { +async function getMatchTeams(inviteTeam = null) { loading.value = true; teams.value = await getTeams(); - const matchTeamId = inviteTeamId || (team.value ? team.value.teamId : ''); - const validTeam = teams.value.find(i => i.teamId && i.teamId === matchTeamId); + const inviteIdentity = typeof inviteTeam === "string" ? { teamId: inviteTeam } : (inviteTeam || {}); + const cachedIdentity = get(HOME_CURRENT_TEAM_CACHE_KEY) || {}; + const targetIdentity = getTeamIdentity({ + teamId: inviteIdentity.teamId || team.value?.teamId || cachedIdentity.teamId, + corpId: inviteIdentity.corpId || team.value?.corpId || cachedIdentity.corpId, + }); + const validTeam = teams.value.find(i => isSameTeam(i, targetIdentity)); const firstTeam = teams.value[0] if (validTeam || firstTeam) { changeTeam(validTeam || firstTeam); @@ -115,7 +149,7 @@ onShow(async () => { referenceCustomerIds.value[inviteTeam.teamId] = inviteTeam.referenceCustomerId; } if (account.value && account.value.openid) { - getMatchTeams(inviteTeam && inviteTeam.teamId ? inviteTeam.teamId : ''); + getMatchTeams(inviteTeam && inviteTeam.teamId ? inviteTeam : null); } else { teams.value = []; } diff --git a/pages/login/redirect-page.vue b/pages/login/redirect-page.vue index e3fc409..6669a3c 100644 --- a/pages/login/redirect-page.vue +++ b/pages/login/redirect-page.vue @@ -11,6 +11,7 @@ import api from "@/utils/api"; import { set } from "@/utils/cache"; import { toast } from "@/utils/widget"; import useAccountStore from "@/store/account"; +import { normalizeCorpId, normalizeCorpIdFields } from "@/utils/api-base-config"; const env = __VITE_ENV__; const appid = env.MP_WX_APP_ID; @@ -49,17 +50,18 @@ function parseInviteOptions(options = {}) { return acc; }, {}); return { - ...options, - ...data, + ...normalizeCorpIdFields(options), + ...normalizeCorpIdFields(data), }; } async function syncExternalUserRelation({ corpId, externalUserId, corpUserId }) { + const normalizedCorpId = normalizeCorpId(corpId); const currentAccount = account.value || {}; - if (!(corpId && externalUserId && currentAccount.openid)) return; + if (!(normalizedCorpId && externalUserId && currentAccount.openid)) return; try { const res = await api('syncWxappExternalUserRelation', { - corpId, + corpId: normalizedCorpId, externalUserId, unionid: currentAccount.unionid || '', openid: currentAccount.openid, @@ -74,14 +76,19 @@ async function syncExternalUserRelation({ corpId, externalUserId, corpUserId }) } async function changeTeam({ teamId, corpId, corpUserId, externalUserId, qrid, referenceCustomerId }) { + const normalizedCorpId = normalizeCorpId(corpId); loading.value = true; - const res = await api("getTeamData", { teamId, corpId, withCorpName: true }); + const res = await api("getTeamData", { teamId, corpId: normalizedCorpId, withCorpName: true }); loading.value = false; if (res && res.data) { - team.value = res.data; + team.value = normalizeCorpIdFields({ + ...res.data, + corpId: res.data.corpId || normalizedCorpId, + }); team.value.corpName = res.data.corpName; set('home-invite-team-info', { teamId: team.value.teamId, + corpId: team.value.corpId, corpUserId: corpUserId || '', externalUserId: externalUserId || '', qrid, diff --git a/pages/message/message.vue b/pages/message/message.vue index 1b569ce..571b47d 100644 --- a/pages/message/message.vue +++ b/pages/message/message.vue @@ -70,6 +70,8 @@ import useAccountStore from "@/store/account.js"; import { globalTimChatManager } from "@/utils/tim-chat.js"; import { mergeConversationWithGroupDetails } from "@/utils/conversation-merger.js"; import { globalUnreadListenerManager } from "@/utils/global-unread-listener.js"; +import { get } from "@/utils/cache"; +import { normalizeCorpId } from "@/utils/api-base-config"; import useGroupAvatars from "./hooks/use-group-avatars.js"; import GroupAvatar from "@/components/group-avatar.vue"; import { @@ -94,6 +96,7 @@ const loadingMore = ref(false); const hasMore = ref(false); const refreshing = ref(false); const showSubscribeEntry = ref(false); +const HOME_CURRENT_TEAM_CACHE_KEY = "home-current-team-info"; // 群聊头像管理 const { loadGroupAvatars, getAvatarList } = useGroupAvatars(); @@ -510,11 +513,23 @@ const cleanMessageText = (text) => { return text.replace(/[\r\n]+/g, " ").trim(); }; +function getCurrentTeamCorpId() { + const currentTeam = get(HOME_CURRENT_TEAM_CACHE_KEY) || {}; + const currentCorpId = normalizeCorpId(currentTeam.corpId || ""); + const hasCurrentCorpId = currentCorpId && teams.value.some((item) => { + return normalizeCorpId(item?.corpId || "") === currentCorpId; + }); + if (hasCurrentCorpId) return currentCorpId; + + const firstTeam = teams.value.find((item) => item?.corpId); + return normalizeCorpId(firstTeam?.corpId || ""); +} + const handleSubscribeReminder = async () => { await requestConversationSubscribeMessage({ role: SUBSCRIBE_MESSAGE_ROLE.PATIENT, scene: SUBSCRIBE_MESSAGE_SCENE.LIST, - corpId: teams.value.find((item) => item?.corpId)?.corpId || "", + corpId: getCurrentTeamCorpId(), userId: openid.value || account.value?.openid || "", openid: openid.value || account.value?.openid || "", unionid: account.value?.unionid || "", @@ -525,7 +540,7 @@ const handleSubscribeReminder = async () => { }; const loadSubscribeEntryState = async () => { - const currentCorpId = teams.value.find((item) => item?.corpId)?.corpId || ""; + const currentCorpId = getCurrentTeamCorpId(); showSubscribeEntry.value = await checkConversationSubscribeEntryVisible( currentCorpId, true diff --git a/store/account.js b/store/account.js index a6cbd19..08be0f4 100644 --- a/store/account.js +++ b/store/account.js @@ -4,6 +4,7 @@ import api from '@/utils/api'; import { toast } from '@/utils/widget'; import { initGlobalTIM, globalTimChatManager } from "@/utils/tim-chat.js"; import { globalUnreadListenerManager } from "@/utils/global-unread-listener.js"; +import { normalizeCorpId, normalizeCorpIdFields } from "@/utils/api-base-config"; const env = __VITE_ENV__; export default defineStore("accountStore", () => { @@ -43,15 +44,16 @@ export default defineStore("accountStore", () => { }); loading.value = false if (res.success && res.data) { - account.value = res.data; - openid.value = res.data.openid; + const normalizedAccount = normalizeCorpIdFields(res.data); + account.value = normalizedAccount; + openid.value = normalizedAccount.openid; // 保存账户信息和 openId 到本地存储 - uni.setStorageSync('account', res.data); - uni.setStorageSync('openid', res.data.openid); + uni.setStorageSync('account', normalizedAccount); + uni.setStorageSync('openid', normalizedAccount.openid); // initIMAfterLogin(openid.value) - return res.data + return normalizedAccount } } toast('登录失败,请重新登录'); @@ -134,7 +136,7 @@ export default defineStore("accountStore", () => { async function searchTeams() { const res = await api('getWxappRelateTeams', { openid: account.value.openid }); - teams.value = res && Array.isArray(res.data) ? res.data : []; + teams.value = res && Array.isArray(res.data) ? normalizeCorpIdFields(res.data) : []; return teams.value; } @@ -148,13 +150,14 @@ export default defineStore("accountStore", () => { } async function getExternalUserId(corpId) { + const normalizedCorpId = normalizeCorpId(corpId); const unionid = account.value?.unionid; const openid = account.value?.openid; - if (!(corpId && unionid && openid)) { + if (!(normalizedCorpId && unionid && openid)) { externalUserId.value = ''; return }; - const res = await api('getUnionidToExternalUserid', { unionid, openid, corpId }, false); + const res = await api('getUnionidToExternalUserid', { unionid, openid, corpId: normalizedCorpId }, false); const id = res && res.success && typeof res.data === 'string' && res.data.trim() ? res.data.trim() : ''; externalUserId.value = id; return id; @@ -173,4 +176,4 @@ export default defineStore("accountStore", () => { }, { immediate: true }) return { account, teams, hasImCorpId, login, initIMAfterLogin, logout, openid, isIMInitialized, externalUserId, getExternalUserId, getTeams } -}) \ No newline at end of file +}) diff --git a/utils/api-base-config.js b/utils/api-base-config.js index 18d7e80..444ecfd 100644 --- a/utils/api-base-config.js +++ b/utils/api-base-config.js @@ -23,6 +23,21 @@ export function normalizeCorpId(corpId) { return CORP_ID_ALIAS_MAP[normalizedCorpId] || normalizedCorpId; } +export function normalizeCorpIdFields(value) { + if (Array.isArray(value)) { + return value.map((item) => normalizeCorpIdFields(item)); + } + if (!value || typeof value !== "object") { + return value; + } + return Object.keys(value).reduce((acc, key) => { + acc[key] = key === "corpId" + ? normalizeCorpId(value[key]) + : normalizeCorpIdFields(value[key]); + return acc; + }, {}); +} + function readCachedContext() { if (typeof uni === "undefined" || typeof uni.getStorageSync !== "function") { return null; @@ -30,10 +45,14 @@ function readCachedContext() { try { const cached = uni.getStorageSync(API_CONTEXT_CACHE_KEY); if (!cached || typeof cached !== "object" || !cached.baseUrl) return null; - return { - corpId: cached.corpId || "", + const context = { + corpId: normalizeCorpId(cached.corpId), baseUrl: normalizeBaseUrl(cached.baseUrl), }; + if (context.corpId !== (cached.corpId || "")) { + writeCachedContext(context); + } + return context; } catch (error) { return null; } @@ -45,7 +64,7 @@ function writeCachedContext(context) { } try { uni.setStorageSync(API_CONTEXT_CACHE_KEY, { - corpId: context.corpId || "", + corpId: normalizeCorpId(context.corpId), baseUrl: normalizeBaseUrl(context.baseUrl), }); } catch (error) { @@ -55,7 +74,7 @@ function writeCachedContext(context) { function createContext(corpId, baseUrl) { return { - corpId: corpId || "", + corpId: normalizeCorpId(corpId), baseUrl: normalizeBaseUrl(baseUrl), }; } diff --git a/utils/cache.js b/utils/cache.js index 9b473b0..794332e 100644 --- a/utils/cache.js +++ b/utils/cache.js @@ -1,5 +1,6 @@ -const env = __VITE_ENV__; +import { normalizeCorpIdFields } from './api-base-config' +const env = __VITE_ENV__; const PREFIX = env.MP_CACHE_PREFIX const EXPIRE_PREFIX = `${PREFIX}_expire_` @@ -43,14 +44,15 @@ function isExpired(key) { */ function set(key, value, expire = 0) { try { + const normalizedValue = normalizeCorpIdFields(value) // 序列化数据 let serializedValue - if (typeof value === 'object' && value !== null) { + if (typeof normalizedValue === 'object' && normalizedValue !== null) { // 对象和数组需要JSON序列化 - serializedValue = JSON.stringify(value) + serializedValue = JSON.stringify(normalizedValue) } else { // 基本类型直接存储 - serializedValue = value + serializedValue = normalizedValue } uni.setStorageSync(getKey(key), serializedValue) @@ -90,14 +92,22 @@ function get(key, defaultValue = null) { try { // 尝试解析JSON const parsed = JSON.parse(value) - return parsed + const normalizedValue = normalizeCorpIdFields(parsed) + if (JSON.stringify(normalizedValue) !== JSON.stringify(parsed)) { + uni.setStorageSync(getKey(key), JSON.stringify(normalizedValue)) + } + return normalizedValue } catch (e) { // 如果解析失败,说明是普通字符串,直接返回 return value } } - return value + const normalizedValue = normalizeCorpIdFields(value) + if (JSON.stringify(normalizedValue) !== JSON.stringify(value)) { + uni.setStorageSync(getKey(key), normalizedValue) + } + return normalizedValue } catch (e) { console.error('缓存获取失败:', e) return defaultValue