activiti7的流程圖、模闆圖及子流程圖展示
流程圖需展示流程完成情況,模闆圖根據key找到最新模闆展示。子流程需從主流程中找到CallActiviti的節點,找到對應的子流程id(已啟動)或模闆key(未啟動),再進行對應的流程或模闆展示。
//根據流程id 展示流程圖
private void outPutImageByInstanceId(String instanceId,HttpServletResponse response){
if(StringUtils.isEmpty(instanceId)){
LOG.info(“流程id為空!”);
return;
}
LOG.info(“檢視完整流程圖!流程執行個體ID:{}”, instanceId);
// 擷取流程執行個體(id查詢隻能查到單獨的記錄,如果是其他條件,此處需換為list)
HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(instanceId).singleResult();
if (processInstance == null) {
LOG.error(“流程執行個體ID:{}沒查詢到流程執行個體!”, instanceId);
return;
}
// 根據流程對象擷取流程對象模型
BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
// 構造曆史流程查詢
HistoricActivityInstanceQuery historyInstanceQuery = historyService.createHistoricActivityInstanceQuery().processInstanceId(instanceId);
// 查詢曆史節點
List<HistoricActivityInstance> historicActivityInstanceList = historyInstanceQuery.orderByHistoricActivityInstanceStartTime().asc().list();
if (historicActivityInstanceList == null || historicActivityInstanceList.size() == 0) {
LOG.info("流程執行個體ID:{}沒有曆史節點資訊!", instanceId);
outPutImg(response, bpmnModel, null, null);
return;
}
// 已執行的節點ID集合(将historicActivityInstanceList中元素的activityId字段取出封裝到executedActivityIdList)
List<String> executedActivityIdList = historicActivityInstanceList.stream().map(item -> item.getActivityId()).collect(Collectors.toList());
// 擷取流程定義
ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService).getDeployedProcessDefinition(processInstance.getProcessDefinitionId());
//擷取流程線
List<String> flowIds = ActivitiUtils.getHighLightedFlows(bpmnModel, processDefinition, historicActivityInstanceList);
//輸出圖像
outPutImg(response, bpmnModel, flowIds, executedActivityIdList);
}
//展示模闆圖(根據流程定義key展示最新的模闆圖,此處也可以換為根據模闆key展示最新模闆圖)
public void showImgTemplate(String processDefinitonKey, HttpServletResponse response) {
if (StringUtils.isEmpty(processDefinitonKey)) return;
//根據key查詢最新的流程定義
List list = repositoryService.createProcessDefinitionQuery().processDefinitionKey(processDefinitonKey).latestVersion().list();
if(ListUtils.isEmpty(list)){
LOG.error(“流程定義Key:{}沒查詢到流程定義!”, processDefinitonKey);
return;
}
// 根據流程對象擷取流程對象模型
BpmnModel bpmnModel = repositoryService.getBpmnModel(list.get(0).getId());
//輸出圖像
outPutImg(response, bpmnModel, null, null);
}
//圖像輸出(圖像均為svg格式,activiti7如何指定圖像格式,還待完善)
private void outPutImg(HttpServletResponse response, BpmnModel bpmnModel, List flowIds, List executedActivityIdList) {
InputStream imageStream = null;
try {
if(null == flowIds && null ==executedActivityIdList){
imageStream = processDiagramGenerator.generateDiagram(bpmnModel,“宋體”, “微軟雅黑”, “黑體”);
}else{
imageStream = processDiagramGenerator.generateDiagram(bpmnModel, executedActivityIdList, flowIds,
“宋體”, “微軟雅黑”, “黑體”, true, “png”);
}
// 輸出資源内容到相應對象
byte[] b = new byte[1024];
int len;
while ((len = imageStream.read(b, 0, 1024)) != -1) {
response.getOutputStream().write(b, 0, len);
}
response.getOutputStream().flush();
response.setContentType(“image/png”);
} catch (Exception e) {
LOG.error(“流程圖輸出異常!”, e);
} finally { // 流關閉
if (null != imageStream) {
try {
imageStream.close();
} catch (IOException e) {
LOG.error(“流程圖輸入流關閉異常!”, e);
imageStream = null;
}
}
}
}
//查詢流程圖節點資訊(可根據節點的位置資訊,定位圖中每個節點位置。添加相應的前端事件,展示節點資訊。也可以根據其中callActiviti的節點,找到子流程的流程id或key,用于展示子流程圖)
public List getImgNode(String instanceId ) {
String instanceId = inst.getInstanceId();
LOG.info(“檢視完整流程圖!流程執行個體ID:{}”, instanceId);
HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(instanceId).singleResult();
if (processInstance == null) {
LOG.info(“流程執行個體ID:{}沒查詢到流程執行個體!”, instanceId);
result.setDetail(“activiti流程執行個體查詢為空”);
return result;
}
// 根據流程對象擷取流程對象模型
BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
List nodeList = getNodeByModel(bpmnModel,inst.getTemplateId(),inst,null);
return nodeList ;
}
//根據BpmnModel查詢補充節點資訊
public List getNodeByModel(BpmnModel bpmnModel,String templateId) {
List nodeList = new ArrayList<>();
List<org.activiti.bpmn.model.Process> ps = bpmnModel.getProcesses();
if (ps != null && ps.size() > 0) {
for (Process process : ps) {
Collection elements = process.getFlowElements();
if (elements != null && elements.size() > 0) {
for (FlowElement el : elements) {
try{
if (el instanceof UserTask) {
BpmImageNode bpmNode = new BpmImageNode();
bpmNode.setType(“UserTask”);
UserTask ut = (UserTask) el;
GraphicInfo artifactGraphicInfo = bpmnModel.getGraphicInfo(ut.getId());//id為baseElement的id
if (artifactGraphicInfo != null) {
bpmNode.setX(artifactGraphicInfo.getX());
bpmNode.setY(artifactGraphicInfo.getY());
bpmNode.setWidth(artifactGraphicInfo.getWidth());
bpmNode.setHeight(artifactGraphicInfo.getHeight());
}
//TODO 此處根據自己的需要完善邏輯
//可補充任務送出資訊,任務表單資訊等節點資訊
nodeList.add(bpmNode);
}else if(el instanceof CallActivity){
CallActivity ut = (CallActivity) el;
String processDefinitonKey = ((CallActivityBehavior)(ut.getBehavior())).getProcessDefinitonKey();
BpmImageNode bpmNode = new BpmImageNode();
bpmNode.setType(“CallActivity”);
List wfInstanceChildList = null;
//TODO WfInstanceChild是自己系統儲存的流程資訊,此處根據自己項目需要完善
if(ListUtils.isEmpty(wfInstanceChildList)){
//子流程未開始
bpmNode.setTemplateKey(processDefinitonKey);
}else{
//子流程已開始
List instanceIds = new ArrayList<>();
//TODO 此處可根據自己的項目來查詢子流程的Id
bpmNode.setInstanceIds(instanceIds);
}
GraphicInfo artifactGraphicInfo = bpmnModel.getGraphicInfo(ut.getId());//id為baseElement的id
if (artifactGraphicInfo != null) {
bpmNode.setX(artifactGraphicInfo.getX());
bpmNode.setY(artifactGraphicInfo.getY());
bpmNode.setWidth(artifactGraphicInfo.getWidth());
bpmNode.setHeight(artifactGraphicInfo.getHeight());
}
nodeList.add(bpmNode);
}
}catch(Exception e){
LOG.error(e.getMessage(),e);
}
}
}
}
}
return nodeList;
}