Commit f6faedcc by wangshuo

合并dev

parents 2a0ea353 ffb989e8
...@@ -6,9 +6,9 @@ ...@@ -6,9 +6,9 @@
"@babel/core": "7.2.2", "@babel/core": "7.2.2",
"@loadable/component": "^5.10.1", "@loadable/component": "^5.10.1",
"@svgr/webpack": "4.1.0", "@svgr/webpack": "4.1.0",
"antd-mobile": "^2.2.11", "antd-mobile": "^2.2.13",
"autoprefixer": "^9.5.1", "autoprefixer": "^9.6.0",
"axios": "^0.18.0", "axios": "^0.19.0",
"babel-core": "7.0.0-bridge.0", "babel-core": "7.0.0-bridge.0",
"babel-eslint": "9.0.0", "babel-eslint": "9.0.0",
"babel-jest": "23.6.0", "babel-jest": "23.6.0",
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
"eslint-plugin-jsx-a11y": "6.1.2", "eslint-plugin-jsx-a11y": "6.1.2",
"eslint-plugin-react": "7.12.4", "eslint-plugin-react": "7.12.4",
"file-loader": "2.0.0", "file-loader": "2.0.0",
"formik": "^1.5.4", "formik": "^1.5.7",
"fs-extra": "7.0.1", "fs-extra": "7.0.1",
"html-webpack-plugin": "4.0.0-alpha.2", "html-webpack-plugin": "4.0.0-alpha.2",
"http-proxy-middleware": "^0.19.1", "http-proxy-middleware": "^0.19.1",
...@@ -51,7 +51,6 @@ ...@@ -51,7 +51,6 @@
"postcss-loader": "3.0.0", "postcss-loader": "3.0.0",
"postcss-preset-env": "6.5.0", "postcss-preset-env": "6.5.0",
"postcss-safe-parser": "4.0.1", "postcss-safe-parser": "4.0.1",
"rc-form": "^2.4.4",
"react": "^16.8.6", "react": "^16.8.6",
"react-app-polyfill": "^0.2.2", "react-app-polyfill": "^0.2.2",
"react-dev-utils": "^8.0.0", "react-dev-utils": "^8.0.0",
...@@ -60,7 +59,7 @@ ...@@ -60,7 +59,7 @@
"react-lazy-load": "^3.0.13", "react-lazy-load": "^3.0.13",
"react-mobile-swiper": "^1.1.4", "react-mobile-swiper": "^1.1.4",
"react-redux": "^7.0.2", "react-redux": "^7.0.2",
"react-router-dom": "^5.0.0", "react-router-dom": "^5.0.1",
"redux": "^4.0.1", "redux": "^4.0.1",
"redux-immutable": "^4.0.0", "redux-immutable": "^4.0.0",
"redux-logger": "^3.0.6", "redux-logger": "^3.0.6",
......
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8"/>
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" /> <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico"/>
<meta <meta
name="viewport" 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 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/ 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. Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build. It will be replaced with the URL of the `public` folder during the build.
...@@ -23,19 +23,19 @@ ...@@ -23,19 +23,19 @@
Learn how to configure a non-root public URL by running `npm run build`. Learn how to configure a non-root public URL by running `npm run build`.
--> -->
<title>React App</title> <title>React App</title>
</head> </head>
<body> <body>
<noscript>You need to enable JavaScript to run this app.</noscript> <noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div> <div id="root"></div>
<!-- <!--
This HTML file is a template. This HTML file is a template.
If you open it directly in the browser, you will see an empty page. 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. You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag. The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`. To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`. To create a production bundle, use `npm run build` or `yarn build`.
--> -->
</body> </body>
</html> </html>
...@@ -21,7 +21,6 @@ class App extends Component { ...@@ -21,7 +21,6 @@ class App extends Component {
componentDidMount() { componentDidMount() {
//平台信息 //平台信息
cookie.set('plat', '5') 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 React, { Component } from 'react';
import { Flex, NavBar, List, InputItem, Button, WhiteSpace, WingBlank, Toast } from 'antd-mobile'; import { Flex, NavBar, List, InputItem, Button, WhiteSpace, WingBlank, Toast } from 'antd-mobile';
import { createForm } from 'rc-form';
class orderinfo extends Component { class orderinfo extends Component {
submit = () => { submit = () => {
...@@ -87,6 +86,5 @@ class orderinfo extends Component { ...@@ -87,6 +86,5 @@ class orderinfo extends Component {
} }
} }
const Basicorderinfo = createForm()(orderinfo);
export default Basicorderinfo; export default orderinfo;
\ No newline at end of file \ No newline at end of file
...@@ -5,23 +5,21 @@ import { withFormik, FastField, Form } from "formik"; ...@@ -5,23 +5,21 @@ import { withFormik, FastField, Form } from "formik";
import { compose } from 'redux'; import { compose } from 'redux';
import { accountLogin } from '@/store/userAction'; import { accountLogin } from '@/store/userAction';
import { connect } from "react-redux"; import { connect } from "react-redux";
import { isEmpty } from 'lodash'
import Header from "../common/Header"; import Header from "../common/Header";
import Input from '../common/Input' import Input from '../common/Input'
import LoginButton from '../common/LoginButton' import LoginButton from '../common/LoginButton'
import PasswordInput from '../common/passwordInput' import PasswordInput from '../common/passwordInput'
// import VeriCodeButton from '../common/veriCodeInput'
// import LoginWays from '../common/LoginWays'
class AccountLogin extends PureComponent { class AccountLogin extends PureComponent {
componentDidMount(){
console.log(this.props.location)
}
render() { render() {
const {
errors,
values
} = this.props
return ( return (
<div className={'account-login'}> <div className={'account-login'}>
<Header/> <Header/>
...@@ -52,10 +50,9 @@ class AccountLogin extends PureComponent { ...@@ -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> <Link className={'forgot-password-btn'} to='/passport/forgot-password'>忘记密码</Link>
</Form> </Form>
{/*<LoginWays loginWays={this.props.loginWays}/>*/}
</div> </div>
); );
} }
......
import React from 'react' import React from 'react'
import './loginButton.scss' import './loginButton.scss'
import classnames from 'classnames'
const LoginButton = React.memo(({onClick}) => { const LoginButton = React.memo(({onClick, active}) => {
return ( return (
<button type={'submit'} onClick={onClick} className={'login-button'}> <button type={'submit'}
onClick={onClick}
className={classnames('login-button', {active})}>
登录 登录
</button> </button>
); );
......
...@@ -8,4 +8,9 @@ ...@@ -8,4 +8,9 @@
color: $white; color: $white;
background: $bg_ccc; background: $bg_ccc;
border: none; border: none;
&.active {
background-color: $active;
color: $white;
}
} }
\ No newline at end of file
import React, { Component } from 'react'; import React, { Component } from 'react';
import './veri-code-input.scss' import './veri-code-input.scss'
import { http, api } from '@/utils';
import { Toast } from "antd-mobile";
import classnames from 'classnames' import classnames from 'classnames'
...@@ -9,19 +12,32 @@ class VeriCodeInput extends Component { ...@@ -9,19 +12,32 @@ class VeriCodeInput extends Component {
count = 10 count = 10
state = { state = {
counting: false, counting: false,
count: this.count count: this.count,
isFirst: true
} }
timer = null timer = null
countDown = () => { countDown = () => {
let {count} = this.state 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) { if (!this.state.counting) {
this.sendCode() if (!this.sendCode()) {
return
}
this.setState({count: count--, counting: true}) this.setState({count: count--, counting: true})
this.timer = setInterval(() => { this.timer = setInterval(() => {
if (count <= 0) { if (count <= 0) {
this.setState({counting: false, count: this.count})
clearInterval(this.timer) clearInterval(this.timer)
this.setState({counting: false, count: this.count})
return return
} }
this.setState({count: count--}) this.setState({count: count--})
...@@ -30,7 +46,36 @@ class VeriCodeInput extends Component { ...@@ -30,7 +46,36 @@ class VeriCodeInput extends Component {
} }
sendCode = () => { 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() { render() {
......
...@@ -3,7 +3,7 @@ import { Route, Switch, Redirect } from 'react-router-dom' ...@@ -3,7 +3,7 @@ import { Route, Switch, Redirect } from 'react-router-dom'
import './passport.scss' import './passport.scss'
import { WithFullSize } from '@/HOCs' import { WithFullSize } from '@/HOCs'
import WechatLogin from './wechatLogin' import Login from './login'
import AccountLogin from './accountLogin' import AccountLogin from './accountLogin'
import ForgotPassword from './forgotPassword' import ForgotPassword from './forgotPassword'
import SetPassword from './setPassword' import SetPassword from './setPassword'
...@@ -17,6 +17,7 @@ import wechat from './wechat.png' ...@@ -17,6 +17,7 @@ import wechat from './wechat.png'
class Passport extends Component { class Passport extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
...@@ -49,10 +50,10 @@ class Passport extends Component { ...@@ -49,10 +50,10 @@ class Passport extends Component {
<Switch> <Switch>
<Redirect exact <Redirect exact
from={'/passport'} from={'/passport'}
to={{...location, ...{pathname: '/passport/account-login'}}} to={{...location, ...{pathname: '/passport/login'}}}
/> />
<Route path={match.url + '/wechat-login'} <Route path={match.url + '/login'}
render={() => <WechatLogin loginWays={this.state.loginWays}/>}/> render={props => <Login {...props} loginWays={this.state.loginWays}/>}/>
<Route path={match.url + '/account-login'} component={AccountLogin}/> <Route path={match.url + '/account-login'} component={AccountLogin}/>
<Route path={match.url + '/forgot-password'} component={ForgotPassword}/> <Route path={match.url + '/forgot-password'} component={ForgotPassword}/>
<Route path={match.url + '/set-password'} component={SetPassword}/> <Route path={match.url + '/set-password'} component={SetPassword}/>
......
import React, { PureComponent } from 'react' import React, { Component } from 'react'
import './wechatLogin.scss' import './wechatLogin.scss'
import Input from "../common/Input" import Input from "../common/Input"
import LoginButton from '../common/LoginButton' import LoginButton from '../common/LoginButton'
import LoginWays from '../common/LoginWays' import LoginWays from '../common/LoginWays'
import Header from '../common/Header' import Header from '../common/Header'
import VeriCodeInput from '../common/veriCodeInput' 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() { render() {
const { const {
loginWays, loginWays,
errors,
values
} = this.props } = this.props
return ( return (
<div className='login'> <div className='login'>
<Header/> <Header/>
<Form className="login-info"> <Form className="login-info">
<FastField <Field
name='tel' name='tel'
render={({field}) => ( render={({field}) => (
<Input <Input
...@@ -32,25 +68,35 @@ class WechatLogin extends PureComponent { ...@@ -32,25 +68,35 @@ class WechatLogin extends PureComponent {
/> />
)} )}
> >
</FastField> </Field>
<FastField {
type='number' this.state.validate &&
name='veriCode' <Field
render={({field}) => ( type='number'
<VeriCodeInput name='veriCode'
{...field} render={({field}) => (
className={'verification'} <VeriCodeInput
icon={<i className={'iconfont iconduanxin'} {...field}
style={{fontSize: '20px', left: '12px'}} className={'verification'}
/>} icon={<i className={'iconfont iconduanxin'}
placeholder={'请输入验证码'} 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> </Form>
<LoginWays onClick={this.selectLoginWays} loginWays={loginWays}/> <LoginWays onClick={this.loginWaysClick} loginWays={loginWays}/>
</div> </div>
) )
} }
...@@ -61,17 +107,37 @@ const FormikConfig = { ...@@ -61,17 +107,37 @@ const FormikConfig = {
tel: '', tel: '',
veriCode: '' veriCode: ''
}), }),
handleSubmit(values, {setError}) { handleSubmit(values, {props}) {
console.log(values) 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, validateOnChange: true,
/*validate: (values) => { validate: (values) => {
let errors = {} let errors = {}
if (!/^1[3-9](\d{9})$/.test(values.tel)) { if (!/^1[3-9](\d{9})$/.test(values.tel)) {
errors.tel = '手机号不正确' errors.tel = '请填写正确格式的手机号'
}
if (!/[0-9]{6}/.test(values.veriCode)) {
errors.veriCode = '请输入验证码'
} }
return errors return errors
}*/ }
} }
export default withFormik(FormikConfig)(WechatLogin) export default compose(
\ No newline at end of file connect(
null,
{quickLogin}
),
withFormik(FormikConfig),
)(WechatLogin)
\ No newline at end of file
...@@ -9,32 +9,37 @@ const accountLogin = user => dispatch => { ...@@ -9,32 +9,37 @@ const accountLogin = user => dispatch => {
password: encrypt(user.password), password: encrypt(user.password),
is_encrypt: 1 is_encrypt: 1
}).then(res => { }).then(res => {
const data = res.data return storeUser(res, dispatch)
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 quickLogin = user => dispatch => {
const CAPTCHA_LOGIN = 'CAPTCHA_LOGIN' return http.post(`${api['passport-api']}/quick_login`, user)
const captchaLogin = payload => dispatch => { .then(res => {
return http.post(`${api['passport-api']}/`) 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' const SET_CURRENT_USER = 'SET_CURRENT_USER'
...@@ -55,5 +60,6 @@ const logout = () => dispatch => { ...@@ -55,5 +60,6 @@ const logout = () => dispatch => {
export { export {
accountLogin, accountLogin,
SET_CURRENT_USER, SET_CURRENT_USER,
setCurrentUser setCurrentUser,
quickLogin
} }
\ No newline at end of file
export {default as http} from './http' export { default as http } from './http'
export {default as api} from './api' export { default as api } from './api'
export {html} export { html, initCaptcha }
export const getParam = (key, str) => { export const getParam = (key, str) => {
...@@ -19,7 +19,49 @@ const htmlDecode = content => { ...@@ -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 = () => { export const is_weixin = () => {
var ua = window.navigator.userAgent.toLowerCase(); var ua = window.navigator.userAgent.toLowerCase();
if (ua.match(/MicroMessenger/i) == 'micromessenger') { 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