feat: Airwallex 发卡管理后台完整实现
- 后端: FastAPI + SQLAlchemy + SQLite, JWT认证, 代理支持的AirwallexClient - 前端: React 18 + Vite + Ant Design 5, 中文界面 - 功能: 卡片管理, 持卡人管理, 交易记录, API令牌, 系统设置, 审计日志 - 第三方API: X-API-Key认证, 权限控制 - Docker部署: docker-compose编排前后端
This commit is contained in:
51
frontend/src/pages/Login.tsx
Normal file
51
frontend/src/pages/Login.tsx
Normal file
@@ -0,0 +1,51 @@
|
||||
import { useState } from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { Card, Form, Input, Button, message } from 'antd'
|
||||
import { UserOutlined, LockOutlined, CreditCardOutlined } from '@ant-design/icons'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
|
||||
export default function Login() {
|
||||
const [loading, setLoading] = useState(false)
|
||||
const login = useAuthStore((s) => s.login)
|
||||
const navigate = useNavigate()
|
||||
|
||||
const onFinish = async (values: { username: string; password: string }) => {
|
||||
setLoading(true)
|
||||
try {
|
||||
await login(values.username, values.password)
|
||||
message.success('登录成功')
|
||||
navigate('/')
|
||||
} catch (err: unknown) {
|
||||
const error = err as { response?: { data?: { detail?: string } } }
|
||||
message.error(error.response?.data?.detail || '登录失败,请检查用户名和密码')
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="login-container">
|
||||
<Card className="login-card">
|
||||
<div style={{ textAlign: 'center', marginBottom: 32 }}>
|
||||
<CreditCardOutlined style={{ fontSize: 48, color: '#667eea' }} />
|
||||
<h2 className="login-title" style={{ marginTop: 12 }}>
|
||||
Airwallex 发卡管理系统
|
||||
</h2>
|
||||
</div>
|
||||
<Form name="login" onFinish={onFinish} size="large" autoComplete="off">
|
||||
<Form.Item name="username" rules={[{ required: true, message: '请输入用户名' }]}>
|
||||
<Input prefix={<UserOutlined />} placeholder="用户名" />
|
||||
</Form.Item>
|
||||
<Form.Item name="password" rules={[{ required: true, message: '请输入密码' }]}>
|
||||
<Input.Password prefix={<LockOutlined />} placeholder="密码" />
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
<Button type="primary" htmlType="submit" loading={loading} block>
|
||||
登录
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Card>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user