在 Flowable 工作流引擎中,获取历史表单数据是常见的需求,主要用于数据审计、回溯和分析。Flowable 将表单数据以流程变量的形式持久化存储,并通过历史服务提供查询接口。以下是核心方法总结。

📊 一、历史表单数据存储原理

Flowable 中的表单数据(无论是动态表单还是外置表单)在提交后都会转化为流程变量,存储在历史表 ACT_HI_VARINST 或历史详情表 ACT_HI_DETAIL 中。流程实例运行时,数据可能存储在运行时变量表(ACT_RU_VARIABLE)中;流程结束后,运行时数据被清除,但历史表数据会永久保留。

🔍 二、获取历史表单数据的核心方法

1. 通过 HistoryService 查询历史变量

最直接的方式是通过 HistoricVariableInstanceQuery 获取所有流程变量,其中包含表单数据:

HistoryService historyService = processEngine.getHistoryService();
List<HistoricVariableInstance> variables = historyService
    .createHistoricVariableInstanceQuery()
    .processInstanceId("processInstanceId")
    .list();

Map<String, Object> formData = new HashMap<>();
for (HistoricVariableInstance variable : variables) {
    formData.put(variable.getVariableName(), variable.getValue());
}

适用场景:快速获取流程实例中所有表单数据(包括启动表单和任务表单)。

2. 通过 HistoricDetailQuery 查询表单属性详情

如果需要更详细的提交记录(如表单字段的每次提交详情),可使用 HistoricDetailQuery 筛选表单类型数据:

List<HistoricDetail> details = historyService
    .createHistoricDetailQuery()
    .processInstanceId("processInstanceId")
    .formProperties() // 筛选表单提交数据
    .list();

for (HistoricDetail detail : details) {
    if (detail instanceof HistoricFormProperty) {
        HistoricFormProperty formProp = (HistoricFormProperty) detail;
        String fieldId = formProp.getPropertyId();
        String fieldValue = formProp.getPropertyValue();
        // 处理字段数据
    }
}

适用场景:审计日志、数据变更追踪。

3. 查询特定任务节点的历史表单数据

若需获取某个历史任务节点的表单数据,可结合历史任务查询和变量查询:

// 查询历史任务
HistoricTaskInstance task = historyService.createHistoricTaskInstanceQuery()
    .taskId("taskId")
    .singleResult();

// 获取该任务相关的变量
List<HistoricVariableInstance> taskVariables = historyService
    .createHistoricVariableInstanceQuery()
    .taskId("taskId")
    .list();

注意:部分场景下任务变量可能存储在流程实例级变量中,需根据业务设计调整查询方式。

⚙️ 三、外置表单和特殊类型的处理

  • 外置表单:使用 JSON/HTML 定义的表单,其数据同样以流程变量形式存储,因此上述方法完全适用。
  • 文件上传字段:如果表单中包含文件附件,需查询历史详情中的变量更新记录,并自定义反序列化逻辑:
    List<HistoricDetail> fileDetails = historyService
        .createHistoricDetailQuery()
        .processInstanceId(processInstanceId)
        .variableUpdates()
        .list();
    

💡 四、实践建议和注意事项

  1. 性能优化:历史数据量可能很大,建议在查询时添加分页限制(如 .listPage(0, 100)),避免一次性加载过多数据。
  2. 数据类型转换:复杂类型(如日期、JSON)在历史变量中可能以序列化字符串或特殊格式存储,获取后需根据业务逻辑进行转换。
  3. 错误处理:调用查询方法时,应注意捕获 FlowableObjectNotFoundException 等异常,防止无效 ID 导致服务崩溃。
  4. 业务状态关联:如需频繁检查审批状态,建议将关键状态(如 approved)同步到业务表,避免频繁查询历史表。

📋 核心方法对比

下表总结了不同方法的适用场景:

方法 主要接口 适用场景 性能建议
查询历史变量 HistoricVariableInstanceQuery 获取全部表单数据 注意数据量,建议分页
查询表单属性详情 HistoricDetailQuery 审计日志、详细变更记录 数据量大时需分页
查询任务节点变量 HistoricTaskInstanceQuery 获取特定任务节点的数据 目标明确,效率较高

💎 总结

获取 Flowable 历史表单数据主要依靠 HistoryService 提供的查询接口。最通用高效的方法是使用 HistoricVariableInstanceQuery 获取流程实例的所有变量。若需更详细的提交记录,可结合 HistoricDetailQuery

在实际开发中,请根据你的具体需求选择合适的方法,并注意处理大量数据时的性能问题以及复杂数据类型的转换。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