Feat: [前端]:修改个人信息功能完成

This commit is contained in:
fanxb 2019-11-17 17:30:35 +08:00
parent 0390308d44
commit df5fb48be0
19 changed files with 600 additions and 78 deletions

View File

@ -0,0 +1 @@
INSERT INTO `bookmark`.`url`(`method`, `url`, `type`) VALUES ('GET', '/baseInfo/verifyEmail', 0);

1
front/.gitignore vendored
View File

@ -24,3 +24,4 @@ yarn-error.log*
.vscode .vscode
yarn.lock yarn.lock
.idea .idea
public/files

View File

@ -6,10 +6,11 @@ import {Provider} from "react-redux";
import ClipboardJS from "clipboard"; import ClipboardJS from "clipboard";
import store from "./redux"; import store from "./redux";
import NotFound from "./pages/public/notFound/NotFound"; import NotFound from "./pages/public/notFound/NotFound";
import UserSpace from './pages/userSpace'; import UserSpace from "./pages/userSpace";
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 EmailVerify from "./pages/public/EmailVerify";
import ManageOverview from "./pages/manage/OverView"; import ManageOverview from "./pages/manage/OverView";
@ -41,7 +42,6 @@ class App extends Component {
<Provider store={store}> <Provider store={store}>
<div className="fullScreen" style={mainStyle}> <div className="fullScreen" style={mainStyle}>
<Switch> <Switch>
{/*书签管理页面*/} {/*书签管理页面*/}
<Redirect exact path="/" to="/manage/overview" /> <Redirect exact path="/" to="/manage/overview" />
<Route exact path="/manage/overview" component={ManageOverview} /> <Route exact path="/manage/overview" component={ManageOverview} />
@ -52,6 +52,7 @@ class App extends Component {
<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} />
<Route exact path="/public/verifyEmail" component={EmailVerify} />
<Route exact path="/404" component={NotFound} /> <Route exact path="/404" component={NotFound} />
{/* 当前面的路由都匹配不到时就会重定向到/404 */} {/* 当前面的路由都匹配不到时就会重定向到/404 */}
<Redirect path="/" to="/404" /> <Redirect path="/" to="/404" />

View File

@ -0,0 +1,31 @@
import React from "react";
import { message, Modal, Input } from "antd";
import http from "../util/httpUtil";
export default class PasswordCheck extends React.Component {
constructor(props) {
super(props);
this.state = {
password: ""
};
}
/**
* 提交
*/
async submit() {
console.log(this.state);
let actionId = await http.post("/user/checkPassword", { password: this.state.password });
this.props.onChange(actionId);
}
render() {
const { visible, onClose } = this.props;
const { password } = this.state;
return (
<Modal title="密码校验" visible={visible} onOk={this.submit.bind(this)} onCancel={onClose}>
<Input.Password placeholder="输入旧密码" value={password} onChange={e => this.setState({ password: e.target.value })} />
</Modal>
);
}
}

View File

@ -1,5 +1,5 @@
import React from "react"; import React from "react";
import { Input, Select } from "antd"; import { Input, Select, Empty } from "antd";
import styles from "./index.module.less"; import styles from "./index.module.less";
import httpUtil from "../../util/httpUtil"; import httpUtil from "../../util/httpUtil";
@ -46,7 +46,7 @@ class Search extends React.Component {
this.timer = setTimeout(() => { this.timer = setTimeout(() => {
this.search(content); this.search(content);
this.clearTimer(); this.clearTimer();
}, 300); }, 200);
} }
clearTimer() { clearTimer() {
@ -119,8 +119,36 @@ class Search extends React.Component {
} }
} }
/**
* 渲染结果列表
*/
renderResults() {
const { resultList, currentIndex, currentOptionIndex, isFocus } = this.state;
if (currentOptionIndex !== 0 || !isFocus) {
return;
}
if (resultList.length > 0) {
return (
<div className={styles.resultList}>
{resultList.map((item, index) => (
<div
className={`${styles.item} ${index === currentIndex ? styles.checked : ""}`}
key={item.bookmarkId}
onClick={() => window.open(item.url)}
>
<span style={{ fontWeight: 600 }}>{item.name}&emsp;</span>
<span style={{ fontSize: "0.8em", fontWeight: 400 }}>{item.url}</span>
</div>
))}
</div>
);
} else {
return <Empty className={styles.resultList} image={Empty.PRESENTED_IMAGE_SIMPLE} />;
}
}
render() { render() {
const { content, resultList, currentIndex, options, currentOptionIndex } = this.state; const { content, options, currentOptionIndex } = this.state;
const prefix = ( const prefix = (
<Select value={options[currentOptionIndex]} onChange={this.valueIndexChange.bind(this)}> <Select value={options[currentOptionIndex]} onChange={this.valueIndexChange.bind(this)}>
{options.map((item, index) => ( {options.map((item, index) => (
@ -143,22 +171,9 @@ class Search extends React.Component {
onChange={this.contentChange.bind(this)} onChange={this.contentChange.bind(this)}
onKeyDown={this.keyUp.bind(this)} onKeyDown={this.keyUp.bind(this)}
onFocus={() => this.setState({ isFocus: true })} onFocus={() => this.setState({ isFocus: true })}
onBlur={() => this.setState({ isFocus: false })} onBlur={() => setTimeout(() => this.setState({ isFocus: false }), 200)}
/> />
{resultList.length > 0 ? ( {this.renderResults()}
<div className={styles.resultList}>
{resultList.map((item, index) => (
<div
className={`${styles.item} ${index === currentIndex ? styles.checked : ""}`}
key={item.bookmarkId}
onClick={() => window.open(item.url)}
>
<span style={{ fontWeight: 600 }}>{item.name}&emsp;</span>
<span style={{ fontSize: "0.8em", fontWeight: 400 }}>{item.url}</span>
</div>
))}
</div>
) : null}
</div> </div>
); );
} }

View File

@ -7,8 +7,10 @@
background: white; background: white;
z-index: 1000; z-index: 1000;
width: 100%; width: 100%;
border: 1px solid black; border: 1px solid #f2f4f5;
border-top: 0; border-top: 0;
padding-top: 1em;
margin: 0;
.item { .item {
cursor: pointer; cursor: pointer;
@ -19,19 +21,6 @@
vertical-align: baseline; vertical-align: baseline;
} }
// .item > span {
// display: inline-block;
// padding-right: 0.5em;
// }
// .item:first-child {
// flex: 1;
// }
// .item:last-child {
// flex: 2;
// }
.item:hover { .item:hover {
background: #f2f4f5; background: #f2f4f5;
} }

View File

@ -1,6 +1,7 @@
body { body {
margin: 0; margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
@ -13,6 +14,7 @@ html,
body { body {
width: 100%; width: 100%;
height: 100%; height: 100%;
background: #f6f6f6;
font-family: "lucida grande", "lucida sans unicode", lucida, helvetica, "Hiragino Sans GB", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif; font-family: "lucida grande", "lucida sans unicode", lucida, helvetica, "Hiragino Sans GB", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif;
} }
.fullScreen { .fullScreen {
@ -32,3 +34,7 @@ body {
.across-center { .across-center {
align-items: center; align-items: center;
} }
.pointer{
cursor: pointer;
}

View File

@ -20,32 +20,37 @@ function mapDispatchToProps(dispatch) {
class MainLayout extends React.Component { class MainLayout extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
console.log(props);
this.state = {}; this.state = {};
} }
componentWillMount() { async componentWillMount() {
httpUtil.get("/user/currentUserInfo").then(res => this.props.changeUserInfo(res)); if (!this.props.username) {
let res = await httpUtil.get("/user/currentUserInfo");
this.props.changeUserInfo(res);
}
} }
renderUserArea() { renderUserArea() {
const { userInfo } = this.props; const { username, icon } = this.props;
const menu = ( const menu = (
<Menu onClick={this.onClick}> <Menu onClick={this.onClick}>
<Menu.Item key="personSpace">个人资料</Menu.Item> <Menu.Item key="personSpace">个人资料</Menu.Item>
<Menu.Item key="logout">退出登陆</Menu.Item> <Menu.Item key="logout">退出登陆</Menu.Item>
</Menu> </Menu>
); );
if (userInfo !== null) { if (username != null) {
return ( return (
<Dropdown overlay={menu} placement="bottomCenter" trigger={["hover", "click"]}> <Dropdown overlay={menu} placement="bottomCenter" trigger={["hover", "click"]}>
<span style={{ cursor: "pointer" }}>{userInfo.username}</span> <span style={{ cursor: "pointer" }}>
<img className={styles.icon} src={icon} alt="icon" />
{username}
</span>
</Dropdown> </Dropdown>
); );
} else { } else {
return ( return (
<div> <div>
<Link to="/public/login">登陆</Link> <Link to="/public/login">登陆</Link>&emsp;
<Link to="/public/register">注册</Link> <Link to="/public/register">注册</Link>
</div> </div>
); );
@ -69,7 +74,7 @@ class MainLayout extends React.Component {
render() { render() {
return ( return (
<div className={"fullScreen " + styles.main}> <div className={styles.main}>
<div className={styles.header}> <div className={styles.header}>
<a href="/"> <a href="/">
<img style={{ width: "1.5rem" }} src="/img/bookmarkLogo.png" alt="logo" /> <img style={{ width: "1.5rem" }} src="/img/bookmarkLogo.png" alt="logo" />
@ -77,15 +82,15 @@ class MainLayout extends React.Component {
{this.renderUserArea()} {this.renderUserArea()}
</div> </div>
<Divider style={{ margin: 0 }} /> <Divider style={{ margin: 0 }} />
<div className={styles.content}>{this.props.children}</div> <div style={{ minHeight: `calc(${document.body.clientHeight}px - 1.45rem)` }} className={styles.content}>
{this.props.children}
</div>
<div className={styles.footer}>
开源地址<a href="https://github.com/FleyX/bookmark">github.com/FleyX/bookmark</a>
</div>
</div> </div>
); );
} }
} }
export default withRouter( export default withRouter(connect(mapStateToProps, mapDispatchToProps)(MainLayout));
connect(
mapStateToProps,
mapDispatchToProps
)(MainLayout)
);

View File

@ -8,7 +8,14 @@
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
padding: 0.1rem 0.5rem; padding: 0.1rem 0.5rem;
height: 0.5rem;
background-color: @mainContentColor; background-color: @mainContentColor;
.icon {
width: 0.4rem;
height: 0.4rem;
border-radius: 50%;
}
} }
.content { .content {
@ -27,4 +34,13 @@
} }
} }
} }
.footer {
text-align: center;
font-size: 1em;
margin-top: 0.1rem;
padding: 0.2rem;
height: 0.6rem;
background: @mainContentColor;
}
} }

View File

@ -0,0 +1,42 @@
import React from "react";
import { Link } from "react-router-dom";
import MainLayout from "../../../layout/MainLayout/index";
import http from "../../../util/httpUtil";
import queryString from "query-string";
const style = {
"text-align": "center",
"padding-top": "200px"
};
class EmailVerify extends React.Component {
constructor(props) {
super(props);
this.state = {
message: "正在校验中,请稍候!"
};
}
async componentDidMount() {
let param = queryString.parseUrl(window.location.href);
try {
await http.get(`baseInfo/verifyEmail?secret=${param.query.key}`);
this.setState({ message: "校验成功,3s后跳转到首页" });
setTimeout(() => {
window.location.href = "/";
}, 3000);
} catch (e) {
this.setState({ message: "校验失败" });
}
}
render() {
return (
<MainLayout>
<div style={{ textAlign: "center" }}>{this.state.message}</div>
</MainLayout>
);
}
}
export default EmailVerify;

View File

@ -0,0 +1,64 @@
import React from "react";
import { message } from "antd";
import styles from "./index.module.less";
import MainLayout from "../../layout/MainLayout";
import { connect } from "react-redux";
import * as action from "../../redux/action/LoginInfoAction";
import httpUtil from "../../util/httpUtil";
function mapStateToProps(state) {
return state[action.DATA_NAME];
}
function mapDispatchToProps(dispatch) {
return {
updateOne: (key, value) => dispatch(action.updateOne(key, value))
};
}
class UserSpace extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
async changeIcon(e) {
let file = e.target.files[0];
if (!file || file.size > 500 * 1024) {
message.error("文件大小请勿超过500KB");
return;
}
let formData = new FormData();
formData.append("file", file);
let res = await httpUtil.post("/user/icon", formData, {
headers: { "Content-Type": "multipart/form-data" }
});
console.log(res);
this.props.updateOne("icon", res);
}
render() {
const { icon, username } = this.props;
return (
<MainLayout>
{/* 头像昵称 */}
<div className={styles.head}>
<div className={styles.icon}>
<img src={icon} alt="icon" className={styles.full} />
<label className={styles.full}>
<input type="file" style={{ display: "none" }} onChange={this.changeIcon.bind(this)} />
<div className={styles.full + " " + styles.changeIcon}>
<span>编辑</span>
</div>
</label>
</div>
<div>{username}</div>
</div>
{/* 个人资料 */}
<div></div>
</MainLayout>
);
}
}
export default connect(mapStateToProps, mapDispatchToProps)(UserSpace);

View File

@ -0,0 +1,41 @@
@import "../../global.less";
.head {
background: @mainContentColor;
padding: 0.1rem;
display: flex;
.icon {
position: relative;
border-radius: 5px;
@media (min-width: 768px) {
width: 150px;
height: 150px;
}
@media (max-width: 768px) {
width: 75px;
height: 75px;
}
.full {
position: absolute;
width: 100%;
height: 100%;
}
.changeIcon {
background-color: transparent;
color: rgba(173, 166, 166, 0);
display: flex;
justify-content: center;
align-items: center;
font-size: 2em;
}
.changeIcon:hover {
// background-color: rbga(173, 166, 166, 1);
background-color: rgba(173, 166, 166, 0.8) !important;
color: white;
}
}
}

View File

@ -0,0 +1,181 @@
import React from "react";
import { message, Button, Tooltip, Input, Form } from "antd";
import styles from "./index.module.less";
import { connect } from "react-redux";
import * as action from "../../../../redux/action/LoginInfoAction";
import httpUtil from "../../../../util/httpUtil";
import PasswordCheck from "../../../../components/PasswordCheck";
function mapStateToProps(state) {
return state[action.DATA_NAME];
}
function mapDispatchToProps(dispatch) {
return {
updateOne: (key, value) => dispatch(action.updateOne(key, value))
};
}
class UserInfo extends React.Component {
constructor(props) {
super(props);
console.log(props);
this.state = {
email: null,
isEmail: false,
username: null,
isUsername: false,
password: "",
repeatPassword: "",
isPassword: false,
actionId: null,
isModelShow: false,
//
currentAction: null,
//
currentShowKey: null
};
}
/**
* 修改头像
* @param {*} e
*/
async changeIcon(e) {
let file = e.target.files[0];
if (!file || file.size > 500 * 1024) {
message.error("文件大小请勿超过500KB");
return;
}
let formData = new FormData();
formData.append("file", file);
let res = await httpUtil.post("/user/icon", formData, {
headers: { "Content-Type": "multipart/form-data" }
});
console.log(res);
this.props.updateOne("icon", res);
}
/**
* 更新
* @param {*} itemKey 修改的字段
* @param {*} isShowKey 是否修改字段
*/
async submit(itemKey, isShowKey) {
if (this.state[itemKey] == null || this.state[itemKey] == "") {
message.error("请修改后重试");
return;
}
const { password, repeatPassword, actionId, email, username } = this.state;
if (itemKey === "password" && password !== repeatPassword) {
message.error("两次密码不一致");
return;
}
if ((itemKey === "password" || itemKey === "email") && actionId == null) {
message.warning("敏感操作,需校验密码");
this.setState({ isModelShow: true, currentAction: itemKey, currentShowKey: isShowKey });
return;
}
try {
if (itemKey === "password") {
await httpUtil.post("/baseInfo/password", { actionId, password });
message.info("密码更新成功");
} else if (itemKey === "email") {
await httpUtil.post("/baseInfo/email", { actionId, email });
this.props.updateOne("newEmail", email);
message.info("新邮箱验证邮件已发送,请注意查收");
} else {
await httpUtil.post("/baseInfo/username", { username });
this.props.updateOne("username", username);
}
this.setState({ [isShowKey]: false });
} finally {
this.setState({ actionId: null });
}
}
async actionIdChange(actionId) {
const { currentAction, currentShowKey } = this.state;
this.setState({ actionId, isModelShow: false, currentAction: null, currentShowKey: null });
this.submit(currentAction, currentShowKey);
}
/**
* 渲染用户名
* @param {string} itemKey
* @param {string} isShowKey
*/
renderItem(label, itemKey, isShowKey) {
let repeatPassword = this.state.repeatPassword;
let itemValue = this.state[itemKey] === null ? this.props[itemKey] : this.state[itemKey];
let isShow = this.state[isShowKey];
let block;
if (isShow) {
block = (
<div>
{itemKey == "password" ? (
<div>
<Input.Password value={itemValue} placeholder="新密码" onChange={e => this.setState({ [itemKey]: e.target.value })} />
<Input.Password value={repeatPassword} placeholder="重复密码" onChange={e => this.setState({ repeatPassword: e.target.value })} />
</div>
) : (
<Input value={itemValue} onChange={e => this.setState({ [itemKey]: e.target.value })} />
)}
<div style={{ marginTop: "0.1rem" }}>
<Button type="primary" onClick={this.submit.bind(this, itemKey, isShowKey)}>
保存
</Button>
&nbsp;&nbsp;
<Button onClick={() => this.setState({ [isShowKey]: false })}>取消</Button>
</div>
</div>
);
} else {
block = (
<Tooltip title="点击编辑">
<div
className={itemKey === "username" ? styles.username : "" + " pointer " + styles.value}
onClick={() => this.setState({ [isShowKey]: true })}
>
{itemKey === "password" ? "********" : itemValue}
</div>
</Tooltip>
);
}
return (
<div className={styles.item + " flex"}>
{label.length > 0 ? <div className={styles.label}>{label}</div> : null}
{block}
</div>
);
}
render() {
const { isModelShow } = this.state;
const { icon, username } = this.props;
return (
<div className={styles.head}>
{/* 头像昵称 */}
<div className={styles.icon}>
<img src={icon} alt="icon" className={styles.full} />
<label className={styles.full}>
<input type="file" style={{ display: "none" }} onChange={this.changeIcon.bind(this)} />
<div className={styles.full + " " + styles.changeIcon}>
<span>编辑</span>
</div>
</label>
</div>
{/* 个人信息 */}
<div className={styles.userinfo}>
{this.renderItem("", "username", "isUsername")}
{this.renderItem("邮箱", "email", "isEmail")}
{this.renderItem("密码", "password", "isPassword")}
</div>
<PasswordCheck visible={isModelShow} onClose={() => this.setState({ isModelShow: false })} onChange={this.actionIdChange.bind(this)} />
</div>
);
}
}
export default connect(mapStateToProps, mapDispatchToProps)(UserInfo);

View File

@ -0,0 +1,68 @@
@import "../../../../global.less";
.head {
background: @mainContentColor;
padding: 0.1rem;
display: flex;
.icon {
position: relative;
border-radius: 5px;
margin-right: 1em;
@media (min-width: 768px) {
width: 150px;
height: 150px;
}
@media (max-width: 768px) {
width: 75px;
height: 75px;
}
.full {
position: absolute;
width: 100%;
height: 100%;
}
.changeIcon {
background-color: transparent;
color: rgba(173, 166, 166, 0);
display: flex;
justify-content: center;
align-items: center;
font-size: 2em;
}
.changeIcon:hover {
// background-color: rbga(173, 166, 166, 1);
background-color: rgba(173, 166, 166, 0.8) !important;
color: white;
}
}
.userinfo {
flex: 1;
.username {
font-size: 0.4rem;
color: black;
font-weight: 600;
}
.item {
font-size: 1.5em;
padding-top: 1em;
padding-bottom: 1em;
border-bottom: 1px solid #ebebeb;
.label {
width: 5em;
color: black;
}
.value {
min-width: 5em;
}
}
}
}

View File

@ -1,20 +1,33 @@
import React from "react"; import React from "react";
import styles from "./index.module.less"; import styles from "./index.module.less";
import MainLayout from "../../layout/MainLayout"; import MainLayout from "../../layout/MainLayout";
import { connect } from "react-redux";
import * as action from "../../redux/action/LoginInfoAction";
import UserInfo from "./components/UserInfo";
function mapStateToProps(state) {
return state[action.DATA_NAME];
}
function mapDispatchToProps(dispatch) {
return {
updateOne: (key, value) => dispatch(action.updateOne(key, value))
};
}
class UserSpace extends React.Component { class UserSpace extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = {}; this.state = {};
} }
render() { render() {
const { icon, username } = this.props;
return ( return (
<MainLayout> <MainLayout>
<div className={styles.main}>你好</div> <UserInfo />
</MainLayout> </MainLayout>
); );
} }
} }
export default UserSpace; export default connect(mapStateToProps, mapDispatchToProps)(UserSpace);

View File

@ -1,3 +1,41 @@
.main{ @import "../../global.less";
.head {
background: @mainContentColor;
padding: 0.1rem;
display: flex;
.icon {
position: relative;
border-radius: 5px;
@media (min-width: 768px) {
width: 150px;
height: 150px;
}
@media (max-width: 768px) {
width: 75px;
height: 75px;
}
.full {
position: absolute;
width: 100%;
height: 100%;
}
.changeIcon {
background-color: transparent;
color: rgba(173, 166, 166, 0);
display: flex;
justify-content: center;
align-items: center;
font-size: 2em;
}
.changeIcon:hover {
// background-color: rbga(173, 166, 166, 1);
background-color: rgba(173, 166, 166, 0.8) !important;
color: white;
}
}
} }

View File

@ -5,8 +5,7 @@ export function getInitData() {
let token = localStorage.getItem("token"); let token = localStorage.getItem("token");
window.token = token; window.token = token;
return { return {
token, token
userInfo: null
}; };
} }
@ -30,12 +29,19 @@ export const CHANGE_USER_INFO = "changeUserInfo";
export const changeUserInfo = userInfo => { export const changeUserInfo = userInfo => {
return { return {
type: CHANGE_USER_INFO, type: CHANGE_USER_INFO,
data: { data: Object.assign({}, userInfo)
userInfo
}
}; };
}; };
//更新一个数据
export const UPDATE_ONE = "updateOne";
export const updateOne = (key, value) => {
let data = {};
data[key] = value;
return { type: UPDATE_ONE, data };
};
// 退出登录 // 退出登录
export const LOGOUT = "logout"; export const LOGOUT = "logout";

View File

@ -4,6 +4,7 @@ const LoginStatusReducer = (state = loginAction.getInitData(), action) => {
switch (action.type) { switch (action.type) {
case loginAction.CHANGE_TOKEN: case loginAction.CHANGE_TOKEN:
case loginAction.CHANGE_USER_INFO: case loginAction.CHANGE_USER_INFO:
case loginAction.UPDATE_ONE:
case loginAction.LOGOUT: case loginAction.LOGOUT:
return { ...state, ...action.data }; return { ...state, ...action.data };
default: default:

View File

@ -4,7 +4,7 @@ import axios from "axios";
//定义http实例 //定义http实例
const instance = axios.create({ const instance = axios.create({
baseURL: "/bookmark/api", baseURL: "/bookmark/api",
timeout: 15000 timeout: 60000
}); });
//实例添加请求拦截器 //实例添加请求拦截器
@ -28,7 +28,7 @@ instance.interceptors.response.use(
message.error(data.message); message.error(data.message);
return Promise.reject(data.message); return Promise.reject(data.message);
} else { } else {
showError(data); showError(data, res.config.url.replace(res.config.baseURL, ""));
return Promise.reject(data.message); return Promise.reject(data.message);
} }
}, },
@ -39,7 +39,10 @@ instance.interceptors.response.use(
} }
); );
function showError(response) { function showError(response, url) {
if (url === "/user/currentUserInfo") {
return;
}
let description, let description,
message = "出问题啦"; message = "出问题啦";
if (response) { if (response) {