Files
vd_test_fixture/edc-web/app/static/js/devices.js
wangfq ee136cc707 feat: edc-web 设备日志管理页 + 在线状态实时刷新
- 新增 /device-logs 设备事件日志管理页 (admin 权限)
  - 支持按设备序列号/事件类型筛选查询
  - 支持 admin 按条件删除日志
  - 不同事件类型彩色标识 (在线=绿, 离线=红, 通信不良=橙)
- 新增 /api/devices/<id>/status 设备状态 API
- 设备列表页:每 5s 异步刷新所有设备在线状态
- 测试操作页:顶部显示设备状态,每 5s 异步刷新
- dnt_info state 支持三态显示 (在线/离线/通信不良)
- 导航栏增加「设备日志」入口 (admin only)
2026-06-10 09:14:32 +08:00

88 lines
2.8 KiB
JavaScript

// 设备列表页
async function loadDevices() {
const resp = await fetch("/api/devices");
const devices = await resp.json();
renderTable(devices);
}
function renderTable(devices) {
const tbody = document.querySelector("#device-table tbody");
tbody.innerHTML = devices.map(d => {
const stateLabel = getStateLabel(d.state);
const stateClass = getStateClass(d.state);
return `
<tr>
<td>${d.serial}</td>
<td class="editable-name" onclick="editName(${d.id}, '${esc(d.name)}', this)">
${d.name || '(点击编辑)'}
</td>
<td>${d.ip || '-'}</td>
<td class="${stateClass} status-cell" data-device-id="${d.id}">
${stateLabel}
</td>
<td>${d.version || '-'}</td>
<td>${d.last_login || '-'}</td>
<td>
<button class="btn-test" onclick="location.href='/test/${d.id}'">测试</button>
${USER_ROLE === 'admin' ? `<button class="btn-config" onclick="location.href='/fixture/${d.id}'">配置</button>` : ''}
</td>
</tr>`;
}).join("");
}
function getStateLabel(state) {
return {0: '离线', 1: '在线', 2: '通信不良'}[state] || '未知';
}
function getStateClass(state) {
return {0: 'status-offline', 1: 'status-online', 2: 'status-poor'}[state] || '';
}
// 异步刷新所有设备的在线状态
async function refreshDeviceStatuses() {
const cells = document.querySelectorAll(".status-cell");
for (const cell of cells) {
const deviceId = cell.dataset.deviceId;
if (!deviceId) continue;
try {
const resp = await fetch(`/api/devices/${deviceId}/status`);
const data = await resp.json();
if (data.ok) {
cell.textContent = data.state_name;
cell.className = getStateClass(data.state) + " status-cell";
cell.dataset.deviceId = deviceId;
}
} catch (e) {
// 网络错误静默跳过
}
}
}
function esc(s) { return s.replace(/'/g, "\\'").replace(/"/g, "&quot;"); }
async function editName(id, currentName, td) {
const input = document.createElement("input");
input.value = currentName;
td.innerHTML = "";
td.appendChild(input);
input.focus();
async function save() {
const name = input.value.trim();
td.textContent = name || "(点击编辑)";
await fetch(`/api/devices/${id}/name`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name }),
});
}
input.addEventListener("blur", save);
input.addEventListener("keydown", e => { if (e.key === "Enter") save(); });
}
loadDevices();
// 每 5 秒异步刷新设备在线状态
setInterval(refreshDeviceStatuses, 5000);