获取到当前工序的流程图
通过processId获取各节点信息,包括变量及签核用户信息
后端数据整理
@GetMapping("/getHisBpmn")
public List<Map<String, Object>> getHisBpmn(@RequestParam("processId") String processId) {
List<Map<String, Object>> listMap = new ArrayList<>();
List<HistoricProcessInstance> list = historyService
.createHistoricProcessInstanceQuery()
.processInstanceId(processId)
.orderByProcessInstanceEndTime()
.desc()
.list();
List<HistoricTaskInstance> taskInstances = historyService
.createHistoricTaskInstanceQuery()
.processInstanceId(processId)
.orderByHistoricTaskInstanceEndTime()
.asc()
.list();
List<HistoricVariableInstance> variableInstances = historyService
.createHistoricVariableInstanceQuery()
.processInstanceId(processId)
.list();
List<HistoricActivityInstance> activityInstances = historyService
.createHistoricActivityInstanceQuery()
.processInstanceId(processId)
.orderByHistoricActivityInstanceEndTime()
.desc()
.list();
BpmnModel bpmnModel = repositoryService.getBpmnModel(taskInstances.get(0).getProcessDefinitionId());
List<Process> listProcess = bpmnModel.getProcesses();
List<UserTask> datas = new ArrayList<>();
listProcess.stream().forEach(item -> {
List<UserTask> type = item.findFlowElementsOfType(UserTask.class);
datas.addAll(type);
});
datas.stream().forEach(item -> {
Map<String, Object> map = new HashMap<>();
GraphicInfo info = bpmnModel.getGraphicInfo(item.getId());
map.put("x", info.getX());
map.put("y", info.getY());
map.put("xOffset", info.getWidth());
map.put("yOffset", info.getHeight());
taskInstances.stream().forEach(items -> {
if (items.getTaskDefinitionKey().equals(item.getId())) {
System.out.println(items);
map.put("approver", items.getAssignee());
map.put("taskId", items.getId());
map.put("approver_node", items.getName());
Map<String, Object> variableMap = new HashMap<>();
variableInstances.stream().forEach(itemVar -> {
if (itemVar.getVariableName().indexOf(items.getId()) != -1) {
variableMap.put(itemVar.getVariableName(),itemVar.getValue());
}
});
map.put("variable",variableMap);
}
});
listMap.add(map);
});
return listMap;
}
前端代码编写及获取任务节点信息
下载layui相关JS CSS文件
代码编写获取流程图及节点信息
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>社区疫情管理系统</title>
<link rel="stylesheet" href="/layui/css/layui.css">
<script src="/jquery-3.3.1.min.js"></script>
<script src="/layui/layui.js"></script>
</head>
<body id="login">
<div class="login">
<h2>社区疫情管理系统</h2>
<form class="layui-form" method="post" onsubmit="return false">
<div class="layui-form-item">
<input type="username" name="username" placeholder="用户名(随意输入)" required lay-verify="required" class="layui-input">
<i class="layui-icon input-icon"></i>
</div>
<div class="layui-form-item">
<input type="password" name="password" placeholder="密码(随意输入)" required lay-verify="required" class="layui-input">
<i class="layui-icon input-icon"></i>
</div>
<div class="layui-form-item">
<input type="checkbox" name="box" lay-skin="primary" title="记住密码" checked="">
<a class="back" href="javascript:;" style="margin-top: 10px;" id="register">立即注册</a>
<a class="back" href="javascript:;" style="margin-top: 10px;margin-right: 10px" id="forgotPassword">忘记密码</a>
</div>
<div class="layui-form-item">
<button style="width: 100%" class="layui-btn" lay-submit lay-filter="login">立即登录</button>
</div>
</form>
</div>
</body>
<script type="text/javascript">
layui.use(['form', 'layer', 'table', 'laytpl', 'laydate'], function () {
var form = layui.form,
layer = parent.layer === undefined ? layui.layer : top.layer,
$ = layui.jquery,
laytpl = layui.laytpl,
table = layui.table;
let bpmnData = [];
$.ajax({
url:'/flower/getHisBpmn',
type:'GET',
async: false,
data:{processId:'88354a82-6c5f-11ed-86a0-98eecb9c046b'},
success:function (res) {
bpmnData = res;
}
})
form.on('submit(login)', function (data) {
var hh = '';
var index = layui.layer.open({
fix: false, //不固定
maxmin: true,
shadeClose: true,
area: ['958px', '365px'],
title: "流程图",
type: 1,
content: '<img src="http://localhost:8888/flower/genProcessDiagram?processInstanceId=88354a82-6c5f-11ed-86a0-98eecb9c046b" />',
success: function (layero, index) {
console.log(layero)
console.log(index)
// layero.on('mousemove', function(e){
layero.on('click', function(e){
let x = e.offsetX
let y = e.offsetY
let status = 0
let bpmnDataParam = {};
for (var i = 0; i < bpmnData.length; i++) {
let xMin = bpmnData[i].x
let xMax = bpmnData[i].x + bpmnData[i].xOffset
let yMin = bpmnData[i].y
let yMax = bpmnData[i].y + bpmnData[i].yOffset
if((xMin < x && x < xMax) && (yMin < y && y < yMax)){
status = 1
bpmnDataParam = bpmnData[i];
}
}
if(status != 0){
console.log()
showTrip(hh,x,y,this,bpmnDataParam)
}
})
}
})
return false;
});
function showTrip(hh,x,y,that,bpmnDataParam) {
console.log(bpmnDataParam)
let flag = true;
for (let key in bpmnDataParam.variable){
if(key.indexOf(':code') != -1){
flag = false
}
}
let messageDiv = '';
if(flag){
messageDiv = '任务ID:' + bpmnDataParam['taskId'] + '<br>\n'+
'请假天数:' + bpmnDataParam['variable'][bpmnDataParam['taskId'] + ':dayNumber'] + '<br>\n'+
'备注:' + bpmnDataParam['variable'][bpmnDataParam['taskId'] + ':message'] + '<br>\n'+
'描述:' + bpmnDataParam['variable'][bpmnDataParam['taskId'] + ':remark'] + '<br>\n';
}else {
messageDiv = '任务ID:' + bpmnDataParam['taskId'] + '<br>\n'+
'驳回原因:' + bpmnDataParam['variable'][bpmnDataParam['taskId'] + ':message'] + '<br>\n'
}
let showDiv = ' \n' +
'<div class="layui-bg-gray" style="padding: 10px">\n' +
' <div class="layui-row layui-col-space15">\n' +
' <div class="layui-col-md12">\n' +
' <div class="layui-card">\n' +
' <div class="layui-card-header">当前节点:' + bpmnDataParam.approver_node + '</div>\n' +
' <div class="layui-card-body">\n' +
messageDiv +
' </div>\n' +
' </div>\n' +
' </div>\n' +
'</div> ';
hh = layer.tips(showDiv, that, {
area: ['330px', 'auto'],
tips: [1, '#9c9c9c'],//显示方向以及背景颜色(1.上 2右 3下 4左)
time: 4000,//4秒后销毁
success:function (layeroI,index) {
console.log( )
let yL = parseInt(layeroI.css("top").replaceAll("px",""));
let lL = parseInt(layeroI.css("left").replaceAll("px",""));
layeroI.css("top",(yL + y)+"px")
layeroI.css("left",(lL + x)+"px")
}
});
}
})
</script>
</html>
前端页面呈现效果