diff --git a/src/App.js b/src/App.js index 3072aca5..ae698ffb 100644 --- a/src/App.js +++ b/src/App.js @@ -97,13 +97,17 @@ const ProjectIndex = Loadable({ loading: Loading, }); +const LoginRegisterPage = Loadable({ + loader: () => import("./modules/loginRegister/LoginRegisterPage"), + loading: Loading, +}); // const CreateMerge = Loadable({ // loader: () => import('./forge/Merge/NewMerge'), // loading: Loading, // }) // 此处仅维护前端可能的一级路由,不用进行项目或者组织判断的字段。 -const keyWord = ["explore", "settings", "setting", "mulan", "wiki", "issues", "setting", "trending", "code", "projects", "pulls", "mine", "login", "register", "email", "export", "nopage", "404", "403", "500", "501", "search", "organize"]; +const keyWord = ["explore", "settings", "setting", "mulan", "wiki", "issues", "setting", "trending", "code", "projects", "pulls", "mine", "login", "register", "email", "export", "nopage", "404", "403", "500", "501", "search", "organize","login","register","resetPassword"]; class App extends Component { constructor(props) { @@ -303,14 +307,14 @@ class App extends Component { }> - { return () } } - /> + /> */} {/*403*/} @@ -330,7 +334,24 @@ class App extends Component { } /> + {/* 登录 */} + } + > + + {/* 注册 */} + } + > + {/* 忘记密码 */} + } + > + {/* 组织 */} { //登录账号 - this.setState({ - isRender: true - }) + if(window.location.pathname === "/"){ + window.location.href="/login"; + }else{ + this.setState({ + isRender: true + }) + } } educoderloginysl = () => { + //退出账号时清除登录页面的下次自动登录(用户再次打开登录页面时下次自动登录框不勾选) + cookie.remove("autologin"); //退出账号 var url = `/accounts/logout.json`; axios.get((url)).then((result) => { @@ -460,7 +467,7 @@ class NewHeader extends Component { this.educoderlogin()} className="mr5 color-grey-6">登录 { settings && settings.common && settings.common.register && - 注册 + 注册 } : diff --git a/src/modules/login/LoginDialog.js b/src/modules/login/LoginDialog.js index 6311a5cd..fd8c4673 100644 --- a/src/modules/login/LoginDialog.js +++ b/src/modules/login/LoginDialog.js @@ -376,7 +376,7 @@ class LoginDialog extends Component { const messge = (

登录密码出错已达上限,账号已被锁定;

-

请10分钟后重新登录或找回密码

+

请10分钟后重新登录或找回密码

) this.openNotifications(messge); @@ -414,7 +414,6 @@ class LoginDialog extends Component { let { disabled } = this.state; if (disabled === false && e.keyCode === 13) { this.loginEDU() - console.log(1) } }; getloginurl = (url) => { @@ -516,7 +515,7 @@ class LoginDialog extends Component { } value={this.state.loginValue} name="username" - placeholder="请输入有效的手机号/邮箱号" > + placeholder="请输入邮箱地址/用户名" >

{Phonenumberisnotco}

@@ -533,7 +532,7 @@ class LoginDialog extends Component { this.loginEDU : () => { } } - placeholder="密码" + placeholder="请输入登录密码" />

@@ -560,9 +559,9 @@ class LoginDialog extends Component { - this.getloginurl(`${settings && settings.common && settings.common.lost_password}`)} className="mr3 color-grey-9">找回密码 + 找回密码 - this.getloginurl(`${settings && settings.common && settings.common.register}`)} className="color-grey-9">注册 + 注册

