Activiti6.8 流程刪除和任務(wù)撤回實(shí)現(xiàn)方法
當(dāng)前使用的BPM引擎為Activiti6.0,客戶(hù)需求是流程發(fā)起人能將整個(gè)流程撤銷(xiāo),對(duì)于某個(gè)流程節(jié)點(diǎn),辦理人可以撤回已經(jīng)辦理的任務(wù),同時(shí)前提是該任務(wù)節(jié)點(diǎn)的下個(gè)節(jié)點(diǎn)未被辦理。
1、流程刪除
首先說(shuō)下發(fā)起人對(duì)整個(gè)流程的撤銷(xiāo),直接刪除流程,傳入流程實(shí)例ID,結(jié)束一個(gè)流程。執(zhí)行此方法后,流程實(shí)例的當(dāng)前任務(wù)act_ru_task會(huì)被刪除,流程歷史act_hi_taskinst不會(huì)被刪除,并且流程歷史的狀態(tài)置為finished完成。
runtimeService.deleteProcessInstance(instanceId, deleteReason);
2、任務(wù)撤回
已執(zhí)行任務(wù)的撤回操作相對(duì)來(lái)說(shuō)復(fù)雜些,這里先分步驟說(shuō)下總體思路:
1)選擇一條已辦理任務(wù),根據(jù)該任務(wù)查詢(xún)出任務(wù)ID =myTaskId和流程實(shí)例ID=processInstanceId;
2)根據(jù)processInstanceId判斷當(dāng)前流程是否已結(jié)束或已掛起,流程結(jié)束或掛起則無(wú)法執(zhí)行撤回操作;
3)根據(jù)myTaskId查詢(xún)選擇任務(wù)的歷史任務(wù)實(shí)例historicTaskInstance,進(jìn)而查詢(xún)出對(duì)應(yīng)歷史活動(dòng)實(shí)例historicActivityInstance,最終得到活動(dòng)標(biāo)識(shí)myActivityId;
4)根據(jù)活動(dòng)標(biāo)識(shí)myActivityId獲取該任務(wù)對(duì)應(yīng)的FlowNode對(duì)象myFlowNode;
5)查詢(xún)出該任務(wù)節(jié)點(diǎn)的所有下一任務(wù)節(jié)點(diǎn)flowElementList,此處是任務(wù)節(jié)點(diǎn)Task,排查其它類(lèi)型活動(dòng)節(jié)點(diǎn);
6)判斷flowElementList中是否有代辦事項(xiàng),如果有則可以執(zhí)行撤回操作,否則表示該任務(wù)的所有下一任務(wù)都執(zhí)行完畢,此時(shí)不允許再執(zhí)行撤回操作;
7)對(duì)下一節(jié)點(diǎn)代辦任務(wù),同樣查詢(xún)出對(duì)應(yīng)的FlowNode對(duì)象flowNode;
8)借助FlowNode對(duì)象myFlowNode和flowNode,反方向執(zhí)行一次任務(wù),即從代辦任務(wù)節(jié)點(diǎn)反方向流轉(zhuǎn)到當(dāng)前任務(wù)節(jié)點(diǎn),從而完成了任務(wù)撤回操作。
完整代碼如下:
public Result cancelTask(ActivitiTask doneTask) {
try {
// doneTask為封裝的Task對(duì)象
String processInstanceId = doneTask.getInstanceId();
String myTaskId = doneTask.getTaskId();
// 校驗(yàn)流程是否結(jié)束
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
.processInstanceId(processInstanceId).active()
.singleResult();
if(processInstance == null) {
return Result.error("流程已結(jié)束或已掛起,無(wú)法執(zhí)行撤回操作");
}
// 當(dāng)前任務(wù)
HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().taskId(myTaskId)
.processInstanceId(processInstanceId).singleResult();
if(historicTaskInstance==null) {
? ? return Result.error("當(dāng)前任務(wù)不存在,無(wú)法撤回");
}
String myActivityId = null;
List<HistoricActivityInstance> actInstList =
historyService.createHistoricActivityInstanceQuery()
.executionId(historicTaskInstance.getExecutionId())
.finished().list();
for(HistoricActivityInstance hai : actInstList) {
? ? if(myTaskId.equals(hai.getTaskId())) {
myActivityId = hai.getActivityId();
break;
? ? }
}
BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
FlowNode myFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(myActivityId);
// 獲取所有下一任務(wù)節(jié)點(diǎn)的標(biāo)識(shí)ID
Map<String, String> taskKeyMap = Maps.newHashMap();
// 獲取所有下一任務(wù)節(jié)點(diǎn)對(duì)應(yīng)的FlowElement
List<FlowElement> flowElementList = getOutgoingTask(bpmnModel, myActivityId);
for(FlowElement flowElement : flowElementList) {
String eleId = flowElement.getId();
taskKeyMap.put(eleId, eleId);
}
// 獲取當(dāng)前流程代辦事項(xiàng),沒(méi)有代辦事項(xiàng)表明流程結(jié)束或已掛起
List<Task> alltaskList = taskService.createTaskQuery().processInstanceId(processInstanceId).list();
if(alltaskList.size() <= 0) {
return Result.error("流程已結(jié)束或已掛起,無(wú)法執(zhí)行撤回操作");
}
// 判斷所有下一任務(wù)節(jié)點(diǎn)中是否有代辦任務(wù),沒(méi)有則表示任務(wù)已辦理或已撤回,此時(shí)無(wú)法再執(zhí)行撤回操作
List<Task> nextTaskList = Lists.newArrayList();
for(Task task : alltaskList) {
if(taskKeyMap.containsKey(task.getTaskDefinitionKey())) {
nextTaskList.add(task);
}
}
if(nextTaskList.size() <= 0) {
return Result.error("任務(wù)已辦理或已撤回,無(wú)法執(zhí)行撤回操作");
}
// 執(zhí)行撤回操作
for(Task task : nextTaskList) {
Execution execution = runtimeService.createExecutionQuery()
? ? .executionId(task.getExecutionId()).singleResult();
? ? String activityId = execution.getActivityId();
? ? FlowNode flowNode = (FlowNode) bpmnModel.getMainProcess()
? ? .getFlowElement(activityId);
? ??
? ? // 記錄原活動(dòng)方向
? ? List<SequenceFlow> oriSequenceFlows = new ArrayList<SequenceFlow>();
? ? oriSequenceFlows.addAll(flowNode.getOutgoingFlows());
? ? flowNode.getOutgoingFlows().clear();
? ? // 建立新方向
? ? List<SequenceFlow> newSequenceFlowList = new ArrayList<SequenceFlow>();
? ? SequenceFlow newSequenceFlow = new SequenceFlow();
? ? newSequenceFlow.setId("sid-"+UUID.randomUUID().toString());
? ? newSequenceFlow.setSourceFlowElement(flowNode);
? ? newSequenceFlow.setTargetFlowElement(myFlowNode);
? ? newSequenceFlowList.add(newSequenceFlow);
? ? flowNode.setOutgoingFlows(newSequenceFlowList);
? ??
? ? taskService.addComment(task.getId(), task.getProcessInstanceId(), "主動(dòng)撤回");
? ? taskService.resolveTask(task.getId());
? ? taskService.claim(task.getId(), doneTask.getTodoUserId());
? ? taskService.complete(task.getId());
? ? flowNode.setOutgoingFlows(oriSequenceFlows);
}
return Result.success();
} catch (Exception e) {
logger.error(e.getMessage(), e);
return Result.error("任務(wù)撤回失敗500");
}
}