website-01/store/adminStore.ts

61 lines
1.8 KiB
TypeScript
Raw Normal View History

2026-06-22 14:43:46 +08:00
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=/;`;
}
}
/** 同步到 localStorageaxios 拦截器从这里取 */
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<AdminState>()(
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 }),
},
),
);