|
@@ -0,0 +1,133 @@
|
|
|
|
|
+/**
|
|
|
|
|
+ * Copyright © 2021-2026 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
|
|
|
|
|
+ */
|
|
|
|
|
+package com.jeeplus.flowable.service;
|
|
|
|
|
+
|
|
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
+import org.flowable.engine.impl.persistence.entity.HistoricActivityInstanceEntityImpl;
|
|
|
|
|
+import org.flowable.engine.history.HistoricActivityInstance;
|
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
+import org.springframework.jdbc.core.JdbcTemplate;
|
|
|
|
|
+import org.springframework.jdbc.core.RowMapper;
|
|
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
|
|
+
|
|
|
|
|
+import java.sql.ResultSet;
|
|
|
|
|
+import java.sql.SQLException;
|
|
|
|
|
+import java.sql.Timestamp;
|
|
|
|
|
+import java.util.*;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 流程归档数据查询服务(冷表回查)
|
|
|
|
|
+ * 当热表中查不到数据时,从归档表中查询历史数据
|
|
|
|
|
+ *
|
|
|
|
|
+ * @author jeeplus
|
|
|
|
|
+ * @version 2024-01-01
|
|
|
|
|
+ */
|
|
|
|
|
+@Slf4j
|
|
|
|
|
+@Service
|
|
|
|
|
+public class FlowArchiveService {
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private JdbcTemplate jdbcTemplate;
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 从归档表查询活动实例列表
|
|
|
|
|
+ */
|
|
|
|
|
+ public List<HistoricActivityInstance> findActivityInstances(String processInstanceId) {
|
|
|
|
|
+ String sql = "SELECT * FROM act_hi_actinst_archive WHERE PROC_INST_ID_ = ? ORDER BY START_TIME_ ASC";
|
|
|
|
|
+ return jdbcTemplate.query(sql, new Object[]{processInstanceId}, new HistoricActivityInstanceRowMapper());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 从归档表查询已结束的活动实例列表
|
|
|
|
|
+ */
|
|
|
|
|
+ public List<HistoricActivityInstance> findFinishedActivityInstances(String processInstanceId) {
|
|
|
|
|
+ String sql = "SELECT * FROM act_hi_actinst_archive WHERE PROC_INST_ID_ = ? AND END_TIME_ IS NOT NULL ORDER BY END_TIME_ ASC";
|
|
|
|
|
+ return jdbcTemplate.query(sql, new Object[]{processInstanceId}, new HistoricActivityInstanceRowMapper());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 从归档表查询历史流程实例
|
|
|
|
|
+ */
|
|
|
|
|
+ public Map<String, Object> findHistoricProcessInstance(String processInstanceId) {
|
|
|
|
|
+ String sql = "SELECT * FROM act_hi_procinst_archive WHERE PROC_INST_ID_ = ?";
|
|
|
|
|
+ List<Map<String, Object>> result = jdbcTemplate.queryForList(sql, processInstanceId);
|
|
|
|
|
+ return result.isEmpty() ? null : result.get(0);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 从归档表查询历史变量
|
|
|
|
|
+ */
|
|
|
|
|
+ public List<Map<String, Object>> findHistoricVariables(String processInstanceId) {
|
|
|
|
|
+ String sql = "SELECT * FROM act_hi_varinst_archive WHERE PROC_INST_ID_ = ?";
|
|
|
|
|
+ return jdbcTemplate.queryForList(sql, processInstanceId);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 从归档表查询指定流程变量的值
|
|
|
|
|
+ */
|
|
|
|
|
+ public Map<String, Object> findHistoricVariable(String processInstanceId, String variableName) {
|
|
|
|
|
+ String sql = "SELECT * FROM act_hi_varinst_archive WHERE PROC_INST_ID_ = ? AND NAME_ = ?";
|
|
|
|
|
+ List<Map<String, Object>> result = jdbcTemplate.queryForList(sql, processInstanceId, variableName);
|
|
|
|
|
+ return result.isEmpty() ? null : result.get(0);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 从归档表查询任务评论
|
|
|
|
|
+ */
|
|
|
|
|
+ public List<Map<String, Object>> findTaskComments(String taskId) {
|
|
|
|
|
+ String sql = "SELECT * FROM act_hi_comment_archive WHERE TASK_ID_ = ? ORDER BY TIME_ DESC";
|
|
|
|
|
+ return jdbcTemplate.queryForList(sql, taskId);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 从归档表查询历史任务实例
|
|
|
|
|
+ */
|
|
|
|
|
+ public List<Map<String, Object>> findHistoricTaskInstances(String processInstanceId) {
|
|
|
|
|
+ String sql = "SELECT * FROM act_hi_taskinst_archive WHERE PROC_INST_ID_ = ?";
|
|
|
|
|
+ return jdbcTemplate.queryForList(sql, processInstanceId);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 检查流程实例是否在归档表中
|
|
|
|
|
+ */
|
|
|
|
|
+ public boolean isArchived(String processInstanceId) {
|
|
|
|
|
+ String sql = "SELECT COUNT(1) FROM act_hi_procinst_archive WHERE PROC_INST_ID_ = ?";
|
|
|
|
|
+ Integer count = jdbcTemplate.queryForObject(sql, Integer.class, processInstanceId);
|
|
|
|
|
+ return count != null && count > 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * HistoricActivityInstance 行映射器
|
|
|
|
|
+ * 将归档表数据映射为 Flowable 的 HistoricActivityInstance 对象
|
|
|
|
|
+ */
|
|
|
|
|
+ private static class HistoricActivityInstanceRowMapper implements RowMapper<HistoricActivityInstance> {
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public HistoricActivityInstance mapRow(ResultSet rs, int rowNum) throws SQLException {
|
|
|
|
|
+ HistoricActivityInstanceEntityImpl entity = new HistoricActivityInstanceEntityImpl();
|
|
|
|
|
+ entity.setId(rs.getString("ID_"));
|
|
|
|
|
+ entity.setRevision(rs.getInt("REV_"));
|
|
|
|
|
+ entity.setProcessDefinitionId(rs.getString("PROC_DEF_ID_"));
|
|
|
|
|
+ entity.setProcessInstanceId(rs.getString("PROC_INST_ID_"));
|
|
|
|
|
+ entity.setExecutionId(rs.getString("EXECUTION_ID_"));
|
|
|
|
|
+ entity.setActivityId(rs.getString("ACT_ID_"));
|
|
|
|
|
+ entity.setTaskId(rs.getString("TASK_ID_"));
|
|
|
|
|
+ // entity.setCallProcessInstanceId - 跳过,非关键字段
|
|
|
|
|
+ entity.setActivityName(rs.getString("ACT_NAME_"));
|
|
|
|
|
+ entity.setActivityType(rs.getString("ACT_TYPE_"));
|
|
|
|
|
+ entity.setAssignee(rs.getString("ASSIGNEE_"));
|
|
|
|
|
+ Timestamp startTime = rs.getTimestamp("START_TIME_");
|
|
|
|
|
+ if (startTime != null) {
|
|
|
|
|
+ entity.setStartTime(new Date(startTime.getTime()));
|
|
|
|
|
+ }
|
|
|
|
|
+ Timestamp endTime = rs.getTimestamp("END_TIME_");
|
|
|
|
|
+ if (endTime != null) {
|
|
|
|
|
+ entity.setEndTime(new Date(endTime.getTime()));
|
|
|
|
|
+ }
|
|
|
|
|
+ entity.setDurationInMillis(rs.getLong("DURATION_"));
|
|
|
|
|
+ entity.setDeleteReason(rs.getString("DELETE_REASON_"));
|
|
|
|
|
+ entity.setTenantId(rs.getString("TENANT_ID_"));
|
|
|
|
|
+ return entity;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|