Commit c831ef54 by zhanghaozhe

Merge branch 'passport'

parents 1158e481 22330281
......@@ -25,7 +25,7 @@ class App extends Component {
cookie.set('plat', '5')
http.get(`${api.home}/m/user_info`).then(res => {
this.props.setCurrentUser(this.storeUser(res))
this.props.setCurrentUser(this.storeUser({...res, data: {}}))
})
}
......
......@@ -8,6 +8,7 @@
border: 1px solid $border_ccc;
border-radius: 3px;
-webkit-appearance: none;
font-size: 15px;
&::-webkit-input-placeholder {
color: $color_999;
......
......@@ -3,43 +3,36 @@ import './clearable-input.scss'
import classnames from 'classnames'
class ClearableInput extends Component {
constructor(props) {
super(props);
this.state = {
value: ''
}
}
handleChange = (e) => {
let {onChange} = this.props
let val = e.target.value
this.setState({value: val})
onChange && onChange(val)
}
clearInput = () => {
this.setState({value: ''})
}
render() {
let {wrapperClass, inputClass, placeholder, type = 'text', onChange, icon, ...rest} = this.props
let {
value,
name,
wrapperClass,
inputClass,
type = 'text',
icon,
setValues,
...rest
} = this.props
let clearIconStyle = {
display: this.state.value.length ? 'block' : 'none'
display: value && value.length ? 'block' : 'none'
}
return (
<div className={classnames('clearable-input-wrapper', wrapperClass)}>
<input
type={type}
value={value}
className={inputClass}
value={this.state.value}
onChange={this.handleChange}
placeholder={placeholder}
{...rest}
name={name}
/>
{icon}
<i
className={'iconfont icondanseshixintubiao-3 clear'}
onClick={this.clearInput}
onClick={() => {
setValues({[name]: ''})
}}
style={clearIconStyle}
/>
</div>
......
......@@ -4,3 +4,7 @@ export { default as Tag } from './CategoryTag'
export { default as OrderItem } from './OrderList'
export { default as HeaderBar } from './HeaderBar'
export { default as ToApp } from './ToApp'
export { default as Captcha } from './Captcha'
export { default as ClearableInput } from "./ClearableInput";
.custom-button {
width:300px;
height:44px;
border-radius:3px;
width: 300px;
height: 44px;
border-radius: 3px;
-webkit-appearance: none;
border: none;
font-size: $font_18;
color: $white;
&.active {
background: $active;
color: $white;
}
}
\ No newline at end of file
......@@ -3,9 +3,9 @@ import './button.scss'
import classnames from 'classnames'
const Button = ({className, children}) => {
const Button = ({children, active}) => {
return (
<button className={classnames('custom-button', className)}>
<button className={classnames('custom-button', {active})}>
{children}
</button>
);
......
import React, { Component } from 'react';
import './veri-code-input.scss'
import { http, api } from '@/utils';
import { http, api, validateEmail, validateTel } from '@/utils';
import { Toast } from "antd-mobile";
import { has } from 'lodash'
import classnames from 'classnames'
......@@ -17,11 +18,12 @@ class VeriCodeInput extends Component {
}
timer = null
countDown = () => {
let {count} = this.state
if (!this.state.isFirst) {
Toast.info('请重新进行滑块验证',2,null,false)
Toast.info('请重新进行滑块验证', 2, null, false)
this.props.instance.refresh()
this.setState({
isFirst: true
......@@ -45,8 +47,40 @@ class VeriCodeInput extends Component {
}
}
getType = () => {
const {account} = this.props
if (validateEmail(account)) {
return 'email'
}
}
sendCode = () => {
if (!this.validate()) return
console.log(this.getType())
this.getType() === 'email' ? this.sendEmail() : this.sendSMS();
return true;
}
sendEmail = () => {
const {account, challenge} = this.props
http.post(`${api['passport-api']}/send_email_code`, {
email: account,
challenge
}).then(res => {
if (res.data.errno === 0) {
Toast.info('验证码发送成功', 2, null, false)
} else {
Toast.info(res.data.msg, 2, null, false)
}
this.setState({
isFirst: false
})
})
}
sendSMS = () => {
const {action, tel, challenge} = this.props
http.post(`${api['passport-api']}/quick_sms`, {
phone_num: tel,
......@@ -62,15 +96,23 @@ class VeriCodeInput extends Component {
isFirst: false
})
})
return true
}
validate = () => {
const {tel, challenge} = this.props
if (!tel) {
Toast.info('手机号码不能为空', 2, null, false)
const {tel, challenge, account} = this.props
let hasTel = has(this.props, 'tel')
let content
if (hasTel) {
content = '手机号码不能为空'
} else {
content = '手机号或电子邮件不能为空'
}
if ((hasTel && !tel) || (!hasTel && !account)) {
Toast.info(content, 2, null, false)
return false
}
if (!challenge) {
Toast.info('请进行滑块验证', 2, null, false)
return false
......
.forgot-password {
height: 100%;
padding: 38px 36px;
.content {
padding: 38px 36px;
}
.place {
width: 100%;
......@@ -13,12 +18,8 @@
margin-bottom: 21px;
}
.verify-code{
.verify-code {
margin-bottom: 21px;
}
.next {
background: $active;
color: $white;
}
}
\ No newline at end of file
import React, { Component } from 'react'
import './forgot-password.scss'
import ClearableInput from '@common/ClearableInput'
import VeriCodeButton from '../common/veriCodeInput'
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 { validateTel, validateEmail } from "@/utils";
import { quickLogin } from '@/store/userAction';
import { isEmpty } from "lodash";
class ForgotPassword extends Component {
constructor(props) {
super(props);
this.state = {
verificationCode: '',
password: ''
}
state = {
validate: null,
captchaInstance: null
}
setTel = (val) => {
this.setState({tel: val})
}
setVerificationCode = (val) => {
this.setState({verificationCode: val});
getCaptchaInstance = instance => {
this.setState({
captchaInstance: instance
})
}
onVerify = (err, data) => {
if (err) {
console.log(err)
} else {
this.setState({
validate: data.validate
})
}
}
render() {
const {
values,
errors
} = this.props
console.log(this.props)
return (
<div className={'forgot-password'}>
<ClearableInput
type={'tel'}
placeholder={'请输入注册时的邮箱账号或手机号'}
onChange={this.setTel}
wrapperClass={'tel-input'}
icon={<i className={'iconfont iconshouji'}
style={{fontSize: '22px', left: '11px'}}
/>}
/>
<VeriCodeButton
className={'verify-code'}
onChange={this.setVerificationCode}
icon={<i className={'iconfont iconduanxin'}
style={{fontSize: '20px', left: '12px'}}
/>}
/>
<div className="place"/>
<Button className={'next'}>下一步</Button>
<HeaderBar title='忘记密码'/>
<div className="content">
<Form className='forgot-password-form'>
<Field
name={'account'}
render={({field, form}) => {
return (
<ClearableInput
{...field}
setValues={form.setValues}
type={'tel'}
placeholder={'请输入注册时的邮箱账号或手机号'}
wrapperClass={'tel-input'}
icon={<i className={'iconfont iconshouji'}
style={{fontSize: '22px', left: '11px'}}
/>}
/>)
}}
/>
{
this.state.validate &&
<Field
name='veriCode'
render={({field}) => {
return (
<VeriCodeInput
{...field}
className={'verify-code'}
icon={<i className={'iconfont iconduanxin'}
style={{fontSize: '20px', left: '12px'}}
/>}
account={values.account}
challenge={this.state.validate}
instance={this.state.captchaInstance}
/>
)
}}
/>
}
<Captcha getInstance={this.getCaptchaInstance} onVerify={this.onVerify}/>
<Button active={values.account && values.veriCode && isEmpty(errors)}>下一步</Button>
</Form>
</div>
</div>
);
}
}
export default ForgotPassword
\ No newline at end of file
const formikConfig = {
mapPropsToValues: () => ({
account: '',
veriCode: ''
}),
validateOnchange: true,
validate: values => {
let errors = {}
if (!validateTel(values.account) && !validateEmail(values.account)) {
errors.account = '请输入正确的手机号或邮箱地址'
}
return errors
},
handleSubmit(values, {props}) {
console.log(props)
props.quickLogin({
phone_num: values.account,
phone_code: values.veriCode
}).then(res => {
if (res.hasError) {
Toast.info(res.msg);
} else {
let state = props.location.state || {from: {pathname: '/'}}
props.history.replace(state.from)
}
})
},
}
export default compose(
connect(
null,
{quickLogin}
),
withFormik(formikConfig)
)(ForgotPassword)
\ No newline at end of file
......@@ -44,7 +44,6 @@ class Passport extends Component {
render() {
let {match, location} = this.props
console.log(location)
return (
<div className="passport">
<Switch>
......
......@@ -7,12 +7,12 @@ import Header from '../common/Header'
import VeriCodeInput from '../common/veriCodeInput'
import { Form, Field, withFormik } from "formik"
import Captcha from '@/common/Captcha'
import { http, api } from '@/utils';
import { quickLogin } from '@/store/userAction';
import { connect } from 'react-redux';
import { compose } from 'redux';
import { isEmpty } from 'lodash'
import { Toast } from 'antd-mobile';
import {validateTel} from "@/utils";
class WechatLogin extends Component {
......@@ -124,7 +124,7 @@ const FormikConfig = {
validateOnChange: true,
validate: (values) => {
let errors = {}
if (!/^1[3-9](\d{9})$/.test(values.tel)) {
if (!validateTel(values.tel)) {
errors.tel = '请填写正确格式的手机号'
}
if (!/[0-9]{6}/.test(values.veriCode)) {
......
import React, { Component } from 'react';
import './set-password.scss'
import { withFormik, Form, Field } from "formik";
import PasswordInput from '../common/passwordInput'
import Button from '../common/Button'
import classnames from 'classnames'
import { compose } from 'redux'
class SetPassword extends Component {
......@@ -26,14 +26,25 @@ class SetPassword extends Component {
}
render() {
return (
<div className={'set-password'}>
<p className='title'>密码需要包含6-16位字母及数字</p>
<PasswordInput
placeholder={'设置密码'}
onChange={this.handleChange}
/>
<Button className={'btn-active'}>完成</Button>
<Form>
<Field
name='password'
render={({field}) => {
return (
<PasswordInput
placeholder={'设置密码'}
onChange={this.handleChange}
{...field}
/>
)
}}
/>
<Button className={'btn-active'}>完成</Button>
</Form>
<p className='user-agreement'>
<i className={classnames({
'iconfont iconiconfront-3': this.state.agree,
......@@ -47,4 +58,15 @@ class SetPassword extends Component {
}
}
export default SetPassword;
\ No newline at end of file
const formikConfig = {
mapValuesToProps: () => ({
password: ''
}),
handleSubmit: (values) => {
}
}
export default compose(
withFormik(formikConfig)
)(SetPassword);
\ No newline at end of file
export { default as http } from './http'
export { default as api } from './api'
export { html, initCaptcha }
export { html, initCaptcha, validateTel, validateEmail }
export const getParam = (key, str) => {
......@@ -69,3 +69,12 @@ export const is_weixin = () => {
}
return false;
}
function validateTel(tel) {
return /^1[3-9](\d{9})$/.test(tel)
}
function validateEmail(email) {
var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(String(email).toLowerCase());
}
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