yxh
2026-10-03 d553a4be94d4f6ee162cc353a28b220403909cfc
src/hooks/web/useIdleLogout.ts
@@ -1,6 +1,7 @@
import { watch } from 'vue'
import { useIdle } from '@vueuse/core'
import { ElMessage } from 'element-plus'
import { releaseBedOnExit } from '@/utils/releaseBed'
/**
 * 空闲超时自动退出(需求:30 分钟不操作才要求重新输入密码)。
@@ -93,20 +94,32 @@
      onTimeout()
      return
    }
    doIdleLogout()
    void doIdleLogout()
  })
}
/**
 * 实际执行空闲登出:清理本地凭证并跳转登录页。
 * 实际执行空闲登出:释放床位 + 清理本地凭证并跳转登录页。
 *
 * 之所以不调用 userStore.loginOut()(那是"主动退出"):
 *   · 那个接口会请求后端注销 token — 对本场景没必要,且可能因网络问题卡住;
 *   · 空闲登出只需保证本地凭证清干净 + 回到登录页。
 *
 * ⚠️ 但**必须**单独调一次「释放床位」:
 *   医生在「诊室选择」页选好床位后就占用了该床位(`clinic_room.doc_id`)。
 *   原先本函数只清本地凭证、不通知后端 ⇒ 空闲超时后床位**一直显示被占用**,
 *   其他医生选不到这个床位。这正是"医生忘了离座就退出系统"的主要场景。
 */
function doIdleLogout(): void {
async function doIdleLogout(): Promise<void> {
  ElMessage.warning(`已超过 ${IDLE_TIMEOUT_MINUTES} 分钟未操作,请重新登录`)
  // 先释放床位,再清凭证 —— 顺序不能反:释放接口需要携带当前令牌
  try {
    await releaseBedOnExit('idle-timeout')
  } catch {
    /* releaseBedOnExit 内部已兜底,不会抛错;此处仅为防御性写法 */
  }
  cleanupCredentials()
  // 用 replace 避免用户按"返回"回到已登出的页面