1. 結束/終止 正在執行的流程例項
思路:跟回退一樣的思路一樣,直接從當前節點跳到結束節點(EndEvent)
/**
* 結束任務
* @param taskId 當前任務ID
*/
public void endTask(String taskId) {
// 當前任務
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());
List endEventList = bpmnModel.getMainProcess().findFlowElementsOfType(EndEvent.class);
FlowNode endFlowNode = endEventList.get(0);
FlowNode currentFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(task.getTaskDefinitionKey());
// 臨時儲存當前活動的原始方向
List originalSequenceFlowList = new ArrayList<>();
originalSequenceFlowList.addAll(currentFlowNode.getOutgoingFlows());
// 清理活動方向
currentFlowNode.getOutgoingFlows().clear();
// 建立新方向
SequenceFlow newSequenceFlow = new SequenceFlow();
newSequenceFlow.setId("newSequenceFlowId");
newSequenceFlow.setSourceFlowElement(currentFlowNode);
newSequenceFlow.setTargetFlowElement(endFlowNode);
List newSequenceFlowList = new ArrayList<>();
newSequenceFlowList.add(newSequenceFlow);
// 當前節點指向新的方向
currentFlowNode.setOutgoingFlows(newSequenceFlowList);
// 完成當前任務
taskService.complete(task.getId());
// 可以不用恢復原始方向,不影響其它的流程
// currentFlowNode.setOutgoingFlows(originalSequenceFlowList);
}
補充1:關於BUSINESS_KEY_
BUSINESS_KEY_ 欄位是用於將業務系統與Actititi工作流關聯的關鍵欄位,通常我們用它來存放業務表的ID,比如:請假ID、報銷ID等等。
但是,通常我們們系統不可能只有一個流程,假設我們做的是一個OA系統,那麼公司的流程有請假、採購、報銷等等流程,那這一個欄位如何區分到底是哪個業務流程的ID呢,換言之,假設BUSINESS_KEY_這個欄位現在是2,那麼我怎麼知道這個2是請假表的ID,還是採購表的ID呢?因此,要想通過這個一個欄位區分不同的型別就要求這個欄位是唯一的,比如我們可以加上業務標識,比如:holiday:2,purchase:3等等。還有一種方式,利用另外一個空閒欄位TENANT_ID_,我們可以把業務型別存到TENANT_ID_欄位中,這樣TENANT_ID_和BUSINESS_KEY_兩個欄位就能唯一確定是哪個業務的那個ID。
/**
* 7.1.0.M6的act_ru_task表中有BUSINESS_KEY_欄位,因此可以直接task.getBusinessKey()
* 而7.1.0.M5中沒有這個欄位,因此要想獲取BUSINESS_KEY_必須從act_ru_execution表中取
*/
@Test
public void testBusinessKey() {
List<Task> taskList = taskService.createTaskQuery().taskCandidateOrAssigned("lisi").taskTenantId("11").list();
Set<String> processInstanceIds = taskList.stream().map(Task::getProcessInstanceId).collect(Collectors.toSet());
List<ProcessInstance> processInstances = runtimeService.createProcessInstanceQuery().processInstanceIds(processInstanceIds).list();
List<String> businessKeyList = processInstances.stream().map(ProcessInstance::getBusinessKey).collect(Collectors.toList());
System.out.println(businessKeyList);
Pattern pattern = Pattern.compile("^(\\w+):(\\d+)$");
List<Integer> businessIds = new ArrayList<>();
businessKeyList.forEach(businessKey->{
Matcher matcher = pattern.matcher(businessKey);
if (matcher.find()) {
String id = matcher.group(2);
businessIds.add(Integer.valueOf(id));
}
});
}
補充2:Activiti不同版本的Bug
首先,我發現不同版本的表結構不一樣,當用 7.1.0.M5 版本時,啟動就報錯,缺少欄位
org.apache.ibatis.exceptions.PersistenceException: ### Error updating database. Cause: java.sql.SQLSyntaxErrorException: Unknown column 'VERSION_' in 'field list' ### The error may exist in org/activiti/db/mapping/entity/Deployment.xml ### The error may involve org.activiti.engine.impl.persistence.entity.DeploymentEntityImpl.insertDeployment-Inline ### The error occurred while setting parameters ### SQL: insert into ACT_RE_DEPLOYMENT(ID_, NAME_, CATEGORY_, KEY_, TENANT_ID_, DEPLOY_TIME_, ENGINE_VERSION_, VERSION_, PROJECT_RELEASE_VERSION_) values(?, ?, ?, ?, ?, ?, ?, ?, ?) ### Cause: java.sql.SQLSyntaxErrorException: Unknown column 'VERSION_' in 'field list' at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) ~[mybatis-3.5.0.jar:3.5.0] at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:200) ~[mybatis-3.5.0.jar:3.5.0] at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:185) ~[mybatis-3.5.0.jar:3.5.0] at org.activiti.engine.impl.db.DbSqlSession.flushRegularInsert(DbSqlSession.java:787) ~[activiti-engine-7.1.0.M5.jar:na] at org.activiti.engine.impl.db.DbSqlSession.flushInsertEntities(DbSqlSession.java:662) ~[activiti-engine-7.1.0.M5.jar:na] at org.activiti.engine.impl.db.DbSqlSession.flushInserts(DbSqlSession.java:642) ~[activiti-engine-7.1.0.M5.jar:na] at org.activiti.engine.impl.db.DbSqlSession.flush(DbSqlSession.java:525) ~[activiti-engine-7.1.0.M5.jar:na]
解決辦法也很簡單,將缺失的欄位加上即可:
ALTER TABLE `act_re_deployment`
ADD COLUMN `VERSION_` int(11) NULL DEFAULT NULL,
ADD COLUMN `PROJECT_RELEASE_VERSION_` varchar(255) NULL DEFAULT NULL;
其次,我發現在啟動流程例項查詢流程定義時,7.1.0.M5是按版本升序取第一個,而7.1.0.M6是降序
同時,還發現7.1.0.M6有一個明顯的Bug,這個Bug會導致當有多個部署的時候,即當act_re_deployment表中的記錄多於1條時,就無法使用processRuntime.start()啟動流程例項
本著用新不用舊的原則,還是建議用7.1.0.M6
補充3:任務監聽器
@Slf4j
@Component
public class TaskCreateListener implements TaskRuntimeEventListener<TaskCreatedEvent> {
@Override
public void onEvent(TaskCreatedEvent event) {
System.out.println("任務被建立");
}
}
@Slf4j
@Component
public class TaskAssignedListener implements TaskRuntimeEventListener<TaskAssignedEvent> {
@Override
public void onEvent(TaskAssignedEvent event) {
System.out.println("任務被指派");
}
}
@Slf4j
@Component
public class TaskCompletedListener implements TaskRuntimeEventListener<TaskCompletedEvent> {
@Override
public void onEvent(TaskCompletedEvent event) {
System.out.println("任務被完成");
}
}
關於Activiti就到此為止了,以後也不想再碰這玩意兒了,太難用了