Commit b41c453e by zhanghaozhe

忘记密码

parent 983b183b
......@@ -10,7 +10,7 @@ export const delCountryNum = () => ({
type: 'DEL_COUNTRY_NUM'
});
export default (state = {}, action) => {
export default (state = {num: 86, code: null}, action) => {
const { type, payload } = action;
switch (type) {
case ADD_COUNTRY_NUM:
......
......@@ -53,7 +53,8 @@ class Country extends Component {
num,
code: getParam('share_code')
});
history.push(`/detail?id=${getParam('id')}`);
// history.push(`/detail?id=${getParam('id')}`);
history.go(-1)
e.preventDefault();
}
......
......@@ -6,13 +6,8 @@ import more from '../../icons/more.png'
class LoginWays extends PureComponent {
state = {
ways: browser.isWeixin ? this.props.loginWays.slice(0, 2) : this.props.loginWays.slice(0, 1)
}
componentDidMount() {
this.setState({
ways: this.filterWays()
})
ways: browser.isWeixin ? this.props.loginWays.slice(0, 2) : this.props.loginWays.slice(0, 1),
showMore: true
}
......@@ -21,12 +16,13 @@ class LoginWays extends PureComponent {
}
filterWays = () => {
return browser.isWeixin ? this.props.loginWays : this.state.ways.filter(item => item.id !== 'wechat')
return browser.isWeixin ? this.props.loginWays : this.props.loginWays.filter(item => item.id !== 'wechat')
}
showMore = () => {
this.setState({
ways: this.props.loginWays
ways: this.filterWays(),
showMore: false
})
}
......@@ -46,7 +42,7 @@ class LoginWays extends PureComponent {
})
}
{
this.state.ways.length !== this.props.loginWays.length &&
this.state.showMore &&
<li className={'more'} onClick={this.showMore}>
<img src={more} alt="更多"/>
<p>更多</p>
......
import React, { Component } from 'react';
import ClearableInput from '@common/ClearableInput'
import './index.scss'
import { Link } from "react-router-dom";
class ClearableInputWithCountryCodes extends Component {
render() {
const {country, ...rest} = this.props
return (
<div className={'clearable-input-with-country-codes'}>
<div className="country-code">
<Link to={'/country'}>
+{country && country.num || 86}
<i className={'iconfont iconiconfront-69'}/>
</Link>
</div>
<ClearableInput {...rest}/>
</div>
);
}
}
export default ClearableInputWithCountryCodes;
\ No newline at end of file
.clearable-input-with-country-codes {
display: flex;
border: 1px solid #ccc;
border-radius: 3px;
margin-bottom: 24px;
.clearable-input-wrapper {
margin-bottom: 0;
flex: 1 1 auto;
input {
padding-left: 10px;
border: none;
width: 100%;
padding-right: 34px;
}
}
.country-code {
flex-shrink: 0;
display: flex;
justify-content: center;
align-items: center;
font-size: 15px;
color: #333;
width: 63px;
text-align: center;
border-right: 1px solid #ccc;
.iconfont {
margin-left: 3px;
}
}
}
\ No newline at end of file
......@@ -3,13 +3,19 @@ import './index.scss'
import Input from '../Input'
class InputWithCountryCodes extends Component {
static defaultProps = {
countryCode: '86'
}
render() {
const {countryCode, ...rest} = this.props
return (
<div className={'input-with-country-codes'}>
<div className="country-codes">
<i className={'iconfont iconiconfront-69'}></i>
+{countryCode}
<i className={'iconfont iconiconfront-69'}/>
</div>
<Input/>
<Input {...rest}/>
</div>
);
}
......
.input-with-country-codes{
.input-wrapper{
.input{
.input-with-country-codes {
display: flex;
border: 1px solid #ccc;
border-radius: 3px;
margin-bottom: 24px;
.tel-input {
margin-bottom: 0;
.input {
padding-left: 10px;
border: none;
}
}
.country-codes{
font-size: 10px;
.country-codes {
flex-shrink: 0;
display: flex;
justify-content: center;
align-items: center;
font-size: 15px;
color: #333;
width: 63px;
text-align: center;
border-right: 1px solid #ccc;
}
}
\ No newline at end of file
import React, { Component } from 'react';
import './veri-code-input.scss'
import { http, validateEmail, validateTel } from '@/utils';
import { http, validateEmail } from '@/utils';
import { Toast } from "antd-mobile";
import { has } from 'lodash'
......@@ -47,8 +47,8 @@ class VeriCodeInput extends Component {
}
getType = () => {
const {account} = this.props
if (validateEmail(account)) {
const {email} = this.props
if (validateEmail(email)) {
return 'email'
}
}
......@@ -61,9 +61,9 @@ class VeriCodeInput extends Component {
}
sendEmail = () => {
const {account, challenge} = this.props
const {email, challenge} = this.props
http.post(`${API['passport-api']}/send_email_code`, {
email: account,
email,
challenge
}).then(res => {
if (res.data.errno === 0) {
......@@ -79,14 +79,15 @@ class VeriCodeInput extends Component {
}
sendSMS = () => {
const {action, tel, account, challenge, checking} = this.props
if (!tel && !account) {
Toast.info('请输入手机号或邮箱地址')
const {action, tel, account, challenge, checking, country} = this.props
if (!tel) {
Toast.info('请输入手机号')
return
}
http.post(`${API['passport-api']}/quick_sms`, {
phone_num: tel || account,
action: action || 'login',
area_code: country.num,
challenge,
checking
}).then(res => {
......@@ -103,7 +104,7 @@ class VeriCodeInput extends Component {
validate = () => {
const {tel, challenge, account} = this.props
const {tel, challenge, email} = this.props
let hasTel = has(this.props, 'tel')
let content
......@@ -111,15 +112,15 @@ class VeriCodeInput extends Component {
if (!tel) {
content = '手机号码不能为空'
}
if (!validateTel(tel)) {
if (!/\d/.test(tel)) {
content = '请输入正确格式的手机号码'
}
} else {
if (!account) {
content = '手机号或电子邮件不能为空'
if (!email) {
content = '电子邮件不能为空'
}
if (!validateTel(account) && !validateEmail(account)) {
content = '请输入正确格式的手机号或电子邮件'
if (!validateEmail(email)) {
content = '请输入正确格式的电子邮件'
}
}
......
......@@ -4,6 +4,13 @@
.content {
padding: 38px 36px;
text-align: center;
.to-email{
line-height: 55px;
font-size: 15px;
color: #666;
}
}
......@@ -14,10 +21,6 @@
background: #56abff;
}
.tel-input {
margin-bottom: 21px;
}
.verify-code {
margin-bottom: 21px;
}
......@@ -25,4 +28,5 @@
.next_step {
margin-top: 32px;
}
}
\ No newline at end of file
......@@ -6,10 +6,12 @@ import { withFormik, Form, Field } from 'formik';
import { connect } from 'react-redux';
import { compose } from 'redux';
import { Toast } from "antd-mobile";
import { HeaderBar, Captcha, ClearableInput } from "@/common";
import { validateTel, validateEmail, http, api } from "@/utils";
import { HeaderBar, Captcha } from "@/common";
import ClearableInput from '../common/clearableInputWithCountryCodes'
import { validateTel, http, api } from "@/utils";
import { quickLogin } from '@/store/userAction';
import OnSubmissionError from '../common/OnSubmissionError'
import { Link } from "react-router-dom";
class ForgotPassword extends Component {
......@@ -42,7 +44,8 @@ class ForgotPassword extends Component {
render() {
const {
values,
isValid
isValid,
country
} = this.props
return (
<div className={'forgot-password'}>
......@@ -50,18 +53,16 @@ class ForgotPassword extends Component {
<div className="content">
<Form className='forgot-password-form'>
<Field
name={'account'}
name={'tel'}
render={({field, form}) => {
return (
<ClearableInput
{...field}
type={'tel'}
placeholder={'请输入注册时的邮箱账号或手机号'}
placeholder={'请输入注册时的手机号'}
wrapperClass={'tel-input'}
setFieldValue={form.setFieldValue}
icon={<i className={'iconfont iconshouji'}
style={{fontSize: '22px', left: '11px'}}
/>}
country={country}
/>)
}}
/>
......@@ -77,11 +78,12 @@ class ForgotPassword extends Component {
icon={<i className={'iconfont iconduanxin'}
style={{fontSize: '20px', left: '12px'}}
/>}
account={values.account}
tel={values.tel}
challenge={this.state.validate}
instance={this.state.captchaInstance}
action={'auth'}
checking={1}
country={country}
/>
)
}}
......@@ -90,6 +92,7 @@ class ForgotPassword extends Component {
<OnSubmissionError callback={this.onSubmissionError}/>
<Captcha getInstance={this.getCaptchaInstance} onVerify={this.onVerify}/>
<Button className={'next_step'} active={isValid}>下一步</Button>
<Link className={'to-email'} to={`/passport/forgot-password-email`} replace>邮箱找回</Link>
</Form>
</div>
</div>
......@@ -101,37 +104,26 @@ class ForgotPassword extends Component {
const formikConfig = {
mapPropsToValues: () => ({
account: '',
tel: '',
veriCode: ''
}),
validateOnChange: true,
validateOnBlur: true,
validate: values => {
let errors = {}
if (!validateTel(values.account) && !validateEmail(values.account)) {
errors.account = '请输入正确的手机号或邮箱地址'
if (!validateTel(values.tel)) {
errors.tel = '请输入正确的手机号'
}
values.veriCode.toString().length !== 6 && (errors.veriCode = '验证码格式不正确')
return errors
},
handleSubmit(values, {props}) {
let account, address
if (validateEmail(values.account)) {
account = 'email'
address = 'check_email_code'
sessionStorage.setItem('r_type', 'email')
sessionStorage.setItem('email', values.account)
} else {
account = 'phone'
address = 'check_phone_code'
sessionStorage.setItem('r_type', 'phone')
sessionStorage.setItem('tel', values.account)
}
http.post(`${API['passport-api']}/${address}`, {
[account]: values.account,
code: values.veriCode
sessionStorage.setItem('r_type', 'phone')
sessionStorage.setItem('tel', values.tel)
http.post(`${API['passport-api']}/check_phone_code`, {
phone: values.tel,
code: values.veriCode,
area_code: props.country.num
}).then(res => {
if (res.data.errno == 0) {
props.history.push('/passport/set-password', {from: props.location})
......@@ -145,7 +137,7 @@ const formikConfig = {
export default compose(
connect(
null,
state => ({country: state.country}),
{quickLogin}
),
withFormik(formikConfig)
......
import React, { Component } from 'react'
import './index.scss'
import VeriCodeInput from '../common/veriCodeInput'
import Button from '../common/Button'
import { withFormik, Form, Field } from 'formik';
import { connect } from 'react-redux';
import { compose } from 'redux';
import { Toast } from "antd-mobile";
import { HeaderBar, Captcha, ClearableInput } from "@/common";
import { validateEmail, http, api } from "@/utils";
import { quickLogin } from '@/store/userAction';
import OnSubmissionError from '../common/OnSubmissionError'
import { Link } from "react-router-dom";
class ForgotPassword extends Component {
state = {
validate: null,
captchaInstance: null
}
getCaptchaInstance = instance => {
this.setState({
captchaInstance: instance
})
}
onVerify = (err, data) => {
if (err) {
console.log(err)
} else {
this.setState({
validate: data.validate
})
}
}
onSubmissionError = () => {
const errors = Object.values(this.props.errors);
errors.length && Toast.info(errors[0], 2, null, false)
}
render() {
const {
values,
isValid
} = this.props
return (
<div className={'forgot-password-email'}>
<HeaderBar title='忘记密码' arrow={true}/>
<div className="content">
<Form className='forgot-password-form'>
<Field
name={'email'}
render={({field, form}) => {
return (
<ClearableInput
{...field}
type={'email'}
placeholder={'请输入注册时的邮箱账号'}
wrapperClass={'email-input'}
setFieldValue={form.setFieldValue}
/>)
}}
/>
{
this.state.validate &&
<Field
name='veriCode'
render={({field}) => {
return (
<VeriCodeInput
{...field}
className={'verify-code'}
icon={<i className={'iconfont iconduanxin'}
style={{fontSize: '20px', left: '12px'}}
/>}
email={values.email}
challenge={this.state.validate}
instance={this.state.captchaInstance}
action={'auth'}
checking={1}
/>
)
}}
/>
}
<OnSubmissionError callback={this.onSubmissionError}/>
<Captcha getInstance={this.getCaptchaInstance} onVerify={this.onVerify}/>
<Button className={'next_step'} active={isValid}>下一步</Button>
<Link className={'to-phone'} to={'/passport/forgot-password'} replace>手机号找回</Link>
</Form>
</div>
</div>
);
}
}
const formikConfig = {
mapPropsToValues: () => ({
email: '',
veriCode: ''
}),
validateOnChange: true,
validateOnBlur: true,
validate: values => {
let errors = {}
if (!validateEmail(values.email)) {
errors.email = '请输入正确的邮箱地址'
}
values.veriCode.toString().length !== 6 && (errors.veriCode = '验证码格式不正确')
return errors
},
handleSubmit(values, {props}) {
sessionStorage.setItem('r_type', 'email')
sessionStorage.setItem('email', values.email)
http.post(`${API['passport-api']}/check_email_code`, {
email: values.email,
code: values.veriCode
}).then(res => {
if (res.data.errno == 0) {
props.history.push('/passport/set-password', {from: props.location})
} else {
Toast.info(res.data.msg, 2, null, false)
}
})
},
}
export default compose(
connect(
null,
{quickLogin}
),
withFormik(formikConfig)
)(ForgotPassword)
\ No newline at end of file
.forgot-password-email {
height: 100%;
.content {
padding: 38px 36px;
text-align: center;
.to-phone{
line-height: 55px;
font-size: 15px;
color: #666;
}
.email-input{
margin-bottom: 21px;
input{
padding-left: 10px;
}
}
}
.place {
width: 100%;
height: 39px;
margin-bottom: 33px;
background: #56abff;
}
.verify-code {
margin-bottom: 21px;
}
.next_step {
margin-top: 32px;
}
}
\ No newline at end of file
......@@ -8,8 +8,10 @@ import AccountLogin from './accountLogin'
import ForgotPassword from './forgotPassword'
import SetPassword from './setPassword'
import BindingTel from './bindingTel'
import ForgotPasswordEmail from './forgotPasswordEmail'
import { connect } from "react-redux";
import { compose } from "redux";
import {getParam} from "@/utils";
import account from './icons/account.png'
import qq from './icons/qq.png'
......@@ -96,6 +98,7 @@ class Passport extends Component {
}}/>
<Route path={match.url + '/account-login'} component={AccountLogin}/>
<Route path={match.url + '/forgot-password'} component={ForgotPassword}/>
<Route path={match.url + '/forgot-password-email'} component={ForgotPasswordEmail}/>
<Route path={match.url + '/set-password'} component={SetPassword}/>
<Route path={match.url + '/binding-tel'} component={BindingTel}/>
</Switch>
......
......@@ -85,9 +85,9 @@ class Login extends Component {
type={'tel'}
placeholder={'手机号快捷登录(免注册)'}
wrapperClass={'tel-input'}
icon={<i className={'iconfont iconshouji'}
/*icon={<i className={'iconfont iconshouji'}
style={{fontSize: '22px', left: '10px'}}
/>}
/>}*/
/>
)}
>
......
......@@ -8,9 +8,9 @@
padding: 0 38px;
flex: 1 0 auto;
.tel-input {
/*.tel-input {
margin-bottom: 24px;
}
}*/
.verification{
margin-bottom: 24px;
......
......@@ -16,10 +16,6 @@ import { connect } from "react-redux";
class SetPassword extends Component {
componentDidMount() {
// console.log(this.props.location);
}
render() {
let {values, errors, location} = this.props
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment