9.9 KiB
9.9 KiB
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 分钟 步骤:
# 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 服务函数
// 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}`);
};
创建新的类型定义
// 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 页面骨架
// 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 端点不正确或权限不足 解决:
- 检查 API 端点 URL
- 检查用户权限
- 查看浏览器控制台错误日志
问题 2:菜单项不显示
原因:权限检查失败 解决:
- 检查 DynamicMenu.tsx 的权限逻辑
- 验证用户权限是否包含该页面路径
- 查看控制台的权限检查日志(带 🔍 标记)
问题 3:创建/编辑后页面没有刷新
原因:未调用 fetchList() 解决:
- 确保在 submitCreate/submitEdit 中调用 fetchList()
- 检查是否有错误导致代码未执行到刷新逻辑
问题 4:Token 过期导致 401 错误
原因:Token 已过期,ApiClient 应该自动处理 解决:
- 检查 refreshToken 是否存在
- 查看浏览器控制台的 token 刷新日志
- 检查后端是否正确响应 token 刷新请求
性能优化建议
当前架构的瓶颈
-
大型页面文件
- UserLevelConfigs.tsx: 292 行
- SystemConfigs.tsx: 284 行
- 建议:拆分为表格、表单、操作等子组件
-
重复的 CRUD 代码
- 每个管理页面都有类似的列表、创建、编辑、删除逻辑
- 建议:提取通用的 CRUD Hook 或高阶组件
-
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. 提交代码
有用的命令
# 启动开发服务器
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 模式
- 路由已注册
- 菜单项已添加
- 权限检查已配置(如需要)
- 表单验证规则完整
- 错误处理到位
- 加载状态反馈清晰