deploy-ease-platform/frontend/src/pages/Login/index.tsx
dengqichen 0ebbf82ae7 1
2024-12-27 16:55:06 +08:00

172 lines
6.2 KiB
TypeScript

import React, {useEffect, useState} from 'react';
import {Form, Input, Button, message, Select} from 'antd';
import {useNavigate} from 'react-router-dom';
import {useDispatch} from 'react-redux';
import {login} from './service';
import {getEnabledTenants} from '@/pages/System/Tenant/service';
import {setToken, setUserInfo, setMenus} from '../../store/userSlice';
import {getCurrentUserMenus} from '@/pages/System/Menu/service';
import type { TenantResponse } from '@/pages/System/Tenant/types';
import styles from './index.module.css';
interface LoginForm {
tenantId: string;
username: string;
password: string;
}
const Login: React.FC = () => {
const navigate = useNavigate();
const dispatch = useDispatch();
const [form] = Form.useForm<LoginForm>();
const [loading, setLoading] = useState(false);
const [tenants, setTenants] = useState<TenantResponse[]>([]);
useEffect(() => {
const fetchTenants = async () => {
try {
const data = await getEnabledTenants();
setTenants(data);
} catch (error) {
console.error('获取租户列表失败:', error);
}
};
fetchTenants();
}, []);
// 加载菜单数据
const loadMenuData = async () => {
try {
const menuData = await getCurrentUserMenus();
if (menuData && menuData.length > 0) {
dispatch(setMenus(menuData));
}
} catch (error) {
console.error('获取菜单数据失败:', error);
}
};
const handleFinish = async (values: LoginForm) => {
setLoading(true);
try {
// 1. 登录获取 token 和用户信息
const loginData = await login(values);
dispatch(setToken(loginData.token));
dispatch(setUserInfo({
id: loginData.id,
username: loginData.username,
nickname: loginData.nickname,
email: loginData.email,
phone: loginData.phone
}));
// 2. 获取菜单数据
await loadMenuData();
message.success('登录成功');
navigate('/');
} catch (error) {
console.error('登录失败:', error);
} finally {
setLoading(false);
}
};
return (
<div className={styles.loginContainer}>
{/* 左侧区域 */}
<div className={styles.leftSection}>
<div>
<h1 className="text-xl font-bold">Deploy Ease Platform</h1>
</div>
<div className="space-y-4">
<blockquote className="text-2xl font-medium">
"平台帮助我们显著提升了部署效率,让团队可以更专注于业务开发。"
</blockquote>
</div>
</div>
{/* 右侧登录区域 */}
<div className={styles.rightSection}>
<div className={styles.loginBox}>
<div className={styles.logo}>
<h1></h1>
<p className="text-gray-500 mt-2"></p>
</div>
<Form<LoginForm>
form={form}
name="login"
onFinish={handleFinish}
autoComplete="off"
size="large"
layout="vertical"
>
<Form.Item
name="tenantId"
rules={[{required: true, message: '请选择租户!'}]}
>
<Select
placeholder="系统管理租户"
options={tenants.map(tenant => ({
label: tenant.name,
value: tenant.code
}))}
className={styles.input}
dropdownStyle={{
padding: '8px',
borderRadius: '8px',
}}
/>
</Form.Item>
<Form.Item
name="username"
rules={[{required: true, message: '请输入用户名!'}]}
>
<Input
placeholder="admin"
className={styles.input}
/>
</Form.Item>
<Form.Item
name="password"
rules={[{required: true, message: '请输入密码!'}]}
>
<Input.Password
placeholder="········"
className={styles.input}
/>
</Form.Item>
<Form.Item>
<Button
type="primary"
htmlType="submit"
block
loading={loading}
className={styles.loginButton}
>
</Button>
</Form.Item>
</Form>
<div className="text-center text-sm text-gray-500 mt-4">
<a href="#" className="text-[#2563eb] hover:text-[#1d4ed8] mx-1">
</a>
<a href="#" className="text-[#2563eb] hover:text-[#1d4ed8] mx-1">
</a>
</div>
</div>
</div>
</div>
);
};
export default Login;