fix(frontend): 终端弹框适配与审计实时监控布局优化

- 修复 LiveMonitorDialog 连接中卡死:WebSocket 先连、延后挂载 xterm
- 审计实时监控弹框对齐 WebSSH 布局:92vw 宽、520px 高、支持全屏
- 修复服务器终端弹框右侧黑边:fit 后同步 PTY resize,延迟二次 fit
- 抽取 xterm-utils 公共适配逻辑,统一 ResizeObserver 处理
This commit is contained in:
Logan.Li committed 2026-06-25 23:31:44 +08:00
1 parent be2a377f01
commit bfd6431b9d
4 files changed
+228 -126

No files matched your search

+66
View File
@@ -0,0 +1,66 @@
import type { Terminal as XTerm } from 'xterm';
import type { FitAddon } from 'xterm-addon-fit';
/** FitAddon 适配终端并同步远端 PTY 尺寸(WebSSH resize) // Logan.Li */
export function fitTerminal(fit: FitAddon, term: XTerm, ws?: WebSocket | null) {
fit.fit();
if (ws?.readyState === WebSocket.OPEN) {
const { cols, rows } = term;
ws.send(JSON.stringify({ status: 1, cols, rows }));
}
}
/** 等待容器就绪后挂载 xterm,并延迟二次 fit 消除右侧黑边 // Logan.Li */
export function mountXterm(
term: XTerm,
fit: FitAddon,
getContainer: () => HTMLDivElement | null,
ws?: WebSocket | null,
) {
const applyFit = () => {
try {
fitTerminal(fit, term, ws);
term.focus();
} catch {
/* noop */
}
};
const tryMount = () => {
const el = getContainer();
if (!el) {
requestAnimationFrame(tryMount);
return;
}
term.open(el);
requestAnimationFrame(applyFit);
setTimeout(applyFit, 100);
};
tryMount();
}
/** ResizeObserver 监听容器尺寸,持续 fit // Logan.Li */
export function attachTerminalResize(
container: HTMLDivElement,
fit: FitAddon,
term: XTerm,
ws?: WebSocket | null,
) {
let timer: ReturnType<typeof setTimeout>;
const ro = new ResizeObserver(() => {
clearTimeout(timer);
timer = setTimeout(() => {
try {
fitTerminal(fit, term, ws);
} catch {
/* noop */
}
}, 60);
});
ro.observe(container);
return () => {
clearTimeout(timer);
ro.disconnect();
};
}