feat: 动态选择任务接收人

approve-sys
tony 3 years ago
parent d1fc179f7d
commit 60b0f82f3e

@ -135,6 +135,12 @@ public class FlowTaskController {
return AjaxResult.success(); return AjaxResult.success();
} }
@ApiOperation(value = "获取下一节点")
@PostMapping(value = "/nextFlowNode")
public AjaxResult getNextFlowNode(@RequestBody FlowTaskVo flowTaskVo) {
return flowTaskService.getNextFlowNode(flowTaskVo);
}
/** /**
* *
* *

@ -28,9 +28,12 @@ public class FlowTaskVo {
@ApiModelProperty("流程实例Id") @ApiModelProperty("流程实例Id")
private String instanceId; private String instanceId;
@ApiModelProperty("退回节点") @ApiModelProperty("节点")
private String targetKey; private String targetKey;
@ApiModelProperty("流程变量信息") @ApiModelProperty("流程变量信息")
private Map<String, Object> values; private Map<String, Object> values;
@ApiModelProperty("审批人")
private String assignee;
} }

@ -5,6 +5,7 @@ import com.ruoyi.flowable.domain.vo.FlowTaskVo;
import org.flowable.task.api.Task; import org.flowable.task.api.Task;
import java.io.InputStream; import java.io.InputStream;
import java.util.List;
/** /**
* @author XuanXuan * @author XuanXuan
@ -142,4 +143,11 @@ public interface IFlowTaskService {
* @return * @return
*/ */
AjaxResult processVariables(String taskId); AjaxResult processVariables(String taskId);
/**
*
* @param flowTaskVo
* @return
*/
AjaxResult getNextFlowNode(FlowTaskVo flowTaskVo);
} }

