mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-10-31 18:28:43 +08:00 
			
		
		
		
	【功能新增】AI:图片管理
This commit is contained in:
		| @@ -13,8 +13,8 @@ import lombok.Getter; | |||||||
| public enum AiImageStatusEnum { | public enum AiImageStatusEnum { | ||||||
|  |  | ||||||
|     IN_PROGRESS(10, "进行中"), |     IN_PROGRESS(10, "进行中"), | ||||||
|     SUCCESS(20, "完成"), |     SUCCESS(20, "已完成"), | ||||||
|     FAIL(30, "失败"); |     FAIL(30, "已失败"); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 状态 |      * 状态 | ||||||
|   | |||||||
| @@ -7,7 +7,9 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam; | |||||||
| import cn.iocoder.yudao.framework.common.pojo.PageResult; | import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||||||
| import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | ||||||
| import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageDrawReqVO; | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageDrawReqVO; | ||||||
|  | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImagePageReqVO; | ||||||
| import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageRespVO; | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageRespVO; | ||||||
|  | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageUpdatePublicStatusReqVO; | ||||||
| import cn.iocoder.yudao.module.ai.controller.admin.image.vo.midjourney.AiMidjourneyActionReqVO; | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.midjourney.AiMidjourneyActionReqVO; | ||||||
| import cn.iocoder.yudao.module.ai.controller.admin.image.vo.midjourney.AiMidjourneyImagineReqVO; | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.midjourney.AiMidjourneyImagineReqVO; | ||||||
| import cn.iocoder.yudao.module.ai.dal.dataobject.image.AiImageDO; | import cn.iocoder.yudao.module.ai.dal.dataobject.image.AiImageDO; | ||||||
| @@ -17,7 +19,9 @@ import io.swagger.v3.oas.annotations.Parameter; | |||||||
| import io.swagger.v3.oas.annotations.tags.Tag; | import io.swagger.v3.oas.annotations.tags.Tag; | ||||||
| import jakarta.annotation.Resource; | import jakarta.annotation.Resource; | ||||||
| import jakarta.annotation.security.PermitAll; | import jakarta.annotation.security.PermitAll; | ||||||
|  | import jakarta.validation.Valid; | ||||||
| import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||||
|  | import org.springframework.security.access.prepost.PreAuthorize; | ||||||
| import org.springframework.validation.annotation.Validated; | import org.springframework.validation.annotation.Validated; | ||||||
| import org.springframework.web.bind.annotation.*; | import org.springframework.web.bind.annotation.*; | ||||||
|  |  | ||||||
| @@ -88,4 +92,31 @@ public class AiImageController { | |||||||
|         return success(imageId); |         return success(imageId); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     // ================ 绘图管理 ================ | ||||||
|  |  | ||||||
|  |     @GetMapping("/page") | ||||||
|  |     @Operation(summary = "获得绘画分页") | ||||||
|  |     @PreAuthorize("@ss.hasPermission('ai:image:query')") | ||||||
|  |     public CommonResult<PageResult<AiImageRespVO>> getImagePage(@Valid AiImagePageReqVO pageReqVO) { | ||||||
|  |         PageResult<AiImageDO> pageResult = imageService.getImagePage(pageReqVO); | ||||||
|  |         return success(BeanUtils.toBean(pageResult, AiImageRespVO.class)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @PutMapping("/update-public-status") | ||||||
|  |     @Operation(summary = "更新绘画发布状态") | ||||||
|  |     @PreAuthorize("@ss.hasPermission('ai:image:update')") | ||||||
|  |     public CommonResult<Boolean> updateImagePublicStatus(@Valid @RequestBody AiImageUpdatePublicStatusReqVO updateReqVO) { | ||||||
|  |         imageService.updateImagePublicStatus(updateReqVO); | ||||||
|  |         return success(true); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @DeleteMapping("/delete") | ||||||
|  |     @Operation(summary = "删除绘画") | ||||||
|  |     @Parameter(name = "id", description = "编号", required = true) | ||||||
|  |     @PreAuthorize("@ss.hasPermission('ai:image:delete')") | ||||||
|  |     public CommonResult<Boolean> deleteImage(@RequestParam("id") Long id) { | ||||||
|  |         imageService.deleteImage(id); | ||||||
|  |         return success(true); | ||||||
|  |     } | ||||||
|  |  | ||||||
| } | } | ||||||
| @@ -10,7 +10,7 @@ import org.springframework.ai.stabilityai.api.StabilityAiImageOptions; | |||||||
|  |  | ||||||
| import java.util.Map; | import java.util.Map; | ||||||
|  |  | ||||||
| @Schema(description = "管理后台 - 绘画 Request VO") | @Schema(description = "管理后台 - AI 绘画 Request VO") | ||||||
| @Data | @Data | ||||||
| public class AiImageDrawReqVO { | public class AiImageDrawReqVO { | ||||||
|  |  | ||||||
|   | |||||||
| @@ -0,0 +1,36 @@ | |||||||
|  | package cn.iocoder.yudao.module.ai.controller.admin.image.vo; | ||||||
|  |  | ||||||
|  | import cn.iocoder.yudao.framework.common.pojo.PageParam; | ||||||
|  | import io.swagger.v3.oas.annotations.media.Schema; | ||||||
|  | import lombok.Data; | ||||||
|  | import lombok.EqualsAndHashCode; | ||||||
|  | import lombok.ToString; | ||||||
|  | import org.springframework.format.annotation.DateTimeFormat; | ||||||
|  |  | ||||||
|  | import java.time.LocalDateTime; | ||||||
|  |  | ||||||
|  | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | ||||||
|  |  | ||||||
|  | @Schema(description = "管理后台 - AI 绘画分页 Request VO") | ||||||
|  | @Data | ||||||
|  | @EqualsAndHashCode(callSuper = true) | ||||||
|  | @ToString(callSuper = true) | ||||||
|  | public class AiImagePageReqVO extends PageParam { | ||||||
|  |  | ||||||
|  |     @Schema(description = "用户编号", example = "28987") | ||||||
|  |     private Long userId; | ||||||
|  |  | ||||||
|  |     @Schema(description = "平台") | ||||||
|  |     private String platform; | ||||||
|  |  | ||||||
|  |     @Schema(description = "绘画状态", example = "1") | ||||||
|  |     private Integer status; | ||||||
|  |  | ||||||
|  |     @Schema(description = "是否发布", example = "1") | ||||||
|  |     private Boolean publicStatus; | ||||||
|  |  | ||||||
|  |     @Schema(description = "创建时间") | ||||||
|  |     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | ||||||
|  |     private LocalDateTime[] createTime; | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -4,10 +4,11 @@ import cn.iocoder.yudao.framework.ai.core.model.midjourney.api.MidjourneyApi; | |||||||
| import io.swagger.v3.oas.annotations.media.Schema; | import io.swagger.v3.oas.annotations.media.Schema; | ||||||
| import lombok.Data; | import lombok.Data; | ||||||
|  |  | ||||||
|  | import java.time.LocalDateTime; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| import java.util.Map; | import java.util.Map; | ||||||
|  |  | ||||||
| @Schema(description = "管理后台 - 绘画 Response VO") | @Schema(description = "管理后台 - AI 绘画 Response VO") | ||||||
| @Data | @Data | ||||||
| public class AiImageRespVO { | public class AiImageRespVO { | ||||||
|  |  | ||||||
| @@ -47,11 +48,10 @@ public class AiImageRespVO { | |||||||
|     @Schema(description = "绘制参数") |     @Schema(description = "绘制参数") | ||||||
|     private Map<String, String> options; |     private Map<String, String> options; | ||||||
|  |  | ||||||
|     // TODO @fan:进度是百分比,还是一个数字哈?感觉这个可以统一成通用字段; |  | ||||||
|     @Schema(description = "mj 进度") |  | ||||||
|     private String progress; |  | ||||||
|  |  | ||||||
|     @Schema(description = "mj buttons 按钮") |     @Schema(description = "mj buttons 按钮") | ||||||
|     private List<MidjourneyApi.Button> buttons; |     private List<MidjourneyApi.Button> buttons; | ||||||
|  |  | ||||||
|  |     @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) | ||||||
|  |     private LocalDateTime createTime; | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,18 @@ | |||||||
|  | package cn.iocoder.yudao.module.ai.controller.admin.image.vo; | ||||||
|  |  | ||||||
|  | import io.swagger.v3.oas.annotations.media.Schema; | ||||||
|  | import jakarta.validation.constraints.NotNull; | ||||||
|  | import lombok.Data; | ||||||
|  |  | ||||||
|  | @Schema(description = "管理后台 - AI 绘画修改发布状态 Request VO") | ||||||
|  | @Data | ||||||
|  | public class AiImageUpdatePublicStatusReqVO { | ||||||
|  |  | ||||||
|  |     @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "15583") | ||||||
|  |     private Long id; | ||||||
|  |  | ||||||
|  |     @Schema(description = "是否发布", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") | ||||||
|  |     @NotNull(message = "是否发布不能为空") | ||||||
|  |     private Boolean publicStatus; | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -5,7 +5,7 @@ import jakarta.validation.constraints.NotEmpty; | |||||||
| import jakarta.validation.constraints.NotNull; | import jakarta.validation.constraints.NotNull; | ||||||
| import lombok.Data; | import lombok.Data; | ||||||
|  |  | ||||||
| @Schema(description = "管理后台 - Action(Midjourney) Request VO") | @Schema(description = "管理后台 - AI 绘图操作(Midjourney) Request VO") | ||||||
| @Data | @Data | ||||||
| public class AiMidjourneyActionReqVO { | public class AiMidjourneyActionReqVO { | ||||||
|  |  | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ import lombok.Data; | |||||||
|  |  | ||||||
| import java.util.List; | import java.util.List; | ||||||
|  |  | ||||||
| @Schema(description = "管理后台 - 绘画生成(Midjourney) Request VO") | @Schema(description = "管理后台 - AI 绘画生成(Midjourney) Request VO") | ||||||
| @Data | @Data | ||||||
| public class AiMidjourneyImagineReqVO { | public class AiMidjourneyImagineReqVO { | ||||||
|  |  | ||||||
|   | |||||||
| @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam; | |||||||
| import cn.iocoder.yudao.framework.common.pojo.PageResult; | import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||||||
| import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | ||||||
| import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | ||||||
|  | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImagePageReqVO; | ||||||
| import cn.iocoder.yudao.module.ai.dal.dataobject.image.AiImageDO; | import cn.iocoder.yudao.module.ai.dal.dataobject.image.AiImageDO; | ||||||
| import org.apache.ibatis.annotations.Mapper; | import org.apache.ibatis.annotations.Mapper; | ||||||
|  |  | ||||||
| @@ -21,6 +22,16 @@ public interface AiImageMapper extends BaseMapperX<AiImageDO> { | |||||||
|         return this.selectOne(AiImageDO::getTaskId, taskId); |         return this.selectOne(AiImageDO::getTaskId, taskId); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     default PageResult<AiImageDO> selectPage(AiImagePageReqVO reqVO) { | ||||||
|  |         return selectPage(reqVO, new LambdaQueryWrapperX<AiImageDO>() | ||||||
|  |                 .eqIfPresent(AiImageDO::getUserId, reqVO.getUserId()) | ||||||
|  |                 .eqIfPresent(AiImageDO::getPlatform, reqVO.getPlatform()) | ||||||
|  |                 .eqIfPresent(AiImageDO::getStatus, reqVO.getStatus()) | ||||||
|  |                 .eqIfPresent(AiImageDO::getPublicStatus, reqVO.getPublicStatus()) | ||||||
|  |                 .betweenIfPresent(AiImageDO::getCreateTime, reqVO.getCreateTime()) | ||||||
|  |                 .orderByDesc(AiImageDO::getId)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     default PageResult<AiImageDO> selectPage(Long userId, PageParam pageReqVO) { |     default PageResult<AiImageDO> selectPage(Long userId, PageParam pageReqVO) { | ||||||
|         return selectPage(pageReqVO, new LambdaQueryWrapperX<AiImageDO>() |         return selectPage(pageReqVO, new LambdaQueryWrapperX<AiImageDO>() | ||||||
|                 .eq(AiImageDO::getUserId, userId) |                 .eq(AiImageDO::getUserId, userId) | ||||||
|   | |||||||
| @@ -4,9 +4,12 @@ import cn.iocoder.yudao.framework.ai.core.model.midjourney.api.MidjourneyApi; | |||||||
| import cn.iocoder.yudao.framework.common.pojo.PageParam; | import cn.iocoder.yudao.framework.common.pojo.PageParam; | ||||||
| import cn.iocoder.yudao.framework.common.pojo.PageResult; | import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||||||
| import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageDrawReqVO; | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageDrawReqVO; | ||||||
|  | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImagePageReqVO; | ||||||
|  | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageUpdatePublicStatusReqVO; | ||||||
| import cn.iocoder.yudao.module.ai.controller.admin.image.vo.midjourney.AiMidjourneyActionReqVO; | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.midjourney.AiMidjourneyActionReqVO; | ||||||
| import cn.iocoder.yudao.module.ai.controller.admin.image.vo.midjourney.AiMidjourneyImagineReqVO; | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.midjourney.AiMidjourneyImagineReqVO; | ||||||
| import cn.iocoder.yudao.module.ai.dal.dataobject.image.AiImageDO; | import cn.iocoder.yudao.module.ai.dal.dataobject.image.AiImageDO; | ||||||
|  | import jakarta.validation.Valid; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * AI 绘图 Service 接口 |  * AI 绘图 Service 接口 | ||||||
| @@ -49,6 +52,28 @@ public interface AiImageService { | |||||||
|      */ |      */ | ||||||
|     void deleteImageMy(Long id, Long userId); |     void deleteImageMy(Long id, Long userId); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 获得绘画分页 | ||||||
|  |      * | ||||||
|  |      * @param pageReqVO 分页查询 | ||||||
|  |      * @return 绘画分页 | ||||||
|  |      */ | ||||||
|  |     PageResult<AiImageDO> getImagePage(AiImagePageReqVO pageReqVO); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 更新绘画发布状态 | ||||||
|  |      * | ||||||
|  |      * @param updateReqVO 更新信息 | ||||||
|  |      */ | ||||||
|  |     void updateImagePublicStatus(@Valid AiImageUpdatePublicStatusReqVO updateReqVO); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 删除绘画 | ||||||
|  |      * | ||||||
|  |      * @param id 编号 | ||||||
|  |      */ | ||||||
|  |     void deleteImage(Long id); | ||||||
|  |  | ||||||
|     // ================ midjourney 专属 ================ |     // ================ midjourney 专属 ================ | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|   | |||||||
| @@ -14,6 +14,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam; | |||||||
| import cn.iocoder.yudao.framework.common.pojo.PageResult; | import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||||||
| import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | ||||||
| import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageDrawReqVO; | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageDrawReqVO; | ||||||
|  | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImagePageReqVO; | ||||||
|  | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageUpdatePublicStatusReqVO; | ||||||
| import cn.iocoder.yudao.module.ai.controller.admin.image.vo.midjourney.AiMidjourneyActionReqVO; | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.midjourney.AiMidjourneyActionReqVO; | ||||||
| import cn.iocoder.yudao.module.ai.controller.admin.image.vo.midjourney.AiMidjourneyImagineReqVO; | import cn.iocoder.yudao.module.ai.controller.admin.image.vo.midjourney.AiMidjourneyImagineReqVO; | ||||||
| import cn.iocoder.yudao.module.ai.dal.dataobject.image.AiImageDO; | import cn.iocoder.yudao.module.ai.dal.dataobject.image.AiImageDO; | ||||||
| @@ -134,6 +136,27 @@ public class AiImageServiceImpl implements AiImageService { | |||||||
|         imageMapper.deleteById(id); |         imageMapper.deleteById(id); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public PageResult<AiImageDO> getImagePage(AiImagePageReqVO pageReqVO) { | ||||||
|  |         return imageMapper.selectPage(pageReqVO); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void updateImagePublicStatus(AiImageUpdatePublicStatusReqVO updateReqVO) { | ||||||
|  |         // 1. 校验存在 | ||||||
|  |         validateImageExists(updateReqVO.getId()); | ||||||
|  |         // 2. 更新发布状态 | ||||||
|  |         imageMapper.updateById(BeanUtils.toBean(updateReqVO, AiImageDO.class)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void deleteImage(Long id) { | ||||||
|  |         // 1. 校验存在 | ||||||
|  |         validateImageExists(id); | ||||||
|  |         // 2. 删除 | ||||||
|  |         imageMapper.deleteById(id); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     private AiImageDO validateImageExists(Long id) { |     private AiImageDO validateImageExists(Long id) { | ||||||
|         AiImageDO image = imageMapper.selectById(id); |         AiImageDO image = imageMapper.selectById(id); | ||||||
|         if (image == null) { |         if (image == null) { | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ public enum AiPlatformEnum { | |||||||
|     GEMIR ("gemir ", "gemir "), // 谷歌 |     GEMIR ("gemir ", "gemir "), // 谷歌 | ||||||
|  |  | ||||||
|     STABLE_DIFFUSION("StableDiffusion", "StableDiffusion"), // Stability AI |     STABLE_DIFFUSION("StableDiffusion", "StableDiffusion"), // Stability AI | ||||||
|     MIDJOURNEY("midjourney", "midjourney"), // TODO MJ 提供的绘图,接入中 |     MIDJOURNEY("Midjourney", "Midjourney"), | ||||||
|     SUNO("Suno", "Suno"), // Suno AI |     SUNO("Suno", "Suno"), // Suno AI | ||||||
|     ; |     ; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,23 +0,0 @@ | |||||||
| package cn.iocoder.yudao.framework.ai.core.model.midjourney; |  | ||||||
|  |  | ||||||
| import lombok.Data; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Midjourney 属性 |  | ||||||
|  * |  | ||||||
|  * @author fansili |  | ||||||
|  * @time 2024/6/5 15:02 |  | ||||||
|  * @since 1.0 |  | ||||||
|  */ |  | ||||||
| @Data |  | ||||||
| public class MidjourneyConfig { |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * keys |  | ||||||
|      */ |  | ||||||
|     private String key; |  | ||||||
|     /** |  | ||||||
|      * 请求地址 |  | ||||||
|      */ |  | ||||||
|     private String url; |  | ||||||
| } |  | ||||||
		Reference in New Issue
	
	Block a user
	 YunaiV
					YunaiV