forked from Gitlink/forgeplus-react
394 lines
17 KiB
JavaScript
394 lines
17 KiB
JavaScript
import React, { useEffect, useRef, useState } from "react";
|
||
import { Form, Input, Button, Checkbox, message, Select, Modal } from "antd";
|
||
import { Link } from "react-router-dom";
|
||
import axios from 'axios';
|
||
import { setmiyah ,getImageUrl ,isMobile} from 'educoder';
|
||
import './LoginRegisterPage.scss';
|
||
const Option = Select.Option;
|
||
|
||
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);
|
||
const [getCaptchaBut, setGetCaptchaBut] = useState(false);
|
||
const [mess, setMess] = useState(undefined);
|
||
const [tipVisable, setTipVisable] = useState(false);
|
||
//用于表单提交时会再次校验数据
|
||
const [userNameGo, setUserNameGo] = useState(true);
|
||
const [phoneGo, setPhoneGo] = useState(true);
|
||
const [visible, setVisible] = useState(false);
|
||
const seconds = useRef();
|
||
let interval = undefined;
|
||
//页面加载完自动聚焦到第一个输入框
|
||
const inputEl = useRef(null);
|
||
|
||
|
||
//注册表单提交
|
||
function handleSubmit() {
|
||
validateFields((err, values) => {
|
||
if (!err) {
|
||
values.agreement && axios.post(`/accounts/register.json`, {
|
||
login: values.login,
|
||
password: values.register_psd,
|
||
company_name: values.company_name,
|
||
user_type: values.user_type,
|
||
professional_field:values.professional_field,
|
||
code: values.captcha
|
||
}).then((response) => {
|
||
if (response.data && response.data.status === -6) {
|
||
//验证码不正确
|
||
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 {
|
||
setLoginStr(values.login);
|
||
setMess(response.data.message);
|
||
}
|
||
})
|
||
}
|
||
});
|
||
}
|
||
|
||
|
||
//判断手机是否注册
|
||
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&&response.data&&response.data.status === -2) {
|
||
setGetCaptchaBut(false);
|
||
setMess(response.data.message);
|
||
callback('该手机已被注册');
|
||
} else {
|
||
setLoginStr(value);
|
||
setGetCaptchaBut(true);
|
||
setPhoneGo(false);
|
||
callback();
|
||
}
|
||
}) : callback(); setLoginStr(undefined);
|
||
}
|
||
|
||
|
||
//检查密码是否符合格式
|
||
function checkPassWord(rule, value, callback) {
|
||
if (!value) {
|
||
setTipVisable(true);
|
||
callback('请输入登录密码');
|
||
} else if (/(?!.*\s)(?!^[\u4e00-\u9fa5]+$)^.{8,16}$/.test(value)) {
|
||
callback()
|
||
} else {
|
||
setTipVisable(true);
|
||
if (value.length < 8 || value.length > 16) {
|
||
callback('密码长度为8-16个字符');
|
||
} else {
|
||
callback('密码不能使用空格');
|
||
}
|
||
}
|
||
}
|
||
|
||
//确认勾选服务
|
||
function comfirmRead(rule, value, callback) {
|
||
if (value) {
|
||
callback();
|
||
} 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 (loginStr) {
|
||
// 倒计时开始
|
||
setCountDown(true);
|
||
setGetCaptchaBut(false);
|
||
seconds.current = 60;
|
||
setSecondsStr(60);
|
||
!interval && clearInterval(interval);
|
||
interval = setInterval(() => {
|
||
if (seconds.current > 1) {
|
||
let oldSeconds = seconds.current;
|
||
seconds.current = oldSeconds - 1;
|
||
setSecondsStr(oldSeconds - 1);
|
||
} else {
|
||
clearInterval(interval);
|
||
//倒计时结束->可以获取验证码
|
||
setGetCaptchaBut(true);
|
||
setCountDown(false);
|
||
}
|
||
}, 1000)
|
||
|
||
//请求获取验证码接口
|
||
axios.get(`/accounts/get_verification_code.json`, {
|
||
params: {
|
||
login: loginStr,
|
||
type: 1,
|
||
smscode: setmiyah(loginStr),
|
||
}
|
||
}).then(response => {
|
||
if (response.data && response.data.status === 0) {
|
||
//验证码发送成功
|
||
message.success({ content: <span>验证码已发送,请注意查收。</span> });
|
||
} else {
|
||
//验证码发送失败,获取验证码按钮变灰并且文案变回【获取验证码】
|
||
setGetCaptchaBut(false);
|
||
setCountDown(false);
|
||
clearInterval(interval);
|
||
setMess(response.data.message);
|
||
}
|
||
})
|
||
}
|
||
}
|
||
|
||
//清除密码框的value属性->DOM看不见密码值
|
||
function clear() {
|
||
const password = document.getElementById("register_register_psd");
|
||
const passwordComfirm = document.getElementById("register_psdComfirm");
|
||
if (password && password.type === "password") {
|
||
setTimeout(() => {
|
||
password.removeAttribute('value');
|
||
}, 0)
|
||
}
|
||
if (passwordComfirm && passwordComfirm.type === "password") {
|
||
setTimeout(() => {
|
||
passwordComfirm.removeAttribute('value');
|
||
}, 0)
|
||
}
|
||
}
|
||
|
||
useEffect(() => {
|
||
// inputEl.current.focus();
|
||
clear();
|
||
}, [])
|
||
|
||
const settings=localStorage.getItem('chromesetting')?JSON.parse(localStorage.getItem('chromesetting')):{};
|
||
let professional_field=settings.professional_field||[];
|
||
|
||
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 label={"专业领域"} className="inline_input">
|
||
{getFieldDecorator('professional_field', {
|
||
rules: [
|
||
{
|
||
required: true,
|
||
message: "请选择专业领域"
|
||
},
|
||
],
|
||
validateTrigger: "onBlur",
|
||
validateFirst: true,
|
||
})(<Select placeholder="请选择专业领域" >
|
||
{
|
||
professional_field.map(i=>{
|
||
return <Option value={i.value}>{i.name}</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>
|
||
|
||
<p>7、用户需承诺代码仓库创建内容不违反任何国家法律法规;不侵犯任何单位及个人的版权和权益。</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>
|
||
)
|
||
}
|
||
export default Form.create({ name: 'register' })(Register); |