Files
TurboSu/static/js/pages/debug.js
T

130 lines
4.8 KiB
JavaScript

const PageDebug = {
_el: null,
_autoScroll: true,
_paused: false,
_rawData: [],
_fieldData: {},
_maxRawLines: 200,
init() {
this._el = document.getElementById('page-debug');
},
render() {
this._el.innerHTML = this._template();
this._bindEvents();
WS.on('telemetry', (data) => this._onTelemetry(data));
},
_bindEvents() {
document.getElementById('debug-clear-btn')?.addEventListener('click', () => {
this._rawData = [];
this._fieldData = {};
this._renderFields();
this._renderRaw();
});
document.getElementById('debug-pause-btn')?.addEventListener('click', () => {
this._paused = !this._paused;
const btn = document.getElementById('debug-pause-btn');
btn.textContent = this._paused ? '▶ 继续' : '⏸ 暂停';
});
document.getElementById('debug-autoscroll')?.addEventListener('change', (e) => {
this._autoScroll = e.target.checked;
});
document.getElementById('debug-show-log')?.addEventListener('click', async () => {
try {
const res = await fetch('/api/logs?lines=100');
const data = await res.json();
const el = document.getElementById('debug-raw');
if (el) el.innerHTML = data.lines.map(l =>
`<span style="color:${l.includes('ERROR')?'red':l.includes('WARNING')?'#f90':l.includes('INFO')?'#888':'#555'}">${l}</span>`
).join('\n');
} catch (e) { console.error(e); }
});
},
_onTelemetry(data) {
if (this._paused) return;
this._fieldData = data;
this._renderFields();
const timestamp = new Date().toISOString();
this._rawData.push({ timestamp, data: { ...data } });
if (this._rawData.length > this._maxRawLines) {
this._rawData.shift();
}
this._renderRaw();
},
_renderFields() {
const container = document.getElementById('debug-fields');
if (!container) return;
const keys = Object.keys(this._fieldData).filter(k => k !== 'raw');
container.innerHTML = keys.map(k => {
const val = this._fieldData[k];
const displayVal = typeof val === 'number' ? val.toFixed(3) : val;
return `
<div class="debug-field">
<div class="debug-field-name">${k}</div>
<div class="debug-field-value">${displayVal}</div>
</div>`;
}).join('') || '<div style="color:var(--text-tertiary);padding:20px;">等待数据...</div>';
},
_renderRaw() {
const el = document.getElementById('debug-raw');
if (!el) return;
const lines = this._rawData.map(entry => {
const ts = entry.timestamp.substring(11, 23);
const preview = JSON.stringify(entry.data).substring(0, 300);
return `<span style="color:var(--text-tertiary)">[${ts}]</span> <span style="color:var(--accent)">→</span> ${preview}`;
});
el.innerHTML = lines.join('\n') || '等待数据...';
if (this._autoScroll) {
el.scrollTop = el.scrollHeight;
}
},
cleanup() {
WS.off('telemetry', this._onTelemetry);
},
_template() {
return `
<div class="debug-container">
<div class="debug-toolbar animated">
<h2 style="font-size:20px;font-weight:700;">数据测试</h2>
<span style="flex:1;"></span>
<button id="debug-pause-btn" class="btn btn-sm btn-secondary">⏸ 暂停</button>
<button id="debug-clear-btn" class="btn btn-sm btn-secondary">清空</button>
<label style="display:flex;align-items:center;gap:6px;font-size:12px;color:var(--text-secondary);">
<input type="checkbox" id="debug-autoscroll" checked> 自动滚动
</label>
<button id="debug-show-log" class="btn btn-sm btn-secondary">📄 日志</button>
</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:16px;flex:1;min-height:0;">
<div style="overflow-y:auto;">
<h4 style="font-size:14px;color:var(--text-secondary);margin-bottom:12px;">解析后的数据字段</h4>
<div id="debug-fields">
<div style="color:var(--text-tertiary);padding:20px;">等待数据...</div>
</div>
</div>
<div style="overflow-y:auto;">
<h4 style="font-size:14px;color:var(--text-secondary);margin-bottom:12px;">原始 JSON 数据流</h4>
<div id="debug-raw" class="debug-data"></div>
</div>
</div>
</div>`;
}
};
window.PageDebug = PageDebug;