feat(plc_debug): 新增Out信号选择列,支持批量添加到指示灯/按键

在PLC调试界面指示灯与按键之间插入Out信号选择列:
- 展示所有已注册out信号(含地址、描述、值)
- 支持多选勾选(含整行点击切换)
- ← 左箭头:批量添加到指示灯列
- → 右箭头:批量添加到按键列
- 原有功能(LED绑定/按键翻转/勾选删除)完整保留
This commit is contained in:
ypc 2026-07-07 09:46:49 +08:00
parent 6bdd467998
commit fac40ea953
3 changed files with 1463 additions and 944 deletions

File diff suppressed because it is too large Load Diff

View File

@ -778,6 +778,83 @@ body.login-page #main-content { margin-left: 0; display: flex; align-items: cent
border-bottom: 2px solid var(--primary);
font-size: 16px;
}
/* 信号选择列 */
.plc-signal-col {
width: 280px;
min-width: 260px;
flex-shrink: 0;
background: var(--card-bg);
border-radius: var(--radius);
box-shadow: var(--shadow);
padding: 16px;
min-height: 200px;
}
.plc-signal-col h3 {
margin-bottom: 4px;
font-size: 16px;
}
.plc-arrow-row {
display: flex;
justify-content: center;
gap: 24px;
padding: 4px 0 12px 0;
border-bottom: 2px solid var(--primary);
margin-bottom: 8px;
}
.plc-arrow-btn {
width: 36px;
height: 36px;
border-radius: 50%;
border: 2px solid var(--primary);
background: #fff;
color: var(--primary);
font-size: 20px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.2s;
line-height: 1;
}
.plc-arrow-btn:hover {
background: var(--primary);
color: #fff;
}
.plc-arrow-btn:active {
transform: scale(0.9);
}
.plc-sig-list {
max-height: calc(100vh - 380px);
overflow-y: auto;
}
.plc-sig-check-item {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 6px;
border-bottom: 1px solid #f0f0f0;
cursor: pointer;
font-size: 12px;
transition: background 0.15s;
}
.plc-sig-check-item:hover {
background: #f0f8ff;
}
.plc-sig-check-item .plc-sig-saddr {
color: var(--primary);
font-weight: 600;
font-family: monospace;
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.plc-sig-check-item .plc-sig-val {
font-weight: 700;
color: var(--info);
min-width: 30px;
text-align: right;
}
.plc-item {
display: flex;
align-items: center;

View File

@ -8,6 +8,7 @@ var PlcDebugPage = (function() {
var outSignals = [];
var ledChecked = {}; // {idx: true}
var btnChecked = {}; // {idx: true}
var signalChecked = {}; // {idx: true} 信号选择列勾选
function getOutSignals() {
if (typeof App !== 'undefined' && App.getSignalData) {
@ -135,6 +136,32 @@ var PlcDebugPage = (function() {
}
html += '</div>';
// 信号选择列
html += '<div class="plc-signal-col">';
html += '<h3>📋 Out 信号</h3>';
html += '<div class="plc-arrow-row">';
html += '<button class="plc-arrow-btn" id="plc-arrow-left" title="选中信号→添加到指示灯">←</button>';
html += '<button class="plc-arrow-btn" id="plc-arrow-right" title="选中信号→添加到按键">→</button>';
html += '</div>';
html += '<div class="plc-sig-list">';
if (outSignals.length === 0) {
html += '<div style="color:#999;text-align:center;padding:20px">暂无 out 信号</div>';
}
else
{
for (var s = 0; s < outSignals.length; s++) {
var sig = outSignals[s];
var sigChk = signalChecked[s] ? ' checked' : '';
html += '<div class="plc-sig-check-item">'
+ '<input type="checkbox" class="plc-sig-cb" data-sig-idx="' + s + '"' + sigChk + '>'
+ '<span class="plc-sig-saddr" title="' + fmtVal(sig.saddr) + (sig.desc ? ' - ' + fmtVal(sig.desc) : '') + '">' + fmtVal(sig.saddr) + '</span>'
+ (sig.desc ? '<span style="color:#999;font-size:11px;max-width:60px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">' + fmtVal(sig.desc) + '</span>' : '')
+ '<span class="plc-sig-val">' + fmtVal(sig.val) + '</span>'
+ '</div>';
}
}
html += '</div></div>';
// 按键
html += '<div class="plc-col"><h3>🔘 按键</h3>';
for (var j = 0; j < PlcDebugButtons.length; j++) {
@ -233,6 +260,86 @@ var PlcDebugPage = (function() {
};
}
// 信号选择列勾选框
var sigCbs = document.querySelectorAll('.plc-sig-cb');
for (var p = 0; p < sigCbs.length; p++) {
sigCbs[p].onclick = function(e) {
e.stopPropagation();
var sigIdx = parseInt(this.getAttribute('data-sig-idx'));
if (!isNaN(sigIdx)) {
if (this.checked) signalChecked[sigIdx] = true; else delete signalChecked[sigIdx];
}
};
}
// 信号选择列整行点击切换勾选
var sigRows = document.querySelectorAll('.plc-sig-check-item');
for (var q = 0; q < sigRows.length; q++) {
sigRows[q].onclick = function(e) {
if (e.target.tagName === 'INPUT') return;
var cb = this.querySelector('.plc-sig-cb');
if (cb) {
cb.checked = !cb.checked;
var sigIdx = parseInt(cb.getAttribute('data-sig-idx'));
if (!isNaN(sigIdx)) {
if (cb.checked) signalChecked[sigIdx] = true; else delete signalChecked[sigIdx];
}
}
};
}
// 左箭头 → 添加到指示灯
var arrowLeft = document.getElementById('plc-arrow-left');
if (arrowLeft) {
arrowLeft.onclick = function(e) {
e.stopPropagation();
var added = 0;
for (var k in signalChecked) {
if (signalChecked.hasOwnProperty(k)) {
var idx = parseInt(k);
if (idx >= 0 && idx < outSignals.length) {
PlcDebugLeds.push({ saddr: outSignals[idx].saddr, desc: outSignals[idx].desc || '', val: outSignals[idx].val });
added++;
}
}
}
if (added > 0) {
showToast('✅ 已添加 ' + added + ' 个信号到指示灯');
signalChecked = {};
renderAll();
}
else {
showToast('⚠️ 请先勾选信号');
}
};
}
// 右箭头 → 添加到按键
var arrowRight = document.getElementById('plc-arrow-right');
if (arrowRight) {
arrowRight.onclick = function(e) {
e.stopPropagation();
var added = 0;
for (var k in signalChecked) {
if (signalChecked.hasOwnProperty(k)) {
var idx = parseInt(k);
if (idx >= 0 && idx < outSignals.length) {
PlcDebugButtons.push({ saddr: outSignals[idx].saddr, desc: outSignals[idx].desc || '', val: outSignals[idx].val });
added++;
}
}
}
if (added > 0) {
showToast('✅ 已添加 ' + added + ' 个信号到按键');
signalChecked = {};
renderAll();
}
else {
showToast('⚠️ 请先勾选信号');
}
};
}
document.getElementById('plc-refresh').onclick = function() {
refreshOutData();
renderAll();
@ -259,7 +366,7 @@ var PlcDebugPage = (function() {
return {
render: function(container) {
ledChecked = {}; btnChecked = {};
ledChecked = {}; btnChecked = {}; signalChecked = {};
container.innerHTML = ''
+ '<div class="page-header"><h2>PLC 调试</h2><p>指示灯绑定 out 已注册信号(>0 亮/≤0 灭),按键绑定 out 已注册信号(点击翻转 0↔1)</p></div>'
+ '<div id="plc-content"></div>';