Browse Source

关闭窗口时退出登录

master
hejl 1 week ago
parent
commit
56b7d150b5
  1. 166
      gofaster/app/dist/renderer/js/index.js
  2. 52
      gofaster/app/src/main/index.js
  3. 164
      gofaster/app/src/renderer/components/MainLayout.vue

166
gofaster/app/dist/renderer/js/index.js vendored

@ -3489,47 +3489,80 @@ __webpack_require__.r(__webpack_exports__); @@ -3489,47 +3489,80 @@ __webpack_require__.r(__webpack_exports__);
}
}
// 处理应用关闭事件
// 统一的退出登录函数
const performLogout = () => {
if (!isLoggedIn.value) return
try {
console.log('开始执行退出登录')
// 获取token并尝试调用后端接口
const token = localStorage.getItem('token')
if (token) {
// 异步调用登出接口,不等待结果
_services_userService__WEBPACK_IMPORTED_MODULE_3__.userService.logout(token).catch(error => {
console.error('调用登出接口失败:', error)
})
}
// 清除本地状态
localStorage.removeItem('user')
localStorage.removeItem('isLoggedIn')
localStorage.removeItem('token')
// 清除用户对象状态
Object.assign(currentUser, {
id: null,
name: '',
email: '',
avatar: null,
role: '',
lastLogin: null,
lastLoginIP: '',
status: 1,
roles: []
})
// 更新登录状态
isLoggedIn.value = false
// 停止会话超时检测
stopSessionTimeoutCheck()
console.log('退出登录完成')
} catch (error) {
console.error('退出登录失败:', error)
}
}
// 处理应用关闭事件(主进程事件)
const handleAppWillClose = () => {
console.log('主进程 app-will-close 事件触发')
performLogout()
}
// 处理页面卸载事件
const handleBeforeUnload = () => {
if (isLoggedIn.value) {
// 同步执行退出登录,不等待异步操作
try {
const token = localStorage.getItem('token')
if (token) {
// 这里可以发送一个同步的退出登录请求,但考虑到应用即将关闭,主要是清除本地状态
_services_userService__WEBPACK_IMPORTED_MODULE_3__.userService.logout(token).catch(error => {
console.error('应用关闭时调用登出接口失败:', error)
})
}
} catch (error) {
console.error('应用关闭时退出登录失败:', error)
} finally {
// 清除本地状态
localStorage.removeItem('user')
localStorage.removeItem('isLoggedIn')
localStorage.removeItem('token')
// 清除用户对象状态
currentUser.id = null
currentUser.name = ''
currentUser.email = ''
currentUser.avatar = null
currentUser.role = ''
currentUser.lastLogin = null
currentUser.lastLoginIP = ''
currentUser.status = 1
currentUser.roles = []
// 更新登录状态
isLoggedIn.value = false
// 停止会话超时检测
stopSessionTimeoutCheck()
}
console.log('beforeunload 事件触发,执行退出登录')
performLogout()
}
}
// 处理页面隐藏事件
const handleVisibilityChange = () => {
if (document.visibilityState === 'hidden' && isLoggedIn.value) {
console.log('页面隐藏,可能应用即将关闭,执行退出登录')
performLogout()
}
}
// 处理窗口焦点丢失事件
const handleWindowBlur = () => {
// 可以在这里添加额外的检查逻辑
// 暂时不执行退出登录,因为用户可能只是切换到其他窗口
}
// 自动退出登录(不显示提示)
const autoLogout = async () => {
try {
@ -3683,25 +3716,25 @@ __webpack_require__.r(__webpack_exports__); @@ -3683,25 +3716,25 @@ __webpack_require__.r(__webpack_exports__);
document.addEventListener(event, updateUserActivity, { passive: true })
})
// 监听应用关闭事件
// 1. 监听主进程应用关闭事件(主要方案)
if (window.electronAPI && window.electronAPI.onAppWillClose) {
console.log('注册主进程 app-will-close 事件监听器')
window.electronAPI.onAppWillClose(handleAppWillClose)
} else {
// 兼容性处理:如果electronAPI不可用,使用备用方案
console.warn('electronAPI不可用,无法注册应用关闭事件监听器')
// 可以在这里添加其他备用方案,比如使用localStorage或其他方式
console.warn('electronAPI不可用,无法注册主进程应用关闭事件监听器')
}
// 添加页面卸载事件监听器作为备用方案
window.addEventListener('beforeunload', () => {
if (isLoggedIn.value) {
// 同步清除本地状态
localStorage.removeItem('user')
localStorage.removeItem('isLoggedIn')
localStorage.removeItem('token')
stopSessionTimeoutCheck()
}
})
// 2. 监听页面卸载事件(备用方案)
console.log('注册 beforeunload 事件监听器')
window.addEventListener('beforeunload', handleBeforeUnload)
// 3. 监听页面隐藏事件(额外备用方案)
console.log('注册 visibilitychange 事件监听器')
document.addEventListener('visibilitychange', handleVisibilityChange)
// 4. 监听窗口焦点丢失事件(Windows 特有,暂时只记录不执行退出)
console.log('注册 window blur 事件监听器')
window.addEventListener('blur', handleWindowBlur)
// 检查登录状态
const savedIsLoggedIn = localStorage.getItem('isLoggedIn')
@ -3775,19 +3808,24 @@ __webpack_require__.r(__webpack_exports__); @@ -3775,19 +3808,24 @@ __webpack_require__.r(__webpack_exports__);
})
// 组件卸载时清理事件监听器
;(0,vue__WEBPACK_IMPORTED_MODULE_0__.onUnmounted)(() => {
document.removeEventListener('click', handleGlobalClick)
// 移除用户活动监听器
const userActivityEvents = ['mousedown', 'mousemove', 'keypress', 'scroll', 'touchstart', 'click']
userActivityEvents.forEach(event => {
document.removeEventListener(event, updateUserActivity)
})
// 停止会话超时检测
stopSessionTimeoutCheck()
})
// 组件卸载时清理事件监听器
;(0,vue__WEBPACK_IMPORTED_MODULE_0__.onUnmounted)(() => {
document.removeEventListener('click', handleGlobalClick)
// 移除用户活动监听器
const userActivityEvents = ['mousedown', 'mousemove', 'keypress', 'scroll', 'touchstart', 'click']
userActivityEvents.forEach(event => {
document.removeEventListener(event, updateUserActivity)
})
// 移除应用关闭相关的事件监听器
window.removeEventListener('beforeunload', handleBeforeUnload)
document.removeEventListener('visibilitychange', handleVisibilityChange)
window.removeEventListener('blur', handleWindowBlur)
// 停止会话超时检测
stopSessionTimeoutCheck()
})
// 提供响应式数据给子组件
;(0,vue__WEBPACK_IMPORTED_MODULE_0__.provide)('isLoggedIn', isLoggedIn)
@ -9023,7 +9061,7 @@ __webpack_require__.r(__webpack_exports__); @@ -9023,7 +9061,7 @@ __webpack_require__.r(__webpack_exports__);
/******/
/******/ /* webpack/runtime/getFullHash */
/******/ (() => {
/******/ __webpack_require__.h = () => ("4a166f955d2fe42e")
/******/ __webpack_require__.h = () => ("d5031258c9bcadee")
/******/ })();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */

