1739f7a2f9
为 server/manage/getNodes 返回节点级今日、本月与累计流量统计, 并在节点管理页名称悬浮层展示上行、下行和合计流量。 同时为自动上线补齐单节点同步入口,在管理端保存、 批量更新以及 REST/WS 心跳后立即同步 show 状态, 避免复制节点后开启自动上线仍需等待定时任务。 另优化管理端前端 Docker 发布流程,默认仅构建 amd64, 并收敛 BuildKit 缓存导出以缩短发布时间
150 lines
6.5 KiB
Markdown
150 lines
6.5 KiB
Markdown
# 变更提案: admin-frontend-node-auto-online-immediate-sync
|
||
|
||
## 元信息
|
||
```yaml
|
||
类型: 修复
|
||
方案类型: implementation
|
||
优先级: P1
|
||
状态: 已规划
|
||
创建: 2026-04-28
|
||
```
|
||
|
||
---
|
||
|
||
## 1. 需求
|
||
|
||
### 背景
|
||
节点管理页复制节点后,新节点会保留原节点的 `auto_online` 状态但被复制接口强制设为隐藏。管理员修改新节点信息并安装节点后,即使自动上线处于开启状态,节点也不会立即显示,需要手动关闭自动上线、打开显隐、再重新开启自动上线。
|
||
|
||
代码事实:
|
||
- `ManageController::copy()` 复制节点后设置 `show = 0`。
|
||
- `NodeEditorDialog` 保存会提交 `show` 与 `auto_online`,但后端 `save()` 只落库,不主动执行自动上线同步。
|
||
- `ServerAutoOnlineService::sync()` 目前只由 `sync:server-auto-online` 定时命令每 5 分钟调用。
|
||
- REST 节点心跳 `ServerService::touchNode()` 只更新在线缓存,不会触发自动上线同步;WebSocket 状态上报还绕过了 `touchNode()` 直接写缓存。
|
||
|
||
### 目标
|
||
- 自动上线开启的节点在管理端保存、开启自动上线或节点心跳上报后,立即按当前在线状态和墙检测状态同步 `show`。
|
||
- 保持现有定时任务兜底能力,避免依赖管理员手动切换显隐。
|
||
- 保持墙检测自动隐藏规则不被绕过。
|
||
|
||
### 约束条件
|
||
```yaml
|
||
时间约束: 无
|
||
性能约束: 单节点心跳只能同步当前节点,不能触发全量扫描
|
||
兼容性约束: 保持 sync:server-auto-online 命令输出结构不变
|
||
业务约束: 自动上线仍以 available_status 和墙状态为准;未开启 auto_online 的节点不改变手动显隐
|
||
```
|
||
|
||
### 验收标准
|
||
- [ ] `ServerAutoOnlineService` 支持单节点同步,并复用定时全量同步的同一套判定逻辑。
|
||
- [ ] 管理端保存节点、开启自动上线、批量开启自动上线后,若节点当前为在线或待同步且未被墙检测否决,应立即 `show=1`。
|
||
- [ ] 节点心跳上报后,若该节点开启自动上线,应立即同步 `show`,不必等待 Scheduler。
|
||
- [ ] 被墙状态或 `gfw_auto_hidden` 未恢复正常时,自动上线不会把节点重新显示。
|
||
- [ ] 单元测试覆盖单节点同步和心跳触发场景。
|
||
|
||
---
|
||
|
||
## 2. 方案
|
||
|
||
### 技术方案
|
||
将 `ServerAutoOnlineService` 中的自动上线判定抽出为可复用的 `syncServer(Server $server)` 单节点入口。全量定时命令继续调用 `sync()`,内部复用同一判定函数。
|
||
|
||
在两个关键触发点调用单节点同步:
|
||
- 管理端 `ManageController` 的 `save()`、`update()`、`batchUpdate()` 在节点开启 `auto_online` 后立即调用。
|
||
- `ServerService::touchNode()` 在节点心跳刷新后,如果节点开启 `auto_online`,立即调用;WebSocket 状态上报改为复用 `touchNode()`。
|
||
|
||
### 影响范围
|
||
```yaml
|
||
涉及模块:
|
||
- server-auto-online: 抽取单节点同步入口,复用全量同步逻辑
|
||
- admin-server-manage: 保存/开关/批量更新自动上线时立即同步
|
||
- server-heartbeat: REST 与 WebSocket 节点心跳后触发当前节点同步
|
||
- tests: 补充自动上线单节点与心跳行为验证
|
||
预计变更文件: 5
|
||
```
|
||
|
||
### 风险评估
|
||
| 风险 | 等级 | 应对 |
|
||
|------|------|------|
|
||
| 节点心跳频繁导致额外数据库写入 | 中 | 只在 `auto_online=true` 时执行;状态无变化时不保存 |
|
||
| 保存接口中 `show` 与 `auto_online` 同时提交时语义冲突 | 低 | 自动上线开启时以自动同步判定为准,符合 UI 中显隐开关被托管的文案 |
|
||
| 墙检测自动隐藏被误清除 | 中 | 单节点同步复用原有 `isGfwBlocked/isGfwHeld` 判定,只在正常状态时清除 hold |
|
||
|
||
### 方案取舍
|
||
```yaml
|
||
唯一方案理由: 问题根因在后端自动上线语义只由定时任务触发;把同步能力收敛到服务层并在业务事件中调用,可以同时覆盖管理端保存、开关和节点真实上线心跳。
|
||
放弃的替代路径:
|
||
- 仅前端保存后强制提交 show=1: 会绕过离线/被墙判断,且无法覆盖节点稍后才心跳上线的场景。
|
||
- 缩短 Scheduler 间隔: 仍不是立即上线,并增加全量扫描频率。
|
||
- 复制节点时默认关闭 auto_online: 会改变复制语义,仍要求管理员额外操作。
|
||
回滚边界: 可独立回退 ServerAutoOnlineService 单节点入口、ManageController 调用点和 ServerService::touchNode 调用点;数据库结构不变。
|
||
```
|
||
|
||
---
|
||
|
||
## 3. 技术设计
|
||
|
||
### 架构设计
|
||
```mermaid
|
||
flowchart TD
|
||
A[管理端保存/开启自动上线] --> B[ManageController]
|
||
C[REST/WS 节点心跳上报] --> D[ServerService::touchNode]
|
||
B --> E[ServerAutoOnlineService::syncServer]
|
||
D --> E
|
||
F[sync:server-auto-online] --> G[ServerAutoOnlineService::sync]
|
||
G --> E
|
||
E --> H[按 available_status + GFW 状态同步 show]
|
||
```
|
||
|
||
### API 设计
|
||
不新增外部 API。现有接口保持不变:
|
||
- `POST /server/manage/save`
|
||
- `POST /server/manage/update`
|
||
- `POST /server/manage/batchUpdate`
|
||
- 节点心跳/报告接口
|
||
|
||
### 数据模型
|
||
不新增字段。
|
||
|
||
---
|
||
|
||
## 4. 核心场景
|
||
|
||
### 场景: 复制节点后自动上线立即生效
|
||
**模块**: admin-frontend / server-auto-online
|
||
**条件**: 新节点由复制产生,`show=0`,`auto_online=1`,节点已经心跳在线且未被墙检测否决。
|
||
**行为**: 管理员在节点管理页编辑并保存该节点。
|
||
**结果**: 后端保存后立即执行单节点自动上线同步,节点 `show=1`,前端刷新列表后显示为上线。
|
||
|
||
### 场景: 节点稍后才上线
|
||
**模块**: server-heartbeat / server-auto-online
|
||
**条件**: 节点保存时尚未心跳,`auto_online=1`,`show=0`。
|
||
**行为**: 节点安装完成并上报心跳。
|
||
**结果**: REST 与 WebSocket 心跳都会通过 `touchNode()` 更新在线缓存并立即同步当前节点,节点不需要等待下一轮 Scheduler。
|
||
|
||
---
|
||
|
||
## 5. 验证策略
|
||
|
||
```yaml
|
||
verifyMode: test-first
|
||
reviewerFocus:
|
||
- app/Services/ServerAutoOnlineService.php 单节点与全量同步是否共用判定逻辑
|
||
- app/Services/ServerService.php 与 app/WebSocket/NodeEventHandlers.php 心跳触发是否只影响 auto_online 节点
|
||
- app/Http/Controllers/V2/Admin/Server/ManageController.php 管理端更新后的同步时机
|
||
testerFocus:
|
||
- vendor/bin/phpunit tests/Unit/ServerAutoOnlineServiceTest.php
|
||
- npm --prefix admin-frontend run build
|
||
uiValidation: none
|
||
riskBoundary:
|
||
- 不修改数据库结构
|
||
- 不修改节点列表视觉结构
|
||
- 不改变未开启 auto_online 节点的手动显隐行为
|
||
```
|
||
|
||
---
|
||
|
||
## 6. 成果设计
|
||
|
||
N/A。此任务不包含视觉产出。
|