| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- <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>
- <motion.div
- class="overflow-x-hidden font-sans"
- :key="$route.fullPath"
- :initial="{ opacity: 0 }"
- :animate="{ opacity: 1, transition: { duration: 0.5, ease: 'easeOut' } }"
- >
- <router-view></router-view>
- </motion.div>
- </template>
- <style scoped>
- /* 修改垂直滚动条 */
- ::-webkit-scrollbar {
- width: 5px; /* 修改宽度 */
- }
- ::-webkit-scrollbar-thumb {
- border-radius: 5px;
- }
- /* 修改滚动条轨道背景色 */
- ::-webkit-scrollbar-track {
- background-color: transparent;
- }
- /* 修改滚动条滑块颜色 */
- ::-webkit-scrollbar-thumb {
- background-color: #0a5f73;
- }
- /* 修改滚动条滑块悬停时的颜色 */
- ::-webkit-scrollbar-thumb:hover {
- background-color: #30459c;
- }
- </style>
|