news 2026/6/18 17:18:09

驰骋BPM组织结构设计技术报告

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
驰骋BPM组织结构设计技术报告

驰骋低代码 BPM 组织结构设计 — 技术报告

文档版本:2026-06
章节编号:3.1
依据代码:CCFlow/Components/BP.En30/Port(组织实体)、CCFlow/Components/BP.WF/Port/OrganizationAPI.cs(同步接口)、CCFlow/Components/BP.WF/Template/FindWorker.cs(流程选人引擎)
说明:本文基于源码静态分析撰写,用于技术分享与方案论证,力求准确描述设计思想并客观分析优劣。


一、为什么组织结构设计如此重要

1.1 基本定义

组织结构是指:系统运行要依赖的人员、部门、角色,以及人员与部门、角色之间的对应关系。

在驰骋 BPM(CCBPM)中,这一概念直接落地为Port_*系列数据表,实体类统一归属BP.Port命名空间。流程引擎的节点接收人规则、表单权限、组织隔离、待办推送等能力,均以这套结构为数据底座。

1.2 组织结构是应用系统的基石

组织结构不仅是 BPM 的专属需求,更是整个应用系统的基础,也是权限管理的基本条件

依赖方典型场景
工作流引擎按"部门 + 角色"计算下一节点处理人
权限体系按部门、岗位控制菜单、数据范围
低代码平台组织树选人、按组织隔离应用与流程
第三方集成HR/OA 主数据向 BPM 同步或映射

若组织模型与业务语义不匹配,轻则集成成本陡增,重则流程"找不到人"、权限穿透或数据串租户——这类问题在生产环境中极难补救。

1.3 业界设计的困境

每个架构师对组织结构的理解、应用方向、部署环境各不相同,导致表结构设计千差万别

  • 有的系统只有「用户—部门」二元关系,角色挂在用户上,无法表达"同一人不同部门担任不同岗位";
  • 有的把角色做成全局属性,忽略"财务部经理"与"市场部经理"虽同为"经理"但权责不同的现实;
  • 有的为追求范式化拆出十几张表,集成时映射成本极高;
  • 有的为图省事把部门、岗位、人员揉进一张宽表,无法支撑树形部门与多组织隔离。

核心矛盾:模型太简单则无法覆盖政企复杂场景;模型太复杂则难以与存量 HR/OA 系统对接。究竟哪种设计能覆盖绝大多数场景?这是本报告要回答的问题。

1.4 驰骋的命题

驰骋结合十余年 BPM 交付与组织结构集成经验,提出一套经过大量项目验证的五表核心模型。其目标不是学术上的"最范式化",而是:

用尽可能少的表,表达尽可能完整的组织语义,并让整个工作流引擎能用一条 SQL 完成"按部门+角色找人"。


二、驰骋五表核心模型

2.1 五表总览

#表名实体类职责
1Port_DeptDept部门树
2Port_EmpEmp人员主档
3Port_StationStation角色(岗位)
4Port_DeptEmpDeptEmp部门—人员(支持兼职)
5Port_DeptEmpStationDeptEmpStation部门—角色—人员(三要素绑定)

另有扩展表Port_StationType(角色分类)、Port_Org/Port_OrgAdminer(多组织管理)等,服务于集团/SAAS 模式,不改变五表核心语义。

2.2 实体关系

ParentNo 树形

FK_Dept 主部门

FK_Dept

FK_Emp

FK_StationType

FK_Dept

FK_Emp

FK_Station

Port_Dept

Port_Emp

Port_DeptEmp

Port_StationType

Port_Station

Port_DeptEmpStation

2.3 各表设计要点(代码印证)

