12 KiB
12 KiB
部署记录流程图前端绘制指南
概述
本文档说明前端如何调用API获取部署记录的工作流流程图数据,以及如何使用这些数据绘制流程图并标记节点状态。
API接口
获取部署流程图数据
接口地址: GET /api/v1/deploy/records/{deployRecordId}/flow-graph
路径参数:
deployRecordId(Long): 部署记录ID
响应示例:
{
"success": true,
"message": "操作成功",
"data": {
"deployRecordId": 16,
"workflowInstanceId": 16,
"processInstanceId": "b24d97ec-b97f-11f0-be70-de5a4815c9ef",
"deployStatus": "REJECTED",
"graph": {
"nodes": [
{
"id": "startNode",
"nodeCode": "start",
"nodeType": "START",
"nodeName": "开始",
"position": {
"x": 100,
"y": 200
},
"configs": {},
"inputMapping": {},
"outputs": []
},
{
"id": "sid_4ee9fab9_d626_4691_816c_9435902fc3d0",
"nodeCode": "approval",
"nodeType": "APPROVAL",
"nodeName": "审批节点",
"position": {
"x": 300,
"y": 200
},
"configs": {
"userIds": ["admin"]
},
"inputMapping": {},
"outputs": []
},
{
"id": "endNode",
"nodeCode": "end",
"nodeType": "END",
"nodeName": "结束",
"position": {
"x": 500,
"y": 200
},
"configs": {},
"inputMapping": {},
"outputs": []
}
],
"edges": [
{
"source": "startNode",
"target": "sid_4ee9fab9_d626_4691_816c_816c_9435902fc3d0"
},
{
"source": "sid_4ee9fab9_d626_4691_816c_9435902fc3d0",
"target": "endNode"
}
]
},
"nodeInstances": [
{
"id": 1,
"processInstanceId": "b24d97ec-b97f-11f0-be70-de5a4815c9ef",
"nodeId": "startNode",
"nodeName": "开始",
"nodeType": "START",
"status": "COMPLETED",
"startTime": "2025-11-04T21:10:00",
"endTime": "2025-11-04T21:10:01"
},
{
"id": 2,
"processInstanceId": "b24d97ec-b97f-11f0-be70-de5a4815c9ef",
"nodeId": "sid_4ee9fab9_d626_4691_816c_9435902fc3d0",
"nodeName": "审批节点",
"nodeType": "APPROVAL",
"status": "REJECTED",
"startTime": "2025-11-04T21:10:01",
"endTime": "2025-11-04T21:14:34"
},
{
"id": null,
"processInstanceId": "b24d97ec-b97f-11f0-be70-de5a4815c9ef",
"nodeId": "endNode",
"nodeName": "结束",
"nodeType": "END",
"status": "NOT_STARTED",
"startTime": null,
"endTime": null
}
]
}
}
数据结构说明
DeployRecordFlowGraphDTO
| 字段 | 类型 | 说明 |
|---|---|---|
deployRecordId |
Long | 部署记录ID |
workflowInstanceId |
Long | 工作流实例ID |
processInstanceId |
String | Flowable流程实例ID |
deployStatus |
String | 部署状态(CREATED/PENDING_APPROVAL/RUNNING/SUCCESS/FAILED/REJECTED/CANCELLED/TERMINATED/PARTIAL_SUCCESS) |
graph |
WorkflowDefinitionGraph | 流程图结构数据(包含节点和边的位置信息) |
nodeInstances |
List | 节点执行状态列表 |
WorkflowDefinitionGraph
| 字段 | 类型 | 说明 |
|---|---|---|
nodes |
List | 节点列表(包含位置信息) |
edges |
List | 边列表(连接关系) |
WorkflowDefinitionGraphNode
| 字段 | 类型 | 说明 |
|---|---|---|
id |
String | 节点ID(用于匹配nodeInstances) |
nodeCode |
String | 节点代码 |
nodeType |
String | 节点类型(START/END/APPROVAL/SHELL等) |
nodeName |
String | 节点名称 |
position |
Map<String, Object> | 节点位置信息(x, y坐标) |
configs |
Map<String, Object> | 节点配置信息 |
inputMapping |
Map<String, Object> | 输入映射 |
outputs |
List | 输出字段列表 |
WorkflowNodeInstanceDTO
| 字段 | 类型 | 说明 |
|---|---|---|
id |
Long | 节点实例ID(可能为null,表示未开始) |
nodeId |
String | 节点ID(与graph.nodes中的id匹配) |
nodeName |
String | 节点名称 |
nodeType |
String | 节点类型 |
status |
String | 节点执行状态(NOT_STARTED/RUNNING/COMPLETED/FAILED/REJECTED等) |
startTime |
LocalDateTime | 开始时间 |
endTime |
LocalDateTime | 结束时间 |
前端绘制流程
1. 调用API获取数据
// 使用React示例
const fetchDeployFlowGraph = async (deployRecordId: number) => {
const response = await fetch(`/api/v1/deploy/records/${deployRecordId}/flow-graph`, {
headers: {
'Authorization': `Bearer ${token}`
}
});
const result = await response.json();
return result.data;
};
2. 绘制流程图
使用流程图库(如 react-flow、antv x6、mxGraph 等)绘制流程图:
步骤1:创建节点映射
// 将nodeInstances转换为Map,方便查找
const nodeStatusMap = new Map(
data.nodeInstances.map(node => [node.nodeId, node])
);
步骤2:根据graph.nodes创建节点
const flowNodes = data.graph.nodes.map(node => {
const nodeInstance = nodeStatusMap.get(node.id);
const status = nodeInstance?.status || 'NOT_STARTED';
return {
id: node.id,
type: mapNodeType(node.nodeType), // 根据节点类型选择不同的节点组件
position: { x: node.position.x, y: node.position.y },
data: {
label: node.nodeName,
nodeType: node.nodeType,
status: status, // 节点状态,用于样式标记
nodeInstance: nodeInstance, // 完整的节点实例信息
configs: node.configs
},
style: getNodeStyle(status) // 根据状态设置样式
};
});
步骤3:根据graph.edges创建边
const flowEdges = data.graph.edges.map(edge => ({
id: `${edge.source}-${edge.target}`,
source: edge.source,
target: edge.target,
style: getEdgeStyle(edge, nodeStatusMap) // 根据节点状态设置边的样式
}));
3. 节点状态样式映射
// 节点状态颜色映射
const statusColorMap = {
'NOT_STARTED': '#d9d9d9', // 灰色 - 未开始
'RUNNING': '#1890ff', // 蓝色 - 运行中
'COMPLETED': '#52c41a', // 绿色 - 已完成
'FAILED': '#ff4d4f', // 红色 - 失败
'REJECTED': '#ff4d4f', // 红色 - 审批被拒绝
'CANCELLED': '#d9d9d9', // 灰色 - 已取消
'TERMINATED': '#ff4d4f' // 红色 - 已终止
};
const getNodeStyle = (status: string) => {
return {
background: statusColorMap[status] || '#d9d9d9',
border: `2px solid ${statusColorMap[status] || '#d9d9d9'}`,
borderRadius: '8px',
padding: '10px',
color: '#fff',
fontWeight: 'bold'
};
};
4. 边的状态样式
const getEdgeStyle = (edge: any, nodeStatusMap: Map<string, any>) => {
const sourceStatus = nodeStatusMap.get(edge.source)?.status || 'NOT_STARTED';
const targetStatus = nodeStatusMap.get(edge.target)?.status || 'NOT_STARTED';
// 如果源节点已完成,边显示为已完成
if (sourceStatus === 'COMPLETED') {
return {
stroke: '#52c41a',
strokeWidth: 2
};
}
// 如果源节点失败或被拒绝,边显示为失败
if (sourceStatus === 'FAILED' || sourceStatus === 'REJECTED') {
return {
stroke: '#ff4d4f',
strokeWidth: 2,
strokeDasharray: '5,5' // 虚线表示流程中断
};
}
// 默认样式
return {
stroke: '#d9d9d9',
strokeWidth: 1
};
};
5. 整体部署状态标记
// 根据deployStatus显示整体状态
const deployStatusMap = {
'CREATED': { color: '#1890ff', text: '已创建' },
'PENDING_APPROVAL': { color: '#faad14', text: '待审批' },
'RUNNING': { color: '#1890ff', text: '运行中' },
'SUCCESS': { color: '#52c41a', text: '部署成功' },
'FAILED': { color: '#ff4d4f', text: '部署失败' },
'REJECTED': { color: '#ff4d4f', text: '审批被拒绝' },
'CANCELLED': { color: '#d9d9d9', text: '已取消' },
'TERMINATED': { color: '#ff4d4f', text: '已终止' },
'PARTIAL_SUCCESS': { color: '#faad14', text: '部分成功' }
};
// 在流程图上方显示整体状态
const statusInfo = deployStatusMap[data.deployStatus];
完整示例(React + react-flow)
import React, { useEffect, useState } from 'react';
import ReactFlow, { Node, Edge } from 'react-flow-renderer';
interface DeployFlowGraphProps {
deployRecordId: number;
}
const DeployFlowGraph: React.FC<DeployFlowGraphProps> = ({ deployRecordId }) => {
const [nodes, setNodes] = useState<Node[]>([]);
const [edges, setEdges] = useState<Edge[]>([]);
const [deployStatus, setDeployStatus] = useState<string>('');
useEffect(() => {
fetchDeployFlowGraph(deployRecordId).then(data => {
// 创建节点状态映射
const nodeStatusMap = new Map(
data.nodeInstances.map(node => [node.nodeId, node])
);
// 创建节点
const flowNodes = data.graph.nodes.map(node => {
const nodeInstance = nodeStatusMap.get(node.id);
const status = nodeInstance?.status || 'NOT_STARTED';
return {
id: node.id,
type: 'default',
position: { x: node.position.x, y: node.position.y },
data: {
label: (
<div>
<div>{node.nodeName}</div>
<div style={{ fontSize: '12px', color: getStatusColor(status) }}>
{getStatusText(status)}
</div>
</div>
),
status: status
},
style: {
background: getStatusColor(status),
color: '#fff',
border: `2px solid ${getStatusColor(status)}`,
borderRadius: '8px',
padding: '10px',
width: 150
}
};
});
// 创建边
const flowEdges = data.graph.edges.map(edge => ({
id: `${edge.source}-${edge.target}`,
source: edge.source,
target: edge.target,
style: {
stroke: getEdgeColor(edge, nodeStatusMap),
strokeWidth: 2
}
}));
setNodes(flowNodes);
setEdges(flowEdges);
setDeployStatus(data.deployStatus);
});
}, [deployRecordId]);
return (
<div>
<div style={{ marginBottom: '20px' }}>
<h3>部署状态:{getDeployStatusText(deployStatus)}</h3>
</div>
<ReactFlow nodes={nodes} edges={edges} fitView />
</div>
);
};
注意事项
-
节点ID匹配:
graph.nodes中的id与nodeInstances中的nodeId需要匹配,用于确定每个节点的执行状态。 -
未开始的节点:如果某个节点还没有开始执行,
nodeInstances中可能没有对应的记录,或者status为NOT_STARTED,id可能为null。 -
状态优先级:
- 如果部署状态为
REJECTED,说明审批被拒绝,相关审批节点的状态应该也是REJECTED。 - 如果部署状态为
PARTIAL_SUCCESS,说明部分节点失败,需要检查哪些节点的状态是FAILED。
- 如果部署状态为
-
节点位置:
graph.nodes中的position字段包含了节点在画布上的位置信息(x, y坐标),直接使用即可。 -
边的绘制顺序:
graph.edges中的边定义了节点之间的连接关系,按照source和target绘制即可。
状态流转示意
CREATED → PENDING_APPROVAL → RUNNING → SUCCESS
↓
FAILED/REJECTED
- CREATED:部署记录已创建,工作流已启动
- PENDING_APPROVAL:等待审批中
- RUNNING:审批通过,正在执行部署
- SUCCESS:部署成功
- FAILED:部署失败
- REJECTED:审批被拒绝(终态)
- CANCELLED:已取消
- TERMINATED:已终止
- PARTIAL_SUCCESS:部分成功(工作流完成但存在失败的节点)