Commit e299a048 by zhanghaozhe

快捷登录

parent 740c97d8
......@@ -5,7 +5,7 @@
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico"/>
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
content="width=device-width, initial-scale=1, shrink-to-fit=no,user-scalable=no"
/>
<meta name="theme-color" content="#000000"/>
<!--
......@@ -38,25 +38,4 @@
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
<script>
var url = 'https://cstaticdun.126.net/load.min.js' + '?t=' + getTimestamp(60 * 1000)
loadScript(url)
function getTimestamp(msec) {
msec = !msec && msec !== 0 ? msec : 1
return parseInt((new Date()).valueOf() / msec, 10)
}
function loadScript(src) {
var head = document.head || document.getElementsByTagName('head')[0]
var script = document.createElement('script')
script.type = 'text/javascript'
script.src = src
head.appendChild(script)
}
</script>
</html>
......@@ -21,7 +21,6 @@ class App extends Component {
componentDidMount() {
//平台信息
cookie.set('plat', '5')
......
import React, { Component } from 'react';
import { initCaptcha } from '@/utils';
const CAPTCHAID = '6b0f5f6c8f334f3693ee754ba5692e36'
class Captcha extends Component {
componentDidMount() {
const {getInstance, handleError, onVerify} = this.props
initCaptcha(function () {
initNECaptcha({
element: '#captcha',
captchaId: CAPTCHAID,
mode: 'float',
width: 'auto',
onVerify: function (err, data) {
onVerify(err,data)
}
},
instance => {
getInstance && getInstance(instance)
},
err => {
handleError && handleError(err)
}
)
})
}
render() {
return (
<div id={'captcha'} style={{'marginBottom': '33px'}}></div>
);
}
}
export default Captcha;
\ No newline at end of file
......@@ -5,22 +5,21 @@ import { withFormik, FastField, Form } from "formik";
import { compose } from 'redux';
import { accountLogin } from '@/store/userAction';
import { connect } from "react-redux";
import { isEmpty } from 'lodash'
import Header from "../common/Header";
import Input from '../common/Input'
import LoginButton from '../common/LoginButton'
import PasswordInput from '../common/passwordInput'
// import VeriCodeButton from '../common/veriCodeInput'
class AccountLogin extends PureComponent {
componentDidMount(){
console.log(this.props.location)
}
render() {
const {
errors,
values
} = this.props
return (
<div className={'account-login'}>
<Header/>
......@@ -51,7 +50,7 @@ class AccountLogin extends PureComponent {
/>
)}
/>
<LoginButton/>
<LoginButton active={values.account && values.password && isEmpty(errors)}/>
<Link className={'forgot-password-btn'} to='/passport/forgot-password'>忘记密码</Link>
</Form>
</div>
......
import React from 'react'
import './loginButton.scss'
import classnames from 'classnames'
const LoginButton = React.memo(({onClick}) => {
const LoginButton = React.memo(({onClick, active}) => {
return (
<button type={'submit'} onClick={onClick} className={'login-button'}>
<button type={'submit'}
onClick={onClick}
className={classnames('login-button', {active})}>
登录
</button>
);
......
......@@ -8,4 +8,9 @@
color: $white;
background: $bg_ccc;
border: none;
&.active {
background-color: $active;
color: $white;
}
}
\ No newline at end of file
import React, { Component } from 'react';
import './veri-code-input.scss'
import { http, api } from '@/utils';
import { Toast } from "antd-mobile";
import classnames from 'classnames'
......@@ -9,19 +12,32 @@ class VeriCodeInput extends Component {
count = 10
state = {
counting: false,
count: this.count
count: this.count,
isFirst: true
}
timer = null
countDown = () => {
let {count} = this.state
if (!this.state.isFirst) {
Toast.info('请重新进行滑块验证',2,null,false)
this.props.instance.refresh()
this.setState({
isFirst: true
})
return
}
if (!this.state.counting) {
this.sendCode()
if (!this.sendCode()) {
return
}
this.setState({count: count--, counting: true})
this.timer = setInterval(() => {
if (count <= 0) {
this.setState({counting: false, count: this.count})
clearInterval(this.timer)
this.setState({counting: false, count: this.count})
return
}
this.setState({count: count--})
......@@ -30,7 +46,36 @@ class VeriCodeInput extends Component {
}
sendCode = () => {
if (!this.validate()) return
const {action, tel, challenge} = this.props
http.post(`${api['passport-api']}/quick_sms`, {
phone_num: tel,
action: action || 'login',
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
})
})
return true
}
validate = () => {
const {tel, challenge} = this.props
if (!tel) {
Toast.info('手机号码不能为空', 2, null, false)
return false
}
if (!challenge) {
Toast.info('请进行滑块验证', 2, null, false)
return false
}
return true
}
render() {
......
import React, { PureComponent } from 'react'
import React, { Component } from 'react'
import './wechatLogin.scss'
import Input from "../common/Input"
import LoginButton from '../common/LoginButton'
import LoginWays from '../common/LoginWays'
import Header from '../common/Header'
import VeriCodeInput from '../common/veriCodeInput'
import { Form, FastField, withFormik } from "formik"
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';
class WechatLogin extends PureComponent {
componentDidMount(){
console.log(this.props)
class WechatLogin extends Component {
state = {
validate: null,
captchaInstance: null
}
loginWaysClick = index => {
switch (index) {
case 0:
this.props.history.push('/passport/account-login')
break;
}
}
handleClick = () => {
/*setTimeout(() => {
console.log(this.props.errors)
})*/
console.log(this.props.errors)
}
getCaptchaInstance = instance => {
this.setState({
captchaInstance: instance
})
}
onVerify = (err, data) => {
if (err) {
console.log(err)
} else {
this.setState({
validate: data.validate
})
}
}
render() {
const {
loginWays,
errors,
values
} = this.props
return (
<div className='login'>
<Header/>
<Form className="login-info">
<FastField
<Field
name='tel'
render={({field}) => (
<Input
......@@ -42,8 +75,8 @@ class WechatLogin extends PureComponent {
/>
)}
>
</FastField>
<FastField
</Field>
<Field
type='number'
name='veriCode'
render={({field}) => (
......@@ -53,11 +86,18 @@ class WechatLogin extends PureComponent {
icon={<i className={'iconfont iconduanxin'}
style={{fontSize: '20px', left: '12px'}}
/>}
tel={values.tel}
challenge={this.state.validate}
errors={errors}
placeholder={'请输入验证码'}
instance={this.state.captchaInstance}
/>
)}
/>
<LoginButton/>
<Captcha getInstance={this.getCaptchaInstance}
onVerify={this.onVerify}
/>
<LoginButton onClick={this.handleClick} active={values.tel && values.veriCode && isEmpty(errors)}/>
</Form>
<LoginWays onClick={this.loginWaysClick} loginWays={loginWays}/>
......@@ -71,17 +111,38 @@ const FormikConfig = {
tel: '',
veriCode: ''
}),
handleSubmit(values, {setError}) {
console.log(values)
handleSubmit(values, {props}) {
props.quickLogin({
phone_num: values.tel,
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)
}
})
},
validateOnChange: false,
/*validate: (values) => {
validateOnChange: true,
validate: (values) => {
let errors = {}
if (!/^1[3-9](\d{9})$/.test(values.tel)) {
errors.tel = '手机号不正确'
errors.tel = '请填写正确格式的手机号'
}
if (!/[0-9]{6}/.test(values.veriCode)) {
errors.veriCode = '请输入验证码'
}
return errors
}*/
}
}
export default withFormik(FormikConfig)(WechatLogin)
\ No newline at end of file
export default compose(
connect(
null,
{quickLogin}
),
withFormik(FormikConfig),
)(WechatLogin)
\ No newline at end of file
......@@ -9,32 +9,37 @@ const accountLogin = user => dispatch => {
password: encrypt(user.password),
is_encrypt: 1
}).then(res => {
const data = res.data
let payload
if (data.errno === 0) {
const {user_name: username, avatar_file: avatar, ...rest} = data.data.user_info
payload = {
hasError: false,
msg: data.msg,
data: {username, avatar, ...rest}
}
} else {
payload = {
hasError: true,
msg: data.msg
}
}
dispatch(setCurrentUser(payload))
return payload
return storeUser(res, dispatch)
})
}
/*
const CAPTCHA_LOGIN = 'CAPTCHA_LOGIN'
const captchaLogin = payload => dispatch => {
return http.post(`${api['passport-api']}/`)
const quickLogin = user => dispatch => {
return http.post(`${api['passport-api']}/quick_login`, user)
.then(res => {
return storeUser(res, dispatch)
})
}
const storeUser = (res, dispatch) => {
const data = res.data
let payload
if (data.errno === 0) {
const {user_name: username, avatar_file: avatar, ...rest} = data.data.user_info
payload = {
hasError: false,
msg: data.msg,
data: {username, avatar, ...rest}
}
} else {
payload = {
hasError: true,
msg: data.msg
}
}
dispatch(setCurrentUser(payload))
return payload
}
*/
const SET_CURRENT_USER = 'SET_CURRENT_USER'
......@@ -55,5 +60,6 @@ const logout = () => dispatch => {
export {
accountLogin,
SET_CURRENT_USER,
setCurrentUser
setCurrentUser,
quickLogin
}
\ No newline at end of file
export { default as http } from './http'
export { default as api } from './api'
export { html }
export { html, initCaptcha }
export const getParam = (key, str) => {
......@@ -21,3 +19,46 @@ const htmlDecode = content => {
}
//加载网易易盾辅助函数
function getTimestamp(msec) {
msec = !msec && msec !== 0 ? msec : 1
return parseInt((new Date()).valueOf() / msec, 10)
}
function loadScript(src, cb) {
var head = document.head || document.getElementsByTagName('head')[0]
var script = document.createElement('script')
cb = cb || function () {
}
script.type = 'text/javascript'
script.src = src
if (!('onload' in script)) {
script.onreadystatechange = function () {
if (this.readyState !== 'complete' && this.readyState !== 'loaded') return
this.onreadystatechange = null
cb(script)
}
}
script.onload = function () {
this.onload = null
cb(script)
}
head.appendChild(script)
}
function initCaptcha(cb) {
if (window.initNECaptcha) {
cb()
} else {
const url = 'http://cstaticdun.126.net/load.min.js' + '?t=' + getTimestamp(1 * 60 * 1000)
loadScript(url, cb)
}
}
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