Selaa lähdekoodia

添加火山方舟大模型 图生视频 相关接口

cmy 1 kuukausi sitten
vanhempi
commit
f63eed2676
25 muutettua tiedostoa jossa 925 lisäystä ja 11 poistoa
  1. 12 0
      db/ai_volcengine_video_collect.sql
  2. 16 0
      db/ai_volcengine_video_task.sql
  3. 19 0
      db/ai_volcengine_video_task_detail.sql
  4. 61 0
      src/main/java/com/backendsys/modules/ai/volcengine/controller/VolcengineVideoController.java
  5. 9 0
      src/main/java/com/backendsys/modules/ai/volcengine/dao/VolcengineVideoCollectDao.java
  6. 19 0
      src/main/java/com/backendsys/modules/ai/volcengine/dao/VolcengineVideoTaskDao.java
  7. 9 0
      src/main/java/com/backendsys/modules/ai/volcengine/dao/VolcengineVideoTaskDetailDao.java
  8. 39 0
      src/main/java/com/backendsys/modules/ai/volcengine/entity/VolcengineVideoCollect.java
  9. 89 0
      src/main/java/com/backendsys/modules/ai/volcengine/entity/VolcengineVideoTask.java
  10. 33 0
      src/main/java/com/backendsys/modules/ai/volcengine/entity/VolcengineVideoTaskDTO.java
  11. 76 0
      src/main/java/com/backendsys/modules/ai/volcengine/entity/VolcengineVideoTaskDetail.java
  12. 10 0
      src/main/java/com/backendsys/modules/ai/volcengine/service/VolcengineVideoCollectService.java
  13. 8 0
      src/main/java/com/backendsys/modules/ai/volcengine/service/VolcengineVideoTaskDetailService.java
  14. 16 0
      src/main/java/com/backendsys/modules/ai/volcengine/service/VolcengineVideoTaskService.java
  15. 56 0
      src/main/java/com/backendsys/modules/ai/volcengine/service/impl/VolcengineVideoCollectServiceImpl.java
  16. 12 0
      src/main/java/com/backendsys/modules/ai/volcengine/service/impl/VolcengineVideoTaskDetailServiceImpl.java
  17. 230 0
      src/main/java/com/backendsys/modules/ai/volcengine/service/impl/VolcengineVideoTaskServiceImpl.java
  18. 7 0
      src/main/java/com/backendsys/modules/sdk/volcengine/controller/VolcengineDemoController.java
  19. 22 0
      src/main/java/com/backendsys/modules/sdk/volcengine/entity/VolcengineImage2VideoParams.java
  20. 2 0
      src/main/java/com/backendsys/modules/sdk/volcengine/service/VolcengineImage2VideoService.java
  21. 33 8
      src/main/java/com/backendsys/modules/sdk/volcengine/service/impl/VolcengineImage2VideoServiceImpl.java
  22. 5 1
      src/main/resources/application-dev.yml
  23. 5 1
      src/main/resources/application-local.yml
  24. 5 1
      src/main/resources/application-prod.yml
  25. 132 0
      src/main/resources/mapper/ai/volcengine/VolcengineVideoTaskDao.xml

+ 12 - 0
db/ai_volcengine_video_collect.sql

