跳到主要内容

SayClaw Admin 前端重构计划

决策:弃用 Soybean Admin (Vue) 模板,基于设计稿从零构建 React 应用。

1. 为什么重构

问题说明
模板臃肿Soybean Admin 自带大量我们不用的功能,打包体积大
定制成本高改模板样式 = 和 UnoCSS + 模板约定打架
设计稿已就绪admin-full-design.html 包含全部 12 个页面的完整 UI
技术栈统一文档站 (Docusaurus) 已是 React,统一降低心智负担

2. 技术选型

选择理由
框架React 18 + TypeScript生态最大,AI 辅助编码支持最好
构建Vite 6快,和之前一致
路由React Router v7成熟稳定
状态Zustand轻量,比 Redux 少 90% 模板代码
HTTPky (或 axios)轻量 fetch wrapper
样式CSS Modules + CSS 变量零运行时,直接复用设计稿的 CSS 变量和类名
图表RechartsReact 原生,Dashboard 图表用
表格@tanstack/react-table排序、分页、筛选
表单React Hook Form轻量表单验证
包管理pnpm与现有项目一致
代码质量ESLint + Prettier + Biome

3. 项目结构

sayclaw-admin-v2/
├── public/
│ └── favicon.svg
├── src/
│ ├── main.tsx # 入口
│ ├── App.tsx # 路由定义
│ │
│ ├── assets/
│ │ ├── icons/ # SVG 图标(从设计稿提取)
│ │ └── styles/
│ │ ├── variables.css # 设计稿 CSS 变量(绿色主题)
│ │ ├── global.css # 全局重置 + 基础样式
│ │ └── components.css # 共用组件样式
│ │
│ ├── components/ # 通用 UI 组件
│ │ ├── Layout/
│ │ │ ├── Sidebar.tsx # 侧栏导航
│ │ │ ├── MainLayout.tsx # 主布局(侧栏 + 内容区)
│ │ │ └── PageBanner.tsx # 页面顶部绿色 Banner
│ │ ├── Table/
│ │ │ ├── DataTable.tsx # 通用数据表格
│ │ │ └── Pagination.tsx # 分页
│ │ ├── Form/
│ │ │ ├── Input.tsx
│ │ │ ├── Select.tsx
│ │ │ ├── Switch.tsx
│ │ │ └── DateRangePicker.tsx
│ │ ├── Modal.tsx # 通用弹窗
│ │ ├── Tag.tsx # 状态标签 (green/blue/yellow/red/gray)
│ │ ├── Button.tsx # 按钮
│ │ ├── Card.tsx # 卡片容器
│ │ ├── TabBar.tsx # Tab 切换栏
│ │ └── SearchBox.tsx # 搜索框
│ │
│ ├── pages/ # 12 个页面
│ │ ├── Dashboard/ # 数据总览
│ │ │ └── index.tsx
│ │ ├── AdminUsers/ # 后台账号
│ │ │ └── index.tsx
│ │ ├── ApiKeys/ # API 密钥(3 Tab)
│ │ │ ├── index.tsx
│ │ │ ├── MasterKeys.tsx
│ │ │ ├── SubKeys.tsx
│ │ │ └── AiModels.tsx
│ │ ├── PortalUsers/ # 员工账号
│ │ │ └── index.tsx
│ │ ├── Usage/ # 使用记录
│ │ │ └── index.tsx
│ │ ├── Servers/ # 服务器管理
│ │ │ └── index.tsx
│ │ ├── Instances/ # OC 实例
│ │ │ └── index.tsx
│ │ ├── Scheduler/ # 调度管理(2 Tab)
│ │ │ ├── index.tsx
│ │ │ ├── CronJobs.tsx
│ │ │ └── TaskQueue.tsx
│ │ ├── AuditLog/ # 审计日志(2 Tab)
│ │ │ ├── index.tsx
│ │ │ ├── LlmRequestLog.tsx
│ │ │ └── OpsLog.tsx
│ │ └── Shrimp/ # 捕虾场(3 子页面)
│ │ ├── Professions.tsx # 职能虾管理
│ │ ├── Pool.tsx # 虾池管理
│ │ ├── Claims.tsx # 捕获记录
│ │ └── ProfessionModal.tsx # 新增/编辑弹窗
│ │
│ ├── services/ # API 层
│ │ ├── request.ts # HTTP client (ky/axios 封装)
│ │ ├── auth.ts # 登录、OAuth、JWT
│ │ ├── dashboard.ts # 统计数据
│ │ ├── admin-users.ts # 后台账号 CRUD
│ │ ├── api-keys.ts # 主Key/子Key/模型
│ │ ├── portal-users.ts # Portal 用户
│ │ ├── instances.ts # OC 实例
│ │ ├── servers.ts # 服务器
│ │ ├── scheduler.ts # Cron + 任务队列
│ │ ├── audit.ts # 审计日志 + LLM日志
│ │ └── shrimp.ts # 捕虾场全部 API
│ │
│ ├── stores/ # Zustand stores
│ │ ├── useAuthStore.ts # 登录态、JWT、用户信息
│ │ └── useGlobalStore.ts # 侧栏折叠、主题等
│ │
│ ├── hooks/ # 自定义 hooks
│ │ ├── useAuth.ts # 鉴权守卫
│ │ └── useTimezone.ts # 时区检测 + 格式化
│ │
│ └── utils/
│ ├── format.ts # 日期/金额/token 格式化
│ └── constants.ts # 路由路径、枚举值

├── index.html
├── vite.config.ts
├── tsconfig.json
├── package.json
└── .env # VITE_API_BASE_URL=https://api.sayclaw.ai/api/v1

4. 路由设计

