!383 注册页面UI更新

pull/383/MERGE
肖诗雅 5 years ago committed by ChenX
parent 0ed1ef97e1
commit 9d16e5f5fc

@ -18,6 +18,7 @@ export const SignUrl = {
regist: CURRENT_HOST + "/CAD-reg",
SMSCode: CURRENT_HOST + "/CAD-checkCode",
LoginStatus: CURRENT_HOST + "/CAD-loginStatus",
checkRegUser: CURRENT_HOST + "/CAD-checkRegUser",
}
export const ImgsUrl = {
get: CURRENT_HOST + "/CAD-imageList",

@ -256,3 +256,58 @@ export function getFileSize(size: number)
size /= 1024;
}
}
//CookieUtils
/**
* cookie
* @param name
* @param value
* @param expiresHours
*/
export function addCookie(name, value, expiresHours)
{
let cookieString = `${name}=${escape(value)}`;
// 判断是否设置过期时间,0代表关闭浏览器时失效
if (expiresHours > 0)
{
const date = new Date();
date.setTime(date.getTime() + expiresHours * 1000);
cookieString = `${cookieString};expires=${date.toUTCString()}`;
}
document.cookie = cookieString;
}
/**
* cookie
* @param name
* @param value
* @param expiresHours
*/
export function editCookie(name, value, expiresHours)
{
let cookieString = `${name}=${escape(value)}`;
if (expiresHours > 0)
{
const date = new Date();
date.setTime(date.getTime() + expiresHours * 1000); // 单位是毫秒
// @ts-ignore
cookieString = `${cookieString};expires=${date.toGMTString()}`;
}
document.cookie = cookieString;
}
/**
* cookie
* @param name
*/
export function getCookieValue(name)
{
const strCookie = document.cookie;
const arrCookie = strCookie.split('; ');
for (const cookie of arrCookie)
{
const arr = cookie.split('=');
if (arr[0] === name)
return unescape(arr[1]);
}
}

@ -7,7 +7,7 @@ export enum ZINDEX
MainContent = "35", //主要内容的层级
ToolBar = "2", //工具栏
RightMenu = "31",//右键菜单
Portal = "34", //model.less
Portal = "37", //Modal.less
ToolsBlock_small = "32",
CommandInput = "28",
TransparentTerminal = "0",

@ -138,21 +138,77 @@
}
.regist{
overflow: auto;
min-width: 660px;
min-width: 600px;
width: 620px;
height: 100%;
margin: 0 auto;
letter-spacing: 2.5px;
.regist-content{
position: relative;
top: 30%;
background: #fff;
padding: 10px;
top: 38%;
transform: translateY(-30%);
.regist-header{
background: #48aff0;
display: flex;
height: 72px;
position: relative;
img{
position: absolute;
top: 12%;
width: 55px;
height: auto;
vertical-align: middle;
margin-right: 10px;
margin-left: 65px;
}
.regist-slogan{
text-align: center;
width: 100%;
span{
color: #fff;
font-size: 26px;
line-height: 72px;
}
}
}
.regist-title{
text-align: center;
height: 48px;
span{
color: #48aff0;
font-size: x-large;
line-height: 48px;
}
}
.info-block{
width: 70%;
margin: 10px auto;
padding: 5px 20px;
min-width: 480px;
>div{
width: 60%;
min-width: 330px;
margin: 0 auto;
}
.item{
padding-bottom: 10px;
}
}
}
.item{
display: flex;
>label{
display: inline-block;
width: 90px;
text-align: right;
&>span:first-child{
color: red;
}
.bp3-input-group:not(.check-code){
width: 330px;
}
.bp3-button{
width: 150px;
}
}
.regist-footer{
.bp3-button{
width: 330px;
}
}
.center{
@ -161,7 +217,15 @@
}
a{
text-decoration: none;
color: #106ba3;
color: #48aff0;
}
.bp3-button{
background: #48aff0;
color: #fff;
}
.bp3-disabled{
background: #D1D1D1;
color: #9BA4AC;
}
}
.content{

@ -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>

@ -10,7 +10,7 @@
@infoSelectWidth:9rem;
.bp3-portal{
z-index: 34;
z-index: 37;
}
#modal{

Loading…
Cancel
Save