fix:固定时间戳单位为秒

This commit is contained in:
huertian
2025-01-03 14:09:53 +08:00
parent f990f6b7a3
commit 6dd845cdd7
8 changed files with 303 additions and 267 deletions

View File

@ -56,11 +56,12 @@
### 课程任务相关字段 ### 课程任务相关字段
1. **进度状态 (progressStatus)** 1. **进度状态 (progressStatus)**
- 0: 脚本上传 - 0: 未开始
- 1: 脚本确认 - 1: 脚本制作
- 2: 视频拍摄 - 2: 脚本审核
- 3: 后期制作 - 3: 脚本确认
- 4: 任务完成 - 4: 视频拍摄与制作
- 5: 视频确认
## 用户接口 ## 用户接口
@ -274,12 +275,12 @@
### 1. 获取课程任务列表 ### 1. 获取课程任务列表
- **接口**`GET /api/lesson-tasks` - **接口**`GET /api/lesson-tasks`
- **描述**:分页获取课程任务列表 - **描述**:分页获取课程任务列表,可按用户筛选
- **认证**:需要 - **认证**:需要
- **查询参数** - **查询参数**
- `page`: 页码(从 1 开始) - `page`: 页码(从 1 开始)
- `size`: 每页数量(默认 10 - `size`: 每页数量(默认 10
- `userId`: 用户 ID可选 - `userId`: 用户ID可选
- **成功响应** - **成功响应**
```json ```json
{ {
@ -288,27 +289,35 @@
"data": { "data": {
"content": [ "content": [
{ {
"id": 6, "id": 1,
"courseName": "Test Course", "courseName": "数学",
"microLessonName": "Test Lesson", "microLessonName": "数学1-1",
"userId": 12, "userId": 1,
"progressStatus": 1, "progressStatus": 4,
"scriptUploadTime": 1734578081, "scriptCreateTime": 1734940587,
"scriptConfirmTime": 1734578081, "scriptReviewTime": null,
"videoCaptureTime": 1734578081, "scriptConfirmTime": 1734940825,
"videoConfirmTime": 1734578081, "videoCreateTime": 1734940832,
"finishTime": 1734578081, "videoConfirmTime": 1734940837,
"advise": "Test advice", "finishTime": 1734940837,
"createdAt": 1734578081, "advise": "",
"updatedAt": 1734578081 "createdAt": 1734674726,
"updatedAt": 1734940837
} }
], ],
"totalElements": 4, "pageable": {
"pageNumber": 0,
"pageSize": 10,
"sort": {
"empty": true,
"unsorted": true,
"sorted": false
}
},
"totalElements": 7,
"totalPages": 1, "totalPages": 1,
"size": 10,
"number": 0,
"first": true,
"last": true, "last": true,
"first": true,
"empty": false "empty": false
} }
} }
@ -317,29 +326,30 @@
### 2. 获取单个课程任务 ### 2. 获取单个课程任务
- **接口**`GET /api/lesson-tasks/{id}` - **接口**`GET /api/lesson-tasks/{id}`
- **描述**:获取指定 ID 的课程任务 - **描述**根据ID获取课程任务详情
- **认证**:需要 - **认证**:需要
- **路径参数** - **路径参数**
- `id`: 课程任务 ID - `id`: 课程任务ID
- **成功响应** - **成功响应**
```json ```json
{ {
"code": 10000, "code": 10000,
"message": "成功", "message": "成功",
"data": { "data": {
"id": 6, "id": 1,
"courseName": "Test Course", "courseName": "数学",
"microLessonName": "Test Lesson", "microLessonName": "数学1-1",
"userId": 12, "userId": 1,
"progressStatus": 1, "progressStatus": 4,
"scriptUploadTime": 1734578081, "scriptCreateTime": 1734940587,
"scriptConfirmTime": 1734578081, "scriptReviewTime": null,
"videoCaptureTime": 1734578081, "scriptConfirmTime": 1734940825,
"videoConfirmTime": 1734578081, "videoCreateTime": 1734940832,
"finishTime": 1734578081, "videoConfirmTime": 1734940837,
"advise": "Test advice", "finishTime": 1734940837,
"createdAt": 1734578081, "advise": "",
"updatedAt": 1734578081 "createdAt": 1734674726,
"updatedAt": 1734940837
} }
} }
``` ```
@ -352,10 +362,10 @@
- **请求体** - **请求体**
```json ```json
{ {
"courseName": "Java基础", // 课程名称,不可为空 "courseName": "测试课程",
"microLessonName": "Java变量", // 微课名称,不可为空 "microLessonName": "测试微课",
"userId": 1, // 负责人ID不可为空关联users表 "userId": 1,
"advise": "请注意讲解速度" // 任务建议或备注,可选 "advise": "任务说明"
} }
``` ```
- **成功响应** - **成功响应**
@ -364,19 +374,20 @@
"code": 10000, "code": 10000,
"message": "成功", "message": "成功",
"data": { "data": {
"id": 6, "id": 11,
"courseName": "Java基础", "courseName": "测试课程",
"microLessonName": "Java变量", "microLessonName": "测试微课",
"userId": 1, "userId": 1,
"progressStatus": 1, "progressStatus": 0,
"scriptUploadTime": , "scriptCreateTime": null,
"scriptConfirmTime": , "scriptReviewTime": null,
"videoCaptureTime": , "scriptConfirmTime": null,
"videoConfirmTime": , "videoCreateTime": null,
"finishTime": , "videoConfirmTime": null,
"advise": "请注意讲解速度", "finishTime": null,
"createdAt": 1734578081, "advise": "任务说明",
"updatedAt": 1734578081 "createdAt": 1735003870,
"updatedAt": 1735003870
} }
} }
``` ```
@ -384,23 +395,15 @@
### 4. 更新课程任务 ### 4. 更新课程任务
- **接口**`PUT /api/lesson-tasks/{id}` - **接口**`PUT /api/lesson-tasks/{id}`
- **描述**:更新指定 ID 的课程任务 - **描述**:更新课程任务信息
- **认证**:需要 - **认证**:需要
- **路径参数** - **路径参数**
- `id`: 课程任务 ID - `id`: 课程任务ID
- **请求体** - **请求体**
```json ```json
{ {
"courseName": "Updated Course", // 课程名称 "progressStatus": 1,
"microLessonName": "Updated Lesson", // 微课名称 "advise": "更新的任务说明"
"userId": 12, // 用户ID
"progressStatus": 2, // 进度状态
"scriptUploadTime": 1734578081, // 脚本上传时间
"scriptConfirmTime": 1734578081, // 脚本确认时间
"videoCaptureTime": 1734578081, // 视频录制时间
"videoConfirmTime": 1734578081, // 视频确认时间
"finishTime": 1734578081, // 完成时间
"advise": "Updated advice" // 建议
} }
``` ```
- **成功响应** - **成功响应**
@ -409,46 +412,31 @@
"code": 10000, "code": 10000,
"message": "成功", "message": "成功",
"data": { "data": {
"id": 6, "id": 11,
"courseName": "Updated Course", "courseName": "测试课程",
"microLessonName": "Updated Lesson", "microLessonName": "测试微课",
"userId": 12, "userId": 1,
"progressStatus": 2, "progressStatus": 1,
"scriptUploadTime": 1734578081, "scriptCreateTime": 1735003922,
"scriptConfirmTime": 1734578081, "scriptReviewTime": null,
"videoCaptureTime": 1734578081, "scriptConfirmTime": null,
"videoConfirmTime": 1734578081, "videoCreateTime": null,
"finishTime": 1734578081, "videoConfirmTime": null,
"advise": "Updated advice", "finishTime": null,
"createdAt": 1734578081, "advise": "更新的任务说明",
"updatedAt": 1734578081 "createdAt": 1735003870,
"updatedAt": 1735003922
} }
} }
``` ```
### 5. 删除课程任务 ### 5. 获取部门课程任务
- **接口**`DELETE /api/lesson-tasks/{id}`
- **描述**:删除指定 ID 的课程任务
- **认证**:需要
- **路径参数**
- `id`: 课程任务 ID
- **成功响应**
```json
{
"code": 10000,
"message": "成功",
"data": null
}
```
### 6. 按部门 ID 查询课程任务
- **接口**`GET /api/lesson-tasks/department/{departmentId}` - **接口**`GET /api/lesson-tasks/department/{departmentId}`
- **描述**:获取指定部门下正常状态用户的课程任务列表(分页) - **描述**:获取指定部门的课程任务列表
- **认证**:需要 - **认证**:需要
- **路径参数** - **路径参数**
- `departmentId`: 部门 ID - `departmentId`: 部门ID
- **查询参数** - **查询参数**
- `page`: 页码(从 1 开始) - `page`: 页码(从 1 开始)
- `size`: 每页数量(默认 10 - `size`: 每页数量(默认 10
@ -461,89 +449,51 @@
"content": [ "content": [
{ {
"id": 1, "id": 1,
"courseName": "物理", "courseName": "数学",
"microLessonName": "微课1-1", "microLessonName": "数学1-1",
"userId": 1, "userId": 1,
"username": "教师账号1", // 新增:用户名字段 "username": "教师账号1",
"progressStatus": 4, "progressStatus": 4,
"scriptUploadTime": 1734498510, "scriptCreateTime": 1734940587,
"scriptConfirmTime": 1734498510, "scriptReviewTime": null,
"videoCaptureTime": 1734498510, "scriptConfirmTime": 1734940825,
"videoConfirmTime": 1734498510, "videoCreateTime": 1734940832,
"finishTime": 1734498510, "videoConfirmTime": 1734940837,
"advise": null, "finishTime": 1734940837,
"createdAt": 1734578081, "advise": "",
"updatedAt": 1734580393 "createdAt": 1734674726,
"updatedAt": 1734940837
} }
], ],
"totalElements": 10, "pageable": {
"totalPages": 1, "pageNumber": 0,
"size": 10, "pageSize": 10
"number": 0, },
"first": true, "totalElements": 11,
"last": true, "totalPages": 2
"empty": false
} }
} }
``` ```
### 7. 更新课程任务进度 ### 6. 删除课程任务
- **接口**`PUT /api/lesson-tasks/{id}` - **接口**`DELETE /api/lesson-tasks/{id}`
- **描述**更新课程任务的进度状态和建议 - **描述**删除指定的课程任务
- **认证**:需要 - **认证**:需要
- **路径参数** - **路径参数**
- `id`: 课程任务 ID - `id`: 课程任务ID
- **请求体**
```json
{
"progressStatus": 2, // 进度状态(可选)
"advise": "{\"method\":\"wechat\",\"uploaded\":true}" // 建议(可选)
}
```
- **说明**
- 更新进度状态时会自动更新对应的时间戳:
- 状态 1更新 scriptUploadTime
- 状态 2更新 scriptConfirmTime
- 状态 3更新 videoCaptureTime
- 状态 4更新 videoConfirmTime
- 状态 5更新 finishTime
- 只会更新请求体中包含的字段,未提供的字段保持不变
- **成功响应** - **成功响应**
```json ```json
{ {
"code": 10000, "code": 10000,
"message": "成功", "message": "成功",
"data": { "data": null
"id": 10,
"courseName": "测试课程",
"microLessonName": "测试微课",
"userId": 1,
"progressStatus": 2,
"scriptUploadTime": null,
"scriptConfirmTime": 1734663755,
"videoCaptureTime": null,
"videoConfirmTime": null,
"finishTime": null,
"advise": "{\"method\":\"wechat\",\"uploaded\":true}",
"createdAt": 1734602440,
"updatedAt": 1734663755
}
} }
``` ```
## 注意事项 ## 注意事项
1. 所有需要认证的接口必须在请求头中携带有效的 JWT 令牌 1. 所有时间戳字段均使用秒级时间戳10位
2. 所有时间戳字段均为秒级时间戳 2. 课程任务状态变更时会自动记录相应的时间戳
3. 分页接口的页码从 1 开始 3. 部门课程任务列表会额外返回用户名信息
4. 用户密码在传输和存储时都会进行加密处理 4. 分页参数中的页码从1开始
5. 课程任务的 progressStatus 字段状态码说明:
- 0: 脚本上传
- 1: 脚本确认
- 2: 视频拍摄
- 3: 后期制作
- 4: 任务完成
6. 用户状态说明:
- 1: 正常
- 0: 禁用

