Merge pull request '改版登录注册重置密码' (#449) from tongChong/forgeplus-react:dev_military_admin into pre_dev_military

This commit is contained in:
tongChong 2022-09-16 13:49:55 +08:00
commit b87c57f77d
15 changed files with 502 additions and 349 deletions

View File

@ -527,6 +527,17 @@ class Detail extends Component {
</div> : ""
}
hideModal = () => {
this.setState({
visible: false
});
this.props.history.push('/projects');
}
sureModal = () => {
const { getListData } = this.props;
getListData && getListData(1);
}
render() {
const { projectDetail, watchers_count, praises_count,
@ -550,7 +561,7 @@ class Detail extends Component {
}
return (
<div>
<SpecialModal {...this.props} visible={visible} hideModal={this.sureModal} user_apply_signatures={user_apply_signatures} project_id={project_id} sureModal={this.sureModal}></SpecialModal>
<SpecialModal {...this.props} visible={visible} hideModal={this.hideModal} user_apply_signatures={user_apply_signatures} project_id={project_id} sureModal={this.sureModal}></SpecialModal>
<div className="detailHeader-wrapper open-sourse">
<div className="normal">
<AlignTop style={{ padding: "18px 0px 10px", justifyContent: "space-between" }}>

View File

@ -37,7 +37,7 @@ function SpecialModal({ visible , hideModal , sureModal , showNotification , use
}
}
return(
<Modal title="提示" visible={visible} closable={false} onCancel={hideModal} onOk={sure}>
<Modal title="提示" visible={visible} closable={false} maskClosable={false} onCancel={hideModal} onOk={sure}>
{
!user_apply_signatures || (user_apply_signatures && user_apply_signatures.status !== "waiting") ?
<div style={{width:"420px",textAlign:'center',margin:"0 auto",paddingBottom:"30px",position:"relative"}}>

View File

@ -4,7 +4,7 @@ $deg2: -36deg;
$bgcolorlist:#254dea #e33230 #0766fb #f02c66 #6038ff #f85e55 #c13cff #2cb840 #5744f6 #e9862e;
.home-fifth-section {
min-height: 50vh;
// min-height: 50vh;
background: linear-gradient(#fff 0%, #cbdcff 100%);
.fifth-main {

View File

@ -1,5 +1,5 @@
.home-first-section {
height: 90vh;
height: 93vh;
min-height: 650px;
// background: linear-gradient(
// #1a2358 0%,
@ -32,6 +32,7 @@
align-items: center;
height: 80vh;
min-height: 600px;
margin-top: 6vh;
}
.website {

View File

@ -478,15 +478,15 @@ export default Form.create()(
</React.Fragment>}
</div>
{!current_user.enterpriseCertification && current_user.login &&<div className="edu-back-white padding30 mt20 font-16 text-center mb50">
<a onClick={goUserProfiles} className="color-blue_41">请先完善主体信息</a>
{(!current_user.enterpriseCertification&&!current_user.authentication) && current_user.login &&<div className="edu-back-white padding30 mt20 font-16 text-center mb50">
<a onClick={goUserProfiles} className="color-blue_41">请先进行实名认证</a>
</div>}
{/* {!current_user.login &&<div className="edu-back-white padding30 mt20 font-16 text-center mb50">
<span className="color-blue_41">创客任务仅限登录用户查看请先注册登录红山开源账号</span>
</div>} */}
{current_user.enterpriseCertification && detailData.status === 3 && (!detailData.exceptClosedBoolean) && signContent()}
{(current_user.enterpriseCertification||current_user.authentication) && detailData.status === 3 && (!detailData.exceptClosedBoolean) && signContent()}
<div className="applyList edu-back-white padding30 mt20">
<div className="font-16 font-bd">交稿

View File

@ -153,7 +153,7 @@ export default ({ history, current_user, showLoginDialog, location, mygetHelmeta
content: <div className="mt10">
<p>完成条件后重新点击查看您的最新参与资格</p>
<div className="inline mt10">
<span className="mr30"> <i className="iconfont icon-mingpian"></i> <span className="color-red">主体信息未认证</span> </span>
<span className="mr30"> <i className="iconfont icon-mingpian"></i> <span className="color-red">未进行实名未认证</span> </span>
</div>
</div>,
onOk: () => {

View File

@ -126,21 +126,21 @@ class EducoderLogin extends Component {
justifyContent: "center",
width: "100%",
}}>
<div className="font-14 color-grey-9 " style={{marginTop:"20px"}}><span className="font-18">©</span>&nbsp;{moment().year()}&nbsp;GitLink | <span className="ml15 mr15">ICP13000930</span><a href="https://team.trustie.net" style={{"color":"#888"}} target="_blank">GitLink</a>&nbsp;&nbsp;&nbsp;&amp;&nbsp;&nbsp;&nbsp;IntelliDE inside.</div>
<div className="font-14 color-grey-9 " style={{marginTop:"20px"}}><span className="font-18">©</span>&nbsp;{moment().year()}&nbsp; | <span className="ml15 mr15">ICP13000930</span><a href="https://team.trustie.net" style={{"color":"#888"}} target="_blank"></a>&nbsp;&nbsp;&nbsp;&amp;&nbsp;&nbsp;&nbsp;IntelliDE inside.</div>
</div>:
this.props.mygetHelmetapi===undefined||this.props.mygetHelmetapi.main_site===null|| this.props.mygetHelmetapi.main_site===undefined? <div style={{
display: "flex",
justifyContent: "center",
width: "100%",
}}>
<div className="font-14 color-grey-9 " style={{marginTop:"20px"}}><span className="font-18">©</span>&nbsp;{moment().year()}&nbsp;GitLink | <span className="ml15 mr15">ICP13000930</span><a href="https://team.trustie.net" style={{"color":"#888"}} target="_blank">GitLink</a>&nbsp;&nbsp;&nbsp;&amp;&nbsp;&nbsp;&nbsp;IntelliDE inside.</div>
<div className="font-14 color-grey-9 " style={{marginTop:"20px"}}><span className="font-18">©</span>&nbsp;{moment().year()}&nbsp; | <span className="ml15 mr15">ICP13000930</span><a href="https://team.trustie.net" style={{"color":"#888"}} target="_blank"></a>&nbsp;&nbsp;&nbsp;&amp;&nbsp;&nbsp;&nbsp;IntelliDE inside.</div>
</div>:this.props.mygetHelmetapi.main_site===true?
<div style={{
display: "flex",
justifyContent: "center",
width: "100%",
}}>
<div className="font-14 color-grey-9 " style={{marginTop:"20px"}}><span className="font-18">©</span>&nbsp;{moment().year()}&nbsp;GitLink | <span className="ml15 mr15">ICP13000930</span><a href="https://team.trustie.net" style={{"color":"#888"}} target="_blank">GitLink</a>&nbsp;&nbsp;&nbsp;&amp;&nbsp;&nbsp;&nbsp;IntelliDE inside.</div>
<div className="font-14 color-grey-9 " style={{marginTop:"20px"}}><span className="font-18">©</span>&nbsp;{moment().year()}&nbsp; | <span className="ml15 mr15">ICP13000930</span><a href="https://team.trustie.net" style={{"color":"#888"}} target="_blank"></a>&nbsp;&nbsp;&nbsp;&amp;&nbsp;&nbsp;&nbsp;IntelliDE inside.</div>
</div>
:""
}

View File

@ -466,6 +466,7 @@ class LoginDialog extends Component {
}
const main_web_site_url =localStorage.chromesetting && JSON.parse(localStorage.chromesetting).main_web_site_url;
const current_main_site_url =localStorage.chromesetting && JSON.parse(localStorage.chromesetting).current_main_site_url;
return (
<Dialog open={true} id="DialogID"
@ -566,9 +567,9 @@ class LoginDialog extends Component {
<label htmlFor="p_autolog" style={{ top: '0px' }}>下次自动登录</label>
</span>
<span className="fr">
<a onClick={(url) => this.getloginurl(`${main_web_site_url}/account/lost_password`)}
<a onClick={(url) => this.getloginurl(`/resetPassword`)}
className="mr3 color-grey-9">找回密码</a><em className="vertical-line"></em>
<a onClick={(url) => this.getloginurl(`${main_web_site_url}/user_join`)} className="color-grey-9">注册</a>
<a onClick={(url) => this.getloginurl(`/register`)} className="color-grey-9">注册</a>
</span>
</p>
{

View File

@ -4,82 +4,88 @@ import { Link } from "react-router-dom";
import axios from 'axios';
import educoderLogo from '../login/educoder.png';
import cookie from 'react-cookies';
import { getImageUrl} from 'educoder';
import './LoginRegisterPage.scss';
function Login(props){
const [message,setMessage] = useState();
function Login(props) {
const [message, setMessage] = useState();
const [setting, setSetting] = useState(undefined);
const {form, location} = props;
const {getFieldDecorator } = form;
const {search} = location;
const { form, location } = props;
const { getFieldDecorator } = form;
const { search } = location;
useEffect(()=>{
useEffect(() => {
//DOMvalue
clear;
//
setSetting(JSON.parse(localStorage.getItem("chromesetting")));
},[])
}, [])
//
function handleSubmit(){
function handleSubmit() {
form.validateFields((err, values) => {
if (!err) {
axios.post(`/accounts/login.json`, {
login: values.username,
password: values.password,
autologin: values.remember?1:0,
autologin: values.remember ? 1 : 0,
}).then((response) => {
if (!response.data.login) {
response.data.status === -2 ? setMessage(response.data.message) : setMessage("错误的账号或密码");
} else {
//
cookie.save('autologin',values.remember);
cookie.save('autologin', values.remember);
const searchParams = new URLSearchParams(search.substring(1));
const goPage = searchParams.get("go_page");
//
window.location.href = goPage ? goPage : `/${response.data.login}`
}
}).catch((error) => {
console.log('error',error);
console.log('error', error);
})
}
});
}
//
function comfirmWrite(rule, value, callback, index){
function comfirmWrite(rule, value, callback, index) {
setMessage(undefined);
value ? callback():index === 1? callback("请输入邮箱地址或用户名登录"):callback("请输入登录密码");
value ? callback() : index === 1 ? callback("请输入邮箱地址或用户名登录") : callback("请输入登录密码");
}
//value->DOM
function clear(){
function clear() {
const password = document.getElementById("login_password");
if(password && password.type==="password"){
setTimeout(()=>{
if (password && password.type === "password") {
setTimeout(() => {
password.removeAttribute('value');
},0)
}, 0)
}
}
return(
const settings = JSON.parse(localStorage.getItem('chromesetting'));
return (
<div>
<div className="right_cont login_content">
<div className="logoimgbox">
{settings && <img alt="红山开源" className="logoimg" src={getImageUrl(`/${settings.nav_logo_url}`)}></img>}
</div>
<div className="login_register_head">
<span>欢迎登录 GitLink</span>
<span>欢迎登录 红山开源</span>
<span className="link_span">没有账号<Link to={`/register`}>去注册</Link></span>
</div>
<p className = {message?"message active":"message"}>{message}</p>
<p className={message ? "message active" : "message"}>{message}</p>
<Form className="login-form">
<Form.Item>
{getFieldDecorator('username',{
rules:[
{getFieldDecorator('username', {
rules: [
{
validator: (rule, value, callback) => { comfirmWrite(rule, value, callback, 1) }
}
],
validateTrigger:"onBlur",
})(<Input className="account" placeholder="请输入邮箱地址/用户名"/>)}
validateTrigger: "onBlur",
})(<Input className="account" placeholder="请输入手机账号" />)}
</Form.Item>
<Form.Item>
@ -89,9 +95,9 @@ function Login(props){
validator: (rule, value, callback) => { comfirmWrite(rule, value, callback, 2) }
}
],
validateTrigger:"onBlur",
validateTrigger: "onBlur",
})(
<Input.Password className="psd" placeholder="请输入登录密码" onBlur={clear} onChange={clear}/>,
<Input.Password className="psd" placeholder="请输入登录密码" onBlur={clear} onChange={clear} />,
)}
</Form.Item>
@ -109,19 +115,19 @@ function Login(props){
{
setting && setting.third_party && setting.third_party.length > 0 ?
<p className="quick_logon">
<p className="quick_logon_p"></p>
<span className={"startlogin"}>&nbsp;快速登录&nbsp;</span>
{setting.third_party.map((item,key)=>{
return(
<a href={`${item.url}`}>
<img src={item.name === "educoder" ? educoderLogo : ""} width="46px" alt={`${item.name}登录`} />
</a>
)
})
}
</p>
:""
<p className="quick_logon">
<p className="quick_logon_p"></p>
<span className={"startlogin"}>&nbsp;快速登录&nbsp;</span>
{setting.third_party.map((item, key) => {
return (
<a href={`${item.url}`}>
<img src={item.name === "educoder" ? educoderLogo : ""} width="46px" alt={`${item.name}登录`} />
</a>
)
})
}
</p>
: ""
}
</div>
</div>

View File

@ -1,26 +1,42 @@
import React from "react";
import React, { useEffect } from "react";
import Login from "./Login";
import Register from "./Register";
import ResetPassword from "./ResetPassword";
import logo from './img/logo.svg';
import banner from './img/banner.png';
import ball from './img/ball.png';
import img1 from './img/img1.png';
import img2 from './img/img2.png';
import { getImageUrl} from 'educoder';
// import logo from './img/logo.svg';
// import banner from './img/banner.png';
// import ball from './img/ball.png';
// import img1 from './img/img1.png';
// import img2 from './img/img2.png';
import '../loginRegister/LoginRegisterPage.scss';
function LoginRegisterPage(props){
return(
function LoginRegisterPage(props) {
useEffect(() => {
// mate
const addMeta = (name, content) => {
const meta = document.createElement('meta');
meta.content = content;
meta.name = name;
document.getElementsByTagName('head')[0].appendChild(meta);
};
addMeta(
'viewport',
'width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover',
);
})
return (
<div className="loginRegister">
<div className="login_register_left">
{/* <div className="login_register_left">
<img src={logo} className="logo" onClick={()=>{window.location.href='/'}}></img>
<img src={ball} className="ball"></img>
<img src={banner} className="banner"></img>
</div>
</div> */}
<div className="login_register_right">
{props.location.pathname === "/login" ? <Login {...props}/> : props.location.pathname === "/register" ? <Register/> : <ResetPassword/>}
<img src={img1} className="img1"></img>
<img src={img2} className="img2"></img>
{props.location.pathname === "/login" ? <Login {...props} /> : props.location.pathname === "/register" ? <Register /> : <ResetPassword />}
{/* <img src={img1} className="img1"></img>
<img src={img2} className="img2"></img> */}
</div>
<div className="clear"></div>
</div>

View File

@ -33,6 +33,8 @@
.Register_content{top: 8em; }
.ResetPassword_content{top: 16vh; }
}
.login_register_left{
height: 100%;
background-image: url(./img/bg.png);
@ -60,6 +62,7 @@
}
.login_register_right{
height: 100%;
padding-top:10vh;
background-image: url(./img/rightBg.png);
.img1{
width: 15vw;
@ -72,16 +75,18 @@
margin-left: 22vw;
}
.right_cont{
position: absolute;
// position: absolute;
margin:0 auto;
z-index: 2;
left: 45vw;
// left: 45vw;
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;
margin-bottom: 1vh;
&>span:first-child{
font-size: 1.5em;
font-weight: 600;
@ -89,17 +94,17 @@
line-height: 1.5;
}
//注册页面的获取验证码输入框
& .ant-input{width: 18rem; }
// .ant-input{width: 18rem; }
}
//第一个输入框
& .account{margin-top: 4vh; }
.account{margin-top: 4vh; }
//所有的链接
& a{
a{
color: #466AFF;
&:hover{opacity:0.8; }
}
//登录 注册 重置密码并登录按钮
& .login_register_cofBut{
.login_register_cofBut{
font-size: 1em;
width: 100%;
height: 3.1em;
@ -128,31 +133,35 @@
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{
.message.active{
margin-bottom: -30px !important;
}
//antd 输入框样式
& .ant-input{
.ant-input,.ant-select-selection{
height: 3.1em;
background-color: #F7F7F7 !important;
font-size: 1em;
color: #333333;
&:hover{border-color:#466AFF; }
}
& .ant-form-explain{
.ant-select-selection__rendered{
line-height: 3em;
}
.ant-form-explain{
margin-top: 0.5vh;
margin-bottom: -10px;
}
//输入框
.ant-form-item{
margin-bottom: 15px;
@ -167,7 +176,13 @@
background-color: #466AFF;
border: #466AFF;
}
.inline_input {
display: flex;
.ant-form-item-control-wrapper{
flex: 1;
}
}
.ant-checkbox-checked::after{
border: 1px solid #466AFF;
}
@ -230,4 +245,72 @@
}
& .login_register_cofBut{margin-top: 1.5vh; }
}
}
}
.logoimgbox{
text-align: center;
.logoimg{
width: 150px;
max-width: 30vw;
margin-bottom: 2vh;
}
}
/*当页面宽度小于786px*/
@media screen and (max-width:786px) {
.login_register_right{
padding-top:0;
}
.login_register_right .right_cont{
padding:8vh 15px
}
.ant-form-item-label, .ant-form-item-control-wrapper{
width: auto !important;
}
.login_register_right .right_cont .inline_input{
display: block;
}
.logoimgbox{
.logoimg{
width: 150px;
}
}
}
@media screen and (max-width:375px) {
.login_register_right .right_cont{
font-size: 13px;
padding:5vh 15px
}
.logoimgbox{
.logoimg{
margin-bottom: 0;
}
}
}
@media screen and (max-width:360px) {
.login_register_right .right_cont{
font-size: 12px;
padding:5vh 10px
}
.logoimgbox{
display: none;
}
}
.login_agreement{
width: 90vw !important;
max-width: 1000px;
.ant-modal-header{
display: none;
}
.ant-modal-body{
max-height: 55vh;
overflow-y:scroll;
h3{
margin:.75em auto;
}
p{
margin:.45em auto;
}
}
}

View File

@ -1,16 +1,15 @@
import React, { useEffect, useRef, useState } from "react";
import { Form, Input, Button, Checkbox, message } from "antd";
import { Form, Input, Button, Checkbox, message, Select, Modal } from "antd";
import { Link } from "react-router-dom";
import axios from 'axios';
import { setmiyah } from 'educoder';
import { setmiyah ,getImageUrl ,isMobile} from 'educoder';
import './LoginRegisterPage.scss';
const Option = Select.Option;
function Register(props){
const {form} = props;
const {getFieldDecorator } = form;
//
const [emailStr, setEmailStr] = useState(undefined);
//check.json
function Register(props) {
const { form } = props;
const { getFieldDecorator,setFieldsValue,validateFields,getFieldValue } = form;
//
const [loginStr, setLoginStr] = useState(undefined);
const [secondsStr, setSecondsStr] = useState(60);
const [countDown, setCountDown] = useState(false);
@ -19,120 +18,102 @@ function Register(props){
const [tipVisable, setTipVisable] = useState(false);
//
const [userNameGo, setUserNameGo] = useState(true);
const [emailGo, setEmailGo] = useState(true);
const [phoneGo, setPhoneGo] = useState(true);
const [visible, setVisible] = useState(false);
const seconds = useRef();
let interval = undefined;
//
const inputEl = useRef(null);
//
function handleSubmit(){
form.validateFields((err, values) => {
function handleSubmit() {
validateFields((err, values) => {
if (!err) {
values.agreement && axios.post(`/accounts/register.json`, {
login: values.email,
namespace: values.register_username,
login: values.login,
password: values.register_psd,
password_confirmation: values.psdComfirm,
company_name: values.company_name,
user_type: values.user_type,
code: values.captcha
}).then((response)=>{
if(response.data && response.data.status === -6){
}).then((response) => {
if (response.data && response.data.status === -6) {
//
form.setFields({captcha: {value:values.captcha,errors:[new Error('验证码错误,请重新输入')]}});
//-undefined,
setEmailStr(values.email);
}else if(response.data && response.data.status === 0){
//forge
window.location.href = "/"+values.register_username;
form.setFields({ captcha: { value: values.captcha, errors: [new Error('验证码错误,请重新输入')] } });
//-undefined,
setLoginStr(values.login);
} else if (response.data && response.data.status === 0) {
window.location.href = "/"
} else {
setEmailStr(values.email);
setLoginStr(values.login);
setMess(response.data.message);
}
})
}
});
}
//username
function usernameConfirm(rule, value, callback){
setUserNameGo(true);
value && (userNameGo || value !== loginStr) ? axios.post(`/accounts/check.json`, {
value: value,
type: 1
//
function phoneConfirm(rule, value, callback) {
setPhoneGo(true);
value && (phoneGo || value !== loginStr) ? axios.get(`/accounts/valid_email_and_phone.json`, {
params: {
login: value,
type: 1
}
}).then(response => {
if (response.data.status === -1) {
callback('该名称已经被使用');
if (response.data.status === -2) {
setGetCaptchaBut(false);
setMess(response.data.message);
callback('该手机已被注册');
} else {
setLoginStr(value);
setUserNameGo(false);
callback();
}
}):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('该邮箱已被注册');
} else {
setEmailStr(value);
setGetCaptchaBut(true);
setEmailGo(false);
setPhoneGo(false);
callback();
}
}):callback();setEmailStr(undefined);
}) : callback(); setLoginStr(undefined);
}
//
function comfirmPassWord(rule, value, callback, index) {
if ((index === 2 && value && form.getFieldValue('register_psd') && value !== form.getFieldValue('register_psd')) || (index === 1 && value && form.getFieldValue('psdComfirm') && value !== form.getFieldValue('psdComfirm'))) {
if(index===1){
form.setFields({psdComfirm: {value:form.getFieldValue('psdComfirm'),errors:[new Error('密码不一致,请重新输入')]}});
callback();
}else{
callback('密码不一致,请重新输入');
}
} else {
callback();
}
}
//
function checkPassWord(rule, value, callback){
if(!value){
function checkPassWord(rule, value, callback) {
if (!value) {
setTipVisable(true);
callback('请输入登录密码');
}else if(/(?!.*\s)(?!^[\u4e00-\u9fa5]+$)^.{8,16}$/.test(value)){
} else if (/(?!.*\s)(?!^[\u4e00-\u9fa5]+$)^.{8,16}$/.test(value)) {
callback()
}else{
} else {
setTipVisable(true);
if(value.length<8 || value.length>16){
if (value.length < 8 || value.length > 16) {
callback('密码长度为8-16个字符');
}else{
} else {
callback('密码不能使用空格');
}
}
}
//
function comfirmRead(rule, value, callback){
if(value){
function comfirmRead(rule, value, callback) {
if (value) {
callback();
}else{
} else {
callback("请阅读并接受我们的服务条款");
}
}
//
function getCaptcha() {
if(isMobile){
let phone=getFieldValue('login');
const pattern = /^1(3|4|5|6|7|8|9)\d{9}$/;
if (!pattern.test(phone)) {
message.error('您输入的手机号不正确');
return;
}
}
setMess(undefined);
if (emailStr) {
if (loginStr) {
//
setCountDown(true);
setGetCaptchaBut(false);
@ -155,15 +136,14 @@ function Register(props){
//
axios.get(`/accounts/get_verification_code.json`, {
params: {
login: emailStr,
login: loginStr,
type: 1,
smscode: setmiyah(emailStr),
smscode: setmiyah(loginStr),
}
}).then(response => {
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>验证码已发送请注意查收</span> });
} else {
//,
setGetCaptchaBut(false);
@ -176,146 +156,214 @@ function Register(props){
}
//value->DOM
function clear(){
function clear() {
const password = document.getElementById("register_register_psd");
const passwordComfirm = document.getElementById("register_psdComfirm");
if(password && password.type==="password"){
setTimeout(()=>{
if (password && password.type === "password") {
setTimeout(() => {
password.removeAttribute('value');
},0)
}, 0)
}
if(passwordComfirm && passwordComfirm.type==="password"){
setTimeout(()=>{
if (passwordComfirm && passwordComfirm.type === "password") {
setTimeout(() => {
passwordComfirm.removeAttribute('value');
},0)
}, 0)
}
}
useEffect(() => {
inputEl.current.focus();
clear;
// inputEl.current.focus();
clear();
}, [])
return(
<div>
<div className="right_cont Register_content">
<div className="login_register_head">
<span>欢迎注册 GitLink</span>
<span className="link_span">已有账号<Link to={`/login`}>立即登录</Link></span>
</div>
<p className={mess ? "message active" : "message"}>{mess}</p>
<Form className="login-form">
<Form.Item>
{getFieldDecorator('register_username',{
rules:[
{
required:true,
message:"请输入用户名"
},
{
pattern: /^[a-zA-Z]/,
message: "用户名必须以字母开头"
},
{
pattern: /[a-zA-Z0-9]$/,
message: "用户名只能使用英文字母和数字"
},
{
min: 4,
max: 15,
message: "用户名长度为4到15个字符"
},
{
validator: (rule, value, callback) => { usernameConfirm(rule, value, callback) }
}
],
validateTrigger:"onBlur",
validateFirst: true,
})(<Input ref={inputEl} className="account" placeholder="请输入4-15位用户名以字母开头只能使用字母和数字" readOnly onFocus={()=>{document.getElementById("register_register_username").removeAttribute("readOnly")}}/>)}
</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")}} />)}
</Form.Item>
const settings=JSON.parse(localStorage.getItem('chromesetting'));
<Form.Item>
<div className="login_register_head">
{getFieldDecorator('captcha', {
rules: [{
required: true,
message: "请输入验证码"
}],
validateTrigger: "onBlur",
})(
<Input className="captcha" placeholder="请输入验证码" readOnly onFocus={()=>{document.getElementById("register_captcha").removeAttribute("readOnly")}} />
)}
<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:[
{
validator: (rule, value, callback) => { comfirmPassWord(rule, value, callback, 1) }
},
{
validator: (rule, value, callback) => { checkPassWord(rule, value, callback) }
}
],
validateTrigger:"onBlur",
validateFirst: true,
})(<Input.Password className="register_psd" placeholder="请输入登录密码" onBlur={clear} onChange={clear} readOnly onFocus={()=>{document.getElementById("register_register_psd").removeAttribute("readOnly")}}/>)}
</Form.Item>
<span className="password_tips" style={{display:tipVisable?"none":"block"}}>请输入8-16位密码区分大小写不能使用空格</span>
<Form.Item>
{getFieldDecorator('psdComfirm', {
rules: [
{
required: true,
message: "请确认登录密码"
},
{
validator: (rule, value, callback) => { comfirmPassWord(rule, value, callback, 2) }
}
],
validateTrigger: "onBlur",
validateFirst: true,
})(<Input.Password className="psdComfirm" placeholder="请确认登录密码" onBlur={clear} onChange={clear} readOnly onFocus={()=>{document.getElementById("register_psdComfirm").removeAttribute("readOnly")}}/>)}
</Form.Item>
<Form.Item className="register_last_form">
{getFieldDecorator('agreement', {
valuePropName: 'checked',
initialValue: false,
rules: [
{
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>)}
</Form.Item>
<Button type="primary" htmlType="submit" className="login_register_cofBut" onClick={handleSubmit}>注册</Button>
</Form>
return (
<div className="right_cont Register_content">
<div className="logoimgbox">
{settings&&<img alt="红山开源" className="logoimg" src={getImageUrl(`/${settings.nav_logo_url}`)}></img>}
</div>
<div className="login_register_head">
<span>欢迎注册 红山开源</span>
<span className="link_span">已有账号<Link to={`/login`}>立即登录</Link></span>
</div>
<p className={mess ? "message active" : "message"}>{mess}</p>
<Form className="login-form">
<Form.Item>
{getFieldDecorator('login', {
rules: [
{
required: true,
message: "请输入手机号"
},
{
validator: (rule, val, callback) => {
const pattern = /^1(3|4|5|6|7|8|9)\d{9}$/;
if (pattern.test(val)) {
setGetCaptchaBut(true);
callback();
} else {
setGetCaptchaBut(false);
callback('请输入正确的手机号码!');
}
}
},
{
validator: (rule, value, callback) => { phoneConfirm(rule, value, callback) }
}
],
validateTrigger: "onBlur",
validateFirst: true,
})(<Input ref={inputEl} className="login" placeholder="请输入手机号" />)}
</Form.Item>
<Form.Item>
<div className="login_register_head">
{getFieldDecorator('captcha', {
rules: [{
required: true,
message: "请输入验证码"
}],
validateTrigger: "onBlur",
})(
<Input className="captcha" placeholder="请输入验证码" />
)}
<Button className={getCaptchaBut||(isMobile && !countDown) ? 'codeBut' : 'codeBut disable'} disabled={!getCaptchaBut && !(isMobile && !countDown)} onClick={getCaptcha}>{getCaptchaBut||(isMobile && !countDown) || (!getCaptchaBut && !countDown) ? "获取验证码" : `重发(${secondsStr}s)`}</Button>
</div>
</Form.Item>
<Form.Item>
{getFieldDecorator('register_psd', {
rules: [
{
validator: (rule, value, callback) => { checkPassWord(rule, value, callback) }
}
],
validateTrigger: "onBlur",
validateFirst: true,
})(<Input.Password className="register_psd" placeholder="请输入登录密码" onBlur={clear} onChange={clear} />)}
</Form.Item>
<span className="password_tips" style={{ display: tipVisable ? "none" : "block" }}>请输入8-16位密码区分大小写不能使用空格</span>
<Form.Item label={"单位"} className="inline_input">
{getFieldDecorator('company_name', {
rules: [
{
required: true,
message: "请输入单位"
},
],
validateTrigger: "onBlur",
validateFirst: true,
})(<Input placeholder="请输入单位" />)}
</Form.Item>
<Form.Item label={"用户类型"} className="inline_input">
{getFieldDecorator('user_type', {
rules: [
{
required: true,
message: "请选择用户类型"
},
],
validateTrigger: "onBlur",
validateFirst: true,
})(<Select placeholder="请选择用户类型" >
<Option value="0">事业单位</Option>
<Option value="1">企业单位</Option>
<Option value="2">科研人员</Option>
<Option value="3">高校教师</Option>
<Option value="4">高校学生</Option>
<Option value="5">程序员</Option>
<Option value="6">其他</Option>
</Select>)}
</Form.Item>
<Form.Item className="register_last_form">
{getFieldDecorator('agreement', {
valuePropName: 'checked',
initialValue: false,
rules: [
{
validator: (rule, value, callback) => { comfirmRead(rule, value, callback) }
}
],
})(<Checkbox>我已阅读并接受 <a className="login-form-forgot" onClick={() => { setVisible(true) }}>红山开源服务协议条款</a></Checkbox>)}
</Form.Item>
<Button type="primary" htmlType="submit" className="login_register_cofBut" onClick={handleSubmit}>注册</Button>
</Form>
<Modal
title="红山开源服务协议条款"
visible={visible}
onOk={() => { setVisible(false) ;setFieldsValue({agreement:true})}}
onCancel={() => { setVisible(false);setFieldsValue({agreement:false}) }}
className="login_agreement"
>
<h3>尊敬的用户您好</h3>
<p>欢迎使用红山开源平台在您使用红山开源平台前请认真阅读并遵守红山开源服务协议以下简称本协议请您务必审慎阅读充分理解协议的各条款内容 当您在注册过程中点击查看并同意本服务协议按照注册流程成功注册为红山开源平台的用户即表示您已充分阅读理解并完全接受本协议中的全部条款本条款旨在保障您权益维护平台正常秩序实现平台规范化运营给您提供一个良好的开发环境如您违反条款中的规定事项一经发现平台有权变更暂停或终止您对平台服务的使用而无须事先声明包括但不限于限制您使用平台服务的次数与资源账号永久封闭等</p>
<p>请您在进行注册前承诺接受并遵守本协议的约定届时您不应以未阅读本协议的内容等理由主张本协议无效或本协议中的某些条款无效或要求撤销本协议</p>
<h3>红山开源平台权利和义务</h3>
<p>1尊重用户隐私尊重用户隐私保障用户隐私安全是红山开源平台的一项基本政策</p>
<p>2管理平台用户红山开源平台依据国家法律地方法律和国际法律等的标准以及本行业的规则来管理平台注册用户</p>
<p>3处理用户反馈红山开源平台的相关人员会及时处理用户反馈的问题并给予及时回复</p>
<h3>用户权利和义务</h3>
用户在使用红山开源平台的过程中必须遵守如下原则
<p>1遵守所有中华人民共和国的法律法规规章制度规范政策行政命令强制标准及行业标准等统称为法律法规 </p>
<p>2不干扰和混乱网络服务包括但不限于使用插件外挂或非经红山平台授权的第三方工具或服务接入平台服务和相关系统</p>
<p>3遵守所有使用网络服务的网络协议规定程序和惯例如在此方面造成任何后果及损失由用户自行承担全部责任</p>
<p>4不传输任何骚扰性的中伤他人的辱骂性的恐吓性的伤害性的庸俗的淫秽的以及含有中国法律法规规章条例以及任何具有法律效力之规范所限制或禁止的其他内容等信息资料一经发现红山平台将按照国家有关规定及时删除网站中含有上述内容的地址目录并保留原始记录在二十四小时之内向公安机关报告</p>
<p>5不传输任何教唆他人构成犯罪行为或疑似包含犯罪行为煽动性的资料</p>
<p>6用户不得故意或者过失损害红山开源平台合法权利和利益包括但不限于恶意获取删除或修改平台的原始数据和其他数据及其他任何有损本平台一切相关知识产权的行为</p>
<h3>关于责任</h3>
鉴于网络服务的特殊性用户同意红山开源团队有权在事先通知的情况下变更中断升级部分网络服务红山开源团队不担保网络服务不会中断但承诺在用户可承受的时间内快速恢复服务同时确保用户数据的安全性和可靠性
<h3>保障网络信息安全</h3>
用户不得利用平台服务从事以下危害计算机网络信息安全的活动
<p> (1) 未经允许进入计算机信息网络或者使用计算机信息网络资源的</p>
<p>(2) 未经允许对计算机信息网络功能进行删除修改或者增加的</p>
<p>(3) 未经允许对进入计算机信息网络中存储处理或者传输的数据和应用程序进行删除修改或者增加的</p>
<p>(4) 故意制作传播计算机病毒等破坏性程序的</p>
<p>(5) 其他危害计算机信息网络安全的行为</p>
<h3>服务条款的修改</h3>
红山开源团队保留在必要时对本协议修改的权利一旦发生变动这些条款可由红山开源团队及时更新且毋须另行通知修改后的条款一旦在网页上公布即有效代替原来的服务条款用户可随时查阅最新版服务条款
<h3>用户须知</h3>
用户充分理解并同意用户对自己使用平台服务的一切行为及由此产生的一切结果负责包括但不限于用户所发表的任何内容提供的任何服务以及由此产生的任何后果用户应对平台服务的内容应自行判断并决定是否使用并承担因使用平台服务及其相关内容而引起的所有风险包括因对平台服务及其内容的真实性完整性准确性及时性及实用性的依赖而产生的风险平台不对此提供任何担保和保证不对因前述风险而导致的任何后果或损失对用户承担责任
<h3>如果用户违反了法律法规或本协议红山开源平台有权依据合理判断对违反法律法规或本协议的行为作出处理并对违反法律法规及本协议的任何用户调查并采取适当的法律行动包括但不限于民事诉讼等用户应当自行承担由此产生的任何法律责任</h3>
<h3>本协议最终解释权归红山开源团队所有</h3>
</Modal>
</div>
)
}

View File

@ -2,12 +2,12 @@ import React, { useEffect, useRef, useState } from "react";
import { Form, Input, Button, message } from "antd";
import { Link } from "react-router-dom";
import axios from 'axios';
import { setmiyah } from 'educoder';
import { setmiyah ,getImageUrl,isMobile} from 'educoder';
import './LoginRegisterPage.scss';
function ResetPassword(props) {
const {form } = props;
const {getFieldDecorator } = form;
const {getFieldDecorator,getFieldValue } = form;
const [emailStr, setEmailStr] = useState(undefined);
const [secondsStr, setSecondsStr] = useState(60);
const [countDown, setCountDown] = useState(false);
@ -26,15 +26,14 @@ function ResetPassword(props) {
form.validateFieldsAndScroll((err, values) => {
if (!err) {
axios.post(`/accounts/reset_password.json`, {
login: values.email,
password: values.psd,
password_confirmation: values.psdComfirm,
login: values.login,
new_password: values.psd,
code: values.captcha,
}).then((response) => {
if (response.data.status === 0) {
if (response.data.status === 1) {
//
axios.post(`/accounts/login.json`, {
login: values.email,
login: values.login,
password: values.psd
}).then((login_response) => {
if (!login_response.data.login) {
@ -46,8 +45,8 @@ function ResetPassword(props) {
console.log('error',error);
})
} else {
//-undefined,
setEmailStr(values.email);
//-undefined,
setEmailStr(values.login);
const message = response.data.message;
message === "验证码不正确" ? form.setFields({captcha: {value:values.captcha,errors:[new Error('验证码错误,请重新输入')]}}) : setMess(message);
}
@ -56,38 +55,25 @@ 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) {
value && (emailGo || value !== emailStr) ? axios.get(`/accounts/valid_email_and_phone.json`,{params: {
login: value,
type: 1
}}).then(response => {
if (response.data && response.data.status === -2) {
setEmailStr(value);
setGetCaptchaBut(true);
setEmailGo(false);
callback();
} else {
setGetCaptchaBut(false);
callback('此邮箱未注册');
callback('此手机号未注册');
}
}):callback();setEmailStr(undefined);
}
//
function comfirmPassWord(rule, value, callback, index) {
if ((index === 2 && value && form.getFieldValue('psd') && value !== form.getFieldValue('psd')) || (index === 1 && value && form.getFieldValue('psdComfirm') && value !== form.getFieldValue('psdComfirm'))) {
if(index===1){
form.setFields({psdComfirm: {value:form.getFieldValue('psdComfirm'),errors:[new Error('密码不一致,请重新输入')]}});
callback();
}else{
callback('密码不一致,请重新输入');
}
} else {
callback();
}
}
//
function checkPassWord(rule, value, callback){
@ -108,6 +94,14 @@ function ResetPassword(props) {
//
function getCaptcha() {
if(isMobile){
let phone=getFieldValue('login');
const pattern = /^1(3|4|5|6|7|8|9)\d{9}$/;
if (!pattern.test(phone)) {
message.error('您输入的手机号不正确');
return;
}
}
setMess(undefined);
if (emailStr) {
//
@ -139,8 +133,7 @@ function ResetPassword(props) {
}).then(response => {
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>验证码已发送请注意查收</span>});
} else {
//,
setGetCaptchaBut(false);
@ -173,9 +166,14 @@ function ResetPassword(props) {
clear;
}, [])
const settings=JSON.parse(localStorage.getItem('chromesetting'));
return (
<div>
<div className="right_cont ResetPassword_content">
<div className="logoimgbox">
{settings&&<img alt="红山开源" className="logoimg" src={getImageUrl(`/${settings.nav_logo_url}`)}></img>}
</div>
<div className="login_register_head">
<span>找回密码</span>
<span className="link_span">已有账号<Link to={`/login`}>立即登录</Link></span>
@ -183,15 +181,21 @@ function ResetPassword(props) {
<p className={mess ? "message active" : "message"}>{mess}</p>
<Form className="login-form">
<Form.Item>
{getFieldDecorator('email', {
{getFieldDecorator('login', {
rules: [
{
type: 'email',
message: '请输入正确的邮箱格式',
validator: (rule, val, callback) => {
const pattern = /^1(3|4|5|6|7|8|9)\d{9}$/;
if (pattern.test(val)) {
callback();
} else {
callback('请输入正确的手机号码!');
}
}
},
{
required: true,
message: "请输入已注册的邮箱"
message: "请输入已注册的手机号"
},
{
validator: (rule, value, callback) => { emailConfirm(rule, value, callback) }
@ -199,7 +203,7 @@ 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="请输入已注册的手机号" />)}
</Form.Item>
@ -212,43 +216,26 @@ function ResetPassword(props) {
}],
validateTrigger: "onBlur",
})(
<Input className="captcha" placeholder="请输入验证码" readOnly onFocus={()=>{document.getElementById("resetPassword_captcha").removeAttribute("readOnly")}} />
<Input className="captcha" placeholder="请输入验证码" />
)}
<Button className={getCaptchaBut ? 'codeBut':'codeBut disable'} disabled={!getCaptchaBut} onClick={getCaptcha}>{getCaptchaBut || (!getCaptchaBut && !countDown)?"获取验证码":`重发(${secondsStr}s)`}</Button>
{/* <Button className={getCaptchaBut ? 'codeBut':'codeBut disable'} disabled={!getCaptchaBut} onClick={getCaptcha}>{getCaptchaBut || (!getCaptchaBut && !countDown)?"获取验证码":`重发(${secondsStr}s)`}</Button> */}
<Button className={getCaptchaBut||(isMobile && !countDown) ? 'codeBut' : 'codeBut disable'} disabled={!getCaptchaBut && !(isMobile && !countDown)} onClick={getCaptcha}>{getCaptchaBut||(isMobile && !countDown) || (!getCaptchaBut && !countDown) ? "获取验证码" : `重发(${secondsStr}s)`}</Button>
</div>
</Form.Item>
<Form.Item>
{getFieldDecorator('psd', {
rules: [
{
validator: (rule, value, callback) => { comfirmPassWord(rule, value, callback,1) }
},
{
validator: (rule, value, callback) => { checkPassWord(rule, value, callback) }
}
],
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} />)}
</Form.Item>
<span className="password_tips" style={{display:tipVisable?"none":"block"}}>请输入8-16位密码区分大小写不能使用空格</span>
<Form.Item>
{getFieldDecorator('psdComfirm', {
rules: [
{
required: true,
message: "请确认新密码"
},
{
validator: (rule, value, callback) => { comfirmPassWord(rule, value, callback,2) }
}
],
validateTrigger: "onBlur",
validateFirst: true,
})(<Input.Password className="psdComfirm" placeholder="请确认新密码" onBlur={clear} onChange={clear} readOnly onFocus={()=>{document.getElementById("resetPassword_psdComfirm").removeAttribute("readOnly")}} />)}
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit" className="login_register_cofBut" onClick={handleSubmit}>重置密码并登录</Button>

View File

@ -829,11 +829,11 @@ class NewHeader extends Component {
<span className="login-box">
<a onClick={() => this.educoderlogin()} className={`mr5 ${activeIndex ? 'color-home' : 'color-grey-6'}`}>登录</a>
{
settings && settings.new_course && settings.new_course.register_url && (
// settings && settings.new_course && settings.new_course.register_url && (
activeIndex ?
<Button className="register-button" type="primary" size="large" ><a href={`${settings.new_course.register_url}`}>免费注册</a></Button> :
<span><em className="vertical-line"></em><a className={`ml5 ${activeIndex ? 'color-home' : 'color-grey-6'}`} href={`${settings.new_course.register_url}`} target="_blank"></a></span>
)
<Button className="register-button" type="primary" size="large" ><a href={'/register'}>免费注册</a></Button> :
<span><em className="vertical-line"></em><a className={`ml5 ${activeIndex ? 'color-home' : 'color-grey-6'}`} href={'/register'} target="_blank"></a></span>
// )
}
</span>
:

View File

@ -385,7 +385,7 @@ class LoginRegisterComponent extends Component {
登录密码出错已达上限账号已被锁定
</p>
<p className="mt10">
请10分钟后重新登录或<a href={'https://www.trustie.net/account/lost_password'} style={{
请10分钟后重新登录或<a href={'/resetPassword'} style={{
textDecoration: "underline",
color: "#4CACFF",
}}>找回密码</a>
@ -1243,7 +1243,7 @@ class LoginRegisterComponent extends Component {
color: '#676767',
}}>我已阅读并同意
<span>
<a href={'https://gitlink.org.cn/forums/5029/detail'} target="_blank" className={"color-blue"}>服务协议条款</a>
<a href={'https://红山开源.org.cn/forums/5029/detail'} target="_blank" className={"color-blue"}>服务协议条款</a>
</span></span></Checkbox>:""}
<Button className=" font-16 mb20" type="primary" style={this.props.mygetHelmetapi&&this.props.mygetHelmetapi.main_site===true?{height:"46px", width: "100%",marginTop:"26px"}:{height:"46px", width: "100%"}} onClick={() => this.postregistered()}
size={"large"}>{this.props.weixinlogin?"注册并绑定":"注册"}</Button>