主要更新: - 修复了所有主要的代码逻辑错误 - 实现了完整的任务清理系统 - 添加了系统设置页面的任务清理管理功能 - 修复了API调用认证问题 - 优化了密码加密和验证机制 - 统一了错误处理模式 - 添加了详细的文档和测试工具 新增功能: - 任务清理管理界面 - 任务归档和清理日志 - API监控和诊断工具 - 完整的测试套件 技术改进: - 修复了Repository方法调用错误 - 统一了模型方法调用 - 改进了类型安全性 - 优化了代码结构和可维护性
8.5 KiB
8.5 KiB
任务完成后作品保存流程说明
🎯 功能概述
当任务执行成功后,系统会自动将结果保存到用户的"我的作品"中,并将相关信息添加到数据库中。用户可以通过API接口查看、管理自己的作品。
📋 完整流程
1. 任务执行成功触发
外部API返回结果 → TaskQueueService.updateTaskAsCompleted()
2. 任务队列状态更新
// TaskQueueService.updateTaskAsCompleted()
taskQueue.updateStatus(TaskQueue.QueueStatus.COMPLETED);
taskQueueRepository.save(taskQueue);
3. 积分处理
// 扣除冻结的积分
userService.deductFrozenPoints(taskQueue.getTaskId());
4. 作品创建
// 创建用户作品
UserWork work = userWorkService.createWorkFromTask(taskQueue.getTaskId(), resultUrl);
5. 作品数据提取
// 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. 作品信息设置
// 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. 数据库保存
// 保存到数据库
work = userWorkRepository.save(work);
8. 原始任务状态更新
// 更新原始任务状态
updateOriginalTaskStatus(taskQueue, "COMPLETED", resultUrl, null);
🗄️ 数据库表结构
user_works 表
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. 作品删除
- 软删除作品
- 保留数据完整性
🔄 定时任务
清理过期失败作品
@Scheduled(cron = "0 0 3 * * ?") // 每天凌晨3点执行
public void cleanupExpiredFailedWorks() {
// 清理超过30天的失败作品
int cleanedCount = userWorkService.cleanupExpiredFailedWorks();
}
🧪 测试验证
系统包含完整的集成测试,验证:
- 文生视频任务完成后作品创建
- 图生视频任务完成后作品创建
- 重复作品创建处理
- 作品标题生成
- 用户作品列表获取
- 作品统计信息
📝 使用示例
前端调用示例
// 获取我的作品列表
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;
};
✅ 系统状态
当前系统已经完全实现了任务完成后作品保存功能:
- ✅ 任务完成触发作品创建
- ✅ 作品信息自动提取和设置
- ✅ 作品数据保存到数据库
- ✅ 我的作品API接口完整
- ✅ 权限控制和安全验证
- ✅ 防重复创建机制
- ✅ 异常处理和日志记录
- ✅ 完整的测试覆盖
用户现在可以在任务完成后,通过"我的作品"功能查看和管理自己生成的所有视频作品。