View File

@ -11,9 +11,10 @@ public class LessonTaskDTO {
private Long userId; private Long userId;
private String username; // 添加用户名字段 private String username; // 添加用户名字段
private Integer progressStatus; private Integer progressStatus;
private Long scriptUploadTime; private Long scriptCreateTime;
private Long scriptReviewTime;
private Long scriptConfirmTime; private Long scriptConfirmTime;
private Long videoCaptureTime; private Long videoCreateTime;
private Long videoConfirmTime; private Long videoConfirmTime;
private Long finishTime; private Long finishTime;
private String advise; private String advise;
@ -29,9 +30,10 @@ public class LessonTaskDTO {
dto.setUserId(lessonTask.getUserId()); dto.setUserId(lessonTask.getUserId());
dto.setUsername(username); dto.setUsername(username);
dto.setProgressStatus(lessonTask.getProgressStatus()); dto.setProgressStatus(lessonTask.getProgressStatus());
dto.setScriptUploadTime(lessonTask.getScriptUploadTime()); dto.setScriptCreateTime(lessonTask.getScriptCreateTime());
dto.setScriptReviewTime(lessonTask.getScriptReviewTime());
dto.setScriptConfirmTime(lessonTask.getScriptConfirmTime()); dto.setScriptConfirmTime(lessonTask.getScriptConfirmTime());
dto.setVideoCaptureTime(lessonTask.getVideoCaptureTime()); dto.setVideoCreateTime(lessonTask.getVideoCreateTime());
dto.setVideoConfirmTime(lessonTask.getVideoConfirmTime()); dto.setVideoConfirmTime(lessonTask.getVideoConfirmTime());
dto.setFinishTime(lessonTask.getFinishTime()); dto.setFinishTime(lessonTask.getFinishTime());
dto.setAdvise(lessonTask.getAdvise()); dto.setAdvise(lessonTask.getAdvise());
@ -88,12 +90,20 @@ public class LessonTaskDTO {
this.progressStatus = progressStatus; this.progressStatus = progressStatus;
} }
public Long getScriptUploadTime() { public Long getScriptCreateTime() {
return scriptUploadTime; return scriptCreateTime;
} }
public void setScriptUploadTime(Long scriptUploadTime) { public void setScriptCreateTime(Long scriptCreateTime) {
this.scriptUploadTime = scriptUploadTime; this.scriptCreateTime = scriptCreateTime;
}
public Long getScriptReviewTime() {
return scriptReviewTime;
}
public void setScriptReviewTime(Long scriptReviewTime) {
this.scriptReviewTime = scriptReviewTime;
} }
public Long getScriptConfirmTime() { public Long getScriptConfirmTime() {
@ -104,12 +114,12 @@ public class LessonTaskDTO {
this.scriptConfirmTime = scriptConfirmTime; this.scriptConfirmTime = scriptConfirmTime;
} }
public Long getVideoCaptureTime() { public Long getVideoCreateTime() {
return videoCaptureTime; return videoCreateTime;
} }
public void setVideoCaptureTime(Long videoCaptureTime) { public void setVideoCreateTime(Long videoCreateTime) {
this.videoCaptureTime = videoCaptureTime; this.videoCreateTime = videoCreateTime;
} }
public Long getVideoConfirmTime() { public Long getVideoConfirmTime() {

View File

@ -10,9 +10,10 @@ public class LessonTaskRequest {
private String microLessonName; private String microLessonName;
private Long userId; private Long userId;
private Integer progressStatus; private Integer progressStatus;
private Long scriptUploadTime; private Long scriptCreateTime;
private Long scriptReviewTime;
private Long scriptConfirmTime; private Long scriptConfirmTime;
private Long videoCaptureTime; private Long videoCreateTime;
private Long videoConfirmTime; private Long videoConfirmTime;
private Long finishTime; private Long finishTime;
private String advise; private String advise;
@ -49,12 +50,20 @@ public class LessonTaskRequest {
this.progressStatus = progressStatus; this.progressStatus = progressStatus;
} }
public Long getScriptUploadTime() { public Long getScriptCreateTime() {
return scriptUploadTime; return scriptCreateTime;
} }
public void setScriptUploadTime(Long scriptUploadTime) { public void setScriptCreateTime(Long scriptCreateTime) {
this.scriptUploadTime = scriptUploadTime; this.scriptCreateTime = scriptCreateTime;
}
public Long getScriptReviewTime() {
return scriptReviewTime;
}
public void setScriptReviewTime(Long scriptReviewTime) {
this.scriptReviewTime = scriptReviewTime;
} }
public Long getScriptConfirmTime() { public Long getScriptConfirmTime() {
@ -65,12 +74,12 @@ public class LessonTaskRequest {
this.scriptConfirmTime = scriptConfirmTime; this.scriptConfirmTime = scriptConfirmTime;
} }
public Long getVideoCaptureTime() { public Long getVideoCreateTime() {
return videoCaptureTime; return videoCreateTime;
} }
public void setVideoCaptureTime(Long videoCaptureTime) { public void setVideoCreateTime(Long videoCreateTime) {
this.videoCaptureTime = videoCaptureTime; this.videoCreateTime = videoCreateTime;
} }
public Long getVideoConfirmTime() { public Long getVideoConfirmTime() {

View File

@ -32,9 +32,10 @@ public class LessonTask implements Serializable {
@Column(nullable = false) @Column(nullable = false)
private Integer progressStatus; private Integer progressStatus;
private Long scriptUploadTime; private Long scriptCreateTime;
private Long scriptReviewTime;
private Long scriptConfirmTime; private Long scriptConfirmTime;
private Long videoCaptureTime; private Long videoCreateTime;
private Long videoConfirmTime; private Long videoConfirmTime;
private Long finishTime; private Long finishTime;
@ -48,9 +49,9 @@ public class LessonTask implements Serializable {
@PrePersist @PrePersist
protected void onCreate() { protected void onCreate() {
logger.info("创建新课程任务 - 课程名称: {}, 课名称: {}, 用户ID: {}", logger.info("创建新课程任务 - 课程名称: {}, 课名称: {}, 用户ID: {}",
this.courseName, this.microLessonName, this.userId); this.courseName, this.microLessonName, this.userId);
progressStatus = 1; progressStatus = 0;
long now = System.currentTimeMillis() / 1000; long now = System.currentTimeMillis() / 1000;
createdAt = now; createdAt = now;
updatedAt = now; updatedAt = now;
@ -60,7 +61,7 @@ public class LessonTask implements Serializable {
@PreUpdate @PreUpdate
protected void onUpdate() { protected void onUpdate() {
logger.info("更新课程任务 - ID: {}, 课程名称: {}, 课名称: {}", logger.info("更新课程任务 - ID: {}, 课程名称: {}, 课名称: {}",
this.id, this.courseName, this.microLessonName); this.id, this.courseName, this.microLessonName);
updatedAt = System.currentTimeMillis() / 1000; updatedAt = System.currentTimeMillis() / 1000;
logger.info("更新课程任务成功 - ID: {}, 更新时间: {}", id, updatedAt); logger.info("更新课程任务成功 - ID: {}, 更新时间: {}", id, updatedAt);

View File

@ -47,6 +47,18 @@ public class User implements UserDetails {
@Column(name = "updated_at", nullable = false) @Column(name = "updated_at", nullable = false)
private Long updatedAt; private Long updatedAt;
@PrePersist
protected void onCreate() {
long now = System.currentTimeMillis() / 1000;
createdAt = now;
updatedAt = now;
}
@PreUpdate
protected void onUpdate() {
updatedAt = System.currentTimeMillis() / 1000;
}
@Override @Override
public Collection<? extends GrantedAuthority> getAuthorities() { public Collection<? extends GrantedAuthority> getAuthorities() {
return Collections.singletonList(new SimpleGrantedAuthority("ROLE_USER")); return Collections.singletonList(new SimpleGrantedAuthority("ROLE_USER"));

View File

@ -53,12 +53,12 @@ public class LessonTaskService {
@Transactional @Transactional
@CacheEvict(value = { "lessonTasks", "lessonTask" }, allEntries = true) @CacheEvict(value = { "lessonTasks", "lessonTask" }, allEntries = true)
public LessonTask create(LessonTaskRequest request) { public LessonTask create(LessonTaskRequest request) {
logger.info("开始创建课程任务 - 课程名称: {}, 课名称: {}, 用户ID: {}", logger.info("开始创建课程任务 - 课程名称: {}, 课名称: {}, 用户ID: {}",
request.getCourseName(), request.getMicroLessonName(), request.getUserId()); request.getCourseName(), request.getMicroLessonName(), request.getUserId());
validateRequest(request); validateRequest(request);
LessonTask task = new LessonTask(); LessonTask task = new LessonTask();
BeanUtils.copyProperties(request, task); BeanUtils.copyProperties(request, task);
task.setProgressStatus(0); // 初始状态 task.setProgressStatus(0); // 初始状态:未开始
LessonTask savedTask = lessonTaskRepository.save(task); LessonTask savedTask = lessonTaskRepository.save(task);
logger.info("创建课程任务成功 - 任务ID: {}", savedTask.getId()); logger.info("创建课程任务成功 - 任务ID: {}", savedTask.getId());
return savedTask; return savedTask;
@ -76,36 +76,42 @@ public class LessonTaskService {
// 根据进度状态更新时间戳 // 根据进度状态更新时间戳
long currentTime = System.currentTimeMillis() / 1000; long currentTime = System.currentTimeMillis() / 1000;
switch (request.getProgressStatus()) { switch (request.getProgressStatus()) {
case 0: // 初始状态 case 0: // 未开始
task.setScriptUploadTime(null); task.setScriptCreateTime(null);
task.setScriptReviewTime(null);
task.setScriptConfirmTime(null); task.setScriptConfirmTime(null);
task.setVideoCaptureTime(null); task.setVideoCreateTime(null);
task.setVideoConfirmTime(null); task.setVideoConfirmTime(null);
task.setFinishTime(null); task.setFinishTime(null);
break; break;
case 1: // 脚本上传 case 1: // 脚本制作
task.setScriptUploadTime(currentTime); task.setScriptCreateTime(currentTime);
task.setScriptReviewTime(null);
task.setScriptConfirmTime(null); task.setScriptConfirmTime(null);
task.setVideoCaptureTime(null); task.setVideoCreateTime(null);
task.setVideoConfirmTime(null); task.setVideoConfirmTime(null);
task.setFinishTime(null); task.setFinishTime(null);
break; break;
case 2: // 脚本确认 case 2: // 脚本审核
task.setScriptReviewTime(currentTime);
task.setScriptConfirmTime(null);
task.setVideoCreateTime(null);
task.setVideoConfirmTime(null);
task.setFinishTime(null);
break;
case 3: // 脚本确认
task.setScriptConfirmTime(currentTime); task.setScriptConfirmTime(currentTime);
task.setVideoCaptureTime(null); task.setVideoCreateTime(null);
task.setVideoConfirmTime(null); task.setVideoConfirmTime(null);
task.setFinishTime(null); task.setFinishTime(null);
break; break;
case 3: // 视频拍摄 case 4: // 视频拍摄与制作
task.setVideoCaptureTime(currentTime); task.setVideoCreateTime(currentTime);
task.setVideoConfirmTime(null); task.setVideoConfirmTime(null);
task.setFinishTime(null); task.setFinishTime(null);
break; break;
case 4: // 视频确认 case 5: // 视频确认
task.setVideoConfirmTime(currentTime); task.setVideoConfirmTime(currentTime);
task.setFinishTime(null);
break;
case 5: // 任务完成
task.setFinishTime(currentTime); task.setFinishTime(currentTime);
break; break;
} }
@ -164,7 +170,7 @@ public class LessonTaskService {
* 根据部门ID和状态查询课程任务列表分页 * 根据部门ID和状态查询课程任务列表分页
* *
* @param departmentId 部门ID * @param departmentId 部门ID
* @param status 任务状态可选0-脚本上传, 1-脚本确认, 2-视频拍摄, 3-后期制作, 4-任务完成 * @param status 任务状态可选0-未开始, 1-脚本制作, 2-脚本审核, 3-脚本确认, 4-视频拍摄与制作, 5-视频确认
* @param pageable 分页参数 * @param pageable 分页参数
* @return 课程任务分页数据 * @return 课程任务分页数据
*/ */
@ -191,7 +197,7 @@ public class LessonTaskService {
throw new IllegalArgumentException("课程名称不能为空"); throw new IllegalArgumentException("课程名称不能为空");
} }
if (request.getMicroLessonName() == null || request.getMicroLessonName().trim().isEmpty()) { if (request.getMicroLessonName() == null || request.getMicroLessonName().trim().isEmpty()) {
throw new IllegalArgumentException("课名称不能为空"); throw new IllegalArgumentException("课名称不能为空");
} }
if (request.getUserId() == null) { if (request.getUserId() == null) {
throw new IllegalArgumentException("用户ID不能为空"); throw new IllegalArgumentException("用户ID不能为空");

View File

@ -76,8 +76,7 @@ public class UserService implements UserDetailsService {
user.setJobs(request.getJobs()); user.setJobs(request.getJobs());
user.setCreatorId(request.getCreatorId()); user.setCreatorId(request.getCreatorId());
user.setStatus(1); user.setStatus(1);
user.setCreatedAt(System.currentTimeMillis() / 1000); // 时间戳由 @PrePersist 处理,这里不需要手动设置
user.setUpdatedAt(System.currentTimeMillis() / 1000);
userRepository.save(user); userRepository.save(user);

View File

@ -15,7 +15,8 @@ CREATE TABLE departments (
``` ```
### 字段说明 ### 字段说明
- `id`: 部门ID自增主键
- `id`: 部门 ID自增主键
- `name`: 部门名称,不可为空 - `name`: 部门名称,不可为空
- `description`: 部门描述,可为空 - `description`: 部门描述,可为空
- `created_at`: 创建时间,毫秒级时间戳 - `created_at`: 创建时间,毫秒级时间戳
@ -45,11 +46,12 @@ CREATE TABLE users (
``` ```
### 字段说明 ### 字段说明
- `id`: 用户ID自增主键
- `id`: 用户 ID自增主键
- `username`: 用户名,不可为空 - `username`: 用户名,不可为空
- `email`: 邮箱地址,不可为空,唯一索引 - `email`: 邮箱地址,不可为空,唯一索引
- `password`: 密码(加密存储),不可为空 - `password`: 密码(加密存储),不可为空
- `department_id`: 所属部门ID外键关联departments表 - `department_id`: 所属部门 ID外键关联 departments
- `roles`: 用户角色,整数枚举: - `roles`: 用户角色,整数枚举:
- 1: 教师 - 1: 教师
- 2: 普通管理员 - 2: 普通管理员
@ -60,8 +62,8 @@ CREATE TABLE users (
- 2: 课程购买方项目负责人 - 2: 课程购买方项目负责人
- 3: 课程制作方沟通联络人 - 3: 课程制作方沟通联络人
- 4: 系统制作方项目负责人 - 4: 系统制作方项目负责人
- `avatar`: 用户头像URL可为空 - `avatar`: 用户头像 URL可为空
- `creator_id`: 创建该用户的管理员ID - `creator_id`: 创建该用户的管理员 ID
- `status`: 用户状态: - `status`: 用户状态:
- 1: 正常 - 1: 正常
- 0: 禁用 - 0: 禁用
@ -69,6 +71,7 @@ CREATE TABLE users (
- `updated_at`: 更新时间,毫秒级时间戳 - `updated_at`: 更新时间,毫秒级时间戳
### 索引 ### 索引
- 主键索引:`id` - 主键索引:`id`
- 外键索引:`idx_users_department_id (department_id)` - 外键索引:`idx_users_department_id (department_id)`
- 唯一索引:`email` - 唯一索引:`email`
@ -78,68 +81,114 @@ CREATE TABLE users (
存储课程制作任务的信息和进度。 存储课程制作任务的信息和进度。
```sql ```sql
CREATE TABLE lesson_tasks ( CREATE TABLE lesson_tasks
id BIGINT AUTO_INCREMENT PRIMARY KEY, (
course_name VARCHAR(100) NOT NULL COMMENT '课程名称', id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID系统自动生成的唯一标识',
micro_lesson_name VARCHAR(100) NOT NULL COMMENT '微课名称', course_name VARCHAR(100) NOT NULL COMMENT '所属课程名称,标识任务所属的主课程',
user_id BIGINT NOT NULL COMMENT '负责人ID', micro_lesson_name VARCHAR(100) NOT NULL COMMENT '具体微课名称,标识任务所属的具体微课单元',
progress_status INT NOT NULL DEFAULT 0 COMMENT '当前任务进度状态: 0-脚本上传, 1-脚本确认, 2-视频拍摄, 3-后期制作, 4-任务完成', user_id BIGINT NOT NULL COMMENT '任务负责人ID关联users表的主键id',
script_upload_time BIGINT DEFAULT NULL COMMENT '脚本上传时间(时间戳)', progress_status INT NOT NULL DEFAULT 0 COMMENT '任务进度状态:
script_confirm_time BIGINT DEFAULT NULL COMMENT '脚本确认时间(时间戳)', 0-未开始:任务创建后的初始状态
video_capture_time BIGINT DEFAULT NULL COMMENT '视频拍摄时间(时间戳)', 1-脚本制作:正在编写课程脚本
video_confirm_time BIGINT DEFAULT NULL COMMENT '视频确认时间(时间戳)', 2-脚本审核:脚本提交审核阶段
finish_time BIGINT DEFAULT NULL COMMENT '任务完成时间(时间戳)', 3-脚本确认:脚本审核通过确认
advise TEXT DEFAULT NULL COMMENT '任务建议或备注', 4-视频拍摄与制作:进行视频录制和后期制作
created_at BIGINT NOT NULL COMMENT '创建时间(时间戳)', 5-视频确认:最终视频审核确认',
updated_at BIGINT NOT NULL COMMENT '更新时间(时间戳)', script_create_time BIGINT DEFAULT NULL COMMENT '脚本开始制作的时间戳状态1时记录',
FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE, script_review_time BIGINT DEFAULT NULL COMMENT '脚本提交审核的时间戳状态2时记录',
INDEX idx_lesson_tasks_user_id (user_id), script_confirm_time BIGINT DEFAULT NULL COMMENT '脚本审核通过的时间戳状态3时记录',
INDEX idx_lesson_tasks_progress_status (progress_status) video_create_time BIGINT DEFAULT NULL COMMENT '开始视频制作的时间戳状态4时记录',
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT ='课程任务表'; video_confirm_time BIGINT DEFAULT NULL COMMENT '视频审核通过的时间戳状态5时记录',
finish_time BIGINT DEFAULT NULL COMMENT '整个任务完成的时间戳,最终确认后记录',
advise TEXT DEFAULT NULL COMMENT '任务相关的建议、修改意见或其他重要备注信息',
created_at BIGINT NOT NULL COMMENT '记录创建的时间戳,系统自动生成',
updated_at BIGINT NOT NULL COMMENT '记录最后更新的时间戳,系统自动更新',
-- 外键约束确保user_id关联到users表的有效用户
CONSTRAINT fk_lesson_tasks_user FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE ON UPDATE CASCADE,
-- 索引设计:
-- 1. 用户ID索引用于快速查找特定用户的所有任务
INDEX idx_user_id (user_id),
-- 2. 进度状态索引:用于按状态筛选和统计任务
INDEX idx_progress_status (progress_status),
-- 3. 课程名称索引:用于按课程分组和查询
INDEX idx_course_name (course_name),
-- 4. 复合索引:用于同时按用户和状态查询
INDEX idx_user_progress (user_id, progress_status)
) ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4
COMMENT='课程任务管理表:记录微课制作的完整流程,包括脚本编写、审核、视频制作等各个环节的进度和时间节点';
``` ```
### 字段说明 ### 字段说明
- `id`: 任务ID自增主键
- `id`: 任务 ID自增主键
- `course_name`: 课程名称,不可为空 - `course_name`: 课程名称,不可为空
- `micro_lesson_name`: 微课名称,不可为空 - `micro_lesson_name`: 微课名称,不可为空
- `user_id`: 负责人ID外键关联users表 - `user_id`: 负责人 ID外键关联 users
- `progress_status`: 任务进度状态: - `progress_status`: 任务进度状态:
- 0: 脚本上传 - 0: 未开始
- 1: 脚本确认 - 1: 脚本制作
- 2: 视频拍摄 - 2: 脚本审核
- 3: 后期制作 - 3: 脚本确认
- 4: 任务完成 - 4: 视频拍摄与制作
- `script_upload_time`: 脚本上传时间,毫秒级时间戳 - 5: 视频确认
- `script_confirm_time`: 脚本确认时间,毫秒级时间戳 - `script_create_time`: 脚本开始制作的时间戳,状态 1 时记录
- `video_capture_time`: 视频拍摄时间,毫秒级时间戳 - `script_review_time`: 脚本提交审核的时间戳,状态 2 时记录
- `video_confirm_time`: 视频确认时间,毫秒级时间戳 - `script_confirm_time`: 脚本审核通过的时间戳,状态 3 时记录
- `finish_time`: 任务完成时间,毫秒级时间戳 - `video_create_time`: 开始视频制作的时间戳,状态 4 时记录
- `advise`: 任务相关的建议或备注,文本字段 - `video_confirm_time`: 视频审核通过的时间戳,状态 5 时记录
- `created_at`: 创建时间,毫秒级时间戳 - `finish_time`: 整个任务完成的时间戳,最终确认后记录
- `updated_at`: 更新时间,毫秒级时间戳 - `advise`: 任务相关的建议、修改意见或其他重要备注信息
- `created_at`: 记录创建的时间戳,系统自动生成
- `updated_at`: 记录最后更新的时间戳,系统自动更新
### 索引 ### 索引
- 主键索引:`id` - 主键索引:`id`
- 外键索引:`idx_lesson_tasks_user_id (user_id)` - 外键索引:`idx_user_id (user_id)`
- 普通索引:`idx_lesson_tasks_progress_status (progress_status)` - 普通索引:`idx_progress_status (progress_status)`
- 普通索引:`idx_course_name (course_name)`
- 复合索引:`idx_user_progress (user_id, progress_status)`
## 数据库关系 ## 数据库关系
1. `users.department_id` -> `departments.id` 1. `users.department_id` -> `departments.id`
- 一个部门可以有多个用户 - 一个部门可以有多个用户
- 一个用户只能属于一个部门 - 一个用户只能属于一个部门
- 使用RESTRICT约束防止删除仍有用户的部门 - 使用 RESTRICT 约束,防止删除仍有用户的部门
2. `lesson_tasks.user_id` -> `users.id` 2. `lesson_tasks.user_id` -> `users.id`
- 一个用户可以负责多个课程任务 - 一个用户可以负责多个课程任务
- 一个课程任务只能有一个负责人 - 一个课程任务只能有一个负责人
- 使用CASCADE约束删除用户时自动删除其负责的课程任务 - 使用 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类型存储毫秒级时间戳 1. 所有时间戳字段使用 BIGINT 类型,存储毫秒级时间戳
2. 字符编码统一使用utf8mb4支持完整的Unicode字符集 2. 字符编码统一使用 utf8mb4支持完整的 Unicode 字符集
3. 所有表都使用InnoDB引擎支持事务和外键 3. 所有表都使用 InnoDB 引擎,支持事务和外键
4. 关键字段都建立了适当的索引以提高查询性能 4. 关键字段都建立了适当的索引以提高查询性能
5. 用户密码在存储前需要进行加密处理 5. 用户密码在存储前需要进行加密处理
6. 删除用户时会自动删除其关联的课程任务,但不会影响部门数据 6. 删除用户时会自动删除其关联的课程任务,但不会影响部门数据