Files

78 lines
4.3 KiB
Markdown
Raw Permalink Normal View History

# Changelog: 全站 bug 审查修复 (前端9项 + 后端5项)
**日期**: 2026-06-01
**变更摘要**: 全站巡检发现并修复 14 个 bug1 P0 + 9 P1 + 4 P2),涵盖前端全局搜索崩溃、TOTP登录流程断裂、服务器编辑域名污染、后端Redis阻塞、并发session竞态等
## 动机
对 Nexus 全站进行系统性 bug 审查,发现多个影响生产使用的问题。最严重的 3 个:全局搜索因 `http` 未导入直接崩溃、TOTP 双因素登录完全不可用、编辑服务器后域名被端口字符串污染导致后续连接失败。
## 涉及文件
| 文件 | 变更类型 | 说明 |
|------|----------|------|
| `frontend/src/App.vue` | 修改 | 添加 `http` 导入 |
| `frontend/src/pages/LoginPage.vue` | 修改 | TOTP异常捕获 + 锁定倒计时响应式 |
| `frontend/src/pages/ServersPage.vue` | 修改 | 编辑时 domain 不再拼接端口 |
| `frontend/src/pages/PushPage.vue` | 修改 | Set 索引 → 迭代器 |
| `frontend/src/pages/SettingsPage.vue` | 修改 | API字符串值转数字 |
| `frontend/src/api/index.ts` | 修改 | 删除重复 getList 定义 |
| `frontend/src/pages/TerminalPage.vue` | 修改 | 路径验证正则放松 |
| `frontend/src/composables/useWebSocket.ts` | 修改 | 关闭旧连接再建新连接 |
| `server/api/websocket.py` | 修改 | redis.keys → scan_iter |
| `server/application/services/auth_service.py` | 修改 | TTL 仅在无TTL时设置 |
| `server/api/servers.py` | 修改 | 批量操作加 asyncio.Lock |
| `server/api/settings.py` | 修改 | 弃用API替换 |
## 详细变更
### 前端 P0 修复
1. **App.vue `http` 未导入** — 第320行 `doSearch()` 调用 `http.get()` 但只导入了 `api`,导致 `ReferenceError: http is not defined`。修复:`import { api, http } from '@/api'`
### 前端 P1 修复
2. **TOTP 登录流程断裂**`api()` 在后端返回 202 时抛 `TotpRequiredError`(非 `ApiError` 子类),`LoginPage` catch 只检查 `e instanceof ApiError`TOTP 用户看到"网络错误"无法登录。修复:导入 `TotpRequiredError` 并在 catch 中优先检查
3. **ServersPage 编辑域名污染**`editServer()` 设置 `form.address = domain:port`,保存时 `domain: form.address` 发送含端口字符串。修复:`form.address = item.domain`
4. **PushPage Set 索引无效**`selectedIds.value[0]``Set<number>` 返回 `undefined`。修复:`selectedIds.value.values().next().value`
5. **SettingsPage 类型转换** — API 返回 `value: "80"` 字符串直接赋值给 number 字段。修复:正则检测纯数字字符串并 `Number()` 转换
### 前端 P2 修复
6. **api/index.ts 重复定义**`getList` 方法定义两次,删除第二个
7. **LoginPage 锁定倒计时**`remainingMinutes` computed 依赖 `Date.now()` 非响应式。修复:使用 `ref(Date.now())` + `watch(lockoutUntil)` + 30秒定时器
8. **TerminalPage 路径验证过严** — 正则 `/^[a-zA-Z0-9/._\-]+$/` 排除空格/中文/~。修复:`/^[^\x00-\x1f\x7f"']+$/` 仅排除控制字符和引号
9. **useWebSocket 连接泄漏** — CONNECTING/CLOSING 状态时创建新连接但不关闭旧连接。修复:关闭旧连接后再创建新的
### 后端 P1 修复
10. **websocket.py redis.keys() 阻塞**`KEYS` 命令 O(N) 扫描整个键空间。修复:`scan_iter(match="ws:count:*")` 非阻塞迭代
11. **auth_service.py TTL 重置** — 每次 `sadd``expire` 重置 TTL,频繁刷新的管理员 refresh token 键永不过期。修复:`ttl = await redis.ttl(key)`,仅在 `ttl < 0` 时设置 expire
12. **servers.py 并发 session commit** — 批量操作中 `asyncio.gather` 并发协程共享同一 db session 并 `commit()`。修复:添加 `asyncio.Lock()` 序列化 commit
### 后端 P2 修复
13. **settings.py asyncio.get_event_loop()** — Python 3.10+ 弃用。修复:`asyncio.get_running_loop()`
14. **settings.py datetime.utcfromtimestamp()** — Python 3.12+ 弃用。修复:`datetime.fromtimestamp(ts, tz=timezone.utc)`
## 是否需迁移/重启
- ✅ 需重启 — 后端代码变更
- ✅ 前端需重新构建部署
## 验证方式
1. 登录页 → 输入 admin/Nexus@2026 → 成功跳转仪表盘 ✓
2. 全局搜索框 → 输入"机器人" → 无崩溃(之前会 ReferenceError)✓
3. 控制台零错误 ✓
4. 健康检查 → `ok`