|
@@ -54,7 +54,7 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.
|
|
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
|
|
|
|
|
/**
|
|
|
- * 流程任务 Service 实现类
|
|
|
+ * 流程任务实例 Service 实现类
|
|
|
*
|
|
|
* @author jason
|
|
|
* @author 芋道源码
|
|
@@ -66,14 +66,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|
|
@Resource
|
|
|
private TaskService taskService;
|
|
|
@Resource
|
|
|
- private RuntimeService runtimeService;
|
|
|
- @Resource
|
|
|
private HistoryService historyService;
|
|
|
- @Resource
|
|
|
- private RepositoryService repositoryService;
|
|
|
-
|
|
|
- @Resource
|
|
|
- private ProcessDiagramGenerator processDiagramGenerator;
|
|
|
|
|
|
@Resource
|
|
|
private SysUserService userService;
|
|
@@ -118,6 +111,14 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|
|
return BpmTaskConvert.INSTANCE.convertList3(tasks, bpmTaskExtDOMap, processInstance, userMap, deptMap);
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public List<Task> getTasksByProcessInstanceId(String processInstanceId) {
|
|
|
+ if (StrUtil.isEmpty(processInstanceId)) {
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+ return taskService.createTaskQuery().processInstanceId(processInstanceId).list();
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public List<Task> getTasksByProcessInstanceIds(List<String> processInstanceIds) {
|
|
|
if (CollUtil.isEmpty(processInstanceIds)) {
|
|
@@ -270,129 +271,6 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|
|
// taskService.addComment(task.getId(), task.getProcessInstanceId(), reqVO.getComment());
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public FileResp getHighlightImg(String processInstanceId) {
|
|
|
- // 查询历史
|
|
|
- //TODO 云扬四海 貌似流程结束后,点击审批进度会报错
|
|
|
- // TODO @Li:一些 historyService 的查询,貌似比较通用,是不是抽一些小方法出来
|
|
|
- HistoricProcessInstance hpi = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
|
|
|
- // 如果不存在实例。 说明数据异常
|
|
|
- if (hpi == null) {
|
|
|
-// throw exception(PROCESS_INSTANCE_NOT_EXISTS);
|
|
|
- throw new RuntimeException("不存在");
|
|
|
- }
|
|
|
- // 如果有结束时间 返回model的流程图
|
|
|
- if (!ObjectUtils.isEmpty(hpi.getEndTime())) {
|
|
|
- ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().processDefinitionId(hpi.getProcessDefinitionId()).singleResult();
|
|
|
- String resourceName = Optional.ofNullable(pd.getDiagramResourceName()).orElse(pd.getResourceName());
|
|
|
- BpmnModel bpmnModel = repositoryService.getBpmnModel(pd.getId());
|
|
|
- InputStream inputStream = processDiagramGenerator.generateDiagram(bpmnModel, new ArrayList<>(1), new ArrayList<>(1),
|
|
|
- "宋体", "宋体", "宋体");
|
|
|
- FileResp fileResp = new FileResp();
|
|
|
- fileResp.setFileName( resourceName + ".svg");
|
|
|
- fileResp.setFileByte(IoUtil.readBytes(inputStream));
|
|
|
- return fileResp;
|
|
|
- }
|
|
|
- // 没有结束时间。说明流程在执行过程中
|
|
|
- // TODO @Li:一些 runtimeService 的查询,貌似比较通用,是不是抽一些小方法出来
|
|
|
- ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
|
|
|
-
|
|
|
- List<String> highLightedActivities = new ArrayList<>();
|
|
|
- // 获取所有活动节点
|
|
|
- List<HistoricActivityInstance> finishedInstances = historyService.createHistoricActivityInstanceQuery()
|
|
|
- .processInstanceId(processInstanceId).finished().list();
|
|
|
- finishedInstances.stream().map(HistoricActivityInstance::getActivityId)
|
|
|
- .forEach(highLightedActivities::add);
|
|
|
- // 已完成的节点+当前节点
|
|
|
- highLightedActivities.addAll(runtimeService.getActiveActivityIds(processInstanceId));
|
|
|
-
|
|
|
- BpmnModel bpmnModel = repositoryService.getBpmnModel(pi.getProcessDefinitionId());
|
|
|
- // 经过的流
|
|
|
- List<String> highLightedFlowIds = getHighLightedFlows(bpmnModel, processInstanceId);
|
|
|
-
|
|
|
- //设置"宋体"
|
|
|
- try (InputStream inputStream = processDiagramGenerator.generateDiagram(bpmnModel, highLightedActivities, highLightedFlowIds,
|
|
|
- "宋体", "宋体", "宋体")){
|
|
|
- FileResp fileResp = new FileResp();
|
|
|
- fileResp.setFileName( hpi.getProcessDefinitionName() + ".svg");
|
|
|
- fileResp.setFileByte(IoUtil.readBytes(inputStream));
|
|
|
- return fileResp;
|
|
|
- } catch (IOException e) {
|
|
|
- log.error("[getHighlightImg][流程({}) 生成图表失败]", processInstanceId, e);
|
|
|
- throw exception(HIGHLIGHT_IMG_ERROR);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // TODO @Li:这个方法的可读性还有一定的优化空间,可以思考下哈。
|
|
|
- /**
|
|
|
- * 获取指定 processInstanceId 已经高亮的Flows
|
|
|
- * 获取已经流转的线 参考: https://blog.csdn.net/qiuxinfa123/article/details/119579863
|
|
|
- * @param bpmnModel model
|
|
|
- * @param processInstanceId 流程实例Id
|
|
|
- * @return 获取已经流转的列表
|
|
|
- */
|
|
|
- private List<String> getHighLightedFlows(BpmnModel bpmnModel, String processInstanceId) {
|
|
|
- // 获取所有的线条
|
|
|
- List<HistoricActivityInstance> historicActivityInstances = historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId)
|
|
|
- .orderByHistoricActivityInstanceId().asc().list();
|
|
|
- // 高亮流程已发生流转的线id集合
|
|
|
- List<String> highLightedFlowIds = new ArrayList<>();
|
|
|
- // 全部活动节点
|
|
|
- List<FlowNode> historicActivityNodes = new ArrayList<>();
|
|
|
- // 已完成的历史活动节点
|
|
|
- List<HistoricActivityInstance> finishedActivityInstances = new ArrayList<>();
|
|
|
-
|
|
|
- for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) {
|
|
|
- FlowNode flowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(historicActivityInstance.getActivityId(), true);
|
|
|
- historicActivityNodes.add(flowNode);
|
|
|
- // 结束时间不为空,则是已完成节点
|
|
|
- if (historicActivityInstance.getEndTime() != null) {
|
|
|
- finishedActivityInstances.add(historicActivityInstance);
|
|
|
- }
|
|
|
- }
|
|
|
- // 提取活动id 是唯一的。塞入Map
|
|
|
- Map<String, HistoricActivityInstance> historicActivityInstanceMap = CollectionUtils.convertMap(historicActivityInstances, HistoricActivityInstance::getActivityId);
|
|
|
- // 遍历已完成的活动实例,从每个实例的outgoingFlows中找到已执行的
|
|
|
- for (HistoricActivityInstance currentActivityInstance : finishedActivityInstances) {
|
|
|
- // 获得当前活动对应的节点信息及outgoingFlows信息
|
|
|
- FlowNode currentFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(currentActivityInstance.getActivityId(), true);
|
|
|
- List<SequenceFlow> sequenceFlows = currentFlowNode.getOutgoingFlows();
|
|
|
-
|
|
|
- // 遍历outgoingFlows并找到已流转的 满足如下条件认为已已流转:
|
|
|
- // 1.当前节点是并行网关或兼容网关,则通过outgoingFlows能够在历史活动中找到的全部节点均为已流转
|
|
|
- // 2.当前节点是以上两种类型之外的,通过outgoingFlows查找到的时间最早的流转节点视为有效流转
|
|
|
- if (BpmnXMLConstants.ELEMENT_GATEWAY_PARALLEL.equals(currentActivityInstance.getActivityType())
|
|
|
- || BpmnXMLConstants.ELEMENT_GATEWAY_INCLUSIVE.equals(currentActivityInstance.getActivityType())) {
|
|
|
- // 遍历历史活动节点,找到匹配流程目标节点的
|
|
|
- for (SequenceFlow sequenceFlow : sequenceFlows) {
|
|
|
- FlowNode targetFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(sequenceFlow.getTargetRef(), true);
|
|
|
- if (historicActivityNodes.contains(targetFlowNode)) {
|
|
|
- highLightedFlowIds.add(targetFlowNode.getId());
|
|
|
- }
|
|
|
- }
|
|
|
- } else {
|
|
|
- long earliestStamp = 0L;
|
|
|
- String highLightedFlowId = null;
|
|
|
- // 循环流出的流
|
|
|
- for (SequenceFlow sequenceFlow : sequenceFlows) {
|
|
|
- HistoricActivityInstance historicActivityInstance = historicActivityInstanceMap.get(sequenceFlow.getTargetRef());
|
|
|
- if (historicActivityInstance == null) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- final long startTime = historicActivityInstance.getStartTime().getTime();
|
|
|
- // 遍历匹配的集合,取得开始时间最早的一个
|
|
|
- if (earliestStamp == 0 || earliestStamp >= startTime) {
|
|
|
- highLightedFlowId = sequenceFlow.getId();
|
|
|
- earliestStamp = startTime;
|
|
|
- }
|
|
|
- }
|
|
|
- highLightedFlowIds.add(highLightedFlowId);
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
- return highLightedFlowIds;
|
|
|
- }
|
|
|
-
|
|
|
private Task getTask(String id) {
|
|
|
return taskService.createTaskQuery().taskId(id).singleResult();
|
|
|
}
|