KingFusion驾驶舱开发实战:转运信息模块(AGV状态+任务列表+完成率+转运次数)

发布时间:2026/10/23 18:53:20

KingFusion驾驶舱开发实战:转运信息模块(AGV状态+任务列表+完成率+转运次数) 2026-08-07 | 雷工笔记 | MES系列合集一、背景驾驶舱是MES系统的仪表盘也是工厂管理层最关注的功能模块。之前我分享了产能信息和设备信息模块今天继续完善转运信息区域。转运信息模块的核心是AGV小车的运行状态和任务数据展示。现场有5台AGV小车由AGV调度系统统一管理通过API接口将AGV状态实时上报给MES系统MES收到后更新到数据库驾驶舱再从数据库读取数据展示给用户。整体数据链路AGV调度系统 → API上报 → MES接口 → PM_AGVStatusDetail表 → 计算工程 → 驾驶舱前端 PM_AGVTaskDetail表 → (case 8~11) → 图表/变量本文聚焦计算工程后端脚本SQL查询和前端客户端页面变量绑定的具体实现不带任何概念包装全是代码和踩坑记录。二、涉及的表结构2.1 PM_AGVStatusDetailAGV状态详情这个表由AGV调度系统通过API实时更新写入5台AGV各有一条记录字段如下CREATE TABLE ”public”.”PM_AGVStatusDetail” ( ”id” int4 NOT NULL, ”c_AGVCode” int4 NOT NULL, -- AGV设备编码1~5 ”c_AGVStatus” int4 NOT NULL, -- 状态0未定义,1停止,2运行,3空闲,4读卡停止,5管制 ”c_AGVBattery” int4, -- 电池电量 ”c_AGVAlarm” int4, -- 报警状态 ”c_AGVPosition” varchar(50), -- 当前位置 ”c_FinchTime” timestamp -- 更新时间 ); ALTER TABLE ”PM_AGVStatusDetail” ADD CONSTRAINT ”AGV” UNIQUE (”c_AGVCode”);2.2 PM_AGVTaskDetailAGV任务详情每一条记录代表一次AGV转运任务字段如下CREATE TABLE ”public”.”PM_AGVTaskDetail” ( ”ID” int4 NOT NULL, ”c_TaskID” varchar(100), -- 调度AGV任务编码 ”c_AGVCode” int4, -- AGV设备编码 ”c_LocationCode” varchar(50), -- 当前位置 ”c_AGVTaskStatus” varchar(20), -- 任务状态创建/执行中/已完成 ”c_CreateTime” timestamp, -- 任务创建时间 ”c_FinchTime” timestamp, -- 完成时间 ”c_UpdateTime” timestamp -- 更新时间 );三、功能实现的四个步骤3.1 AGV状态更新case 8需求从PM_AGVStatusDetail表读取5台AGV的状态码赋值给5个工程变量 $System.状态_AGV01 ~ $System.状态_AGV05图形模型根据变量值显示不同颜色的AGV图标。后端计算工程脚本PM_cockpit请求式计算case 8://驾驶舱-转运信息-AGV状态 var sql SELECT ”c_AGVCode”, ”c_AGVStatus” FROM ”PM_AGVStatusDetail” ORDER BY ”c_AGVCode”; var res[]; var ret await SQLQuery(RFM_PM, sql, res); OutParam.recordsres; OutParam.errorCoderet; break;前端客户端驾驶舱页面变量触发事件var M { type: 8 }; requestCalculationPost($System.RFM_PM, PM_cockpit, M, function (res) { if (res.Code 0 res.errorCode 0) { var resdata res.records; for (var i 0; i resdata.length; i) { var code resdata[i].c_AGVCode; var status resdata[i].c_AGVStatus; if (code 1) $System.状态_AGV01 status; else if (code 2) $System.状态_AGV02 status; else if (code 3) $System.状态_AGV03 status; else if (code 4) $System.状态_AGV04 status; else if (code 5) $System.状态_AGV05 status; } } });状态码 → 颜色映射状态码含义图标颜色0未定义灰色1停止红色2运行绿色3空闲黄色4读卡停止橙色5管制紫色3.2 AGV任务列表case 9需求在Datagrid中展示最近10条AGV任务记录5个字段任务编码、AGV编号、当前位置、任务状态、创建时间。后端case 9://驾驶舱-转运信息-AGV任务列表 var sql SELECT ”c_TaskID”, ”c_AGVCode”, ”c_LocationCode”, ”c_AGVTaskStatus”, ”c_CreateTime” FROM ”PM_AGVTaskDetail” ORDER BY ”c_UpdateTime” DESC NULLS LAST LIMIT 10; var res[]; var ret await SQLQuery(RFM_PM, sql, res); OutParam.recordsres; OutParam.errorCoderet; break;关键细节ORDER BY c_UpdateTime DESC NULLS LAST。为什么加 NULLS LAST因为未完成的任务 c_UpdateTime 为NULL不处理的话NULL值会排在最前面导致取到的10条记录全是NULL。加上 NULLS LAST 确保真正有更新时间的记录排前面。前端绑定Datagridvar M { type: 9 }; requestCalculationPost($System.RFM_PM, PM_cockpit, M, function (res) { if (res.Code 0 res.errorCode 0) { var resdata res.records; if (resdata.length 0) { $Function.tip(info, 无AGV任务数据); } else { var datagrid1 []; for (var i 0; i resdata.length; i) { var data2 {}; data2.number i 1; data2.c_TaskID resdata[i].c_TaskID; data2.c_AGVCode resdata[i].c_AGVCode; data2.c_LocationCode resdata[i].c_LocationCode || ; data2.c_AGVTaskStatus resdata[i].c_AGVTaskStatus; data2.c_CreateTime resdata[i].c_CreateTime; datagrid1.push(data2); } $(DatagridX.id).datagrid({ data: datagrid1 }); } } });3.3 近7日转运完成率case 10需求折线图展示近7天每天AGV转运任务的完成率已完成任务数 / 总任务数 × 100%。后端case 10://驾驶舱-转运信息-近七日转运完成率 var sql SELECT ”c_CreateTime”::date AS ”date”, ROUND(COUNT(*) FILTER (WHERE ”c_AGVTaskStatus” 已完成) * 100.0 / NULLIF(COUNT(*), 0), 1) AS ”rate” FROM ”PM_AGVTaskDetail” WHERE ”c_CreateTime” CURRENT_DATE - 7 GROUP BY ”c_CreateTime”::date ORDER BY ”c_CreateTime”::date; var res[]; var ret await SQLQuery(RFM_PM, sql, res); OutParam.recordsres; OutParam.errorCoderet; break;技术要点NULLIF(COUNT(*), 0)防止当天没有任务时除零报错FILTER (WHERE ...)是PostgreSQL的聚合过滤语法比CASE WHEN更简洁::date是PostgreSQL的类型转换语法将timestamp转为date以按天分组前端ECharts折线图CustomCharts52var dates getLastSevenDays(); // 生成最近7天日期数组 var M { type: 10 }; requestCalculationPost($System.RFM_PM, PM_cockpit, M, function (res) { if (res.Code 0 res.errorCode 0) { var resdata res.records; // 构建日期→完成率映射 var rateMap {}; for (var i 0; i resdata.length; i) { var d resdata[i].date; var parts d.split(-); rateMap[parts[1] - parts[2]] Number(resdata[i].rate); } // 按7天顺序填充数据无数据的天填0 var chartData []; for (var j 0; j dates.length; j) { chartData.push(rateMap[dates[j]] || 0); } option { title: { text: ”近七日转运完成率”, ... }, xAxis: { data: dates, ... }, yAxis: { name: 单位(100%), ... }, series: [{ data: chartData, type: line, lineStyle: { color: DeepSkyBlue, width: 5 }, ... }] }; CustomCharts52.$Children.echart.setOption(option, true); } });3.4 近7日转运次数case 11需求柱状图展示近7天每天AGV转运任务的总数量。后端case 11://驾驶舱-转运信息-近七日转运次数 var sql SELECT ”c_CreateTime”::date AS ”date”, COUNT(*) AS ”cnt” FROM ”PM_AGVTaskDetail” WHERE ”c_CreateTime” CURRENT_DATE - 7 GROUP BY ”c_CreateTime”::date ORDER BY ”c_CreateTime”::date; var res[]; var ret await SQLQuery(RFM_PM, sql, res); OutParam.recordsres; OutParam.errorCoderet; break;前端的绑定逻辑与完成率类似只是后端返回的是 cnt数量而非 rate百分比图表改为柱状图CustomCharts53使用渐变色柱状条。四、遇到的坑和解决坑1PostgreSQL 的列名必须加双引号KingFusion 连接的是 PostgreSQL 数据库PG 对大小写敏感KingFusion 建立表时字段名带了双引号如 c_AGVCode后续查询必须原样加上双引号否则报错字段不存在。错误写法var sql SELECT c_AGVCode, c_AGVStatus FROM PM_AGVStatusDetail;正确写法var sql SELECT ”c_AGVCode”, ”c_AGVStatus” FROM ”PM_AGVStatusDetail”;坑2NULL值排序问题ORDER BY c_UpdateTime DESC 时NULL值在PostgreSQL中默认排在最前面DESC排序时导致 LIMIT 10 取到的都是没有更新时间的记录真正需要的最新记录反而取不到。解决加 NULLS LAST让NULL值排到最后。坑3静态数据到动态数据的过渡之前驾驶舱的图表数据是静态写死的比如完成率 [95, 96, 95, 97, 98, 95, 97]转运次数 [50, 45, 42, 36, 38, 31, 50]。改动态数据后需要前端构建 日期→数据 映射然后按7天固定顺序填充某天无数据时填0避免图表数据错位。坑4刷新机制设计AGV状态需要实时更新但又不希望频繁调用后端。最终采用页面变量取反触发的方式页面创建时取反变量 → 触发一次查询如需定时刷新在定时器位置取反同一变量即可这样刷新的频率和触发时机完全可配置不用修改查询逻辑五、总结转运信息模块的开发核心就两件事后端写SQL、前端绑定变量。但细节决定成败数据库设计决定了能做什么功能PM_AGVStatusDetail 和 PM_AGVTaskDetail 两张表分别支撑了状态展示和任务统计SQL查询要考虑PG的特殊语法和NULL值处理前端架构用页面变量触发取代直接调用刷新机制更灵活代码管理每次测试通过后代码备份到知识库并在驾驶舱页面创建Excalidraw逻辑流程图避免时间久了忘记相关文章KingFusion驾驶舱开发实战产能信息模块KingFusion驾驶舱开发实战设备信息模块代码备份本文所有代码已归档到个人知识库持续更新。
延伸阅读

