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 = { export type CurrentLoginUserDTO = {
user: any; userInfo: any;
roleKey: string; roleKey: string;
permissions: Set<string>; permissions: Set<string>;
}; };
@ -61,3 +61,8 @@ export const getCaptchaCode = () => {
export const loginByPassword = (data: LoginByPasswordDTO) => { export const loginByPassword = (data: LoginByPasswordDTO) => {
return http.request<ResponseData<TokenDTO>>("post", "/login", { data }); 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() { function toCorrectRoute() {
whiteList.includes(to.fullPath) ? next(_from.fullPath) : next(); /** 新增判断是否存在登录信息 */
whiteList.includes(to.fullPath) && userInfo ? next(_from.fullPath) : next();
} }
if (userInfo) { if (userInfo) {
// 无权限跳转403页面 // 无权限跳转403页面

View File

@ -30,7 +30,7 @@ export function getToken(): TokenDTO {
// 此处与`TokenKey`相同,此写法解决初始化时`Cookies`中不存在`TokenKey`报错 // 此处与`TokenKey`相同,此写法解决初始化时`Cookies`中不存在`TokenKey`报错
return Cookies.get(tokenKey) return Cookies.get(tokenKey)
? JSON.parse(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 NProgress from "../progress";
import { getToken, formatToken } from "@/utils/auth"; import { getToken, formatToken } from "@/utils/auth";
import { message } from "../message"; 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; const { VITE_APP_BASE_API } = import.meta.env;
// 相关配置请参考www.axios-js.com/zh-cn/docs/#axios-request-config-1 // 相关配置请参考www.axios-js.com/zh-cn/docs/#axios-request-config-1
@ -101,9 +105,32 @@ class PureHttp {
const instance = PureHttp.axiosInstance; const instance = PureHttp.axiosInstance;
instance.interceptors.response.use( instance.interceptors.response.use(
(response: PureHttpResponse) => { (response: PureHttpResponse) => {
// 请求返回失败时,有业务错误时,弹出错误提示
if (response.data.code !== 0) { 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" }); message(response.data.msg, { type: "error" });
} }
}
const $config = response.config; const $config = response.config;
// 关闭进度条动画 // 关闭进度条动画
NProgress.done(); NProgress.done();
@ -151,15 +178,20 @@ class PureHttp {
resolve(response); resolve(response);
}) })
.catch(error => { .catch(error => {
if (error.response.status >= 500) { // 某些情况网络失效此时直接进入error流程所以在这边也进行拦截
if (error.response && error.response.status >= 500) {
message("网络异常", { type: "error" }); 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" }); message("请求接口不存在", { type: "error" });
} }
reject(error.response.statusText); reject(error);
}); });
}); });
} }

View File

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

View File

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