From 25e13ed139c12418e2fb44fe3ffc13b78422f516 Mon Sep 17 00:00:00 2001 From: gitee Date: Fri, 18 Apr 2025 13:39:28 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E9=98=B6=E6=AE=B5?= =?UTF-8?q?=E6=80=A7=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ai/service/hub/aop/AuditLogDTO.java | 7 + .../service/hub/config/MinioClientConfig.java | 42 ++--- .../hub/constant/ComfyuiRunStatusEnum.java | 28 +++ .../hub/controller/ApplicationController.java | 79 +++++++++ .../hub/controller/AuditLogController.java | 55 ++++++ .../hub/controller/AuthController.java | 31 ++-- .../hub/controller/ComfyUIController.java | 48 ------ .../hub/controller/FileController.java | 72 ++++++++ .../hub/controller/ModelController.java | 99 +++++++++++ .../hub/controller/PermissionController.java | 98 +++++++++++ .../hub/controller/RoleController.java | 84 +++++++++ .../hub/controller/SysUserController.java | 38 ----- .../hub/controller/TaskController.java | 65 +++++++ .../hub/controller/UserController.java | 98 +++++++++++ .../ai/service/hub/domain/ComfyuiPrompt.java | 6 + .../ai/service/hub/domain/ComfyuiTask.java | 15 +- .../service/hub/domain/ComfyuiTaskParam.java | 2 +- .../ai/service/hub/domain/Permission.java | 65 +++++++ .../ai/service/hub/domain/SysApp.java | 8 + .../ai/service/hub/domain/SysRole.java | 8 +- .../service/hub/domain/SysRolePermission.java | 48 ++++++ .../ai/service/hub/domain/SysUser.java | 2 +- .../hub/dto/comfyui/ComfyUIPromptDTO.java | 35 ++++ .../dto/comfyui/ComfyUIPromptParamDTO.java | 57 +++++++ .../hub/dto/comfyui/ComfyUITaskResult.java | 15 ++ .../service/hub/dto/comfyui/ServerNode.java | 60 +++++++ .../ai/service/hub/dto/comfyui/TaskDTO.java | 103 +++++++++++ .../ai/service/hub/dto/sys/AppDTO.java | 29 ++++ .../ai/service/hub/dto/sys/FileDTO.java | 24 +++ .../ai/service/hub/dto/sys/PermissionDTO.java | 40 +++++ .../ai/service/hub/dto/sys/SysRoleDTO.java | 34 ++++ .../ai/service/hub/dto/sys/UserDTO.java | 34 ++++ .../service/hub/mapper/PermissionMapper.java | 18 ++ .../hub/mapper/SysRolePermissionMapper.java | 18 ++ .../service/hub/service/AuditLogService.java | 5 + .../hub/service/ComfyUIApiService.java | 6 +- .../service/hub/service/ComfyUIService.java | 34 +++- .../hub/service/ComfyUITaskScheduler.java | 160 ++++++++++++++++++ .../hub/service/ComfyuiTaskParamService.java | 4 + .../hub/service/ComfyuiTaskResultService.java | 3 + .../hub/service/ComfyuiTaskService.java | 8 + .../ai/service/hub/service/NodeManager.java | 15 ++ .../hub/service/PermissionService.java | 29 ++++ .../hub/service/SchedulingStrategy.java | 8 + .../ai/service/hub/service/SysAppService.java | 13 ++ .../service/hub/service/SysFileService.java | 14 ++ .../hub/service/SysRolePermissionService.java | 13 ++ .../service/hub/service/SysRoleService.java | 12 ++ .../service/hub/service/SysUserService.java | 12 ++ .../ai/service/hub/service/TaskService.java | 15 ++ .../hub/service/impl/AuditLogServiceImpl.java | 11 ++ .../service/impl/ComfyUIApiServiceImpl.java | 32 ++++ .../hub/service/impl/ComfyUINodeManager.java | 95 +++++++++++ .../hub/service/impl/ComfyUIServiceImpl.java | 72 +++++++- .../impl/ComfyuiTaskParamServiceImpl.java | 11 ++ .../impl/ComfyuiTaskResultServiceImpl.java | 10 ++ .../service/impl/ComfyuiTaskServiceImpl.java | 72 ++++++++ .../service/impl/FifoSchedulingStrategy.java | 39 +++++ .../service/impl/PermissionServiceImpl.java | 55 ++++++ .../hub/service/impl/SysAppServiceImpl.java | 28 ++- .../hub/service/impl/SysFileServiceImpl.java | 53 ++++++ .../impl/SysRolePermissionServiceImpl.java | 22 +++ .../hub/service/impl/SysRoleServiceImpl.java | 26 +++ .../hub/service/impl/SysUserServiceImpl.java | 27 +++ .../hub/service/impl/TaskServiceImpl.java | 39 +++++ .../ai/service/hub/vo/LoginReqVo.java | 14 ++ .../hub/vo/comfyui/TaskResultResVo.java | 15 +- src/main/resources/application.yml | 2 +- .../resources/mapper/ComfyuiPromptMapper.xml | 3 +- .../resources/mapper/ComfyuiTaskMapper.xml | 5 +- .../resources/mapper/PermissionMapper.xml | 24 +++ src/main/resources/mapper/SysAppMapper.xml | 1 + .../mapper/SysRolePermissionMapper.xml | 20 +++ .../ai/service/hub/ComfyUIApiServiceTest.java | 14 +- 74 files changed, 2340 insertions(+), 166 deletions(-) create mode 100644 src/main/java/com/supervision/ai/service/hub/constant/ComfyuiRunStatusEnum.java create mode 100644 src/main/java/com/supervision/ai/service/hub/controller/ApplicationController.java create mode 100644 src/main/java/com/supervision/ai/service/hub/controller/AuditLogController.java delete mode 100644 src/main/java/com/supervision/ai/service/hub/controller/ComfyUIController.java create mode 100644 src/main/java/com/supervision/ai/service/hub/controller/FileController.java create mode 100644 src/main/java/com/supervision/ai/service/hub/controller/ModelController.java create mode 100644 src/main/java/com/supervision/ai/service/hub/controller/PermissionController.java create mode 100644 src/main/java/com/supervision/ai/service/hub/controller/RoleController.java delete mode 100644 src/main/java/com/supervision/ai/service/hub/controller/SysUserController.java create mode 100644 src/main/java/com/supervision/ai/service/hub/controller/TaskController.java create mode 100644 src/main/java/com/supervision/ai/service/hub/controller/UserController.java create mode 100644 src/main/java/com/supervision/ai/service/hub/domain/Permission.java create mode 100644 src/main/java/com/supervision/ai/service/hub/domain/SysRolePermission.java create mode 100644 src/main/java/com/supervision/ai/service/hub/dto/comfyui/ComfyUIPromptDTO.java create mode 100644 src/main/java/com/supervision/ai/service/hub/dto/comfyui/ComfyUIPromptParamDTO.java create mode 100644 src/main/java/com/supervision/ai/service/hub/dto/comfyui/ComfyUITaskResult.java create mode 100644 src/main/java/com/supervision/ai/service/hub/dto/comfyui/ServerNode.java create mode 100644 src/main/java/com/supervision/ai/service/hub/dto/comfyui/TaskDTO.java create mode 100644 src/main/java/com/supervision/ai/service/hub/dto/sys/AppDTO.java create mode 100644 src/main/java/com/supervision/ai/service/hub/dto/sys/FileDTO.java create mode 100644 src/main/java/com/supervision/ai/service/hub/dto/sys/PermissionDTO.java create mode 100644 src/main/java/com/supervision/ai/service/hub/dto/sys/SysRoleDTO.java create mode 100644 src/main/java/com/supervision/ai/service/hub/dto/sys/UserDTO.java create mode 100644 src/main/java/com/supervision/ai/service/hub/mapper/PermissionMapper.java create mode 100644 src/main/java/com/supervision/ai/service/hub/mapper/SysRolePermissionMapper.java create mode 100644 src/main/java/com/supervision/ai/service/hub/service/ComfyUITaskScheduler.java create mode 100644 src/main/java/com/supervision/ai/service/hub/service/NodeManager.java create mode 100644 src/main/java/com/supervision/ai/service/hub/service/PermissionService.java create mode 100644 src/main/java/com/supervision/ai/service/hub/service/SchedulingStrategy.java create mode 100644 src/main/java/com/supervision/ai/service/hub/service/SysRolePermissionService.java create mode 100644 src/main/java/com/supervision/ai/service/hub/service/TaskService.java create mode 100644 src/main/java/com/supervision/ai/service/hub/service/impl/ComfyUINodeManager.java create mode 100644 src/main/java/com/supervision/ai/service/hub/service/impl/FifoSchedulingStrategy.java create mode 100644 src/main/java/com/supervision/ai/service/hub/service/impl/PermissionServiceImpl.java create mode 100644 src/main/java/com/supervision/ai/service/hub/service/impl/SysRolePermissionServiceImpl.java create mode 100644 src/main/java/com/supervision/ai/service/hub/service/impl/TaskServiceImpl.java create mode 100644 src/main/java/com/supervision/ai/service/hub/vo/LoginReqVo.java create mode 100644 src/main/resources/mapper/PermissionMapper.xml create mode 100644 src/main/resources/mapper/SysRolePermissionMapper.xml diff --git a/src/main/java/com/supervision/ai/service/hub/aop/AuditLogDTO.java b/src/main/java/com/supervision/ai/service/hub/aop/AuditLogDTO.java index 85487f4..d482bf0 100644 --- a/src/main/java/com/supervision/ai/service/hub/aop/AuditLogDTO.java +++ b/src/main/java/com/supervision/ai/service/hub/aop/AuditLogDTO.java @@ -102,6 +102,13 @@ public class AuditLogDTO implements Serializable { this.startTime = LocalDateTime.now(); } + public AuditLogDTO(String recordType, String userId, String appName, String ip) { + this.recordType = recordType; + this.userId = userId; + this.appName = appName; + this.ip = ip; + } + public AuditLog toAuditLog(){ AuditLog auditLog = new AuditLog(); auditLog.setId(id); diff --git a/src/main/java/com/supervision/ai/service/hub/config/MinioClientConfig.java b/src/main/java/com/supervision/ai/service/hub/config/MinioClientConfig.java index dd4c7aa..475ab7a 100644 --- a/src/main/java/com/supervision/ai/service/hub/config/MinioClientConfig.java +++ b/src/main/java/com/supervision/ai/service/hub/config/MinioClientConfig.java @@ -1,18 +1,17 @@ package com.supervision.ai.service.hub.config; +import io.minio.BucketExistsArgs; +import io.minio.MakeBucketArgs; import io.minio.MinioClient; -import io.minio.SetBucketLifecycleArgs; import io.minio.errors.*; -import io.minio.messages.*; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; - import java.io.IOException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; -import java.util.List; /** * Endpoint 对象存储服务的URL @@ -22,6 +21,7 @@ import java.util.List; * @author qmy * @since 1.0.0 */ +@Slf4j @Configuration public class MinioClientConfig { @@ -39,34 +39,20 @@ public class MinioClientConfig { @Bean @Primary - public MinioClient minioClient() { + public MinioClient minioClient() throws ServerException, InsufficientDataException, ErrorResponseException, + IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, + XmlParserException, InternalException { MinioClient client = MinioClient.builder() .endpoint(endpoint) .credentials(accessKey, secretKey) .build(); - try { - client.setBucketLifecycle( - SetBucketLifecycleArgs - .builder() - .config(new LifecycleConfiguration( - List.of( - new LifecycleRule(Status.ENABLED, - null, - new Expiration((ResponseDate) null, 1, null), - new RuleFilter("temp-"), - "TempFileDeleteRule", - null, - null, - null) - ) - )) - .bucket(bucketName) - .build() - ); - } catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidKeyException | - InvalidResponseException | IOException | NoSuchAlgorithmException | ServerException | - XmlParserException e) { - throw new RuntimeException(e); + + // 判断bucket是否存在,如果不存在则创建 + if (!client.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) { + log.info("未找到bucket:{},自动创建...", bucketName); + client.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build()); + } else { + log.info("bucket:{}已存在...", bucketName); } return client; } diff --git a/src/main/java/com/supervision/ai/service/hub/constant/ComfyuiRunStatusEnum.java b/src/main/java/com/supervision/ai/service/hub/constant/ComfyuiRunStatusEnum.java new file mode 100644 index 0000000..5b4aedc --- /dev/null +++ b/src/main/java/com/supervision/ai/service/hub/constant/ComfyuiRunStatusEnum.java @@ -0,0 +1,28 @@ +package com.supervision.ai.service.hub.constant; + +import lombok.Getter; + +@Getter +public enum ComfyuiRunStatusEnum { + + //未开始 + NOT_STARTED("0"), + + //进行中 + RUNNING("1"), + + //成功 + SUCCESS("2"), + + //失败 + FAILED("2"), + + //取消 + CANCELED("3"); + + private String status; + + ComfyuiRunStatusEnum(String status) { + this.status = status; + } +} diff --git a/src/main/java/com/supervision/ai/service/hub/controller/ApplicationController.java b/src/main/java/com/supervision/ai/service/hub/controller/ApplicationController.java new file mode 100644 index 0000000..73c945a --- /dev/null +++ b/src/main/java/com/supervision/ai/service/hub/controller/ApplicationController.java @@ -0,0 +1,79 @@ +package com.supervision.ai.service.hub.controller; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.supervision.ai.service.hub.dto.common.R; +import com.supervision.ai.service.hub.dto.sys.AppDTO; +import com.supervision.ai.service.hub.service.SysAppService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +/** + * 应用管理 + */ +@RestController +@RequestMapping("/app") +@RequiredArgsConstructor +public class ApplicationController { + + private final SysAppService sysAppService; + + /** + * 保存应用信息 + * @param appDTO + * @return + */ + @PostMapping("/save") + public R saveApp(@RequestBody AppDTO appDTO) { + String id = sysAppService.saveApp(appDTO); + return R.ok(id); + } + + /** + * 更新应用信息 + * @param appDTO + * @return + */ + @PostMapping("/update") + public R updateApp(@RequestBody AppDTO appDTO) { + Boolean success = sysAppService.updateApp(appDTO); + return R.ok(success); + } + + /** + * 删除应用信息 + * @param appDTO + * @return + */ + @PostMapping("/delete") + public R deleteApp(@RequestBody AppDTO appDTO) { + Boolean success = sysAppService.deleteApp(appDTO); + return R.ok(success); + } + + /** + * 分页查询应用信息 + * @param appName + * @param page + * @param pageSize + * @return + */ + @GetMapping("/pageList") + public R> pageList(@RequestParam(name = "appName", required = false) String appName, + @RequestParam (name = "page", required = false,defaultValue = "1") Integer page, + @RequestParam (name = "pageSize", required = false,defaultValue = "10") Integer pageSize) { + IPage appList = sysAppService.pageList(appName, page, pageSize); + return R.ok(appList); + } + + /** + * 根据id查询应用信息 + * @param id + * @return + */ + @PostMapping("/queryById") + public R queryById(@RequestParam String id) { + AppDTO app = sysAppService.queryById(id); + return R.ok(app); + } +} + diff --git a/src/main/java/com/supervision/ai/service/hub/controller/AuditLogController.java b/src/main/java/com/supervision/ai/service/hub/controller/AuditLogController.java new file mode 100644 index 0000000..b469e2c --- /dev/null +++ b/src/main/java/com/supervision/ai/service/hub/controller/AuditLogController.java @@ -0,0 +1,55 @@ +package com.supervision.ai.service.hub.controller; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.supervision.ai.service.hub.aop.AuditLogDTO; +import com.supervision.ai.service.hub.dto.common.R; +import com.supervision.ai.service.hub.service.AuditLogService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +/** + * 审计日志管理 + */ +@RestController +@RequestMapping("/auditLog") +@RequiredArgsConstructor +public class AuditLogController { + + private final AuditLogService auditLogService; + + /** + * 分页查询审计日志 + * @param recordType + * @param userId + * @param appName + * @param ip + * @param page + * @param pageSize + * @return + */ + @RequestMapping("/pageList") + public R> pageList(@RequestParam("recordType") String recordType, + @RequestParam("userId") String userId, + @RequestParam("appName") String appName, + @RequestParam("ip") String ip, + @RequestParam (name = "page", required = false,defaultValue = "1") Integer page, + @RequestParam (name = "pageSize", required = false,defaultValue = "10") Integer pageSize) { + AuditLogDTO auditLogDTO = new AuditLogDTO(recordType,userId,appName,ip); + IPage list = auditLogService.pageList(auditLogDTO,page,pageSize); + return R.ok(list); + } + + + /** + * 跟据id查询审计日志 + * @param id + * @return + */ + @RequestMapping("/queryById") + public R queryById(@RequestParam(name="id") String id) { + AuditLogDTO auditLogDTO = auditLogService.queryById(id); + return R.ok(auditLogDTO); + } +} diff --git a/src/main/java/com/supervision/ai/service/hub/controller/AuthController.java b/src/main/java/com/supervision/ai/service/hub/controller/AuthController.java index c9a53d1..726d8c4 100644 --- a/src/main/java/com/supervision/ai/service/hub/controller/AuthController.java +++ b/src/main/java/com/supervision/ai/service/hub/controller/AuthController.java @@ -1,14 +1,13 @@ package com.supervision.ai.service.hub.controller; +import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.StrUtil; +import com.supervision.ai.service.hub.dto.common.R; import com.supervision.ai.service.hub.service.impl.AuthService; -import lombok.Data; +import com.supervision.ai.service.hub.vo.LoginReqVo; import lombok.RequiredArgsConstructor; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; - -import java.util.HashMap; -import java.util.Map; +import java.util.List; @RestController @RequestMapping("/auth") @@ -18,20 +17,10 @@ public class AuthController { private final AuthService authService; @PostMapping("/login") - public ResponseEntity login(@RequestBody LoginRequest request) { - try { - String token = authService.login(request.getAppName(), request.getPassword()); - Map response = new HashMap<>(); - response.put("token", token); - return ResponseEntity.ok(response); - } catch (RuntimeException e) { - return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(e.getMessage()); - } - } - - @Data - public static class LoginRequest { - private String appName; - private String password; + public R login(@RequestBody LoginReqVo loginReqVo) { + Assert.notEmpty(List.of(loginReqVo.getUsername(), loginReqVo.getAppName()), "appName和userName不能同时为空"); + String name = StrUtil.isNotEmpty(loginReqVo.getAppName()) ? loginReqVo.getAppName() : loginReqVo.getUsername(); + String token = authService.login(name, loginReqVo.getPassword()); + return R.ok(token); } } diff --git a/src/main/java/com/supervision/ai/service/hub/controller/ComfyUIController.java b/src/main/java/com/supervision/ai/service/hub/controller/ComfyUIController.java deleted file mode 100644 index dae0148..0000000 --- a/src/main/java/com/supervision/ai/service/hub/controller/ComfyUIController.java +++ /dev/null @@ -1,48 +0,0 @@ -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("/model") -@RequiredArgsConstructor -public class ComfyUIController { - - private final ComfyUIService comfyUIService; - - /** - * 运行prompt - * @param runPromptReqVo prompt信息 - * @return - */ - @PostMapping("/run") - public R runPrompt(@RequestBody RunPromptReqVo runPromptReqVo) { - - String taskId = comfyUIService.runPrompt(runPromptReqVo); - return R.ok(taskId); - } - - @GetMapping("/getTaskById") - public R> queryHistory(@RequestParam(name = "taskId", required = false) String taskId) { - List taskResultResVos = comfyUIService.queryHistory(taskId); - return R.ok(taskResultResVos); - } - - @PostMapping("/uploadImage") - public R 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); - } -} diff --git a/src/main/java/com/supervision/ai/service/hub/controller/FileController.java b/src/main/java/com/supervision/ai/service/hub/controller/FileController.java new file mode 100644 index 0000000..ff1e3fb --- /dev/null +++ b/src/main/java/com/supervision/ai/service/hub/controller/FileController.java @@ -0,0 +1,72 @@ +package com.supervision.ai.service.hub.controller; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.supervision.ai.service.hub.dto.common.R; +import com.supervision.ai.service.hub.dto.sys.FileDTO; +import com.supervision.ai.service.hub.service.SysFileService; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +/** + * 文件管理 + */ +@RestController +@RequestMapping("/file") +@RequiredArgsConstructor +public class FileController { + + private final SysFileService fileService; + + /** + * 上传文件 + * @param file 文件 + * @return + */ + @PostMapping("/upload") + public R upload(@RequestPart("file") MultipartFile file) { + + String fileId = fileService.upload(file); + return R.ok(fileId); + } + + + /** + * 分页查询文件列表 + * @param fileName + * @param fileType + * @param page + * @param pageSize + * @return + */ + @PostMapping("/pageList") + public R> pageList(@RequestParam(name = "fileName", required = false) String fileName, + @RequestParam(name = "fileType", required = false) String fileType, + @RequestParam (name = "page", required = false,defaultValue = "1") Integer page, + @RequestParam (name = "pageSize", required = false,defaultValue = "10") Integer pageSize) { + IPage list = fileService.pageList(fileName, fileType, page, pageSize); + return R.ok(list); + } + + /** + * 查询文件详情 + * @param id 文件ID + * @return + */ + @PostMapping("/queryById") + public R queryById(@RequestParam(name = "id") String id) { + FileDTO file = fileService.queryById(id); + return R.ok(file); + } + + /** + * 下载文件 + * @param fileId + * @param response + */ + @GetMapping("/downLoad") + public void downLoad(@RequestParam("fileId") String fileId, HttpServletResponse response) { + fileService.downLoad(fileId,response); + } +} diff --git a/src/main/java/com/supervision/ai/service/hub/controller/ModelController.java b/src/main/java/com/supervision/ai/service/hub/controller/ModelController.java new file mode 100644 index 0000000..8d8bdd6 --- /dev/null +++ b/src/main/java/com/supervision/ai/service/hub/controller/ModelController.java @@ -0,0 +1,99 @@ +package com.supervision.ai.service.hub.controller; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.supervision.ai.service.hub.dto.comfyui.ComfyUIPromptDTO; +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; + +@RestController +@RequestMapping("/model") +@RequiredArgsConstructor +public class ModelController { + + private final ComfyUIService comfyUIService; + + + /** + * 保存模型 + * @param comfyUIPromptDTO 模型信息 + * @return + */ + @PostMapping("/save") + public R saveModel(@RequestBody ComfyUIPromptDTO comfyUIPromptDTO) { + String modelId = comfyUIService.saveModel(comfyUIPromptDTO); + return R.ok(modelId); + } + + /** + * 更新模型 + * @param comfyUIPromptDTO 模型信息 + * @return + */ + @PostMapping("/update") + public R updateModel(@RequestBody ComfyUIPromptDTO comfyUIPromptDTO) { + Boolean success = comfyUIService.updateModel(comfyUIPromptDTO); + return R.ok(success); + } + + @PostMapping("/delete") + public R deleteModel(@RequestBody ComfyUIPromptDTO comfyUIPromptDTO) { + Boolean success = comfyUIService.deleteModel(comfyUIPromptDTO); + return R.ok(success); + } + + @GetMapping("/queryById") + public R queryById(@RequestParam(name = "id") String id) { + ComfyUIPromptDTO comfyUIPromptDTO = comfyUIService.queryById(id); + return R.ok(comfyUIPromptDTO); + } + + @PostMapping("/pageList") + public R> pageList(@RequestParam(name = "promptName", required = false) String promptName, + @RequestParam(name = "promptType", required = false) String promptType, + @RequestParam(name = "page", defaultValue = "1") Integer page, + @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) { + IPage pageList = comfyUIService.pageList(promptName, promptType, page, pageSize); + return R.ok(pageList); + } + + /** + * 执行任务 + * @param runPromptReqVo prompt信息 + * @return + */ + @PostMapping("/executeTask") + public R executeTask(@RequestBody RunPromptReqVo runPromptReqVo) { + + String taskId = comfyUIService.executeTask(runPromptReqVo); + return R.ok(taskId); + } + + @GetMapping("/getTaskById") + public R getTaskById(@RequestParam(name = "taskId", required = false) String taskId) { + TaskResultResVo taskResultResVos = comfyUIService.getTaskById(taskId); + return R.ok(taskResultResVos); + } + + @GetMapping("/queryTaskPageList") + public R> queryTaskPageList(@RequestParam(name = "taskId", required = false) String taskId) { + IPage taskResultResVos = comfyUIService.queryHistory(taskId); + return R.ok(taskResultResVos); + } + + @PostMapping("/uploadImage") + public R 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); + } +} diff --git a/src/main/java/com/supervision/ai/service/hub/controller/PermissionController.java b/src/main/java/com/supervision/ai/service/hub/controller/PermissionController.java new file mode 100644 index 0000000..d317a3f --- /dev/null +++ b/src/main/java/com/supervision/ai/service/hub/controller/PermissionController.java @@ -0,0 +1,98 @@ +package com.supervision.ai.service.hub.controller; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.supervision.ai.service.hub.dto.sys.PermissionDTO; +import com.supervision.ai.service.hub.dto.common.R; +import com.supervision.ai.service.hub.service.PermissionService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 权限管理 + */ +@RestController +@RequestMapping("/permission") +@RequiredArgsConstructor +public class PermissionController { + + private final PermissionService permissionService; + + /** + * 保存权限 + * @param permissionDTO 权限信息 + * @return 权限ID + */ + @PostMapping("/save") + public R savePermission(@RequestBody PermissionDTO permissionDTO) { + + String permissionId = permissionService.savePermission(permissionDTO); + return R.ok(permissionId); + } + + + /** + * 更新权限 + * @param permissionDTO + * @return + */ + @PostMapping("/update") + public R updatePermission(@RequestBody PermissionDTO permissionDTO) { + + Boolean success = permissionService.updatePermission(permissionDTO); + return R.ok(success); + } + + /** + * 删除权限 + * @param permissionDTO + * @return + */ + @PostMapping("/delete") + public R deletePermission(@RequestBody PermissionDTO permissionDTO) { + + Boolean success = permissionService.deletePermission(permissionDTO.getId()); + return R.ok(success); + } + + /** + * 查询权限 + * @param type 权限类型 + * @return 返回一个树形结构 + */ + @GetMapping("/query") + public R> queryPermission(@RequestParam (name = "type", required = false) String type) { + + List list = permissionService.queryPermission(type); + return R.ok(list); + } + + /** + * 分页查询权限 + * @param permissionName + * @param page + * @param pageSize + * @return + */ + @PostMapping("/pageList") + public R> pageList(@RequestParam (name = "permissionName", required = false) String permissionName, + @RequestParam (name = "page", required = false) Integer page, + @RequestParam(name = "pageSize", required = false) Integer pageSize) { + + IPage list = permissionService.pageList(permissionName, page, pageSize); + return R.ok(list); + } + + /** + * 根据ID查询权限 + * @param id + * @return + */ + @GetMapping("/queryById") + public R queryById(@RequestParam(name = "id") String id) { + + PermissionDTO permissionDTO = permissionService.queryById(id); + return R.ok(permissionDTO); + } +} diff --git a/src/main/java/com/supervision/ai/service/hub/controller/RoleController.java b/src/main/java/com/supervision/ai/service/hub/controller/RoleController.java new file mode 100644 index 0000000..c6075a2 --- /dev/null +++ b/src/main/java/com/supervision/ai/service/hub/controller/RoleController.java @@ -0,0 +1,84 @@ +package com.supervision.ai.service.hub.controller; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.supervision.ai.service.hub.dto.common.R; +import com.supervision.ai.service.hub.dto.sys.SysRoleDTO; +import com.supervision.ai.service.hub.service.SysRoleService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +/** + * 角色管理 + */ +@RestController +@RequestMapping("/role") +@RequiredArgsConstructor +public class RoleController { + + private final SysRoleService roleService; + + /** + * 保存角色信息 + * @param roleDTO 权限信息 + * @return 权限ID + */ + @PostMapping("/save") + public R saveRole(@RequestBody SysRoleDTO roleDTO) { + + String roleId = roleService.saveRole(roleDTO); + return R.ok(roleId); + } + + + /** + * 更新角色 + * @param roleDTO + * @return + */ + @PostMapping("/update") + public R updateRole(@RequestBody SysRoleDTO roleDTO) { + + Boolean success = roleService.updateRole(roleDTO); + return R.ok(success); + } + + /** + * 删除角色 + * @param roleDTO + * @return + */ + @PostMapping("/delete") + public R deleteRole(@RequestBody SysRoleDTO roleDTO) { + + Boolean success = roleService.deleteRole(roleDTO.getId()); + return R.ok(success); + } + + + /** + * 分页查询角色 + * @param roleName + * @param page + * @param pageSize + * @return + */ + @PostMapping("/pageList") + public R> pageList(@RequestParam (name = "roleName", required = false) String roleName, + @RequestParam (name = "page", defaultValue = "1", required = false) Integer page, + @RequestParam(name = "pageSize",defaultValue = "10", required = false) Integer pageSize ) { + + IPage list = roleService.pageList(roleName, page, pageSize); + return R.ok(list); + } + + /** + * 根据id查询角色 + * @return + */ + @GetMapping("/queryById") + public R queryById(@RequestParam(name = "id") String id) { + + SysRoleDTO sysRoleDTO = roleService.queryById(id); + return R.ok(sysRoleDTO); + } +} diff --git a/src/main/java/com/supervision/ai/service/hub/controller/SysUserController.java b/src/main/java/com/supervision/ai/service/hub/controller/SysUserController.java deleted file mode 100644 index 2454037..0000000 --- a/src/main/java/com/supervision/ai/service/hub/controller/SysUserController.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.supervision.ai.service.hub.controller; - -import com.supervision.ai.service.hub.domain.SysUser; -import com.supervision.ai.service.hub.service.SysUserService; -import lombok.RequiredArgsConstructor; -import org.springframework.http.ResponseEntity; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - * 用户控制器,用于处理用户相关接口 - */ -@RestController -@RequestMapping("/user") -@RequiredArgsConstructor -public class SysUserController { - - private final SysUserService sysUserService; - - /** - * 查看当前用户详情接口 - * - * @return 当前登录用户的详细信息,如果用户不存在,则返回 404 - */ - @GetMapping("/me") - public ResponseEntity getCurrentUserDetails() { - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - String username = authentication.getName(); - SysUser user = sysUserService.getByUsername(username); - if (user == null) { - return ResponseEntity.status(404).body("用户不存在"); - } - return ResponseEntity.ok(user); - } -} diff --git a/src/main/java/com/supervision/ai/service/hub/controller/TaskController.java b/src/main/java/com/supervision/ai/service/hub/controller/TaskController.java new file mode 100644 index 0000000..de8559e --- /dev/null +++ b/src/main/java/com/supervision/ai/service/hub/controller/TaskController.java @@ -0,0 +1,65 @@ +package com.supervision.ai.service.hub.controller; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.supervision.ai.service.hub.dto.common.R; +import com.supervision.ai.service.hub.dto.comfyui.TaskDTO; +import com.supervision.ai.service.hub.service.TaskService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * + * 任务管理 + */ +@RestController +@RequestMapping("/task") +@RequiredArgsConstructor +public class TaskController { + + private final TaskService taskService; + + /** + * 分页查询任务信息 + * @param taskName + * @param taskType + * @param status + * @param page + * @param pageSize + * @return + */ + @GetMapping("/pageList") + public R> pageList(@RequestParam(name = "taskName", required = false) String taskName, + @RequestParam(name = "taskType", required = false) String taskType, + @RequestParam(name = "status", required = false) String status, + @RequestParam(name = "page", defaultValue = "1") Integer page, + @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) { + IPage pageList = taskService.pageList(taskName, taskType, status, page, pageSize); + return R.ok(pageList); + } + + + + /** + * 取消(终止)任务 + * @param taskIds + * @return + */ + @PostMapping("/cancel") + public R cancelTask(List taskIds) { + Boolean success = taskService.cancelTask(taskIds); + return R.ok(success); + } + + /** + * 重试任务 + * @param taskIds + * @return + */ + @PostMapping("/retry") + public R retryTask(List taskIds) { + Boolean success = taskService.retryTask(taskIds); + return R.ok(success); + } +} diff --git a/src/main/java/com/supervision/ai/service/hub/controller/UserController.java b/src/main/java/com/supervision/ai/service/hub/controller/UserController.java new file mode 100644 index 0000000..8f52a14 --- /dev/null +++ b/src/main/java/com/supervision/ai/service/hub/controller/UserController.java @@ -0,0 +1,98 @@ +package com.supervision.ai.service.hub.controller; + +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.supervision.ai.service.hub.domain.SysUser; +import com.supervision.ai.service.hub.dto.common.R; +import com.supervision.ai.service.hub.dto.sys.UserDTO; +import com.supervision.ai.service.hub.service.SysUserService; +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 用户控制器,用于处理用户相关接口 + */ +@RestController +@RequestMapping("/user") +@RequiredArgsConstructor +public class UserController { + + private final SysUserService sysUserService; + + /** + * 查看当前用户详情接口 + * + * @return 当前登录用户的详细信息,如果用户不存在,则返回 404 + */ + @GetMapping("/me") + public R getCurrentUserDetails() { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + String username = authentication.getName(); + SysUser user = sysUserService.getByUsername(username); + Assert.notNull(user, "用户不存在"); + return R.ok(user); + } + + /** + * 保存用户信息 + * @param user 用户信息 + * @return + */ + @PostMapping("/save") + public R saveUser(UserDTO user) { + String userId = sysUserService.saveUser(user); + return R.ok(userId); + } + + /** + * 更新用户信息 + * @param user 用户信息 + * @return + */ + @PostMapping("/update") + public R updateUser(UserDTO user) { + Boolean success = sysUserService.updateUser(user); + return R.ok(success); + } + + /** + * 删除用户 + * @param user 用户信息 + * @return + */ + @PostMapping("/delete") + public R deleteUser(UserDTO user) { + Boolean success = sysUserService.deleteUser(user.getId()); + return R.ok(success); + } + + /** + * 查询用户列表 + * @param userName 用户名 + * @param page 页码 + * @param pageSize 每页数量 + * @return 用户列表 + */ + @GetMapping("/pageList") + public R> queryList(@RequestParam(name = "userName", required = false) String userName, + @RequestParam (name = "page", required = false,defaultValue = "1") Integer page, + @RequestParam (name = "pageSize", required = false,defaultValue = "10") Integer pageSize) { + IPage list = sysUserService.pageList(userName, page, pageSize); + return R.ok(list); + } + + /** + * 根据ID查询用户 + * @param id 用户ID + * @return 用户信息 + */ + @GetMapping("/queryById") + public R queryById(@RequestParam(name = "id") String id) { + UserDTO userDTO = sysUserService.queryById(id); + return R.ok(userDTO); + } +} diff --git a/src/main/java/com/supervision/ai/service/hub/domain/ComfyuiPrompt.java b/src/main/java/com/supervision/ai/service/hub/domain/ComfyuiPrompt.java index 78ebfbb..230a3a8 100644 --- a/src/main/java/com/supervision/ai/service/hub/domain/ComfyuiPrompt.java +++ b/src/main/java/com/supervision/ai/service/hub/domain/ComfyuiPrompt.java @@ -38,6 +38,12 @@ public class ComfyuiPrompt implements Serializable { @TableField(typeHandler = FastjsonTypeHandler.class) private JSONObject prompt; + + /** + * 提示词图片id + */ + private String iconFileId; + /** * 创建人id */ diff --git a/src/main/java/com/supervision/ai/service/hub/domain/ComfyuiTask.java b/src/main/java/com/supervision/ai/service/hub/domain/ComfyuiTask.java index 0f3305b..164886c 100644 --- a/src/main/java/com/supervision/ai/service/hub/domain/ComfyuiTask.java +++ b/src/main/java/com/supervision/ai/service/hub/domain/ComfyuiTask.java @@ -1,10 +1,12 @@ package com.supervision.ai.service.hub.domain; +import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.annotation.*; import java.io.Serializable; -import java.time.LocalDate; import java.time.LocalDateTime; + +import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler; import lombok.Data; /** @@ -43,18 +45,25 @@ public class ComfyuiTask implements Serializable { /** * 开始运行时间 */ - private LocalDate runStartTime; + private LocalDateTime runStartTime; /** * 运行结束时间 */ - private LocalDate runEndTime; + private LocalDateTime runEndTime; /** * webhook url */ private String webHook; + private String comfyuiTaskId; + + @TableField(typeHandler = FastjsonTypeHandler.class) + private JSONObject prompt; + + private String comfyuiServer; + /** * 创建人id */ diff --git a/src/main/java/com/supervision/ai/service/hub/domain/ComfyuiTaskParam.java b/src/main/java/com/supervision/ai/service/hub/domain/ComfyuiTaskParam.java index d2c6ec7..ba72675 100644 --- a/src/main/java/com/supervision/ai/service/hub/domain/ComfyuiTaskParam.java +++ b/src/main/java/com/supervision/ai/service/hub/domain/ComfyuiTaskParam.java @@ -60,7 +60,7 @@ public class ComfyuiTaskParam implements Serializable { private String paramType; /** - * 组件类型 + * 组件类型 1:input 2:select 3:textarea 4. image 5:checkbox 6:radio */ private String componentType; diff --git a/src/main/java/com/supervision/ai/service/hub/domain/Permission.java b/src/main/java/com/supervision/ai/service/hub/domain/Permission.java new file mode 100644 index 0000000..9d3617e --- /dev/null +++ b/src/main/java/com/supervision/ai/service/hub/domain/Permission.java @@ -0,0 +1,65 @@ +package com.supervision.ai.service.hub.domain; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.time.LocalDateTime; +import lombok.Data; + +/** + * 权限表 + * @TableName permission + */ +@TableName(value ="permission") +@Data +public class Permission implements Serializable { + /** + * 权限id + */ + @TableId + private String id; + + /** + * 名称 + */ + private String name; + + /** + * 类型 0:菜单权限 1:接口权限 + */ + private String type; + + /** + * 权限码值 + */ + private String code; + + /** + * 父级id + */ + private String parentId; + + /** + * + */ + private String createUserId; + + /** + * + */ + private LocalDateTime createTime; + + /** + * + */ + private LocalDateTime updateTime; + + /** + * + */ + private String updateUserId; + + @TableField(exist = false) + private static final long serialVersionUID = 1L; +} \ No newline at end of file diff --git a/src/main/java/com/supervision/ai/service/hub/domain/SysApp.java b/src/main/java/com/supervision/ai/service/hub/domain/SysApp.java index d01ee72..b46abf0 100644 --- a/src/main/java/com/supervision/ai/service/hub/domain/SysApp.java +++ b/src/main/java/com/supervision/ai/service/hub/domain/SysApp.java @@ -4,6 +4,8 @@ import com.baomidou.mybatisplus.annotation.*; import java.io.Serializable; import java.time.LocalDateTime; +import java.util.List; +import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler; import lombok.Data; /** @@ -33,6 +35,12 @@ public class SysApp implements Serializable { */ private Integer status; + /** + * 权限url集合 + */ + @TableField(typeHandler = FastjsonTypeHandler.class) + private List scopes; + /** * 创建人id */ diff --git a/src/main/java/com/supervision/ai/service/hub/domain/SysRole.java b/src/main/java/com/supervision/ai/service/hub/domain/SysRole.java index 0ac93a0..d2aa50c 100644 --- a/src/main/java/com/supervision/ai/service/hub/domain/SysRole.java +++ b/src/main/java/com/supervision/ai/service/hub/domain/SysRole.java @@ -14,22 +14,22 @@ import lombok.Data; @Data public class SysRole implements Serializable { /** - * + * 主键 */ private String id; /** - * + * 角色名 */ private String roleName; /** - * + * 角色描述 */ private String roleDesc; /** - * + * 角色code */ private String roleCode; diff --git a/src/main/java/com/supervision/ai/service/hub/domain/SysRolePermission.java b/src/main/java/com/supervision/ai/service/hub/domain/SysRolePermission.java new file mode 100644 index 0000000..8d7cb82 --- /dev/null +++ b/src/main/java/com/supervision/ai/service/hub/domain/SysRolePermission.java @@ -0,0 +1,48 @@ +package com.supervision.ai.service.hub.domain; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.time.LocalDateTime; +import lombok.Data; + +/** + * + * @TableName sys_role_permission + */ +@TableName(value ="sys_role_permission") +@Data +public class SysRolePermission implements Serializable { + /** + * 角色id + */ + private String rId; + + /** + * 权限id + */ + private String pId; + + /** + * + */ + private String createUserId; + + /** + * + */ + private LocalDateTime createTime; + + /** + * + */ + private LocalDateTime updateTime; + + /** + * + */ + private String updateUserId; + + @TableField(exist = false) + private static final long serialVersionUID = 1L; +} \ No newline at end of file diff --git a/src/main/java/com/supervision/ai/service/hub/domain/SysUser.java b/src/main/java/com/supervision/ai/service/hub/domain/SysUser.java index 0c82bcf..c2b3e36 100644 --- a/src/main/java/com/supervision/ai/service/hub/domain/SysUser.java +++ b/src/main/java/com/supervision/ai/service/hub/domain/SysUser.java @@ -20,7 +20,7 @@ public class SysUser implements Serializable { private String id; /** - * + * 应用id */ private String appId; diff --git a/src/main/java/com/supervision/ai/service/hub/dto/comfyui/ComfyUIPromptDTO.java b/src/main/java/com/supervision/ai/service/hub/dto/comfyui/ComfyUIPromptDTO.java new file mode 100644 index 0000000..0febdea --- /dev/null +++ b/src/main/java/com/supervision/ai/service/hub/dto/comfyui/ComfyUIPromptDTO.java @@ -0,0 +1,35 @@ +package com.supervision.ai.service.hub.dto.comfyui; + +import com.alibaba.fastjson.JSONObject; +import lombok.Data; + +import java.util.List; + +@Data +public class ComfyUIPromptDTO { + + private String id; + + /** + * 提示词名 + */ + private String promptName; + + /** + * 提示词类型 0:文生图 1:图生图 2:图生视频 + */ + private String promptType; + + /** + * 提示词 + */ + private JSONObject prompt; + + /** + * 提示词图片id + */ + private String iconFileId; + + + private List params; +} diff --git a/src/main/java/com/supervision/ai/service/hub/dto/comfyui/ComfyUIPromptParamDTO.java b/src/main/java/com/supervision/ai/service/hub/dto/comfyui/ComfyUIPromptParamDTO.java new file mode 100644 index 0000000..2293962 --- /dev/null +++ b/src/main/java/com/supervision/ai/service/hub/dto/comfyui/ComfyUIPromptParamDTO.java @@ -0,0 +1,57 @@ +package com.supervision.ai.service.hub.dto.comfyui; + +import lombok.Data; + +@Data +public class ComfyUIPromptParamDTO { + + /** + * 主键id + */ + private String id; + + /** + * 提示词id + */ + private String promptId; + + /** + * 参数key + */ + private String paramKey; + + /** + * 参数json路径,用户后端设置模板中的值 + */ + private String paramPath; + + /** + * 参数类型 0:整数 1:浮点型 2:字符串 3:布尔值 + */ + private Integer paramType; + + /** + * 组件类型,用于前端展示 + */ + private String componentType; + + /** + * 标签,用于前端展示 + */ + private String label; + + /** + * 是否必填 + */ + private Boolean required; + + /** + * 默认值,用于前端展示 + */ + private String defaultValue; + + /** + * 值 + */ + private Object value; +} diff --git a/src/main/java/com/supervision/ai/service/hub/dto/comfyui/ComfyUITaskResult.java b/src/main/java/com/supervision/ai/service/hub/dto/comfyui/ComfyUITaskResult.java new file mode 100644 index 0000000..bf326f0 --- /dev/null +++ b/src/main/java/com/supervision/ai/service/hub/dto/comfyui/ComfyUITaskResult.java @@ -0,0 +1,15 @@ +package com.supervision.ai.service.hub.dto.comfyui; + +import lombok.Data; + +@Data +public class ComfyUITaskResult { + + private String id; + + private String taskId; + + private String fileId; + + private String fileName; +} diff --git a/src/main/java/com/supervision/ai/service/hub/dto/comfyui/ServerNode.java b/src/main/java/com/supervision/ai/service/hub/dto/comfyui/ServerNode.java new file mode 100644 index 0000000..2205eb8 --- /dev/null +++ b/src/main/java/com/supervision/ai/service/hub/dto/comfyui/ServerNode.java @@ -0,0 +1,60 @@ +package com.supervision.ai.service.hub.dto.comfyui; + +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.concurrent.CopyOnWriteArrayList; + +@Data +public class ServerNode { + + private String id; + + private String host; + + private int port; + + /** + * 失败次数 + */ + private int failureCount; + + /** + * 正在运行的任务数量 + */ + private int runningTaskCount; + + private LocalDateTime lastSelectedTime; + + /** + * 正在运行的任务列表 + */ + private CopyOnWriteArrayList runningTasks = new CopyOnWriteArrayList<>(); + public ServerNode() { + } + + public ServerNode(String id, String host, int port, int failureCount) { + this.id = id; + this.host = host; + this.port = port; + this.failureCount = failureCount; + } + + public void incrementFailureCount() { + this.failureCount++; + this.lastSelectedTime = LocalDateTime.now(); + } + + public void resetFailureCount() { + this.failureCount = 0; + this.lastSelectedTime = LocalDateTime.now(); + } + + public void addRunningTask(TaskDTO task) { + this.runningTasks.add(task); + } + + public void removeRunningTask(TaskDTO task) { + this.runningTasks.remove(task); + } +} diff --git a/src/main/java/com/supervision/ai/service/hub/dto/comfyui/TaskDTO.java b/src/main/java/com/supervision/ai/service/hub/dto/comfyui/TaskDTO.java new file mode 100644 index 0000000..a3e43b1 --- /dev/null +++ b/src/main/java/com/supervision/ai/service/hub/dto/comfyui/TaskDTO.java @@ -0,0 +1,103 @@ +package com.supervision.ai.service.hub.dto.comfyui; + +import cn.hutool.core.collection.CollUtil; +import com.alibaba.fastjson.JSONObject; +import com.supervision.ai.service.hub.domain.ComfyuiTask; +import com.supervision.ai.service.hub.domain.ComfyuiTaskParam; +import com.supervision.ai.service.hub.domain.ComfyuiTaskResult; +import lombok.Data; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@Data +public class TaskDTO { + + private String id; + + /** + * 提示词id + */ + private String promptId; + + /** + * comfyui平台任务id + */ + private String comfyuiTaskId; + + + private String comfyuiServer;; + + /** + * 创建人id + */ + private String userId; + + /** + * 应用id + */ + private String appId; + + /** + * 运行状态 0未开始、1进行中、2成功、3失败 + */ + private String runStatus; + + /** + * 开始运行时间 + */ + private LocalDateTime runStartTime; + + /** + * 运行结束时间 + */ + private LocalDateTime runEndTime; + + /** + * webhook url + */ + private String webHook; + + private JSONObject prompt; + + + private List params = new ArrayList<>(); + + + private List results = new ArrayList<>(); + + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + + public TaskDTO() { + } + + public TaskDTO(ComfyuiTask task, List params, List taskResults) { + this.id = task.getId(); + this.promptId = task.getPromptId(); + this.comfyuiTaskId = task.getComfyuiTaskId(); + this.comfyuiServer = task.getComfyuiServer(); + this.userId = task.getUserId(); + this.appId = task.getAppId(); + this.runStatus = task.getRunStatus(); + this.runStartTime = task.getRunStartTime(); + this.runEndTime = task.getRunEndTime(); + this.webHook = task.getWebHook(); + this.prompt = task.getPrompt(); + this.createTime = task.getCreateTime(); + this.params = params; + if (CollUtil.isNotEmpty(taskResults)){ + for (ComfyuiTaskResult taskResult : taskResults) { + ComfyUITaskResult result = new ComfyUITaskResult(); + result.setId(taskResult.getId()); + result.setTaskId(taskResult.getTaskId()); + result.setFileId(taskResult.getResultFileId()); + this.results.add(result); + } + } + } +} diff --git a/src/main/java/com/supervision/ai/service/hub/dto/sys/AppDTO.java b/src/main/java/com/supervision/ai/service/hub/dto/sys/AppDTO.java new file mode 100644 index 0000000..1920a22 --- /dev/null +++ b/src/main/java/com/supervision/ai/service/hub/dto/sys/AppDTO.java @@ -0,0 +1,29 @@ +package com.supervision.ai.service.hub.dto.sys; + +import lombok.Data; + +import java.util.List; + +@Data +public class AppDTO { + + private String id; + + /** + * 应用名 + */ + private String appName; + + /** + * 密码 + */ + private String password; + + /** + * 状态 0:禁用 1:启用 + */ + private Integer status; + + + private List scopes; +} diff --git a/src/main/java/com/supervision/ai/service/hub/dto/sys/FileDTO.java b/src/main/java/com/supervision/ai/service/hub/dto/sys/FileDTO.java new file mode 100644 index 0000000..c9fa936 --- /dev/null +++ b/src/main/java/com/supervision/ai/service/hub/dto/sys/FileDTO.java @@ -0,0 +1,24 @@ +package com.supervision.ai.service.hub.dto.sys; + +import lombok.Data; + +@Data +public class FileDTO { + + private String id; + + /** + * 文件名 + */ + private String fileName; + + /** + * 文件大小 + */ + private String fileSize; + + /** + * 文件类型 + */ + private String fileType; +} diff --git a/src/main/java/com/supervision/ai/service/hub/dto/sys/PermissionDTO.java b/src/main/java/com/supervision/ai/service/hub/dto/sys/PermissionDTO.java new file mode 100644 index 0000000..b265a60 --- /dev/null +++ b/src/main/java/com/supervision/ai/service/hub/dto/sys/PermissionDTO.java @@ -0,0 +1,40 @@ +package com.supervision.ai.service.hub.dto.sys; + +import lombok.Data; + +import java.util.List; + + +@Data +public class PermissionDTO { + + /** + * 权限id + */ + private String id; + + /** + * 名称 + */ + private String name; + + /** + * 类型 0:菜单权限 1:接口权限 + */ + private String type; + + /** + * 权限码值 全局唯一不允许重复 + */ + private String code; + + /** + * 父级id + */ + private String parentId; + + + + private List children; + +} diff --git a/src/main/java/com/supervision/ai/service/hub/dto/sys/SysRoleDTO.java b/src/main/java/com/supervision/ai/service/hub/dto/sys/SysRoleDTO.java new file mode 100644 index 0000000..4face3d --- /dev/null +++ b/src/main/java/com/supervision/ai/service/hub/dto/sys/SysRoleDTO.java @@ -0,0 +1,34 @@ +package com.supervision.ai.service.hub.dto.sys; + +import lombok.Data; + +import java.util.List; + +@Data +public class SysRoleDTO { + + /** + * 主键 + */ + private String id; + + /** + * 角色名 + */ + private String roleName; + + /** + * 角色描述 + */ + private String roleDesc; + + /** + * 角色code + */ + private String roleCode; + + /** + * 权限集合 + */ + private List permissionList; +} diff --git a/src/main/java/com/supervision/ai/service/hub/dto/sys/UserDTO.java b/src/main/java/com/supervision/ai/service/hub/dto/sys/UserDTO.java new file mode 100644 index 0000000..ee2e659 --- /dev/null +++ b/src/main/java/com/supervision/ai/service/hub/dto/sys/UserDTO.java @@ -0,0 +1,34 @@ +package com.supervision.ai.service.hub.dto.sys; + +import lombok.Data; + +import java.util.List; + +@Data +public class UserDTO { + + private String id; + + /** + *应用id + */ + private String appId; + + /** + * 用户名 + */ + private String userName; + + + private String password; + + + /** + * 状态 0:禁用 1:启用 + */ + private String status; + /** + * 角色集合 + */ + private List roleList; +} diff --git a/src/main/java/com/supervision/ai/service/hub/mapper/PermissionMapper.java b/src/main/java/com/supervision/ai/service/hub/mapper/PermissionMapper.java new file mode 100644 index 0000000..4e811ce --- /dev/null +++ b/src/main/java/com/supervision/ai/service/hub/mapper/PermissionMapper.java @@ -0,0 +1,18 @@ +package com.supervision.ai.service.hub.mapper; + +import com.supervision.ai.service.hub.domain.Permission; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** +* @author Administrator +* @description 针对表【permission(权限表)】的数据库操作Mapper +* @createDate 2025-04-14 16:01:14 +* @Entity com.supervision.ai.service.hub.domain.Permission +*/ +public interface PermissionMapper extends BaseMapper { + +} + + + + diff --git a/src/main/java/com/supervision/ai/service/hub/mapper/SysRolePermissionMapper.java b/src/main/java/com/supervision/ai/service/hub/mapper/SysRolePermissionMapper.java new file mode 100644 index 0000000..efa8cc4 --- /dev/null +++ b/src/main/java/com/supervision/ai/service/hub/mapper/SysRolePermissionMapper.java @@ -0,0 +1,18 @@ +package com.supervision.ai.service.hub.mapper; + +import com.supervision.ai.service.hub.domain.SysRolePermission; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** +* @author Administrator +* @description 针对表【sys_role_permission】的数据库操作Mapper +* @createDate 2025-04-14 16:01:04 +* @Entity com.supervision.ai.service.hub.domain.SysRolePermission +*/ +public interface SysRolePermissionMapper extends BaseMapper { + +} + + + + diff --git a/src/main/java/com/supervision/ai/service/hub/service/AuditLogService.java b/src/main/java/com/supervision/ai/service/hub/service/AuditLogService.java index 3264236..8818de8 100644 --- a/src/main/java/com/supervision/ai/service/hub/service/AuditLogService.java +++ b/src/main/java/com/supervision/ai/service/hub/service/AuditLogService.java @@ -1,5 +1,6 @@ package com.supervision.ai.service.hub.service; +import com.baomidou.mybatisplus.core.metadata.IPage; import com.supervision.ai.service.hub.aop.AuditLogDTO; import com.supervision.ai.service.hub.domain.AuditLog; import com.baomidou.mybatisplus.extension.service.IService; @@ -12,4 +13,8 @@ import com.baomidou.mybatisplus.extension.service.IService; public interface AuditLogService extends IService { void saveAuditLog(AuditLogDTO auditLogDTO); + + IPage pageList(AuditLogDTO auditLogDTO, Integer page, Integer pageSize); + + AuditLogDTO queryById(String id); } diff --git a/src/main/java/com/supervision/ai/service/hub/service/ComfyUIApiService.java b/src/main/java/com/supervision/ai/service/hub/service/ComfyUIApiService.java index 17ecd87..1edbe43 100644 --- a/src/main/java/com/supervision/ai/service/hub/service/ComfyUIApiService.java +++ b/src/main/java/com/supervision/ai/service/hub/service/ComfyUIApiService.java @@ -6,6 +6,7 @@ import com.supervision.ai.service.hub.dto.comfyui.PromptRunDTO; import com.supervision.ai.service.hub.dto.comfyui.ResourceViewDTO; import java.util.Map; +import java.util.function.Consumer; public interface ComfyUIApiService { @@ -19,11 +20,14 @@ public interface ComfyUIApiService { /** * 查询执行历史 * @param promptId 提示词id,为空时查询全部 - * @return + * @return 经过多次测试发现返回结果只有为空或者completed=true的情况 */ Map queryHistory(String promptId); + void asyncQueryHistory(String promptId, Consumer callback); + + ImageUploadDTO uploadImage(byte[] file, String fileName); ResourceViewDTO downloadView(String imageId); diff --git a/src/main/java/com/supervision/ai/service/hub/service/ComfyUIService.java b/src/main/java/com/supervision/ai/service/hub/service/ComfyUIService.java index 11ece9a..0d50197 100644 --- a/src/main/java/com/supervision/ai/service/hub/service/ComfyUIService.java +++ b/src/main/java/com/supervision/ai/service/hub/service/ComfyUIService.java @@ -1,20 +1,50 @@ package com.supervision.ai.service.hub.service; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.supervision.ai.service.hub.dto.comfyui.ComfyUIPromptDTO; 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; +import java.util.Map; public interface ComfyUIService { - String runPrompt(RunPromptReqVo runPromptReqVo); + String executeTask(RunPromptReqVo runPromptReqVo); - List queryHistory(String promptId); + IPage queryHistory(String promptId); + + /** + * 从返回的结果中判断任务是否完成 + * @param result 任务执行的结果 + * @return + */ + boolean taskIsCompleted(Map result); + + /** + * 从返回的结果中获取图片列表 + * @param result 任务执行的结果 + * @return + */ + List getImageList(Map result); String uploadImage(MultipartFile file) throws IOException; void downloadView(String imageId, HttpServletResponse response) throws IOException; + + String saveModel(ComfyUIPromptDTO comfyUIPromptDTO); + + Boolean updateModel(ComfyUIPromptDTO comfyUIPromptDTO); + + Boolean deleteModel(ComfyUIPromptDTO comfyUIPromptDTO); + + ComfyUIPromptDTO queryById(String id); + + IPage pageList(String promptName, String promptType, Integer page, Integer pageSize); + + TaskResultResVo getTaskById(String taskId); + } diff --git a/src/main/java/com/supervision/ai/service/hub/service/ComfyUITaskScheduler.java b/src/main/java/com/supervision/ai/service/hub/service/ComfyUITaskScheduler.java new file mode 100644 index 0000000..326abc9 --- /dev/null +++ b/src/main/java/com/supervision/ai/service/hub/service/ComfyUITaskScheduler.java @@ -0,0 +1,160 @@ +package com.supervision.ai.service.hub.service; + +import cn.hutool.core.bean.BeanPath; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.alibaba.fastjson.JSONObject; +import com.supervision.ai.service.hub.constant.ComfyuiParamTypeEnum; +import com.supervision.ai.service.hub.constant.ComfyuiRunStatusEnum; +import com.supervision.ai.service.hub.domain.ComfyuiTaskParam; +import com.supervision.ai.service.hub.dto.comfyui.*; +import com.supervision.ai.service.hub.dto.sys.FileDTO; +import com.supervision.ai.service.hub.service.impl.ComfyUIApiServiceImpl; +import lombok.extern.slf4j.Slf4j; +import java.time.LocalDateTime; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.stream.Collectors; + +@Slf4j +public class ComfyUITaskScheduler { + + private final NodeManager nodeManager; + private final SchedulingStrategy strategy; + + private final Map comfyUIApiServiceMap = new ConcurrentHashMap<>(); + + private ComfyUIService comfyUIService; + + private ComfyuiTaskService comfyUITaskService; + + private SysFileService sysFileService; + + + public ComfyUITaskScheduler(NodeManager nodeManager, SchedulingStrategy strategy) { + this.nodeManager = nodeManager; + this.strategy = strategy; + } + + /** + * 执行任务 + */ + void executeTask() { + TaskDTO task = strategy.selectNextTask(); + if (task == null) { + log.info("executeTask:没有获取到可用的任务...."); + return; + } + + while (true) { + ServerNode node = nodeManager.selectAvailableNode(); + if (null == node) { + log.error("executeTask:没有获取到可用的节点...."); + return; + } + // 运行提示词 + try { + boolean success = runPrompt(node, task); + if (success) { + log.info("executeTask:任务:{}执行成功", task.getId()); + break; + } else { + // 失败后重新选择节点 + node = nodeManager.selectAvailableNode(); + if (null == node) { + log.error("executeTask:没有获取到可用的节点...."); + break; + } + } + } catch (Exception e) { + //todo: 如果是链接异常设置节点 + throw new RuntimeException(e); + } + + } + } + + + private boolean runPrompt(ServerNode node,TaskDTO task){ + ComfyUIApiService comfyUIApiService = this.getComfyUIApiService(node); + + // 设置参数内容 + JSONObject prompt = task.getPrompt(); + for (ComfyuiTaskParam param : task.getParams()) { + if (StrUtil.equals("4",param.getComponentType())){ + // 上传图片 + FileDTO fileDTO = sysFileService.queryById(param.getValue()); + byte[] bytes = sysFileService.downloadFile(param.getValue()); + ImageUploadDTO imageUploadDTO = comfyUIApiService.uploadImage(bytes, param.getValue() + "." + fileDTO.getFileType()); + param.setValue(imageUploadDTO.getName()); + } + ComfyuiParamTypeEnum comfyuiParamTypeEnum = ComfyuiParamTypeEnum.getByCode(Integer.parseInt(param.getParamType())); + Object value = comfyuiParamTypeEnum.coverType(param.getValue()); + log.info("设置参数key:{},参数value:{}", param.getParamKey(), value); + BeanPath.create(param.getParamKey()).set(prompt, value); + } + // 运行提示词 + PromptRunDTO promptRunDTO = comfyUIApiService.runPrompt(prompt); + Map error = promptRunDTO.getError(); + + if (CollUtil.isNotEmpty(error)){ + // 执行失败 + String errorMessage = (String) error.get("message"); + log.error("executeTask:任务:{}执行失败,错误信息:{}",task.getId(),errorMessage); + nodeManager.markNodeFailed(node.getId()); + return false; + }else { + // 任务提交成功 + nodeManager.recoverNode(node.getId()); + node.addRunningTask(task); + task.setComfyuiServer(node.getHost()+":"+node.getPort()); + task.setRunStatus(ComfyuiRunStatusEnum.RUNNING.getStatus()); + task.setRunStartTime(LocalDateTime.now()); + comfyUITaskService.updateTaskResult(task); + return true; + } + } + + /** + * 查询任务结果 + */ + void queryTaskResult() { + List serverNodes = nodeManager.listAllNodes(); + for (ServerNode serverNode : serverNodes) { + CopyOnWriteArrayList runningTasks = serverNode.getRunningTasks(); + for (TaskDTO taskDTO : runningTasks) { + ComfyUIApiService comfyUIApiService = this.getComfyUIApiService(serverNode); + comfyUIApiService.asyncQueryHistory(taskDTO.getComfyuiTaskId(), result -> { + Map taskResult = JSONUtil.toBean(result, HashMap.class); + Map thisResult = (Map) taskResult.get(taskDTO.getComfyuiTaskId()); + boolean finish = comfyUIService.taskIsCompleted(thisResult); + if (finish){ + // 移除运行中的任务 + serverNode.removeRunningTask(taskDTO); + List imageList = comfyUIService.getImageList(thisResult); + List comfyUITaskResults = imageList.stream().map(imageId -> { + ComfyUITaskResult comfyUITaskResult = new ComfyUITaskResult(); + comfyUITaskResult.setTaskId(taskDTO.getId()); + comfyUITaskResult.setFileName(imageId); + return comfyUITaskResult; + }).collect(Collectors.toList()); + taskDTO.setResults(comfyUITaskResults); + taskDTO.setRunStatus(ComfyuiRunStatusEnum.SUCCESS.getStatus()); + taskDTO.setRunEndTime(LocalDateTime.now()); + comfyUITaskService.updateTaskResult(taskDTO); + comfyUITaskService.notifyWebhook(taskDTO); + } + }); + } + } + } + + private ComfyUIApiService getComfyUIApiService(ServerNode node) { + return comfyUIApiServiceMap.computeIfAbsent(node.getId(), + id -> new ComfyUIApiServiceImpl(node.getHost(), String.valueOf(node.getPort()))); + } +} diff --git a/src/main/java/com/supervision/ai/service/hub/service/ComfyuiTaskParamService.java b/src/main/java/com/supervision/ai/service/hub/service/ComfyuiTaskParamService.java index 33a5c7e..8ceeb76 100644 --- a/src/main/java/com/supervision/ai/service/hub/service/ComfyuiTaskParamService.java +++ b/src/main/java/com/supervision/ai/service/hub/service/ComfyuiTaskParamService.java @@ -3,6 +3,8 @@ package com.supervision.ai.service.hub.service; import com.supervision.ai.service.hub.domain.ComfyuiTaskParam; import com.baomidou.mybatisplus.extension.service.IService; +import java.util.List; + /** * @author Administrator * @description 针对表【comfyui_task_param(comfyui任务参数表)】的数据库操作Service @@ -10,4 +12,6 @@ import com.baomidou.mybatisplus.extension.service.IService; */ public interface ComfyuiTaskParamService extends IService { + + List listByTaskIds(List taskIds); } diff --git a/src/main/java/com/supervision/ai/service/hub/service/ComfyuiTaskResultService.java b/src/main/java/com/supervision/ai/service/hub/service/ComfyuiTaskResultService.java index b8adb5d..43e053d 100644 --- a/src/main/java/com/supervision/ai/service/hub/service/ComfyuiTaskResultService.java +++ b/src/main/java/com/supervision/ai/service/hub/service/ComfyuiTaskResultService.java @@ -2,6 +2,7 @@ package com.supervision.ai.service.hub.service; import com.supervision.ai.service.hub.domain.ComfyuiTaskResult; import com.baomidou.mybatisplus.extension.service.IService; +import java.util.List; /** * @author Administrator @@ -10,4 +11,6 @@ import com.baomidou.mybatisplus.extension.service.IService; */ public interface ComfyuiTaskResultService extends IService { + + List listByTaskIds(List taskIds); } diff --git a/src/main/java/com/supervision/ai/service/hub/service/ComfyuiTaskService.java b/src/main/java/com/supervision/ai/service/hub/service/ComfyuiTaskService.java index f8986ea..62f8551 100644 --- a/src/main/java/com/supervision/ai/service/hub/service/ComfyuiTaskService.java +++ b/src/main/java/com/supervision/ai/service/hub/service/ComfyuiTaskService.java @@ -2,6 +2,8 @@ package com.supervision.ai.service.hub.service; import com.supervision.ai.service.hub.domain.ComfyuiTask; import com.baomidou.mybatisplus.extension.service.IService; +import com.supervision.ai.service.hub.dto.comfyui.TaskDTO; +import java.util.List; /** * @author Administrator @@ -10,4 +12,10 @@ import com.baomidou.mybatisplus.extension.service.IService; */ public interface ComfyuiTaskService extends IService { + void updateTaskResult(TaskDTO taskDTO); + + List queryNotStartedTask(int size); + + + void notifyWebhook(TaskDTO taskDTO); } diff --git a/src/main/java/com/supervision/ai/service/hub/service/NodeManager.java b/src/main/java/com/supervision/ai/service/hub/service/NodeManager.java new file mode 100644 index 0000000..0f2ae18 --- /dev/null +++ b/src/main/java/com/supervision/ai/service/hub/service/NodeManager.java @@ -0,0 +1,15 @@ +package com.supervision.ai.service.hub.service; + +import com.supervision.ai.service.hub.dto.comfyui.ServerNode; + +import java.util.List; + +public interface NodeManager { + ServerNode selectAvailableNode(); + void markNodeFailed(String nodeId); + void recoverNode(String nodeId); + + List listAllNodes(); + + void addNode(ServerNode node); +} diff --git a/src/main/java/com/supervision/ai/service/hub/service/PermissionService.java b/src/main/java/com/supervision/ai/service/hub/service/PermissionService.java new file mode 100644 index 0000000..254be0c --- /dev/null +++ b/src/main/java/com/supervision/ai/service/hub/service/PermissionService.java @@ -0,0 +1,29 @@ +package com.supervision.ai.service.hub.service; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.supervision.ai.service.hub.domain.Permission; +import com.baomidou.mybatisplus.extension.service.IService; +import com.supervision.ai.service.hub.dto.sys.PermissionDTO; + +import java.util.List; + +/** +* @author Administrator +* @description 针对表【permission(权限表)】的数据库操作Service +* @createDate 2025-04-14 16:01:14 +*/ +public interface PermissionService extends IService { + + String savePermission(PermissionDTO permissionDTO); + + Boolean updatePermission(PermissionDTO permissionDTO); + + Boolean deletePermission(String id); + + List queryPermission(String type); + + + IPage pageList(String permissionName, Integer page, Integer pageSize); + + PermissionDTO queryById(String id); +} diff --git a/src/main/java/com/supervision/ai/service/hub/service/SchedulingStrategy.java b/src/main/java/com/supervision/ai/service/hub/service/SchedulingStrategy.java new file mode 100644 index 0000000..979415b --- /dev/null +++ b/src/main/java/com/supervision/ai/service/hub/service/SchedulingStrategy.java @@ -0,0 +1,8 @@ +package com.supervision.ai.service.hub.service; + +import com.supervision.ai.service.hub.dto.comfyui.TaskDTO; + +public interface SchedulingStrategy { + + TaskDTO selectNextTask(); +} diff --git a/src/main/java/com/supervision/ai/service/hub/service/SysAppService.java b/src/main/java/com/supervision/ai/service/hub/service/SysAppService.java index 71c26c9..af43f71 100644 --- a/src/main/java/com/supervision/ai/service/hub/service/SysAppService.java +++ b/src/main/java/com/supervision/ai/service/hub/service/SysAppService.java @@ -1,7 +1,9 @@ package com.supervision.ai.service.hub.service; +import com.baomidou.mybatisplus.core.metadata.IPage; import com.supervision.ai.service.hub.domain.SysApp; import com.baomidou.mybatisplus.extension.service.IService; +import com.supervision.ai.service.hub.dto.sys.AppDTO; /** * @author Administrator @@ -16,4 +18,15 @@ public interface SysAppService extends IService { * @return SysApp */ SysApp getByAppName(String appName); + + String saveApp(AppDTO appDTO); + + Boolean updateApp(AppDTO appDTO); + + Boolean deleteApp(AppDTO appDTO); + + IPage pageList(String appName, Integer page, Integer pageSize); + + AppDTO queryById(String id); + } diff --git a/src/main/java/com/supervision/ai/service/hub/service/SysFileService.java b/src/main/java/com/supervision/ai/service/hub/service/SysFileService.java index f0c5928..eb8be3a 100644 --- a/src/main/java/com/supervision/ai/service/hub/service/SysFileService.java +++ b/src/main/java/com/supervision/ai/service/hub/service/SysFileService.java @@ -1,7 +1,11 @@ package com.supervision.ai.service.hub.service; +import com.baomidou.mybatisplus.core.metadata.IPage; import com.supervision.ai.service.hub.domain.SysFile; import com.baomidou.mybatisplus.extension.service.IService; +import com.supervision.ai.service.hub.dto.sys.FileDTO; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.web.multipart.MultipartFile; /** * @author Administrator @@ -10,4 +14,14 @@ import com.baomidou.mybatisplus.extension.service.IService; */ public interface SysFileService extends IService { + String upload(MultipartFile file); + + IPage pageList(String fileName, String fileType ,Integer page, Integer pageSize); + + FileDTO queryById(String id); + + void downLoad(String fileId, HttpServletResponse response); + + + byte[] downloadFile(String fileId); } diff --git a/src/main/java/com/supervision/ai/service/hub/service/SysRolePermissionService.java b/src/main/java/com/supervision/ai/service/hub/service/SysRolePermissionService.java new file mode 100644 index 0000000..f95bace --- /dev/null +++ b/src/main/java/com/supervision/ai/service/hub/service/SysRolePermissionService.java @@ -0,0 +1,13 @@ +package com.supervision.ai.service.hub.service; + +import com.supervision.ai.service.hub.domain.SysRolePermission; +import com.baomidou.mybatisplus.extension.service.IService; + +/** +* @author Administrator +* @description 针对表【sys_role_permission】的数据库操作Service +* @createDate 2025-04-14 16:01:04 +*/ +public interface SysRolePermissionService extends IService { + +} diff --git a/src/main/java/com/supervision/ai/service/hub/service/SysRoleService.java b/src/main/java/com/supervision/ai/service/hub/service/SysRoleService.java index e5e20b5..8980fa8 100644 --- a/src/main/java/com/supervision/ai/service/hub/service/SysRoleService.java +++ b/src/main/java/com/supervision/ai/service/hub/service/SysRoleService.java @@ -1,7 +1,9 @@ package com.supervision.ai.service.hub.service; +import com.baomidou.mybatisplus.core.metadata.IPage; import com.supervision.ai.service.hub.domain.SysRole; import com.baomidou.mybatisplus.extension.service.IService; +import com.supervision.ai.service.hub.dto.sys.SysRoleDTO; /** * @author Administrator @@ -10,4 +12,14 @@ import com.baomidou.mybatisplus.extension.service.IService; */ public interface SysRoleService extends IService { + String saveRole(SysRoleDTO roleDTO); + + Boolean updateRole(SysRoleDTO roleDTO); + + Boolean deleteRole(String id); + + IPage pageList(String roleName, Integer page, Integer pageSize); + + SysRoleDTO queryById(String id); + } diff --git a/src/main/java/com/supervision/ai/service/hub/service/SysUserService.java b/src/main/java/com/supervision/ai/service/hub/service/SysUserService.java index 0c48816..8aecd39 100644 --- a/src/main/java/com/supervision/ai/service/hub/service/SysUserService.java +++ b/src/main/java/com/supervision/ai/service/hub/service/SysUserService.java @@ -1,7 +1,9 @@ package com.supervision.ai.service.hub.service; +import com.baomidou.mybatisplus.core.metadata.IPage; import com.supervision.ai.service.hub.domain.SysUser; import com.baomidou.mybatisplus.extension.service.IService; +import com.supervision.ai.service.hub.dto.sys.UserDTO; /** * @author Administrator @@ -17,4 +19,14 @@ public interface SysUserService extends IService { * @return SysUser */ SysUser getByUsername(String username); + + UserDTO queryById(String id); + + String saveUser(UserDTO user); + + Boolean updateUser(UserDTO user); + + Boolean deleteUser(String id); + + IPage pageList(String userName, Integer page, Integer pageSize); } diff --git a/src/main/java/com/supervision/ai/service/hub/service/TaskService.java b/src/main/java/com/supervision/ai/service/hub/service/TaskService.java new file mode 100644 index 0000000..e716941 --- /dev/null +++ b/src/main/java/com/supervision/ai/service/hub/service/TaskService.java @@ -0,0 +1,15 @@ +package com.supervision.ai.service.hub.service; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.supervision.ai.service.hub.dto.comfyui.TaskDTO; +import java.util.List; + +public interface TaskService { + IPage pageList(String taskName, String taskType, String status, Integer page, Integer pageSize); + + Boolean suspendTask(List taskIds); + + Boolean cancelTask(List taskIds); + + Boolean retryTask(List taskIds); +} diff --git a/src/main/java/com/supervision/ai/service/hub/service/impl/AuditLogServiceImpl.java b/src/main/java/com/supervision/ai/service/hub/service/impl/AuditLogServiceImpl.java index 24c614b..2637c43 100644 --- a/src/main/java/com/supervision/ai/service/hub/service/impl/AuditLogServiceImpl.java +++ b/src/main/java/com/supervision/ai/service/hub/service/impl/AuditLogServiceImpl.java @@ -1,5 +1,6 @@ package com.supervision.ai.service.hub.service.impl; +import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.supervision.ai.service.hub.aop.AuditLogDTO; import com.supervision.ai.service.hub.domain.AuditLog; @@ -25,6 +26,16 @@ public class AuditLogServiceImpl extends ServiceImpl AuditLog auditLog = auditLogDTO.toAuditLog(); this.save(auditLog); } + + @Override + public IPage pageList(AuditLogDTO auditLogDTO, Integer page, Integer pageSize) { + return null; + } + + @Override + public AuditLogDTO queryById(String id) { + return null; + } } diff --git a/src/main/java/com/supervision/ai/service/hub/service/impl/ComfyUIApiServiceImpl.java b/src/main/java/com/supervision/ai/service/hub/service/impl/ComfyUIApiServiceImpl.java index 6c874e4..90f48e2 100644 --- a/src/main/java/com/supervision/ai/service/hub/service/impl/ComfyUIApiServiceImpl.java +++ b/src/main/java/com/supervision/ai/service/hub/service/impl/ComfyUIApiServiceImpl.java @@ -15,7 +15,11 @@ 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.net.URI; +import java.net.http.HttpClient; import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.function.Consumer; @Slf4j @Service @@ -29,6 +33,14 @@ public class ComfyUIApiServiceImpl implements ComfyUIApiService { private static final ObjectMapper objectMapper = new ObjectMapper(); + public ComfyUIApiServiceImpl() { + } + + public ComfyUIApiServiceImpl(String comfyUIServiceIp, String comfyUIServicePort) { + this.comfyUIServiceIp = comfyUIServiceIp; + this.comfyUIServicePort = comfyUIServicePort; + } + @Override public PromptRunDTO runPrompt(JSONObject prompt) { String url = "http://" + comfyUIServiceIp + ":" + comfyUIServicePort + "/prompt"; @@ -54,6 +66,8 @@ public class ComfyUIApiServiceImpl implements ComfyUIApiService { String url = "http://" + comfyUIServiceIp + ":" + comfyUIServicePort + "/history" + (StrUtil.isEmpty(promptId)? "" : "/"+promptId); log.info("comfyUI queryHistory 请求地址:{}",url); + HttpRequest header = HttpUtil.createGet(url).header("Accept", "application/json"); + HttpResponse response = header.executeAsync(); try (HttpResponse execute = HttpUtil.createGet(url).execute()){ if (execute.isOk()){ String body = execute.body(); @@ -68,6 +82,24 @@ public class ComfyUIApiServiceImpl implements ComfyUIApiService { } } + @Override + public void asyncQueryHistory(String promptId, Consumer callback) { + + String url = "http://" + comfyUIServiceIp + ":" + comfyUIServicePort + "/history" + (StrUtil.isEmpty(promptId)? "" : "/"+promptId); + java.net.http.HttpClient client = HttpClient.newHttpClient(); + java.net.http.HttpRequest request = java.net.http.HttpRequest.newBuilder() + .uri(URI.create(url)) + .build(); + CompletableFuture> future = client.sendAsync(request, java.net.http.HttpResponse.BodyHandlers.ofString()); + + future.thenApply(java.net.http.HttpResponse::body) + .thenAccept(callback) + .exceptionally(ex -> { + log.error("asyncQueryHistory:发送请求失败", ex); + return null; + }); + } + @Override public ImageUploadDTO uploadImage(byte[] file, String fileName) { String url = "http://" + comfyUIServiceIp + ":" + comfyUIServicePort + "/upload/image"; diff --git a/src/main/java/com/supervision/ai/service/hub/service/impl/ComfyUINodeManager.java b/src/main/java/com/supervision/ai/service/hub/service/impl/ComfyUINodeManager.java new file mode 100644 index 0000000..616e18c --- /dev/null +++ b/src/main/java/com/supervision/ai/service/hub/service/impl/ComfyUINodeManager.java @@ -0,0 +1,95 @@ +package com.supervision.ai.service.hub.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import com.supervision.ai.service.hub.dto.comfyui.ServerNode; +import com.supervision.ai.service.hub.service.NodeManager; +import lombok.extern.slf4j.Slf4j; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +@Slf4j +public class ComfyUINodeManager implements NodeManager { + + private List serverNodes = new ArrayList<>(); + + private int retryTimeThread = 60; + @Override + public ServerNode selectAvailableNode() { + // 优先选择空闲且没有失败次数的节点 + // 如果所有的节点都没有失败次数,则选择正在运行次数最小的节点(本次规则中选择运行次数为0的节点) + // 如果所有的节点都失效,则选择一个静默时间最长的节点 + ServerNode selectedNode = null; + for (ServerNode node : serverNodes) { + log.info("开始查找存活且空闲的节点...."); + if (node.getRunningTaskCount() == 0 && node.getFailureCount() == 0) { + selectedNode = node; + log.info("查找到存活且空闲的节点:host:{}:{}....",node.getId(),node.getPort()); + node.setLastSelectedTime(LocalDateTime.now()); + break; + } + } + if (null == selectedNode){ + log.warn("没有查找到存活且空闲的节点,开始查找已经离线的节点...."); + List failServerNode = new ArrayList<>(); + for (ServerNode node : serverNodes) { + if (node.getFailureCount() != 0) { + failServerNode.add(node); + } + } + log.info("所有离线节点个数为:{}",failServerNode.size()); + failServerNode.sort(Comparator.comparing(ServerNode::getLastSelectedTime)); + ServerNode last = CollUtil.getLast(failServerNode); + // 给失败的节点一次机会 + if (last.getLastSelectedTime().plusSeconds(retryTimeThread).isBefore(LocalDateTime.now())) { + log.info("选择失败的节点:host:{}:{},上次检查时间是:{}....",last.getId(),last.getPort(),last.getLastSelectedTime()); + selectedNode = last; + selectedNode.setLastSelectedTime(LocalDateTime.now()); + } + } + return selectedNode; + } + + @Override + public void markNodeFailed(String nodeId) { + for (ServerNode node : serverNodes) { + if (node.getId().equals(nodeId)) { + node.incrementFailureCount(); + break; + } + } + } + + @Override + public void recoverNode(String nodeId) { + for (ServerNode node : serverNodes) { + if (node.getId().equals(nodeId)) { + node.resetFailureCount(); + break; + } + } + } + + @Override + public List listAllNodes() { + return this.serverNodes; + } + + @Override + public void addNode(ServerNode node) { + // 检查节点是否已经存在 + for (ServerNode serverNode : serverNodes) { + if (StrUtil.equals(serverNode.getHost(), node.getHost()) && serverNode.getPort() == node.getPort()) { + // 节点已经存在 + log.info("节点已经存在,host:{},port:{}", node.getHost(), node.getPort()); + return; + } + } + // 添加节点 + serverNodes.add(node); + log.info("添加节点成功,id:{},host:{},port:{}", node.getId(), node.getHost(), node.getPort()); + } +} diff --git a/src/main/java/com/supervision/ai/service/hub/service/impl/ComfyUIServiceImpl.java b/src/main/java/com/supervision/ai/service/hub/service/impl/ComfyUIServiceImpl.java index 190ae45..4d28096 100644 --- a/src/main/java/com/supervision/ai/service/hub/service/impl/ComfyUIServiceImpl.java +++ b/src/main/java/com/supervision/ai/service/hub/service/impl/ComfyUIServiceImpl.java @@ -5,12 +5,11 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.metadata.IPage; import com.supervision.ai.service.hub.constant.ComfyuiParamTypeEnum; import com.supervision.ai.service.hub.domain.ComfyuiPrompt; import com.supervision.ai.service.hub.domain.ComfyuiPromptParam; -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.dto.comfyui.*; import com.supervision.ai.service.hub.service.ComfyUIApiService; import com.supervision.ai.service.hub.service.ComfyUIService; import com.supervision.ai.service.hub.service.ComfyUIPromptParamService; @@ -42,7 +41,7 @@ public class ComfyUIServiceImpl implements ComfyUIService { @Override - public String runPrompt(RunPromptReqVo runPromptReqVo) { + public String executeTask(RunPromptReqVo runPromptReqVo) { Assert.notEmpty(runPromptReqVo.getPromptId(),"promptId不能为空"); boolean exist = comfyuiPromptService.promptExist(runPromptReqVo.getPromptId()); Assert.isTrue(exist,"promptId不存在"); @@ -84,16 +83,16 @@ public class ComfyUIServiceImpl implements ComfyUIService { } @Override - public List queryHistory(String promptId) { + public IPage queryHistory(String promptId) { Map history = comfyUIApiService.queryHistory(promptId); if (CollUtil.isEmpty(history)){ - return new ArrayList<>(); + return null; } List resultResVos = new ArrayList<>(); for (Map.Entry entry : history.entrySet()) { TaskResultResVo taskResultResVo = new TaskResultResVo(); Object value = entry.getValue(); - taskResultResVo.setPromptId(entry.getKey()); + taskResultResVo.setModelId(entry.getKey()); if (null != value){ Map status = (Map) ((Map) value).get("status"); Boolean completed = (Boolean) status.get("completed"); @@ -103,14 +102,39 @@ public class ComfyUIServiceImpl implements ComfyUIService { for (Map.Entry outputEntry : outputs.entrySet()) { Map outputEntryValue = (Map) outputEntry.getValue(); List> images = (List>) outputEntryValue.get("images"); - taskResultResVo.setImages(images.stream().map(image -> (String)(image.get("filename"))).collect(Collectors.toList())); + taskResultResVo.setOutputImages(images.stream().map(image -> (String)(image.get("filename"))).collect(Collectors.toList())); } } } } resultResVos.add(taskResultResVo); } - return resultResVos; + return null; + } + + @Override + public boolean taskIsCompleted(Map result){ + if (CollUtil.isEmpty(result)){ + return false; + } + Map status = (Map) ((Map) result).get("status"); + return (Boolean) status.get("completed"); + } + + @Override + public List getImageList(Map result){ + List imageList = new ArrayList<>(); + if (CollUtil.isNotEmpty(result)){ + Map outputs = (Map) result.get("outputs"); + if (CollUtil.isNotEmpty(outputs)){ + for (Map.Entry outputEntry : outputs.entrySet()) { + Map outputEntryValue = (Map) outputEntry.getValue(); + List> images = (List>) outputEntryValue.get("images"); + imageList = images.stream().map(image -> (String)(image.get("filename"))).collect(Collectors.toList()); + } + } + } + return imageList; } @Override @@ -134,4 +158,34 @@ public class ComfyUIServiceImpl implements ComfyUIService { outputStream.write(resourceViewDTO.getContent()); } } + + @Override + public String saveModel(ComfyUIPromptDTO comfyUIPromptDTO) { + return null; + } + + @Override + public Boolean updateModel(ComfyUIPromptDTO comfyUIPromptDTO) { + return null; + } + + @Override + public Boolean deleteModel(ComfyUIPromptDTO comfyUIPromptDTO) { + return null; + } + + @Override + public ComfyUIPromptDTO queryById(String id) { + return null; + } + + @Override + public IPage pageList(String promptName, String promptType, Integer page, Integer pageSize) { + return null; + } + + @Override + public TaskResultResVo getTaskById(String taskId) { + return null; + } } diff --git a/src/main/java/com/supervision/ai/service/hub/service/impl/ComfyuiTaskParamServiceImpl.java b/src/main/java/com/supervision/ai/service/hub/service/impl/ComfyuiTaskParamServiceImpl.java index 11df76c..47f36cb 100644 --- a/src/main/java/com/supervision/ai/service/hub/service/impl/ComfyuiTaskParamServiceImpl.java +++ b/src/main/java/com/supervision/ai/service/hub/service/impl/ComfyuiTaskParamServiceImpl.java @@ -1,10 +1,13 @@ package com.supervision.ai.service.hub.service.impl; +import cn.hutool.core.collection.CollUtil; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.supervision.ai.service.hub.domain.ComfyuiTaskParam; import com.supervision.ai.service.hub.service.ComfyuiTaskParamService; import com.supervision.ai.service.hub.mapper.ComfyuiTaskParamMapper; import org.springframework.stereotype.Service; +import java.util.ArrayList; +import java.util.List; /** * @author Administrator @@ -15,6 +18,14 @@ import org.springframework.stereotype.Service; public class ComfyuiTaskParamServiceImpl extends ServiceImpl implements ComfyuiTaskParamService{ + @Override + public List listByTaskIds(List taskIds) { + if (CollUtil.isEmpty(taskIds)){ + return new ArrayList<>(); + } + return this.lambdaQuery() + .in(ComfyuiTaskParam::getTaskId, taskIds).list(); + } } diff --git a/src/main/java/com/supervision/ai/service/hub/service/impl/ComfyuiTaskResultServiceImpl.java b/src/main/java/com/supervision/ai/service/hub/service/impl/ComfyuiTaskResultServiceImpl.java index d90edb2..2d71d0b 100644 --- a/src/main/java/com/supervision/ai/service/hub/service/impl/ComfyuiTaskResultServiceImpl.java +++ b/src/main/java/com/supervision/ai/service/hub/service/impl/ComfyuiTaskResultServiceImpl.java @@ -1,10 +1,13 @@ package com.supervision.ai.service.hub.service.impl; +import cn.hutool.core.collection.CollUtil; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.supervision.ai.service.hub.domain.ComfyuiTaskResult; import com.supervision.ai.service.hub.service.ComfyuiTaskResultService; import com.supervision.ai.service.hub.mapper.ComfyuiTaskResultMapper; import org.springframework.stereotype.Service; +import java.util.ArrayList; +import java.util.List; /** * @author Administrator @@ -15,6 +18,13 @@ import org.springframework.stereotype.Service; public class ComfyuiTaskResultServiceImpl extends ServiceImpl implements ComfyuiTaskResultService{ + @Override + public List listByTaskIds(List taskIds) { + if (CollUtil.isEmpty(taskIds)){ + return new ArrayList<>(); + } + return this.lambdaQuery().in(ComfyuiTaskResult::getTaskId, taskIds).list(); + } } diff --git a/src/main/java/com/supervision/ai/service/hub/service/impl/ComfyuiTaskServiceImpl.java b/src/main/java/com/supervision/ai/service/hub/service/impl/ComfyuiTaskServiceImpl.java index 8c5c17a..5bbb439 100644 --- a/src/main/java/com/supervision/ai/service/hub/service/impl/ComfyuiTaskServiceImpl.java +++ b/src/main/java/com/supervision/ai/service/hub/service/impl/ComfyuiTaskServiceImpl.java @@ -1,20 +1,92 @@ package com.supervision.ai.service.hub.service.impl; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpResponse; +import cn.hutool.http.HttpUtil; +import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.supervision.ai.service.hub.constant.ComfyuiRunStatusEnum; import com.supervision.ai.service.hub.domain.ComfyuiTask; +import com.supervision.ai.service.hub.domain.ComfyuiTaskParam; +import com.supervision.ai.service.hub.domain.ComfyuiTaskResult; +import com.supervision.ai.service.hub.dto.comfyui.ComfyUITaskResult; +import com.supervision.ai.service.hub.dto.comfyui.TaskDTO; +import com.supervision.ai.service.hub.service.ComfyuiTaskParamService; +import com.supervision.ai.service.hub.service.ComfyuiTaskResultService; import com.supervision.ai.service.hub.service.ComfyuiTaskService; import com.supervision.ai.service.hub.mapper.ComfyuiTaskMapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import java.util.*; +import java.util.stream.Collectors; + /** * @author Administrator * @description 针对表【comfyui_task(comfyui任务表)】的数据库操作Service实现 * @createDate 2025-04-11 15:51:10 */ +@Slf4j @Service +@RequiredArgsConstructor public class ComfyuiTaskServiceImpl extends ServiceImpl implements ComfyuiTaskService{ + private final ComfyuiTaskParamService comfyuiTaskParamService; + + private final ComfyuiTaskResultService comfyuiTaskResultService; + @Override + public void updateTaskResult(TaskDTO taskDTO) { + + } + + @Override + public List queryNotStartedTask(int size) { + if (size == 0){ + return new ArrayList<>(); + } + List comfyuiTaskList = this.lambdaQuery() + .eq(ComfyuiTask::getRunStatus, ComfyuiRunStatusEnum.NOT_STARTED.getStatus()) + .orderByAsc(ComfyuiTask::getCreateTime).last("limit " + size).list(); + if (CollUtil.isEmpty(comfyuiTaskList)){ + return new ArrayList<>(); + } + List taskIds = comfyuiTaskList.stream().map(ComfyuiTask::getId).distinct().toList(); + + Map> taskParamMap = comfyuiTaskParamService.listByTaskIds(taskIds) + .stream().collect(Collectors.groupingBy(ComfyuiTaskParam::getTaskId)); + Map> taskResultMap = comfyuiTaskResultService.listByTaskIds(taskIds) + .stream().collect(Collectors.groupingBy(ComfyuiTaskResult::getTaskId)); + + return comfyuiTaskList.stream() + .map(comfyuiTask->new TaskDTO(comfyuiTask, taskParamMap.get(comfyuiTask.getId()), taskResultMap.get(comfyuiTask.getId()))) + .collect(Collectors.toList()); + } + + @Override + public void notifyWebhook(TaskDTO taskDTO) { + if (StrUtil.isEmpty(taskDTO.getWebHook())){ + log.info("notifyWebhook:没有配置webhook地址,taskId:{}",taskDTO.getId()); + return; + } + Map boyMap = new HashMap<>(); + boyMap.put("taskId", taskDTO.getId()); + boyMap.put("status",taskDTO.getRunStatus()); + boyMap.put("outputImages", taskDTO.getResults().stream().map(ComfyUITaskResult::getFileId).collect(Collectors.toList())); + HttpRequest request = HttpUtil.createPost(taskDTO.getWebHook()) + .header("Content-Type", "application/json") + .body(JSONUtil.toJsonStr(boyMap)); + try (HttpResponse execute = request.execute()){ + if (execute.getStatus() != 200){ + log.error("notifyWebhook:发送webhook失败,taskId:{},status:{},response:{}",taskDTO.getId(),taskDTO.getRunStatus(),execute.body()); + } + }catch (Exception e){ + log.error("notifyWebhook:发送webhook失败,taskId:{},status:{},error:{}",taskDTO.getId(),taskDTO.getRunStatus(),e.getMessage()); + } + } } diff --git a/src/main/java/com/supervision/ai/service/hub/service/impl/FifoSchedulingStrategy.java b/src/main/java/com/supervision/ai/service/hub/service/impl/FifoSchedulingStrategy.java new file mode 100644 index 0000000..0e27b7d --- /dev/null +++ b/src/main/java/com/supervision/ai/service/hub/service/impl/FifoSchedulingStrategy.java @@ -0,0 +1,39 @@ +package com.supervision.ai.service.hub.service.impl; + +import cn.hutool.core.collection.CollUtil; +import com.supervision.ai.service.hub.dto.comfyui.TaskDTO; +import com.supervision.ai.service.hub.service.ComfyuiTaskService; +import com.supervision.ai.service.hub.service.SchedulingStrategy; +import lombok.extern.slf4j.Slf4j; + +import java.util.Comparator; +import java.util.List; +import java.util.concurrent.LinkedBlockingQueue; + +@Slf4j +public class FifoSchedulingStrategy implements SchedulingStrategy { + + private final ComfyuiTaskService comfyuiTaskService; + + private final LinkedBlockingQueue taskQueue = new LinkedBlockingQueue<>(); + + public FifoSchedulingStrategy(ComfyuiTaskService comfyuiTaskService) { + this.comfyuiTaskService = comfyuiTaskService; + } + + @Override + public TaskDTO selectNextTask() { + if (taskQueue.isEmpty()) { + List taskDTOS = comfyuiTaskService.queryNotStartedTask(10); + if (CollUtil.isEmpty(taskDTOS)){ + log.info("selectNextTask:未从queryNotStartedTask中获取到可用的元素...."); + return null; + } + taskDTOS.sort(Comparator.comparing(TaskDTO::getRunStartTime)); + for (TaskDTO taskDTO : taskDTOS) { + taskQueue.offer(taskDTO); + } + } + return taskQueue.poll(); + } +} diff --git a/src/main/java/com/supervision/ai/service/hub/service/impl/PermissionServiceImpl.java b/src/main/java/com/supervision/ai/service/hub/service/impl/PermissionServiceImpl.java new file mode 100644 index 0000000..6e95dd2 --- /dev/null +++ b/src/main/java/com/supervision/ai/service/hub/service/impl/PermissionServiceImpl.java @@ -0,0 +1,55 @@ +package com.supervision.ai.service.hub.service.impl; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.supervision.ai.service.hub.domain.Permission; +import com.supervision.ai.service.hub.dto.sys.PermissionDTO; +import com.supervision.ai.service.hub.service.PermissionService; +import com.supervision.ai.service.hub.mapper.PermissionMapper; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** +* @author Administrator +* @description 针对表【permission(权限表)】的数据库操作Service实现 +* @createDate 2025-04-14 16:01:14 +*/ +@Service +public class PermissionServiceImpl extends ServiceImpl + implements PermissionService{ + + @Override + public String savePermission(PermissionDTO permissionDTO) { + return null; + } + + @Override + public Boolean updatePermission(PermissionDTO permissionDTO) { + return null; + } + + @Override + public Boolean deletePermission(String id) { + return null; + } + + @Override + public List queryPermission(String type) { + return null; + } + + @Override + public IPage pageList(String permissionName, Integer page, Integer pageSize) { + return null; + } + + @Override + public PermissionDTO queryById(String id) { + return null; + } +} + + + + diff --git a/src/main/java/com/supervision/ai/service/hub/service/impl/SysAppServiceImpl.java b/src/main/java/com/supervision/ai/service/hub/service/impl/SysAppServiceImpl.java index feda79c..4a3c81f 100644 --- a/src/main/java/com/supervision/ai/service/hub/service/impl/SysAppServiceImpl.java +++ b/src/main/java/com/supervision/ai/service/hub/service/impl/SysAppServiceImpl.java @@ -1,11 +1,12 @@ package com.supervision.ai.service.hub.service.impl; +import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.supervision.ai.service.hub.domain.SysApp; +import com.supervision.ai.service.hub.dto.sys.AppDTO; import com.supervision.ai.service.hub.service.SysAppService; import com.supervision.ai.service.hub.mapper.SysAppMapper; import org.springframework.stereotype.Service; - /** * @author Administrator * @description 针对表【sys_app】的数据库操作Service实现 @@ -19,6 +20,31 @@ public class SysAppServiceImpl extends ServiceImpl public SysApp getByAppName(String appName) { return this.lambdaQuery().eq(SysApp::getAppName, appName).one(); } + + @Override + public String saveApp(AppDTO appDTO) { + return null; + } + + @Override + public Boolean updateApp(AppDTO appDTO) { + return null; + } + + @Override + public Boolean deleteApp(AppDTO appDTO) { + return null; + } + + @Override + public IPage pageList(String appName, Integer page, Integer pageSize) { + return null; + } + + @Override + public AppDTO queryById(String id) { + return null; + } } diff --git a/src/main/java/com/supervision/ai/service/hub/service/impl/SysFileServiceImpl.java b/src/main/java/com/supervision/ai/service/hub/service/impl/SysFileServiceImpl.java index decf5c3..fafcf68 100644 --- a/src/main/java/com/supervision/ai/service/hub/service/impl/SysFileServiceImpl.java +++ b/src/main/java/com/supervision/ai/service/hub/service/impl/SysFileServiceImpl.java @@ -1,20 +1,73 @@ package com.supervision.ai.service.hub.service.impl; +import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.supervision.ai.service.hub.domain.SysFile; +import com.supervision.ai.service.hub.dto.sys.FileDTO; import com.supervision.ai.service.hub.service.SysFileService; import com.supervision.ai.service.hub.mapper.SysFileMapper; +import io.minio.GetObjectArgs; +import io.minio.MinioClient; +import io.minio.errors.*; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.io.InputStream; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; /** * @author Administrator * @description 针对表【sys_file(系统文件表)】的数据库操作Service实现 * @createDate 2025-04-11 15:51:10 */ +@Slf4j @Service +@RequiredArgsConstructor public class SysFileServiceImpl extends ServiceImpl implements SysFileService{ + private final MinioClient minioClient; + + @Value("${minio.bucketName}") + private String bucketName; + @Override + public String upload(MultipartFile file) { + return null; + } + + @Override + public IPage pageList(String fileName, String fileType , Integer page, Integer pageSize) { + return null; + } + + @Override + public FileDTO queryById(String id) { + return null; + } + + @Override + public void downLoad(String fileId, HttpServletResponse response) { + + } + + @Override + public byte[] downloadFile(String fileId) { + try { + InputStream inputStream = minioClient.getObject( + GetObjectArgs.builder().bucket(bucketName).object(fileId).build()); + return inputStream.readAllBytes(); + } catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidKeyException | + InvalidResponseException | IOException | NoSuchAlgorithmException | ServerException | + XmlParserException e) { + throw new RuntimeException(e); + } + } } diff --git a/src/main/java/com/supervision/ai/service/hub/service/impl/SysRolePermissionServiceImpl.java b/src/main/java/com/supervision/ai/service/hub/service/impl/SysRolePermissionServiceImpl.java new file mode 100644 index 0000000..4f91f3e --- /dev/null +++ b/src/main/java/com/supervision/ai/service/hub/service/impl/SysRolePermissionServiceImpl.java @@ -0,0 +1,22 @@ +package com.supervision.ai.service.hub.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.supervision.ai.service.hub.domain.SysRolePermission; +import com.supervision.ai.service.hub.service.SysRolePermissionService; +import com.supervision.ai.service.hub.mapper.SysRolePermissionMapper; +import org.springframework.stereotype.Service; + +/** +* @author Administrator +* @description 针对表【sys_role_permission】的数据库操作Service实现 +* @createDate 2025-04-14 16:01:04 +*/ +@Service +public class SysRolePermissionServiceImpl extends ServiceImpl + implements SysRolePermissionService{ + +} + + + + diff --git a/src/main/java/com/supervision/ai/service/hub/service/impl/SysRoleServiceImpl.java b/src/main/java/com/supervision/ai/service/hub/service/impl/SysRoleServiceImpl.java index 4548afc..88021b7 100644 --- a/src/main/java/com/supervision/ai/service/hub/service/impl/SysRoleServiceImpl.java +++ b/src/main/java/com/supervision/ai/service/hub/service/impl/SysRoleServiceImpl.java @@ -1,7 +1,9 @@ package com.supervision.ai.service.hub.service.impl; +import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.supervision.ai.service.hub.domain.SysRole; +import com.supervision.ai.service.hub.dto.sys.SysRoleDTO; import com.supervision.ai.service.hub.service.SysRoleService; import com.supervision.ai.service.hub.mapper.SysRoleMapper; import org.springframework.stereotype.Service; @@ -15,6 +17,30 @@ import org.springframework.stereotype.Service; public class SysRoleServiceImpl extends ServiceImpl implements SysRoleService{ + @Override + public String saveRole(SysRoleDTO roleDTO) { + return null; + } + + @Override + public Boolean updateRole(SysRoleDTO roleDTO) { + return null; + } + + @Override + public Boolean deleteRole(String id) { + return null; + } + + @Override + public IPage pageList(String roleName, Integer page, Integer pageSize) { + return null; + } + + @Override + public SysRoleDTO queryById(String id) { + return null; + } } diff --git a/src/main/java/com/supervision/ai/service/hub/service/impl/SysUserServiceImpl.java b/src/main/java/com/supervision/ai/service/hub/service/impl/SysUserServiceImpl.java index 529fae4..5cc3e1b 100644 --- a/src/main/java/com/supervision/ai/service/hub/service/impl/SysUserServiceImpl.java +++ b/src/main/java/com/supervision/ai/service/hub/service/impl/SysUserServiceImpl.java @@ -1,7 +1,9 @@ package com.supervision.ai.service.hub.service.impl; +import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.supervision.ai.service.hub.domain.SysUser; +import com.supervision.ai.service.hub.dto.sys.UserDTO; import com.supervision.ai.service.hub.service.SysUserService; import com.supervision.ai.service.hub.mapper.SysUserMapper; import org.springframework.stereotype.Service; @@ -19,6 +21,31 @@ public class SysUserServiceImpl extends ServiceImpl public SysUser getByUsername(String username) { return this.lambdaQuery().eq(SysUser::getUserName, username).one(); } + + @Override + public UserDTO queryById(String id) { + return null; + } + + @Override + public String saveUser(UserDTO user) { + return null; + } + + @Override + public Boolean updateUser(UserDTO user) { + return null; + } + + @Override + public Boolean deleteUser(String id) { + return null; + } + + @Override + public IPage pageList(String userName, Integer page, Integer pageSize) { + return null; + } } diff --git a/src/main/java/com/supervision/ai/service/hub/service/impl/TaskServiceImpl.java b/src/main/java/com/supervision/ai/service/hub/service/impl/TaskServiceImpl.java new file mode 100644 index 0000000..edbca89 --- /dev/null +++ b/src/main/java/com/supervision/ai/service/hub/service/impl/TaskServiceImpl.java @@ -0,0 +1,39 @@ +package com.supervision.ai.service.hub.service.impl; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.supervision.ai.service.hub.dto.comfyui.TaskDTO; +import com.supervision.ai.service.hub.service.ComfyuiTaskService; +import com.supervision.ai.service.hub.service.TaskService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Slf4j +@Service +@RequiredArgsConstructor +public class TaskServiceImpl implements TaskService { + + private final ComfyuiTaskService comfyuiTaskService; + + @Override + public IPage pageList(String taskName, String taskType, String status, Integer page, Integer pageSize) { + return null; + } + + @Override + public Boolean suspendTask(List taskIds) { + return null; + } + + @Override + public Boolean cancelTask(List taskIds) { + return null; + } + + @Override + public Boolean retryTask(List taskIds) { + return null; + } +} diff --git a/src/main/java/com/supervision/ai/service/hub/vo/LoginReqVo.java b/src/main/java/com/supervision/ai/service/hub/vo/LoginReqVo.java new file mode 100644 index 0000000..b2fb8cd --- /dev/null +++ b/src/main/java/com/supervision/ai/service/hub/vo/LoginReqVo.java @@ -0,0 +1,14 @@ +package com.supervision.ai.service.hub.vo; + +import lombok.Data; + +@Data +public class LoginReqVo { + + // appName 和 username 不能同时为空 + private String appName; + + private String username; + + private String password; +} diff --git a/src/main/java/com/supervision/ai/service/hub/vo/comfyui/TaskResultResVo.java b/src/main/java/com/supervision/ai/service/hub/vo/comfyui/TaskResultResVo.java index 796881b..9e0e5e5 100644 --- a/src/main/java/com/supervision/ai/service/hub/vo/comfyui/TaskResultResVo.java +++ b/src/main/java/com/supervision/ai/service/hub/vo/comfyui/TaskResultResVo.java @@ -1,5 +1,6 @@ package com.supervision.ai.service.hub.vo.comfyui; +import com.supervision.ai.service.hub.dto.comfyui.ComfyUIPromptParamDTO; import lombok.Data; import java.util.List; @@ -9,9 +10,17 @@ import java.util.List; @Data public class TaskResultResVo { - private String promptId; + private String taskId; - private boolean completed; + private String status; - private List images; + private String modelName; + + private String modelType; + + private String modelId; + + private List outputImages; + + private List taskParams; } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index ee61af7..20fb42e 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -40,4 +40,4 @@ minio: endpoint: http:192.168.10.137:9002 accessKey: admin secretKey: 12345678 - bucketName: nxfuhsi \ No newline at end of file + bucketName: ai-service-hub \ No newline at end of file diff --git a/src/main/resources/mapper/ComfyuiPromptMapper.xml b/src/main/resources/mapper/ComfyuiPromptMapper.xml index 1e1bb5a..e1f9f50 100644 --- a/src/main/resources/mapper/ComfyuiPromptMapper.xml +++ b/src/main/resources/mapper/ComfyuiPromptMapper.xml @@ -8,6 +8,7 @@ + @@ -16,7 +17,7 @@ - id,prompt_name,prompt_type, + id,prompt_name,prompt_type,icon_file_id, prompt,create_user_id,create_time, update_time,update_user_id diff --git a/src/main/resources/mapper/ComfyuiTaskMapper.xml b/src/main/resources/mapper/ComfyuiTaskMapper.xml index b519ec3..defda7f 100644 --- a/src/main/resources/mapper/ComfyuiTaskMapper.xml +++ b/src/main/resources/mapper/ComfyuiTaskMapper.xml @@ -13,6 +13,9 @@ + + + @@ -21,7 +24,7 @@ id,prompt_id,user_id, - app_id,run_status,run_start_time, + app_id,run_status,run_start_time,prompt,comfyui_server,comfyui_task_id, run_end_time,web_hook,create_user_id, create_time,update_time,update_user_id diff --git a/src/main/resources/mapper/PermissionMapper.xml b/src/main/resources/mapper/PermissionMapper.xml new file mode 100644 index 0000000..702b838 --- /dev/null +++ b/src/main/resources/mapper/PermissionMapper.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + id,name,type, + code,parent_id,create_user_id, + create_time,update_time,update_user_id + + diff --git a/src/main/resources/mapper/SysAppMapper.xml b/src/main/resources/mapper/SysAppMapper.xml index 0083d24..c7ef897 100644 --- a/src/main/resources/mapper/SysAppMapper.xml +++ b/src/main/resources/mapper/SysAppMapper.xml @@ -8,6 +8,7 @@ + diff --git a/src/main/resources/mapper/SysRolePermissionMapper.xml b/src/main/resources/mapper/SysRolePermissionMapper.xml new file mode 100644 index 0000000..d38ec8f --- /dev/null +++ b/src/main/resources/mapper/SysRolePermissionMapper.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + r_id,p_id,create_user_id, + create_time,update_time,update_user_id + + diff --git a/src/test/java/com/supervision/ai/service/hub/ComfyUIApiServiceTest.java b/src/test/java/com/supervision/ai/service/hub/ComfyUIApiServiceTest.java index 13eaf00..46e9468 100644 --- a/src/test/java/com/supervision/ai/service/hub/ComfyUIApiServiceTest.java +++ b/src/test/java/com/supervision/ai/service/hub/ComfyUIApiServiceTest.java @@ -31,10 +31,18 @@ public class ComfyUIApiServiceTest { } @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\":\"保存图像\"}}}}"; + public void runPromptTest() throws InterruptedException { + //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\":\"保存图像\"}}}}"; + String prompt = "{\"prompt\":{\"6\":{\"inputs\":{\"text\":\"A young boy stands calmly in the foreground, looking directly at the camera, as a house fire rages in the background. Flames engulf the structure, with smoke billowing into the air. Firefighters in protective gear rush to the scene, a fire truck labeled '38' visible behind them. The girl's neutral expression contrasts sharply with the chaos of the fire, creating a poignant and emotionally charged scene.\",\"clip\":[\"38\",0]},\"class_type\":\"CLIPTextEncode\",\"_meta\":{\"title\":\"CLIP Text Encode (Positive Prompt)\"}},\"7\":{\"inputs\":{\"text\":\"worst quality, inconsistent motion, blurry, jittery, distorted\",\"clip\":[\"38\",0]},\"class_type\":\"CLIPTextEncode\",\"_meta\":{\"title\":\"CLIP Text Encode (Negative Prompt)\"}},\"8\":{\"inputs\":{\"samples\":[\"72\",0],\"vae\":[\"44\",2]},\"class_type\":\"VAEDecode\",\"_meta\":{\"title\":\"VAE解码\"}},\"38\":{\"inputs\":{\"clip_name\":\"t5xxl_fp16.safetensors\",\"type\":\"ltxv\",\"device\":\"default\"},\"class_type\":\"CLIPLoader\",\"_meta\":{\"title\":\"加载CLIP\"}},\"41\":{\"inputs\":{\"filename_prefix\":\"ComfyUI\",\"fps\":24.000000000000004,\"lossless\":false,\"quality\":90,\"method\":\"default\",\"images\":[\"8\",0]},\"class_type\":\"SaveAnimatedWEBP\",\"_meta\":{\"title\":\"保存动画(WEBP)\"}},\"44\":{\"inputs\":{\"ckpt_name\":\"ltx-video-2b-v0.9.safetensors\"},\"class_type\":\"CheckpointLoaderSimple\",\"_meta\":{\"title\":\"Checkpoint加载器(简易)\"}},\"69\":{\"inputs\":{\"frame_rate\":25.000000000000004,\"positive\":[\"77\",0],\"negative\":[\"77\",1]},\"class_type\":\"LTXVConditioning\",\"_meta\":{\"title\":\"LTXV条件\"}},\"71\":{\"inputs\":{\"steps\":50,\"max_shift\":2.0500000000000003,\"base_shift\":0.9500000000000002,\"stretch\":true,\"terminal\":0.10000000000000002,\"latent\":[\"77\",2]},\"class_type\":\"LTXVScheduler\",\"_meta\":{\"title\":\"LTXV调度器\"}},\"72\":{\"inputs\":{\"add_noise\":true,\"noise_seed\":2025,\"cfg\":3,\"model\":[\"44\",0],\"positive\":[\"69\",0],\"negative\":[\"69\",1],\"sampler\":[\"73\",0],\"sigmas\":[\"71\",0],\"latent_image\":[\"77\",2]},\"class_type\":\"SamplerCustom\",\"_meta\":{\"title\":\"自定义采样器\"}},\"73\":{\"inputs\":{\"sampler_name\":\"euler\"},\"class_type\":\"KSamplerSelect\",\"_meta\":{\"title\":\"K采样器选择\"}},\"77\":{\"inputs\":{\"width\":704,\"height\":480,\"length\":161,\"batch_size\":1,\"positive\":[\"6\",0],\"negative\":[\"7\",0],\"vae\":[\"44\",2],\"image\":[\"78\",0]},\"class_type\":\"LTXVImgToVideo\",\"_meta\":{\"title\":\"LTXV图像到视频\"}},\"78\":{\"inputs\":{\"image\":\"8.png\"},\"class_type\":\"LoadImage\",\"_meta\":{\"title\":\"加载图像\"}}}}"; PromptRunDTO res = comfyUIApiService.runPrompt(JSON.parseObject(prompt)); - log.info(JSONUtil.toJsonStr(res)); + + log.info("执行工作流成功,res:{}", JSONUtil.toJsonStr(res)); + for (int i = 0; i < 50; i++) { + String promptId = res.getPrompt_id(); + Map history = comfyUIApiService.queryHistory(promptId); + log.info("查询任务状态:{}",JSONUtil.toJsonStr(history)); + Thread.sleep(1000 *1); + } } @Test