diff --git a/pages/home/home.vue b/pages/home/home.vue index 0b5f4f3..1169ce5 100644 --- a/pages/home/home.vue +++ b/pages/home/home.vue @@ -48,6 +48,7 @@ import pageLoading from "./loading.vue"; const { account } = storeToRefs(useAccount()); const { login, getTeams } = useAccount(); const env = __VITE_ENV__; +const appid = env.MP_WX_APP_ID; const shareAppVersion = env.MP_SHARE_WX_APP_VERSION; const team = ref(null); @@ -58,6 +59,8 @@ const consultRef = ref(null); const archiveRef = ref(null); const corpUserIds = ref({}); const referenceCustomerIds = ref({}); +const pendingAction = ref(null); +const awaitingArchiveBinding = ref(false); const HOME_CURRENT_TEAM_CACHE_KEY = "home-current-team-info"; const corpId = computed(() => team.value?.corpId); @@ -84,7 +87,7 @@ function cacheCurrentTeam(currentTeam) { function isSameTeam(candidate, target = {}) { const targetTeamId = target.teamId || ""; - if (!candidate || !candidate.teamId || candidate.teamId !== targetTeamId) return false; + if (!candidate || !candidate.teamId || String(candidate.teamId) !== String(targetTeamId)) return false; const targetCorpId = normalizeCorpId(target.corpId || ""); if (!targetCorpId) return true; @@ -95,37 +98,183 @@ function isSameTeam(candidate, target = {}) { 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, - corpId: normalizeCorpId(res.data.corpId || corpId), - }; - team.value.corpName = corpName; - cacheCurrentTeam(team.value); - } else { + try { + const res = await api("getTeamData", { teamId, corpId, withCorpName: true }); + if (res && res.data) { + team.value = { + ...res.data, + corpId: normalizeCorpId(res.data.corpId || corpId), + }; + team.value.corpName = corpName || res.data.corpName || res.data.corp_name || ""; + cacheCurrentTeam(team.value); + return team.value; + } toast(res?.message || "获取团队信息失败"); + return null; + } finally { + loading.value = false; } } +function parsePendingAction(options = {}) { + const type = options.type || ""; + if (type === "experienceCoupon" && options.issueId && options.corpId) { + return { + type, + corpId: normalizeCorpId(options.corpId), + teamId: options.teamId || "", + issueId: options.issueId, + memberId: options.memberId || options.customerId || "", + couponId: options.couponId || "", + unionid: options.unionid || "", + externalUserId: options.externalUserId || "", + }; + } + if (type === "appointmentRegistration" && options.customerId && options.corpId) { + return { + type, + corpId: normalizeCorpId(options.corpId), + teamId: options.teamId || "", + customerId: options.customerId, + name: options.name || "", + corpName: options.corpName || "", + appointmentId: options.appointmentId || "", + month: options.month || "", + externalUserId: options.externalUserId || "", + corpUserId: options.corpUserId || "", + }; + } + return null; +} + +function buildActionUrl(action) { + const params = Object.entries(action) + .filter(([key, value]) => key !== "type" && value) + .map(([key, value]) => `${key}=${encodeURIComponent(value)}`) + .join("&"); + const page = action.type === "experienceCoupon" + ? "/pages/experience-coupon/claim" + : "/pages/record/appointment-record"; + return `${page}?${params}`; +} + +function buildArchiveBindUrl(action) { + const customerId = action.memberId || action.customerId; + return [ + `/pages/archive/edit-archive?corpId=${encodeURIComponent(action.corpId)}`, + `teamId=${encodeURIComponent(team.value?.teamId || action.teamId)}`, + `bindCustomerId=${encodeURIComponent(customerId)}`, + `source=${encodeURIComponent(action.type)}`, + ].join("&"); +} + +async function syncPendingExternalUser(action) { + if (!action?.externalUserId || !account.value?.openid || !action.corpId) return; + try { + await api("syncWxappExternalUserRelation", { + corpId: action.corpId, + externalUserId: action.externalUserId, + unionid: action.unionid || account.value.unionid || "", + openid: account.value.openid, + corpUserId: action.corpUserId || "", + }, false); + } catch (error) { + console.warn("同步外部联系人关系失败", error); + } +} + +async function continuePendingAction() { + const action = pendingAction.value; + if (!action || !account.value?.openid || !team.value?.teamId) return; + + if (action.teamId && String(action.teamId) !== String(team.value.teamId)) { + toast("未找到目标服务团队"); + pendingAction.value = null; + return; + } + + await syncPendingExternalUser(action); + + const customerId = action.memberId || action.customerId; + const customerRes = await api( + "getCustomerByCustomerId", + { corpId: action.corpId, customerId }, + false + ); + const customer = customerRes?.data || null; + if (!customer) { + toast(customerRes?.message || "目标档案不存在"); + pendingAction.value = null; + return; + } + + const archiveBound = String(customer.miniAppId || "") === String(account.value.openid); + if (!archiveBound) { + if (awaitingArchiveBinding.value) { + awaitingArchiveBinding.value = false; + pendingAction.value = null; + return; + } + awaitingArchiveBinding.value = true; + uni.navigateTo({ url: buildArchiveBindUrl(action) }); + return; + } + + pendingAction.value = null; + awaitingArchiveBinding.value = false; + uni.navigateTo({ url: buildActionUrl(action) }); +} + async function getMatchTeams(inviteTeam = null) { loading.value = true; - teams.value = await getTeams(); - 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); - } else { + try { + teams.value = await getTeams(); + 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, + }); + let validTeam = teams.value.find(i => isSameTeam(i, targetIdentity)); + + if (pendingAction.value && targetIdentity.teamId && account.value?.openid) { + if (!validTeam) { + const bindRes = await api("bindWxappWithTeam", { + appid, + corpId: targetIdentity.corpId, + teamId: targetIdentity.teamId, + openid: account.value.openid, + }); + if (!bindRes?.success) { + toast(bindRes?.message || "关联医生团队失败"); + team.value = null; + return null; + } + teams.value = await getTeams(); + validTeam = teams.value.find(i => isSameTeam(i, targetIdentity)); + } + + // 链接中的团队是本次动作的作用域,即使用户已绑定多个团队,也必须切换到该团队。 + const targetTeam = await changeTeam({ + ...targetIdentity, + corpName: validTeam?.corpName || "", + }); + if (targetTeam) { + teams.value = teams.value.length ? teams.value : [targetTeam]; + return targetTeam; + } + return null; + } + + const firstTeam = teams.value[0]; + if (validTeam || firstTeam) { + return await changeTeam(validTeam || firstTeam); + } team.value = null; + return null; + } finally { + loading.value = false; } - loading.value = false; } // useLoad((opts) => { @@ -134,8 +283,8 @@ async function getMatchTeams(inviteTeam = null) { // } // }); -onLoad(() => { - if (!account.value) login(); +onLoad((options = {}) => { + pendingAction.value = parsePendingAction(options); }) onShow(async () => { @@ -149,7 +298,11 @@ onShow(async () => { referenceCustomerIds.value[inviteTeam.teamId] = inviteTeam.referenceCustomerId; } if (account.value && account.value.openid) { - getMatchTeams(inviteTeam && inviteTeam.teamId ? inviteTeam : null); + const targetTeam = pendingAction.value?.teamId + ? { teamId: pendingAction.value.teamId, corpId: pendingAction.value.corpId } + : null; + await getMatchTeams(targetTeam || (inviteTeam && inviteTeam.teamId ? inviteTeam : null)); + await continuePendingAction(); } else { teams.value = []; } @@ -161,7 +314,7 @@ onShow(async () => { } }); -onShareAppMessage((res) => { +onShareAppMessage(() => { if (team.value && team.value.supportPatientForward === 'YES') { const customer = customers.value[0]; const referenceCustomerId = customer ? customer._id : ''; @@ -173,9 +326,9 @@ onShareAppMessage((res) => { } }) -watch(account, (n, o) => { +watch(account, async (n, o) => { if (n && !o) { - getMatchTeams(); + if (!pendingAction.value) await getMatchTeams(); } else if (!n && o) { teams.value = []; }