✨ Feat: [前台]:登陆,注册重置密码完成
This commit is contained in:
parent
58e43d0f39
commit
b32c50e8f5
@ -1,9 +1,9 @@
|
|||||||
{
|
{
|
||||||
"name": "chat-room",
|
"name": "bookmark-world",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"homepage": ".",
|
"homepage": ".",
|
||||||
"proxy": "http://ali.tapme.top:8081/mock/16/chat/api/",
|
"proxy": "http://10.82.17.56:8088/bookmark/api",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"antd": "^3.19.8",
|
"antd": "^3.19.8",
|
||||||
"axios": "^0.19.0",
|
"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 { withRouter } from "react-router-dom";
|
||||||
import { Provider } from "react-redux";
|
import { Provider } from "react-redux";
|
||||||
import store from "./redux";
|
import store from "./redux";
|
||||||
import Main from "./pages/index";
|
|
||||||
import NotFound from "./pages/public/notFound/NotFound";
|
import NotFound from "./pages/public/notFound/NotFound";
|
||||||
|
|
||||||
import Login from "./pages/public/Login";
|
import Login from "./pages/public/Login";
|
||||||
import RegisterOrReset from "./pages/public/RegisterOrReset";
|
import RegisterOrReset from "./pages/public/RegisterOrReset";
|
||||||
|
|
||||||
|
import ManageOverview from "./pages/manage/OverView";
|
||||||
|
|
||||||
class App extends Component {
|
class App extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
@ -23,7 +24,10 @@ class App extends Component {
|
|||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<div className="fullScreen" style={mainStyle}>
|
<div className="fullScreen" style={mainStyle}>
|
||||||
<Switch>
|
<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/login" component={Login} />
|
||||||
<Route exact path="/public/register" component={RegisterOrReset} />
|
<Route exact path="/public/register" component={RegisterOrReset} />
|
||||||
<Route exact path="/public/resetPassword" component={RegisterOrReset} />
|
<Route exact path="/public/resetPassword" component={RegisterOrReset} />
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Icon } from "antd";
|
import { Icon } from "antd";
|
||||||
|
|
||||||
const IconFont = Icon.createFromIconfontCN({
|
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 React from "react";
|
||||||
import styles from "./index.module.less";
|
import styles from "./index.module.less";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
@ -29,7 +32,9 @@ const LoginOrRegister = ({ type }) => {
|
|||||||
export function LoginLayout({ type, children }) {
|
export function LoginLayout({ type, children }) {
|
||||||
return (
|
return (
|
||||||
<div className={"fullScreen " + styles.main}>
|
<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}>
|
<div className={styles.content}>
|
||||||
{type === RESET_PASSWORD_TYPE ? <div style={{ fontSize: "0.3rem" }}>重置密码</div> : <LoginOrRegister type={type} />}
|
{type === RESET_PASSWORD_TYPE ? <div style={{ fontSize: "0.3rem" }}>重置密码</div> : <LoginOrRegister type={type} />}
|
||||||
{children}
|
{children}
|
||||||
|
@ -13,9 +13,10 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
left: 5%;
|
left: 5%;
|
||||||
top: 5%;
|
top: 5%;
|
||||||
font-size: 4em;
|
|
||||||
font-weight: 700;
|
img {
|
||||||
color: #1890ff;
|
width: 2rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.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) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
email: "",
|
str: "",
|
||||||
password: "",
|
password: "",
|
||||||
rememberMe: false
|
rememberMe: false
|
||||||
};
|
};
|
||||||
@ -35,28 +35,51 @@ class Login extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
submit = () => {
|
submit = () => {
|
||||||
axios.post("/public/login", this.state).then(res => {
|
axios
|
||||||
localStorage.setItem("token", res.token);
|
.post("/user/login", this.state)
|
||||||
localStorage.setItem("userInfo", JSON.stringify(res.userInfo));
|
.then(res => {
|
||||||
window.token = res.token;
|
const token = res.token;
|
||||||
window.userInfo = res.userInfo;
|
delete res.token;
|
||||||
|
localStorage.setItem("token", token);
|
||||||
|
localStorage.setItem("userInfo", JSON.stringify(res));
|
||||||
|
window.token = token;
|
||||||
|
window.userInfo = res;
|
||||||
message.success("登录成功");
|
message.success("登录成功");
|
||||||
this.props.updateLoginInfo(res.token, res.userInfo);
|
this.props.updateLoginInfo(token, res);
|
||||||
if (this.query.redirect) {
|
if (this.query.redirect) {
|
||||||
this.props.history.replace(decodeURIComponent(this.query.redirect));
|
this.props.history.replace(decodeURIComponent(this.query.redirect));
|
||||||
} else {
|
} else {
|
||||||
this.props.history.replace("/");
|
this.props.history.replace("/");
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
message.error(error);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { email, password, rememberMe } = this.state;
|
const { str, password, rememberMe } = this.state;
|
||||||
return (
|
return (
|
||||||
<LoginLayout type={LOGIN_TYPE}>
|
<LoginLayout type={LOGIN_TYPE}>
|
||||||
<div className={styles.main}>
|
<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
|
||||||
<Input type="text" size="large" name="password" value={password} onChange={this.valueChange} addonBefore={<IconFont type="icon-password" style={{ fontSize: "0.3rem" }} />} placeholder="密码" />
|
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}>
|
<div className={styles.action}>
|
||||||
<Checkbox value={rememberMe} name="rememberMe" onChange={this.valueChange}>
|
<Checkbox value={rememberMe} name="rememberMe" onChange={this.valueChange}>
|
||||||
记住我
|
记住我
|
||||||
|
@ -1,53 +1,144 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import IconFont from "../../../components/IconFont";
|
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 { LoginLayout, REGISTER_TYPE, RESET_PASSWORD_TYPE } from "../../../layout/LoginLayout";
|
||||||
import styles from "./index.module.less";
|
import styles from "./index.module.less";
|
||||||
import { Link } from "react-router-dom";
|
|
||||||
import axios from "../../../util/httpUtil";
|
import axios from "../../../util/httpUtil";
|
||||||
|
|
||||||
export default class Register extends React.Component {
|
export default class Register extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
console.log(props);
|
||||||
let type = props.location.pathname.split("/").reverse()[0];
|
let type = props.location.pathname.split("/").reverse()[0];
|
||||||
this.state = {
|
this.state = {
|
||||||
current: type === "register" ? REGISTER_TYPE : RESET_PASSWORD_TYPE,
|
current: type === "register" ? REGISTER_TYPE : RESET_PASSWORD_TYPE,
|
||||||
|
username: "",
|
||||||
email: "",
|
email: "",
|
||||||
password: "",
|
password: "",
|
||||||
repassword: "",
|
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 => {
|
changeData = e => {
|
||||||
this.setState({ [e.target.name]: e.target.value });
|
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() {
|
render() {
|
||||||
const { current, email, password, repassword, code } = this.state;
|
const { current, username, email, password, repassword, authCode, authCodeText, isCountDown } = this.state;
|
||||||
return (
|
return (
|
||||||
<LoginLayout type={current}>
|
<LoginLayout type={current}>
|
||||||
<div className={styles.main}>
|
<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="邮箱" />
|
{current === REGISTER_TYPE ? (
|
||||||
<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
|
<Input
|
||||||
type="text"
|
type="text"
|
||||||
size="large"
|
size="large"
|
||||||
name="code"
|
name="username"
|
||||||
value={code}
|
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="authCode"
|
||||||
|
value={authCode}
|
||||||
onChange={this.changeData}
|
onChange={this.changeData}
|
||||||
addonBefore={<IconFont type="icon-yanzhengma54" style={{ fontSize: "0.3rem" }} />}
|
addonBefore={<IconFont type="icon-yanzhengma54" style={{ fontSize: "0.3rem" }} />}
|
||||||
addonAfter={
|
addonAfter={
|
||||||
<span style={{ cursor: "pointer" }} onClick={this.getCode}>
|
<span style={{ cursor: isCountDown ? "" : "pointer" }} onClick={this.getCode}>
|
||||||
获取验证码
|
{authCodeText}
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
placeholder="验证码"
|
placeholder="验证码"
|
||||||
|
@ -1,43 +1,55 @@
|
|||||||
import { notification } from "antd";
|
import { notification } from "antd";
|
||||||
|
import { createBrowserHistory } from "history";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|
||||||
|
const history = createBrowserHistory();
|
||||||
|
|
||||||
//定义http实例
|
//定义http实例
|
||||||
const instance = axios.create({
|
const instance = axios.create({
|
||||||
// baseURL: "http://ali.tapme.top:8081/mock/16/chat/api/",
|
// baseURL: "http://ali.tapme.top:8081/mock/16/chat/api/",
|
||||||
headers: {
|
headers: {
|
||||||
token: window.token
|
"jwt-token": window.token
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//实例添加拦截器
|
//实例添加拦截器
|
||||||
instance.interceptors.response.use(
|
instance.interceptors.response.use(
|
||||||
function(res) {
|
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) {
|
function(error) {
|
||||||
console.log(error);
|
showError(error.response);
|
||||||
let message, description;
|
}
|
||||||
if (error.response === undefined) {
|
);
|
||||||
|
|
||||||
|
function showError(response) {
|
||||||
|
let description,
|
||||||
message = "出问题啦";
|
message = "出问题啦";
|
||||||
description = "你的网络有问题";
|
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 {
|
} else {
|
||||||
message = "出问题啦:" + error.response.status;
|
description = "无网络连接";
|
||||||
description = JSON.stringify(error.response.data);
|
|
||||||
//401跳转到登录页面
|
|
||||||
}
|
}
|
||||||
notification.open({
|
notification.open({
|
||||||
message,
|
message,
|
||||||
description,
|
description,
|
||||||
duration: 2
|
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);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
export default instance;
|
export default instance;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user