fix(cablemanager): 修复 cablemanager 无法操作 + 一直刷新的问题

- 根因1: GET /api/audio-cable-groups 服务端返回 {groups: list},但前端 loadGroups() 读 data.audioCableGroups → 永远读到 undefined → 始终空列表
  修复: 服务端 L3447 同时返回 groups 和 audioCableGroups 两个别名;前端 loadGroups() 优先读 audioCableGroups,不存在则回退 groups
- 根因2: WebSocket onmessage 收到 init_state/state_update 立即 reloadAll(带 toast),若事件频繁会反复 re-render + 连弹『数据已刷新』toast → 看起来一直刷新且输入框总被重置
  修复: 新增 scheduleAutoReload() 节流(两次自动刷新之间至少间隔 900ms);且自动刷新统一走 reloadAll({silent:true}) 不弹成功/失败 toast;仅用户点刷新按钮才弹提示
- 本地实测: PORT=8999 启动 server 后 /api/stations → {success:true, stations:[]},/api/audio-cable-groups → {success:true, groups:[], audioCableGroups:[]},两个端点均 200 且响应结构含双别名 key
- APP_VERSION_TEXT bump 到 v1.0.109
This commit is contained in:
2026-08-17 17:55:09 +08:00
parent a3ff8664ee
commit fb17de6493
3 changed files with 27 additions and 7 deletions
+25 -5
View File
@@ -1499,7 +1499,7 @@
const res = await fetch('/api/audio-cable-groups');
const data = await res.json();
if (data.success) {
audioCableGroups = data.audioCableGroups || [];
audioCableGroups = Array.isArray(data.audioCableGroups) ? data.audioCableGroups : (Array.isArray(data.groups) ? data.groups : []);
} else {
throw new Error(data.message || '加载分组失败');
}
@@ -1516,7 +1516,8 @@
if (!Array.isArray(stations)) stations = [];
}
async function reloadAll() {
async function reloadAll(options) {
const silent = !!(options && options.silent);
try {
await Promise.all([loadGroups(), loadStations()]);
renderGroupList();
@@ -1530,9 +1531,9 @@
renderDualLists();
}
}
showToast('成功', '数据已刷新', 'success');
if (!silent) showToast('成功', '数据已刷新', 'success');
} catch (e) {
showToast('错误', e?.message || String(e), 'error');
if (!silent) showToast('错误', e?.message || String(e), 'error');
}
}
@@ -1558,6 +1559,25 @@
}
let ws;
let _autoReloadTimer = 0;
let _autoReloadPending = false;
function scheduleAutoReload() {
_autoReloadPending = true;
const now = Date.now();
const wait = Math.max(0, 900 - (now - _autoReloadTimer));
const fire = () => {
if (!_autoReloadPending) return;
_autoReloadPending = false;
_autoReloadTimer = Date.now();
reloadAll({ silent: true }).catch(() => {});
};
if (wait === 0) {
Promise.resolve().then(fire);
} else {
clearTimeout(scheduleAutoReload._t);
scheduleAutoReload._t = setTimeout(fire, wait);
}
}
function connectWebSocket() {
try {
const wsProto = window.location.protocol === 'https:' ? 'wss' : 'ws';
@@ -1572,7 +1592,7 @@
try {
const data = JSON.parse(event.data);
if (data.type === 'init_state' || data.type === 'state_update') {
reloadAll().catch(() => {});
scheduleAutoReload();
}
} catch (e) {}
};