更多相关文章

2026/10/21 7:22:24

产业链外部风险敞口测算数据

数据来源由数据皮皮侠团队人工整理,全部内容真实有效时间跨度2010-2023 年区域跨度76 个国家17个制造业行业数据格式数据简介本数据为76个国家17个制造业行业“国家—行业—目的国—年份”多维面板数据,基于投入产出表测算整理而成。产业链外部风险敞口&…

2026/10/21 1:28:32

利用全息光学元件在光纤后产生贝塞尔光束

摘要贝塞尔光束由于其扩展的聚焦深度在许多应用中十分有用。在本例中,我们展示了如何从单模光纤的输出中产生贝塞尔光束。不同于利用准直透镜和锥透镜的传统方法,我们设计了一个集透镜和锥透镜功能于一体的全息光学元件(HOE)。这种光路是在VirtualLab Fu…

2026/10/21 5:33:19

任务分配与协作能力横评:项目管理工具谁能让团队协作更高效?

团队协作是否高效,不取决于工具数量,而在于任务分配链路是否顺畅,以及工具边界是否匹配团队类型。 不少团队引入项目管理工具后,依然面临任务分配混乱、进度不同步、跨部门协作断层、工具使用率低等问题。 这篇文章沿着任务创建、…

2026/10/24 9:43:55

