From 94a515924b22fbdc6ded825f33eef14cc3505215 Mon Sep 17 00:00:00 2001 From: zhanchao Date: Mon, 17 Aug 2026 18:34:36 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B7=B3=E8=BD=AC=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hooks/use-team-access.js | 91 +++++++++++++++++++++++++++++ pages/experience-coupon/claim.vue | 76 ++++++------------------ pages/record/appointment-record.vue | 47 +++++++-------- 3 files changed, 129 insertions(+), 85 deletions(-) create mode 100644 hooks/use-team-access.js diff --git a/hooks/use-team-access.js b/hooks/use-team-access.js new file mode 100644 index 0000000..b361ef0 --- /dev/null +++ b/hooks/use-team-access.js @@ -0,0 +1,91 @@ +import api from "@/utils/api"; +import { set } from "@/utils/cache"; +import { normalizeCorpId } from "@/utils/api-base-config"; + +function buildTeamLoginUrl(redirectUrl) { + const query = [ + "source=teamInvite", + `redirectUrl=${encodeURIComponent(redirectUrl || "")}`, + ].join("&"); + return `/pages/login/login?${query}`; +} + +export function useTeamAccess() { + async function getTeamInfo({ corpId, teamId, fallbackCorpName = "" }) { + if (!corpId || !teamId) return null; + try { + const res = await api( + "getTeamData", + { corpId, teamId, withCorpName: true }, + false + ); + const team = res?.data || null; + if (!team) return null; + return { + ...team, + corpName: team.corpName || team.corp_name || fallbackCorpName, + }; + } catch (error) { + console.warn("getTeamData failed", error); + return null; + } + } + + async function openTeamLogin({ + corpId, + teamId, + redirectUrl, + fallbackCorpName = "", + corpUserId = "", + externalUserId = "", + }) { + if (!corpId || !teamId) { + return { success: false, message: "团队信息缺失,暂无法授权" }; + } + + const team = await getTeamInfo({ corpId, teamId, fallbackCorpName }); + set("invite-team-info", { + corpId, + teamId, + corpUserId, + externalUserId, + corpName: team?.corpName || fallbackCorpName, + teamName: team?.name || team?.teamName || "", + avatars: Array.isArray(team?.memberList) + ? team.memberList.map((member) => member?.avatar || "").filter(Boolean) + : [], + }); + uni.navigateTo({ url: buildTeamLoginUrl(redirectUrl) }); + return { success: true, team }; + } + + async function ensureTeamAdded({ appid, account, getTeams, corpId, teamId }) { + if (!appid || !account?.openid || !corpId || !teamId) { + return { success: false, message: "团队信息缺失,暂无法绑定" }; + } + const teams = await getTeams(); + const linked = (teams || []).some( + (team) => + normalizeCorpId(team.corpId) === normalizeCorpId(corpId) && + String(team.teamId) === String(teamId) + ); + if (linked) return { success: true, alreadyLinked: true }; + + const res = await api( + "bindWxappWithTeam", + { appid, corpId, teamId, openid: account.openid }, + false + ); + if (!res?.success) { + return { success: false, message: res?.message || "添加团队失败" }; + } + await getTeams(); + return { success: true, alreadyLinked: false }; + } + + return { + getTeamInfo, + openTeamLogin, + ensureTeamAdded, + }; +} diff --git a/pages/experience-coupon/claim.vue b/pages/experience-coupon/claim.vue index bb24395..c699149 100644 --- a/pages/experience-coupon/claim.vue +++ b/pages/experience-coupon/claim.vue @@ -32,15 +32,16 @@ import { storeToRefs } from "pinia"; import { onLoad, onShow } from "@dcloudio/uni-app"; import useAccount from "@/store/account"; import api from "@/utils/api"; -import { set } from "@/utils/cache"; import { hideLoading, loading, toast } from "@/utils/widget"; import { normalizeCorpId } from "@/utils/api-base-config"; +import { useTeamAccess } from "@/hooks/use-team-access"; import FullPage from "@/components/full-page.vue"; const env = __VITE_ENV__; const appid = env.MP_WX_APP_ID; const { account } = storeToRefs(useAccount()); const { getTeams, login } = useAccount(); +const { openTeamLogin: openTeamInviteLogin, ensureTeamAdded: ensureJoinedTeam } = useTeamAccess(); const corpId = ref(""); const issueId = ref(""); @@ -54,7 +55,6 @@ const posterVisible = ref(false); const archiveBindPending = ref(false); const bindingTeamId = ref(""); const bindCorpName = ref(""); -const bindingTeam = ref(null); const projectNameText = computed(() => { const projects = Array.isArray(issue.value?.projectSnapshot) ? issue.value.projectSnapshot : []; @@ -133,50 +133,22 @@ function buildClaimUrl() { return `/pages/experience-coupon/claim?${params}`; } -function buildTeamLoginUrl() { - const query = [ - "source=teamInvite", - `redirectUrl=${encodeURIComponent(buildClaimUrl())}`, - ].join("&"); - return `/pages/login/login?${query}`; -} - -async function getBindingTeam() { - if (!corpId.value || !bindingTeamId.value) return null; - if (bindingTeam.value) return bindingTeam.value; - try { - const res = await api( - "getTeamData", - { corpId: corpId.value, teamId: bindingTeamId.value, withCorpName: true }, - false - ); - const data = res?.data || null; - bindingTeam.value = data; - bindCorpName.value = data?.corpName || data?.corp_name || bindCorpName.value; - return data; - } catch (e) { - console.warn("getTeamData failed", e); - return null; - } -} - async function openTeamLogin() { const customer = await getIssueCustomer(); if (!customer || !bindingTeamId.value) { tip.value = "体验券发放档案缺少所属团队,暂无法领取"; return false; } - const team = await getBindingTeam(); - set("invite-team-info", { + const result = await openTeamInviteLogin({ corpId: corpId.value, teamId: bindingTeamId.value, - corpName: bindCorpName.value || issue.value?.corpName || "", - teamName: team?.name || team?.teamName || "", - avatars: Array.isArray(team?.memberList) - ? team.memberList.map((member) => member?.avatar || "").filter(Boolean) - : [], + redirectUrl: buildClaimUrl(), + fallbackCorpName: bindCorpName.value || issue.value?.corpName || "", }); - uni.navigateTo({ url: buildTeamLoginUrl() }); + if (!result.success) { + tip.value = result.message; + return false; + } return false; } @@ -194,32 +166,20 @@ async function ensureTeamAdded() { return false; } - const teams = await getTeams(); - const linked = (teams || []).some( - (team) => - normalizeCorpId(team.corpId) === corpId.value && - String(team.teamId) === String(bindingTeamId.value) - ); - if (linked) return true; - loading("添加团队中..."); try { - const res = await api( - "bindWxappWithTeam", - { - appid, - corpId: corpId.value, - teamId: bindingTeamId.value, - openid: account.value?.openid || "", - }, - false - ); - if (!res?.success) { - tip.value = res?.message || "添加团队失败"; + const res = await ensureJoinedTeam({ + appid, + account: account.value, + getTeams, + corpId: corpId.value, + teamId: bindingTeamId.value, + }); + if (!res.success) { + tip.value = res.message; toast(tip.value); return false; } - await getTeams(); return true; } finally { hideLoading(); diff --git a/pages/record/appointment-record.vue b/pages/record/appointment-record.vue index 09ec3a6..48870b0 100644 --- a/pages/record/appointment-record.vue +++ b/pages/record/appointment-record.vue @@ -65,7 +65,7 @@ import { storeToRefs } from "pinia"; import useAccount from "@/store/account"; import api from "@/utils/api"; import { normalizeCorpId } from "@/utils/api-base-config"; -import { set } from "@/utils/cache"; +import { useTeamAccess } from "@/hooks/use-team-access"; import { hideLoading, loading as showLoading, toast } from "@/utils/widget"; import FullPage from "@/components/full-page.vue"; @@ -73,6 +73,7 @@ const env = __VITE_ENV__; const appid = env.MP_WX_APP_ID; const { account, externalUserId } = storeToRefs(useAccount()); const { getTeams, getExternalUserId, login } = useAccount(); +const { openTeamLogin: openTeamInviteLogin, ensureTeamAdded: ensureJoinedTeam } = useTeamAccess(); const corpId = ref(""); const teamId = ref(""); @@ -112,18 +113,11 @@ function buildCurrentUrl() { return `/pages/record/appointment-record?${params}`; } -function buildTeamLoginUrl() { - const query = [ - "source=teamInvite", - `redirectUrl=${encodeURIComponent(buildCurrentUrl())}`, - ].join("&"); - return `/pages/login/login?${query}`; -} - async function ensureLogin() { if (!account.value) await login(); if (!account.value) { - uni.navigateTo({ url: "/pages/login/login" }); + await ensureCustomerContext(); + await openTeamLogin(); return false; } return true; @@ -132,20 +126,23 @@ async function ensureLogin() { async function ensurePhoneAuthorized() { if (account.value?.mobile) return true; await ensureCustomerContext(); + return openTeamLogin(); +} + +async function openTeamLogin() { if (!corpId.value || !teamId.value) { toast("预约团队信息缺失,暂无法查看预约记录"); return false; } - set("invite-team-info", { + const res = await openTeamInviteLogin({ corpId: corpId.value, teamId: teamId.value, corpUserId: corpUserId.value || "", externalUserId: routeExternalUserId.value || externalUserId.value || "", - corpName: corpName.value || "", - teamName: "", - avatars: [], + fallbackCorpName: corpName.value || "", + redirectUrl: buildCurrentUrl(), }); - uni.navigateTo({ url: buildTeamLoginUrl() }); + if (!res.success) toast(res.message); return false; } @@ -166,24 +163,19 @@ async function ensureTeamAdded() { toast("预约团队信息缺失,暂无法查看预约记录"); return false; } - const teams = await getTeams(); - const linked = (teams || []).some( - (team) => normalizeCorpId(team.corpId) === corpId.value && String(team.teamId) === String(teamId.value) - ); - if (linked) return true; showLoading("添加团队中..."); try { - const res = await api("bindWxappWithTeam", { + const res = await ensureJoinedTeam({ appid, + account: account.value, + getTeams, corpId: corpId.value, teamId: teamId.value, - openid: account.value?.openid || "", - }, false); - if (!res?.success) { - toast(res?.message || "添加团队失败"); + }); + if (!res.success) { + toast(res.message); return false; } - await getTeams(); return true; } finally { hideLoading(); @@ -203,6 +195,7 @@ async function ensureArchiveBound() { } async function ensureAccessReady() { + await ensureCustomerContext(); const okLogin = await ensureLogin(); if (!okLogin) return false; const okPhone = await ensurePhoneAuthorized(); @@ -542,4 +535,4 @@ onShow(async () => { font-size: 28rpx; color: #999; } - \ No newline at end of file +