Browse Source

完成风格LoRA(加入/取消收藏)接口

tsurumure 3 tháng trước cách đây
mục cha
commit
61f94b6462

+ 4 - 3
db/crt_lora_style.sql

@@ -13,10 +13,11 @@ CREATE TABLE `crt_lora_style` (
     `thumb` VARCHAR(1000) COMMENT '风格缩略图',
     `lora_style_name` VARCHAR(255) 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, category_id, name, thumb, lora_style_name, lora_style_path) VALUES
-    (1, 1, 'Hyatsu梦幻宝石眼睛v2', '', 'hyatsu_gemstone_dream_eyes_v2', '/etc/ComfyUI/custom_nodes/xxx/hyatsu_gemstone_dream_eyes_v2.safetensors'),
-    (2, 1, '日系漫画风', '', '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)
 ;

+ 6 - 3
db/crt_lora_style_collect.sql

@@ -6,13 +6,16 @@ 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) VALUES
-    (1, 1),
-    (1, 2)
+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')
 ;

+ 9 - 1
src/main/java/com/backendsys/modules/crt/controller/CrtLoraStyleController.java

@@ -3,6 +3,7 @@ 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;
@@ -10,6 +11,8 @@ 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
@@ -39,6 +42,11 @@ public class CrtLoraStyleController {
         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));
+    }
 
 }

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

@@ -15,7 +15,15 @@ public class CrtLoraStyle {
     @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;                  // 排序
 }

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

@@ -1,13 +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;
 }

+ 7 - 2
src/main/java/com/backendsys/modules/crt/service/CrtLoraStyleService.java

@@ -2,19 +2,24 @@ 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);
 
-    // 获取短剧创作-风格分类列表
-    List<CrtLoraStyleCategory> selectCrtLoraStyleCategoryList();
+    // 获取短剧创作-风格LoRA列表-加入/取消收藏
+    Map<String, Object> setLoraStyleCollect(CrtLoraStyleCollect crtLoraStyleCollect);
 
 }

+ 78 - 12
src/main/java/com/backendsys/modules/crt/service/impl/CrtLoraStyleServiceImpl.java

@@ -1,5 +1,9 @@
 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;
@@ -15,6 +19,7 @@ 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;
@@ -35,19 +40,45 @@ public class CrtLoraStyleServiceImpl implements CrtLoraStyleService {
     @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集合
+        // 查询当前用户,已经收藏的风格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();  // 分页
@@ -56,30 +87,65 @@ public class CrtLoraStyleServiceImpl implements CrtLoraStyleService {
         List<CrtLoraStyle> list = new ArrayList<>();
         if (!crtLoraStyleCollectList.isEmpty()) {
 
-            LambdaQueryWrapper<CrtLoraStyle> wrapper = new LambdaQueryWrapper<>();
-            List<Long> lora_style_ids = crtLoraStyleCollectList.stream()
+            // 获得已经收藏的风格LoRA ID集合
+            List<Long> collect_lora_style_ids = crtLoraStyleCollectList.stream()
                 .map(CrtLoraStyleCollect::getLora_style_id)
                 .collect(Collectors.toList());
-            wrapper.in(CrtLoraStyle::getId, lora_style_ids);
+
+            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);
-            list = list.stream().map(item -> {
-                item.setUser_id(crtLoraStyle.getUser_id());
-                return item;
-            }).collect(Collectors.toList());
+
+            // 按照 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 List<CrtLoraStyleCategory> selectCrtLoraStyleCategoryList() {
-        PageUtils.startPage();  // 分页
-        return crtLoraStyleCategoryDao.selectList(null);
+    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());
     }
 
 }

+ 4 - 1
src/main/resources/mapper/crt/drama/CrtLoraStyleDao.xml

@@ -9,7 +9,8 @@
         s.name,
         COALESCE(s.thumb, '') thumb,
         s.lora_style_name,
-        s.lora_style_path
+        s.lora_style_path,
+        s.sort
     </sql>
 
     <resultMap id="resultMapCrtLoraStyle" type="java.util.LinkedHashMap">
@@ -20,6 +21,7 @@
         <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>
 
     <!-- 查 列表 -->
@@ -36,6 +38,7 @@
                 AND s.name LIKE CONCAT('%', #{name}, '%')
             </if>
         </where>
+        ORDER BY s.sort DESC
     </select>
 
 </mapper>