一、工程上这些表单改起来有多折腾
做工程管理系统的人都深有体会:质量验收、材料报验这类工作,最麻烦的并不是流程本身,而是那些表单。
每个地区的质监站,对检验批、分部分项验收表的格式要求都“各有千秋”。监理和甲方还总在施工过程中临时添加字段、修改公式、调整签字栏位置。以前我们上PMIS项目时,每来一个新模板或一次小改动,都得走“提需求→IT排期→前后端改代码→联调→发版”的全流程。等这一圈走完,黄花菜都凉了。
施工现场等不起。一来二去,就变成了纸质先签字、回头再补录,系统慢慢就成了摆设。
二、换个思路:把表单层彻底解耦
后来我们想:能不能让熟悉业务逻辑的实施同事自己去管理表单样式,开发这边只负责对接数据和提交接口?
评估了一圈,最终选定了FlashTable这款轻量的表单引擎。它的思路跟硬编码页面完全不同——把我们手头那些Word/Excel统表直接解析成标准JSON结构,然后在一个独立的运行时页面里渲染。我们在主系统里嵌入一个iframe,指向它的viewer路由,这样主业务和表单渲染就彻底分开了。
整体交互流程大致如下:

三、集成时踩过的点和具体做法
1. 用postMessage把主系统和表单引擎串起来
因为涉及跨域问题,我们直接采用了postMessage做异步通信。主系统不用管表单内部怎么渲染,只要监听message事件即可。大致代码如下:
// 主系统监听 FlashTable 的生命周期消息
window.addEventListener('message', (event) => {
// 生产环境务必校验 origin,这里用具体地址示例,严禁直接用 '*'
const allowedOrigin = 'https://cxist-template:1000';
if (event.origin !== allowedOrigin) return;
const { type, data } = event.data;
switch (type) {
case 'FORM_READY':
// 表单加载完成,把业务上下文数据塞过去
const iframeWin = document.getElementById('ft-iframe').contentWindow;
iframeWin.postMessage({
action: 'SET_DATA',
payload: { projectId: "PRJ-2026-004", contractNo: "CON-HT-0988" }
}, allowedOrigin); // 发送时也指定具体 origin,不建议 '*'
break;
case 'FORM_SA VE':
// 拦截到保存动作,拿到结构化的 JSON,直接调后端接口存起来
sa veProjectFormData(data);
break;
}
});
这里有一个小教训:在FORM_READY事件没收到之前,别急着往里灌数据,否则大概率白屏。另外,FORM_SA VE拿到的data就是完整的表单值JSON,结构和后端约定的完全一致,直接入库即可。
2. 动态行、列,让材料试验表不再死板
像钢筋拉伸试验、混凝土试块报告这类表格,一次试验有多少组试件是不确定的,行数必须动态变化。FlashTable支持在模板里配置动态行规则,只要给一个JSON描述就能搞定,完全不用改任何代码:
{
"dynamicRows": {
"targetRowIndex": 6,
"minRows": 1,
"maxRows": 100,
"bindField": "test_items_array"
}
}
引擎会根据传进去的test_items_array数组长度,自动把第6行当作骨架,向下克隆出对应行数。边框、线条、打印页边距都会自适应,打印出来和线下表格一模一样。这一点,现场监理非常认可。
3. 外部数据联动与自动回填
表单上有些字段需要根据设备编号或合同号从PMIS主系统拉取数据。我们没有在表单页面里写任何fetch代码,完全依靠FlashTable的数据源配置就解决了。配置一个url,用resultPath标明取值路径,引擎在触发联动时自己去请求,然后按路径取出值填入指定单元格。
{
"dataSource": {
"url": "https://main-system:2000/api/v1/equipment/detail?id={{equipment_id}}",
"method": "GET",
"resultPath": "data.specification.model_name",
"targetFieldName": "model_specification_cell"
}
}
这样一来,实施人员在模板里配好数据源就能直接使用,不用反复找开发,省去了不少沟通成本。
四、私有化部署和安全那点事
因为是国企项目,数据必须留在内网。FlashTable提供了全Docker化的离线部署方式,我们把镜像包拷进内网服务器,解压后执行一键脚本就能启动,依赖全部自带。即使完全断网也能正常运行。
# 解压离线镜像安装包并执行一键部署脚本
tar -xzvf flashtable.tar.gz -C /opt/flashtable
cd /opt/flashtable
./1key_deploy.sh
容器启动后,再在PMIS里把iframe地址指向它即可。这种部署方式对信创环境也比较友好,省去了很多环境配置的麻烦。
五、改造后的实际效果
表单样式调整、打印设置、公式级联这些工作,现在都由业务端的同事在模板里自行配置,开发这边终于不用再当“表格修改工”了。
前端统一采用JSON交互,无论表单多复杂,最终入库的都是结构化数据。与合同、物资、成本等其他模块打通变得简单很多,不再需要为每个表单独写一套数据解析逻辑。
新增一种报验单的周期,从原来的一两周缩短到一两天甚至半天。工程现场“即改即用”的需求基本能够得到满足。
整个过程做下来,感觉对于中型以上的工程项目管理系统来说确实很实用。既没有动原有核心业务,又把最烦人的表单变更问题处理得比较干净。核心思路就是:用FlashTable这类引擎把表单渲染独立出去,再靠postMessage和JSON映射将两边的数据和动作衔接起来。结构清晰,后续维护也很轻松。
