此bpmn文件为代码创建流程
org.activiti
activiti-spring-boot-starter
7.1.0.M6
org.springframework.boot
spring-boot-starter-security
#默认为true,表不存在生成表
spring.activiti.database-schema-update=true
#历史记录
spring.activiti.db-history-used=true
#历史记录级别,这是最高
spring.activiti.history-level=full
#关闭重复生成不同版本号的数据
spring.activiti.deployment-mode=never-fail
不排除访问会跳转到登录,用户是:user,密码如下图,启动项目时生成
@SpringBootApplication(
exclude = {org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class,
org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration.class}
)
package net.test.springbootweb.workflow;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.*;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
/**
* Desc:CreateWorkFlow
* Date:2021/12/6
*
* @author author
*/
@RestController
@RequestMapping("workFlow")
public class CreateWorkFlow {
@Autowired
private RepositoryService repositoryService;
@Autowired
private RuntimeService runtimeService;
@Autowired
private TaskService taskService;
public static final String BASE_CHAR = "abcdefghijklmnopqrstuvwxyz";
/**
* 创建流程定义
*
* @param flowName 流程名称
* @param auditType 审批类型:会签AND、或签OR、依次审批IN
* @param flowNodeDef 审批节点数量
* @return
*/
@PostMapping("createWorkFlow")
public String createWorkFlow(String flowName, String auditType, int flowNodeDef) {
Process process = new Process();
//流程定义id,此处加上随机一个小写字母,是因为uuid如果以数字开头,会报错
String processKey = RandomUtil.randomString(BASE_CHAR, 1) + IdUtil.fastSimpleUUID();
process.setId(processKey);
process.setName(flowName);
//设置开始节点
StartEvent startEvent = new StartEvent();
startEvent.setId("start");
process.addFlowElement(startEvent);
//生成流程引擎节点任务
int taskId;
for (taskId = 0; taskId < flowNodeDef; taskId++) {
String taskKey = "task" + taskId;
String assignee = "user" + taskId;
String inputDataItem = "userList" + taskId;
String completionCondition = "";
if ("AND".equalsIgnoreCase(auditType)) {
completionCondition = "${nrOfCompletedInstances/nrOfInstances == 1}";//会签
} else if ("OR".equalsIgnoreCase(auditType)) {
completionCondition = "${nrOfCompletedInstances == 1}";//或签
} else if ("".equalsIgnoreCase(auditType) || null == auditType) {
completionCondition = "${nrOfCompletedInstances/nrOfInstances >= 0.6}";//按一定比例通过
}
//设置任务节点
UserTask userTask = new UserTask();
userTask.setId(taskKey);
String name = IdUtil.fastSimpleUUID();//可以与自己的节点ID关联起来
userTask.setName(name);
userTask.setAssignee("${" + assignee + "}");
MultiInstanceLoopCharacteristics loopCharacteristics = new MultiInstanceLoopCharacteristics();
loopCharacteristics.setSequential("IN".equalsIgnoreCase(auditType));//依次审批
loopCharacteristics.setElementVariable(assignee);
loopCharacteristics.setInputDataItem("${" + inputDataItem + "}");
loopCharacteristics.setCompletionCondition(completionCondition);
userTask.setLoopCharacteristics(loopCharacteristics);
process.addFlowElement(userTask);
//设置网关判断条件
ExclusiveGateway exclusiveGateway = new ExclusiveGateway();
exclusiveGateway.setId("createExclusiveGateway" + taskId);
process.addFlowElement(exclusiveGateway);
}
//设置结束节点
EndEvent endEvent = new EndEvent();
endEvent.setId("end");
process.addFlowElement(endEvent);
//设置节点之间的连线
SequenceFlow sequenceFlow = new SequenceFlow();
sequenceFlow.setSourceRef("start");
sequenceFlow.setTargetRef(taskId > 0 ? "task0" : "end");//大于一个节点
process.addFlowElement(sequenceFlow);
String refuseCondition = "${approve==false}";//自定义
String approveCondition = "${approve==true}";
for (int i = 0; i < taskId; i++) {
//节点之间的连线
String gatewayVar = "createExclusiveGateway" + i;
SequenceFlow flow = new SequenceFlow();
flow.setSourceRef("task" + i);
flow.setTargetRef(gatewayVar);
process.addFlowElement(flow);
//不通过节点
SequenceFlow noFlow = new SequenceFlow();
noFlow.setSourceRef(gatewayVar);
noFlow.setTargetRef("end");
noFlow.setName("不通过");
noFlow.setConditionExpression(refuseCondition);
process.addFlowElement(noFlow);
//通过的节点
SequenceFlow yesFlow = new SequenceFlow();
yesFlow.setSourceRef(gatewayVar);
yesFlow.setTargetRef(taskId == (i + 1) ? "end" : "task" + (i + 1));
yesFlow.setName("通过");
yesFlow.setConditionExpression(approveCondition);
process.addFlowElement(yesFlow);
}
//创建一个bpmnModel对象,添加process
BpmnModel bpmnModel = new BpmnModel();
bpmnModel.addProcess(process);
//将bpmnModel 转化为xml 测试展示
BpmnXMLConverter bpmnXMLConverter = new BpmnXMLConverter();
byte[] convertToXML = bpmnXMLConverter.convertToXML(bpmnModel);
try {
String localPath = System.getProperty("user.dir") + File.separator + flowName + ".bpmn";
FileUtils.writeByteArrayToFile(new File(localPath), convertToXML);
} catch (IOException e) {
e.printStackTrace();
}
//部署流程
repositoryService.createDeployment().addBpmnModel(processKey + ".bpmn", bpmnModel).name(flowName).deploy();
return processKey;
}
/**
* 开启流程实例
*
* @param users 用户List,如:man1:man2:man3,woman1:woman2,mange1
* @param processKey 流程定义key
* @param businessKey 业务关联key
* @return
*/
@PostMapping("startWorkFlow")
public String startWorkFlow(String users, String processKey, String businessKey) {
List userList = Arrays.asList(users.split(","));
HashMap map = new HashMap<>();
for (int i = 0; i < userList.size(); i++) {
map.put("userList" + i, Arrays.asList(userList.get(i).split(":")));
}
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processKey, businessKey, map);
return processInstance.getId();//实例ID,可保存在业务流程字段中,方便使用
}
/**
* 审批流程
*
* @param user 用户
* @param businessKey 业务关联key
* @param isApproved 是否通过
* @return
*/
@PostMapping("approveTask")
public String approveTask(String user, String businessKey, boolean isApproved) {
List tasks = taskService.createTaskQuery().processInstanceBusinessKey(businessKey).taskAssignee(user).list();
if (CollUtil.isNotEmpty(tasks)) {
Task task = tasks.get(0);
HashMap map = new HashMap<>();
map.put("approve", isApproved);
taskService.complete(task.getId(), map);
if (!isApproved) {
List list = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).list();
if (CollUtil.isNotEmpty(list)) {
ProcessInstance processInstance = list.get(0);
runtimeService.deleteProcessInstance(processInstance.getId(), "已拒绝");
return "process instance finished";
}
} else {
List list = taskService.createTaskQuery().processInstanceBusinessKey(businessKey).list();
if (CollUtil.isEmpty(list)) {
return "completed";
}
}
return "execution succeed";
}
return "Task not found";
}
}
package net.test.springbootweb.workflow;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricProcessInstanceQuery;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
* Desc:QueryWorkFlow
* Date:2021/12/8
*
* @author author
*/
@RestController
@RequestMapping("workFlow")
public class QueryWorkFlow {
@Autowired
private ProcessEngine processEngine;
/**
* 获取部署的流程定义
*
* @return
*/
@PostMapping("getWorkFlowList")
public String getWorkFlowList() {
RepositoryService repositoryService = processEngine.getRepositoryService();
List list = repositoryService.createProcessDefinitionQuery().list();
JSONArray array = new JSONArray();
for (ProcessDefinition processDefinition : list) {
JSONObject object = new JSONObject();
object.put("定义ID", processDefinition.getId());
object.put("定义名称", processDefinition.getName());
object.put("定义KEY", processDefinition.getKey());
object.put("部署ID", processDefinition.getDeploymentId());
array.add(object);
}
return JSONArray.toJSONString(array, SerializerFeature.WriteMapNullValue);
}
/**
* 根据定义key获取开启的实例
*
* @param processKey 流程定义key
* @return
*/
@PostMapping("getProcessInstanceList")
public String getProcessInstanceList(String processKey) {
HistoricProcessInstanceQuery query = processEngine.getHistoryService().createHistoricProcessInstanceQuery().processDefinitionKey(processKey);
List list = query.list();//所有实例
List finished = query.finished().list();//已完成的实例
RuntimeService runtimeService = processEngine.getRuntimeService();
List runInstance = runtimeService.createProcessInstanceQuery().processDefinitionKey(processKey).list();//正在进行中的实例
JSONArray array = new JSONArray();
for (HistoricProcessInstance historicProcessInstance : list) {
JSONObject object = new JSONObject();
object.put("实例ID", historicProcessInstance.getId());
object.put("实例名称", historicProcessInstance.getName());
object.put("业务KEY", historicProcessInstance.getBusinessKey());
object.put("删除原因", historicProcessInstance.getDeleteReason());
object.put("开始时间", historicProcessInstance.getStartTime());
object.put("结束时间", historicProcessInstance.getEndTime());
array.add(object);
}
return JSONArray.toJSONString(array, SerializerFeature.WriteMapNullValue);
}
/**
* 根据用户获取任务列表
*
* @param user
* @return
*/
@PostMapping("getCurtTaskByUser")
public String getCurtTaskByUser(String user) {
TaskService taskService = processEngine.getTaskService();
List list = taskService.createTaskQuery().taskAssignee(user).list();
JSONArray array = new JSONArray();
for (Task task : list) {
JSONObject object = new JSONObject();
object.put("任务ID", task.getId());
object.put("任务名称", task.getName());
object.put("业务KEY", task.getBusinessKey());
object.put("定义ID", task.getProcessDefinitionId());
object.put("过程实例ID", task.getProcessInstanceId());
array.add(object);
}
return JSONArray.toJSONString(array, SerializerFeature.WriteMapNullValue);
}
/**
* 获取用户的历史任务
*
* @param user
* @return
*/
@PostMapping("getHistoryTaskByUser")
public String getHistoryTaskByUser(String user) {
HistoryService historyService = processEngine.getHistoryService();
List list = historyService.createHistoricTaskInstanceQuery().taskAssignee(user).finished().list();
JSONArray array = new JSONArray();
//用户的所有的流程实例
Set instanceIds = list.stream().map(HistoricTaskInstance::getProcessInstanceId).collect(Collectors.toSet());
if (CollUtil.isNotEmpty(instanceIds)) {
Map instanceMap = historyService.createHistoricProcessInstanceQuery().processInstanceIds(instanceIds).list()
.stream().collect(Collectors.toMap(HistoricProcessInstance::getId, HistoricProcessInstance::getBusinessKey));
for (HistoricTaskInstance historicTaskInstance : list) {
JSONObject object = new JSONObject();
object.put("历史任务ID", historicTaskInstance.getId());
object.put("历史任务名称", historicTaskInstance.getName());
object.put("实例开始时间", historicTaskInstance.getStartTime());
object.put("实例结束时间", historicTaskInstance.getEndTime());
object.put("流程持续时间", historicTaskInstance.getDurationInMillis());
object.put("历史业务KEY", instanceMap.get(historicTaskInstance.getProcessInstanceId()));
array.add(object);
}
}
return JSONArray.toJSONString(array, SerializerFeature.WriteMapNullValue);
}
}