@@ -0,0 +1,12 @@
+DROP TABLE IF EXISTS `ai_volcengine_video_collect`;
+CREATE TABLE `ai_volcengine_video_collect`  (
+                                                `id` bigint NOT NULL AUTO_INCREMENT,
+                                                `user_id` bigint NULL DEFAULT NULL COMMENT '用户id',
+                                                `task_id` bigint NULL DEFAULT NULL COMMENT '任务id',
+                                                `task_detail_id` bigint NULL DEFAULT NULL COMMENT '任务明细id',
+                                                `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
+                                                PRIMARY KEY (`id`) USING BTREE,
+                                                INDEX `user_id`(`user_id` ASC) USING BTREE,
+                                                INDEX `task_id`(`task_id` ASC) USING BTREE,
+                                                INDEX `task_detail_id`(`task_detail_id` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '火山大模型生成视频收藏表' ROW_FORMAT = Dynamic;

+ 16 - 0
db/ai_volcengine_video_task.sql

@@ -0,0 +1,16 @@
+DROP TABLE IF EXISTS `ai_volcengine_video_task`;
+CREATE TABLE `ai_volcengine_video_task`  (
+                                             `id` bigint NOT NULL AUTO_INCREMENT COMMENT '任务id',
+                                             `user_id` bigint NULL DEFAULT NULL COMMENT '用户id',
+                                             `model` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '模型',
+                                             `img_url` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '图片地址',
+                                             `resolution` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '分辨率',
+                                             `duration` tinyint NULL DEFAULT NULL COMMENT '视频时长(秒)',
+                                             `text` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '文本描述',
+                                             `camerafixed` tinyint NULL DEFAULT NULL COMMENT '是否固定镜头 1-是 0-否',
+                                             `quantity` tinyint NULL DEFAULT NULL COMMENT '生成数量',
+                                             `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+                                             `update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+                                             PRIMARY KEY (`id`) USING BTREE,
+                                             INDEX `user_id`(`user_id` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '火山大模型视频生成任务表' ROW_FORMAT = Dynamic;

+ 19 - 0
db/ai_volcengine_video_task_detail.sql

@@ -0,0 +1,19 @@
+DROP TABLE IF EXISTS `ai_volcengine_video_task_detail`;
+CREATE TABLE `ai_volcengine_video_task_detail`  (
+                                                    `id` bigint NOT NULL AUTO_INCREMENT COMMENT '任务明细id',
+                                                    `user_id` bigint NULL DEFAULT NULL COMMENT '用户id',
+                                                    `task_id` bigint NULL DEFAULT NULL COMMENT '主表id',
+                                                    `volcengine_task_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '火山大模型任务id',
+                                                    `cover_img_url` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '封面图地址(首帧)',
+                                                    `seed` int NULL DEFAULT NULL COMMENT '种子',
+                                                    `status` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '状态\r\nqueued:排队中。\r\nrunning:任务运行中。\r\ncancelled:取消任务,取消状态24h自动删除(只支持排队中状态的任务被取消)。\r\nsucceeded: 任务成功。\r\nfailed:任务失败。',
+                                                    `video_origin_url` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '视频原始地址',
+                                                    `video_url` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '转存视频地址',
+                                                    `object_key` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '对象key',
+                                                    `error_msg` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '失败信息',
+                                                    `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+                                                    `update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+                                                    PRIMARY KEY (`id`) USING BTREE,
+                                                    INDEX `user_id`(`user_id` ASC) USING BTREE,
+                                                    INDEX `task_id`(`task_id` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '火山大模型视频生成任务明细表' ROW_FORMAT = Dynamic;

+ 61 - 0
src/main/java/com/backendsys/modules/ai/volcengine/controller/VolcengineVideoController.java

@@ -0,0 +1,61 @@
+package com.backendsys.modules.ai.volcengine.controller;
+
+import com.backendsys.modules.ai.volcengine.entity.VolcengineVideoCollect;
+import com.backendsys.modules.ai.volcengine.entity.VolcengineVideoTask;
+import com.backendsys.modules.ai.volcengine.entity.VolcengineVideoTaskDTO;
+import com.backendsys.modules.ai.volcengine.service.VolcengineVideoCollectService;
+import com.backendsys.modules.ai.volcengine.service.VolcengineVideoTaskService;
+import com.backendsys.modules.common.config.security.utils.SecurityUtil;
+import com.backendsys.modules.common.utils.Result;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.AllArgsConstructor;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+@AllArgsConstructor
+@Validated
+@RestController
+@Tag(name = "火山大模型 视频生成")
+public class VolcengineVideoController {
+
+    private final VolcengineVideoTaskService volcengineVideoTaskService;
+
+    private final VolcengineVideoCollectService volcengineVideoCollectService;
+
+
+    @Operation(summary = "创建图生视频任务")
+//    @PreAuthorize("@sr.hasPermission('36.4')")
+    @PostMapping("/api/ai/volcegine/generateVideo")
+    public Result generateVideo(@Validated(VolcengineVideoTask.Generate.class) @RequestBody VolcengineVideoTask volcengineVideoTask) {
+        volcengineVideoTask.setUser_id(SecurityUtil.getUserId());
+        return Result.success().put("data", volcengineVideoTaskService.generateVideo(volcengineVideoTask));
+    }
+
+    @Operation(summary = "查询图生视频任务状态")
+//    @PreAuthorize("@sr.hasPermission('36.4')")
+    @GetMapping("/api/ai/volcegine/video/getTaskStatus/{volcengineTaskId}")
+    public Result getTaskStatus(@PathVariable String volcengineTaskId) {
+        return Result.success().put("data", volcengineVideoTaskService.selectTaskStatus(volcengineTaskId));
+    }
+
+
+    @Operation(summary = "分页获取图生视频任务记录")
+//    @PreAuthorize("@sr.hasPermission('36.4')")
+    @GetMapping("/api/ai/volcegine/video/getTaskList")
+    public Result getTaskList(VolcengineVideoTaskDTO dto) {
+        dto.setUser_id(SecurityUtil.getUserId());
+        return Result.success().put("data", volcengineVideoTaskService.selectTaskList(dto));
+    }
+
+    @Operation(summary = "视频收藏/取消收藏")
+//    @PreAuthorize("@sr.hasPermission('36.4')")
+    @PutMapping("/api/ai/volcegine/video/setCollect")
+    public Result setCollect(@Validated(VolcengineVideoCollect.Collect.class) @RequestBody VolcengineVideoCollect volcengineVideoCollect) {
+        volcengineVideoCollect.setUser_id(SecurityUtil.getUserId());
+        return Result.success().put("data", volcengineVideoCollectService.setCollect(volcengineVideoCollect));
+
+    }
+
+
+}

+ 9 - 0
src/main/java/com/backendsys/modules/ai/volcengine/dao/VolcengineVideoCollectDao.java

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

+ 19 - 0
src/main/java/com/backendsys/modules/ai/volcengine/dao/VolcengineVideoTaskDao.java

@@ -0,0 +1,19 @@
+package com.backendsys.modules.ai.volcengine.dao;
+
+import com.backendsys.modules.ai.volcengine.entity.VolcengineVideoTask;
+import com.backendsys.modules.ai.volcengine.entity.VolcengineVideoTaskDTO;
+import com.backendsys.modules.ai.volcengine.entity.VolcengineVideoTaskDetail;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+@Mapper
+public interface VolcengineVideoTaskDao extends BaseMapper<VolcengineVideoTask> {
+
+    List<VolcengineVideoTask> selectTaskCollectList(@Param("dto") VolcengineVideoTaskDTO dto);
+
+    List<VolcengineVideoTask> selectTaskList(@Param("dto") VolcengineVideoTaskDTO dto);
+
+}

+ 9 - 0
src/main/java/com/backendsys/modules/ai/volcengine/dao/VolcengineVideoTaskDetailDao.java

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

+ 39 - 0
src/main/java/com/backendsys/modules/ai/volcengine/entity/VolcengineVideoCollect.java

@@ -0,0 +1,39 @@
+package com.backendsys.modules.ai.volcengine.entity;
+
+import com.backendsys.config.Mybatis.handler.timezone.LocalDateTimeAdapter;
+import com.backendsys.entity.validator.RangeArray;
+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;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@TableName("ai_volcengine_video_collect")
+@Data
+public class VolcengineVideoCollect {
+
+    public static interface Collect{}
+
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    private Long user_id;
+
+    private Long task_id;
+
+    @NotNull(message = "任务明细id不能为空", groups = { Collect.class })
+    private Long task_detail_id;
+
+    @JsonAdapter(LocalDateTimeAdapter.class)
+    private LocalDateTime create_time;
+
+    @TableField(exist = false)
+    @NotNull(message = "收藏状态不能为空", groups = { Collect.class })
+    @RangeArray(message="收藏状态取值有误,范围应是(-1取消收藏, 1加入收藏)", value = {"-1", "1"}, groups = { Collect.class })
+    private Integer is_collect;
+
+}

+ 89 - 0
src/main/java/com/backendsys/modules/ai/volcengine/entity/VolcengineVideoTask.java

@@ -0,0 +1,89 @@
+package com.backendsys.modules.ai.volcengine.entity;
+
+import com.backendsys.config.Mybatis.handler.timezone.LocalDateTimeAdapter;
+import com.backendsys.entity.validator.RangeArray;
+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;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Size;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+@TableName("ai_volcengine_video_task")
+@Data
+public class VolcengineVideoTask {
+
+    public static interface Query{}
+    public static interface Generate{}
+
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 用户ID
+     */
+    private Long user_id;
+
+    /**
+     * 模型
+     */
+    @NotBlank(message = "请选择模型", groups = { Generate.class })
+    private String model;
+    /**
+     * 图片地址
+     */
+    @NotBlank(message = "请上传图片", groups = { Generate.class })
+    private String img_url;
+
+    /**
+     * 分辨率 480p 720p 1080p
+     */
+    @NotBlank(message = "请选择分辨率", groups = { Generate.class })
+    private String resolution;
+
+    /**
+     * 时长 秒
+     */
+    @NotNull(message = "请选择时长", groups = { Generate.class })
+    @RangeArray(message="时长取值有误,范围应是(5, 10)", value = { "5", "10" })
+    private Integer duration;
+
+    /**
+     * 文本说明
+     */
+    @Size(max = 500, message = "提示词长度不能超过 {max} 字符", groups = { Generate.class })
+    private String text;
+
+    /**
+     * 是否固定镜头 1-是 0-否
+     */
+    private Integer camerafixed;
+
+    /**
+     * 生成数量
+     */
+    @NotNull(message="生成数量不能为空")
+    @RangeArray(message="生成数量取值有误,范围应是(1, 2, 3, 4)", value = { "1", "2", "3", "4" }, groups = { Generate.class })
+    private Integer quantity;
+
+    @JsonAdapter(LocalDateTimeAdapter.class)
+    private LocalDateTime create_time;
+    @JsonAdapter(LocalDateTimeAdapter.class)
+    private LocalDateTime update_time;
+
+    @TableField(exist = false)
+    private List<VolcengineVideoTaskDetail> detail_list;
+
+    /**
+     * 是否收藏 1-是 0-否
+     */
+    @TableField(exist = false)
+    private Integer is_collect;
+
+}

+ 33 - 0
src/main/java/com/backendsys/modules/ai/volcengine/entity/VolcengineVideoTaskDTO.java

@@ -0,0 +1,33 @@
+package com.backendsys.modules.ai.volcengine.entity;
+
+import lombok.Data;
+
+@Data
+public class VolcengineVideoTaskDTO {
+
+    /**
+     * 模型
+     */
+    private String model;
+
+    /**
+     * 日期范围 0-今天 1-昨天 2-近三天 3-近5天 4-近7天 5-近14天 6-自定义
+     */
+    private Integer date_range;
+    /**
+     * 日期时间范围
+     */
+    private String create_begin_date;
+    private String create_end_date;
+
+    /**
+     * 是否只看收藏 1-是 0-否
+     */
+    private Integer only_collections;
+
+    /**
+     * 用户ID
+     */
+    private Long user_id;
+
+}

+ 76 - 0
src/main/java/com/backendsys/modules/ai/volcengine/entity/VolcengineVideoTaskDetail.java

@@ -0,0 +1,76 @@
+package com.backendsys.modules.ai.volcengine.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;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@TableName("ai_volcengine_video_task_detail")
+@Data
+public class VolcengineVideoTaskDetail {
+
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 用户ID
+     */
+    private Long user_id;
+    /**
+     * 任务ID
+     */
+    private Long task_id;
+    /**
+     * 火山大模型任务ID
+     */
+    private String volcengine_task_id;
+    /**
+     * 封面图片URL
+     */
+    private String cover_img_url;
+    /**
+     * 种子
+     */
+    private Integer seed;
+    /**
+     * 任务状态
+     * queued:排队中。
+     * running:任务运行中。
+     * cancelled:取消任务,取消状态24h自动删除(只支持排队中状态的任务被取消)。
+     * succeeded: 任务成功。
+     * failed:任务失败。
+     */
+    private String status;
+    /**
+     * 视频原始URL
+     */
+    private String video_origin_url;
+    /**
+     * 视频转存URL
+     */
+    private String video_url;
+    /**
+     * 存储对象key
+     */
+    private String object_key;
+    /**
+     * 失败信息
+     */
+    private String error_msg;
+
+    @JsonAdapter(LocalDateTimeAdapter.class)
+    private LocalDateTime create_time;
+    @JsonAdapter(LocalDateTimeAdapter.class)
+    private LocalDateTime update_time;
+
+    /**
+     * 是否收藏 1-是 0-否
+     */
+    @TableField(exist = false)
+    private Integer is_collect;
+}

+ 10 - 0
src/main/java/com/backendsys/modules/ai/volcengine/service/VolcengineVideoCollectService.java

@@ -0,0 +1,10 @@
+package com.backendsys.modules.ai.volcengine.service;
+
+import com.backendsys.modules.ai.volcengine.entity.VolcengineVideoCollect;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+public interface VolcengineVideoCollectService extends IService<VolcengineVideoCollect> {
+
+    boolean setCollect(VolcengineVideoCollect volcengineVideoCollect);
+
+}

+ 8 - 0
src/main/java/com/backendsys/modules/ai/volcengine/service/VolcengineVideoTaskDetailService.java

@@ -0,0 +1,8 @@
+package com.backendsys.modules.ai.volcengine.service;
+
+import com.backendsys.modules.ai.volcengine.entity.VolcengineVideoTaskDetail;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+public interface VolcengineVideoTaskDetailService extends IService<VolcengineVideoTaskDetail> {
+
+}

+ 16 - 0
src/main/java/com/backendsys/modules/ai/volcengine/service/VolcengineVideoTaskService.java

@@ -0,0 +1,16 @@
+package com.backendsys.modules.ai.volcengine.service;
+
+import com.backendsys.modules.ai.volcengine.entity.VolcengineVideoTask;
+import com.backendsys.modules.ai.volcengine.entity.VolcengineVideoTaskDTO;
+import com.backendsys.modules.ai.volcengine.entity.VolcengineVideoTaskDetail;
+import com.backendsys.utils.response.PageEntity;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+public interface VolcengineVideoTaskService extends IService<VolcengineVideoTask> {
+
+    VolcengineVideoTask generateVideo(VolcengineVideoTask volcengineVideoTask);
+
+    VolcengineVideoTaskDetail selectTaskStatus(String volcengineTaskId);
+
+    PageEntity selectTaskList(VolcengineVideoTaskDTO dto);
+}

+ 56 - 0
src/main/java/com/backendsys/modules/ai/volcengine/service/impl/VolcengineVideoCollectServiceImpl.java

@@ -0,0 +1,56 @@
+package com.backendsys.modules.ai.volcengine.service.impl;
+
+import com.backendsys.exception.CustException;
+import com.backendsys.modules.ai.volcengine.dao.VolcengineVideoCollectDao;
+import com.backendsys.modules.ai.volcengine.dao.VolcengineVideoTaskDetailDao;
+import com.backendsys.modules.ai.volcengine.entity.VolcengineVideoCollect;
+import com.backendsys.modules.ai.volcengine.entity.VolcengineVideoTaskDetail;
+import com.backendsys.modules.ai.volcengine.service.VolcengineVideoCollectService;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class VolcengineVideoCollectServiceImpl extends ServiceImpl<VolcengineVideoCollectDao, VolcengineVideoCollect> implements VolcengineVideoCollectService {
+
+    @Autowired
+    private VolcengineVideoTaskDetailDao volcengineVideoTaskDetailDao;
+
+    @Override
+    public boolean setCollect(VolcengineVideoCollect volcengineVideoCollect) {
+
+        // 是否收藏 (-1取消收藏, 1加入收藏)
+        Integer isCollect = volcengineVideoCollect.getIs_collect();
+        Long taskDetailId = volcengineVideoCollect.getTask_detail_id();
+
+        // 查询当前用户,是否已经收藏过该风格
+        LambdaQueryWrapper<VolcengineVideoCollect> wrapperCollect = new LambdaQueryWrapper<>();
+        wrapperCollect.eq(VolcengineVideoCollect::getUser_id, volcengineVideoCollect.getUser_id());
+        wrapperCollect.eq(VolcengineVideoCollect::getTask_detail_id, taskDetailId);
+
+        if (isCollect == 1) {
+            // 如果已经收藏过,则不变
+            VolcengineVideoCollect detail = baseMapper.selectOne(wrapperCollect);
+            if (detail == null) {
+
+                // [DB] 判断任务是否存在
+                VolcengineVideoTaskDetail taskDetail = volcengineVideoTaskDetailDao.selectOne(Wrappers.<VolcengineVideoTaskDetail>lambdaQuery().eq(VolcengineVideoTaskDetail::getId, taskDetailId));
+                if (taskDetail == null) {
+                    throw new CustException("视频不存在");
+                }
+                volcengineVideoCollect.setTask_id(taskDetail.getTask_id());
+
+                // [DB] 加入收藏
+                baseMapper.insert(volcengineVideoCollect);
+            }
+        } else {
+            // [DB] 取消收藏
+            baseMapper.delete(wrapperCollect);
+        }
+
+        return true;
+    }
+
+}

+ 12 - 0
src/main/java/com/backendsys/modules/ai/volcengine/service/impl/VolcengineVideoTaskDetailServiceImpl.java

@@ -0,0 +1,12 @@
+package com.backendsys.modules.ai.volcengine.service.impl;
+
+import com.backendsys.modules.ai.volcengine.dao.VolcengineVideoTaskDetailDao;
+import com.backendsys.modules.ai.volcengine.entity.VolcengineVideoTaskDetail;
+import com.backendsys.modules.ai.volcengine.service.VolcengineVideoTaskDetailService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+@Service
+public class VolcengineVideoTaskDetailServiceImpl extends ServiceImpl<VolcengineVideoTaskDetailDao, VolcengineVideoTaskDetail> implements VolcengineVideoTaskDetailService {
+
+}

+ 230 - 0
src/main/java/com/backendsys/modules/ai/volcengine/service/impl/VolcengineVideoTaskServiceImpl.java

@@ -0,0 +1,230 @@
+package com.backendsys.modules.ai.volcengine.service.impl;
+
+import com.backendsys.exception.CustException;
+import com.backendsys.modules.ai.volcengine.dao.VolcengineVideoTaskDao;
+import com.backendsys.modules.ai.volcengine.entity.VolcengineVideoTask;
+import com.backendsys.modules.ai.volcengine.entity.VolcengineVideoTaskDTO;
+import com.backendsys.modules.ai.volcengine.entity.VolcengineVideoTaskDetail;
+import com.backendsys.modules.ai.volcengine.service.VolcengineVideoTaskDetailService;
+import com.backendsys.modules.ai.volcengine.service.VolcengineVideoTaskService;
+import com.backendsys.modules.common.config.security.utils.SecurityUtil;
+import com.backendsys.modules.upload.entity.SysFileResult;
+import com.backendsys.modules.upload.service.SysFileService;
+import com.backendsys.utils.response.PageEntity;
+import com.backendsys.utils.response.PageInfoResult;
+import com.backendsys.utils.v2.PageUtils;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.volcengine.ark.runtime.model.content.generation.CreateContentGenerationTaskRequest;
+import com.volcengine.ark.runtime.model.content.generation.CreateContentGenerationTaskResult;
+import com.volcengine.ark.runtime.model.content.generation.GetContentGenerationTaskRequest;
+import com.volcengine.ark.runtime.model.content.generation.GetContentGenerationTaskResponse;
+import com.volcengine.ark.runtime.service.ArkService;
+import okhttp3.ConnectionPool;
+import okhttp3.Dispatcher;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.PostConstruct;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+@Service
+public class VolcengineVideoTaskServiceImpl extends ServiceImpl<VolcengineVideoTaskDao, VolcengineVideoTask> implements VolcengineVideoTaskService {
+
+    @Autowired
+    private VolcengineVideoTaskDetailService volcengineVideoTaskDetailService;
+
+    @Autowired
+    private SysFileService sysFileService;
+
+    @Value("${volcengine.api-key}")
+    private String apiKey;
+
+    private final ConnectionPool connectionPool = new ConnectionPool(20, 5, TimeUnit.MINUTES);
+    private final Dispatcher dispatcher = new Dispatcher();
+    private ArkService service;
+
+    @PostConstruct
+    public void init() {
+        this.service = ArkService.builder()
+                .dispatcher(dispatcher)
+                .connectionPool(connectionPool)
+                .apiKey(apiKey)
+                .build();
+    }
+
+    @Transactional
+    @Override
+    public VolcengineVideoTask generateVideo(VolcengineVideoTask volcengineVideoTask) {
+        // 生成任务主表记录
+        this.baseMapper.insert(volcengineVideoTask);
+
+        List<CreateContentGenerationTaskRequest.Content> contents = new ArrayList<>();
+
+        // 图生视频功能 构建请求参数
+        // 文本提示词与参数组合
+        if (StringUtils.isNotBlank(volcengineVideoTask.getText())) {
+            StringBuilder text = new StringBuilder(volcengineVideoTask.getText());
+            if(StringUtils.isNotBlank(volcengineVideoTask.getResolution())) {
+                text.append(" --rs ").append(volcengineVideoTask.getResolution());
+            }
+            if(volcengineVideoTask.getDuration() != null) {
+                text.append(" --dur ").append(volcengineVideoTask.getDuration());
+            }
+            if(volcengineVideoTask.getCamerafixed() != null) {
+                if (volcengineVideoTask.getCamerafixed() == 1) {
+                    text.append(" --cf true");
+                } else {
+                    text.append(" --cf false");
+                }
+            }
+
+            contents.add(CreateContentGenerationTaskRequest.Content.builder()
+                    .type("text")
+                    .text(text.toString())
+                    .build());
+        }
+
+        // 首帧图片 (若仅需使用文本生成视频功能,可将此部分内容进行注释处理。)
+        contents.add(CreateContentGenerationTaskRequest.Content.builder()
+                .type("image_url")
+                .imageUrl(CreateContentGenerationTaskRequest.ImageUrl.builder()
+                        .url(volcengineVideoTask.getImg_url())
+                        .build())
+                .build());
+        // 创建视频生成任务
+        CreateContentGenerationTaskRequest createRequest = CreateContentGenerationTaskRequest.builder()
+                .model(volcengineVideoTask.getModel())
+                .content(contents)
+                // todo callback_url 回调地址
+//                .callbackUrl()
+                .build();
+
+        //根据数量生成任务,记录明细
+        List<VolcengineVideoTaskDetail> detailList = new ArrayList<>();
+        int num = 0;
+        while (volcengineVideoTask.getQuantity() > num) {
+
+            VolcengineVideoTaskDetail volcengineVideoTaskDetail = new VolcengineVideoTaskDetail();
+            volcengineVideoTaskDetail.setTask_id(volcengineVideoTask.getId());
+            volcengineVideoTaskDetail.setUser_id(volcengineVideoTask.getUser_id());
+            volcengineVideoTaskDetail.setCover_img_url(volcengineVideoTask.getImg_url());
+            volcengineVideoTaskDetail.setStatus("queued");
+            // 创建图生视频任务
+            CreateContentGenerationTaskResult taskResult = service.createContentGenerationTask(createRequest);
+
+            volcengineVideoTaskDetail.setVolcengine_task_id(taskResult.getId());
+            detailList.add(volcengineVideoTaskDetail);
+            num++;
+        }
+        if(!detailList.isEmpty()){
+            volcengineVideoTaskDetailService.saveBatch(detailList);
+            volcengineVideoTask.setDetail_list(detailList);
+        }
+
+        return volcengineVideoTask;
+    }
+
+    @Override
+    public VolcengineVideoTaskDetail selectTaskStatus(String volcengineTaskId) {
+
+        VolcengineVideoTaskDetail volcengineVideoTaskDetail = volcengineVideoTaskDetailService.getOne(Wrappers.<VolcengineVideoTaskDetail>lambdaQuery()
+                .eq(VolcengineVideoTaskDetail::getVolcengine_task_id, volcengineTaskId));
+        if(volcengineVideoTaskDetail == null) {
+            throw new CustException("找不到该图生视频信息,请检查参数是否有误");
+        }
+        // 成功或失败的直接返回
+        if("succeeded".equals(volcengineVideoTaskDetail.getStatus()) || "failed".equals(volcengineVideoTaskDetail.getStatus())) {
+            return volcengineVideoTaskDetail;
+        }
+
+        GetContentGenerationTaskRequest getRequest = GetContentGenerationTaskRequest.builder()
+                .taskId(volcengineTaskId)
+                .build();
+
+        GetContentGenerationTaskResponse response = service.getContentGenerationTask(getRequest);
+        // 更新任务明细
+        volcengineVideoTaskDetail.setStatus(response.getStatus());
+        if(response.getSeed() != null) {
+            volcengineVideoTaskDetail.setSeed(response.getSeed().intValue());
+        }
+        if("succeeded".equals(response.getStatus())) {
+            // 成功,保存视频url
+            String videoOriginUrl = response.getContent().getVideoUrl();
+            volcengineVideoTaskDetail.setVideo_origin_url(videoOriginUrl);
+
+            // URL转存文件
+            SysFileResult sysFileResult = sysFileService.urlToUploadFile(videoOriginUrl, SecurityUtil.getUserId());
+            String objectKey = sysFileResult.getKey();
+            String videoUrl = sysFileResult.getDomain() + "/" + sysFileResult.getKey();
+            volcengineVideoTaskDetail.setVideo_url(videoUrl);
+            volcengineVideoTaskDetail.setObject_key(objectKey);
+        } else {
+            if(response.getError() !=null) {
+                volcengineVideoTaskDetail.setError_msg(response.getError().toString());
+            }
+        }
+
+        volcengineVideoTaskDetailService.updateById(volcengineVideoTaskDetail);
+
+        return volcengineVideoTaskDetail;
+
+    }
+
+    @Override
+    public PageEntity selectTaskList(VolcengineVideoTaskDTO dto) {
+        PageUtils.startPage();
+        List<VolcengineVideoTask> list = new ArrayList<>();
+        // 时间范围
+        if(dto.getDate_range() != null) {
+            String today = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+            switch (dto.getDate_range()) {
+                case 0:
+                    // 今天
+                    dto.setCreate_begin_date(today);
+                    dto.setCreate_end_date(today);
+                    break;
+                case 1:
+                    // 昨天
+                    String yesterday = LocalDate.now().minusDays(1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+                    dto.setCreate_begin_date(yesterday);
+                    dto.setCreate_end_date(yesterday);
+                    break;
+                case 2:
+                    // 近3天
+                    dto.setCreate_begin_date(LocalDate.now().minusDays(2).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
+                    dto.setCreate_end_date(today);
+                    break;
+                case 3:
+                    // 近5天
+                    dto.setCreate_begin_date(LocalDate.now().minusDays(4).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
+                    dto.setCreate_end_date(today);
+                    break;
+                case 4:
+                    // 近7天
+                    dto.setCreate_begin_date(LocalDate.now().minusDays(6).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
+                    dto.setCreate_end_date(today);
+                    break;
+                case 5:
+                    // 近14天
+                    dto.setCreate_begin_date(LocalDate.now().minusDays(13).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
+                    dto.setCreate_end_date(today);
+                    break;
+            }
+        }
+        if(dto.getOnly_collections() != null && dto.getOnly_collections() == 1){
+            // 只看收藏
+            list = baseMapper.selectTaskCollectList(dto);
+        } else {
+            list = baseMapper.selectTaskList(dto);
+        }
+        return new PageInfoResult(list).toEntity();
+    }
+}

+ 7 - 0
src/main/java/com/backendsys/modules/sdk/volcengine/controller/VolcengineDemoController.java

@@ -60,4 +60,11 @@ public class VolcengineDemoController {
         return Result.success().put("data", volcengineImage2VideoService.queryImage2VideoTask(taskId));
     }
 
+    @Anonymous
+    @Operation(summary = "【图生视频】查询任务列表")
+    @GetMapping("/api/volcegine/queryImage2VideoTaskList")
+    public Result queryImage2VideoTaskList(String taskIds) {
+        return Result.success().put("data", volcengineImage2VideoService.queryImage2VideoTaskList(taskIds));
+    }
+
 }

+ 22 - 0
src/main/java/com/backendsys/modules/sdk/volcengine/entity/VolcengineImage2VideoParams.java

@@ -8,6 +8,7 @@ import lombok.Data;
 @Data
 public class VolcengineImage2VideoParams {
 
+    private String model;
     /**
      * 图片地址
      */
@@ -16,4 +17,25 @@ public class VolcengineImage2VideoParams {
      * 文本说明
      */
     private String text;
+
+    /**
+     * 分辨率 480p 720p 1080p
+     */
+    private String resolution;
+
+    /**
+     * 视频时长 单位秒
+     */
+    private Integer duration;
+
+    /**
+     * 摄像头固定 1-是 0-否
+     */
+    private Integer camerafixed;
+
+    /**
+     * 种子
+     */
+//    private Integer seed;
+
 }

+ 2 - 0
src/main/java/com/backendsys/modules/sdk/volcengine/service/VolcengineImage2VideoService.java

@@ -3,6 +3,7 @@ package com.backendsys.modules.sdk.volcengine.service;
 import com.backendsys.modules.sdk.volcengine.entity.VolcengineImage2VideoParams;
 import com.volcengine.ark.runtime.model.content.generation.CreateContentGenerationTaskResult;
 import com.volcengine.ark.runtime.model.content.generation.GetContentGenerationTaskResponse;
+import com.volcengine.ark.runtime.model.content.generation.ListContentGenerationTasksResponse;
 
 public interface VolcengineImage2VideoService {
 
@@ -10,4 +11,5 @@ public interface VolcengineImage2VideoService {
 
     GetContentGenerationTaskResponse queryImage2VideoTask(String taskId);
 
+    ListContentGenerationTasksResponse queryImage2VideoTaskList(String taskIds);
 }

+ 33 - 8
src/main/java/com/backendsys/modules/sdk/volcengine/service/impl/VolcengineImage2VideoServiceImpl.java

@@ -2,10 +2,7 @@ package com.backendsys.modules.sdk.volcengine.service.impl;
 
 import com.backendsys.modules.sdk.volcengine.entity.VolcengineImage2VideoParams;
 import com.backendsys.modules.sdk.volcengine.service.VolcengineImage2VideoService;
-import com.volcengine.ark.runtime.model.content.generation.CreateContentGenerationTaskRequest;
-import com.volcengine.ark.runtime.model.content.generation.CreateContentGenerationTaskResult;
-import com.volcengine.ark.runtime.model.content.generation.GetContentGenerationTaskRequest;
-import com.volcengine.ark.runtime.model.content.generation.GetContentGenerationTaskResponse;
+import com.volcengine.ark.runtime.model.content.generation.*;
 import com.volcengine.ark.runtime.service.ArkService;
 import okhttp3.ConnectionPool;
 import okhttp3.Dispatcher;
@@ -13,6 +10,7 @@ import org.apache.commons.lang.StringUtils;
 import org.springframework.stereotype.Service;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 
@@ -31,16 +29,31 @@ public class VolcengineImage2VideoServiceImpl implements VolcengineImage2VideoSe
 
     @Override
     public CreateContentGenerationTaskResult image2Video(VolcengineImage2VideoParams params) {
-        String model = "doubao-seedance-1-0-pro-250528";
+//        String model = "doubao-seedance-1-0-pro-250528";
 
         List<CreateContentGenerationTaskRequest.Content> contents = new ArrayList<>();
 
         // 图生视频功能
         // 文本提示词与参数组合
         if (StringUtils.isNotBlank(params.getText())) {
+            StringBuilder text = new StringBuilder(params.getText());
+            if(StringUtils.isNotBlank(params.getResolution())) {
+                text.append(" --rs ").append(params.getResolution());
+            }
+            if(params.getDuration() != null) {
+                text.append(" --dur ").append(params.getDuration());
+            }
+            if(params.getCamerafixed() != null) {
+                if (params.getCamerafixed() == 1) {
+                    text.append(" --cf true");
+                } else {
+                    text.append(" --cf false");
+                }
+            }
+
             contents.add(CreateContentGenerationTaskRequest.Content.builder()
                     .type("text")
-                    .text(params.getText())
+                    .text(text.toString())
                     .build());
         }
 
@@ -48,12 +61,12 @@ public class VolcengineImage2VideoServiceImpl implements VolcengineImage2VideoSe
         contents.add(CreateContentGenerationTaskRequest.Content.builder()
                 .type("image_url")
                 .imageUrl(CreateContentGenerationTaskRequest.ImageUrl.builder()
-                        .url(params.getImageUrl()) // 请上传可以访问的图片URL
+                        .url(params.getImageUrl())
                         .build())
                 .build());
         // 创建视频生成任务
         CreateContentGenerationTaskRequest createRequest = CreateContentGenerationTaskRequest.builder()
-                .model(model)
+                .model(params.getModel())
                 .content(contents)
                 .build();
 
@@ -72,4 +85,16 @@ public class VolcengineImage2VideoServiceImpl implements VolcengineImage2VideoSe
 
     }
 
+    @Override
+    public ListContentGenerationTasksResponse queryImage2VideoTaskList(String taskIds) {
+        List<String> taskIdList = Arrays.asList(taskIds.split( ","));
+        ListContentGenerationTasksRequest req = ListContentGenerationTasksRequest.builder()
+                .taskIds(taskIdList)
+                .pageNum(1)
+                .pageSize(taskIdList.size())
+                .build();
+
+        return service.listContentGenerationTasks(req);
+    }
+
 }

+ 5 - 1
src/main/resources/application-dev.yml

@@ -215,4 +215,8 @@ comfyui:
   ports: 8000, 8001, 8002, 8003, 8004, 8005, 8006, 8007
   token: $2b$12$.MR4qGaFetN1FPQzbfyIrehsyjnPJ12xAZhR/l7KZpLkUPQTCG4gy
   is-save: true
-  # queue-key: comfyui:queue
+  # queue-key: comfyui:queue
+
+# 火山大模型
+volcengine:
+  api-key: ea19ba93-41fa-4bd9-90ec-6b203be84e33

+ 5 - 1
src/main/resources/application-local.yml

@@ -225,4 +225,8 @@ comfyui:
   ports: 8000, 8001, 8002, 8003, 8004, 8005, 8006, 8007
   token: $2b$12$.MR4qGaFetN1FPQzbfyIrehsyjnPJ12xAZhR/l7KZpLkUPQTCG4gy
   is-save: false
-  # queue-key: comfyui:queue
+  # queue-key: comfyui:queue
+
+# 火山大模型
+volcengine:
+  api-key: ea19ba93-41fa-4bd9-90ec-6b203be84e33

+ 5 - 1
src/main/resources/application-prod.yml

@@ -216,4 +216,8 @@ comfyui:
   ports: 8000, 8001, 8002, 8003, 8004, 8005, 8006, 8007
   token: $2b$12$.MR4qGaFetN1FPQzbfyIrehsyjnPJ12xAZhR/l7KZpLkUPQTCG4gy
   is-save: true
-  # queue-key: comfyui:queue
+  # queue-key: comfyui:queue
+
+# 火山大模型
+volcengine:
+  api-key: ea19ba93-41fa-4bd9-90ec-6b203be84e33

+ 132 - 0
src/main/resources/mapper/ai/volcengine/VolcengineVideoTaskDao.xml

@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.backendsys.modules.ai.volcengine.dao.VolcengineVideoTaskDao">
+
+
+    <resultMap id="resultMapTask" type="com.backendsys.modules.ai.volcengine.entity.VolcengineVideoTask">
+        <id property="id" column="id" jdbcType="BIGINT" />
+        <result property="user_id" column="user_id" jdbcType="BIGINT" />
+        <result property="model" column="model" jdbcType="VARCHAR" />
+        <result property="img_url" column="img_url"  jdbcType="VARCHAR" />
+        <result property="resolution" column="resolution" jdbcType="VARCHAR" />
+        <result property="duration" column="duration" jdbcType="INTEGER" />
+        <result property="text" column="text" jdbcType="VARCHAR" />
+        <result property="camerafixed" column="camerafixed" jdbcType="INTEGER" />
+        <result property="quantity" column="quantity" jdbcType="INTEGER" />
+        <result property="is_collect" column="is_collect" jdbcType="INTEGER" />
+        <result property="create_time" column="create_time" />
+        <result property="update_time" column="update_time" />
+        <collection select="queryDetailById" property="detail_list" javaType="java.util.List"
+                    ofType="com.backendsys.modules.ai.volcengine.entity.VolcengineVideoTaskDetail" column="{id=id, user_id=user_id}">
+            <id property="id" column="id" />
+            <result property="user_id" column="user_id" />
+            <result property="task_id" column="task_id" />
+            <result property="volcengine_task_id" column="volcengine_task_id" />
+            <result property="cover_img_url" column="cover_img_url" />
+            <result property="seed" column="seed" />
+            <result property="status" column="status" />
+            <result property="video_origin_url" column="video_origin_url" />
+            <result property="video_url" column="video_url"/>
+            <result property="object_key" column="object_key"/>
+            <result property="error_msg" column="error_msg" />
+            <result property="create_time" column="create_time" />
+            <result property="update_time" column="update_time" />
+            <result property="is_collect" column="is_collect" jdbcType="INTEGER" />
+        </collection>
+    </resultMap>
+
+    <resultMap id="resultMapTaskCollect" type="com.backendsys.modules.ai.volcengine.entity.VolcengineVideoTask">
+        <id property="id" column="id" jdbcType="BIGINT" />
+        <result property="user_id" column="user_id" jdbcType="BIGINT" />
+        <result property="model" column="model" jdbcType="VARCHAR" />
+        <result property="img_url" column="img_url"  jdbcType="VARCHAR" />
+        <result property="resolution" column="resolution" jdbcType="VARCHAR" />
+        <result property="duration" column="duration" jdbcType="INTEGER" />
+        <result property="text" column="text" jdbcType="VARCHAR" />
+        <result property="camerafixed" column="camerafixed" jdbcType="INTEGER" />
+        <result property="quantity" column="quantity" jdbcType="INTEGER" />
+        <result property="is_collect" column="is_collect" jdbcType="INTEGER" />
+        <result property="create_time" column="create_time" />
+        <result property="update_time" column="update_time" />
+        <collection select="queryDetailCollectById" property="detail_list" javaType="java.util.List"
+                    ofType="com.backendsys.modules.ai.volcengine.entity.VolcengineVideoTaskDetail" column="{id=id, user_id=user_id}">
+            <id property="id" column="id" />
+            <result property="user_id" column="user_id" />
+            <result property="task_id" column="task_id" />
+            <result property="volcengine_task_id" column="volcengine_task_id" />
+            <result property="cover_img_url" column="cover_img_url" />
+            <result property="seed" column="seed" />
+            <result property="status" column="status" />
+            <result property="video_origin_url" column="video_origin_url" />
+            <result property="video_url" column="video_url"/>
+            <result property="object_key" column="object_key"/>
+            <result property="error_msg" column="error_msg" />
+            <result property="create_time" column="create_time" />
+            <result property="update_time" column="update_time" />
+            <result property="is_collect" column="is_collect" jdbcType="INTEGER" />
+        </collection>
+    </resultMap>
+
+    <select id="selectTaskList" resultMap="resultMapTask">
+        SELECT avvt.*,
+               (case when (select count(1)
+                           from ai_volcengine_video_collect
+                           where task_id=avvt.id and user_id=#{dto.user_id})>0
+                   then 1 else 0 end) as is_collect
+        from ai_volcengine_video_task avvt
+        <where>
+            <if test="dto.model != null and dto.model != ''">
+                and avvt.model = #{dto.model}
+            </if>
+            <if test="dto.create_begin_date != null and dto.create_begin_date != '' and dto.create_end_date !=null and dto.create_end_date != ''">
+                and date_format(avvt.create_time,'%Y-%m-%d') BETWEEN #{dto.create_begin_date} and #{dto.create_end_date}
+            </if>
+        </where>
+        order by create_time desc
+    </select>
+
+    <select id="queryDetailById" resultType="com.backendsys.modules.ai.volcengine.entity.VolcengineVideoTaskDetail">
+        SELECT avvtd.*,
+               (case when (select count(1)
+                           from ai_volcengine_video_collect
+                           where task_id=avvtd.task_id and task_detail_id=avvtd.id and user_id=#{user_id})>0
+                   then 1 else 0 end) as is_collect
+        FROM ai_volcengine_video_task_detail avvtd
+        WHERE avvtd.task_id = #{id}
+        order by update_time desc
+    </select>
+
+    <select id="selectTaskCollectList"
+            resultMap="resultMapTaskCollect">
+        select * from (SELECT avvt.*,
+               (case when (select count(1)
+                           from ai_volcengine_video_collect
+                           where task_id=avvt.id and user_id=#{dto.user_id})>0
+                         then 1 else 0 end) as is_collect
+        from ai_volcengine_video_task avvt
+        <where>
+            <if test="dto.model != null and dto.model != ''">
+                and avvt.model = #{dto.model}
+            </if>
+            <if test="dto.create_begin_date != null and dto.create_begin_date != '' and dto.create_end_date !=null and dto.create_end_date != ''">
+                and date_format(avvt.create_time,'%Y-%m-%d') BETWEEN #{dto.create_begin_date} and #{dto.create_end_date}
+            </if>
+        </where>
+        order by create_time desc
+        ) t
+        where t.is_collect=1
+    </select>
+
+    <select id="queryDetailCollectById" resultType="com.backendsys.modules.ai.volcengine.entity.VolcengineVideoTaskDetail">
+        select * from (SELECT avvtd.*,
+               (case when (select count(1)
+                           from ai_volcengine_video_collect
+                           where task_id=avvtd.task_id and task_detail_id=avvtd.id and user_id=#{user_id})>0
+                         then 1 else 0 end) as is_collect
+        FROM ai_volcengine_video_task_detail avvtd
+        WHERE avvtd.task_id = #{id}
+        order by update_time desc
+        ) t
+        where t.is_collect=1
+    </select>
+</mapper>