✨ Feat: [前台]:登陆,注册重置密码完成
This commit is contained in:
parent
58e43d0f39
commit
b32c50e8f5
@ -1,9 +1,9 @@
|
||||
{
|
||||
"name": "chat-room",
|
||||
"name": "bookmark-world",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"homepage": ".",
|
||||
"proxy": "http://ali.tapme.top:8081/mock/16/chat/api/",
|
||||
"proxy": "http://10.82.17.56:8088/bookmark/api",
|
||||
"dependencies": {
|
||||
"antd": "^3.19.8",
|
||||
"axios": "^0.19.0",
|
||||
|
BIN
front/public/img/bookmarkLogo.png
Normal file
BIN
front/public/img/bookmarkLogo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.3 KiB |
@ -3,12 +3,13 @@ import { Route, Switch, Redirect } from "react-router-dom";
|
||||
import { withRouter } from "react-router-dom";
|
||||
import { Provider } from "react-redux";
|
||||
import store from "./redux";
|
||||
import Main from "./pages/index";
|
||||
import NotFound from "./pages/public/notFound/NotFound";
|
||||
|
||||
import Login from "./pages/public/Login";
|
||||
import RegisterOrReset from "./pages/public/RegisterOrReset";
|
||||
|
||||
import ManageOverview from "./pages/manage/OverView";
|
||||
|
||||
class App extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
@ -23,7 +24,10 @@ class App extends Component {
|
||||
<Provider store={store}>
|
||||
<div className="fullScreen" style={mainStyle}>
|
||||
<Switch>
|
||||
<Route exact path="/" component={Main} />
|
||||
<Redirect exact path="/" to="/manage/overview" />
|
||||
<Route exact path="/manage/overview" component={ManageOverview} />
|
||||
|
||||
{/* 公共页面 */}
|
||||
<Route exact path="/public/login" component={Login} />
|
||||
<Route exact path="/public/register" component={RegisterOrReset} />
|
||||
<Route exact path="/public/resetPassword" component={RegisterOrReset} />
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Icon } from "antd";
|
||||
|
||||
const IconFont = Icon.createFromIconfontCN({
|
||||
scriptUrl: "//at.alicdn.com/t/font_1261825_09wguqxg78th.js"
|
||||
scriptUrl: "//at.alicdn.com/t/font_1261825_snxc2hrpa4o.js"
|
||||
|
||||
});
|
||||
|
||||
|
@ -1,3 +1,6 @@
|
||||
/**
|
||||
* 登陆/注册/重置密码 通用布局
|
||||
*/
|
||||
import React from "react";
|
||||
import styles from "./index.module.less";
|
||||
import { Link } from "react-router-dom";
|
||||
@ -29,7 +32,9 @@ const LoginOrRegister = ({ type }) => {
|
||||
export function LoginLayout({ type, children }) {
|
||||
return (
|
||||
<div className={"fullScreen " + styles.main}>
|
||||
<div className={styles.LOGO}>CR</div>
|
||||
<div className={styles.LOGO}>
|
||||
<img src="/img/bookmarkLogo.png" alt="logo" />
|
||||
</div>
|
||||
<div className={styles.content}>
|
||||
{type === RESET_PASSWORD_TYPE ? <div style={{ fontSize: "0.3rem" }}>重置密码</div> : <LoginOrRegister type={type} />}
|
||||
{children}
|
||||
|
@ -13,9 +13,10 @@
|
||||
position: absolute;
|
||||
left: 5%;
|
||||
top: 5%;
|
||||
font-size: 4em;
|
||||
font-weight: 700;
|
||||
color: #1890ff;
|
||||
|
||||
img {
|
||||
width: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
|
0
front/src/layout/MainLayout/index.jsx
Normal file
0
front/src/layout/MainLayout/index.jsx
Normal file
0
front/src/layout/MainLayout/index.module.less
Normal file
0
front/src/layout/MainLayout/index.module.less
Normal file
12
front/src/pages/manage/OverView/index.jsx
Normal file
12
front/src/pages/manage/OverView/index.jsx
Normal file
@ -0,0 +1,12 @@
|
||||
import React from "react";
|
||||
|
||||
export default class OverView extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {};
|
||||
}
|
||||
|
||||
render() {
|
||||
return <div>主界面</div>;
|
||||
}
|
||||
}
|
0
front/src/pages/manage/OverView/index.module.less
Normal file
0
front/src/pages/manage/OverView/index.module.less
Normal file
@ -23,7 +23,7 @@ class Login extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
email: "",
|
||||
str: "",
|
||||
password: "",
|
||||
rememberMe: false
|
||||
};
|
||||
@ -35,28 +35,51 @@ class Login extends Component {
|
||||
};
|
||||
|
||||
submit = () => {
|
||||
axios.post("/public/login", this.state).then(res => {
|
||||
localStorage.setItem("token", res.token);
|
||||
localStorage.setItem("userInfo", JSON.stringify(res.userInfo));
|
||||
window.token = res.token;
|
||||
window.userInfo = res.userInfo;
|
||||
message.success("登录成功");
|
||||
this.props.updateLoginInfo(res.token, res.userInfo);
|
||||
if (this.query.redirect) {
|
||||
this.props.history.replace(decodeURIComponent(this.query.redirect));
|
||||
} else {
|
||||
this.props.history.replace("/");
|
||||
}
|
||||
});
|
||||
axios
|
||||
.post("/user/login", this.state)
|
||||
.then(res => {
|
||||
const token = res.token;
|
||||
delete res.token;
|
||||
localStorage.setItem("token", token);
|
||||
localStorage.setItem("userInfo", JSON.stringify(res));
|
||||
window.token = token;
|
||||
window.userInfo = res;
|
||||
message.success("登录成功");
|
||||
this.props.updateLoginInfo(token, res);
|
||||
if (this.query.redirect) {
|
||||
this.props.history.replace(decodeURIComponent(this.query.redirect));
|
||||
} else {
|
||||
this.props.history.replace("/");
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
message.error(error);
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { email, password, rememberMe } = this.state;
|
||||
const { str, password, rememberMe } = this.state;
|
||||
return (
|
||||
<LoginLayout type={LOGIN_TYPE}>
|
||||
<div className={styles.main}>
|
||||
<Input type="text" size="large" name="email" value={email} onChange={this.valueChange} addonBefore={<IconFont type="icon-mail" style={{ fontSize: "0.3rem" }} />} placeholder="邮箱" />
|
||||
<Input type="text" size="large" name="password" value={password} onChange={this.valueChange} addonBefore={<IconFont type="icon-password" style={{ fontSize: "0.3rem" }} />} placeholder="密码" />
|
||||
<Input
|
||||
type="text"
|
||||
size="large"
|
||||
name="str"
|
||||
value={str}
|
||||
onChange={this.valueChange}
|
||||
addonBefore={<IconFont type="icon-mail" style={{ fontSize: "0.3rem" }} />}
|
||||
placeholder="邮箱或者用户名"
|
||||
/>
|
||||
<Input.Password
|
||||
type="password"
|
||||
size="large"
|
||||
name="password"
|
||||
value={password}
|
||||
onChange={this.valueChange}
|
||||
addonBefore={<IconFont type="icon-password" style={{ fontSize: "0.3rem" }} />}
|
||||
placeholder="密码"
|
||||
/>
|
||||
<div className={styles.action}>
|
||||
<Checkbox value={rememberMe} name="rememberMe" onChange={this.valueChange}>
|
||||
记住我
|
||||
|
@ -1,53 +1,144 @@
|
||||
import React from "react";
|
||||
import IconFont from "../../../components/IconFont";
|
||||
import { Button, Input, Checkbox } from "antd";
|
||||
import { Button, Input, message } from "antd";
|
||||
import { LoginLayout, REGISTER_TYPE, RESET_PASSWORD_TYPE } from "../../../layout/LoginLayout";
|
||||
import styles from "./index.module.less";
|
||||
import { Link } from "react-router-dom";
|
||||
import axios from "../../../util/httpUtil";
|
||||
|
||||
export default class Register extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
console.log(props);
|
||||
let type = props.location.pathname.split("/").reverse()[0];
|
||||
this.state = {
|
||||
current: type === "register" ? REGISTER_TYPE : RESET_PASSWORD_TYPE,
|
||||
username: "",
|
||||
email: "",
|
||||
password: "",
|
||||
repassword: "",
|
||||
code: ""
|
||||
authCode: "",
|
||||
authCodeText: "获取验证码",
|
||||
isCountDown: false
|
||||
};
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.timer != null) {
|
||||
clearInterval(this.timer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取验证码
|
||||
*/
|
||||
getCode = () => {};
|
||||
getCode = () => {
|
||||
if (this.state.isCountDown) {
|
||||
return;
|
||||
}
|
||||
axios.get("/user/authCode?email=" + this.state.email).then(() => {
|
||||
message.success("发送成功,请注意查收(检查垃圾箱)");
|
||||
let count = 60;
|
||||
this.setState({ authCodeText: `${count}s后重试`, isCountDown: true });
|
||||
this.timer = setInterval(() => {
|
||||
count--;
|
||||
if (count === 0) {
|
||||
this.setState({ isCountDown: false, authCodeText: "获取验证码" });
|
||||
clearInterval(this.timer);
|
||||
return;
|
||||
}
|
||||
this.setState({ authCodeText: `${count}s后重试` });
|
||||
}, 1000);
|
||||
});
|
||||
};
|
||||
|
||||
changeData = e => {
|
||||
this.setState({ [e.target.name]: e.target.value });
|
||||
};
|
||||
|
||||
submit = () => {};
|
||||
/**
|
||||
* 提交表单
|
||||
*/
|
||||
submit = () => {
|
||||
const { current, username, email, password, repassword, authCode } = this.state;
|
||||
if (password !== repassword) {
|
||||
message.error("两次密码不一致");
|
||||
return;
|
||||
}
|
||||
let form = { username, email, password, authCode };
|
||||
if (current === REGISTER_TYPE) {
|
||||
axios
|
||||
.put("/user", form)
|
||||
.then(() => {
|
||||
message.success("注册成功");
|
||||
setTimeout(() => this.props.history.replace("/public/login"), 500);
|
||||
})
|
||||
.catch(error => message.error(error));
|
||||
} else {
|
||||
delete form.username;
|
||||
axios
|
||||
.post("/user/resetPassword", form)
|
||||
.then(() => {
|
||||
message.success("操作成功");
|
||||
console.log(this.location);
|
||||
setTimeout(() => this.props.history.replace("/public/login"), 500);
|
||||
})
|
||||
.catch(error => message.error(error));
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { current, email, password, repassword, code } = this.state;
|
||||
const { current, username, email, password, repassword, authCode, authCodeText, isCountDown } = this.state;
|
||||
return (
|
||||
<LoginLayout type={current}>
|
||||
<div className={styles.main}>
|
||||
<Input type="text" size="large" name="email" value={email} onChange={this.changeData} addonBefore={<IconFont type="icon-mail" style={{ fontSize: "0.3rem" }} />} placeholder="邮箱" />
|
||||
<Input type="password" size="large" name="password" value={password} onChange={this.changeData} addonBefore={<IconFont type="icon-password" style={{ fontSize: "0.3rem" }} />} placeholder="密码" />
|
||||
<Input type="password" size="large" name="repassword" value={repassword} onChange={this.changeData} addonBefore={<IconFont type="icon-password" style={{ fontSize: "0.3rem" }} />} placeholder="重复密码" />
|
||||
{current === REGISTER_TYPE ? (
|
||||
<Input
|
||||
type="text"
|
||||
size="large"
|
||||
name="username"
|
||||
value={username}
|
||||
onChange={this.changeData}
|
||||
addonBefore={<IconFont type="icon-person" style={{ fontSize: "0.3rem" }} />}
|
||||
placeholder="用户名"
|
||||
/>
|
||||
) : null}
|
||||
<Input
|
||||
type="email"
|
||||
size="large"
|
||||
name="email"
|
||||
value={email}
|
||||
onChange={this.changeData}
|
||||
addonBefore={<IconFont type="icon-mail" style={{ fontSize: "0.3rem" }} />}
|
||||
placeholder="邮箱"
|
||||
/>
|
||||
<Input
|
||||
type="password"
|
||||
size="large"
|
||||
name="password"
|
||||
value={password}
|
||||
onChange={this.changeData}
|
||||
addonBefore={<IconFont type="icon-password" style={{ fontSize: "0.3rem" }} />}
|
||||
placeholder="密码"
|
||||
/>
|
||||
<Input
|
||||
type="password"
|
||||
size="large"
|
||||
name="repassword"
|
||||
value={repassword}
|
||||
onChange={this.changeData}
|
||||
addonBefore={<IconFont type="icon-password" style={{ fontSize: "0.3rem" }} />}
|
||||
placeholder="重复密码"
|
||||
/>
|
||||
<Input
|
||||
type="text"
|
||||
size="large"
|
||||
name="code"
|
||||
value={code}
|
||||
name="authCode"
|
||||
value={authCode}
|
||||
onChange={this.changeData}
|
||||
addonBefore={<IconFont type="icon-yanzhengma54" style={{ fontSize: "0.3rem" }} />}
|
||||
addonAfter={
|
||||
<span style={{ cursor: "pointer" }} onClick={this.getCode}>
|
||||
获取验证码
|
||||
<span style={{ cursor: isCountDown ? "" : "pointer" }} onClick={this.getCode}>
|
||||
{authCodeText}
|
||||
</span>
|
||||
}
|
||||
placeholder="验证码"
|
||||
|
@ -1,43 +1,55 @@
|
||||
import { notification } from "antd";
|
||||
import { createBrowserHistory } from "history";
|
||||
import axios from "axios";
|
||||
|
||||
const history = createBrowserHistory();
|
||||
|
||||
//定义http实例
|
||||
const instance = axios.create({
|
||||
// baseURL: "http://ali.tapme.top:8081/mock/16/chat/api/",
|
||||
headers: {
|
||||
token: window.token
|
||||
"jwt-token": window.token
|
||||
}
|
||||
});
|
||||
|
||||
//实例添加拦截器
|
||||
instance.interceptors.response.use(
|
||||
function(res) {
|
||||
return res.data;
|
||||
console.log(res);
|
||||
const data = res.data;
|
||||
if (data.code === 1) {
|
||||
return data.data;
|
||||
} else if (data.code === -2) {
|
||||
return Promise.reject(data.message);
|
||||
} else {
|
||||
showError(data);
|
||||
return Promise.reject(data.message);
|
||||
}
|
||||
},
|
||||
function(error) {
|
||||
console.log(error);
|
||||
let message, description;
|
||||
if (error.response === undefined) {
|
||||
message = "出问题啦";
|
||||
description = "你的网络有问题";
|
||||
} else {
|
||||
message = "出问题啦:" + error.response.status;
|
||||
description = JSON.stringify(error.response.data);
|
||||
//401跳转到登录页面
|
||||
}
|
||||
notification.open({
|
||||
message,
|
||||
description,
|
||||
duration: 2
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (error.response && error.response.status === 401) {
|
||||
let redirect = encodeURIComponent(window.location.pathname + window.location.search);
|
||||
window.location.replace("/public/login?redirect=" + redirect);
|
||||
}
|
||||
}, 1000);
|
||||
return Promise.reject(error);
|
||||
showError(error.response);
|
||||
}
|
||||
);
|
||||
|
||||
function showError(response) {
|
||||
let description,
|
||||
message = "出问题啦";
|
||||
if (response) {
|
||||
description = response.message;
|
||||
if (response.code === -1) {
|
||||
setTimeout(() => {
|
||||
let redirect = encodeURIComponent(window.location.pathname + window.location.search);
|
||||
history.replace("/public/login?redirect=" + redirect);
|
||||
}, 1000);
|
||||
}
|
||||
} else {
|
||||
description = "无网络连接";
|
||||
}
|
||||
notification.open({
|
||||
message,
|
||||
description,
|
||||
duration: 2
|
||||
});
|
||||
}
|
||||
|
||||
export default instance;
|
||||
|
Loading…
x
Reference in New Issue
Block a user