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

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

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

8.5 KiB
Raw Blame History

任务完成后作品保存流程说明

🎯 功能概述

当任务执行成功后,系统会自动将结果保存到用户的"我的作品"中并将相关信息添加到数据库中。用户可以通过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;
};

系统状态

当前系统已经完全实现了任务完成后作品保存功能:

  1. 任务完成触发作品创建
  2. 作品信息自动提取和设置
  3. 作品数据保存到数据库
  4. 我的作品API接口完整
  5. 权限控制和安全验证
  6. 防重复创建机制
  7. 异常处理和日志记录
  8. 完整的测试覆盖

用户现在可以在任务完成后,通过"我的作品"功能查看和管理自己生成的所有视频作品。