feat: 新增token过期 跳出提示框 并跳转登录页的逻辑

This commit is contained in:
valarchie 2023-07-07 18:07:13 +08:00
parent de5550e216
commit d0d9bee8b7
6 changed files with 79 additions and 26 deletions

View File

@ -36,7 +36,7 @@ export type TokenDTO = {
};
export type CurrentLoginUserDTO = {
user: any;
userInfo: any;
roleKey: string;
permissions: Set<string>;
};
@ -61,3 +61,8 @@ export const getCaptchaCode = () => {
export const loginByPassword = (data: LoginByPasswordDTO) => {
return http.request<ResponseData<TokenDTO>>("post", "/login", { data });
};
/** 获取当前登录用户接口 */
export const getLoginUserInfo = () => {
return http.request<ResponseData<TokenDTO>>("get", "/getLoginUserInfo");
};

View File

@ -122,7 +122,8 @@ router.beforeEach((to: ToRouteType, _from, next) => {
}
/** 如果已经登录并存在登录信息后不能跳转到路由白名单,而是继续保持在当前页面 */
function toCorrectRoute() {
whiteList.includes(to.fullPath) ? next(_from.fullPath) : next();
/** 新增判断是否存在登录信息 */
whiteList.includes(to.fullPath) && userInfo ? next(_from.fullPath) : next();
}
if (userInfo) {
// 无权限跳转403页面

View File

@ -30,7 +30,7 @@ export function getToken(): TokenDTO {
// 此处与`TokenKey`相同,此写法解决初始化时`Cookies`中不存在`TokenKey`报错
return Cookies.get(tokenKey)
? JSON.parse(Cookies.get(tokenKey))
: storageSession().getItem<TokenDTO>(sessionKey).token;
: storageSession().getItem<TokenDTO>(sessionKey)?.token;
}
/**

View File

@ -13,6 +13,10 @@ import { stringify } from "qs";
import NProgress from "../progress";
import { getToken, formatToken } from "@/utils/auth";
import { message } from "../message";
import { ElMessageBox } from "element-plus";
import { router } from "@/router";
import { removeToken } from "@/utils/auth";
// console.log("Utils:" + router);
const { VITE_APP_BASE_API } = import.meta.env;
// 相关配置请参考www.axios-js.com/zh-cn/docs/#axios-request-config-1
@ -101,9 +105,32 @@ class PureHttp {
const instance = PureHttp.axiosInstance;
instance.interceptors.response.use(
(response: PureHttpResponse) => {
// 请求返回失败时,有业务错误时,弹出错误提示
if (response.data.code !== 0) {
// token失效时弹出过期提示
if (response.data.code === 20101) {
ElMessageBox.confirm(
"登录状态已过期,您可以继续留在该页面,或者重新登录",
"系统提示",
{
confirmButtonText: "重新登录",
cancelButtonText: "取消",
type: "warning"
}
)
.then(() => {
removeToken();
router.push("/login");
})
.catch(() => {
message("取消重新登录", { type: "info" });
});
} else {
// 其余情况弹出错误提示框
message(response.data.msg, { type: "error" });
}
}
const $config = response.config;
// 关闭进度条动画
NProgress.done();
@ -151,15 +178,20 @@ class PureHttp {
resolve(response);
})
.catch(error => {
if (error.response.status >= 500) {
// 某些情况网络失效此时直接进入error流程所以在这边也进行拦截
if (error.response && error.response.status >= 500) {
message("网络异常", { type: "error" });
}
if (error.response.status >= 400 && error.response.status < 500) {
if (
error.response &&
error.response.status >= 400 &&
error.response.status < 500
) {
message("请求接口不存在", { type: "error" });
}
reject(error.response.statusText);
reject(error);
});
});
}

View File

@ -1,12 +1,17 @@
<script setup lang="ts">
import { useRouter } from "vue-router";
// import { useRouter } from "vue-router";
import noAccess from "@/assets/status/403.svg?component";
import * as CommonAPI from "@/api/common";
defineOptions({
name: "403"
});
const router = useRouter();
async function getConfig() {
await CommonAPI.getLoginUserInfo().then(res => {
console.log(res);
});
}
</script>
<template>
@ -49,7 +54,7 @@ const router = useRouter();
</p>
<el-button
type="primary"
@click="router.push('/')"
@click="getConfig"
v-motion
:initial="{
opacity: 0,

View File

@ -81,7 +81,8 @@ const onLogin = async (formEl: FormInstance | undefined) => {
password: rsaEncrypt(ruleForm.password),
captchaCode: ruleForm.captchaCode,
captchaCodeKey: ruleForm.captchaCodeKey
}).then(({ data }) => {
})
.then(({ data }) => {
// tokensessionStorage
setTokenFromBackend(data);
//
@ -92,6 +93,9 @@ const onLogin = async (formEl: FormInstance | undefined) => {
if (isRememberMe.value) {
savePassword(ruleForm.password);
}
})
.catch(() => {
loading.value = false;
});
} else {
loading.value = false;
@ -221,13 +225,19 @@ onBeforeUnmount(() => {
:prefix-icon="useRenderIcon('ri:shield-keyhole-line')"
>
<template v-slot:append>
<img
width="120"
height="40"
class="cursor-pointer"
<el-image
style="
justify-content: center;
width: 120px;
height: 40px;
"
:src="captchaCodeBase64"
@click="getCaptchaCode"
/>
>
<template #error>
<span>Loading</span>
</template>
</el-image>
</template>
</el-input>
</el-form-item>