85 lines
2.9 KiB
JavaScript
85 lines
2.9 KiB
JavaScript
/**
|
||
* @file signal-store.js
|
||
* @brief 信号数据缓存 — 纯内存, WS 推送驱动, 不持久化 + 增量 DOM 刷新
|
||
*/
|
||
|
||
var SignalStore = {
|
||
data: { out: [], yk: [], ao: [], param: [] },
|
||
|
||
/**
|
||
* @brief 合并 WS 推送数据 + 增量更新可见 DOM (不重刷整页)
|
||
*/
|
||
update: function(push) {
|
||
var self = this;
|
||
['out', 'yk', 'ao', 'param'].forEach(function(type) {
|
||
if (!push[type]) return;
|
||
var map = {};
|
||
self.data[type].forEach(function(s) { map[s.saddr] = s; });
|
||
push[type].forEach(function(s) { map[s.saddr] = s; });
|
||
self.data[type] = Object.keys(map).map(function(k) { return map[k]; });
|
||
|
||
/* 增量更新可见页面 DOM (仅更新变化的单元格,不重绘整页) */
|
||
var tbody = document.getElementById('tbody-' + type);
|
||
if (!tbody) return;
|
||
push[type].forEach(function(s) {
|
||
var row = tbody.querySelector('tr[data-saddr="' + s.saddr.replace(/"/g, '\\"') + '"]');
|
||
if (!row) return;
|
||
/* 更新值列 (class=cell-val) */
|
||
var valCell = row.querySelector('.cell-val');
|
||
if (valCell && s.val !== undefined) {
|
||
var nv = (s.val === null || s.val === '') ? '—' : String(s.val);
|
||
if (valCell.textContent.trim() !== nv) {
|
||
valCell.textContent = nv;
|
||
valCell.classList.add('changed');
|
||
setTimeout(function() { valCell.classList.remove('changed'); }, 600);
|
||
}
|
||
}
|
||
/* 更新 ctrl_type 列 (YK/AO) */
|
||
if (s.ctrl_type !== undefined) {
|
||
var ctrlCell = row.querySelector('.cell-ctrl');
|
||
if (ctrlCell) {
|
||
var ct = (s.ctrl_type == 1) ? (I18n.t('signal.ctrl_sbo') || 'SBO') : (I18n.t('signal.ctrl_direct') || 'Direct');
|
||
if (ctrlCell.textContent.trim() !== ct) ctrlCell.textContent = ct;
|
||
}
|
||
}
|
||
/* Param: 更新定值区值 */
|
||
if (type === 'param' && s.setting_zone_list) {
|
||
s.setting_zone_list.forEach(function(z) {
|
||
var zoneInput = row.querySelector('.param-zone-val[data-zone="' + z.id + '"]');
|
||
if (zoneInput) {
|
||
var zv = z.val || '';
|
||
if (zoneInput.textContent !== zv) zoneInput.textContent = zv;
|
||
}
|
||
});
|
||
}
|
||
});
|
||
});
|
||
|
||
/* PLC Debug 页增量刷新 */
|
||
if (typeof PlcDebugPage !== 'undefined' && PlcDebugPage.incrRefresh) {
|
||
PlcDebugPage.incrRefresh();
|
||
}
|
||
},
|
||
|
||
get: function(type) {
|
||
return this.data[type] || [];
|
||
},
|
||
|
||
/** @brief 删除信号 (内存 + 立即移除 DOM,不等后端确认) */
|
||
remove: function(type, saddr) {
|
||
this.data[type] = this.data[type].filter(function(s) { return s.saddr !== saddr; });
|
||
/* 立即从页面移除对应行 */
|
||
var row = document.querySelector('#tbody-' + type + ' tr[data-saddr="' + saddr.replace(/"/g, '\\"') + '"]');
|
||
if (row) {
|
||
row.style.transition = 'opacity 0.2s';
|
||
row.style.opacity = '0';
|
||
setTimeout(function() { if (row.parentNode) row.parentNode.removeChild(row); }, 200);
|
||
}
|
||
},
|
||
|
||
/** @brief 清空所有缓存 (WebSocket 断连时调用) */
|
||
clear: function() {
|
||
this.data = { out: [], yk: [], ao: [], param: [] };
|
||
}
|
||
};
|