52
gofaster/app/src/main/index.js

@ -401,14 +401,23 @@ function createWindow() { @@ -401,14 +401,23 @@ function createWindow() {
}
})
// 窗口关闭事件
mainWindow.on('closed', () => {
// 保存窗口状态
if (windowStateManager) {
windowStateManager.saveState(mainWindow)
}
mainWindow = null
})
// 窗口即将关闭事件(更早触发)
mainWindow.on('close', (event) => {
console.log('窗口即将关闭,发送退出登录事件')
// 立即发送事件,不等待
if (!mainWindow.isDestroyed()) {
mainWindow.webContents.send('app-will-close')
}
})
// 窗口关闭事件
mainWindow.on('closed', () => {
// 保存窗口状态
if (windowStateManager) {
windowStateManager.saveState(mainWindow)
}
mainWindow = null
})
} catch (error) {
console.error('Failed to create window:', error)
@ -615,32 +624,17 @@ ipcMain.handle('get-window-state-info', async () => { @@ -615,32 +624,17 @@ ipcMain.handle('get-window-state-info', async () => {
}); // 闭合 app.whenReady().then() 的回调函数
app.on('window-all-closed', () => {
// 通知渲染进程应用即将关闭,执行退出登录
if (mainWindow && !mainWindow.isDestroyed()) {
mainWindow.webContents.send('app-will-close')
// 延迟退出,给渲染进程时间处理退出登录
setTimeout(() => {
if (process.platform !== 'darwin') {
app.quit()
}
}, 1000) // 延迟1秒退出
} else {
if (process.platform !== 'darwin') app.quit()
// 由于已经在窗口 close 事件中处理了退出登录,这里直接退出
if (process.platform !== 'darwin') {
app.quit()
}
})
// 应用即将退出时的处理
app.on('before-quit', () => {
// 通知渲染进程应用即将退出,执行退出登录
if (mainWindow && !mainWindow.isDestroyed()) {
mainWindow.webContents.send('app-will-close')
// 延迟退出,给渲染进程时间处理退出登录
setTimeout(() => {
app.quit()
}, 1000) // 延迟1秒退出
} else {
app.quit()
}
// 由于已经在窗口 close 事件中处理了退出登录,这里不需要再次调用 app.quit()
// 避免无限递归调用
console.log('应用即将退出,退出登录已在窗口关闭时处理')
})
// 应用退出时的处理

164
gofaster/app/src/renderer/components/MainLayout.vue

@ -750,47 +750,80 @@ export default { @@ -750,47 +750,80 @@ export default {
}
}
//
// 退
const performLogout = () => {
if (!isLoggedIn.value) return
try {
console.log('开始执行退出登录')
// token
const token = localStorage.getItem('token')
if (token) {
//
userService.logout(token).catch(error => {
console.error('调用登出接口失败:', error)
})
}
//
localStorage.removeItem('user')
localStorage.removeItem('isLoggedIn')
localStorage.removeItem('token')
//
Object.assign(currentUser, {
id: null,
name: '',
email: '',
avatar: null,
role: '',
lastLogin: null,
lastLoginIP: '',
status: 1,
roles: []
})
//
isLoggedIn.value = false
//
stopSessionTimeoutCheck()
console.log('退出登录完成')
} catch (error) {
console.error('退出登录失败:', error)
}
}
//
const handleAppWillClose = () => {
console.log('主进程 app-will-close 事件触发')
performLogout()
}
//
const handleBeforeUnload = () => {
if (isLoggedIn.value) {
// 退
try {
const token = localStorage.getItem('token')
if (token) {
// 退
userService.logout(token).catch(error => {
console.error('应用关闭时调用登出接口失败:', error)
})
}
} catch (error) {
console.error('应用关闭时退出登录失败:', error)
} finally {
//
localStorage.removeItem('user')
localStorage.removeItem('isLoggedIn')
localStorage.removeItem('token')
//
currentUser.id = null
currentUser.name = ''
currentUser.email = ''
currentUser.avatar = null
currentUser.role = ''
currentUser.lastLogin = null
currentUser.lastLoginIP = ''
currentUser.status = 1
currentUser.roles = []
//
isLoggedIn.value = false
//
stopSessionTimeoutCheck()
}
console.log('beforeunload 事件触发,执行退出登录')
performLogout()
}
}
//
const handleVisibilityChange = () => {
if (document.visibilityState === 'hidden' && isLoggedIn.value) {
console.log('页面隐藏,可能应用即将关闭,执行退出登录')
performLogout()
}
}
//
const handleWindowBlur = () => {
//
// 退
}
// 退
const autoLogout = async () => {
try {
@ -944,25 +977,25 @@ export default { @@ -944,25 +977,25 @@ export default {
document.addEventListener(event, updateUserActivity, { passive: true })
})
//
// 1.
if (window.electronAPI && window.electronAPI.onAppWillClose) {
console.log('注册主进程 app-will-close 事件监听器')
window.electronAPI.onAppWillClose(handleAppWillClose)
} else {
// electronAPI使
console.warn('electronAPI不可用,无法注册应用关闭事件监听器')
// 使localStorage
console.warn('electronAPI不可用,无法注册主进程应用关闭事件监听器')
}
//
window.addEventListener('beforeunload', () => {
if (isLoggedIn.value) {
//
localStorage.removeItem('user')
localStorage.removeItem('isLoggedIn')
localStorage.removeItem('token')
stopSessionTimeoutCheck()
}
})
// 2.
console.log('注册 beforeunload 事件监听器')
window.addEventListener('beforeunload', handleBeforeUnload)
// 3.
console.log('注册 visibilitychange 事件监听器')
document.addEventListener('visibilitychange', handleVisibilityChange)
// 4. Windows 退
console.log('注册 window blur 事件监听器')
window.addEventListener('blur', handleWindowBlur)
//
const savedIsLoggedIn = localStorage.getItem('isLoggedIn')
@ -1036,19 +1069,24 @@ export default { @@ -1036,19 +1069,24 @@ export default {
})
//
onUnmounted(() => {
document.removeEventListener('click', handleGlobalClick)
//
const userActivityEvents = ['mousedown', 'mousemove', 'keypress', 'scroll', 'touchstart', 'click']
userActivityEvents.forEach(event => {
document.removeEventListener(event, updateUserActivity)
})
//
stopSessionTimeoutCheck()
})
//
onUnmounted(() => {
document.removeEventListener('click', handleGlobalClick)
//
const userActivityEvents = ['mousedown', 'mousemove', 'keypress', 'scroll', 'touchstart', 'click']
userActivityEvents.forEach(event => {
document.removeEventListener(event, updateUserActivity)
})
//
window.removeEventListener('beforeunload', handleBeforeUnload)
document.removeEventListener('visibilitychange', handleVisibilityChange)
window.removeEventListener('blur', handleWindowBlur)
//
stopSessionTimeoutCheck()
})
//
provide('isLoggedIn', isLoggedIn)

Loading…
Cancel
Save