|
|
@@ -0,0 +1,81 @@
|
|
|
+import { onMounted, onUnmounted } from 'vue'
|
|
|
+import { ElMessageBox } from 'element-plus'
|
|
|
+import { useRouter } from 'vue-router'
|
|
|
+import { useUserStore } from '@/store/modules/user'
|
|
|
+import { getAccessToken } from '@/utils/auth'
|
|
|
+import { throttle } from 'lodash-es'
|
|
|
+
|
|
|
+// --- 关键修改:将变量移到函数外部,变成全局共享变量 ---
|
|
|
+let timer: ReturnType<typeof setTimeout> | null = null
|
|
|
+const TIMEOUT = 30 * 60 * 1000 // 30分钟
|
|
|
+const events = ['click', 'mousedown', 'keydown', 'scroll', 'mousemove']
|
|
|
+
|
|
|
+export function useAutoLogout() {
|
|
|
+ const userStore = useUserStore()
|
|
|
+ const router = useRouter()
|
|
|
+
|
|
|
+ // 处理登出逻辑
|
|
|
+ const handleLogout = () => {
|
|
|
+ // 防止重复触发,先清理
|
|
|
+ removeListeners()
|
|
|
+ userStore.loginOut()
|
|
|
+
|
|
|
+ ElMessageBox.alert('长时间未操作,登录已超时,请重新登录!', '提示', {
|
|
|
+ confirmButtonText: '确定',
|
|
|
+ type: 'warning',
|
|
|
+ showClose: false,
|
|
|
+ callback: () => {
|
|
|
+ router.push('/login')
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ // 节流的重置计时器
|
|
|
+ const resetTimer = throttle(() => {
|
|
|
+ // 这里引用的 timer 是文件顶部的全局变量
|
|
|
+ if (timer) clearTimeout(timer)
|
|
|
+
|
|
|
+ // 只有有 Token 时才开启倒计时
|
|
|
+ if (getAccessToken()) {
|
|
|
+ timer = setTimeout(handleLogout, TIMEOUT)
|
|
|
+ }
|
|
|
+ }, 1000)
|
|
|
+
|
|
|
+ const addListeners = () => {
|
|
|
+ // 每次添加前先移除,防止重复绑定导致事件堆积
|
|
|
+ removeListeners()
|
|
|
+
|
|
|
+ events.forEach((event) => {
|
|
|
+ window.addEventListener(event, resetTimer)
|
|
|
+ })
|
|
|
+ resetTimer()
|
|
|
+ }
|
|
|
+
|
|
|
+ const removeListeners = () => {
|
|
|
+ if (timer) {
|
|
|
+ clearTimeout(timer)
|
|
|
+ timer = null
|
|
|
+ }
|
|
|
+ events.forEach((event) => {
|
|
|
+ window.removeEventListener(event, resetTimer)
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ // 注意:如果你要在路由守卫中手动控制,
|
|
|
+ // 建议去掉这里的生命周期钩子,或者只在 App.vue 中保留
|
|
|
+ // 如果这里保留,会导致只要 import 并在组件 setup 中调用,就会自动开启监听
|
|
|
+ onMounted(() => {
|
|
|
+ // 如果你想完全由路由守卫控制,注释掉下面这行
|
|
|
+ // addListeners()
|
|
|
+ })
|
|
|
+
|
|
|
+ onUnmounted(() => {
|
|
|
+ // 组件卸载时销毁监听
|
|
|
+ removeListeners()
|
|
|
+ })
|
|
|
+
|
|
|
+ return {
|
|
|
+ addListeners,
|
|
|
+ removeListeners
|
|
|
+ }
|
|
|
+}
|