Commit 2aff972600005080775f2d3df10763a0fb83e001

Authored by Lesan
1 parent 4bb52bb3

feat: AI工作流优化

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 {
63 63  
64 64 // ========== AI 工作流 1-040-011-000 ==========
65 65 ErrorCode WORKFLOW_NOT_EXISTS = new ErrorCode(1_040_011_000, "工作流不存在");
66   - ErrorCode WORKFLOW_KEY_EXISTS = new ErrorCode(1_040_011_001, "工作流标识已存在");
  66 + ErrorCode WORKFLOW_CODE_EXISTS = new ErrorCode(1_040_011_001, "工作流标识已存在");
67 67  
68 68 }
... ...
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 {
67 67 return success(BeanUtils.toBean(pageResult, AiWorkflowRespVO.class));
68 68 }
69 69  
70   - // TODO @lesan:要不融合到 updateWorkflow 接口?
71   - @PutMapping("/updateWorkflowModel")
72   - @Operation(summary = "更新 AI 工作流模型")
73   - @PreAuthorize("@ss.hasPermission('ai:workflow:update')")
74   - public CommonResult<Boolean> updateWorkflowModel(@Valid @RequestBody AiWorkflowUpdateModelReqVO updateReqVO) {
75   - workflowService.updateWorkflowModel(updateReqVO);
76   - return success(true);
77   - }
78   -
79 70 @PostMapping("/test")
80 71 @Operation(summary = "测试 AI 工作流")
81 72 @PreAuthorize("@ss.hasPermission('ai:workflow:test')")
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/workflow/vo/AiWorkflowPageReqVO.java
1 1 package cn.iocoder.yudao.module.ai.controller.admin.workflow.vo;
2 2  
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
3 4 import cn.iocoder.yudao.framework.common.pojo.PageParam;
  5 +import cn.iocoder.yudao.framework.common.validation.InEnum;
