ソースを参照

Merge branch 'dev-yhq' into develop

tsurumure 3 ヶ月 前
コミット
eb56c87fb1
36 ファイル変更767 行追加46 行削除
  1. 15 5
      db/crt_drama_project.sql
  2. 12 12
      db/crt_drama_project_settings.sql
  3. 6 5
      db/crt_drama_project_storyboard.sql
  4. 2 2
      db/crt_drama_task.sql
  5. 8 4
      db/crt_lora_style.sql
  6. 17 0
      db/crt_lora_style_category.sql
  7. 21 0
      db/crt_lora_style_collect.sql
  8. 10 3
      db/sys_user_role_permission.sql
  9. 6 0
      db/sys_user_role_permission_relation.sql
  10. 1 0
      src/main/java/com/backendsys/modules/common/config/security/utils/SecurityUtil.java
  11. 40 0
      src/main/java/com/backendsys/modules/crt/controller/CrtDramaProjectController.java
  12. 51 0
      src/main/java/com/backendsys/modules/crt/controller/CrtDramaProjectStoryboardController.java
  13. 52 0
      src/main/java/com/backendsys/modules/crt/controller/CrtLoraStyleController.java
  14. 15 0
      src/main/java/com/backendsys/modules/crt/dao/CrtDramaProjectDao.java
  15. 9 0
      src/main/java/com/backendsys/modules/crt/dao/CrtDramaProjectStoryboardDao.java
  16. 9 0
      src/main/java/com/backendsys/modules/crt/dao/CrtLoraStyleCategoryDao.java
  17. 9 0
      src/main/java/com/backendsys/modules/crt/dao/CrtLoraStyleCollectDao.java
  18. 15 0
      src/main/java/com/backendsys/modules/crt/dao/CrtLoraStyleDao.java
  19. 16 2
      src/main/java/com/backendsys/modules/crt/entity/CrtDramaProject.java
  20. 5 5
      src/main/java/com/backendsys/modules/crt/entity/CrtDramaProjectSettings.java
  21. 4 4
      src/main/java/com/backendsys/modules/crt/entity/CrtDramaProjectStoryboard.java
  22. 1 1
      src/main/java/com/backendsys/modules/crt/entity/CrtDramaTask.java
  23. 12 0
      src/main/java/com/backendsys/modules/crt/entity/CrtLoraStyle.java
  24. 15 0
      src/main/java/com/backendsys/modules/crt/entity/CrtLoraStyleCategory.java
  25. 30 0
      src/main/java/com/backendsys/modules/crt/entity/CrtLoraStyleCollect.java
  26. 12 0
      src/main/java/com/backendsys/modules/crt/service/CrtDramaProjectService.java
  27. 13 0
      src/main/java/com/backendsys/modules/crt/service/CrtDramaProjectStoryboardService.java
  28. 25 0
      src/main/java/com/backendsys/modules/crt/service/CrtLoraStyleService.java
  29. 30 0
      src/main/java/com/backendsys/modules/crt/service/impl/CrtDramaProjectServiceImpl.java
  30. 63 0
      src/main/java/com/backendsys/modules/crt/service/impl/CrtDramaProjectStoryboardServiceImpl.java
  31. 151 0
      src/main/java/com/backendsys/modules/crt/service/impl/CrtLoraStyleServiceImpl.java
  32. 1 1
      src/main/java/com/backendsys/modules/upload/controller/SysFileCategoryController.java
  33. 1 1
      src/main/java/com/backendsys/modules/upload/controller/SysFileController.java
  34. 1 1
      src/main/java/com/backendsys/modules/upload/service/impl/SysFileCategoryServiceImpl.java
  35. 45 0
      src/main/resources/mapper/crt/drama/CrtDramaProjectDao.xml
  36. 44 0
      src/main/resources/mapper/crt/drama/CrtLoraStyleDao.xml

+ 15 - 5
db/crt_drama_project.sql