{ diff --git a/src/modules/login/educoder.png b/src/modules/login/educoder.png index dbe8fb56..ee7b29f6 100644 Binary files a/src/modules/login/educoder.png and b/src/modules/login/educoder.png differ diff --git a/src/modules/loginRegister/Login.jsx b/src/modules/loginRegister/Login.jsx new file mode 100644 index 00000000..f8206e03 --- /dev/null +++ b/src/modules/loginRegister/Login.jsx @@ -0,0 +1,131 @@ +import React, { useEffect, useState } from "react"; +import { Form, Input, Button, Checkbox } from "antd"; +import { Link } from "react-router-dom"; +import axios from 'axios'; +import educoderLogo from '../login/educoder.png'; +import cookie from 'react-cookies'; +import './LoginRegisterPage.scss'; + +function Login(props){ + const [message,setMessage] = useState(); + const [setting, setSetting] = useState(undefined); + const {form} = props; + const {getFieldDecorator } = form; + + useEffect(()=>{ + //控制密码输入框在DOM不可见value + clear; + //请求settings.json接口获取第三方登录平台信息 + axios.get(`/setting.json`).then((response) => { + if (response && response.data) { + setSetting(response.data.setting); + } + }) + },[]) + + // 登录表单提交 + function handleSubmit(){ + form.validateFields((err, values) => { + if (!err) { + axios.post(`/accounts/login.json`, { + login: values.username, + password: values.password, + 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); + window.location.href = "/"+response.data.login; + } + }).catch((error) => { + console.log('error',error); + }) + } + }); + } + + //校验用户名 + function comfirmWrite(rule, value, callback, index){ + setMessage(undefined); + value ? callback():index === 1? callback("请输入邮箱地址或用户名登录"):callback("请输入登录密码"); + } + + //清除密码框的value属性->DOM看不见密码值 + function clear(){ + const password = document.getElementById("login_password"); + if(password && password.type==="password"){ + setTimeout(()=>{ + password.removeAttribute('value'); + },0) + } + } + + return( +
+
+
+ 欢迎登录 GitLink + 没有账号?去注册 +
+

{message}

+
+ + {getFieldDecorator('username',{ + rules:[ + { + validator: (rule, value, callback) => { comfirmWrite(rule, value, callback, 1) } + } + ], + validateTrigger:"onBlur", + })()} + + + + {getFieldDecorator('password', { + rules: [ + { + validator: (rule, value, callback) => { comfirmWrite(rule, value, callback, 2) } + } + ], + validateTrigger:"onBlur", + })( + , + )} + + +
+ + {getFieldDecorator('remember', { + valuePropName: 'checked', + initialValue: cookie.load('autologin'), + })(下次自动登录)} + + 忘记密码? +
+ +
+ + { + setting && setting.third_party && setting.third_party.length > 0 ? +

+

+  快速登录  + {setting.third_party.map((item,key)=>{ + return( + + {`${item.name}登录`} + + ) + }) + } +

+ :"" + } +
+
+ ) + +} +export default Form.create({ name: 'login' })(Login); \ No newline at end of file diff --git a/src/modules/loginRegister/LoginRegisterPage.jsx b/src/modules/loginRegister/LoginRegisterPage.jsx new file mode 100644 index 00000000..b606e057 --- /dev/null +++ b/src/modules/loginRegister/LoginRegisterPage.jsx @@ -0,0 +1,28 @@ +import React from "react"; +import Login from "./Login"; +import Register from "./Register"; +import ResetPassword from "./ResetPassword"; +import logo from './img/logo.png'; +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( +
+
+ + + +
+
+ {props.location.pathname === "/login" ? : props.location.pathname === "/register" ? : } + + +
+
+ ) +} +export default LoginRegisterPage; \ No newline at end of file diff --git a/src/modules/loginRegister/LoginRegisterPage.scss b/src/modules/loginRegister/LoginRegisterPage.scss new file mode 100644 index 00000000..7113b49f --- /dev/null +++ b/src/modules/loginRegister/LoginRegisterPage.scss @@ -0,0 +1,237 @@ +.login_register{ + height: 100%; +} +.login_register_left,.login_register_right,.right_cont{ + background-size: cover; + background-repeat: no-repeat; + background-position: center; +} +.login_register_left{ + display: flex; + position: absolute; + justify-content: center; + width: 30%; + height: 100%; + background-image: url(./img/bg.png); + .logo{ + height: 65px; + margin-top: 160px; + } + .ball{ + height: 220px; + z-index: 3; + position: absolute; + bottom: 270px; + animation: moving2 10s linear infinite; + } + @keyframes moving2 { + 0% { + transform: rotate(0deg); + } + 50% { + transform: rotate(180deg); + } + 100% { + transform: rotate(360deg); + } + } + .banner{ + height: 486px; + position: absolute; + bottom: -90px; + left: 10px; + } +} +.login_register_right{ + background-image: url(./img/rightBg.png); + position: absolute; + top: 0; + left: 30%; + right: 0; + height: 100%; + .img1{ + position: relative; + left: 130px; + top: 50%; + } + .img2{ + position: relative; + top: 65%; + left: 550px; + } + .right_cont{ + width: 37.5rem; + position: absolute; + top: 15%; + left: 16%; + z-index: 3; + border-radius: 7px; + background-color: white; + padding: 55px 90px; + & .register_tips{ + margin-top: -15px; + padding-bottom: 8px; + color: #808080; + font-size: 13px; + } + & .login_register_head{ + display: flex; + justify-content: space-between; + align-items: center; + &>span:first-child{ + font-size: 24px; + font-weight: 600; + color: #000000; + line-height: 33px; + } + & .ant-input{ + width: 19rem; + } + } + & .account{ + margin-top: 36px; + } + & .login_register_cofBut{ + width: 100%; + height: 44px; + background: #466AFF; + border-color: #466AFF; + border-radius: 7px; + margin-top: 20px; + font-size: 15px; + &:hover{ + background: #3456E5; + border-color: #3456E5; + } + } + & a{ + color: #466AFF; + &:hover{ + opacity:0.8; + } + } + & .link_span{ + font-weight: 500; + font-size: 15px; + color: #808080; + } + & .ant-input{ + height: 44px; + background-color: #F7F7F7 !important; + font-size: 15px; + color: #333333; + &:hover{ + border-color:#466AFF; + } + } + & .has-success .ant-input{ + background-color: #F7F7F7; + } + & .ant-form-explain{ + margin-top: 5px; + } + & .message, .ant-form-explain{ + color: #D40000; + font-size: 13px; + } + & .message.active{ + margin-bottom: -30px !important; + margin-top: 10px; + } + //取消antd表单默认样式 + .has-error .ant-input{ + background: #F7F7F7; + border-color: #D40000; + } + //修改复选框默认antd样式 + .ant-checkbox-checked .ant-checkbox-inner { + background-color: #466AFF; + border: #466AFF; + } + + .ant-checkbox-checked::after{ + border: 1px solid #466AFF; + } + .ant-checkbox-wrapper:hover .ant-checkbox-inner, .ant-checkbox:hover .ant-checkbox-inner, .ant-checkbox-input:focus + .ant-checkbox-inner,.ant-radio-checked .ant-radio-inner,.ant-radio-wrapper:hover .ant-radio, .ant-radio:hover .ant-radio-inner, .ant-radio-input:focus + .ant-radio-inner { + border-color: #466AFF; + } + } + .login_content{ + background-image: url(./img/loginBg.png); + height: 480px; + & .login_register_cofBut{ + margin-top: 0; + } + & .login_register_head{ + & checkbox{ + font-size: 15px; + color: #3C476E; + line-height: 21px; + } + & .goResetPsdBut{ + margin-top: -25px; + } + } + & .quick_logon{ + text-align: center; + & .quick_logon_p{ + border-top: 1px solid #979797; + margin-top: 24px; + } + & .startlogin{ + position: relative; + background: #dfe0f7; + display: block; + width: 90px; + top: -15px; + left: 39%; + font-size: 13px; + color: #8D8D8D; + } + } + } + .Register_content{ + background-image: url(./img/registerBg.png); + & .register_last_form .ant-form-item-control{ + line-height: 0.5; + } + } + .ResetPassword_content{ + background-image: url(./img/resetPasswordBg.png); + height: 550px; + & .resetFailCaptcha{ + position: absolute; + top: 25px; + color: #D40000; + font-size: 13px; + } + } + .codeBut{ + height: 45px; + background: #F7F7F7; + border-radius: 7px; + border: 1px solid rgba(167, 177, 200, 0.33); + margin-left: 14px; + width: 102px; + color: #466AFF; + font-size: 15px; + } + .codeBut.disable{ + color: rgba(0, 0, 0, 0.25); + background-color: #f5f5f5; + border-color: #d9d9d9; + } +} +.ant-message-notice-content{ + box-shadow: 0px 1px 8px 1px rgba(0, 0, 0, 0.11); + border-radius: 10px; + margin-top: 2rem; + margin-left: 10%; + font-size: 15px; + & a{ + color: #466AFF; + &:hover{ + opacity:0.8; + } + } +} diff --git a/src/modules/loginRegister/Register.jsx b/src/modules/loginRegister/Register.jsx new file mode 100644 index 00000000..7d32a250 --- /dev/null +++ b/src/modules/loginRegister/Register.jsx @@ -0,0 +1,312 @@ +import React, { useEffect, useRef, useState } from "react"; +import { Form, Input, Button, Checkbox, message } from "antd"; +import { Link } from "react-router-dom"; +import axios from 'axios'; +import { setmiyah } from 'educoder'; +import './LoginRegisterPage.scss'; + +function Register(props){ + const {form} = props; + const {getFieldDecorator } = form; + const [emailStr, setEmailStr] = 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 [emailGo, setEmailGo] = useState(true); + const seconds = useRef(); + let interval = undefined; + //页面加载完自动聚焦到第一个输入框 + const inputEl = useRef(null); + + //注册表单提交 + function handleSubmit(){ + form.validateFields((err, values) => { + if (!err) { + values.agreement && axios.post(`/accounts/register.json`, { + login: values.email, + namespace: values.register_username, + password: values.register_psd, + password_confirmation: values.psdComfirm, + code: values.captcha + }).then((response)=>{ + if(response.data && response.data.status === -6){ + //验证码不正确 + form.setFields({captcha: {value:values.captcha,errors:[new Error('验证码错误,请重新输入')]}}) + }else if(response.data && response.data.status === 0){ + //注册成功,页面跳转即可,注册后登录流程forge处理了 + window.location.href = "/"+values.register_username; + }else{ + setMess(response.data.message); + } + }) + } + }); + } + + //判断用户名(username)是否注册 + function usernameConfirm(rule, value, callback){ + setUserNameGo(true); + value && userNameGo ? axios.post(`/accounts/check.json`, { + value: value, + type: 1 + }).then(response => { + if (response.data.status === -1) { + callback('该名称已经被使用'); + } else { + setUserNameGo(false); + callback(); + } + }):callback() + } + + //判断邮箱是否注册 + function emailConfirm(rule, value, callback) { + setEmailGo(true); + value && emailGo ? axios.post(`/accounts/check.json`, { + value: value, + type: 2 + }).then(response => { + if (response.data.status === -1) { + callback('该邮箱已被注册'); + } else { + setEmailStr(value); + setGetCaptchaBut(true); + setEmailGo(false); + callback(); + } + }):callback();setEmailStr(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){ + 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() { + setMess(undefined); + if (emailStr) { + // 倒计时开始 + setCountDown(true); + setGetCaptchaBut(false); + seconds.current = 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: emailStr, + type: 1, + smscode: setmiyah(emailStr), + } + }).then(response => { + if (response.data && response.data.status === 0) { + //验证码发送成功 + let email = emailStr.substring(emailStr.indexOf("@")+1); + message.success({content:验证码已发送,请注意查收。前往邮箱}); + } 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; + }, []) + + return( +
+
+
+ 欢迎注册 GitLink + 已有账号,立即登录 +
+

{mess}

+
+ + {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, + })({document.getElementById("register_register_username").removeAttribute("readOnly")}}/>)} + + + {getFieldDecorator('email',{ + rules:[ + { + type: 'email', + message: '请输入正确的邮箱格式', + }, + { + required:true, + message:"请输入邮箱地址" + }, + { + validator: (rule, value, callback) => { emailConfirm(rule, value, callback) } + } + ], + validateTrigger:"onBlur", + validateFirst: true, + })({document.getElementById("register_email").removeAttribute("readOnly")}} />)} + + +
+ + {getFieldDecorator('captcha', { + rules: [{ + required: true, + message: "请输入验证码" + }], + validateTrigger: "onBlur", + })( + {document.getElementById("register_captcha").removeAttribute("readOnly")}} /> + )} + + +
+ + + {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, + })({document.getElementById("register_register_psd").removeAttribute("readOnly")}}/>)} + + 请输入8-16位密码,区分大小写、不能使用空格 + + + {getFieldDecorator('psdComfirm', { + rules: [ + { + required: true, + message: "请确认登录密码" + }, + { + validator: (rule, value, callback) => { comfirmPassWord(rule, value, callback, 2) } + } + ], + validateTrigger: "onBlur", + validateFirst: true, + })({document.getElementById("register_psdComfirm").removeAttribute("readOnly")}}/>)} + + + + + {getFieldDecorator('agreement', { + valuePropName: 'checked', + initialValue: false, + rules: [ + { + validator: (rule, value, callback) => { comfirmRead(rule, value, callback) } + } + ], + })(我已阅读并接受《GitLink服务协议条款》)} + + +
+
+
+ ) +} +export default Form.create({ name: 'register' })(Register); \ No newline at end of file diff --git a/src/modules/loginRegister/ResetPassword.jsx b/src/modules/loginRegister/ResetPassword.jsx new file mode 100644 index 00000000..1147de8b --- /dev/null +++ b/src/modules/loginRegister/ResetPassword.jsx @@ -0,0 +1,257 @@ +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 './LoginRegisterPage.scss'; + +function ResetPassword(props) { + const {form } = props; + const {getFieldDecorator } = form; + const [emailStr, setEmailStr] = 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); + //用于限制表单提交时会再次调用check.json接口校验数据 + const [emailGo, setEmailGo] = useState(true); + const seconds = useRef(); + let interval = undefined; + //页面加载完自动聚焦到第一个输入框 + const inputEl = useRef(null); + + //重置密码表单提交 + function handleSubmit() { + form.validateFieldsAndScroll((err, values) => { + if (!err) { + axios.post(`/accounts/reset_password.json`, { + login: values.email, + password: values.psd, + password_confirmation: values.psdComfirm, + code: values.captcha, + }).then((response) => { + if (response.data.status === 0) { + //重置密码成功,调用登录接口 + axios.post(`/accounts/login.json`, { + login: values.email, + password: values.psd + }).then((login_response) => { + if (!login_response.data.login) { + setMess(login_response.data.message); + } else { + window.location.href = "/" + login_response.data.login; + } + }).catch((error) => { + console.log('error',error); + }) + } else { + const message = response.data.message; + message === "验证码不正确" ? form.setFields({captcha: {value:values.captcha,errors:[new Error('验证码错误,请重新输入')]}}) : setMess(message); + } + }) + } + }); + } + + //判断邮箱是否注册 + function emailConfirm(rule, value, callback) { + setEmailGo(true); + value && emailGo ? 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 { + 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){ + 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 getCaptcha() { + setMess(undefined); + if (emailStr) { + // 倒计时开始 + setCountDown(true); + setGetCaptchaBut(false); + seconds.current = 60; + !interval && clearInterval(interval); + interval = setInterval(() => { + if (seconds.current > 1) { + let oldSeconds = seconds.current; + seconds.current = oldSeconds - 1; + setSecondsStr(oldSeconds - 1); + } else { + //倒计时结束->可以获取验证码 + setGetCaptchaBut(true); + setCountDown(false); + clearInterval(interval); + } + }, 1000) + + //请求获取验证码接口 + axios.get(`/accounts/get_verification_code.json`, { + params: { + login: emailStr, + type: 2, + smscode: setmiyah(emailStr), + } + }).then(response => { + if (response.data && response.data.status === 0) { + //验证码发送成功 + let email = emailStr.substring(emailStr.indexOf("@")+1); + message.success({content:验证码已发送,请注意查收。前往邮箱}); + } else { + //验证码发送失败,获取验证码按钮变灰并且文案变回【获取验证码】 + setGetCaptchaBut(false); + setCountDown(false); + clearInterval(interval); + setMess(response.data.message); + } + }) + } + } + + //清除密码框的value属性->DOM看不见密码值 + function clear(){ + const password = document.getElementById("resetPassword_psd"); + const passwordComfirm = document.getElementById("resetPassword_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; + }, []) + + return ( +
+
+
+ 找回密码 + 已有账号,立即登录 +
+