4 6 import io.swagger.v3.oas.annotations.media.Schema;
5 7 import lombok.Data;
6 8 import org.springframework.format.annotation.DateTimeFormat;
... ... @@ -17,7 +19,11 @@ public class AiWorkflowPageReqVO extends PageParam {
17 19 private String name;
18 20  
19 21 @Schema(description = "标识", example = "FLOW")
20   - private String definitionKey;
  22 + private String code;
  23 +
  24 + @Schema(description = "状态", example = "1")
  25 + @InEnum(CommonStatusEnum.class)
  26 + private Integer status;
21 27  
22 28 @Schema(description = "创建时间")
23 29 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
... ...
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 {
13 13 private Long id;
14 14  
15 15 @Schema(description = "工作流标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "FLOW")
16   - private String definitionKey;
  16 + private String code;
17 17  
18 18 @Schema(description = "工作流名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "工作流")
19 19 private String name;
20 20  
  21 + @Schema(description = "备注", requiredMode = Schema.RequiredMode.REQUIRED, example = "工作流")
  22 + private String remark;
  23 +
  24 + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  25 + private Integer status;
  26 +
21 27 @Schema(description = "工作流模型 JSON", requiredMode = Schema.RequiredMode.REQUIRED, example = "{}")
22   - private String model;
  28 + private String graph;
23 29  
24 30 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "时间戳格式")
25 31 private LocalDateTime createTime;
... ...
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;
2 2  
3 3 import io.swagger.v3.oas.annotations.media.Schema;
4 4 import jakarta.validation.constraints.NotEmpty;
  5 +import jakarta.validation.constraints.NotNull;
5 6 import lombok.Data;
6 7  
7 8 @Schema(description = "管理后台 - AI 工作流新增/修改 Request VO")
... ... @@ -13,10 +14,21 @@ public class AiWorkflowSaveReqVO {
13 14  
14 15 @Schema(description = "工作流标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "FLOW")
15 16 @NotEmpty(message = "工作流标识不能为空")
16   - private String definitionKey;
  17 + private String code;
17 18  
18 19 @Schema(description = "工作流名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "工作流")
19 20 @NotEmpty(message = "工作流名称不能为空")
20 21 private String name;
21 22  
  23 + @Schema(description = "备注", example = "FLOW")
  24 + private String remark;
  25 +
  26 + @Schema(description = "工作流模型", requiredMode = Schema.RequiredMode.REQUIRED, example = "{}")
  27 + @NotEmpty(message = "工作流模型不能为空")
  28 + private String graph;
  29 +
  30 + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "FLOW")
  31 + @NotNull(message = "状态不能为空")
  32 + private Integer status;
  33 +
22 34 }
... ...
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 {
12 12  
13 13 @Schema(description = "工作流模型", requiredMode = Schema.RequiredMode.REQUIRED, example = "{}")
14 14 @NotEmpty(message = "工作流模型不能为空")
15   - private String model;
  15 + private String graph;
16 16  
17 17 @Schema(description = "参数", requiredMode = Schema.RequiredMode.REQUIRED, example = "{}")
18 18 private Map<String, Object> params;
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/workflow/vo/AiWorkflowUpdateModelReqVO.java deleted
1   -package cn.iocoder.yudao.module.ai.controller.admin.workflow.vo;
2   -
3   -import io.swagger.v3.oas.annotations.media.Schema;
4   -import jakarta.validation.constraints.NotEmpty;
5   -import lombok.Data;
6   -
7   -@Schema(description = "管理后台 - AI 工作流修改流程模型 Request VO")
8   -@Data
9   -public class AiWorkflowUpdateModelReqVO {
10   -
11   - @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
12   - private Long id;
13   -
14   - @Schema(description = "工作流模型", requiredMode = Schema.RequiredMode.REQUIRED, example = "{}")
15   - @NotEmpty(message = "工作流模型不能为空")
16   - private String model;
17   -
18   -}
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/workflow/AiWorkflowDO.java
1 1 package cn.iocoder.yudao.module.ai.dal.dataobject.workflow;
2 2  
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
3 4 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 5 import com.baomidou.mybatisplus.annotation.KeySequence;
5 6 import com.baomidou.mybatisplus.annotation.TableId;
... ... @@ -28,13 +29,23 @@ public class AiWorkflowDO extends BaseDO {
28 29 /**
29 30 * 工作流标识
30 31 */
31   - // TODO @lesan:要不换成 code?主要想,和 bpm 工作流,有点区分,字段上。
32   - private String definitionKey;
  32 + private String code;
33 33  
34   - // TODO @lesan:graph 用这个如何?发现大家貌似更爱用这个字段哈。图!
35 34 /**
36 35 * 工作流模型 JSON 数据
37 36 */
38   - private String model;
  37 + private String graph;
  38 +
  39 + /**
  40 + * 备注
  41 + */
  42 + private String remark;
  43 +
  44 + /**
  45 + * 状态
  46 + *
  47 + * 枚举 {@link CommonStatusEnum}
  48 + */
  49 + private Integer status;
39 50  
40 51 }
... ...
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;
15 15 @Mapper
16 16 public interface AiWorkflowMapper extends BaseMapperX<AiWorkflowDO> {
17 17  
18   - default AiWorkflowDO selectByKey(String key) {
19   - return selectOne(AiWorkflowDO::getDefinitionKey, key);
  18 + default AiWorkflowDO selectByCode(String code) {
  19 + return selectOne(AiWorkflowDO::getCode, code);
20 20 }
21 21  
22 22 default PageResult<AiWorkflowDO> selectPage(AiWorkflowPageReqVO pageReqVO) {
23 23 return selectPage(pageReqVO, new LambdaQueryWrapperX<AiWorkflowDO>()
  24 + .eqIfPresent(AiWorkflowDO::getStatus, pageReqVO.getStatus())
24 25 .likeIfPresent(AiWorkflowDO::getName, pageReqVO.getName())
25   - .likeIfPresent(AiWorkflowDO::getDefinitionKey, pageReqVO.getDefinitionKey()));
  26 + .likeIfPresent(AiWorkflowDO::getCode, pageReqVO.getCode())
  27 + .betweenIfPresent(AiWorkflowDO::getCreateTime, pageReqVO.getCreateTime()));
26 28 }
27 29  
28 30 }
... ...
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;
4 4 import cn.iocoder.yudao.module.ai.controller.admin.workflow.vo.AiWorkflowPageReqVO;
5 5 import cn.iocoder.yudao.module.ai.controller.admin.workflow.vo.AiWorkflowSaveReqVO;
6 6 import cn.iocoder.yudao.module.ai.controller.admin.workflow.vo.AiWorkflowTestReqVO;
7   -import cn.iocoder.yudao.module.ai.controller.admin.workflow.vo.AiWorkflowUpdateModelReqVO;
8 7 import cn.iocoder.yudao.module.ai.dal.dataobject.workflow.AiWorkflowDO;
9 8 import jakarta.validation.Valid;
10 9  
... ... @@ -54,13 +53,6 @@ public interface AiWorkflowService {
54 53 PageResult<AiWorkflowDO> getWorkflowPage(AiWorkflowPageReqVO pageReqVO);
55 54  
56 55 /**
57   - * 修改工作流模型 JSON 数据
58   - *
59   - * @param updateReqVO 更新数据
60   - */
61   - void updateWorkflowModel(AiWorkflowUpdateModelReqVO updateReqVO);
62   -
63   - /**
64 56 * 测试 AI 工作流
65 57 *
66 58 * @param testReqVO 测试数据
... ...
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;
7 7 import cn.iocoder.yudao.module.ai.controller.admin.workflow.vo.AiWorkflowPageReqVO;
8 8 import cn.iocoder.yudao.module.ai.controller.admin.workflow.vo.AiWorkflowSaveReqVO;
9 9 import cn.iocoder.yudao.module.ai.controller.admin.workflow.vo.AiWorkflowTestReqVO;
10   -import cn.iocoder.yudao.module.ai.controller.admin.workflow.vo.AiWorkflowUpdateModelReqVO;
11 10 import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiApiKeyDO;
12 11 import cn.iocoder.yudao.module.ai.dal.dataobject.workflow.AiWorkflowDO;
13 12 import cn.iocoder.yudao.module.ai.dal.mysql.workflow.AiWorkflowMapper;
... ... @@ -22,7 +21,7 @@ import org.springframework.stereotype.Service;
22 21 import java.util.Map;
23 22  
24 23 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
25   -import static cn.iocoder.yudao.module.ai.enums.ErrorCodeConstants.WORKFLOW_KEY_EXISTS;
  24 +import static cn.iocoder.yudao.module.ai.enums.ErrorCodeConstants.WORKFLOW_CODE_EXISTS;
26 25 import static cn.iocoder.yudao.module.ai.enums.ErrorCodeConstants.WORKFLOW_NOT_EXISTS;
27 26  
28 27 /**
... ... @@ -42,16 +41,15 @@ public class AiWorkflowServiceImpl implements AiWorkflowService {
42 41  
43 42 @Override
44 43 public Long createWorkflow(AiWorkflowSaveReqVO createReqVO) {
45   - validateWorkflowForCreateOrUpdate(null, createReqVO.getDefinitionKey());
  44 + validateWorkflowForCreateOrUpdate(null, createReqVO.getCode());
46 45 AiWorkflowDO workflow = BeanUtils.toBean(createReqVO, AiWorkflowDO.class);
47   - workflow.setModel(StrUtil.EMPTY);
48 46 workflowMapper.insert(workflow);
49 47 return workflow.getId();
50 48 }
51 49  
52 50 @Override
53 51 public void updateWorkflow(AiWorkflowSaveReqVO updateReqVO) {
54   - validateWorkflowForCreateOrUpdate(updateReqVO.getId(), updateReqVO.getDefinitionKey());
  52 + validateWorkflowForCreateOrUpdate(updateReqVO.getId(), updateReqVO.getCode());
55 53 AiWorkflowDO workflow = BeanUtils.toBean(updateReqVO, AiWorkflowDO.class);
56 54 workflowMapper.updateById(workflow);
57 55 }
... ... @@ -73,21 +71,15 @@ public class AiWorkflowServiceImpl implements AiWorkflowService {
73 71 }
74 72  
75 73 @Override
76   - public void updateWorkflowModel(AiWorkflowUpdateModelReqVO updateReqVO) {
77   - validateWorkflowExists(updateReqVO.getId());
78   - workflowMapper.updateById(new AiWorkflowDO().setId(updateReqVO.getId()).setModel(updateReqVO.getModel()));
79   - }
80   -
81   - @Override
82 74 public Object testWorkflow(AiWorkflowTestReqVO testReqVO) {
83 75 Map<String, Object> variables = testReqVO.getParams();
84   - Tinyflow tinyflow = parseFlowParam(testReqVO.getModel());
  76 + Tinyflow tinyflow = parseFlowParam(testReqVO.getGraph());
85 77 return tinyflow.toChain().executeForResult(variables);
86 78 }
87 79  
88   - private void validateWorkflowForCreateOrUpdate(Long id, String key) {
  80 + private void validateWorkflowForCreateOrUpdate(Long id, String code) {
89 81 validateWorkflowExists(id);
90   - validateKeyUnique(id, key);
  82 + validateCodeUnique(id, code);
91 83 }
92 84  
93 85 private void validateWorkflowExists(Long id) {
... ... @@ -100,27 +92,27 @@ public class AiWorkflowServiceImpl implements AiWorkflowService {
100 92 }
101 93 }
102 94  
103   - private void validateKeyUnique(Long id, String key) {
104   - if (StrUtil.isBlank(key)) {
  95 + private void validateCodeUnique(Long id, String code) {
  96 + if (StrUtil.isBlank(code)) {
105 97 return;
106 98 }
107   - AiWorkflowDO workflow = workflowMapper.selectByKey(key);
  99 + AiWorkflowDO workflow = workflowMapper.selectByCode(code);
108 100 if (ObjUtil.isNull(workflow)) {
109 101 return;
110 102 }
111 103 if (ObjUtil.isNull(id)) {
112   - throw exception(WORKFLOW_KEY_EXISTS);
  104 + throw exception(WORKFLOW_CODE_EXISTS);
113 105 }
114 106 if (ObjUtil.notEqual(workflow.getId(), id)) {
115   - throw exception(WORKFLOW_KEY_EXISTS);
  107 + throw exception(WORKFLOW_CODE_EXISTS);
116 108 }
117 109 }
118 110  
119   - private Tinyflow parseFlowParam(String model) {
  111 + private Tinyflow parseFlowParam(String graph) {
120 112 // TODO @lesan:可以使用 jackson 哇?
121   - JSONObject json = JSONObject.parseObject(model);
  113 + JSONObject json = JSONObject.parseObject(graph);
122 114 JSONArray nodeArr = json.getJSONArray("nodes");
123   - Tinyflow tinyflow = new Tinyflow(json.toJSONString());
  115 + Tinyflow tinyflow = new Tinyflow(json.toJSONString());
124 116 for (int i = 0; i < nodeArr.size(); i++) {
125 117 JSONObject node = nodeArr.getJSONObject(i);
126 118 switch (node.getString("type")) {
... ...