# 任务完成后作品保存流程说明 ## 🎯 **功能概述** 当任务执行成功后,系统会自动将结果保存到用户的"我的作品"中,并将相关信息添加到数据库中。用户可以通过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 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 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 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. **✅ 完整的测试覆盖** 用户现在可以在任务完成后,通过"我的作品"功能查看和管理自己生成的所有视频作品。