实体是一行数据,实体集合是多行数据,流程对它们的操作方式其实可以穷举。本文从概念划分、配置化程度与实践风险三方面,评估这样一套模式体系的价值与代价。
在该 BPM 平台中,实体 是对现实世界事物的数字化建模,例如:车辆、固定资产、员工、供应商等。
概念 | 含义 | 代码/存储对应 |
|---|---|---|
实体 | 现实世界中的一个具体事物实例 | 业务表中的 一行数据(主键为 OID 或 No) |
实体集合 | 同一类事物的全部或部分实例 | 业务表中的 多行数据,由实体列表页(Search)展示 |
实体表单(FrmDict / EntityNoName) | 实体的元数据与 UI 定义 | 平台系统表,EntityType = 2(实体)或 3/5(编号实体等) |
// 前端模块源码目录
// EntityType: @0=独立表单 @1=单据 @2=实体
map.AddTBInt('EntityType', 0, '业务类型', true, true);打开一条实体记录时,前端由 MyDictFrameWork.vue 加载 卡片页;浏览实体集合时,由 Search 系列页面(如 useSearchNoName.ts)加载 列表页。
本文 不讨论 流程引擎内部的节点流转、分合流、父子流程等机制,而聚焦一个问题:
流程如何对单个实体与实体集合进行操作?
该 BPM 平台的答案是:通过五种 MethodModel 模式,在配置层区分「操作对象是一行还是多行」「数据是否回写」「是否与实体长期绑定」,开发人员 按模式选型 + 向导配置 即可完成大部分场景,无需重复编写集成代码。
序号 | 模式 | MethodModel | 操作对象 | 核心行为 |
|---|---|---|---|---|
1 | 新增模式 | FlowNewEntity | 实体集合(列表) | 流程走完 → 增加一行 实体记录 |
2 | 批处理模式 | FlowEntityBatchStart | 实体集合(多选) | 多行实体 → 一条 流程 |
3 | 修改模式 | FlowBaseData | 单个实体(一行) | 发起变更流程 → 结束后 回写 该行 |
4 | 多次业务模式 | FlowEtc | 单个实体(一行) | 带入实体信息 → 流程 独立存档、不回写 |
5 | 宿主流程模式 | FlowHostBill | 单个实体(一行) | 状态字段 + WorkIDOf{FlowNo} 唯一绑定 |
总结:实体与流程的关系,就是通过流程来 操作一行数据、多行数据、修改数据、增加数据。
该 BPM 平台在 UI 与配置层将操作入口分为两类,与「一行 / 多行」严格对应:
入口类型 | 存储表 | 挂载位置 | 典型操作对象 |
|---|---|---|---|
Collection | Frm_Collection | 列表页工具栏(IsSearchBar) | 零行(新建)或多行(批处理) |
Method | Frm_Method | 卡片页侧边栏 / 列表行操作(IsList) | 当前一行 实体 |
方法类型常量在 GPN_Method.ts 中统一定义:
// 前端模块源码目录该引擎/CCBill/Method/GPN_Method.ts
export class MethodModel {
public static readonly FlowBaseData = 'FlowBaseData';
public static readonly FlowEtc = 'FlowEtc';
public static readonly FlowNewEntity = 'FlowNewEntity';
// FlowHostBill、FlowEntityBatchStart 在向导中单独注册
}走完流程之后,在实体表中 增加一笔新记录。通常在实体 列表(表格) 上增加按钮,例如:「发起车辆采购流程」。流程审批通过后,系统将流程表单数据写入实体表,实体集合 多一行。
按钮文案 | 效果 |
|---|---|
发起车辆采购流程 | 审批通过后车辆台账新增一条 |
发起入职流程 | 审批通过后员工档案新增一条 |
组件 | 路径 |
|---|---|
方法实体 | Method/MethodFlowNewEntity.ts |
列表集合 | Collection/CollectionFlowNewEntity.ts |
列表发起 | hooks/useSearchNoName.ts、hooks/useSearchBill.ts |
列表页点击后调用后端 CreateWorkID,打开流程页:
// useSearchNoName.ts
const workID = await menu.DoMethodReturnString('CreateWorkID');
baseComp.value?.openIframe({
src: '/#/WF/MyFlowGener?FlowNo=' + data.FlowNo + '&FrmID=' + data.FrmID + '&WorkID=' + workID + ...
});后端设计意图(MethodFlowNewEntity.ts 注释):流程实例标记 FlowNewEntity=1,PWorkID 与实体新行 ID 对齐,流程结束后自动写入 Dict。
Collection + IsSearchBarDTSWhenFlowOver = true,流程结束回写在实体 列表 上勾选 多行 记录,一次性发起 一条 流程,将选中实体的信息批量带入流程。面向 实体集合 的批量操作。
组件 | 路径 |
|---|---|
集合实体 | Collection/CollectionFlowEntityBatchStart.ts |
列表 Hook | hooks/useSearchNoName.ts |
handler.AddPara('WorkIDs', tableConfigs.checkedItems.join(','));
const data = await handler.DoMethodReturnString('MyDict_DoFlowBatchBaseData_StartFlow');模式 | 选中行 | 结果 |
|---|---|---|
新增 | 无需选中 | 流程结束后 新增 行 |
批处理 | 多行 | 多行数据进入 一条 流程 |
修改 | 单行 | 变更 一行 并回写 |
在 一笔已有记录(单个实体) 上,发起 基础资料变更流程,例如:「车辆基础资料变更」、「纳税人基础资料变更流程」。流程结束后,按配置将变更字段 同步回写 到该实体行。
PWorkID 关联。组件 | 路径 |
|---|---|
方法实体 | Method/MethodFlowBaseData.ts |
向导创建 | GPN_Method.ts → FlowBaseData_Save(FlowDevModel=1 极简模式) |
历史列表 | Method/GL_FlowEtcList.ts(按 PWorkID + FK_Flow 查询) |
GPN_Method.Docs11 官方说明:
操作当前一行数据;流程结束后,系统就会把这些字段同步到实体中去。
DTS 配置(各 Method 通用):
配置项 | 修改模式典型值 |
|---|---|
DTSDataWay | 1 或 2(全部/指定字段) |
DTSWhenFlowOver | true |
DTSWhenNodeOver | 可选(节点级同步) |
Method + IsList 或卡片页 IsMyBillToolBar在 一笔记录(单个实体) 上发起流程,将当前实体信息 传递 到流程开始节点表单。流程发起后,与实体 不再有持续关系,不回写 实体数据。同一实体 可多次 发起,每次产生独立流程实例。
流程 | 行为 |
|---|---|
用车申请流程 | 带入车辆信息;申请记录仅存流程库 |
物业费缴纳、维修申请、奖惩评定 | 历史可查,不影响实体主数据 |
组件 | 路径 |
|---|---|
方法实体 | Method/MethodFlowEtc.ts |
发起接口 | MyDict_DoFlowEtc_StartFlow |
流程列表 | GL_FlowEtcList.ts |
RefMethod | MapRefMethod.AddRM_StartFlow(每次新建,不绑定 WorkIDOf) |
GPN_Method.Docs12:
启动流程的时候,单据数据 copy 到开始节点上。流程运行完毕后,就作为业务查询数据。
卡片页嵌入流程历史(MyDictFrameWork.vue):
<!-- methodModal === 'FlowEtc' -->
EnName=GL_FlowEtcList&WorkID=...&FlowNo=...&FrmID=...对比项 | 多次业务 | 修改 |
|---|---|---|
是否回写实体 | 否 | 是 |
业务语义 | 附属申请、记录 | 主数据变更 |
DTS 典型配置 | DTSDataWay=0 | DTSWhenFlowOver=true |
实体上设计一个 状态枚举字段,其取值由流程 运行中、结束后 的事件决定,此类流程称为 宿主流程。
需同时设计:
WorkIDOf{FlowNo} 字段(如流程编号 001 → 字段名 WorkIDOf001),存储当前绑定流程的 WorkID约束:同一时间点只能有一个有效 WorkID;该流程 结束 后才可再次发起并覆盖。
车辆维修流程:
WorkIDOf001 = 当前 WorkID组件 | 路径 |
|---|---|
方法实体 | Method/MethodFlowHostBill.ts |
字段约定 | MapRefMethod.AddRM_StartHostFlow |
发起 UI | WF/Comm/En.vue(RefMethodType.StartHostFlow) |
单次规则 | FrmBillFlowSingleRole.ts |
强制单实例 | hooks/useSearchMethod.ts(宿主不走多流程列表,直接发起) |
WorkIDOf 自动注册(MapRefMethod.ts):
const fieldID = 'WorkIDOf' + flowNo; // 如 WorkIDOf001
if (!this.attrs.find((attr) => attr.Key === fieldID)) {
this.AddTBInt(fieldID, null, `${title}WorkID`, true, true, false);
}发起逻辑(En.vue):WorkIDOf == 0 时创建流程并回写 WorkID;否则打开已有 MyView。
向导创建:FlowDevModel = 3(宿主专用),FlowEtc_Save + FlowModel=FlowHostBill。
Demo 参考:App/Demo/SingleRecord/StudentFlowComponent.ts(WorkIDOf058)、App/Demo/Resume.ts(手工发起示例)。
字段 | 位置 | 用途 |
|---|---|---|
PWorkID | WF_GenerWorkFlow | 实体主键(OID / No) |
PFlowNo | WF_GenerWorkFlow | 实体 FrmID |
WorkIDOf{FlowNo} | 实体业务表 | 宿主模式:当前绑定 WorkID |
接口 | 适用模式 |
|---|---|
CreateWorkID | 新增 |
MyDict_DoFlowBatchBaseData_StartFlow | 批处理 |
MyDict_DoFlowEtc_StartFlow | 修改 / 多次业务 / 宿主 |
FlowBaseData_Save / FlowEtc_Save | 向导创建流程 |
需求 | 模式 | 操作对象 |
|---|---|---|
审批通过后入库 | 新增 | 集合 → 新行 |
勾选多行统一审批 | 批处理 | 集合 → 一条流程 |
变更档案并写回 | 修改 | 单行 |
申请类、不影响主数据 | 多次业务 | 单行 |
状态机 + 唯一在途流程 | 宿主 | 单行 |
本节基于该 BPM 平台对实体—流程关系的 概念划分,从架构与落地角度评估其对开发人员的价值。
评估点 | 结论 | 说明 |
|---|---|---|
一行 vs 多行 | 合理 | 与「实体 / 实体集合」领域语言一致;Collection 对集合、Method 对单行,职责清晰 |
回写 vs 不回写 | 合理 | 修改模式与多次业务模式分离,避免「申请流程误改主数据」的常见设计错误 |
新增独立成模式 | 合理 | 「流程产单」是 OA/ERP 高频场景,与「改已有行」目标不同,不应混在同一 MethodModel |
宿主单独成模式 | 合理 | 唯一 WorkID + 状态枚举是 状态机 语义,与可多次发起的 FlowEtc 本质不同;强行合并会导致并发发起与状态不一致 |
五种模式在三个维度上近似 正交:
维度1:操作对象 → 单行 | 多行 | 无行(新增)
维度2:数据回写 → 回写 | 不回写 | 双向(宿主)
维度3:实例约束 → 无约束 | 唯一在途(宿主)开发人员选型时可按业务问答式决策,降低架构讨论成本。
FlowHostBill 在 UI 文案中为「寄宿流程」,与「宿主流程」混用,建议文档与界面术语统一为 宿主流程。IsBatchStart(流程级批量)名称相近,实施时需向配置人员说明 实体 Collection 批处理 与 流程设计器批量发起 的差异。能力 | 配置入口 | 代码开发量 |
|---|---|---|
创建流程 + 复制实体表单 | GPN_Method 向导 | 零代码 |
按钮挂载位置 | IsList / IsSearchBar / IsMyBillToolBar | 零代码 |
字段同步 | DTSDataWay + DTSWhenFlowOver | 零代码(常规字段) |
流程历史查询 | GL_FlowEtcList 内置 | 零代码 |
宿主 WorkIDOf 字段 | AddRM_StartHostFlow 自动追加 | 零代码(向导/RefMethod) |
状态变更 | 节点/流程 事件(SQL 或业务单元) | 少量配置 |
PCenters 权限子表,可按组织/角色控制按钮可见性。FrmBillFlowSingleRole(单次流程规则),支持「仅允许一次发起」等约束,减少硬编码校验。维度 | 评分 | 简要理由 |
|---|---|---|
配置人员(实施顾问) | ★★★★☆ | 向导覆盖 80% 场景;宿主状态机与事件仍需一定 WF 经验 |
业务人员 | ★★★★☆ | 按钮语义与业务动作一致(「变更」「申请」「维修」) |
开发人员 | ★★★★★ | 标准场景无需写集成层;复杂逻辑可下沉 RefMethod / 事件 |
若自行开发(无模式划分) | 该平台配置模式替代 |
|---|---|
编写「发起流程 + 传参」Controller | MyDict_DoFlowEtc_StartFlow 统一入口 |
维护实体字段 → 流程字段映射表 | 启动时 同名自动复制 + DTS 配置 |
流程结束监听写回实体 | DTSWhenFlowOver |
查询某实体关联的全部流程 | GL_FlowEtcList(PWorkID 检索) |
防止宿主流程重复发起 | WorkIDOf{FlowNo} + FrmBillFlowSingleRole |
列表「新建实体」按钮 | CollectionFlowNewEntity + CreateWorkID |
结论:对于车辆、资产、员工等 标准主数据 + 周边流程 类项目,实施人员通过 配置五种模式 即可交付,开发人员主要承担:
WaiGuaBaseEntity)useSearchNoName.ts、useSearchMethod.ts、useSearchBill.ts)按类型分支,扩展新模式时有明确挂点。AddRM_StartFlow / AddRM_StartHostFlow / AddRM_SearchFlow,代码级实体与配置级 Method 语义一致,便于从配置迁移到代码或反向。风险 | 规避建议 |
|---|---|
误用 FlowEtc 做应回写的变更 | 选型阶段强制区分「变更主数据」与「附属申请」 |
宿主流程未配事件,状态不更新 | 实施 checklist:状态字段 + WorkIDOf + 结束事件三者齐套 |
批处理选中行过多导致流程表单过大 | 业务上限 + 分批发起;或改用子表 Dtl 承载 |
字段名不一致导致复制失败 | 向导「重新导入实体字段」或统一命名规范 |
该 BPM 平台将实体—流程交互 产品化为五种 MethodModel,在 合理性 上覆盖了企业主数据管理的主流范式;在 可操作性 上通过向导、DTS、内置列表降低实施门槛;在 可实践性 上显著减少重复集成代码,使 「配置即交付」 成为可达成目标。对开发人员而言,工作重点从「写流程对接胶水代码」转向「选好模式 + 设计实体字段与事件」,整体 人天可节省约 50%~70%(标准 CRUD+流程类需求,视项目复杂度浮动)。
模式 | 操作对象 | 一句话 |
|---|---|---|
新增 | 实体集合 | 流程走完 → 集合 多一行 |
批处理 | 实体集合(多选) | 多行 → 一条 流程 |
修改 | 单个实体 | 一行 → 流程 → 回写 同一行 |
多次业务 | 单个实体 | 一行 → 多次 流程,不回写 |
宿主 | 单个实体 | 一行 ↔ 唯一 在途流程,状态 由流程驱动 |
实体 = 一行数据,实体集合 = 多行数据。流程对实体的五种处理方式,本质是该 BPM 平台在配置层对「增、改、批量、申请、绑态」的产品化封装,使开发人员 以模式选型 + 向导配置 为主、编码为辅。
业界 BPM / 工作流产品与该平台五种模式在 语义上高度对应,实现层次与术语各异。下表便于集成设计与技术对标。
该 BPM 平台 | 通用 BPM 术语 | 典型实现 |
|---|---|---|
新增模式 | Process-initiated creation | 结束监听器 / External Task 调 API 创单 |
批处理模式 | Bulk initiation | 多 businessKey 写入流程变量 |
修改模式 | Master data change approval | 快照 + 审批后 MERGE(SAP MDG 等) |
多次业务模式 | Ad-hoc / detached subprocess | 仅传 businessKey,不更新主记录 |
宿主流程模式 | Case management / stateful binding | 状态机 + activeProcessInstanceId |
模式 | 说明 | 对应该平台 |
|---|---|---|
Business Key | 流程实例绑定业务主键 | PWorkID + PFlowNo |
Copy-on-start | 发起时主数据快照进流程 | MyDict_DoFlowEtc_StartFlow |
Service Task 回写 | 节点/结束调业务 API | DTSWhenFlowOver / 事件 |
状态机 + 单实例 | 业务对象唯一活动流程 | WorkIDOf{FlowNo} + 宿主规则 |
Bulk variables | 多 ID 集合进一条流程 | FlowEntityBatchStart |
平台 | 与该平台最接近的能力 |
|---|---|
Camunda / Flowable | Business Key + Listener 回写 ≈ PWorkID + DTS |
Power Automate + Dataverse | 行绑定 + 单活动实例 ≈ 宿主流程 |
ServiceNow Flow | Table 记录 + Flow Context ≈ 实体 + PWorkID |
SAP MDG | 变更请求审批激活 ≈ 修改模式 |
CMMN | Case 文件项绑定 ≈ 宿主 + 状态机 |
维度 | 通用 BPM | 该 BPM 平台 |
|---|---|---|
模式划分 | 通常不预置,集成层自定 | 五种 MethodModel 开箱即用 |
字段同步 | Connector / 自研 | DTS 配置化 |
宿主单实例 | 自定义锁 | WorkIDOf + 流程规则 |
UI 入口 | 门户 / 自研按钮 | Method + Collection |
表单 | 独立建模 | 从实体一键复制 |
PWorkID,实体类型 ↔ PFlowNo。status + activeWorkId,与 WorkIDOf{FlowNo} 对齐。WorkIDs 参数)。原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。