Files
goalfylearning-admin-web/QUICK_REFERENCE.md

393 lines
9.9 KiB
Markdown
Raw Permalink 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 管理后台 - 快速参考指南
## 项目信息
| 项目 | 说明 |
|------|------|
| **名称** | goalfymax-admin-web |
| **框架** | React 18.3.1 + TypeScript + Vite |
| **UI 库** | Ant Design 5.27.4 |
| **路由** | React Router 7.9.4 |
| **HTTP** | Axios 1.12.2 |
| **状态管理** | Jotai 2.15.0 |
| **总文件数** | 48 个 TS/TSX 文件 |
---
## 目录速查表
| 目录 | 用途 | 示例 |
|------|------|------|
| `src/pages/` | 页面组件 | UserLevelConfigs.tsx |
| `src/services/` | API 服务 | userLevelConfigApi.ts |
| `src/types/` | TypeScript 类型 | userLevelConfig.ts |
| `src/components/` | 可复用组件 | Layout.tsx, DynamicMenu.tsx |
| `src/hooks/` | 自定义 Hooks | useAuth.ts, usePagePermissions.ts |
| `src/atoms/` | Jotai 状态管理 | auth.ts |
| `src/routes/` | 路由配置 | DynamicRoutes.tsx |
| `src/utils/` | 工具函数 | storageMigration.ts |
---
## 关键概念速览
### 1. 双层路由系统
```
App.tsx (静态路由) + DynamicRoutes.tsx (权限感知路由)
Layout 组件 (侧边栏 + 菜单)
DynamicMenu (权限过滤菜单项)
```
### 2. API 调用流程
```
页面组件 → API 服务 → ApiClient → Axios → 后端 API
```
### 3. 权限检查层级
```
页面权限 (usePagePermissions) → 菜单权限 (DynamicMenu) → 操作权限 (usePermissions)
```
---
## 常见任务速查
### 添加新的配置管理页面
**所需文件数**3-4 个
**开发时间**:约 30-60 分钟
**步骤**
```bash
# 1. 创建类型定义
src/types/xxxConfig.ts
# 2. 创建 API 服务
src/services/xxxConfigApi.ts
# 3. 创建页面组件
src/pages/XxxConfigs.tsx
# 4. 更新路由 (src/App.tsx)
<Route path="/system/xxx-configs" element={<XxxConfigs />} />
# 5. 更新菜单 (src/components/DynamicMenu.tsx)
# 6. 更新子导航 (src/components/Layout.tsx)
```
### 快速复制模板
**UserLevelConfigs 类似的 CRUD 页面**
- 类型定义:`src/types/userLevelConfig.ts` (47 行)
- API 服务:`src/services/userLevelConfigApi.ts` (60 行)
- 页面组件:`src/pages/UserLevelConfigs.tsx` (292 行)
**SystemConfigs 类似的配置管理**
- 类型定义:`src/types/systemConfig.ts` (51 行)
- API 服务:`src/services/systemConfigApi.ts` (66 行)
- 页面组件:`src/pages/SystemConfigs.tsx` (284 行)
---
## 重要文件速查
### 核心基础设施
| 文件 | 行数 | 作用 |
|------|------|------|
| `src/App.tsx` | 68 | 主应用入口,静态路由定义 |
| `src/services/api.ts` | 587 | 核心 API 客户端 + 所有 API 服务导出 |
| `src/components/Layout.tsx` | 298 | 主布局(侧边栏 + 主区域 + 子导航) |
| `src/components/DynamicMenu.tsx` | 228 | 权限感知菜单 |
| `src/hooks/useAuth.ts` | ? | 认证管理 Hook |
| `src/hooks/usePagePermissions.ts` | ? | 页面权限 Hook |
### 配置管理示例
| 功能 | 页面 | 类型 | API 服务 |
|------|------|------|----------|
| 用户等级配置 | UserLevelConfigs.tsx | userLevelConfig.ts | userLevelConfigApi.ts |
| 系统配置 | SystemConfigs.tsx | systemConfig.ts | systemConfigApi.ts |
| GoalfyMax 用户 | GoalfyMaxUsers.tsx | - | api.ts (GoalfyMaxUsersApi) |
---
## 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 服务函数
```typescript
// src/services/xxxConfigApi.ts
import { apiClient } from './api';
import type { XxxConfig, XxxConfigListRequest } from '../types/xxxConfig';
export const getXxxConfigList = async (params: XxxConfigListRequest) => {
const response = await apiClient.get('/admin/xxx-configs', { params });
return response.data;
};
export const createXxxConfig = async (data: any) => {
const response = await apiClient.post('/admin/xxx-configs', data);
return response.data;
};
export const updateXxxConfig = async (id: number, data: any) => {
const response = await apiClient.put(`/admin/xxx-configs/${id}`, data);
return response.data;
};
export const deleteXxxConfig = async (id: number) => {
await apiClient.delete(`/admin/xxx-configs/${id}`);
};
```
### 创建新的类型定义
```typescript
// 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;
}
```
### 创建 CRUD 页面骨架
```typescript
// src/pages/XxxConfigs.tsx
import React, { useEffect, useState } from 'react';
import { Table, Button, Modal, Form, Input, message } from 'antd';
import { PlusOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons';
import type { XxxConfig } from '../types/xxxConfig';
import { getXxxConfigList, createXxxConfig, updateXxxConfig, deleteXxxConfig } from '../services/xxxConfigApi';
export default function XxxConfigs() {
const [loading, setLoading] = useState(false);
const [list, setList] = useState<XxxConfig[]>([]);
const [total, setTotal] = useState(0);
const [page, setPage] = useState(1);
const [size, setSize] = useState(10);
const [editing, setEditing] = useState<XxxConfig | null>(null);
const [editOpen, setEditOpen] = useState(false);
const [createOpen, setCreateOpen] = useState(false);
const [form] = Form.useForm();
const [createForm] = Form.useForm();
const fetchList = async () => {
setLoading(true);
try {
const res = await getXxxConfigList({ page, size });
setList(res?.data ?? []);
setTotal(res?.total ?? 0);
} catch (e) {
message.error('获取列表失败');
} finally {
setLoading(false);
}
};
useEffect(() => {
fetchList();
}, [page, size]);
// ... 其他 handlers
return (
<div>
<Button type="primary" icon={<PlusOutlined />} onClick={() => setCreateOpen(true)}>
新建
</Button>
<Table dataSource={list} loading={loading} pagination={{
current: page, pageSize: size, total,
onChange: (p, s) => { setPage(p); setSize(s); }
}} />
{/* 弹窗 */}
</div>
);
}
```
---
## 常见错误和解决方案
### 问题 1页面显示后没有数据
**原因**API 端点不正确或权限不足
**解决**
1. 检查 API 端点 URL
2. 检查用户权限
3. 查看浏览器控制台错误日志
### 问题 2菜单项不显示
**原因**:权限检查失败
**解决**
1. 检查 DynamicMenu.tsx 的权限逻辑
2. 验证用户权限是否包含该页面路径
3. 查看控制台的权限检查日志(带 🔍 标记)
### 问题 3创建/编辑后页面没有刷新
**原因**:未调用 fetchList()
**解决**
1. 确保在 submitCreate/submitEdit 中调用 fetchList()
2. 检查是否有错误导致代码未执行到刷新逻辑
### 问题 4Token 过期导致 401 错误
**原因**Token 已过期ApiClient 应该自动处理
**解决**
1. 检查 refreshToken 是否存在
2. 查看浏览器控制台的 token 刷新日志
3. 检查后端是否正确响应 token 刷新请求
---
## 性能优化建议
### 当前架构的瓶颈
1. **大型页面文件**
- UserLevelConfigs.tsx: 292 行
- SystemConfigs.tsx: 284 行
- 建议:拆分为表格、表单、操作等子组件
2. **重复的 CRUD 代码**
- 每个管理页面都有类似的列表、创建、编辑、删除逻辑
- 建议:提取通用的 CRUD Hook 或高阶组件
3. **API 响应处理不一致**
- userLevelConfigApi 返回 response.data
- systemConfigApi 返回 response
- 建议:统一响应处理方式
---
## 开发工作流
### 开发新功能的标准步骤
```
1. 分析需求,确定数据模型
2. 创建 TypeScript 类型定义 (src/types/)
3. 创建 API 服务函数 (src/services/)
4. 创建页面组件 (src/pages/)
5. 注册路由 (src/App.tsx)
6. 添加菜单项 (src/components/DynamicMenu.tsx)
7. 更新子导航(如需要) (src/components/Layout.tsx)
8. 本地测试
9. 提交代码
```
---
## 有用的命令
```bash
# 启动开发服务器
npm run dev
# 构建生产版本
npm run build
# 代码检查
npm run lint
# 预览生产构建
npm run preview
```
---
## 文档链接
- **项目架构概览**PROJECT_ARCHITECTURE.md
- **API 模式详解**API_PATTERNS.md
- **Ant Design 文档**https://ant.design/
- **React Router 文档**https://reactrouter.com/
- **Jotai 文档**https://jotai.org/
---
## 常用类名和常量
### 用户等级配置
- 页面:`/system/user-level-configs`
- 菜单 key`system-user-level-configs`
- 类型文件:`userLevelConfig.ts`
- API 服务:`userLevelConfigApi.ts`
### 系统配置
- 页面:`/system/system-configs`
- 菜单 key`system-system-configs``system-global-configs`
- 类型文件:`systemConfig.ts`
- API 服务:`systemConfigApi.ts`
---
## 快速检查清单
创建新页面前,检查:
- [ ] 后端 API 已实现
- [ ] 类型定义完整
- [ ] API 服务函数齐全CRUD 所有操作)
- [ ] 页面组件遵循 CRUD 模式
- [ ] 路由已注册
- [ ] 菜单项已添加
- [ ] 权限检查已配置(如需要)
- [ ] 表单验证规则完整
- [ ] 错误处理到位
- [ ] 加载状态反馈清晰