|
@@ -20,6 +20,8 @@ import Settings from '../../../../config/defaultSettings';
|
|
|
import { api } from '@/services/env';
|
|
|
import SelectCompany from './selectCompany';
|
|
|
import { getCode } from '@/services/user/login';
|
|
|
+import { isInMobileMode } from '@/utils';
|
|
|
+import { VIDEO_LIST } from '@/mocks/video';
|
|
|
|
|
|
const useStyles = createStyles(({ token }) => {
|
|
|
return {
|
|
@@ -45,6 +47,12 @@ const useStyles = createStyles(({ token }) => {
|
|
|
backgroundColor: token.colorBgTextHover,
|
|
|
},
|
|
|
},
|
|
|
+ login_page: {
|
|
|
+ position: 'relative',
|
|
|
+ width: '100%',
|
|
|
+ height: '100vh',
|
|
|
+ overflow: 'hidden'
|
|
|
+ },
|
|
|
container: {
|
|
|
display: 'flex',
|
|
|
flexDirection: 'column',
|
|
@@ -53,7 +61,16 @@ const useStyles = createStyles(({ token }) => {
|
|
|
backgroundImage:
|
|
|
"url('https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/V-_oS6r-i7wAAAAAAAAAAAAAFl94AQBr')",
|
|
|
backgroundSize: '100% 100%',
|
|
|
+ position: 'absolute',
|
|
|
+ width: '100%',
|
|
|
+ top: 0,
|
|
|
+ left: 0
|
|
|
},
|
|
|
+ top_video: {
|
|
|
+ width: '100%',
|
|
|
+ height: '100%',
|
|
|
+ objectFit: 'cover'
|
|
|
+ }
|
|
|
};
|
|
|
});
|
|
|
|
|
@@ -81,8 +98,14 @@ const Login: React.FC = () => {
|
|
|
const { styles } = useStyles();
|
|
|
const [codeType, setCodeType] = useState<1 | 2>(1)//1钉钉验证码 2短信验证码
|
|
|
const [loading, setLoading] = useState<boolean>(false)
|
|
|
+ const [backUrl, setBackUrl] = useState<string>()
|
|
|
/******************************/
|
|
|
|
|
|
+ useEffect(() => {
|
|
|
+ const videoLength = VIDEO_LIST.length
|
|
|
+ setBackUrl(VIDEO_LIST[Math.floor(Math.random() * videoLength)])
|
|
|
+ }, [VIDEO_LIST])
|
|
|
+
|
|
|
// 获取TOKEN
|
|
|
useEffect(() => {
|
|
|
const hash = window.location.hash
|
|
@@ -166,127 +189,139 @@ const Login: React.FC = () => {
|
|
|
const { fail, code } = userLoginState;
|
|
|
|
|
|
return (
|
|
|
- <div className={styles.container}>
|
|
|
- <Helmet>
|
|
|
- <title>登录页 - {Settings.title}</title>
|
|
|
- </Helmet>
|
|
|
- <div style={{ flex: '1', padding: '32px 0' }}>
|
|
|
- {(localStorage.getItem('Admin-Token') && companyList?.length > 0) ? <SelectCompany
|
|
|
- companyList={companyList}
|
|
|
- loading={false}
|
|
|
- setCompanyHandle={setCompanyHandle}
|
|
|
- logOut={logOut}
|
|
|
- /> : <LoginForm
|
|
|
- contentStyle={{
|
|
|
- minWidth: 280,
|
|
|
- maxWidth: '75vw',
|
|
|
- }}
|
|
|
- title={Settings.title}
|
|
|
- subTitle={'趣程数字业务指挥中心(整合公众号/企微/广告投放)'}
|
|
|
- onFinish={async (values) => {
|
|
|
- await handleSubmit(values as API.LoginParams);
|
|
|
- }}
|
|
|
- // initialValues={{ phone: 15394409016 }}
|
|
|
- loading={loading}
|
|
|
- >
|
|
|
- <Tabs
|
|
|
- activeKey={type}
|
|
|
- onChange={setType}
|
|
|
- centered
|
|
|
- items={[
|
|
|
- {
|
|
|
- key: 'mobile',
|
|
|
- label: '手机号登录',
|
|
|
- },
|
|
|
- ]}
|
|
|
- />
|
|
|
+ <div className={`${styles.login_page} ${isInMobileMode() ? 'mobile_page' : 'window_page'}`}>
|
|
|
+ {(!isInMobileMode() && backUrl) &&
|
|
|
+ <video
|
|
|
+ src={backUrl}
|
|
|
+ muted
|
|
|
+ loop
|
|
|
+ autoPlay
|
|
|
+ preload="metadata"
|
|
|
+ poster="https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/V-_oS6r-i7wAAAAAAAAAAAAAFl94AQBr"
|
|
|
+ playsInline
|
|
|
+ className={styles.top_video}
|
|
|
+ ></video>}
|
|
|
+ <div className={styles.container}>
|
|
|
+ <Helmet>
|
|
|
+ <title>登录页 - {Settings.title}</title>
|
|
|
+ </Helmet>
|
|
|
+ <div style={{ flex: '1', padding: '32px 0' }}>
|
|
|
+ {(localStorage.getItem('Admin-Token') && companyList?.length > 0) ? <SelectCompany
|
|
|
+ companyList={companyList}
|
|
|
+ loading={false}
|
|
|
+ setCompanyHandle={setCompanyHandle}
|
|
|
+ logOut={logOut}
|
|
|
+ /> : <LoginForm
|
|
|
+ contentStyle={{
|
|
|
+ minWidth: 280,
|
|
|
+ maxWidth: '75vw',
|
|
|
+ }}
|
|
|
+ title={Settings.title}
|
|
|
+ subTitle={'趣程数字业务指挥中心(整合公众号/企微/广告投放)'}
|
|
|
+ onFinish={async (values) => {
|
|
|
+ await handleSubmit(values as API.LoginParams);
|
|
|
+ }}
|
|
|
+ loading={loading}
|
|
|
+ >
|
|
|
+ <Tabs
|
|
|
+ activeKey={type}
|
|
|
+ onChange={setType}
|
|
|
+ centered
|
|
|
+ items={[
|
|
|
+ {
|
|
|
+ key: 'mobile',
|
|
|
+ label: '手机号登录',
|
|
|
+ },
|
|
|
+ ]}
|
|
|
+ />
|
|
|
|
|
|
- {fail && code === 500 && <LoginMessage content="验证码错误" />}
|
|
|
- {type === 'mobile' && (
|
|
|
- <>
|
|
|
- <ProFormText
|
|
|
- fieldProps={{
|
|
|
- size: 'large',
|
|
|
- prefix: <MobileOutlined />,
|
|
|
- }}
|
|
|
- name="phone"
|
|
|
- placeholder={'手机号'}
|
|
|
- rules={[
|
|
|
+ {fail && code === 500 && <LoginMessage content="验证码错误" />}
|
|
|
+ {type === 'mobile' && (
|
|
|
+ <>
|
|
|
+ <ProFormText
|
|
|
+ fieldProps={{
|
|
|
+ size: 'large',
|
|
|
+ prefix: <MobileOutlined />,
|
|
|
+ }}
|
|
|
+ name="phone"
|
|
|
+ placeholder={'手机号'}
|
|
|
+ rules={[
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: '请输入手机号!',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ pattern: /^1\d{10}$/,
|
|
|
+ message: '手机号格式错误!',
|
|
|
+ },
|
|
|
+ ]}
|
|
|
+ />
|
|
|
+ <ProFormCaptcha
|
|
|
+ fieldProps={{
|
|
|
+ size: 'large',
|
|
|
+ prefix: <LockOutlined />,
|
|
|
+ }}
|
|
|
+ captchaProps={{
|
|
|
+ size: 'large',
|
|
|
+ }}
|
|
|
+ placeholder={'请输入验证码'}
|
|
|
+ captchaTextRender={(timing, count) => {
|
|
|
+ if (timing) {
|
|
|
+ return `${count} 获取验证码`;
|
|
|
+ }
|
|
|
+ return '获取验证码';
|
|
|
+ }}
|
|
|
+ name="code"
|
|
|
+ rules={[
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: '请输入验证码!',
|
|
|
+ },
|
|
|
+ ]}
|
|
|
+ phoneName={'phone'}
|
|
|
+ onGetCaptcha={async (phone) => {
|
|
|
+ try {
|
|
|
+ if (!phone) {
|
|
|
+ message.error('请输入手机号!');
|
|
|
+ return Promise.reject('请输入手机号!');
|
|
|
+ }
|
|
|
+ const result = await getCode({ phone, code: codeType });
|
|
|
+ if (result?.data) {
|
|
|
+ message.success('获取验证码成功!');
|
|
|
+ return;
|
|
|
+ } else {
|
|
|
+ return Promise.reject('获取验证码失败,请稍后再试!');
|
|
|
+ }
|
|
|
+ } catch (error) { }
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ </>
|
|
|
+ )}
|
|
|
+ <div
|
|
|
+ style={{
|
|
|
+ marginBlockEnd: 40,
|
|
|
+ textAlign: 'center'
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <Radio.Group
|
|
|
+ value={codeType}
|
|
|
+ onChange={(e) => setCodeType(e.target.value)}
|
|
|
+ options={[
|
|
|
{
|
|
|
- required: true,
|
|
|
- message: '请输入手机号!',
|
|
|
+ label: '钉钉验证码',
|
|
|
+ value: 1,
|
|
|
},
|
|
|
{
|
|
|
- pattern: /^1\d{10}$/,
|
|
|
- message: '手机号格式错误!',
|
|
|
- },
|
|
|
- ]}
|
|
|
- />
|
|
|
- <ProFormCaptcha
|
|
|
- fieldProps={{
|
|
|
- size: 'large',
|
|
|
- prefix: <LockOutlined />,
|
|
|
- }}
|
|
|
- captchaProps={{
|
|
|
- size: 'large',
|
|
|
- }}
|
|
|
- placeholder={'请输入验证码'}
|
|
|
- captchaTextRender={(timing, count) => {
|
|
|
- if (timing) {
|
|
|
- return `${count} 获取验证码`;
|
|
|
+ label: '手机验证码',
|
|
|
+ value: 2,
|
|
|
}
|
|
|
- return '获取验证码';
|
|
|
- }}
|
|
|
- name="code"
|
|
|
- rules={[
|
|
|
- {
|
|
|
- required: true,
|
|
|
- message: '请输入验证码!',
|
|
|
- },
|
|
|
]}
|
|
|
- phoneName={'phone'}
|
|
|
- onGetCaptcha={async (phone) => {
|
|
|
- try {
|
|
|
- if (!phone) {
|
|
|
- message.error('请输入手机号!');
|
|
|
- return Promise.reject('请输入手机号!');
|
|
|
- }
|
|
|
- const result = await getCode({ phone, code: codeType });
|
|
|
- if (result?.data) {
|
|
|
- message.success('获取验证码成功!');
|
|
|
- return;
|
|
|
- } else {
|
|
|
- return Promise.reject('获取验证码失败,请稍后再试!');
|
|
|
- }
|
|
|
- } catch (error) { }
|
|
|
- }}
|
|
|
/>
|
|
|
- </>
|
|
|
- )}
|
|
|
- <div
|
|
|
- style={{
|
|
|
- marginBlockEnd: 40,
|
|
|
- textAlign: 'center'
|
|
|
- }}
|
|
|
- >
|
|
|
- <Radio.Group
|
|
|
- value={codeType}
|
|
|
- onChange={(e) => setCodeType(e.target.value)}
|
|
|
- options={[
|
|
|
- {
|
|
|
- label: '钉钉验证码',
|
|
|
- value: 1,
|
|
|
- },
|
|
|
- {
|
|
|
- label: '手机验证码',
|
|
|
- value: 2,
|
|
|
- }
|
|
|
- ]}
|
|
|
- />
|
|
|
- </div>
|
|
|
- </LoginForm>}
|
|
|
+ </div>
|
|
|
+ </LoginForm>}
|
|
|
+ </div>
|
|
|
+ <Footer />
|
|
|
</div>
|
|
|
- <Footer />
|
|
|
</div>
|
|
|
);
|
|
|
};
|