init
This commit is contained in:
109
frontend/src/components/Login.jsx
Normal file
109
frontend/src/components/Login.jsx
Normal file
@ -0,0 +1,109 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Form, Input, Button, Card, Typography, message } from 'antd';
|
||||
import { UserOutlined, LockOutlined } from '@ant-design/icons';
|
||||
|
||||
const { Title } = Typography;
|
||||
|
||||
const Login = ({ onLogin }) => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const onFinish = async (values) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
// 调用后端登录API
|
||||
const response = await fetch('http://localhost:3001/api/auth/login', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
username: values.username,
|
||||
password: values.password,
|
||||
}),
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
// 保存登录状态和令牌
|
||||
localStorage.setItem('isLoggedIn', 'true');
|
||||
localStorage.setItem('loginTime', Date.now().toString());
|
||||
localStorage.setItem('authToken', data.token);
|
||||
localStorage.setItem('userInfo', JSON.stringify(data.user));
|
||||
|
||||
message.success(data.message || '登录成功!');
|
||||
onLogin(true);
|
||||
} else {
|
||||
message.error(data.message || '登录失败!');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('登录错误:', error);
|
||||
message.error('网络错误,请稍后重试!');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
minHeight: '100vh',
|
||||
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)'
|
||||
}}>
|
||||
<Card style={{ width: 400, boxShadow: '0 4px 12px rgba(0,0,0,0.15)' }}>
|
||||
<div style={{ textAlign: 'center', marginBottom: 24 }}>
|
||||
<Title level={2} style={{ color: '#1890ff', marginBottom: 8 }}>
|
||||
会议签到系统
|
||||
</Title>
|
||||
<p style={{ color: '#666', margin: 0 }}>管理员登录</p>
|
||||
</div>
|
||||
|
||||
<Form
|
||||
name="login"
|
||||
onFinish={onFinish}
|
||||
autoComplete="off"
|
||||
size="large"
|
||||
>
|
||||
<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}
|
||||
style={{ width: '100%' }}
|
||||
>
|
||||
登录
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
|
||||
<div style={{ textAlign: 'center', color: '#999', fontSize: '12px' }}>
|
||||
<p>默认账号:admin / admin123</p>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Login;
|
||||
Reference in New Issue
Block a user