一、工程上这些表单改起来有多折腾
做工程管理系统的都懂,质量验收、材料报验这摊事儿,最麻烦的不是流程,是表。不同地区的质监站对检验批、分部分项验收表的格式要求不一样,监理和甲方又总在施工过程中临时加字段、改公式、调签字栏。以前我们的 PMIS 项目,每来一个新模板或一点小改动,都得走“提需求→IT 排期→前后端改代码→联调→发版”的全流程,等走完黄花菜都凉了。现场等不了,经常就变成纸质先签,回头再补录,系统慢慢就成了摆设。
二、换个思路:把表单层彻底解耦
后来我们想,能不能让熟悉业务的实施同事自己去管表单样式,开发只负责对接数据和提交接口就行。评估了一圈,最后选中了 FlashTable 这个轻量的表单引擎。它不把每个报验单当成一个硬编码页面,而是把我们手头那些 Word/Excel 的统表直接解析成标准 JSON 结构,然后在独立的运行时页面里渲染。我们在主系统里嵌一个 iframe,指向它的 viewer 路由,这样主业务和表单渲染就拆开了。整体交互大概是下面这样:
三、集成时踩过的点和具体做法
1. 用 postMessage 把主系统和表单引擎串起来
因为可能跨域,我们直接用 postMessage 做异步通信。主系统不用管表单内部怎么渲染,只要监听 message 事件就行。大致代码如下:
// 主系统监听 FlashTable 的生命周期消息
window.addEventListener('message', (event) => {
// 生产环境务必校验 origin,这里用具体地址示例,严禁直接用 '*'
const allowedOrigin = 'http://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_SAVE':
// 拦截到保存动作,拿到结构化的 JSON,直接调后端接口存起来
saveProjectFormData(data);
break;
}
});
这里有个小教训:FORM_READY 没收到之前别急着往里灌数据,否则大概率白屏。另外 FORM_SAVE 拿到的 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": "http://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 映射把两边的数据和动作接上,结构清晰,后面维护也轻松