Commit b8bae97016d64a2a712053ff7d555b61370e4e89

Authored by YunaiV
1 parent ec1376f4

【功能新增】AI:图片管理

Showing 13 changed files with 155 additions and 34 deletions
yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/enums/image/AiImageStatusEnum.java
@@ -13,8 +13,8 @@ import lombok.Getter; @@ -13,8 +13,8 @@ import lombok.Getter;
13 public enum AiImageStatusEnum { 13 public enum AiImageStatusEnum {
14 14
15 IN_PROGRESS(10, "进行中"), 15 IN_PROGRESS(10, "进行中"),
16 - SUCCESS(20, "完成"),  
17 - FAIL(30, "失败"); 16 + SUCCESS(20, "已完成"),
  17 + FAIL(30, "已失败");
18 18
19 /** 19 /**
20 * 状态 20 * 状态
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/image/AiImageController.java
@@ -7,7 +7,9 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam; @@ -7,7 +7,9 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam;
7 import cn.iocoder.yudao.framework.common.pojo.PageResult; 7 import cn.iocoder.yudao.framework.common.pojo.PageResult;
8 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 8 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
9 import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageDrawReqVO; 9 import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageDrawReqVO;
  10 +import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImagePageReqVO;
10 import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageRespVO; 11 import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageRespVO;
  12 +import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageUpdatePublicStatusReqVO;
11 import cn.iocoder.yudao.module.ai.controller.admin.image.vo.midjourney.AiMidjourneyActionReqVO; 13 import cn.iocoder.yudao.module.ai.controller.admin.image.vo.midjourney.AiMidjourneyActionReqVO;
12 import cn.iocoder.yudao.module.ai.controller.admin.image.vo.midjourney.AiMidjourneyImagineReqVO; 14 import cn.iocoder.yudao.module.ai.controller.admin.image.vo.midjourney.AiMidjourneyImagineReqVO;
13 import cn.iocoder.yudao.module.ai.dal.dataobject.image.AiImageDO; 15 import cn.iocoder.yudao.module.ai.dal.dataobject.image.AiImageDO;
@@ -17,7 +19,9 @@ import io.swagger.v3.oas.annotations.Parameter; @@ -17,7 +19,9 @@ import io.swagger.v3.oas.annotations.Parameter;
17 import io.swagger.v3.oas.annotations.tags.Tag; 19 import io.swagger.v3.oas.annotations.tags.Tag;
18 import jakarta.annotation.Resource; 20 import jakarta.annotation.Resource;
19 import jakarta.annotation.security.PermitAll; 21 import jakarta.annotation.security.PermitAll;
  22 +import jakarta.validation.Valid;
20 import lombok.extern.slf4j.Slf4j; 23 import lombok.extern.slf4j.Slf4j;
  24 +import org.springframework.security.access.prepost.PreAuthorize;
21 import org.springframework.validation.annotation.Validated; 25 import org.springframework.validation.annotation.Validated;
22 import org.springframework.web.bind.annotation.*; 26 import org.springframework.web.bind.annotation.*;
23 27
@@ -88,4 +92,31 @@ public class AiImageController { @@ -88,4 +92,31 @@ public class AiImageController {
88 return success(imageId); 92 return success(imageId);
89 } 93 }
90 94
  95 + // ================ 绘图管理 ================
  96 +
  97 + @GetMapping("/page")
  98 + @Operation(summary = "获得绘画分页")
  99 + @PreAuthorize("@ss.hasPermission('ai:image:query')")
  100 + public CommonResult<PageResult<AiImageRespVO>> getImagePage(@Valid AiImagePageReqVO pageReqVO) {
  101 + PageResult<AiImageDO> pageResult = imageService.getImagePage(pageReqVO);
  102 + return success(BeanUtils.toBean(pageResult, AiImageRespVO.class));
  103 + }
  104 +
  105 + @PutMapping("/update-public-status")
  106 + @Operation(summary = "更新绘画发布状态")
  107 + @PreAuthorize("@ss.hasPermission('ai:image:update')")
  108 + public CommonResult<Boolean> updateImagePublicStatus(@Valid @RequestBody AiImageUpdatePublicStatusReqVO updateReqVO) {
  109 + imageService.updateImagePublicStatus(updateReqVO);
  110 + return success(true);
  111 + }
  112 +
  113 + @DeleteMapping("/delete")
  114 + @Operation(summary = "删除绘画")
  115 + @Parameter(name = "id", description = "编号", required = true)
  116 + @PreAuthorize("@ss.hasPermission('ai:image:delete')")
  117 + public CommonResult<Boolean> deleteImage(@RequestParam("id") Long id) {
  118 + imageService.deleteImage(id);
  119 + return success(true);
  120 + }
  121 +
91 } 122 }
92 \ No newline at end of file 123 \ No newline at end of file
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/image/vo/AiImageDrawReqVO.java
@@ -10,7 +10,7 @@ import org.springframework.ai.stabilityai.api.StabilityAiImageOptions; @@ -10,7 +10,7 @@ import org.springframework.ai.stabilityai.api.StabilityAiImageOptions;
10 10
11 import java.util.Map; 11 import java.util.Map;
12 12
13 -@Schema(description = "管理后台 - 绘画 Request VO") 13 +@Schema(description = "管理后台 - AI 绘画 Request VO")
14 @Data 14 @Data
15 public class AiImageDrawReqVO { 15 public class AiImageDrawReqVO {
16 16
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/image/vo/AiImagePageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.ai.controller.admin.image.vo;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +import org.springframework.format.annotation.DateTimeFormat;
  9 +
  10 +import java.time.LocalDateTime;
  11 +
  12 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  13 +
  14 +@Schema(description = "管理后台 - AI 绘画分页 Request VO")
  15 +@Data
  16 +@EqualsAndHashCode(callSuper = true)
  17 +@ToString(callSuper = true)
  18 +public class AiImagePageReqVO extends PageParam {
  19 +
  20 + @Schema(description = "用户编号", example = "28987")
  21 + private Long userId;
  22 +
  23 + @Schema(description = "平台")
  24 + private String platform;
  25 +
  26 + @Schema(description = "绘画状态", example = "1")
  27 + private Integer status;
  28 +
  29 + @Schema(description = "是否发布", example = "1")
  30 + private Boolean publicStatus;
  31 +
  32 + @Schema(description = "创建时间")
  33 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  34 + private LocalDateTime[] createTime;
  35 +
  36 +}
0 \ No newline at end of file 37 \ No newline at end of file
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/image/vo/AiImageRespVO.java
@@ -4,10 +4,11 @@ import cn.iocoder.yudao.framework.ai.core.model.midjourney.api.MidjourneyApi; @@ -4,10 +4,11 @@ import cn.iocoder.yudao.framework.ai.core.model.midjourney.api.MidjourneyApi;
4 import io.swagger.v3.oas.annotations.media.Schema; 4 import io.swagger.v3.oas.annotations.media.Schema;
5 import lombok.Data; 5 import lombok.Data;
6 6
  7 +import java.time.LocalDateTime;
7 import java.util.List; 8 import java.util.List;
8 import java.util.Map; 9 import java.util.Map;
9 10
10 -@Schema(description = "管理后台 - 绘画 Response VO") 11 +@Schema(description = "管理后台 - AI 绘画 Response VO")
11 @Data 12 @Data
12 public class AiImageRespVO { 13 public class AiImageRespVO {
13 14
@@ -47,11 +48,10 @@ public class AiImageRespVO { @@ -47,11 +48,10 @@ public class AiImageRespVO {
47 @Schema(description = "绘制参数") 48 @Schema(description = "绘制参数")
48 private Map<String, String> options; 49 private Map<String, String> options;
49 50
50 - // TODO @fan:进度是百分比,还是一个数字哈?感觉这个可以统一成通用字段;  
51 - @Schema(description = "mj 进度")  
52 - private String progress;  
53 -  
54 @Schema(description = "mj buttons 按钮") 51 @Schema(description = "mj buttons 按钮")
55 private List<MidjourneyApi.Button> buttons; 52 private List<MidjourneyApi.Button> buttons;
56 53
  54 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  55 + private LocalDateTime createTime;
  56 +
57 } 57 }
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/image/vo/AiImageUpdatePublicStatusReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.ai.controller.admin.image.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.NotNull;
  5 +import lombok.Data;
  6 +
  7 +@Schema(description = "管理后台 - AI 绘画修改发布状态 Request VO")
  8 +@Data
  9 +public class AiImageUpdatePublicStatusReqVO {
  10 +
  11 + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "15583")
  12 + private Long id;
  13 +
  14 + @Schema(description = "是否发布", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
  15 + @NotNull(message = "是否发布不能为空")
  16 + private Boolean publicStatus;
  17 +
  18 +}
0 \ No newline at end of file 19 \ No newline at end of file
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/image/vo/midjourney/AiMidjourneyActionReqVO.java
@@ -5,7 +5,7 @@ import jakarta.validation.constraints.NotEmpty; @@ -5,7 +5,7 @@ import jakarta.validation.constraints.NotEmpty;
5 import jakarta.validation.constraints.NotNull; 5 import jakarta.validation.constraints.NotNull;
6 import lombok.Data; 6 import lombok.Data;
7 7
8 -@Schema(description = "管理后台 - Action(Midjourney) Request VO") 8 +@Schema(description = "管理后台 - AI 绘图操作(Midjourney) Request VO")
9 @Data 9 @Data
10 public class AiMidjourneyActionReqVO { 10 public class AiMidjourneyActionReqVO {
11 11
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/image/vo/midjourney/AiMidjourneyImagineReqVO.java
@@ -7,7 +7,7 @@ import lombok.Data; @@ -7,7 +7,7 @@ import lombok.Data;
7 7
8 import java.util.List; 8 import java.util.List;
9 9
10 -@Schema(description = "管理后台 - 绘画生成(Midjourney) Request VO") 10 +@Schema(description = "管理后台 - AI 绘画生成(Midjourney) Request VO")
11 @Data 11 @Data
12 public class AiMidjourneyImagineReqVO { 12 public class AiMidjourneyImagineReqVO {
13 13
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/image/AiImageMapper.java
@@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam; @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 5 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
6 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; 6 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  7 +import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImagePageReqVO;
7 import cn.iocoder.yudao.module.ai.dal.dataobject.image.AiImageDO; 8 import cn.iocoder.yudao.module.ai.dal.dataobject.image.AiImageDO;
8 import org.apache.ibatis.annotations.Mapper; 9 import org.apache.ibatis.annotations.Mapper;
9 10
@@ -21,6 +22,16 @@ public interface AiImageMapper extends BaseMapperX&lt;AiImageDO&gt; { @@ -21,6 +22,16 @@ public interface AiImageMapper extends BaseMapperX&lt;AiImageDO&gt; {
21 return this.selectOne(AiImageDO::getTaskId, taskId); 22 return this.selectOne(AiImageDO::getTaskId, taskId);
22 } 23 }
23 24
  25 + default PageResult<AiImageDO> selectPage(AiImagePageReqVO reqVO) {
  26 + return selectPage(reqVO, new LambdaQueryWrapperX<AiImageDO>()
  27 + .eqIfPresent(AiImageDO::getUserId, reqVO.getUserId())
  28 + .eqIfPresent(AiImageDO::getPlatform, reqVO.getPlatform())
  29 + .eqIfPresent(AiImageDO::getStatus, reqVO.getStatus())
  30 + .eqIfPresent(AiImageDO::getPublicStatus, reqVO.getPublicStatus())
  31 + .betweenIfPresent(AiImageDO::getCreateTime, reqVO.getCreateTime())
  32 + .orderByDesc(AiImageDO::getId));
  33 + }
  34 +
24 default PageResult<AiImageDO> selectPage(Long userId, PageParam pageReqVO) { 35 default PageResult<AiImageDO> selectPage(Long userId, PageParam pageReqVO) {
25 return selectPage(pageReqVO, new LambdaQueryWrapperX<AiImageDO>() 36 return selectPage(pageReqVO, new LambdaQueryWrapperX<AiImageDO>()
26 .eq(AiImageDO::getUserId, userId) 37 .eq(AiImageDO::getUserId, userId)
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/image/AiImageService.java
@@ -4,9 +4,12 @@ import cn.iocoder.yudao.framework.ai.core.model.midjourney.api.MidjourneyApi; @@ -4,9 +4,12 @@ import cn.iocoder.yudao.framework.ai.core.model.midjourney.api.MidjourneyApi;
4 import cn.iocoder.yudao.framework.common.pojo.PageParam; 4 import cn.iocoder.yudao.framework.common.pojo.PageParam;
5 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageDrawReqVO; 6 import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageDrawReqVO;
  7 +import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImagePageReqVO;
  8 +import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageUpdatePublicStatusReqVO;
7 import cn.iocoder.yudao.module.ai.controller.admin.image.vo.midjourney.AiMidjourneyActionReqVO; 9 import cn.iocoder.yudao.module.ai.controller.admin.image.vo.midjourney.AiMidjourneyActionReqVO;
8 import cn.iocoder.yudao.module.ai.controller.admin.image.vo.midjourney.AiMidjourneyImagineReqVO; 10 import cn.iocoder.yudao.module.ai.controller.admin.image.vo.midjourney.AiMidjourneyImagineReqVO;
9 import cn.iocoder.yudao.module.ai.dal.dataobject.image.AiImageDO; 11 import cn.iocoder.yudao.module.ai.dal.dataobject.image.AiImageDO;
  12 +import jakarta.validation.Valid;
10 13
11 /** 14 /**
12 * AI 绘图 Service 接口 15 * AI 绘图 Service 接口
@@ -49,6 +52,28 @@ public interface AiImageService { @@ -49,6 +52,28 @@ public interface AiImageService {
49 */ 52 */
50 void deleteImageMy(Long id, Long userId); 53 void deleteImageMy(Long id, Long userId);
51 54
  55 + /**
  56 + * 获得绘画分页
  57 + *
  58 + * @param pageReqVO 分页查询
  59 + * @return 绘画分页
  60 + */
  61 + PageResult<AiImageDO> getImagePage(AiImagePageReqVO pageReqVO);
  62 +
  63 + /**
  64 + * 更新绘画发布状态
  65 + *
  66 + * @param updateReqVO 更新信息
  67 + */
  68 + void updateImagePublicStatus(@Valid AiImageUpdatePublicStatusReqVO updateReqVO);
  69 +
  70 + /**
  71 + * 删除绘画
  72 + *
  73 + * @param id 编号
  74 + */
  75 + void deleteImage(Long id);
  76 +
52 // ================ midjourney 专属 ================ 77 // ================ midjourney 专属 ================
53 78
54 /** 79 /**
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/image/AiImageServiceImpl.java
@@ -14,6 +14,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam; @@ -14,6 +14,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam;
14 import cn.iocoder.yudao.framework.common.pojo.PageResult; 14 import cn.iocoder.yudao.framework.common.pojo.PageResult;
15 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 15 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
16 import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageDrawReqVO; 16 import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageDrawReqVO;
  17 +import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImagePageReqVO;
  18 +import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageUpdatePublicStatusReqVO;
17 import cn.iocoder.yudao.module.ai.controller.admin.image.vo.midjourney.AiMidjourneyActionReqVO; 19 import cn.iocoder.yudao.module.ai.controller.admin.image.vo.midjourney.AiMidjourneyActionReqVO;
18 import cn.iocoder.yudao.module.ai.controller.admin.image.vo.midjourney.AiMidjourneyImagineReqVO; 20 import cn.iocoder.yudao.module.ai.controller.admin.image.vo.midjourney.AiMidjourneyImagineReqVO;
19 import cn.iocoder.yudao.module.ai.dal.dataobject.image.AiImageDO; 21 import cn.iocoder.yudao.module.ai.dal.dataobject.image.AiImageDO;
@@ -134,6 +136,27 @@ public class AiImageServiceImpl implements AiImageService { @@ -134,6 +136,27 @@ public class AiImageServiceImpl implements AiImageService {
134 imageMapper.deleteById(id); 136 imageMapper.deleteById(id);
135 } 137 }
136 138
  139 + @Override
  140 + public PageResult<AiImageDO> getImagePage(AiImagePageReqVO pageReqVO) {
  141 + return imageMapper.selectPage(pageReqVO);
  142 + }
  143 +
  144 + @Override
  145 + public void updateImagePublicStatus(AiImageUpdatePublicStatusReqVO updateReqVO) {
  146 + // 1. 校验存在
  147 + validateImageExists(updateReqVO.getId());
  148 + // 2. 更新发布状态
  149 + imageMapper.updateById(BeanUtils.toBean(updateReqVO, AiImageDO.class));
  150 + }
  151 +
  152 + @Override
  153 + public void deleteImage(Long id) {
  154 + // 1. 校验存在
  155 + validateImageExists(id);
  156 + // 2. 删除
  157 + imageMapper.deleteById(id);
  158 + }
  159 +
137 private AiImageDO validateImageExists(Long id) { 160 private AiImageDO validateImageExists(Long id) {
138 AiImageDO image = imageMapper.selectById(id); 161 AiImageDO image = imageMapper.selectById(id);
139 if (image == null) { 162 if (image == null) {
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/enums/AiPlatformEnum.java
@@ -21,7 +21,7 @@ public enum AiPlatformEnum { @@ -21,7 +21,7 @@ public enum AiPlatformEnum {
21 GEMIR ("gemir ", "gemir "), // 谷歌 21 GEMIR ("gemir ", "gemir "), // 谷歌
22 22
23 STABLE_DIFFUSION("StableDiffusion", "StableDiffusion"), // Stability AI 23 STABLE_DIFFUSION("StableDiffusion", "StableDiffusion"), // Stability AI
24 - MIDJOURNEY("midjourney", "midjourney"), // TODO MJ 提供的绘图,接入中 24 + MIDJOURNEY("Midjourney", "Midjourney"),
25 SUNO("Suno", "Suno"), // Suno AI 25 SUNO("Suno", "Suno"), // Suno AI
26 ; 26 ;
27 27
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/model/midjourney/MidjourneyConfig.java deleted
1 -package cn.iocoder.yudao.framework.ai.core.model.midjourney;  
2 -  
3 -import lombok.Data;  
4 -  
5 -/**  
6 - * Midjourney 属性  
7 - *  
8 - * @author fansili  
9 - * @time 2024/6/5 15:02  
10 - * @since 1.0  
11 - */  
12 -@Data  
13 -public class MidjourneyConfig {  
14 -  
15 - /**  
16 - * keys  
17 - */  
18 - private String key;  
19 - /**  
20 - * 请求地址  
21 - */  
22 - private String url;  
23 -}