08a0157c95
调度页执行周期可视化/单次执行/分类选机/推送源对齐;登录 IP 门控与无缝导航; 服务器批量后台任务、执行记录、凭据合并、各页激活刷新与错误提示修复。 Co-authored-by: Cursor <cursoragent@cursor.com>
52 lines
2.0 KiB
Markdown
52 lines
2.0 KiB
Markdown
# 实施计划 — 登录 IP 门禁 + SPA 无感切换
|
||
|
||
**设计**: [`2026-06-08-login-gate-seamless-nav-design.md`](../specs/2026-06-08-login-gate-seamless-nav-design.md)
|
||
|
||
## 阶段划分
|
||
|
||
| 阶段 | 范围 | 估时 | 可独立部署 |
|
||
|------|------|------|------------|
|
||
| **P0** | `GET /api/auth/login-access` + LoginPage 门禁 UI | 0.5~1d | 是 |
|
||
| **P1** | `router-view` key、登录 replace + chunk 预载 | 0.5d | 是 |
|
||
| **P2** | keep-alive + 各页 `onActivated` 静默刷新 | 2~3d | 是(逐页) |
|
||
| **P3** | `useCachedQuery` + 统计/分类共享 store | 3~5d | 否(需全链路) |
|
||
| **P4** | 侧栏预取 + 骨架屏 | 1~2d | 是 |
|
||
|
||
## P0 实施步骤
|
||
|
||
1. 新增 `server/utils/login_allowlist.py`:`is_login_allowed(client_ip) -> tuple[bool, str|None]`
|
||
2. `auth_service.login` 改为调用上述函数
|
||
3. `GET /api/auth/login-access` + `PUBLIC_EXACT_PATHS`
|
||
4. `LoginPage`:checking / blocked / form 三态
|
||
5. `tests/test_login_access.py`
|
||
6. changelog + audit + 部署
|
||
|
||
## P1 实施步骤
|
||
|
||
1. `App.vue`:`route.fullPath` → `route.name`(或移除 key)
|
||
2. 回归 `ScriptRunsPage`:`watch(route.params.id)`
|
||
3. `LoginPage`:`router.replace` + 动态 import 预载 Dashboard
|
||
4. 浏览器:登录 → 仪表盘无闪屏验证
|
||
|
||
## P2 实施步骤
|
||
|
||
1. `App.vue`:`keep-alive` + `include` 列表
|
||
2. 各页 `defineOptions({ name: '...' })`
|
||
3. 将 `onMounted(load)` 拆为 `onMounted` + `onActivated(() => load({ silent: true }))`
|
||
4. **排除** `TerminalPage`
|
||
5. E2E:连续切换 10 次菜单,Network 观察无重复全量请求风暴
|
||
|
||
## P3/P4(后续迭代)
|
||
|
||
见设计文档 §4.2;单独开 changelog 与验收报告。
|
||
|
||
## 测试要点
|
||
|
||
- P0:`pytest tests/test_login_access.py`;非白名单 curl 预检与 POST login 结论一致
|
||
- P1~P2:Playwright 或手动 — 侧栏往返服务器↔脚本,无整页白屏
|
||
- 安全:登出后 keep-alive 内无上一用户数据残留
|
||
|
||
## 回滚
|
||
|
||
各阶段可 git revert 独立 commit;P0 回滚不影响已登录会话。
|