Files
fe_supplier_frontend/src/pages/login/login.tsx
2025-07-18 16:09:31 +08:00

251 lines
8.1 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, Checkbox, Tabs, message } from 'antd';
import { UserOutlined, LockOutlined, EyeInvisibleOutlined, EyeTwoTone } from '@ant-design/icons';
import { history, useIntl } from 'umi';
import './login.less';
import { getCaptcha, supplierLogin, expertLogin, accountLogin, getUserinfo } from '@/servers/api/login';
import { encryptWithRsa } from '@/utils/encryptWithRsa'
const { TabPane } = Tabs;
const LoginPage: React.FC = () => {
const [activeKey, setActiveKey] = useState('supplierLogin');
const [form] = Form.useForm();
const [loading, setLoading] = useState(false);
const [captchaImg, setCaptchaImg] = useState<string>('');
// const [captchaKey, setCaptchaKey] = useState<string>('');
//切换后 走不同接口
const loginApiMap: { [key: string]: (params: any) => Promise<any> } = {
supplierLogin,
expertLogin,
accountLogin
};
const intl = useIntl();
useEffect(() => {
fetchCaptcha();
}, [activeKey]);
// 组件挂载时,检查是否有记住的用户名
useEffect(() => {
const savedUser = localStorage.getItem('remember_user');
if (savedUser) {
const user = JSON.parse(savedUser);
form.setFieldsValue({
username: user.username,
password: user.password,
remember: true,
});
}
}, [form]);
const onFinish = async (values: any) => {
setLoading(true);
try {
const params = {
...values,
password: encryptWithRsa(values.password, false),
encryptValue: encryptWithRsa(values.identifying)
};
const loginRes = await loginApiMap[activeKey](params);
if (loginRes.code === 200) {
if (values.remember) {
localStorage.setItem('remember_user', JSON.stringify({
username: values.username,
password: values.password,
}));
} else {
localStorage.removeItem('remember_user');
}
sessionStorage.setItem('token', loginRes.data.token);
//存入供应商用户id
if (activeKey === 'supplierLogin') {
sessionStorage.setItem('userId', loginRes.data.supplierUser.userId);
} else if (activeKey === 'expertLogin') {
//存入专家用户id
// sessionStorage.setItem('userId', loginRes.data.expertUser.userId);
} else if (activeKey === 'accountLogin') {
//存入招标代理用户id
sessionStorage.setItem('userId', loginRes.data.user.userId);
//部门
// queryUserOrgAll().then((res) => {
// const { code, data } = res;
// if (code == 200) {
// sessionStorage.setItem('userOrgAll', JSON.stringify(data) );
// }
// })
}
sessionStorage.setItem('currentUser', JSON.stringify(loginRes.data));
getUserinfo().then(async (res) => {
// if(res.code == 200) {
const roleIdList = res.authorityList.map((item: any) => {
return item.roleId
})
console.log(roleIdList, 'roleIdList');
sessionStorage.setItem('Userinfo', JSON.stringify(res));
// const menuList = await findMenuList({ roleIdList });
// sessionStorage.setItem('menuList', JSON.stringify(menuList.data));
// }
})
message.success('登录成功');
history.push('/index');
} else {
message.error(loginRes.message || '登录失败');
}
} finally {
setLoading(false);
}
};
const fetchCaptcha = async () => {
const res = await getCaptcha();
if (res.code === 200) {
setCaptchaImg(res.data.base64Image);
// setCaptchaKey(res.data.code);
}
};
const handleTabChange = (key: string) => {
setActiveKey(key);
form.resetFields();
};
// 根据当前选中的Tab决定跳转到哪个注册页面
const handleRegister = () => {
switch (activeKey) {
case 'supplierLogin':
history.push('/register/supplier');
break;
case 'expertLogin':
history.push('/register/expert');
break;
default:
// 招标代理不提供注册功能
break;
}
};
// 渲染注册链接只在供应商和专家Tab下显示
const renderRegisterLink = () => {
if (activeKey === 'agent') {
return null; // 招标代理不显示注册链接
}
return (
<div className="register-link">
{intl.formatMessage({ id: 'login.register.tip' })}
<a onClick={handleRegister}>
{intl.formatMessage({ id: 'login.register.action' })}
</a>
</div>
);
};
// 忘记密码点击
const onForgot = () => {
history.push('/forgot?type='+activeKey);
}
return (
<div className='login-page'>
<div className='login-container'>
{/* <div className='back-home'>
<a onClick={() => history.push('/index')}>
<HomeOutlined /> {intl.formatMessage({ id: 'login.back.home' })}
</a>
</div> */}
<div className='login-title'>{intl.formatMessage({ id: 'login.title' })}</div>
<div className="login-tab-container">
<Tabs activeKey={activeKey} onChange={handleTabChange} className='login-tabs'>
<TabPane tab={intl.formatMessage({ id: 'login.tab.supplier' })} key="supplierLogin" />
<TabPane tab={intl.formatMessage({ id: 'login.tab.expert' })} key="expertLogin" />
<TabPane tab={intl.formatMessage({ id: 'login.tab.agent' })} key="accountLogin" />
</Tabs>
</div>
<Form
form={form}
name="login"
className='login-form'
initialValues={{ remember: false }}
onFinish={onFinish}
>
<Form.Item
name="account"
rules={[{ required: true, message: intl.formatMessage({ id: 'login.username.placeholder' }) + '!' }]}
>
<Input
prefix={<UserOutlined className="site-form-item-icon" />}
placeholder={intl.formatMessage({ id: 'login.username.placeholder' })}
size="large"
/>
</Form.Item>
<Form.Item
name="password"
rules={[{ required: true, message: intl.formatMessage({ id: 'login.password.placeholder' }) + '!' }]}
>
<Input.Password
prefix={<LockOutlined className="site-form-item-icon" />}
placeholder={intl.formatMessage({ id: 'login.password.placeholder' })}
iconRender={visible => (visible ? <EyeTwoTone /> : <EyeInvisibleOutlined />)}
size="large"
/>
</Form.Item>
<Form.Item
name="identifying"
rules={[{ required: true, message: intl.formatMessage({ id: 'login.captcha.placeholder' }) + '!' }]}
>
<Input
placeholder={intl.formatMessage({ id: 'login.captcha.placeholder' })}
size="large"
maxLength={6}
autoComplete="off"
prefix={null}
suffix={
<img
src={`data:image/png;base64,${captchaImg}`}
alt="验证码"
style={{ cursor: 'pointer', height: 32, verticalAlign: 'middle' }}
onClick={fetchCaptcha}
/>
}
/>
</Form.Item>
<Form.Item>
<div className='login-options'>
<Form.Item name="remember" valuePropName="checked" noStyle>
<Checkbox>{intl.formatMessage({ id: 'login.remember' })}</Checkbox>
</Form.Item>
<Button type="link" onClick={()=>onForgot()} className="login-form-forgot" href="">
{intl.formatMessage({ id: 'login.forgot' })}
</Button>
</div>
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit" className="login-form-button" loading={loading} size="large">
{intl.formatMessage({ id: 'login.button' })}
</Button>
{activeKey !== 'accountLogin' && renderRegisterLink()}
</Form.Item>
</Form>
</div>
</div>
);
};
export default LoginPage;