// 测试信息页 — 三视图 (全部 / B2 / B4) // ─── 视图定义 ─────────────────────────────────── const VIEWS = { all: { label: '全部数据', data_source: '', // '' = 不过滤 cols: [ { key: 'id', title: 'ID' }, { key: 'serial', title: '设备编码' }, { key: 'dpg430_addr', title: '地址' }, { key: 'model', title: '型号', render: r => r.sub_type === 1 ? 'PD132' : r.sub_type === 2 ? 'DLD110' : '-' }, { key: 'str_type', title: '类型' }, { key: 'data_source', title: '来源' }, { key: 'test_mode', title: '测试模式', render: r => r.test_mode === 1 ? '波动' : '灵敏度' }, { key: 'ppvalue', title: '峰峰值(V)', render: r => r.ppvalue?.toFixed(2) || '-' }, { key: 'idle_freq', title: '开始频率' }, { key: 'enter_dist', title: '进入距离' }, { key: 'exit_dist', title: '离开距离' }, { key: 'remain_count', title: '剩余次数' }, { key: 'curr_dist', title: '当前距离' }, { key: 'create_time', title: '时间' }, ], }, b2: { label: '灵敏度测试', data_source: 'B2', cols: [ { key: 'id', title: 'ID' }, { key: 'serial', title: '设备编码' }, { key: 'dpg430_addr', title: '地址' }, { key: 'model', title: '型号', render: r => r.sub_type === 1 ? 'PD132' : r.sub_type === 2 ? 'DLD110' : '-' }, { key: 'str_type', title: '类型' }, { key: 'test_mode', title: '测试模式', render: r => r.test_mode === 1 ? '波动' : '灵敏度' }, { key: 'iffinish', title: '完成', render: r => r.iffinish === '1' ? '是' : '否' }, { key: 'fault_info', title: '故障信息' }, { key: 'relay_out', title: '继电器' }, { key: 'ppvalue', title: '峰峰值(V)', render: r => r.ppvalue?.toFixed(2) || '-' }, { key: 'idle_freq', title: '开始频率' }, { key: 'enter_freq', title: '进入频率' }, { key: 'exit_freq', title: '离开频率' }, { key: 'enter_dist', title: '进入距离' }, { key: 'exit_dist', title: '离开距离' }, { key: 'enter_speed', title: '进入速度', render: r => toSpeed(r.enter_speed) }, { key: 'exit_speed', title: '离开速度', render: r => toSpeed(r.exit_speed) }, { key: 'create_time', title: '时间' }, ], }, b4: { label: '波动测试', data_source: 'B4', cols: [ { key: 'id', title: 'ID' }, { key: 'serial', title: '设备编码' }, { key: 'dpg430_addr', title: '地址' }, { key: 'remain_count', title: '剩余次数' }, { key: 'work_freq', title: '工作频率(Hz)' }, { key: 'curr_dist', title: '当前距离(mm)' }, { key: 'speed', title: '速度(dm/s)' }, { key: 'near_dist', title: '最近距离(mm)' }, { key: 'far_dist', title: '最远距离(mm)' }, { key: 'b4_enter_dist', title: '进入高度(mm)' }, { key: 'b4_leave_dist', title: '离开高度(mm)' }, { key: 'relay_out', title: '继电器' }, { key: 'create_time', title: '时间' }, ], }, }; // ─── 状态 ─────────────────────────────────────── let currentView = 'all'; let currentPage = 1; let totalPages = 1; function toSpeed(v) { if (v === null || v === undefined || v === '') return '-'; return (parseFloat(v) / 10).toFixed(1); } // ─── 视图切换 ──────────────────────────────────── function switchView(view) { currentView = view; document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active')); document.getElementById('tab-' + view).classList.add('active'); // 重置分页 currentPage = 1; searchData(1); } // ─── 查询 ──────────────────────────────────────── async function searchData(page = 1) { currentPage = page; const serial = document.getElementById("search-serial").value; const dateFrom = document.getElementById("search-date-from").value; const dateTo = document.getElementById("search-date-to").value; const v = VIEWS[currentView]; const perPage = parseInt(document.getElementById("per-page").value) || 20; const params = new URLSearchParams({ page, per_page: perPage }); if (serial) params.set("serial", serial); if (dateFrom) params.set("date_from", dateFrom); if (dateTo) params.set("date_to", dateTo); // 按 data_source 过滤(全部不过滤) if (v.data_source) { params.set("data_source", v.data_source); } try { const resp = await fetch(`/api/test-data?${params}`); const data = await resp.json(); renderTable(data.records); totalPages = data.pages; renderPagination(); } catch (e) { console.error("查询失败:", e); } } // ─── 渲染表头 ──────────────────────────────────── function renderHead() { const thead = document.querySelector("#test-data-table thead"); const v = VIEWS[currentView]; thead.innerHTML = '' + v.cols.map(c => `${c.title}`).join('') + ''; } // ─── 渲染数据行 ────────────────────────────────── function renderTable(records) { renderHead(); const tbody = document.querySelector("#test-data-table tbody"); const v = VIEWS[currentView]; const nCols = v.cols.length; if (!records.length) { tbody.innerHTML = `暂无数据`; return; } tbody.innerHTML = records.map(r => '' + v.cols.map(c => { if (c.render) return `${c.render(r)}`; const val = r[c.key]; return `${val !== null && val !== undefined && val !== '' ? val : '-'}`; }).join('') + '' ).join(""); } // ─── 分页 ──────────────────────────────────────── function renderPagination() { const div = document.getElementById("pagination"); let html = ""; html += ``; for (let i = 1; i <= totalPages; i++) { if (i === currentPage) { html += ``; } else { html += ``; } } html += ``; div.innerHTML = html; } // ─── 导出 ──────────────────────────────────────── function exportCSV() { const serial = document.getElementById("search-serial").value; const dateFrom = document.getElementById("search-date-from").value; const dateTo = document.getElementById("search-date-to").value; const v = VIEWS[currentView]; const params = new URLSearchParams(); if (serial) params.set("serial", serial); if (dateFrom) params.set("date_from", dateFrom); if (dateTo) params.set("date_to", dateTo); if (v.data_source) params.set("data_source", v.data_source); window.location.href = `/api/test-data/export?${params}`; } // ─── 初始加载 ──────────────────────────────────── renderHead(); searchData(1);