/**
* 根据流程实例Id,获取实时流程图片
*
* @param processInstanceId
* @param
* @param useCustomColor true:用自定义的颜色(完成节点绿色,当前节点红色),default:用默认的颜色(红色)
* @return
*/
public void getFlowImgByInstanceId(String processInstanceId, HttpServletResponse response, boolean useCustomColor) {
try {
if (org.springframework.util.StringUtils.isEmpty(processInstanceId)) {
log.error("processInstanceId is null");
return;
}
// 获取历史流程实例
HistoricProcessInstance historicProcessInstance = historyService
.createHistoricProcessInstanceQuery()
.processInstanceId(processInstanceId).singleResult();
// 获取流程中已经执行的节点,按照执行先后顺序排序
List historicActivityInstances = historyService
.createHistoricActivityInstanceQuery()
.processInstanceId(processInstanceId)
.orderByHistoricActivityInstanceId()
.desc().list();
// 高亮已经执行流程节点ID集合
List highLightedActivitiIds = new ArrayList<>();
int index = 1;
for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) {
if (useCustomColor) {
// 用自定义颜色
if (index == historicActivityInstances.size()) {
// 当前节点
highLightedActivitiIds.add(historicActivityInstance.getActivityId() + "#");
} else {
// 已完成节点
highLightedActivitiIds.add(historicActivityInstance.getActivityId());
}
} else {
// 用默认颜色
highLightedActivitiIds.add(historicActivityInstance.getActivityId());
}
index++;
}
ProcessDiagramGenerator processDiagramGenerator = null;
if (useCustomColor) {
// 使用自定义的程序图片生成器
processDiagramGenerator = new CustomProcessDiagramGenerator();
} else {
// 使用默认的程序图片生成器
processDiagramGenerator = new DefaultProcessDiagramGenerator();
}
BpmnModel bpmnModel = repositoryService
.getBpmnModel(historicProcessInstance.getProcessDefinitionId());
// 高亮流程已发生流转的线id集合
List highLightedFlowIds = getHighLightedFlows(bpmnModel, historicActivityInstances);
// 使用默认配置获得流程图表生成器,并生成追踪图片字符流
InputStream imageStream = processDiagramGenerator.generateDiagram(bpmnModel,
highLightedActivitiIds, highLightedFlowIds, "宋体",
"宋体", "宋体");
// 输出图片内容
Integer byteSize = 1024;
byte[] b = new byte[byteSize];
int len;
while ((len = imageStream.read(b, 0, byteSize)) != -1) {
response.getOutputStream().write(b, 0, len);
}
} catch (Exception e) {
log.error("processInstanceId" + processInstanceId + "生成流程图失败,原因:" + e.getMessage(), e);
}
}
/**
* 获取已经流转的线
*
* @param bpmnModel
* @param historicActivityInstances
* @return
*/
private static List getHighLightedFlows(BpmnModel bpmnModel,
List historicActivityInstances) {
// 流转线ID集合
List flowIdList = new ArrayList();
// 全部活动实例
List historicFlowNodeList = new LinkedList();
// 已完成的历史活动节点
List finishedActivityInstanceList = new LinkedList();
for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) {
historicFlowNodeList.add((FlowNode) bpmnModel.getMainProcess().getFlowElement(historicActivityInstance.getActivityId(), true));
if (historicActivityInstance.getEndTime() != null) {
finishedActivityInstanceList.add(historicActivityInstance);
}
}
// 遍历已完成的活动实例,从每个实例的outgoingFlows中找到已执行的
FlowNode currentFlowNode = null;
for (HistoricActivityInstance currentActivityInstance : finishedActivityInstanceList) {
// 获得当前活动对应的节点信息及outgoingFlows信息
currentFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(currentActivityInstance.getActivityId(), true);
List sequenceFlowList = currentFlowNode.getOutgoingFlows();
/**
* 遍历outgoingFlows并找到已已流转的
* 满足如下条件认为已已流转:
* 1.当前节点是并行网关或包含网关,则通过outgoingFlows能够在历史活动中找到的全部节点均为已流转
* 2.当前节点是以上两种类型之外的,通过outgoingFlows查找到的时间最近的流转节点视为有效流转
*/
FlowNode targetFlowNode = null;
if ("parallelGateway".equals(currentActivityInstance.getActivityType())
|| "inclusiveGateway".equals(currentActivityInstance.getActivityType())) {
// 遍历历史活动节点,找到匹配Flow目标节点的
for (SequenceFlow sequenceFlow : sequenceFlowList) {
targetFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(sequenceFlow.getTargetRef(), true);
if (historicFlowNodeList.contains(targetFlowNode)
&& (sequenceFlowList.size() > 1 || Objects.nonNull(currentActivityInstance.getEndTime()))) {
flowIdList.add(sequenceFlow.getId());
}
}
} else {
// 遍历历史活动节点,找到匹配Flow目标节点的
for (SequenceFlow sequenceFlow : sequenceFlowList) {
for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) {
if (historicActivityInstance.getActivityId().equals(sequenceFlow.getTargetRef())) {
if(Objects.nonNull(currentActivityInstance.getEndTime())
&& Objects.nonNull(historicActivityInstance.getStartTime())){
String endTime = DateUtil.format(currentActivityInstance.getEndTime(), "yyyy-MM-dd HH:mm:ss");
String startTime = DateUtil.format(historicActivityInstance.getStartTime(), "yyyy-MM-dd HH:mm:ss");
if(startTime.equals(endTime)){
flowIdList.add(sequenceFlow.getId());
}
}
}
}
}
}
}
return flowIdList;
}
显示效果如下:
更新时间:2024-07-22
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号