Files
goalfylearning-admin-web/PROJECT_ARCHITECTURE.md

14 KiB
Raw Blame History

Goalfymax 管理后台项目架构概览

项目概述

这是一个基于 React 18 + Vite + Ant Design 5 + React Router 7 的现代管理后台应用。

  • 技术栈React 18.3.1 + TypeScript + Vite 5.4.20 + Ant Design 5.27.4
  • 状态管理Jotai原子状态管理
  • HTTP 客户端Axios 1.12.2
  • 日期处理Dayjs 1.11.18
  • 总文件数48 个 TypeScript/TSX 文件
  • 代码行数~7000+ 行代码

目录结构

src/
├── App.tsx                    # 主应用入口,定义静态路由
├── main.tsx                   # Vite 应用入口点
├── index.css                  # 全局样式
├── App.css                    # 应用样式
│
├── atoms/                     # 状态管理Jotai 原子状态)
│   └── auth.ts               # 认证状态原子
│
├── components/               # 可复用 UI 组件
│   ├── Layout.tsx            # 主布局组件(侧边栏+主区域)
│   ├── DynamicMenu.tsx       # 动态菜单组件(权限感知)
│   ├── DynamicMenu.css       # 菜单样式
│   ├── AuthGuard.tsx         # 认证守卫组件
│   ├── PermissionGuard.tsx   # 权限守卫组件
│   ├── PagePermissionGuard.tsx
│   ├── QuotaCharts.tsx       # 配额图表组件
│   ├── QuotaRulesForm.tsx    # 配额规则表单
│   ├── QuotaRulesTable.tsx   # 配额规则表格
│   ├── QuotaHistoryTable.tsx # 配额历史表格
│   ├── QuotaFilters.tsx      # 配额过滤器
│   ├── QuotaStats.tsx        # 配额统计
│   └── UserProjectQuotaPage.tsx
│
├── hooks/                    # 自定义 React Hooks
│   ├── useAuth.ts           # 认证 Hook登录、登出、Token 管理)
│   ├── usePagePermissions.ts # 页面权限 Hook
│   └── usePermissions.ts     # 操作权限 Hook
│
├── pages/                    # 页面组件
│   ├── Dashboard.tsx         # 仪表盘
│   ├── Overview.tsx          # 总览页
│   ├── Operations.tsx        # 运营页
│   ├── Monitoring.tsx        # 监控页
│   ├── Finance.tsx           # 财务页
│   ├── SystemHealth.tsx      # 系统健康
│   ├── QuotaRules.tsx        # 配额规则管理
│   ├── UserProjectQuota.tsx  # 用户项目配额管理
│   ├── UserManagement.tsx    # 系统用户管理
│   ├── RoleManagement.tsx    # 角色管理
│   ├── GoalfyMaxUsers.tsx    # GoalfyMax 用户管理
│   ├── UserLevelConfigs.tsx  # 用户等级配置管理
│   ├── SystemConfigs.tsx     # 系统配置管理
│   ├── UserFeedback.tsx      # 用户反馈管理
│   ├── MessagePush.tsx       # 消息推送管理
│   ├── TokenHistory.tsx      # Token 历史
│   ├── TokenAnalytics.tsx    # Token 分析
│   ├── VendorModelPricing.tsx# 供应商模型价格管理
│   └── ...
│
├── routes/                   # 路由配置
│   └── DynamicRoutes.tsx     # 动态路由配置(基于权限的动态路由)
│
├── services/                 # API 服务层
│   ├── api.ts               # 核心 API 客户端ApiClient+ API 服务导出
│   ├── userLevelConfigApi.ts # 用户等级配置 API
│   ├── systemConfigApi.ts    # 系统配置 API
│   ├── userApi.ts           # 用户 API
│   ├── roleApi.ts           # 角色 API
│   └── ...
│
├── types/                    # TypeScript 类型定义
│   ├── userLevelConfig.ts    # 用户等级配置类型
│   ├── systemConfig.ts       # 系统配置类型
│   ├── quota.ts             # 配额类型
│   ├── userProjectQuota.ts   # 用户项目配额类型
│   └── ...
│
├── utils/                    # 工具函数
│   └── storageMigration.ts   # 存储迁移工具
│
└── assets/                   # 静态资源
    └── react.svg

核心架构设计

1. 路由设计

双层路由系统

App.tsx 中的静态路由

  • 定义所有可用的路由路径
  • 组织模块化的路由结构dashboard、operations、monitoring、system 等)
// 示例:系统管理路由
<Route path="/system" element={<Navigate to="/system/quota-rules" replace />} />
<Route path="/system/quota-rules" element={<QuotaRulesPage />} />
<Route path="/system/user-management" element={<UserManagement />} />
<Route path="/system/user-level-configs" element={<UserLevelConfigs />} />
<Route path="/system/system-configs" element={<SystemConfigs />} />

