oak-general-business/src/components/user/login/web.tsx

368 lines
14 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.

// @ts-nocheck
// Segmented这个对象在antd里的声明是错误的
import React, { useEffect, useState } from 'react';
import {
isMobile,
isPassword,
isCaptcha,
} from 'oak-domain/lib/utils/validator';
import { Form, Input, Button, Checkbox, Typography, Segmented, Divider, Space, Tooltip, Image } from 'antd';
import {
LockOutlined,
MobileOutlined,
QrcodeOutlined,
DesktopOutlined,
MailOutlined,
ExclamationCircleOutlined,
RightOutlined,
LinkOutlined,
} from '@ant-design/icons';
import { WebComponentProps } from 'oak-frontend-base';
import { EntityDict } from '../../../oak-app-domain';
import classNames from 'classnames';
import Style from './web.module.less';
import WeChatLoginQrCode from '../../common/weChatLoginQrCode';
import WechatLoginQrCodeForPublic from '../../wechatLogin/qrCode';
import WeChatLoginGrant from '../../common/weChatLoginGrant';
import SmsLogin from './sms';
import PasswordLogin from './password';
import EmailLogin from './email';
type Option = {
label: string;
value: string;
};
export default function Render(
props: WebComponentProps<
EntityDict,
'token',
false,
{
loginMode?: number;
appId: string;
loading: boolean;
width: string;
isSupportWechatGrant: boolean;
domain?: string;
disabled?: string;
redirectUri: string;
url: string;
passportTypes: EntityDict['passport']['Schema']['type'][];
callback: (() => void) | undefined;
inputOptions: Option[];
scanOptions: Option[];
smsDigit: number;
emailDigit: number;
pwdAllowMobile: boolean;
pwdAllowEmail: boolean;
pwdAllowLoginName: boolean;
pwdMode: 'all' | 'plain' | 'sha1';
allowRegister: boolean;
oauthOptions: {
name: string,
value: string,
logo?: string,
}[];
goRegister: () => void;
goOauthLogin: (oauthProviderId: string) => void;
},
{
setLoginMode: (value: number) => void;
}
>
) {
const { data, methods } = props;
const {
width,
loading,
loginMode,
appId,
domain,
isSupportWechatGrant,
disabled,
redirectUri,
url,
passportTypes,
callback,
inputOptions,
scanOptions,
smsDigit,
emailDigit,
pwdAllowMobile,
pwdAllowEmail,
pwdAllowLoginName,
pwdMode,
allowRegister,
oauthOptions,
goRegister,
goOauthLogin,
} = data;
const { t, setLoginMode, } = methods;
let redirectUri2 = redirectUri;
if (!(redirectUri.startsWith('https') || redirectUri.startsWith('http'))) {
const hostname = domain || window.location.hostname;
const port = window.location.port ? `:${window.location.port}` : '';
const path = redirectUri.startsWith('/') ? redirectUri : `/${redirectUri}`;
redirectUri2 = encodeURIComponent(
`${window.location.protocol}//${hostname}${port}${path}`
);
}
// 构建微信扫码所需state参数url存在扫码后重定向url否则返回上一页
let state = '';
if (url) {
state = encodeURIComponent(decodeURIComponent(url));
}
const [showInput, setShowInput] = useState(true);
useEffect(() => {
if (loginMode === 'sms' || loginMode === 'email' || loginMode === 'password') {
setShowInput(true)
} else {
setShowInput(false)
}
}, [loginMode]);
const InputMethods = inputOptions && inputOptions.length > 0 ? (
// <div className={Style['loginbox-methods']}>
// <Divider plain style={{ fontSize: 13, color: '#808080', }}>{t('otherMethods')}</Divider>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 24 }}>
{inputOptions.map((ele) => {
let icon = <></>;
if (ele.value === 'sms') {
icon = <MobileOutlined />;
} else if (ele.value === 'password') {
icon = <DesktopOutlined />;
} else if (ele.value === 'email') {
icon = <MailOutlined />;
}
return (
<Space
key={ele.value}
size={4}
style={{ cursor: 'pointer' }}
onClick={() => {
setLoginMode(ele.value)
}}
>
{icon}
<div>{ele.label}</div>
</Space>
)
})}
</div>
// </div>
) : <></>
const ScanMethods = scanOptions && scanOptions.length > 0 ? (
// <div className={Style['loginbox-methods']}>
// <Divider plain style={{ fontSize: 13, color: '#808080', }}>{t('otherMethods')}</Divider>
<Space
style={{ cursor: 'pointer' }}
onClick={() => {
setLoginMode(scanOptions[0].value)
}}
>
<QrcodeOutlined />
<div>{t('scanLogin')}</div>
</Space>
// </div>
) : <></>
const OauthMethods = oauthOptions && oauthOptions.length > 0 ? (
// <div className={Style['loginbox-methods']}>
// <Divider plain style={{ fontSize: 13, color: '#808080', }}>{t('otherMethods')}</Divider>
<Space
style={{ cursor: 'pointer' }}
>
{oauthOptions?.map((ele) => (
<Tooltip title={ele.name}>
<Image
preview={false}
width={20}
height={20}
src={ele.logo}
onClick={() => {
goOauthLogin(ele.value)
}}
placeholder={<LinkOutlined />}
/>
</Tooltip>
))}
</Space>
// </div>
) : <></>
const Tip = <div className={Style['loginbox-tip']}>
<Space>
<ExclamationCircleOutlined />
<div>{t('tip')}</div>
</Space>
</div>
return (
<div
className={classNames(Style['loginbox-wrap'], {
[Style['loginbox-wrap__mobile']]: width === 'xs',
})}
>
<div className={Style['loginbox-hd']}>
<Segmented
className={Style.segmented}
value={loginMode}
block
onChange={setLoginMode}
options={showInput ? inputOptions.map((ele) => ({
label: ele.label,
value: ele.value,
})) : scanOptions.map((ele) => ({
label: ele.label,
value: ele.value,
}))}
></Segmented>
</div>
<div
className={classNames(Style['loginbox-bd'], {
[Style['loginbox-bd__grant']]: isSupportWechatGrant,
})}
>
{isSupportWechatGrant ? (
<div className={Style['loginbox-grant']}>
<WeChatLoginGrant
disabled={!!disabled}
disableText={disabled}
appId={appId}
scope="snsapi_userinfo"
redirectUri={redirectUri2}
state={state}
/>
</div>
) : (
<>
{showInput ? (
<>
<div
className={Style['loginbox-password']}
style={{
display: loginMode === 'password' ? 'block' : 'none',
}}
>
<PasswordLogin
disabled={disabled}
url={url}
callback={callback}
pwdAllowMobile={pwdAllowMobile}
pwdAllowEmail={pwdAllowEmail}
pwdAllowLoginName={pwdAllowLoginName}
pwdMode={pwdMode}
/>
{allowRegister && (
<div className={Style['loginbox-register']}>
{/* <Button type='link' iconPosition='end' icon={<RightOutlined />}>去注册</Button> */}
<Button type='link' onClick={() => {
goRegister && goRegister()
}}>{`${t('goRegister')} >`}</Button>
</div>
)}
</div>
<div
className={Style['loginbox-mobile']}
style={{
display: loginMode === 'sms' ? 'block' : 'none',
}}
>
<SmsLogin
disabled={disabled}
url={url}
callback={callback}
digit={smsDigit}
/>
{Tip}
</div>
<div
className={Style['loginbox-email']}
style={{
display: loginMode === 'email' ? 'block' : 'none',
}}
>
<EmailLogin
disabled={disabled}
url={url}
callback={callback}
digit={emailDigit}
/>
{Tip}
</div>
{(scanOptions?.length > 0 || oauthOptions?.length > 0) ? (
<div className={Style['loginbox-methods']}>
<Divider plain style={{ fontSize: 13, color: '#808080', }}>{t('otherMethods')}</Divider>
<Space split={<Divider type="vertical" />}>
{ScanMethods}
{OauthMethods}
</Space>
</div>
) : (<></>)}
</>
) : (
<>
{loginMode === 'wechatWeb' &&
<div
className={Style['loginbox-qrcode']}
>
<WeChatLoginQrCode
disabled={!!disabled}
disableText={disabled}
appId={appId}
scope="snsapi_login"
redirectUri={redirectUri2}
state={state}
/>
{Tip}
</div>}
{loginMode === 'wechatPublicForWeb' && <div
className={Style['loginbox-qrcode']}
>
<WechatLoginQrCodeForPublic
type="login"
oakPath="$login-wechatLogin/qrCode"
oakAutoUnmount={true}
url={state}
size={180}
/>
{Tip}
</div>}
{loginMode === 'wechatMpForWeb' && <div
className={Style['loginbox-qrcode']}
>
<WechatLoginQrCodeForPublic
type="login"
oakPath="$login-wechatLogin/qrCode"
oakAutoUnmount={true}
url={state}
size={180}
qrCodeType={'wechatMpDomainUrl'}
/>
{Tip}
</div>}
{(inputOptions?.length > 0 || oauthOptions?.length > 0) ? (
<div className={Style['loginbox-methods']}>
<Divider plain style={{ fontSize: 13, color: '#808080', }}>{t('otherMethods')}</Divider>
<Space split={<Divider type="vertical" />}>
{InputMethods}
{OauthMethods}
</Space>
</div>
) : (<></>)}
</>
)}
</>
)}
</div>
</div >
);
}