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"
name="viewport"
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,19 +23,19 @@
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>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
</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.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</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,25 +68,35 @@ class WechatLogin extends PureComponent {
/>
)}
>
</FastField>
<FastField
type='number'
name='veriCode'
render={({field}) => (
<VeriCodeInput
{...field}
className={'verification'}
icon={<i className={'iconfont iconduanxin'}
style={{fontSize: '20px', left: '12px'}}
/>}
placeholder={'请输入验证码'}
/>
)}
</Field>
{
this.state.validate &&
<Field
type='number'
name='veriCode'
render={({field}) => (
<VeriCodeInput
{...field}
className={'verification'}
icon={<i className={'iconfont iconduanxin'}
style={{fontSize: '20px', left: '12px'}}
/>}
tel={values.tel}
challenge={this.state.validate}
errors={errors}
placeholder={'请输入验证码'}
instance={this.state.captchaInstance}
/>
)}
/>
}
<Captcha getInstance={this.getCaptchaInstance}
onVerify={this.onVerify}
/>
<LoginButton/>
<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,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 { 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