Files
AIGC/demo/TASK_TO_WORK_FLOW.md
AIGC Developer 8c55f9f376 feat: 完成代码逻辑错误修复和任务清理系统实现
主要更新:
- 修复了所有主要的代码逻辑错误
- 实现了完整的任务清理系统
- 添加了系统设置页面的任务清理管理功能
- 修复了API调用认证问题
- 优化了密码加密和验证机制
- 统一了错误处理模式
- 添加了详细的文档和测试工具

新增功能:
- 任务清理管理界面
- 任务归档和清理日志
- API监控和诊断工具
- 完整的测试套件

技术改进:
- 修复了Repository方法调用错误
- 统一了模型方法调用
- 改进了类型安全性
- 优化了代码结构和可维护性
2025-10-27 10:46:49 +08:00

308 lines
8.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 任务完成后作品保存流程说明
## 🎯 **功能概述**
当任务执行成功后,系统会自动将结果保存到用户的"我的作品"中并将相关信息添加到数据库中。用户可以通过API接口查看、管理自己的作品。
## 📋 **完整流程**
### 1. **任务执行成功触发**
```
外部API返回结果 → TaskQueueService.updateTaskAsCompleted()
```
### 2. **任务队列状态更新**
```java
// TaskQueueService.updateTaskAsCompleted()
taskQueue.updateStatus(TaskQueue.QueueStatus.COMPLETED);
taskQueueRepository.save(taskQueue);
```
### 3. **积分处理**
```java
// 扣除冻结的积分
userService.deductFrozenPoints(taskQueue.getTaskId());
```
### 4. **作品创建**
```java
// 创建用户作品
UserWork work = userWorkService.createWorkFromTask(taskQueue.getTaskId(), resultUrl);
```
### 5. **作品数据提取**
```java
// UserWorkService.createWorkFromTask()
// 检查是否已存在作品(防重复)
Optional<UserWork> existingWork = userWorkRepository.findByTaskId(taskId);
if (existingWork.isPresent()) {
return existingWork.get(); // 返回已存在的作品
}
// 从原始任务中提取数据
TextToVideoTask task = textToVideoTaskRepository.findByTaskId(taskId);
// 或
ImageToVideoTask task = imageToVideoTaskRepository.findByTaskId(taskId);
```
### 6. **作品信息设置**
```java
// UserWorkService.createTextToVideoWork() 或 createImageToVideoWork()
UserWork work = new UserWork();
work.setUsername(task.getUsername()); // 用户名
work.setTaskId(task.getTaskId()); // 任务ID
work.setWorkType(UserWork.WorkType.TEXT_TO_VIDEO); // 作品类型
work.setTitle(generateTitle(task.getPrompt())); // 自动生成标题
work.setDescription("文生视频作品"); // 作品描述
work.setPrompt(task.getPrompt()); // 原始提示词
work.setResultUrl(resultUrl); // 结果视频URL
work.setDuration(String.valueOf(task.getDuration()) + "s"); // 视频时长
work.setAspectRatio(task.getAspectRatio()); // 宽高比
work.setQuality(task.isHdMode() ? "HD" : "SD"); // 画质
work.setPointsCost(task.getCostPoints()); // 消耗积分
work.setStatus(UserWork.WorkStatus.COMPLETED); // 作品状态
work.setCompletedAt(LocalDateTime.now()); // 完成时间
```
### 7. **数据库保存**
```java
// 保存到数据库
work = userWorkRepository.save(work);
```
### 8. **原始任务状态更新**
```java
// 更新原始任务状态
updateOriginalTaskStatus(taskQueue, "COMPLETED", resultUrl, null);
```
## 🗄️ **数据库表结构**
### user_works 表
```sql
CREATE TABLE user_works (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(100) NOT NULL COMMENT '用户名',
task_id VARCHAR(50) NOT NULL UNIQUE COMMENT '任务ID',
work_type ENUM('TEXT_TO_VIDEO', 'IMAGE_TO_VIDEO') NOT NULL COMMENT '作品类型',
title VARCHAR(200) COMMENT '作品标题',
description TEXT COMMENT '作品描述',
prompt TEXT COMMENT '生成提示词',
result_url VARCHAR(500) COMMENT '结果视频URL',
thumbnail_url VARCHAR(500) COMMENT '缩略图URL',
duration VARCHAR(10) COMMENT '视频时长',
aspect_ratio VARCHAR(10) COMMENT '宽高比',
quality VARCHAR(20) COMMENT '画质',
file_size VARCHAR(20) COMMENT '文件大小',
points_cost INT NOT NULL DEFAULT 0 COMMENT '消耗积分',
status ENUM('PROCESSING', 'COMPLETED', 'FAILED', 'DELETED') NOT NULL DEFAULT 'PROCESSING' COMMENT '作品状态',
is_public BOOLEAN NOT NULL DEFAULT FALSE COMMENT '是否公开',
view_count INT NOT NULL DEFAULT 0 COMMENT '浏览次数',
like_count INT NOT NULL DEFAULT 0 COMMENT '点赞次数',
download_count INT NOT NULL DEFAULT 0 COMMENT '下载次数',
tags VARCHAR(500) COMMENT '标签',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
completed_at DATETIME COMMENT '完成时间'
);
```
## 🔌 **API接口**
### 获取我的作品列表
```
GET /api/works/my-works?page=0&size=10
Authorization: Bearer <token>
Response:
{
"success": true,
"data": [
{
"id": 1,
"username": "user1",
"taskId": "txt2vid_123",
"workType": "TEXT_TO_VIDEO",
"title": "一只可爱的小猫...",
"description": "文生视频作品",
"prompt": "一只可爱的小猫在花园里玩耍",
"resultUrl": "https://example.com/video.mp4",
"duration": "10s",
"aspectRatio": "16:9",
"quality": "HD",
"pointsCost": 80,
"status": "COMPLETED",
"isPublic": false,
"viewCount": 0,
"likeCount": 0,
"downloadCount": 0,
"createdAt": "2024-01-01T10:00:00",
"completedAt": "2024-01-01T10:05:00"
}
],
"totalElements": 1,
"totalPages": 1,
"currentPage": 0,
"size": 10,
"stats": {
"completedCount": 1,
"processingCount": 0,
"failedCount": 0,
"totalPointsCost": 80,
"totalCount": 1,
"publicCount": 0
}
}
```
### 获取作品详情
```
GET /api/works/{workId}
Authorization: Bearer <token>
Response:
{
"success": true,
"data": {
"id": 1,
"username": "user1",
"taskId": "txt2vid_123",
"workType": "TEXT_TO_VIDEO",
"title": "一只可爱的小猫...",
"description": "文生视频作品",
"prompt": "一只可爱的小猫在花园里玩耍",
"resultUrl": "https://example.com/video.mp4",
"duration": "10s",
"aspectRatio": "16:9",
"quality": "HD",
"pointsCost": 80,
"status": "COMPLETED",
"isPublic": false,
"viewCount": 1,
"likeCount": 0,
"downloadCount": 0,
"createdAt": "2024-01-01T10:00:00",
"completedAt": "2024-01-01T10:05:00"
}
}
```
## 🛡️ **安全特性**
### 1. **防重复创建**
- 检查是否已存在相同任务ID的作品
- 如果存在则返回已存在的作品,不创建新作品
### 2. **权限控制**
- 只有作品所有者可以查看、编辑、删除作品
- 通过JWT Token验证用户身份
### 3. **数据完整性**
- 事务保证数据一致性
- 作品创建失败不影响任务完成状态
### 4. **异常处理**
- 完善的错误处理机制
- 详细的日志记录
## 📊 **作品管理功能**
### 1. **作品查看**
- 分页获取用户作品列表
- 获取作品详细信息
- 作品统计信息
### 2. **作品编辑**
- 修改作品标题
- 修改作品描述
- 设置作品标签
- 设置作品公开状态
### 3. **作品互动**
- 作品点赞
- 作品下载记录
- 浏览次数统计
### 4. **作品删除**
- 软删除作品
- 保留数据完整性
## 🔄 **定时任务**
### 清理过期失败作品
```java
@Scheduled(cron = "0 0 3 * * ?") // 每天凌晨3点执行
public void cleanupExpiredFailedWorks() {
// 清理超过30天的失败作品
int cleanedCount = userWorkService.cleanupExpiredFailedWorks();
}
```
## 🧪 **测试验证**
系统包含完整的集成测试,验证:
- 文生视频任务完成后作品创建
- 图生视频任务完成后作品创建
- 重复作品创建处理
- 作品标题生成
- 用户作品列表获取
- 作品统计信息
## 📝 **使用示例**
### 前端调用示例
```javascript
// 获取我的作品列表
const getMyWorks = async (page = 0, size = 10) => {
const response = await fetch(`/api/works/my-works?page=${page}&size=${size}`, {
headers: {
'Authorization': `Bearer ${token}`
}
});
const data = await response.json();
return data;
};
// 获取作品详情
const getWorkDetail = async (workId) => {
const response = await fetch(`/api/works/${workId}`, {
headers: {
'Authorization': `Bearer ${token}`
}
});
const data = await response.json();
return data;
};
// 更新作品信息
const updateWork = async (workId, updateData) => {
const response = await fetch(`/api/works/${workId}`, {
method: 'PUT',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(updateData)
});
const data = await response.json();
return data;
};
```
## ✅ **系统状态**
当前系统已经完全实现了任务完成后作品保存功能:
1. **✅ 任务完成触发作品创建**
2. **✅ 作品信息自动提取和设置**
3. **✅ 作品数据保存到数据库**
4. **✅ 我的作品API接口完整**
5. **✅ 权限控制和安全验证**
6. **✅ 防重复创建机制**
7. **✅ 异常处理和日志记录**
8. **✅ 完整的测试覆盖**
用户现在可以在任务完成后,通过"我的作品"功能查看和管理自己生成的所有视频作品。