"use client"; import * as React from "react"; import { LoginForm } from "@/components/auth/login-form"; import { RegisterForm } from "@/components/auth/register-form"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; const LoginFormCard = (props: { clientId: string; tenantId: string; callback: string; initialEmail: string; }) => { const [tab, setTab] = React.useState<"login" | "register">("login"); const [captcha, setCaptcha] = React.useState(""); const [captchaKey, setCaptchaKey] = React.useState(""); const [loginExternalError, setLoginExternalError] = React.useState< string | null >(null); const [loginPrefill, setLoginPrefill] = React.useState<{ email: string; password: string; } | null>(null); React.useEffect(() => { setCaptchaKey(String(Date.now())); }, []); function refreshCaptcha() { setCaptchaKey(String(Date.now())); } async function loginTokenAndStore(payload: { email: string; password: string; }) { const tokenRes = await fetch("/api/auth/login-token", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ tenantId: props.tenantId, email: payload.email, password: payload.password, captcha, }), }); const tokenJson = (await tokenRes.json()) as { access_token?: string; refresh_token?: string; token_type?: string; expires_in?: number; message?: string; }; if (!tokenRes.ok || !tokenJson.access_token || !tokenJson.refresh_token) { throw new Error(tokenJson.message || "登录失败"); } try { sessionStorage.setItem("iam_access_token", tokenJson.access_token); sessionStorage.setItem("iam_refresh_token", tokenJson.refresh_token); if (tokenJson.token_type) { sessionStorage.setItem("iam_token_type", tokenJson.token_type); } if (typeof tokenJson.expires_in === "number") { sessionStorage.setItem("iam_expires_in", String(tokenJson.expires_in)); } sessionStorage.setItem("iam_token_issued_at", String(Date.now())); } catch {} } async function loginAndRedirect(payload: { email: string; password: string; }) { await loginTokenAndStore(payload); const res = await fetch("/api/auth/login", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ clientId: props.clientId, tenantId: props.tenantId, callback: props.callback, email: payload.email, password: payload.password, captcha, rememberMe: true, }), }); const json = (await res.json()) as { redirectTo?: string; message?: string; }; if (!res.ok || !json.redirectTo) { throw new Error(json.message || "登录失败"); } window.location.href = json.redirectTo; } return ( 统一登录 使用 IAM 账号登录以访问业务系统 setTab(v as "login" | "register")} className="w-full" > 登录 注册 setLoginExternalError(null)} captcha={captcha} onCaptchaChange={setCaptcha} captchaKey={captchaKey} onRefreshCaptcha={refreshCaptcha} /> { setLoginPrefill(p); }} onLoginAfterRegister={async (p) => { try { await loginAndRedirect(p); } catch (err) { const msg = err instanceof Error ? err.message : "登录失败"; setLoginExternalError( `注册成功,但登录失败:${msg}。请在“登录”页修正验证码后继续。`, ); setTab("login"); setCaptcha(""); refreshCaptcha(); } }} /> ); }; export default LoginFormCard;