🔨 执行日志.
This commit is contained in:
@@ -3,8 +3,8 @@
|
|||||||
title-align="start"
|
title-align="start"
|
||||||
title="执行日志"
|
title="执行日志"
|
||||||
width="94%"
|
width="94%"
|
||||||
:top="40"
|
:top="44"
|
||||||
:body-style="{ padding: '0', height: 'calc(100vh - 140px)', overflow: 'hidden' }"
|
:body-style="{ padding: '0', height: 'calc(100vh - 138px)', overflow: 'hidden' }"
|
||||||
:align-center="false"
|
:align-center="false"
|
||||||
:draggable="true"
|
:draggable="true"
|
||||||
:mask-closable="false"
|
:mask-closable="false"
|
||||||
@@ -40,8 +40,6 @@
|
|||||||
|
|
||||||
const log = ref();
|
const log = ref();
|
||||||
|
|
||||||
// TODO 卸载
|
|
||||||
|
|
||||||
// 打开
|
// 打开
|
||||||
const open = async (id: number) => {
|
const open = async (id: number) => {
|
||||||
setVisible(true);
|
setVisible(true);
|
||||||
@@ -51,7 +49,9 @@
|
|||||||
const { data } = await getExecLog(id);
|
const { data } = await getExecLog(id);
|
||||||
// 打开日志
|
// 打开日志
|
||||||
await nextTick(() => {
|
await nextTick(() => {
|
||||||
log.value.open(data);
|
setTimeout(() => {
|
||||||
|
log.value.open(data);
|
||||||
|
}, 50);
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
@@ -71,7 +71,6 @@
|
|||||||
const handleClear = () => {
|
const handleClear = () => {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
console.log('clear');
|
|
||||||
};
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import type { IDisposable, ITerminalInitOnlyOptions, ITerminalOptions, Terminal
|
|||||||
import type { FitAddon } from 'xterm-addon-fit';
|
import type { FitAddon } from 'xterm-addon-fit';
|
||||||
import type { SearchAddon } from 'xterm-addon-search';
|
import type { SearchAddon } from 'xterm-addon-search';
|
||||||
import type { CanvasAddon } from 'xterm-addon-canvas';
|
import type { CanvasAddon } from 'xterm-addon-canvas';
|
||||||
|
import type { WebLinksAddon } from 'xterm-addon-web-links';
|
||||||
|
|
||||||
// appender 配置
|
// appender 配置
|
||||||
export const AppenderOptions: ITerminalOptions & ITerminalInitOnlyOptions = {
|
export const AppenderOptions: ITerminalOptions & ITerminalInitOnlyOptions = {
|
||||||
@@ -43,6 +44,7 @@ export interface LogAddons extends Record<string, IDisposable> {
|
|||||||
fit: FitAddon;
|
fit: FitAddon;
|
||||||
canvas: CanvasAddon;
|
canvas: CanvasAddon;
|
||||||
search: SearchAddon;
|
search: SearchAddon;
|
||||||
|
weblink: WebLinksAddon;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 执行日志 appender 定义
|
// 执行日志 appender 定义
|
||||||
|
|||||||
@@ -131,8 +131,6 @@
|
|||||||
|
|
||||||
// 清理并且关闭
|
// 清理并且关闭
|
||||||
const closeAll = () => {
|
const closeAll = () => {
|
||||||
// TODO
|
|
||||||
console.log('closeAll');
|
|
||||||
// 清理轮询
|
// 清理轮询
|
||||||
clearAllInterval();
|
clearAllInterval();
|
||||||
// 关闭 appender
|
// 关闭 appender
|
||||||
@@ -156,8 +154,8 @@
|
|||||||
@host-real-width: @host-width + 16px;
|
@host-real-width: @host-width + 16px;
|
||||||
|
|
||||||
.log-panel-container {
|
.log-panel-container {
|
||||||
width: calc(100% - 32px);
|
width: 100%;
|
||||||
height: calc(100% - 32px);
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { ILogAppender, LogAddons, LogAppenderConf, LogDomRef } from './const';
|
import type { ILogAppender, LogAddons, LogAppenderConf, LogDomRef } from './const';
|
||||||
import type { ExecTailRequest } from '@/api/exec/exec';
|
|
||||||
import { AppenderOptions } from './const';
|
import { AppenderOptions } from './const';
|
||||||
|
import type { ExecTailRequest } from '@/api/exec/exec';
|
||||||
import { getExecLogTailToken } from '@/api/exec/exec';
|
import { getExecLogTailToken } from '@/api/exec/exec';
|
||||||
import { webSocketBaseUrl } from '@/utils/env';
|
import { webSocketBaseUrl } from '@/utils/env';
|
||||||
import { Message } from '@arco-design/web-vue';
|
import { Message } from '@arco-design/web-vue';
|
||||||
@@ -12,6 +12,7 @@ import { Terminal } from 'xterm';
|
|||||||
import { FitAddon } from 'xterm-addon-fit';
|
import { FitAddon } from 'xterm-addon-fit';
|
||||||
import { SearchAddon } from 'xterm-addon-search';
|
import { SearchAddon } from 'xterm-addon-search';
|
||||||
import { CanvasAddon } from 'xterm-addon-canvas';
|
import { CanvasAddon } from 'xterm-addon-canvas';
|
||||||
|
import { WebLinksAddon } from 'xterm-addon-web-links';
|
||||||
|
|
||||||
// 执行日志 appender 实现
|
// 执行日志 appender 实现
|
||||||
export default class LogAppender implements ILogAppender {
|
export default class LogAppender implements ILogAppender {
|
||||||
@@ -105,13 +106,16 @@ export default class LogAppender implements ILogAppender {
|
|||||||
const fit = new FitAddon();
|
const fit = new FitAddon();
|
||||||
const search = new SearchAddon();
|
const search = new SearchAddon();
|
||||||
const canvas = new CanvasAddon();
|
const canvas = new CanvasAddon();
|
||||||
|
const weblink = new WebLinksAddon();
|
||||||
terminal.loadAddon(fit);
|
terminal.loadAddon(fit);
|
||||||
terminal.loadAddon(search);
|
terminal.loadAddon(search);
|
||||||
terminal.loadAddon(canvas);
|
terminal.loadAddon(canvas);
|
||||||
|
terminal.loadAddon(weblink);
|
||||||
return {
|
return {
|
||||||
fit,
|
fit,
|
||||||
search,
|
search,
|
||||||
canvas
|
canvas,
|
||||||
|
weblink
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,37 +227,40 @@ export default class LogAppender implements ILogAppender {
|
|||||||
|
|
||||||
// 关闭 client
|
// 关闭 client
|
||||||
closeClient(): void {
|
closeClient(): void {
|
||||||
// 关闭 ws
|
try {
|
||||||
if (this.client && this.client.readyState === WebSocket.OPEN) {
|
// 清理持久化
|
||||||
this.client.close();
|
clearInterval(this.keepAliveTask);
|
||||||
|
// 关闭 ws
|
||||||
|
if (this.client && this.client.readyState === WebSocket.OPEN) {
|
||||||
|
this.client.close();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
}
|
}
|
||||||
// 清理持久化
|
|
||||||
clearInterval(this.keepAliveTask);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 关闭 view
|
// 关闭 view
|
||||||
closeView(): void {
|
closeView(): void {
|
||||||
// 关闭 terminal
|
|
||||||
Object.values(this.appenderRel).forEach(s => {
|
|
||||||
if (s.addons) {
|
|
||||||
Object.values(s.addons).forEach(s => s.dispose());
|
|
||||||
}
|
|
||||||
s.terminal?.dispose();
|
|
||||||
});
|
|
||||||
// 移除自适应事件
|
// 移除自适应事件
|
||||||
removeEventListen(window, 'resize', this.fitAllFn);
|
removeEventListen(window, 'resize', this.fitAllFn);
|
||||||
|
// 关闭 terminal
|
||||||
|
Object.values(this.appenderRel).forEach(s => {
|
||||||
|
try {
|
||||||
|
// 卸载插件
|
||||||
|
Object.values(s.addons)
|
||||||
|
.filter(Boolean)
|
||||||
|
.forEach(s => s.dispose());
|
||||||
|
// 卸载终端
|
||||||
|
s.terminal?.dispose();
|
||||||
|
} catch (e) {
|
||||||
|
// 卸载可能会报错
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 关闭
|
// 关闭
|
||||||
close(): void {
|
close(): void {
|
||||||
try {
|
this.closeClient();
|
||||||
this.closeClient();
|
this.closeView();
|
||||||
this.closeView();
|
|
||||||
} catch (ex) {
|
|
||||||
// TODO
|
|
||||||
console.log('errr');
|
|
||||||
console.error(ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理消息
|
// 处理消息
|
||||||
|
|||||||
@@ -245,7 +245,7 @@
|
|||||||
height: calc(100% - @header-height);
|
height: calc(100% - @header-height);
|
||||||
position: relative;
|
position: relative;
|
||||||
background: #202020;
|
background: #202020;
|
||||||
padding: 4px 0 0 4px;
|
padding: 4px 0 4px 4px;
|
||||||
|
|
||||||
.log-appender {
|
.log-appender {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|||||||
@@ -43,8 +43,6 @@
|
|||||||
// 打开
|
// 打开
|
||||||
const open = () => {
|
const open = () => {
|
||||||
nextTick(async () => {
|
nextTick(async () => {
|
||||||
// TODO
|
|
||||||
console.log(props.appender);
|
|
||||||
if (props.appender) {
|
if (props.appender) {
|
||||||
// 初始化
|
// 初始化
|
||||||
await props.appender.init(logRefs.value);
|
await props.appender.init(logRefs.value);
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.editor-wrapper {
|
.editor-wrapper {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: calc(100% - 66px);
|
height: calc(100% - 56px);
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -216,7 +216,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
@form-width: 420px;
|
@form-width: 380px;
|
||||||
@history-width: 320px;
|
@history-width: 320px;
|
||||||
@command-gap: @form-width + @history-width + 32px;
|
@command-gap: @form-width + @history-width + 32px;
|
||||||
|
|
||||||
|
|||||||
@@ -176,7 +176,9 @@ export default class SshSession implements ISshSession {
|
|||||||
}
|
}
|
||||||
// 加载插件
|
// 加载插件
|
||||||
for (const addon of Object.values(this.addons)) {
|
for (const addon of Object.values(this.addons)) {
|
||||||
this.inst.loadAddon(addon);
|
if (addon) {
|
||||||
|
this.inst.loadAddon(addon);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,6 +246,7 @@ export default class SshSession implements ISshSession {
|
|||||||
// 卸载终端
|
// 卸载终端
|
||||||
this.inst.dispose();
|
this.inst.dispose();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
// 卸载可能会报错
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user