From 2aff972600005080775f2d3df10763a0fb83e001 Mon Sep 17 00:00:00 2001 From: Lesan <1960681385@qq.com> Date: Fri, 28 Mar 2025 15:54:46 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20AI=E5=B7=A5=E4=BD=9C=E6=B5=81=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module/ai/enums/ErrorCodeConstants.java | 2 +- .../admin/workflow/AiWorkflowController.java | 9 ----- .../workflow/vo/AiWorkflowPageReqVO.java | 8 ++++- .../admin/workflow/vo/AiWorkflowRespVO.java | 10 ++++-- .../workflow/vo/AiWorkflowSaveReqVO.java | 14 +++++++- .../workflow/vo/AiWorkflowTestReqVO.java | 2 +- .../vo/AiWorkflowUpdateModelReqVO.java | 18 ---------- .../dal/dataobject/workflow/AiWorkflowDO.java | 19 +++++++--- .../dal/mysql/workflow/AiWorkflowMapper.java | 8 +++-- .../service/workflow/AiWorkflowService.java | 8 ----- .../workflow/AiWorkflowServiceImpl.java | 36 ++++++++----------- 11 files changed, 64 insertions(+), 70 deletions(-) delete mode 100644 yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/workflow/vo/AiWorkflowUpdateModelReqVO.java diff --git a/yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/enums/ErrorCodeConstants.java b/yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/enums/ErrorCodeConstants.java index fa072f3fcb..8a8a388324 100644 --- a/yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/enums/ErrorCodeConstants.java +++ b/yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/enums/ErrorCodeConstants.java @@ -63,6 +63,6 @@ public interface ErrorCodeConstants { // ========== AI 工作流 1-040-011-000 ========== ErrorCode WORKFLOW_NOT_EXISTS = new ErrorCode(1_040_011_000, "工作流不存在"); - ErrorCode WORKFLOW_KEY_EXISTS = new ErrorCode(1_040_011_001, "工作流标识已存在"); + ErrorCode WORKFLOW_CODE_EXISTS = new ErrorCode(1_040_011_001, "工作流标识已存在"); } diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/workflow/AiWorkflowController.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/workflow/AiWorkflowController.java index 44e60a0e98..d558d90454 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/workflow/AiWorkflowController.java +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/workflow/AiWorkflowController.java @@ -67,15 +67,6 @@ public class AiWorkflowController { return success(BeanUtils.toBean(pageResult, AiWorkflowRespVO.class)); } - // TODO @lesan:要不融合到 updateWorkflow 接口? - @PutMapping("/updateWorkflowModel") - @Operation(summary = "更新 AI 工作流模型") - @PreAuthorize("@ss.hasPermission('ai:workflow:update')") - public CommonResult updateWorkflowModel(@Valid @RequestBody AiWorkflowUpdateModelReqVO updateReqVO) { - workflowService.updateWorkflowModel(updateReqVO); - return success(true); - } - @PostMapping("/test") @Operation(summary = "测试 AI 工作流") @PreAuthorize("@ss.hasPermission('ai:workflow:test')") diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/workflow/vo/AiWorkflowPageReqVO.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/workflow/vo/AiWorkflowPageReqVO.java index 5418057817..e55b85ea90 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/workflow/vo/AiWorkflowPageReqVO.java +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/workflow/vo/AiWorkflowPageReqVO.java @@ -1,6 +1,8 @@ package cn.iocoder.yudao.module.ai.controller.admin.workflow.vo; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.validation.InEnum; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; @@ -17,7 +19,11 @@ public class AiWorkflowPageReqVO extends PageParam { private String name; @Schema(description = "标识", example = "FLOW") - private String definitionKey; + private String code; + + @Schema(description = "状态", example = "1") + @InEnum(CommonStatusEnum.class) + private Integer status; @Schema(description = "创建时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/workflow/vo/AiWorkflowRespVO.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/workflow/vo/AiWorkflowRespVO.java index b1c66b91de..e3a28ad648 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/workflow/vo/AiWorkflowRespVO.java +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/workflow/vo/AiWorkflowRespVO.java @@ -13,13 +13,19 @@ public class AiWorkflowRespVO { private Long id; @Schema(description = "工作流标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "FLOW") - private String definitionKey; + private String code; @Schema(description = "工作流名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "工作流") private String name; + @Schema(description = "备注", requiredMode = Schema.RequiredMode.REQUIRED, example = "工作流") + private String remark; + + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Integer status; + @Schema(description = "工作流模型 JSON", requiredMode = Schema.RequiredMode.REQUIRED, example = "{}") - private String model; + private String graph; @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "时间戳格式") private LocalDateTime createTime; diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/workflow/vo/AiWorkflowSaveReqVO.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/workflow/vo/AiWorkflowSaveReqVO.java index 5c4ebc4a4b..0a63c37732 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/workflow/vo/AiWorkflowSaveReqVO.java +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/workflow/vo/AiWorkflowSaveReqVO.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.ai.controller.admin.workflow.vo; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; import lombok.Data; @Schema(description = "管理后台 - AI 工作流新增/修改 Request VO") @@ -13,10 +14,21 @@ public class AiWorkflowSaveReqVO { @Schema(description = "工作流标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "FLOW") @NotEmpty(message = "工作流标识不能为空") - private String definitionKey; + private String code; @Schema(description = "工作流名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "工作流") @NotEmpty(message = "工作流名称不能为空") private String name; + @Schema(description = "备注", example = "FLOW") + private String remark; + + @Schema(description = "工作流模型", requiredMode = Schema.RequiredMode.REQUIRED, example = "{}") + @NotEmpty(message = "工作流模型不能为空") + private String graph; + + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "FLOW") + @NotNull(message = "状态不能为空") + private Integer status; + } diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/workflow/vo/AiWorkflowTestReqVO.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/workflow/vo/AiWorkflowTestReqVO.java index 077a3020a6..4dc509e89d 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/workflow/vo/AiWorkflowTestReqVO.java +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/workflow/vo/AiWorkflowTestReqVO.java @@ -12,7 +12,7 @@ public class AiWorkflowTestReqVO { @Schema(description = "工作流模型", requiredMode = Schema.RequiredMode.REQUIRED, example = "{}") @NotEmpty(message = "工作流模型不能为空") - private String model; + private String graph; @Schema(description = "参数", requiredMode = Schema.RequiredMode.REQUIRED, example = "{}") private Map params; diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/workflow/vo/AiWorkflowUpdateModelReqVO.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/workflow/vo/AiWorkflowUpdateModelReqVO.java deleted file mode 100644 index 00a279ba54..0000000000 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/workflow/vo/AiWorkflowUpdateModelReqVO.java +++ /dev/null @@ -1,18 +0,0 @@ -package cn.iocoder.yudao.module.ai.controller.admin.workflow.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.NotEmpty; -import lombok.Data; - -@Schema(description = "管理后台 - AI 工作流修改流程模型 Request VO") -@Data -public class AiWorkflowUpdateModelReqVO { - - @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Long id; - - @Schema(description = "工作流模型", requiredMode = Schema.RequiredMode.REQUIRED, example = "{}") - @NotEmpty(message = "工作流模型不能为空") - private String model; - -} diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/workflow/AiWorkflowDO.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/workflow/AiWorkflowDO.java index ef05f7ea17..d844f7da2e 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/workflow/AiWorkflowDO.java +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/workflow/AiWorkflowDO.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.ai.dal.dataobject.workflow; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; @@ -28,13 +29,23 @@ public class AiWorkflowDO extends BaseDO { /** * 工作流标识 */ - // TODO @lesan:要不换成 code?主要想,和 bpm 工作流,有点区分,字段上。 - private String definitionKey; + private String code; - // TODO @lesan:graph 用这个如何?发现大家貌似更爱用这个字段哈。图! /** * 工作流模型 JSON 数据 */ - private String model; + private String graph; + + /** + * 备注 + */ + private String remark; + + /** + * 状态 + * + * 枚举 {@link CommonStatusEnum} + */ + private Integer status; } diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/workflow/AiWorkflowMapper.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/workflow/AiWorkflowMapper.java index f6be0cec7b..3770dbf0b5 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/workflow/AiWorkflowMapper.java +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/workflow/AiWorkflowMapper.java @@ -15,14 +15,16 @@ import org.apache.ibatis.annotations.Mapper; @Mapper public interface AiWorkflowMapper extends BaseMapperX { - default AiWorkflowDO selectByKey(String key) { - return selectOne(AiWorkflowDO::getDefinitionKey, key); + default AiWorkflowDO selectByCode(String code) { + return selectOne(AiWorkflowDO::getCode, code); } default PageResult selectPage(AiWorkflowPageReqVO pageReqVO) { return selectPage(pageReqVO, new LambdaQueryWrapperX() + .eqIfPresent(AiWorkflowDO::getStatus, pageReqVO.getStatus()) .likeIfPresent(AiWorkflowDO::getName, pageReqVO.getName()) - .likeIfPresent(AiWorkflowDO::getDefinitionKey, pageReqVO.getDefinitionKey())); + .likeIfPresent(AiWorkflowDO::getCode, pageReqVO.getCode()) + .betweenIfPresent(AiWorkflowDO::getCreateTime, pageReqVO.getCreateTime())); } } diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/workflow/AiWorkflowService.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/workflow/AiWorkflowService.java index bbc167d486..51a3aea751 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/workflow/AiWorkflowService.java +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/workflow/AiWorkflowService.java @@ -4,7 +4,6 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.ai.controller.admin.workflow.vo.AiWorkflowPageReqVO; import cn.iocoder.yudao.module.ai.controller.admin.workflow.vo.AiWorkflowSaveReqVO; import cn.iocoder.yudao.module.ai.controller.admin.workflow.vo.AiWorkflowTestReqVO; -import cn.iocoder.yudao.module.ai.controller.admin.workflow.vo.AiWorkflowUpdateModelReqVO; import cn.iocoder.yudao.module.ai.dal.dataobject.workflow.AiWorkflowDO; import jakarta.validation.Valid; @@ -53,13 +52,6 @@ public interface AiWorkflowService { */ PageResult getWorkflowPage(AiWorkflowPageReqVO pageReqVO); - /** - * 修改工作流模型 JSON 数据 - * - * @param updateReqVO 更新数据 - */ - void updateWorkflowModel(AiWorkflowUpdateModelReqVO updateReqVO); - /** * 测试 AI 工作流 * diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/workflow/AiWorkflowServiceImpl.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/workflow/AiWorkflowServiceImpl.java index 0bf299da49..70d28496c8 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/workflow/AiWorkflowServiceImpl.java +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/workflow/AiWorkflowServiceImpl.java @@ -7,7 +7,6 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.ai.controller.admin.workflow.vo.AiWorkflowPageReqVO; import cn.iocoder.yudao.module.ai.controller.admin.workflow.vo.AiWorkflowSaveReqVO; import cn.iocoder.yudao.module.ai.controller.admin.workflow.vo.AiWorkflowTestReqVO; -import cn.iocoder.yudao.module.ai.controller.admin.workflow.vo.AiWorkflowUpdateModelReqVO; import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiApiKeyDO; import cn.iocoder.yudao.module.ai.dal.dataobject.workflow.AiWorkflowDO; import cn.iocoder.yudao.module.ai.dal.mysql.workflow.AiWorkflowMapper; @@ -22,7 +21,7 @@ import org.springframework.stereotype.Service; import java.util.Map; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.ai.enums.ErrorCodeConstants.WORKFLOW_KEY_EXISTS; +import static cn.iocoder.yudao.module.ai.enums.ErrorCodeConstants.WORKFLOW_CODE_EXISTS; import static cn.iocoder.yudao.module.ai.enums.ErrorCodeConstants.WORKFLOW_NOT_EXISTS; /** @@ -42,16 +41,15 @@ public class AiWorkflowServiceImpl implements AiWorkflowService { @Override public Long createWorkflow(AiWorkflowSaveReqVO createReqVO) { - validateWorkflowForCreateOrUpdate(null, createReqVO.getDefinitionKey()); + validateWorkflowForCreateOrUpdate(null, createReqVO.getCode()); AiWorkflowDO workflow = BeanUtils.toBean(createReqVO, AiWorkflowDO.class); - workflow.setModel(StrUtil.EMPTY); workflowMapper.insert(workflow); return workflow.getId(); } @Override public void updateWorkflow(AiWorkflowSaveReqVO updateReqVO) { - validateWorkflowForCreateOrUpdate(updateReqVO.getId(), updateReqVO.getDefinitionKey()); + validateWorkflowForCreateOrUpdate(updateReqVO.getId(), updateReqVO.getCode()); AiWorkflowDO workflow = BeanUtils.toBean(updateReqVO, AiWorkflowDO.class); workflowMapper.updateById(workflow); } @@ -72,22 +70,16 @@ public class AiWorkflowServiceImpl implements AiWorkflowService { return workflowMapper.selectPage(pageReqVO); } - @Override - public void updateWorkflowModel(AiWorkflowUpdateModelReqVO updateReqVO) { - validateWorkflowExists(updateReqVO.getId()); - workflowMapper.updateById(new AiWorkflowDO().setId(updateReqVO.getId()).setModel(updateReqVO.getModel())); - } - @Override public Object testWorkflow(AiWorkflowTestReqVO testReqVO) { Map variables = testReqVO.getParams(); - Tinyflow tinyflow = parseFlowParam(testReqVO.getModel()); + Tinyflow tinyflow = parseFlowParam(testReqVO.getGraph()); return tinyflow.toChain().executeForResult(variables); } - private void validateWorkflowForCreateOrUpdate(Long id, String key) { + private void validateWorkflowForCreateOrUpdate(Long id, String code) { validateWorkflowExists(id); - validateKeyUnique(id, key); + validateCodeUnique(id, code); } private void validateWorkflowExists(Long id) { @@ -100,27 +92,27 @@ public class AiWorkflowServiceImpl implements AiWorkflowService { } } - private void validateKeyUnique(Long id, String key) { - if (StrUtil.isBlank(key)) { + private void validateCodeUnique(Long id, String code) { + if (StrUtil.isBlank(code)) { return; } - AiWorkflowDO workflow = workflowMapper.selectByKey(key); + AiWorkflowDO workflow = workflowMapper.selectByCode(code); if (ObjUtil.isNull(workflow)) { return; } if (ObjUtil.isNull(id)) { - throw exception(WORKFLOW_KEY_EXISTS); + throw exception(WORKFLOW_CODE_EXISTS); } if (ObjUtil.notEqual(workflow.getId(), id)) { - throw exception(WORKFLOW_KEY_EXISTS); + throw exception(WORKFLOW_CODE_EXISTS); } } - private Tinyflow parseFlowParam(String model) { + private Tinyflow parseFlowParam(String graph) { // TODO @lesan:可以使用 jackson 哇? - JSONObject json = JSONObject.parseObject(model); + JSONObject json = JSONObject.parseObject(graph); JSONArray nodeArr = json.getJSONArray("nodes"); - Tinyflow tinyflow = new Tinyflow(json.toJSONString()); + Tinyflow tinyflow = new Tinyflow(json.toJSONString()); for (int i = 0; i < nodeArr.size(); i++) { JSONObject node = nodeArr.getJSONObject(i); switch (node.getString("type")) {