feat: AI工作流优化
This commit is contained in:
parent
4bb52bb37d
commit
2aff972600
|
@ -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, "工作流标识已存在");
|
||||
|
||||
}
|
||||
|
|
|
@ -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<Boolean> updateWorkflowModel(@Valid @RequestBody AiWorkflowUpdateModelReqVO updateReqVO) {
|
||||
workflowService.updateWorkflowModel(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PostMapping("/test")
|
||||
@Operation(summary = "测试 AI 工作流")
|
||||
@PreAuthorize("@ss.hasPermission('ai:workflow:test')")
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
|
@ -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<String, Object> params;
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
|
@ -15,14 +15,16 @@ import org.apache.ibatis.annotations.Mapper;
|
|||
@Mapper
|
||||
public interface AiWorkflowMapper extends BaseMapperX<AiWorkflowDO> {
|
||||
|
||||
default AiWorkflowDO selectByKey(String key) {
|
||||
return selectOne(AiWorkflowDO::getDefinitionKey, key);
|
||||
default AiWorkflowDO selectByCode(String code) {
|
||||
return selectOne(AiWorkflowDO::getCode, code);
|
||||
}
|
||||
|
||||
default PageResult<AiWorkflowDO> selectPage(AiWorkflowPageReqVO pageReqVO) {
|
||||
return selectPage(pageReqVO, new LambdaQueryWrapperX<AiWorkflowDO>()
|
||||
.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()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<AiWorkflowDO> getWorkflowPage(AiWorkflowPageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 修改工作流模型 JSON 数据
|
||||
*
|
||||
* @param updateReqVO 更新数据
|
||||
*/
|
||||
void updateWorkflowModel(AiWorkflowUpdateModelReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 测试 AI 工作流
|
||||
*
|
||||
|
|
|
@ -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<String, Object> 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")) {
|
||||
|
|
Loading…
Reference in New Issue