手机号注册登录+声明功能优化

This commit is contained in:
谢思 2022-11-15 15:16:27 +08:00
parent c2bb54738a
commit 0a32913247
11 changed files with 481 additions and 409 deletions

View File

@ -141,58 +141,3 @@ body {
min-height: calc(100% - 60px) !important;
}
}
.feedBackModal .ant-modal-header{
border-bottom: none;
background: none;
padding: 16px 24px 0;
}
.feedBackModal .ant-modal-title{
font-weight:500 !important;
color:#151d40;
font-size:18px;
}
.feedBackModal .anticon-close{
font-size: 22px;
}
.feedBackModal .ant-modal-footer{
border-top: none;
text-align: center;
padding-bottom: 40px;
}
.feedBackModal .ant-modal-content{
background-image:linear-gradient(359.37deg,#ebf3ff 0%,#f8fbff 55.01%,#cbdbff 100%);
border:1.5px solid #ffffff;
}
.feedBackModal .feedBackText{
padding: 20px;
font-size:15px;
color:#202d40;
}
.feedBackModal .feedBackText::placeholder{
color:#afb7c2;
}
.feedBackModal .gotoIssueFeedBack{
color: rgba(70, 106, 255, 1);
}
.feedBackBox{
position: relative;
background-color: white;
}
.feedBackText.errorInput{
border: 1px solid #f60011;
}
.errorInput{
background-color:rgba(255, 0, 0, 0.04) !important;
}
.ant-input.errorInput:hover{
background-color: white !important;
}
.countNumBox{
position: absolute;
bottom: 2px;
right: 10px;
}

View File

@ -25,7 +25,7 @@ if (isDev) {
}
debugType = window.location.search.indexOf('debug=t') !== -1 ? 'teacher' :
window.location.search.indexOf('debug=s') !== -1 ? 'student' :
window.location.search.indexOf('debug=a') !== -1 ? 'admin' : parsed.debug || 'admin'
window.location.search.indexOf('debug=a') !== -1 ? 'admin' : parsed.debug || ''
}
window._debugType = debugType;
export function initAxiosInterceptors(props) {

View File

@ -460,3 +460,58 @@ li.ant-menu-item{
}
}
}
.feedBackModal .ant-modal-header{
border-bottom: none;
background: none;
padding: 16px 24px 0;
}
.feedBackModal .ant-modal-title{
font-weight:500 !important;
color:#151d40;
font-size:18px;
}
.feedBackModal .anticon-close{
font-size: 22px;
}
.feedBackModal .ant-modal-footer{
border-top: none;
text-align: center;
padding-bottom: 40px;
}
.feedBackModal .ant-modal-content{
background-image:linear-gradient(359.37deg,#ebf3ff 0%,#f8fbff 55.01%,#cbdbff 100%);
border:1.5px solid #ffffff;
}
.feedBackModal .feedBackText{
padding: 20px;
font-size:15px;
color:#202d40;
}
.feedBackModal .feedBackText::placeholder{
color:#afb7c2;
}
.feedBackModal .gotoIssueFeedBack{
color: rgba(70, 106, 255, 1);
}
.feedBackBox{
position: relative;
background-color: white;
}
.feedBackText.errorInput{
border: 1px solid #f60011;
}
.errorInput{
background-color:rgba(255, 0, 0, 0.04) !important;
}
.ant-input.errorInput:hover{
background-color: white !important;
}
.countNumBox{
position: absolute;
bottom: 2px;
right: 10px;
}

View File

@ -657,7 +657,7 @@ a.issue-type-button.active:hover {
line-height: 18px;
margin-left: 8px;
background-color: rgba(235,244,254,1);
color: #1890ff;
color: $primary-color;
font-size: 12px;
padding: 2px 8px;
border-radius: 9px;

View File

@ -13,6 +13,9 @@
.menuPanels{
width: 295px;
&.maxWidth{
width: 400px;
}
.leftline{
position: relative;
color: #666;
@ -43,16 +46,13 @@
}
.claimNote_input{
// up, right, botton, left
margin: 5px 10px 5px 10px;
padding-top: 10px;
padding-bottom: 10px;
padding: 15px;
}
.claimNote{
// up, right, botton, left
margin: 5px 14px 0px 14px;
padding-bottom: 5px;
margin: 5px 14px;
padding-bottom: 10px;
word-break: break-all;
}
.attrPerson{
padding-top: 12px;

View File

@ -1,288 +1,341 @@
import React, { Component } from "react";
import React from "react";
import axios from "axios";
import { AlignCenter , FlexAJ } from '../Component/layout';
import { Popover, List, Button, Dropdown, Input} from "antd";
import { AlignCenter, FlexAJ } from "../Component/layout";
import { Popover, Button, Input } from "antd";
import { Link } from "react-router-dom";
import { getImageUrl } from "educoder";
import "./claim.scss"
import "./claim.scss";
const { TextArea } = Input;
class claims extends React.Component {
constructor(props) {
super(props);
this.state = {
claimerdata: new Array(),
currentUserClaimed:0,
issue_id:this.props.issue_id,
claimNoteBody:'',
claimNoteBodyChanged:false,
claimNotePop:false
};
};
constructor(props) {
super(props);
this.state = {
claimerData: new Array(),
currentUserClaimed: 0,
issue_id: this.props.issue_id,
claimNoteBody: "",
claimNoteBodyChanged: false,
claimNotePop: false,
claimNoteBodyError: undefined,
// 原声明信息
currentUserClaimedContent: undefined
};
}
getClaimers = ()=>{
const {issue_id} = this.state;
axios.get(`/issues/${issue_id}/claims.json`)
.then((result) => {
if(result){
getClaimers = () => {
const { issue_id } = this.state;
const { current_user } = this.props;
axios
.get(`/issues/${issue_id}/claims.json`)
.then((result) => {
if (result) {
this.setState({
claimerdata: result.data.claimers,
currentUserClaimed: result.data.currentUserclaimed,
});
}
}).catch(function (error) {
console.log(error);
});
};
delClaim = () => {
if (this.props.checkIfLogin() === false) {
this.props.showLoginDialog();
return;
} else {
const {issue_id} = this.state;
axios({
method: 'delete',
url: `/issues/${issue_id}/claims.json`
}).then(result => {
this.setState({
claimerdata: result.data.claimers,
currentUserClaimed: result.data.currentUserclaimed,
claimNotePop:false,
claimNoteBody:'',
});
const { refreshFunc } = this.props;
refreshFunc && refreshFunc();
})
.catch(error => {
console.log(error);
claimerData: result.data.claimers,
currentUserClaimed: result.data.currentUserclaimed,
});
// 如果用户有声明此issue则赋值currentUserClaimedContent、claimNoteBody
if(result.data.currentUserclaimed){
const map = result.data.claimers.filter(item =>{return item.user_login === current_user.login});
this.setState({
currentUserClaimedContent: map[0],
claimNoteBody: map[0] && map[0].note_body
})
}
}
};
changeClaimNote = (e)=>{
})
.catch(function (error) {
console.log(error);
});
};
delClaim = () => {
if (this.props.checkIfLogin() === false) {
this.props.showLoginDialog();
return;
} else {
const { issue_id } = this.state;
axios({
method: "delete",
url: `/issues/${issue_id}/claims.json`,
})
.then((result) => {
this.setState({
claimerData: result.data.claimers,
currentUserClaimed: result.data.currentUserclaimed,
claimNotePop: false,
claimNoteBody: "",
currentUserClaimedContent: undefined
});
const { refreshFunc } = this.props;
refreshFunc && refreshFunc();
})
.catch((error) => {
console.log(error);
});
}
};
changeClaimNote = (e) => {
this.setState({
claimNoteBodyError: undefined,
claimNoteBody: e.target.value,
claimNoteBodyChanged: true,
});
};
};
yesClaim = ()=>{
const {issue_id,claimNoteBody} = this.state;
const { refreshFunc } = this.props;
axios.post(`/issues/${issue_id}/claims.json`, {
claim_note: claimNoteBody
})
.then(result => {
this.setState({
claimerdata: result.data.claimers,
yesClaim = () => {
const { issue_id, claimNoteBody, currentUserClaimed, currentUserClaimedContent} = this.state;
const { refreshFunc, current_user} = this.props;
if(claimNoteBody){
// 新增声明
if(!currentUserClaimed){
axios.post(`/issues/${issue_id}/claims.json`, {
claim_note: claimNoteBody,
})
.then((result) => {
const map = result.data.claimers.filter(item =>{return item.user_login === current_user.login});
this.setState({
claimerData: result.data.claimers,
currentUserClaimed: result.data.currentUserclaimed,
claimNotePop:false,
claimNotePop: false,
currentUserClaimedContent: map[0],
claimNoteBody: map[0] && map[0].note_body
});
refreshFunc && refreshFunc();
})
.catch(error => {
})
.catch((error) => {
console.log(error);
});
};
addClaim = ()=> {
if (this.props.checkIfLogin() === false) {
this.props.showLoginDialog();
return;
}else{
this.setState({
claimNotePop: true,
});
}
};
updateClaim = (claimId,key)=>{
const {issue_id,claimNoteBody,claimNoteBodyChanged} = this.state;
const { refreshFunc } = this.props;
if(claimNoteBodyChanged){
// 更新声明
axios.put(`/issues/${issue_id}/claims.json`, {
claim_note: claimNoteBody,
claim_id: claimId
claim_id: currentUserClaimedContent.claim_id,
})
.then(result => {
.then((result) => {
this.setState({
claimerdata: result.data.claimers,
currentUserClaimed: result.data.currentUserclaimed,
});
refreshFunc && refreshFunc();
})
.catch(error => {
console.log(error);
claimerData: result.data.claimers,
currentUserClaimed: result.data.currentUserclaimed,
claimNotePop: false
});
}
this.setVisibleFunc(false,key)
};
refreshFunc && refreshFunc();
})
.catch((error) => {
console.log(error);
});
}
}else{
this.setState({claimNoteBodyError: '请输入您的声明留言'});
}
};
addClaim = () => {
if (this.props.checkIfLogin() === false) {
this.props.showLoginDialog();
return;
} else {
this.setState({
claimNotePop: true,
});
}
};
cancleClaim = ()=>{
cancelClaim = () => {
const {currentUserClaimedContent} = this.state;
this.setState({
claimNotePop: false,
})
};
claimNoteBodyError: undefined,
claimNoteBody: currentUserClaimedContent ? currentUserClaimedContent.note_body : ''
});
};
componentDidMount = () => {
this.getClaimers();
};
componentDidMount = () => {
this.getClaimers();
};
setVisibleFunc = (flag,index) => {
const {claimerdata} = this.state
var lx = claimerdata.concat();
lx.map(i=>i.visible =false);
if(flag){
setVisibleFunc = (flag, index) => {
const { claimerData } = this.state;
var lx = claimerData.concat();
lx.map((i) => (i.visible = false));
if (flag) {
lx[index].visible = flag;
}
lx.splice();
this.setState({
claimerdata:lx
})
}
claimerData: lx,
});
};
render() {
const {
claimerdata,
currentUserClaimed,
issue_id
} = this.state;
const rednerlist = (item)=>{
return (
<div>
<Link to={`/${item && item.user_login}`} className="show-user-link">
<img
className="radius"
src={getImageUrl(`/${item && item.user_picture}`)}
alt=""
width="30"
height="30"/>
</Link>
<Link to={`/${item && item.user_login}`}
className="show-user-link color-black ml10 fwb">
{item && item.user_name}
</Link>
<span className="color-grey-8"> 声明于 {item.created_at}</span>
</div>
);
};
const renderClaim = ()=>{
return(
<div className="claimNote_input">
<span> 声明留言</span> <br/>
<TextArea rows={4} type="text" placeholder="例如可以留言你的解决思路......" onChange={this.changeClaimNote}/><br/><br/>
<div style={{display:"flex",justifyContent:'center'}}>
<Button onClick={()=>this.cancleClaim()} > </Button>
<Button onClick={()=>this.yesClaim()} style={{marginLeft:"20px"}} type={'primary'} > </Button>
</div>
</div>
)
};
render() {
const { claimerData, currentUserClaimed, claimNoteBody, claimNoteBodyError } = this.state;
const renderUser = (item,key)=>{
const { current_user} = this.props;
const renderClaim = () => {
return (
<div className="claimNote_input" style={{ width: "400" }}>
<div className="mb5"> 声明留言</div>
<TextArea
rows={6}
type="text"
placeholder="例如可以留言你的解决思路......"
onChange={this.changeClaimNote}
value={claimNoteBody}
className={claimNoteBodyError ? 'error' : ''}
/>
<div className="mt10" style={{color: 'red'}}>{claimNoteBodyError}</div>
<div style={{ display: "flex", justifyContent: "center" }} className="mt10">
<Button onClick={() => this.cancelClaim()}> </Button>
<Button
onClick={() => this.yesClaim()}
style={{ marginLeft: "20px" }}
type={"primary"}
>
</Button>
</div>
</div>
);
};
return (
<div>
<FlexAJ className="menuMaininfos">
<AlignCenter>
<Link to={`/${item && item.user_login}`} className="show-user-link">
<img
className="radius"
src={getImageUrl(`/${item && item.user_picture}`)}
alt=""
width="30"
height="30"/>
</Link>
<Link to={`/${item && item.user_login}`}
className="show-user-link color-black ml10 fwb">
<div >
{current_user.login == item.user_login?(<div></div>
):(
<div>{item && item.user_name}</div>
)}
</div>
</Link>
<div style={{marginLeft:"10px"}}> <span className="color-grey-8"> 声明于 {item.created_at}</span></div>
</AlignCenter>
</FlexAJ>
<div className="claimNote">
{current_user.login==item.user_login?(
<div><span>你的留言</span><br/>
<TextArea onChange={this.changeClaimNote} type="text" defaultValue={item.note_body} /><br/>
<div style={{display:"flex",justifyContent:'center',paddingBottom:"10px",paddingTop:"10px"}}>
<Button onClick={()=>this.updateClaim(item.claim_id,key)} type={'primary'} >更新声明留言</Button>
</div>
</div>
):
(
const renderUser = (item, key) => {
const { current_user } = this.props;
return (
<div>
<FlexAJ className="menuMaininfos">
<AlignCenter>
<Link
to={`/${item && item.user_login}`}
className="show-user-link"
>
<img
className="radius"
src={getImageUrl(`/${item && item.user_picture}`)}
alt=""
width="30"
height="30"
/>
</Link>
<Link
to={`/${item && item.user_login}`}
className="show-user-link color-black ml10 fwb"
>
<div>
{item.note_body.length==0?(
<span>未留言</span>
):(
<div><span>声明留言</span><br/>
<span>{item.note_body}</span></div>
)}
{current_user.login == item.user_login ? (
<div></div>
) : (
<div>{item && item.user_name}</div>
)}
</div>
)}
</div>
</div>
)
};
return (
<div>
{currentUserClaimed===1?(
<div><Button onClick={()=>this.delClaim()} >取消声明</Button>
</div>
):(
<Popover visible={this.state.claimNotePop} content={renderClaim()} trigger='click' placement="bottom" overlayClassName="menuPanels">
<Button onClick={()=> this.addClaim()} type="primary"><i className="iconfont icon-shengming font-14 mr5 color-white"></i></Button>
</Popover>
)}
<div className="ant-divider ant-divider-horizontal"> </div>
{
claimerdata&&claimerdata.length>0?(
<div>
<div className="mt15">
<span>声明要关注/解决此疑修的用户</span>
<span className="infoCount">{claimerdata.length}</span>
</Link>
<div style={{ marginLeft: "10px" }}>
{" "}
<span className="color-grey-8"> 声明于 {item.created_at}</span>
</div>
<div className="attrPerson" onMouseLeave={()=>this.setVisibleFunc(false)}>
{claimerdata.map((item,key)=>{
return(
<Popover content={renderUser(item,key)} visible={item.visible} placement="top" overlayClassName="menuPanels">
<Link key={key} to={`/${item.user_login}`}>
<img src={getImageUrl(`/${item.user_picture}`)} alt="" onMouseOver={()=>this.setVisibleFunc(true,key)}/>
</Link>
</Popover>
)
})}
</AlignCenter>
</FlexAJ>
<div className="claimNote">
{current_user.login == item.user_login ? (
<div>
<div className="mb5">你的留言</div>
<span>{item.note_body}</span>
<br />
<div
style={{
display: "flex",
justifyContent: "center",
paddingBottom: "10px",
paddingTop: "10px",
}}
>
<Button
onClick={() => this.delClaim()}
type={"primary"}
>
取消声明
</Button>
</div>
</div>
</div>):(
<div className='mt15'>
) : (
<div>
{item.note_body.length == 0 ? (
<span>未留言</span>
) : (
<div>
<div className="mb5">声明留言</div>
<span>{item.note_body}</span>
</div>
)}
</div>
)}
</div>
</div>
);
};
return (
<div>
<Popover
visible={this.state.claimNotePop}
content={renderClaim()}
trigger="click"
placement="bottom"
overlayClassName="menuPanels maxWidth"
>
{currentUserClaimed === 1 ? <a
className="topWrapper_btn"
onClick={() => {this.setState({claimNotePop: true});}}
style={{ display: "inline-block" }}
>
更改声明
</a> : <Button onClick={() => this.addClaim()} type="primary">
<i className="iconfont icon-shengming font-14 mr5 color-white"></i>
声明
</Button>}
</Popover>
<div className="ant-divider ant-divider-horizontal"> </div>
{claimerData && claimerData.length > 0 ? (
<div>
<div className="mt15">
<span>声明要关注/解决此疑修的用户</span>
<span className="infoCount">0</span>
<span className="infoCount">{claimerData.length}</span>
</div>
)}
</div>
);
}
}
<div
className="attrPerson"
onMouseLeave={() => this.setVisibleFunc(false)}
>
{claimerData.map((item, key) => {
return (
<Popover
content={renderUser(item, key)}
visible={item.visible}
placemen
t="top"
overlayClassName="menuPanels"
width={400}
>
<Link key={key} to={`/${item.user_login}`}>
<img
src={getImageUrl(`/${item.user_picture}`)}
alt=""
onMouseOver={() => this.setVisibleFunc(true, key)}
/>
</Link>
</Popover>
);
})}
</div>
</div>
) : (
<div className="mt15">
<span>声明要关注/解决此疑修的用户</span>
<span className="infoCount">0</span>
</div>
)}
</div>
);
}
}
export default claims;
export default claims;

View File

@ -518,7 +518,7 @@ class LoginDialog extends Component {
}
value={this.state.loginValue}
name="username"
placeholder="请输入邮箱地址/用户名" ></input>
placeholder="请输入手机号/邮箱/用户名" ></input>
<div style={{ height: '25px' }}><p className="color-orange edu-txt-left none" id="username_error_notice"
style={{ display: Phonenumberisnotco === undefined ? 'none' : 'block' }}>{Phonenumberisnotco}</p></div>

View File

@ -15,13 +15,14 @@ function Login(props){
useEffect(()=>{
//DOMvalue
clear;
clear();
//
setSetting(JSON.parse(localStorage.getItem("chromesetting")));
},[])
//
function handleSubmit(){
setMessage(undefined);
form.validateFields((err, values) => {
if (!err) {
axios.post(`/accounts/login.json`, {
@ -46,12 +47,6 @@ function Login(props){
});
}
//
function comfirmWrite(rule, value, callback, index){
setMessage(undefined);
value ? callback():index === 1? callback("请输入邮箱地址或用户名登录"):callback("请输入登录密码");
}
//value->DOM
function clear(){
const password = document.getElementById("login_password");
@ -65,28 +60,30 @@ function Login(props){
return(
<div>
<div className="right_cont login_content">
<div className="login_register_head">
<div className="login_register_head mb30">
<span>欢迎登录 GitLink</span>
<span className="link_span">没有账号<Link to={`/register`}>去注册</Link></span>
</div>
<p className = {message?"message active":"message"}>{message}</p>
<p className = {message?"message active mb10":"message"}>{message}</p>
<Form className="login-form">
<Form.Item>
{getFieldDecorator('username',{
rules:[
{
validator: (rule, value, callback) => { comfirmWrite(rule, value, callback, 1) }
required:true,
message:"请输入手机号/邮箱/用户名"
}
],
validateTrigger:"onBlur",
})(<Input className="account" placeholder="请输入邮箱地址/用户名"/>)}
})(<Input className="account" placeholder="请输入手机号/邮箱/用户名"/>)}
</Form.Item>
<Form.Item>
{getFieldDecorator('password', {
rules: [
{
validator: (rule, value, callback) => { comfirmWrite(rule, value, callback, 2) }
required:true,
message:"请输入登录密码"
}
],
validateTrigger:"onBlur",

View File

@ -78,7 +78,7 @@
padding: 2.5em 5em;
border-radius: 7px;
font-size: 15px;
& .login_register_head{
.login_register_head{
display: flex;
justify-content: space-between;
align-items: center;
@ -89,17 +89,15 @@
line-height: 1.5;
}
//注册页面的获取验证码输入框
& .ant-input{width: 18rem; }
.ant-input{width: 18rem; }
}
//第一个输入框
& .account{margin-top: 4vh; }
//所有的链接
& a{
.link_span a{
color: #466AFF;
&:hover{opacity:0.8; }
}
//登录 注册 重置密码并登录按钮
& .login_register_cofBut{
.login_register_cofBut{
font-size: 1em;
width: 100%;
height: 3.1em;
@ -128,28 +126,25 @@
border-color: #d9d9d9;
}
//输入密码提示框
& .password_tips{
.password_tips{
margin-top: -10px;
padding-bottom: 8px;
color: #808080;
font-size: 0.9em;
}
& .message, .ant-form-explain{
.message, .ant-form-explain{
color: #D40000;
font-size: 13px;
}
& .message.active{
margin-bottom: -30px !important;
}
//antd 输入框样式
& .ant-input{
.ant-input{
height: 3.1em;
background-color: #F7F7F7 !important;
font-size: 1em;
color: #333333;
&:hover{border-color:#466AFF; }
}
& .ant-form-explain{
.ant-form-explain{
margin-top: 0.5vh;
margin-bottom: -10px;
}
@ -181,20 +176,20 @@
top: 18vh;
background-image: url(./img/loginBg.png);
//下次自动登录&&忘记密码
& .login_register_head.login{
.login_register_head.login{
.ant-form-item{
margin-bottom: 0;
margin-top: -1vh;
}
}
//第三方登录
& .quick_logon{
.quick_logon{
text-align: center;
& .quick_logon_p{
.quick_logon_p{
border-top: 1px solid #979797;
margin-top: 24px;
}
& .startlogin{
.startlogin{
position: relative;
background: #dee1f4;
display: block;
@ -211,10 +206,10 @@
.Register_content{
// top: 8em;
background-image: url(./img/registerBg.png);
& .register_last_form .ant-form-item-control{
.register_last_form .ant-form-item-control{
line-height: 0.5;
}
& .login_register_cofBut{margin-top: 0.5vh; }
.login_register_cofBut{margin-top: 0.5vh; }
}
//找回密码框样式
@ -222,12 +217,21 @@
// top: 12vh;
background-image: url(./img/resetPasswordBg.png);
// height: 550px;
& .resetFailCaptcha{
.resetFailCaptcha{
position: absolute;
top: 25px;
color: #D40000;
font-size: 13px;
}
& .login_register_cofBut{margin-top: 1.5vh; }
.login_register_cofBut{margin-top: 1.5vh; }
}
}
.registerNav{
.type{color: #000;}
.activeRegisterNav{
color: $primary-color;
display: inline-block;
border-bottom: 2px solid;
}
}

View File

@ -7,7 +7,7 @@ import './LoginRegisterPage.scss';
function Register(props){
const {form} = props;
const {getFieldDecorator } = form;
const {getFieldDecorator, setFieldsValue } = form;
//
const [emailStr, setEmailStr] = useState(undefined);
//check.json
@ -20,10 +20,12 @@ function Register(props){
//
const [userNameGo, setUserNameGo] = useState(true);
const [emailGo, setEmailGo] = useState(true);
// (/)
const [registerType, setRegisterType] = useState(0);
const seconds = useRef();
let interval = undefined;
//
const inputEl = useRef(null);
// const inputEl = useRef(null);
//
function handleSubmit(){
@ -52,7 +54,7 @@ function Register(props){
}
});
}
//username
function usernameConfirm(rule, value, callback){
setUserNameGo(true);
@ -70,23 +72,33 @@ function Register(props){
}):callback();setLoginStr(undefined);
}
//
///
function emailConfirm(rule, value, callback) {
setEmailGo(true);
value && (emailGo || value !== emailStr) ? axios.post(`/accounts/check.json`, {
value: value,
type: 2
}).then(response => {
if (response.data.status === -1) {
setGetCaptchaBut(false);
callback(response.data.message);
} else {
setEmailStr(value);
setGetCaptchaBut(true);
setEmailGo(false);
callback();
if(value){
if((/(^(\d{3,4}-)?\d{7,8})$|([1][3,4,5,6,7,8,9][0-9]{9})/.test(value) && !registerType) || (/^[a-zA-Z0-9]+([.\-_\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/.test(value) && registerType)){
setEmailGo(true);
(emailGo || value !== emailStr) ? axios.get(`/accounts/valid_email_and_phone.json`, {
params: {
login: value,
type: 1
}
}).then(response => {
if(!response.data.status){
setEmailStr(value);
setGetCaptchaBut(true);
setEmailGo(false);
callback();
}else{
setGetCaptchaBut(false);
callback(response.data.message);
}
}):callback();setEmailStr(undefined);
}else{
callback(`请输入正确的${registerType ? '邮箱地址' : '手机号'}`);
}
}):callback();setEmailStr(undefined);
}else{
callback(`请输入${registerType ? '邮箱地址' : '手机号'}`);
}
}
//
@ -163,7 +175,7 @@ function Register(props){
if (response.data && response.data.status === 0) {
//
let email = emailStr.substring(emailStr.indexOf("@")+1);
message.success({content:<span>验证码已发送请注意查收<a href={`https://mail.${email}`} target="_blank">前往邮箱</a></span>});
message.success({content:<span>验证码已发送请注意查收{registerType ? <a href={`https://mail.${email}`} target="_blank">前往邮箱</a> : ''}</span>});
} else {
//,
setGetCaptchaBut(false);
@ -192,17 +204,27 @@ function Register(props){
}
useEffect(() => {
inputEl.current.focus();
clear;
// inputEl.current.focus();
// clear;
}, [])
function changeRegisterType(type){
setGetCaptchaBut(false);
setRegisterType(type);
setFieldsValue({'email': undefined})
}
return(
<div>
<div className="right_cont Register_content">
<div className="login_register_head">
<div className="login_register_head mb30">
<span>欢迎注册 GitLink</span>
<span className="link_span">已有账号<Link to={`/login`}>立即登录</Link></span>
</div>
<div className="registerNav mb20 font-18">
<a className={`type ${registerType ? '' : 'activeRegisterNav'}`} onClick={()=>{changeRegisterType(0)}}>手机号注册</a>
<a className={`type ${registerType ? 'activeRegisterNav' : ''} ml50`} onClick={()=>{changeRegisterType(1)}}>邮箱注册</a>
</div>
<p className={mess ? "message active" : "message"}>{mess}</p>
<Form className="login-form">
<Form.Item>
@ -231,29 +253,21 @@ function Register(props){
],
validateTrigger:"onBlur",
validateFirst: true,
})(<Input ref={inputEl} className="account" placeholder="请输入4-15位用户名以字母开头只能使用字母和数字" readOnly onFocus={()=>{document.getElementById("register_register_username").removeAttribute("readOnly")}}/>)}
// ref={inputEl}
})(<Input placeholder="请输入4-15位用户名以字母开头只能使用字母和数字" autoComplete="off"/>)}
</Form.Item>
<Form.Item>
{getFieldDecorator('email',{
rules:[
{
type: 'email',
message: '请输入正确的邮箱格式',
},
{
required:true,
message:"请输入邮箱地址"
},
{
validator: (rule, value, callback) => { emailConfirm(rule, value, callback) }
}
],
validateTrigger:"onBlur",
validateFirst: true,
})(<Input className="email" placeholder="请输入邮箱地址" readOnly onFocus={()=>{document.getElementById("register_email").removeAttribute("readOnly")}} />)}
})(<Input className="email" placeholder={`请输入${registerType ? '邮箱地址' : '手机号'}`} autoComplete="off"/>)}
</Form.Item>
<Form.Item>
<div className="login_register_head">
{getFieldDecorator('captcha', {
@ -263,12 +277,12 @@ function Register(props){
}],
validateTrigger: "onBlur",
})(
<Input className="captcha" placeholder="请输入验证码" readOnly onFocus={()=>{document.getElementById("register_captcha").removeAttribute("readOnly")}} />
<Input className="captcha" placeholder="请输入验证码" autoComplete="off"/>
)}
<Button className={getCaptchaBut ? 'codeBut':'codeBut disable'} disabled={!getCaptchaBut} onClick={getCaptcha}>{getCaptchaBut || (!getCaptchaBut && !countDown)?"获取验证码":`重发(${secondsStr}s)`}</Button>
</div>
</Form.Item>
<Form.Item>
{getFieldDecorator('register_psd',{
rules:[
@ -281,7 +295,7 @@ function Register(props){
],
validateTrigger:"onBlur",
validateFirst: true,
})(<Input.Password className="register_psd" placeholder="请输入登录密码" onBlur={clear} onChange={clear} readOnly onFocus={()=>{document.getElementById("register_register_psd").removeAttribute("readOnly")}}/>)}
})(<Input.Password className="register_psd" placeholder="请输入登录密码" onBlur={clear} onChange={clear} autoComplete="new-password"/>)}
</Form.Item>
<span className="password_tips" style={{display:tipVisable?"none":"block"}}>请输入8-16位密码区分大小写不能使用空格</span>
@ -298,10 +312,9 @@ function Register(props){
],
validateTrigger: "onBlur",
validateFirst: true,
})(<Input.Password className="psdComfirm" placeholder="请确认登录密码" onBlur={clear} onChange={clear} readOnly onFocus={()=>{document.getElementById("register_psdComfirm").removeAttribute("readOnly")}}/>)}
})(<Input.Password className="psdComfirm" placeholder="请确认登录密码" onBlur={clear} onChange={clear} autoComplete="new-password"/>)}
</Form.Item>
<Form.Item className="register_last_form">
{getFieldDecorator('agreement', {
valuePropName: 'checked',
@ -311,7 +324,7 @@ function Register(props){
validator: (rule, value, callback) => { comfirmRead(rule, value, callback) }
}
],
})(<Checkbox>我已阅读并接受<a className="login-form-forgot" href="https://forum.trustie.net/forums/5029/detail" target="_blank">GitLink服务协议条款</a></Checkbox>)}
})(<Checkbox className="link_span">我已阅读并接受<a className="login-form-forgot" href="https://forum.trustie.net/forums/5029/detail" target="_blank">GitLink服务协议条款</a></Checkbox>)}
</Form.Item>
<Button type="primary" htmlType="submit" className="login_register_cofBut" onClick={handleSubmit}>注册</Button>
</Form>

View File

@ -56,23 +56,34 @@ function ResetPassword(props) {
});
}
//
///
function emailConfirm(rule, value, callback) {
setEmailGo(true);
value && (emailGo || value !== emailStr) ? axios.post(`/accounts/check.json`, {
value: value,
type: 2
}).then(response => {
if (response.data && response.data.status === -1) {
setEmailStr(value);
setGetCaptchaBut(true);
setEmailGo(false);
callback();
} else {
setGetCaptchaBut(false);
callback('此邮箱未注册');
if(/(^(\d{3,4}-)?\d{7,8})$|([1][3,4,5,6,7,8,9][0-9]{9})/.test(value) || /^[a-zA-Z0-9]+([.\-_\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/.test(value)){
setEmailGo(true);
if(value && (emailGo || value !== emailStr)){
axios.get(`/accounts/valid_email_and_phone.json`, {
params: {
login: value,
type: 2
}
}).then(response => {
if (response.data && !response.data.status) {
setEmailStr(value);
setGetCaptchaBut(true);
setEmailGo(false);
callback();
} else {
setGetCaptchaBut(false);
callback('此手机号/邮箱未注册');
}
})
}else{
callback()
}
}):callback();setEmailStr(undefined);
setEmailStr(undefined);
}else{
callback("请输入正确的手机号/邮箱")
}
}
//
@ -140,7 +151,7 @@ function ResetPassword(props) {
if (response.data && response.data.status === 0) {
//
let email = emailStr.substring(emailStr.indexOf("@")+1);
message.success({content:<span>验证码已发送请注意查收<a href={`https://mail.${email}`} target="_blank">前往邮箱</a></span>});
message.success({content:<span>验证码已发送请注意查收{emailStr.indexOf("@") === -1 ? '' : <a href={`https://mail.${email}`} target="_blank">前往邮箱</a>}</span>});
} else {
//,
setGetCaptchaBut(false);
@ -151,7 +162,7 @@ function ResetPassword(props) {
})
}
}
//value->DOM
function clear(){
const password = document.getElementById("resetPassword_psd");
@ -170,13 +181,12 @@ function ResetPassword(props) {
useEffect(() => {
inputEl.current.focus();
clear;
}, [])
return (
<div>
<div className="right_cont ResetPassword_content">
<div className="login_register_head">
<div className="login_register_head mb30">
<span>找回密码</span>
<span className="link_span">已有账号<Link to={`/login`}>立即登录</Link></span>
</div>
@ -185,13 +195,9 @@ function ResetPassword(props) {
<Form.Item>
{getFieldDecorator('email', {
rules: [
{
type: 'email',
message: '请输入正确的邮箱格式',
},
{
required: true,
message: "请输入已注册的邮箱"
message: "请输入已注册的手机号/邮箱"
},
{
validator: (rule, value, callback) => { emailConfirm(rule, value, callback) }
@ -199,10 +205,9 @@ function ResetPassword(props) {
],
validateTrigger: "onBlur",
validateFirst: true,
})(<Input ref={inputEl} className="account" placeholder="请输入已注册的邮箱" readOnly onFocus={()=>{document.getElementById("resetPassword_email").removeAttribute("readOnly")}} />)}
})(<Input ref={inputEl} className="account" placeholder="请输入已注册的手机号/邮箱" autoComplete="off"/>)}
</Form.Item>
<Form.Item>
<div className="login_register_head">
{getFieldDecorator('captcha', {
@ -212,7 +217,7 @@ function ResetPassword(props) {
}],
validateTrigger: "onBlur",
})(
<Input className="captcha" placeholder="请输入验证码" readOnly onFocus={()=>{document.getElementById("resetPassword_captcha").removeAttribute("readOnly")}} />
<Input className="captcha" placeholder="请输入验证码" autoComplete="off"/>
)}
<Button className={getCaptchaBut ? 'codeBut':'codeBut disable'} disabled={!getCaptchaBut} onClick={getCaptcha}>{getCaptchaBut || (!getCaptchaBut && !countDown)?"获取验证码":`重发(${secondsStr}s)`}</Button>
</div>
@ -230,7 +235,7 @@ function ResetPassword(props) {
],
validateTrigger: "onBlur",
validateFirst: true,
})(<Input.Password className="psd" placeholder="请输入新密码" onBlur={clear} onChange={clear} readOnly onFocus={()=>{document.getElementById("resetPassword_psd").removeAttribute("readOnly")}} />)}
})(<Input.Password className="psd" placeholder="请输入新密码" onBlur={clear} onChange={clear} autoComplete="new-password"/>)}
</Form.Item>
<span className="password_tips" style={{display:tipVisable?"none":"block"}}>请输入8-16位密码区分大小写不能使用空格</span>
@ -247,7 +252,7 @@ function ResetPassword(props) {
],
validateTrigger: "onBlur",
validateFirst: true,
})(<Input.Password className="psdComfirm" placeholder="请确认新密码" onBlur={clear} onChange={clear} readOnly onFocus={()=>{document.getElementById("resetPassword_psdComfirm").removeAttribute("readOnly")}} />)}
})(<Input.Password className="psdComfirm" placeholder="请确认新密码" onBlur={clear} onChange={clear} autoComplete="new-password"/>)}
</Form.Item>
<Form.Item>