DynamicRoutes.tsx 中的权限感知路由

  • 根据用户权限动态显示/隐藏路由
  • 使用 usePagePermissions() hook 获取用户权限
  • 只挂载有权限访问的路由

2. 菜单系统

DynamicMenu 组件特点:

  • 权限感知的菜单项过滤
  • 支持一级和二级菜单
  • 自动同步当前路由位置
  • 详细的权限检查日志

核心逻辑:

const filterAccessibleMenus = (items: MenuItem[]): MenuItem[] => {
  // 1. 仪表盘始终显示
  // 2. 父级菜单权限检查(如 /system、/operations
  // 3. 单个菜单项权限检查
  // 4. 返回过滤后的菜单项
}

3. API 调用模式

分层结构

UI 组件
  ↓
Custom Hook (useXxx)
  ↓
API Service (xxxApi.ts)
  ↓
ApiClient (api.ts)
  ↓
Axios 实例 + 拦截器
  ↓
后端 API

ApiClient 类特性

  • 自动 Token 管理:请求自动附加 Authorization 头
  • Token 刷新机制401 错误时自动刷新 token
  • 请求队列:刷新 token 期间的请求入队等待
  • 错误处理:统一处理认证失败和其他错误

API 服务示例

系统配置 APIsystemConfigApi.ts

export const getSystemConfigList = async (params) => {
  const response = await apiClient.get('/admin/system-configs', { params });
  return response; // 返回完整响应对象
}

export const createSystemConfig = async (data) => {
  const response = await apiClient.post('/admin/system-configs', data);
  return response.data;
}

用户等级配置 APIuserLevelConfigApi.ts

export const getUserLevelConfigList = async (params) => {
  const response = await apiClient.get('/admin/user-level-configs', { params });
  return response.data;
}

关键文件详解

1. 用户等级配置UserLevelConfigs

文件清单

  • /src/pages/UserLevelConfigs.tsx - 页面组件292 行)
  • /src/services/userLevelConfigApi.ts - API 服务60 行)
  • /src/types/userLevelConfig.ts - 类型定义47 行)

功能

  • 列表查询(分页)
  • 创建新等级配置
  • 编辑等级配置
  • 删除等级配置
  • 启用/禁用等级配置

数据模型

interface UserLevelConfig {
  id: number;
  level_name: string;           // 等级名称
  level_code: string;           // 等级代码
  project_limit: number;        // 项目数限制
  description: string;          // 描述
  sort_order: number;           // 排序顺序
  status: number;              // 1=启用, 0=禁用
  created_at: string;
  updated_at: string;
}

2. 系统配置SystemConfigs

文件清单

  • /src/pages/SystemConfigs.tsx - 页面组件284 行)
  • /src/services/systemConfigApi.ts - API 服务66 行)
  • /src/types/systemConfig.ts - 类型定义51 行)

功能

  • 列表查询(分页)
  • 创建新系统配置
  • 编辑系统配置
  • 删除系统配置
  • 启用/禁用系统配置

数据模型

interface SystemConfig {
  id: number;
  key: string;                  // 唯一标识
  name: string;                 // 配置名称
  value: string;                // 配置值
  type: string;                 // 配置类型string, int, bool, json
  desc: string;                 // 配置描述
  status: number;              // 1=启用, 0=禁用
  createdAt: string;
  updatedAt: string;
}

3. Layout 组件(布局)

结构

┌─────────────────────────────┐
│       Header顶部栏        │
├─────────┬───────────────────┤
│         │                   │
│ Sidebar │    Main Content   │
│(Menus)  │   (页面内容)      │
│         │                   │
├─────────┼───────────────────┤
│         Footer页脚        │
└─────────────────────────────┘

特性

  • 侧边栏可折叠/展开(按钮)
  • 动态菜单DynamicMenu
  • 子导航标签(针对多级菜单页面)
  • 用户认证状态显示 + 登出按钮

4. 认证流程useAuth Hook

功能

  • SSO 单点登录
  • Token 管理access_token + refresh_token
  • 自动 Token 刷新
  • Token 过期检测和重新登录

API 端点规范

用户等级配置

GET    /admin/user-level-configs          # 列表(分页)
GET    /admin/user-level-configs/all      # 全部(不分页)
GET    /admin/user-level-configs/:id      # 详情
POST   /admin/user-level-configs          # 创建
PUT    /admin/user-level-configs/:id      # 更新
PUT    /admin/user-level-configs/:id/status  # 更新状态
DELETE /admin/user-level-configs/:id      # 删除

系统配置

GET    /admin/system-configs              # 列表(分页)
GET    /admin/system-configs/all          # 全部(不分页)
GET    /admin/system-configs/:id          # 详情
GET    /admin/system-configs/key/:key     # 按 Key 查询
POST   /admin/system-configs              # 创建
PUT    /admin/system-configs/:id          # 更新
PUT    /admin/system-configs/:id/status   # 更新状态
DELETE /admin/system-configs/:id          # 删除

