import type { PartnerMe } from '@dukang/shared-types'; import { isOnAppPath, toAppPath } from '@dukang/weixin-sdk'; export const apiBase = '/api/v1'; const LAST_PHONE = 'partnerLastPhone'; const PARTNER_PROFILE = 'partnerProfile'; export type PartnerSessionProfile = Pick; export type PartnerAuthPayload = { accessToken: string; partner?: PartnerSessionProfile; }; export type ApiRequestOptions = RequestInit & { /** 保留字段,兼容旧调用;错误提示由页面自行处理 */ silent?: boolean; }; export function getLastPhone() { return localStorage.getItem(LAST_PHONE) ?? ''; } export function getPartnerProfile(): PartnerSessionProfile | null { try { const raw = localStorage.getItem(PARTNER_PROFILE); return raw ? (JSON.parse(raw) as PartnerSessionProfile) : null; } catch { return null; } } export async function request( clientApp: string, path: string, options: ApiRequestOptions = {}, ): Promise { const { silent, ...fetchOptions } = options; const token = localStorage.getItem('accessToken'); const headers: Record = { 'Content-Type': 'application/json', 'X-Client-App': clientApp, ...(fetchOptions.headers as Record), }; if (token) headers.Authorization = `Bearer ${token}`; const res = await fetch(`${apiBase}${path}`, { ...fetchOptions, headers }); const json = await res.json().catch(() => ({ code: res.status, message: '网络异常' })); const rawMessage = json.message; const message = Array.isArray(rawMessage) ? rawMessage.join(';') : (rawMessage || (res.status === 401 ? '登录已过期,请重新登录' : '请求失败')); if (res.status === 401 || json.code === 401) { if (token && localStorage.getItem('accessToken') === token) { clearAuth(); if (typeof window !== 'undefined' && !isOnAppPath('/login')) { window.location.href = toAppPath('/login'); } } throw new Error(message); } if (json.code !== 0) { throw new Error(message); } return json.data as T; } export function saveAuth(data: PartnerAuthPayload) { localStorage.setItem('accessToken', data.accessToken); if (data.partner) { localStorage.setItem(PARTNER_PROFILE, JSON.stringify(data.partner)); localStorage.setItem(LAST_PHONE, data.partner.phone); } } export function clearAuth() { localStorage.removeItem('accessToken'); localStorage.removeItem(PARTNER_PROFILE); } export function isLoggedIn() { return !!localStorage.getItem('accessToken'); }