158 lines
5.0 KiB
JavaScript
158 lines
5.0 KiB
JavaScript
import { LOCAL_STORAGE_KEYS } from '../../../../config/constants';
|
|
import { isCaptcha, isMobile } from "oak-domain/lib/utils/validator";
|
|
const SEND_KEY = LOCAL_STORAGE_KEYS.captchaSendAt;
|
|
const SEND_CAPTCHA_LATENCY = process.env.NODE_ENV === 'development' ? 10 : 60;
|
|
export default OakComponent({
|
|
isList: false,
|
|
projection: {
|
|
id: 1,
|
|
mobile: 1,
|
|
userId: 1,
|
|
},
|
|
data: {
|
|
counter: 0,
|
|
loading: false,
|
|
lastSendAt: undefined,
|
|
mobile: '',
|
|
captcha: '',
|
|
validMobile: false,
|
|
validCaptcha: false,
|
|
allowSubmit: false,
|
|
},
|
|
properties: {
|
|
disabled: '',
|
|
url: '', // 登录系统之后要返回的页面
|
|
callback: undefined, // 登录成功回调,排除微信登录方式
|
|
allowPassword: false, //小程序切换密码登录
|
|
allowWechatMp: false, //小程序切换授权登录
|
|
setLoginMode: (value) => undefined,
|
|
digit: 4 //验证码位数,
|
|
},
|
|
formData({ features, props }) {
|
|
const { lastSendAt } = this.state;
|
|
let counter = 0;
|
|
if (typeof lastSendAt === 'number') {
|
|
const now = Date.now();
|
|
counter = Math.max(SEND_CAPTCHA_LATENCY - Math.ceil((now - lastSendAt) / 1000), 0);
|
|
if (counter > 0) {
|
|
this.counterHandler = setTimeout(() => this.reRender(), 1000);
|
|
}
|
|
else if (this.counterHandler) {
|
|
clearTimeout(this.counterHandler);
|
|
this.counterHandler = undefined;
|
|
}
|
|
}
|
|
return {
|
|
counter,
|
|
};
|
|
},
|
|
lifetimes: {},
|
|
listeners: {
|
|
'validMobile,validCaptcha'(prev, next) {
|
|
const { allowSubmit } = this.state;
|
|
if (allowSubmit) {
|
|
if (!(next.validMobile && next.validCaptcha)) {
|
|
this.setState({
|
|
allowSubmit: false,
|
|
});
|
|
}
|
|
}
|
|
else {
|
|
if (next.validMobile && next.validCaptcha) {
|
|
this.setState({
|
|
allowSubmit: true,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
},
|
|
methods: {
|
|
async sendCaptcha() {
|
|
const { mobile } = this.state;
|
|
try {
|
|
const result = await this.features.token.sendCaptcha('mobile', mobile, 'login');
|
|
// 显示返回消息
|
|
this.setMessage({
|
|
type: 'success',
|
|
content: result,
|
|
});
|
|
const lastSendAt = Date.now();
|
|
await this.save(SEND_KEY, lastSendAt);
|
|
this.setState({
|
|
lastSendAt,
|
|
}, () => this.reRender());
|
|
}
|
|
catch (err) {
|
|
this.setMessage({
|
|
type: 'error',
|
|
content: err.message,
|
|
});
|
|
}
|
|
},
|
|
async loginByCaptcha() {
|
|
const { url, callback } = this.props;
|
|
const { mobile, captcha } = this.state;
|
|
try {
|
|
this.setState({
|
|
loading: true,
|
|
});
|
|
await this.features.token.loginByMobile(mobile, captcha);
|
|
this.setState({
|
|
loading: false,
|
|
});
|
|
if (callback) {
|
|
callback();
|
|
return;
|
|
}
|
|
if (url) {
|
|
this.redirectTo({
|
|
url,
|
|
});
|
|
return;
|
|
}
|
|
}
|
|
catch (err) {
|
|
this.setState({
|
|
loading: false,
|
|
});
|
|
this.setMessage({
|
|
type: 'error',
|
|
content: err.message,
|
|
});
|
|
}
|
|
},
|
|
inputChange(type, value) {
|
|
const { digit } = this.props;
|
|
switch (type) {
|
|
case 'mobile':
|
|
const validMobile = !!isMobile(value);
|
|
this.setState({
|
|
mobile: value,
|
|
validMobile,
|
|
});
|
|
break;
|
|
case 'captcha':
|
|
const validCaptcha = !!isCaptcha(value, digit);
|
|
this.setState({
|
|
captcha: value,
|
|
validCaptcha
|
|
});
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
},
|
|
inputChangeMp(event) {
|
|
const { detail, target: { dataset }, } = event;
|
|
const { attr } = dataset;
|
|
const { value } = detail;
|
|
this.inputChange(attr, value);
|
|
},
|
|
changeLoginMp(e) {
|
|
const { setLoginMode } = this.props;
|
|
const { value } = e.currentTarget.dataset;
|
|
setLoginMode && setLoginMode(value);
|
|
}
|
|
},
|
|
});
|