|
|
|
@ -1,14 +1,15 @@
|
|
|
|
|
import * as React from 'react';
|
|
|
|
|
import { KeyBoard } from '../../../Common/KeyEnum';
|
|
|
|
|
import { InputGroup, Label, Classes, Button, Checkbox, Dialog, Intent, Tooltip, Position } from '@blueprintjs/core';
|
|
|
|
|
import { InputGroup, Classes, Button, Checkbox, Dialog, Intent, Tooltip, Position } from '@blueprintjs/core';
|
|
|
|
|
import { TopPanelStore } from '../../Store/TopPanelStore';
|
|
|
|
|
import { inject, observer } from 'mobx-react';
|
|
|
|
|
import { IObservableValue, observable } from 'mobx';
|
|
|
|
|
import { PostJson, RequestStatus } from '../../../Common/Request';
|
|
|
|
|
import { SignUrl, ResourcesCDN_HOST } from '../../../Common/HostUrl';
|
|
|
|
|
import { AppToaster } from '../Toaster';
|
|
|
|
|
import { addCookie, editCookie, getCookieValue } from '../../../Common/Utils';
|
|
|
|
|
|
|
|
|
|
interface IRegistState
|
|
|
|
|
interface IRegistInput
|
|
|
|
|
{
|
|
|
|
|
user_phone: string;
|
|
|
|
|
pass_word: string;
|
|
|
|
@ -34,18 +35,23 @@ enum InputType
|
|
|
|
|
|
|
|
|
|
@inject("store")
|
|
|
|
|
@observer
|
|
|
|
|
export default class Regist extends React.Component<{ store?: TopPanelStore }, IRegistState> {
|
|
|
|
|
export default class Regist extends React.Component<{ store?: TopPanelStore }> {
|
|
|
|
|
@observable private errMsg: string = "";
|
|
|
|
|
@observable private flag: InputType = InputType.OK;
|
|
|
|
|
@observable private inputIntent: InputIntent;
|
|
|
|
|
@observable private SMSBtnText: string = "获取短信验证码";
|
|
|
|
|
//防止提示
|
|
|
|
|
@observable private pwdInputType1 = false;
|
|
|
|
|
@observable private pwdInputType2 = false;
|
|
|
|
|
//输入内容
|
|
|
|
|
@observable private registInput: IRegistInput;
|
|
|
|
|
private openAgreement = observable.box(false);
|
|
|
|
|
private phoneRegex = new RegExp(`\^1\\d{10}$`);
|
|
|
|
|
private pswRegex = new RegExp(`\^[^\\u4e00-\\u9fa5]+$`);
|
|
|
|
|
constructor(props)
|
|
|
|
|
{
|
|
|
|
|
super(props);
|
|
|
|
|
this.state = {
|
|
|
|
|
this.registInput = {
|
|
|
|
|
user_phone: "",
|
|
|
|
|
pass_word: "",
|
|
|
|
|
check_code: "",
|
|
|
|
@ -58,6 +64,15 @@ export default class Regist extends React.Component<{ store?: TopPanelStore }, I
|
|
|
|
|
PHONE: Intent.NONE,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
componentWillMount()
|
|
|
|
|
{
|
|
|
|
|
const countdown = getCookieValue('secondsremained') ? getCookieValue('secondsremained') : 0; // 获取cookie值
|
|
|
|
|
if (countdown !== undefined && countdown > 0)
|
|
|
|
|
{
|
|
|
|
|
this.SMSBtnText = `${countdown}s后重新获取`;
|
|
|
|
|
this.settime(); // 开始倒计时
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
handleRegist = async () =>
|
|
|
|
|
{
|
|
|
|
|
if (this.inputIntent.PSW !== Intent.SUCCESS)
|
|
|
|
@ -87,7 +102,7 @@ export default class Regist extends React.Component<{ store?: TopPanelStore }, I
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (this.state.check_code === "")
|
|
|
|
|
if (this.registInput.check_code === "")
|
|
|
|
|
{
|
|
|
|
|
AppToaster.show({
|
|
|
|
|
message: "验证码不能为空",
|
|
|
|
@ -96,7 +111,7 @@ export default class Regist extends React.Component<{ store?: TopPanelStore }, I
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (!this.state.agreement_checked)
|
|
|
|
|
if (!this.registInput.agreement_checked)
|
|
|
|
|
{
|
|
|
|
|
AppToaster.show({
|
|
|
|
|
message: "需同意注册协议方可注册",
|
|
|
|
@ -105,7 +120,7 @@ export default class Regist extends React.Component<{ store?: TopPanelStore }, I
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
let data = await PostJson(SignUrl.regist, this.state);
|
|
|
|
|
let data = await PostJson(SignUrl.regist, this.registInput);
|
|
|
|
|
if (data.err_code === RequestStatus.Ok)
|
|
|
|
|
{
|
|
|
|
|
//注册成功 跳转到登陆
|
|
|
|
@ -117,24 +132,18 @@ export default class Regist extends React.Component<{ store?: TopPanelStore }, I
|
|
|
|
|
this.props.store.openRegist = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
handleCheckPhoneNum = async (text: string) =>
|
|
|
|
|
{
|
|
|
|
|
let data = await PostJson(SignUrl.checkRegUser, {
|
|
|
|
|
user_phone: text,
|
|
|
|
|
});
|
|
|
|
|
return data.err_code === RequestStatus.Ok
|
|
|
|
|
}
|
|
|
|
|
handleSMS = async () =>
|
|
|
|
|
{
|
|
|
|
|
let num = 120;
|
|
|
|
|
this.SMSBtnText = `${num}s后重新获取`;
|
|
|
|
|
//120秒倒数
|
|
|
|
|
let tim = setInterval(() =>
|
|
|
|
|
{
|
|
|
|
|
num--;
|
|
|
|
|
this.SMSBtnText = `${num}s后重新获取`;
|
|
|
|
|
if (num === 1)
|
|
|
|
|
{
|
|
|
|
|
clearInterval(tim);
|
|
|
|
|
this.SMSBtnText = "获取短信验证码";
|
|
|
|
|
}
|
|
|
|
|
return "";
|
|
|
|
|
}, 1000);
|
|
|
|
|
this.SMSBtnText = `正在请求...`;
|
|
|
|
|
let data = await PostJson(SignUrl.SMSCode, {
|
|
|
|
|
user_phone: this.state.user_phone
|
|
|
|
|
user_phone: this.registInput.user_phone
|
|
|
|
|
});
|
|
|
|
|
if (data.err_code === RequestStatus.Ok)
|
|
|
|
|
{
|
|
|
|
@ -143,13 +152,42 @@ export default class Regist extends React.Component<{ store?: TopPanelStore }, I
|
|
|
|
|
message: "短信已发送,请注意查收",
|
|
|
|
|
timeout: 1000,
|
|
|
|
|
});
|
|
|
|
|
addCookie('secondsremained', 120, 120);
|
|
|
|
|
const countdown = getCookieValue('secondsremained') ? getCookieValue('secondsremained') : 0; // 获取cookie值
|
|
|
|
|
if (countdown !== undefined && countdown > 0)
|
|
|
|
|
{
|
|
|
|
|
this.settime(); // 开始倒计时
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
this.SMSBtnText = `获取短信验证码`;
|
|
|
|
|
}
|
|
|
|
|
private settime = () =>
|
|
|
|
|
{
|
|
|
|
|
let countdown = 120;
|
|
|
|
|
// @ts-ignore
|
|
|
|
|
countdown = getCookieValue('secondsremained');
|
|
|
|
|
const timer = setInterval(() =>
|
|
|
|
|
{
|
|
|
|
|
if (countdown <= 0)
|
|
|
|
|
{
|
|
|
|
|
clearInterval(timer);
|
|
|
|
|
this.SMSBtnText = '获取短信验证码';
|
|
|
|
|
} else
|
|
|
|
|
{
|
|
|
|
|
this.SMSBtnText = `${countdown}s后重新获取`;
|
|
|
|
|
countdown--;
|
|
|
|
|
}
|
|
|
|
|
editCookie('secondsremained', countdown, countdown + 1);
|
|
|
|
|
}, 1000);
|
|
|
|
|
}
|
|
|
|
|
valueTest = (type: InputType, text: string) =>
|
|
|
|
|
valueTest = async (type: InputType) =>
|
|
|
|
|
{
|
|
|
|
|
let text = "";
|
|
|
|
|
switch (type)
|
|
|
|
|
{
|
|
|
|
|
case InputType.PSW:
|
|
|
|
|
text = this.registInput.pass_word;
|
|
|
|
|
if (text.length >= 6 && text.length <= 20)
|
|
|
|
|
{
|
|
|
|
|
if (this.pswRegex.test(text))
|
|
|
|
@ -171,13 +209,14 @@ export default class Regist extends React.Component<{ store?: TopPanelStore }, I
|
|
|
|
|
this.flag = InputType.PSW;
|
|
|
|
|
this.inputIntent.PSW = Intent.DANGER;
|
|
|
|
|
}
|
|
|
|
|
if (this.state.pswConfirm === text)
|
|
|
|
|
if (this.registInput.pswConfirm === text)
|
|
|
|
|
this.inputIntent.ComfirmPSW = Intent.SUCCESS;
|
|
|
|
|
else
|
|
|
|
|
this.inputIntent.ComfirmPSW = Intent.DANGER;
|
|
|
|
|
break;
|
|
|
|
|
case InputType.ComfirmPSW:
|
|
|
|
|
if (text === this.state.pass_word)
|
|
|
|
|
text = this.registInput.pswConfirm;
|
|
|
|
|
if (text === this.registInput.pass_word)
|
|
|
|
|
{
|
|
|
|
|
this.flag = InputType.OK;
|
|
|
|
|
this.errMsg = "";
|
|
|
|
@ -191,11 +230,22 @@ export default class Regist extends React.Component<{ store?: TopPanelStore }, I
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case InputType.PHONE:
|
|
|
|
|
text = this.registInput.user_phone;
|
|
|
|
|
if (this.phoneRegex.test(text))
|
|
|
|
|
{
|
|
|
|
|
this.flag = InputType.OK;
|
|
|
|
|
this.errMsg = "";
|
|
|
|
|
this.inputIntent.PHONE = Intent.SUCCESS;
|
|
|
|
|
let checkPhonePass = await this.handleCheckPhoneNum(text);
|
|
|
|
|
if (checkPhonePass)
|
|
|
|
|
{
|
|
|
|
|
this.flag = InputType.OK;
|
|
|
|
|
this.errMsg = "";
|
|
|
|
|
this.inputIntent.PHONE = Intent.SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
this.errMsg = "该手机号已被注册";
|
|
|
|
|
this.flag = InputType.PHONE;
|
|
|
|
|
this.inputIntent.PHONE = Intent.DANGER;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
@ -208,23 +258,9 @@ export default class Regist extends React.Component<{ store?: TopPanelStore }, I
|
|
|
|
|
}
|
|
|
|
|
render()
|
|
|
|
|
{
|
|
|
|
|
const infoBlockStyle: React.CSSProperties = {
|
|
|
|
|
background: "#fff",
|
|
|
|
|
border: "1px solid lightgrey",
|
|
|
|
|
width: "70%",
|
|
|
|
|
margin: "10px auto",
|
|
|
|
|
padding: "20px",
|
|
|
|
|
minWidth: "480px",
|
|
|
|
|
};
|
|
|
|
|
return (
|
|
|
|
|
<div
|
|
|
|
|
className="regist"
|
|
|
|
|
style={{
|
|
|
|
|
background: "#f2f2f2",
|
|
|
|
|
width: "75%",
|
|
|
|
|
height: "100%",
|
|
|
|
|
margin: "0 auto",
|
|
|
|
|
}}
|
|
|
|
|
onKeyDown={e =>
|
|
|
|
|
{
|
|
|
|
|
if (e.keyCode === KeyBoard.Enter)
|
|
|
|
@ -233,127 +269,117 @@ export default class Regist extends React.Component<{ store?: TopPanelStore }, I
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
}
|
|
|
|
|
}}>
|
|
|
|
|
<div className="regist-content">
|
|
|
|
|
<div
|
|
|
|
|
className="regist-header"
|
|
|
|
|
style={{ textAlign: "center" }}>
|
|
|
|
|
<div className="regist-content" >
|
|
|
|
|
<div className="regist-header">
|
|
|
|
|
<img
|
|
|
|
|
style={{
|
|
|
|
|
width: "80px",
|
|
|
|
|
height: "auto",
|
|
|
|
|
verticalAlign: "middle",
|
|
|
|
|
marginRight: "10px",
|
|
|
|
|
}}
|
|
|
|
|
src={`${ResourcesCDN_HOST}cf.png`}
|
|
|
|
|
alt=""
|
|
|
|
|
/>
|
|
|
|
|
<h1>
|
|
|
|
|
晨丰家具设计软件
|
|
|
|
|
<span style={{ color: "#2f7cff" }}>用户注册</span>
|
|
|
|
|
</h1>
|
|
|
|
|
<div className="regist-slogan">
|
|
|
|
|
<span>智能设计从晨丰开始!</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="regist-title" >
|
|
|
|
|
<span>新用户注册</span>
|
|
|
|
|
</div>
|
|
|
|
|
<img style={{ height: "16px" }} src={`${ResourcesCDN_HOST}divider.png`} />
|
|
|
|
|
<div className="info-block">
|
|
|
|
|
<div>
|
|
|
|
|
|
|
|
|
|
<div className="info-block" style={infoBlockStyle}>
|
|
|
|
|
<div style={{ width: "60%", minWidth: 395, margin: "0 auto" }}>
|
|
|
|
|
<div className="item">
|
|
|
|
|
<Label className={Classes.INLINE}>
|
|
|
|
|
<span>* </span>
|
|
|
|
|
<span>密码:</span>
|
|
|
|
|
</Label>
|
|
|
|
|
<Tooltip
|
|
|
|
|
content={this.errMsg}
|
|
|
|
|
position={Position.TOP}
|
|
|
|
|
intent={Intent.WARNING}
|
|
|
|
|
isOpen={this.flag === InputType.PSW}>
|
|
|
|
|
isOpen={this.flag === InputType.PHONE}
|
|
|
|
|
>
|
|
|
|
|
<InputGroup
|
|
|
|
|
type="password"
|
|
|
|
|
value={this.state.pass_word}
|
|
|
|
|
intent={this.inputIntent.PSW}
|
|
|
|
|
value={this.registInput.user_phone}
|
|
|
|
|
intent={this.inputIntent.PHONE}
|
|
|
|
|
name="txt"
|
|
|
|
|
placeholder={"手机号"}
|
|
|
|
|
onChange={e =>
|
|
|
|
|
{
|
|
|
|
|
this.setState({ pass_word: e.target.value });
|
|
|
|
|
this.valueTest(InputType.PSW, e.target.value)
|
|
|
|
|
this.registInput.user_phone = e.target.value;
|
|
|
|
|
this.valueTest(InputType.PHONE)
|
|
|
|
|
}}
|
|
|
|
|
onBlur={() => (this.flag = InputType.OK)}
|
|
|
|
|
/>
|
|
|
|
|
</Tooltip>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="item">
|
|
|
|
|
<Label className={Classes.INLINE}>
|
|
|
|
|
<span>* </span>
|
|
|
|
|
<span>确认密码:</span>
|
|
|
|
|
</Label>
|
|
|
|
|
<InputGroup
|
|
|
|
|
className={"check-code"}
|
|
|
|
|
value={this.registInput.check_code}
|
|
|
|
|
placeholder={"请输入验证码"}
|
|
|
|
|
onChange={e =>
|
|
|
|
|
{
|
|
|
|
|
this.registInput.check_code = e.target.value;
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
<Button
|
|
|
|
|
disabled={!(this.inputIntent.PHONE === Intent.SUCCESS) || !(this.SMSBtnText === "获取短信验证码")}
|
|
|
|
|
style={{ height: 30, marginLeft: 10 }}
|
|
|
|
|
text={this.SMSBtnText}
|
|
|
|
|
intent={Intent.NONE}
|
|
|
|
|
onClick={this.handleSMS}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="item">
|
|
|
|
|
<Tooltip
|
|
|
|
|
content={this.errMsg}
|
|
|
|
|
position={Position.TOP}
|
|
|
|
|
intent={Intent.WARNING}
|
|
|
|
|
isOpen={this.flag === InputType.ComfirmPSW}>
|
|
|
|
|
isOpen={this.flag === InputType.PSW}>
|
|
|
|
|
<InputGroup
|
|
|
|
|
type="password"
|
|
|
|
|
value={this.state.pswConfirm}
|
|
|
|
|
intent={this.inputIntent.ComfirmPSW}
|
|
|
|
|
type={this.pwdInputType1 ? "password" : "text"}
|
|
|
|
|
onInput={() => this.pwdInputType1 = true}
|
|
|
|
|
value={this.registInput.pass_word}
|
|
|
|
|
intent={this.inputIntent.PSW}
|
|
|
|
|
autoComplete={"new-password"}
|
|
|
|
|
placeholder={"密码: 6-20个大小英文字母、符号或数字"}
|
|
|
|
|
onChange={e =>
|
|
|
|
|
{
|
|
|
|
|
this.setState({ pswConfirm: e.target.value });
|
|
|
|
|
this.valueTest(InputType.ComfirmPSW, e.target.value);
|
|
|
|
|
this.registInput.pass_word = e.target.value;
|
|
|
|
|
this.valueTest(InputType.PSW)
|
|
|
|
|
}}
|
|
|
|
|
onBlur={() => (this.flag = InputType.OK)}
|
|
|
|
|
onBlur={() => this.flag = InputType.OK}
|
|
|
|
|
/>
|
|
|
|
|
</Tooltip>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="item">
|
|
|
|
|
<Label className={Classes.INLINE}>
|
|
|
|
|
<span>* </span>
|
|
|
|
|
<span>联系手机:</span>
|
|
|
|
|
</Label>
|
|
|
|
|
<Tooltip
|
|
|
|
|
content={this.errMsg}
|
|
|
|
|
position={Position.TOP}
|
|
|
|
|
intent={Intent.WARNING}
|
|
|
|
|
isOpen={this.flag === InputType.PHONE}
|
|
|
|
|
>
|
|
|
|
|
isOpen={this.flag === InputType.ComfirmPSW}>
|
|
|
|
|
<InputGroup
|
|
|
|
|
value={this.state.user_phone}
|
|
|
|
|
intent={this.inputIntent.PHONE}
|
|
|
|
|
type={this.pwdInputType2 ? "password" : "text"}
|
|
|
|
|
onInput={() => this.pwdInputType2 = true}
|
|
|
|
|
value={this.registInput.pswConfirm}
|
|
|
|
|
intent={this.inputIntent.ComfirmPSW}
|
|
|
|
|
autoComplete={"new-password"}
|
|
|
|
|
placeholder={"确认密码: 请再次输入您的密码"}
|
|
|
|
|
onChange={e =>
|
|
|
|
|
{
|
|
|
|
|
this.setState({ user_phone: e.target.value });
|
|
|
|
|
this.valueTest(InputType.PHONE, e.target.value)
|
|
|
|
|
this.registInput.pswConfirm = e.target.value;
|
|
|
|
|
this.valueTest(InputType.ComfirmPSW);
|
|
|
|
|
}}
|
|
|
|
|
onBlur={() => (this.flag = InputType.OK)}
|
|
|
|
|
/>
|
|
|
|
|
</Tooltip>
|
|
|
|
|
<Button
|
|
|
|
|
disabled={!(this.inputIntent.PHONE === Intent.SUCCESS) || !(this.SMSBtnText === "获取短信验证码")}
|
|
|
|
|
style={{ height: 30, marginLeft: 10 }}
|
|
|
|
|
text={this.SMSBtnText}
|
|
|
|
|
intent={Intent.NONE}
|
|
|
|
|
onClick={this.handleSMS}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="item">
|
|
|
|
|
<Label className={Classes.INLINE}>
|
|
|
|
|
<span>* </span>
|
|
|
|
|
<span>短信验证码:</span>
|
|
|
|
|
</Label>
|
|
|
|
|
<InputGroup
|
|
|
|
|
value={this.state.check_code}
|
|
|
|
|
onChange={e =>
|
|
|
|
|
{
|
|
|
|
|
this.setState({ check_code: e.target.value });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="regist-footer" style={infoBlockStyle}>
|
|
|
|
|
<div className="regist-footer info-block" >
|
|
|
|
|
<div className="item center">
|
|
|
|
|
<div style={{ display: "flex" }}>
|
|
|
|
|
<Checkbox
|
|
|
|
|
checked={this.state.agreement_checked}
|
|
|
|
|
checked={this.registInput.agreement_checked}
|
|
|
|
|
onChange={() =>
|
|
|
|
|
{
|
|
|
|
|
this.setState({ agreement_checked: !this.state.agreement_checked });
|
|
|
|
|
this.registInput.agreement_checked = !this.registInput.agreement_checked;
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
<span>
|
|
|
|
@ -369,19 +395,20 @@ export default class Regist extends React.Component<{ store?: TopPanelStore }, I
|
|
|
|
|
</div>
|
|
|
|
|
<div className="item center">
|
|
|
|
|
<Button
|
|
|
|
|
style={{ width: 173 }}
|
|
|
|
|
style={{ width: 330 }}
|
|
|
|
|
disabled={!this.registInput.agreement_checked}
|
|
|
|
|
text="注册"
|
|
|
|
|
className="bp3-intent-success"
|
|
|
|
|
onClick={this.handleRegist}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="item center">
|
|
|
|
|
<div className="item center" style={{ fontSize: 15 }}>
|
|
|
|
|
我已注册,
|
|
|
|
|
<a
|
|
|
|
|
target="_blank"
|
|
|
|
|
onClick={() => { this.props.store.openRegist = !this.props.store.openRegist; }}
|
|
|
|
|
>
|
|
|
|
|
登录
|
|
|
|
|
点击登录
|
|
|
|
|
</a>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
@ -411,7 +438,7 @@ class UserAgreement extends React.Component<IUserAgreementProps, {}> {
|
|
|
|
|
>
|
|
|
|
|
<div
|
|
|
|
|
className={Classes.DIALOG_BODY}
|
|
|
|
|
style={{ padding: 20 }}
|
|
|
|
|
style={{ padding: 20, height: 600, overflow: "auto" }}
|
|
|
|
|
>
|
|
|
|
|
<p><strong>尊敬的用户,欢迎您注册成为本网站用户。在注册前请您仔细阅读如下服务条款:</strong></p>
|
|
|
|
|
|
|
|
|
|