子账号登录微信授权

This commit is contained in:
2026-07-10 11:03:11 +08:00
parent f4f4f1b4aa
commit 9c5cb69730
11 changed files with 535 additions and 251 deletions
+47 -25
View File
@@ -2,14 +2,15 @@ import type { ClientRuntimeConfig, WechatLoginResult } from '@dukang/shared-type
import { isWxAuthorizeEnabled } from '@dukang/shared-types';
import { WECHAT_INAPP_REQUIRED_MSG } from '@dukang/weixin-sdk';
import { isWechatEnv, weixinSdk } from './weixin';
import { request, saveAuth } from './api';
import { request, saveWechatSession, type PartnerSessionPayload } from './api';
export type PartnerProfile = {
id: string;
name: string;
phone: string;
companyName: string;
companyName?: string;
hasWechat?: boolean;
isPrimary?: boolean;
};
export async function fetchClientConfig(): Promise<ClientRuntimeConfig> {
@@ -20,7 +21,7 @@ export async function fetchPartnerProfile(): Promise<PartnerProfile> {
return request<PartnerProfile>('PARTNER_H5', '/partner/me');
}
/** 微信内上传照片前需完成公众号授权绑定 */
/** 微信内上传照片前需完成公众号 OAuth 绑定 */
export function needsWechatAuth(
profile: PartnerProfile | null,
config?: Pick<ClientRuntimeConfig, 'wxAuthorize'> | null,
@@ -34,24 +35,30 @@ export async function checkNeedsWechatAuth(profile: PartnerProfile | null): Prom
return needsWechatAuth(profile, config);
}
/** 处理微信登录/绑定结果,返回是否已拿到 token 可进入首页 */
export function handlePartnerWechatLoginResult(result: WechatLoginResult): boolean {
if (!result.accessToken) return false;
saveAuth({ accessToken: result.accessToken });
return true;
export function sessionFromWechatLogin(result: WechatLoginResult): PartnerSessionPayload | null {
if (!result.accessToken || !result.refreshToken) return null;
const partner = result.partner;
return {
accessToken: result.accessToken,
refreshToken: result.refreshToken,
partner: partner
? {
id: String(partner.id ?? ''),
name: String(partner.name ?? ''),
phone: String(partner.phone ?? ''),
companyName: partner.companyName ? String(partner.companyName) : undefined,
isPrimary: partner.isPrimary !== false,
}
: undefined,
};
}
/** 微信登录成功后拉取并缓存合伙人资料,供一键登录页展示 */
export async function persistPartnerProfileAfterLogin(): Promise<void> {
try {
const profile = await fetchPartnerProfile();
saveAuth({
accessToken: localStorage.getItem('accessToken') ?? '',
partner: profile,
});
} catch {
/* ignore */
}
/** 处理微信登录/绑定结果,写入 7 天免登录 session */
export function handlePartnerWechatLoginResult(result: WechatLoginResult): PartnerSessionPayload | null {
const session = sessionFromWechatLogin(result);
if (!session) return null;
saveWechatSession(session);
return session;
}
export async function handlePartnerWechatCallback(): Promise<WechatLoginResult | null> {
@@ -62,12 +69,12 @@ export async function handlePartnerWechatCallback(): Promise<WechatLoginResult |
}
/**
* 微信授权登录(对齐 C 端:仅微信内置浏览器走 OAuth)。
* 返回 true = 已登录;void = 已跳转授权页等待回调。
* 微信一键登录(已绑定微信的合伙人账号免验证码)。
* 返回 session = 已登录;void = 已跳转授权页等待回调。
*/
export async function loginPartnerWithWechat(): Promise<boolean | void> {
export async function loginPartnerWithWechat(): Promise<PartnerSessionPayload | null | void> {
const config = await fetchClientConfig();
if (!isWxAuthorizeEnabled(config)) return false;
if (!isWxAuthorizeEnabled(config)) return null;
if (!isWechatEnv()) {
throw new Error(WECHAT_INAPP_REQUIRED_MSG);
}
@@ -75,6 +82,14 @@ export async function loginPartnerWithWechat(): Promise<boolean | void> {
if (result) return handlePartnerWechatLoginResult(result);
}
/** 短信登录成功后于微信内自动发起 OAuth,绑定 openId 便于后续免登 */
export async function bindPartnerWechatAfterSmsLogin(): Promise<void> {
const config = await fetchClientConfig();
if (!isWxAuthorizeEnabled(config)) return;
if (!isWechatEnv()) return;
await weixinSdk.login();
}
export async function authorizePartnerWechat(): Promise<WechatLoginResult | void> {
const config = await fetchClientConfig();
if (!isWxAuthorizeEnabled(config)) return;
@@ -84,7 +99,14 @@ export async function authorizePartnerWechat(): Promise<WechatLoginResult | void
return weixinSdk.login();
}
/** @deprecated 使用 handlePartnerWechatLoginResult */
export function savePartnerWechatAuth(result: WechatLoginResult): boolean {
/** OAuth 回跳统一处理(登录页 / 录店页等) */
export async function processPartnerWechatOAuthCallback(): Promise<PartnerSessionPayload | null> {
const result = await handlePartnerWechatCallback();
if (!result) return null;
return handlePartnerWechatLoginResult(result);
}
/** @deprecated 使用 handlePartnerWechatLoginResult */
export function savePartnerWechatAuth(result: WechatLoginResult): boolean {
return !!handlePartnerWechatLoginResult(result);
}