长度面积单位知多少

有时日常生活中除了常见的米,厘米,总还听到华里,公尺,还有总说一个小姑凉腰很细,1尺9的腰,到底是多少呢?咱们今天就一一搞清楚,以免闹出笑话,据说一个小孩说我的牙刷6米长…

2026/10/24 9:43:55

新手figma制作天气图标简易版步骤2

新手figma制作天气图标简易版步骤2 1.和之前的步骤一样讲云朵用圆和矩形做出来 2.云朵的效果设置为 背景模糊为10-30% 制作月亮时可以使用矩形来做(如果直接用圆形最终得到的月亮两端太尖) 3.将矩形的圆角半径拉到最大变成圆形4.复制一个拖到第一个…

2026/10/24 9:43:55

Claude Code 换第三方 API 全过程:从注册到跑通的 5 个坑

上个月看到 AI 编程的账单,我在那愣了几秒。钱不算多,问题是我想不起来花在哪了。工具一直在用,任务一直在跑,到月底给我一个数字,我连它是怎么攒出来的都不知道。于是花了一个下午把这件事理清楚。写下来是因为踩的坑…

2026/10/24 9:43:55

零基础C语言项目实战:从猜数字到通讯录与链表

简介:面向C语言初学者与进阶者的项目实战合集,以完整的源码工程承载图书管理、文件读写、链表与排序等典型练习,帮助读者把零散语法知识整合成可运行的程序。压缩包内共341个文件,以136个.c源文件和22个.h头文件为主体&#xff0c…