@@ -10,15 +10,25 @@ CREATE TABLE `crt_drama_project` (
     `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT 'ID',
     `user_id` BIGINT NOT NULL COMMENT '用户ID',
     `project_name` VARCHAR(50) NOT NULL COMMENT '项目名称',
-    `crt_drama_lora_style_id` BIGINT COMMENT '风格LoRA ID',
-    `crt_drama_lora_character_ids` VARCHAR(10) COMMENT '人物LoRA ID (多个值使用逗号分隔)',
+    `drama_lora_style_id` BIGINT COMMENT '风格LoRA ID',
+    `drama_lora_character_ids` VARCHAR(10) COMMENT '人物LoRA ID (多个值使用逗号分隔)',
     `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_crt_drama_lora_style_id` (`crt_drama_lora_style_id`)
+    INDEX `idx_drama_lora_style_id` (`drama_lora_style_id`)
 ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='短剧创作-项目表';
 
-INSERT INTO crt_drama_project(user_id, project_name, crt_drama_lora_style_id, crt_drama_lora_character_ids) VALUES
+INSERT INTO crt_drama_project(user_id, project_name, drama_lora_style_id, drama_lora_character_ids) VALUES
     (1, '测试项目', null, null),
-    (1, '我的仙狐娘娘', 1, '1,2')
+    (1, '我的仙狐娘娘', 1, '1,2'),
+    (1, '数量测试项目3', null, null),
+    (1, '数量测试项目4', null, null),
+    (1, '数量测试项目5', null, null),
+    (1, '数量测试项目6', null, null),
+    (1, '数量测试项目7', null, null),
+    (1, '数量测试项目8', null, null),
+    (1, '数量测试项目9', null, null),
+    (1, '数量测试项目10', null, null),
+    (1, '数量测试项目11', null, null),
+    (1, '数量测试项目12', null, null)
 ;

+ 12 - 12
db/crt_drama_project_settings.sql

@@ -4,27 +4,27 @@ Source Database: backendsys
 Date: 2025/06/03 10:09:22
 */
 
-DROP TABLE IF EXISTS `crt_drama_project_settings`;
-CREATE TABLE `crt_drama_project_settings` (
+DROP TABLE IF EXISTS `drama_project_settings`;
+CREATE TABLE `drama_project_settings` (
     PRIMARY KEY (`id`),
     `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT 'ID',
-    `crt_drama_project_id` BIGINT NOT NULL COMMENT '项目ID',
-    `crt_drama_project_setting_type` INT NOT NULL COMMENT '项目配置类型 (1: 生图配置, 2: 生视频配置)',
+    `drama_project_id` BIGINT NOT NULL COMMENT '项目ID',
+    `drama_project_setting_type` INT NOT NULL COMMENT '项目配置类型 (1: 生图配置, 2: 生视频配置)',
     `aspect_ratio` VARCHAR(10) COMMENT '画面比例 (枚举)(16:9 - 1280*720, 9:16 - 720*1280, 1:1 - 1024*1024)',
-    `crt_model_id` BIGINT COMMENT '基础模型ID (固定值接口)(1: F.1-dev.safetensors)',
-    `crt_lora_style_id` BIGINT COMMENT '风格LoRA ID',
-    `crt_lora_style_strength` FLOAT COMMENT '风格强度 (默认值:1,范围:0~2.0,保留小数点后一位)',
-    INDEX `idx_crt_model_id` (`crt_model_id`),
-    INDEX `idx_crt_lora_style_id` (`crt_lora_style_id`),
-    INDEX `idx_crt_drama_project_id` (`crt_drama_project_id`)
+    `model_id` BIGINT COMMENT '基础模型ID (固定值接口)(1: F.1-dev.safetensors)',
+    `lora_style_id` BIGINT COMMENT '风格LoRA ID',
+    `lora_style_strength` FLOAT COMMENT '风格强度 (默认值:1,范围:0~2.0,保留小数点后一位)',
+    INDEX `idx_model_id` (`model_id`),
+    INDEX `idx_lora_style_id` (`lora_style_id`),
+    INDEX `idx_drama_project_id` (`drama_project_id`)
 ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='短剧创作-项目配置表';
 
 /*
- 当配置类型为生图配置时,aspect_ratio、crt_drama_base_model_id、crt_drama_lora_style_id、crt_drama_lora_style_strength 为必填项
+ 当配置类型为生图配置时,aspect_ratio、drama_base_model_id、drama_lora_style_id、drama_lora_style_strength 为必填项
  当配置类型为生视频配置时,aspect_ratio 为必填项
  */
 
-INSERT INTO crt_drama_project_settings(crt_drama_project_id, crt_drama_project_setting_type, aspect_ratio, crt_model_id, crt_lora_style_id, crt_lora_style_strength) VALUES
+INSERT INTO drama_project_settings(drama_project_id, drama_project_setting_type, aspect_ratio, model_id, lora_style_id, lora_style_strength) VALUES
     (1, 1, '16:9', 1, 1, 1),
     (1, 2, '16:9', null, null, null)
 ;

+ 6 - 5
db/crt_drama_project_storyboard.sql

@@ -10,7 +10,7 @@ CREATE TABLE `crt_drama_project_storyboard` (
     `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT 'ID',
     `user_id` BIGINT NOT NULL COMMENT '用户ID',
 
-    `crt_drama_project_id` BIGINT COMMENT '项目ID',
+    `drama_project_id` BIGINT NOT NULL COMMENT '项目ID',
     `episode_num` INT NOT NULL COMMENT '集数 (不超过999集)',
     `sort` INT NOT NULL COMMENT '排序',
 
@@ -18,7 +18,7 @@ CREATE TABLE `crt_drama_project_storyboard` (
     `story_framing` VARCHAR(500) COMMENT '景别',
     `story_scene` VARCHAR(500) COMMENT '场景',
     `story_weather_time` VARCHAR(500) COMMENT '天气/时间',
-    `crt_lora_figure_ids` VARCHAR(255) COMMENT '人物LoRA ID (创建时,跟随项目的人物LoRAID)(多个人物ID以逗号分隔)',
+    `lora_figure_ids` VARCHAR(255) COMMENT '人物LoRA ID (创建时,跟随项目的人物LoRAID)(多个人物ID以逗号分隔)',
 
     `param_image_count` INT DEFAULT '1' COMMENT '每次生成图片数量 (默认值:1,整数范围:1~4)',
     `param_prompt_weight` FLOAT DEFAULT '3.5' COMMENT '提示词引导系数 (默认值:3.5,小数点后一位,范围:1~30)',
@@ -40,8 +40,9 @@ CREATE TABLE `crt_drama_project_storyboard` (
     INDEX `idx_user_id` (`user_id`)
 ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='短剧创作-分镜表';
 
-INSERT INTO crt_drama_project_storyboard(user_id, crt_drama_project_id, episode_num, sort, story_prompt, story_framing, story_scene, story_weather_time,
-                                         crt_lora_figure_ids, text_to_image_prompt) VALUES
+INSERT INTO crt_drama_project_storyboard(user_id, drama_project_id, episode_num, sort, story_prompt, story_framing, story_scene, story_weather_time,
+                                         lora_figure_ids, text_to_image_prompt) VALUES
     (1, 1, 1, 2, null, null, null, null, '1,2', null),
-    (1, 1, 1, 1, '全景俯拍,跟镜柳王妃慢慢走向王府大门', '全景', '王府门口外景', '下雪的夜晚', '1,2', '漆黑的夜晚,大雪,光线昏暗,远景,高角度,从上面拍摄,宽阔的街道从左下延伸到右上,街道两旁的建筑是中国古代风格,街道尽头画面右上角的建筑比其他建筑高,仅有一个女人背对镜头走在街道上,穿着红色连帽斗篷,一袭纯红色的绸缎轻纱质感长裙,裙摆到脚踝,双足赤裸,红色连帽斗篷,女人的位置处在画面左上,画面右侧的屋檐上站着一只头部朝向女人小乌鸦,以中国古风动漫风格呈现')
+    (1, 1, 2, 1, '全景俯拍,跟镜柳王妃慢慢走向王府大门', '全景', '王府门口外景', '下雪的夜晚', '1,2', '漆黑的夜晚,大雪,光线昏暗,远景,高角度,从上面拍摄,宽阔的街道从左下延伸到右上,街道两旁的建筑是中国古代风格,街道尽头画面右上角的建筑比其他建筑高,仅有一个女人背对镜头走在街道上,穿着红色连帽斗篷,一袭纯红色的绸缎轻纱质感长裙,裙摆到脚踝,双足赤裸,红色连帽斗篷,女人的位置处在画面左上,画面右侧的屋檐上站着一只头部朝向女人小乌鸦,以中国古风动漫风格呈现'),
+    (1, 2, 10, 1, null, null, null, null, '1,2', null)
 ;

+ 2 - 2
db/crt_drama_task.sql

@@ -9,7 +9,7 @@ CREATE TABLE `crt_drama_task` (
     PRIMARY KEY (`id`),
     `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT 'ID',
     `user_id` BIGINT NOT NULL COMMENT '用户ID',
-    `crt_drama_project_id` BIGINT NOT NULL COMMENT '项目ID',
+    `drama_project_id` BIGINT NOT NULL COMMENT '项目ID',
     `task_id` VARCHAR(255) NOT NULL COMMENT '任务ID',
     `task_type` TINYINT NOT NULL COMMENT '任务类型 (1:图像, 2:视频)',
     `task_status` TINYINT DEFAULT '-1' COMMENT '任务状态 (-1:未开始, 1:进行中, 2:成功, 3:失败)',
@@ -18,7 +18,7 @@ CREATE TABLE `crt_drama_task` (
     `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_crt_drama_project_id` (`crt_drama_project_id`),
+    INDEX `idx_drama_project_id` (`drama_project_id`),
     INDEX `idx_task_id` (`task_id`)
 ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='短剧创作-生图任务表';
 

+ 8 - 4
db/crt_lora_style.sql

@@ -8,12 +8,16 @@ DROP TABLE IF EXISTS `crt_lora_style`;
 CREATE TABLE `crt_lora_style` (
     PRIMARY KEY (`id`),
     `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT 'ID',
+    `category_id` BIGINT NOT NULL COMMENT '风格分类ID',
     `name` VARCHAR(255) NOT NULL COMMENT '风格名称',
+    `thumb` VARCHAR(1000) COMMENT '风格缩略图',
     `lora_style_name` VARCHAR(255) NOT NULL COMMENT '风格LoRA名称',
-    `lora_style_path` VARCHAR(500) NOT NULL COMMENT '风格LoRA路径'
+    `lora_style_path` VARCHAR(500) NOT NULL COMMENT '风格LoRA路径',
+    `sort` INT DEFAULT '1' COMMENT '排序',
+    INDEX `idx_category_id` (`category_id`)
 ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='短剧创作-风格LoRA表';
 
-INSERT INTO crt_lora_style(id, name, lora_style_name, lora_style_path) VALUES
-    (1, 'Hyatsu梦幻宝石眼睛v2', 'hyatsu_gemstone_dream_eyes_v2', '/etc/ComfyUI/custom_nodes/xxx/hyatsu_gemstone_dream_eyes_v2.safetensors'),
-    (2, '日系漫画风', 'japanese_anime_style', '/etc/ComfyUI/custom_nodes/xxx/japanese_anime_style.safetensors')
+INSERT INTO crt_lora_style(id, category_id, name, thumb, lora_style_name, lora_style_path, sort) VALUES
+    (1, 1, 'Hyatsu梦幻宝石眼睛v2', '', 'hyatsu_gemstone_dream_eyes_v2', '/etc/ComfyUI/custom_nodes/xxx/hyatsu_gemstone_dream_eyes_v2.safetensors', 2),
+    (2, 1, '日系漫画风', '', 'japanese_anime_style', '/etc/ComfyUI/custom_nodes/xxx/japanese_anime_style.safetensors', 1)
 ;

+ 17 - 0
db/crt_lora_style_category.sql

@@ -0,0 +1,17 @@
+/**
+Source Server Version: 8.0.31
+Source Database: backendsys
+Date: 2025/06/03 10:09:22
+*/
+
+DROP TABLE IF EXISTS `crt_lora_style_category`;
+CREATE TABLE `crt_lora_style_category` (
+    PRIMARY KEY (`id`),
+    `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT 'ID',
+    `category_name` VARCHAR(255) NOT NULL COMMENT '风格分类名称'
+) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='短剧创作-风格分类表';
+
+INSERT INTO crt_lora_style_category(id, category_name) VALUES
+    (1, '动漫'),
+    (2, '写实')
+;

+ 21 - 0
db/crt_lora_style_collect.sql

@@ -0,0 +1,21 @@
+/**
+Source Server Version: 8.0.31
+Source Database: backendsys
+Date: 2025/06/03 10:09:22
+*/
+
+DROP TABLE IF EXISTS `crt_lora_style_collect`;
+CREATE TABLE `crt_lora_style_collect` (
+    PRIMARY KEY (`id`),
+    `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT 'ID',
+    `user_id` BIGINT NOT NULL COMMENT '用户ID',
+    `lora_style_id` BIGINT NOT NULL COMMENT '风格ID',
+    `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+    INDEX `idx_user_id` (`user_id`),
+    INDEX `idx_lora_style_id` (`lora_style_id`)
+) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='短剧创作-风格LoRA-用户收藏表';
+
+INSERT INTO crt_lora_style_collect(user_id, lora_style_id, create_time) VALUES
+    (1, 1, '2025-06-07 16:26:33'),
+    (1, 2, '2025-06-07 16:25:00')
+;

+ 10 - 3
db/sys_user_role_permission.sql

@@ -17,11 +17,11 @@ CREATE TABLE `sys_user_role_permission` (
 INSERT INTO sys_user_role_permission(id, parent_id, permission_name, sort) VALUES
     ('1', -1, '文件管理', null),
         ('1.1', '1', '文件管理', null),
-            ('1.1.1', '1.1', '查看文件 (全)', null),
+            ('1.1.1', '1.1', '查看文件 (全权限)', null),
             ('1.1.2', '1.1', '查看文件 (自己)', null),
             ('1.1.3', '1.1', '上传文件', null),
             ('1.1.4', '1.1', '编辑文件', null),
-            ('1.1.5', '1.1', '删除文件 (全)', null),
+            ('1.1.5', '1.1', '删除文件 (全权限)', null),
             ('1.1.6', '1.1', '删除文件 (自己)', null),
 
     ('2', -1, '创意中心', 2),
@@ -36,6 +36,13 @@ INSERT INTO sys_user_role_permission(id, parent_id, permission_name, sort) VALUE
     ('35', -1, 'AI模特', 7),
         ('35.1', '35', 'AI模特-运营权限', null),
 
+    ('36', -1, 'AI短剧创作', 8),
+        ('36.1', '36', 'AI短剧创作-项目管理', null),
+            ('36.1.1', '36.1', 'AI短剧创作-项目列表 (全权限)', null),
+            ('36.1.2', '36.1', 'AI短剧创作-项目列表 (自己)', null),
+
+
+
     ('3', -1, '系统用户管理', 900),
         ('3.1', '3', '系统用户列表 (在线的)', null),
         ('3.2', '3', '系统用户列表', null),
@@ -117,7 +124,7 @@ INSERT INTO sys_user_role_permission(id, parent_id, permission_name, sort) VALUE
             ('10.6.1', '10.6', '导航详情', null),
             ('10.6.2', '10.6', '创建导航', null),
             ('10.6.3', '10.6', '编辑导航', null),
-            ('10.6.4', '10.6', '删除导航', null),
+            ('10.6.4', '10.6', '删除导航', null)
 
     -- ('11', -1, '商品管理', null),
     --     ('11.1', '11', '商品列表', null),

+ 6 - 0
db/sys_user_role_permission_relation.sql

@@ -99,6 +99,12 @@ INSERT INTO sys_user_role_permission_relation(role_id, permission_id) VALUES
     (1, '35'),
         (1, '35.1'),
 
+    (1, '36'),
+        (1, '36.1'),
+            (1, '36.1.1'),
+            (1, '36.1.2'),
+
+
 
     (1, '100'),
         (1, '101'),

+ 1 - 0
src/main/java/com/backendsys/modules/common/config/security/utils/SecurityUtil.java

@@ -36,6 +36,7 @@ import java.util.List;
  * 权限注解
  * @PreAuthorize("@sr.hasPermission('3.2.1')")
  * @PreAuthorize("@sr.hasPermissions(T(java.util.Arrays).asList('3.2.1', '3.2.2'))")
+ * @PreAuthorize("@sr.hasPermissions(T(java.util.Arrays).asList('3.2.1', '3.2.2'), T(com.backendsys.modules.common.enums.MatchType).OR)")
  */
 @Service("sr")
 public class SecurityUtil {

+ 40 - 0
src/main/java/com/backendsys/modules/crt/controller/CrtDramaProjectController.java

@@ -0,0 +1,40 @@
+package com.backendsys.modules.crt.controller;
+
+import com.backendsys.modules.cms.article.entity.ArticleCategory;
+import com.backendsys.modules.common.config.security.utils.SecurityUtil;
+import com.backendsys.modules.common.utils.Result;
+import com.backendsys.modules.crt.entity.CrtDramaProject;
+import com.backendsys.modules.crt.service.CrtDramaProjectService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@Validated
+@RestController
+@Tag(name = "短剧创作-项目管理")
+public class CrtDramaProjectController {
+
+    @Autowired
+    private CrtDramaProjectService crtDramaProjectService;
+
+
+    @Operation(summary = "获取短剧创作-项目列表 (全权限)")
+    @PreAuthorize("@sr.hasPermission('36.1.1')")
+    @GetMapping("/api/crt/drama/getDramaProjectAllList")
+    public Result getDramaProjectAllList(@Validated CrtDramaProject crtDramaProject) {
+        return Result.success().put("data", crtDramaProjectService.selectCrtDramaProjectList(crtDramaProject));
+    }
+
+    @Operation(summary = "获取短剧创作-项目列表 (我的)")
+    @PreAuthorize("@sr.hasPermissions(T(java.util.Arrays).asList('36.1.1', '36.1.2'), T(com.backendsys.modules.common.enums.MatchType).OR)")
+    @GetMapping("/api/crt/drama/getDramaProjectList")
+    public Result getDramaProjectList(@Validated CrtDramaProject crtDramaProject) {
+        crtDramaProject.setUser_id(SecurityUtil.getUserId());
+        return Result.success().put("data", crtDramaProjectService.selectCrtDramaProjectList(crtDramaProject));
+    }
+
+}

+ 51 - 0
src/main/java/com/backendsys/modules/crt/controller/CrtDramaProjectStoryboardController.java

@@ -0,0 +1,51 @@
+package com.backendsys.modules.crt.controller;
+
+import com.backendsys.modules.common.config.security.utils.SecurityUtil;
+import com.backendsys.modules.common.utils.Result;
+import com.backendsys.modules.crt.entity.CrtDramaProject;
+import com.backendsys.modules.crt.service.CrtDramaProjectService;
+import com.backendsys.modules.crt.service.CrtDramaProjectStoryboardService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+@Validated
+@RestController
+@Tag(name = "短剧创作-项目管理-分镜管理")
+public class CrtDramaProjectStoryboardController {
+
+    @Autowired
+    private CrtDramaProjectStoryboardService crtDramaProjectStoryboardService;
+
+
+    // { drama_project_id }
+    @Operation(summary = "创建分镜")
+    @PostMapping("/api/crt/drama/createStoryboard")
+    public Result createStoryboard(@Validated(CrtDramaProject.CreateStoryboard.class) @RequestBody CrtDramaProject crtDramaProject) {
+        crtDramaProject.setUser_id(SecurityUtil.getUserId());
+        return Result.success().put("data", crtDramaProjectStoryboardService.createStoryboard(crtDramaProject));
+    }
+
+
+//    @Operation(summary = "获取短剧创作-项目列表 (全权限)")
+//    @PreAuthorize("@sr.hasPermission('36.1.1')")
+//    @GetMapping("/api/crt/drama/getDramaProjectAllList")
+//    public Result getDramaProjectAllList(@Validated CrtDramaProject crtDramaProject) {
+//        return Result.success().put("data", crtDramaProjectService.selectCrtDramaProjectList(crtDramaProject));
+//    }
+//
+//    @Operation(summary = "获取短剧创作-项目列表 (我的)")
+//    @PreAuthorize("@sr.hasPermissions(T(java.util.Arrays).asList('36.1.1', '36.1.2'), T(com.backendsys.modules.common.enums.MatchType).OR)")
+//    @GetMapping("/api/crt/drama/getDramaProjectList")
+//    public Result getDramaProjectList(@Validated CrtDramaProject crtDramaProject) {
+//        crtDramaProject.setUser_id(SecurityUtil.getUserId());
+//        return Result.success().put("data", crtDramaProjectService.selectCrtDramaProjectList(crtDramaProject));
+//    }
+
+}

+ 52 - 0
src/main/java/com/backendsys/modules/crt/controller/CrtLoraStyleController.java

@@ -0,0 +1,52 @@
+package com.backendsys.modules.crt.controller;
+
+import com.backendsys.modules.common.config.security.utils.SecurityUtil;
+import com.backendsys.modules.common.utils.Result;
+import com.backendsys.modules.crt.entity.CrtLoraStyle;
+import com.backendsys.modules.crt.entity.CrtLoraStyleCollect;
+import com.backendsys.modules.crt.service.CrtLoraStyleService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+@Validated
+@RestController
+@Tag(name = "短剧创作-风格LoRA")
+public class CrtLoraStyleController {
+
+    @Autowired
+    private CrtLoraStyleService crtLoraStyleService;
+
+    @Operation(summary = "获取短剧创作-风格LoRA列表")
+    @GetMapping("/api/crt/drama/getLoraStyleList")
+    public Result getLoraStyleList(@Validated CrtLoraStyle crtLoraStyle) {
+        return Result.success().put("data", crtLoraStyleService.selectCrtLoraStyleList(crtLoraStyle));
+    }
+
+    @Operation(summary = "获取短剧创作-风格分类列表")
+    @GetMapping("/api/crt/drama/getLoraStyleCategoryList")
+    public Result getLoraStyleCategoryList() {
+        return Result.success().put("data", crtLoraStyleService.selectCrtLoraStyleCategoryList());
+    }
+
+    @Operation(summary = "获取短剧创作-风格LoRA列表-我收藏的")
+    @GetMapping("/api/crt/drama/getLoraStyleListByCollect")
+    public Result getLoraStyleListByCollect(@Validated CrtLoraStyle crtLoraStyle) {
+        crtLoraStyle.setUser_id(SecurityUtil.getUserId());
+        return Result.success().put("data", crtLoraStyleService.selectCrtLoraStyleListByCollect(crtLoraStyle));
+    }
+
+    @Operation(summary = "获取短剧创作-风格LoRA列表-加入/取消收藏")
+    @PostMapping("/api/crt/drama/setLoraStyleCollect")
+    public Result setLoraStyleCollect(@Validated(CrtLoraStyleCollect.Collect.class) @RequestBody CrtLoraStyleCollect crtLoraStyleCollect) {
+        crtLoraStyleCollect.setUser_id(SecurityUtil.getUserId());
+        return Result.success().put("data", crtLoraStyleService.setLoraStyleCollect(crtLoraStyleCollect));
+    }
+
+}

+ 15 - 0
src/main/java/com/backendsys/modules/crt/dao/CrtDramaProjectDao.java

@@ -0,0 +1,15 @@
+package com.backendsys.modules.crt.dao;
+
+import com.backendsys.modules.crt.entity.CrtDramaProject;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+import java.util.Map;
+
+@Mapper
+public interface CrtDramaProjectDao extends BaseMapper<CrtDramaProject> {
+
+    List<Map<String, Object>> selectCrtDramaProjectList(CrtDramaProject crtDramaProject);
+
+}

+ 9 - 0
src/main/java/com/backendsys/modules/crt/dao/CrtDramaProjectStoryboardDao.java

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

+ 9 - 0
src/main/java/com/backendsys/modules/crt/dao/CrtLoraStyleCategoryDao.java

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

+ 9 - 0
src/main/java/com/backendsys/modules/crt/dao/CrtLoraStyleCollectDao.java

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

+ 15 - 0
src/main/java/com/backendsys/modules/crt/dao/CrtLoraStyleDao.java

@@ -0,0 +1,15 @@
+package com.backendsys.modules.crt.dao;
+
+import com.backendsys.modules.crt.entity.CrtLoraStyle;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+import java.util.Map;
+
+@Mapper
+public interface CrtLoraStyleDao extends BaseMapper<CrtLoraStyle> {
+
+    List<Map<String, Object>> selectCrtLoraStyleList(CrtLoraStyle crtLoraStyle);
+
+}

+ 16 - 2
src/main/java/com/backendsys/modules/crt/entity/CrtDramaProject.java

@@ -4,7 +4,9 @@ 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 jakarta.validation.constraints.Max;
 import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
 import jakarta.validation.constraints.Size;
 import lombok.Data;
 import java.util.List;
@@ -15,21 +17,33 @@ public class CrtDramaProject {
 
     public static interface Detail{}
     public static interface Create{}
+    public static interface CreateStoryboard{}
     public static interface Update{}
     public static interface Delete{}
 
     @TableId(type = IdType.AUTO)
+
     private Long id;
+
+    @TableField(exist = false)
+    @NotNull(message = "项目ID不能为空", groups = { CreateStoryboard.class })
+    private Long drama_project_id;
+
     private Long user_id;
     @NotEmpty(message = "项目名称不能为空", groups = { Create.class, Update.class })
     @Size(max = 50, message = "项目名称长度不能超过50个字符", groups = { Create.class, Update.class })
     private String project_name;
 
+    @TableField(exist = false)
+    @NotNull(message = "集数不能为空", groups = { CreateStoryboard.class })
+    @Max(value = 999, message = "集数长度不超过 {value}", groups = { CreateStoryboard.class })
+    private Integer episode_num;
+
     @TableField(exist = false)
     private List<Integer> storyboard_episode_nums;  // 集数 (子查询)
 
-    private Long crt_drama_lora_style_id;
-    private String crt_drama_lora_character_ids;
+    private Long drama_lora_style_id;
+    private String drama_lora_character_ids;
     private String create_time;
     private String update_time;
 

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

@@ -13,11 +13,11 @@ public class CrtDramaProjectSettings {
 
     @TableId(type = IdType.AUTO)
     private Long id;
-    private Long crt_drama_project_id;
-    private Integer crt_drama_project_setting_type;
+    private Long drama_project_id;
+    private Integer drama_project_setting_type;
     private String aspect_ratio;
-    private Long crt_model_id;
-    private Long crt_lora_style_id;
-    private Float crt_lora_style_strength;
+    private Long model_id;
+    private Long lora_style_id;
+    private Float lora_style_strength;
 
 }

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

@@ -18,7 +18,7 @@ public class CrtDramaProjectStoryboard {
     private Long id;
 
     private Long user_id;
-    private Long crt_drama_project_id;              // 项目ID
+    private Long drama_project_id;                  // 项目ID
     private Integer episode_num;                    // 集数 (不超过999集)
     private Integer sort;                           // 排序
 
@@ -26,7 +26,7 @@ public class CrtDramaProjectStoryboard {
     private String story_framing;                   // 景别
     private String story_scene;                     // 场景
     private String story_weather_time;              // 天气/时间
-    private String crt_lora_figure_ids;             // 人物LoRA ID (创建时,跟随项目的人物LoRAID)(多个人物ID以逗号分隔)
+    private String lora_figure_ids;                 // 人物LoRA ID (创建时,跟随项目的人物LoRAID)(多个人物ID以逗号分隔)
 
     private Integer param_image_count;              // 每次生成图片数量 (默认值:1,整数范围:1~4)
     private Float param_prompt_weight;              // 提示词引导系数 (默认值:3.5,小数点后一位,范围:1~30)
@@ -40,8 +40,8 @@ public class CrtDramaProjectStoryboard {
     private String param_video_reference_images;    // 参考图 (1~4张)(多图以逗号分隔)
     private String image_to_video_prompt;           // 图生视频提示词 (生视频时必填)
 
-    private Integer generate_image_status;           // 生图状态 (-1:未生图, 1:生成中, 2:已生图)
-    private Integer generate_video_status;           // 生视频状态 (-1:未生视频, 1:生成中, 2:已生视频)
+    private Integer generate_image_status;          // 生图状态 (-1:未生图, 1:生成中, 2:已生图)
+    private Integer generate_video_status;          // 生视频状态 (-1:未生视频, 1:生成中, 2:已生视频)
 
     private String create_time;
     private String update_time;

+ 1 - 1
src/main/java/com/backendsys/modules/crt/entity/CrtDramaTask.java

@@ -12,7 +12,7 @@ public class CrtDramaTask {
     @TableId(type = IdType.AUTO)
     private Long id;
     private Long user_id;                       // 用户ID
-    private Long crt_drama_project_id;          // 项目ID
+    private Long drama_project_id;          // 项目ID
     private String task_id;                     // 任务ID
     private Integer task_type;                  // 任务类型 (1:图像, 2:视频)
     private Integer task_status;                // 任务状态 (-1:未开始, 1:进行中, 2:成功, 3:失败)

+ 12 - 0
src/main/java/com/backendsys/modules/crt/entity/CrtLoraStyle.java

@@ -1,6 +1,7 @@
 package com.backendsys.modules.crt.entity;
 
 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 lombok.Data;
@@ -11,7 +12,18 @@ public class CrtLoraStyle {
 
     @TableId(type = IdType.AUTO)
     private Long id;
+    @TableField(exist = false)
+    private Long user_id;
+    private Long category_id;
+    @TableField(exist = false)
+    private String category_name;
     private String name;                   // 风格名称
+    private String thumb;                  // 风格缩略图
     private String lora_style_name;        // 风格LoRA名称
     private String lora_style_path;        // 风格LoRA路径
+
+    @TableField(exist = false)
+    private Integer is_collect;            // 收藏状态 (-1取消收藏, 1加入收藏)
+
+    private Integer sort;                  // 排序
 }

+ 15 - 0
src/main/java/com/backendsys/modules/crt/entity/CrtLoraStyleCategory.java

@@ -0,0 +1,15 @@
+package com.backendsys.modules.crt.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+@Data
+@TableName("crt_lora_style_category")
+public class CrtLoraStyleCategory {
+
+    @TableId(type = IdType.AUTO)
+    private Long id;
+    private String category_name;                   // 风格分类名称
+}

+ 30 - 0
src/main/java/com/backendsys/modules/crt/entity/CrtLoraStyleCollect.java

@@ -0,0 +1,30 @@
+package com.backendsys.modules.crt.entity;
+
+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 jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+@Data
+@TableName("crt_lora_style_collect")
+public class CrtLoraStyleCollect {
+
+    public static interface Collect{}
+
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    private Long user_id;
+
+    @NotNull(message = "lora_style_id 不能为空", groups = { Collect.class })
+    private Long lora_style_id;
+
+    @TableField(exist = false)
+    @NotNull(message = "收藏状态不能为空", groups = { Collect.class })
+    @RangeArray(message="收藏状态取值有误,范围应是(-1取消收藏, 1加入收藏)", value = {"-1", "1"}, groups = { Collect.class })
+    private Integer is_collect;
+    private String create_time;
+}

+ 12 - 0
src/main/java/com/backendsys/modules/crt/service/CrtDramaProjectService.java

@@ -0,0 +1,12 @@
+package com.backendsys.modules.crt.service;
+
+import com.backendsys.modules.cms.article.entity.ArticleCategory;
+import com.backendsys.modules.crt.entity.CrtDramaProject;
+import com.backendsys.utils.response.PageEntity;
+
+public interface CrtDramaProjectService {
+
+    // 获取短剧创作-项目列表
+    PageEntity selectCrtDramaProjectList(CrtDramaProject crtDramaProject);
+
+}

+ 13 - 0
src/main/java/com/backendsys/modules/crt/service/CrtDramaProjectStoryboardService.java

@@ -0,0 +1,13 @@
+package com.backendsys.modules.crt.service;
+
+
+import com.backendsys.modules.crt.entity.CrtDramaProject;
+
+import java.util.Map;
+
+public interface CrtDramaProjectStoryboardService {
+
+    // 创建分镜
+    Map<String, Object> createStoryboard(CrtDramaProject crtDramaProject);
+
+}

+ 25 - 0
src/main/java/com/backendsys/modules/crt/service/CrtLoraStyleService.java

@@ -0,0 +1,25 @@
+package com.backendsys.modules.crt.service;
+
+import com.backendsys.modules.crt.entity.CrtLoraStyle;
+import com.backendsys.modules.crt.entity.CrtLoraStyleCategory;
+import com.backendsys.modules.crt.entity.CrtLoraStyleCollect;
+import com.backendsys.utils.response.PageEntity;
+
+import java.util.List;
+import java.util.Map;
+
+public interface CrtLoraStyleService {
+
+    // 获取短剧创作-风格LoRA列表
+    PageEntity selectCrtLoraStyleList(CrtLoraStyle crtLoraStyle);
+
+    // 获取短剧创作-风格分类列表
+    List<CrtLoraStyleCategory> selectCrtLoraStyleCategoryList();
+
+    // 获取短剧创作-风格LoRA列表-用户收藏的
+    PageEntity selectCrtLoraStyleListByCollect(CrtLoraStyle crtLoraStyle);
+
+    // 获取短剧创作-风格LoRA列表-加入/取消收藏
+    Map<String, Object> setLoraStyleCollect(CrtLoraStyleCollect crtLoraStyleCollect);
+
+}

+ 30 - 0
src/main/java/com/backendsys/modules/crt/service/impl/CrtDramaProjectServiceImpl.java

@@ -0,0 +1,30 @@
+package com.backendsys.modules.crt.service.impl;
+
+import com.backendsys.modules.cms.article.entity.ArticleCategory;
+import com.backendsys.modules.crt.dao.CrtDramaProjectDao;
+import com.backendsys.modules.crt.entity.CrtDramaProject;
+import com.backendsys.modules.crt.service.CrtDramaProjectService;
+import com.backendsys.utils.response.PageEntity;
+import com.backendsys.utils.response.PageInfoResult;
+import com.backendsys.utils.v2.PageUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Map;
+
+@Service
+public class CrtDramaProjectServiceImpl implements CrtDramaProjectService {
+
+    @Autowired
+    private CrtDramaProjectDao crtDramaProjectDao;
+
+    // 获取短剧创作-项目列表
+    @Override
+    public PageEntity selectCrtDramaProjectList(CrtDramaProject crtDramaProject) {
+        PageUtils.startPage();  // 分页
+        List<Map<String, Object>> list = crtDramaProjectDao.selectCrtDramaProjectList(crtDramaProject);
+        return new PageInfoResult(list).toEntity();
+    }
+
+}

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

@@ -0,0 +1,63 @@
+package com.backendsys.modules.crt.service.impl;
+
+import com.backendsys.exception.CustException;
+import com.backendsys.modules.crt.dao.CrtDramaProjectDao;
+import com.backendsys.modules.crt.dao.CrtDramaProjectStoryboardDao;
+import com.backendsys.modules.crt.entity.CrtDramaProject;
+import com.backendsys.modules.crt.entity.CrtDramaProjectStoryboard;
+import com.backendsys.modules.crt.service.CrtDramaProjectStoryboardService;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+@Service
+public class CrtDramaProjectStoryboardServiceImpl implements CrtDramaProjectStoryboardService {
+
+    @Autowired
+    private CrtDramaProjectDao crtDramaProjectDao;
+    @Autowired
+    private CrtDramaProjectStoryboardDao crtDramaProjectStoryboardDao;
+
+    /**
+     * 创建分镜
+     */
+    @Override
+    public Map<String, Object> createStoryboard(CrtDramaProject crtDramaProject) {
+
+        Long user_id = crtDramaProject.getUser_id();
+        Long drama_project_id = crtDramaProject.getDrama_project_id();
+        Integer episode_num = crtDramaProject.getEpisode_num();
+        Integer sort = 1;
+
+        // 判断 项目 是否存在
+        LambdaQueryWrapper<CrtDramaProject> wrapperDramaProject = new LambdaQueryWrapper<>();
+        wrapperDramaProject.eq(CrtDramaProject::getId, drama_project_id);
+        Boolean is_exist_project = crtDramaProjectDao.exists(wrapperDramaProject);
+        if (!is_exist_project) throw new CustException("项目不存在");
+
+        // 判断 (项目ID + 集数) 是否存在,如果存在则不能创建
+        LambdaQueryWrapper<CrtDramaProjectStoryboard> wrapperStoryboard = new LambdaQueryWrapper<>();
+        wrapperStoryboard.eq(CrtDramaProjectStoryboard::getDrama_project_id, drama_project_id);
+        wrapperStoryboard.eq(CrtDramaProjectStoryboard::getEpisode_num, episode_num);
+        Boolean is_exist_storyboard = crtDramaProjectStoryboardDao.exists(wrapperStoryboard);
+        if (is_exist_storyboard) throw new CustException("该项目集数已存在,请勿重复创建");
+
+        // [DB] 创建分镜
+        CrtDramaProjectStoryboard entity = new CrtDramaProjectStoryboard();
+        entity.setUser_id(user_id);
+        entity.setDrama_project_id(drama_project_id);
+        entity.setEpisode_num(episode_num);
+        entity.setSort(sort);
+        crtDramaProjectStoryboardDao.insert(entity);
+
+        Map<String, Object> resp = new LinkedHashMap<>();
+        resp.put("drama_project_id", drama_project_id);
+        resp.put("drama_project_storyboard_id", entity.getId());
+        resp.put("drama_project_storyboard_episode_num", episode_num);
+        return resp;
+    }
+
+}

+ 151 - 0
src/main/java/com/backendsys/modules/crt/service/impl/CrtLoraStyleServiceImpl.java

@@ -0,0 +1,151 @@
+package com.backendsys.modules.crt.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.convert.Convert;
+import com.backendsys.exception.CustException;
+import com.backendsys.modules.common.config.security.utils.SecurityUtil;
+import com.backendsys.modules.crt.dao.CrtLoraStyleCategoryDao;
+import com.backendsys.modules.crt.dao.CrtLoraStyleCollectDao;
+import com.backendsys.modules.crt.dao.CrtLoraStyleDao;
+import com.backendsys.modules.crt.entity.CrtLoraStyle;
+import com.backendsys.modules.crt.entity.CrtLoraStyleCategory;
+import com.backendsys.modules.crt.entity.CrtLoraStyleCollect;
+import com.backendsys.modules.crt.service.CrtLoraStyleService;
+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;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@Service
+public class CrtLoraStyleServiceImpl implements CrtLoraStyleService {
+
+    @Autowired
+    private CrtLoraStyleDao crtLoraStyleDao;
+    @Autowired
+    private CrtLoraStyleCollectDao crtLoraStyleCollectDao;
+    @Autowired
+    private CrtLoraStyleCategoryDao crtLoraStyleCategoryDao;
+
+    /**
+     * 获取短剧创作-风格LoRA列表
+     */
+    @Override
+    public PageEntity selectCrtLoraStyleList(CrtLoraStyle crtLoraStyle) {
+        PageUtils.startPage();  // 分页
+
+        List<Map<String, Object>> list = crtLoraStyleDao.selectCrtLoraStyleList(crtLoraStyle);
+        if (!list.isEmpty()) {
+
+            // 查询风格LoRA-当前用户的收藏状态,将收藏状态添加到 list 中
+            LambdaQueryWrapper<CrtLoraStyleCollect> wrapperCollect = new LambdaQueryWrapper<>();
+            wrapperCollect.eq(CrtLoraStyleCollect::getUser_id, SecurityUtil.getUserId());
+            List<CrtLoraStyleCollect> collectList = crtLoraStyleCollectDao.selectList(wrapperCollect);
+            List<Long> collect_lora_style_ids = collectList.stream().map(item -> item.getLora_style_id()).collect(Collectors.toList());
+
+            // 将收藏状态添加到 list 中
+            list = list.stream().map(item -> {
+                item.put("is_collect", (collect_lora_style_ids.contains(Convert.toLong(item.get("id")))) ? 1 : -1);
+                return item;
+            }).collect(Collectors.toList());
+
+        }
+        return new PageInfoResult(list).toEntity();
+    }
+
+    /**
+     * 获取短剧创作-风格分类列表
+     */
+    @Override
+    public List<CrtLoraStyleCategory> selectCrtLoraStyleCategoryList() {
+        PageUtils.startPage();  // 分页
+        return crtLoraStyleCategoryDao.selectList(null);
+    }
+
+    /**
+     * 获取短剧创作-风格LoRA列表-用户收藏的
+     */
+    @Override
+    public PageEntity selectCrtLoraStyleListByCollect(CrtLoraStyle crtLoraStyle) {
+
+        // 查询当前用户,已经收藏的风格ID集合 (按创建时间倒序)
+        LambdaQueryWrapper<CrtLoraStyleCollect> wrapperCollect = new LambdaQueryWrapper<>();
+        wrapperCollect.eq(CrtLoraStyleCollect::getUser_id, crtLoraStyle.getUser_id());
+        wrapperCollect.orderByDesc(CrtLoraStyleCollect::getCreate_time);
+        List<CrtLoraStyleCollect> crtLoraStyleCollectList = crtLoraStyleCollectDao.selectList(wrapperCollect);
+
+        PageUtils.startPage();  // 分页
+
+        // 根据ID集合,查询风格LoRA列表
+        List<CrtLoraStyle> list = new ArrayList<>();
+        if (!crtLoraStyleCollectList.isEmpty()) {
+
+            // 获得已经收藏的风格LoRA ID集合
+            List<Long> collect_lora_style_ids = crtLoraStyleCollectList.stream()
+                .map(CrtLoraStyleCollect::getLora_style_id)
+                .collect(Collectors.toList());
+
+            LambdaQueryWrapper<CrtLoraStyle> wrapper = new LambdaQueryWrapper<>();
+            wrapper.in(CrtLoraStyle::getId, collect_lora_style_ids);
+            if (!crtLoraStyle.getName().isEmpty()) wrapper.like(CrtLoraStyle::getName, crtLoraStyle.getName());
+            if (crtLoraStyle.getCategory_id() != null) wrapper.eq(CrtLoraStyle::getCategory_id, crtLoraStyle.getCategory_id());
+
+            // [DB] 查询风格LoRA列表 (已经收藏的
+            list = crtLoraStyleDao.selectList(wrapper);
+
+            // 按照 lora_style_ids 的顺序 (按创建时间倒序) 对 list 进行重新排序
+            CollUtil.sort(list, Comparator.comparingInt(item -> collect_lora_style_ids.indexOf(item.getId())));
+
+            list = list.stream()
+                .map(item -> {
+                    item.setUser_id(crtLoraStyle.getUser_id());
+                    item.setIs_collect(1);
+                    return item;
+                }).collect(Collectors.toList());
+        }
+        return new PageInfoResult(list).toEntity();
+    }
+
+    /**
+     * 获取短剧创作-风格LoRA列表-加入/取消收藏
+     */
+    @Override
+    public Map<String, Object> setLoraStyleCollect(CrtLoraStyleCollect crtLoraStyleCollect) {
+
+        // 是否收藏 (-1取消收藏, 1加入收藏)
+        Integer is_collect = crtLoraStyleCollect.getIs_collect();
+        Long lora_style_id = crtLoraStyleCollect.getLora_style_id();
+
+        // 查询当前用户,是否已经收藏过该风格
+        LambdaQueryWrapper<CrtLoraStyleCollect> wrapperCollect = new LambdaQueryWrapper<>();
+        wrapperCollect.eq(CrtLoraStyleCollect::getUser_id, crtLoraStyleCollect.getUser_id());
+        wrapperCollect.eq(CrtLoraStyleCollect::getLora_style_id, lora_style_id);
+
+        if (is_collect == 1) {
+            // 如果已经收藏过,则不变
+            CrtLoraStyleCollect detail = crtLoraStyleCollectDao.selectOne(wrapperCollect);
+            if (detail == null) {
+
+                // [DB] 判断风格LoRA是否存在
+                Boolean is_exist = crtLoraStyleDao.exists(new LambdaQueryWrapper<CrtLoraStyle>().eq(CrtLoraStyle::getId, lora_style_id));
+                if (!is_exist) throw new CustException("风格LoRA不存在");
+
+                // [DB] 加入收藏
+                crtLoraStyleCollectDao.insert(crtLoraStyleCollect);
+            }
+        } else {
+            // [DB] 取消收藏
+            crtLoraStyleCollectDao.delete(wrapperCollect);
+        }
+
+        return Map.of("lora_style_id", crtLoraStyleCollect.getLora_style_id());
+    }
+
+}

+ 1 - 1
src/main/java/com/backendsys/modules/upload/controller/SysFileCategoryController.java

@@ -26,7 +26,7 @@ public class SysFileCategoryController {
     private SysFileCategoryService sysFileCategoryService;
 
     /** 没必要 */
-//    @Operation(summary = "获取文件分类列表 (全)")
+//    @Operation(summary = "获取文件分类列表 (全权限)")
 //    @GetMapping("/api/upload/getUploadFileCategoryAllList")
 //    public Result getUploadFileCategoryAllList(@Validated SysFileCategory sysFileCategory) {
 //        return Result.success().put("data", sysFileCategoryService.selectUploadFileCategoryList(sysFileCategory));

+ 1 - 1
src/main/java/com/backendsys/modules/upload/controller/SysFileController.java

@@ -40,7 +40,7 @@ public class SysFileController {
      * 获取上传文件列表
      * - 缩略图 (?imageView2/1/w/100/h/100/q/60)
      */
-    @Operation(summary = "获取文件列表 (全)")
+    @Operation(summary = "获取文件列表 (全权限)")
     @PreAuthorize("@sr.hasPermission('1.1.1')")
     @GetMapping("/api/upload/getUploadFileAllList")
     public Result getUploadFileAllList(@Validated SysFile sysFile) {

+ 1 - 1
src/main/java/com/backendsys/modules/upload/service/impl/SysFileCategoryServiceImpl.java

@@ -36,7 +36,7 @@ public class SysFileCategoryServiceImpl implements SysFileCategoryService {
     @Override
     public Map<String, Object> selectUploadFileCategoryList(SysFileCategory sysFileCategory) {
 
-        // [DB] 获得文件分类列表(全部)
+        // [DB] 获得文件分类列表
         List<Map<String, Object>> list = sysFileCategoryDao.selectUploadFileCategoryList(sysFileCategory);
         // [DB] 获得文件总数量
         Long all_file_list_total = sysFileDao.selectCount(new LambdaQueryWrapper<SysFile>().eq(SysFile::getUser_id, sysFileCategory.getUser_id()));

+ 45 - 0
src/main/resources/mapper/crt/drama/CrtDramaProjectDao.xml

@@ -0,0 +1,45 @@
+<?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.crt.dao.CrtDramaProjectDao">
+
+    <sql id="includeCrtDramaProject">
+        p.id,
+        p.user_id,
+        p.project_name,
+        COALESCE(p.drama_lora_style_id, '') drama_lora_style_id,
+        COALESCE(p.drama_lora_character_ids, '') drama_lora_character_ids,
+        p.create_time,
+        p.update_time
+    </sql>
+
+    <resultMap id="resultMapCrtDramaProject" type="java.util.LinkedHashMap">
+        <id property="id" column="id" jdbcType="BIGINT" />
+        <result property="user_id" column="user_id" javaType="java.lang.Long" />
+        <result property="project_name" column="project_name" />
+        <result property="storyboard_episode_nums" column="storyboard_episode_nums" javaType="java.util.List"
+                jdbcType="VARCHAR" typeHandler="com.backendsys.config.Mybatis.handler.StringToListTypeHandler" />
+        <result property="drama_lora_style_id" column="drama_lora_style_id" javaType="java.lang.Long" />
+        <result property="drama_lora_character_ids" column="drama_lora_character_ids" />
+        <result property="create_time" column="create_time" />
+        <result property="update_time" column="update_time" />
+    </resultMap>
+
+    <!-- 查 列表 -->
+    <select id="selectCrtDramaProjectList" resultMap="resultMapCrtDramaProject">
+        SELECT
+            <include refid="includeCrtDramaProject" />,
+            GROUP_CONCAT(ps.episode_num ORDER BY ps.episode_num) AS storyboard_episode_nums
+        FROM crt_drama_project p
+        LEFT JOIN crt_drama_project_storyboard ps ON p.id = ps.drama_project_id
+        <where>
+            <if test="user_id != null and user_id != ''">
+                AND p.user_id = #{user_id}
+            </if>
+            <if test="project_name != null and project_name != ''">
+                AND p.project_name LIKE CONCAT('%', #{project_name}, '%')
+            </if>
+        </where>
+        GROUP BY p.id
+    </select>
+
+</mapper>

+ 44 - 0
src/main/resources/mapper/crt/drama/CrtLoraStyleDao.xml

@@ -0,0 +1,44 @@
+<?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.crt.dao.CrtLoraStyleDao">
+
+    <sql id="includeCrtLoraStyle">
+        s.id,
+        s.category_id,
+        COALESCE(sc.category_name, '') category_name,
+        s.name,
+        COALESCE(s.thumb, '') thumb,
+        s.lora_style_name,
+        s.lora_style_path,
+        s.sort
+    </sql>
+
+    <resultMap id="resultMapCrtLoraStyle" type="java.util.LinkedHashMap">
+        <id property="id" column="id" jdbcType="BIGINT" />
+        <result property="category_id" column="category_id" javaType="java.lang.Long" />
+        <result property="category_name" column="category_name" />
+        <result property="name" column="name" />
+        <result property="thumb" column="thumb" />
+        <result property="lora_style_name" column="lora_style_name" />
+        <result property="lora_style_path" column="lora_style_path" />
+        <result property="sort" column="sort" javaType="java.lang.Integer" />
+    </resultMap>
+
+    <!-- 查 列表 -->
+    <select id="selectCrtLoraStyleList" resultMap="resultMapCrtLoraStyle">
+        SELECT
+            <include refid="includeCrtLoraStyle" />
+        FROM crt_lora_style s
+        LEFT JOIN crt_lora_style_category sc ON s.category_id = sc.id
+        <where>
+            <if test="category_id != null and category_id != ''">
+                AND s.category_id = #{category_id}
+            </if>
+            <if test="name != null and name != ''">
+                AND s.name LIKE CONCAT('%', #{name}, '%')
+            </if>
+        </where>
+        ORDER BY s.sort DESC
+    </select>
+
+</mapper>