Port_Dept — 部门
Map map = new Map("Port_Dept", "部门"); map.ItIsEnableVer = true; map.AddTBStringPK(DeptAttr.No, null, "编号", true, false, 1, 50, 20); map.AddTBString(DeptAttr.Name, null, "名称", true, false, 0, 100, 30); map.AddTBString(DeptAttr.NameOfPath, null, "部门路径", true, false, 0, 100, 30); map.AddTBString(DeptAttr.ParentNo, null, "父节点编号", true, true, 0, 100, 30); map.AddTBString(DeptAttr.OrgNo, null, "OrgNo", true, true, 0, 50, 30); map.AddTBString(DeptAttr.Leader, null, "部门领导", true, true,0,50,100);
  • 树形结构:ParentNo自关联,NameOfPath冗余全路径以加速展示与检索。
  • Leader存部门领导登录账号(非中文名),直接支撑"找部门负责人"类流程规则。
  • OrgNo在集团/SAAS 模式下做组织隔离。
Port_Emp — 人员
map.AddTBStringPK(EmpAttr.No, null, "编号", true, false, 1, 50, 30); //如果是集团模式或者是SAAS模式. if (BP.Difference.SystemConfig.CCBPMRunModel == CCBPMRunModel.SAAS) map.AddTBString(EmpAttr.UserID, null, "用户ID", true, false, 0, 50, 30); map.AddTBString(EmpAttr.Name, null, "名称", true, false, 0, 200, 30); map.AddTBString(EmpAttr.PinYin, null, "拼音", false, false, 0, 200, 30); map.AddDDLEntities(EmpAttr.FK_Dept, null, "部门", new BP.Port.Depts(), false); map.AddTBString(EmpAttr.Tel, null, "手机号", false, false, 0, 20, 20); map.AddTBString(EmpAttr.Email, null, "邮箱", false, false, 0, 50, 50); map.AddTBString(EmpAttr.Leader, null, "直属部门领导", false, false, 0, 20, 130); map.SetHelperAlert(EmpAttr.Leader, "这里是领导的登录帐号,不是中文名字,用于流程的接受人规则中。"); map.AddTBString(EmpAttr.LeaderName, null, "领导名", true, true, 0, 20, 130); map.AddTBString(EmpAttr.OrgNo, null, "组织编号", true, true, 0, 50, 50);
  • FK_Dept表示主部门,满足"此人默认归属哪里"的高频查询。
  • SAAS 模式下UserIDNo组织编号_UserID)分离,允许跨租户账号重复。
  • Leader字段支撑"找直属领导"规则,与部门领导字段语义区分清晰。
Port_Station — 角色
Map map = new Map("Port_Station", "角色"); // map.setCodeStruct("3"); // map.setIsAutoGenerNo(true); map.AddTBStringPK(StationAttr.No, null, "编号", true, true, 1, 50, 200); map.AddTBString(StationAttr.Name, null, "名称", true, false, 0, 100, 200); map.AddDDLEntities(StationAttr.FK_StationType, null, "类型", new StationTypes(), true); map.AddTBString(StationAttr.OrgNo, null, "隶属组织", false, false, 0, 50, 250);
  • 角色是岗位抽象(如"部门经理"“出纳”),不直接绑定人员。
  • 通过FK_StationType分类,便于流程设计器按类型筛选。
  • 集团模式下可通过GroupStationModel配置为"组织级角色"或"部门级角色"。
Port_DeptEmp — 部门人员(兼职)
Map map = new Map("Port_DeptEmp", "部门人员信息"); map.IndexField = DeptEmpAttr.FK_Dept; map.AddMyPK(); map.AddTBString(DeptEmpAttr.FK_Dept, null, "部门", false, false, 1, 50, 1); map.AddDDLEntities(DeptEmpAttr.FK_Emp, null, "操作员", new BP.Port.Emps(), false); map.AddTBString(DeptEmpAttr.OrgNo, null, "组织编码", false, false, 0, 50, 50);
  • 主键MyPK = FK_Dept + "_" + FK_Emp,一人可挂多个部门。
  • 删除时级联清理该人员在该部门下的Port_DeptEmpStation记录,保证数据一致性。
