3. Process practice-integrating bpmn-js

1. bpmn-js

Download: https://bpmn.io/toolkit/bpmn-js/

The purpose of this article is not to write bpmn-js, but to directly copy a pre-made one as follows:

2. Business access address

http://localhost:8080/bpmnjs/dist/index.html?type=lookBpmn &instanceId=180001
& amp;deploymentFileUUID=8 & amp;deploymentName=qingjia.bpmn & amp;AssigneeName=zhangsan

3. The main logic code for JavaScript display is as follows:

//Example
https://blog.csdn.net/qq_35664308/article/details/110469247
//Set color
https://github.com/bpmn-io/bpmn-js-examples/tree/master/colors

$.ajax({<!-- -->
    //Get highlight
    url: publicurl + 'activitiHistory/gethighLine',
    type: 'GET',
    data: param1,
    dataType:'json',
    success: function (result) {<!-- -->
      //Get the color fill to ColorJson
      // [{"name": "xx usertask name",
      // "stroke":"gray",
      // "fill":"#eae9e9"}...]
      var ColorJson=tools.getByColor(result.obj)
        $.ajax({<!-- -->
            //Get process definition
            url: publicurl + 'processDefinition/getDefinitionXML',
            type: 'GET',
            data: param,
            dataType:'text',
            success: function (result) {<!-- -->
                var newXmlData = result
                tools.createDiagram(newXmlData, bpmnModeler, container);
                setTimeout(function () {<!-- -->
                    for (var i in ColorJson) {<!-- -->
                        //Set flow chart color
                        /**
                           var modeling = bpmnModeler.get('modeling');
                            var elementRegistry = bpmnModeler.get('elementRegistry')
                            var elementToColor = elementRegistry.get(json.name);
                            if(elementToColor){
                                modeling.setColor([elementToColor], {
                                    stroke: json.stroke,
                                    fill: json.fill
                                });
                            }
                        **/
                        tools.setColor(ColorJson[i],bpmnModeler)
                    }
                }, 200)
            },
            error: function (err) {<!-- -->
                console.log(err)
            }
        });
    },

task’s html color filling code

<rect x="0" y="0" width="85" height="55" rx="10" ry="10" style="stroke: green; stroke-width: 2px; fill: yellow; fill-opacity: 0.95;"></rect>

4. Java interface implementation, according to the business execution path, query the history table act_hi_procinst, node-node connection, node mark and mark node are currently passed to the executor.

/**
 *index.js
 * AssigneeName parameter is the handler
 * deploymentName act_ge_bytearray table name field xml name
 * deploymentFileUUID ID of the act_re_deployment table
 * instanceId instance ID
 *
 * http://localhost:8080/bpmnjs/dist/index.html?type=lookBpmn & amp;instanceId=10823123-92ac-11eb-9909-dc7196b7d4a6 & amp;deploymentFileUUID=z3d6aeda-91d0-11eb-95aa-dc7196b7d4a6 & amp ;deploymentName=springboot02.bpmn & amp;AssigneeName=salaboy
 */

@RestController
@RequestMapping("/activitiHistory")
public class ActivitiHistoryController {<!-- -->


    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private HistoryService historyService;

    //Get process definition XML
    @GetMapping(value = "/getDefinitionXML")
    public void getProcessDefineXML(HttpServletResponse response,
                                    @RequestParam("deploymentId") String deploymentId,
                                    @RequestParam("resourceName") String resourceName) {<!-- -->



        try {<!-- -->
            InputStream inputStream = repositoryService.getResourceAsStream(deploymentId,resourceName);
            int count = inputStream.available();
            byte[] bytes = new byte[count];
            response.setContentType("text/xml");
            OutputStream outputStream = response.getOutputStream();
            while (inputStream.read(bytes) != -1) {<!-- -->
                outputStream.write(bytes);
            }
            inputStream.close();
        } catch (Exception e) {<!-- -->
            e.toString();
        }
    }


    //task instance history
    @GetMapping(value = "/getInstancesByPiID")
    public AjaxResponse getInstancesByPiID(@RequestParam("piID") String piID) {<!-- -->
        try {<!-- -->

            //------------------------------------------------another way of writing --------------------------
            List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery()
                    .orderByHistoricTaskInstanceEndTime().asc()
                    .processInstanceId(piID)
                    .list();

            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(),
                    GlobalConfig.ResponseCode.SUCCESS.getDesc(), historicTaskInstances);
        } catch (Exception e) {<!-- -->
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(),
                    "Failed to obtain historical task", e.toString());
        }

    }



    //Flowchart highlight
    @GetMapping("/gethighLine")
    public AjaxResponse gethighLine(@RequestParam("instanceId") String instanceId, String AssigneeName) {<!-- -->
        try {<!-- -->
            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
                    .processInstanceId(instanceId).singleResult();
            //Get bpmnModel object
            BpmnModel bpmnModel = repositoryService.getBpmnModel(historicProcessInstance.getProcessDefinitionId());
            //Because we only define one Process here, just get the first one in the collection
            Process process = bpmnModel.getProcesses().get(0);
            //Get all FlowElement information
            Collection<FlowElement> flowElements = process.getFlowElements();

            Map<String, String> map = new HashMap<>();
            for (FlowElement flowElement : flowElements) {<!-- -->
                //Determine whether it is connected
                if (flowElement instanceof SequenceFlow) {<!-- -->
                    SequenceFlow sequenceFlow = (SequenceFlow) flowElement;
                    String ref = sequenceFlow.getSourceRef();
                    String targetRef = sequenceFlow.getTargetRef();
                    map.put(ref + targetRef, sequenceFlow.getId());
                }
            }

            //Get process instance historical nodes (all)
            List<HistoricActivityInstance> list1 = historyService.createHistoricActivityInstanceQuery()
                    .processInstanceId(instanceId)
                    .list();
            //Remove delete reason data. Currently, there is no problem with jump, but there is a problem with execution.
            List<HistoricActivityInstance> list= new ArrayList<>();
            for (HistoricActivityInstance h:list1) {<!-- -->
                if(StringUtils.isBlank(h.getDeleteReason())){<!-- -->
                    list.add(h);
                }
            }


            //Pairwise combination key of each historical node
            Set<String> keyList = new HashSet<>();
            for (HistoricActivityInstance i : list) {<!-- -->
                for (HistoricActivityInstance j : list) {<!-- -->
                    if (i != j) {<!-- -->
                        keyList.add(i.getActivityId() + j.getActivityId());
                    }
                }
            }
            //Highlight connection ID
            Set<String> highLine = new HashSet<>();
            keyList.forEach(s -> highLine.add(map.get(s)));


            //Get process instance historical node (completed)
            List<HistoricActivityInstance> listFinished = historyService.createHistoricActivityInstanceQuery()
                    .processInstanceId(instanceId)
                    .finished()
                    .list();
            //Highlight node ID
            Set<String> highPoint = new HashSet<>();
            listFinished.forEach(s -> highPoint.add(s.getActivityId()));

            //Get process instance historical node (to-do node)
            List<HistoricActivityInstance> listUnFinished = historyService.createHistoricActivityInstanceQuery()
                    .processInstanceId(instanceId)
                    .unfinished()
                    .list();

            //Highlighted connections that need to be removed
            Set<String> set = new HashSet<>();
            //To-do highlighted node
            Set<String> waitingToDo = new HashSet<>();
            listUnFinished.forEach(s -> {<!-- -->
                waitingToDo.add(s.getActivityId());

                for (FlowElement flowElement : flowElements) {<!-- -->
                    //Determine whether it is a user node
                    if (flowElement instanceof UserTask) {<!-- -->
                        UserTask userTask = (UserTask) flowElement;

                        if (userTask.getId().equals(s.getActivityId())) {<!-- -->
                            List<SequenceFlow> outgoingFlows = userTask.getOutgoingFlows();
                            //Because the highlighted connection query is all nodes combined in pairs, and the connections sent out after the to-do node are also included, so the connections immediately after the highlighted to-do node must be removed.
                            if (outgoingFlows != null & amp; & amp; outgoingFlows.size() > 0) {<!-- -->
                                outgoingFlows.forEach(a -> {<!-- -->
                                    if (a.getSourceRef().equals(s.getActivityId())) {<!-- -->
                                        set.add(a.getId());
                                    }
                                });
                            }
                        }
                    }
                }
            });

            highLine.removeAll(set);


            //Get the current user
            //User sysUser = getSysUser();
            Set<String> iDo = new HashSet<>(); //Save and highlight my management node
            //Tasks completed by the current user
            List<HistoricTaskInstance> taskInstanceList = historyService.createHistoricTaskInstanceQuery()
                    .taskAssignee(AssigneeName)
                    .finished()
                    .processInstanceId(instanceId).list();

            taskInstanceList.forEach(a -> iDo.add(a.getTaskDefinitionKey()));

            Map<String, Object> reMap = new HashMap<>();
            reMap.put("highPoint", highPoint);
            reMap.put("highLine", highLine);
            reMap.put("waitingToDo", waitingToDo);
            reMap.put("iDo", iDo);

            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(),
                    GlobalConfig.ResponseCode.SUCCESS.getDesc(), reMap);

        } catch (Exception e) {<!-- -->
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(),
                    "Rendering history process failed", e.toString());
        }
    }


}