Commit f6faedcc by wangshuo

合并dev

parents 2a0ea353 ffb989e8
......@@ -6,9 +6,9 @@
"@babel/core": "7.2.2",
"@loadable/component": "^5.10.1",
"@svgr/webpack": "4.1.0",
"antd-mobile": "^2.2.11",
"autoprefixer": "^9.5.1",
"axios": "^0.18.0",
"antd-mobile": "^2.2.13",
"autoprefixer": "^9.6.0",
"axios": "^0.19.0",
"babel-core": "7.0.0-bridge.0",
"babel-eslint": "9.0.0",
"babel-jest": "23.6.0",
......@@ -30,7 +30,7 @@
"eslint-plugin-jsx-a11y": "6.1.2",
"eslint-plugin-react": "7.12.4",
"file-loader": "2.0.0",
"formik": "^1.5.4",
"formik": "^1.5.7",
"fs-extra": "7.0.1",
"html-webpack-plugin": "4.0.0-alpha.2",
"http-proxy-middleware": "^0.19.1",
......@@ -51,7 +51,6 @@
"postcss-loader": "3.0.0",
"postcss-preset-env": "6.5.0",
"postcss-safe-parser": "4.0.1",
"rc-form": "^2.4.4",
"react": "^16.8.6",
"react-app-polyfill": "^0.2.2",
"react-dev-utils": "^8.0.0",
......@@ -60,7 +59,7 @@
"react-lazy-load": "^3.0.13",
"react-mobile-swiper": "^1.1.4",
"react-redux": "^7.0.2",
"react-router-dom": "^5.0.0",
"react-router-dom": "^5.0.1",
"redux": "^4.0.1",
"redux-immutable": "^4.0.0",
"redux-logger": "^3.0.6",
......
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
<head>
<meta charset="utf-8"/>
<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" />
<meta name="theme-color" content="#000000"/>
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json"/>
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
......@@ -23,11 +23,11 @@
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
......@@ -36,6 +36,6 @@
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
-->
</body>
</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
import React, { Component } from 'react';
import { Flex, NavBar, List, InputItem, Button, WhiteSpace, WingBlank, Toast } from 'antd-mobile';
import { createForm } from 'rc-form';
class orderinfo extends Component {
submit = () => {
......@@ -87,6 +86,5 @@ class orderinfo extends Component {
}
}
const Basicorderinfo = createForm()(orderinfo);
export default Basicorderinfo;
\ No newline at end of file
export default orderinfo;
\ No newline at end of file
......@@ -5,23 +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'
// import LoginWays from '../common/LoginWays'
class AccountLogin extends PureComponent {
componentDidMount(){
console.log(this.props.location)
}
render() {
const {
errors,
values
} = this.props
return (
<div className={'account-login'}>
<Header/>
......@@ -52,10 +50,9 @@ class AccountLogin extends PureComponent {
/>
)}
/>
<LoginButton/>
<LoginButton active={values.account && values.password && isEmpty(errors)}/>
<Link className={'forgot-password-btn'} to='/passport/forgot-password'>忘记密码</Link>
</Form>
{/*<LoginWays loginWays={this.props.loginWays}/>*/}
</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() {
......
......@@ -3,7 +3,7 @@ import { Route, Switch, Redirect } from 'react-router-dom'
import './passport.scss'
import { WithFullSize } from '@/HOCs'
import WechatLogin from './wechatLogin'
import Login from './login'
import AccountLogin from './accountLogin'
import ForgotPassword from './forgotPassword'
import SetPassword from './setPassword'
......@@ -17,6 +17,7 @@ import wechat from './wechat.png'
class Passport extends Component {
constructor(props) {
super(props);
this.state = {
......@@ -49,10 +50,10 @@ class Passport extends Component {
<Switch>
<Redirect exact
from={'/passport'}
to={{...location, ...{pathname: '/passport/account-login'}}}
to={{...location, ...{pathname: '/passport/login'}}}
/>
<Route path={match.url + '/wechat-login'}
render={() => <WechatLogin loginWays={this.state.loginWays}/>}/>
<Route path={match.url + '/login'}
render={props => <Login {...props} loginWays={this.state.loginWays}/>}/>
<Route path={match.url + '/account-login'} component={AccountLogin}/>
<Route path={match.url + '/forgot-password'} component={ForgotPassword}/>
<Route path={match.url + '/set-password'} component={SetPassword}/>
......
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 {
class WechatLogin extends Component {
state = {
validate: null,
captchaInstance: null
}
loginWaysClick = index => {
switch (index) {
case 0:
this.props.history.push('/passport/account-login')
break;
}
}
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
......@@ -32,8 +68,10 @@ class WechatLogin extends PureComponent {
/>
)}
>
</FastField>
<FastField
</Field>
{
this.state.validate &&
<Field
type='number'
name='veriCode'
render={({field}) => (
......@@ -43,14 +81,22 @@ 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 active={values.tel && values.veriCode && isEmpty(errors)}/>
</Form>
<LoginWays onClick={this.selectLoginWays} loginWays={loginWays}/>
<LoginWays onClick={this.loginWaysClick} loginWays={loginWays}/>
</div>
)
}
......@@ -61,17 +107,37 @@ 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,6 +9,18 @@ const accountLogin = user => dispatch => {
password: encrypt(user.password),
is_encrypt: 1
}).then(res => {
return storeUser(res, dispatch)
})
}
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) {
......@@ -26,15 +38,8 @@ const accountLogin = user => dispatch => {
}
dispatch(setCurrentUser(payload))
return payload
})
}
/*
const CAPTCHA_LOGIN = 'CAPTCHA_LOGIN'
const captchaLogin = payload => dispatch => {
return http.post(`${api['passport-api']}/`)
}
*/
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 { default as http } from './http'
export { default as api } from './api'
export { html, initCaptcha }
export const getParam = (key, str) => {
......@@ -19,7 +19,49 @@ const htmlDecode = content => {
}
// 判断是否是微信环境 是返回true;否则返回false
//加载网易易盾辅助函数
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)
}
}
export const is_weixin = () => {
var ua = window.navigator.userAgent.toLowerCase();
if (ua.match(/MicroMessenger/i) == 'micromessenger') {
......
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