From 4f645c6e78c674bd993ebf92f18e719b304ae086 Mon Sep 17 00:00:00 2001 From: huertian Date: Mon, 6 Jan 2025 16:15:16 +0800 Subject: [PATCH] =?UTF-8?q?docs:=E5=88=A0=E9=99=A4=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- API文档.md | 645 ------------------------------------------ 批量添加用户模版.xlsx | Bin 10380 -> 0 bytes 批量添加课程模版.xlsx | Bin 10197 -> 0 bytes 批量添加部门模版.xlsx | Bin 9560 -> 0 bytes 数据库.md | 194 ------------- 5 files changed, 839 deletions(-) delete mode 100644 API文档.md delete mode 100644 批量添加用户模版.xlsx delete mode 100644 批量添加课程模版.xlsx delete mode 100644 批量添加部门模版.xlsx delete mode 100644 数据库.md diff --git a/API文档.md b/API文档.md deleted file mode 100644 index d1fc934..0000000 --- a/API文档.md +++ /dev/null @@ -1,645 +0,0 @@ -# 进度管理系统 API 文档 - -## 基础信息 - -- 基础 URL: `http://localhost:1218` -- 所有请求和响应均使用 JSON 格式 -- 所有需要认证的接口都需要在请求头中携带 `Authorization: Bearer {token}` - -## 通用响应格式 - -```json -{ - "code": 10000, // 响应码 - "message": "成功", // 响应消息 - "data": {} // 响应数据 -} -``` - -### 响应码说明 - -| 响应码 | 说明 | 消息 | -| ------ | ---------- | ---------- | -| 10000 | 成功 | 成功 | -| 10001 | 参数错误 | 参数无效 | -| 10002 | 非教师用户 | 非教师用户 | -| 10003 | 用户不存在 | 用户不存在 | -| 10004 | 密码错误 | 密码错误 | -| 10005 | 邮箱已存在 | 邮箱已存在 | -| 10006 | 未授权 | 未授权 | -| 10007 | 令牌过期 | 令牌已过期 | -| 10008 | 令牌无效 | 无效的令牌 | -| 10009 | 系统错误 | 系统错误 | - -## 字段说明 - -### 用户相关字段 - -1. **角色 (roles)** - - - 1: 教师 - - 2: 普通管理员 - - 3: 沟通联络人 - - 4: 系统管理员 - -2. **岗位 (jobs)** - - - 1: 课程制作教师 - - 2: 课程购买方项目负责人 - - 3: 课程制作方沟通联络人 - - 4: 系统制作方项目负责人 - -3. **用户状态 (status)** - - - 1: 正常 - - 0: 禁用 - -4. **Spring Security 相关字段** - - `enabled`: 账号是否启用(true: 启用,false: 禁用) - - `accountNonExpired`: 账号是否未过期(true: 未过期,false: 已过期) - - `accountNonLocked`: 账号是否未锁定(true: 未锁定,false: 已锁定) - - `credentialsNonExpired`: 密码是否未过期(true: 未过期,false: 已过期) - - `authorities`: 用户权限列表,包含用户被授予的所有权限(如 "ROLE_USER") - -### 课程任务相关字段 - -1. **进度状态 (progressStatus)** - - 0: 未开始 - - 1: 脚本制作 - - 2: 脚本审核 - - 3: 脚本确认 - - 4: 视频拍摄与制作 - - 5: 视频确认 - -## 用户接口 - -### 1. 用户注册 - -- **接口**:`POST /api/users` -- **描述**:创建新用户 -- **认证**:不需要 -- **请求体**: - ```json - { - "username": "testuser", // 用户名,不可为空 - "email": "test@example.com", // 邮箱,不可为空且唯一 - "password": "password123", // 密码,不可为空 - "departmentId": 1, // 部门ID,不可为空,关联departments表 - "roles": 1, // 角色:1-教师,2-普通管理员,3-沟通联络人,4-系统管理员 - "jobs": 1, // 岗位:1-课程制作教师,2-课程购买方项目负责人,3-课程制作方沟通联络人,4-系统制作方项目负责人 - "avatar": "http://example.com/avatar.jpg", // 头像URL,可选 - "creatorId": 1 // 创建者ID,不可为空 - } - ``` -- **成功响应**: - ```json - { - "code": 10000, - "message": "成功", - "data": null - } - ``` -- **错误响应**: - ```json - { - "code": 10005, - "message": "邮箱已存在", - "data": null - } - ``` - -### 2. 用户登录 - -- **接口**:`POST /api/users/login` -- **描述**:用户登录获取 token -- **认证**:不需要 -- **请求体**: - ```json - { - "email": "test@example.com", // 邮箱 - "password": "password123", // 密码 - "remember": true // 是否记住登录(可选) - } - ``` -- **成功响应**: - ```json - { - "code": 10000, - "message": "成功", - "data": { - "token": "eyJhbGciOiJIUzM4NCJ9..." // JWT令牌 - } - } - ``` - -### 3. 用户登出 - -- **接口**:`POST /api/users/logout` -- **描述**:用户登出,使当前 token 失效 -- **认证**:需要 -- **成功响应**: - ```json - { - "code": 10000, - "message": "成功", - "data": "登出成功" - } - ``` - -### 4. 获取当前用户信息 - -- **接口**:`GET /api/users/current` -- **描述**:获取当前登录用户信息 -- **认证**:需要 -- **成功响应**: - ```json - { - "code": 10000, - "message": "成功", - "data": { - "id": 12, - "username": "testuser", - "email": "test@example.com", - "departmentId": 1, - "roles": 1, - "jobs": 1, - "avatar": null, - "creatorId": 1, - "status": 1, - "createdAt": 1734578081, - "updatedAt": 1734578081, - "enabled": true, - "authorities": [ - { - "authority": "ROLE_USER" - } - ] - } - } - ``` - -### 5. 获取用户列表 - -- **接口**:`GET /api/users/list` -- **描述**:分页获取用户列表 -- **认证**:需要 -- **查询参数**: - - `page`: 页码(从 1 开始) - - `limit`: 每页数量(默认 10) -- **成功响应**: - ```json - { - "code": 10000, - "message": "成功", - "data": { - "list": [ - { - "id": 1, - "username": "admin", - "email": "admin@example.com", - "departmentId": 1, - "roles": 4, - "jobs": 4, - "avatar": null, - "creatorId": 1, - "status": 1, - "createdAt": 1734578081, - "updatedAt": 1734578081 - } - ], - "total": 12, - "currentPage": 1, - "pageSize": 10 - } - } - ``` - -### 6. 禁用用户 - -- **接口**:`POST /api/users/disable/{userId}` -- **描述**:禁用指定用户 -- **认证**:需要 -- **路径参数**: - - `userId`: 用户 ID -- **成功响应**: - ```json - { - "code": 10000, - "message": "成功", - "data": "用户已禁用" - } - ``` - -### 7. 查询部门用户列表 - -- **接口**:`GET /api/users/department/{departmentId}` -- **描述**:获取指定部门下的所有正常状态用户列表 -- **认证**:需要 -- **路径参数**: - - `departmentId`: 部门 ID -- **成功响应**: - ```json - { - "code": 10000, - "message": "成功", - "data": [ - { - "id": 2, - "username": "普通管理员账号2", - "email": "user2@qq.com", - "password": null, - "departmentId": 1, - "roles": 2, - "jobs": 2, - "avatar": null, - "creatorId": 1, - "status": 1, - "createdAt": 1734504506, - "updatedAt": 1734504506, - "enabled": true, - "authorities": [ - { - "authority": "ROLE_USER" - } - ], - "accountNonExpired": true, - "accountNonLocked": true, - "credentialsNonExpired": true - } - ] - } - ``` -- **错误响应**: - ```json - { - "code": 50000, - "message": "获取部门用户列表失败", - "data": null - } - ``` - -### 8. 搜索教师信息 - -- **接口**:`GET /api/users/teacher/search` -- **描述**:通过邮箱搜索教师信息 -- **认证**:需要 -- **查询参数**: - - `email`: 教师邮箱 -- **成功响应**: - ```json - { - "code": 10000, - "message": "成功", - "data": { - "id": 1, - "username": "张三", - "email": "user1@qq.com", - "password": null, - "departmentId": 2, - "roles": 1, - "jobs": 1, - "avatar": null, - "creatorId": 1, - "status": 1, - "createdAt": 1734504506, - "updatedAt": 1734504506, - "enabled": true, - "accountNonExpired": true, - "accountNonLocked": true, - "credentialsNonExpired": true, - "authorities": [ - { - "authority": "ROLE_USER" - } - ] - } - } - ``` -- **错误响应**: - ```json - { - "code": 10009, - "message": "系统错误", - "data": null - } - ``` - -## 课程任务接口 - -### 1. 获取课程任务列表 - -- **接口**:`GET /api/lesson-tasks` -- **描述**:分页获取课程任务列表,可按用户筛选 -- **认证**:需要 -- **查询参数**: - - `page`: 页码(从 1 开始) - - `size`: 每页数量(默认 10) - - `userId`: 用户 ID(可选) -- **成功响应**: - ```json - { - "code": 10000, - "message": "成功", - "data": { - "content": [ - { - "id": 1, - "courseName": "数学", - "microLessonName": "数学1-1", - "userId": 1, - "progressStatus": 4, - "scriptCreateTime": 1734940587, - "scriptReviewTime": null, - "scriptConfirmTime": 1734940825, - "videoCreateTime": 1734940832, - "videoConfirmTime": 1734940837, - "finishTime": 1734940837, - "advise": "", - "createdAt": 1734674726, - "updatedAt": 1734940837 - } - ], - "pageable": { - "pageNumber": 0, - "pageSize": 10, - "sort": { - "empty": true, - "unsorted": true, - "sorted": false - } - }, - "totalElements": 7, - "totalPages": 1, - "last": true, - "first": true, - "empty": false - } - } - ``` - -### 2. 获取单个课程任务 - -- **接口**:`GET /api/lesson-tasks/{id}` -- **描述**:根据 ID 获取课程任务详情 -- **认证**:需要 -- **路径参数**: - - `id`: 课程任务 ID -- **成功响应**: - ```json - { - "code": 10000, - "message": "成功", - "data": { - "id": 1, - "courseName": "数学", - "microLessonName": "数学1-1", - "userId": 1, - "progressStatus": 4, - "scriptCreateTime": 1734940587, - "scriptReviewTime": null, - "scriptConfirmTime": 1734940825, - "videoCreateTime": 1734940832, - "videoConfirmTime": 1734940837, - "finishTime": 1734940837, - "advise": "", - "createdAt": 1734674726, - "updatedAt": 1734940837 - } - } - ``` - -### 3. 创建课程任务 - -- **接口**:`POST /api/lesson-tasks` -- **描述**:创建新的课程任务 -- **认证**:需要 -- **请求体**: - ```json - { - "courseName": "测试课程", - "microLessonName": "测试微课", - "userId": 1, - "advise": "任务说明" - } - ``` -- **成功响应**: - ```json - { - "code": 10000, - "message": "成功", - "data": { - "id": 11, - "courseName": "测试课程", - "microLessonName": "测试微课", - "userId": 1, - "progressStatus": 0, - "scriptCreateTime": null, - "scriptReviewTime": null, - "scriptConfirmTime": null, - "videoCreateTime": null, - "videoConfirmTime": null, - "finishTime": null, - "advise": "任务说明", - "createdAt": 1735003870, - "updatedAt": 1735003870 - } - } - ``` - -### 4. 更新课程任务 - -- **接口**:`PUT /api/lesson-tasks/{id}` -- **描述**:更新课程任务信息 -- **认证**:需要 -- **路径参数**: - - `id`: 课程任务 ID -- **请求体**: - ```json - { - "progressStatus": 1, - "advise": "更新的任务说明" - } - ``` -- **成功响应**: - ```json - { - "code": 10000, - "message": "成功", - "data": { - "id": 11, - "courseName": "测试课程", - "microLessonName": "测试微课", - "userId": 1, - "progressStatus": 1, - "scriptCreateTime": 1735003922, - "scriptReviewTime": null, - "scriptConfirmTime": null, - "videoCreateTime": null, - "videoConfirmTime": null, - "finishTime": null, - "advise": "更新的任务说明", - "createdAt": 1735003870, - "updatedAt": 1735003922 - } - } - ``` - -### 5. 获取部门课程任务 - -- **接口**:`GET /api/lesson-tasks/department/{departmentId}` -- **描述**:获取指定部门的课程任务列表 -- **认证**:需要 -- **路径参数**: - - `departmentId`: 部门 ID -- **查询参数**: - - `page`: 页码(从 1 开始) - - `size`: 每页数量(默认 10) -- **成功响应**: - ```json - { - "code": 10000, - "message": "成功", - "data": { - "content": [ - { - "id": 1, - "courseName": "数学", - "microLessonName": "数学1-1", - "userId": 1, - "username": "教师账号1", - "progressStatus": 4, - "scriptCreateTime": 1734940587, - "scriptReviewTime": null, - "scriptConfirmTime": 1734940825, - "videoCreateTime": 1734940832, - "videoConfirmTime": 1734940837, - "finishTime": 1734940837, - "advise": "", - "createdAt": 1734674726, - "updatedAt": 1734940837 - } - ], - "pageable": { - "pageNumber": 0, - "pageSize": 10 - }, - "totalElements": 11, - "totalPages": 2 - } - } - ``` - -### 6. 删除课程任务 - -- **接口**:`DELETE /api/lesson-tasks/{id}` -- **描述**:删除指定的课程任务 -- **认证**:需要 -- **路径参数**: - - `id`: 课程任务 ID -- **成功响应**: - ```json - { - "code": 10000, - "message": "成功", - "data": null - } - ``` - -## 批量导入接口 - -### 1. 批量导入用户 - -- **接口**:`POST /api/import/users` -- **描述**:通过 Excel 文件批量导入用户 -- **认证**:需要 -- **请求体**: - - `Content-Type`: `multipart/form-data` - - `file`: Excel 文件(.xlsx) -- **Excel 文件格式**: - | 用户名 | 邮箱 | 密码 | 部门名称 | - |--------|------|------|----------| - | 张三 | zhangsan@example.com | 123456 | 技术部 | -- **成功响应**: - ```json - { - "code": 10000, - "message": "成功", - "data": "成功导入2条数据" - } - ``` -- **错误响应**: - ```json - { - "code": 10012, - "message": "成功导入0条数据。错误信息:第2行邮箱已存在;第3行部门不存在;", - "data": null - } - ``` - -### 2. 批量导入课程任务 - -- **接口**:`POST /api/import/lesson-tasks` -- **描述**:通过 Excel 文件批量导入课程任务 -- **认证**:需要 -- **请求体**: - - `Content-Type`: `multipart/form-data` - - `file`: Excel 文件(.xlsx) -- **Excel 文件格式**: - | 课程名称 | 微课名称 | 教师邮箱 | - |----------|----------|-----------| - | 数学课程 | 第一章 | teacher@example.com | -- **成功响应**: - ```json - { - "code": 10000, - "message": "成功", - "data": "成功导入3条数据" - } - ``` -- **错误响应**: - ```json - { - "code": 10012, - "message": "成功导入0条数据。错误信息:第2行未找到教师用户(teacher@example.com);", - "data": null - } - ``` - -### 3. 批量导入部门 - -- **接口**:`POST /api/import/departments` -- **描述**:通过 Excel 文件批量导入部门 -- **认证**:需要 -- **请求体**: - - `Content-Type`: `multipart/form-data` - - `file`: Excel 文件(.xlsx) -- **Excel 文件格式**: - | 部门名称 | 部门描述 | - |----------|----------| - | 技术部 | 负责技术研发 | -- **成功响应**: - ```json - { - "code": 10000, - "message": "成功", - "data": "成功导入2条数据" - } - ``` -- **错误响应**: - ```json - { - "code": 10012, - "message": "成功导入0条数据。错误信息:第2行部门名称已存在;", - "data": null - } - ``` - -## 注意事项 - -1. 所有时间戳字段均使用秒级时间戳(10 位) -2. 课程任务状态变更时会自动记录相应的时间戳 -3. 部门课程任务列表会额外返回用户名信息 -4. 分页参数中的页码从 1 开始 -5. 批量导入时,Excel 文件必须严格按照模板格式填写 -6. 批量导入时,如果某行数据导入失败,会在返回信息中说明具体原因 -7. 批量导入时,如果全部数据导入失败,会返回错误状态码(10012) diff --git a/批量添加用户模版.xlsx b/批量添加用户模版.xlsx deleted file mode 100644 index f3e5070cf1ee22f797e5fa8db053762835c2a0d9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10380 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 E0A>2)*Z=?k diff --git a/批量添加课程模版.xlsx b/批量添加课程模版.xlsx deleted file mode 100644 index cd30c307e77b93e8e294bd607c8c58164b93835a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10197 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 diff --git a/批量添加部门模版.xlsx b/批量添加部门模版.xlsx deleted file mode 100644 index 438ca251714ffcabf22fae5a16149c71ee770982..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9560 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 `departments.id` - - - 一个部门可以有多个用户 - - 一个用户只能属于一个部门 - - 使用 RESTRICT 约束,防止删除仍有用户的部门 - -2. `lesson_tasks.user_id` -> `users.id` - - - 一个用户可以负责多个课程任务 - - 一个课程任务只能有一个负责人 - - 使用 CASCADE 约束,删除用户时自动删除其负责的课程任务 - -3. `lesson_tasks` 和 `users` 表关系: - - - 一对多关系:一个用户(users)可以负责多个课程任务(lesson_tasks) - - 通过 `user_id` 外键关联,确保任务负责人的有效性 - - 使用 CASCADE 级联删除:当用户被删除时,相关任务也会被自动删除 - - 使用 CASCADE 级联更新:当用户 ID 更新时,相关任务的 user_id 也会自动更新 - -4. 索引说明: - - - `idx_user_id`: 优化按负责人查询任务的性能 - - `idx_progress_status`: 优化按任务状态筛选和统计的性能 - - `idx_course_name`: 优化按课程名称查询和分组的性能 - - `idx_user_progress`: 优化同时按用户和任务状态查询的性能,适用于查看特定用户的特定状态任务 - -5. 时间节点追踪: - - 系统通过各个时间戳字段(script_create_time, script_review_time 等)完整记录任务的每个阶段 - - 可以通过这些时间戳计算各阶段的耗时,用于任务进度分析和效率优化 - -## 注意事项 - -1. 所有时间戳字段使用 BIGINT 类型,存储毫秒级时间戳 -2. 字符编码统一使用 utf8mb4,支持完整的 Unicode 字符集 -3. 所有表都使用 InnoDB 引擎,支持事务和外键 -4. 关键字段都建立了适当的索引以提高查询性能 -5. 用户密码在存储前需要进行加密处理 -6. 删除用户时会自动删除其关联的课程任务,但不会影响部门数据