import { create } from 'zustand'; import { persist, createJSONStorage } from 'zustand/middleware'; import type { AdminInfo } from '@/lib/types'; const TOKEN_COOKIE = process.env.NEXT_PUBLIC_TOKEN_KEY ?? 'admin_token'; const TOKEN_LS_KEY = TOKEN_COOKIE; // 文档要求:JWT 仅前端 localStorage 存储 /** 把 token 同步到 Cookie,便于 Edge middleware 在 SSR 前拦截 */ function syncCookie(token: string | null): void { if (typeof document === 'undefined') return; if (token) { const expires = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toUTCString(); document.cookie = `${TOKEN_COOKIE}=${encodeURIComponent(token)}; expires=${expires}; path=/; SameSite=Lax`; } else { document.cookie = `${TOKEN_COOKIE}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/;`; } } /** 同步到 localStorage,axios 拦截器从这里取 */ function syncLocalStorage(token: string | null): void { if (typeof window === 'undefined') return; if (token) { window.localStorage.setItem(TOKEN_LS_KEY, token); } else { window.localStorage.removeItem(TOKEN_LS_KEY); } } interface AdminState { token: string | null; admin: AdminInfo | null; setLogin: (token: string, admin: AdminInfo) => void; logout: () => void; hasAuth: () => boolean; } export const useAdminStore = create()( persist( (set, get) => ({ token: null, admin: null, setLogin: (token, admin) => { syncLocalStorage(token); syncCookie(token); set({ token, admin }); }, logout: () => { syncLocalStorage(null); syncCookie(null); set({ token: null, admin: null }); }, hasAuth: () => Boolean(get().token), }), { name: 'corp_admin_session', storage: createJSONStorage(() => localStorage), partialize: (s) => ({ token: s.token, admin: s.admin }), }, ), );