idea的Flowable BPMN visualizer插件
- @Test
- void completeTask1(){
- Map
map = new HashMap<>(); - map.put("flag",false); //设置为true,结束多人会签
- taskService.complete("71337501-b22e-11ec-a534-c03c59ad2248",map);
- System.out.println("complete ....");
- }
MulitiInstanceCompleteTask.completeTask()被执行1次,控制台有如下打印。:
当前意见:false,表示当前会签任务没有结束,继续会签直到遇到true为止。
act_ru_task:还有2条任务(删除一条任务了)
第8步:再次通过任务id,去完成任务(查看多人会签任务时,有2个人去完成任务的效果是怎么样的)
map.put("flag",true); //设置为true,结束多人会签
第9步:验证3
MulitiInstanceCompleteTask.completeTask()又被执行1次,控制台有如下打印。:
当前意见:true,表示当前会签结束了,即“用户任务”这个节点完成了,流转空结束事件。
act_ru_task:3条任务都删除了,甚至连没有去完成的那1条任务也被删除了。
应用场景
用户任务4回退到用户任务3,或者从用户任务4回退到用户任务1。
- /**
- * moveActivityIdTo(),可以从当前的流程跳转到任意的节点
- */
- @Test
- public void rollbackTask(){
- ProcessEngine processEngine = configuration.buildProcessEngine();
- RuntimeService runtimeService = processEngine.getRuntimeService();
- runtimeService.createChangeActivityStateBuilder()
- .processInstanceId("67501")
- .moveActivityIdTo("usertask4","usertask3")//方法1:可以从当前活动的节点(Id),跳转指定的新的节点(Id)
- //.moveActivityIdsToSingleActivityId(currentActivityIds,newActivityId)
- .changeState();//改变状态
- }
- @Test
- public void rollbackTask1(){
- ProcessEngine processEngine = configuration.buildProcessEngine();
- RuntimeService runtimeService = processEngine.getRuntimeService();
- List
newActivityIds = new ArrayList(); - newActivityIds.add("usertask1");
- runtimeService.createChangeActivityStateBuilder()
- .processInstanceId("67501")
- //方法1:可以从当前活动的节点(Id),跳转指定的新的节点(Id)
- //.moveActivityIdTo("usertask4","usertask3")
- //方法2:从当前活动的节点(id),跳转到List
ids集合(多个节点)。 - .moveSingleActivityIdToActivityIds("usertask4",newActivityIds)
- .changeState();//改变状态
- }
- @Test
- public void rollbackTask1(){
- ProcessEngine processEngine = configuration.buildProcessEngine();
- RuntimeService runtimeService = processEngine.getRuntimeService();
- List
newActivityIds = new ArrayList(); - newActivityIds.add("usertask1");
- runtimeService.createChangeActivityStateBuilder()
- .processInstanceId("67501")
- //方法1:可以从当前活动的节点(Id),跳转指定的新的节点(Id)
- //.moveActivityIdTo("usertask4","usertask3")
- //方法2:从当前活动的节点(id),跳转到List
ids集合(多个节点)。 - //.moveSingleActivityIdToActivityIds("usertask4",newActivityIds)
- //方法3:不管当前节点是哪个了,就是要从当前执行实例跳到哪个节点。参数1:执行id,参数2:目标id。
- .moveExecutionToActivityId("77501","usertask3")
- .changeState();//改变状态
- }
moveActivityIdTo(String currentActivityId,String newActivityId)
这个方法来处理。应用场景
业务副总肯定是不能回退到行政副总。即使你可以强行跳过来,但这种逻辑是不合理的。
从业务副总回退到业务负责人,这是串行的,和上面的操作一样。
关注1:从并行节点回退到串行节点。并行审批流转到业务副总(没处理),同时流转到行政副总(没处理)。编码要实现,业务副总(没处理)回退到用户审批01(起始节点)。自动地,行政副总要自动回退到用户审批01(起始节点)。
关注2:并行审批流转到业务副总(没处理),同时流转到行政副总(已处理,到达并行网关之集合)。因为是并行网关,所以也要等待业务副总(没处理)审批是吧。这时想编码要实现,业务副总(没处理)回退到用户审批01(起始节点)。自动地,行政副总要自动回退到用户审批01(起始节点)。
关注3:从串行节点回退到并行节点。总经理回退到并行网关中的业务副总、行政副总。
关注4:总经理回退到用户审批01(起始节点),其实也是串行的,和上面的操作一样。
- /**
- * 回退操作
- * 业务副总驳回到到用户审批处 那么行政审批的应该自动回到到用户审批处
- */
- @Test
- public void rollbackTask(){
- ProcessEngine processEngine = configuration.buildProcessEngine();
- RuntimeService runtimeService = processEngine.getRuntimeService();
- // 当前的Task对应的用户任务的Id
- List
currentActivityIds = new ArrayList(); - currentActivityIds.add("usertask4"); // 业务副总
- currentActivityIds.add("usertask3"); // 行政副总
- // 需要回退的目标节点的用户任务Id
- String newActivityId = "usertask1"; // 用户审批01
- // 回退操作
- runtimeService.createChangeActivityStateBuilder()
- .processInstanceId("95001")
- .moveActivityIdsToSingleActivityId(currentActivityIds,newActivityId)
- .changeState();
- }
第6步:验证
task表
act_hi_actinst表,查看任务列表
第三步:演示2:并行审批流转到业务副总(没处理),同时流转到行政副总(已处理,到达并行网关之集合)。因为是并行网关,所以也要等待业务副总(没处理)审批是吧。这时想编码要实现,业务副总(没处理)回退到用户审批01(起始节点)。自动地,行政副总要自动回退到用户审批01(起始节点)。
第1步:完成任务:用户审批01,user1。业务负责人,user2。行政副总,user4。
第2步:验证
task表,只有1条任务,流转到(即等待)业务副总user3
act_hi_actinst表,查看任务列表
第3步:业务副总(没处理)回退到用户审批01,重新去录入相关数据。行政副总会自动回退到用户审批01:
- /**
- * 回退操作
- * 业务副总驳回到到用户审批处
- */
- @Test
- public void rollbackTask(){
- ProcessEngine processEngine = configuration.buildProcessEngine();
- RuntimeService runtimeService = processEngine.getRuntimeService();
- // 当前的Task对应的用户任务的Id
- List
currentActivityIds = new ArrayList(); - currentActivityIds.add("usertask4"); // 业务副总
- //currentActivityIds.add("usertask3"); //行政副总
- // 需要回退的目标节点的用户任务Id
- String newActivityId = "usertask1"; // 用户审批01
- // 回退操作
- runtimeService.createChangeActivityStateBuilder()
- .processInstanceId("95001")
- .moveActivityIdsToSingleActivityId(currentActivityIds,newActivityId)
- .changeState();
- }
第四步:演示3:总经理回退到并行网关中的业务副总、行政副总。
- @Test
- public void rollbackTask(){
- ProcessEngine processEngine = configuration.buildProcessEngine();
- RuntimeService runtimeService = processEngine.getRuntimeService();
- // 当前的Task对应的用户任务的Id
- List
newActivityId = new ArrayList(); - newActivityId.add("usertask2"); //业务负责人
- newActivityId.add("usertask3"); //行政副总
- // 回退操作
- runtimeService.createChangeActivityStateBuilder()
- .processInstanceId("95001")
- .moveSingleActivityIdToActivityIds("usertask5",newActivityId)
- .changeState();
- }
- /**
- * 回退操作
- * 从子流程回退到主流程操作
- */
- @Test
- void rollbackMainTask(){
-
- // 回退操作
- runtimeService.createChangeActivityStateBuilder()
- .processInstanceId("2501")
- // 没有多个时,可用此方法
- .moveActivityIdTo("usertask2","usertask1")
- .changeState();
- }
-
- }
- /**
- * 回退操作
- * 从子流程回退到主流程操作:moveExecutionToActivityId不关心当前的节点
- */
- @Test
- void rollbackMainTask(){
-
- // 回退操作
- runtimeService.createChangeActivityStateBuilder()
- .processInstanceId("2501")
- .moveExecutionToActivityId("5003","usertask1")
- .changeState();
- }
- /**
- * 回退操作
- */
- @Test
- void rollbackSubTask(){
-
- // 回退操作
- runtimeService.createChangeActivityStateBuilder()
- .processInstanceId("2501")
- //当然也可以回退到usertask1
- .moveActivityIdTo("usertask3","usertask2")
- .changeState();
- }
第四步:验证
task表
act_hi_actinst
撤消 = 回退 + 删除历史记录信息
实际开发过程中,要结合历史数据。通过一些sql语句,所这些回退节点都找出来。如果说操作比较复杂,你可能还要去重、编排、处理。
- /**
- * 查看部署的流程内置的表单信息
- */
- @Test
- public void getStartFromData(){
- ProcessEngine processEngine = configuration.buildProcessEngine();
- StartFormData startFormData = processEngine.getFormService().getStartFormData("inner_form:1:4");
- List
formProperties = startFormData.getFormProperties(); - for (FormProperty formProperty : formProperties) {
- String id = formProperty.getId();
- String name = formProperty.getName();
- FormType type = formProperty.getType();
- System.out.println("id = " + id);
- System.out.println("name = " + name);
- System.out.println("type.getClass() = " + type.getClass());
- }
- }
- /**
- * 正常的启动流程
- */
- @Test
- void startFlow() throws Exception{
- Map
map = new HashMap<>(); - map.put("days","5");
- map.put("startDate","20220403");
- map.put("reason","想休息下");
- ProcessInstance processInstance = runtimeService
- .startProcessInstanceById("myProcess:5:4dd61987-b313-11ec-882d-c03c59ad2248",map);
- }
-
-
- /**
- * 通过FormService来启动一个表单流程
- * @throws Exception
- */
- @Test
- void startFormFlow() throws Exception{
- ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
- .deploymentId("4da14de4-b313-11ec-882d-c03c59ad2248")
- .singleResult();
- // map只能是
- Map
map = new HashMap<>(); - map.put("days","2");
- map.put("startDate","20220406");
- map.put("reason","出去玩玩");
- // 提交启动的表单数据
- // ProcessInstance processInstance = processEngine.getFormService().submitStartFormData("inner_form:1:4", map);
- ProcessInstance processInstance = processEngine.getFormService().submitStartFormData(processDefinition.getId(), map);
-
- }
- /**
- * 根据Task编号来查看表单数据
- */
- @Test
- public void getTaskFormData(){
- ProcessEngine processEngine = configuration.buildProcessEngine();
- String taskId = "2508";// taskId,即任务编号
- TaskFormData taskFormData = processEngine.getFormService().getTaskFormData(taskId);
- List
formProperties = taskFormData.getFormProperties(); - for (FormProperty formProperty : formProperties) {
- System.out.println("formProperty.getId() = " + formProperty.getId());
- System.out.println("formProperty.getName() = " + formProperty.getName());
- System.out.println("formProperty.getValue() = " + formProperty.getValue());
- }
- }
- /**
- * 根据Task编号来修改(保存、更新)表单数据
- */
- @Test
- public void saveOrupdateTaskFormData(){
- ProcessEngine processEngine = configuration.buildProcessEngine();
- String taskId = "2508";// taskId,即任务编号
- Map
map = new HashMap(); - map.put("reson","巴拉巴拉");
- FormService formService = processEngine.getFormService();
- formService.saveFormData(taskId,map);
- }
- /**
- * 直接完成任务
- */
- @Test
- public void submitTaskFormData1(){
- // 直接完成
- ProcessEngine processEngine = configuration.buildProcessEngine();
- processEngine.getTaskService().complete("2508");
- }
-
- /**
- * 保存表单数据并完成任务
- */
- @Test
- public void submitTaskFormData2(){
- ProcessEngine processEngine = configuration.buildProcessEngine();
- String taskId = "2508";
- // 完成任务的同时可以修改(保存、更新)表单数据
- Map
map = new HashMap(); - map.put("days","7");
- map.put("startDate","20220408");
- map.put("reason","9出去玩玩");
- processEngine.getFormService().submitTaskFormData(taskId,map);
- }
- /**
- * 查看已经完成的Task的表单数据
- */
- @Test
- void getHisTaskFormData(){
- String taskId = "80efeb32-b313-11ec-a7ff-c03c59ad2248";
- List
list = processEngine.getHistoryService() - .createHistoricDetailQuery()
- .taskId(taskId)
- .formProperties()
- .list();
- for (HistoricDetail historicDetail : list) {
- HistoricFormPropertyEntityImpl his = (HistoricFormPropertyEntityImpl) historicDetail;
- System.out.println("his.getPropertyId() = " + his.getPropertyId());
- System.out.println("his.getPropertyValue() = " + his.getPropertyValue());
- }
- }
- {
- "key": "form1",
- "name": "请假流程",
- "fields": [
- {
- "id": "startTime",
- "name": "开始时间",
- "type": "date",
- "required": true,
- "placeholder": "empty"
- },
- {
- "id": "days",
- "name": "请假天数",
- "type": "string",
- "required": true,
- "placeholder": "empty"
- },
- {
- "id": "reason",
- "name": "请假原因",
- "type": "text",
- "required": true,
- "placeholder": "empty"
- }
- ]
- }
- @Autowired
- private FormRepositoryService formRepositoryService;
-
- /**
- * 部署form表单:在外置Form表单中我们需要在流程部署完毕后,再对表单做部署的操作
- */
- @Test
- public void deployForm() throws Exception{
-
- FormDeployment formDeployment = formRepositoryService.createDeployment()
- .addClasspathResource("holiday.form")
- .name("test")
- .parentDeploymentId("1") //和我们上面部署的流程关联
- .deploy();
- System.out.println("formDeployment.getId() = " + formDeployment.getId());
- }
- /**
- * 启动流程实例,并且设置对应的值
- */
- @Test
- void startTask(){
- Map
map = new HashMap<>(); - map.put("days","4");
- map.put("startTime","20220404");
- map.put("reason","出去玩玩");
- ProcessInstance processInstance = runtimeService.startProcessInstanceWithForm(
- "myProcess:1:4"
- , null
- , map
- , "请假流程");
- String id = processInstance.getId();
- System.out.println("id = " + id);
-
- }
- /**
- * 查看流程定义表单数据
- */
- @Test
- public void getTaskFormData1(){
- Task task = taskService.createTaskQuery()
- .processDefinitionId("myProcess:1:4")
- .taskAssignee("zhangsan")
- .singleResult();
- // FormInfo 表单的元数据信息
- FormInfo formInfo = runtimeService.getStartFormModel("myProcess:1:4", "5001");
- System.out.println("formInfo.getId() = " + formInfo.getId());
- System.out.println("formInfo.getName() = " + formInfo.getName());
- System.out.println("formInfo.getKey() = " + formInfo.getKey());
- // FormModel 表单中的具体信息 具体实现是 SimpleFormModel
- SimpleFormModel formModel = (SimpleFormModel) formInfo.getFormModel();
- List
fields = formModel.getFields(); - for (FormField field : fields) {
- System.out.println("field.getId() = " + field.getId());
- System.out.println("field.getName() = " + field.getName());
- System.out.println("field.getValue() = " + field.getValue());
- }
- System.out.println("formModel = " + formModel);
- }
-
- /**
- * 查看具体的Task的表单数据
- */
- @Test
- void getTaskData(){
- FormInfo formInfo = taskService.getTaskFormModel("17505");
- System.out.println("formInfo.getId() = " + formInfo.getId());
- System.out.println("formInfo.getName() = " + formInfo.getName());
- System.out.println("formInfo.getKey() = " + formInfo.getKey());
- SimpleFormModel formModel = (SimpleFormModel) formInfo.getFormModel();
- List
fields = formModel.getFields(); - for (FormField field : fields) {
- System.out.println("field.getId() = " + field.getId());
- System.out.println("field.getName() = " + field.getName());
- System.out.println("field.getValue() = " + field.getValue());
- }
- }
taskService.completeTaskWithForm
来完成表单的任务
- /**
- * 完成任务
- */
- @Test
- public void completeTaskForm(){
- Map
map = new HashMap<>(); - map.put("days","4");
- map.put("startTime","20220404");
- map.put("reason","出去玩玩");
- String taskId = "5010";
- String formDefinitionId = "2503";
- String outcome = "波哥";
- taskService.completeTaskWithForm(taskId,formDefinitionId,outcome,map);
- }
2022-03-27T23:36:14
2022-03-27T23:36:14
这个时间之前还没有处理,那么就会触发定时边界事件,从而从人工任务3。zhangsan
的位置。启动事件:根据设置循环启动流程实例
边界事件:即使设置了循环时间也只会触发1次
中间事件:即使设置了循环时间也只会触发1次
- public class MyOneDelegate implements JavaDelegate {
- @Override
- public void execute(DelegateExecution execution) {
-
- System.out.println("完成自动审批任务-----》MyOneDelegate" + LocalDateTime.now().toString());
- // 业务执行发现有问题 此处的errorCode需要和定义的error标签中的errorCode保持一致
- throw new BpmnError("abcd");
- }
- }
- /**
- * 通过信号发送来触发信号启动事件的执行
- * 全局的信息
- */
- @Test
- void signalReceived() throws Exception {
- runtimeService.signalEventReceived("firstSignal");
- // 我们得保证容器的运行,所以需要阻塞
- TimeUnit.MINUTES.sleep(1);
- }
- /**
- * 通过信号发送来触发信号启动事件的执行
- * 全局的信息
- */
- @Test
- void signalGolbal() throws Exception {
- runtimeService.signalEventReceived("secondSingal");
- // 我们得保证容器的运行,所以需要阻塞
- TimeUnit.MINUTES.sleep(1);
- }
- @Test
- public void signalGlobal() throws Exception{
- String signal = "signal2";
- Map
variables = new HashMap(); - processEngine.getRuntimeService().signalEventReceived(signal,variables);
- }
- public class MyOneDelegate implements JavaDelegate {
- @Override
- public void execute(DelegateExecution execution) {
-
- System.out.println("微信支付-----》MyOneDelegate" + LocalDateTime.now().toString());
- System.out.println("余额不足....");
- throw new BpmnError("payFail");
- }
- }