瀏覽代碼

完成 获取分集生图记录 接口(新增缩略图)

tsurumure 1 月之前
父節點
當前提交
ae680492f6

+ 1 - 0
db/crt_generate_image.sql

@@ -13,6 +13,7 @@ CREATE TABLE `crt_generate_image` (
     `prompt_id` VARCHAR(255) COMMENT '任务ID',
     `url_origin` VARCHAR(2000) NOT NULL COMMENT '原图',
     `url` VARCHAR(2000) COMMENT '转存图',
+    `target` INT COMMENT '上传目标 (-1:本地, 1:腾讯云, 2:阿里云, 3.抖音云)',
     `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
     `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
     INDEX `idx_user_id` (`user_id`)

+ 7 - 1
src/main/java/com/backendsys/modules/crt/controller/CrtGenerateController.java

@@ -29,7 +29,6 @@ public class CrtGenerateController {
         return Result.success().put("data", crtGenerateService.getQueue());
     }
 
-    // 生成图片
     @PreAuthorize("@sr.hasPermission('36.3')")
     @Operation(summary = "生成图片")
     @PostMapping("/api/crt/generate/image")
@@ -37,6 +36,13 @@ public class CrtGenerateController {
         return Result.success().put("data", crtGenerateService.generateImage(crtDramaProjectStoryboard));
     }
 
+    @PreAuthorize("@sr.hasPermission('36.3')")
+    @Operation(summary = "获取分集生图记录")
+    @GetMapping("/api/crt/getGenerateImage")
+    public Result getGenerateImage(@Validated(CrtDramaProjectStoryboard.GenerateImageList.class) CrtDramaProjectStoryboard crtDramaProjectStoryboard) {
+        return Result.success().put("data", crtGenerateService.selectGenerateImage(crtDramaProjectStoryboard));
+    }
+
     // 生成视频
 
 }

+ 3 - 2
src/main/java/com/backendsys/modules/crt/entity/CrtDramaProjectStoryboard.java

