登录修改
This commit is contained in:
parent
a39d4e2311
commit
8a258d55d4
|
|
@ -8,9 +8,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&_dev {
|
&_dev {
|
||||||
height: 280px;
|
// height: 280px;
|
||||||
border: 1px dashed var(--oak-color-primary);
|
border: 1px dashed var(--oak-color-primary);
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
|
||||||
&_header {
|
&_header {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -36,7 +37,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&_btn {
|
&_btn {
|
||||||
margin-top: 16px;
|
// margin-top: 16px;
|
||||||
width: 80px;
|
width: 80px;
|
||||||
height: 80px;
|
height: 80px;
|
||||||
border-radius: 40px;
|
border-radius: 40px;
|
||||||
|
|
@ -102,16 +103,16 @@
|
||||||
|
|
||||||
&_disable {
|
&_disable {
|
||||||
&_border {
|
&_border {
|
||||||
height: 202px;
|
height: 220px;
|
||||||
width: 202px;
|
width: 220px;
|
||||||
margin: 15px;
|
// margin: 15px;
|
||||||
background-color: #f5f7fa;
|
background-color: #f5f7fa;
|
||||||
color: rgba(0, 0, 0, .4);
|
color: rgba(0, 0, 0, .4);
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding: 15px;
|
// padding: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&_info {
|
&_info {
|
||||||
|
|
@ -124,7 +125,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&_err {
|
&_err {
|
||||||
height: 280px;
|
// height: 280px;
|
||||||
border: 1px dashed var(--oak-color-primary);
|
border: 1px dashed var(--oak-color-primary);
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,8 @@ export default OakComponent({
|
||||||
isSupportWechatGrant: false,
|
isSupportWechatGrant: false,
|
||||||
domain: undefined,
|
domain: undefined,
|
||||||
passportTypes: [],
|
passportTypes: [],
|
||||||
options: [],
|
inputOptions: [],
|
||||||
|
scanOptions: [],
|
||||||
allowSms: false,
|
allowSms: false,
|
||||||
allowPassword: false,
|
allowPassword: false,
|
||||||
allowWechatMp: false,
|
allowWechatMp: false,
|
||||||
|
|
@ -28,38 +29,44 @@ export default OakComponent({
|
||||||
return {};
|
return {};
|
||||||
},
|
},
|
||||||
listeners: {
|
listeners: {
|
||||||
'onlyPassword,onlyCaptcha'(prev, next) {
|
// 'onlyPassword,onlyCaptcha'(prev, next) {
|
||||||
let loginMode = this.state.loginMode, options = this.state.options;
|
// let loginMode = this.state.loginMode, inputOptions = this.state.inputOptions, scanOptions = this.state.scanOptions;
|
||||||
if (next.onlyPassword) {
|
// if (next.onlyPassword) {
|
||||||
loginMode = 'password';
|
// loginMode = 'password';
|
||||||
options = [{
|
// inputOptions = [{
|
||||||
label: this.t('passport:v.type.password'),
|
// label: this.t('passport:v.type.password'),
|
||||||
value: 'password',
|
// value: 'password',
|
||||||
}];
|
// }];
|
||||||
}
|
// } else if (next.onlyCaptcha) {
|
||||||
else if (next.onlyCaptcha) {
|
// loginMode = 'sms';
|
||||||
loginMode = 'sms';
|
// inputOptions = [{
|
||||||
options = [{
|
// label: this.t('passport:v.type.sms'),
|
||||||
label: this.t('passport:v.type.sms'),
|
// value: 'sms',
|
||||||
value: 'sms',
|
// }];
|
||||||
}];
|
// } else {
|
||||||
}
|
// const { passportTypes } = this.state;
|
||||||
else {
|
// if (passportTypes && passportTypes.length > 0) {
|
||||||
const { passportTypes } = this.state;
|
// passportTypes.forEach((ele: EntityDict['passport']['Schema']['type']) => {
|
||||||
if (passportTypes && passportTypes.length > 0) {
|
// if (ele === 'sms' || ele === 'email' || ele === 'password') {
|
||||||
passportTypes.forEach((ele) => {
|
// inputOptions.push({
|
||||||
options.push({
|
// label: this.t(`passport:v.type.${ele}`),
|
||||||
label: this.t(`passport:v.type.${ele}`),
|
// value: ele
|
||||||
value: ele
|
// })
|
||||||
});
|
// } else if (ele === 'wechatMpForWeb' || ele === 'wechatPublicForWeb') {
|
||||||
});
|
// scanOptions.push({
|
||||||
}
|
// label: this.t(`passport:v.type.${ele}`),
|
||||||
}
|
// value: ele
|
||||||
this.setState({
|
// })
|
||||||
loginMode,
|
// }
|
||||||
options,
|
// });
|
||||||
});
|
// }
|
||||||
}
|
// }
|
||||||
|
// this.setState({
|
||||||
|
// loginMode,
|
||||||
|
// inputOptions,
|
||||||
|
// scanOptions,
|
||||||
|
// })
|
||||||
|
// }
|
||||||
},
|
},
|
||||||
lifetimes: {
|
lifetimes: {
|
||||||
async ready() {
|
async ready() {
|
||||||
|
|
@ -67,30 +74,42 @@ export default OakComponent({
|
||||||
const { result: applicationPassports } = await this.features.cache.exec('getApplicationPassports', { applicationId: application.id });
|
const { result: applicationPassports } = await this.features.cache.exec('getApplicationPassports', { applicationId: application.id });
|
||||||
const defaultPassport = applicationPassports.find((ele) => ele.isDefault);
|
const defaultPassport = applicationPassports.find((ele) => ele.isDefault);
|
||||||
const passportTypes = applicationPassports.map((ele) => ele.passport.type);
|
const passportTypes = applicationPassports.map((ele) => ele.passport.type);
|
||||||
|
const { onlyCaptcha, onlyPassword } = this.props;
|
||||||
let loginMode = (await this.load(LOGIN_MODE)) || defaultPassport.passport.type;
|
let loginMode = (await this.load(LOGIN_MODE)) || defaultPassport.passport.type;
|
||||||
let options = [];
|
let inputOptions = [], scanOptions = [];
|
||||||
if (this.props.onlyPassword) {
|
if (onlyPassword) {
|
||||||
loginMode = 'password';
|
loginMode = 'password';
|
||||||
options = [{
|
inputOptions = [{
|
||||||
label: this.t('passport:v.type.password'),
|
label: this.t('passport:v.type.password') + this.t('Login'),
|
||||||
value: 'password',
|
value: 'password',
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
else if (this.props.onlyCaptcha) {
|
else if (onlyCaptcha) {
|
||||||
loginMode = 'sms';
|
loginMode = 'sms';
|
||||||
options = [{
|
inputOptions = [{
|
||||||
label: this.t('passport:v.type.sms'),
|
label: this.t('passport:v.type.sms') + this.t('Login'),
|
||||||
value: 'sms',
|
value: 'sms',
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
passportTypes.forEach((ele) => {
|
passportTypes.forEach((ele) => {
|
||||||
options.push({
|
if (ele === 'sms' || ele === 'email' || ele === 'password') {
|
||||||
label: this.t(`passport:v.type.${ele}`),
|
inputOptions.push({
|
||||||
value: ele
|
label: this.t(`passport:v.type.${ele}`) + this.t('Login'),
|
||||||
});
|
value: ele
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (ele === 'wechatWeb' || ele === 'wechatMpForWeb' || ele === 'wechatPublicForWeb') {
|
||||||
|
scanOptions.push({
|
||||||
|
label: this.t(`passport:v.type.${ele}`) + this.t('Login'),
|
||||||
|
value: ele
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (!passportTypes.includes(loginMode)) {
|
||||||
|
loginMode = defaultPassport.passport.type;
|
||||||
|
}
|
||||||
const appType = application?.type;
|
const appType = application?.type;
|
||||||
const config = application?.config;
|
const config = application?.config;
|
||||||
let appId;
|
let appId;
|
||||||
|
|
@ -109,9 +128,9 @@ export default OakComponent({
|
||||||
domain = config2?.wechat?.domain;
|
domain = config2?.wechat?.domain;
|
||||||
}
|
}
|
||||||
else if (appType === 'wechatMp') {
|
else if (appType === 'wechatMp') {
|
||||||
allowSms = passportTypes.includes('sms');
|
allowSms = passportTypes.includes('sms') && !onlyPassword;
|
||||||
allowPassword = passportTypes.includes('password');
|
allowPassword = passportTypes.includes('password') && !onlyCaptcha;
|
||||||
allowWechatMp = passportTypes.includes('wechatMp');
|
allowWechatMp = passportTypes.includes('wechatMp') && !onlyCaptcha && !onlyPassword;
|
||||||
}
|
}
|
||||||
this.setState({
|
this.setState({
|
||||||
loginMode,
|
loginMode,
|
||||||
|
|
@ -119,7 +138,8 @@ export default OakComponent({
|
||||||
isSupportWechatGrant,
|
isSupportWechatGrant,
|
||||||
domain,
|
domain,
|
||||||
passportTypes,
|
passportTypes,
|
||||||
options,
|
inputOptions,
|
||||||
|
scanOptions,
|
||||||
allowSms,
|
allowSms,
|
||||||
allowPassword,
|
allowPassword,
|
||||||
allowWechatMp,
|
allowWechatMp,
|
||||||
|
|
|
||||||
|
|
@ -10,5 +10,8 @@
|
||||||
"Mobile": "请输入手机号",
|
"Mobile": "请输入手机号",
|
||||||
"Password": "请输入密码"
|
"Password": "请输入密码"
|
||||||
},
|
},
|
||||||
"resendAfter": "秒后可重发"
|
"resendAfter": "秒后可重发",
|
||||||
|
"otherMethods": "其他登录方式",
|
||||||
|
"scanLogin": "扫码登录",
|
||||||
|
"tip": "未注册用户首次登录将自动注册"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,8 @@ export default function Render(props: WebComponentProps<EntityDict, 'token', fal
|
||||||
url: string;
|
url: string;
|
||||||
passportTypes: EntityDict['passport']['Schema']['type'][];
|
passportTypes: EntityDict['passport']['Schema']['type'][];
|
||||||
callback: (() => void) | undefined;
|
callback: (() => void) | undefined;
|
||||||
options: Option[];
|
inputOptions: Option[];
|
||||||
|
scanOptions: Option[];
|
||||||
}, {
|
}, {
|
||||||
setLoginMode: (value: number) => void;
|
setLoginMode: (value: number) => void;
|
||||||
}>): React.JSX.Element;
|
}>): React.JSX.Element;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
// Segmented这个对象在antd里的声明是错误的
|
// Segmented这个对象在antd里的声明是错误的
|
||||||
import React from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { Segmented } from 'antd';
|
import { Segmented, Divider, Space } from 'antd';
|
||||||
|
import { MobileOutlined, QrcodeOutlined, DesktopOutlined, MailOutlined, ExclamationCircleOutlined, } from '@ant-design/icons';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import Style from './web.module.less';
|
import Style from './web.module.less';
|
||||||
import WeChatLoginQrCode from '../../common/weChatLoginQrCode';
|
import WeChatLoginQrCode from '../../common/weChatLoginQrCode';
|
||||||
|
|
@ -11,7 +12,7 @@ import SmsLogin from './sms';
|
||||||
import PasswordLogin from './password';
|
import PasswordLogin from './password';
|
||||||
export default function Render(props) {
|
export default function Render(props) {
|
||||||
const { data, methods } = props;
|
const { data, methods } = props;
|
||||||
const { width, loading, loginMode, appId, domain, isSupportWechatGrant, disabled, redirectUri, url, passportTypes, callback, options, } = data;
|
const { width, loading, loginMode, appId, domain, isSupportWechatGrant, disabled, redirectUri, url, passportTypes, callback, inputOptions, scanOptions, } = data;
|
||||||
const { t, setLoginMode } = methods;
|
const { t, setLoginMode } = methods;
|
||||||
let redirectUri2 = redirectUri;
|
let redirectUri2 = redirectUri;
|
||||||
if (!(redirectUri.startsWith('https') || redirectUri.startsWith('http'))) {
|
if (!(redirectUri.startsWith('https') || redirectUri.startsWith('http'))) {
|
||||||
|
|
@ -25,15 +26,65 @@ export default function Render(props) {
|
||||||
if (url) {
|
if (url) {
|
||||||
state = encodeURIComponent(decodeURIComponent(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 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 Tip = <div className={Style['loginbox-tip']}>
|
||||||
|
<Space>
|
||||||
|
<ExclamationCircleOutlined />
|
||||||
|
<div>{t('tip')}</div>
|
||||||
|
</Space>
|
||||||
|
</div>;
|
||||||
return (<div className={classNames(Style['loginbox-wrap'], {
|
return (<div className={classNames(Style['loginbox-wrap'], {
|
||||||
[Style['loginbox-wrap__mobile']]: width === 'xs',
|
[Style['loginbox-wrap__mobile']]: width === 'xs',
|
||||||
})}>
|
})}>
|
||||||
{options?.length > 1 ? (<div className={Style['loginbox-hd']}>
|
<div className={Style['loginbox-hd']}>
|
||||||
<Segmented className={Style.segmented} value={loginMode} block onChange={setLoginMode} options={options.map((ele) => ({
|
<Segmented className={Style.segmented} value={loginMode} block onChange={setLoginMode} options={showInput ? inputOptions.map((ele) => ({
|
||||||
label: ele.label,
|
label: ele.label,
|
||||||
value: ele.value,
|
value: ele.value,
|
||||||
}))}></Segmented>
|
})) : scanOptions.map((ele) => ({
|
||||||
</div>) : (<div className={Style['loginbox-hd']}></div>)}
|
label: ele.label,
|
||||||
|
value: ele.value,
|
||||||
|
}))}></Segmented>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className={classNames(Style['loginbox-bd'], {
|
<div className={classNames(Style['loginbox-bd'], {
|
||||||
[Style['loginbox-bd__grant']]: isSupportWechatGrant,
|
[Style['loginbox-bd__grant']]: isSupportWechatGrant,
|
||||||
|
|
@ -41,22 +92,32 @@ export default function Render(props) {
|
||||||
{isSupportWechatGrant ? (<div className={Style['loginbox-grant']}>
|
{isSupportWechatGrant ? (<div className={Style['loginbox-grant']}>
|
||||||
<WeChatLoginGrant disabled={!!disabled} disableText={disabled} appId={appId} scope="snsapi_userinfo" redirectUri={redirectUri2} state={state}/>
|
<WeChatLoginGrant disabled={!!disabled} disableText={disabled} appId={appId} scope="snsapi_userinfo" redirectUri={redirectUri2} state={state}/>
|
||||||
</div>) : (<>
|
</div>) : (<>
|
||||||
<div className={Style['loginbox-password']} style={{
|
{showInput ? (<>
|
||||||
display: loginMode === 'password' ? 'block' : 'none',
|
<div className={Style['loginbox-password']} style={{
|
||||||
}}>
|
display: loginMode === 'password' ? 'block' : 'none',
|
||||||
<PasswordLogin disabled={disabled} url={url} callback={callback}/>
|
}}>
|
||||||
</div>
|
<PasswordLogin disabled={disabled} url={url} callback={callback}/>
|
||||||
<div className={Style['loginbox-mobile']} style={{
|
{Tip}
|
||||||
display: loginMode === 'sms' ? 'block' : 'none',
|
</div>
|
||||||
}}>
|
<div className={Style['loginbox-mobile']} style={{
|
||||||
<SmsLogin disabled={disabled} url={url} callback={callback}/>
|
display: loginMode === 'sms' ? 'block' : 'none',
|
||||||
</div>
|
}}>
|
||||||
{loginMode === 'wechatWeb' && <div className={Style['loginbox-qrcode']}>
|
<SmsLogin disabled={disabled} url={url} callback={callback}/>
|
||||||
<WeChatLoginQrCode disabled={!!disabled} disableText={disabled} appId={appId} scope="snsapi_login" redirectUri={redirectUri2} state={state}/>
|
{Tip}
|
||||||
</div>}
|
</div>
|
||||||
{loginMode === 'wechatPublicForWeb' && <div className={Style['loginbox-qrcode']}>
|
{ScanMethods}
|
||||||
<WechatLoginQrCodeForPublic type="login" oakPath="$login-wechatLogin/qrCode" oakAutoUnmount={true} url={state}/>
|
</>) : (<>
|
||||||
</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={200}/>
|
||||||
|
{Tip}
|
||||||
|
</div>}
|
||||||
|
{InputMethods}
|
||||||
|
</>)}
|
||||||
</>)}
|
</>)}
|
||||||
</div>
|
</div>
|
||||||
</div>);
|
</div>);
|
||||||
|
|
|
||||||
|
|
@ -21,14 +21,16 @@
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-shadow: 0 2px 4px rgb(0 0 0 / 8%), 0 0 4px rgb(0 0 0 / 8%);
|
box-shadow: 0 2px 4px rgb(0 0 0 / 8%), 0 0 4px rgb(0 0 0 / 8%);
|
||||||
|
transition: all 0.5s;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-hd {
|
&-hd {
|
||||||
padding: 32px;
|
padding: 32px;
|
||||||
|
padding-bottom: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-bd {
|
&-bd {
|
||||||
height: 310px;
|
min-height: 320px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-only {
|
&-only {
|
||||||
|
|
@ -37,17 +39,21 @@
|
||||||
|
|
||||||
&-mobile {
|
&-mobile {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 0 32px;
|
padding: 32px;
|
||||||
|
height: 220px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-password {
|
&-password {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 0 32px;
|
padding: 32px;
|
||||||
|
height: 220px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-qrcode {
|
&-qrcode {
|
||||||
padding: 0 32px;
|
padding: 0 32px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
height: 268px;
|
||||||
|
padding-top: 16px;
|
||||||
|
|
||||||
&__sociallogin {
|
&__sociallogin {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
@ -95,4 +101,23 @@
|
||||||
cursor: default;
|
cursor: default;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-methods {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 0px 24px 16px 24px;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #6c7d8f;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-tip {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #808080;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { EntityDict } from '../../../oak-app-domain';
|
import { EntityDict } from '../../../oak-app-domain';
|
||||||
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<EntityDict, keyof EntityDict, false, {
|
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<EntityDict, keyof EntityDict, false, {
|
||||||
type: "login" | "bind";
|
type: "bind" | "login";
|
||||||
url: string;
|
url: string;
|
||||||
|
size: undefined;
|
||||||
}>) => React.ReactElement;
|
}>) => React.ReactElement;
|
||||||
export default _default;
|
export default _default;
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ export default OakComponent({
|
||||||
properties: {
|
properties: {
|
||||||
type: 'bind',
|
type: 'bind',
|
||||||
url: '',
|
url: '',
|
||||||
|
size: undefined,
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async createWechatLogin() {
|
async createWechatLogin() {
|
||||||
|
|
|
||||||
|
|
@ -7,4 +7,5 @@ export default function Render(props: WebComponentProps<EntityDict, 'wechatLogin
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
successful: boolean;
|
successful: boolean;
|
||||||
type: EntityDict['wechatLogin']['Schema']['type'];
|
type: EntityDict['wechatLogin']['Schema']['type'];
|
||||||
|
size: number;
|
||||||
}, {}>): React.JSX.Element;
|
}, {}>): React.JSX.Element;
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import QrCode from '../../../components/common/qrCode';
|
import QrCode from '../../../components/common/qrCode';
|
||||||
export default function Render(props) {
|
export default function Render(props) {
|
||||||
const { oakFullpath, qrCodeUrl, loading, successful, type } = props.data;
|
const { oakFullpath, qrCodeUrl, loading, successful, type, size } = props.data;
|
||||||
return (<div>
|
return (<div>
|
||||||
<QrCode loading={loading} url={qrCodeUrl} disableDownload={true} tips={<div>微信扫一扫</div>} successful={successful} type={type}/>
|
<QrCode loading={loading} url={qrCodeUrl} disableDownload={true} tips={<div>微信扫一扫</div>} successful={successful} type={type} size={size}/>
|
||||||
</div>);
|
</div>);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -317,7 +317,10 @@ const i18ns = [
|
||||||
"Mobile": "请输入手机号",
|
"Mobile": "请输入手机号",
|
||||||
"Password": "请输入密码"
|
"Password": "请输入密码"
|
||||||
},
|
},
|
||||||
"resendAfter": "秒后可重发"
|
"resendAfter": "秒后可重发",
|
||||||
|
"otherMethods": "其他登录方式",
|
||||||
|
"scanLogin": "扫码登录",
|
||||||
|
"tip": "未注册用户首次登录将自动注册"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -319,7 +319,10 @@ const i18ns = [
|
||||||
"Mobile": "请输入手机号",
|
"Mobile": "请输入手机号",
|
||||||
"Password": "请输入密码"
|
"Password": "请输入密码"
|
||||||
},
|
},
|
||||||
"resendAfter": "秒后可重发"
|
"resendAfter": "秒后可重发",
|
||||||
|
"otherMethods": "其他登录方式",
|
||||||
|
"scanLogin": "扫码登录",
|
||||||
|
"tip": "未注册用户首次登录将自动注册"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&_dev {
|
&_dev {
|
||||||
height: 280px;
|
// height: 280px;
|
||||||
border: 1px dashed var(--oak-color-primary);
|
border: 1px dashed var(--oak-color-primary);
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
|
||||||
&_header {
|
&_header {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -36,7 +37,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&_btn {
|
&_btn {
|
||||||
margin-top: 16px;
|
// margin-top: 16px;
|
||||||
width: 80px;
|
width: 80px;
|
||||||
height: 80px;
|
height: 80px;
|
||||||
border-radius: 40px;
|
border-radius: 40px;
|
||||||
|
|
@ -102,16 +103,16 @@
|
||||||
|
|
||||||
&_disable {
|
&_disable {
|
||||||
&_border {
|
&_border {
|
||||||
height: 202px;
|
height: 220px;
|
||||||
width: 202px;
|
width: 220px;
|
||||||
margin: 15px;
|
// margin: 15px;
|
||||||
background-color: #f5f7fa;
|
background-color: #f5f7fa;
|
||||||
color: rgba(0, 0, 0, .4);
|
color: rgba(0, 0, 0, .4);
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding: 15px;
|
// padding: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&_info {
|
&_info {
|
||||||
|
|
@ -124,7 +125,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&_err {
|
&_err {
|
||||||
height: 280px;
|
// height: 280px;
|
||||||
border: 1px dashed var(--oak-color-primary);
|
border: 1px dashed var(--oak-color-primary);
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,8 @@ export default OakComponent({
|
||||||
isSupportWechatGrant: false,
|
isSupportWechatGrant: false,
|
||||||
domain: undefined as string | undefined,
|
domain: undefined as string | undefined,
|
||||||
passportTypes: [] as EntityDict['passport']['Schema']['type'][],
|
passportTypes: [] as EntityDict['passport']['Schema']['type'][],
|
||||||
options: [] as Option[],
|
inputOptions: [] as Option[],
|
||||||
|
scanOptions: [] as Option[],
|
||||||
allowSms: false,
|
allowSms: false,
|
||||||
allowPassword: false,
|
allowPassword: false,
|
||||||
allowWechatMp: false,
|
allowWechatMp: false,
|
||||||
|
|
@ -37,36 +38,44 @@ export default OakComponent({
|
||||||
return {};
|
return {};
|
||||||
},
|
},
|
||||||
listeners: {
|
listeners: {
|
||||||
'onlyPassword,onlyCaptcha'(prev, next) {
|
// 'onlyPassword,onlyCaptcha'(prev, next) {
|
||||||
let loginMode = this.state.loginMode, options = this.state.options;
|
// let loginMode = this.state.loginMode, inputOptions = this.state.inputOptions, scanOptions = this.state.scanOptions;
|
||||||
if (next.onlyPassword) {
|
// if (next.onlyPassword) {
|
||||||
loginMode = 'password';
|
// loginMode = 'password';
|
||||||
options = [{
|
// inputOptions = [{
|
||||||
label: this.t('passport:v.type.password'),
|
// label: this.t('passport:v.type.password'),
|
||||||
value: 'password',
|
// value: 'password',
|
||||||
}];
|
// }];
|
||||||
} else if (next.onlyCaptcha) {
|
// } else if (next.onlyCaptcha) {
|
||||||
loginMode = 'sms';
|
// loginMode = 'sms';
|
||||||
options = [{
|
// inputOptions = [{
|
||||||
label: this.t('passport:v.type.sms'),
|
// label: this.t('passport:v.type.sms'),
|
||||||
value: 'sms',
|
// value: 'sms',
|
||||||
}];
|
// }];
|
||||||
} else {
|
// } else {
|
||||||
const { passportTypes } = this.state;
|
// const { passportTypes } = this.state;
|
||||||
if (passportTypes && passportTypes.length > 0) {
|
// if (passportTypes && passportTypes.length > 0) {
|
||||||
passportTypes.forEach((ele: EntityDict['passport']['Schema']['type']) => {
|
// passportTypes.forEach((ele: EntityDict['passport']['Schema']['type']) => {
|
||||||
options.push({
|
// if (ele === 'sms' || ele === 'email' || ele === 'password') {
|
||||||
label: this.t(`passport:v.type.${ele}`),
|
// inputOptions.push({
|
||||||
value: ele
|
// label: this.t(`passport:v.type.${ele}`),
|
||||||
})
|
// value: ele
|
||||||
});
|
// })
|
||||||
}
|
// } else if (ele === 'wechatMpForWeb' || ele === 'wechatPublicForWeb') {
|
||||||
}
|
// scanOptions.push({
|
||||||
this.setState({
|
// label: this.t(`passport:v.type.${ele}`),
|
||||||
loginMode,
|
// value: ele
|
||||||
options,
|
// })
|
||||||
})
|
// }
|
||||||
}
|
// });
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// this.setState({
|
||||||
|
// loginMode,
|
||||||
|
// inputOptions,
|
||||||
|
// scanOptions,
|
||||||
|
// })
|
||||||
|
// }
|
||||||
},
|
},
|
||||||
lifetimes: {
|
lifetimes: {
|
||||||
async ready() {
|
async ready() {
|
||||||
|
|
@ -75,29 +84,42 @@ export default OakComponent({
|
||||||
const defaultPassport = applicationPassports.find((ele: EntityDict['applicationPassport']['Schema']) => ele.isDefault);
|
const defaultPassport = applicationPassports.find((ele: EntityDict['applicationPassport']['Schema']) => ele.isDefault);
|
||||||
const passportTypes = applicationPassports.map((ele: EntityDict['applicationPassport']['Schema']) => ele.passport.type);
|
const passportTypes = applicationPassports.map((ele: EntityDict['applicationPassport']['Schema']) => ele.passport.type);
|
||||||
|
|
||||||
|
const { onlyCaptcha, onlyPassword } = this.props;
|
||||||
|
|
||||||
let loginMode = (await this.load(LOGIN_MODE)) || defaultPassport.passport.type;
|
let loginMode = (await this.load(LOGIN_MODE)) || defaultPassport.passport.type;
|
||||||
let options: Option[] = [];
|
let inputOptions: Option[] = [], scanOptions: Option[] = [];
|
||||||
if (this.props.onlyPassword) {
|
if (onlyPassword) {
|
||||||
loginMode = 'password';
|
loginMode = 'password';
|
||||||
options = [{
|
inputOptions = [{
|
||||||
label: this.t('passport:v.type.password'),
|
label: this.t('passport:v.type.password') + this.t('Login'),
|
||||||
value: 'password',
|
value: 'password',
|
||||||
}];
|
}];
|
||||||
} else if (this.props.onlyCaptcha) {
|
} else if (onlyCaptcha) {
|
||||||
loginMode = 'sms';
|
loginMode = 'sms';
|
||||||
options = [{
|
inputOptions = [{
|
||||||
label: this.t('passport:v.type.sms'),
|
label: this.t('passport:v.type.sms') + this.t('Login'),
|
||||||
value: 'sms',
|
value: 'sms',
|
||||||
}];
|
}];
|
||||||
} else {
|
} else {
|
||||||
passportTypes.forEach((ele: EntityDict['passport']['Schema']['type']) => {
|
passportTypes.forEach((ele: EntityDict['passport']['Schema']['type']) => {
|
||||||
options.push({
|
if (ele === 'sms' || ele === 'email' || ele === 'password') {
|
||||||
label: this.t(`passport:v.type.${ele}`),
|
inputOptions.push({
|
||||||
value: ele
|
label: this.t(`passport:v.type.${ele}`) + this.t('Login'),
|
||||||
})
|
value: ele
|
||||||
|
})
|
||||||
|
} else if (ele === 'wechatWeb' || ele === 'wechatMpForWeb' || ele === 'wechatPublicForWeb') {
|
||||||
|
scanOptions.push({
|
||||||
|
label: this.t(`passport:v.type.${ele}`) + this.t('Login'),
|
||||||
|
value: ele
|
||||||
|
})
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!passportTypes.includes(loginMode)) {
|
||||||
|
loginMode = defaultPassport.passport.type;
|
||||||
|
}
|
||||||
|
|
||||||
const appType = application?.type as AppType;
|
const appType = application?.type as AppType;
|
||||||
const config = application?.config;
|
const config = application?.config;
|
||||||
let appId;
|
let appId;
|
||||||
|
|
@ -114,9 +136,9 @@ export default OakComponent({
|
||||||
appId = config2?.wechat?.appId;
|
appId = config2?.wechat?.appId;
|
||||||
domain = config2?.wechat?.domain;
|
domain = config2?.wechat?.domain;
|
||||||
} else if (appType === 'wechatMp') {
|
} else if (appType === 'wechatMp') {
|
||||||
allowSms = passportTypes.includes('sms');
|
allowSms = passportTypes.includes('sms') && !onlyPassword;
|
||||||
allowPassword = passportTypes.includes('password');
|
allowPassword = passportTypes.includes('password') && !onlyCaptcha;
|
||||||
allowWechatMp = passportTypes.includes('wechatMp');
|
allowWechatMp = passportTypes.includes('wechatMp') && !onlyCaptcha && !onlyPassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState(
|
this.setState(
|
||||||
|
|
@ -126,7 +148,8 @@ export default OakComponent({
|
||||||
isSupportWechatGrant,
|
isSupportWechatGrant,
|
||||||
domain,
|
domain,
|
||||||
passportTypes,
|
passportTypes,
|
||||||
options,
|
inputOptions,
|
||||||
|
scanOptions,
|
||||||
allowSms,
|
allowSms,
|
||||||
allowPassword,
|
allowPassword,
|
||||||
allowWechatMp,
|
allowWechatMp,
|
||||||
|
|
|
||||||
|
|
@ -10,5 +10,8 @@
|
||||||
"Mobile": "请输入手机号",
|
"Mobile": "请输入手机号",
|
||||||
"Password": "请输入密码"
|
"Password": "请输入密码"
|
||||||
},
|
},
|
||||||
"resendAfter": "秒后可重发"
|
"resendAfter": "秒后可重发",
|
||||||
}
|
"otherMethods": "其他登录方式",
|
||||||
|
"scanLogin": "扫码登录",
|
||||||
|
"tip": "未注册用户首次登录将自动注册"
|
||||||
|
}
|
||||||
|
|
@ -21,14 +21,16 @@
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-shadow: 0 2px 4px rgb(0 0 0 / 8%), 0 0 4px rgb(0 0 0 / 8%);
|
box-shadow: 0 2px 4px rgb(0 0 0 / 8%), 0 0 4px rgb(0 0 0 / 8%);
|
||||||
|
transition: all 0.5s;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-hd {
|
&-hd {
|
||||||
padding: 32px;
|
padding: 32px;
|
||||||
|
padding-bottom: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-bd {
|
&-bd {
|
||||||
height: 310px;
|
min-height: 320px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-only {
|
&-only {
|
||||||
|
|
@ -37,17 +39,21 @@
|
||||||
|
|
||||||
&-mobile {
|
&-mobile {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 0 32px;
|
padding: 32px;
|
||||||
|
height: 220px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-password {
|
&-password {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 0 32px;
|
padding: 32px;
|
||||||
|
height: 220px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-qrcode {
|
&-qrcode {
|
||||||
padding: 0 32px;
|
padding: 0 32px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
height: 268px;
|
||||||
|
padding-top: 16px;
|
||||||
|
|
||||||
&__sociallogin {
|
&__sociallogin {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
@ -95,4 +101,23 @@
|
||||||
cursor: default;
|
cursor: default;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-methods {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 0px 24px 16px 24px;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #6c7d8f;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-tip {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #808080;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -6,10 +6,14 @@ import {
|
||||||
isPassword,
|
isPassword,
|
||||||
isCaptcha,
|
isCaptcha,
|
||||||
} from 'oak-domain/lib/utils/validator';
|
} from 'oak-domain/lib/utils/validator';
|
||||||
import { Form, Input, Button, Checkbox, Typography, Segmented } from 'antd';
|
import { Form, Input, Button, Checkbox, Typography, Segmented, Divider, Space } from 'antd';
|
||||||
import {
|
import {
|
||||||
LockOutlined,
|
LockOutlined,
|
||||||
MobileOutlined,
|
MobileOutlined,
|
||||||
|
QrcodeOutlined,
|
||||||
|
DesktopOutlined,
|
||||||
|
MailOutlined,
|
||||||
|
ExclamationCircleOutlined,
|
||||||
} from '@ant-design/icons';
|
} from '@ant-design/icons';
|
||||||
import { WebComponentProps } from 'oak-frontend-base';
|
import { WebComponentProps } from 'oak-frontend-base';
|
||||||
import { EntityDict } from '../../../oak-app-domain';
|
import { EntityDict } from '../../../oak-app-domain';
|
||||||
|
|
@ -44,7 +48,8 @@ export default function Render(
|
||||||
url: string;
|
url: string;
|
||||||
passportTypes: EntityDict['passport']['Schema']['type'][];
|
passportTypes: EntityDict['passport']['Schema']['type'][];
|
||||||
callback: (() => void) | undefined;
|
callback: (() => void) | undefined;
|
||||||
options: Option[];
|
inputOptions: Option[];
|
||||||
|
scanOptions: Option[];
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
setLoginMode: (value: number) => void;
|
setLoginMode: (value: number) => void;
|
||||||
|
|
@ -64,7 +69,8 @@ export default function Render(
|
||||||
url,
|
url,
|
||||||
passportTypes,
|
passportTypes,
|
||||||
callback,
|
callback,
|
||||||
options,
|
inputOptions,
|
||||||
|
scanOptions,
|
||||||
} = data;
|
} = data;
|
||||||
const { t, setLoginMode } = methods;
|
const { t, setLoginMode } = methods;
|
||||||
|
|
||||||
|
|
@ -84,28 +90,88 @@ export default function Render(
|
||||||
state = encodeURIComponent(decodeURIComponent(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
|
||||||
|
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 Tip = <div className={Style['loginbox-tip']}>
|
||||||
|
<Space>
|
||||||
|
<ExclamationCircleOutlined />
|
||||||
|
<div>{t('tip')}</div>
|
||||||
|
</Space>
|
||||||
|
</div>
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={classNames(Style['loginbox-wrap'], {
|
className={classNames(Style['loginbox-wrap'], {
|
||||||
[Style['loginbox-wrap__mobile']]: width === 'xs',
|
[Style['loginbox-wrap__mobile']]: width === 'xs',
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{options?.length > 1 ? (
|
<div className={Style['loginbox-hd']}>
|
||||||
<div className={Style['loginbox-hd']}>
|
<Segmented
|
||||||
<Segmented
|
className={Style.segmented}
|
||||||
className={Style.segmented}
|
value={loginMode}
|
||||||
value={loginMode}
|
block
|
||||||
block
|
onChange={setLoginMode}
|
||||||
onChange={setLoginMode}
|
options={showInput ? inputOptions.map((ele) => ({
|
||||||
options={options.map((ele) => ({
|
label: ele.label,
|
||||||
label: ele.label,
|
value: ele.value,
|
||||||
value: ele.value,
|
})) : scanOptions.map((ele) => ({
|
||||||
}))}
|
label: ele.label,
|
||||||
></Segmented>
|
value: ele.value,
|
||||||
</div>
|
}))}
|
||||||
) : (
|
></Segmented>
|
||||||
<div className={Style['loginbox-hd']}></div>
|
</div>
|
||||||
)}
|
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className={classNames(Style['loginbox-bd'], {
|
className={classNames(Style['loginbox-bd'], {
|
||||||
|
|
@ -125,55 +191,70 @@ export default function Render(
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<div
|
{showInput ? (
|
||||||
className={Style['loginbox-password']}
|
<>
|
||||||
style={{
|
<div
|
||||||
display: loginMode === 'password' ? 'block' : 'none',
|
className={Style['loginbox-password']}
|
||||||
}}
|
style={{
|
||||||
>
|
display: loginMode === 'password' ? 'block' : 'none',
|
||||||
<PasswordLogin
|
}}
|
||||||
disabled={disabled}
|
>
|
||||||
url={url}
|
<PasswordLogin
|
||||||
callback={callback}
|
disabled={disabled}
|
||||||
/>
|
url={url}
|
||||||
</div>
|
callback={callback}
|
||||||
<div
|
/>
|
||||||
className={Style['loginbox-mobile']}
|
{Tip}
|
||||||
style={{
|
</div>
|
||||||
display: loginMode === 'sms' ? 'block' : 'none',
|
<div
|
||||||
}}
|
className={Style['loginbox-mobile']}
|
||||||
>
|
style={{
|
||||||
<SmsLogin
|
display: loginMode === 'sms' ? 'block' : 'none',
|
||||||
disabled={disabled}
|
}}
|
||||||
url={url}
|
>
|
||||||
callback={callback}
|
<SmsLogin
|
||||||
/>
|
disabled={disabled}
|
||||||
</div>
|
url={url}
|
||||||
{loginMode === 'wechatWeb' && <div
|
callback={callback}
|
||||||
className={Style['loginbox-qrcode']}
|
/>
|
||||||
>
|
{Tip}
|
||||||
<WeChatLoginQrCode
|
</div>
|
||||||
disabled={!!disabled}
|
{ScanMethods}
|
||||||
disableText={disabled}
|
</>
|
||||||
appId={appId}
|
) : (
|
||||||
scope="snsapi_login"
|
<>
|
||||||
redirectUri={redirectUri2}
|
{loginMode === 'wechatWeb' &&
|
||||||
state={state}
|
<div
|
||||||
/>
|
className={Style['loginbox-qrcode']}
|
||||||
</div>}
|
>
|
||||||
{loginMode === 'wechatPublicForWeb' && <div
|
<WeChatLoginQrCode
|
||||||
className={Style['loginbox-qrcode']}
|
disabled={!!disabled}
|
||||||
>
|
disableText={disabled}
|
||||||
<WechatLoginQrCodeForPublic
|
appId={appId}
|
||||||
type="login"
|
scope="snsapi_login"
|
||||||
oakPath="$login-wechatLogin/qrCode"
|
redirectUri={redirectUri2}
|
||||||
oakAutoUnmount={true}
|
state={state}
|
||||||
url={state}
|
/>
|
||||||
/>
|
{Tip}
|
||||||
</div>}
|
</div>}
|
||||||
|
{loginMode === 'wechatPublicForWeb' && <div
|
||||||
|
className={Style['loginbox-qrcode']}
|
||||||
|
>
|
||||||
|
<WechatLoginQrCodeForPublic
|
||||||
|
type="login"
|
||||||
|
oakPath="$login-wechatLogin/qrCode"
|
||||||
|
oakAutoUnmount={true}
|
||||||
|
url={state}
|
||||||
|
size={200}
|
||||||
|
/>
|
||||||
|
{Tip}
|
||||||
|
</div>}
|
||||||
|
{InputMethods}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div >
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ export default OakComponent({
|
||||||
properties: {
|
properties: {
|
||||||
type: 'bind' as EntityDict['wechatLogin']['Schema']['type'],
|
type: 'bind' as EntityDict['wechatLogin']['Schema']['type'],
|
||||||
url: '',
|
url: '',
|
||||||
|
size: undefined,
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async createWechatLogin() {
|
async createWechatLogin() {
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,12 @@ export default function Render(
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
successful: boolean;
|
successful: boolean;
|
||||||
type: EntityDict['wechatLogin']['Schema']['type'];
|
type: EntityDict['wechatLogin']['Schema']['type'];
|
||||||
|
size: number;
|
||||||
},
|
},
|
||||||
{}
|
{}
|
||||||
>
|
>
|
||||||
) {
|
) {
|
||||||
const { oakFullpath, qrCodeUrl, loading, successful, type } = props.data;
|
const { oakFullpath, qrCodeUrl, loading, successful, type, size } = props.data;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -31,6 +32,7 @@ export default function Render(
|
||||||
tips={<div>微信扫一扫</div>}
|
tips={<div>微信扫一扫</div>}
|
||||||
successful={successful}
|
successful={successful}
|
||||||
type={type}
|
type={type}
|
||||||
|
size={size}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -319,7 +319,10 @@ const i18ns: I18n[] = [
|
||||||
"Mobile": "请输入手机号",
|
"Mobile": "请输入手机号",
|
||||||
"Password": "请输入密码"
|
"Password": "请输入密码"
|
||||||
},
|
},
|
||||||
"resendAfter": "秒后可重发"
|
"resendAfter": "秒后可重发",
|
||||||
|
"otherMethods": "其他登录方式",
|
||||||
|
"scanLogin": "扫码登录",
|
||||||
|
"tip": "未注册用户首次登录将自动注册"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue