flowable实现流程回退任务

参考文章:
flowable审批,在下个节点没审批前,如何撤回审批。
Flowable 快速入门教程:任务驳回与回退
flowable实战(五)flowable驳回/退回上一步/退回到

一、背景

公司项目是统一在公司自己的框架下实现的,然后现在在做的项目使用了flowable工作流。

昨儿忽然提了一个需求:在中心签领之前,企业可以撤回任务。比如企业上报了自己的信息,中心端需要签领后审核,但忽然企业发现自己上报的信息有些问题,这时可以点击【撤回】按钮,将该条上报信息撤回。(串行普通节点的回退)。

其中部分代码详细实现不可以粘贴出来,就主要记录一下大概思路~~

自己瞎实现,还请各位大佬可以指正错误~~~呜呜呜呜呜呜呜。

二、思路

1、获取当前任务节点
2、判断是否被签领
3、若被签领,则提示不能撤回。
4、若未被签领,则执行退回任务。

//核心
runtimeService.createChangeActivityStateBuilder()
        .processInstanceId(proInstanceId)
        .moveActivityIdsToSingleActivityId(curTaskKeys, targetTaskKey)
        .changeState();

5、自动签领任务。
6、返回要跳转的路径

三、代码

1、flowableEngineAPI.quash()实现!!

/**
	 * 撤回任务
	 */
	public DataObject quash(String piid, String taskid, String taskkey) throws AppException{
    
    
		//存最终结果
		DataObject result = DataObject.getInstance();
		
		//判空
		this.isEmpty(piid, "流程实例id不可为空");

		//获取当前任务信息
		Task task = taskService.createTaskQuery().taskId(taskid).singleResult();
		//判断该任务是否被签领
		String assignee = task.getAssignee();
		if (null != assignee){
    
    
			result.put("statu","0");
			result.put("msg","任务已被签领,无法撤回!");
		}else{
    
    
			//获取历史任务节点
			List<HistoricTaskInstance> historicTaskInstanceList = historyService.createHistoricTaskInstanceQuery().processInstanceId(task.getProcessInstanceId()).orderByHistoricTaskInstanceStartTime().asc().list();
			Iterator<HistoricTaskInstance> it = historicTaskInstanceList.iterator();
			//循环节点,获取当前节点的上一节点的key
			String tkey = "";
			while(it.hasNext())    {
    
    
				HistoricTaskInstance his = it.next();
				if (!taskkey.equals(his.getTaskDefinitionKey())){
    
    
					tkey = his.getTaskDefinitionKey();
				}
			}

			//回退(节点跳转)
			runtimeService.createChangeActivityStateBuilder()
				.processInstanceId(piid)
				.moveActivityIdTo(taskkey, tkey)
				.changeState();

			//删除当前任务节点,不知道咋实现

			//返回成功消息
			result.put("statu","1");
			result.put("msg","撤回成功!请尽快完成任务");

		}
		return result;
	}


2、contrller层

/**
	 * 撤回任务,并进入相应页面
	 *
	 * @param para
	 * @return
	 * @author: tcy
	 * 时间:2021年12月07日
	 */
	@PostMapping("/quash")
	@ResponseBody
	public DataObject quash(@RequestBody DataObject para) {
    
    
		String piid = para.getString("piid");
		String pdkey = para.getString("pdkey");

		//获取当前任务节点
		DataObject rdo = DataObject.getInstance();
		rdo.put("piid",piid);
		DataObject active = flowableEngineAPI.getActiveTaskListByPiid(rdo);
		DataStore rows = active.getDataStore("rows");
		DataObject row = rows.getRow(0);
		String taskid = row.getString("taskid");//任务id
		String taskkey = row.getString("taskkey");//任务名称

		//执行退回任务
		DataObject result = flowableEngineAPI.quash(piid,taskid,taskkey);

		//自动签领任务
		String statu = result.getString("statu");
		if ("1".equals(statu)){
    
    
			active = flowableEngineAPI.getActiveTaskListByPiid(rdo);
			rows = active.getDataStore("rows");
			taskid = rows.getString(0, "taskid");
			String curruser = SecurityUtils.getUser().getUserId();
			rdo.clear();
			rdo.put("userid", curruser);
			rdo.put("taskid", taskid);
			//签领任务
			flowableEngineAPI.claim(rdo);

			//返回需跳转的路径
			rdo.clear();
			rdo.put("pdkey", pdkey);
			rdo.put("taskkey", active.getDataStore("rows").getString(0, "taskkey"));
			DataObject path = flowableService.getTaskPath(rdo);
			result.put("piid",piid);
			result.put("task_path",path.getString("task_path"));

		}
		return result;
	}

3、前端

layui.sight.ajaxRequest({
    
    
                    type: 'post',
                    async: true,
                    url: layui.sight.compileUrl('${rc.contextPath}/flowable/quash'),//调用方法路径
                    data: {
    
    //方法需要的参数
                        piid: '${piid}',
                        pdkey: '${pdkey}'
                    },
                    callback: function (data) {
    
    
                    //回调
                        var statu = data.statu;
                        layer.confirm(data.msg + '<br>', {
    
    
                                btn: ['确认']
                            }, function(){
    
    
                            //当可以执行撤回时,刷新页面
                            if ("1" == statu){
    
    
                                var url = layui.sight.compileUrl('${rc.contextPath}' + data.task_path + '?piid=' + data.piid);
                                window.open(url, target = "_self");
                            }else{
    
    
                            //不可以执行撤回时,直接关闭该弹窗
                                return;
                            }
                            }
                        );
                    },
                    failedCallback: function (data) {
    
     }
                });

四、问题

造成的脏数据(撤回的节点)未删除。

猜你喜欢

转载自blog.csdn.net/qq_42622871/article/details/121787127