mirror of
				https://github.com/pure-admin/pure-admin-thin.git
				synced 2025-11-04 17:44:48 +08:00 
			
		
		
		
	feat: 新增token过期 跳出提示框 并跳转登录页的逻辑
This commit is contained in:
		
							parent
							
								
									de5550e216
								
							
						
					
					
						commit
						d0d9bee8b7
					
				@ -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");
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -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页面
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 | 
			
		||||
@ -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) {
 | 
			
		||||
          message(response.data.msg, { type: "error" });
 | 
			
		||||
          // 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);
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -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,
 | 
			
		||||
 | 
			
		||||
@ -81,18 +81,22 @@ const onLogin = async (formEl: FormInstance | undefined) => {
 | 
			
		||||
        password: rsaEncrypt(ruleForm.password),
 | 
			
		||||
        captchaCode: ruleForm.captchaCode,
 | 
			
		||||
        captchaCodeKey: ruleForm.captchaCodeKey
 | 
			
		||||
      }).then(({ data }) => {
 | 
			
		||||
        // 登录成功后 将token存储到sessionStorage中
 | 
			
		||||
        setTokenFromBackend(data);
 | 
			
		||||
        // 获取后端路由
 | 
			
		||||
        initRouter().then(() => {
 | 
			
		||||
          router.push(getTopMenu(true).path);
 | 
			
		||||
          message("登录成功", { type: "success" });
 | 
			
		||||
      })
 | 
			
		||||
        .then(({ data }) => {
 | 
			
		||||
          // 登录成功后 将token存储到sessionStorage中
 | 
			
		||||
          setTokenFromBackend(data);
 | 
			
		||||
          // 获取后端路由
 | 
			
		||||
          initRouter().then(() => {
 | 
			
		||||
            router.push(getTopMenu(true).path);
 | 
			
		||||
            message("登录成功", { type: "success" });
 | 
			
		||||
          });
 | 
			
		||||
          if (isRememberMe.value) {
 | 
			
		||||
            savePassword(ruleForm.password);
 | 
			
		||||
          }
 | 
			
		||||
        })
 | 
			
		||||
        .catch(() => {
 | 
			
		||||
          loading.value = false;
 | 
			
		||||
        });
 | 
			
		||||
        if (isRememberMe.value) {
 | 
			
		||||
          savePassword(ruleForm.password);
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
    } else {
 | 
			
		||||
      loading.value = false;
 | 
			
		||||
      return fields;
 | 
			
		||||
@ -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>
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user