Activiti关于获得用户审批流程的问题

项目里面要用activiti写用户审批流程,在用户审批结束之后,正在运行的流程里面用户审批的流程结束,页面上无法显示已经结束的审批流程。想让大家看看目前做法是否可行,还有没有更简单的方法,这样后期方便维护。

目前用户流程中的审批已经写好,需要添加用户结束的审批流程,并在里面添加必要的流程变量,有没有办法一下都取出来,因为后面要做分页。

图中做了两个query,想分别取出正在运行的审批流程和已经结束的审批流程,但是最后合在一起的话分页会很麻烦,不知道有没有办法将query合并起来。

img

该回答引用ChatGPT

如有疑问,可以回复我!

可以尝试将两个查询(正在运行的审批流程和已结束的审批流程)放在同一个查询中,然后按照创建时间对结果进行排序。这样可以简化查询逻辑,同时也方便进行分页。以下是一个示例代码:


// 获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

// 获取TaskService和HistoryService
TaskService taskService = processEngine.getTaskService();
HistoryService historyService = processEngine.getHistoryService();

// 正在运行的审批流程查询
TaskQuery runningTasksQuery = taskService.createTaskQuery()
    .taskDefinitionKey("Activity_test_Approval")
    .taskCandidateOrAssigned(currentUserId)
    .orderByTaskCreateTime().asc();

// 已结束的审批流程查询
HistoricTaskInstanceQuery finishedTasksQuery = historyService.createHistoricTaskInstanceQuery()
    .taskDefinitionKey("Activity_test_Approval")
    .finished()
    .orderByTaskCreateTime().desc();

// 合并正在运行的审批流程和已结束的审批流程
List<Task> runningTasks = runningTasksQuery.list();
List<HistoricTaskInstance> finishedTasks = finishedTasksQuery.list();

List<Object> allTasks = new ArrayList<>();
allTasks.addAll(runningTasks);
allTasks.addAll(finishedTasks);

// 对结果进行排序
allTasks.sort((task1, task2) -> {
    Date createTime1 = task1 instanceof Task ? ((Task) task1).getCreateTime() : ((HistoricTaskInstance) task1).getCreateTime();
    Date createTime2 = task2 instanceof Task ? ((Task) task2).getCreateTime() : ((HistoricTaskInstance) task2).getCreateTime();
    return createTime1.compareTo(createTime2);
});

// 计算总数
long total = runningTasksQuery.count() + finishedTasksQuery.count();

// 对结果进行分页
int pageSize = 10;
int pageNumber = 1; // 从1开始
List<Object> pagedTasks = allTasks.subList((pageNumber - 1) * pageSize, Math.min(pageNumber * pageSize, allTasks.size()));

这个示例代码首先分别获取正在运行的审批流程和已结束的审批流程,然后将它们合并到一个列表中,并按照创建时间对结果进行排序。接着,计算总数以及进行分页。

这种方法可以简化查询逻辑,并且使分页更加简单。不过,请注意,如果任务数量很大,这种方法可能会导致性能问题。如果您在实际应用中遇到性能问题,可以尝试优化查询逻辑,例如使用原生SQL查询或者其他技术

这个可以将数据转入一个list再分页,否则需要一个游标,很麻烦

参考GPT和自己的思路:您好!根据您的描述,您的目标是使用 Activiti 来管理用户的审批流程,并能够方便地查看正在运行的流程和已经结束的流程。同时,您希望能够将这些查询结果合并,并支持分页功能。

首先,您可以考虑使用 Activiti 提供的 HistoricTaskInstanceQuery 来查询已经结束的审批流程。这个查询会返回所有历史任务实例(包括已经完成的任务)。您可以使用这个查询来获取所有已经结束的审批流程,并根据需要设置查询条件(例如按照任务完成时间排序)。

其次,您可以使用 TaskQuery 来查询正在运行的审批流程。这个查询会返回所有当前运行中的任务实例。您可以根据任务定义 key 或候选人或任务负责人来过滤结果。同样,您也可以设置查询条件(例如按照任务创建时间排序)。

对于合并查询结果并支持分页功能的问题,您可以考虑使用 Java 中的 List 接口来合并查询结果,并在应用程序层面进行分页。具体来说,您可以将 TaskQuery 和 HistoricTaskInstanceQuery 查询结果存储到两个不同的 List 中,并使用 Java 的 addAll() 方法将这两个 List 合并起来。然后,您可以使用 Java 的 subList() 方法来实现分页功能。

下面是一个简单的 Java 代码示例,演示了如何合并 TaskQuery 和 HistoricTaskInstanceQuery 查询结果,并实现分页功能:

List<Task> runningTasks = taskService.createTaskQuery()
        .taskDefinitionKey("Acti wity_test_Approval")
        .taskCandidateOrAssigned(currentUserId)
        .orderByTaskCreateTime().asc()
        .list();

List<HistoricTaskInstance> historicTasks = historyService.createHistoricTaskInstanceQuery()
        .taskDefinitionKey("Activity_test_LApproval")
        .orderByHistoricTaskInstanceEndTime().desc()
        .list();

List<AbstractTaskInstance> allTasks = new ArrayList<>();
allTasks.addAll(runningTasks);
allTasks.addAll(historicTasks);

int total = allTasks.size();
int pageSize = 10;
int pageIndex = 2;
int fromIndex = (pageIndex - 1) * pageSize;
int toIndex = Math.min(pageIndex * pageSize, total);

List<AbstractTaskInstance> pagedTasks = allTasks.subList(fromIndex, toIndex);

