import type { ClientRuntimeConfig, WechatLoginResult } from '@dukang/shared-types'; import { isWxAuthorizeEnabled } from '@dukang/shared-types'; import { WECHAT_INAPP_REQUIRED_MSG } from '@dukang/weixin-sdk'; import { isWechatEnv, weixinSdk } from './weixin'; import { request, saveWechatSession, type ShopSessionPayload } from './api'; export type ShopAccountProfile = { id: string; storeId: string; name: string; phone: string; /** 是否已绑定微信(来自 /shop/auth/me account.hasWechat) */ hasWechat?: boolean; wxOpenId?: string | null; store?: { name: string }; }; export async function fetchClientConfig(): Promise { return request('SHOP_H5', '/common/client-config'); } export async function fetchShopAccount(): Promise { const me = await request<{ id?: string; storeId?: string; name?: string; phone?: string; account?: { id?: string; name?: string; phone?: string; hasWechat?: boolean; }; store?: { name?: string } | null; }>('SHOP_H5', '/shop/auth/me'); return { id: String(me.account?.id ?? me.id ?? ''), storeId: String(me.storeId ?? ''), name: String(me.account?.name ?? me.name ?? ''), phone: String(me.account?.phone ?? me.phone ?? ''), hasWechat: !!me.account?.hasWechat, store: me.store?.name ? { name: String(me.store.name) } : undefined, }; } export function needsWechatAuth( profile: ShopAccountProfile | null, config?: Pick | null, ): boolean { if (config && !isWxAuthorizeEnabled(config)) return false; const unbound = !!profile && !(profile.hasWechat || profile.wxOpenId); return isWechatEnv() && unbound; } export async function checkNeedsWechatAuth(profile: ShopAccountProfile | null): Promise { const config = await fetchClientConfig(); return needsWechatAuth(profile, config); } export function sessionFromWechatLogin(result: WechatLoginResult): ShopSessionPayload | null { if (!result.accessToken || !result.refreshToken) return null; const store = result.store as Record | undefined; const stores = Array.isArray((result as { stores?: unknown }).stores) ? ((result as { stores: ShopSessionPayload['stores'] }).stores) : undefined; const account = (result as { account?: ShopSessionPayload['account'] }).account; return { accessToken: result.accessToken, refreshToken: result.refreshToken, stores, account, selectedStoreId: (result as { selectedStoreId?: string }).selectedStoreId, store: store ? { id: String(store.id ?? account?.id ?? ''), storeId: String(store.storeId ?? ''), name: String(store.name ?? account?.name ?? ''), phone: String(store.phone ?? account?.phone ?? ''), storeName: String(store.storeName ?? store.name ?? ''), isPrimary: account?.isPrimary, stores, } : undefined, }; } /** 处理微信登录/绑定结果,写入 7 天免登录 session */ export function handleShopWechatLoginResult(result: WechatLoginResult): ShopSessionPayload | null { const session = sessionFromWechatLogin(result); if (!session) return null; saveWechatSession(session); return session; } /** @deprecated 使用 handleShopWechatLoginResult */ export function saveShopWechatAuth(result: WechatLoginResult): boolean { return !!handleShopWechatLoginResult(result); } export async function handleShopWechatCallback(): Promise { if (!isWechatEnv()) return null; const config = await fetchClientConfig(); if (!isWxAuthorizeEnabled(config)) return null; return weixinSdk.handleOAuthCallback(); } /** * 微信一键登录(已绑定微信的门店账号免验证码)。 * 返回 session = 已登录;void = 已跳转授权页等待回调。 */ export async function loginShopWithWechat(): Promise { const config = await fetchClientConfig(); if (!isWxAuthorizeEnabled(config)) return null; if (!isWechatEnv()) { throw new Error(WECHAT_INAPP_REQUIRED_MSG); } const result = await weixinSdk.login(); if (result) return handleShopWechatLoginResult(result); } /** 短信登录成功后于微信内自动发起 OAuth,绑定 openId 便于后续免登 */ export async function bindShopWechatAfterSmsLogin(): Promise { const config = await fetchClientConfig(); if (!isWxAuthorizeEnabled(config)) return; if (!isWechatEnv()) return; await weixinSdk.login(); } export async function authorizeShopWechat(): Promise { const config = await fetchClientConfig(); if (!isWxAuthorizeEnabled(config)) return; if (!isWechatEnv()) { throw new Error(WECHAT_INAPP_REQUIRED_MSG); } return weixinSdk.login(); }