@ -15,14 +15,15 @@ import com.ruoyi.flowable.domain.dto.FlowTaskDto;
import com.ruoyi.flowable.domain.vo.FlowTaskVo; import com.ruoyi.flowable.domain.vo.FlowTaskVo;
import com.ruoyi.flowable.factory.FlowServiceFactory; import com.ruoyi.flowable.factory.FlowServiceFactory;
import com.ruoyi.flowable.flow.CustomProcessDiagramGenerator; import com.ruoyi.flowable.flow.CustomProcessDiagramGenerator;
import com.ruoyi.flowable.flow.FindNextNodeUtil;
import com.ruoyi.flowable.flow.FlowableUtils; import com.ruoyi.flowable.flow.FlowableUtils;
import com.ruoyi.flowable.service.IFlowTaskService; import com.ruoyi.flowable.service.IFlowTaskService;
import com.ruoyi.flowable.service.ISysDeployFormService; import com.ruoyi.flowable.service.ISysDeployFormService;
import com.ruoyi.system.domain.SysForm; import com.ruoyi.system.domain.SysForm;
import com.ruoyi.system.service.ISysRoleService; import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService; import com.ruoyi.system.service.ISysUserService;
import liquibase.pro.packaged.S;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.flowable.bpmn.model.Process; import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.*; import org.flowable.bpmn.model.*;
@ -32,6 +33,7 @@ import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.engine.ProcessEngineConfiguration; import org.flowable.engine.ProcessEngineConfiguration;
import org.flowable.engine.history.HistoricActivityInstance; import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance; import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.repository.ProcessDefinition; import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.Execution; import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ProcessInstance; import org.flowable.engine.runtime.ProcessInstance;
@ -106,8 +108,12 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
// } // }
taskService.setVariables(task.getTaskId(), map); taskService.setVariables(task.getTaskId(), map);
} }
// 设置任务处理人员 // 设置任务审批人员
taskService.setAssignee(task.getTaskId(), userId.toString()); taskService.setAssignee(task.getTaskId(), userId.toString());
// todo : 这种方式无法动态设置任务接收人
// if (StringUtils.isNotBlank(task.getAssignee())) {
// taskService.addCandidateUser(task.getTaskId(), task.getAssignee());
// }
// 提交任务 // 提交任务
taskService.complete(task.getTaskId()); taskService.complete(task.getTaskId());
@ -495,7 +501,7 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
} }
/** /**
* *
* *
* @param flowTaskVo * @param flowTaskVo
* @return * @return
@ -544,7 +550,6 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
Execution execution = runtimeService.createExecutionQuery().executionId(task.getExecutionId()).singleResult(); Execution execution = runtimeService.createExecutionQuery().executionId(task.getExecutionId()).singleResult();
String activityId = execution.getActivityId(); String activityId = execution.getActivityId();
log.warn("------->> activityId:{}", activityId);
FlowNode flowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(activityId); FlowNode flowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(activityId);
//记录原活动方向 //记录原活动方向
@ -598,13 +603,7 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
// 当前流程信息 // 当前流程信息
flowTask.setTaskId(task.getId()); flowTask.setTaskId(task.getId());
flowTask.setTaskDefKey(task.getTaskDefinitionKey()); flowTask.setTaskDefKey(task.getTaskDefinitionKey());
// // 审批人员信息
// SysUser sysUser = sysUserService.selectUserById(Long.parseLong(task.getAssignee()));
// flowTask.setAssigneeId(sysUser.getUserId());
// flowTask.setAssigneeName(sysUser.getNickName());
// flowTask.setDeptName(sysUser.getDept().getDeptName());
flowTask.setCreateTime(task.getCreateTime()); flowTask.setCreateTime(task.getCreateTime());
// flowTask.setProcVars(task.getProcessVariables());
flowTask.setProcDefId(task.getProcessDefinitionId()); flowTask.setProcDefId(task.getProcessDefinitionId());
flowTask.setTaskName(task.getName()); flowTask.setTaskName(task.getName());
// 流程定义信息 // 流程定义信息
@ -655,10 +654,6 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
// 当前流程信息 // 当前流程信息
flowTask.setTaskId(histTask.getId()); flowTask.setTaskId(histTask.getId());
// 审批人员信息 // 审批人员信息
// SysUser sysUser = sysUserService.selectUserById(Long.parseLong(histTask.getAssignee()));
// flowTask.setAssigneeId(sysUser.getUserId());
// flowTask.setAssigneeName(sysUser.getNickName());
// flowTask.setDeptName(sysUser.getDept().getDeptName());
flowTask.setCreateTime(histTask.getCreateTime()); flowTask.setCreateTime(histTask.getCreateTime());
flowTask.setFinishTime(histTask.getEndTime()); flowTask.setFinishTime(histTask.getEndTime());
flowTask.setDuration(getDate(histTask.getDurationInMillis())); flowTask.setDuration(getDate(histTask.getDurationInMillis()));
@ -725,6 +720,7 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
flowTask.setAssigneeName(sysUser.getNickName()); flowTask.setAssigneeName(sysUser.getNickName());
flowTask.setDeptName(sysUser.getDept().getDeptName()); flowTask.setDeptName(sysUser.getDept().getDeptName());
} }
// 展示审批人员
List<HistoricIdentityLink> linksForTask = historyService.getHistoricIdentityLinksForTask(histIns.getTaskId()); List<HistoricIdentityLink> linksForTask = historyService.getHistoricIdentityLinksForTask(histIns.getTaskId());
StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder = new StringBuilder();
for (HistoricIdentityLink identityLink : linksForTask) { for (HistoricIdentityLink identityLink : linksForTask) {
@ -790,39 +786,11 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
*/ */
@Override @Override
public InputStream diagram(String processId) { public InputStream diagram(String processId) {
// HistoricProcessInstance instance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processId).singleResult();
// //获得已经办理的历史节点
// List<HistoricActivityInstance> activityInstances = historyService.createHistoricActivityInstanceQuery().processInstanceId(processId).orderByHistoricActivityInstanceStartTime().asc().list();
// List<String> activties = new ArrayList<>();
// List<String> flows = new ArrayList<>();
// for (HistoricActivityInstance activityInstance : activityInstances) {
// if ("sequenceFlow".equals(activityInstance.getActivityType())) {
// //需要高亮显示的连接线
// flows.add(activityInstance.getActivityId());
// } else {
// //需要高亮显示的节点
// activties.add(activityInstance.getActivityId());
// }
// }
// BpmnModel bpmnModel = repositoryService.getBpmnModel(instance.getProcessDefinitionId());
// //获得图片流
// DefaultProcessDiagramGenerator diagramGenerator = new DefaultProcessDiagramGenerator();
// return diagramGenerator.generateDiagram(
// bpmnModel,
// "png",
// activties,
// flows,
// "宋体",
// "宋体",
// "宋体",
// null,
// 1.0,
// false);
String processDefinitionId; String processDefinitionId;
//1.获取当前的流程实例 // 获取当前的流程实例
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processId).singleResult(); ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processId).singleResult();
if (Objects.isNull(processInstance)) {// 如果流程已经结束,则得到结束节点 // 如果流程已经结束,则得到结束节点
if (Objects.isNull(processInstance)) {
HistoricProcessInstance pi = historyService.createHistoricProcessInstanceQuery().processInstanceId(processId).singleResult(); HistoricProcessInstance pi = historyService.createHistoricProcessInstanceQuery().processInstanceId(processId).singleResult();
processDefinitionId = pi.getProcessDefinitionId(); processDefinitionId = pi.getProcessDefinitionId();
@ -832,10 +800,7 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
processDefinitionId = pi.getProcessDefinitionId(); processDefinitionId = pi.getProcessDefinitionId();
} }
// 获得活动的节点
/**
*
*/
List<HistoricActivityInstance> highLightedFlowList = historyService.createHistoricActivityInstanceQuery().processInstanceId(processId).orderByHistoricActivityInstanceStartTime().asc().list(); List<HistoricActivityInstance> highLightedFlowList = historyService.createHistoricActivityInstanceQuery().processInstanceId(processId).orderByHistoricActivityInstanceStartTime().asc().list();
List<String> highLightedFlows = new ArrayList<>(); List<String> highLightedFlows = new ArrayList<>();
@ -853,10 +818,7 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
//获取流程图 //获取流程图
BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId); BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
ProcessEngineConfiguration configuration = processEngine.getProcessEngineConfiguration(); ProcessEngineConfiguration configuration = processEngine.getProcessEngineConfiguration();
// ProcessDiagramGenerator diagramGenerator = engconf.getProcessDiagramGenerator();
//获取自定义图片生成器 //获取自定义图片生成器
ProcessDiagramGenerator diagramGenerator = new CustomProcessDiagramGenerator(); ProcessDiagramGenerator diagramGenerator = new CustomProcessDiagramGenerator();
InputStream in = diagramGenerator.generateDiagram(bpmnModel, "png", highLightedNodes, highLightedFlows, configuration.getActivityFontName(), InputStream in = diagramGenerator.generateDiagram(bpmnModel, "png", highLightedNodes, highLightedFlows, configuration.getActivityFontName(),
@ -883,6 +845,47 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
} }
} }
/**
*
*
* @param flowTaskVo
* @return
*/
@Override
public AjaxResult getNextFlowNode(FlowTaskVo flowTaskVo) {
Task task = taskService.createTaskQuery().taskId(flowTaskVo.getTaskId()).singleResult();
List<FlowTaskDto> nextNodeList = new ArrayList<>();
if (Objects.nonNull(task)) {
ExecutionEntity ee = (ExecutionEntity) runtimeService.createExecutionQuery()
.executionId(task.getExecutionId()).singleResult();
// 当前审批节点
String crruentActivityId = ee.getActivityId();
BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());
FlowNode flowNode = (FlowNode) bpmnModel.getFlowElement(crruentActivityId);
// 输出连线
List<SequenceFlow> outFlows = flowNode.getOutgoingFlows();
for (SequenceFlow sequenceFlow : outFlows) {
// 下一个审userTask
FlowElement targetFlow = sequenceFlow.getTargetFlowElement();
if (targetFlow instanceof UserTask) {
FlowTaskDto flowTaskDto = new FlowTaskDto();
// 当流程设计时未指定任务接受人员/组时 判定为用户动态选择下一任务审批人
// todo 1. 读取自定义节点属性来验证是否动态选择审批人
// 2. 验证表达式
if (StringUtils.isBlank(((UserTask) targetFlow).getAssignee()) &&
CollectionUtils.isEmpty(((UserTask) targetFlow).getCandidateGroups()) &&
CollectionUtils.isEmpty(((UserTask) targetFlow).getCandidateUsers())) {
flowTaskDto.setTaskDefKey(targetFlow.getId());
flowTaskDto.setTaskName(targetFlow.getName());
nextNodeList.add(flowTaskDto);
}
}
}
}
return AjaxResult.success(nextNodeList);
}
/** /**
* *
* *

@ -46,6 +46,15 @@ export function returnList(data) {
}) })
} }
// 下一节点
export function getNextFlowNode(data) {
return request({
url: '/flowable/task/nextFlowNode',
method: 'post',
data: data
})
}
// 部署流程实例 // 部署流程实例
export function deployStart(deployId) { export function deployStart(deployId) {
return request({ return request({

@ -29,6 +29,15 @@
>{{item.name}}</el-radio-button> >{{item.name}}</el-radio-button>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item label="任务接收" prop="targetKey" v-show="taskForm.noUserShow">
<el-radio-group v-model="taskForm.assignee">
<<el-radio-button
v-for="item in userList"
:key="item.userId"
:label="item.userId"
>{{item.nickName}}</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item label="审批意见" prop="comment" :rules="[{ required: true, message: '请输入意见', trigger: 'blur' }]"> <el-form-item label="审批意见" prop="comment" :rules="[{ required: true, message: '请输入意见', trigger: 'blur' }]">
<el-input style="width: 30%;" type="textarea" v-model="taskForm.comment" placeholder="请输入意见"/> <el-input style="width: 30%;" type="textarea" v-model="taskForm.comment" placeholder="请输入意见"/>
</el-form-item> </el-form-item>
@ -104,8 +113,8 @@
<script> <script>
import { flowRecord } from "@/api/flowable/finished"; import { flowRecord } from "@/api/flowable/finished";
import Parser from '@/components/parser/Parser' import Parser from '@/components/parser/Parser'
import {definitionStart, getProcessVariables } from "@/api/flowable/definition"; import {definitionStart, getProcessVariables, userList } from "@/api/flowable/definition";
import {complete, rejectTask, returnList, returnTask} from "@/api/flowable/todo"; import {complete, rejectTask, returnList, returnTask, getNextFlowNode} from "@/api/flowable/todo";
export default { export default {
name: "Record", name: "Record",
components: { components: {
@ -123,14 +132,17 @@ export default {
variablesForm: {}, // variablesForm: {}, //
taskForm:{ taskForm:{
returnTaskShow: false, // 退 returnTaskShow: false, // 退
defaultTaskShow: true, // defaultTaskShow: true, //
noUserShow: false, //
comment:"", // comment:"", //
procInsId: "", // procInsId: "", //
instanceId: "", // instanceId: "", //
deployId: "", // deployId: "", //
taskId: "" ,// taskId: "" ,//
procDefId: "", // procDefId: "", //
assignee: null
}, },
userList:[], //
formConf: {}, // formConf: {}, //
formConfOpen: false, // formConfOpen: false, //
variables: [], // variables: [], //
@ -218,6 +230,17 @@ export default {
this.variables = res.data.variables; this.variables = res.data.variables;
this.variableOpen = true this.variableOpen = true
}); });
const params = {
taskId: taskId
}
getNextFlowNode(params).then(res => {
if (res.data){
userList().then(res =>{
this.userList = res.data;
this.taskForm.noUserShow = true;
})
}
})
} }
}, },
/** 审批任务 */ /** 审批任务 */
@ -307,12 +330,14 @@ export default {
this.returnTaskList = res.data; this.returnTaskList = res.data;
this.taskForm.returnTaskShow = true; this.taskForm.returnTaskShow = true;
this.taskForm.defaultTaskShow = false; this.taskForm.defaultTaskShow = false;
this.taskForm.noUserShow = false;
}) })
}, },
/** 取消回退任务按钮 */ /** 取消回退任务按钮 */
cancelTask() { cancelTask() {
this.taskForm.returnTaskShow = false; this.taskForm.returnTaskShow = false;
this.taskForm.defaultTaskShow = true; this.taskForm.defaultTaskShow = true;
this.taskForm.noUserShow = true;
this.returnTaskList = []; this.returnTaskList = [];
}, },
/** 提交退回任务 */ /** 提交退回任务 */

Loading…
Cancel
Save