diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f61d3f..bdeb8aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,23 @@ All notable changes to this project will be documented in this file. +## [v1.6.1] - 2026-09-28 + +### 修复 + +- **Cloudflare 隧道弹窗完善**:编辑弹窗回填已配置的暴露域名与回源 service(后端从 `config.yml` 解析);按「基本信息 / 暴露规则 / 网络调优」分组,增加模式说明;云端规则模式隐藏本地域名配置并提示规则由 Cloudflare 面板管理 +- **详情弹窗**:改为状态卡 + `config.yml` / 日志分页,日志每 3 秒自动刷新,支持一键复制配置,刷新按钮带加载状态 +- **二进制弹窗**:显示当前版本与目标文件;镜像列表为空时回退官方源 +- **保存校验**:提交前校验名称、token 与本地规则模式的暴露域名 + +### 变更 + +- 版本号提升到 1.6.1;`AgentVersion` 保持 **0.14.1**,本次无 Agent 行为变化 + +### 测试 + +- `go test ./...`、`go vet ./...`、`npm run typecheck`、`npm test`、`npm run build` 通过 + ## [v1.6.0] - 2026-09-28 ### 新增 diff --git a/VERSION b/VERSION index dc1e644..9c6d629 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.6.0 +1.6.1 diff --git a/docs/README.md b/docs/README.md index 20d9782..7ae752f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,7 +1,7 @@ # Fonu 文档索引 > 维护约定:新增方案 / 审查文档时在下方登记;方案落地后在「状态」列标注实施结果,并给已被推翻的描述加时效说明。 -> 最近更新:2026-09-28(v1.6.0) +> 最近更新:2026-09-28(v1.6.1) ## 方案与设计(本目录) diff --git a/docs/system-upgrade.md b/docs/system-upgrade.md index 6e69930..ad3a8aa 100644 --- a/docs/system-upgrade.md +++ b/docs/system-upgrade.md @@ -238,16 +238,16 @@ FONU_VERSION=<旧版本> docker compose up -d --no-deps --force-recreate fonu ## 10. 在线升级验证 -示例页面用于验证升级结果。v1.6.0 的验证流程: +示例页面用于验证升级结果。v1.6.1 的验证流程: 1. 确认当前线上实例为 v1.3.0,且 `fonu-updater` sidecar 已运行。 -2. 确认远端 `main` 分支的 `VERSION` 为 `1.6.0`。 +2. 确认远端 `main` 分支的 `VERSION` 为 `1.6.1`。 3. 在侧栏看到「一键升级」后点击并确认。 4. 等待升级弹窗显示成功,页面自动刷新。 5. 打开侧栏「示例页面」,确认: - 页面路由为 `/example`; - - 页面显示的版本为 `1.6.0`; - - 页面显示验证标识 `v1.6.0-example-page`; + - 页面显示的版本为 `1.6.1`; + - 页面显示验证标识 `v1.6.1-example-page`; - 页面显示独立的「本次升级验证」区块; - 「升级验证」显示为「通过」。 diff --git a/internal/cloudflared/model.go b/internal/cloudflared/model.go index 8126eb6..02e921a 100644 --- a/internal/cloudflared/model.go +++ b/internal/cloudflared/model.go @@ -53,6 +53,8 @@ type Tunnel struct { LastError string `json:"last_error"` MetricsPort int `json:"metrics_port"` AutoStart bool `json:"auto_start"` + Hostnames []string `json:"hostnames"` + OriginService string `json:"origin_service"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } diff --git a/internal/cloudflared/service.go b/internal/cloudflared/service.go index dd756a1..b9600ee 100644 --- a/internal/cloudflared/service.go +++ b/internal/cloudflared/service.go @@ -48,11 +48,23 @@ func (s *Service) EnsureDirs() error { } func (s *Service) List(ctx context.Context) ([]Tunnel, error) { - return s.store.List(ctx) + items, err := s.store.List(ctx) + if err != nil { + return nil, err + } + for i := range items { + s.attachConfig(&items[i]) + } + return items, nil } func (s *Service) Get(ctx context.Context, id int64) (Tunnel, error) { - return s.store.Get(ctx, id) + item, err := s.store.Get(ctx, id) + if err != nil { + return Tunnel{}, err + } + s.attachConfig(&item) + return item, nil } // Create 解析 token、生成 creds.json 与 config.yml,并写入数据库。 @@ -158,13 +170,13 @@ func (s *Service) Start(ctx context.Context, id int64) (Tunnel, error) { return Tunnel{}, err } _ = s.store.SetRuntime(ctx, id, "starting", "", 0) - return s.store.Get(ctx, id) + return s.Get(ctx, id) } func (s *Service) Stop(ctx context.Context, id int64) (Tunnel, error) { _ = s.manager.Stop(id) _ = s.store.SetRuntime(ctx, id, "stopped", "", 0) - return s.store.Get(ctx, id) + return s.Get(ctx, id) } func (s *Service) Restart(ctx context.Context, id int64) (Tunnel, error) { @@ -179,6 +191,33 @@ func (s *Service) RuntimeStatus(ctx context.Context, id int64) (RuntimeStatus, e return s.manager.Status(id), nil } +// attachConfig 从 config.yml 回填域名与回源 service,供编辑弹窗使用。 +func (s *Service) attachConfig(item *Tunnel) { + data, err := os.ReadFile(item.ConfigPath) + if err != nil { + return + } + lines := strings.Split(string(data), "\n") + for i, raw := range lines { + line := strings.TrimSpace(raw) + host, found := strings.CutPrefix(line, "- hostname:") + if !found { + continue + } + host = strings.TrimSpace(host) + if host == "" { + continue + } + item.Hostnames = append(item.Hostnames, host) + if i+1 >= len(lines) { + continue + } + if service, ok := strings.CutPrefix(strings.TrimSpace(lines[i+1]), "service:"); ok && item.OriginService == "" { + item.OriginService = strings.TrimSpace(service) + } + } +} + func (s *Service) Logs(ctx context.Context, id int64, lines int) (string, error) { tunnel, err := s.store.Get(ctx, id) if err != nil { diff --git a/web/package-lock.json b/web/package-lock.json index 6d1654a..ea013ea 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -1,12 +1,12 @@ { "name": "fonu-web", - "version": "1.6.0", + "version": "1.6.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "fonu-web", - "version": "1.6.0", + "version": "1.6.1", "dependencies": { "@codemirror/commands": "^6.11.1", "@codemirror/lang-javascript": "^6.2.5", diff --git a/web/package.json b/web/package.json index 17822bf..3e455ff 100644 --- a/web/package.json +++ b/web/package.json @@ -1,7 +1,7 @@ { "name": "fonu-web", "private": true, - "version": "1.6.0", + "version": "1.6.1", "packageManager": "npm@10.9.4", "type": "module", "scripts": { diff --git a/web/src/api/types.ts b/web/src/api/types.ts index 13dd9a4..444f3d4 100644 --- a/web/src/api/types.ts +++ b/web/src/api/types.ts @@ -1064,6 +1064,8 @@ export interface CfTunnel { last_error?: string metrics_port?: number auto_start: boolean + hostnames?: string[] + origin_service?: string created_at: string updated_at: string } diff --git a/web/src/views/CloudflareView.vue b/web/src/views/CloudflareView.vue index 9a433f3..8322f0b 100644 --- a/web/src/views/CloudflareView.vue +++ b/web/src/views/CloudflareView.vue @@ -38,32 +38,39 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - +
+ + {{ modeHint }} + + 基本信息 + + + + + + + + 暴露规则 + + + + + + + + + + 云端规则模式下,本地域名与回源配置不生效,请在 Cloudflare 面板管理 ingress。 + + 网络调优 + + + + + + + +
- +
-
- - 连接数 {{ detailStatus?.connections ?? 0 }} - 延迟 {{ (detailStatus?.latency_ms ?? 0).toFixed(0) }} ms - {{ detailStatus?.transport || '—' }} +
+
+
{{ detailStatus?.connections ?? 0 }}
+
{{ (detailStatus?.latency_ms ?? 0).toFixed(0) }} ms
+
{{ detailStatus?.transport || '—' }}
+
{{ detailStatus?.metrics_port || '—' }}

{{ detailStatus.bandwidth_notice }}

-

config.yml

-
{{ detailConfig || '暂无配置' }}
-

日志

-
{{ detailLogs || '暂无日志' }}
+ + +
复制
+
{{ detailConfig || '暂无配置' }}
+
+ +
刷新
+
{{ detailLogs || '暂无日志' }}
+
+
- - {{ binaryVersion || '未安装' }} - - - - +
+
+
{{ binaryVersion || '未安装' }}
+
cloudflared
+
+ + + + + +

下载后会校验文件大小与可执行性,并原子替换现有二进制。国内环境推荐 gh-proxy 镜像。

+