Toggle navigation
Toggle navigation
This project
Loading...
Sign in
万朱浩
/
Venue-Ops
Go to a project
Toggle navigation
Projects
Groups
Snippets
Help
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
马一丁
2025-11-19 20:12:37 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
269b2ec5dd0b2e736425c688fd423c84d54e2823
269b2ec5
1 parent
d8afd95c
Optimize Log Display Logic
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
90 additions
and
38 deletions
templates/index.html
templates/index.html
View file @
269b2ec
...
...
@@ -317,26 +317,35 @@
/* 控制台输出 */
.console-output
{
flex
:
1
;
padding
:
15px
;
background-color
:
#000000
;
color
:
#00ff00
;
font-family
:
'Courier New'
,
monospace
;
font-size
:
12px
;
overflow-y
:
auto
;
overflow-x
:
hidden
;
overflow
:
hidden
;
/* 【图层优化】容器本身不滚动,由console-layer滚动 */
white-space
:
pre-wrap
;
word-break
:
break-all
;
min-height
:
0
;
/* 允许内容缩小 */
position
:
relative
;
/* 【图层优化】作为定位上下文,让console-layer相对于此容器定位 */
}
.console-layer
{
display
:
none
;
visibility
:
hidden
;
/* 使用visibility替代display,避免重排 */
position
:
absolute
;
/* 相对于.console-output绝对定位 */
top
:
0
;
left
:
0
;
width
:
100%
;
min-height
:
100%
;
height
:
100%
;
/* 填满整个黑色框 */
padding
:
15px
;
/* 图层内边距 */
overflow-y
:
auto
;
/* 允许独立滚动 */
overflow-x
:
hidden
;
pointer-events
:
none
;
/* 隐藏层不响应交互 */
box-sizing
:
border-box
;
/* 包含padding在width/height内 */
}
.console-layer.active
{
display
:
block
;
visibility
:
visible
;
/* 显示活动层 */
pointer-events
:
auto
;
/* 活动层响应交互 */
z-index
:
1
;
/* 置顶显示 */
}
.console-line
{
...
...
@@ -1363,7 +1372,8 @@
class
LogVirtualList
{
constructor
(
container
)
{
this
.
container
=
container
;
this
.
scrollElement
=
document
.
getElementById
(
'consoleOutput'
)
||
container
;
// 【图层优化】scrollElement 就是 container(.console-layer),因为每个图层独立滚动
this
.
scrollElement
=
container
;
this
.
lines
=
[];
this
.
pending
=
[];
this
.
pool
=
[];
...
...
@@ -1400,6 +1410,10 @@
this
.
renderTime
=
0
;
// 渲染耗时
this
.
lastRenderLineCount
=
0
;
// 上次渲染的行数
// 【图层优化】窗口激活状态管理
this
.
isActive
=
false
;
// 当前窗口是否为活动窗口
this
.
needsRender
=
false
;
// 非活动窗口是否有待渲染内容
this
.
attachScroll
();
}
...
...
@@ -1585,6 +1599,24 @@
if
(
px
>
0
)
this
.
lineHeight
=
px
;
}
/**
* 【图层优化】设置窗口激活状态
* @param {boolean} active - 是否为活动窗口
*/
setActive
(
active
)
{
this
.
isActive
=
active
;
if
(
active
&&
this
.
needsRender
)
{
// 窗口激活时,如果有待渲染内容,异步渲染
requestIdleCallback
(()
=>
{
if
(
this
.
pending
.
length
>
0
)
{
this
.
flush
();
}
this
.
scheduleRender
(
true
);
this
.
needsRender
=
false
;
},
{
timeout
:
50
});
}
}
append
(
text
,
className
=
'console-line'
)
{
// 在添加内容前检查是否在底部,如果是则标记需要滚动
if
(
this
.
autoScrollEnabled
&&
this
.
isNearBottom
())
{
...
...
@@ -1598,7 +1630,18 @@
this
.
pendingHighWaterMark
=
this
.
pending
.
length
;
}
// 【优化】智能批处理策略
// 【图层优化】非活动窗口处理策略
if
(
!
this
.
isActive
)
{
// 非活动窗口:只累积数据,不触发渲染
// 设置队列上限,防止内存溢出
if
(
this
.
pending
.
length
>=
1000
)
{
this
.
flush
();
// 定期flush避免内存溢出
this
.
needsRender
=
true
;
// 标记需要渲染
}
return
;
// 跳过后续渲染逻辑
}
// 【优化】活动窗口:智能批处理策略
const
now
=
Date
.
now
();
const
timeSinceLastFlush
=
now
-
this
.
lastFlushTime
;
...
...
@@ -1691,6 +1734,16 @@
if
(
!
this
.
container
)
return
;
if
(
!
force
&&
this
.
rafId
)
return
;
// 【图层优化】检查窗口是否可见
if
(
!
force
&&
!
this
.
isActive
)
{
// 非活动窗口:只flush数据,不渲染DOM
if
(
this
.
pending
.
length
>
0
)
{
this
.
flush
();
// 保存数据到lines
this
.
needsRender
=
true
;
// 标记需要渲染
}
return
;
// 跳过DOM操作
}
// 取消之前的请求
if
(
this
.
rafId
)
{
cancelAnimationFrame
(
this
.
rafId
);
...
...
@@ -2698,17 +2751,16 @@
// 更新当前应用
currentApp
=
app
;
//
切换控制台层(不添加系统提示,避免频繁输出
)
//
【图层优化】切换控制台层(纯CSS图层切换,瞬间完成
)
setActiveConsoleLayer
(
app
);
// 更新嵌入页面(右侧内容区域)
updateEmbeddedPage
(
app
);
// 加载对应的控制台输出(只在必要时加载)
if
(
app
===
'forum'
)
{
loadForumLog
();
}
else
if
(
app
===
'report'
)
{
loadReportLog
();
// 【图层优化】移除重复加载逻辑
// 日志数据已通过Socket.IO/SSE实时同步,无需重新加载
// 仅保留特殊页面的初始化逻辑
if
(
app
===
'report'
)
{
// 只在报告界面未初始化时才重新加载
const
reportContent
=
document
.
getElementById
(
'reportContent'
);
if
(
!
reportContent
||
reportContent
.
children
.
length
===
0
)
{
...
...
@@ -2718,8 +2770,6 @@
setTimeout
(()
=>
{
checkReportLockStatus
();
},
500
);
}
else
{
loadConsoleOutput
(
app
);
}
}
...
...
@@ -2806,16 +2856,19 @@
layer
.
dataset
.
app
=
app
;
if
(
app
===
currentApp
)
{
layer
.
classList
.
add
(
'active'
);
layer
.
style
.
display
=
'block'
;
activeConsoleLayer
=
app
;
}
else
{
layer
.
style
.
display
=
'none'
;
}
// 【图层优化】不再设置style.display,完全由CSS类控制
container
.
appendChild
(
layer
);
consoleLayers
[
app
]
=
layer
;
logRenderers
[
app
]
=
new
LogVirtualList
(
layer
);
// 【图层优化】标记活动窗口
if
(
app
===
currentApp
)
{
logRenderers
[
app
].
isActive
=
true
;
}
// 【FIX Bug #3】初始提示立即渲染,避免黑屏
logRenderers
[
app
].
clear
(
`
[
系统
]
$
{
appNames
[
app
]
||
app
}
日志就绪`
);
logRenderers
[
app
].
render
();
// 立即同步渲染
...
...
@@ -2835,7 +2888,7 @@
const
layer
=
document
.
createElement
(
'div'
);
layer
.
className
=
'console-layer'
;
layer
.
dataset
.
app
=
app
;
layer
.
style
.
display
=
app
===
currentApp
?
'block'
:
'none'
;
// 【图层优化】不再设置style.display,完全由CSS类控制
if
(
app
===
currentApp
)
{
layer
.
classList
.
add
(
'active'
);
activeConsoleLayer
=
app
;
...
...
@@ -2844,6 +2897,12 @@
container
.
appendChild
(
layer
);
consoleLayers
[
app
]
=
layer
;
logRenderers
[
app
]
=
new
LogVirtualList
(
layer
);
// 【图层优化】标记活动窗口
if
(
app
===
currentApp
)
{
logRenderers
[
app
].
isActive
=
true
;
}
return
layer
;
}
...
...
@@ -2852,43 +2911,36 @@
if
(
!
container
)
return
;
// 如果已经是当前激活的层,跳过
if
(
activeConsoleLayer
===
app
&&
consoleLayers
[
app
]
&&
consoleLayers
[
app
].
style
.
display
===
'block'
)
{
if
(
activeConsoleLayer
===
app
&&
consoleLayers
[
app
]
&&
consoleLayers
[
app
].
classList
.
contains
(
'active'
)
)
{
return
;
}
//
隐藏旧的激活层
//
【图层优化】标记旧窗口为非活动
if
(
activeConsoleLayer
&&
consoleLayers
[
activeConsoleLayer
])
{
consoleLayers
[
activeConsoleLayer
].
classList
.
remove
(
'active'
);
consoleLayers
[
activeConsoleLayer
].
style
.
display
=
'none'
;
if
(
logRenderers
[
activeConsoleLayer
])
{
logRenderers
[
activeConsoleLayer
].
setActive
(
false
);
}
}
// 获取或创建目标层
const
targetLayer
=
getConsoleLayer
(
app
);
if
(
!
targetLayer
)
return
;
// 显示新的激活层
targetLayer
.
style
.
display
=
'block'
;
// 【图层优化】显示新的激活层(纯CSS类切换,不修改style.display)
targetLayer
.
classList
.
add
(
'active'
);
activeConsoleLayer
=
app
;
//
触发一次渲染以确保内容正确显示
//
【图层优化】标记新窗口为活动,触发异步渲染
const
renderer
=
logRenderers
[
app
];
if
(
renderer
)
{
// 【FIX Bug #1/#3】如果已有数据,立即同步渲染,避免黑屏
if
(
renderer
.
lines
.
length
>
0
||
renderer
.
pending
.
length
>
0
)
{
renderer
.
flush
();
// 先将pending数据合并到lines
renderer
.
render
();
// 立即同步渲染,不使用异步
}
else
{
// 如果没有数据,显示加载提示(同步)
renderer
.
clear
(
`
[
系统
]
正在加载
$
{
appNames
[
app
]
||
app
}
日志
...
`
);
renderer
.
render
();
// 立即渲染加载提示
}
renderer
.
setActive
(
true
);
// 会在内部异步渲染待处理内容
// 确保滚动到底部
if
(
renderer
.
autoScrollEnabled
)
{
// 使用setTimeout确保DOM更新后再滚动
setTimeout
(()
=>
{
requestAnimationFrame
(()
=>
{
renderer
.
scrollToBottom
();
}
,
0
);
});
}
}
}
...
...
Please
register
or
login
to post a comment