This commit is contained in:
eric
2026-03-12 05:40:18 -05:00
parent d514f8348d
commit ffa5043daf
12 changed files with 330 additions and 45 deletions

View File

@@ -79,19 +79,26 @@ export async function pbLogout(): Promise<void> {
}
}
/** 获取当前存储的用户邮箱 */
export function getStoredUserEmail(): string | null {
/** 获取当前存储的用户id + email */
export function getStoredUser(): AuthUser | null {
if (typeof window === "undefined") return null;
try {
const raw = localStorage.getItem(PB_STORAGE_KEYS.user);
if (!raw) return null;
const user = JSON.parse(raw);
return user?.email ?? null;
if (!user?.id || !user?.email) return null;
return { id: user.id, email: user.email };
} catch {
return null;
}
}
/** 获取当前存储的用户邮箱 */
export function getStoredUserEmail(): string | null {
const user = getStoredUser();
return user?.email ?? null;
}
/** 获取存储的 token用于 API 请求) */
export function getStoredToken(): string | null {
if (typeof window === "undefined") return null;

View File

@@ -3,6 +3,7 @@ export {
pbRegister,
pbSaveAuth,
pbLogout,
getStoredUser,
getStoredUserEmail,
getStoredToken,
} from "./auth";

View File

@@ -1,6 +1,7 @@
"use client";
import { useState, useEffect, useCallback } from "react";
import { getStoredUser, getStoredToken } from "@/app/lib/pocketbase";
export interface AuthAndVipState {
user: { id: string; email: string } | null;
@@ -14,7 +15,7 @@ export function useAuthAndVip(): AuthAndVipState {
const [vip, setVip] = useState(false);
const [loading, setLoading] = useState(true);
const refetch = useCallback(async (): Promise<{ user: typeof user; vip: boolean }> => {
const refetch = useCallback(async (): Promise<{ user: { id: string; email: string } | null; vip: boolean }> => {
setLoading(true);
try {
const [meRes, vipRes] = await Promise.all([
@@ -23,15 +24,36 @@ export function useAuthAndVip(): AuthAndVipState {
]);
const meData = await meRes.json();
const vipData = await vipRes.json();
const newUser = meData?.user ?? null;
const newVip = vipData?.vip === true;
let newUser = meData?.user ?? null;
let newVip = vipData?.vip === true;
// 与 Header 一致API 无用户时,尝试从 localStorage 恢复(如 cookie 未同步、localhost 开发等)
if (!newUser) {
const storedUser = getStoredUser();
const storedToken = getStoredToken();
if (storedUser && storedToken) {
newUser = storedUser;
try {
await fetch("/api/auth/sync-session", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ token: storedToken, record: storedUser }),
credentials: "include",
});
} catch {
/* ignore */
}
}
}
setUser(newUser);
setVip(newVip);
return { user: newUser, vip: newVip };
} catch {
setUser(null);
const storedUser = getStoredUser();
setUser(storedUser);
setVip(false);
return { user: null, vip: false };
return { user: storedUser, vip: false };
} finally {
setLoading(false);
}