Port_DeptEmpStation — 三要素绑定(设计灵魂)
Map map = new Map("Port_DeptEmpStation", "部门角色人员对应"); map.AddTBStringPK("MyPK", null, "主键MyPK", false, true, 1, 150, 10); map.AddTBString(DeptEmpStationAttr.FK_Dept, null, "部门", true, true, 1, 100, 1); map.AddTBString(DeptEmpStationAttr.FK_Station, null, "角色", true, true, 1, 50, 1); map.AddTBString(DeptEmpStationAttr.FK_Emp, null, "操作员", true, true, 1, 100, 1); map.AddTBString(DeptEmpAttr.OrgNo, null, "组织编码", true, true, 0, 50, 50);
  • 主键MyPK = FK_Dept + "_" + FK_Emp + "_" + FK_Station
  • 语义:张三在财务部担任出纳,与张三在市场部担任经理是两条独立记录。
  • 这是整个 BPM 选人引擎的核心查询表。

三、设计思想:为什么是五表

3.1 主部门 + 兼职部门的双轨模型

驰骋没有强迫所有关系都走关联表,而是采用双轨策略:

场景使用表原因
默认部门、快速查人Port_Emp.FK_Dept单表查询,性能最优
一人多部门(兼职)Port_DeptEmp不破坏主部门字段的简洁性
部门内岗位绑定Port_DeptEmpStation角色必须带部门上下文

这避免了"所有关系都塞进关联表"导致的性能问题,也避免了"只在用户表上挂一个部门字段"无法表达兼职的局限。

3.2 角色必须带部门上下文

这是驰骋方案与许多简易 OA 的根本分歧

简易方案常把角色直接挂在人员上(User.Role = 经理),但现实中:

  • 张三在 A 部门是部门经理(可审批本部门费用);
  • 张三在 B 部门是普通员工(只能提交申请)。

若角色不绑定部门,流程引擎无法区分"找 A 部门的经理"与"找 B 部门的经理"。

驰骋用Port_DeptEmpStation部门 × 角色 × 人员三维绑定,使语义与政企编制管理一致。

3.3 流程引擎的直接受益

FindWorker.cs中大量接收人规则最终归结为对Port_DeptEmpStation的查询。例如"按角色智能计算"的核心 SQL:

string sql1 = "SELECT FK_Emp FROM Port_DeptEmpStation WHERE FK_Station='" + stas + "' AND FK_Dept='" + depts + "' ";// + sqlEnd; return DBAccess.RunSQLReturnTable(sql1);

BP.Port.Glo中的公共选人方法同样依赖此表:

string sql = "SELECT B.No,B.Name FROM Port_DeptEmpStation A,Port_Emp B WHERE A.FK_Station IN (" + GenerWhereInSQL(stationNos) + ") AND A.FK_Dept IN (" + BP.Port.Glo.GenerWhereInSQL(deptNos) + ") AND A.FK_Emp=B.No";

人员是否拥有某角色,也通过此表判断:

public bool HaveStation(string stationNo) { string sql = "SELECT COUNT(FK_Emp) AS Num FROM Port_DeptEmpStation WHERE FK_Emp='" + this.No + "' AND FK_Station='" + stationNo + "'"; if (DBAccess.RunSQLReturnValInt(sql) == 0) return false; return true; }

设计结论:五表不是"数据库教科书式"的拆表,而是让引擎能用简单 SQL 表达复杂组织语义的最小闭包。


四、与常见设计方案对比

4.1 三种典型路线

方案C:重度 RBAC

User

UserRole

Role

RolePermission

Permission

UserDept

Dept

方案B:驰骋五表

Emp

Dept

DeptEmp

DeptEmpStation

Station

方案A:极简二元

User

Dept

维度方案A:用户—部门方案B:驰骋五表方案C:重度 RBAC
表数量2~35(核心)8~15+
兼职部门不支持或 hack原生支持需额外建模
部门上下文角色不支持原生支持需 RoleScope 扩展
BPM 选人 SQL 复杂度高(需业务层拼装)低(单表/双表 JOIN)高(多表 JOIN + 范围判断)
与 HR 主数据映射简单但不完整中等,语义对齐复杂,概念不对等
权限细粒度中(角色+部门)强(资源级 ACL)
集成维护成本

4.2 为什么不选"角色直接挂用户"

