deploy-ease-platform/frontend/src/pages/Login/index.tsx
2024-12-02 16:37:23 +08:00

141 lines
4.6 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 { MenuResponse } from '@/pages/System/Menu/types';
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.loginBox}>
<div className={styles.logo}>
<h1></h1>
</div>
<Form<LoginForm>
form={form}
name="login"
onFinish={handleFinish}
autoComplete="off"
size="large"
>
<Form.Item
name="tenantId"
rules={[{required: true, message: '请选择租户!'}]}
>
<Select
placeholder="请选择租户"
options={tenants.map(tenant => ({
label: tenant.name,
value: tenant.code
}))}
className={styles.input}
/>
</Form.Item>
<Form.Item
name="username"
rules={[{required: true, message: '请输入用户名!'}]}
>
<Input
placeholder="用户名"
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>
</div>
);
};
export default Login;