import { useEffect, useState } from "react"; import { useNavigate } from "react-router"; import { motion } from "motion/react"; import { Heart } from "lucide-react"; import { useUser } from "../context/UserContext"; import { devLogin, fetchApi, getToken, clearToken, decodeToken } from "../services/api"; import { debugLog, clearDebugLogs } from "../services/debug"; export function LoginPage() { const navigate = useNavigate(); const { setTokenAndUser, fetchProfile } = useUser(); const [error, setError] = useState(""); const [debugInfo, setDebugInfo] = useState([]); const addDebug = (msg: string) => { console.log(msg); setDebugInfo(prev => [...prev.slice(-20), msg]); }; useEffect(() => { clearDebugLogs(); // 收集调试信息(直接在页面显示,排查缓存问题) const infos: string[] = []; const urlOpenid = new URLSearchParams(window.location.search).get('openid'); const cachedToken = getToken(); const ts = new Date().toISOString().slice(11, 19); infos.push(`[${ts}] URL: ${window.location.href.substring(0, 100)}`); infos.push(`[${ts}] urlOpenid=${urlOpenid || '(空)'}`); let cacheOpenid = ''; if (cachedToken) { try { const p = decodeToken(cachedToken); cacheOpenid = p.openid; infos.push(`[${ts}] cache openid=${p.openid}, uid=${p.uid}, exp=${p.exp ? new Date(p.exp * 1000).toLocaleString() : '?'}`); } catch (e) { infos.push(`[${ts}] 缓存 token 解码失败: ${e}`); } } else { infos.push(`[${ts}] 无缓存 token`); } addDebug(infos.join('\n')); // 身份一致性检查 if (urlOpenid && cachedToken) { try { const payload = decodeToken(cachedToken); if (payload.openid !== urlOpenid) { addDebug(`[auth] openid 不一致: URL=${urlOpenid}, cache=${payload.openid},清除缓存`); clearToken(); } } catch (e) { addDebug(`[auth] token 解码失败,清除: ${e}`); clearToken(); } } const params = new URLSearchParams(window.location.search); debugLog(`URL: ${window.location.href.substring(0, 100)}`); debugLog(`search: ${window.location.search}`); const openidParam = params.get('openid'); if (openidParam && openidParam.trim()) { addDebug(`开始登录: openid=${openidParam}`); fetchApi("/auth/openid-login", { method: "POST", body: JSON.stringify({ openid: openidParam }), }).then((res: any) => { addDebug(`openid-login OK: id=${res.user_id}, phone=${res.mobile}`); setTokenAndUser(res.token, { id: res.user_id, openid: res.openid, phone: res.mobile }); fetchProfile().then((dto) => { if (dto) addDebug(`profile: name=${dto.name}, phone=${dto.phone}, onboarded=${dto.is_onboarded}`); navigate(dto?.is_onboarded ? "/home" : "/onboarding", { replace: true }); }).catch((e: any) => { debugLog(`fetchProfile error: ${e?.message}`); setError("登录已失效,请在小程序重新进入"); }); }).catch((e: any) => { addDebug(`openid-login error: ${e?.message}`); setError("登录失败: " + (e?.message || "")); }); return; } addDebug(`no openid, fallback to dev-login`); devLogin().then((res) => { debugLog(`dev-login: openid=${res.openid}, phone=${res.mobile}`); setTokenAndUser(res.token, { id: res.user_id, openid: res.openid, phone: res.mobile }); fetchProfile().then((dto) => { if (dto) debugLog(`fetchProfile: name=${dto.name}, phone=${dto.phone}`); navigate(dto?.is_onboarded ? "/home" : "/onboarding", { replace: true }); }); }).catch((err) => { debugLog(`dev-login error: ${err?.message}`); setError(err?.message || "登录失败,请刷新重试"); }); }, []); // eslint-disable-line react-hooks/exhaustive-deps return (
{/* 调试浮层:点击可关闭 */} {debugInfo.length > 0 && (
setDebugInfo([])} >
H5应用调试
{debugInfo.map((msg, i) => (
{msg}
))}
)}
{error ? (

{error}

) : (

加载中...

)}
); }