Repair the Logic of the Log Viewing System

This commit is contained in:
马一丁
2025-11-15 16:21:49 +08:00
parent 6e8741f0ae
commit cab812e261

View File

@@ -326,6 +326,16 @@
min-height: 0; /* 允许内容缩小 */
}
.console-layer {
display: none;
width: 100%;
min-height: 100%;
}
.console-layer.active {
display: block;
}
.console-line {
margin-bottom: 2px;
}
@@ -1153,9 +1163,7 @@
</div>
<!-- 控制台输出 -->
<div class="console-output" id="consoleOutput">
<div class="console-line">[系统] 等待连接...</div>
</div>
<div class="console-output" id="consoleOutput"></div>
</div>
</div>
@@ -1214,6 +1222,10 @@
let socketConnected = false;
let reportStreamConnected = false;
let backendReachable = false;
const consoleLayerApps = ['insight', 'media', 'query', 'forum', 'report'];
const consoleLayers = {};
const consoleLayerScrollPositions = {};
let activeConsoleLayer = currentApp;
const CONFIG_ENDPOINT = '/api/config';
const SYSTEM_STATUS_ENDPOINT = '/api/system/status';
@@ -1318,9 +1330,11 @@
// 初始化
document.addEventListener('DOMContentLoaded', function() {
initializeConsoleLayers();
initializeSocket();
initializeEventListeners();
ensureSystemReadyOnLoad();
loadConsoleOutput(currentApp);
updateTime();
setInterval(updateTime, 1000);
checkStatus();
@@ -1370,9 +1384,7 @@
socket.on('console_output', function(data) {
// 处理控制台输出
if (data.app === currentApp) {
addConsoleOutput(data.line);
}
addConsoleOutput(data.line, data.app);
// 如果是forum的输出同时也处理为论坛消息
if (data.app === 'forum') {
@@ -2014,6 +2026,7 @@
document.querySelector(`[data-app="${app}"]`).classList.add('active');
currentApp = app;
setActiveConsoleLayer(app);
// 根据应用类型处理不同的显示逻辑
if (app === 'forum') {
@@ -2024,8 +2037,8 @@
document.getElementById('forumContainer').classList.add('active');
document.getElementById('reportContainer').classList.remove('active');
// 清空控制台并加载forum日志
document.getElementById('consoleOutput').innerHTML = '<div class="console-line">[系统] 切换到论坛模式</div>';
// 追加提示并加载forum日志
appendConsoleTextLine('forum', '[系统] 切换到论坛模式');
loadForumLog();
} else if (app === 'report') {
@@ -2036,8 +2049,8 @@
document.getElementById('reportContainer').classList.add('active');
document.getElementById('forumContainer').classList.remove('active');
// 清空控制台并加载report日志
document.getElementById('consoleOutput').innerHTML = '<div class="console-line">[系统] 切换到报告生成模式</div>';
// 追加提示并加载report日志
appendConsoleTextLine('report', '[系统] 切换到报告生成模式');
loadReportLog();
// 只在报告界面未初始化时才重新加载
@@ -2059,11 +2072,8 @@
document.getElementById('forumContainer').classList.remove('active');
document.getElementById('reportContainer').classList.remove('active');
// 清空并加载新的控制台输出
document.getElementById('consoleOutput').innerHTML = '<div class="console-line">[系统] 切换到 ' + appNames[app] + '</div>';
// 重置行计数
lastLineCount[app] = 0;
// 追加提示并加载新的控制台输出
appendConsoleTextLine(app, '[系统] 切换到 ' + appNames[app]);
loadConsoleOutput(app);
}
@@ -2073,6 +2083,127 @@
// 存储最后显示的行数,避免重复加载
let lastLineCount = {};
function getConsoleContainer() {
return document.getElementById('consoleOutput');
}
function initializeConsoleLayers() {
const container = getConsoleContainer();
if (!container) return;
container.innerHTML = '';
consoleLayerApps.forEach(app => {
const layer = document.createElement('div');
layer.className = 'console-layer';
layer.dataset.app = app;
if (app === currentApp) {
layer.classList.add('active');
layer.style.display = 'block';
activeConsoleLayer = app;
} else {
layer.style.display = 'none';
}
const placeholder = document.createElement('div');
placeholder.className = 'console-line';
placeholder.textContent = `[系统] ${appNames[app] || app} 日志就绪`;
layer.appendChild(placeholder);
container.appendChild(layer);
consoleLayers[app] = layer;
});
container.scrollTop = container.scrollHeight;
}
function getConsoleLayer(app) {
if (consoleLayers[app]) {
return consoleLayers[app];
}
const container = getConsoleContainer();
if (!container) return null;
const layer = document.createElement('div');
layer.className = 'console-layer';
layer.dataset.app = app;
layer.style.display = app === currentApp ? 'block' : 'none';
if (app === currentApp) {
layer.classList.add('active');
activeConsoleLayer = app;
}
container.appendChild(layer);
consoleLayers[app] = layer;
return layer;
}
function setActiveConsoleLayer(app) {
const container = getConsoleContainer();
if (!container) return;
if (activeConsoleLayer && consoleLayers[activeConsoleLayer]) {
consoleLayerScrollPositions[activeConsoleLayer] = container.scrollTop;
consoleLayers[activeConsoleLayer].classList.remove('active');
consoleLayers[activeConsoleLayer].style.display = 'none';
}
const targetLayer = getConsoleLayer(app);
if (!targetLayer) return;
targetLayer.style.display = 'block';
targetLayer.classList.add('active');
activeConsoleLayer = app;
const storedScroll = consoleLayerScrollPositions[app];
if (typeof storedScroll === 'number') {
container.scrollTop = storedScroll;
} else {
container.scrollTop = container.scrollHeight;
}
}
function syncConsoleScroll(app) {
if (app !== currentApp) {
return;
}
const container = getConsoleContainer();
if (container) {
container.scrollTop = container.scrollHeight;
consoleLayerScrollPositions[app] = container.scrollTop;
}
}
function appendConsoleTextLine(app, text, className = 'console-line') {
const layer = getConsoleLayer(app);
if (!layer) return;
const line = document.createElement('div');
line.className = className;
line.textContent = text;
layer.appendChild(line);
syncConsoleScroll(app);
}
function appendConsoleElement(app, element) {
const layer = getConsoleLayer(app);
if (!layer || !element) return;
layer.appendChild(element);
syncConsoleScroll(app);
}
function clearConsoleLayer(app, message = null) {
const layer = getConsoleLayer(app);
if (!layer) return;
layer.innerHTML = '';
if (message) {
appendConsoleTextLine(app, message);
}
}
// 加载控制台输出
function loadConsoleOutput(app) {
@@ -2090,21 +2221,15 @@
.then(response => response.json())
.then(data => {
if (data.success && data.output.length > 0) {
const consoleOutput = document.getElementById('consoleOutput');
// 只添加新的行
const lastCount = lastLineCount[app] || 0;
const newLines = data.output.slice(lastCount);
newLines.forEach(line => {
const div = document.createElement('div');
div.className = 'console-line';
div.textContent = line;
consoleOutput.appendChild(div);
});
lastLineCount[app] = data.output.length;
consoleOutput.scrollTop = consoleOutput.scrollHeight;
if (newLines.length > 0) {
newLines.forEach(line => {
appendConsoleTextLine(app, line);
});
lastLineCount[app] = data.output.length;
}
}
})
.catch(error => {
@@ -2129,22 +2254,15 @@
.then(response => response.json())
.then(data => {
if (data.success && data.output.length > 0) {
const consoleOutput = document.getElementById('consoleOutput');
// 只添加新的行
const lastCount = lastLineCount[currentApp] || 0;
const newLines = data.output.slice(lastCount);
if (newLines.length > 0) {
newLines.forEach(line => {
const div = document.createElement('div');
div.className = 'console-line';
div.textContent = line;
consoleOutput.appendChild(div);
appendConsoleTextLine(currentApp, line);
});
lastLineCount[currentApp] = data.output.length;
consoleOutput.scrollTop = consoleOutput.scrollHeight;
}
}
})
@@ -2155,15 +2273,13 @@
}
// 添加控制台输出
function addConsoleOutput(line) {
const consoleOutput = document.getElementById('consoleOutput');
const div = document.createElement('div');
div.className = 'console-line';
div.textContent = line;
consoleOutput.appendChild(div);
function addConsoleOutput(line, app = currentApp) {
const targetApp = app || currentApp;
appendConsoleTextLine(targetApp, line);
// 自动滚动到底部显示最新内容
consoleOutput.scrollTop = consoleOutput.scrollHeight;
if (targetApp !== 'report') {
lastLineCount[targetApp] = (lastLineCount[targetApp] || 0) + 1;
}
}
// 预加载的iframe存储
@@ -2522,15 +2638,16 @@
`;
// 加载控制台日志
const consoleOutput = document.getElementById('consoleOutput');
consoleOutput.innerHTML = '<div class="console-line">[系统] Forum Engine 日志输出</div>';
if (data.log_lines && data.log_lines.length > 0) {
data.log_lines.forEach(line => {
const div = document.createElement('div');
div.className = 'console-line';
div.textContent = line;
consoleOutput.appendChild(div);
if (forumLogLineCount === 0) {
clearConsoleLayer('forum', '[系统] Forum Engine 日志输出');
}
const newLines = data.log_lines.slice(forumLogLineCount);
const linesToProcess = forumLogLineCount === 0 ? data.log_lines : newLines;
linesToProcess.forEach(line => {
appendConsoleTextLine('forum', line);
// 解析并添加到对话区
const parsed = parseForumMessage(line);
@@ -2553,7 +2670,6 @@
});
}
consoleOutput.scrollTop = consoleOutput.scrollHeight;
}
})
.catch(error => {
@@ -2567,15 +2683,10 @@
.then(response => response.json())
.then(data => {
if (data.success && data.log_lines.length > forumLogLineCount) {
const consoleOutput = document.getElementById('consoleOutput');
// 只添加新的行
const newLines = data.log_lines.slice(forumLogLineCount);
newLines.forEach(line => {
const div = document.createElement('div');
div.className = 'console-line';
div.textContent = line;
consoleOutput.appendChild(div);
appendConsoleTextLine('forum', line);
// 如果是论坛对话内容,也显示到左侧对话区
const parsed = parseForumMessage(line);
@@ -2585,7 +2696,6 @@
});
forumLogLineCount = data.log_lines.length;
consoleOutput.scrollTop = consoleOutput.scrollHeight;
}
})
.catch(error => {
@@ -2650,19 +2760,13 @@
.then(response => response.json())
.then(data => {
if (data.success && data.log_lines.length > reportLogLineCount) {
const consoleOutput = document.getElementById('consoleOutput');
// 只添加新的行
const newLines = data.log_lines.slice(reportLogLineCount);
newLines.forEach(line => {
const div = document.createElement('div');
div.className = 'console-line';
div.textContent = line;
consoleOutput.appendChild(div);
appendConsoleTextLine('report', line);
});
reportLogLineCount = data.log_lines.length;
consoleOutput.scrollTop = consoleOutput.scrollHeight;
}
})
.catch(error => {
@@ -2676,15 +2780,16 @@
.then(response => response.json())
.then(data => {
if (data.success) {
const consoleOutput = document.getElementById('consoleOutput');
consoleOutput.innerHTML = '<div class="console-line">[系统] Report Engine 日志监控已启动</div>';
if (reportLogLineCount === 0) {
clearConsoleLayer('report', '[系统] Report Engine 日志监控已启动');
}
if (data.log_lines && data.log_lines.length > 0) {
data.log_lines.forEach(line => {
const div = document.createElement('div');
div.className = 'console-line';
div.textContent = line;
consoleOutput.appendChild(div);
const newLines = data.log_lines.slice(reportLogLineCount);
const linesToProcess = reportLogLineCount === 0 ? data.log_lines : newLines;
linesToProcess.forEach(line => {
appendConsoleTextLine('report', line);
});
// 重置计数器以确保后续消息能正确显示
@@ -2693,8 +2798,6 @@
// 如果没有日志,重置计数器
reportLogLineCount = 0;
}
consoleOutput.scrollTop = consoleOutput.scrollHeight;
}
})
.catch(error => {
@@ -3168,8 +3271,7 @@
safeCloseReportStream(true);
// 清空控制台显示
const consoleOutput = document.getElementById('consoleOutput');
consoleOutput.innerHTML = '<div class="console-line">[系统] 开始生成报告,日志已重置</div>';
clearConsoleLayer('report', '[系统] 开始生成报告,日志已重置');
resetReportStreamOutput('Report Engine 正在调度任务...');
setGenerateButtonState(true);
@@ -3381,9 +3483,6 @@
// 往黑色控制台输出区域追加一条流式日志
function appendReportStreamLine(message, level = 'info', options = {}) {
const consoleOutput = document.getElementById('consoleOutput');
if (!consoleOutput) return;
if (level === 'chunk' && !options.force) {
return; // 章节内容流式写入不再逐条输出
}
@@ -3408,8 +3507,7 @@
textSpan.textContent = message;
line.appendChild(textSpan);
consoleOutput.appendChild(line);
consoleOutput.scrollTop = consoleOutput.scrollHeight;
appendConsoleElement('report', line);
}
function startStreamHeartbeat() {