| New file | 
 |  |  | 
 |  |  | import { | 
 |  |  |     LockOutlined, | 
 |  |  |     MobileOutlined, | 
 |  |  |     UserOutlined, | 
 |  |  | } from '@ant-design/icons'; | 
 |  |  | import { | 
 |  |  |     LoginFormPage, | 
 |  |  |     ProConfigProvider, | 
 |  |  |     ProFormCaptcha, | 
 |  |  |     ProFormCheckbox, | 
 |  |  |     ProFormText, | 
 |  |  |     ProFormSelect | 
 |  |  | } from '@ant-design/pro-components'; | 
 |  |  | import { Button, Divider, Alert, Tabs, message, theme, Form } from 'antd'; | 
 |  |  | import { useState, useEffect } from 'react'; | 
 |  |  | import { FormattedMessage, history, SelectLang, useIntl, useModel, Helmet } from '@umijs/max'; | 
 |  |  | import { flushSync } from 'react-dom'; | 
 |  |  | import { request } from '@umijs/max'; | 
 |  |  | import { setToken } from '@/utils/token-util' | 
 |  |  | import { PROJECT_NAME } from '@/config/setting' | 
 |  |  | import Http from '@/utils/http'; | 
 |  |  |  | 
 |  |  | import logo from './logo.png' | 
 |  |  |  | 
 |  |  | const LoginMessage = ({ content }) => { | 
 |  |  |     return ( | 
 |  |  |         <Alert | 
 |  |  |             style={{ | 
 |  |  |                 marginBottom: 24, | 
 |  |  |             }} | 
 |  |  |             message={content} | 
 |  |  |             type="error" | 
 |  |  |             showIcon | 
 |  |  |         /> | 
 |  |  |     ); | 
 |  |  | }; | 
 |  |  |  | 
 |  |  | const Page = () => { | 
 |  |  |     const intl = useIntl(); | 
 |  |  |     const { initialState, setInitialState } = useModel('@@initialState'); | 
 |  |  |     const { token } = theme.useToken(); | 
 |  |  |  | 
 |  |  |     const [form] = Form.useForm(); | 
 |  |  |     const [loginType, setLoginType] = useState('account'); | 
 |  |  |     const [status, setStatus] = useState(200); | 
 |  |  |     const [rememberMe, setRememberMe] = useState(() => { | 
 |  |  |         const storedValue = localStorage.getItem('rememberMe'); | 
 |  |  |         return storedValue !== null ? JSON.parse(storedValue) : true; | 
 |  |  |     }); | 
 |  |  |     const [rememberData, setRememberData] = useState(() => { | 
 |  |  |         const storedValue = localStorage.getItem('rememberData'); | 
 |  |  |         return storedValue !== null ? JSON.parse(storedValue) : true; | 
 |  |  |     }); | 
 |  |  |     const [hostList, setHostList] = useState([]); | 
 |  |  |  | 
 |  |  |     useEffect(() => { | 
 |  |  |         form.setFieldsValue({ | 
 |  |  |             autoLogin: rememberMe | 
 |  |  |         }); | 
 |  |  |         localStorage.setItem('rememberMe', JSON.stringify(rememberMe)); | 
 |  |  |     }, [rememberMe]) | 
 |  |  |  | 
 |  |  |     useEffect(() => { | 
 |  |  |         form.setFieldsValue({ | 
 |  |  |             username: rememberData.username, | 
 |  |  |             password: rememberData.password | 
 |  |  |         }); | 
 |  |  |         localStorage.setItem('rememberData', JSON.stringify(rememberData)); | 
 |  |  |     }, [rememberData]) | 
 |  |  |  | 
 |  |  |     useEffect(() => { | 
 |  |  |         const fetchHostList = async () => { | 
 |  |  |             const resp = await Http.doGet('api/auth/host'); | 
 |  |  |             const list = resp.data.map(item => ({ | 
 |  |  |                 label: item.name, | 
 |  |  |                 value: item.id | 
 |  |  |             })); | 
 |  |  |             setHostList(list); | 
 |  |  |             if (list && list.length > 0) { | 
 |  |  |                 form.setFieldsValue({ | 
 |  |  |                     hostId: list[0].value | 
 |  |  |                 }); | 
 |  |  |             } | 
 |  |  |         } | 
 |  |  |         fetchHostList(); | 
 |  |  |     }, []); | 
 |  |  |  | 
 |  |  |     const fetchUserInfo = async () => { | 
 |  |  |         const userInfo = await initialState?.fetchUserInfo?.(); | 
 |  |  |         if (userInfo) { | 
 |  |  |             flushSync(() => { | 
 |  |  |                 setInitialState((s) => ({ | 
 |  |  |                     ...s, | 
 |  |  |                     currentUser: userInfo, | 
 |  |  |                 })); | 
 |  |  |             }); | 
 |  |  |         } | 
 |  |  |     }; | 
 |  |  |  | 
 |  |  |  | 
 |  |  |     const handleSubmit = async (values) => { | 
 |  |  |         try { | 
 |  |  |             const r = await request('/api/login', { | 
 |  |  |                 method: 'POST', | 
 |  |  |                 headers: { | 
 |  |  |                     'Content-Type': 'application/json' | 
 |  |  |                 }, | 
 |  |  |                 data: values | 
 |  |  |             }) | 
 |  |  |  | 
 |  |  |             if (r.code === 200) { | 
 |  |  |                 localStorage.removeItem("rememberData"); | 
 |  |  |                 if (rememberMe) { | 
 |  |  |                     setRememberData({ | 
 |  |  |                         username: values.username, | 
 |  |  |                         password: values.password | 
 |  |  |                     }) | 
 |  |  |                 } | 
 |  |  |                 message.success(intl.formatMessage({ | 
 |  |  |                     id: 'pages.login.success', | 
 |  |  |                     defaultMessage: '登录成功!', | 
 |  |  |                 })); | 
 |  |  |                 setToken(r.data.accessToken, values.autoLogin); | 
 |  |  |                 await fetchUserInfo(); | 
 |  |  |                 const urlParams = new URL(window.location.href).searchParams; | 
 |  |  |                 history.push(urlParams.get('redirect') || '/'); | 
 |  |  |                 return; | 
 |  |  |             } | 
 |  |  |             setStatus(r.code); | 
 |  |  |         } catch (error) { | 
 |  |  |             console.log(error); | 
 |  |  |             message.error(intl.formatMessage({ | 
 |  |  |                 id: 'pages.login.failure', | 
 |  |  |                 defaultMessage: '登录失败,请重试!', | 
 |  |  |             })); | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     return ( | 
 |  |  |         <div | 
 |  |  |             style={{ | 
 |  |  |                 backgroundColor: 'white', | 
 |  |  |                 height: '100vh', | 
 |  |  |             }} | 
 |  |  |         > | 
 |  |  |             <LoginFormPage | 
 |  |  |                 form={form} | 
 |  |  |                 backgroundImageUrl="https://mdn.alipayobjects.com/huamei_gcee1x/afts/img/A*y0ZTS6WLwvgAAAAAAAAAAAAADml6AQ/fmt.webp" | 
 |  |  |                 logo={logo} | 
 |  |  |                 backgroundVideoUrl="https://gw.alipayobjects.com/v/huamei_gcee1x/afts/video/jXRBRK_VAwoAAAAAAAAAAAAAK4eUAQBr" | 
 |  |  |                 // title="陆晓涛" | 
 |  |  |                 // subTitle="陆晓涛..." | 
 |  |  |                 containerStyle={{ | 
 |  |  |                     backgroundColor: 'rgba(0, 0, 0,0.65)', | 
 |  |  |                     backdropFilter: 'blur(4px)', | 
 |  |  |                 }} | 
 |  |  |                 onFinish={async (values) => { | 
 |  |  |                     await handleSubmit(values); | 
 |  |  |                 }} | 
 |  |  |                 initialValue={{ | 
 |  |  |                 }} | 
 |  |  |             > | 
 |  |  |                 <Tabs | 
 |  |  |                     centered | 
 |  |  |                     activeKey={loginType} | 
 |  |  |                     onChange={(activeKey) => setLoginType(activeKey)} | 
 |  |  |                 > | 
 |  |  |                     <Tabs.TabPane key={'account'} tab={'账号密码登录'} /> | 
 |  |  |                     <Tabs.TabPane key={'phone'} tab={'手机号登录'} /> | 
 |  |  |                 </Tabs> | 
 |  |  |                 {loginType === 'account' && ( | 
 |  |  |                     <> | 
 |  |  |                         <ProFormSelect | 
 |  |  |                             className="centered-select" | 
 |  |  |                             name="hostId" | 
 |  |  |                             placeholder="机构:" | 
 |  |  |                             rules={[ | 
 |  |  |                                 { | 
 |  |  |                                     required: true, | 
 |  |  |                                     message: '请选择机构!', | 
 |  |  |                                 }, | 
 |  |  |                             ]} | 
 |  |  |                             options={hostList} | 
 |  |  |                         /> | 
 |  |  |                         <ProFormText | 
 |  |  |                             name="username" | 
 |  |  |                             fieldProps={{ | 
 |  |  |                                 size: 'large', | 
 |  |  |                                 prefix: ( | 
 |  |  |                                     <UserOutlined | 
 |  |  |                                         style={{ | 
 |  |  |                                             color: token.colorText, | 
 |  |  |                                         }} | 
 |  |  |                                         className={'prefixIcon'} | 
 |  |  |                                     /> | 
 |  |  |                                 ), | 
 |  |  |                             }} | 
 |  |  |                             placeholder={'用户名: '} | 
 |  |  |                             rules={[ | 
 |  |  |                                 { | 
 |  |  |                                     required: true, | 
 |  |  |                                     message: '请输入用户名!', | 
 |  |  |                                 }, | 
 |  |  |                             ]} | 
 |  |  |                         /> | 
 |  |  |                         <ProFormText.Password | 
 |  |  |                             name="password" | 
 |  |  |                             fieldProps={{ | 
 |  |  |                                 size: 'large', | 
 |  |  |                                 prefix: ( | 
 |  |  |                                     <LockOutlined | 
 |  |  |                                         style={{ | 
 |  |  |                                             color: token.colorText, | 
 |  |  |                                         }} | 
 |  |  |                                         className={'prefixIcon'} | 
 |  |  |                                     /> | 
 |  |  |                                 ), | 
 |  |  |                             }} | 
 |  |  |                             placeholder={'密码: '} | 
 |  |  |                             rules={[ | 
 |  |  |                                 { | 
 |  |  |                                     required: true, | 
 |  |  |                                     message: '请输入密码!', | 
 |  |  |                                 }, | 
 |  |  |                             ]} | 
 |  |  |                         /> | 
 |  |  |                     </> | 
 |  |  |                 )} | 
 |  |  |                 {status !== 200 && loginType === 'account' && ( | 
 |  |  |                     <LoginMessage | 
 |  |  |                         content={'账户或密码错误'} | 
 |  |  |                     /> | 
 |  |  |                 )} | 
 |  |  |                 {loginType === 'phone' && ( | 
 |  |  |                     <> | 
 |  |  |                         <ProFormSelect | 
 |  |  |                             className="centered-select" | 
 |  |  |                             name="hostId" | 
 |  |  |                             placeholder="机构:" | 
 |  |  |                             rules={[ | 
 |  |  |                                 { | 
 |  |  |                                     required: true, | 
 |  |  |                                     message: '请选择机构!', | 
 |  |  |                                 }, | 
 |  |  |                             ]} | 
 |  |  |                             options={hostList} | 
 |  |  |                         /> | 
 |  |  |                         <ProFormText | 
 |  |  |                             fieldProps={{ | 
 |  |  |                                 size: 'large', | 
 |  |  |                                 prefix: ( | 
 |  |  |                                     <MobileOutlined | 
 |  |  |                                         style={{ | 
 |  |  |                                             color: token.colorText, | 
 |  |  |                                         }} | 
 |  |  |                                         className={'prefixIcon'} | 
 |  |  |                                     /> | 
 |  |  |                                 ), | 
 |  |  |                             }} | 
 |  |  |                             name="mobile" | 
 |  |  |                             placeholder={'手机号'} | 
 |  |  |                             rules={[ | 
 |  |  |                                 { | 
 |  |  |                                     required: true, | 
 |  |  |                                     message: '请输入手机号!', | 
 |  |  |                                 }, | 
 |  |  |                                 { | 
 |  |  |                                     pattern: /^1\d{10}$/, | 
 |  |  |                                     message: '手机号格式错误!', | 
 |  |  |                                 }, | 
 |  |  |                             ]} | 
 |  |  |                         /> | 
 |  |  |                         <ProFormCaptcha | 
 |  |  |                             fieldProps={{ | 
 |  |  |                                 size: 'large', | 
 |  |  |                                 prefix: ( | 
 |  |  |                                     <LockOutlined | 
 |  |  |                                         style={{ | 
 |  |  |                                             color: token.colorText, | 
 |  |  |                                         }} | 
 |  |  |                                         className={'prefixIcon'} | 
 |  |  |                                     /> | 
 |  |  |                                 ), | 
 |  |  |                             }} | 
 |  |  |                             captchaProps={{ | 
 |  |  |                                 size: 'large', | 
 |  |  |                             }} | 
 |  |  |                             placeholder={'请输入验证码'} | 
 |  |  |                             captchaTextRender={(timing, count) => { | 
 |  |  |                                 if (timing) { | 
 |  |  |                                     return `${count} ${'获取验证码'}`; | 
 |  |  |                                 } | 
 |  |  |                                 return '获取验证码'; | 
 |  |  |                             }} | 
 |  |  |                             name="captcha" | 
 |  |  |                             rules={[ | 
 |  |  |                                 { | 
 |  |  |                                     required: true, | 
 |  |  |                                     message: '请输入验证码!', | 
 |  |  |                                 }, | 
 |  |  |                             ]} | 
 |  |  |                             onGetCaptcha={async () => { | 
 |  |  |                                 // message.success('获取验证码成功!验证码为:1234'); | 
 |  |  |                                 message.warning('未开启手机号登录! '); | 
 |  |  |                             }} | 
 |  |  |                         /> | 
 |  |  |                     </> | 
 |  |  |                 )} | 
 |  |  |                 <div | 
 |  |  |                     style={{ | 
 |  |  |                         marginBlockEnd: 24, | 
 |  |  |                     }} | 
 |  |  |                 > | 
 |  |  |                     <ProFormCheckbox | 
 |  |  |                         noStyle | 
 |  |  |                         name="autoLogin" | 
 |  |  |                         onChange={(e) => { | 
 |  |  |                             setRememberMe(e.target.checked); | 
 |  |  |                         }} | 
 |  |  |                     > | 
 |  |  |                         自动登录 | 
 |  |  |                     </ProFormCheckbox> | 
 |  |  |                 </div> | 
 |  |  |             </LoginFormPage> | 
 |  |  |         </div> | 
 |  |  |     ); | 
 |  |  | }; | 
 |  |  |  | 
 |  |  | export default () => { | 
 |  |  |     return ( | 
 |  |  |         <ProConfigProvider dark> | 
 |  |  |             <Page /> | 
 |  |  |         </ProConfigProvider> | 
 |  |  |     ); | 
 |  |  | }; |