From 52fe7fa51e7a58679e56e087c497c7bb9c6c8e92 Mon Sep 17 00:00:00 2001 From: zichun Date: Fri, 15 May 2026 17:37:04 +0800 Subject: [PATCH] feat(frontend): LoginForm + LoginHero/Footer + LoginPage 集成 + jsdom polyfills --- frontend/src/pages/login/LoginFooter.tsx | 9 +++++++++ frontend/src/pages/login/LoginForm.tsx | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ frontend/src/pages/login/LoginHero.tsx | 11 +++++++++++ frontend/src/pages/login/LoginPage.test.tsx | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ frontend/src/pages/login/LoginPage.tsx | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- frontend/src/pages/login/loginConstants.ts | 11 +++++++++++ frontend/src/test-utils/setup.ts | 25 ++++++++++++++++++++++++- 7 files changed, 336 insertions(+), 2 deletions(-) create mode 100644 frontend/src/pages/login/LoginFooter.tsx create mode 100644 frontend/src/pages/login/LoginForm.tsx create mode 100644 frontend/src/pages/login/LoginHero.tsx create mode 100644 frontend/src/pages/login/LoginPage.test.tsx create mode 100644 frontend/src/pages/login/loginConstants.ts diff --git a/frontend/src/pages/login/LoginFooter.tsx b/frontend/src/pages/login/LoginFooter.tsx new file mode 100644 index 0000000..b82f2de --- /dev/null +++ b/frontend/src/pages/login/LoginFooter.tsx @@ -0,0 +1,9 @@ +export default function LoginFooter() { + return ( +
+ 🛠 ©Copyright Antler Software | 印刷智慧工厂 | 印刷MES | 印刷ERP | 印刷电商平台 | + 文件智能处理 | 印前自动化 | 400-880-6237 + 沪ICP备14034791号-1 +
+ ); +} diff --git a/frontend/src/pages/login/LoginForm.tsx b/frontend/src/pages/login/LoginForm.tsx new file mode 100644 index 0000000..b8c2347 --- /dev/null +++ b/frontend/src/pages/login/LoginForm.tsx @@ -0,0 +1,97 @@ +import { useEffect } from 'react'; +import { Form, Input, Select, Button, Alert } from 'antd'; +import type { LoginReq } from '../../api/auth'; +import { COMPANY_OPTIONS } from './loginConstants'; + +export interface LoginFormFieldErrors { + username?: string; + password?: string; + companyCode?: string; +} + +interface Props { + onSubmit: (req: LoginReq) => Promise; + loading: boolean; + errorMessage: string | null; + fieldErrors: LoginFormFieldErrors; +} + +export default function LoginForm({ onSubmit, loading, errorMessage, fieldErrors }: Props) { + const [form] = Form.useForm(); + + useEffect(() => { + // 字段级错误同步到 AntD Form 实例 + const errs: Array<{ name: keyof LoginFormFieldErrors; errors: string[] }> = []; + (['username', 'password', 'companyCode'] as const).forEach((k) => { + if (fieldErrors[k]) errs.push({ name: k, errors: [fieldErrors[k]!] }); + }); + if (errs.length > 0) { + form.setFields(errs as any); + } + }, [fieldErrors, form]); + + const handleFinish = async (values: LoginReq) => { + await onSubmit(values); + }; + + return ( +
+ {errorMessage && ( + + )} + + + + + + + + + + +