From bfd7a74831caef3d181bf46874f70ba5b93708f4 Mon Sep 17 00:00:00 2001 From: zhugongping Date: Tue, 6 Oct 2026 08:50:16 +0800 Subject: [PATCH] =?UTF-8?q?modbus=E8=AE=BE=E7=BD=AE=EF=BC=9A=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E4=BE=BF=E6=8D=B7=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yack-web/src/lang/en-US/product.json | 23 +- yack-web/src/lang/zh-CN/product.json | 23 +- .../product/components/modbusColumnBatch.vue | 254 +++++++++++++ .../src/views/iot/product/modbus-derive.js | 44 +++ .../src/views/iot/product/product-modbus.vue | 339 +++++++++++++----- .../views/iot/product/things-model-list.vue | 15 +- 6 files changed, 586 insertions(+), 112 deletions(-) create mode 100644 yack-web/src/views/iot/product/components/modbusColumnBatch.vue create mode 100644 yack-web/src/views/iot/product/modbus-derive.js diff --git a/yack-web/src/lang/en-US/product.json b/yack-web/src/lang/en-US/product.json index c5a255a5..a3334347 100644 --- a/yack-web/src/lang/en-US/product.json +++ b/yack-web/src/lang/en-US/product.json @@ -426,11 +426,6 @@ "product.product-modbus.562372-44": "Add a single data register", "product.product-modbus.562372-45": "Add multiple data registers", "product.product-modbus.562372-46": "The default address cannot be empty", - "product.product-modbus.562372-47": "Register address cannot be empty", - "product.product-modbus.562372-48": "Read only (0- No, 1- Yes) cannot be empty", - "product.product-modbus.562372-49": "Modbus data type cannot be empty", - "product.product-modbus.562372-50": "The number of reads cannot be empty", - "product.product-modbus.562372-51": "Register type 1-IO register 2-data register cannot be empty", "product.product-modbus.562372-52": "Save successful", "product.product-modbus.562372-53": "Modified successfully", "product.product-modbus.562372-311": "Positional offset", @@ -551,5 +546,21 @@ "product.product-things-model.142341-200": "Click symbols to build the formula", "product.product-things-model.142341-201": "Reference product model identifiers", "product.product-things-model.142341-202": "No available identifiers", - "product.product-things-model.142341-203": "Add Calculated Model" + "product.product-things-model.142341-203": "Add Calculated Model", + "product.product-modbus.562372-320": "Batch", + "product.product-modbus.562372-321": "Scope: all {n} rows on this page", + "product.product-modbus.562372-323": "{n} rows updated", + "product.product-modbus.562372-325": "skipped {m} rows (data type mismatch)", + "product.product-modbus.562372-326": "Batch delete", + "product.product-modbus.562372-327": "Select rows to delete first", + "product.product-modbus.562372-328": "The {n} selected rows ({m} already saved) will be removed locally and take effect after you click Save. Continue?", + "product.product-modbus.562372-329": "1 (16-bit)", + "product.product-modbus.562372-330": "2 (32-bit)", + "product.product-modbus.562372-331": "Click \"Edit registers\" to enter edit mode first", + "product.product-modbus.562372-333": "Scope: {n} selected rows", + "product.product-modbus.562372-334": "Advances by read count · Enter or blur to generate", + "product.product-modbus.562372-335": "Generate", + "product.product-modbus.562372-336": "Generated {n} addresses: {from} -> {to}", + "product.product-modbus.562372-337": "{m} duplicate slave + register address pairs on this page", + "product.product-modbus.562372-338": "Product is published; click \"Unpublish\" first to edit registers" } diff --git a/yack-web/src/lang/zh-CN/product.json b/yack-web/src/lang/zh-CN/product.json index e9be7ae1..12af98fd 100644 --- a/yack-web/src/lang/zh-CN/product.json +++ b/yack-web/src/lang/zh-CN/product.json @@ -426,11 +426,6 @@ "product.product-modbus.562372-44": "添加单个数据寄存器", "product.product-modbus.562372-45": "添加多个数据寄存器", "product.product-modbus.562372-46": "默认地址不能为空", - "product.product-modbus.562372-47": "寄存器地址不能为空", - "product.product-modbus.562372-48": "是否只读(0-否,1-是)不能为空", - "product.product-modbus.562372-49": "modbus数据类型不能为空", - "product.product-modbus.562372-50": "读取个数不能为空", - "product.product-modbus.562372-51": "寄存器类型 1-IO寄存器 2-数据寄存器不能为空", "product.product-modbus.562372-52": "保存成功", "product.product-modbus.562372-53": "修改成功", "product.product-modbus.562372-311": "位偏移量", @@ -551,5 +546,21 @@ "product.product-things-model.142341-200": "点击符号快速拼接", "product.product-things-model.142341-201": "引用产品物模型标识", "product.product-things-model.142341-202": "暂无可用标识", - "product.product-things-model.142341-203": "新增计算模型" + "product.product-things-model.142341-203": "新增计算模型", + "product.product-modbus.562372-320": "批量", + "product.product-modbus.562372-321": "作用:本页 {n} 行", + "product.product-modbus.562372-323": "已应用 {n} 行", + "product.product-modbus.562372-325": "跳过 {m} 行(数据类型不匹配)", + "product.product-modbus.562372-326": "批量删除", + "product.product-modbus.562372-327": "请先勾选要删除的行", + "product.product-modbus.562372-328": "将删除勾选的 {n} 行(含已保存 {m} 行),确认后需点击保存生效", + "product.product-modbus.562372-329": "1(16位)", + "product.product-modbus.562372-330": "2(32位)", + "product.product-modbus.562372-331": "请先点击「编辑寄存器」进入编辑状态", + "product.product-modbus.562372-333": "作用:已勾选 {n} 行", + "product.product-modbus.562372-334": "按读取个数递增 · 回车或失焦即生成", + "product.product-modbus.562372-335": "一键生成", + "product.product-modbus.562372-336": "已生成 {n} 行地址:{from} → {to}", + "product.product-modbus.562372-337": "本页有 {m} 处「从机地址 + 寄存器地址」重复,请检查", + "product.product-modbus.562372-338": "产品当前为已发布状态,请先点击「取消发布」后再编辑寄存器" } diff --git a/yack-web/src/views/iot/product/components/modbusColumnBatch.vue b/yack-web/src/views/iot/product/components/modbusColumnBatch.vue new file mode 100644 index 00000000..be99cc13 --- /dev/null +++ b/yack-web/src/views/iot/product/components/modbusColumnBatch.vue @@ -0,0 +1,254 @@ + + + + + diff --git a/yack-web/src/views/iot/product/modbus-derive.js b/yack-web/src/views/iot/product/modbus-derive.js new file mode 100644 index 00000000..f47f3818 --- /dev/null +++ b/yack-web/src/views/iot/product/modbus-derive.js @@ -0,0 +1,44 @@ +/** + * modbus 配置派生规则(唯一口径,页面与批量面板共用) + * + * 红线:`读取个数(quantity)` 是 `数据类型(dataType)` 的派生量,不是独立字段。 + * 后端 ModbusProtocol#handleRead0304 完全按 quantity 分支解析: + * quantity==1 → 16 位(CalculateUtils.handleToUnSign16) + * quantity==2 → 32 位(CalculateUtils.parseValue) + * 其它值 → log.warn 直接丢弃 + * 字典 iot_modbus_data_type(sql/yack-init.sql:2503-2511): + * bit=1 位;ushort/short=16 位 1 个寄存器;long/ulong/float 的 ABCD/CDAB 变体=32 位 2 个寄存器。 + */ + +/** 32 位数据类型集合(占 2 个寄存器) */ +export const MODBUS_32BIT_TYPES = ['long-ABCD', 'long-CDAB', 'ulong-ABCD', 'ulong-CDAB', 'float-ABCD', 'float-CDAB']; + +/** 16 位数据类型集合(占 1 个寄存器) */ +export const MODBUS_16BIT_TYPES = ['ushort', 'short']; + +/** + * 由数据类型推导读取个数 + * @param {string} dataType 字典 iot_modbus_data_type 的值 + * @returns {number|null} 1 | 2;dataType 为空或未知类型返回 null(不派生,避免把 data_type 为空的历史行改坏) + */ +export function deriveQuantity(dataType) { + if (!dataType) return null; + if (dataType === 'bit') return 1; + if (MODBUS_16BIT_TYPES.indexOf(dataType) !== -1) return 1; + if (MODBUS_32BIT_TYPES.indexOf(dataType) !== -1) return 2; + return null; +} + +/** + * 单行占用的寄存器个数(一 key 生成地址序列时的步长) + * dataType 非空 → 以派生值为准(权威);dataType 为空的历史行 → 回退行内 quantity;再缺省 1 + * @param {object} row modbus 配置行 + * @returns {number} 1 | 2 | 行内 quantity + */ +export function resolveQuantity(row) { + if (!row) return 1; + const derived = deriveQuantity(row.dataType); + if (derived !== null) return derived; + const quantity = Number(row.quantity); + return quantity > 0 ? quantity : 1; +} diff --git a/yack-web/src/views/iot/product/product-modbus.vue b/yack-web/src/views/iot/product/product-modbus.vue index c297f742..f740c88a 100644 --- a/yack-web/src/views/iot/product/product-modbus.vue +++ b/yack-web/src/views/iot/product/product-modbus.vue @@ -93,7 +93,8 @@ - + + + @@ -128,19 +130,31 @@ + + +