增加工作流代码可正常启动
This commit is contained in:
parent
bdbd4528a5
commit
45e05fd935
@ -22,7 +22,8 @@
|
|||||||
// 工作流定义相关接口
|
// 工作流定义相关接口
|
||||||
interface WorkflowDefinitionAPI {
|
interface WorkflowDefinitionAPI {
|
||||||
// 基础CRUD接口
|
// 基础CRUD接口
|
||||||
list: '/api/v1/workflow-definitions' // GET 查询列表
|
page: '/api/v1/workflow-definitions/page' // GET 分页查询,支持条件筛选
|
||||||
|
list: '/api/v1/workflow-definitions/list' // GET 查询所有(不分页)
|
||||||
create: '/api/v1/workflow-definitions' // POST 创建
|
create: '/api/v1/workflow-definitions' // POST 创建
|
||||||
update: '/api/v1/workflow-definitions/{id}' // PUT 更新
|
update: '/api/v1/workflow-definitions/{id}' // PUT 更新
|
||||||
delete: '/api/v1/workflow-definitions/{id}' // DELETE 删除
|
delete: '/api/v1/workflow-definitions/{id}' // DELETE 删除
|
||||||
@ -32,6 +33,31 @@ interface WorkflowDefinitionAPI {
|
|||||||
publish: '/api/v1/workflow-definitions/{id}/publish' // POST 发布
|
publish: '/api/v1/workflow-definitions/{id}/publish' // POST 发布
|
||||||
disable: '/api/v1/workflow-definitions/{id}/disable' // POST 禁用
|
disable: '/api/v1/workflow-definitions/{id}/disable' // POST 禁用
|
||||||
enable: '/api/v1/workflow-definitions/{id}/enable' // POST 启用
|
enable: '/api/v1/workflow-definitions/{id}/enable' // POST 启用
|
||||||
|
versions: '/api/v1/workflow-definitions/{code}/versions' // GET 查询所有版本(不分页)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 节点类型相关接口
|
||||||
|
interface NodeTypeAPI {
|
||||||
|
// 查询接口
|
||||||
|
list: '/api/v1/node-types' // GET 获取所有可用的节点类型列表(不分页)
|
||||||
|
getExecutors: '/api/v1/node-types/{type}/executors' // GET 获取指定节点类型支持的执行器列表
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页请求参数
|
||||||
|
interface PageQuery {
|
||||||
|
pageNum: number // 页码,从1开始
|
||||||
|
pageSize: number // 每页大小
|
||||||
|
sortField?: string // 排序字段
|
||||||
|
sortOrder?: 'ascend' | 'descend' // 排序方向
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页响应结构
|
||||||
|
interface PageResponse<T> {
|
||||||
|
records: T[] // 数据列表
|
||||||
|
total: number // 总记录数
|
||||||
|
pages: number // 总页数
|
||||||
|
pageNum: number // 当前页码
|
||||||
|
pageSize: number // 每页大小
|
||||||
}
|
}
|
||||||
|
|
||||||
// 工作流定义数据结构
|
// 工作流定义数据结构
|
||||||
@ -42,10 +68,10 @@ interface WorkflowDefinitionDTO {
|
|||||||
description: string // 描述
|
description: string // 描述
|
||||||
status: 'DRAFT' | 'PUBLISHED' | 'DISABLED' // 状态
|
status: 'DRAFT' | 'PUBLISHED' | 'DISABLED' // 状态
|
||||||
version: number // 版本号
|
version: number // 版本号
|
||||||
nodeConfig: string // 节点配置(JSON)
|
nodeConfig: string // 节点配置(JSON),包含节点的基本信息和执行配置
|
||||||
transitionConfig: string // 流转配置(JSON)
|
transitionConfig: string // 流转配置(JSON),定义节点间的连接和条件
|
||||||
formDefinition: string // 表单定义
|
formDefinition: string // 表单定义(JSON),定义工作流的表单字段和验证规则
|
||||||
graphDefinition: string // 图形信息
|
graphDefinition: string // 图形信息(JSON),定义节点的位置和连线的样式
|
||||||
enabled: boolean // 是否启用
|
enabled: boolean // 是否启用
|
||||||
remark: string // 备注
|
remark: string // 备注
|
||||||
nodes: NodeDefinitionDTO[] // 节点定义列表
|
nodes: NodeDefinitionDTO[] // 节点定义列表
|
||||||
@ -62,6 +88,173 @@ interface NodeDefinitionDTO {
|
|||||||
workflowDefinitionId: number // 工作流定义ID
|
workflowDefinitionId: number // 工作流定义ID
|
||||||
orderNum: number // 排序号
|
orderNum: number // 排序号
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 节点配置示例
|
||||||
|
interface NodeConfig {
|
||||||
|
startNode: {
|
||||||
|
type: 'START'
|
||||||
|
name: string
|
||||||
|
}
|
||||||
|
endNode: {
|
||||||
|
type: 'END'
|
||||||
|
name: string
|
||||||
|
}
|
||||||
|
taskNodes: Array<{
|
||||||
|
id: string
|
||||||
|
type: 'TASK'
|
||||||
|
name: string
|
||||||
|
executor?: string // 执行器类型
|
||||||
|
config?: any // 执行器配置
|
||||||
|
}>
|
||||||
|
}
|
||||||
|
|
||||||
|
// 流转配置示例
|
||||||
|
interface TransitionConfig {
|
||||||
|
transitions: Array<{
|
||||||
|
from: string // 源节点ID
|
||||||
|
to: string // 目标节点ID
|
||||||
|
condition?: string // 流转条件
|
||||||
|
}>
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单定义示例
|
||||||
|
interface FormDefinition {
|
||||||
|
fields: Array<{
|
||||||
|
name: string // 字段名
|
||||||
|
label: string // 字段标签
|
||||||
|
type: 'input' | 'select' | 'date' | 'number' // 字段类型
|
||||||
|
required?: boolean // 是否必填
|
||||||
|
options?: Array<{ // 选项(用于select类型)
|
||||||
|
label: string
|
||||||
|
value: any
|
||||||
|
}>
|
||||||
|
rules?: Array<{ // 验证规则
|
||||||
|
type: string
|
||||||
|
message: string
|
||||||
|
}>
|
||||||
|
}>
|
||||||
|
}
|
||||||
|
|
||||||
|
// 图形定义示例
|
||||||
|
interface GraphDefinition {
|
||||||
|
nodes: Array<{
|
||||||
|
id: string
|
||||||
|
type: string
|
||||||
|
x: number // 节点X坐标
|
||||||
|
y: number // 节点Y坐标
|
||||||
|
properties?: any // 节点属性
|
||||||
|
}>
|
||||||
|
edges: Array<{
|
||||||
|
source: string // 源节点ID
|
||||||
|
target: string // 目标节点ID
|
||||||
|
properties?: any // 连线属性
|
||||||
|
}>
|
||||||
|
}
|
||||||
|
|
||||||
|
// 节点类型数据结构
|
||||||
|
interface NodeTypeDTO {
|
||||||
|
code: string // 节点类型编码
|
||||||
|
name: string // 节点类型名称
|
||||||
|
description: string // 节点类型描述
|
||||||
|
category: 'BASIC' | 'TASK' | 'GATEWAY' | 'EVENT' // 节点类型分类
|
||||||
|
icon: string // 节点图标
|
||||||
|
color: string // 节点颜色
|
||||||
|
executors?: Array<{ // 支持的执行器列表
|
||||||
|
code: string // 执行器编码
|
||||||
|
name: string // 执行器名称
|
||||||
|
description: string // 执行器描述
|
||||||
|
configSchema: any // 执行器配置模式
|
||||||
|
}>
|
||||||
|
configSchema?: any // 节点配置模式
|
||||||
|
defaultConfig?: any // 默认配置
|
||||||
|
}
|
||||||
|
|
||||||
|
// 节点类型示例数据
|
||||||
|
const nodeTypes = [
|
||||||
|
{
|
||||||
|
code: 'START',
|
||||||
|
name: '开始节点',
|
||||||
|
description: '工作流的开始节点',
|
||||||
|
category: 'BASIC',
|
||||||
|
icon: 'play-circle',
|
||||||
|
color: '#52c41a'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'END',
|
||||||
|
name: '结束节点',
|
||||||
|
description: '工作流的结束节点',
|
||||||
|
category: 'BASIC',
|
||||||
|
icon: 'stop',
|
||||||
|
color: '#ff4d4f'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'TASK',
|
||||||
|
name: '任务节点',
|
||||||
|
description: '执行具体任务的节点',
|
||||||
|
category: 'TASK',
|
||||||
|
icon: 'code',
|
||||||
|
color: '#1890ff',
|
||||||
|
executors: [
|
||||||
|
{
|
||||||
|
code: 'SHELL',
|
||||||
|
name: 'Shell脚本',
|
||||||
|
description: '执行Shell脚本',
|
||||||
|
configSchema: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
script: {
|
||||||
|
type: 'string',
|
||||||
|
title: '脚本内容',
|
||||||
|
format: 'shell'
|
||||||
|
},
|
||||||
|
timeout: {
|
||||||
|
type: 'number',
|
||||||
|
title: '超时时间(秒)',
|
||||||
|
default: 300
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'JENKINS',
|
||||||
|
name: 'Jenkins任务',
|
||||||
|
description: '触发Jenkins构建任务',
|
||||||
|
configSchema: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
job: {
|
||||||
|
type: 'string',
|
||||||
|
title: 'Job名称'
|
||||||
|
},
|
||||||
|
parameters: {
|
||||||
|
type: 'object',
|
||||||
|
title: '构建参数'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'GATEWAY',
|
||||||
|
name: '网关节点',
|
||||||
|
description: '控制流程流转的节点',
|
||||||
|
category: 'GATEWAY',
|
||||||
|
icon: 'fork',
|
||||||
|
color: '#faad14',
|
||||||
|
configSchema: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
type: {
|
||||||
|
type: 'string',
|
||||||
|
title: '网关类型',
|
||||||
|
enum: ['PARALLEL', 'EXCLUSIVE', 'INCLUSIVE'],
|
||||||
|
enumNames: ['并行网关', '排他网关', '包容网关']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2.2 工作流实例管理
|
### 2.2 工作流实例管理
|
||||||
@ -69,7 +262,8 @@ interface NodeDefinitionDTO {
|
|||||||
// 工作流实例相关接口
|
// 工作流实例相关接口
|
||||||
interface WorkflowInstanceAPI {
|
interface WorkflowInstanceAPI {
|
||||||
// 基础CRUD接口
|
// 基础CRUD接口
|
||||||
list: '/api/v1/workflow-instance' // GET 查询列表
|
page: '/api/v1/workflow-instance/page' // GET 分页查询,支持条件筛选
|
||||||
|
list: '/api/v1/workflow-instance/list' // GET 查询所有(不分页)
|
||||||
get: '/api/v1/workflow-instance/{id}' // GET 获取详情
|
get: '/api/v1/workflow-instance/{id}' // GET 获取详情
|
||||||
|
|
||||||
// 实例操作接口
|
// 实例操作接口
|
||||||
@ -98,10 +292,11 @@ interface WorkflowInstanceDTO {
|
|||||||
// 节点实例相关接口
|
// 节点实例相关接口
|
||||||
interface NodeInstanceAPI {
|
interface NodeInstanceAPI {
|
||||||
// 查询接口
|
// 查询接口
|
||||||
list: '/api/v1/node-instance' // GET 查询列表
|
page: '/api/v1/node-instance/page' // GET 分页查询,支持条件筛选
|
||||||
|
list: '/api/v1/node-instance/list' // GET 查询所有(不分页)
|
||||||
get: '/api/v1/node-instance/{id}' // GET 获取详情
|
get: '/api/v1/node-instance/{id}' // GET 获取详情
|
||||||
findByWorkflow: '/api/v1/node-instance/workflow/{workflowInstanceId}' // GET 查询工作流下的节点
|
findByWorkflow: '/api/v1/node-instance/workflow/{workflowInstanceId}' // GET 查询工作流下的节点(不分页)
|
||||||
findByStatus: '/api/v1/node-instance/workflow/{workflowInstanceId}/status/{status}' // GET 查询指定状态的节点
|
findByStatus: '/api/v1/node-instance/workflow/{workflowInstanceId}/status/{status}' // GET 查询指定状态的节点(不分页)
|
||||||
|
|
||||||
// 节点操作
|
// 节点操作
|
||||||
updateStatus: '/api/v1/node-instance/{id}/status' // PUT 更新状态
|
updateStatus: '/api/v1/node-instance/{id}/status' // PUT 更新状态
|
||||||
@ -130,12 +325,13 @@ interface NodeInstanceDTO {
|
|||||||
// 日志相关接口
|
// 日志相关接口
|
||||||
interface WorkflowLogAPI {
|
interface WorkflowLogAPI {
|
||||||
// 基础CRUD接口
|
// 基础CRUD接口
|
||||||
list: '/api/v1/workflow-logs' // GET 查询列表
|
page: '/api/v1/workflow-logs/page' // GET 分页查询,支持条件筛选
|
||||||
|
list: '/api/v1/workflow-logs/list' // GET 查询所有(不分页)
|
||||||
create: '/api/v1/workflow-logs' // POST 创建
|
create: '/api/v1/workflow-logs' // POST 创建
|
||||||
|
|
||||||
// 特殊查询接口
|
// 特殊查询接口
|
||||||
getWorkflowLogs: '/api/v1/workflow-logs/workflow/{workflowInstanceId}' // GET 查询工作流日志
|
getWorkflowLogs: '/api/v1/workflow-logs/workflow/{workflowInstanceId}' // GET 查询工作流日志(不分页)
|
||||||
getNodeLogs: '/api/v1/workflow-logs/node/{workflowInstanceId}/{nodeId}' // GET 查询节点日志
|
getNodeLogs: '/api/v1/workflow-logs/node/{workflowInstanceId}/{nodeId}' // GET 查询节点日志(不分页)
|
||||||
record: '/api/v1/workflow-logs/record' // POST 记录日志
|
record: '/api/v1/workflow-logs/record' // POST 记录日志
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,19 +375,38 @@ interface WorkflowLogDTO {
|
|||||||
- 描述
|
- 描述
|
||||||
- 备注
|
- 备注
|
||||||
2. 流程设计器
|
2. 流程设计器
|
||||||
- 节点拖拽
|
- 节点拖拽和布局
|
||||||
- 连线绘制
|
- 连线绘制和调整
|
||||||
- 节点配置
|
- 节点配置(nodeConfig)
|
||||||
|
- 基本信息配置
|
||||||
|
- 执行器类型选择
|
||||||
|
- 执行器参数配置
|
||||||
|
- 流转配置(transitionConfig)
|
||||||
|
- 连线条件配置
|
||||||
|
- 优先级设置
|
||||||
|
- 条件表达式编辑
|
||||||
- 流程校验
|
- 流程校验
|
||||||
3. 表单设计器
|
3. 表单设计器(formDefinition)
|
||||||
- 表单字段配置
|
- 表单字段配置
|
||||||
|
- 字段类型选择
|
||||||
|
- 字段属性设置
|
||||||
|
- 选项配置(针对select类型)
|
||||||
- 字段验证规则
|
- 字段验证规则
|
||||||
|
- 必填验证
|
||||||
|
- 格式验证
|
||||||
|
- 自定义验证
|
||||||
|
- 表单布局设计
|
||||||
- 表单预览
|
- 表单预览
|
||||||
4. 节点配置面板
|
4. 图形布局(graphDefinition)
|
||||||
- 节点基本信息
|
- 节点位置调整
|
||||||
- 节点类型配置
|
- 连线样式设置
|
||||||
- 执行条件配置
|
- 自动布局
|
||||||
- 表单关联配置
|
- 缩放和居中
|
||||||
|
5. 版本管理
|
||||||
|
- 版本历史查看
|
||||||
|
- 版本对比
|
||||||
|
- 版本回滚
|
||||||
|
- 创建新版本
|
||||||
|
|
||||||
### 3.2 工作流实例管理(/workflow/instance)
|
### 3.2 工作流实例管理(/workflow/instance)
|
||||||
|
|
||||||
@ -247,6 +462,90 @@ interface WorkflowLogDTO {
|
|||||||
- 异常趋势图
|
- 异常趋势图
|
||||||
- 异常节点TOP5
|
- 异常节点TOP5
|
||||||
|
|
||||||
|
### 3.4 节点类型管理(/workflow/node-type)
|
||||||
|
|
||||||
|
#### 3.4.1 列表页(/workflow/node-type/list)
|
||||||
|
- 功能点:
|
||||||
|
- 节点类型列表展示
|
||||||
|
- 支持按编码、名称、分类搜索
|
||||||
|
- 支持创建、编辑、删除操作
|
||||||
|
- 支持启用、禁用操作
|
||||||
|
- 列表字段:
|
||||||
|
- 节点类型编码
|
||||||
|
- 节点类型名称
|
||||||
|
- 分类
|
||||||
|
- 图标
|
||||||
|
- 状态
|
||||||
|
- 创建时间
|
||||||
|
- 更新时间
|
||||||
|
- 操作按钮
|
||||||
|
|
||||||
|
#### 3.4.2 编辑页(/workflow/node-type/edit)
|
||||||
|
- 功能点:
|
||||||
|
1. 基本信息编辑
|
||||||
|
- 节点类型编码
|
||||||
|
- 节点类型名称
|
||||||
|
- 描述
|
||||||
|
- 分类
|
||||||
|
- 图标
|
||||||
|
- 颜色
|
||||||
|
2. 执行器配置
|
||||||
|
- 执行器列表管理
|
||||||
|
- 添加/删除执行器
|
||||||
|
- 配置执行器参数
|
||||||
|
- 执行器配置模式定义
|
||||||
|
- JSON Schema编辑器
|
||||||
|
- 配置项验证规则
|
||||||
|
3. 节点配置
|
||||||
|
- 配置模式定义
|
||||||
|
- 默认配置设置
|
||||||
|
- 配置预览
|
||||||
|
|
||||||
|
### 3.5 组件升级
|
||||||
|
1. NodeTypePanel(节点类型面板)
|
||||||
|
```typescript
|
||||||
|
interface NodeTypePanelProps {
|
||||||
|
value?: NodeTypeDTO // 节点类型数据
|
||||||
|
onChange?: (value: NodeTypeDTO) => void // 数据变更回调
|
||||||
|
readOnly?: boolean // 是否只读
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
2. ExecutorConfig(执行器配置)
|
||||||
|
```typescript
|
||||||
|
interface ExecutorConfigProps {
|
||||||
|
executors: Array<{
|
||||||
|
code: string
|
||||||
|
name: string
|
||||||
|
description: string
|
||||||
|
configSchema: any
|
||||||
|
}> // 执行器列表
|
||||||
|
onChange?: (executors: any[]) => void // 配置变更回调
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
3. SchemaEditor(配置模式编辑器)
|
||||||
|
```typescript
|
||||||
|
interface SchemaEditorProps {
|
||||||
|
value?: any // 配置模式数据
|
||||||
|
onChange?: (value: any) => void // 数据变更回调
|
||||||
|
onValidate?: (errors: any[]) => void // 验证回调
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.6 开发计划调整
|
||||||
|
1. 节点类型管理开发(3天)
|
||||||
|
- 实现节点类型CRUD接口
|
||||||
|
- 开发节点类型列表页面
|
||||||
|
- 开发节点类型编辑页面
|
||||||
|
- 实现执行器配置功能
|
||||||
|
- 实现配置模式编辑器
|
||||||
|
|
||||||
|
2. 流程设计器升级(2天)
|
||||||
|
- 改造节点面板,支持从节点类型创建节点
|
||||||
|
- 实现节点配置面板,支持动态表单
|
||||||
|
- 添加执行器选择功能
|
||||||
|
|
||||||
## 四、开发规范
|
## 四、开发规范
|
||||||
|
|
||||||
### 4.1 项目结构
|
### 4.1 项目结构
|
||||||
|
|||||||
@ -123,7 +123,20 @@ public enum ResponseCode {
|
|||||||
WORKFLOW_CONCURRENT_LIMIT_EXCEEDED(2753, "workflow.concurrent.limit.exceeded"),
|
WORKFLOW_CONCURRENT_LIMIT_EXCEEDED(2753, "workflow.concurrent.limit.exceeded"),
|
||||||
WORKFLOW_CONFIG_INVALID(2754, "workflow.config.invalid"),
|
WORKFLOW_CONFIG_INVALID(2754, "workflow.config.invalid"),
|
||||||
WORKFLOW_TRANSITION_INVALID(2755, "workflow.transition.invalid"),
|
WORKFLOW_TRANSITION_INVALID(2755, "workflow.transition.invalid"),
|
||||||
WORKFLOW_CONDITION_INVALID(2756, "workflow.condition.invalid");
|
WORKFLOW_CONDITION_INVALID(2756, "workflow.condition.invalid"),
|
||||||
|
|
||||||
|
// 工作流配置相关错误码 (2760-2769)
|
||||||
|
WORKFLOW_NODE_CONFIG_EMPTY(2760, "workflow.node.config.empty"),
|
||||||
|
WORKFLOW_TRANSITION_CONFIG_EMPTY(2761, "workflow.transition.config.empty"),
|
||||||
|
WORKFLOW_FORM_CONFIG_EMPTY(2762, "workflow.form.config.empty"),
|
||||||
|
WORKFLOW_GRAPH_CONFIG_EMPTY(2763, "workflow.graph.config.empty"),
|
||||||
|
|
||||||
|
// 2200-2299 工作流节点类型错误
|
||||||
|
WORKFLOW_NODE_TYPE_NOT_FOUND(2200, "workflow.node.type.not.found"),
|
||||||
|
WORKFLOW_NODE_TYPE_DISABLED(2201, "workflow.node.type.disabled"),
|
||||||
|
WORKFLOW_NODE_TYPE_CODE_EXISTS(2202, "workflow.node.type.code.exists"),
|
||||||
|
WORKFLOW_NODE_TYPE_INVALID_CATEGORY(2203, "workflow.node.type.invalid.category"),
|
||||||
|
WORKFLOW_NODE_TYPE_INVALID_EXECUTOR(2204, "workflow.node.type.invalid.executor");
|
||||||
|
|
||||||
private final int code;
|
private final int code;
|
||||||
private final String messageKey; // 国际化消息key
|
private final String messageKey; // 国际化消息key
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
package com.qqchen.deploy.backend.workflow.controller;
|
package com.qqchen.deploy.backend.workflow.api;
|
||||||
|
|
||||||
import com.qqchen.deploy.backend.framework.api.Response;
|
import com.qqchen.deploy.backend.framework.api.Response;
|
||||||
import com.qqchen.deploy.backend.framework.controller.BaseController;
|
import com.qqchen.deploy.backend.framework.controller.BaseController;
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
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.NodeTypeDTO;
|
||||||
|
import com.qqchen.deploy.backend.workflow.dto.query.NodeTypeQuery;
|
||||||
|
import com.qqchen.deploy.backend.workflow.engine.definition.TaskExecutorDefinition;
|
||||||
|
import com.qqchen.deploy.backend.workflow.entity.NodeType;
|
||||||
|
import com.qqchen.deploy.backend.workflow.service.INodeTypeService;
|
||||||
|
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.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点类型接口
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Tag(name = "节点类型管理", description = "节点类型相关接口")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/node-type")
|
||||||
|
public class NodeTypeApiController extends BaseController<NodeType, NodeTypeDTO, Long, NodeTypeQuery> {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private INodeTypeService nodeTypeService;
|
||||||
|
|
||||||
|
@Operation(summary = "获取指定节点类型支持的执行器列表")
|
||||||
|
@GetMapping("/{type}/executors")
|
||||||
|
public Response<List<TaskExecutorDefinition>> getExecutors(
|
||||||
|
@Parameter(description = "节点类型", required = true) @PathVariable String type
|
||||||
|
) {
|
||||||
|
log.debug("获取节点类型[{}]支持的执行器列表", type);
|
||||||
|
return Response.success(nodeTypeService.getExecutors(type));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void exportData(HttpServletResponse response, List<NodeTypeDTO> data) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.qqchen.deploy.backend.workflow.controller;
|
package com.qqchen.deploy.backend.workflow.api;
|
||||||
|
|
||||||
import com.qqchen.deploy.backend.framework.api.Response;
|
import com.qqchen.deploy.backend.framework.api.Response;
|
||||||
import com.qqchen.deploy.backend.framework.controller.BaseController;
|
import com.qqchen.deploy.backend.framework.controller.BaseController;
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.qqchen.deploy.backend.workflow.controller;
|
package com.qqchen.deploy.backend.workflow.api;
|
||||||
|
|
||||||
import com.qqchen.deploy.backend.framework.api.Response;
|
import com.qqchen.deploy.backend.framework.api.Response;
|
||||||
import com.qqchen.deploy.backend.framework.controller.BaseController;
|
import com.qqchen.deploy.backend.framework.controller.BaseController;
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.qqchen.deploy.backend.workflow.controller;
|
package com.qqchen.deploy.backend.workflow.api;
|
||||||
|
|
||||||
import com.qqchen.deploy.backend.enums.LogLevelEnum;
|
import com.qqchen.deploy.backend.enums.LogLevelEnum;
|
||||||
import com.qqchen.deploy.backend.framework.api.Response;
|
import com.qqchen.deploy.backend.framework.api.Response;
|
||||||
@ -1,84 +0,0 @@
|
|||||||
package com.qqchen.deploy.backend.workflow.api.dto;
|
|
||||||
|
|
||||||
import com.qqchen.deploy.backend.framework.dto.BaseDTO;
|
|
||||||
import com.qqchen.deploy.backend.workflow.enums.NodeStatusEnum;
|
|
||||||
import com.qqchen.deploy.backend.workflow.enums.NodeTypeEnum;
|
|
||||||
import jakarta.validation.constraints.NotBlank;
|
|
||||||
import jakarta.validation.constraints.NotNull;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 节点实例DTO
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
public class NodeInstanceDTO extends BaseDTO {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 工作流实例ID
|
|
||||||
*/
|
|
||||||
@NotNull(message = "工作流实例ID不能为空")
|
|
||||||
private Long workflowInstanceId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 节点ID
|
|
||||||
*/
|
|
||||||
@NotBlank(message = "节点ID不能为空")
|
|
||||||
private String nodeId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 节点类型
|
|
||||||
*/
|
|
||||||
@NotNull(message = "节点类型不能为空")
|
|
||||||
private NodeTypeEnum nodeType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 节点名称
|
|
||||||
*/
|
|
||||||
@NotBlank(message = "节点名称不能为空")
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 节点状态
|
|
||||||
*/
|
|
||||||
@NotNull(message = "节点状态不能为空")
|
|
||||||
private NodeStatusEnum status;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 开始时间
|
|
||||||
*/
|
|
||||||
private LocalDateTime startTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 结束时间
|
|
||||||
*/
|
|
||||||
private LocalDateTime endTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 节点配置(JSON)
|
|
||||||
*/
|
|
||||||
private String config;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 输入参数(JSON)
|
|
||||||
*/
|
|
||||||
private String input;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 输出结果(JSON)
|
|
||||||
*/
|
|
||||||
private String output;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 错误信息
|
|
||||||
*/
|
|
||||||
private String error;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 前置节点ID
|
|
||||||
*/
|
|
||||||
private String preNodeId;
|
|
||||||
}
|
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
package com.qqchen.deploy.backend.workflow.converter;
|
||||||
|
|
||||||
|
import com.qqchen.deploy.backend.workflow.engine.definition.TaskExecutorDefinition;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JSON转换器接口
|
||||||
|
* 用于处理系统中的JSON序列化和反序列化
|
||||||
|
*/
|
||||||
|
public interface JsonConverter {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将JSON字符串转换为执行器定义列表
|
||||||
|
*
|
||||||
|
* @param json JSON字符串
|
||||||
|
* @return 执行器定义列表
|
||||||
|
*/
|
||||||
|
List<TaskExecutorDefinition> toExecutorList(String json);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将执行器定义列表转换为JSON字符串
|
||||||
|
*
|
||||||
|
* @param executors 执行器定义列表
|
||||||
|
* @return JSON字符串
|
||||||
|
*/
|
||||||
|
String fromExecutorList(List<TaskExecutorDefinition> executors);
|
||||||
|
}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
package com.qqchen.deploy.backend.workflow.converter;
|
package com.qqchen.deploy.backend.workflow.converter;
|
||||||
|
|
||||||
import com.qqchen.deploy.backend.framework.converter.BaseConverter;
|
import com.qqchen.deploy.backend.framework.converter.BaseConverter;
|
||||||
import com.qqchen.deploy.backend.workflow.api.dto.NodeInstanceDTO;
|
import com.qqchen.deploy.backend.workflow.dto.NodeInstanceDTO;
|
||||||
import com.qqchen.deploy.backend.workflow.entity.NodeInstance;
|
import com.qqchen.deploy.backend.workflow.entity.NodeInstance;
|
||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
import org.mapstruct.Mapping;
|
import org.mapstruct.Mapping;
|
||||||
|
|||||||
@ -0,0 +1,36 @@
|
|||||||
|
package com.qqchen.deploy.backend.workflow.converter;
|
||||||
|
|
||||||
|
import com.qqchen.deploy.backend.framework.converter.BaseConverter;
|
||||||
|
import com.qqchen.deploy.backend.workflow.dto.NodeTypeDTO;
|
||||||
|
import com.qqchen.deploy.backend.workflow.entity.NodeType;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.Mapping;
|
||||||
|
import org.mapstruct.MappingTarget;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点类型转换器
|
||||||
|
*/
|
||||||
|
@Mapper(config = BaseConverter.class, componentModel = "spring", uses = {JsonConverter.class})
|
||||||
|
public abstract class NodeTypeConverter implements BaseConverter<NodeType, NodeTypeDTO> {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
protected JsonConverter jsonConverter;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Mapping(target = "executors", expression = "java(jsonConverter.toExecutorList(entity.getExecutors()))")
|
||||||
|
public abstract NodeTypeDTO toDto(NodeType entity);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Mapping(target = "executors", expression = "java(jsonConverter.fromExecutorList(dto.getExecutors()))")
|
||||||
|
public abstract NodeType toEntity(NodeTypeDTO dto);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateEntity(NodeType entity, NodeTypeDTO dto) {
|
||||||
|
// 使用MapStruct生成的更新方法
|
||||||
|
updateEntityInternal(entity, dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Mapping(target = "executors", expression = "java(jsonConverter.fromExecutorList(dto.getExecutors()))")
|
||||||
|
protected abstract void updateEntityInternal(@MappingTarget NodeType entity, NodeTypeDTO dto);
|
||||||
|
}
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
package com.qqchen.deploy.backend.workflow.converter.impl;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.qqchen.deploy.backend.framework.exception.SystemException;
|
||||||
|
import com.qqchen.deploy.backend.workflow.converter.JsonConverter;
|
||||||
|
import com.qqchen.deploy.backend.workflow.engine.definition.TaskExecutorDefinition;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JSON转换器默认实现
|
||||||
|
* 使用Jackson进行JSON序列化和反序列化
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class DefaultJsonConverter implements JsonConverter {
|
||||||
|
|
||||||
|
private final ObjectMapper objectMapper;
|
||||||
|
|
||||||
|
public DefaultJsonConverter(ObjectMapper objectMapper) {
|
||||||
|
this.objectMapper = objectMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TaskExecutorDefinition> toExecutorList(String json) {
|
||||||
|
if (json == null || json.isEmpty()) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return objectMapper.readValue(json, new TypeReference<List<TaskExecutorDefinition>>() {});
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new SystemException("Failed to parse executors JSON: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String fromExecutorList(List<TaskExecutorDefinition> executors) {
|
||||||
|
if (executors == null || executors.isEmpty()) {
|
||||||
|
return "[]";
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return objectMapper.writeValueAsString(executors);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new SystemException("Failed to serialize executors: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -10,6 +10,19 @@ import lombok.EqualsAndHashCode;
|
|||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
import com.qqchen.deploy.backend.framework.dto.BaseDTO;
|
||||||
|
import com.qqchen.deploy.backend.workflow.enums.NodeStatusEnum;
|
||||||
|
import com.qqchen.deploy.backend.workflow.enums.NodeTypeEnum;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点实例DTO
|
||||||
|
*/
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
public class NodeInstanceDTO extends BaseDTO {
|
public class NodeInstanceDTO extends BaseDTO {
|
||||||
@ -41,6 +54,7 @@ public class NodeInstanceDTO extends BaseDTO {
|
|||||||
/**
|
/**
|
||||||
* 节点状态
|
* 节点状态
|
||||||
*/
|
*/
|
||||||
|
@NotNull(message = "节点状态不能为空")
|
||||||
private NodeStatusEnum status;
|
private NodeStatusEnum status;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -0,0 +1,88 @@
|
|||||||
|
package com.qqchen.deploy.backend.workflow.dto;
|
||||||
|
|
||||||
|
import com.qqchen.deploy.backend.framework.dto.BaseDTO;
|
||||||
|
import com.qqchen.deploy.backend.workflow.engine.definition.TaskExecutorDefinition;
|
||||||
|
import com.qqchen.deploy.backend.workflow.enums.NodeCategory;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点类型DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class NodeTypeDTO extends BaseDTO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点类型编码
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "节点类型编码不能为空")
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点类型名称
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "节点类型名称不能为空")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点类型描述
|
||||||
|
*/
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点类型分类
|
||||||
|
*/
|
||||||
|
@NotNull(message = "节点类型分类不能为空")
|
||||||
|
private NodeCategory category;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点图标
|
||||||
|
*/
|
||||||
|
private String icon;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点颜色
|
||||||
|
*/
|
||||||
|
private String color;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务执行器定义列表
|
||||||
|
* 定义该节点类型支持的所有任务执行器
|
||||||
|
* 说明:
|
||||||
|
* 1. 只有TASK类型的节点才需要配置执行器
|
||||||
|
* 2. 一个任务节点可以支持多种执行器
|
||||||
|
* 3. 每种执行器都有自己的配置模式
|
||||||
|
*/
|
||||||
|
@Valid
|
||||||
|
private List<TaskExecutorDefinition> executors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点配置模式(JSON)
|
||||||
|
* 使用JSON Schema格式定义节点的配置结构
|
||||||
|
* 说明:
|
||||||
|
* 1. 基础配置:所有类型节点都需要的配置(如节点名称、描述等)
|
||||||
|
* 2. 分类配置:不同分类节点特有的配置
|
||||||
|
* - TASK:任务节点配置(如执行器选择、重试策略等)
|
||||||
|
* - GATEWAY:网关节点配置(如条件表达式、分支策略等)
|
||||||
|
* - EVENT:事件节点配置(如事件类型、触发条件等)
|
||||||
|
*/
|
||||||
|
private String configSchema;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认配置(JSON)
|
||||||
|
* 符合configSchema定义的默认配置值
|
||||||
|
*/
|
||||||
|
private String defaultConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否启用
|
||||||
|
*/
|
||||||
|
@NotNull(message = "是否启用不能为空")
|
||||||
|
private Boolean enabled = true;
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.qqchen.deploy.backend.workflow.api.query;
|
package com.qqchen.deploy.backend.workflow.dto.query;
|
||||||
|
|
||||||
import com.qqchen.deploy.backend.framework.annotation.QueryField;
|
import com.qqchen.deploy.backend.framework.annotation.QueryField;
|
||||||
import com.qqchen.deploy.backend.framework.enums.QueryType;
|
import com.qqchen.deploy.backend.framework.enums.QueryType;
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
package com.qqchen.deploy.backend.workflow.dto.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.NodeCategory;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点类型查询对象
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class NodeTypeQuery extends BaseQuery {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点类型编码
|
||||||
|
*/
|
||||||
|
@QueryField(field = "code", type = QueryType.LIKE)
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点类型名称
|
||||||
|
*/
|
||||||
|
@QueryField(field = "name", type = QueryType.LIKE)
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点类型分类
|
||||||
|
*/
|
||||||
|
@QueryField(field = "category")
|
||||||
|
private NodeCategory category;
|
||||||
|
}
|
||||||
@ -0,0 +1,93 @@
|
|||||||
|
package com.qqchen.deploy.backend.workflow.engine.definition;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务执行器定义
|
||||||
|
* 用于定义工作流节点支持的任务执行器类型及其配置结构
|
||||||
|
* 主要用于:
|
||||||
|
* 1. 节点类型配置:定义节点类型支持哪些执行器
|
||||||
|
* 2. 流程设计:前端根据执行器定义动态渲染配置表单
|
||||||
|
* 3. 执行引擎:根据执行器定义验证和执行任务
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class TaskExecutorDefinition {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行器编码
|
||||||
|
* 用于标识执行器类型,需要与具体的执行器实现类对应
|
||||||
|
* 例如:
|
||||||
|
* - SHELL:对应ShellTaskExecutor
|
||||||
|
* - JENKINS:对应JenkinsTaskExecutor
|
||||||
|
* - HTTP:对应HttpTaskExecutor
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "执行器编码不能为空")
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行器名称
|
||||||
|
* 用于前端展示,应该是用户友好的名称
|
||||||
|
* 例如:
|
||||||
|
* - Shell脚本执行器
|
||||||
|
* - Jenkins构建执行器
|
||||||
|
* - HTTP接口调用执行器
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "执行器名称不能为空")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行器描述
|
||||||
|
* 详细说明执行器的:
|
||||||
|
* 1. 主要功能和使用场景
|
||||||
|
* 2. 配置参数说明
|
||||||
|
* 3. 注意事项和限制条件
|
||||||
|
*/
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行器配置模式
|
||||||
|
* 使用JSON Schema格式定义执行器的配置结构
|
||||||
|
* 用于:
|
||||||
|
* 1. 前端动态渲染配置表单
|
||||||
|
* 2. 后端验证配置参数
|
||||||
|
*
|
||||||
|
* 示例 - Shell执行器配置模式:
|
||||||
|
* {
|
||||||
|
* "type": "object",
|
||||||
|
* "required": ["script"],
|
||||||
|
* "properties": {
|
||||||
|
* "script": {
|
||||||
|
* "type": "string",
|
||||||
|
* "title": "脚本内容",
|
||||||
|
* "format": "shell",
|
||||||
|
* "description": "需要执行的Shell脚本内容"
|
||||||
|
* },
|
||||||
|
* "timeout": {
|
||||||
|
* "type": "number",
|
||||||
|
* "title": "超时时间",
|
||||||
|
* "description": "脚本执行的最大时间(秒)",
|
||||||
|
* "minimum": 1,
|
||||||
|
* "maximum": 3600,
|
||||||
|
* "default": 300
|
||||||
|
* },
|
||||||
|
* "workingDir": {
|
||||||
|
* "type": "string",
|
||||||
|
* "title": "工作目录",
|
||||||
|
* "description": "脚本执行的工作目录",
|
||||||
|
* "default": "/tmp"
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
private String configSchema;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认配置
|
||||||
|
* 符合configSchema定义的默认配置值
|
||||||
|
* 用于:
|
||||||
|
* 1. 新建节点时的默认值
|
||||||
|
* 2. 重置配置时的参考值
|
||||||
|
*/
|
||||||
|
private String defaultConfig;
|
||||||
|
}
|
||||||
@ -0,0 +1,81 @@
|
|||||||
|
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.NodeCategory;
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.EnumType;
|
||||||
|
import jakarta.persistence.Enumerated;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点类型实体
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@jakarta.persistence.Entity
|
||||||
|
@Table(name = "wf_node_type")
|
||||||
|
@LogicDelete
|
||||||
|
public class NodeType extends Entity<Long> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点类型编码
|
||||||
|
*/
|
||||||
|
@Column(nullable = false, unique = true)
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点类型名称
|
||||||
|
*/
|
||||||
|
@Column(nullable = false)
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点类型描述
|
||||||
|
*/
|
||||||
|
@Column(columnDefinition = "TEXT")
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点类型分类
|
||||||
|
*/
|
||||||
|
@Enumerated(EnumType.STRING)
|
||||||
|
@Column(nullable = false)
|
||||||
|
private NodeCategory category;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点图标
|
||||||
|
*/
|
||||||
|
private String icon;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点颜色
|
||||||
|
*/
|
||||||
|
private String color;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行器列表(JSON)
|
||||||
|
*/
|
||||||
|
@Column(name = "executors", columnDefinition = "TEXT")
|
||||||
|
private String executors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点配置模式(JSON)
|
||||||
|
*/
|
||||||
|
@Column(name = "config_schema", columnDefinition = "TEXT")
|
||||||
|
private String configSchema;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认配置(JSON)
|
||||||
|
*/
|
||||||
|
@Column(name = "default_config", columnDefinition = "TEXT")
|
||||||
|
private String defaultConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否启用
|
||||||
|
*/
|
||||||
|
@Column(nullable = false)
|
||||||
|
private Boolean enabled = true;
|
||||||
|
}
|
||||||
@ -63,6 +63,18 @@ public class WorkflowDefinition extends Entity<Long> {
|
|||||||
@Column(name = "transition_config", columnDefinition = "TEXT")
|
@Column(name = "transition_config", columnDefinition = "TEXT")
|
||||||
private String transitionConfig;
|
private String transitionConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表单定义(JSON)
|
||||||
|
*/
|
||||||
|
@Column(name = "form_definition", columnDefinition = "TEXT")
|
||||||
|
private String formDefinition;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图形信息(JSON)
|
||||||
|
*/
|
||||||
|
@Column(name = "graph_definition", columnDefinition = "TEXT")
|
||||||
|
private String graphDefinition;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 节点定义列表
|
* 节点定义列表
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -0,0 +1,38 @@
|
|||||||
|
package com.qqchen.deploy.backend.workflow.enums;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点分类枚举
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public enum NodeCategory {
|
||||||
|
/**
|
||||||
|
* 基础节点(如开始、结束节点)
|
||||||
|
*/
|
||||||
|
BASIC("基础节点"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务节点(如Shell、Jenkins等执行器节点)
|
||||||
|
*/
|
||||||
|
TASK("任务节点"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 网关节点(如并行、排他、包容网关)
|
||||||
|
*/
|
||||||
|
GATEWAY("网关节点"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 事件节点(如定时器、消息等事件)
|
||||||
|
*/
|
||||||
|
EVENT("事件节点");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分类名称
|
||||||
|
*/
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
NodeCategory(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
package com.qqchen.deploy.backend.workflow.repository;
|
||||||
|
|
||||||
|
import com.qqchen.deploy.backend.framework.repository.IBaseRepository;
|
||||||
|
import com.qqchen.deploy.backend.workflow.entity.NodeType;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点类型仓库接口
|
||||||
|
*/
|
||||||
|
@Repository
|
||||||
|
public interface INodeTypeRepository extends IBaseRepository<NodeType, Long> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据编码查询未删除的节点类型
|
||||||
|
*
|
||||||
|
* @param code 节点类型编码
|
||||||
|
* @return 节点类型
|
||||||
|
*/
|
||||||
|
Optional<NodeType> findByCodeAndDeletedFalse(String code);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查编码是否已存在(排除已删除的)
|
||||||
|
*
|
||||||
|
* @param code 节点类型编码
|
||||||
|
* @return 是否存在
|
||||||
|
*/
|
||||||
|
boolean existsByCodeAndDeletedFalse(String code);
|
||||||
|
}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
package com.qqchen.deploy.backend.workflow.service;
|
package com.qqchen.deploy.backend.workflow.service;
|
||||||
|
|
||||||
import com.qqchen.deploy.backend.framework.service.IBaseService;
|
import com.qqchen.deploy.backend.framework.service.IBaseService;
|
||||||
import com.qqchen.deploy.backend.workflow.api.dto.NodeInstanceDTO;
|
import com.qqchen.deploy.backend.workflow.dto.NodeInstanceDTO;
|
||||||
import com.qqchen.deploy.backend.workflow.entity.NodeInstance;
|
import com.qqchen.deploy.backend.workflow.entity.NodeInstance;
|
||||||
import com.qqchen.deploy.backend.workflow.enums.NodeStatusEnum;
|
import com.qqchen.deploy.backend.workflow.enums.NodeStatusEnum;
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,53 @@
|
|||||||
|
package com.qqchen.deploy.backend.workflow.service;
|
||||||
|
|
||||||
|
import com.qqchen.deploy.backend.framework.service.IBaseService;
|
||||||
|
import com.qqchen.deploy.backend.workflow.dto.NodeTypeDTO;
|
||||||
|
import com.qqchen.deploy.backend.workflow.engine.definition.TaskExecutorDefinition;
|
||||||
|
import com.qqchen.deploy.backend.workflow.entity.NodeType;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点类型服务接口
|
||||||
|
*/
|
||||||
|
public interface INodeTypeService extends IBaseService<NodeType, NodeTypeDTO, Long> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据编码查询节点类型
|
||||||
|
*
|
||||||
|
* @param code 节点类型编码
|
||||||
|
* @return 节点类型
|
||||||
|
*/
|
||||||
|
NodeTypeDTO findByCode(String code);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定节点类型支持的执行器列表
|
||||||
|
* 说明:
|
||||||
|
* 1. 只有TASK类型的节点才有执行器列表
|
||||||
|
* 2. 一个任务节点可以支持多种执行器
|
||||||
|
* 3. 每个执行器都有自己的配置模式
|
||||||
|
*
|
||||||
|
* 使用场景:
|
||||||
|
* 1. 流程设计时,选择节点类型后,需要展示该节点支持的执行器列表
|
||||||
|
* 2. 根据选择的执行器,动态渲染配置表单
|
||||||
|
* 3. 保存节点配置时,验证执行器参数是否符合配置模式
|
||||||
|
*
|
||||||
|
* @param code 节点类型编码
|
||||||
|
* @return 执行器列表
|
||||||
|
*/
|
||||||
|
List<TaskExecutorDefinition> getExecutors(String code);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启用节点类型
|
||||||
|
*
|
||||||
|
* @param id 节点类型ID
|
||||||
|
*/
|
||||||
|
void enable(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 禁用节点类型
|
||||||
|
*
|
||||||
|
* @param id 节点类型ID
|
||||||
|
*/
|
||||||
|
void disable(Long id);
|
||||||
|
}
|
||||||
@ -3,8 +3,8 @@ package com.qqchen.deploy.backend.workflow.service.impl;
|
|||||||
import com.qqchen.deploy.backend.framework.enums.ResponseCode;
|
import com.qqchen.deploy.backend.framework.enums.ResponseCode;
|
||||||
import com.qqchen.deploy.backend.framework.exception.BusinessException;
|
import com.qqchen.deploy.backend.framework.exception.BusinessException;
|
||||||
import com.qqchen.deploy.backend.framework.service.impl.BaseServiceImpl;
|
import com.qqchen.deploy.backend.framework.service.impl.BaseServiceImpl;
|
||||||
import com.qqchen.deploy.backend.workflow.api.dto.NodeInstanceDTO;
|
|
||||||
import com.qqchen.deploy.backend.workflow.converter.NodeInstanceConverter;
|
import com.qqchen.deploy.backend.workflow.converter.NodeInstanceConverter;
|
||||||
|
import com.qqchen.deploy.backend.workflow.dto.NodeInstanceDTO;
|
||||||
import com.qqchen.deploy.backend.workflow.entity.NodeInstance;
|
import com.qqchen.deploy.backend.workflow.entity.NodeInstance;
|
||||||
import com.qqchen.deploy.backend.workflow.enums.NodeStatusEnum;
|
import com.qqchen.deploy.backend.workflow.enums.NodeStatusEnum;
|
||||||
import com.qqchen.deploy.backend.workflow.repository.INodeInstanceRepository;
|
import com.qqchen.deploy.backend.workflow.repository.INodeInstanceRepository;
|
||||||
|
|||||||
@ -0,0 +1,81 @@
|
|||||||
|
package com.qqchen.deploy.backend.workflow.service.impl;
|
||||||
|
|
||||||
|
import com.qqchen.deploy.backend.framework.enums.ResponseCode;
|
||||||
|
import com.qqchen.deploy.backend.framework.exception.BusinessException;
|
||||||
|
import com.qqchen.deploy.backend.framework.service.impl.BaseServiceImpl;
|
||||||
|
import com.qqchen.deploy.backend.workflow.converter.JsonConverter;
|
||||||
|
import com.qqchen.deploy.backend.workflow.converter.NodeTypeConverter;
|
||||||
|
import com.qqchen.deploy.backend.workflow.dto.NodeTypeDTO;
|
||||||
|
import com.qqchen.deploy.backend.workflow.engine.definition.TaskExecutorDefinition;
|
||||||
|
import com.qqchen.deploy.backend.workflow.entity.NodeType;
|
||||||
|
import com.qqchen.deploy.backend.workflow.enums.NodeCategory;
|
||||||
|
import com.qqchen.deploy.backend.workflow.repository.INodeTypeRepository;
|
||||||
|
import com.qqchen.deploy.backend.workflow.service.INodeTypeService;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点类型服务实现类
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class NodeTypeServiceImpl extends BaseServiceImpl<NodeType, NodeTypeDTO, Long> implements INodeTypeService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private INodeTypeRepository nodeTypeRepository;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private NodeTypeConverter nodeTypeConverter;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private JsonConverter jsonConverter;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NodeTypeDTO findByCode(String code) {
|
||||||
|
return nodeTypeRepository.findByCodeAndDeletedFalse(code)
|
||||||
|
.map(nodeTypeConverter::toDto)
|
||||||
|
.orElseThrow(() -> new BusinessException(ResponseCode.WORKFLOW_NODE_TYPE_NOT_FOUND));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TaskExecutorDefinition> getExecutors(String code) {
|
||||||
|
// 1. 查询节点类型
|
||||||
|
NodeType nodeType = nodeTypeRepository.findByCodeAndDeletedFalse(code)
|
||||||
|
.orElseThrow(() -> new BusinessException(ResponseCode.WORKFLOW_NODE_TYPE_NOT_FOUND));
|
||||||
|
|
||||||
|
// 2. 检查节点类型是否为任务节点
|
||||||
|
if (!NodeCategory.TASK.equals(nodeType.getCategory())) {
|
||||||
|
// 非任务节点没有执行器列表
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 检查节点类型是否启用
|
||||||
|
if (!nodeType.getEnabled()) {
|
||||||
|
throw new BusinessException(ResponseCode.WORKFLOW_NODE_TYPE_DISABLED);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 将JSON字符串转换为执行器列表
|
||||||
|
return jsonConverter.toExecutorList(nodeType.getExecutors());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public void enable(Long id) {
|
||||||
|
NodeType nodeType = nodeTypeRepository.findById(id)
|
||||||
|
.orElseThrow(() -> new BusinessException(ResponseCode.WORKFLOW_NODE_TYPE_NOT_FOUND));
|
||||||
|
nodeType.setEnabled(true);
|
||||||
|
nodeTypeRepository.save(nodeType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public void disable(Long id) {
|
||||||
|
NodeType nodeType = nodeTypeRepository.findById(id)
|
||||||
|
.orElseThrow(() -> new BusinessException(ResponseCode.WORKFLOW_NODE_TYPE_NOT_FOUND));
|
||||||
|
nodeType.setEnabled(false);
|
||||||
|
nodeTypeRepository.save(nodeType);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -77,6 +77,9 @@ public class WorkflowDefinitionServiceImpl extends BaseServiceImpl<WorkflowDefin
|
|||||||
current.setName(dto.getName());
|
current.setName(dto.getName());
|
||||||
current.setDescription(dto.getDescription());
|
current.setDescription(dto.getDescription());
|
||||||
current.setNodeConfig(dto.getNodeConfig());
|
current.setNodeConfig(dto.getNodeConfig());
|
||||||
|
current.setTransitionConfig(dto.getTransitionConfig());
|
||||||
|
current.setFormDefinition(dto.getFormDefinition());
|
||||||
|
current.setGraphDefinition(dto.getGraphDefinition());
|
||||||
|
|
||||||
// 保存更新
|
// 保存更新
|
||||||
current = workflowDefinitionRepository.save(current);
|
current = workflowDefinitionRepository.save(current);
|
||||||
@ -163,9 +166,33 @@ public class WorkflowDefinitionServiceImpl extends BaseServiceImpl<WorkflowDefin
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean validate(Long id) {
|
public boolean validate(Long id) {
|
||||||
// TODO: 实现工作流定义验证逻辑
|
WorkflowDefinition definition = workflowDefinitionRepository.findById(id)
|
||||||
|
.orElseThrow(() -> new BusinessException(ResponseCode.WORKFLOW_NOT_FOUND));
|
||||||
|
|
||||||
// 1. 验证节点配置的完整性
|
// 1. 验证节点配置的完整性
|
||||||
// 2. 验证节点之间的连接关系
|
if (definition.getNodeConfig() == null || definition.getNodeConfig().isEmpty()) {
|
||||||
|
throw new BusinessException(ResponseCode.WORKFLOW_NODE_CONFIG_EMPTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 验证流转配置的完整性
|
||||||
|
if (definition.getTransitionConfig() == null || definition.getTransitionConfig().isEmpty()) {
|
||||||
|
throw new BusinessException(ResponseCode.WORKFLOW_TRANSITION_CONFIG_EMPTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 验证表单定义的完整性
|
||||||
|
if (definition.getFormDefinition() == null || definition.getFormDefinition().isEmpty()) {
|
||||||
|
throw new BusinessException(ResponseCode.WORKFLOW_FORM_CONFIG_EMPTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 验证图形信息的完整性
|
||||||
|
if (definition.getGraphDefinition() == null || definition.getGraphDefinition().isEmpty()) {
|
||||||
|
throw new BusinessException(ResponseCode.WORKFLOW_GRAPH_CONFIG_EMPTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: 实现更详细的验证逻辑
|
||||||
|
// 1. 验证节点之间的连接关系
|
||||||
|
// 2. 验证表单字段的合法性
|
||||||
|
// 3. 验证图形布局的合理性
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,6 +223,8 @@ public class WorkflowDefinitionServiceImpl extends BaseServiceImpl<WorkflowDefin
|
|||||||
newDefinition.setEnabled(true);
|
newDefinition.setEnabled(true);
|
||||||
newDefinition.setNodeConfig(oldDefinition.getNodeConfig());
|
newDefinition.setNodeConfig(oldDefinition.getNodeConfig());
|
||||||
newDefinition.setTransitionConfig(oldDefinition.getTransitionConfig());
|
newDefinition.setTransitionConfig(oldDefinition.getTransitionConfig());
|
||||||
|
newDefinition.setFormDefinition(oldDefinition.getFormDefinition());
|
||||||
|
newDefinition.setGraphDefinition(oldDefinition.getGraphDefinition());
|
||||||
|
|
||||||
// 保存新版本
|
// 保存新版本
|
||||||
return workflowDefinitionConverter.toDto(workflowDefinitionRepository.save(newDefinition));
|
return workflowDefinitionConverter.toDto(workflowDefinitionRepository.save(newDefinition));
|
||||||
|
|||||||
@ -393,54 +393,18 @@ CREATE TABLE wf_workflow_definition (
|
|||||||
|
|
||||||
code VARCHAR(100) NOT NULL COMMENT '工作流编码',
|
code VARCHAR(100) NOT NULL COMMENT '工作流编码',
|
||||||
name VARCHAR(100) NOT NULL COMMENT '工作流名称',
|
name VARCHAR(100) NOT NULL COMMENT '工作流名称',
|
||||||
description TEXT NULL COMMENT '工作流描述',
|
description VARCHAR(255) NULL COMMENT '工作流描述',
|
||||||
status VARCHAR(50) NOT NULL DEFAULT 'DRAFT' COMMENT '状态(DRAFT:草稿,PUBLISHED:已发布,DISABLED:已禁用)',
|
status VARCHAR(20) NOT NULL COMMENT '工作流状态(DRAFT/PUBLISHED/DISABLED)',
|
||||||
enabled BIT NOT NULL DEFAULT 1 COMMENT '是否启用(0:禁用,1:启用)',
|
version_no INT NOT NULL DEFAULT 1 COMMENT '版本号',
|
||||||
node_config TEXT NULL COMMENT '节点配置(JSON)',
|
node_config TEXT NULL COMMENT '节点配置(JSON)',
|
||||||
|
transition_config TEXT NULL COMMENT '流转配置(JSON)',
|
||||||
|
form_definition TEXT NULL COMMENT '表单定义(JSON)',
|
||||||
|
graph_definition TEXT NULL COMMENT '图形信息(JSON)',
|
||||||
|
enabled BIT NOT NULL DEFAULT 1 COMMENT '是否启用',
|
||||||
|
|
||||||
CONSTRAINT UK_workflow_definition_code UNIQUE (code)
|
CONSTRAINT UK_workflow_definition_code_version UNIQUE (code, version_no)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='工作流定义表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='工作流定义表';
|
||||||
|
|
||||||
-- 流转配置表
|
|
||||||
CREATE TABLE wf_transition_config (
|
|
||||||
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
|
|
||||||
create_by VARCHAR(255) NULL COMMENT '创建人',
|
|
||||||
create_time DATETIME(6) NULL COMMENT '创建时间',
|
|
||||||
deleted BIT NOT NULL DEFAULT 0 COMMENT '是否删除(0:未删除,1:已删除)',
|
|
||||||
update_by VARCHAR(255) NULL COMMENT '更新人',
|
|
||||||
update_time DATETIME(6) NULL COMMENT '更新时间',
|
|
||||||
version INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号',
|
|
||||||
|
|
||||||
workflow_definition_id BIGINT NOT NULL COMMENT '工作流定义ID',
|
|
||||||
source_node_id VARCHAR(255) NOT NULL COMMENT '源节点ID',
|
|
||||||
target_node_id VARCHAR(255) NOT NULL COMMENT '目标节点ID',
|
|
||||||
transition_condition TEXT NULL COMMENT '流转条件',
|
|
||||||
priority INT NOT NULL DEFAULT 0 COMMENT '优先级',
|
|
||||||
|
|
||||||
CONSTRAINT FK_transition_workflow FOREIGN KEY (workflow_definition_id) REFERENCES wf_workflow_definition (id)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='流转配置表';
|
|
||||||
|
|
||||||
-- 工作流实例表
|
|
||||||
CREATE TABLE wf_workflow_instance (
|
|
||||||
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
|
|
||||||
create_by VARCHAR(255) NULL COMMENT '创建人',
|
|
||||||
create_time DATETIME(6) NULL COMMENT '创建时间',
|
|
||||||
deleted BIT NOT NULL DEFAULT 0 COMMENT '是否删除(0:未删除,1:已删除)',
|
|
||||||
update_by VARCHAR(255) NULL COMMENT '更新人',
|
|
||||||
update_time DATETIME(6) NULL COMMENT '更新时间',
|
|
||||||
version INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号',
|
|
||||||
|
|
||||||
workflow_definition_id BIGINT NOT NULL COMMENT '工作流定义ID',
|
|
||||||
project_env_id BIGINT NULL COMMENT '项目环境ID',
|
|
||||||
business_key VARCHAR(100) NULL COMMENT '业务标识',
|
|
||||||
status VARCHAR(50) NOT NULL DEFAULT 'RUNNING' COMMENT '状态(RUNNING:运行中,COMPLETED:已完成,TERMINATED:已终止,FAILED:失败)',
|
|
||||||
start_time DATETIME(6) NULL COMMENT '开始时间',
|
|
||||||
end_time DATETIME(6) NULL COMMENT '结束时间',
|
|
||||||
error TEXT NULL COMMENT '错误信息',
|
|
||||||
|
|
||||||
CONSTRAINT FK_workflow_instance_definition FOREIGN KEY (workflow_definition_id) REFERENCES wf_workflow_definition (id)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='工作流实例表';
|
|
||||||
|
|
||||||
-- 节点定义表
|
-- 节点定义表
|
||||||
CREATE TABLE wf_node_definition (
|
CREATE TABLE wf_node_definition (
|
||||||
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
|
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
|
||||||
@ -452,14 +416,36 @@ CREATE TABLE wf_node_definition (
|
|||||||
version INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号',
|
version INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号',
|
||||||
|
|
||||||
workflow_definition_id BIGINT NOT NULL COMMENT '工作流定义ID',
|
workflow_definition_id BIGINT NOT NULL COMMENT '工作流定义ID',
|
||||||
node_id VARCHAR(50) NOT NULL COMMENT '节点ID',
|
node_id VARCHAR(100) NOT NULL COMMENT '节点ID',
|
||||||
name VARCHAR(100) NOT NULL COMMENT '节点名称',
|
name VARCHAR(100) NOT NULL COMMENT '节点名称',
|
||||||
type VARCHAR(50) NOT NULL COMMENT '节点类型',
|
type VARCHAR(20) NOT NULL COMMENT '节点类型(START/END/TASK/GATEWAY)',
|
||||||
config TEXT NULL COMMENT '节点配置(JSON)',
|
config TEXT NULL COMMENT '节点配置(JSON)',
|
||||||
order_num INT NOT NULL DEFAULT 0 COMMENT '排序号',
|
order_num INT NOT NULL DEFAULT 0 COMMENT '排序号',
|
||||||
|
|
||||||
CONSTRAINT FK_node_definition_workflow FOREIGN KEY (workflow_definition_id) REFERENCES wf_workflow_definition (id)
|
CONSTRAINT FK_node_definition_workflow FOREIGN KEY (workflow_definition_id) REFERENCES wf_workflow_definition (id),
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='工作流节点定义表';
|
CONSTRAINT UK_node_definition_workflow_node UNIQUE (workflow_definition_id, node_id)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='节点定义表';
|
||||||
|
|
||||||
|
-- 工作流实例表
|
||||||
|
CREATE TABLE wf_workflow_instance (
|
||||||
|
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
|
||||||
|
create_by VARCHAR(255) NULL COMMENT '创建人',
|
||||||
|
create_time DATETIME(6) NULL COMMENT '创建时间',
|
||||||
|
deleted BIT NOT NULL DEFAULT 0 COMMENT '是否删除(0:未删除,1:已删除)',
|
||||||
|
update_by VARCHAR(255) NULL COMMENT '更新人',
|
||||||
|
update_time DATETIME(6) NULL COMMENT '更新时间',
|
||||||
|
version INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号',
|
||||||
|
|
||||||
|
workflow_definition_id BIGINT NOT NULL COMMENT '工作流定义ID',
|
||||||
|
business_key VARCHAR(100) NOT NULL COMMENT '业务标识',
|
||||||
|
status VARCHAR(20) NOT NULL COMMENT '状态(PENDING/RUNNING/COMPLETED/FAILED/CANCELLED)',
|
||||||
|
start_time DATETIME(6) NULL COMMENT '开始时间',
|
||||||
|
end_time DATETIME(6) NULL COMMENT '结束时间',
|
||||||
|
error TEXT NULL COMMENT '错误信息',
|
||||||
|
|
||||||
|
CONSTRAINT FK_workflow_instance_definition FOREIGN KEY (workflow_definition_id) REFERENCES wf_workflow_definition (id),
|
||||||
|
CONSTRAINT UK_workflow_instance_business_key UNIQUE (business_key)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='工作流实例表';
|
||||||
|
|
||||||
-- 节点实例表
|
-- 节点实例表
|
||||||
CREATE TABLE wf_node_instance (
|
CREATE TABLE wf_node_instance (
|
||||||
@ -473,9 +459,9 @@ CREATE TABLE wf_node_instance (
|
|||||||
|
|
||||||
workflow_instance_id BIGINT NOT NULL COMMENT '工作流实例ID',
|
workflow_instance_id BIGINT NOT NULL COMMENT '工作流实例ID',
|
||||||
node_id VARCHAR(100) NOT NULL COMMENT '节点ID',
|
node_id VARCHAR(100) NOT NULL COMMENT '节点ID',
|
||||||
|
node_type VARCHAR(20) NOT NULL COMMENT '节点类型',
|
||||||
name VARCHAR(100) NOT NULL COMMENT '节点名称',
|
name VARCHAR(100) NOT NULL COMMENT '节点名称',
|
||||||
type VARCHAR(50) NOT NULL COMMENT '节点类型',
|
status VARCHAR(20) NOT NULL COMMENT '状态(PENDING/RUNNING/COMPLETED/FAILED/CANCELLED/SKIPPED)',
|
||||||
status VARCHAR(50) NOT NULL DEFAULT 'PENDING' COMMENT '状态(PENDING:待执行,RUNNING:执行中,COMPLETED:已完成,FAILED:失败,TERMINATED:已终止)',
|
|
||||||
start_time DATETIME(6) NULL COMMENT '开始时间',
|
start_time DATETIME(6) NULL COMMENT '开始时间',
|
||||||
end_time DATETIME(6) NULL COMMENT '结束时间',
|
end_time DATETIME(6) NULL COMMENT '结束时间',
|
||||||
config TEXT NULL COMMENT '节点配置(JSON)',
|
config TEXT NULL COMMENT '节点配置(JSON)',
|
||||||
@ -500,11 +486,10 @@ CREATE TABLE wf_workflow_variable (
|
|||||||
workflow_instance_id BIGINT NOT NULL COMMENT '工作流实例ID',
|
workflow_instance_id BIGINT NOT NULL COMMENT '工作流实例ID',
|
||||||
name VARCHAR(100) NOT NULL COMMENT '变量名',
|
name VARCHAR(100) NOT NULL COMMENT '变量名',
|
||||||
value TEXT NULL COMMENT '变量值',
|
value TEXT NULL COMMENT '变量值',
|
||||||
type VARCHAR(50) NOT NULL COMMENT '变量类型',
|
type VARCHAR(20) NOT NULL COMMENT '变量类型',
|
||||||
scope VARCHAR(50) NOT NULL DEFAULT 'GLOBAL' COMMENT '作用域(GLOBAL:全局,NODE:节点)',
|
|
||||||
node_id VARCHAR(100) NULL COMMENT '节点ID(scope为NODE时必填)',
|
|
||||||
|
|
||||||
CONSTRAINT FK_variable_workflow FOREIGN KEY (workflow_instance_id) REFERENCES wf_workflow_instance (id)
|
CONSTRAINT FK_workflow_variable_instance FOREIGN KEY (workflow_instance_id) REFERENCES wf_workflow_instance (id),
|
||||||
|
CONSTRAINT UK_workflow_variable_instance_name UNIQUE (workflow_instance_id, name)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='工作流变量表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='工作流变量表';
|
||||||
|
|
||||||
-- 工作流日志表
|
-- 工作流日志表
|
||||||
@ -548,3 +533,27 @@ CREATE TABLE wf_workflow_permission (
|
|||||||
INDEX idx_department_id (department_id)
|
INDEX idx_department_id (department_id)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='工作流权限';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='工作流权限';
|
||||||
|
|
||||||
|
-- 节点类型表
|
||||||
|
CREATE TABLE wf_node_type (
|
||||||
|
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
|
||||||
|
create_by VARCHAR(255) NULL COMMENT '创建人',
|
||||||
|
create_time DATETIME(6) NULL COMMENT '创建时间',
|
||||||
|
deleted BIT NOT NULL DEFAULT 0 COMMENT '是否删除(0:未删除,1:已删除)',
|
||||||
|
update_by VARCHAR(255) NULL COMMENT '更新人',
|
||||||
|
update_time DATETIME(6) NULL COMMENT '更新时间',
|
||||||
|
version INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号',
|
||||||
|
|
||||||
|
code VARCHAR(100) NOT NULL COMMENT '节点类型编码',
|
||||||
|
name VARCHAR(100) NOT NULL COMMENT '节点类型名称',
|
||||||
|
description TEXT NULL COMMENT '节点类型描述',
|
||||||
|
category VARCHAR(50) NOT NULL COMMENT '节点类型分类',
|
||||||
|
icon VARCHAR(100) NULL COMMENT '节点图标',
|
||||||
|
color VARCHAR(20) NULL COMMENT '节点颜色',
|
||||||
|
executors TEXT NULL COMMENT '执行器列表(JSON)',
|
||||||
|
config_schema TEXT NULL COMMENT '节点配置模式(JSON)',
|
||||||
|
default_config TEXT NULL COMMENT '默认配置(JSON)',
|
||||||
|
enabled BIT NOT NULL DEFAULT 1 COMMENT '是否启用',
|
||||||
|
|
||||||
|
CONSTRAINT UK_node_type_code UNIQUE (code)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='节点类型表';
|
||||||
|
|
||||||
@ -151,3 +151,100 @@ INSERT INTO sys_external_system (
|
|||||||
'TOKEN', NULL, NULL, 'cNSud7D1GmYQKEMco7s5',
|
'TOKEN', NULL, NULL, 'cNSud7D1GmYQKEMco7s5',
|
||||||
NULL, NULL, NULL, '{}'
|
NULL, NULL, NULL, '{}'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
-- --------------------------------------------------------------------------------------
|
||||||
|
-- 初始化工作流相关数据
|
||||||
|
-- --------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- 初始化工作流定义
|
||||||
|
INSERT INTO wf_workflow_definition (
|
||||||
|
id, create_by, create_time, deleted, update_by, update_time, version,
|
||||||
|
code, name, description, status, version_no, node_config, transition_config, form_definition, graph_definition, enabled
|
||||||
|
) VALUES (
|
||||||
|
1, 'admin', NOW(), 0, 'admin', NOW(), 0,
|
||||||
|
'DEPLOY_WORKFLOW', '标准部署流程', '标准的应用部署流程,包含代码拉取、编译构建、部署等步骤',
|
||||||
|
'PUBLISHED', 1,
|
||||||
|
'{"startNode":{"type":"START","name":"开始"},"endNode":{"type":"END","name":"结束"},"taskNodes":[{"id":"build","type":"TASK","name":"构建"},{"id":"deploy","type":"TASK","name":"部署"}]}',
|
||||||
|
'{"transitions":[{"from":"startNode","to":"build"},{"from":"build","to":"deploy"},{"from":"deploy","to":"endNode"}]}',
|
||||||
|
'{"fields":[{"name":"appName","label":"应用名称","type":"input","required":true},{"name":"branch","label":"分支","type":"select","required":true}]}',
|
||||||
|
'{"nodes":[{"id":"startNode","type":"START","x":100,"y":100},{"id":"build","type":"TASK","x":300,"y":100},{"id":"deploy","type":"TASK","x":500,"y":100},{"id":"endNode","type":"END","x":700,"y":100}],"edges":[{"source":"startNode","target":"build"},{"source":"build","target":"deploy"},{"source":"deploy","target":"endNode"}]}',
|
||||||
|
1
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 初始化节点定义
|
||||||
|
INSERT INTO wf_node_definition (
|
||||||
|
id, create_by, create_time, deleted, update_by, update_time, version,
|
||||||
|
workflow_definition_id, node_id, name, type, config, order_num
|
||||||
|
) VALUES
|
||||||
|
-- 开始节点
|
||||||
|
(1, 'admin', NOW(), 0, 'admin', NOW(), 0,
|
||||||
|
1, 'startNode', '开始', 'START',
|
||||||
|
'{"type":"START","name":"开始"}',
|
||||||
|
1),
|
||||||
|
-- 构建节点
|
||||||
|
(2, 'admin', NOW(), 0, 'admin', NOW(), 0,
|
||||||
|
1, 'build', '构建', 'TASK',
|
||||||
|
'{"type":"TASK","name":"构建","executor":"JENKINS","jenkinsJob":"app-build"}',
|
||||||
|
2),
|
||||||
|
-- 部署节点
|
||||||
|
(3, 'admin', NOW(), 0, 'admin', NOW(), 0,
|
||||||
|
1, 'deploy', '部署', 'TASK',
|
||||||
|
'{"type":"TASK","name":"部署","executor":"SHELL","script":"./deploy.sh"}',
|
||||||
|
3),
|
||||||
|
-- 结束节点
|
||||||
|
(4, 'admin', NOW(), 0, 'admin', NOW(), 0,
|
||||||
|
1, 'endNode', '结束', 'END',
|
||||||
|
'{"type":"END","name":"结束"}',
|
||||||
|
4);
|
||||||
|
|
||||||
|
-- 初始化工作流实例
|
||||||
|
INSERT INTO wf_workflow_instance (
|
||||||
|
id, create_by, create_time, deleted, update_by, update_time, version,
|
||||||
|
workflow_definition_id, business_key, status, start_time, end_time, error
|
||||||
|
) VALUES (
|
||||||
|
1, 'admin', NOW(), 0, 'admin', NOW(), 0,
|
||||||
|
1, 'TEST-APP-001', 'RUNNING',
|
||||||
|
NOW(), NULL, NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 初始化节点实例
|
||||||
|
INSERT INTO wf_node_instance (
|
||||||
|
id, create_by, create_time, deleted, update_by, update_time, version,
|
||||||
|
workflow_instance_id, node_id, node_type, name, status, start_time, end_time, config, input, output, error, pre_node_id
|
||||||
|
) VALUES
|
||||||
|
-- 开始节点实例
|
||||||
|
(1, 'admin', NOW(), 0, 'admin', NOW(), 0,
|
||||||
|
1, 'startNode', 'START', '开始', 'COMPLETED',
|
||||||
|
DATE_SUB(NOW(), INTERVAL 5 MINUTE), DATE_SUB(NOW(), INTERVAL 4 MINUTE),
|
||||||
|
'{"type":"START","name":"开始"}',
|
||||||
|
'{"appName":"test-app","branch":"master"}', '{}', NULL, NULL),
|
||||||
|
-- 构建节点实例
|
||||||
|
(2, 'admin', NOW(), 0, 'admin', NOW(), 0,
|
||||||
|
1, 'build', 'TASK', '构建', 'RUNNING',
|
||||||
|
DATE_SUB(NOW(), INTERVAL 3 MINUTE), NULL,
|
||||||
|
'{"type":"TASK","name":"构建","executor":"JENKINS","jenkinsJob":"app-build"}',
|
||||||
|
'{"appName":"test-app","branch":"master"}', NULL, NULL, 'startNode'),
|
||||||
|
-- 部署节点实例
|
||||||
|
(3, 'admin', NOW(), 0, 'admin', NOW(), 0,
|
||||||
|
1, 'deploy', 'TASK', '部署', 'RUNNING',
|
||||||
|
DATE_SUB(NOW(), INTERVAL 2 MINUTE), NULL,
|
||||||
|
'{"type":"TASK","name":"部署","executor":"SHELL","script":"./deploy.sh"}',
|
||||||
|
'{"appName":"test-app","branch":"master"}', NULL, NULL, 'build'),
|
||||||
|
-- 结束节点实例
|
||||||
|
(4, 'admin', NOW(), 0, 'admin', NOW(), 0,
|
||||||
|
1, 'endNode', 'END', '结束', 'COMPLETED',
|
||||||
|
DATE_SUB(NOW(), INTERVAL 1 MINUTE), DATE_SUB(NOW(), INTERVAL 0 MINUTE),
|
||||||
|
'{"type":"END","name":"结束"}',
|
||||||
|
'{}', '{}', NULL, 'deploy');
|
||||||
|
|
||||||
|
-- 初始化工作流变量
|
||||||
|
INSERT INTO wf_workflow_variable (
|
||||||
|
id, create_by, create_time, deleted, update_by, update_time, version,
|
||||||
|
workflow_instance_id, name, value, type
|
||||||
|
) VALUES
|
||||||
|
(1, 'admin', NOW(), 0, 'admin', NOW(), 0,
|
||||||
|
1, 'appName', 'test-app', 'STRING'),
|
||||||
|
(2, 'admin', NOW(), 0, 'admin', NOW(), 0,
|
||||||
|
1, 'branch', 'master', 'STRING'),
|
||||||
|
(3, 'admin', NOW(), 0, 'admin', NOW(), 0,
|
||||||
|
1, 'buildNumber', '123', 'STRING');
|
||||||
@ -222,3 +222,16 @@ workflow.dependency.not.satisfied=工作流依赖条件未满足
|
|||||||
workflow.circular.dependency=工作流存在循环依赖
|
workflow.circular.dependency=工作流存在循环依赖
|
||||||
workflow.schedule.invalid=工作流调度配置无效
|
workflow.schedule.invalid=工作流调度配置无效
|
||||||
workflow.concurrent.limit.exceeded=工作流并发限制超出
|
workflow.concurrent.limit.exceeded=工作流并发限制超出
|
||||||
|
|
||||||
|
# 工作流配置相关错误消息
|
||||||
|
workflow.node.config.empty=节点配置不能为空
|
||||||
|
workflow.transition.config.empty=流转配置不能为空
|
||||||
|
workflow.form.config.empty=表单配置不能为空
|
||||||
|
workflow.graph.config.empty=图形配置不能为空
|
||||||
|
|
||||||
|
# 工作流节点类型错误 (2200-2299)
|
||||||
|
workflow.node.type.not.found=节点类型不存在或已删除
|
||||||
|
workflow.node.type.disabled=节点类型已禁用,无法使用
|
||||||
|
workflow.node.type.code.exists=节点类型编码已存在
|
||||||
|
workflow.node.type.invalid.category=无效的节点类型分类
|
||||||
|
workflow.node.type.invalid.executor=无效的执行器配置
|
||||||
@ -42,3 +42,10 @@ workflow.dependency.not.satisfied=Workflow dependency not satisfied
|
|||||||
workflow.circular.dependency=Circular dependency detected in workflow
|
workflow.circular.dependency=Circular dependency detected in workflow
|
||||||
workflow.schedule.invalid=Invalid workflow schedule configuration
|
workflow.schedule.invalid=Invalid workflow schedule configuration
|
||||||
workflow.concurrent.limit.exceeded=Workflow concurrent limit exceeded
|
workflow.concurrent.limit.exceeded=Workflow concurrent limit exceeded
|
||||||
|
|
||||||
|
# Workflow Node Type Errors (2200-2299)
|
||||||
|
workflow.node.type.not.found=Node type does not exist or has been deleted
|
||||||
|
workflow.node.type.disabled=Node type is disabled and cannot be used
|
||||||
|
workflow.node.type.code.exists=Node type code already exists
|
||||||
|
workflow.node.type.invalid.category=Invalid node type category
|
||||||
|
workflow.node.type.invalid.executor=Invalid executor configuration
|
||||||
Loading…
Reference in New Issue
Block a user