mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-01 22:46:38 +08:00
migrate frontend
This commit is contained in:
@@ -41,6 +41,8 @@ sidebar: false
|
||||
- 将 OpenFlare 管理控制台从 `openflare-server/web` 迁移至 `Wavelet/frontend/app/(main)/openflare/`,复用 Wavelet shadcn 组件与 Session 鉴权;新增 `LegacyOpenFlareBaseService` 对接 `/api/*` 业务 API。
|
||||
- 实装节点、代理规则(6 Section)、配置发布、WAF、网站/证书/DNS、Pages、源站、访问/应用日志、仪表盘、性能调优等业务页面;Admin 设置新增 OpenFlare 运维扩展 Tab。
|
||||
- 修复静态导出构建中 `useSearchParams` 未包裹 Suspense 的问题;`pnpm build:embed` 全量 46 页通过。
|
||||
- 补全前端迁移收尾:新增 `/openflare/about` 关于页与 `AboutService`;补全 `UpdateService` 升级流程(在线升级、手动上传、WebSocket 日志流)及顶栏版本升级入口。
|
||||
- 前端 UI 打磨:节点/WAF/DNS/配置清理等 Dialog 补 RHF+Zod;代理规则详情与访问日志 Tab 补 error 态;`pnpm build:embed` 增至 47 静态页。
|
||||
|
||||
## [v2.3.4] - 2026-06-17
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
> **文档类型**:实现计划(Implementation Plan)
|
||||
> **创建日期**:2026-06-18
|
||||
> **状态**:基本完成(FC-1~19 已实装;验证见 `docs/plan/verify-frontend-*.md`)
|
||||
> **状态**:✅ 迁移完成(FC-1~20 已实装;验证见 `docs/plan/verify-frontend-*.md`)
|
||||
> **前置阅读**:[`Wavelet/AGENTS.md`](../../Wavelet/AGENTS.md)、[`docs/plan/20260618-openflare-wavelet-backend-migration.md`](./20260618-openflare-wavelet-backend-migration.md)
|
||||
> **依赖**:后端阶段一(旧路径 `/api/*` 兼容)完成后启动;阶段二可与后端阶段五并行
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# OpenFlare 前端迁移 — 任务拆分与 AI 委派
|
||||
|
||||
> **状态**:基本完成(验证通过,少量 P1 打磨待办)
|
||||
> **状态**:✅ 迁移完成(多角度验证通过;P2 可选打磨待办)
|
||||
> **目标前端**:`Wavelet/frontend/`(Next.js 16 + shadcn/ui + Session 鉴权)
|
||||
> **验证报告**:[`verify-frontend-routes.md`](./verify-frontend-routes.md)、[`verify-frontend-services.md`](./verify-frontend-services.md)、[`verify-frontend-ui.md`](./verify-frontend-ui.md)、[`verify-frontend-build.md`](./verify-frontend-build.md)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
| F-NODE | 节点(含 Relay/Tunnel 详情) | ✅ |
|
||||
| F-PROXY | 代理规则(含 6 Section 实装) | ✅ |
|
||||
| F-CFG | 配置发布 + 应用日志 | ✅ |
|
||||
| F-DASH | 总览仪表盘 | ✅(缺世界地图) |
|
||||
| F-DASH | 总览仪表盘 | ✅(缺世界地图,P2) |
|
||||
| F-WAF | WAF 规则组 + IP 组 | ✅ |
|
||||
| F-WEB | 网站/证书/DNS | ✅ |
|
||||
| F-PAGES | Pages 托管 | ✅ |
|
||||
@@ -21,6 +21,8 @@
|
||||
| F-PERF | 性能调优 | ✅ |
|
||||
| F-ADMIN | Admin 运维设置扩展 | ✅ |
|
||||
| F-AUTH | Wavelet 登录/用户复用 | ✅(原生,未改登录页) |
|
||||
| F-ABOUT | About 页(FC-20) | ✅ |
|
||||
| F-UPDATE | 服务升级 UI + UpdateService | ✅ |
|
||||
|
||||
## 验证结果摘要
|
||||
|
||||
@@ -28,16 +30,17 @@
|
||||
|---|---|
|
||||
| `tsc --noEmit` | ✅ |
|
||||
| `pnpm lint` | ✅ |
|
||||
| `pnpm build:embed` | ✅(46 静态页;已修 Suspense) |
|
||||
| 路由覆盖 FC-1~19 | ✅ 18 完整 + 1 部分 |
|
||||
| Service 覆盖 | ⚠️ `update` 升级流程待补 |
|
||||
| `pnpm build:embed` | ✅(47 静态页) |
|
||||
| 路由覆盖 FC-1~20 | ✅ 20/20 文件(FC-1 世界地图 P2) |
|
||||
| Service 覆盖 | ✅ 100% |
|
||||
| UI 规范 | ✅ PASS |
|
||||
|
||||
## 剩余 P1 待办
|
||||
## P2 可选待办
|
||||
|
||||
1. **FC-20** About 页或链到 `/docs`
|
||||
2. **UpdateService** 补全 upgrade/manual-upload/WS 日志
|
||||
3. **UI 打磨**:部分 Dialog 补 Zod;access-logs/proxy-detail error 态
|
||||
4. **FC-1** 世界地图(可选,当前用 geo 列表)
|
||||
1. **FC-1** 世界地图(当前用 geo 列表)
|
||||
2. **UI 打磨** — proxy 列表 error 态、access-logs cleanup Zod、node-observability error
|
||||
3. **废弃旧前端** — 移除 `openflare-server/web` 引用(阶段五)
|
||||
4. **E2E** — Playwright 核心路径
|
||||
|
||||
## 验收命令
|
||||
|
||||
|
||||
@@ -10,17 +10,16 @@
|
||||
|------|---------|-----------|--------|
|
||||
| TypeScript | `pnpm exec tsc --noEmit` | **0** | ✅ Pass |
|
||||
| Lint | `pnpm lint` | **0** | ✅ Pass |
|
||||
| Production build | `pnpm build:embed` | **1** | ❌ Fail |
|
||||
| Standard build | `pnpm build` | **1** | ❌ Fail (same error) |
|
||||
| Production build | `pnpm build:embed` | **0** | ✅ Pass |
|
||||
|
||||
**Overall:** TypeScript and lint are clean. Both build targets fail during static page generation due to a missing React `Suspense` boundary around `useSearchParams()`.
|
||||
**Overall:** All three gates pass. Static export completed with **47/47** pages generated.
|
||||
|
||||
---
|
||||
|
||||
## 1. TypeScript (`pnpm exec tsc --noEmit`)
|
||||
|
||||
- **Exit code:** `0`
|
||||
- **Duration:** ~6.2s
|
||||
- **Duration:** ~16.2s
|
||||
- **Errors:** None
|
||||
- **Warnings:** None
|
||||
|
||||
@@ -29,7 +28,7 @@
|
||||
## 2. ESLint (`pnpm lint`)
|
||||
|
||||
- **Exit code:** `0`
|
||||
- **Duration:** ~5.6s
|
||||
- **Duration:** ~24.4s
|
||||
- **Command:** `eslint` (no extra args)
|
||||
- **Errors:** None
|
||||
- **Warnings:** None
|
||||
@@ -40,112 +39,100 @@
|
||||
|
||||
**Production target:** `build:embed` — sets `NEXT_STANDALONE_EXPORT=true`, which enables `output: 'export'` in `next.config.ts` for static export embedded in the Go backend.
|
||||
|
||||
- **Exit code:** `1`
|
||||
- **Duration:** ~57s (compile ~29.5s, TypeScript check ~23.9s)
|
||||
- **Exit code:** `0`
|
||||
- **Duration:** ~72s (compile ~44s, TypeScript check ~20.1s, static generation ~2.2s)
|
||||
|
||||
### Build progress
|
||||
|
||||
- ✅ Compiled successfully
|
||||
- ✅ TypeScript check passed during build
|
||||
- ❌ Static page generation failed at **0/46** pages
|
||||
- ✅ Static page generation completed at **47/47** pages
|
||||
|
||||
### Error
|
||||
### Warnings
|
||||
|
||||
```
|
||||
⨯ useSearchParams() should be wrapped in a suspense boundary at page "/openflare/nodes".
|
||||
Read more: https://nextjs.org/docs/messages/missing-suspense-with-csr-bailout
|
||||
|
||||
Error occurred prerendering page "/openflare/nodes".
|
||||
Export encountered an error on /(main)/openflare/nodes/page: /openflare/nodes, exiting the build.
|
||||
⨯ Next.js build worker exited with code: 1 and signal: null
|
||||
⚠ Statically exporting a Next.js application via `next export` disables API routes and middleware.
|
||||
This command is meant for static-only hosts, and is not necessary to make your application static.
|
||||
Pages in your application without server-side data dependencies will be automatically statically exported by `next build`, including pages powered by `getStaticProps`.
|
||||
Learn more: https://nextjs.org/docs/messages/api-routes-static-export
|
||||
```
|
||||
|
||||
### Affected files
|
||||
### Static pages (47 routes)
|
||||
|
||||
| File | Issue |
|
||||
|------|-------|
|
||||
| `app/(main)/openflare/nodes/page.tsx` | `useSearchParams()` at line 36 (page default export) |
|
||||
| `app/(main)/openflare/nodes/components/node-type-filter.tsx` | `useSearchParams()` at line 57 (rendered inside nodes page) |
|
||||
| Route |
|
||||
|-------|
|
||||
| `/` |
|
||||
| `/_not-found` |
|
||||
| `/admin/database` |
|
||||
| `/admin/demo` |
|
||||
| `/admin/files` |
|
||||
| `/admin/logs` |
|
||||
| `/admin/push` |
|
||||
| `/admin/settings` |
|
||||
| `/admin/system` |
|
||||
| `/admin/tasks` |
|
||||
| `/admin/users` |
|
||||
| `/docs/api` |
|
||||
| `/docs/how-to-use` |
|
||||
| `/docs/privacy-policy` |
|
||||
| `/docs/terms-of-service` |
|
||||
| `/files` |
|
||||
| `/home` |
|
||||
| `/icon` |
|
||||
| `/login` |
|
||||
| `/openflare` |
|
||||
| `/openflare/about` |
|
||||
| `/openflare/access-logs` |
|
||||
| `/openflare/apply-logs` |
|
||||
| `/openflare/config-versions` |
|
||||
| `/openflare/nodes` |
|
||||
| `/openflare/nodes/detail` |
|
||||
| `/openflare/origins` |
|
||||
| `/openflare/origins/detail` |
|
||||
| `/openflare/pages` |
|
||||
| `/openflare/pages/detail` |
|
||||
| `/openflare/performance` |
|
||||
| `/openflare/proxy-routes` |
|
||||
| `/openflare/proxy-routes/detail` |
|
||||
| `/openflare/waf` |
|
||||
| `/openflare/waf/ip-groups` |
|
||||
| `/openflare/websites` |
|
||||
| `/openflare/websites/certificates` |
|
||||
| `/openflare/websites/detail` |
|
||||
| `/openflare/websites/dns-accounts` |
|
||||
| `/register` |
|
||||
| `/settings` |
|
||||
| `/settings/access-token` |
|
||||
| `/settings/appearance` |
|
||||
| `/settings/notifications` |
|
||||
| `/settings/profile` |
|
||||
| `/settings/security` |
|
||||
|
||||
### Build output size
|
||||
|
||||
Not available — build aborted before artifact generation completed.
|
||||
All routes prerendered as static content (`○`). Middleware proxy is present but not exported in static mode (expected).
|
||||
|
||||
---
|
||||
|
||||
## 4. Standard Build (`pnpm build`)
|
||||
## Notes
|
||||
|
||||
Ran for comparison (uses rewrites instead of static export).
|
||||
|
||||
- **Exit code:** `1`
|
||||
- **Duration:** ~65s
|
||||
- **Error:** Identical `useSearchParams()` / missing `Suspense` failure on `/openflare/nodes`
|
||||
- Initial `pnpm build:embed` attempt failed with "Another next build process is already running" due to a stale `.next/lock` from a concurrent build. Lock cleared and build re-run successfully.
|
||||
- Previous verification on this date documented a `useSearchParams()` / missing `Suspense` failure on `/openflare/nodes`. That issue is no longer present in the current tree.
|
||||
|
||||
---
|
||||
|
||||
## Root Cause
|
||||
## CI Gate (recommended)
|
||||
|
||||
Next.js 16 requires `useSearchParams()` to be used inside a `<Suspense>` boundary when pages are statically prerendered/exported. The nodes page is a client component that calls `useSearchParams()` directly in both the page and a child component (`NodeTypeFilter`).
|
||||
|
||||
Other pages in the codebase already follow the correct pattern:
|
||||
|
||||
- `app/(auth)/login/page.tsx` — wraps content in `<Suspense>`
|
||||
- `app/(auth)/register/page.tsx` — wraps content in `<Suspense>`
|
||||
- `app/(main)/admin/tasks/page.tsx` — wraps content in `<Suspense fallback={...}>`
|
||||
- `app/(main)/openflare/proxy-routes/detail/page.tsx` — splits into `page.tsx` + `page-client.tsx` with `<Suspense>`
|
||||
|
||||
---
|
||||
|
||||
## Other `useSearchParams()` Usages (likely to fail after nodes fix)
|
||||
|
||||
These files also use `useSearchParams()` without a visible `Suspense` wrapper at the page level. They may fail once `/openflare/nodes` is fixed and generation continues:
|
||||
|
||||
| File |
|
||||
|------|
|
||||
| `app/(main)/openflare/nodes/detail/page.tsx` |
|
||||
| `app/(main)/openflare/websites/detail/page.tsx` |
|
||||
| `app/(main)/openflare/origins/detail/page.tsx` |
|
||||
| `app/(main)/openflare/apply-logs/page.tsx` |
|
||||
| `app/(main)/openflare/pages/detail/page.tsx` |
|
||||
| `components/auth/login-form.tsx` |
|
||||
| `components/auth/login-page.tsx` |
|
||||
| `components/auth/register-form.tsx` |
|
||||
|
||||
(Auth pages are likely safe because `login/page.tsx` and `register/page.tsx` already wrap them in `<Suspense>`.)
|
||||
|
||||
---
|
||||
|
||||
## Recommendations
|
||||
|
||||
### Priority 1 — Fix `/openflare/nodes` build blocker
|
||||
|
||||
Refactor using the existing `proxy-routes/detail` pattern:
|
||||
|
||||
1. Create `app/(main)/openflare/nodes/page-client.tsx` with the current page logic.
|
||||
2. Change `page.tsx` to a server component that wraps the client component in `<Suspense fallback={<LoadingState />}>`.
|
||||
|
||||
Alternatively, wrap `<NodeTypeFilter />` and the `useSearchParams()` usage in a single child component inside `<Suspense>`.
|
||||
|
||||
### Priority 2 — Audit remaining pages
|
||||
|
||||
Apply the same `Suspense` pattern to all detail/list pages using `useSearchParams()` (see table above) to avoid repeated build failures at 1/46, 2/46, etc.
|
||||
|
||||
### Priority 3 — Add a CI gate
|
||||
|
||||
Run all three checks in CI before merge:
|
||||
Run all three checks before merge:
|
||||
|
||||
```bash
|
||||
cd Wavelet/frontend
|
||||
pnpm exec tsc --noEmit
|
||||
pnpm lint
|
||||
pnpm build:embed
|
||||
```
|
||||
|
||||
### Priority 4 — Optional lint rule
|
||||
|
||||
Consider an ESLint rule or codemod to flag `useSearchParams()` usage outside `Suspense` boundaries, since `tsc` and `eslint` pass even when the production build fails.
|
||||
|
||||
---
|
||||
|
||||
## Actions Taken
|
||||
|
||||
- No code fixes applied. The failure is a structural Next.js `Suspense` requirement, not a trivial one-line lint fix.
|
||||
- Ran all three verification commands on 2026-06-18.
|
||||
- No code changes applied; documentation updated with results.
|
||||
@@ -1,39 +1,50 @@
|
||||
# OpenFlare 前端路由验证报告
|
||||
|
||||
> **验证日期**:2026-06-18
|
||||
> **对照**:`20260618-openflare-wavelet-frontend-migration.md` §6.1(FC-1 ~ FC-20)
|
||||
> **验证日期**:2026-06-18(复验)
|
||||
> **对照**:`20260618-openflare-wavelet-frontend-migration.md` §6.1(FC-1 ~ FC-20)
|
||||
> **扫描路径**:`Wavelet/frontend/app/(main)/openflare/**/page.tsx`
|
||||
|
||||
## 摘要
|
||||
|
||||
| 指标 | 结果 |
|
||||
|---|---|
|
||||
| 计划路由数(FC-1 ~ FC-20) | 20 |
|
||||
| `page.tsx` 文件数 | 20 |
|
||||
| **路由文件覆盖率** | **100%** |
|
||||
| **严格完成**(路由存在且非占位) | **19/20(95%)** |
|
||||
| **加权完成**(FC-1 计 0.5) | **97.5%** |
|
||||
| FC-20 `/openflare/about` | ✅ 已实现 |
|
||||
| 缺失路由 | **无** |
|
||||
|
||||
## 路由对照
|
||||
|
||||
| # | 计划路由 | 状态 | 备注 |
|
||||
|---|---|---|---|
|
||||
| FC-1 | `/openflare` | ⚠️ partial | 仪表盘已实现;世界地图以国家列表替代 |
|
||||
| FC-2 | `/openflare/nodes` | ✅ | |
|
||||
| FC-3 | `/openflare/nodes/detail` | ✅ | Edge/Relay/Tunnel 三种详情 |
|
||||
| FC-4 | `/openflare/proxy-routes` | ✅ | |
|
||||
| FC-5 | `/openflare/proxy-routes/detail` | ✅ | 6 Section + 发布 |
|
||||
| FC-6 | `/openflare/config-versions` | ✅ | |
|
||||
| FC-7 | `/openflare/waf` | ✅ | |
|
||||
| FC-8 | `/openflare/waf/ip-groups` | ✅ | 页内链接 |
|
||||
| FC-9 | `/openflare/websites` | ✅ | |
|
||||
| FC-10 | `/openflare/websites/detail` | ✅ | |
|
||||
| FC-11 | `/openflare/websites/certificates` | ✅ | |
|
||||
| FC-12 | `/openflare/websites/dns-accounts` | ✅ | |
|
||||
| FC-13 | `/openflare/pages` | ✅ | |
|
||||
| FC-14 | `/openflare/pages/detail` | ✅ | |
|
||||
| FC-15 | `/openflare/origins` | ✅ | |
|
||||
| FC-16 | `/openflare/origins/detail` | ✅ | |
|
||||
| FC-17 | `/openflare/access-logs` | ✅ | 4 Tab |
|
||||
| FC-18 | `/openflare/apply-logs` | ✅ | |
|
||||
| FC-19 | `/openflare/performance` | ✅ | |
|
||||
| FC-20 | `/openflare/about` | ❌ | 待实现或复用 `/docs` |
|
||||
|
||||
## 覆盖率
|
||||
|
||||
- **严格完成**:18/20(90%)
|
||||
- **加权**:92.5%(FC-1 计 0.5)
|
||||
- **PlaceholderPage 使用**:0(组件仍存在但未引用)
|
||||
| # | 计划路由 | 页面文件 | 状态 | 备注 |
|
||||
|---|---|---|---|---|
|
||||
| FC-1 | `/openflare` | `openflare/page.tsx` | ⚠️ partial | 仪表盘已实现;世界地图以 `GeoDistributionList` 国家列表替代 |
|
||||
| FC-2 | `/openflare/nodes` | `openflare/nodes/page.tsx` | ✅ | |
|
||||
| FC-3 | `/openflare/nodes/detail` | `openflare/nodes/detail/page.tsx` | ✅ | Edge / Relay / Tunnel |
|
||||
| FC-4 | `/openflare/proxy-routes` | `openflare/proxy-routes/page.tsx` | ✅ | |
|
||||
| FC-5 | `/openflare/proxy-routes/detail` | `openflare/proxy-routes/detail/page.tsx` | ✅ | 6 Section + 发布 |
|
||||
| FC-6 | `/openflare/config-versions` | `openflare/config-versions/page.tsx` | ✅ | |
|
||||
| FC-7 | `/openflare/waf` | `openflare/waf/page.tsx` | ✅ | |
|
||||
| FC-8 | `/openflare/waf/ip-groups` | `openflare/waf/ip-groups/page.tsx` | ✅ | |
|
||||
| FC-9 | `/openflare/websites` | `openflare/websites/page.tsx` | ✅ | |
|
||||
| FC-10 | `/openflare/websites/detail` | `openflare/websites/detail/page.tsx` | ✅ | |
|
||||
| FC-11 | `/openflare/websites/certificates` | `openflare/websites/certificates/page.tsx` | ✅ | |
|
||||
| FC-12 | `/openflare/websites/dns-accounts` | `openflare/websites/dns-accounts/page.tsx` | ✅ | |
|
||||
| FC-13 | `/openflare/pages` | `openflare/pages/page.tsx` | ✅ | |
|
||||
| FC-14 | `/openflare/pages/detail` | `openflare/pages/detail/page.tsx` | ✅ | |
|
||||
| FC-15 | `/openflare/origins` | `openflare/origins/page.tsx` | ✅ | |
|
||||
| FC-16 | `/openflare/origins/detail` | `openflare/origins/detail/page.tsx` | ✅ | |
|
||||
| FC-17 | `/openflare/access-logs` | `openflare/access-logs/page.tsx` | ✅ | 4 Tab |
|
||||
| FC-18 | `/openflare/apply-logs` | `openflare/apply-logs/page.tsx` | ✅ | |
|
||||
| FC-19 | `/openflare/performance` | `openflare/performance/page.tsx` | ✅ | |
|
||||
| FC-20 | `/openflare/about` | `openflare/about/page.tsx` | ✅ | AboutService + 侧栏导航 |
|
||||
|
||||
## 子路由(不在侧栏顶级)
|
||||
|
||||
`/openflare/nodes/detail`、`proxy-routes/detail`、`pages/detail`、`websites/detail`、`websites/certificates`、`websites/dns-accounts`、`waf/ip-groups`、`origins/detail`
|
||||
`/openflare/nodes/detail`、`proxy-routes/detail`、`pages/detail`、`websites/detail`、`websites/certificates`、`websites/dns-accounts`、`waf/ip-groups`、`origins/detail`
|
||||
|
||||
## 结论
|
||||
|
||||
§6.1 路由映射 **基本完成**(20/20 文件)。唯一路由级缺口为 FC-1 世界地图(可选 P2);无缺失 `page.tsx`。
|
||||
@@ -1,8 +1,16 @@
|
||||
# OpenFlare 前端 Service 层验证报告
|
||||
|
||||
> **验证日期**:2026-06-18
|
||||
> **验证日期**:2026-06-18(复验)
|
||||
> **目录**:`Wavelet/frontend/lib/services/openflare/`
|
||||
|
||||
## 覆盖率摘要
|
||||
|
||||
| 维度 | 结果 |
|
||||
|---|---|
|
||||
| §7.1 计划服务文件 | **15 / 15 = 100%** |
|
||||
| 业务 `/api/*` 端点 | **100%** |
|
||||
| 待补 API | **0** |
|
||||
|
||||
## §7.1 对照结果
|
||||
|
||||
| 计划服务 | 实际文件 | 注册 | 方法覆盖 |
|
||||
@@ -21,22 +29,33 @@
|
||||
| access-log | ✅ | `openflareAccessLog` | ✅ |
|
||||
| apply-log | ✅ | `openflareApplyLog` | ✅ |
|
||||
| option | ✅ | `openflareOption` | ✅ |
|
||||
| update | ⚠️ partial | `openflareUpdate` | 仅 `getLatestRelease` |
|
||||
| update | ✅ | `openflareUpdate` | ✅ 6 方法 |
|
||||
| about | ✅ | `openflareAbout` | `getAboutContent()` |
|
||||
|
||||
## update.service.ts 复验
|
||||
|
||||
| 方法 | 端点 |
|
||||
|---|---|
|
||||
| `getLatestRelease(channel?)` | `GET /api/update/latest-release` |
|
||||
| `upgradeServer(channel?)` | `POST /api/update/upgrade` |
|
||||
| `uploadServerBinary(file, onProgress?)` | `POST /api/update/manual-upload` |
|
||||
| `confirmManualServerUpgrade(token)` | `POST /api/update/manual-upgrade` |
|
||||
| `createUpgradeLogsWebSocket()` | `WS /api/update/logs/ws` |
|
||||
| `parseUpgradeStreamSnapshot(raw)` | WS 消息解析 |
|
||||
|
||||
已接入:`use-openflare-server-upgrade.ts`、`openflare-version-entry.tsx`、`openflare-ops.tsx`。
|
||||
|
||||
## 计划外(已实现)
|
||||
|
||||
- `status.service.ts` → `openflareStatus`
|
||||
- `uptimekuma.service.ts` → `openflareUptimeKuma`
|
||||
- `about.service.ts` → `openflareAbout`
|
||||
- `legacy-base.service.ts`(基类)
|
||||
|
||||
## 待补 API
|
||||
|
||||
| 端点 | 说明 |
|
||||
|---|---|
|
||||
| `POST /api/update/upgrade` | 顶栏升级流程 |
|
||||
| `POST /api/update/manual-upload` | 手动上传 |
|
||||
| `POST /api/update/manual-upgrade` | 手动确认升级 |
|
||||
| `WS /api/update/logs/ws` | 升级日志流 |
|
||||
| `GET /api/about` | About 页(FC-20) |
|
||||
无。
|
||||
|
||||
业务 `/api/*` 其余端点均已由 Service 覆盖。
|
||||
## 结论
|
||||
|
||||
Service 层迁移 **完成**。所有计划内业务 API 均已由 Service 覆盖。
|
||||
@@ -1,6 +1,6 @@
|
||||
# OpenFlare 前端 UI 规范验收报告
|
||||
|
||||
> **验证日期**:2026-06-18
|
||||
> **验证日期**:2026-06-18(polish pass 复验)
|
||||
> **范围**:`Wavelet/frontend/app/(main)/openflare/`
|
||||
|
||||
## 总体
|
||||
@@ -9,25 +9,32 @@
|
||||
|---|---|
|
||||
| 标题 `h1 text-2xl font-semibold tracking-tight` | ✅ |
|
||||
| 外壳 `py-6 px-1` | ✅ |
|
||||
| shadcn 组件(无旧 UI) | ✅ |
|
||||
| 单文件 ≤600 行 | ✅(最大 access-logs 584 行) |
|
||||
| loading/empty/error | ⚠️ 部分 Tab 缺 error |
|
||||
| RHF + Zod 表单 | ⚠️ 部分 Dialog 待补 |
|
||||
| shadcn 组件(无旧 UI / HeroUI) | ✅ |
|
||||
| 单文件 ≤600 行 | ✅(最大 `access-logs/page.tsx` 558 行) |
|
||||
| loading/empty/error | ✅ |
|
||||
| RHF + Zod 表单(P1 Dialog) | ✅ |
|
||||
|
||||
**总体结论:PASS**
|
||||
|
||||
## 分模块
|
||||
|
||||
| 模块 | 结论 |
|
||||
|---|---|
|
||||
| Dashboard | ✅ PASS |
|
||||
| Nodes | ⚠️ `node-editor-dialog` 缺 Zod |
|
||||
| Proxy detail | ⚠️ 无效 ID/error 态待统一组件 |
|
||||
| WAF | ⚠️ `rule-entry-dialog` 缺 RHF+Zod |
|
||||
| Websites/Certificates | ⚠️ `dns-account-create-dialog` 缺 Zod |
|
||||
| Access logs | ⚠️ folds/ip-summary Tab 缺 error |
|
||||
| Config versions | ⚠️ cleanup dialog 缺 Zod |
|
||||
| 模块 | 结论 | 说明 |
|
||||
|---|---|---|
|
||||
| Dashboard | ✅ PASS | 标准壳与三态组件 |
|
||||
| Nodes | ✅ PASS | `node-editor-dialog` Zod 已补 |
|
||||
| Proxy detail | ✅ PASS | `ErrorInline` / `EmptyStateWithBorder` 已统一 |
|
||||
| Proxy list | ⚠️ PASS* | 列表 error 仅 toast(P2) |
|
||||
| WAF | ✅ PASS | `rule-entry-dialog` RHF+Zod 已补 |
|
||||
| Websites/Certificates | ✅ PASS | `dns-account-create-dialog` Zod 已补 |
|
||||
| Access logs | ✅ PASS | folds/ip-summary/ip-trend error 已补 |
|
||||
| Config versions | ✅ PASS | `cleanup-dialog` Zod 已补 |
|
||||
| About | ✅ PASS | 页面惯例完整 |
|
||||
| Version upgrade dialog | ✅ PASS | Card/Badge/Markdown 惯例合规 |
|
||||
|
||||
## P1 修复建议
|
||||
## P2 可选改进
|
||||
|
||||
1. `proxy-routes/detail/page-client.tsx` — `EmptyStateWithBorder` / `ErrorInline`
|
||||
2. `access-logs/page.tsx` — folds、ip-summary 的 `isError` 分支
|
||||
3. `node-editor-dialog.tsx`、`rule-entry-dialog.tsx` — 补 Zod schema
|
||||
1. `proxy-routes/page-client.tsx` — 列表 error 改用 `ErrorInline`
|
||||
2. `access-logs/components/cleanup-dialog.tsx` — 补 RHF+Zod
|
||||
3. `access-logs/page.tsx` ip-trend — 改用 shadcn `Input`
|
||||
4. `nodes/components/node-observability.tsx` — 改用 `ErrorInline`+重试
|
||||
5. FC-1 世界地图 — 当前以国家列表替代
|
||||
Reference in New Issue
Block a user