低代码表单怎么和 Flowable 工作流整合?ForgeAdmin 的 3 种数据模式设计
低代码表单怎么和 Flowable 工作流整合Forge 的 3 种数据模式设计低代码搭表单、Flowable 跑审批这两件事单独做都不难。难的是合在一起表单数据要不要落业务表流程变量怎么传审批中途数据存哪这篇拆 Forge 的真实实现看它怎么用 3 种数据模式解决这个整合难题。做过审批系统的人都知道低代码表单和工作流引擎之间有一道缝低代码表单负责收集数据请假天数、报销金额、采购明细工作流引擎负责驱动流程谁审批、怎么流转、什么时候结束但这两边的数据怎么流动是最容易出问题的地方。请假审批的表单数据是只存在流程变量里还是落到业务表还是两边都存不同选择后续的查询、统计、数据权限完全不同。Forge Admin 在这块做了一个很清晰的设计用 3 种数据模式dataMode来定义表单数据和流程的关系。这篇就拆这个设计。一、先看清楚整合的 4 个核心实体Forge 的流程和低代码整合核心是 4 张表的关系。看懂这张图后面的设计就清楚了FlowForm流程表单定义 │ formSchema: JSON 格式的表单协议字段、类型、校验 │ formType: dynamic(动态表单) / external(外部表单) / builtin(内置表单) │ ▼ FlowEntry流程入口 │ modelKey: 绑定哪个流程模型Flowable BPMN │ formKey: 绑定哪个表单FlowForm │ dataMode: 数据模式PROCESS_ONLY / BUSINESS_OBJECT / HYBRID │ objectCode:业务对象编码落哪张业务表 │ ├──► FlowEntryFieldMapping字段映射 │ formField → 表单字段 │ targetField → 业务对象字段 │ flowVariable → 流程变量 │ ▼ FlowFormInstance填报实例快照 │ schemaSnapshot: 提交时的表单 schema 快照 │ formData: 用户填的数据 │ processInstanceId: 关联的流程实例 │ objectCode recordId: 关联的业务记录用一句话说清楚FlowForm定义表单长什么样低代码表单设计器产出FlowEntry是流程入口把表单和流程模型绑在一起并决定数据怎么处理FlowEntryFieldMapping定义表单字段怎么映射到业务表和流程变量FlowFormInstance是每次提交的快照保存当时填的数据和表单结构二、核心设计3 种数据模式整合的难点不在表单怎么渲染而在表单数据提交后怎么处理。Forge 定义了 3 种模式对应 3 种业务场景。模式一PROCESS_ONLY纯流程模式表单数据只存在流程变量里不落业务表。用户填表单 → 表单数据作为流程变量 → 流程流转 → 结束适用场景简单的审批不需要事后查询业务数据。比如请假审批。审批通过后人事在考勤表里手动记录就行不需要自动落一张请假记录表。优点简单不用建业务表不用写字段映射。缺点事后查数据只能查流程历史不能像查业务表那样分页、筛选、统计。模式二BUSINESS_OBJECT业务对象模式表单数据通过字段映射落到业务表里流程里不存表单数据。用户填表单 → 字段映射 → 落业务表 → 流程变量只存关键字段 → 流程流转适用场景审批完要当业务数据用的场景。比如采购审批。采购单审批通过后要变成一条采购记录后续要查询、统计、对账。这种场景必须落业务表。优点数据在业务表里可以正常查询、分页、做数据权限、做统计看板。缺点要建业务表、配字段映射、实现业务对象适配器。模式三HYBRID混合模式表单数据既落业务表又留一份快照在流程侧。用户填表单 → 字段映射 → 落业务表 ↘ 同时存一份 FlowFormInstance 快照 流程变量存关键字段 → 流程流转适用场景既要业务表查询又要追溯提交时表单长什么样。比如合同审批。合同审批通过后要落合同表BUSINESS_OBJECT但三个月后可能要查当时提交审批时填了什么——如果表单结构改过纯业务表无法还原当时的填报内容。HYBRID 模式存了一份 schemaSnapshot formData可以完整还原。优点业务表可查 快照可追溯最完整。缺点数据存两份存储成本略高。三、源码怎么实现的直接看FlowRuntimeServiceImpl.submitByMode()这是整合的核心入口privateFlowStartResultVOsubmitByMode(FlowEntryRuntimeVOruntime,ListFlowEntryFieldMappingmappings,MapString,ObjectformData,FlowEntrySubmitDTOdto,StringdataMode){FlowEntryentryruntime.getEntry();if(BUSINESS_OBJECT.equals(dataMode)){returnsubmitBusinessObject(entry,mappings,formData,dto,false);}if(HYBRID.equals(dataMode)){returnsubmitBusinessObject(entry,mappings,formData,dto,true);}returnsubmitProcessOnly(runtime,mappings,formData,dto);}就 3 个分支对应 3 种模式。BUSINESS_OBJECT 和 HYBRID 走同一个方法区别在keepSnapshot参数。PROCESS_ONLY 怎么处理纯流程模式最简单把表单数据塞进流程变量发起流程完事。privateFlowStartResultVOsubmitProcessOnly(...){// 1. 构建流程变量MapString,ObjectvariablesbuildFlowVariables(formData,mappings,dto);// 2. 创建表单实例记录只存基础信息不存快照FlowFormInstanceinstancenewFlowFormInstance();instance.setDataMode(PROCESS_ONLY);instance.setFormData(toJson(formData));formInstanceMapper.insert(instance);// 3. 发起流程StringprocessInstanceIdflowInstanceService.startProcess(entry.getModelKey(),businessKey,...,variables,...);// 4. 关联回表单实例formInstanceMapper.updateProcessInstance(instanceId,processInstanceId,RUNNING);returnresult;}BUSINESS_OBJECT / HYBRID 怎么处理这两种模式要落业务表核心靠FlowBusinessObjectRuntimeAdapter这个扩展点privateFlowStartResultVOsubmitBusinessObject(FlowEntryentry,ListFlowEntryFieldMappingmappings,MapString,ObjectformData,FlowEntrySubmitDTOdto,booleankeepSnapshot){// 1. 调用业务侧适配器把表单数据落成业务记录BusinessRecordCreateResultrecordbusinessObjectRuntimeAdapter.createBusinessRecord(entry,mappings,formData);// 2. 构建流程变量从字段映射里取MapString,ObjectvariablesbuildFlowVariables(formData,mappings,dto);// 3. HYBRID 模式额外存一份快照if(keepSnapshot){FlowFormInstanceinstancenewFlowFormInstance();instance.setSchemaSnapshot(runtime.getFormVersion().getFormSchema());instance.setFieldRegistry(runtime.getFormVersion().getFieldRegistry());instance.setFormData(toJson(formData));instance.setDataMode(HYBRID);instance.setObjectCode(objectCode);instance.setRecordId(record.getRecordId());// 关联业务记录formInstanceMapper.insert(instance);variables.put(flowFormInstanceId,String.valueOf(formInstanceId));}// 4. 发起流程StringprocessInstanceIdflowInstanceService.startProcess(...);returnresult;}四、关键解耦FlowBusinessObjectRuntimeAdapter注意上面代码里的businessObjectRuntimeAdapter.createBusinessRecord()。这是整个整合设计里最巧妙的一步。问题流程插件要把表单数据落业务表但业务表是业务模块定义的流程插件不知道你的biz_purchase表长什么样。如果让流程插件直接依赖业务模块架构就耦合了——流程插件要认识采购表、合同表、报销表……每加一个业务就要改流程插件。Forge 的解法流程插件定义一个扩展点接口由业务侧实现publicinterfaceFlowBusinessObjectRuntimeAdapter{BusinessRecordCreateResultcreateBusinessRecord(FlowEntryentry,// 流程入口配置ListFlowEntryFieldMappingmappings,// 字段映射规则MapString,ObjectformData// 用户填的表单数据);DataclassBusinessRecordCreateResult{privateStringobjectCode;// 业务对象编码privateLongrecordId;// 业务记录IDprivateStringbusinessKey;// 业务键privateMapString,Objectvariables;// 额外流程变量}}源码注释写得很明确Flow 插件不直接依赖低代码 generator 插件需要 BUSINESS_OBJECT/HYBRID 时由业务侧提供实现把表单数据映射为业务对象记录。业务侧怎么实现ComponentpublicclassPurchaseFlowAdapterimplementsFlowBusinessObjectRuntimeAdapter{AutowiredprivatePurchaseMapperpurchaseMapper;OverridepublicBusinessRecordCreateResultcreateBusinessRecord(FlowEntryentry,ListFlowEntryFieldMappingmappings,MapString,ObjectformData){// 1. 按字段映射把表单数据组装成业务对象PurchasepurchasenewPurchase();for(FlowEntryFieldMappingmapping:mappings){ObjectvalueformData.get(mapping.getFormField());// 反射或手动 set 到业务对象setFieldValue(purchase,mapping.getTargetField(),value);}// 2. 落业务表purchaseMapper.insert(purchase);// 3. 返回业务记录信息BusinessRecordCreateResultresultnewBusinessRecordCreateResult();result.setObjectCode(purchase);result.setRecordId(purchase.getId());result.setBusinessKey(purchase:purchase.getId());returnresult;}}这样流程插件和业务模块完全解耦流程插件只管调适配器、拿记录ID、发起流程业务模块只管按映射规则把表单数据落表字段映射关系在FlowEntryFieldMapping表里配置不用写代码五、字段映射表单字段怎么变成业务数据和流程变量FlowEntryFieldMapping是连接表单和流程/业务表的桥梁publicclassFlowEntryFieldMapping{privateStringformField;// 表单字段名privateStringtargetType;// 映射目标类型业务字段 / 流程变量privateStringtargetField;// 目标字段名privateStringflowVariable;// 流程变量名privateIntegerrequired;// 是否必填}一个表单字段可以同时映射到两个地方表单字段 days请假天数 ├── targetTypeBUSINESS_FIELD, targetFieldleave_days → 落业务表 └── targetTypeFLOW_VARIABLE, flowVariabledays → 流程变量条件分支用这样设计的好处是业务表存完整数据查询、统计、数据权限用流程变量只存条件判断需要的关键字段流程分支用比如days 3走老板审批映射关系可配置不用写代码六、表单类型不只是动态表单FlowForm支持三种表单类型privateStringformType;// dynamic / external / builtin类型说明适用场景dynamic动态表单formSchema 是 JSON 协议运行时渲染标准审批表单请假、报销external外部表单指向一个 URL已有业务页面接审批builtin内置表单指定前端组件路径定制化程度高的表单dynamic类型就是低代码表单和流程整合的核心低代码表单设计器产出的 JSON Schema 存到formSchema字段流程审批时运行时引擎按这个 Schema 渲染表单。external类型则给已有业务页面留了路你的采购管理页面已经做好了只需要在审批时跳过去填不用重新用低代码搭一遍。这种设计保证了整合不是强制的——你可以全用低代码动态表单也可以对接已有页面不用为了用流程引擎就把所有表单重做。七、快照机制为什么 HYBRID 要存两份HYBRID 模式下FlowFormInstance存了这些字段privateStringschemaSnapshot;// 提交时的表单 Schema 快照privateStringfieldRegistry;// 字段目录快照privateStringformData;// 用户填的数据privateStringdataMode;// HYBRIDprivateStringobjectCode;// 业务对象编码privateLongrecordId;// 业务记录ID为什么要存快照因为表单结构会变。假设 3 月你用 v1 版表单提交了采购审批表单有采购金额字段。5 月业务方加了采购用途字段表单变成 v2。如果只存业务表数据3 月的那条采购记录没有采购用途——这没问题。但如果你想在审批历史里还原3 月提交时表单长什么样没有快照就做不到。快照保存的是提交那一刻的表单结构 数据。无论表单后续怎么改历史记录都能完整还原。这对合规审计很重要——政务、金融场景经常要求可追溯当时填了什么、表单是什么样的。八、完整链路从填表到审批的 6 步把整个整合链路串一遍1. 管理员在低代码表单设计器里设计表单 → 存 FlowFormformSchema 2. 管理员创建 FlowEntry绑定 modelKey formKey dataMode 字段映射 3. 用户在待办页面点发起审批 → 运行时加载 FlowEntry FlowForm 4. 运行时引擎按 formSchema 渲染表单 → 用户填写 5. 提交 → FlowRuntimeServiceImpl.submitEntryForm() ├── PROCESS_ONLY表单数据 → 流程变量 → 发起流程 ├── BUSINESS_OBJECT表单数据 → 字段映射 → 落业务表 → 发起流程 └── HYBRID落业务表 存快照 → 发起流程 6. 流程结束 → FlowCallback 回调业务 → 更新业务状态九、和纯 Flowable 接入的关系上一篇《Spring Boot 接 Flowable用 3 个注解搭一个请假审批流程》讲的是业务侧怎么用FlowStart/FlowCallback接流程——那适合已有业务表想加审批的场景。这篇讲的是低代码表单和流程的深度整合——适合用低代码搭表单 走审批 数据落表的场景。两者的关系对比注解化接入FlowStart低代码整合FlowEntry表单来源业务模块自己的页面低代码表单设计器数据存储业务模块自己管由 dataMode 决定字段映射不需要业务方法直接处理FlowEntryFieldMapping 配置适用场景已有业务系统加审批从零搭审批表单 流程 落表侵入性加注解配置化几乎无侵入两条路按场景选已有业务表用注解从零搭用低代码整合。十、总结整合的核心是数据模式 字段映射 扩展点低代码和 Flowable 的整合核心不是表单怎么渲染那是低代码的事而是表单数据提交后怎么和流程、业务表三者协同。Forge 的设计可以总结为 3 层层机制解决什么数据模式PROCESS_ONLY / BUSINESS_OBJECT / HYBRID表单数据存哪字段映射FlowEntryFieldMapping表单字段怎么变成业务数据和流程变量扩展点FlowBusinessObjectRuntimeAdapter流程插件和业务模块解耦这 3 层做到了不耦合流程插件不认识业务表通过扩展点对接可配置字段映射在后台配不改代码可追溯HYBRID 模式存快照历史可还原可选择3 种模式按场景选不是一刀切这才是低代码和工作流整合该有的设计——不是把两边硬拼在一起而是用清晰的数据模式定义边界用扩展点解耦用字段映射做桥梁。源码自取本文所有代码片段均来自仓库可对照核验Giteehttps://gitee.com/ForgeLab/forge-adminGitHubhttps://github.com/yaomindong1996/forge-admin在线演示http://www.dlforgelab.com:8084/forge/login admin / 123456你们的审批表单和工作流是怎么整合的表单数据落业务表还是只存流程变量评论区聊聊。

相关新闻

武清常年手脚冰凉、气色差的女性!提供给你们一套四季温和食补、养护全方案

武清常年手脚冰凉、气色差的女性!提供给你们一套四季温和食补、养护全方案

免责说明:本文仅居家养生、食补养护科普分享,不构成诊疗指导。若长期体虚、经期严重不适,建议前往正规中医院辨证调理,文中食补方式因人而异,仅供日常参考。武清地处北方,四季温差大,秋冬寒湿重…

2026/7/7 17:34:51阅读更多 →
Mac开发环境搭建:从command not found到四维认知模型

Mac开发环境搭建:从command not found到四维认知模型

1. 为什么“入职快速搭建Mac开发机环境”不是个简单任务,而是一场隐性能力测试刚拿到新Mac,屏幕还泛着苹果特有的冷光,HR邮件里写着“明天开始熟悉项目”,你点开终端,敲下brew install node,回车——然后卡…

2026/7/7 17:34:51阅读更多 →
长期观察:靠谱展厅设计公司的几个真实细节

长期观察:靠谱展厅设计公司的几个真实细节

做展厅设计这行五年,跟过不下二十个项目,踩过坑,也见过真功夫。最近常被朋友问:“到底怎么选靠谱的展厅设计公司?”这个问题的答案,其实藏在一些容易被忽略的细节里。 行业深处:那些看得见的“坑…

2026/7/7 17:34:51阅读更多 →
状压dp-基础题目1(糖果)

状压dp-基础题目1(糖果)

基础题目1 解题思路 这题的数据规模:1≤N≤100,1≤M≤20,1≤K≤20,1≤Ti≤M。可以把M种口味用二进制表示,比如,M5时,s00001表示选了第1种口味,第2-5种口味没选。我们可以定义dp数组&#xff0…

2026/7/7 18:44:57阅读更多 →
两节锂离子电池平衡充电方案与BQ25887应用解析

两节锂离子电池平衡充电方案与BQ25887应用解析

1. 两节锂离子电池平衡充电的核心挑战在便携式电子设备中,两节串联锂离子电池(2S)方案越来越普遍,它能提供更高的工作电压(7.4V标称电压)和更大的能量密度。但串联电池组面临一个关键问题:电池单…

2026/7/7 18:44:57阅读更多 →
5步破解CNC编程低效,10秒出程序不是梦

5步破解CNC编程低效,10秒出程序不是梦

5步破解CNC编程低效,10秒出程序不是梦编程一个三轴零件要半小时?CNC自动编程工具来了!麟思数控一键操作,10秒出程序,还能企业定制,效率直接拉满~技术赋能,10秒实现三轴CNC全自动编程…

2026/7/7 18:44:57阅读更多 →
Codex Desktop国内落地指南:本地大模型编程助手配置与排错

Codex Desktop国内落地指南:本地大模型编程助手配置与排错

1. 项目概述:这不是一个“翻墙教程”,而是一份面向国内开发者的 Codex Desktop 实用落地手册 Codex Desktop 是一款基于本地大模型推理能力构建的智能编程助手客户端,它不依赖云端 API 的实时调用,而是将模型权重、推理引擎与 UI…

2026/7/7 18:44:57阅读更多 →
多模态技术对GEO优化的深层影响与行业实践研究

多模态技术对GEO优化的深层影响与行业实践研究

摘要生成式引擎优化(GEO)作为适配AI生成式搜索范式的全新优化体系,彻底颠覆了传统SEO的文本核心逻辑,而多模态技术的迭代落地,成为重塑GEO优化规则、权重体系与内容生态的核心变量。本文基于主流大模型技术架构与2026年…

2026/7/7 18:44:57阅读更多 →
【金蝶云星空】直运采购(无库存)全流程讲解

【金蝶云星空】直运采购(无库存)全流程讲解

导语 现在有一个场景:客户A下单了100台电脑,但是公司没有库存,要找供应商A下单购买,但是货物不经过公司,直接发给客户A。这种直运采购的流程在系统应该怎么走?摘要 本篇文章将用以下问题对直接采购(无库存)…

2026/7/7 18:39:57阅读更多 →
从GitHub安全案例解析常见漏洞与防护实践

从GitHub安全案例解析常见漏洞与防护实践

1. 项目概述:从GitHub Trending看安全实战 最近在GitHub Trending上看到一个项目,叫 skills4/skills ,它因为一些安全漏洞案例被大家讨论。这其实是一个挺典型的场景:一个旨在展示或教授某种技能的仓库,本身却成了安…

2026/7/7 4:43:43阅读更多 →
MLT 2026启示:因果推理与概率建模驱动下一代LLM应用

MLT 2026启示:因果推理与概率建模驱动下一代LLM应用

# MLT 2026启示:因果推理与概率建模驱动下一代LLM应用## 一、背景与挑战:从“黑箱预测”到“可信推理”2026年6月,第7届机器学习与趋势国际会议(MLT 2026)将在悉尼召开。会议议程中,“因果与可解释机器学习…

2026/7/7 2:56:31阅读更多 →
通达OA SQL注入漏洞深度剖析:从手工注入到自动化利用与防御

通达OA SQL注入漏洞深度剖析:从手工注入到自动化利用与防御

1. 项目概述与漏洞背景最近在梳理一些历史OA系统的安全风险时,通达OA v11.6版本中的一个老漏洞又进入了我的视线。这个漏洞位于/general/bi_design/appcenter/report_bi.func.php文件中,是一个典型的SQL注入点。虽然这个漏洞的利用方式看起来并不复杂&am…

2026/7/7 1:03:28阅读更多 →
Acunetix v24.8 深度解析:DAST漏洞扫描器核心原理与DevSecOps实践

Acunetix v24.8 深度解析:DAST漏洞扫描器核心原理与DevSecOps实践

1. 项目概述:Acunetix v24.8 高级版漏洞扫描器深度解析作为一名在网络安全领域摸爬滚打多年的老兵,我深知一款趁手的“兵器”对于安全测试工作意味着什么。今天要聊的,就是Web应用安全测试领域里一个响当当的名字——Acunetix。特别是其v24.8…

2026/7/7 0:02:41阅读更多 →
国产化信创改造:达梦/人大金仓适配与多数据库兼容方案实战(SpringBoot)

国产化信创改造:达梦/人大金仓适配与多数据库兼容方案实战(SpringBoot)

国产化信创改造:达梦/人大金仓适配与多数据库兼容方案实战(SpringBoot) 🌐 演示地址:http://ruoyioffice.com | 📦 源码1GitHub:ruoyi-office | 📦 源码2GitCode:ruoyi-o…

2026/7/7 0:02:41阅读更多 →
CentOS 7/8 SSH 连接失败:5步系统性排错流程与决策树

CentOS 7/8 SSH 连接失败:5步系统性排错流程与决策树

CentOS SSH连接故障排查:从基础检查到深度修复的完整指南引言当你尝试通过Xshell或其他SSH客户端连接CentOS服务器时,突然遭遇"Connection refused"或"Connection timed out"的错误提示,这种经历对任何运维人员或开发者来…

2026/7/7 0:02:41阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/7 5:11:21阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/7 5:11:21阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/7 5:11:21阅读更多 →