增加节点面板查询
This commit is contained in:
parent
e37175099a
commit
5ea3c5396b
@ -0,0 +1,76 @@
|
|||||||
|
package com.qqchen.deploy.backend.workflow.api;
|
||||||
|
|
||||||
|
import com.qqchen.deploy.backend.framework.api.Response;
|
||||||
|
import com.qqchen.deploy.backend.framework.controller.BaseController;
|
||||||
|
import com.qqchen.deploy.backend.workflow.dto.WorkflowNodeDefinitionDTO;
|
||||||
|
import com.qqchen.deploy.backend.workflow.entity.WorkflowNodeDefinition;
|
||||||
|
import com.qqchen.deploy.backend.workflow.enums.NodeCategoryEnums;
|
||||||
|
import com.qqchen.deploy.backend.workflow.query.WorkflowNodeDefinitionQuery;
|
||||||
|
import com.qqchen.deploy.backend.workflow.service.IWorkflowNodeDefinitionService;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 工作流节点定义控制器
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/workflow/node-definition")
|
||||||
|
@Tag(name = "工作流节点定义管理", description = "工作流节点定义管理相关接口")
|
||||||
|
public class WorkflowNodeDefinitionApiController extends BaseController<WorkflowNodeDefinition, WorkflowNodeDefinitionDTO, Long, WorkflowNodeDefinitionQuery> {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IWorkflowNodeDefinitionService workflowNodeDefinitionService;
|
||||||
|
|
||||||
|
@Operation(summary = "根据节点类型获取节点定义")
|
||||||
|
@GetMapping("/type/{type}")
|
||||||
|
public Response<WorkflowNodeDefinitionDTO> getByType(
|
||||||
|
@Parameter(description = "节点类型", required = true) @PathVariable String type
|
||||||
|
) {
|
||||||
|
return Response.success(workflowNodeDefinitionService.getByType(type));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "根据分类获取节点定义列表")
|
||||||
|
@GetMapping("/category/{category}")
|
||||||
|
public Response<List<WorkflowNodeDefinitionDTO>> listByCategory(
|
||||||
|
@Parameter(description = "节点分类", required = true) @PathVariable NodeCategoryEnums category
|
||||||
|
) {
|
||||||
|
return Response.success(workflowNodeDefinitionService.listByCategory(category));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取所有启用的节点定义")
|
||||||
|
@GetMapping("/enabled")
|
||||||
|
public Response<List<WorkflowNodeDefinitionDTO>> listAllEnabled() {
|
||||||
|
return Response.success(workflowNodeDefinitionService.listAllEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "启用节点定义")
|
||||||
|
@PostMapping("/{id}/enable")
|
||||||
|
public Response<Void> enable(
|
||||||
|
@Parameter(description = "节点定义ID", required = true) @PathVariable Long id
|
||||||
|
) {
|
||||||
|
workflowNodeDefinitionService.enable(id);
|
||||||
|
return Response.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "禁用节点定义")
|
||||||
|
@PostMapping("/{id}/disable")
|
||||||
|
public Response<Void> disable(
|
||||||
|
@Parameter(description = "节点定义ID", required = true) @PathVariable Long id
|
||||||
|
) {
|
||||||
|
workflowNodeDefinitionService.disable(id);
|
||||||
|
return Response.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void exportData(HttpServletResponse response, List<WorkflowNodeDefinitionDTO> data) {
|
||||||
|
// 暂不支持导出
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
package com.qqchen.deploy.backend.workflow.converter;
|
||||||
|
|
||||||
|
import com.qqchen.deploy.backend.framework.converter.BaseConverter;
|
||||||
|
import com.qqchen.deploy.backend.workflow.dto.WorkflowNodeDefinitionDTO;
|
||||||
|
import com.qqchen.deploy.backend.workflow.entity.WorkflowNodeDefinition;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 工作流节点定义转换器
|
||||||
|
*/
|
||||||
|
@Mapper(config = BaseConverter.class)
|
||||||
|
public interface WorkflowNodeDefinitionConverter extends BaseConverter<WorkflowNodeDefinition, WorkflowNodeDefinitionDTO> {
|
||||||
|
}
|
||||||
@ -0,0 +1,43 @@
|
|||||||
|
package com.qqchen.deploy.backend.workflow.dto;
|
||||||
|
|
||||||
|
import com.qqchen.deploy.backend.framework.dto.BaseDTO;
|
||||||
|
import com.qqchen.deploy.backend.workflow.enums.NodeCategoryEnums;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 工作流节点定义DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "工作流节点定义")
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class WorkflowNodeDefinitionDTO extends BaseDTO {
|
||||||
|
|
||||||
|
@Schema(description = "节点类型编码")
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
@Schema(description = "节点名称")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "节点描述")
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@Schema(description = "节点分类")
|
||||||
|
private NodeCategoryEnums category;
|
||||||
|
|
||||||
|
@Schema(description = "Flowable配置JSON")
|
||||||
|
private String flowableConfig;
|
||||||
|
|
||||||
|
@Schema(description = "X6图形配置JSON")
|
||||||
|
private String graphConfig;
|
||||||
|
|
||||||
|
@Schema(description = "表单配置JSON")
|
||||||
|
private String formConfig;
|
||||||
|
|
||||||
|
@Schema(description = "排序号")
|
||||||
|
private Integer orderNum;
|
||||||
|
|
||||||
|
@Schema(description = "是否启用")
|
||||||
|
private Boolean enabled;
|
||||||
|
}
|
||||||
@ -0,0 +1,97 @@
|
|||||||
|
package com.qqchen.deploy.backend.workflow.entity;
|
||||||
|
|
||||||
|
import com.qqchen.deploy.backend.framework.annotation.LogicDelete;
|
||||||
|
import com.qqchen.deploy.backend.framework.domain.Entity;
|
||||||
|
import com.qqchen.deploy.backend.workflow.enums.NodeCategoryEnums;
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.EnumType;
|
||||||
|
import jakarta.persistence.Enumerated;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 工作流节点定义
|
||||||
|
* 用于定义工作流中可用的节点类型,包含 Flowable 引擎配置和前端 X6 图形配置
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@jakarta.persistence.Entity
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Table(name = "workflow_node_definition")
|
||||||
|
@LogicDelete
|
||||||
|
public class WorkflowNodeDefinition extends Entity<Long> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点类型编码(如:userTask, serviceTask, shellTask 等)
|
||||||
|
* 对应 Flowable 中的节点类型
|
||||||
|
*/
|
||||||
|
@Column(nullable = false, unique = true)
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点名称
|
||||||
|
*/
|
||||||
|
@Column(nullable = false)
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点描述
|
||||||
|
*/
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点分类
|
||||||
|
*/
|
||||||
|
@Enumerated(EnumType.STRING)
|
||||||
|
@Column(nullable = false)
|
||||||
|
private NodeCategoryEnums category;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flowable 配置 JSON
|
||||||
|
* 包含:
|
||||||
|
* - delegateExpression: 委托表达式
|
||||||
|
* - class: 实现类
|
||||||
|
* - expression: 表达式
|
||||||
|
* - listeners: 监听器配置
|
||||||
|
* - 其他 Flowable 特定配置
|
||||||
|
*/
|
||||||
|
@Column(columnDefinition = "text")
|
||||||
|
private String flowableConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* X6 图形配置 JSON
|
||||||
|
* 包含:
|
||||||
|
* - shape: 节点形状
|
||||||
|
* - width: 宽度
|
||||||
|
* - height: 高度
|
||||||
|
* - ports: 连接点
|
||||||
|
* - icon: 图标
|
||||||
|
* - color: 颜色
|
||||||
|
* - 其他 X6 特定配置
|
||||||
|
*/
|
||||||
|
@Column(columnDefinition = "text", nullable = false)
|
||||||
|
private String graphConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表单配置 JSON
|
||||||
|
* 定义节点的可配置属性,用于前端动态渲染表单
|
||||||
|
* 包含:
|
||||||
|
* - 基础属性(名称、描述等)
|
||||||
|
* - 业务属性(具体节点类型的特定属性)
|
||||||
|
* - 表单验证规则
|
||||||
|
*/
|
||||||
|
@Column(columnDefinition = "text")
|
||||||
|
private String formConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 排序号
|
||||||
|
*/
|
||||||
|
@Column(nullable = false)
|
||||||
|
private Integer orderNum = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否启用
|
||||||
|
*/
|
||||||
|
@Column(nullable = false)
|
||||||
|
private Boolean enabled = true;
|
||||||
|
}
|
||||||
@ -6,7 +6,7 @@ import lombok.Getter;
|
|||||||
* BPMN节点类型枚举
|
* BPMN节点类型枚举
|
||||||
*/
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
public enum BpmnNodeType {
|
public enum BpmnNodeTypeEnums {
|
||||||
START("start", "startEvent"),
|
START("start", "startEvent"),
|
||||||
END("end", "endEvent"),
|
END("end", "endEvent"),
|
||||||
USER_TASK("userTask", "userTask"),
|
USER_TASK("userTask", "userTask"),
|
||||||
@ -17,13 +17,13 @@ public enum BpmnNodeType {
|
|||||||
private final String shape;
|
private final String shape;
|
||||||
private final String bpmnType;
|
private final String bpmnType;
|
||||||
|
|
||||||
BpmnNodeType(String shape, String bpmnType) {
|
BpmnNodeTypeEnums(String shape, String bpmnType) {
|
||||||
this.shape = shape;
|
this.shape = shape;
|
||||||
this.bpmnType = bpmnType;
|
this.bpmnType = bpmnType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BpmnNodeType fromShape(String shape) {
|
public static BpmnNodeTypeEnums fromShape(String shape) {
|
||||||
for (BpmnNodeType type : values()) {
|
for (BpmnNodeTypeEnums type : values()) {
|
||||||
if (type.getShape().equals(shape)) {
|
if (type.getShape().equals(shape)) {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
package com.qqchen.deploy.backend.workflow.enums;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 工作流节点分类枚举
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum NodeCategoryEnums {
|
||||||
|
|
||||||
|
EVENT("EVENT", "事件节点"),
|
||||||
|
TASK("TASK", "任务节点"),
|
||||||
|
GATEWAY("GATEWAY", "网关节点"),
|
||||||
|
CONTAINER("CONTAINER", "容器节点");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分类编码
|
||||||
|
*/
|
||||||
|
private final String code;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分类名称
|
||||||
|
*/
|
||||||
|
private final String name;
|
||||||
|
}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
package com.qqchen.deploy.backend.workflow.handler;
|
package com.qqchen.deploy.backend.workflow.handler;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.qqchen.deploy.backend.workflow.enums.BpmnNodeType;
|
import com.qqchen.deploy.backend.workflow.enums.BpmnNodeTypeEnums;
|
||||||
import com.qqchen.deploy.backend.workflow.model.BpmnNodeConfig;
|
import com.qqchen.deploy.backend.workflow.model.BpmnNodeConfig;
|
||||||
import org.flowable.bpmn.model.FlowElement;
|
import org.flowable.bpmn.model.FlowElement;
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ public interface BpmnNodeHandler<T extends FlowElement> {
|
|||||||
*
|
*
|
||||||
* @return 节点类型
|
* @return 节点类型
|
||||||
*/
|
*/
|
||||||
BpmnNodeType getType();
|
BpmnNodeTypeEnums getType();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取处理的元素类型
|
* 获取处理的元素类型
|
||||||
|
|||||||
@ -2,7 +2,7 @@ package com.qqchen.deploy.backend.workflow.handler.impl;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.qqchen.deploy.backend.workflow.annotation.BpmnNode;
|
import com.qqchen.deploy.backend.workflow.annotation.BpmnNode;
|
||||||
import com.qqchen.deploy.backend.workflow.enums.BpmnNodeType;
|
import com.qqchen.deploy.backend.workflow.enums.BpmnNodeTypeEnums;
|
||||||
import com.qqchen.deploy.backend.workflow.handler.BpmnNodeHandler;
|
import com.qqchen.deploy.backend.workflow.handler.BpmnNodeHandler;
|
||||||
import com.qqchen.deploy.backend.workflow.model.BpmnNodeConfig;
|
import com.qqchen.deploy.backend.workflow.model.BpmnNodeConfig;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@ -51,8 +51,8 @@ public class ShellTaskHandler implements BpmnNodeHandler<ServiceTask> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BpmnNodeType getType() {
|
public BpmnNodeTypeEnums getType() {
|
||||||
return BpmnNodeType.SHELL_TASK;
|
return BpmnNodeTypeEnums.SHELL_TASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
package com.qqchen.deploy.backend.workflow.model;
|
package com.qqchen.deploy.backend.workflow.model;
|
||||||
|
|
||||||
import com.qqchen.deploy.backend.workflow.enums.BpmnNodeType;
|
import com.qqchen.deploy.backend.workflow.enums.BpmnNodeTypeEnums;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -24,7 +24,7 @@ public class BpmnNodeConfig {
|
|||||||
/**
|
/**
|
||||||
* 节点类型
|
* 节点类型
|
||||||
*/
|
*/
|
||||||
private BpmnNodeType type;
|
private BpmnNodeTypeEnums type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 节点属性
|
* 节点属性
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
package com.qqchen.deploy.backend.workflow.parser;
|
package com.qqchen.deploy.backend.workflow.parser;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.qqchen.deploy.backend.workflow.enums.BpmnNodeType;
|
import com.qqchen.deploy.backend.workflow.enums.BpmnNodeTypeEnums;
|
||||||
import com.qqchen.deploy.backend.workflow.model.BpmnNodeConfig;
|
import com.qqchen.deploy.backend.workflow.model.BpmnNodeConfig;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ public class BpmnNodeConfigParser {
|
|||||||
BpmnNodeConfig config = new BpmnNodeConfig();
|
BpmnNodeConfig config = new BpmnNodeConfig();
|
||||||
config.setId(node.path("id").asText());
|
config.setId(node.path("id").asText());
|
||||||
config.setName(node.path("data").path("label").asText());
|
config.setName(node.path("data").path("label").asText());
|
||||||
config.setType(BpmnNodeType.fromShape(node.path("shape").asText()));
|
config.setType(BpmnNodeTypeEnums.fromShape(node.path("shape").asText()));
|
||||||
|
|
||||||
// 解析属性
|
// 解析属性
|
||||||
JsonNode data = node.path("data");
|
JsonNode data = node.path("data");
|
||||||
|
|||||||
@ -0,0 +1,40 @@
|
|||||||
|
package com.qqchen.deploy.backend.workflow.query;
|
||||||
|
|
||||||
|
import com.qqchen.deploy.backend.framework.annotation.QueryField;
|
||||||
|
import com.qqchen.deploy.backend.framework.enums.QueryType;
|
||||||
|
import com.qqchen.deploy.backend.framework.query.BaseQuery;
|
||||||
|
import com.qqchen.deploy.backend.workflow.enums.NodeCategoryEnums;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 工作流节点定义查询对象
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class WorkflowNodeDefinitionQuery extends BaseQuery {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点类型编码
|
||||||
|
*/
|
||||||
|
@QueryField(field = "type", type = QueryType.LIKE)
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点名称
|
||||||
|
*/
|
||||||
|
@QueryField(field = "name", type = QueryType.LIKE)
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点分类
|
||||||
|
*/
|
||||||
|
@QueryField(field = "category", type = QueryType.EQUAL)
|
||||||
|
private NodeCategoryEnums category;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否启用
|
||||||
|
*/
|
||||||
|
@QueryField(field = "enabled", type = QueryType.EQUAL)
|
||||||
|
private Boolean enabled;
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
package com.qqchen.deploy.backend.workflow.repository;
|
||||||
|
|
||||||
|
import com.qqchen.deploy.backend.framework.repository.IBaseRepository;
|
||||||
|
import com.qqchen.deploy.backend.workflow.entity.WorkflowNodeDefinition;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface IWorkflowNodeDefinitionRepository extends IBaseRepository<WorkflowNodeDefinition, Long> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询所有启用的节点定义,按排序号排序
|
||||||
|
*/
|
||||||
|
List<WorkflowNodeDefinition> findByEnabledTrueOrderByOrderNumAsc();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据分类查询启用的节点定义
|
||||||
|
*/
|
||||||
|
List<WorkflowNodeDefinition> findByEnabledTrueAndCategoryOrderByOrderNumAsc(String category);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据类型查询节点定义
|
||||||
|
*/
|
||||||
|
Optional<WorkflowNodeDefinition> findByTypeAndEnabledTrue(String type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查类型是否存在
|
||||||
|
*/
|
||||||
|
boolean existsByTypeAndDeletedFalse(String type);
|
||||||
|
}
|
||||||
@ -0,0 +1,51 @@
|
|||||||
|
package com.qqchen.deploy.backend.workflow.service;
|
||||||
|
|
||||||
|
import com.qqchen.deploy.backend.framework.service.IBaseService;
|
||||||
|
import com.qqchen.deploy.backend.workflow.dto.WorkflowNodeDefinitionDTO;
|
||||||
|
import com.qqchen.deploy.backend.workflow.entity.WorkflowNodeDefinition;
|
||||||
|
import com.qqchen.deploy.backend.workflow.enums.NodeCategoryEnums;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 工作流节点定义服务接口
|
||||||
|
*/
|
||||||
|
public interface IWorkflowNodeDefinitionService extends IBaseService<WorkflowNodeDefinition, WorkflowNodeDefinitionDTO, Long> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据节点类型获取节点定义
|
||||||
|
*
|
||||||
|
* @param type 节点类型
|
||||||
|
* @return 节点定义
|
||||||
|
*/
|
||||||
|
WorkflowNodeDefinitionDTO getByType(String type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据分类获取节点定义列表
|
||||||
|
*
|
||||||
|
* @param category 节点分类
|
||||||
|
* @return 节点定义列表
|
||||||
|
*/
|
||||||
|
List<WorkflowNodeDefinitionDTO> listByCategory(NodeCategoryEnums category);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有启用的节点定义
|
||||||
|
*
|
||||||
|
* @return 节点定义列表
|
||||||
|
*/
|
||||||
|
List<WorkflowNodeDefinitionDTO> listAllEnabled();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启用节点定义
|
||||||
|
*
|
||||||
|
* @param id 节点定义ID
|
||||||
|
*/
|
||||||
|
void enable(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 禁用节点定义
|
||||||
|
*
|
||||||
|
* @param id 节点定义ID
|
||||||
|
*/
|
||||||
|
void disable(Long id);
|
||||||
|
}
|
||||||
@ -0,0 +1,71 @@
|
|||||||
|
package com.qqchen.deploy.backend.workflow.service.impl;
|
||||||
|
|
||||||
|
import com.qqchen.deploy.backend.framework.service.impl.BaseServiceImpl;
|
||||||
|
import com.qqchen.deploy.backend.workflow.dto.WorkflowNodeDefinitionDTO;
|
||||||
|
import com.qqchen.deploy.backend.workflow.entity.WorkflowNodeDefinition;
|
||||||
|
import com.qqchen.deploy.backend.workflow.enums.NodeCategoryEnums;
|
||||||
|
import com.qqchen.deploy.backend.workflow.repository.IWorkflowNodeDefinitionRepository;
|
||||||
|
import com.qqchen.deploy.backend.workflow.service.IWorkflowNodeDefinitionService;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 工作流节点定义服务实现
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class WorkflowNodeDefinitionServiceImpl extends BaseServiceImpl<WorkflowNodeDefinition, WorkflowNodeDefinitionDTO, Long> implements IWorkflowNodeDefinitionService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IWorkflowNodeDefinitionRepository workflowNodeDefinitionRepository;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WorkflowNodeDefinitionDTO getByType(String type) {
|
||||||
|
return workflowNodeDefinitionRepository.findByTypeAndEnabledTrue(type)
|
||||||
|
.map(super.converter::toDto)
|
||||||
|
.orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<WorkflowNodeDefinitionDTO> listByCategory(NodeCategoryEnums category) {
|
||||||
|
return workflowNodeDefinitionRepository.findByEnabledTrueAndCategoryOrderByOrderNumAsc(category.name())
|
||||||
|
.stream()
|
||||||
|
.map(super.converter::toDto)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<WorkflowNodeDefinitionDTO> listAllEnabled() {
|
||||||
|
return workflowNodeDefinitionRepository.findByEnabledTrueOrderByOrderNumAsc()
|
||||||
|
.stream()
|
||||||
|
.map(super.converter::toDto)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void enable(Long id) {
|
||||||
|
WorkflowNodeDefinition definition = workflowNodeDefinitionRepository.findById(id)
|
||||||
|
.orElseThrow(() -> new RuntimeException("Node definition not found: " + id));
|
||||||
|
|
||||||
|
definition.setEnabled(true);
|
||||||
|
workflowNodeDefinitionRepository.save(definition);
|
||||||
|
log.info("Enabled node definition: {}", id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void disable(Long id) {
|
||||||
|
WorkflowNodeDefinition definition = workflowNodeDefinitionRepository.findById(id)
|
||||||
|
.orElseThrow(() -> new RuntimeException("Node definition not found: " + id));
|
||||||
|
|
||||||
|
definition.setEnabled(false);
|
||||||
|
workflowNodeDefinitionRepository.save(definition);
|
||||||
|
log.info("Disabled node definition: {}", id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,7 +3,7 @@ package com.qqchen.deploy.backend.workflow.util;
|
|||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.qqchen.deploy.backend.workflow.constants.BpmnConstants;
|
import com.qqchen.deploy.backend.workflow.constants.BpmnConstants;
|
||||||
import com.qqchen.deploy.backend.workflow.enums.BpmnNodeType;
|
import com.qqchen.deploy.backend.workflow.enums.BpmnNodeTypeEnums;
|
||||||
import com.qqchen.deploy.backend.workflow.handler.BpmnNodeHandler;
|
import com.qqchen.deploy.backend.workflow.handler.BpmnNodeHandler;
|
||||||
import com.qqchen.deploy.backend.workflow.model.BpmnNodeConfig;
|
import com.qqchen.deploy.backend.workflow.model.BpmnNodeConfig;
|
||||||
import com.qqchen.deploy.backend.workflow.parser.BpmnNodeConfigParser;
|
import com.qqchen.deploy.backend.workflow.parser.BpmnNodeConfigParser;
|
||||||
@ -28,7 +28,7 @@ import java.util.stream.Collectors;
|
|||||||
@Component
|
@Component
|
||||||
public class BpmnConverter {
|
public class BpmnConverter {
|
||||||
|
|
||||||
private final Map<BpmnNodeType, BpmnNodeHandler<?>> handlers;
|
private final Map<BpmnNodeTypeEnums, BpmnNodeHandler<?>> handlers;
|
||||||
private final ObjectMapper objectMapper;
|
private final ObjectMapper objectMapper;
|
||||||
private final BpmnNodeConfigParser configParser;
|
private final BpmnNodeConfigParser configParser;
|
||||||
private final BpmnXMLConverter bpmnXMLConverter;
|
private final BpmnXMLConverter bpmnXMLConverter;
|
||||||
|
|||||||
@ -45,7 +45,7 @@ CREATE TABLE sys_department (
|
|||||||
CONSTRAINT UK_department_code UNIQUE (code)
|
CONSTRAINT UK_department_code UNIQUE (code)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='部门表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='部门表';
|
||||||
|
|
||||||
-- 用<EFBFBD><EFBFBD><EFBFBD>表
|
-- 用户表
|
||||||
CREATE TABLE IF NOT EXISTS sys_user (
|
CREATE TABLE IF NOT EXISTS sys_user (
|
||||||
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
|
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
|
||||||
create_by VARCHAR(255) NULL COMMENT '创建人',
|
create_by VARCHAR(255) NULL COMMENT '创建人',
|
||||||
@ -395,7 +395,7 @@ CREATE TABLE workflow_definition (
|
|||||||
name VARCHAR(100) NOT NULL COMMENT '流程名称',
|
name VARCHAR(100) NOT NULL COMMENT '流程名称',
|
||||||
`key` VARCHAR(50) NOT NULL COMMENT '流程标识',
|
`key` VARCHAR(50) NOT NULL COMMENT '流程标识',
|
||||||
flow_version INT NOT NULL COMMENT '流程版本',
|
flow_version INT NOT NULL COMMENT '流程版本',
|
||||||
bpmn_xml TEXT NOT NULL COMMENT 'BPMN XML内容',
|
bpmn_xml TEXT COMMENT 'BPMN XML内容',
|
||||||
graph_json JSON COMMENT 'x6 JSON内容',
|
graph_json JSON COMMENT 'x6 JSON内容',
|
||||||
status VARCHAR(32) NOT NULL COMMENT '状态',
|
status VARCHAR(32) NOT NULL COMMENT '状态',
|
||||||
description VARCHAR(255) NULL COMMENT '流程描述',
|
description VARCHAR(255) NULL COMMENT '流程描述',
|
||||||
@ -466,3 +466,25 @@ CREATE TABLE workflow_log (
|
|||||||
CONSTRAINT FK_workflow_log_instance FOREIGN KEY (workflow_instance_id) REFERENCES workflow_instance(id),
|
CONSTRAINT FK_workflow_log_instance FOREIGN KEY (workflow_instance_id) REFERENCES workflow_instance(id),
|
||||||
CONSTRAINT FK_workflow_log_node_instance FOREIGN KEY (node_instance_id) REFERENCES workflow_node_instance(id)
|
CONSTRAINT FK_workflow_log_node_instance FOREIGN KEY (node_instance_id) REFERENCES workflow_node_instance(id)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='工作流日志表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='工作流日志表';
|
||||||
|
|
||||||
|
-- 创建工作流节点定义表
|
||||||
|
CREATE TABLE workflow_node_definition (
|
||||||
|
id BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||||
|
type VARCHAR(50) NOT NULL COMMENT '节点类型编码',
|
||||||
|
name VARCHAR(100) NOT NULL COMMENT '节点名称',
|
||||||
|
description VARCHAR(500) COMMENT '节点描述',
|
||||||
|
category VARCHAR(50) NOT NULL COMMENT '节点分类',
|
||||||
|
flowable_config TEXT COMMENT 'Flowable引擎配置JSON',
|
||||||
|
graph_config TEXT NOT NULL COMMENT 'X6图形配置JSON',
|
||||||
|
form_config TEXT COMMENT '表单配置JSON',
|
||||||
|
order_num INT NOT NULL DEFAULT 0 COMMENT '排序号',
|
||||||
|
enabled BOOLEAN NOT NULL DEFAULT TRUE COMMENT '是否启用',
|
||||||
|
create_time DATETIME NOT NULL COMMENT '创建时间',
|
||||||
|
create_by VARCHAR(50) NOT NULL COMMENT '创建人',
|
||||||
|
update_time DATETIME NOT NULL COMMENT '更新时间',
|
||||||
|
update_by VARCHAR(50) NOT NULL COMMENT '更新人',
|
||||||
|
version INT NOT NULL DEFAULT 1 COMMENT '版本号',
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT FALSE COMMENT '是否删除',
|
||||||
|
PRIMARY KEY (id),
|
||||||
|
UNIQUE KEY uk_type (type)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='工作流节点定义表';
|
||||||
@ -154,4 +154,307 @@ INSERT INTO sys_external_system (
|
|||||||
|
|
||||||
-- --------------------------------------------------------------------------------------
|
-- --------------------------------------------------------------------------------------
|
||||||
-- 初始化工作流相关数据
|
-- 初始化工作流相关数据
|
||||||
-- --------------------------------------------------------------------------------------
|
-- --------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- 初始化工作流节点定义数据
|
||||||
|
INSERT INTO workflow_node_definition (
|
||||||
|
id, type, name, description, category,
|
||||||
|
flowable_config, graph_config, form_config,
|
||||||
|
order_num, enabled,
|
||||||
|
create_time, create_by, update_time, update_by, version, deleted
|
||||||
|
) VALUES
|
||||||
|
-- 开始节点
|
||||||
|
(1, 'startEvent', '开始节点', '流程的开始节点', 'EVENT',
|
||||||
|
-- Flowable配置
|
||||||
|
'{
|
||||||
|
"type": "startEvent"
|
||||||
|
}',
|
||||||
|
-- X6图形配置
|
||||||
|
'{
|
||||||
|
"shape": "flow-circle",
|
||||||
|
"width": 40,
|
||||||
|
"height": 40,
|
||||||
|
"ports": {
|
||||||
|
"groups": {
|
||||||
|
"bottom": {
|
||||||
|
"position": "bottom",
|
||||||
|
"attrs": {
|
||||||
|
"circle": {
|
||||||
|
"r": 4,
|
||||||
|
"magnet": true,
|
||||||
|
"stroke": "#5F95FF",
|
||||||
|
"strokeWidth": 1,
|
||||||
|
"fill": "#fff"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"items": [
|
||||||
|
{ "group": "bottom", "id": "bottom" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"attrs": {
|
||||||
|
"body": {
|
||||||
|
"fill": "#67C23A",
|
||||||
|
"stroke": "#5F95FF",
|
||||||
|
"strokeWidth": 1
|
||||||
|
},
|
||||||
|
"icon": {
|
||||||
|
"xlinkHref": "path/to/start-icon.svg"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}',
|
||||||
|
-- 表单配置(开始节点一般不需要配置)
|
||||||
|
NULL,
|
||||||
|
10, true,
|
||||||
|
NOW(), 'system', NOW(), 'system', 1, false
|
||||||
|
),
|
||||||
|
|
||||||
|
-- 结束节点
|
||||||
|
(2, 'endEvent', '结束节点', '流程的结束节点', 'EVENT',
|
||||||
|
-- Flowable配置
|
||||||
|
'{
|
||||||
|
"type": "endEvent"
|
||||||
|
}',
|
||||||
|
-- X6图形配置
|
||||||
|
'{
|
||||||
|
"shape": "flow-circle",
|
||||||
|
"width": 40,
|
||||||
|
"height": 40,
|
||||||
|
"ports": {
|
||||||
|
"groups": {
|
||||||
|
"top": {
|
||||||
|
"position": "top",
|
||||||
|
"attrs": {
|
||||||
|
"circle": {
|
||||||
|
"r": 4,
|
||||||
|
"magnet": true,
|
||||||
|
"stroke": "#5F95FF",
|
||||||
|
"strokeWidth": 1,
|
||||||
|
"fill": "#fff"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"items": [
|
||||||
|
{ "group": "top", "id": "top" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"attrs": {
|
||||||
|
"body": {
|
||||||
|
"fill": "#F56C6C",
|
||||||
|
"stroke": "#5F95FF",
|
||||||
|
"strokeWidth": 2
|
||||||
|
},
|
||||||
|
"icon": {
|
||||||
|
"xlinkHref": "path/to/end-icon.svg"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}',
|
||||||
|
-- 表单配置(结束节点一般不需要配置)
|
||||||
|
NULL,
|
||||||
|
90, true,
|
||||||
|
NOW(), 'system', NOW(), 'system', 1, false
|
||||||
|
),
|
||||||
|
|
||||||
|
-- Shell脚本节点
|
||||||
|
(3, 'shellTask', 'Shell脚本', '执行Shell命令的节点', 'TASK',
|
||||||
|
-- Flowable配置
|
||||||
|
'{
|
||||||
|
"type": "shellTask",
|
||||||
|
"delegateExpression": "$${shellTaskDelegate}",
|
||||||
|
"listeners": [
|
||||||
|
{
|
||||||
|
"event": "start",
|
||||||
|
"delegateExpression": "$${shellTaskStartListener}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "end",
|
||||||
|
"delegateExpression": "$${shellTaskEndListener}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}',
|
||||||
|
-- X6图形配置
|
||||||
|
'{
|
||||||
|
"shape": "flow-rect",
|
||||||
|
"width": 120,
|
||||||
|
"height": 60,
|
||||||
|
"ports": {
|
||||||
|
"groups": {
|
||||||
|
"top": {
|
||||||
|
"position": "top",
|
||||||
|
"attrs": {
|
||||||
|
"circle": {
|
||||||
|
"r": 4,
|
||||||
|
"magnet": true,
|
||||||
|
"stroke": "#5F95FF",
|
||||||
|
"strokeWidth": 1,
|
||||||
|
"fill": "#fff"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"bottom": {
|
||||||
|
"position": "bottom",
|
||||||
|
"attrs": {
|
||||||
|
"circle": {
|
||||||
|
"r": 4,
|
||||||
|
"magnet": true,
|
||||||
|
"stroke": "#5F95FF",
|
||||||
|
"strokeWidth": 1,
|
||||||
|
"fill": "#fff"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"items": [
|
||||||
|
{ "group": "top", "id": "top" },
|
||||||
|
{ "group": "bottom", "id": "bottom" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"attrs": {
|
||||||
|
"body": {
|
||||||
|
"fill": "#E6A23C",
|
||||||
|
"stroke": "#5F95FF",
|
||||||
|
"strokeWidth": 1
|
||||||
|
},
|
||||||
|
"icon": {
|
||||||
|
"xlinkHref": "path/to/shell-icon.svg"
|
||||||
|
},
|
||||||
|
"label": {
|
||||||
|
"text": "Shell脚本",
|
||||||
|
"fill": "#ffffff",
|
||||||
|
"fontSize": 12,
|
||||||
|
"textAnchor": "middle"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}',
|
||||||
|
-- 表单配置
|
||||||
|
'{
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "script",
|
||||||
|
"label": "脚本内容",
|
||||||
|
"type": "textarea",
|
||||||
|
"required": true,
|
||||||
|
"placeholder": "请输入shell脚本内容"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "workDir",
|
||||||
|
"label": "工作目录",
|
||||||
|
"type": "input",
|
||||||
|
"required": false,
|
||||||
|
"placeholder": "请输入工作目录路径"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "env",
|
||||||
|
"label": "环境变量",
|
||||||
|
"type": "keyValue",
|
||||||
|
"required": false,
|
||||||
|
"placeholder": "请配置环境变量"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"script": [
|
||||||
|
{ "required": true, "message": "请输入脚本内容" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}',
|
||||||
|
20, true,
|
||||||
|
NOW(), 'system', NOW(), 'system', 1, false
|
||||||
|
),
|
||||||
|
|
||||||
|
-- 排他网关
|
||||||
|
(4, 'exclusiveGateway', '排他网关', '基于条件的分支网关', 'GATEWAY',
|
||||||
|
-- Flowable配置
|
||||||
|
'{
|
||||||
|
"type": "exclusiveGateway"
|
||||||
|
}',
|
||||||
|
-- X6图形配置
|
||||||
|
'{
|
||||||
|
"shape": "flow-rhombus",
|
||||||
|
"width": 60,
|
||||||
|
"height": 60,
|
||||||
|
"ports": {
|
||||||
|
"groups": {
|
||||||
|
"top": {
|
||||||
|
"position": "top",
|
||||||
|
"attrs": {
|
||||||
|
"circle": {
|
||||||
|
"r": 4,
|
||||||
|
"magnet": true,
|
||||||
|
"stroke": "#5F95FF",
|
||||||
|
"strokeWidth": 1,
|
||||||
|
"fill": "#fff"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"bottom": {
|
||||||
|
"position": "bottom",
|
||||||
|
"attrs": {
|
||||||
|
"circle": {
|
||||||
|
"r": 4,
|
||||||
|
"magnet": true,
|
||||||
|
"stroke": "#5F95FF",
|
||||||
|
"strokeWidth": 1,
|
||||||
|
"fill": "#fff"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"left": {
|
||||||
|
"position": "left",
|
||||||
|
"attrs": {
|
||||||
|
"circle": {
|
||||||
|
"r": 4,
|
||||||
|
"magnet": true,
|
||||||
|
"stroke": "#5F95FF",
|
||||||
|
"strokeWidth": 1,
|
||||||
|
"fill": "#fff"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"right": {
|
||||||
|
"position": "right",
|
||||||
|
"attrs": {
|
||||||
|
"circle": {
|
||||||
|
"r": 4,
|
||||||
|
"magnet": true,
|
||||||
|
"stroke": "#5F95FF",
|
||||||
|
"strokeWidth": 1,
|
||||||
|
"fill": "#fff"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"items": [
|
||||||
|
{ "group": "top", "id": "top" },
|
||||||
|
{ "group": "bottom", "id": "bottom" },
|
||||||
|
{ "group": "left", "id": "left" },
|
||||||
|
{ "group": "right", "id": "right" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"attrs": {
|
||||||
|
"body": {
|
||||||
|
"fill": "#9B59B6",
|
||||||
|
"stroke": "#5F95FF",
|
||||||
|
"strokeWidth": 1
|
||||||
|
},
|
||||||
|
"icon": {
|
||||||
|
"xlinkHref": "path/to/exclusive-gateway-icon.svg"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}',
|
||||||
|
-- 表单配置
|
||||||
|
'{
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "defaultFlow",
|
||||||
|
"label": "默认流转路径",
|
||||||
|
"type": "select",
|
||||||
|
"required": false,
|
||||||
|
"placeholder": "请选择默认流转路径"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}',
|
||||||
|
30, true,
|
||||||
|
NOW(), 'system', NOW(), 'system', 1, false
|
||||||
|
);
|
||||||
Loading…
Reference in New Issue
Block a user