2026-04-06 22:37:09 +08:00
|
|
|
|
import { useState, useEffect } from 'react';
|
2026-04-05 23:43:24 +08:00
|
|
|
|
import { Form, Input, Button, Card, message, Typography } from 'antd';
|
|
|
|
|
|
import { UserOutlined, LockOutlined, ThunderboltOutlined } from '@ant-design/icons';
|
|
|
|
|
|
import { useNavigate } from 'react-router-dom';
|
2026-04-06 22:37:09 +08:00
|
|
|
|
import { login, getVersion } from '../../services/api';
|
2026-04-05 23:43:24 +08:00
|
|
|
|
import { setToken, setUser } from '../../utils/auth';
|
|
|
|
|
|
|
|
|
|
|
|
const { Title, Text } = Typography;
|
|
|
|
|
|
|
|
|
|
|
|
export default function LoginPage() {
|
|
|
|
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
|
|
const [guestLoading, setGuestLoading] = useState(false);
|
2026-04-06 22:37:09 +08:00
|
|
|
|
const [versionInfo, setVersionInfo] = useState<any>(null);
|
2026-04-05 23:43:24 +08:00
|
|
|
|
const navigate = useNavigate();
|
|
|
|
|
|
|
2026-04-06 22:37:09 +08:00
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
getVersion().then(setVersionInfo).catch(() => {});
|
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
2026-04-05 23:43:24 +08:00
|
|
|
|
const doLogin = async (username: string, password: string) => {
|
|
|
|
|
|
const res: any = await login(username, password);
|
|
|
|
|
|
setToken(res.access_token);
|
|
|
|
|
|
setUser(res.user);
|
|
|
|
|
|
return res;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const onFinish = async (values: { username: string; password: string }) => {
|
|
|
|
|
|
setLoading(true);
|
|
|
|
|
|
try {
|
|
|
|
|
|
await doLogin(values.username, values.password);
|
|
|
|
|
|
message.success('登录成功');
|
|
|
|
|
|
navigate('/');
|
|
|
|
|
|
} catch {
|
|
|
|
|
|
message.error('用户名或密码错误');
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
setLoading(false);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const onGuestLogin = async () => {
|
|
|
|
|
|
setGuestLoading(true);
|
|
|
|
|
|
try {
|
|
|
|
|
|
await doLogin('visitor', 'visitor123');
|
|
|
|
|
|
message.success('访客登录成功');
|
|
|
|
|
|
navigate('/');
|
|
|
|
|
|
} catch {
|
|
|
|
|
|
message.error('访客登录失败,请联系管理员');
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
setGuestLoading(false);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
minHeight: '100vh', display: 'flex', justifyContent: 'center', alignItems: 'center',
|
|
|
|
|
|
background: 'linear-gradient(135deg, #0a1628 0%, #1a3a5c 50%, #0d2137 100%)',
|
|
|
|
|
|
}}>
|
|
|
|
|
|
<Card style={{ width: 400, borderRadius: 12, boxShadow: '0 8px 32px rgba(0,0,0,0.3)' }}>
|
|
|
|
|
|
<div style={{ textAlign: 'center', marginBottom: 32 }}>
|
2026-04-06 22:05:06 +08:00
|
|
|
|
<ThunderboltOutlined style={{ fontSize: 48, color: '#52c41a' }} />
|
2026-04-05 23:43:24 +08:00
|
|
|
|
<Title level={3} style={{ marginTop: 12, marginBottom: 4 }}>
|
2026-04-06 22:05:06 +08:00
|
|
|
|
中关村医疗器械园智慧能源管理平台
|
2026-04-05 23:43:24 +08:00
|
|
|
|
</Title>
|
|
|
|
|
|
<Text type="secondary">零碳园区 · 智慧运维</Text>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<Form onFinish={onFinish} 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} block>
|
|
|
|
|
|
登 录
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</Form.Item>
|
|
|
|
|
|
<Form.Item style={{ marginBottom: 8 }}>
|
|
|
|
|
|
<Button block loading={guestLoading} onClick={onGuestLogin}
|
2026-04-06 22:05:06 +08:00
|
|
|
|
style={{ borderColor: '#52c41a', color: '#52c41a' }}>
|
2026-04-05 23:43:24 +08:00
|
|
|
|
访客体验入口
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</Form.Item>
|
|
|
|
|
|
<div style={{ textAlign: 'center' }}>
|
|
|
|
|
|
<Text type="secondary" style={{ fontSize: 12 }}>
|
|
|
|
|
|
访客仅可浏览数据,无管理权限
|
|
|
|
|
|
</Text>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</Form>
|
2026-04-06 22:37:09 +08:00
|
|
|
|
{versionInfo && (
|
|
|
|
|
|
<div style={{ textAlign: 'center', marginTop: 16, opacity: 0.4, fontSize: 11 }}>
|
|
|
|
|
|
v{versionInfo.project_version} | Core: v{versionInfo.core_version || '—'}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
)}
|
2026-04-05 23:43:24 +08:00
|
|
|
|
</Card>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|