添加comfyuo接口
parent
fe32142027
commit
7f75464e57
@ -0,0 +1,63 @@
|
||||
package com.supervision.ai.service.hub.config;
|
||||
|
||||
import com.supervision.ai.service.hub.constant.ResultStatusEnum;
|
||||
import com.supervision.ai.service.hub.dto.common.R;
|
||||
import com.supervision.ai.service.hub.exception.BusinessException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
import org.springframework.web.multipart.MaxUploadSizeExceededException;
|
||||
|
||||
/**
|
||||
* 统一异常处理器配置
|
||||
*
|
||||
* @author wb
|
||||
* @date 2022/3/10 13:24
|
||||
*/
|
||||
@Slf4j
|
||||
@Configuration
|
||||
@RestControllerAdvice(annotations = RestController.class, basePackages = {"com.supervision.ai.service.**.controller"})
|
||||
public class ExceptionHandlerConfig {
|
||||
|
||||
/**
|
||||
* 添加手动校验参数的异常处理
|
||||
*
|
||||
* @param exception 参数验证异常
|
||||
* @return 通用返回值
|
||||
*/
|
||||
@ExceptionHandler(IllegalArgumentException.class)
|
||||
public R<?> manualValidationExceptionResponse(IllegalArgumentException exception) {
|
||||
log.error("=========手动校验参数异常=========>>>");
|
||||
log.error(exception.getMessage(), exception);
|
||||
log.error("<<<=========手动校验参数异常=========");
|
||||
return R.fail(ResultStatusEnum.ILLEGAL_ARGUMENT.getCode(), exception.getMessage());
|
||||
}
|
||||
|
||||
@ExceptionHandler(BusinessException.class)
|
||||
public R<?> businessExceptionResponse(BusinessException exception) {
|
||||
log.error("=========运行异常=========>>>");
|
||||
log.error(exception.getMessage(), exception);
|
||||
log.error("<<<=========运行异常=========");
|
||||
|
||||
return R.fail(511, exception.getMessage());
|
||||
}
|
||||
|
||||
@ExceptionHandler(RuntimeException.class)
|
||||
public R<?> manualValidationExceptionResponse(RuntimeException exception) {
|
||||
log.error("=========运行异常=========>>>");
|
||||
log.error(exception.getMessage(), exception);
|
||||
log.error("<<<=========运行异常=========");
|
||||
|
||||
return R.fail(ResultStatusEnum.RUNTIME_EXCEPTION.getCode(), exception.getMessage());
|
||||
}
|
||||
|
||||
@ExceptionHandler(MaxUploadSizeExceededException.class)
|
||||
public R<?> handleMaxSizeException(MaxUploadSizeExceededException exception) {
|
||||
log.error("=========文件大小超出限制异常=========>>>");
|
||||
log.error(exception.getMessage(), exception);
|
||||
log.error("<<<=========文件大小超出限制异常=========");
|
||||
return R.fail(ResultStatusEnum.EXCEED_FILE_SIZE.getCode(), exception.getMessage());
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.supervision.ai.service.hub.config;
|
||||
|
||||
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
|
||||
import org.apache.ibatis.reflection.MetaObject;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* @author Ray
|
||||
*/
|
||||
public class MyMetaObjectHandler implements MetaObjectHandler {
|
||||
public MyMetaObjectHandler() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertFill(MetaObject metaObject) {
|
||||
this.setFieldValByName("createTime", LocalDateTime.now(), metaObject);
|
||||
this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateFill(MetaObject metaObject) {
|
||||
this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package com.supervision.ai.service.hub.config;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* MybatisPlus配置
|
||||
*
|
||||
* @author qmy
|
||||
* @version 1.0.0 2020/10/22 9:47
|
||||
* @since JDK1.8
|
||||
*/
|
||||
@Configuration
|
||||
public class MybatisPlusConfig {
|
||||
|
||||
@Bean
|
||||
public MyMetaObjectHandler myMetaObjectHandler() {
|
||||
return new MyMetaObjectHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
* 拦截器配置
|
||||
*/
|
||||
@Bean
|
||||
public MybatisPlusInterceptor mybatisPlusInterceptor() {
|
||||
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
||||
interceptor.addInnerInterceptor(this.paginationInterceptor());
|
||||
return interceptor;
|
||||
}
|
||||
|
||||
private PaginationInnerInterceptor paginationInterceptor() {
|
||||
PaginationInnerInterceptor paginationInterceptor = new PaginationInnerInterceptor();
|
||||
paginationInterceptor.setOverflow(false);
|
||||
/**
|
||||
* 注意! 此处要设置数据库类型.
|
||||
*/
|
||||
paginationInterceptor.setDbType(DbType.POSTGRE_SQL);
|
||||
return paginationInterceptor;
|
||||
}
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
package com.supervision.ai.service.hub.constant;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public enum ComfyuiParamTypeEnum {
|
||||
// 整数
|
||||
INTEGER(0,"整数", Integer.class) {
|
||||
@Override
|
||||
public Object coverType(Object value) {
|
||||
if (null == value){
|
||||
return null;
|
||||
}
|
||||
if (value instanceof Integer){
|
||||
return value;
|
||||
}
|
||||
Assert.isTrue(NumberUtil.isNumber(value.toString()),"参数类型错误");
|
||||
return NumberUtil.parseInt(value.toString());
|
||||
}
|
||||
},
|
||||
// 浮点型
|
||||
FLOAT(1,"浮点型", Float.class) {
|
||||
@Override
|
||||
public Object coverType(Object value) {
|
||||
if (null == value){
|
||||
return null;
|
||||
}
|
||||
if (value instanceof Float){
|
||||
return value;
|
||||
}
|
||||
Assert.isTrue(NumberUtil.isNumber(value.toString()),"参数类型错误");
|
||||
return NumberUtil.parseFloat(value.toString());
|
||||
}
|
||||
},
|
||||
// 字符串
|
||||
STRING(2,"字符串",String.class) {
|
||||
@Override
|
||||
public Object coverType(Object value) {
|
||||
if (null == value){
|
||||
return null;
|
||||
}
|
||||
if (value instanceof String){
|
||||
return value;
|
||||
}
|
||||
return value.toString();
|
||||
}
|
||||
},
|
||||
// 布尔值
|
||||
BOOLEAN(3,"布尔值",Boolean.class) {
|
||||
@Override
|
||||
public Object coverType(Object value) {
|
||||
if (null == value){
|
||||
return null;
|
||||
}
|
||||
if (value instanceof Boolean){
|
||||
return value;
|
||||
}
|
||||
Assert.isTrue(false,"参数类型错误");
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
private final int code;
|
||||
private final String desc;
|
||||
|
||||
private final Class<?> type;
|
||||
|
||||
ComfyuiParamTypeEnum(int code, String desc,Class<?> type) {
|
||||
this.code = code;
|
||||
this.desc = desc;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
|
||||
public static ComfyuiParamTypeEnum getByCode(int code){
|
||||
for (ComfyuiParamTypeEnum value : ComfyuiParamTypeEnum.values()) {
|
||||
if (value.getCode() == code){
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public abstract Object coverType(Object value);
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package com.supervision.ai.service.hub.controller;
|
||||
|
||||
import com.supervision.ai.service.hub.dto.common.R;
|
||||
import com.supervision.ai.service.hub.service.ComfyUIService;
|
||||
import com.supervision.ai.service.hub.vo.comfyui.RunPromptReqVo;
|
||||
import com.supervision.ai.service.hub.vo.comfyui.TaskResultResVo;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/comfyui")
|
||||
@RequiredArgsConstructor
|
||||
public class ComfyUIController {
|
||||
|
||||
private final ComfyUIService comfyUIService;
|
||||
|
||||
/**
|
||||
* 运行prompt
|
||||
* @param runPromptReqVo prompt信息
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/run")
|
||||
public R<String> runPrompt(@RequestBody RunPromptReqVo runPromptReqVo) {
|
||||
|
||||
String taskId = comfyUIService.runPrompt(runPromptReqVo);
|
||||
return R.ok(taskId);
|
||||
}
|
||||
|
||||
@GetMapping("/queryHistory")
|
||||
public R<List<TaskResultResVo>> queryHistory(@RequestParam(name = "promptId", required = false) String promptId) {
|
||||
List<TaskResultResVo> taskResultResVos = comfyUIService.queryHistory(promptId);
|
||||
return R.ok(taskResultResVos);
|
||||
}
|
||||
|
||||
@PostMapping("/uploadImage")
|
||||
public R<String> uploadImage(@RequestParam("file") MultipartFile file) throws Exception {
|
||||
String imageId = comfyUIService.uploadImage(file);
|
||||
return R.ok(imageId);
|
||||
}
|
||||
|
||||
@GetMapping("/downloadView")
|
||||
public void downloadView(@RequestParam("fileName") String fileName, HttpServletResponse response) throws Exception {
|
||||
comfyUIService.downloadView(fileName, response);
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package com.supervision.ai.service.hub.dto.comfyui;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 图片上传请求响应
|
||||
*/
|
||||
@Data
|
||||
public class ImageUploadDTO {
|
||||
|
||||
private String name;
|
||||
private String subfolder;
|
||||
private String type;
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.supervision.ai.service.hub.dto.comfyui;
|
||||
|
||||
import lombok.Data;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 运行提示词请求结果
|
||||
*/
|
||||
@Data
|
||||
public class PromptRunDTO {
|
||||
|
||||
private String prompt_id;
|
||||
|
||||
private int number;
|
||||
|
||||
private Map<String,Object> node_errors;
|
||||
|
||||
private Map<String,Object> error;
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package com.supervision.ai.service.hub.dto.comfyui;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ResourceViewDTO {
|
||||
|
||||
private String fileName;
|
||||
|
||||
private String contentType;
|
||||
|
||||
private byte[] content;
|
||||
|
||||
public ResourceViewDTO() {
|
||||
}
|
||||
|
||||
public ResourceViewDTO(String fileName, String contentType, byte[] content) {
|
||||
this.fileName = fileName;
|
||||
this.contentType = contentType;
|
||||
this.content = content;
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 文 件 名: CustomException
|
||||
* 版 权:
|
||||
* 描 述: <描述>
|
||||
* 修 改 人: RedName
|
||||
* 修改时间: 2022/8/5
|
||||
* 跟踪单号: <跟踪单号>
|
||||
* 修改单号: <修改单号>
|
||||
* 修改内容: <修改内容>
|
||||
*/
|
||||
package com.supervision.ai.service.hub.exception;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
/**
|
||||
* <功能详细描述>
|
||||
* 自定义异常
|
||||
*
|
||||
* @author ljt
|
||||
* @version [版本号, 2022/8/5]
|
||||
* @see [相关类/方法]
|
||||
* @since [产品/模块版本]
|
||||
*/
|
||||
@Slf4j
|
||||
public class BusinessException extends RuntimeException {
|
||||
/**
|
||||
* 异常编码
|
||||
*/
|
||||
private final Integer code;
|
||||
|
||||
/**
|
||||
* 异常信息
|
||||
*/
|
||||
private final String message;
|
||||
|
||||
public BusinessException(Throwable cause) {
|
||||
super(cause);
|
||||
this.code = HttpStatus.INTERNAL_SERVER_ERROR.value();
|
||||
this.message = null;
|
||||
|
||||
}
|
||||
|
||||
public BusinessException(Throwable cause, String message) {
|
||||
super(cause);
|
||||
this.code = HttpStatus.INTERNAL_SERVER_ERROR.value();
|
||||
this.message = message;
|
||||
|
||||
}
|
||||
|
||||
public BusinessException(String message) {
|
||||
this.code = HttpStatus.INTERNAL_SERVER_ERROR.value();
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public BusinessException(String message, Integer code) {
|
||||
this.message = message;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public BusinessException(String message, Throwable e) {
|
||||
super(message, e);
|
||||
log.error(message, e);
|
||||
this.code = HttpStatus.INTERNAL_SERVER_ERROR.value();
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.supervision.ai.service.hub.mapper;
|
||||
|
||||
import com.supervision.ai.service.hub.domain.ComfyuiPrompt;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
* @description 针对表【comfyui_prompt(comfyui提示词表)】的数据库操作Mapper
|
||||
* @createDate 2025-03-31 17:49:56
|
||||
* @Entity com.supervision.ai.service.hub.domain.ComfyuiPrompt
|
||||
*/
|
||||
public interface ComfyuiPromptMapper extends BaseMapper<ComfyuiPrompt> {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,18 @@
|
||||
package com.supervision.ai.service.hub.mapper;
|
||||
|
||||
import com.supervision.ai.service.hub.domain.ComfyuiPromptParam;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
* @description 针对表【comfyui_prompt_param】的数据库操作Mapper
|
||||
* @createDate 2025-03-31 17:49:56
|
||||
* @Entity com.supervision.ai.service.hub.domain.ComfyuiPromptParam
|
||||
*/
|
||||
public interface ComfyuiPromptParamMapper extends BaseMapper<ComfyuiPromptParam> {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,37 @@
|
||||
package com.supervision.ai.service.hub.service;
|
||||
|
||||
import com.supervision.ai.service.hub.domain.ComfyuiPromptParam;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
* @description 针对表【comfyui_prompt_param】的数据库操作Service
|
||||
* @createDate 2025-03-31 17:49:56
|
||||
*/
|
||||
public interface ComfyUIPromptParamService extends IService<ComfyuiPromptParam> {
|
||||
|
||||
/**
|
||||
* 参数校验
|
||||
* @param params 待校验参数
|
||||
* @param promptId 提示id
|
||||
* @return true 通过校验 false 未通过校验
|
||||
*/
|
||||
boolean requiredCheck(Map<String,Object> params, String promptId);
|
||||
|
||||
|
||||
boolean requiredCheck(Map<String,Object> params, List<ComfyuiPromptParam> promptParamList);
|
||||
|
||||
/**
|
||||
* 根据promptId查询参数
|
||||
* @param promptId 提示词id
|
||||
* @return
|
||||
*/
|
||||
List<ComfyuiPromptParam> listByPromptId(String promptId);
|
||||
|
||||
|
||||
ComfyuiPromptParam selectPromptParam(String paramKey,List<ComfyuiPromptParam> promptParamList);
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package com.supervision.ai.service.hub.service;
|
||||
|
||||
import com.supervision.ai.service.hub.vo.comfyui.RunPromptReqVo;
|
||||
import com.supervision.ai.service.hub.vo.comfyui.TaskResultResVo;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public interface ComfyUIService {
|
||||
|
||||
|
||||
String runPrompt(RunPromptReqVo runPromptReqVo);
|
||||
|
||||
List<TaskResultResVo> queryHistory(String promptId);
|
||||
|
||||
String uploadImage(MultipartFile file) throws IOException;
|
||||
|
||||
void downloadView(String imageId, HttpServletResponse response) throws IOException;
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
package com.supervision.ai.service.hub.service.impl;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.supervision.ai.service.hub.dto.comfyui.ImageUploadDTO;
|
||||
import com.supervision.ai.service.hub.dto.comfyui.PromptRunDTO;
|
||||
import com.supervision.ai.service.hub.dto.comfyui.ResourceViewDTO;
|
||||
import com.supervision.ai.service.hub.service.ComfyUIApiService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class ComfyUIApiServiceImpl implements ComfyUIApiService {
|
||||
|
||||
@Value("${comfyUI.server.ip}")
|
||||
private String comfyUIServiceIp;
|
||||
|
||||
@Value("${comfyUI.server.port}")
|
||||
private String comfyUIServicePort;
|
||||
|
||||
private static final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
@Override
|
||||
public PromptRunDTO runPrompt(JSONObject prompt) {
|
||||
String url = "http://" + comfyUIServiceIp + ":" + comfyUIServicePort + "/prompt";
|
||||
log.info("comfyUI runPrompt 请求地址:{}",url);
|
||||
HttpRequest request = HttpUtil.createPost(url).body(prompt.toJSONString());
|
||||
try (HttpResponse execute = request.execute()){
|
||||
String body = execute.body();
|
||||
log.info("comfyUI runPrompt 请求结果:{}",body);
|
||||
if (execute.isOk()){
|
||||
try {
|
||||
return objectMapper.readValue(body, PromptRunDTO.class);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}else {
|
||||
throw new RuntimeException("/prompt请求失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> queryHistory(String promptId) {
|
||||
|
||||
String url = "http://" + comfyUIServiceIp + ":" + comfyUIServicePort + "/history" + (StrUtil.isEmpty(promptId)? "" : "/"+promptId);
|
||||
log.info("comfyUI queryHistory 请求地址:{}",url);
|
||||
try (HttpResponse execute = HttpUtil.createGet(url).execute()){
|
||||
if (execute.isOk()){
|
||||
String body = execute.body();
|
||||
try {
|
||||
return objectMapper.readValue(body, Map.class);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}else {
|
||||
throw new RuntimeException("/history请求失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageUploadDTO uploadImage(byte[] file, String fileName) {
|
||||
String url = "http://" + comfyUIServiceIp + ":" + comfyUIServicePort + "/upload/image";
|
||||
HttpRequest request = HttpUtil.createPost(url);
|
||||
request.form("image",file,fileName);
|
||||
try (HttpResponse execute = request.execute()){
|
||||
if (execute.isOk()){
|
||||
String body = execute.body();
|
||||
log.info("comfyUI uploadImage 请求结果:{}",body);
|
||||
try {
|
||||
return objectMapper.readValue(body, ImageUploadDTO.class);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}else {
|
||||
throw new RuntimeException("/upload/image请求失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceViewDTO downloadView(String imageId) {
|
||||
Assert.notEmpty(imageId,"imageId不能为空");
|
||||
String url = "http://" + comfyUIServiceIp + ":" + comfyUIServicePort + "/view?filename=" + imageId;
|
||||
log.info("comfyUI downloadImage 请求地址:{}",url);
|
||||
try (HttpResponse execute = HttpUtil.createGet(url).execute()){
|
||||
if (execute.isOk()){
|
||||
return new ResourceViewDTO(execute.getFileNameFromDisposition("filename"),
|
||||
execute.header("content-type"), execute.bodyBytes());
|
||||
}else {
|
||||
throw new RuntimeException("下载图片请求失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
package com.supervision.ai.service.hub.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.supervision.ai.service.hub.domain.ComfyuiPromptParam;
|
||||
import com.supervision.ai.service.hub.service.ComfyUIPromptParamService;
|
||||
import com.supervision.ai.service.hub.mapper.ComfyuiPromptParamMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
* @description 针对表【comfyui_prompt_param】的数据库操作Service实现
|
||||
* @createDate 2025-03-31 17:49:56
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class ComfyUIPromptParamServiceImpl extends ServiceImpl<ComfyuiPromptParamMapper, ComfyuiPromptParam>
|
||||
implements ComfyUIPromptParamService {
|
||||
|
||||
|
||||
@Override
|
||||
public boolean requiredCheck(Map<String, Object> params, String promptId) {
|
||||
Assert.notEmpty(promptId, "promptId不能为空");
|
||||
List<ComfyuiPromptParam> list = this.lambdaQuery()
|
||||
.eq(ComfyuiPromptParam::getPromptId, promptId).eq(ComfyuiPromptParam::getRequired, true).list();
|
||||
|
||||
return requiredCheck(params, list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requiredCheck(Map<String, Object> params, List<ComfyuiPromptParam> promptParamList) {
|
||||
if (CollUtil.isEmpty(promptParamList)) {
|
||||
return true;
|
||||
}
|
||||
if (CollUtil.isEmpty(params)){
|
||||
return false;
|
||||
}
|
||||
for (ComfyuiPromptParam comfyuiPromptParam : promptParamList) {
|
||||
Object value = params.get(comfyuiPromptParam.getParamKey());
|
||||
if (null == value || "".equals(value)) {
|
||||
log.error("参数{}为必填项,请检查",comfyuiPromptParam.getParamKey());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ComfyuiPromptParam> listByPromptId(String promptId) {
|
||||
return super.lambdaQuery().eq(ComfyuiPromptParam::getPromptId, promptId).list();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComfyuiPromptParam selectPromptParam(String paramKey, List<ComfyuiPromptParam> promptParamList) {
|
||||
if (CollUtil.isEmpty(promptParamList)){
|
||||
return null;
|
||||
}
|
||||
for (ComfyuiPromptParam comfyuiPromptParam : promptParamList) {
|
||||
if (StrUtil.equals(comfyuiPromptParam.getParamKey(), paramKey)){
|
||||
return comfyuiPromptParam;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,28 @@
|
||||
package com.supervision.ai.service.hub.service.impl;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.supervision.ai.service.hub.domain.ComfyuiPrompt;
|
||||
import com.supervision.ai.service.hub.service.ComfyUIPromptService;
|
||||
import com.supervision.ai.service.hub.mapper.ComfyuiPromptMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
* @description 针对表【comfyui_prompt(comfyui提示词表)】的数据库操作Service实现
|
||||
* @createDate 2025-03-31 17:49:56
|
||||
*/
|
||||
@Service
|
||||
public class ComfyUIPromptServiceImpl extends ServiceImpl<ComfyuiPromptMapper, ComfyuiPrompt>
|
||||
implements ComfyUIPromptService {
|
||||
|
||||
@Override
|
||||
public boolean promptExist(String promptId) {
|
||||
Assert.notEmpty(promptId,"promptId不能为空");
|
||||
return this.lambdaQuery().eq(ComfyuiPrompt::getId, promptId).exists();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,20 @@
|
||||
package com.supervision.ai.service.hub.vo.comfyui;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
public class RunPromptReqVo {
|
||||
|
||||
/**
|
||||
* 提示词ID
|
||||
*/
|
||||
private String promptId;
|
||||
|
||||
/**
|
||||
* 参数
|
||||
*/
|
||||
private Map<String,Object> params;
|
||||
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package com.supervision.ai.service.hub.vo.comfyui;
|
||||
|
||||
import lombok.Data;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 任务执行结果
|
||||
*/
|
||||
@Data
|
||||
public class TaskResultResVo {
|
||||
|
||||
private String promptId;
|
||||
|
||||
private boolean completed;
|
||||
|
||||
private List<String> images;
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
<?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.supervision.ai.service.hub.mapper.ComfyuiPromptMapper">
|
||||
|
||||
<resultMap id="BaseResultMap" type="com.supervision.ai.service.hub.domain.ComfyuiPrompt">
|
||||
<id property="id" column="id" jdbcType="VARCHAR"/>
|
||||
<result property="promptName" column="prompt_name" jdbcType="VARCHAR"/>
|
||||
<result property="promptType" column="prompt_type" jdbcType="VARCHAR"/>
|
||||
<result property="prompt" column="prompt" jdbcType="OTHER" typeHandler="com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler"/>
|
||||
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
|
||||
<result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
id,prompt_name,prompt_type,
|
||||
prompt,create_time,update_time
|
||||
</sql>
|
||||
</mapper>
|
@ -0,0 +1,22 @@
|
||||
<?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.supervision.ai.service.hub.mapper.ComfyuiPromptParamMapper">
|
||||
|
||||
<resultMap id="BaseResultMap" type="com.supervision.ai.service.hub.domain.ComfyuiPromptParam">
|
||||
<id property="id" column="id" jdbcType="VARCHAR"/>
|
||||
<result property="promptId" column="prompt_id" jdbcType="VARCHAR"/>
|
||||
<result property="paramKey" column="param_key" jdbcType="VARCHAR"/>
|
||||
<result property="paramType" column="param_type" jdbcType="INTEGER"/>
|
||||
<result property="required" column="required" jdbcType="BOOLEAN"/>
|
||||
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
|
||||
<result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
id,prompt_id,param_key,
|
||||
param_type,required,create_time,
|
||||
update_time
|
||||
</sql>
|
||||
</mapper>
|
@ -0,0 +1,60 @@
|
||||
package com.supervision.ai.service.hub;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.supervision.ai.service.hub.domain.ComfyuiPrompt;
|
||||
import com.supervision.ai.service.hub.dto.comfyui.ImageUploadDTO;
|
||||
import com.supervision.ai.service.hub.dto.comfyui.PromptRunDTO;
|
||||
import com.supervision.ai.service.hub.dto.comfyui.ResourceViewDTO;
|
||||
import com.supervision.ai.service.hub.service.ComfyUIApiService;
|
||||
import com.supervision.ai.service.hub.service.ComfyUIPromptService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@SpringBootTest
|
||||
public class ComfyUIApiServiceTest {
|
||||
|
||||
@Autowired
|
||||
private ComfyUIApiService comfyUIApiService;
|
||||
@Test
|
||||
public void uploadImageTest() {
|
||||
byte[] bytes = FileUtil.readBytes("C:\\Users\\Administrator\\Downloads\\Arya.png");
|
||||
ImageUploadDTO res = comfyUIApiService.uploadImage(bytes, "图片1");
|
||||
log.info(JSONUtil.toJsonStr(res));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void runPromptTest() {
|
||||
String prompt = "{\"prompt\":{\"4\":{\"inputs\":{\"ckpt_name\":\"sd_xl_base_1.0.safetensors\"},\"class_type\":\"CheckpointLoaderSimple\",\"_meta\":{\"title\":\"Load Checkpoint - BASE\"}},\"5\":{\"inputs\":{\"width\":1024,\"height\":1024,\"batch_size\":1},\"class_type\":\"EmptyLatentImage\",\"_meta\":{\"title\":\"空Latent图像\"}},\"6\":{\"inputs\":{\"text\":\"a cat under the snow with blue eyes, covered by snow, cinematic style, medium shot, professional photo, animal\",\"clip\":[\"4\",1]},\"class_type\":\"CLIPTextEncode\",\"_meta\":{\"title\":\"CLIP文本编码\"}},\"7\":{\"inputs\":{\"text\":\"text, watermark\",\"clip\":[\"4\",1]},\"class_type\":\"CLIPTextEncode\",\"_meta\":{\"title\":\"CLIP文本编码\"}},\"10\":{\"inputs\":{\"add_noise\":\"enable\",\"noise_seed\":2025,\"steps\":25,\"cfg\":8,\"sampler_name\":\"euler\",\"scheduler\":\"normal\",\"start_at_step\":0,\"end_at_step\":20,\"return_with_leftover_noise\":\"enable\",\"model\":[\"4\",0],\"positive\":[\"6\",0],\"negative\":[\"7\",0],\"latent_image\":[\"5\",0]},\"class_type\":\"KSamplerAdvanced\",\"_meta\":{\"title\":\"KSampler (Advanced) - BASE\"}},\"11\":{\"inputs\":{\"add_noise\":\"disable\",\"noise_seed\":0,\"steps\":25,\"cfg\":8,\"sampler_name\":\"euler\",\"scheduler\":\"normal\",\"start_at_step\":20,\"end_at_step\":10000,\"return_with_leftover_noise\":\"disable\",\"model\":[\"12\",0],\"positive\":[\"15\",0],\"negative\":[\"16\",0],\"latent_image\":[\"10\",0]},\"class_type\":\"KSamplerAdvanced\",\"_meta\":{\"title\":\"KSampler (Advanced) - REFINER\"}},\"12\":{\"inputs\":{\"ckpt_name\":\"sd_xl_refiner_1.0.safetensors\"},\"class_type\":\"CheckpointLoaderSimple\",\"_meta\":{\"title\":\"Load Checkpoint - REFINER\"}},\"15\":{\"inputs\":{\"text\":\"evening sunset scenery blue sky nature, glass bottle with a galaxy in it\",\"clip\":[\"12\",1]},\"class_type\":\"CLIPTextEncode\",\"_meta\":{\"title\":\"CLIP文本编码\"}},\"16\":{\"inputs\":{\"text\":\"text, watermark\",\"clip\":[\"12\",1]},\"class_type\":\"CLIPTextEncode\",\"_meta\":{\"title\":\"CLIP文本编码\"}},\"17\":{\"inputs\":{\"samples\":[\"11\",0],\"vae\":[\"12\",2]},\"class_type\":\"VAEDecode\",\"_meta\":{\"title\":\"VAE解码\"}},\"19\":{\"inputs\":{\"filename_prefix\":\"ComfyUI\",\"images\":[\"17\",0]},\"class_type\":\"SaveImage\",\"_meta\":{\"title\":\"保存图像\"}}}}";
|
||||
PromptRunDTO res = comfyUIApiService.runPrompt(JSON.parseObject(prompt));
|
||||
log.info(JSONUtil.toJsonStr(res));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queryHistoryTest() {
|
||||
Map<String, Object> res = comfyUIApiService.queryHistory("512f2ad2-2c7b-4227-8e52-86be11c3d5b9");
|
||||
log.info(JSONUtil.toJsonStr(res));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void downloadImageTest() {
|
||||
ResourceViewDTO resourceViewDTO = comfyUIApiService.downloadView("ComfyUI_00070_.png");
|
||||
FileUtil.writeBytes(resourceViewDTO.getContent(), "C:\\Users\\Administrator\\Downloads\\ComfyUI_00070_.png");
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private ComfyUIPromptService comfyUIPromptService;
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
ComfyuiPrompt comfyuiPrompt = comfyUIPromptService.getById("1");
|
||||
System.out.println(comfyuiPrompt);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue