| | |
| | | import { watch } from 'vue' |
| | | import { useIdle } from '@vueuse/core' |
| | | import { ElMessage } from 'element-plus' |
| | | import { releaseBedOnExit } from '@/utils/releaseBed' |
| | | |
| | | /** |
| | | * 空闲超时自动退出(需求:30 分钟不操作才要求重新输入密码)。 |
| | |
| | | * · 有任何鼠标/键盘/触摸/滚动操作 → 计时器重置; |
| | | * · 连续 30 分钟**无任何操作** → 主动清理登录态并跳转登录页(要求重新输密码); |
| | | * · 有操作时不主动登出(token 自身的续期由 axios 拦截器的 refresh-token 负责)。 |
| | | * · 【本次】空闲登出**不再释放诊室工位**(工位保留,重新登录即可继续使用)。 |
| | | * |
| | | * 用法(在 permission.ts 中调用一次即可,内部自带幂等保护): |
| | | * setupIdleLogout() |
| | |
| | | } |
| | | |
| | | /** |
| | | * 实际执行空闲登出:释放床位 + 清理本地凭证并跳转登录页。 |
| | | * 实际执行空闲登出:**只清本地凭证并跳转登录页,不释放工位**。 |
| | | * |
| | | * 之所以不调用 userStore.loginOut()(那是"主动退出"): |
| | | * · 那个接口会请求后端注销 token — 对本场景没必要,且可能因网络问题卡住; |
| | | * · 空闲登出只需保证本地凭证清干净 + 回到登录页。 |
| | | * |
| | | * ⚠️ 但**必须**单独调一次「释放床位」: |
| | | * 医生在「诊室选择」页选好床位后就占用了该床位(`clinic_room.doc_id`)。 |
| | | * 原先本函数只清本地凭证、不通知后端 ⇒ 空闲超时后床位**一直显示被占用**, |
| | | * 其他医生选不到这个床位。这正是"医生忘了离座就退出系统"的主要场景。 |
| | | * 【重要变更(本次)】空闲超时**不再释放诊室工位**。 |
| | | * --------------------------------------------------------------- |
| | | * 原先本函数会先调 `releaseBedOnExit('idle-timeout')`,把 `clinic_room.doc_id` 清空。 |
| | | * 实测问题:医生离开电脑 30 分钟以上(例如去做检查、离开 1 小时回来), |
| | | * 回来时工位已经被释放 → 工作台只能只读、并提示"请重新就坐", |
| | | * 而医生本人并没有离座。这不符合实际使用场景。 |
| | | * |
| | | * 现在的口径: |
| | | * · 空闲超时 → **只要求重新输入密码**(token 清掉、回登录页),**工位保留**; |
| | | * · 重新登录后 `roomStore.fetchMySeat()` 会自动恢复「我的工位」,可直接继续使用; |
| | | * · 工位的释放只发生在**用户主动操作**:手动「离座」、手动「退出登录」。 |
| | | * · 医生真的下班忘离座的兜底:① 闭诊时系统统一清空当班工位;② 管理员可在 |
| | | * 诊室管理页「清空工位」。 |
| | | */ |
| | | async function doIdleLogout(): Promise<void> { |
| | | ElMessage.warning(`已超过 ${IDLE_TIMEOUT_MINUTES} 分钟未操作,请重新登录`) |
| | | |
| | | // 先释放床位,再清凭证 —— 顺序不能反:释放接口需要携带当前令牌 |
| | | try { |
| | | await releaseBedOnExit('idle-timeout') |
| | | } catch { |
| | | /* releaseBedOnExit 内部已兜底,不会抛错;此处仅为防御性写法 */ |
| | | } |
| | | |
| | | cleanupCredentials() |
| | | |