{mess}

+
+ + {getFieldDecorator('email', { + rules: [ + { + type: 'email', + message: '请输入正确的邮箱格式', + }, + { + required: true, + message: "请输入已注册的邮箱" + }, + { + validator: (rule, value, callback) => { emailConfirm(rule, value, callback) } + } + ], + validateTrigger: "onBlur", + validateFirst: true, + })({document.getElementById("resetPassword_email").removeAttribute("readOnly")}} />)} + + +
+ + {getFieldDecorator('captcha', { + rules: [{ + required: true, + message: "请输入验证码" + }], + validateTrigger: "onBlur", + })( + {document.getElementById("resetPassword_captcha").removeAttribute("readOnly")}} /> + )} + + +
+ + + {getFieldDecorator('psd', { + rules: [ + { + validator: (rule, value, callback) => { comfirmPassWord(rule, value, callback,1) } + }, + { + validator: (rule, value, callback) => { checkPassWord(rule, value, callback) } + } + ], + validateTrigger: "onBlur", + validateFirst: true, + })({document.getElementById("resetPassword_psd").removeAttribute("readOnly")}} />)} + + 请输入8-16位密码,区分大小写、不能使用空格 + + + {getFieldDecorator('psdComfirm', { + rules: [ + { + required: true, + message: "请确认新密码" + }, + { + validator: (rule, value, callback) => { comfirmPassWord(rule, value, callback,2) } + } + ], + validateTrigger: "onBlur", + validateFirst: true, + })({document.getElementById("resetPassword_psdComfirm").removeAttribute("readOnly")}} />)} + + + + + +
+
+
+ ) + +} +export default Form.create({ name: 'resetPassword' })(ResetPassword); \ No newline at end of file diff --git a/src/modules/loginRegister/img/ball.png b/src/modules/loginRegister/img/ball.png new file mode 100644 index 00000000..e0b1aebf Binary files /dev/null and b/src/modules/loginRegister/img/ball.png differ diff --git a/src/modules/loginRegister/img/banner.png b/src/modules/loginRegister/img/banner.png new file mode 100644 index 00000000..17243f6d Binary files /dev/null and b/src/modules/loginRegister/img/banner.png differ diff --git a/src/modules/loginRegister/img/bg.png b/src/modules/loginRegister/img/bg.png new file mode 100644 index 00000000..9795223e Binary files /dev/null and b/src/modules/loginRegister/img/bg.png differ diff --git a/src/modules/loginRegister/img/contBg.png b/src/modules/loginRegister/img/contBg.png new file mode 100644 index 00000000..4fd22760 Binary files /dev/null and b/src/modules/loginRegister/img/contBg.png differ diff --git a/src/modules/loginRegister/img/img1.png b/src/modules/loginRegister/img/img1.png new file mode 100644 index 00000000..1f7210b3 Binary files /dev/null and b/src/modules/loginRegister/img/img1.png differ diff --git a/src/modules/loginRegister/img/img2.png b/src/modules/loginRegister/img/img2.png new file mode 100644 index 00000000..c6a9b8f8 Binary files /dev/null and b/src/modules/loginRegister/img/img2.png differ diff --git a/src/modules/loginRegister/img/loginBg.png b/src/modules/loginRegister/img/loginBg.png new file mode 100644 index 00000000..d704d257 Binary files /dev/null and b/src/modules/loginRegister/img/loginBg.png differ diff --git a/src/modules/loginRegister/img/logo.png b/src/modules/loginRegister/img/logo.png new file mode 100644 index 00000000..ac07686b Binary files /dev/null and b/src/modules/loginRegister/img/logo.png differ diff --git a/src/modules/loginRegister/img/registerBg.png b/src/modules/loginRegister/img/registerBg.png new file mode 100644 index 00000000..8c34bfb1 Binary files /dev/null and b/src/modules/loginRegister/img/registerBg.png differ diff --git a/src/modules/loginRegister/img/resetPasswordBg.png b/src/modules/loginRegister/img/resetPasswordBg.png new file mode 100644 index 00000000..fe5aae02 Binary files /dev/null and b/src/modules/loginRegister/img/resetPasswordBg.png differ diff --git a/src/modules/loginRegister/img/rightBg.png b/src/modules/loginRegister/img/rightBg.png new file mode 100644 index 00000000..8e03b05b Binary files /dev/null and b/src/modules/loginRegister/img/rightBg.png differ