import { App, Button, Checkbox, Form, Input, Typography } from "antd"; import { LockOutlined, ReloadOutlined, SafetyOutlined, UserOutlined } from "@ant-design/icons"; import { useCallback, useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { getCurrentUser, getOpenPlatformConfig, getSystemParamValue } from "@/api"; import { fetchCaptcha, login, type CaptchaResponse } from "@/api/auth"; import type { SysPlatformConfig } from "@/types"; import "./index.less"; const { Title, Text, Link } = Typography; type LoginFormValues = { username: string; password: string; captchaCode?: string; remember?: boolean; tenantCode?: string; }; export default function Login() { const { t } = useTranslation(); const [captcha, setCaptcha] = useState(null); const [captchaEnabled, setCaptchaEnabled] = useState(true); const [loading, setLoading] = useState(false); const [platformConfig, setPlatformConfig] = useState(null); const [form] = Form.useForm(); const { message } = App.useApp(); const loadCaptcha = useCallback(async () => { if (!captchaEnabled) { return; } const data = await fetchCaptcha(); setCaptcha(data); }, [captchaEnabled]); useEffect(() => { const init = async () => { try { const [captchaValue, config] = await Promise.all([ getSystemParamValue("security.captcha.enabled", "true"), getOpenPlatformConfig() ]); setPlatformConfig(config); const enabled = captchaValue !== "false"; setCaptchaEnabled(enabled); if (enabled) { await loadCaptcha(); } } catch { setCaptchaEnabled(true); await loadCaptcha(); } }; init(); }, [loadCaptcha]); useEffect(() => { const searchParams = new URLSearchParams(window.location.search); if (searchParams.get("timeout") === "1") { message.warning(t("login.loginTimeout")); window.history.replaceState({}, document.title, window.location.pathname); } }, [t]); const onFinish = async (values: LoginFormValues) => { setLoading(true); try { const data = await login({ username: values.username, password: values.password, tenantCode: values.tenantCode, captchaId: captchaEnabled ? captcha?.captchaId : undefined, captchaCode: captchaEnabled ? values.captchaCode : undefined }); localStorage.setItem("accessToken", data.accessToken); localStorage.setItem("refreshToken", data.refreshToken); localStorage.setItem("username", values.username); if (data.availableTenants) { localStorage.setItem("availableTenants", JSON.stringify(data.availableTenants)); const payload = JSON.parse(atob(data.accessToken.split(".")[1])); localStorage.setItem("activeTenantId", String(payload.tenantId)); } try { const profile = await getCurrentUser(); sessionStorage.setItem("userProfile", JSON.stringify(profile)); localStorage.setItem("displayName", profile.displayName || profile.username || values.username); localStorage.setItem("username", profile.username || values.username); } catch { sessionStorage.removeItem("userProfile"); localStorage.removeItem("displayName"); } message.success(t("common.success")); window.location.href = "/"; } catch { if (captchaEnabled) { await loadCaptcha(); } } finally { setLoading(false); } }; const loginStyle = platformConfig?.loginBgUrl ? { backgroundImage: `url(${platformConfig.loginBgUrl})`, backgroundSize: "cover", backgroundPosition: "center", position: "relative" as const } : {}; const leftStyle = platformConfig?.loginBgUrl ? { ...loginStyle, background: "rgba(255, 255, 255, 0.2)", backdropFilter: "blur(10px)" } : {}; const rightStyle = platformConfig?.loginBgUrl ? { background: "rgba(255, 255, 255, 0.85)", backdropFilter: "blur(20px)" } : {}; return (
Logo {platformConfig?.projectName || "UnisBase"}

{t("login.heroTitle1")}
{t("login.heroTitle2")}
{t("login.heroTitle3")}

{platformConfig?.systemDescription || t("login.heroDesc")}

{t("login.enterpriseSecurity")}
{t("login.welcome")} {t("login.subtitle")}
} placeholder={t("login.username")} autoComplete="username" spellCheck={false} aria-label={t("login.username")} /> {captchaEnabled ? (
} placeholder={t("login.captcha")} maxLength={6} aria-label={t("login.captcha")} />
) : null}
{t("login.rememberMe")} {t("login.forgotPassword")}
{t("login.demoAccount")} admin / {t("login.password")}{" "} 123456
); }