许多系统采用UserStation(用户—角色)二元关联。其缺陷在 BPM 场景下会被放大:

  1. 无法表达"同一人不同部门不同岗位"——政企兼职极常见;
  2. 流程按部门找人时语义模糊——"财务部经理"究竟指哪个部门;
  3. 集成时需大量业务规则补偿——在应用层判断"当前流程实例部门"再过滤角色。

驰骋在数据模型层一次性解决,使引擎逻辑保持简洁、可测试、可审计。

4.3 为什么不选"十几张表的完整 IAM"

完整身份与访问管理(IAM)模型适合统一身份平台,但对 BPM 集成而言往往过度设计

  • HR 系统通常提供的是部门、人员、岗位,而非 Permission、Resource、Policy;
  • 映射链路过长,任一环节不一致即导致"流程找不到人";
  • 运维人员难以理解"为什么这个人有角色但流程选不到"。

驰骋五表在表达能力集成友好度之间取了工程上的平衡点。


五、优劣分析

5.1 优势

优势说明
语义贴近政企编制部门树 + 岗位 + 兼职,与真实组织管理一致,业务人员易理解
BPM 原生适配FindWorker引擎直接查询Port_DeptEmpStation,无需应用层翻译
集成面收敛视图/接口集成都只需对齐五表,文档与 API 边界清晰
多组织可扩展通过OrgNo字段贯通五表,单组织到 SAAS 无需改模型
双轨性能主部门走Port_Emp.FK_Dept快速查询,复杂关系走关联表
级联一致性DeptEmp删除自动清理DeptEmpStation,减少脏数据
经大量项目验证OrganizationAPI提供完整增删改同步能力,降低对接风险

5.2 局限与应对

局限影响驰骋的应对
五表同步成本外部 HR 需维护 DeptEmp + DeptEmpStation提供Port_Emp_Save一次调用写入三表;推荐视图模式合并库
角色非全局"全公司总监"类岗位需特殊处理可用虚拟部门、或按组织根部门绑定角色
冗余字段NameOfPath、DeptEmp 中 Vue3 辅助列换取查询性能与前端展示便利
复合主键MyPK拼接规则在 SAAS 下有变体统一由实体beforeUpdateInsertAction生成,集成时调用 API 即可
非完整 IAM不支持资源级 ACL、动态策略权限场景由应用系统承担;BPM 聚焦流程选人
标签/用户组非核心Port_Team系列为辅助不影响五表主模型,按需启用

5.3 客观评价

驰骋五表模型不是万能的组织架构,而是为 BPM 工作流场景优化的最小完备集

  • 若您的核心需求是"复杂审批流按部门岗位找人、支持兼职、支持多组织",五表方案高度匹配
  • 若您的核心需求是"细粒度资源权限、零信任策略、跨系统联邦身份",应在五表之上叠加专业 IAM,而非替换五表;
  • 若您的组织极简单(无兼职、无多岗位),五表略显"重",但集成接口与视图模式使额外成本可控,且为未来业务扩展留有余地。

六、多组织运行模式

五表模型通过CCBPMRunModel配置项支持三种运行模式,无需修改表结构:

模式组织特征
0单组织OrgNo隔离,一个admin管理全部
1集团组织多独立组织,OrgNo隔离;用户账号全局唯一;可共享流程
2SAAS多租户;账号可跨租户重复;Emp.UserID+Emp.No双字段

扩展表Port_OrgPort_OrgAdminer在集团/SAAS 模式下管理组织生命周期与管理员权限,与五表通过OrgNo松耦合。


七、集成实践:两种模式

驰骋提供两种组织结构集成路径,均围绕五表展开:

7.1 视图模式(推荐)

删除 CCBPM 侧五张物理表,创建同结构视图,将业务库组织数据映射过来。优势:

  • 单一数据源,无同步延迟;
  • 业务系统改组织,BPM 即时生效;
  • 维护成本最低。

7.2 接口模式(数据同步)

通过OrganizationAPI在组织变更时主动同步。核心接口:

接口作用
Port_Org_Save同步组织及主管理员
Port_Dept_Save/Port_Dept_Delete同步部门
Port_Emp_Save/Port_Emp_Delete同步人员及部门角色关系
Port_Station_Save/Port_Station_Delete同步角色

