From 34981c30a78e8bbd7791131059a9210f9928b62c Mon Sep 17 00:00:00 2001
From: 刘光辉 <347230014@qq.com>
Date: 星期四, 17 九月 2026 09:24:09 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master' into master
---
jnpf-flowable/jnpf-flowable-biz/src/main/java/jnpf/flowable/util/RecordUtil.java | 348 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 348 insertions(+), 0 deletions(-)
diff --git a/jnpf-flowable/jnpf-flowable-biz/src/main/java/jnpf/flowable/util/RecordUtil.java b/jnpf-flowable/jnpf-flowable-biz/src/main/java/jnpf/flowable/util/RecordUtil.java
new file mode 100644
index 0000000..493e570
--- /dev/null
+++ b/jnpf-flowable/jnpf-flowable-biz/src/main/java/jnpf/flowable/util/RecordUtil.java
@@ -0,0 +1,348 @@
+package jnpf.flowable.util;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.google.common.collect.ImmutableList;
+import jnpf.flowable.entity.*;
+import jnpf.flowable.enums.*;
+import jnpf.flowable.mapper.*;
+import jnpf.flowable.model.record.ProgressModel;
+import jnpf.flowable.model.record.RecordVo;
+import jnpf.flowable.model.record.UserItem;
+import jnpf.flowable.model.task.FlowModel;
+import jnpf.flowable.model.templatenode.nodejson.NodeModel;
+import jnpf.flowable.model.util.FlowNature;
+import jnpf.permission.entity.UserEntity;
+import jnpf.util.JsonUtil;
+import jnpf.util.RandomUtil;
+import jnpf.util.StringUtil;
+import jnpf.util.UploaderUtil;
+import lombok.RequiredArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 绫荤殑鎻忚堪
+ *
+ * @author JNPF@YinMai Info. Co., Ltd
+ * @version 5.0.x
+ * @since 2024/4/26 17:05
+ */
+@Component
+@RequiredArgsConstructor
+public class RecordUtil {
+
+ private final ServiceUtil serviceUtil;
+
+ private final RecordMapper recordMapper;
+
+ private final CirculateMapper circulateMapper;
+
+ private final OperatorMapper operatorMapper;
+
+ private final EventLogMapper eventLogMapper;
+
+ private final NodeRecordMapper nodeRecordMapper;
+
+ private final TriggerTaskMapper triggerTaskMapper;
+
+ private final TriggerLaunchflowMapper triggerLaunchflowMapper;
+
+
+ /**
+ * 鑾峰彇娴佽浆璁板綍
+ *
+ * @param records 娴佽浆璁板綍闆嗗悎
+ */
+ public List<RecordVo> getRecordList(List<RecordEntity> records) {
+ return getRecordList(records, new ArrayList<>());
+ }
+
+ /**
+ * 鑾峰彇娴佽浆璁板綍
+ *
+ * @param records 娴佽浆璁板綍闆嗗悎
+ */
+ public List<RecordVo> getRecordList(List<RecordEntity> records, List<TemplateNodeEntity> nodeEntities) {
+ List<RecordVo> vos = new ArrayList<>();
+ if (CollUtil.isNotEmpty(records)) {
+ List<UserEntity> userList = serviceUtil.getUserName(records.stream().map(RecordEntity::getHandleId).collect(Collectors.toList()));
+ for (RecordEntity recordEntity : records) {
+ String nodeCode = recordEntity.getNodeCode();
+ RecordVo vo = JsonUtil.getJsonToBean(recordEntity, RecordVo.class);
+ UserEntity userEntity = userList.stream().filter(t -> t.getId().equals(recordEntity.getHandleId())).findFirst().orElse(null);
+ vo.setUserName(userEntity != null ? userEntity.getRealName() + "/" + userEntity.getAccount() : "");
+ if (userEntity != null) {
+ vo.setHeadIcon(UploaderUtil.uploaderImg(userEntity.getHeadIcon()));
+ }
+ // 璁剧疆娴佽浆鎿嶄綔浜�
+ String handleUserId = recordEntity.getHandleUserId();
+ if (StringUtil.isNotEmpty(handleUserId)) {
+ List<String> userIds = Arrays.stream(handleUserId.split(",")).collect(Collectors.toList());
+ List<UserEntity> handleUserList = serviceUtil.getUserName(userIds);
+ List<String> handleUserName = new ArrayList<>();
+ for (String userId : userIds) {
+ UserEntity user = handleUserList.stream().filter(t -> t.getId().equals(userId)).findFirst().orElse(null);
+ if (null != user) {
+ handleUserName.add(user.getRealName() + "/" + user.getAccount());
+ }
+ }
+ if (CollUtil.isNotEmpty(handleUserName)) {
+ vo.setHandleUserName(String.join(",", handleUserName));
+ }
+ }
+ if (recordEntity.getExpandField() != null) {
+ List<Map<String, Object>> expandField = JsonUtil.getJsonToListMap(recordEntity.getExpandField());
+ vo.setApprovalField(expandField);
+ }
+ TemplateNodeEntity templateNode = nodeEntities.stream().filter(e -> Objects.equals(nodeCode, e.getNodeCode())).findFirst().orElse(null);
+ if (templateNode != null) {
+ vo.setIsOutSideNode(Objects.equals(templateNode.getNodeType(), NodeEnum.OUTSIDE.getType()));
+ }
+ vos.add(vo);
+ }
+ }
+ return vos;
+ }
+
+ /**
+ * 杩涘害
+ *
+ * @param flowModel 鍙傛暟
+ */
+ public List<ProgressModel> getProgressList(FlowModel flowModel) {
+ List<ProgressModel> progressList = new ArrayList<>();
+ String opType = flowModel.getOpType();
+ TaskEntity taskEntity = flowModel.getTaskEntity();
+ RecordEntity recordEntity = flowModel.getRecordEntity();
+ List<TemplateNodeEntity> nodeEntities = flowModel.getNodeEntityList();
+
+ List<NodeRecordEntity> nodeRecordList = nodeRecordMapper.getList(taskEntity.getId());
+
+ List<OperatorEntity> operatorList = operatorMapper.getList(taskEntity.getId());
+ List<RecordEntity> recordList = recordMapper.getList(taskEntity.getId());
+ List<EventLogEntity> eventLogList = eventLogMapper.getList(taskEntity.getId());
+ List<CirculateEntity> circulateList = circulateMapper.getList(taskEntity.getId());
+
+ List<String> userIds = new ArrayList<>();
+ List<String> operatorUserIds = operatorList.stream().map(OperatorEntity::getHandleId).collect(Collectors.toList());
+ List<String> recordUserIds = recordList.stream().map(RecordEntity::getHandleId).collect(Collectors.toList());
+ userIds.addAll(operatorUserIds);
+ userIds.addAll(recordUserIds);
+ userIds = userIds.stream().distinct().collect(Collectors.toList());
+
+ List<UserEntity> users = serviceUtil.getUserName(userIds, false);
+
+ for (NodeRecordEntity nodeRecord : nodeRecordList) {
+
+ TemplateNodeEntity nodeEntity = nodeEntities.stream().filter(e -> e.getNodeCode().equals(nodeRecord.getNodeCode())).findFirst().orElse(null);
+
+ if (null != nodeEntity) {
+
+
+ NodeModel nodeModel = JsonUtil.getJsonToBean(nodeEntity.getNodeJson(), NodeModel.class);
+ if (!nodeModel.getType().equals(NodeEnum.SUB_FLOW.getType())) {
+
+
+ ProgressModel model = new ProgressModel();
+ model.setId(RandomUtil.uuId());
+ model.setStartTime(nodeRecord.getCreatorTime().getTime());
+ model.setNodeId(nodeRecord.getNodeId());
+ model.setNodeCode(nodeRecord.getNodeCode());
+ model.setNodeName(nodeRecord.getNodeName());
+ model.setNodeType(NodeEnum.APPROVER.getType());
+ model.setNodeStatus(nodeRecord.getNodeStatus());
+ boolean isCirculate = circulateList.stream().anyMatch(e -> e.getNodeId().equals(nodeRecord.getNodeId()));
+ model.setIsCirculate(isCirculate);
+ List<String> typeList = ImmutableList.of(NodeEnum.START.getType(), NodeEnum.OUTSIDE.getType());
+ if (typeList.contains(nodeModel.getType())) {
+ model.setNodeType(nodeModel.getType());
+ progressList.add(model);
+ continue;
+ }
+
+ model.setCounterSign(nodeModel.getCounterSign());
+ model.setAssigneeType(nodeModel.getAssigneeType());
+
+ List<RecordEntity> records = recordList.stream()
+ .filter(e -> Objects.equals(e.getNodeCode(), nodeModel.getNodeId()) && Objects.equals(e.getNodeId(), nodeRecord.getNodeId()))
+ .sorted(Comparator.comparing(RecordEntity::getHandleTime).reversed()).collect(Collectors.toList());
+
+ model.setApproverCount(records.size());
+
+ List<UserItem> items = new ArrayList<>();
+ for (int i = 0; i < records.size(); i++) {
+ UserItem item = new UserItem();
+ RecordEntity recordEntity1 = records.get(i);
+ UserEntity user = users.stream().filter(e -> ObjectUtil.equals(recordEntity1.getHandleId(), e.getId())).findFirst().orElse(null);
+ if (user != null) {
+ item.setHeadIcon(UploaderUtil.uploaderImg(user.getHeadIcon()));
+ item.setUserId(user.getId());
+ item.setUserName(user.getRealName());
+ } else {
+ item.setHeadIcon(UploaderUtil.uploaderImg(FlowNature.SYSTEM_HEAD_ICON));
+ item.setUserId(FlowNature.SYSTEM_CODE);
+ item.setUserName(FlowNature.SYSTEM_NAME);
+ }
+ item.setHandleType(recordEntity1.getHandleType());
+ items.add(item);
+ if (i == 3) {
+ break;
+ }
+ }
+ model.setApprover(items);
+ // 鍒ゆ柇鏄惁瀛樺湪浠诲姟娴佺▼
+ model.setShowTaskFlow(triggerTaskMapper.existTriggerTask(taskEntity.getId(), model.getNodeId()));
+ progressList.add(model);
+ }
+ }
+ }
+
+ // 褰撳墠鑺傜偣
+ List<Integer> status = ImmutableList.of(TaskStatusEnum.RECALL.getCode(), TaskStatusEnum.BACKED.getCode(), TaskStatusEnum.CANCEL.getCode());
+ if (taskEntity.getEndTime() == null && !status.contains(taskEntity.getStatus())) {
+ String currentNodeCode = taskEntity.getCurrentNodeCode();
+ if (StringUtils.isNotBlank(currentNodeCode)) {
+ List<String> currentCodeList = Arrays.stream(currentNodeCode.split(",")).collect(Collectors.toList());
+
+ for (int i = 0; i < currentCodeList.size(); i++) {
+ String nodeCode = currentCodeList.get(i);
+
+ TemplateNodeEntity nodeEntity = nodeEntities.stream().filter(e -> e.getNodeCode().equals(nodeCode)).findFirst().orElse(null);
+ if (null == nodeEntity) {
+ continue;
+ }
+ NodeModel nodeModel = JsonUtil.getJsonToBean(nodeEntity.getNodeJson(), NodeModel.class);
+ if (nodeModel.getType().equals(NodeEnum.SUB_FLOW.getType())) {
+ continue;
+ }
+
+ boolean isProcessing = ObjectUtil.equals(nodeEntity.getNodeType(), NodeEnum.PROCESSING.getType());
+ boolean isOutside = ObjectUtil.equals(nodeEntity.getNodeType(), NodeEnum.OUTSIDE.getType());
+ ProgressModel model = new ProgressModel();
+ model.setId(RandomUtil.uuId());
+
+ model.setNodeCode(nodeCode);
+ model.setNodeName(nodeModel.getNodeName());
+ String s = isOutside ? NodeEnum.OUTSIDE.getType() : NodeEnum.APPROVER.getType();
+ model.setNodeType(isProcessing ? NodeEnum.PROCESSING.getType() : s);
+ model.setNodeStatus(isProcessing ? NodeStateEnum.TRANSACT.getCode() : NodeStateEnum.APPROVAL.getCode());
+ model.setCounterSign(nodeModel.getCounterSign());
+ model.setAssigneeType(nodeModel.getAssigneeType());
+
+ List<OperatorEntity> operators = operatorList.stream()
+ .filter(e -> Objects.equals(e.getNodeCode(), nodeModel.getNodeId())
+ && !(ObjectUtil.equals(e.getCompletion(), FlowNature.ACTION) && null == e.getHandleTime() && !ObjectUtil.equals(e.getParentId(), FlowNature.PARENT_ID))
+ && !Objects.equals(e.getStatus(), OperatorStateEnum.ASSIST.getCode())
+ && !Objects.equals(e.getStatus(), OperatorStateEnum.FUTILITY.getCode())
+ ).sorted(Comparator.comparing(OperatorEntity::getCreatorTime, Comparator.reverseOrder())
+ .thenComparing(OperatorEntity::getCompletion))
+ .collect(Collectors.toList());
+
+ if (CollUtil.isNotEmpty(operators)) {
+ OperatorEntity operator = operators.get(0);
+ String nodeId = operator.getNodeId();
+ model.setStartTime(operator.getCreatorTime().getTime());
+ operators = operators.stream().filter(e -> ObjectUtil.equals(e.getNodeId(), nodeId)).collect(Collectors.toList());
+ // 瑙﹀彂鑺傜偣閫夋嫨鍚屾锛屽彉鏇翠负绛夊緟涓姸鎬�
+ if (ObjectUtil.equals(operator.getStatus(), OperatorStateEnum.WAITING.getCode())) {
+ model.setNodeStatus(NodeStateEnum.WAIT.getCode());
+ }
+ model.setNodeId(nodeId);
+ boolean isCirculate = circulateList.stream().anyMatch(e -> e.getNodeId().equals(nodeId));
+ model.setIsCirculate(isCirculate);
+ } else {
+ List<EventLogEntity> eventLogs = eventLogList.stream().filter(e -> Objects.equals(e.getNodeCode(), nodeCode)).sorted(Comparator.comparing(EventLogEntity::getCreatorTime, Comparator.reverseOrder())).collect(Collectors.toList());
+ if (CollUtil.isNotEmpty(eventLogs)) {
+ EventLogEntity eventLog = eventLogs.get(0);
+ String nodeId = eventLog.getNodeId();
+ model.setStartTime(eventLog.getCreatorTime().getTime());
+ model.setOutSideStatus(Objects.equals(eventLog.getStatus(), 0));
+ model.setErrorTip(eventLog.getResult());
+ model.setErrorData(eventLog.getData());
+ model.setNodeId(nodeId);
+ if (Objects.equals(OpTypeEnum.LAUNCH_DETAIL.getType(), opType)) {
+ model.setIsRetry(true);
+ }
+ if (Objects.equals(OpTypeEnum.DONE.getType(), opType)
+ && recordEntity != null
+ && Objects.equals(recordEntity.getNodeCode(), eventLog.getUpNode())) {
+ model.setIsRetry(true);
+ }
+
+ }
+ }
+
+ if (StringUtil.isNotEmpty(model.getNodeId())) {
+ // 鍒ゆ柇鏄惁瀛樺湪浠诲姟娴佺▼
+ boolean isTrigger = triggerTaskMapper.existTriggerTask(taskEntity.getId(), model.getNodeId());
+ if (isTrigger) {
+ model.setNodeStatus(NodeStateEnum.WAIT.getCode());
+ }
+ }
+
+
+ List<RecordEntity> records = recordList.stream()
+ .filter(e -> Objects.equals(e.getNodeCode(), nodeModel.getNodeId()))
+ .sorted(Comparator.comparing(RecordEntity::getHandleTime).reversed()).collect(Collectors.toList());
+
+ List<UserItem> items = new ArrayList<>();
+ for (OperatorEntity operator : operators) {
+ UserItem item = new UserItem();
+ UserEntity user = users.stream().filter(e -> ObjectUtil.equals(operator.getHandleId(), e.getId())).findFirst().orElse(null);
+ if (user != null) {
+ item.setHeadIcon(UploaderUtil.uploaderImg(user.getHeadIcon()));
+ item.setUserId(user.getId());
+ item.setUserName(user.getRealName());
+ } else {
+ if (ObjectUtil.equals(operator.getHandleId(), FlowNature.SYSTEM_CODE)) {
+ item.setHeadIcon(FlowNature.SYSTEM_HEAD_ICON);
+ item.setUserName(FlowNature.SYSTEM_NAME);
+ item.setUserId(FlowNature.SYSTEM_CODE);
+ }
+ }
+
+ if (null != operator.getHandleStatus() && null != operator.getHandleTime()) {
+ item.setHandleType(operator.getHandleStatus());
+ } else {
+ RecordEntity recordEntity1 = records.stream().sorted(Comparator.comparing(RecordEntity::getId).reversed())
+ .filter(e -> ObjectUtil.equals(e.getOperatorId(), operator.getId())
+ && ObjectUtil.equals(e.getNodeId(), operator.getNodeId())
+ && !ObjectUtil.equals(e.getStatus(), FlowNature.INVALID)
+ && !ObjectUtil.equals(e.getHandleType(), RecordEnum.BACK.getCode()))
+ .findFirst().orElse(null);
+ if (null != recordEntity1) {
+ item.setHandleType(recordEntity1.getHandleType());
+ } else {
+ // -1.寰呭 -2.鏈 -3.寰呭姙鐞� -4.鏈姙鐞嗭紙鏆傛湭鐢ㄥ埌锛�
+ item.setHandleType(isProcessing ? -3 : -1);
+ }
+ }
+ items.add(item);
+ }
+ model.setApproverCount(items.size());
+ items = items.stream().sorted(Comparator.comparing(UserItem::getHandleType)).collect(Collectors.toList());
+ if (items.size() > 4) {
+ items = items.subList(0, 4);
+ }
+ model.setApprover(items);
+ progressList.add(model);
+ }
+ }
+ }
+
+ // 娣诲姞缁撴潫鑺傜偣
+ if (taskEntity.getEndTime() != null) {
+ ProgressModel model = new ProgressModel();
+ model.setId(RandomUtil.uuId());
+ model.setStartTime(taskEntity.getEndTime().getTime());
+ model.setNodeType(NodeEnum.END.getType());
+ model.setNodeName(FlowNature.END_NAME);
+ progressList.add(model);
+ }
+ return progressList;
+ }
+}
--
Gitblit v1.8.0