Showing
1 changed file
with
110 additions
and
49 deletions
| @@ -172,16 +172,32 @@ | @@ -172,16 +172,32 @@ | ||
| 172 | /* 控制台输出 */ | 172 | /* 控制台输出 */ |
| 173 | .console-output { | 173 | .console-output { |
| 174 | flex: 1; | 174 | flex: 1; |
| 175 | - padding: 15px; | ||
| 176 | background-color: #000000; | 175 | background-color: #000000; |
| 177 | color: #00ff00; | 176 | color: #00ff00; |
| 178 | font-family: 'Courier New', monospace; | 177 | font-family: 'Courier New', monospace; |
| 179 | font-size: 12px; | 178 | font-size: 12px; |
| 179 | + overflow: hidden; /* 隐藏滚动条,由内部面板控制 */ | ||
| 180 | + position: relative; | ||
| 181 | + min-height: 0; /* 允许内容缩小 */ | ||
| 182 | + max-height: 100%; /* 限制最大高度 */ | ||
| 183 | + } | ||
| 184 | + | ||
| 185 | + /* 控制台面板 */ | ||
| 186 | + .console-panel { | ||
| 187 | + position: absolute; | ||
| 188 | + top: 0; | ||
| 189 | + left: 0; | ||
| 190 | + width: 100%; | ||
| 191 | + height: 100%; | ||
| 192 | + padding: 15px; | ||
| 180 | overflow-y: auto; | 193 | overflow-y: auto; |
| 181 | white-space: pre-wrap; | 194 | white-space: pre-wrap; |
| 182 | word-break: break-all; | 195 | word-break: break-all; |
| 183 | - min-height: 0; /* 允许内容缩小 */ | ||
| 184 | - max-height: 100%; /* 限制最大高度 */ | 196 | + display: none; /* 默认隐藏 */ |
| 197 | + } | ||
| 198 | + | ||
| 199 | + .console-panel.active { | ||
| 200 | + display: block; /* 激活时显示 */ | ||
| 185 | } | 201 | } |
| 186 | 202 | ||
| 187 | .console-line { | 203 | .console-line { |
| @@ -304,7 +320,20 @@ | @@ -304,7 +320,20 @@ | ||
| 304 | 320 | ||
| 305 | <!-- 控制台输出 --> | 321 | <!-- 控制台输出 --> |
| 306 | <div class="console-output" id="consoleOutput"> | 322 | <div class="console-output" id="consoleOutput"> |
| 307 | - <div class="console-line">[系统] 等待连接...</div> | 323 | + <!-- Insight Engine 控制台 --> |
| 324 | + <div class="console-panel active" id="console-insight"> | ||
| 325 | + <div class="console-line">[系统] Insight Engine 控制台</div> | ||
| 326 | + </div> | ||
| 327 | + | ||
| 328 | + <!-- Media Engine 控制台 --> | ||
| 329 | + <div class="console-panel" id="console-media"> | ||
| 330 | + <div class="console-line">[系统] Media Engine 控制台</div> | ||
| 331 | + </div> | ||
| 332 | + | ||
| 333 | + <!-- Query Engine 控制台 --> | ||
| 334 | + <div class="console-panel" id="console-query"> | ||
| 335 | + <div class="console-line">[系统] Query Engine 控制台</div> | ||
| 336 | + </div> | ||
| 308 | </div> | 337 | </div> |
| 309 | </div> | 338 | </div> |
| 310 | </div> | 339 | </div> |
| @@ -338,6 +367,9 @@ | @@ -338,6 +367,9 @@ | ||
| 338 | checkStatus(); | 367 | checkStatus(); |
| 339 | setInterval(checkStatus, 5000); | 368 | setInterval(checkStatus, 5000); |
| 340 | 369 | ||
| 370 | + // 初始化行计数 | ||
| 371 | + lastLineCount = { insight: 1, media: 1, query: 1 }; // 跳过初始消息 | ||
| 372 | + | ||
| 341 | // 定期刷新控制台输出 | 373 | // 定期刷新控制台输出 |
| 342 | setInterval(() => { | 374 | setInterval(() => { |
| 343 | refreshConsoleOutput(); | 375 | refreshConsoleOutput(); |
| @@ -363,8 +395,16 @@ | @@ -363,8 +395,16 @@ | ||
| 363 | }); | 395 | }); |
| 364 | 396 | ||
| 365 | socket.on('console_output', function(data) { | 397 | socket.on('console_output', function(data) { |
| 366 | - if (data.app === currentApp) { | ||
| 367 | - addConsoleOutput(data.line); | 398 | + // 直接添加到对应应用的控制台面板,不依赖currentApp |
| 399 | + const consolePanel = document.getElementById(`console-${data.app}`); | ||
| 400 | + if (consolePanel) { | ||
| 401 | + const div = document.createElement('div'); | ||
| 402 | + div.className = 'console-line'; | ||
| 403 | + div.textContent = data.line; | ||
| 404 | + consolePanel.appendChild(div); | ||
| 405 | + | ||
| 406 | + // 自动滚动到底部 | ||
| 407 | + consolePanel.scrollTop = consolePanel.scrollHeight; | ||
| 368 | } | 408 | } |
| 369 | }); | 409 | }); |
| 370 | 410 | ||
| @@ -449,12 +489,24 @@ | @@ -449,12 +489,24 @@ | ||
| 449 | 489 | ||
| 450 | currentApp = app; | 490 | currentApp = app; |
| 451 | 491 | ||
| 452 | - // 清空并加载新的控制台输出 | ||
| 453 | - document.getElementById('consoleOutput').innerHTML = '<div class="console-line">[系统] 切换到 ' + app + ' 应用</div>'; | 492 | + // 切换控制台面板显示 |
| 493 | + document.querySelectorAll('.console-panel').forEach(panel => { | ||
| 494 | + panel.classList.remove('active'); | ||
| 495 | + }); | ||
| 496 | + document.getElementById(`console-${app}`).classList.add('active'); | ||
| 454 | 497 | ||
| 455 | - // 重置行计数 | ||
| 456 | - lastLineCount[app] = 0; | ||
| 457 | - loadConsoleOutput(app); | 498 | + // 只在面板为空时加载输出,不重置行计数 |
| 499 | + const consolePanel = document.getElementById(`console-${app}`); | ||
| 500 | + if (consolePanel && consolePanel.children.length <= 1) { // 只有初始消息 | ||
| 501 | + loadConsoleOutput(app); | ||
| 502 | + } | ||
| 503 | + | ||
| 504 | + // 切换后滚动到底部 | ||
| 505 | + setTimeout(() => { | ||
| 506 | + if (consolePanel) { | ||
| 507 | + consolePanel.scrollTop = consolePanel.scrollHeight; | ||
| 508 | + } | ||
| 509 | + }, 100); | ||
| 458 | 510 | ||
| 459 | // 更新嵌入页面 | 511 | // 更新嵌入页面 |
| 460 | updateEmbeddedPage(app); | 512 | updateEmbeddedPage(app); |
| @@ -469,7 +521,7 @@ | @@ -469,7 +521,7 @@ | ||
| 469 | .then(response => response.json()) | 521 | .then(response => response.json()) |
| 470 | .then(data => { | 522 | .then(data => { |
| 471 | if (data.success && data.output.length > 0) { | 523 | if (data.success && data.output.length > 0) { |
| 472 | - const consoleOutput = document.getElementById('consoleOutput'); | 524 | + const consolePanel = document.getElementById(`console-${app}`); |
| 473 | 525 | ||
| 474 | // 只添加新的行 | 526 | // 只添加新的行 |
| 475 | const lastCount = lastLineCount[app] || 0; | 527 | const lastCount = lastLineCount[app] || 0; |
| @@ -479,11 +531,11 @@ | @@ -479,11 +531,11 @@ | ||
| 479 | const div = document.createElement('div'); | 531 | const div = document.createElement('div'); |
| 480 | div.className = 'console-line'; | 532 | div.className = 'console-line'; |
| 481 | div.textContent = line; | 533 | div.textContent = line; |
| 482 | - consoleOutput.appendChild(div); | 534 | + consolePanel.appendChild(div); |
| 483 | }); | 535 | }); |
| 484 | 536 | ||
| 485 | lastLineCount[app] = data.output.length; | 537 | lastLineCount[app] = data.output.length; |
| 486 | - consoleOutput.scrollTop = consoleOutput.scrollHeight; | 538 | + consolePanel.scrollTop = consolePanel.scrollHeight; |
| 487 | } | 539 | } |
| 488 | }) | 540 | }) |
| 489 | .catch(error => { | 541 | .catch(error => { |
| @@ -491,48 +543,57 @@ | @@ -491,48 +543,57 @@ | ||
| 491 | }); | 543 | }); |
| 492 | } | 544 | } |
| 493 | 545 | ||
| 494 | - // 刷新当前应用的控制台输出 | 546 | + // 刷新所有应用的控制台输出 |
| 495 | function refreshConsoleOutput() { | 547 | function refreshConsoleOutput() { |
| 496 | - if (appStatus[currentApp] === 'running' || appStatus[currentApp] === 'starting') { | ||
| 497 | - fetch(`/api/output/${currentApp}`) | ||
| 498 | - .then(response => response.json()) | ||
| 499 | - .then(data => { | ||
| 500 | - if (data.success && data.output.length > 0) { | ||
| 501 | - const consoleOutput = document.getElementById('consoleOutput'); | ||
| 502 | - | ||
| 503 | - // 只添加新的行 | ||
| 504 | - const lastCount = lastLineCount[currentApp] || 0; | ||
| 505 | - const newLines = data.output.slice(lastCount); | ||
| 506 | - | ||
| 507 | - if (newLines.length > 0) { | ||
| 508 | - newLines.forEach(line => { | ||
| 509 | - const div = document.createElement('div'); | ||
| 510 | - div.className = 'console-line'; | ||
| 511 | - div.textContent = line; | ||
| 512 | - consoleOutput.appendChild(div); | ||
| 513 | - }); | 548 | + // 为每个应用刷新输出,不只是当前应用 |
| 549 | + Object.keys(appStatus).forEach(app => { | ||
| 550 | + if (appStatus[app] === 'running' || appStatus[app] === 'starting') { | ||
| 551 | + fetch(`/api/output/${app}`) | ||
| 552 | + .then(response => response.json()) | ||
| 553 | + .then(data => { | ||
| 554 | + if (data.success && data.output.length > 0) { | ||
| 555 | + const consolePanel = document.getElementById(`console-${app}`); | ||
| 556 | + | ||
| 557 | + // 只添加新的行 | ||
| 558 | + const lastCount = lastLineCount[app] || 0; | ||
| 559 | + const newLines = data.output.slice(lastCount); | ||
| 514 | 560 | ||
| 515 | - lastLineCount[currentApp] = data.output.length; | ||
| 516 | - consoleOutput.scrollTop = consoleOutput.scrollHeight; | 561 | + if (newLines.length > 0) { |
| 562 | + newLines.forEach(line => { | ||
| 563 | + const div = document.createElement('div'); | ||
| 564 | + div.className = 'console-line'; | ||
| 565 | + div.textContent = line; | ||
| 566 | + consolePanel.appendChild(div); | ||
| 567 | + }); | ||
| 568 | + | ||
| 569 | + lastLineCount[app] = data.output.length; | ||
| 570 | + // 只有当前显示的面板才自动滚动 | ||
| 571 | + if (app === currentApp) { | ||
| 572 | + consolePanel.scrollTop = consolePanel.scrollHeight; | ||
| 573 | + } | ||
| 574 | + } | ||
| 517 | } | 575 | } |
| 518 | - } | ||
| 519 | - }) | ||
| 520 | - .catch(error => { | ||
| 521 | - console.error('刷新输出失败:', error); | ||
| 522 | - }); | ||
| 523 | - } | 576 | + }) |
| 577 | + .catch(error => { | ||
| 578 | + console.error(`刷新${app}输出失败:`, error); | ||
| 579 | + }); | ||
| 580 | + } | ||
| 581 | + }); | ||
| 524 | } | 582 | } |
| 525 | 583 | ||
| 526 | // 添加控制台输出 | 584 | // 添加控制台输出 |
| 527 | function addConsoleOutput(line) { | 585 | function addConsoleOutput(line) { |
| 528 | - const consoleOutput = document.getElementById('consoleOutput'); | ||
| 529 | - const div = document.createElement('div'); | ||
| 530 | - div.className = 'console-line'; | ||
| 531 | - div.textContent = line; | ||
| 532 | - consoleOutput.appendChild(div); | ||
| 533 | - | ||
| 534 | - // 自动滚动到底部显示最新内容 | ||
| 535 | - consoleOutput.scrollTop = consoleOutput.scrollHeight; | 586 | + // 根据当前应用添加到对应的控制台面板 |
| 587 | + const consolePanel = document.getElementById(`console-${currentApp}`); | ||
| 588 | + if (consolePanel) { | ||
| 589 | + const div = document.createElement('div'); | ||
| 590 | + div.className = 'console-line'; | ||
| 591 | + div.textContent = line; | ||
| 592 | + consolePanel.appendChild(div); | ||
| 593 | + | ||
| 594 | + // 自动滚动到底部显示最新内容 | ||
| 595 | + consolePanel.scrollTop = consolePanel.scrollHeight; | ||
| 596 | + } | ||
| 536 | } | 597 | } |
| 537 | 598 | ||
| 538 | // 预加载的iframe存储 | 599 | // 预加载的iframe存储 |
-
Please register or login to post a comment