Files
webui4frpc/.zcode/plans/plan-sess_cf2ae9b7-2221-409b-b804-66d894f1b069.md
jianf b518a13446 feat: Phase C 完成 — ModelRouter 风格 UI 重设计 + 模拟 frps 测试 + lastSync 修复 + 集群作坊搭建
- 主题: sakura×frost 玻璃拟态 (theme.css) + SCSS 变量重映射
- 侧栏: 玻璃侧栏 246px + 渐变品牌区 + 面包屑导航
- 状态页: 玻璃 KPI 卡 + 远程节点/本地服务卡片网格
- 集群页: 英雄玻璃卡 + 横向环拓扑链 + 待办命令/活跃拓扑/日志区
- 令牌环: 新增 lastSync 上次同步时间替代周期计数
- 模拟 frps: frps2/frps3 容器 + test-forward.sh 全链路验证脚本
- 修复: BinaryPath 空导致 worker 不启动, 撤销仅撤第一个 link, 任务复活风暴 (published 追踪)
2026-08-18 23:38:20 +08:00

88 lines
8.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Phase C — ModelRouter 风格重设计 + 模拟 frps 转发下发测试
## 决策(用户未选择,依最佳判断)
- **视觉方向 = 忠实采用 sakura×frost 玻璃拟态**(ModelRouter 主色 #FF7FAC + 动态光斑背景 + KPI 卡 + cardIn 入场 + 渐变按钮)。在线/成功状态仍用绿色 #17a964(与 ModelRouter 一致,不破坏 webui4frpc "绿=在线" 语义)。不加强调色切换器/深色模式(控范围,可后续加)。
- **模拟 frps = 加 2 个真实 frps 容器**(frps2/frps3)+ 一个死地址 remote,写 `test-forward.sh` 验证 下发→claim→起 worker→连通 全链路。
---
## Part 1 — 主题令牌:theme.css + variables.scss(换成 sakura/frost)
**web/src/styles/theme.css**(重写 `:root` + 增全局组件类):
- 调色:`--w4f-primary:#FF7FAC; -h:#F33B7C; -50:#FFF0F5; -100:#FFE4E9; -200:#FFCDD9; -300:#FF9EB5`;`--w4f-secondary:#88C0D0; -h:#4C8DAE; -50:#F0F9FC`;`--w4f-danger:#DB3694; -50:#FEEAF6`;`--w4f-ok:#17a964; --w4f-warn:#b7791f; --w4f-info:#3f6ef5`。
- 表面/文字:`--w4f-bg-1:#eef2ff; -2:#fff; -3:#ffe9f0`;`--w4f-card:rgba(255,255,255,.60); -2:rgba(255,255,255,.42)`;`--w4f-line:rgba(255,127,172,.18); -strong:rgba(120,90,150,.22)`;`--w4f-fg:#3b3350; --w4f-muted:#7c7a95`。
- 光斑:`--w4f-blob1/2/3`(sakura/frost/pink 透明色)。
- 阴影:`--w4f-sh-sm/md/lg`(紫灰调 `rgba(120,90,160,..)`);`--w4f-glass:18px; --w4f-ease-spring:cubic-bezier(.34,1.56,.64,1)`。
- EP 覆盖:`--el-color-primary:#FF7FAC` + light-3/5/7/8/9 + dark-2;`--el-color-success:#17a964; danger:#DB3694;` 圆角/字体。
- body:14px/1.55 `Quicksand,Nunito,Inter,...` 字号栈(不联网加载 web 字体,用系统栈接近),letter-spacing .02em。
- **动态光斑背景**:`#bgfx` fixed + 3 `.blob` `filter:blur(64px)` + `@keyframes drift1/2/3`,`prefers-reduced-motion` 关动画。
- 全局类:`.w4f-card`(玻璃 + `cardIn` 入场动画)、`.w4f-kpi`(KPI 卡基座 k-lab+blink dot/k-val/k-sub/k-chart 位)、`.w4f-bar`(5px 渐变条)、`.w4f-tag` 变体、`.w4f-btn`(渐变主按钮 + ghost/danger/small 变体)、sakura 滚动条。
**web/src/styles/variables.scss**(SCSS 变量重映射,保持视图内 `$color-*` 自动跟随):
- `$color-primary:#FF7FAC; -h:#F33B7C; -50:#FFF0F5; -100:#FFE4E9`;`$color-secondary:#88C0D0; -50:#F0F9FC`;`$color-success:#17a964`(保绿);`$color-danger:#DB3694; -50:#FEEAF6`;`$color-info:#3f6ef5`。
- 文字色换紫灰调(primary #3b3350 / secondary #5a5470 / muted #7c7a95 / light #9c98b0);glass/shadow/radius/ease 对齐 theme.css。
## Part 2 — App.vue:玻璃侧栏 + 光斑背景层 + 面包屑
- 模板加 `<div class="bgfx" aria-hidden="true"><i class="blob b1"/><i class="blob b2"/><i class="blob b3"/></div>` 作固定背景(z-index -10)。
- 侧栏 246px 玻璃(`backdrop-filter:blur(glass*.7) saturate(1.3)`),品牌区渐变 logo 方块 "W"(渐变 primary→secondary + 阴影),nav item active = ModelRouter 渐变瓦片(`linear-gradient(120deg,primary-50,secondary-50)` + primary-h 文字 + sh-sm,而非当前整块填色);footer 活跃点 + "token-ring · M6" 药丸。
- 内容区顶部加 `.breadcrumb` 显示当前视图名(状态/连接配置/设置/集群),对齐 ModelRouter 布局。
- `.content` 滚动区,各视图自带内边距。
## Part 3 — StatusView.vue 重设计
- 顶栏玻璃卡:面包屑标题 + "每 5 秒自动刷新" + 刷新(ghost) + 添加远程节点(渐变 primary)。
- **KPI 网格**(auto-fit minmax 168px):远程节点数(sub: 在线 X)、在线 worker 数、本地服务数、活跃转发数。每卡 k-lab+blink dot、k-val 27px tabular-nums、k-sub。
- 远程节点卡:玻璃 + cardIn,左边框色按健康(绿/红),名称 + 连接药丸(ok 绿/pending 青/err 红点),操作按钮(启=渐变 / 停=ghost / 编辑=ghost / 删=danger small),meta(pid/err/vhost 药丸),forwards 药丸 chips,per-proxy 行带 5px bar 指示。
- 本地服务卡:玻璃,proto 药丸,targets 带 → + 状态药丸。
- el-dialog 沿用(EP 覆盖自动 sakura 化)。
## Part 4 — ClusterView.vue 重设计
- Hero 玻璃卡:渐变标题 + sub,状态药丸(运行中=绿点 blink / 待加入=青 / 已脱离=红)+ 成员数 + 周期 + leader ♔。
- **KPI 行**:成员数、活跃转发、待办命令、周期。
- 操作工具条:创建集群(渐变 primary) / 加入…(ghost) / 退出(danger) / 刷新(ghost small),保留既 `!isMember`/`isMember` 安全门。
- 环拓扑:横向玻璃节点卡链,leader=青调 + 边框、self=sakura 高亮发光、dead=红暗;负载 bar;addr mono;移除按钮(small danger);→ 箭头。
- 待办命令/活跃拓扑/集群日志:玻璃卡 + sticky 表头 + 药丸标签(新增 sakura / 撤销·移除 danger / owner self=sakura)+ 彩色 kind 徽章 + self 高亮,全部 cardIn 入场。
- 保留加入 el-dialog。
## Part 5 — 模拟 frps 节点 + 转发下发测试
**新增 frps 配置 + 容器**:
- `deploy/frps2.toml`:bindPort 7001, vhostHTTPPort 7081, auth.token=demo-token。
- `deploy/frps3.toml`:bindPort 7002, vhostHTTPPort 7082, auth.token=demo-token。
- `deploy/run-cluster.sh` 增启动 `w4f-frps2`(--network-alias frps2, -p 7001:7001 -p 7081:7081) 与 `w4f-frps3`(alias frps3, -p 7002:7002 -p 7082:7082)。
- `deploy/compose.yaml` 增 frps2/frps3 服务(compose 用户同步)。
- `deploy/start-mock-frps.sh`:仅启 frps2/frps3(先 `docker rm -f` 这两个再 run),供集群已起时补启。
**`deploy/test-forward.sh`**(核心验证脚本,Basic Auth admin:admin123):
1. 确认 ring:`GET node-a:7501 /cluster/ring` 断言 3 节点。
2. 快照原 canvas:`GET node-a /canvas` 存原始 `{locals,remotes,links}`。
3. 创建 4 条转发(`PUT node-a /canvas`,localOnly=false,local.ip=`backend` docker DNS,port 8080):
- `fwd-frps1` → remote frps:7000, remotePort 18091
- `fwd-frps2` → remote frps2:7001, remotePort 18092
- `fwd-frps3` → remote frps3:7002, remotePort 18093
- `fwd-dead` → remote 192.0.2.1:7000, remotePort 18094(死地址:验下发+起 worker,conn 失败)
4. 轮询 `GET /cluster/ring`(1s×~25):断言 4 条 pending→0 且 topology 出现 4 条带 ownerId;打印每条由谁 claim(最低负载)。
5. 轮询各 owner `GET /status`:断言对应 remote process.state=running。
6. 轮询 owner `GET /profiles/{remote}/logs`:真实 frps 断言含 `login to server success`;dead 断言 worker running 但 connState=failed。
7. 撤销测试:`PUT /canvas` 还原为步骤2快照(移除我们的 locals)→ 轮询 topology 4 条消失 + owner /status worker 已停。
8. 打印结果表(task / target / claimed-by / worker / conn / 结论)。
9. 清理:canvas 已在步骤7还原;不删容器。
**验证连通可选项**:真实 frps 的 vhost/remotePort 不映射到宿主(dispatch 验证不需打隧道);如需端到端打隧道验证,可 `docker exec` 在 net 内 curl `frps2:18092` 命中 backend——纳入脚本 step 6.5。
## Part 6 — 构建 + 验证
1. `cd web && npm run build`
2. 同步前端:`rm -rf internal/httpapi/dist && cp -r web/dist internal/httpapi/dist`
3. `go build -o deploy/artifacts/webui4frpc ./cmd/webui4frpc`
4. 起/刷集群:`bash deploy/run-cluster.sh`(或既有集群:`bash deploy/start-mock-frps.sh && docker restart w4f-node-a w4f-node-b w4f-node-c`)
5. `bash deploy/test-forward.sh` —— 验证转发下发链路
6. **视觉验证**(直击"太丑"反馈):用浏览器打开 `http://localhost:7501`(admin/admin123),截图 状态页 + 集群页,对照 ModelRouter 确认 光斑背景/玻璃 KPI 卡/渐变按钮/入场动画 到位。若不符则迭代。
## 影响文件
- 主题:`web/src/styles/theme.css`(重写)、`web/src/styles/variables.scss`(重映射)
- 壳:`web/src/App.vue`(侧栏+光斑+面包屑)
- 视图:`web/src/views/StatusView.vue`、`web/src/views/ClusterView.vue`(重设计)
- 部署:`deploy/frps2.toml`、`deploy/frps3.toml`(新)、`deploy/run-cluster.sh`、`deploy/compose.yaml`、`deploy/start-mock-frps.sh`(新)、`deploy/test-forward.sh`(新)