Files
MYXY_Web/src/pages/AdminLogin.tsx

195 lines
6.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React, { useState, useEffect } from 'react';
import { Form, Input, Button, Card, Typography, message, Space, Checkbox } from 'antd';
import { UserOutlined, LockOutlined, SafetyOutlined } from '@ant-design/icons';
import { useNavigate } from 'react-router-dom';
import { useAuth } from '../contexts/AuthContext';
const { Title, Text } = Typography;
/**
* 运营管理系统后台登录页面
* 路径:/admin
*/
const AdminLogin: React.FC = () => {
const [loading, setLoading] = useState(false);
const { login, isAuthenticated } = useAuth();
const navigate = useNavigate();
const [form] = Form.useForm();
// 如果已登录,重定向到管理后台
useEffect(() => {
if (isAuthenticated) {
navigate('/admin/dashboard', { replace: true });
}
}, [isAuthenticated, navigate]);
/**
* 处理登录表单提交
* @param values - 表单值
*/
const handleLogin = async (values: {
username: string;
password: string;
remember?: boolean;
}) => {
setLoading(true);
try {
const success = await login(values.username, values.password);
if (success) {
navigate('/admin/dashboard', { replace: true });
}
} catch (error) {
// 错误已在AuthContext中处理
} finally {
setLoading(false);
}
};
return (
<div style={{
minHeight: '100vh',
background: 'linear-gradient(135deg, #1e3c72 0%, #2a5298 100%)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
padding: '20px'
}}>
<Card
style={{
width: '100%',
maxWidth: '450px',
boxShadow: '0 10px 40px rgba(0, 0, 0, 0.15)',
borderRadius: '16px',
border: '1px solid rgba(255, 255, 255, 0.1)'
}}
styles={{ body: { padding: '48px 40px' } }}
>
<Space orientation="vertical" size="large" style={{ width: '100%' }}>
{/* 系统标题 */}
<div style={{ textAlign: 'center' }}>
<div style={{
width: '72px',
height: '72px',
background: 'linear-gradient(45deg, #1890ff, #722ed1)',
borderRadius: '16px',
margin: '0 auto 20px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontSize: '32px',
color: 'white'
}}>
<SafetyOutlined />
</div>
<Title level={2} style={{ margin: 0, color: '#1f2937' }}>
</Title>
<Text type="secondary" style={{ fontSize: '16px' }}>
西
</Text>
</div>
{/* 安全提示 */}
<div style={{
background: '#f6ffed',
border: '1px solid #b7eb8f',
borderRadius: '8px',
padding: '12px 16px',
textAlign: 'center'
}}>
<Text style={{ color: '#52c41a', fontSize: '14px' }}>
🔒 使
</Text>
</div>
{/* 登录表单 */}
<Form
name="admin-login"
onFinish={handleLogin}
autoComplete="off"
size="large"
initialValues={{ remember: false }}
>
<Form.Item
name="username"
rules={[
{ required: true, message: '请输入管理员账号!' },
{ min: 3, message: '账号至少3个字符' }
]}
>
<Input
prefix={<UserOutlined style={{ color: '#8c8c8c' }} />}
placeholder="管理员账号"
style={{
borderRadius: '10px',
border: '1px solid #d9d9d9'
}}
/>
</Form.Item>
<Form.Item
name="password"
rules={[
{ required: true, message: '请输入密码!' },
{ min: 6, message: '密码至少6个字符' }
]}
>
<Input.Password
prefix={<LockOutlined style={{ color: '#8c8c8c' }} />}
placeholder="密码"
style={{
borderRadius: '10px',
border: '1px solid #d9d9d9'
}}
/>
</Form.Item>
<Form.Item>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<Form.Item name="remember" valuePropName="checked" style={{ margin: 0 }}>
<Checkbox></Checkbox>
</Form.Item>
<a href="#" style={{ color: '#1890ff' }}>
</a>
</div>
</Form.Item>
<Form.Item>
<Button
type="primary"
htmlType="submit"
loading={loading}
style={{
width: '100%',
height: '48px',
borderRadius: '10px',
fontSize: '16px',
fontWeight: '500',
background: 'linear-gradient(45deg, #1890ff, #722ed1)',
border: 'none',
boxShadow: '0 4px 12px rgba(24, 144, 255, 0.3)'
}}
>
{loading ? '登录中...' : '登录管理后台'}
</Button>
</Form.Item>
</Form>
{/* 底部信息 */}
<div style={{ textAlign: 'center' }}>
<Text type="secondary" style={{ fontSize: '12px' }}>
v1.0.0 |
<a href="#" style={{ color: '#1890ff', marginLeft: '4px' }}>
</a>
</Text>
</div>
</Space>
</Card>
</div>
);
};
export default AdminLogin;