Port_Emp_Save的实现体现了五表联动逻辑——一次调用完成Port_EmpPort_DeptEmpPort_DeptEmpStation的写入:

//插入部门. BP.Port.DeptEmp de = new BP.Port.DeptEmp(); de.MyPK = de.DeptNo + "_" + userNo; //更新角色. if (stats == null) stats = ""; string[] strs = stats.Split(','); // ... DeptEmpStation des = new DeptEmpStation(); des.DeptNo = deptNo; des.EmpNo = userNo; des.StationNo = str; des.OrgNo = orgNo; des.MyPK = de.DeptNo + "_" + des.EmpNo + "_" + des.StationNo; des.DirectInsert();

集成建议

  • 数据库可合并 → 优先视图模式;
  • 数据库必须分离 → 接口模式,一人多部门时每个部门各调用一次Port_Emp_Save

八、总结

8.1 设计命题回顾

#命题驰骋的回答
1组织结构是什么人员、部门、角色及其对应关系
2为何重要应用系统基础,权限与流程的前提
3为何设计千差万别场景、环境、理解差异导致模型分化
4哪种设计覆盖大多数场景五表核心模型,经大量政企项目验证
5五表是什么Dept、Emp、Station、DeptEmp、DeptEmpStation
6优劣如何流程语义完备、集成面收敛;非完整 IAM,同步需规范
7如何落地视图模式或 OrganizationAPI,按部署条件选择

8.2 一句话概括

驰骋 BPM 用五张表把"谁在哪个部门担任什么角色"这一政企最核心的组织语义数据结构化了,使整个工作流引擎能用简洁 SQL 完成复杂选人——这是多年集成经验沉淀下的工程选择,而非纸上谈兵。

8.3 延伸阅读

  • 组织结构数据字典与运行模式:doc/组织结构.md
  • 工作流引擎整体技术白皮书:doc/驰骋BPM工作流引擎技术白皮书2026版.md

本文档由驰骋 BPM 技术团队基于源码分析编写,转载请注明出处。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/18 17:14:49

YTPro的贡献指南:提交PR的步骤与代码审查流程

YTPro的贡献指南:提交PR的步骤与代码审查流程 【免费下载链接】YTPro Youtube client with older Android version support, background player, Google Gemini ✨ and many more features. 项目地址: https://gitcode.com/GitHub_Trending/yt/YTPro YTPro是…

作者头像 李华
网站建设 2026/6/18 17:13:09

QMCDecode终极指南:快速解锁QQ音乐加密格式的13种方法

QMCDecode终极指南:快速解锁QQ音乐加密格式的13种方法 【免费下载链接】QMCDecode QQ音乐QMC格式转换为普通格式(qmcflac转flac,qmc0,qmc3转mp3, mflac,mflac0等转flac),仅支持macOS,可自动识别到QQ音乐下载目录,默认转…

作者头像 李华
网站建设 2026/6/18 17:10:44

WorkshopDL:跨平台Steam创意工坊模组下载器技术解析与实战指南

WorkshopDL:跨平台Steam创意工坊模组下载器技术解析与实战指南 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL WorkshopDL是一款开源的跨平台Steam创意工坊模组下载…

作者头像 李华
网站建设 2026/6/18 17:03:48

储能型光伏电站电池容量优化配置及协同控制策略研究

摘要:本研究旨在优化储能型光伏电站电池容量配置与协调控制,通过分析光伏电站的结构设计、储能单元的容量配置及充放电策略以及电网和负荷单元的设计,构建了光伏储电站可靠性模型。通过对不同类型储能电池的性能参数进行分析和比较&#xff0…

作者头像 李华
网站建设 2026/6/18 16:53:44

DSP56800开发工具链深度解析:从编译链接到启动代码实战

1. 项目概述:DSP56800开发工具链深度解析 如果你正在或即将踏入基于Freescale(现NXP)DSP56800/E系列数字信号控制器的嵌入式开发领域,那么你迟早会与一套名为CodeWarrior的集成开发环境(IDE)及其背后的命令…

作者头像 李华