[根目录](../../CLAUDE.md) > **app/backend** --- # 管理后台前端(PlayEdu Backend) ## 变更记录 (Changelog) ### 2025-11-24 22:45:26 - 初始化模块文档 --- ## 模块职责 PlayEdu 管理后台是供平台管理员使用的 Web 应用,提供: - 课程管理(线上课程、线下课程、实验课程、软件模块) - 教材与知识点管理 - 考试与题库管理 - 学员与部门管理 - 资源库管理(视频、文档、音频、图片、附件) - AI 知识库管理 - 系统配置与权限管理 - 数据统计与日志查看 --- ## 入口与启动 **主入口文件**:`src/main.tsx` **启动命令**: ```bash cd app/backend npm install npm run dev ``` **构建命令**: ```bash npm run build ``` **开发服务器**:`http://localhost:5173`(Vite 默认端口) **生产构建输出**:`dist/` --- ## 对外接口 ### API 通信 - **API Base URL**:配置在 `src/api/internal/httpClient.ts` - **认证方式**:Bearer Token(存储在 localStorage) ### ⚠️ httpClient 响应数据结构(重要) **httpClient 已经解包了一层**,调用 `client.get/post/put` 返回的是 `response.data`,即: ```typescript // 后端原始响应 { "code": 0, "msg": "", "data": [...] } // httpClient.get() 返回的 res 就是上面这个对象 const res = await client.get('/api/xxx'); // res = { code: 0, msg: "", data: [...] } // res.data = [...] ✅ 正确 // res.data.data ❌ 错误!多解了一层 ``` **正确用法**: ```typescript const res: any = await someApi.getData(); const items = res.data || []; // ✅ 直接用 res.data ``` **错误用法**: ```typescript const res: any = await someApi.getData(); const items = res.data.data || []; // ❌ 多解了一层,永远是 undefined ``` ### 主要 API 模块(位于 `src/api/`): - `login.ts` - 管理员登录与认证 - `course.ts` - 课程管理 - `paper.ts` / `question.ts` - 考试与题库 - `user.ts` / `department.ts` - 学员与部门 - `resource.ts` / `resource-category.ts` - 资源管理 - `knowledge-*.ts` - AI 知识库 - `system.ts` / `app-config.ts` - 系统配置 - `upload.ts` - 文件上传(支持 S3/OSS) ### 路由结构 - **公开路由**:`/login` - 登录页 - **管理员路由**(需认证): - `/dashboard` - 数据看板 - `/course/*` - 课程管理 - `/offline-course/*` - 线下课程 - `/lab-course/*` - 实验课程 - `/textbook/*` - 教材管理 - `/exam/*` - 考试管理 - `/question/*` - 题库管理 - `/resource/*` - 资源库 - `/repository/*` - 仓库管理 - `/knowledge/*` - AI 知识库 - `/user/*` - 学员管理 - `/department/*` - 部门管理 - `/system/*` - 系统配置 --- ## 关键依赖与配置 ### 技术栈 - **框架**:React 18.2 + TypeScript 4.9 - **构建工具**:Vite 7.1.3 - **UI 库**:Ant Design 5.12.2 - **状态管理**:Redux Toolkit + React-Redux - **路由**:React Router DOM 6.9 - **HTTP 客户端**:Axios 1.3.4 - **富文本编辑器**:Quill 2.0.3 + Braft Editor - **图表**:ECharts 5.4.2 + ECharts for React - **视频播放器**:XGPlayer 3.0.13 + HLS 支持 - **文件上传**:Uppy 4.x(支持 AWS S3) - **国际化**:i18next + react-i18next - **工具库**:Day.js、Moment.js、Lodash、XLSX、FileSaver ### 配置文件 - `package.json` - 依赖与脚本定义 - `vite.config.ts` - Vite 构建配置(未找到,可能使用默认配置) - `tsconfig.json` - TypeScript 配置 - `eslint.config.js` - ESLint 配置(使用 Prettier 集成) ### 代码规范工具 - ESLint 9.x(@typescript-eslint/eslint-plugin) - Prettier 3.6.2 - 格式化命令:`npm run format` --- ## 数据模型 ### Redux Store 结构(`src/store/`) - `user.ts` / `userSlice` - 当前管理员信息 - `system.ts` / `systemSlice` - 系统配置(API URL、logo、名称等) - `resource.ts` / `resourceSlice` - 资源 URL 映射 ### 本地存储(localStorage) - `token` - 认证 Token - `api_url` - API 服务器地址 - `system_name` - 系统名称 - `language` - 界面语言(zh-CN / zh-TC) --- ## 测试与质量 - **代码检查**:ESLint(`npm run lint` / `npm run lint:quiet`) - **代码格式化**:Prettier(`npm run format`) - **类型检查**:TypeScript 严格模式 - **浏览器兼容性**:通过 Vite 自动处理 polyfills --- ## 常见问题 (FAQ) ### Q1:如何添加新的管理页面? 1. 在 `src/pages/` 下创建新页面组件 2. 在路由配置中添加路由(通常在 `App.tsx` 或独立的路由文件中) 3. 添加对应的 API 调用(在 `src/api/` 中) 4. 更新导航菜单(如果需要) ### Q2:如何配置 API 服务器地址? - 开发环境:在 `src/api/internal/httpClient.ts` 中配置 `baseURL` - 生产环境:通过环境变量或运行时配置 ### Q3:文件上传如何工作? - 使用 Uppy 组件(`@uppy/react`) - 支持直传到 S3/OSS(通过 `@uppy/aws-s3`) - 上传接口:`POST /backend/v1/upload/*` ### Q4:如何支持国际化? - 配置文件:`src/i18n/config.ts` - 语言包:`src/i18n/locales/` 目录 - 使用 `useTranslation()` Hook 进行翻译 --- ## 相关文件清单 ### 配置文件 - `app/backend/package.json` - NPM 依赖配置 - `app/backend/README.md` - 模块说明 ### 核心代码 - `src/main.tsx` - 应用入口 - `src/App.tsx` - 根组件与路由配置 - `src/api/` - API 接口定义 - `src/store/` - Redux 状态管理 - `src/pages/` - 页面组件 - `src/compenents/` - 可复用组件 - `src/assets/` - 静态资源(图片、字体、样式) ### 样式文件 - `src/index.less` - 全局样式 - `src/App.module.less` - 根组件样式 - 组件样式:`*.module.less` / `*.module.scss`