fix(web): 补回缺失的登录页(task-3 重构路由时误删,审计发现致命缺陷)
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
// 登录页:语义对齐 web.archived/src/app/LoginPage.jsx(提交 d97cade)。
|
||||
// 提交 GET /api/gateways 校验 Basic 凭证,成功后写入 localStorage('creatorhub.auth') 并跳转首页。
|
||||
// 仅用 antd 默认组件:Card/Form/Input/Button/Alert。
|
||||
import { history } from '@umijs/max';
|
||||
import { Alert, Button, Card, Form, Input, Typography } from 'antd';
|
||||
import { useState } from 'react';
|
||||
|
||||
interface FormValues {
|
||||
username: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
export default function Page() {
|
||||
const [form] = Form.useForm<FormValues>();
|
||||
const [busy, setBusy] = useState(false);
|
||||
const [error, setError] = useState('');
|
||||
|
||||
async function onFinish({ username, password }: FormValues) {
|
||||
setBusy(true);
|
||||
setError('');
|
||||
const controller = new AbortController();
|
||||
const timer = window.setTimeout(() => controller.abort(), 15000);
|
||||
try {
|
||||
const response = await fetch('/api/gateways', {
|
||||
headers: { Authorization: `Basic ${btoa(`${username}:${password}`)}` },
|
||||
signal: controller.signal,
|
||||
});
|
||||
if (response.status === 401) throw new Error('用户名或密码不正确');
|
||||
if (!response.ok) throw new Error(`认证服务不可用(${response.status})`);
|
||||
localStorage.setItem('creatorhub.auth', `${username}:${password}`);
|
||||
history.replace('/accounts');
|
||||
} catch (reason: any) {
|
||||
setError(
|
||||
reason.name === 'AbortError' ? '认证请求超时,请检查控制面连接' : reason.message || '登录失败',
|
||||
);
|
||||
} finally {
|
||||
window.clearTimeout(timer);
|
||||
setBusy(false);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{ display: 'flex', minHeight: '100vh', alignItems: 'center', justifyContent: 'center', padding: 16 }}>
|
||||
<Card style={{ width: 360 }}>
|
||||
<Typography.Title level={4} style={{ marginBottom: 24, textAlign: 'center' }}>
|
||||
CreatorHub
|
||||
</Typography.Title>
|
||||
{error ? <Alert type="error" showIcon style={{ marginBottom: 16 }} message={error} /> : null}
|
||||
<Form form={form} layout="vertical" onFinish={onFinish} requiredMark={false}>
|
||||
<Form.Item name="username" label="用户名" rules={[{ required: true, message: '请输入用户名' }]}>
|
||||
<Input autoComplete="username" />
|
||||
</Form.Item>
|
||||
<Form.Item name="password" label="密码" rules={[{ required: true, message: '请输入密码' }]}>
|
||||
<Input.Password autoComplete="current-password" />
|
||||
</Form.Item>
|
||||
<Button type="primary" htmlType="submit" block loading={busy}>
|
||||
{busy ? '登录中…' : '登录'}
|
||||
</Button>
|
||||
</Form>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user