393 lines
9.9 KiB
Markdown
393 lines
9.9 KiB
Markdown
# 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. 检查是否有错误导致代码未执行到刷新逻辑
|
||
|
||
### 问题 4:Token 过期导致 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 模式
|
||
- [ ] 路由已注册
|
||
- [ ] 菜单项已添加
|
||
- [ ] 权限检查已配置(如需要)
|
||
- [ ] 表单验证规则完整
|
||
- [ ] 错误处理到位
|
||
- [ ] 加载状态反馈清晰
|
||
|