一、流程定义
/**
* 发布规则文件
*
* @param bpmnName
*/
public void deploy(String bpmnName) {
String bpmn = "templates/bpmn/" + bpmnName + ".bpmn";
String png = "templates/bpmn/" + bpmnName + ".png";
log.debug(String.format("xml:%s,png", bpmn, png));
repositoryService.createDeployment()//创建一个部署对象
.name(bpmnName)//添加部署的名称
.addInputStream(bpmn, this.getClass().getClassLoader().getResourceAsStream(bpmn)).deploy();//完成部署
}
二 、流程发起
这里有个情况要注意,假设流程目前有两个任务节点,申请人发起--》审批人审批,那么在申请人发起流程的同时,调用审批接口自动将当前申请人任务审批通过
@PostMapping(value = "/startProcessInstance")
@ApiOperation(value = "开始流程", notes = "开始流程")
public R startProcessInstance(@RequestBody @Validated @ApiParam(value = "开始流程请求对象") @Valid StartProcessInstanceReq startProcessInstanceReq) {
try {
Map<String, Object> variables = startProcessInstanceReq.getVariables();//流程配置参数
variables.put("applyUserId", startProcessInstanceReq.getApplyUserId());//流程发起人
ProcessInstance processInstance = activitiService.startProcessInstance(startProcessInstanceReq.getInstanceKey(), variables);
log.debug("processInstance:" + processInstance.getProcessDefinitionId());
return R.ok().put("processInstanceId", processInstance.getId());
} catch (Exception e) {
return R.error(-1, e.getMessage());
}
}
@Override
public ProcessInstance startProcessInstance(String instanceKey, Map variables) {
/**
* 启动请假单流程 并获取流程实例
* 因为该请假单流程可以会启动多个所以每启动一个请假单流程都会在数据库中插入一条新版本的流程数据
* 通过key启动的流程就是当前key下最新版本的流程
*
*/
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(instanceKey, variables);
log.debug(String.format("id:%s,activitiId:%s", processInstance.getId(), processInstance.getActivityId()));
return processInstance;
}
三、 流程审批
流程审批的通过和驳回都可以通过画线设置变量的形式实现
@PostMapping(value = "/completeTask")
@ApiOperation(value = "审核任务", notes = "审核任务")
public Result completeTask(@RequestBody @ApiParam(value = "审核任务请求对象") @Valid CompleteTaskReq completeTaskReq) {
try {
Map<String, Object> param = new HashMap<>();
param.put("isFinish", false);//流程是否完成
activitiService.completeTask(completeTaskReq.getTaskId(), completeTaskReq.getAssignee(), completeTaskReq.getVariables(), param);
//流程是否结束
return Result.success(param.get("isFinish"));
} catch (Exception e) {
return Result.error(e.getMessage());
}
}
@Override
public void completeTask(String taskId, String assignee, Map<String, Object> variables, Map<String, Object> param) {
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
if (!StringUtils.isBlank(assignee)) {
taskService.setAssignee(taskId, assignee);
}
taskService.complete(taskId, variables);
}
四、代办已办
这里实现了,代办列表、已办列表的查询,和对于已办列表 根据业务编号RecordId去重查询的功能。
注意点:
taskService.createTaskQuery().taskCandidateOrAssigned(assignee)待办是可以带着候选人和任务指派人,已办的historyService.createHistoricTaskInstanceQuery().taskAssignee("12312")和候选人两个条件是分开的,因此如果你的流程模型只设置了候选人没有设置任务指派人就会查不到
@Override
public List queryWaitTask(int firstResult, int maxResults) {
List<Task> list = taskService.createTaskQuery().listPage(firstResult, maxResults);
return listToBeanVo(list, TaskVo.class, "variables");
}
@Override
public QueryTaskResp queryTaskHistoryList(QueryTaskHistoryListReq queryTaskHistoryReq) {
// 确保有受理人
if (StringUtils.isEmpty(queryTaskHistoryReq.getAssignee())) {
SysUser sysUser = iCommonInitService.GetLoginUser();
queryTaskHistoryReq.setAssignee(sysUser.getUserId());
}
// 创建查询对象并设置条件
HistoricTaskInstanceQuery historicTaskInstanceQuery = historyService.createHistoricTaskInstanceQuery()
.taskAssignee(queryTaskHistoryReq.getAssignee())
.orderByHistoricTaskInstanceStartTime().desc(); // 按开始时间降序排序
// 根据请求条件过滤
Optional.ofNullable(queryTaskHistoryReq.getProcessDefinitionKey())
.filter(processDefinitionKey -> StringUtils.isNotEmpty(processDefinitionKey))
.ifPresent(historicTaskInstanceQuery::processDefinitionKey);
if (queryTaskHistoryReq.getStartTime() != null) {
historicTaskInstanceQuery.taskCreatedAfter(queryTaskHistoryReq.getStartTime());
}
if (queryTaskHistoryReq.getEndTime() != null) {
historicTaskInstanceQuery.taskCreatedBefore(queryTaskHistoryReq.getEndTime());
}
if (queryTaskHistoryReq.getRecordStateId() != null) {
historicTaskInstanceQuery.processVariableValueEquals("recordStateId", queryTaskHistoryReq.getRecordStateId());
}
if (StringUtils.isNotEmpty(queryTaskHistoryReq.getCreatedName())) {
historicTaskInstanceQuery.processVariableValueLike("createdName", queryTaskHistoryReq.getCreatedName());
}
// 获取所有相关的历史任务实例
List<HistoricTaskInstance> allTaskInstances = historicTaskInstanceQuery.list(); // 获取所有符合条件的历史任务实例
if (CollectionUtils.isEmpty(allTaskInstances)) {
return new QueryTaskResp(null, 0);
}
// 使用 Map 去重,保留最近的记录
Map<String, HistoricTaskInstance> recentTasksMap = new HashMap<>();
for (HistoricTaskInstance taskInstance : allTaskInstances) {
// 获取任务的 recordId 变量
HistoricVariableInstance recordIdVariable = historyService.createHistoricVariableInstanceQuery()
.variableName("recordId")
.processInstanceId(taskInstance.getProcessInstanceId())// 根据需要调整查询条件
.singleResult();
String recordId = recordIdVariable != null ? (String) recordIdVariable.getValue() : null;
// 只保留 recordId 不为空的记录,并按最近时间去重
if (recordId != null) {
if (!recentTasksMap.containsKey(recordId) ||
taskInstance.getStartTime().after(recentTasksMap.get(recordId).getStartTime())) {
recentTasksMap.put(recordId, taskInstance);
}
}
}
// 获取去重后的任务实例列表
List<HistoricTaskInstance> recentTasks = new ArrayList<>(recentTasksMap.values());
// 进行分页
long totalRecords = recentTasks.size();
List<HistoricTaskInstance> paginatedList = recentTasks.stream()
.skip((queryTaskHistoryReq.getPageNum() - 1) * queryTaskHistoryReq.getPageSize())
.limit(queryTaskHistoryReq.getPageSize())
.collect(Collectors.toList());
return new QueryTaskResp(returnVariableList(paginatedList), totalRecords);
}