Ver código fonte

没操作自动退出

yanghao 3 semanas atrás
pai
commit
c730a46ade
1 arquivos alterados com 81 adições e 0 exclusões
  1. 81 0
      src/App.vue

+ 81 - 0
src/App.vue

@@ -1,5 +1,86 @@
 <script setup lang="ts">
+import { onBeforeUnmount, onMounted, watch } from "vue";
+import { useRoute } from "vue-router";
 import { motion } from "motion-v";
+import { deleteUserCache } from "@hooks/useCache";
+import { manualLogoutKey, reloginCancelKey } from "@/config/axios/service";
+import { removeToken, getAccessToken } from "@/utils/auth";
+import { useUserStore } from "@/stores/useUserStore";
+
+const route = useRoute();
+const userStore = useUserStore();
+
+const IDLE_TIMEOUT = 30 * 60 * 1000;
+const activityEvents = [
+  "click",
+  "mousemove",
+  "keydown",
+  "scroll",
+  "touchstart",
+];
+
+let idleTimer: number | null = null;
+
+const isLoginPage = () => route.path === "/login";
+
+const clearIdleTimer = () => {
+  if (idleTimer) {
+    window.clearTimeout(idleTimer);
+    idleTimer = null;
+  }
+};
+
+const logoutByIdle = () => {
+  clearIdleTimer();
+
+  if (!getAccessToken() || isLoginPage()) {
+    return;
+  }
+
+  deleteUserCache();
+  userStore.resetState();
+  sessionStorage.setItem(manualLogoutKey, "true");
+  sessionStorage.removeItem(reloginCancelKey);
+  removeToken();
+  window.location.href = "/login";
+};
+
+const resetIdleTimer = () => {
+  clearIdleTimer();
+
+  if (!getAccessToken() || isLoginPage()) {
+    return;
+  }
+
+  idleTimer = window.setTimeout(() => {
+    logoutByIdle();
+  }, IDLE_TIMEOUT);
+};
+
+const handleUserActivity = () => {
+  resetIdleTimer();
+};
+
+onMounted(() => {
+  activityEvents.forEach((eventName) => {
+    window.addEventListener(eventName, handleUserActivity, true);
+  });
+
+  watch(
+    () => route.path,
+    () => {
+      resetIdleTimer();
+    },
+    { immediate: true },
+  );
+});
+
+onBeforeUnmount(() => {
+  clearIdleTimer();
+  activityEvents.forEach((eventName) => {
+    window.removeEventListener(eventName, handleUserActivity, true);
+  });
+});
 </script>
 
 <template>