2026/10/24 9:38:55

阿里云专有云DataWorks V3.12.0实战避坑指南

简介:本资源是阿里云专有云企业版V3.12.0 DataWorks官方用户指南(PDF版),面向企业大数据平台管理员、数据开发工程师及数据治理从业者,解决专有云环境下DataWorks平台部署后快速上手、规范操作与安全治理等核心问题。文…

2026/10/23 22:56:35

金融AI落地指南:从调研报告到技术选型与工程实践

简介:这份PDF报告聚焦2025年金融服务业中国AI现状与趋势,面向金融科技从业者、AI战略规划人员及关注行业数字化转型的研究者,帮助读者把握生成式AI在银行、支付、交易等场景中的落地路径与投资方向。资源包内含1个PDF文件,大小约1…

2026/10/24 0:02:40

MATLAB缩进快捷键与批量格式化实战指南

1. 被自动缩进折磨的那些年如果你写过MATLAB代码,大概率经历过这种场景:从某个文档、网页或者聊天记录里复制了一段代码,粘贴进编辑器之后,每一行前面都带着莫名其妙的空格,有的行首是四个空格,有的是一个T…

2026/10/24 0:02:40

用Poco实现Qt风格信号与槽的跨平台C++方案

简介:本资源是一份面向C中级开发者的技术实践工程,聚焦于在非Qt框架环境下模拟实现Qt核心通信机制——信号与槽,借助Poco网络库的事件系统完成解耦式对象通信。适用于需在跨平台C项目中引入松耦合回调机制、但受限于无法集成Qt依赖的开发场景…

2026/10/24 0:02:40

ESXi裸机虚拟化安装指南:从硬件兼容到虚拟机部署

1. 为什么还要折腾ESXi:从一台闲置机器说起手里攒了几台淘汰下来的迷你主机,配置不算差,i5加16G内存,扔了可惜,装个桌面系统又觉得浪费。这种场景下,ESXi就成了一个绕不开的选择。它是一套裸机虚拟化平台&a…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