1、依赖
<dependency><groupId>com.ikaiyong.score</groupId><artifactId>score-spring-boot-starter-flowable</artifactId></dependency>
2、流程部署相关
如下建立对应文件和文件夹
2.1 流程部署
/*** 部署流程* @param name*/@GetMapping("/deployPc")public CommonResult<String> deployPc(@NotBlank(message = "流程部署文件不能为空") String name) {String id = myProcessService.deployPc(name);// String id = myProcessService.deployPc("process/mjAddi.bpmn20.xml");return CommonResult.success(id);}
2.2 部署流程列表查询
// 根据名字查流程定义列表,不传则查所有
public List<MyProcessDefinitionVo> processDefList(String procName) {ProcessDefinitionQuery pdq = repositoryService.createProcessDefinitionQuery();if(StringUtils.isNotBlank(procName)) {pdq.processDefinitionName(procName);}List<ProcessDefinition> pdList = pdq.active().latestVersion().list();return beanUtils.copyList(pdList, MyProcessDefinitionVo.class);}
3、流程实例
3.1 发起流程
要点一个是可以指定发起人,二是将processId和自定义表单绑定
@Transactional(rollbackFor = Exception.class)public String startMjProc(PoliceAddiscoreFlowVo policeAddiscoreFlowVo) {// 发起流程// 指定发起人identityService.setAuthenticatedUserId(policeAddiscoreFlowVo.getPoliceNum());Map<String, Object> var = new HashMap<>();var.put("mjNum", policeAddiscoreFlowVo.getPoliceNum());String procInsId = runtimeService.startProcessInstanceById(policeAddiscoreFlowVo.getProcessId(), var).getId();policeAddiscoreFlowVo.setProcessId(procInsId);// 保存表单policeAddiscoreFlowVo.setId(IdUtil.fastUUID());policeAddiscoreFlowVo.setState(ApproveStateEnum.APVING.getValue());policeAddiscoreFlowVo.setCreateTime(new Date());TPoliceAddiscoreFlow addiscoreFlow = new TPoliceAddiscoreFlow();BeanUtils.copyProperties(policeAddiscoreFlowVo, addiscoreFlow);addiscoreFlow.setId(IdUtil.fastUUID());tPoliceAddiscoreFlowMapper.insert(addiscoreFlow);}
3.2 审批
可以有参数一起传入,也可以没有,具体看API就行
taskService.complete(task.getId(), variables);
3.3 候选人认领
// 认领任务
taskService.claim(approveVo.getTaskId(), approveVo.getPoliceNum());
3.4 删除/撤销任务
需要添加删除原因,在查询时可以查到
runtimeService.deleteProcessInstance(processId, deleteReason);
3.5回退
回退操作需要用到activityId,所以回退前要先查询这个id
@Transactional(rollbackFor = Exception.class)public void backProc(PoliceAddiscoreFlowVo policeAddiscoreFlowVo) {String processId = policeAddiscoreFlowVo.getProcessId();Execution actExecution = runtimeService.createExecutionQuery().processInstanceId(processId).list().get(0);HistoricActivityInstance hisActIns = historyService.createHistoricActivityInstanceQuery().processInstanceId(processId).taskAssignee(policeAddiscoreFlowVo.getPoliceNum()).orderByHistoricActivityInstanceStartTime().desc().list().get(0);runtimeService.createChangeActivityStateBuilder().processInstanceId(processId).moveActivityIdTo(actExecution.getActivityId(), hisActIns.getActivityId()).changeState();}
回退相对比较复杂,重点记录一下
1.串行路线上的退回:流程中没有任何网关(排他网关/并行网关)和会签多实例。
2.退回到并行网关分支中的某一个节点上:
3.并行网关中的某一个分支节点上发起退回,退回到并行网关前面的某一个节点上
4.子流程中退回到主干流程中某一个节点/主干流程退回到子流程中某一个节点。
如下图:
1.普通串行路线上的退回(此流程中没有并行网关的退回时),此方法支持普通串行节点/会签多实例节点/排他网关节点:
runtimeService.createChangeActivityStateBuilder()
.processInstanceId(proInstanceId)
.moveActivityIdsToSingleActivityId(curTaskKeys, targetTaskKey)
.changeState();
或者
moveActivityIdTo(String currentActivityId,String newActivityId);
2.并行网关中发起退回(即撤销当前的网关),这个地方不能用
moveActivityIdTo(String currentActivityId,String newActivityId);
是因为当某一个分支完成,它的is_active为0,另一条分支没有完成时。这时候这个方法是取不到所的分支的key的,它只有is_active为1的key能取到,不然就会造成多一条垃圾数据,同时再走并行时,任何一个分支不会等另一个分支就完走到分支的合并节点上,这就是bug,所以要改为以下方法:
// 并行网关的退回
List currentExecutionIds = new ArrayList<>();
List executions = runtimeService.createExecutionQuery().parentId(proInstanceId).list();
for (Execution execution : executions) {
System.out.println("并行网关节点数:"+execution.getActivityId());
currentExecutionIds.add(execution.getId());
}
runtimeService.createChangeActivityStateBuilder()
.moveExecutionsToSingleActivityId(currentExecutionIds, targetTaskKey)
.changeState();
3.退回到并行网关中的某一个节点:经试验退回时必须同时退回并行网关中的所有分支。
List targetTaskKeys = new ArrayList<>();
targetTaskKeys.add("sid-CA74ADED-7E70-451D-951C-95988BFC3F07");
targetTaskKeys.add("sid-7922C598-74FD-4848-95AC-D9790AF68432");runtimeService.createChangeActivityStateBuilder()
.processInstanceId(proInstanceId)
.moveSingleActivityIdToActivityIds("sid-CAD50E6F-7E0C-437D-816B-DDBA1A976A79", targetTaskKeys)
.changeState();
4.主干流程和子流程的退回(没有试验过),官方提供了以下方法:
moveActivityIdToParentActivityId(String currentActivityId, String newActivityId)moveActivityIdToSubProcessInstanceActivityId(String currentActivityId, String newActivityId, String callActivityId)
3.6 根据流程id查询所有节点
List<HistoricTaskInstance> res = historyService.createHistoricTaskInstanceQuery().processInstanceId(processInsId).includeProcessVariables().orderByHistoricTaskInstanceStartTime().asc().list();
3.7 查询我申请的列表
List<HistoricProcessInstance> res = historyService.createHistoricProcessInstanceQuery().startedBy(userId).orderByProcessInstanceStartTime().desc().list();
3.8 查询我的待办
List<Task> tasks = taskService.createTaskQuery().active().taskCandidateOrAssigned(searchForm.getUserId()).orderByTaskCreateTime().desc().list();
3.9 查询我的已办
List<HistoricTaskInstance> res = historyService.createHistoricTaskInstanceQuery().taskAssignee(searchForm.getUserId()).finished().orderByHistoricTaskInstanceEndTime().desc().list();