Merge branch 'main' into dev-his-archive

This commit is contained in:
huxuejian 2026-06-25 10:00:25 +08:00
commit 9b5ab9fa9c
7 changed files with 125 additions and 35 deletions

View File

@ -2,7 +2,7 @@
import dbStore from "@/store/db"; import dbStore from "@/store/db";
import accountStore from "@/store/account"; import accountStore from "@/store/account";
import { globalUnreadListenerManager } from "@/utils/global-unread-listener.js"; 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 { export default {
async onLaunch(options) { async onLaunch(options) {
@ -35,7 +35,9 @@ export default {
// //
if (storedAccount) { if (storedAccount) {
account.account = storedAccount; const normalizedAccount = normalizeCorpIdFields(storedAccount);
account.account = normalizedAccount;
uni.setStorageSync("account", normalizedAccount);
} }
// IM // IM

View File

@ -31,7 +31,8 @@ import { onLoad, onShow, onShareAppMessage } from "@dcloudio/uni-app";
import useAccount from "@/store/account"; import useAccount from "@/store/account";
import api from "@/utils/api"; import api from "@/utils/api";
import { toast } from "@/utils/widget"; 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 FullPage from "@/components/full-page.vue";
import articleList from "./article-list.vue"; import articleList from "./article-list.vue";
@ -57,6 +58,7 @@ const consultRef = ref(null);
const archiveRef = ref(null); const archiveRef = ref(null);
const corpUserIds = ref({}); const corpUserIds = ref({});
const referenceCustomerIds = ref({}); const referenceCustomerIds = ref({});
const HOME_CURRENT_TEAM_CACHE_KEY = "home-current-team-info";
const corpId = computed(() => team.value?.corpId); const corpId = computed(() => team.value?.corpId);
@ -68,23 +70,55 @@ function handleCustomersUpdate(newCustomers) {
customers.value = 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 }) { async function changeTeam({ teamId, corpId, corpName }) {
loading.value = true; loading.value = true;
const res = await api("getTeamData", { teamId, corpId }); const res = await api("getTeamData", { teamId, corpId });
loading.value = false; loading.value = false;
if (res && res.data) { if (res && res.data) {
team.value = res.data; team.value = {
...res.data,
corpId: normalizeCorpId(res.data.corpId || corpId),
};
team.value.corpName = corpName; team.value.corpName = corpName;
cacheCurrentTeam(team.value);
} else { } else {
toast(res?.message || "获取团队信息失败"); toast(res?.message || "获取团队信息失败");
} }
} }
async function getMatchTeams(inviteTeamId = '') { async function getMatchTeams(inviteTeam = null) {
loading.value = true; loading.value = true;
teams.value = await getTeams(); teams.value = await getTeams();
const matchTeamId = inviteTeamId || (team.value ? team.value.teamId : ''); const inviteIdentity = typeof inviteTeam === "string" ? { teamId: inviteTeam } : (inviteTeam || {});
const validTeam = teams.value.find(i => i.teamId && i.teamId === matchTeamId); 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] const firstTeam = teams.value[0]
if (validTeam || firstTeam) { if (validTeam || firstTeam) {
changeTeam(validTeam || firstTeam); changeTeam(validTeam || firstTeam);
@ -115,7 +149,7 @@ onShow(async () => {
referenceCustomerIds.value[inviteTeam.teamId] = inviteTeam.referenceCustomerId; referenceCustomerIds.value[inviteTeam.teamId] = inviteTeam.referenceCustomerId;
} }
if (account.value && account.value.openid) { if (account.value && account.value.openid) {
getMatchTeams(inviteTeam && inviteTeam.teamId ? inviteTeam.teamId : ''); getMatchTeams(inviteTeam && inviteTeam.teamId ? inviteTeam : null);
} else { } else {
teams.value = []; teams.value = [];
} }

View File

@ -11,6 +11,7 @@ import api from "@/utils/api";
import { set } from "@/utils/cache"; import { set } from "@/utils/cache";
import { toast } from "@/utils/widget"; import { toast } from "@/utils/widget";
import useAccountStore from "@/store/account"; import useAccountStore from "@/store/account";
import { normalizeCorpId, normalizeCorpIdFields } from "@/utils/api-base-config";
const env = __VITE_ENV__; const env = __VITE_ENV__;
const appid = env.MP_WX_APP_ID; const appid = env.MP_WX_APP_ID;
@ -49,17 +50,18 @@ function parseInviteOptions(options = {}) {
return acc; return acc;
}, {}); }, {});
return { return {
...options, ...normalizeCorpIdFields(options),
...data, ...normalizeCorpIdFields(data),
}; };
} }
async function syncExternalUserRelation({ corpId, externalUserId, corpUserId }) { async function syncExternalUserRelation({ corpId, externalUserId, corpUserId }) {
const normalizedCorpId = normalizeCorpId(corpId);
const currentAccount = account.value || {}; const currentAccount = account.value || {};
if (!(corpId && externalUserId && currentAccount.openid)) return; if (!(normalizedCorpId && externalUserId && currentAccount.openid)) return;
try { try {
const res = await api('syncWxappExternalUserRelation', { const res = await api('syncWxappExternalUserRelation', {
corpId, corpId: normalizedCorpId,
externalUserId, externalUserId,
unionid: currentAccount.unionid || '', unionid: currentAccount.unionid || '',
openid: currentAccount.openid, openid: currentAccount.openid,
@ -74,14 +76,19 @@ async function syncExternalUserRelation({ corpId, externalUserId, corpUserId })
} }
async function changeTeam({ teamId, corpId, corpUserId, externalUserId, qrid, referenceCustomerId }) { async function changeTeam({ teamId, corpId, corpUserId, externalUserId, qrid, referenceCustomerId }) {
const normalizedCorpId = normalizeCorpId(corpId);
loading.value = true; 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; loading.value = false;
if (res && res.data) { if (res && res.data) {
team.value = res.data; team.value = normalizeCorpIdFields({
...res.data,
corpId: res.data.corpId || normalizedCorpId,
});
team.value.corpName = res.data.corpName; team.value.corpName = res.data.corpName;
set('home-invite-team-info', { set('home-invite-team-info', {
teamId: team.value.teamId, teamId: team.value.teamId,
corpId: team.value.corpId,
corpUserId: corpUserId || '', corpUserId: corpUserId || '',
externalUserId: externalUserId || '', externalUserId: externalUserId || '',
qrid, qrid,

View File

@ -70,6 +70,8 @@ import useAccountStore from "@/store/account.js";
import { globalTimChatManager } from "@/utils/tim-chat.js"; import { globalTimChatManager } from "@/utils/tim-chat.js";
import { mergeConversationWithGroupDetails } from "@/utils/conversation-merger.js"; import { mergeConversationWithGroupDetails } from "@/utils/conversation-merger.js";
import { globalUnreadListenerManager } from "@/utils/global-unread-listener.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 useGroupAvatars from "./hooks/use-group-avatars.js";
import GroupAvatar from "@/components/group-avatar.vue"; import GroupAvatar from "@/components/group-avatar.vue";
import { import {
@ -94,6 +96,7 @@ const loadingMore = ref(false);
const hasMore = ref(false); const hasMore = ref(false);
const refreshing = ref(false); const refreshing = ref(false);
const showSubscribeEntry = ref(false); const showSubscribeEntry = ref(false);
const HOME_CURRENT_TEAM_CACHE_KEY = "home-current-team-info";
// //
const { loadGroupAvatars, getAvatarList } = useGroupAvatars(); const { loadGroupAvatars, getAvatarList } = useGroupAvatars();
@ -510,11 +513,23 @@ const cleanMessageText = (text) => {
return text.replace(/[\r\n]+/g, " ").trim(); 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 () => { const handleSubscribeReminder = async () => {
await requestConversationSubscribeMessage({ await requestConversationSubscribeMessage({
role: SUBSCRIBE_MESSAGE_ROLE.PATIENT, role: SUBSCRIBE_MESSAGE_ROLE.PATIENT,
scene: SUBSCRIBE_MESSAGE_SCENE.LIST, scene: SUBSCRIBE_MESSAGE_SCENE.LIST,
corpId: teams.value.find((item) => item?.corpId)?.corpId || "", corpId: getCurrentTeamCorpId(),
userId: openid.value || account.value?.openid || "", userId: openid.value || account.value?.openid || "",
openid: openid.value || account.value?.openid || "", openid: openid.value || account.value?.openid || "",
unionid: account.value?.unionid || "", unionid: account.value?.unionid || "",
@ -525,7 +540,7 @@ const handleSubscribeReminder = async () => {
}; };
const loadSubscribeEntryState = async () => { const loadSubscribeEntryState = async () => {
const currentCorpId = teams.value.find((item) => item?.corpId)?.corpId || ""; const currentCorpId = getCurrentTeamCorpId();
showSubscribeEntry.value = await checkConversationSubscribeEntryVisible( showSubscribeEntry.value = await checkConversationSubscribeEntryVisible(
currentCorpId, currentCorpId,
true true

View File

@ -4,6 +4,7 @@ import api from '@/utils/api';
import { toast } from '@/utils/widget'; import { toast } from '@/utils/widget';
import { initGlobalTIM, globalTimChatManager } from "@/utils/tim-chat.js"; import { initGlobalTIM, globalTimChatManager } from "@/utils/tim-chat.js";
import { globalUnreadListenerManager } from "@/utils/global-unread-listener.js"; import { globalUnreadListenerManager } from "@/utils/global-unread-listener.js";
import { normalizeCorpId, normalizeCorpIdFields } from "@/utils/api-base-config";
const env = __VITE_ENV__; const env = __VITE_ENV__;
export default defineStore("accountStore", () => { export default defineStore("accountStore", () => {
@ -43,15 +44,16 @@ export default defineStore("accountStore", () => {
}); });
loading.value = false loading.value = false
if (res.success && res.data) { if (res.success && res.data) {
account.value = res.data; const normalizedAccount = normalizeCorpIdFields(res.data);
openid.value = res.data.openid; account.value = normalizedAccount;
openid.value = normalizedAccount.openid;
// 保存账户信息和 openId 到本地存储 // 保存账户信息和 openId 到本地存储
uni.setStorageSync('account', res.data); uni.setStorageSync('account', normalizedAccount);
uni.setStorageSync('openid', res.data.openid); uni.setStorageSync('openid', normalizedAccount.openid);
// initIMAfterLogin(openid.value) // initIMAfterLogin(openid.value)
return res.data return normalizedAccount
} }
} }
toast('登录失败,请重新登录'); toast('登录失败,请重新登录');
@ -134,7 +136,7 @@ export default defineStore("accountStore", () => {
async function searchTeams() { async function searchTeams() {
const res = await api('getWxappRelateTeams', { openid: account.value.openid }); 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; return teams.value;
} }
@ -148,13 +150,14 @@ export default defineStore("accountStore", () => {
} }
async function getExternalUserId(corpId) { async function getExternalUserId(corpId) {
const normalizedCorpId = normalizeCorpId(corpId);
const unionid = account.value?.unionid; const unionid = account.value?.unionid;
const openid = account.value?.openid; const openid = account.value?.openid;
if (!(corpId && unionid && openid)) { if (!(normalizedCorpId && unionid && openid)) {
externalUserId.value = ''; externalUserId.value = '';
return 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() : ''; const id = res && res.success && typeof res.data === 'string' && res.data.trim() ? res.data.trim() : '';
externalUserId.value = id; externalUserId.value = id;
return id; return id;
@ -173,4 +176,4 @@ export default defineStore("accountStore", () => {
}, { immediate: true }) }, { immediate: true })
return { account, teams, hasImCorpId, login, initIMAfterLogin, logout, openid, isIMInitialized, externalUserId, getExternalUserId, getTeams } return { account, teams, hasImCorpId, login, initIMAfterLogin, logout, openid, isIMInitialized, externalUserId, getExternalUserId, getTeams }
}) })

View File

@ -23,6 +23,21 @@ export function normalizeCorpId(corpId) {
return CORP_ID_ALIAS_MAP[normalizedCorpId] || normalizedCorpId; 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() { function readCachedContext() {
if (typeof uni === "undefined" || typeof uni.getStorageSync !== "function") { if (typeof uni === "undefined" || typeof uni.getStorageSync !== "function") {
return null; return null;
@ -30,10 +45,14 @@ function readCachedContext() {
try { try {
const cached = uni.getStorageSync(API_CONTEXT_CACHE_KEY); const cached = uni.getStorageSync(API_CONTEXT_CACHE_KEY);
if (!cached || typeof cached !== "object" || !cached.baseUrl) return null; if (!cached || typeof cached !== "object" || !cached.baseUrl) return null;
return { const context = {
corpId: cached.corpId || "", corpId: normalizeCorpId(cached.corpId),
baseUrl: normalizeBaseUrl(cached.baseUrl), baseUrl: normalizeBaseUrl(cached.baseUrl),
}; };
if (context.corpId !== (cached.corpId || "")) {
writeCachedContext(context);
}
return context;
} catch (error) { } catch (error) {
return null; return null;
} }
@ -45,7 +64,7 @@ function writeCachedContext(context) {
} }
try { try {
uni.setStorageSync(API_CONTEXT_CACHE_KEY, { uni.setStorageSync(API_CONTEXT_CACHE_KEY, {
corpId: context.corpId || "", corpId: normalizeCorpId(context.corpId),
baseUrl: normalizeBaseUrl(context.baseUrl), baseUrl: normalizeBaseUrl(context.baseUrl),
}); });
} catch (error) { } catch (error) {
@ -55,7 +74,7 @@ function writeCachedContext(context) {
function createContext(corpId, baseUrl) { function createContext(corpId, baseUrl) {
return { return {
corpId: corpId || "", corpId: normalizeCorpId(corpId),
baseUrl: normalizeBaseUrl(baseUrl), baseUrl: normalizeBaseUrl(baseUrl),
}; };
} }

View File

@ -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 PREFIX = env.MP_CACHE_PREFIX
const EXPIRE_PREFIX = `${PREFIX}_expire_` const EXPIRE_PREFIX = `${PREFIX}_expire_`
@ -43,14 +44,15 @@ function isExpired(key) {
*/ */
function set(key, value, expire = 0) { function set(key, value, expire = 0) {
try { try {
const normalizedValue = normalizeCorpIdFields(value)
// 序列化数据 // 序列化数据
let serializedValue let serializedValue
if (typeof value === 'object' && value !== null) { if (typeof normalizedValue === 'object' && normalizedValue !== null) {
// 对象和数组需要JSON序列化 // 对象和数组需要JSON序列化
serializedValue = JSON.stringify(value) serializedValue = JSON.stringify(normalizedValue)
} else { } else {
// 基本类型直接存储 // 基本类型直接存储
serializedValue = value serializedValue = normalizedValue
} }
uni.setStorageSync(getKey(key), serializedValue) uni.setStorageSync(getKey(key), serializedValue)
@ -90,14 +92,22 @@ function get(key, defaultValue = null) {
try { try {
// 尝试解析JSON // 尝试解析JSON
const parsed = JSON.parse(value) 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) { } catch (e) {
// 如果解析失败,说明是普通字符串,直接返回 // 如果解析失败,说明是普通字符串,直接返回
return value return value
} }
} }
return value const normalizedValue = normalizeCorpIdFields(value)
if (JSON.stringify(normalizedValue) !== JSON.stringify(value)) {
uni.setStorageSync(getKey(key), normalizedValue)
}
return normalizedValue
} catch (e) { } catch (e) {
console.error('缓存获取失败:', e) console.error('缓存获取失败:', e)
return defaultValue return defaultValue