这段代码会查询所有符合条件的 Task 和 HistoricTaskInstance 实例,并将它们合并到一个 List 中。然后,它会计算出分页相关的参数,例如 pageSize 和 pageIndex。最后,它会使用 subList() 方法来获取指定页码的任务列表。

希望这些信息能够帮助您解决问题。

生产上为了方便查询,基本上都会自己去维护一个待办任务表,而不依靠工作流的api;
或者可以自己去写sql查询activity的表

参考GPT和自己的思路,建议您可以使用Activiti提供的TaskQuery和HistoricTaskInstanceQuery两个查询接口,将正在运行和已经结束的审批流程查询合并在一起,然后进行分页展示。具体实现可以参考以下代码:

TaskQuery runningTaskQuery = taskService.createTaskQuery()
.taskDefinitionKey("Activity_test_Approval")
.taskCandidateOrAssigned(currentUserId)
.orderByTaskCreateTime().asc();

HistoricTaskInstanceQuery finishedTaskQuery = historyService.createHistoricTaskInstanceQuery()
.taskDefinitionKey("Activity_test_Approval")
.finished()
.orderByHistoricTaskInstanceEndTime().desc();

List<Task> runningTasks = runningTaskQuery.listPage(pageIndex, pageSize);
List<HistoricTaskInstance> finishedTasks = finishedTaskQuery.listPage(pageIndex, pageSize);

// 将正在运行的任务和已经结束的任务合并
List<Task> tasks = new ArrayList<>(runningTasks);
for (HistoricTaskInstance finishedTask : finishedTasks) {
Task task = new TaskEntityImpl();
task.setId(finishedTask.getId());
task.setName(finishedTask.getName());
task.setAssignee(finishedTask.getAssignee());
task.setCreateTime(finishedTask.getStartTime());
task.setExecutionId(finishedTask.getExecutionId());
task.setProcessDefinitionId(finishedTask.getProcessDefinitionId());
task.setProcessInstanceId(finishedTask.getProcessInstanceId());
task.setTaskDefinitionKey(finishedTask.getTaskDefinitionKey());
task.setTaskLocalVariables(finishedTask.getTaskLocalVariables());
task.setProcessVariables(finishedTask.getProcessVariables());
tasks.add(task);
}

// 根据创建时间排序
tasks.sort(Comparator.comparing(Task::getCreateTime));

Long total = runningTaskQuery.count() + finishedTaskQuery.count();

这里首先分别使用TaskQuery和HistoricTaskInstanceQuery查询正在运行和已经结束的审批流程,然后将结果合并在一起,排序后进行分页展示。在合并结果时,需要将HistoricTaskInstance转换为Task对象,这里可以通过创建TaskEntityImpl对象并设置相应属性来实现。

同时,我还注意到您在代码中使用了System.out.println打印信息。建议您使用日志工具来记录日志信息,这样可以更方便地进行管理和维护。

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
首先,如果你想获取已经结束的审批流程,可以使用historyService的相关接口,如下所示:

List<HistoricProcessInstance> processInstanceList = historyService.createHistoricProcessInstanceQuery()
        .finished() // 已结束的流程实例
        .processDefinitionKey("processKey") // 流程定义Key
        .orderByProcessInstanceEndTime().desc() // 按流程实例结束时间倒序排列
        .listPage(start, limit); // 分页查询

其中,processDefinitionKey是流程定义的Key,可以根据需要设置,orderByProcessInstanceEndTime().desc()是按流程实例结束时间倒序排列,以便分页查询。

另外,如果你想将已完成的流程和正在运行的流程一起查询,并按照流程实例开始时间进行排序,可以使用以下代码:

List<ProcessInstance> processInstanceList = runtimeService.createProcessInstanceQuery()
        .processDefinitionKey("processKey") // 流程定义Key
        .orderByProcessInstanceId().desc() // 按流程实例ID倒序排列
        .listPage(start, limit); // 分页查询

List<HistoricProcessInstance> historicProcessInstanceList = historyService.createHistoricProcessInstanceQuery()
        .finished() // 已结束的流程实例
        .processDefinitionKey("processKey") // 流程定义Key
        .orderByProcessInstanceId().desc() // 按流程实例ID倒序排列
        .listPage(start, limit); // 分页查询

List<Map<String, Object>> resultList = new ArrayList<>(processInstanceList.size() + historicProcessInstanceList.size());
for (ProcessInstance pi : processInstanceList) {
    Map<String, Object> map = new HashMap<>();
    map.put("id", pi.getId());
    map.put("name", pi.getName());
    map.put("processDefinitionName", pi.getProcessDefinitionName());
    map.put("startTime", pi.getStartTime());
    map.put("status", "running"); // 运行中
    resultList.add(map);
}
for (HistoricProcessInstance hpi : historicProcessInstanceList) {
    Map<String, Object> map = new HashMap<>();
    map.put("id", hpi.getId());
    map.put("name", hpi.getName());
    map.put("processDefinitionName", hpi.getProcessDefinitionName());
    map.put("startTime", hpi.getStartTime());
    map.put("endTime", hpi.getEndTime());
    map.put("status", "finished"); // 已完成
    resultList.add(map);
}
resultList.sort((o1, o2) -> {
    Date d1 = (Date) o1.get("startTime");
    Date d2 = (Date) o2.get("startTime");
    return d2.compareTo(d1); // 按开始时间倒序排列
});

这里使用了两个query分别查询运行中的流程和已结束的流程,然后将它们合并起来,并按流程实例的开始时间倒序排列。合并后的结果用一个 List<Map<String, Object>> 来表示,其中 status 表示流程实例的状态,可能是运行中或已完成。

希望能对你有所帮助。
如果我的回答解决了您的问题,请采纳!