同意{"<<服务条款>>"}和
@@ -55,6 +61,6 @@ const LoginForm = ({ history, jumpToLogin }) => {
);
-};
+});
-export default withRouter(LoginForm);
+export default LoginForm;
diff --git a/src/application/User/Login/components/LoginForm/style.js b/src/application/User/Login/components/LoginForm/style.js
index 06cb146..ee7cd8e 100644
--- a/src/application/User/Login/components/LoginForm/style.js
+++ b/src/application/User/Login/components/LoginForm/style.js
@@ -61,6 +61,216 @@ export const BeautyCheckBox = styled.ul`
a {
color: #d79088;
}
+
+ &.shake-horizontal {
+ animation-name: shake-horizontal;
+ animation-duration: 400ms;
+ animation-timing-function: ease-in-out;
+ animation-iteration-count: 5s;
+ animation-play-state: running;
+ }
+ @keyframes shake-horizontal {
+ 2% {
+ transform: translate(-5px, 0) rotate(0);
+ }
+
+ 4% {
+ transform: translate(8px, 0) rotate(0);
+ }
+
+ 6% {
+ transform: translate(8px, 0) rotate(0);
+ }
+
+ 8% {
+ transform: translate(9px, 0) rotate(0);
+ }
+
+ 10% {
+ transform: translate(-7px, 0) rotate(0);
+ }
+
+ 12% {
+ transform: translate(1px, 0) rotate(0);
+ }
+
+ 14% {
+ transform: translate(-4px, 0) rotate(0);
+ }
+
+ 16% {
+ transform: translate(7px, 0) rotate(0);
+ }
+
+ 18% {
+ transform: translate(8px, 0) rotate(0);
+ }
+
+ 20% {
+ transform: translate(-7px, 0) rotate(0);
+ }
+
+ 22% {
+ transform: translate(9px, 0) rotate(0);
+ }
+
+ 24% {
+ transform: translate(8px, 0) rotate(0);
+ }
+
+ 26% {
+ transform: translate(-2px, 0) rotate(0);
+ }
+
+ 28% {
+ transform: translate(5px, 0) rotate(0);
+ }
+
+ 30% {
+ transform: translate(6px, 0) rotate(0);
+ }
+
+ 32% {
+ transform: translate(4px, 0) rotate(0);
+ }
+
+ 34% {
+ transform: translate(3px, 0) rotate(0);
+ }
+
+ 36% {
+ transform: translate(7px, 0) rotate(0);
+ }
+
+ 38% {
+ transform: translate(-1px, 0) rotate(0);
+ }
+
+ 40% {
+ transform: translate(3px, 0) rotate(0);
+ }
+
+ 42% {
+ transform: translate(10px, 0) rotate(0);
+ }
+
+ 44% {
+ transform: translate(3px, 0) rotate(0);
+ }
+
+ 46% {
+ transform: translate(-9px, 0) rotate(0);
+ }
+
+ 48% {
+ transform: translate(6px, 0) rotate(0);
+ }
+
+ 50% {
+ transform: translate(-8px, 0) rotate(0);
+ }
+
+ 52% {
+ transform: translate(6px, 0) rotate(0);
+ }
+
+ 54% {
+ transform: translate(1px, 0) rotate(0);
+ }
+
+ 56% {
+ transform: translate(5px, 0) rotate(0);
+ }
+
+ 58% {
+ transform: translate(-4px, 0) rotate(0);
+ }
+
+ 60% {
+ transform: translate(3px, 0) rotate(0);
+ }
+
+ 62% {
+ transform: translate(-5px, 0) rotate(0);
+ }
+
+ 64% {
+ transform: translate(7px, 0) rotate(0);
+ }
+
+ 66% {
+ transform: translate(-8px, 0) rotate(0);
+ }
+
+ 68% {
+ transform: translate(-2px, 0) rotate(0);
+ }
+
+ 70% {
+ transform: translate(-5px, 0) rotate(0);
+ }
+
+ 72% {
+ transform: translate(1px, 0) rotate(0);
+ }
+
+ 74% {
+ transform: translate(1px, 0) rotate(0);
+ }
+
+ 76% {
+ transform: translate(-9px, 0) rotate(0);
+ }
+
+ 78% {
+ transform: translate(6px, 0) rotate(0);
+ }
+
+ 80% {
+ transform: translate(8px, 0) rotate(0);
+ }
+
+ 82% {
+ transform: translate(10px, 0) rotate(0);
+ }
+
+ 84% {
+ transform: translate(-6px, 0) rotate(0);
+ }
+
+ 86% {
+ transform: translate(-1px, 0) rotate(0);
+ }
+
+ 88% {
+ transform: translate(5px, 0) rotate(0);
+ }
+
+ 90% {
+ transform: translate(-1px, 0) rotate(0);
+ }
+
+ 92% {
+ transform: translate(7px, 0) rotate(0);
+ }
+
+ 94% {
+ transform: translate(-3px, 0) rotate(0);
+ }
+
+ 96% {
+ transform: translate(-7px, 0) rotate(0);
+ }
+
+ 98% {
+ transform: translate(-4px, 0) rotate(0);
+ }
+
+ 0%,
+ 100% {
+ transform: translate(0, 0) rotate(0);
+ }
+ }
`;
export const OtherLoginLink = styled.div`
diff --git a/src/application/User/Login/components/PhoneForm/index.js b/src/application/User/Login/components/PhoneForm/index.js
index 2174cdf..6bdd9ec 100644
--- a/src/application/User/Login/components/PhoneForm/index.js
+++ b/src/application/User/Login/components/PhoneForm/index.js
@@ -1,4 +1,4 @@
-import React, { useState } from "react";
+import React, { useState, useCallback } from "react";
import { Header, Container } from "./style";
import { trimPhone } from "../../../../../api/utils";
import StepOne from "./step-one";
@@ -9,12 +9,15 @@ const PhoneForm = props => {
const [phone, setPhone] = useState("");
//验证码触发登录操作
- const triggerLogin = vcode => {
- loginByVcode(trimPhone(phone), vcode);
- };
+ const triggerLogin = useCallback(
+ vcode => {
+ loginByVcode(trimPhone(phone), vcode);
+ },
+ [phone, loginByVcode]
+ );
//切换手机号码和验证码表单
- const onClickNext = () => {
+ const triggerSentVcode = () => {
sentVcode(trimPhone(phone));
};
@@ -46,11 +49,15 @@ const PhoneForm = props => {
{!sentStatus ? (
) : (
-
+
)}
);
diff --git a/src/application/User/Login/components/PhoneForm/step-one/index.js b/src/application/User/Login/components/PhoneForm/step-one/index.js
index 68d6819..a132a33 100644
--- a/src/application/User/Login/components/PhoneForm/step-one/index.js
+++ b/src/application/User/Login/components/PhoneForm/step-one/index.js
@@ -6,7 +6,7 @@ const StepOne = props => {
const inputRef = useRef();
useEffect(() => {
inputRef.current.focus();
- }, []);
+ });
return (
<>
diff --git a/src/application/User/Login/components/PhoneForm/step-two/index.js b/src/application/User/Login/components/PhoneForm/step-two/index.js
index e00c82c..899d9b6 100644
--- a/src/application/User/Login/components/PhoneForm/step-two/index.js
+++ b/src/application/User/Login/components/PhoneForm/step-two/index.js
@@ -2,41 +2,45 @@ import React, { useState, useRef, useEffect } from "react";
import { VcodeBox, Container } from "./style";
const maxLength = 4;
+const sentPeriod = 60;
+let theTimer;
const StepTwo = props => {
- const { phone, triggerLogin } = props;
- const [triggered, setTriggered] = useState(false);
+ const { phone, triggerLogin, reSentVcode } = props;
const [cursorIndex, setCursorIndex] = useState(0);
const [vcode, setVcode] = useState("");
- const [timer, setTimer] = useState(60);
+ const [timer, setTimer] = useState(sentPeriod);
const inputRef = useRef();
-
useEffect(() => {
- let theTimer;
- if (!theTimer) {
- theTimer = setInterval(() => {
- setTimer(timer => timer - 1);
- if(timer <= 0) clearTimeout(theTimer);
- }, 1000);
+ inputRef.current.focus();
+ if (timer === 0) {
+ clearInterval(theTimer);
+ }
+ if (timer !== sentPeriod) {
+ return;
}
- return () => {
- clearTimeout(theTimer);
- };
+ theTimer = setInterval(() => {
+ setTimer(timer => timer - 1);
+ }, 1000);
}, [timer]);
useEffect(() => {
- if (vcode.length === 4 && !triggered) {
+ if (vcode.length === 4) {
triggerLogin(vcode);
- setTriggered(true);
}
- }, [vcode, triggerLogin, triggered]);
+ }, [vcode, triggerLogin]);
const onChangeVcode = e => {
- if(!e.target.value) return;
+ if (!e.target.value) return;
const val = e.target.value;
setVcode(val);
setCursorIndex(val.split("").length);
};
+ const onClickSentVcode = () => {
+ reSentVcode();
+ setTimer(sentPeriod);
+ };
+
return (
验证码已发送至
@@ -44,7 +48,13 @@ const StepTwo = props => {
{phone.replace(/(\d{3})\s(\d{4})\s(\d{4})/g, "+86 $1 **** $3")}
- {timer}S
+ {timer ? (
+ {timer}S
+ ) : (
+
+ 重新发送
+
+ )}
验证码:
diff --git a/src/application/User/Login/components/PhoneForm/step-two/style.js b/src/application/User/Login/components/PhoneForm/step-two/style.js
index 9450fbd..bf7091a 100644
--- a/src/application/User/Login/components/PhoneForm/step-two/style.js
+++ b/src/application/User/Login/components/PhoneForm/step-two/style.js
@@ -12,6 +12,9 @@ export const Container = styled.div`
padding: 0 25px;
margin-top: 10px;
justify-content: space-between;
+ .sentBtn {
+ color: #0066cc;
+ }
}
`;
export const VcodeBox = styled.div`
@@ -37,7 +40,7 @@ export const VcodeBox = styled.div`
.v-code input {
position: absolute;
top: -100%;
- left: -666666px;
+ left: -100%;
opacity: 0;
}
.v-code .line {
diff --git a/src/application/User/Login/index.js b/src/application/User/Login/index.js
index 32e3d66..d200d76 100644
--- a/src/application/User/Login/index.js
+++ b/src/application/User/Login/index.js
@@ -1,5 +1,6 @@
-import React, { useState } from "react";
+import React, { useState, useRef, useEffect } from "react";
import { Container, LogoImg, LogoContainer, LoginContainer } from "./style";
+import { withRouter } from "react-router-dom";
import * as actionCreators from "./store/actionCreators";
import LoginForm from "./components/LoginForm";
import PhoneForm from "./components/PhoneForm";
@@ -8,16 +9,46 @@ import { CSSTransition } from "react-transition-group";
import { connect } from "react-redux";
const Login = props => {
- const { LoginByVcodeDispatch, sentVcodeDispatch, sentStatus } = props;
+ const {
+ LoginByVcodeDispatch,
+ sentVcodeDispatch,
+ sentStatus,
+ loginStatus,
+ changeSentStatusDispatch,
+ history
+ } = props;
const [inPhone, setInPhone] = useState(false);
+ const [agreed, setAgreed] = useState(false);
+ const checkBoxRef = useRef();
+
+ useEffect(() => {
+ if (loginStatus) {
+ history.push("/recommend");
+ }
+ }, [loginStatus, history]);
+
+ const jumpToIndex = () => {
+ history.push("/recommend");
+ };
+
const jumpToLogin = method => {
+ if (!agreed) {
+ // alert("请同意条款");
+ checkBoxRef.current.classList.add("shake-horizontal");
+ setTimeout(() => {
+ checkBoxRef.current.classList.remove("shake-horizontal");
+ }, 500);
+ return;
+ }
if (method === "phone") {
setInPhone(true);
}
};
+
const onPhoneBack = () => {
setInPhone(false);
};
+
return (
<>
@@ -27,10 +58,21 @@ const Login = props => {
-
+
-
+ changeSentStatusDispatch()}
+ >
{
// 映射Redux全局的state到组件的props上
const mapStateToProps = state => ({
userInfo: state.getIn(["user", "userInfo"]),
- sentStatus: state.getIn(["user", "sentStatus"])
+ sentStatus: state.getIn(["user", "sentStatus"]),
+ loginStatus: state.getIn(["user", "loginStatus"])
});
// 映射dispatch到props上
const mapDispatchToProps = dispatch => {
@@ -61,6 +104,9 @@ const mapDispatchToProps = dispatch => {
},
sentVcodeDispatch(phone) {
dispatch(actionCreators.sentVcode(phone));
+ },
+ changeSentStatusDispatch() {
+ dispatch(actionCreators.saveSentStatus(false));
}
};
};
@@ -68,4 +114,4 @@ const mapDispatchToProps = dispatch => {
export default connect(
mapStateToProps,
mapDispatchToProps
-)(React.memo(Login));
+)(React.memo(withRouter(Login)));
diff --git a/src/application/User/Login/store/actionCreators.js b/src/application/User/Login/store/actionCreators.js
index fd56a55..3753f5a 100644
--- a/src/application/User/Login/store/actionCreators.js
+++ b/src/application/User/Login/store/actionCreators.js
@@ -3,7 +3,11 @@ import {
sentVcodeRequest,
loginByVcodeRequest
} from "../../../../api/request";
-import { CHANGE_USER_INFO, CHANGE_SENT_STATUS, CHANGE_IS_LOGIN } from "./constants";
+import {
+ CHANGE_USER_INFO,
+ CHANGE_SENT_STATUS,
+ CHANGE_LOGIN_STATUS
+} from "./constants";
export const saveUserInfo = data => ({
type: CHANGE_USER_INFO,
@@ -15,8 +19,8 @@ export const saveSentStatus = data => ({
data
});
-export const changeIslogin = data => ({
- type: CHANGE_IS_LOGIN,
+export const saveLoginStatus = data => ({
+ type: CHANGE_LOGIN_STATUS,
data
});
@@ -36,7 +40,10 @@ export const loginByVcode = (phone, vcode) => {
return dispatch => {
loginByVcodeRequest(phone, vcode)
.then(res => {
- dispatch(saveUserInfo(res));
+ if (res.code === 200) {
+ dispatch(saveUserInfo(res));
+ dispatch(saveLoginStatus(true));
+ }
})
.catch(() => {
console.log("登录失败!");
@@ -56,4 +63,4 @@ export const sentVcode = phone => {
console.log("请求失败!");
});
};
-};
\ No newline at end of file
+};
diff --git a/src/application/User/Login/store/constants.js b/src/application/User/Login/store/constants.js
index 15c446f..33e0559 100644
--- a/src/application/User/Login/store/constants.js
+++ b/src/application/User/Login/store/constants.js
@@ -2,4 +2,4 @@ export const CHANGE_USER_INFO = "user/login/CHANGE_USER_INFO";
export const CHANGE_SENT_STATUS = "user/login/CHANGE_SENT_STATUS";
-export const CHANGE_IS_LOGIN = "user/login/CHANGE_IS_LOGIN";
+export const CHANGE_LOGIN_STATUS = "user/login/CHANGE_LOGIN_STATUS";
diff --git a/src/application/User/Login/store/reducer.js b/src/application/User/Login/store/reducer.js
index 34e0e66..693f585 100644
--- a/src/application/User/Login/store/reducer.js
+++ b/src/application/User/Login/store/reducer.js
@@ -4,7 +4,7 @@ import { fromJS } from "immutable";
const defaultState = fromJS({
userInfo: {},
sentStatus: false,
- isLogin: false
+ loginStatus: false
});
export default (state = defaultState, action) => {
@@ -13,8 +13,8 @@ export default (state = defaultState, action) => {
return state.set("userInfo", action.data);
case actionTypes.CHANGE_SENT_STATUS:
return state.set("sentStatus", action.data);
- case actionTypes.CHANGE_IS_LOGIN:
- return state.set("isLogin", action.data);
+ case actionTypes.CHANGE_LOGIN_STATUS:
+ return state.set("loginStatus", action.data);
default:
return state;
}