Files
goalfylearning-admin-web/PROJECT_ARCHITECTURE.md

481 lines
14 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.

# 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 等)
```typescript
// 示例:系统管理路由
<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 组件**特点:
- 权限感知的菜单项过滤
- 支持一级和二级菜单
- 自动同步当前路由位置
- 详细的权限检查日志
核心逻辑:
```typescript
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 服务示例
**系统配置 API**systemConfigApi.ts
```typescript
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;
}
```
**用户等级配置 API**userLevelConfigApi.ts
```typescript
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 行)
**功能**
- 列表查询(分页)
- 创建新等级配置
- 编辑等级配置
- 删除等级配置
- 启用/禁用等级配置
**数据模型**
```typescript
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 行)
**功能**
- 列表查询(分页)
- 创建新系统配置
- 编辑系统配置
- 删除系统配置
- 启用/禁用系统配置
**数据模型**
```typescript
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. 操作列(编辑、启用/禁用、删除)
**状态管理**
```typescript
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`)
```typescript
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;
}
```
2. **创建 API 服务** (`src/services/xxxConfigApi.ts`)
```typescript
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 操作
```
3. **创建页面组件** (`src/pages/XxxConfigs.tsx`)
- 参考 UserLevelConfigs.tsx 或 SystemConfigs.tsx 的结构
- 实现列表、创建、编辑、删除、状态切换
4. **添加路由** (`src/App.tsx`)
```typescript
<Route path="/system/xxx-configs" element={<XxxConfigs />} />
```
5. **添加菜单项** (`src/components/DynamicMenu.tsx`)
```typescript
{
key: 'system-xxx-configs',
label: 'Xxx 配置',
icon: <SettingOutlined />,
path: '/xxx-configs',
}
```
---
## 总结
这是一个**结构良好的 React 管理后台**,具有:
- 权限驱动的动态菜单和路由
- 清晰的分层 API 架构
- 完整的 TypeScript 类型支持
- 通用的 CRUD 页面模式
- 自动化的 Token 管理
最近的开发方向是**添加系统配置管理功能**SystemConfigs 和 UserLevelConfigs这些都是遵循统一的模式和最佳实践。