// App.tsx
<Routes>
<Route path="/login" element={<Login />} />

<Route element={<AuthGuard><MainLayout /></AuthGuard>}>
<Route path="/" element={<Navigate to="/dashboard" />} />
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/admin-users" element={<AdminUsers />} />
<Route path="/api-keys" element={<ApiKeys />} />
<Route path="/portal-users" element={<PortalUsers />} />
<Route path="/usage" element={<Usage />} />
<Route path="/servers" element={<Servers />} />
<Route path="/instances" element={<Instances />} />
<Route path="/scheduler" element={<Scheduler />} />
<Route path="/audit" element={<AuditLog />} />
<Route path="/shrimp/professions" element={<Professions />} />
<Route path="/shrimp/pool" element={<Pool />} />
<Route path="/shrimp/claims" element={<Claims />} />
</Route>
</Routes>

5. 设计系统(直接复用设计稿)

CSS 变量(从 admin-full-design.html 提取)

:root {
--primary: #43b581;
--primary-light: #5ec49a;
--primary-dark: #369e6e;
--primary-bg: #eafaf1;
--gradient: linear-gradient(135deg, #43b581, #2d8f63);

--success: #43b581; --success-bg: #eafaf1;
--warning: #f0a020; --warning-bg: #fef8eb;
--danger: #e85d5d; --danger-bg: #fdf0f0;
--info: #5b8def; --info-bg: #edf3fe;

--gray-50 ~ --gray-900 (10 级灰)
--radius: 12px;
--radius-sm: 8px;
--shadow / --shadow-md / --shadow-lg
}

组件 → 设计稿对照

组件设计稿 class复用方式
<PageBanner>.banner直接搬 CSS
<Tag color="green">.tag .tag-greenProps 控制颜色
<DataTable>table th td同样式
<Button variant="primary">.btn .btn-primaryProps 控制变体
<Modal>.modal-overlay .modal搬原样式
<Card>.card搬原样式
<ShrimpCard>.shrimp-card捕虾场专用
<IconBox color="emerald">.si .si-emeraldSVG 渐变图标盒
<SkillPicker>.skill-picker .skill-chip多选 chip
<MdEditor>.md-split左右分栏编辑器

6. 分期交付

Phase 1:骨架 + 核心页面(3 天)

任务交付物
项目初始化Vite + React + TS + pnpm
设计系统CSS 变量 + 全局样式 + 图标 SVG
布局组件Sidebar + MainLayout + PageBanner
通用组件Button, Tag, Card, Modal, Table, Pagination, TabBar
登录页Google OAuth + 密码登录
数据总览统计卡片 + 图表 + 告警表 + 服务器状态
API 层request.ts + auth.ts + dashboard.ts

交付标准: 能登录、看到 Dashboard、侧栏可点击。

Phase 2:管理页面(3 天)

任务交付物
后台账号CRUD 表格 + 新增/编辑弹窗
API 密钥3 Tab(主Key/子Key/模型)+ CRUD
员工账号表格 + 分配实例
使用记录日期筛选 + 请求日志表格

交付标准: 4 个管理页面可正常 CRUD。

Phase 3:基础设施(2 天)

任务交付物
服务器管理服务器卡片 + 资源监控条
OC 实例实例表格 + 健康状态 + 操作按钮
调度管理2 Tab: Cron Jobs + 任务队列
审计日志2 Tab: LLM 请求日志 + 管理操作日志

交付标准: 所有基础设施页面对接真实 API。

Phase 4:捕虾场(2 天)

任务交付物
职能虾管理卡片网格 + 新增弹窗(技能多选 + MD 编辑器)
虾池管理状态 Tab + 表格 + 回收/维护操作
捕获记录只读表格 + 筛选 + CSV 导出

交付标准: 捕虾场 3 页完整可用。

Phase 5:打磨 + 部署(1-2 天)

任务交付物
响应式适配 ≥1024px(不做移动端,后续再说)
错误处理全局错误边界 + API 错误 toast
权限super_admin vs admin 菜单/按钮权限
CI/CDGitLab Pipeline: lint → build → scp 部署
Nginx更新 /var/www/sayclaw-admin 指向新构建产物

总计:11-12 天

7. API 对接清单

现有后端 API(admin-api port 8081):

模块端点数状态
认证 (auth)4✅ 已有
管理员账号4✅ 已有
Portal 用户5✅ 已有
OC 实例11✅ 已有
服务器6✅ 已有
LLM 主Key4✅ 已有
LLM 子Key5✅ 已有
LLM 日志4✅ 已有
Cron/任务队列6✅ 已有
捕虾场10+⚠️ 部分在 MR 中
审计日志2❌ 需新增

8. 部署架构

开发: localhost:5173 (Vite dev server) → proxy → localhost:8081
生产: admin.sayclaw.ai → nginx → /var/www/sayclaw-admin/dist/
↘ /api/v1/* → 127.0.0.1:8081

9. 开发约定

  • 一个页面一个目录,index.tsx 为入口
  • 服务层:所有 API 调用在 services/ 中,页面不直接调 fetch
  • 时间格式:统一 YYYY-MM-DD HH:MM:SS,前端根据浏览器时区显示
  • Git 分支feature/admin-v2-phase-N,每个 Phase 一个 MR
  • 代码仓库sayclaw-app (或新建 sayclaw-admin-v2)

10. 风险 & 决策点

风险缓解
审计日志 API 未实现Phase 3 时后端补上 2 个端点
捕虾场 API 在未合并的 MR 中Phase 4 前合并 backend #5, #6, #7
设计稿主色 (#43b581) 与旧前端 (#5B4FE8) 不同按设计稿绿色走,弃用旧紫色
移动端V2 先不做 H5,后续单独迭代