activity流程撤回功能实现
- 在日常的流程审批过程中,经常会出现操作失误需要撤回重新办理。
- 使用版本为7.1.0.M2
基本逻辑:
- 找到此流程的所有审批意见,把撤回节点的之后的意见和办理记录删除。
- 找到撤回节点和当前节点信息,在当前节点动态构造一条线到撤回的节点并执行。
- 恢复原来的连线。
代码实现
/**
* 根据流程id及用户名撤回该用户最新的一条办理意见
* @param id
* @param userName 流程查询的用户id或用户名
* @return
*/
public nullreleaseCallBack(String id,String userName){
try {
List<Comment> lstComments = new ArrayList<Comment>();
WorkflowBaseEntity baseEntity = workflowBaseService.getById(id);
List<ProcessInstance> lstPis = runtimeService.createProcessInstanceQuery().processInstanceBusinessKey(baseEntity.getId()).list();
// 获取流程实例的ID,这里确切的说只有一条数据,保险起见,弄个Set存放一下
Set<String> st = new HashSet<String>();
for (ProcessInstance pi : lstPis) {
String piId = pi.getProcessInstanceId();
st.add(piId);
}
//获取当前任务节点
List<Task> lst=new ArrayList<>();
for (String piId : st) {
lst = taskService.createTaskQuery().processInstanceId(piId).list();
}
//获取历史审批意见
for (String piId : st) {
List<Comment> lst1 = taskService.getProcessInstanceComments(piId);
if (null != lst) {
lstComments.addAll(lst1);
}
}
//查找审批意见
Comment lastComment=null;
for (Comment comment:lstComments){
//查找当前用户最新的一条
if (userName.equals(comment.getUserId())){
//查找时间最新的一条数据
if (lastComment == null ){
lastComment=comment;
}
if (lastComment!=null && lastComment.getTime().before(comment.getTime())){
lastComment=comment;
}
}
}
//需要删除上一节点后面流程的所有数据
if (lastComment!=null){
for (Comment comment:lstComments){
if (lastComment.getTime().before(comment.getTime())){
//删除上一节点后的所有审批意见
taskService.deleteComment(comment.getId());
//删除所有节点的办理记录
taskService.deleteTask(comment.getId());
}
}
//删除当前用户的审批意见及办理记录
taskService.deleteComment(lastComment.getId());
taskService.deleteTask(lastComment.getId());
}
//如果节点为空则流程已结束,无法撤回
if (lst!=null &&lst.size()>0){
// 取得当前任务
HistoricTaskInstance currTask = historyService
.createHistoricTaskInstanceQuery().taskId(lst.get(0).getId())
.singleResult();
//根据流程id查询代办任务中流程信息
Task task = taskService.createTaskQuery().processInstanceId(currTask.getProcessInstanceId()).singleResult();
//查找所有走过的历史任务
List<HistoricTaskInstance> htlist = historyService.createHistoricTaskInstanceQuery()
.processInstanceId(task.getProcessInstanceId())
.finished().list();
String myTaskId=null;
HistoricTaskInstance myTask=null;
Date date=null;
for (HistoricTaskInstance hti:htlist){
//回退到当前办理人,防止有多条办理信息,找到最新的一条
if (hti.getAssignee().equals(userName)){
//如果当前节点办理时间为最新的则覆盖
if (date!=null && date.after(hti.getStartTime())){
continue;
}else{
myTaskId=hti.getId();
myTask=hti;
date=hti.getStartTime();
}
}
}
//查询流程定义
BpmnModel bpmnModel = repositoryService.getBpmnModel(myTask.getProcessDefinitionId());
//历史完成节点
List<HistoricActivityInstance> hailist = historyService.createHistoricActivityInstanceQuery()
.executionId(myTask.getExecutionId())
.finished().list();
//拿到我的节点
String myActivityId="";
for (HistoricActivityInstance h:hailist){
if (myTaskId.equals(h.getTaskId())){
myActivityId=h.getActivityId();
}
}
//我的流程节点
FlowNode myFlowNode= (FlowNode) bpmnModel.getMainProcess().getFlowElement(myActivityId);
Execution execution = runtimeService.createExecutionQuery()
.executionId(task.getExecutionId())
.singleResult();
//当前流程节点
String activityId = execution.getActivityId();
FlowNode flowNode =(FlowNode) bpmnModel.getMainProcess().getFlowElement(activityId);
//记录原活动节点方向
List<SequenceFlow> oldsequenceFlows=new ArrayList<SequenceFlow>();
oldsequenceFlows.addAll(flowNode.getOutgoingFlows());
//清理活动方向
flowNode.getOutgoingFlows().clear();
//建立新方向
List<SequenceFlow> newSequenceFlows=new ArrayList<>();
SequenceFlow newSequenceFlow=new SequenceFlow();
newSequenceFlow.setId("newSequenceFlow");
newSequenceFlow.setSourceFlowElement(flowNode);
//next为连线条件,与下面的map对应
newSequenceFlow.setConditionExpression("${next=='撤回'}");
newSequenceFlow.setTargetFlowElement(myFlowNode);
newSequenceFlows.add(newSequenceFlow);
flowNode.setOutgoingFlows(newSequenceFlows);
//设置操作人记录和备注信息
Authentication.setAuthenticatedUserId(ShiroUtils.getSessionUserName());
//撤回,设置办理人和连线
Map<String, Object> map = new HashMap<>();
map.put("userId", ShiroUtils.getSessionUserName());
map.put("next", "撤回");
//执行当前构造的流程模型
workflowService.saveSubmitTask2(task.getId(), id, "", map);
//taskService.complete(task.getId());
//恢复原来方向
flowNode.getOutgoingFlows().clear();
flowNode.setOutgoingFlows(oldsequenceFlows);
/*ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
.processInstanceId(task.getProcessInstanceId())
.singleResult();*/
}else{
System.out.println("流程未启动或已结束,无法撤回");
}
} catch (Exception e) {
e.printStackTrace();
}
}