a393b5c0e3
- 系统配置页支持 bool 类型(Switch 控件),供「提现自动对账」「比价期广告」等运营开关使用 - message / Modal.confirm 静态调用迁移到 App.useApp() 的 message / modal,消除 React 19 "Static function can not consume context" 告警;providers 用 <App> 容器包裹全站 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: OuYingJun1024 <1034284404@qq.com> Reviewed-on: #12 Co-authored-by: ouzhou <ouzhou@wonderable.ai> Co-committed-by: ouzhou <ouzhou@wonderable.ai>
55 lines
1.7 KiB
TypeScript
55 lines
1.7 KiB
TypeScript
'use client';
|
|
|
|
import { useState } from 'react';
|
|
import { useRouter } from 'next/navigation';
|
|
import { App, Button, Card, Form, Input } from 'antd';
|
|
import { api, errMsg } from '@/lib/api';
|
|
import { setAuth } from '@/lib/auth';
|
|
import type { LoginResponse } from '@/lib/types';
|
|
|
|
export default function LoginPage() {
|
|
const router = useRouter();
|
|
const { message } = App.useApp();
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
const onFinish = async (values: { username: string; password: string }) => {
|
|
setLoading(true);
|
|
try {
|
|
const { data } = await api.post<LoginResponse>('/admin/api/auth/login', values);
|
|
setAuth(data.access_token, data.admin);
|
|
message.success('登录成功');
|
|
router.replace('/dashboard');
|
|
} catch (e) {
|
|
message.error(errMsg(e, '登录失败'));
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div
|
|
style={{
|
|
minHeight: '100vh',
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
background: '#f0f2f5',
|
|
}}
|
|
>
|
|
<Card title="傻瓜比价 · 运营后台" style={{ width: 360 }}>
|
|
<Form onFinish={onFinish} layout="vertical">
|
|
<Form.Item name="username" label="用户名" rules={[{ required: true, message: '请输入用户名' }]}>
|
|
<Input autoFocus 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" loading={loading} block>
|
|
登录
|
|
</Button>
|
|
</Form>
|
|
</Card>
|
|
</div>
|
|
);
|
|
}
|