Browse Source

解耦生图任务与执行(任务初始化)

tsurumure 1 tháng trước cách đây
mục cha
commit
a72395da00

+ 4 - 20
db/comfyui_task.sql

@@ -9,27 +9,11 @@ CREATE TABLE `comfyui_task` (
     PRIMARY KEY (`id`),
     `id` BIGINT AUTO_INCREMENT COMMENT 'ID',
     `user_id` BIGINT NOT NULL COMMENT '用户ID',
-    `prompt_id` VARCHAR(255) NOT NULL COMMENT '任务ID',
-    `type` VARCHAR(255) NOT NULL COMMENT '任务类型 (Text2Image, ..)',
-    `status` TINYINT DEFAULT '-1' COMMENT '任务状态 (-1:未开始, 1:进行中, 2:成功, 3:失败)',
-    `msg` VARCHAR(2000) COMMENT '任务状态信息,当任务失败时展示失败原因(如触发平台的内容风控等)',
+    `client_id` VARCHAR(255) COMMENT 'Client ID',
+    `task_type` VARCHAR(255) NOT NULL COMMENT '任务类型 (Text2Image, ..)',
+    `task_status` TINYINT DEFAULT '-1' COMMENT '任务状态 (-1:未提交, 1:已提交)',
     `generate_request` TEXT COMMENT '任务请求原始参数 (JSONString)',
-    `generate_response` TEXT COMMENT '任务生成原始结果 (JSONString)',
     `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
     `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
-    INDEX `idx_user_id` (`user_id`),
-    INDEX `idx_tprompt_id` (`prompt_id`)
+    INDEX `idx_user_id` (`user_id`)
 ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='任务表';
-
-/*
-    [可灵] 生视频结果
-    task_result:{
-        "videos":[
-            {
-                "id": "string", //生成的视频ID;全局唯一
-                "url": "string", //生成视频的URL,例如https://p1.a.kwimgs.com/bs2/upload-ylab-stunt/special-effect/output/HB1_PROD_ai_web_46554461/-2878350957757294165/output.mp4(请注意,为保障信息安全,生成的图片/视频会在30天后被清理,请及时转存)
-                "duration": "string" //视频总时长,单位s
-            }
-          ]
-    }
- */

+ 26 - 0
db/comfyui_task_execute.sql

@@ -0,0 +1,26 @@
+/**
+Source Server Version: 8.0.31
+Source Database: backendsys
+Date: 2025/06/03 10:09:22
+*/
+
+DROP TABLE IF EXISTS `comfyui_task_execute`;
+CREATE TABLE `comfyui_task_execute` (
+    PRIMARY KEY (`id`),
+    `id` BIGINT AUTO_INCREMENT COMMENT 'ID',
+    `task_id` BIGINT NOT NULL COMMENT '任务ID',
+    `user_id` BIGINT NOT NULL COMMENT '用户ID',
+    `client_id` VARCHAR(255) COMMENT 'Client ID',
+    `task_type` VARCHAR(255) NOT NULL COMMENT '任务类型 (Text2Image, ..)',
+    `execute_prompt_id` VARCHAR(255) NOT NULL COMMENT '任务提交ID',
+    `execute_status` TINYINT DEFAULT '-1' COMMENT '任务执行状态 (-1:未开始, 1:进行中, 2:成功, 3:失败)',
+    `execute_url` VARCHAR(2000) COMMENT '任务执行URL',
+    `execute_url_port` INT COMMENT '任务执行URL端口',
+    `generate_request` TEXT COMMENT '任务请求原始参数 (JSONString)',
+    `generate_response` TEXT COMMENT '任务生成原始结果 (JSONString)',
+    `reason` TEXT COMMENT '当任务失败时展示失败原因(如触发平台的内容风控等)',
+    `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+    `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+    INDEX `idx_execute_prompt_id` (`execute_prompt_id`),
+    INDEX `idx_user_id` (`user_id`)
+) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='任务执行表';

+ 43 - 46
src/main/java/com/backendsys/modules/crt/service/impl/CrtGenerateServiceImpl.java

@@ -86,27 +86,20 @@ public class CrtGenerateServiceImpl implements CrtGenerateService {
 
         CrtDramaProjectStoryboard storyboardDetail = crtDramaProjectStoryboardDao.selectById(drama_project_storyboard_id);
         if (storyboardDetail == null) throw new CustException("分镜不存在");
-        // System.out.println("- 分镜详情: " + JSONUtil.toJsonStr(storyboardDetail));
 
         Long drama_project_id = storyboardDetail.getDrama_project_id();
         LambdaQueryWrapper<CrtDramaProjectSettings> wrapperSettings = new LambdaQueryWrapper<>();
         wrapperSettings.eq(CrtDramaProjectSettings::getDrama_project_id, drama_project_id);
         List<CrtDramaProjectSettings> settingsDetail = crtDramaProjectSettingsDao.selectList(wrapperSettings);
         if (settingsDetail == null) throw new CustException("项目配置不存在");
-        // System.out.println("- 项目配置: " + JSONUtil.toJsonStr(settingsDetail));
 
         // 项目配置类型 (1:生图配置, 2:生视频配置)
         CrtDramaProjectSettings settings_image = settingsDetail.stream().filter(item -> item.getDrama_project_setting_type() == 1).findFirst().orElse(null);
-        // System.out.println("- 生图配置: " + JSONUtil.toJsonStr(settings_image));
-
         // CrtDramaProjectSettings settings_video = settingsDetail.stream().filter(item -> item.getDrama_project_setting_type() == 2).findFirst().orElse(null);
-        // System.out.println("- 生视频配置: " + JSONUtil.toJsonStr(settings_video));
-
 
-        // 文生图提示词
-        String prompt_text = crtDramaProjectStoryboard.getText_to_image_prompt();
 
-        // == 从 storboard detail 获取参数 =============================================================================
+        // == 从生图参数初始化 ===========================================================================================
+        String prompt_text = crtDramaProjectStoryboard.getText_to_image_prompt();                 // 文生图提示词
         Integer param_batch_size = storyboardDetail.getParam_batch_size();                        // 生成图片数量
         Float param_prompt_flux_guidance = storyboardDetail.getParam_prompt_flux_guidance();      // 提示词引导系数
         String param_sampler = SamplerEnums.getValueByKey(storyboardDetail.getParam_sampler());   // 采样器
@@ -118,69 +111,73 @@ public class CrtGenerateServiceImpl implements CrtGenerateService {
                 Convert.toStr(DateUtil.current()) :
                 storyboardDetail.getParam_seed();
 
-        // [分集详情] 实体类
+        // 画面比例 (从项目配置)(16:9 - 1280*720, 9:16 - 720*1280, 1:1 - 1024*1024)
+        AspectRatioEnums aspect_ratio_option = AspectRatioEnums.of(settings_image.getAspect_ratio());
+        Integer width = aspect_ratio_option.getWidth();     // 1280
+        Integer height = aspect_ratio_option.getHeight();   // 720
+
+        // 获取基础模型 (从项目配置)
+        Long model_id = settings_image.getModel_id();
+        CrtModel modelDetail = crtModelDao.selectById(model_id);
+        String model_name = modelDetail.getModel_name();
+        // =========================================================================================================
+
+
+        // [DB] 更新分集详情记录 (更新种子值、提示词)
         CrtDramaProjectStoryboard entity = new CrtDramaProjectStoryboard();
         entity.setParam_seed(param_seed);
         entity.setText_to_image_prompt(prompt_text);
-
-        // [DB] 更新分集详情记录 (种子值、提示词)
         LambdaQueryWrapper<CrtDramaProjectStoryboard> wrapper = new LambdaQueryWrapper<>();
         wrapper.eq(CrtDramaProjectStoryboard::getId, drama_project_storyboard_id);
         crtDramaProjectStoryboardDao.update(entity, wrapper);
 
-        // [DB] 获取画面比例 (从项目配置)
-        String aspect_ratio = settings_image.getAspect_ratio();
-        AspectRatioEnums aspect_ratio_option = AspectRatioEnums.of(aspect_ratio);
-        Integer width = aspect_ratio_option.getWidth();
-        Integer height = aspect_ratio_option.getHeight();
-//        Integer width = 1280;
-//        Integer height = 720;
-
-        // [DB] 获取基础模型 (从项目配置)
-        Long model_id = settings_image.getModel_id();
-        CrtModel modelDetail = crtModelDao.selectById(model_id);
-        String model_name = modelDetail.getModel_name();
-
         // 风格 Lora 待定
         // 风格 Lora (阙值)待定
 
-        // ===========================================================================================================
-
-        String client_id = Convert.toStr(UUID.randomUUID());
 
-        // -- [ComfyUI] 创建 WebSocket 监听连接 --------------------------
-        Map<String, Object> params = new LinkedHashMap<>();
-        params.put("drama_project_storyboard_id", drama_project_storyboard_id);
-        // - is_save: 是否转存到 cos/tos
-        comfyUISocketService.connectToSse(client_id, 8000, IS_SAVE, params).subscribe();
+        // ===========================================================================================================
 
-        // -- [ComfyUI] 生图参数 ----------------------------------------
+        // -- [ComfyUI] 生图参数 ---------------------------------------------------
         ComfyuiText2Image comfyuiText2Image = new ComfyuiText2Image();
         comfyuiText2Image.setBatch_size(param_batch_size);
         comfyuiText2Image.setPrompt_flux_guidance(param_prompt_flux_guidance);
         comfyuiText2Image.setSampler(param_sampler);
-
         comfyuiText2Image.setStep(param_step);
         comfyuiText2Image.setWidth(width);
         comfyuiText2Image.setHeight(height);
-//        comfyuiText2Image.setStep(5);
-//        comfyuiText2Image.setWidth(400);
-//        comfyuiText2Image.setHeight(200);
-
-        // aspect_ratio 画面比例 (枚举)(16:9 - 1280*720, 9:16 - 720*1280, 1:1 - 1024*1024)
-
         comfyuiText2Image.setModel_name(model_name);
         comfyuiText2Image.setPrompt_text(prompt_text);
         comfyuiText2Image.setSeed(param_seed);
 
-        // -- [ComfyUI] 生图 --------------------------------------------
-        ComfyuiResponse response = comfyuiText2ImageService.generateText2Image(client_id, comfyuiText2Image);
-        System.out.println("结果: " + response);
-        // 结果: ComfyuiResponse(client_id=1a8a2d01-5500-437f-bb11-7a986130da48, prompt_id=c74501ed-6755-48f8-a440-aef3474b523c, number=47, node_errors={}, error=null)
+        String client_id = Convert.toStr(UUID.randomUUID());
+
+        // -- [ComfyUI] 发起生图任务 -----------------------------------------------
+        Long task_id = comfyuiText2ImageService.generateText2Image(client_id, comfyuiText2Image);
+
+
+
+
+//        // -- [ComfyUI] 创建 WebSocket 监听进度 --------------------------
+//        Map<String, Object> params = new LinkedHashMap<>();
+//        params.put("drama_project_storyboard_id", drama_project_storyboard_id);
+//        // - is_save: 是否转存到 cos/tos
+//        comfyUISocketService.connectToSse(client_id, 8000, IS_SAVE, params).subscribe();
+
+        // -- [ComfyUI] 执行/排队生图任务 --------------------------------------------
+
+
+
+
+
+//        ComfyuiResponse response = null; // comfyuiText2ImageService.generateText2Image(client_id, comfyuiText2Image);
+//        System.out.println("结果: " + response);
+//        // 结果: ComfyuiResponse(client_id=1a8a2d01-5500-437f-bb11-7a986130da48, prompt_id=c74501ed-6755-48f8-a440-aef3474b523c, number=47, node_errors={}, error=null)
 
         Map<String, Object> resp = new LinkedHashMap<>();
         resp.put("drama_project_storyboard_id", drama_project_storyboard_id);
-        resp.put("response", response);
+        resp.put("client_id", client_id);
+        resp.put("task_id", task_id);
+//        resp.put("response", response);
         return resp;
     }
 

+ 9 - 0
src/main/java/com/backendsys/modules/sdk/comfyui/dao/ComfyuiTaskExecuteDao.java

@@ -0,0 +1,9 @@
+package com.backendsys.modules.sdk.comfyui.dao;
+
+import com.backendsys.modules.sdk.comfyui.entity.ComfyuiTaskExecute;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface ComfyuiTaskExecuteDao extends BaseMapper<ComfyuiTaskExecute> {
+}

+ 4 - 6
src/main/java/com/backendsys/modules/sdk/comfyui/entity/ComfyuiTask.java

@@ -6,18 +6,16 @@ import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
 
 @Data
-@TableName("crt_task")
+@TableName("comfyui_task")
 public class ComfyuiTask {
 
     @TableId(type = IdType.AUTO)
     private Long id;
     private Long user_id;                 // 用户ID
-    private String prompt_id;             // 任务ID
-    private String type;                  // 任务类型 (Text2Image, ..)
-    private Integer status;               // 任务状态 (-1:未开始, 1:进行中, 2:成功, 3:失败)
-    private String msg;                   // 任务状态信息,当任务失败时展示失败原因(如触发平台的内容风控等)
+    private String client_id;             // Client ID
+    private String task_type;             // 任务类型 (Text2Image, ..)
+    private Integer task_status;          // 任务状态 (-1:未开始, 1:进行中, 2:成功, 3:失败)
     private String generate_request;      // 任务请求原始参数 (JSONString)
-    private String generate_response;     // 任务生成原始结果 (JSONString)
     private String create_time;
     private String update_time;
 

+ 29 - 0
src/main/java/com/backendsys/modules/sdk/comfyui/entity/ComfyuiTaskExecute.java

@@ -0,0 +1,29 @@
+package com.backendsys.modules.sdk.comfyui.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+@Data
+@TableName("comfyui_task_execute")
+public class ComfyuiTaskExecute {
+
+    @TableId(type = IdType.AUTO)
+    private Long id;
+    private Long task_id;
+    private Long user_id;                 // 用户ID
+    private String client_id;             // Client ID
+    private String task_type;             // 任务类型 (Text2Image, ..)
+    private String execute_prompt_id;     // 任务ID
+    private Integer execute_status;       // 任务状态 (-1:未开始, 1:进行中, 2:成功, 3:失败)
+    private String execute_url;           // 任务执行URL
+    private Integer execute_url_port;     // 任务执行URL端口
+
+    private String generate_request;      // 任务请求原始参数 (JSONString)
+    private String generate_response;     // 任务生成原始结果 (JSONString)
+    private String reason;                // 任务状态信息,当任务失败时展示失败原因(如触发平台的内容风控等)
+    private String create_time;
+    private String update_time;
+
+}

+ 2 - 2
src/main/java/com/backendsys/modules/sdk/comfyui/service/ComfyuiText2ImageService.java

@@ -6,9 +6,9 @@ import com.backendsys.modules.sdk.comfyui.entity.ComfyuiText2Image;
 public interface ComfyuiText2ImageService {
 
     // [ComfyUI] 文生图 (7.16生图.json)
-    ComfyuiResponse generateText2Image(String client_id, ComfyuiText2Image comfyuiText2Image);
+    Long generateText2Image(String client_id, ComfyuiText2Image comfyuiText2Image);
 
     // [ComfyUI] 文生图 (基础生图)
-    ComfyuiResponse generateText2ImageSimple(String client_id, ComfyuiText2Image comfyuiText2Image);
+    Long generateText2ImageSimple(String client_id, ComfyuiText2Image comfyuiText2Image);
 
 }

+ 2 - 2
src/main/java/com/backendsys/modules/sdk/comfyui/service/impl/ComfyuiSocketServiceImpl.java

@@ -186,9 +186,9 @@ public class ComfyuiSocketServiceImpl implements ComfyuiSocketService {
                                     dataChildren.put("output", output);
                                     data.put("data", dataChildren);
 
-                                    // [DB] 新增任务记录
+                                    // [DB] 执行任务
                                     CompletableFuture.runAsync(() -> {
-                                        comfyUtil.updateComfyuiTask(prompt_id, JSONUtil.toJsonStr(dataChildren), 2);
+                                        comfyUtil.executeComfyuiTask(prompt_id, JSONUtil.toJsonStr(dataChildren), 2);
                                     });
 
                                 }

+ 24 - 18
src/main/java/com/backendsys/modules/sdk/comfyui/service/impl/ComfyuiText2ImageServiceImpl.java

@@ -26,9 +26,10 @@ public class ComfyuiText2ImageServiceImpl implements ComfyuiText2ImageService {
 
     /**
      * [ComfyUI] 文生图 (7.16生图.json)
+     * // ComfyuiResponse -> void
      */
     @Override
-    public ComfyuiResponse generateText2Image(String client_id, ComfyuiText2Image comfyuiText2Image) {
+    public Long generateText2Image(String client_id, ComfyuiText2Image comfyuiText2Image) {
 
         String prompt = "{"+
                 "  \"3\": {"+
@@ -336,25 +337,28 @@ public class ComfyuiText2ImageServiceImpl implements ComfyuiText2ImageService {
                 "  }"+
                 "}"
         ;
-        JSONObject prompt_object = JSONUtil.parseObj(prompt);
 
-        // [DB] 新增任务记录
-        comfyUtil.insertComfyuiTask(prompt, TaskTypeEnums.TEXT_2_IMAGE.getValue());
 
-        // [ComfyUI] 执行任务
-        Mono<ComfyuiResponse> cfPromptResponseMono = comfyUIService.prompt(client_id, prompt_object);
-        ComfyuiResponse response = cfPromptResponseMono.block();
-        response.setClient_id(client_id);
+        // [DB] 初始化任务
+        Long task_id = comfyUtil.initComfyuiTask(client_id, prompt, TaskTypeEnums.TEXT_2_IMAGE.getValue());
+        return task_id;
 
-        return response;
+//        // [ComfyUI] 执行任务
+//        JSONObject prompt_object = JSONUtil.parseObj(prompt);
+//        Mono<ComfyuiResponse> cfPromptResponseMono = comfyUIService.prompt(client_id, prompt_object);
+//        ComfyuiResponse response = cfPromptResponseMono.block();
+//        response.setClient_id(client_id);
+
+//        return response;
     }
 
 
     /**
      * [ComfyUI] 文生图 (基础生图)
+     * // ComfyuiResponse -> void
      */
     @Override
-    public ComfyuiResponse generateText2ImageSimple(String client_id, ComfyuiText2Image comfyuiText2Image) {
+    public Long generateText2ImageSimple(String client_id, ComfyuiText2Image comfyuiText2Image) {
 
         // [ComfyUI-基础生图]
         String prompt = "{" +
@@ -424,17 +428,19 @@ public class ComfyuiText2ImageServiceImpl implements ComfyuiText2ImageService {
                     "}," +
                 "}"
         ;
-        JSONObject prompt_object = JSONUtil.parseObj(prompt);
 
-        // [DB] 新增任务记录
-        comfyUtil.insertComfyuiTask(prompt, TaskTypeEnums.TEXT_2_IMAGE.getValue());
 
-        // [ComfyUI] 执行任务
-        Mono<ComfyuiResponse> cfPromptResponseMono = comfyUIService.prompt(client_id, prompt_object);
-        ComfyuiResponse response = cfPromptResponseMono.block();
-        response.setClient_id(client_id);
+        // [DB] 初始化任务
+        Long task_id = comfyUtil.initComfyuiTask(client_id, prompt, TaskTypeEnums.TEXT_2_IMAGE.getValue());
+        return task_id;
+
+//        // [ComfyUI] 执行任务
+//        JSONObject prompt_object = JSONUtil.parseObj(prompt);
+//        Mono<ComfyuiResponse> cfPromptResponseMono = comfyUIService.prompt(client_id, prompt_object);
+//        ComfyuiResponse response = cfPromptResponseMono.block();
+//        response.setClient_id(client_id);
 
-        return response;
+//        return response;
     }
 
 }

+ 20 - 15
src/main/java/com/backendsys/modules/sdk/comfyui/utils/ComfyUtil.java

@@ -2,7 +2,9 @@ package com.backendsys.modules.sdk.comfyui.utils;
 
 import com.backendsys.modules.common.config.security.utils.SecurityUtil;
 import com.backendsys.modules.sdk.comfyui.dao.ComfyuiTaskDao;
+import com.backendsys.modules.sdk.comfyui.dao.ComfyuiTaskExecuteDao;
 import com.backendsys.modules.sdk.comfyui.entity.ComfyuiTask;
+import com.backendsys.modules.sdk.comfyui.entity.ComfyuiTaskExecute;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
@@ -12,40 +14,43 @@ public class ComfyUtil {
 
     @Autowired
     private ComfyuiTaskDao comfyuiTaskDao;
+    
+    @Autowired
+    private ComfyuiTaskExecuteDao comfyuiTaskExecuteDao;
 
     /**
-     * [新增] 生成任务的记录
+     * 初始化任务
      */
-    public void insertComfyuiTask(String prompt, String type) {
+    public Long initComfyuiTask(String client_id, String prompt, String type) {
         Long user_id = SecurityUtil.getUserId();
         try {
-            System.out.println("-- 新增任务记录 --");
             ComfyuiTask comfyuiTask = new ComfyuiTask();
             comfyuiTask.setUser_id(user_id);
-            comfyuiTask.setType(type);
+            comfyuiTask.setClient_id(client_id);
+            comfyuiTask.setTask_type(type);
             comfyuiTask.setGenerate_request(prompt);
-
             comfyuiTaskDao.insert(comfyuiTask);
+            return comfyuiTask.getId();
         } catch (Exception e) {
             System.out.println(e.getMessage());
         }
+        return -1L;
     }
     /**
-     * [更新] 生成任务的记录
+     * [更新] 执行任务
      * - status: 任务状态 (-1:未开始, 1:进行中, 2:成功, 3:失败)
      */
-    public void updateComfyuiTask(String prompt_id, String response, Integer status) {
+    public void executeComfyuiTask(String prompt_id, String response, Integer status) {
         try {
-            System.out.println("-- 更新任务记录 --");
-            LambdaQueryWrapper<ComfyuiTask> wrapper = new LambdaQueryWrapper<>();
-            wrapper.eq(ComfyuiTask::getPrompt_id, prompt_id);
+            LambdaQueryWrapper<ComfyuiTaskExecute> wrapper = new LambdaQueryWrapper<>();
+            wrapper.eq(ComfyuiTaskExecute::getExecute_prompt_id, prompt_id);
 
-            ComfyuiTask comfyuiTask = new ComfyuiTask();
-            comfyuiTask.setStatus(status);
-            comfyuiTask.setPrompt_id(prompt_id);
-            comfyuiTask.setGenerate_response(response);
+            ComfyuiTaskExecute comfyuiTaskExecute = new ComfyuiTaskExecute();
+            comfyuiTaskExecute.setExecute_status(status);
+            comfyuiTaskExecute.setExecute_prompt_id(prompt_id);
+            comfyuiTaskExecute.setGenerate_response(response);
 
-            comfyuiTaskDao.update(comfyuiTask, wrapper);
+            comfyuiTaskExecuteDao.update(comfyuiTaskExecute, wrapper);
         } catch (Exception e) {
             System.out.println(e.getMessage());
         }