这是「个人对后勤业务见解」系列的延伸篇,接上一篇讲业财一体化的落地。
核心诉求:从一笔预算追到每一笔支出
业财一体化最能体现价值的功能,是三级联动:点开一笔预算,能看到它下面所有的资金计划;点开一笔资金计划,能看到对应的所有费用执行记录;同时把完成率、执行差值、差异数据一并呈现。
需求一句话就说完了,做起来是另一回事。
数据模型:四个池子
我们最后落到的结构是四个数据池,各自归集一类数据,池与池之间按业务关系建立关联。
合同全量视图
归集施工项目合同、服务采购合同等,字段包括甲实施方、合同金额、履约周期、付款节点、质保条款。关键是要留出和施工项目、供应商、费用执行三方的关联键,否则后面做履约跟踪时会发现关联不上。
预算全量视图
按费用类型和组织层级归集年度预算。这里有个容易踩的坑:预算的调整是常态,一年调整三五次很正常。所以预算全量视图必须保留调整记录,不能只存当前值——否则年底分析执行率时,分母是变的,算出来的数没有意义。
资金计划全量视图
预算是年度的,资金计划通常是季度或月度的。一笔预算下面会挂多笔资金计划,这是第一级展开。
费用明细全量视图
实际发生的每一笔支出,关联到对应的资金计划。这是第二级展开,也是数据量最大的一层。
关联关系怎么建
四个池子之间的关系不是简单的一对多。实际情况是:
一笔预算对应多笔资金计划,一笔资金计划对应多笔费用执行,这条主链是清晰的。但合同横跨其中——一份合同的付款可能分摊在多个资金计划里,也可能一笔费用执行同时关联多份合同(比如按比例分摊的公共费用)。
处理办法是把合同关联做成独立的关联表,而不是在费用明细上加一个合同 ID 字段。前者能表达多对多,后者到第二个需求就撑不住了。
真正的难点是性能
三级联动的查询看着简单,放到多层级组织下就完全不是一回事。
总部、区域、基层三级,数据量差好几个数量级。总部视角要汇总全量,基层视角只看自己那一摊。同一套查询逻辑,在基层几毫秒返回,到总部可能几十秒——但用户不管这个,他在哪一级都期望秒级响应。
预聚合是必须的
实时聚合撑不住。我们的做法是按组织层级和时间维度做预聚合,把常用的汇总指标(预算总额、资金计划总额、执行总额、余额、完成率)提前算好,查询时直接取。
代价是数据有延迟。这一点必须提前和业务方讲清楚,并且在页面上标明数据更新时间。跟他们说「这个看板是 T+1 的」,比让他们对着转圈等三十秒要好得多。
下钻查明细才实时算
汇总层用预聚合,下钻到具体单据时再实时查。因为下钻之后数据量已经收敛到可控范围,实时查得起。
元数据驱动:别为每种费用类型改一次代码
后勤的费用类型很多——办公费、水电费、物业管理费、运输费、福利费、警卫消防费、质保金保证金等等。传统做法是每种类型定制开发一套表单和校验逻辑,加一种就改一次代码。
上线时定了八类,你可以确信第九类半年内就会来。
我们改成了元数据驱动:把科目体系、预算规则、计划规则、填报表单、校对逻辑、分析维度全部抽象成可配置的元数据,业务人员通过界面自助配置新的费用类型,不需要开发介入。
这个改造前期投入不小,大概占了整个模块三成的工作量。但从第三种费用类型开始就回本了,之后每加一种都是净赚。
但要注意抽象的边界
元数据驱动不是万能药。它适用的前提是这些费用类型的要素能够收敛——都能用「科目 + 预算规则 + 填报字段 + 校验规则」这几个要素描述清楚。
确实有几类费用的逻辑特殊到收敛不进去,比如质保金涉及留存、释放、罚扣三种状态流转。这种就老老实实单独写代码,不要为了追求「全部可配置」把配置模型撑到没人能用的地步。
小结
三级联动这个功能,需求描述一句话,实际工作量集中在两处:数据关联关系的设计,和多层级下钻的性能。前者决定了将来能不能扩展,后者决定了上线后有没有人用。
下一篇讲更棘手的:口径、同步和对账。