其他 API

GET    /admin/goalfymax-users             # GoalfyMax 用户列表
GET    /admin/user-feedback               # 用户反馈
GET    /admin/message-push/logs           # 推送记录
GET    /admin/vendor-model-pricing        # 供应商模型价格
POST   /admin/message-push/send           # 发送消息

权限系统

权限检查层级

  1. 页面级权限usePagePermissions

    • 检查用户是否可以访问某个页面
    • 返回可访问的页面列表
  2. 操作级权限usePermissions

    • 检查用户是否可以执行某个操作
    • 如:创建、编辑、删除、启用/禁用
  3. 菜单级权限DynamicMenu

    • 根据页面权限动态显示/隐藏菜单项
    • 支持嵌套菜单的权限管理

权限存储

  • 通过 localStorage 缓存
  • 从后端 SSO API 获取用户权限信息
  • Jotai 原子状态管理

页面模块划分

系统管理(/system

  • 配额/套餐规则
  • 用户项目配额
  • 系统用户管理
  • 角色管理
  • GoalfyMax 用户管理
  • 用户等级配置
  • 系统配置

运营(/operations

  • 用户反馈管理
  • 消息推送管理
  • 供应商模型价格管理

监控(/monitoring

  • Token 历史
  • Token 分析
  • 系统健康

财务(/finance

  • 财务数据统计

通用 CRUD 页面模式

UserLevelConfigs 和 SystemConfigs 采用的设计模式

页面结构

  1. 数据列表(分页表格)
  2. 创建弹窗
  3. 编辑弹窗
  4. 操作列(编辑、启用/禁用、删除)

状态管理

const [list, setList] = useState<T[]>([]);
const [total, setTotal] = useState(0);
const [page, setPage] = useState(1);
const [size, setSize] = useState(10);
const [editing, setEditing] = useState<T | null>(null);
const [editOpen, setEditOpen] = useState(false);
const [createOpen, setCreateOpen] = useState(false);

操作流程

  1. 查询列表fetchList() → API → 更新 state
  2. 创建:表单验证 → API → 刷新列表
  3. 编辑:打开弹窗 → 表单填充 → 表单验证 → API → 刷新列表
  4. 删除:确认弹窗 → API → 刷新列表
  5. 状态切换API → 刷新列表

代码架构建议

当前优点

  1. 清晰的分层结构(页面 → Hook → API → Client
  2. 类型安全(完整的 TypeScript 类型定义)
  3. 权限管理系统
  4. 可复用的 CRUD 模式
  5. 自动 Token 刷新机制

需要关注的方面

  1. 页面文件大小UserLevelConfigs.tsx 和 SystemConfigs.tsx 都接近 300 行,可以考虑拆分
  2. 组件复用:考虑提取通用的 CRUD 表格组件
  3. 错误处理:某些 API 调用的错误处理需要完善
  4. 加载状态:分页加载、动作加载等状态管理可以统一

开发指南

添加新的配置管理页面

步骤

  1. 创建类型定义 (src/types/xxxConfig.ts)
export interface XxxConfig {
  id: number;
  name: string;
  value: string;
  status: number;
  created_at: string;
  updated_at: string;
}

export interface XxxConfigListRequest {
  page?: number;
  size?: number;
}

export interface XxxConfigListResponse {
  data: XxxConfig[];
  total: number;
}
  1. 创建 API 服务 (src/services/xxxConfigApi.ts)
export const getXxxConfigList = async (params) =>
  (await apiClient.get('/admin/xxx-configs', { params })).data;

export const createXxxConfig = async (data) =>
  (await apiClient.post('/admin/xxx-configs', data)).data;
// ... 其他 CRUD 操作
  1. 创建页面组件 (src/pages/XxxConfigs.tsx)
  • 参考 UserLevelConfigs.tsx 或 SystemConfigs.tsx 的结构
  • 实现列表、创建、编辑、删除、状态切换
  1. 添加路由 (src/App.tsx)
<Route path="/system/xxx-configs" element={<XxxConfigs />} />
  1. 添加菜单项 (src/components/DynamicMenu.tsx)
{
  key: 'system-xxx-configs',
  label: 'Xxx 配置',
  icon: <SettingOutlined />,
  path: '/xxx-configs',
}

总结

这是一个结构良好的 React 管理后台,具有:

  • 权限驱动的动态菜单和路由
  • 清晰的分层 API 架构
  • 完整的 TypeScript 类型支持
  • 通用的 CRUD 页面模式
  • 自动化的 Token 管理

最近的开发方向是添加系统配置管理功能SystemConfigs 和 UserLevelConfigs这些都是遵循统一的模式和最佳实践。