@@ -28,12 +28,13 @@ public class CrtDramaProjectStoryboard {
     public static interface Clear{}
     public static interface Delete{}
     public static interface GenerateImage{}
+    public static interface GenerateImageList{}
 
     @TableId(type = IdType.AUTO)
     private Long id;
 
-    @TableField(exist = false)
-    @NotNull(message = "分镜ID不能为空", groups = { Update.class, GenerateImage.class })
+    @TableField("id")
+    @NotNull(message = "分镜ID不能为空", groups = { Update.class, GenerateImage.class, GenerateImageList.class })
     private Long drama_project_storyboard_id;
 
     private Long user_id;

+ 5 - 2
src/main/java/com/backendsys/modules/crt/entity/CrtGenerateImage.java

@@ -2,6 +2,7 @@ package com.backendsys.modules.crt.entity;
 
 import com.backendsys.config.Mybatis.handler.timezone.LocalDateTimeAdapter;
 import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.google.gson.annotations.JsonAdapter;
@@ -18,9 +19,11 @@ public class CrtGenerateImage {
     private Long user_id;                       // 用户ID
     private Long drama_project_storyboard_id;   // 分镜ID
     private String prompt_id;                   // 任务ID
-    private String name;                        // 图片名称
     private String url_origin;                  // 原图
-    private String url;                          // 转存图
+    private String url;                         // 转存图
+    @TableField(exist = false)
+    private String url_thumb;                   // 转存图-缩略图
+    private Integer target;                     // 上传目标 (-1:本地, 1:腾讯云, 2:阿里云, 3.抖音云)
 
     @JsonAdapter(LocalDateTimeAdapter.class)
     private LocalDateTime create_time;

+ 4 - 0
src/main/java/com/backendsys/modules/crt/service/CrtGenerateService.java

@@ -1,6 +1,7 @@
 package com.backendsys.modules.crt.service;
 
 import com.backendsys.modules.crt.entity.CrtDramaProjectStoryboard;
+import com.backendsys.utils.response.PageEntity;
 
 import java.util.Map;
 
@@ -12,4 +13,7 @@ public interface CrtGenerateService {
     // 短剧创作-生成图片
     Map<String, Object> generateImage(CrtDramaProjectStoryboard crtDramaProjectStoryboard);
 
+    // 短剧创作-获取分集生图记录
+    PageEntity selectGenerateImage(CrtDramaProjectStoryboard crtDramaProjectStoryboard);
+
 }

+ 2 - 0
src/main/java/com/backendsys/modules/crt/service/impl/CrtDramaProjectStoryboardServiceImpl.java

@@ -50,9 +50,11 @@ public class CrtDramaProjectStoryboardServiceImpl implements CrtDramaProjectStor
         LambdaQueryWrapper<CrtDramaProjectStoryboard> wrapperStoryboard = new LambdaQueryWrapper<>();
         wrapperStoryboard.eq(CrtDramaProjectStoryboard::getDrama_project_id, project_id);
         wrapperStoryboard.eq(CrtDramaProjectStoryboard::getEpisode_num, episode_num);
+
         List<CrtDramaProjectStoryboard> storyboardList = crtDramaProjectStoryboardDao.selectList(wrapperStoryboard);
         if (storyboardList.isEmpty()) throw new CustException("分镜不存在");
 
+
         // 查询项目设置
         LambdaQueryWrapper<CrtDramaProjectSettings> wrapperSettings = new LambdaQueryWrapper<>();
         wrapperSettings.eq(CrtDramaProjectSettings::getDrama_project_id, project_id);

+ 50 - 11
src/main/java/com/backendsys/modules/crt/service/impl/CrtGenerateServiceImpl.java

@@ -5,9 +5,9 @@ import cn.hutool.core.date.DateUtil;
 import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
 import com.backendsys.exception.CustException;
-import com.backendsys.modules.common.config.security.utils.SecurityUtil;
 import com.backendsys.modules.crt.dao.CrtDramaProjectSettingsDao;
 import com.backendsys.modules.crt.dao.CrtDramaProjectStoryboardDao;
+import com.backendsys.modules.crt.dao.CrtGenerateImageDao;
 import com.backendsys.modules.crt.dao.CrtModelDao;
 import com.backendsys.modules.crt.entity.CrtDramaProjectSettings;
 import com.backendsys.modules.crt.entity.CrtDramaProjectStoryboard;
@@ -19,6 +19,11 @@ import com.backendsys.modules.sdk.comfyui.entity.CFPromptResponse;
 import com.backendsys.modules.sdk.comfyui.entity.CFQueue;
 import com.backendsys.modules.sdk.comfyui.service.ComfyUIService;
 import com.backendsys.modules.sdk.comfyui.service.ComfyUISocketService;
+import com.backendsys.modules.upload.enums.StyleEnums;
+import com.backendsys.modules.upload.utils.UploadUtil;
+import com.backendsys.utils.response.PageEntity;
+import com.backendsys.utils.response.PageInfoResult;
+import com.backendsys.utils.v2.PageUtils;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -28,6 +33,7 @@ import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
+import java.util.stream.Collectors;
 
 @Service
 public class CrtGenerateServiceImpl implements CrtGenerateService {
@@ -43,6 +49,8 @@ public class CrtGenerateServiceImpl implements CrtGenerateService {
     private CrtDramaProjectSettingsDao crtDramaProjectSettingsDao;
     @Autowired
     private CrtDramaProjectStoryboardDao crtDramaProjectStoryboardDao;
+    @Autowired
+    private CrtGenerateImageDao crtGenerateImageDao;
 
     /**
      * [ComfyUI] 查询任务队列
@@ -85,9 +93,17 @@ public class CrtGenerateServiceImpl implements CrtGenerateService {
         System.out.println("- 生图配置: " + JSONUtil.toJsonStr(settings_image));
         System.out.println("- 生视频配置: " + JSONUtil.toJsonStr(settings_video));
 
+        // 用于更新的参数实体类
+        CrtDramaProjectStoryboard entity = new CrtDramaProjectStoryboard();
+        LambdaQueryWrapper<CrtDramaProjectStoryboard> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(CrtDramaProjectStoryboard::getId, drama_project_storyboard_id);
+
+
 
         // 文生图提示词
         String text_to_image_prompt = crtDramaProjectStoryboard.getText_to_image_prompt();
+        // [更新] 文生图提示词
+        entity.setText_to_image_prompt(text_to_image_prompt);
 
         // == 从 storboard detail 获取参数 =============================================================================
         Integer param_batch_size = storyboardDetail.getParam_batch_size();                        // 生成图片数量
@@ -100,16 +116,13 @@ public class CrtGenerateServiceImpl implements CrtGenerateService {
         String param_seed_custom = storyboardDetail.getParam_seed_custom();
         if (param_seed == 1) {
             param_seed_custom = Convert.toStr(DateUtil.current());   // 生成一个随机值 (毫秒时间戳)
-
-            // 【随机值,要保存到数据库】
-            CrtDramaProjectStoryboard entity = new CrtDramaProjectStoryboard();
+            // [更新] 种子值
             entity.setParam_seed_custom(param_seed_custom);
-            LambdaQueryWrapper<CrtDramaProjectStoryboard> wrapper = new LambdaQueryWrapper<>();
-            wrapper.eq(CrtDramaProjectStoryboard::getId, drama_project_storyboard_id);
-            crtDramaProjectStoryboardDao.update(entity, wrapper);
-
         }
 
+        // [db] 更新分集记录
+        crtDramaProjectStoryboardDao.update(entity, wrapper);
+
 
 
         // [db] 获取基础模型 (从项目配置)
@@ -117,16 +130,13 @@ public class CrtGenerateServiceImpl implements CrtGenerateService {
         CrtModel modelDetail = crtModelDao.selectById(model_id);
         String model_name = modelDetail.getModel_name();
 
-
         // 风格 Lora?
         // 风格 Lora (阙值)?
 
-
         // ===========================================================================================================
 
 
 
-
         // -- 前端生成的UUID ---------------------------------------------
         String client_id = Convert.toStr(UUID.randomUUID());
 
@@ -535,4 +545,33 @@ public class CrtGenerateServiceImpl implements CrtGenerateService {
         return resp;
     }
 
+    // 短剧创作-获取分集生图记录
+    @Override
+    public PageEntity selectGenerateImage(CrtDramaProjectStoryboard crtDramaProjectStoryboard) {
+        PageUtils.startPage();  // 分页
+
+        Long drama_project_storyboard_id = crtDramaProjectStoryboard.getDrama_project_storyboard_id();
+
+        LambdaQueryWrapper<CrtGenerateImage> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(CrtGenerateImage::getDrama_project_storyboard_id, drama_project_storyboard_id);
+        wrapper.orderByDesc(CrtGenerateImage::getCreate_time);
+        List<CrtGenerateImage> list = crtGenerateImageDao.selectList(wrapper);
+
+        // 加入缩略图
+        if (!list.isEmpty()) {
+            // 1) 完成分页实体渲染
+            PageEntity pageEntity = new PageInfoResult(list).toEntity();
+            // 2) 分页列表格式化
+            list = list.stream().map(item -> {
+                item.setUrl_thumb(UploadUtil.getImageThumbUrl(item.getUrl(), item.getTarget(), 100, null, StyleEnums.THUMB_BACKGROUND.getValue()));
+                return item;
+            }).collect(Collectors.toList());
+            // 3) 分页实体重新赋值
+            List<Object> objectList = list.stream().map(item -> (Object) item).collect(Collectors.toList());
+            pageEntity.setList(objectList);
+        }
+
+        return new PageInfoResult(list).toEntity();
+    }
+
 }

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

@@ -171,6 +171,7 @@ public class ComfyUISocketServiceImpl implements ComfyUISocketService {
 //                                            String filepath = "http://" + COMFYUI_HOST + ":" + port + "/api/view?filename=" + filename;
 //                                            String filepath_with_token = filepath + "&token=" + COMFYUI_TOKEN;
 
+                                            // ComfyUI 输出的临时目录
                                             String filepath = "http://o.daogu.ai/" + port + "/" + filename;
 
                                             // -- [图片转存储存桶] -------------------------------------
@@ -190,6 +191,7 @@ public class ComfyUISocketServiceImpl implements ComfyUISocketService {
                                                         entity.setPrompt_id(prompt_id);
                                                         entity.setUrl_origin(filepath);
                                                         entity.setUrl(result.getUrl());
+                                                        entity.setTarget(result.getTarget());
                                                         crtGenerateImageDao.insert(entity);
                                                     }
 

+ 2 - 0
src/main/java/com/backendsys/modules/sdk/douyincloud/tos/service/DouyinTosService.java

@@ -11,6 +11,8 @@ import java.io.IOException;
 import java.util.List;
 
 /**
+ * 抖音云 - 对象储存
+ * https://cloud.douyin.com/overview
  * 文档首页/对象存储/SDK参考/Java/对象接口/上传对象/普通上传(Java SDK)
  * https://www.volcengine.com/docs/6349/79898
  * 分片上传

+ 2 - 0
src/main/java/com/backendsys/modules/sdk/douyincloud/tos/service/impl/DouyinTosServiceImpl.java

@@ -157,6 +157,7 @@ public class DouyinTosServiceImpl implements DouyinTosService {
             result.setE_tag(output.getEtag());
             result.setDomain(DOMAIN);
             result.setUrl(DOMAIN + "/" + object_key);
+            result.setTarget(3);
             return result;
 
         } catch (TosClientException | TosServerException e) {
@@ -417,6 +418,7 @@ public class DouyinTosServiceImpl implements DouyinTosService {
                 result.setE_tag(output.getEtag());
                 result.setSize(size);
                 result.setUrl(DOMAIN + "/" + object_key);
+                result.setTarget(3);
                 return result;
 
             } catch (TosClientException | TosServerException e) {

+ 2 - 0
src/main/java/com/backendsys/modules/sdk/tencentcloud/cos/service/impl/TencentCosServiceImpl.java

@@ -185,6 +185,7 @@ public class TencentCosServiceImpl implements TencentCosService {
             result.setE_tag(uploadResult.getETag());
             result.setDomain(ACCESSIBLE_DOMAIN);
             result.setUrl(ACCESSIBLE_DOMAIN + "/" + object_key);
+            result.setTarget(1);
             return result;
 
         } catch (IOException e) {
@@ -401,6 +402,7 @@ public class TencentCosServiceImpl implements TencentCosService {
             result.setE_tag(uploadResult.getETag());
             result.setSize(size);
             result.setUrl(ACCESSIBLE_DOMAIN + "/" + object_key);
+            result.setTarget(1);
             return result;
 
         } catch (CosClientException e) {

+ 0 - 2
src/main/java/com/backendsys/modules/sdk/tencentcloud/cos/utils/TencentCosUtil.java

@@ -37,6 +37,4 @@ public class TencentCosUtil {
         return file;
     }
 
-
-
 }

+ 1 - 0
src/main/java/com/backendsys/modules/upload/entity/SysFileResult.java

@@ -10,4 +10,5 @@ public class SysFileResult {
     private String domain;
     private String url;
     private Long size;
+    private Integer target;
 }

+ 34 - 0
src/main/java/com/backendsys/modules/upload/utils/UploadUtil.java

@@ -1,5 +1,7 @@
 package com.backendsys.modules.upload.utils;
 
+import cn.hutool.core.codec.Base64;
+import cn.hutool.core.convert.Convert;
 import com.backendsys.exception.CustException;
 import com.backendsys.modules.common.utils.CommonUtil;
 import com.backendsys.modules.upload.entity.SysFileResult;
@@ -9,6 +11,7 @@ import net.coobird.thumbnailator.Thumbnails;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.util.UriComponentsBuilder;
 
 import java.io.File;
 import java.io.IOException;
@@ -105,4 +108,35 @@ public class UploadUtil {
         }
     }
 
+    // 不同的云环境 (target),缩略图配置也不一样
+    //   -1:本地:
+    //   1:腾讯云: https://cloud.tencent.com/document/product/436/113295
+    //   2:阿里云:
+    //   3:抖音云: https://www.volcengine.com/docs/6349/153626
+    public static String getImageThumbUrl(String url, Integer target, Integer width, Integer height, String backgroundColor) {
+        if (target == -1) {
+            UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
+            if (width != null) builder.queryParam("w", width);
+            if (height != null) builder.queryParam("h", height);
+            return builder.toUriString();
+//            return url + "?" + "w=" + width + "&h=" + height;
+        }
+        // 腾讯云 (color值通过base64加密, #f8f8f8)
+        if (target == 1) {
+            backgroundColor = "#" + backgroundColor;
+            String w = (width != null) ? Convert.toStr(width) : "";
+            String h = (height != null) ? Convert.toStr(height) : "";
+            return url + "?imageMogr2/thumbnail/" + w + "x" + h + "/pad/1/color/" + Base64.encode(backgroundColor);
+        }
+        // 抖音云
+        if (target == 3) {
+            String w = (width != null) ? (",w_" + width) : "";
+            String h = (height != null) ? (",h_" + height) : "";
+//            return url + "?x-tos-process=image/resize,w_" + width + ",h_" + height + ",m_pad,color_" + backgroundColor;
+            return url + "?x-tos-process=image/resize" + w + h + ",color_" + backgroundColor;
+        }
+        return url;
+    }
+
+
 }