🔨 重构主机模块.

This commit is contained in:
lijiahang
2024-07-22 19:36:02 +08:00
parent b7608fccb3
commit 4bd2de4ce2
64 changed files with 1062 additions and 603 deletions

View File

@@ -17,7 +17,7 @@
<!-- 主机列表 -->
<host-list-view class="host-list"
:hostList="hostList"
empty-value="当前分组内无授权主机/主机未启用 SSH 配置!" />
empty-value="当前分组内无授权主机!" />
</div>
</template>

View File

@@ -49,7 +49,7 @@
const emptyMessage = computed(() => {
if (props.newConnectionType === NewConnectionType.LIST) {
// 列表
return '无授权主机/主机未启用 SSH 配置!';
return '无授权主机!';
} else if (props.newConnectionType === NewConnectionType.FAVORITE) {
// 收藏
return '无收藏记录, 快去点击主机右侧的⭐进行收藏吧!';

View File

@@ -49,7 +49,7 @@
const { toOptions } = useDictStore();
const formModel = ref<LabelExtraSettingModel>({
color: ''
color: '',
});
// 渲染表单

View File

@@ -216,7 +216,7 @@
selectedFiles: Array<string>;
}>();
const emits = defineEmits(['update:selectedFiles', 'loadFile', 'download', 'setLoading']);
const emits = defineEmits(['loadFile', 'download', 'deleteFile', 'setLoading']);
const showHiddenFile = ref(false);
const analysisPaths = ref<Array<PathAnalysis>>([]);
@@ -295,9 +295,12 @@
// 删除选中文件
const deleteSelectFiles = () => {
if (props.selectedFiles?.length) {
props.session?.remove(props.selectedFiles);
}
emits('deleteFile', [...props.selectedFiles]);
};
// 下载文件
const downloadFile = () => {
emits('download', [...props.selectedFiles], true);
};
// 重新连接
@@ -309,12 +312,6 @@
}
};
// 下载文件
const downloadFile = () => {
emits('download', [...props.selectedFiles]);
emits('update:selectedFiles', []);
};
</script>
<style lang="less" scoped>

View File

@@ -161,7 +161,7 @@
selectedFiles: Array<string>;
}>();
const emits = defineEmits(['update:selectedFiles', 'loadFile', 'editFile', 'download']);
const emits = defineEmits(['update:selectedFiles', 'loadFile', 'editFile', 'deleteFile', 'download']);
const openSftpMoveModal = inject(openSftpMoveModalKey) as (sessionId: string, path: string) => void;
const openSftpChmodModal = inject(openSftpChmodModalKey) as (sessionId: string, path: string, permission: number) => void;
@@ -239,7 +239,7 @@
if (!props.session?.connected) {
return;
}
props.session?.remove([path]);
emits('deleteFile', [path]);
};
// 下载文件
@@ -248,7 +248,7 @@
if (!props.session?.connected) {
return;
}
emits('download', [path]);
emits('download', [path], false);
};
// 移动文件

View File

@@ -4,16 +4,17 @@
title-align="start"
title="文件上传"
ok-text="上传"
:body-style="{ padding: '20px' }"
:body-style="{ padding: 0 }"
:align-center="false"
:mask-closable="false"
:unmount-on-close="true"
:on-before-ok="handlerOk"
@cancel="handleClose">
<div class="upload-container">
<div class="parent-wrapper mb16">
<span class="parent-label">上传至文件夹:</span>
<a-input class="parent-input"
<!-- 上传目录 -->
<div class="item-wrapper">
<div class="form-item">
<span class="item-label">上传至文件夹</span>
<a-input class="item-input"
v-model="parentPath"
placeholder="上传目录" />
</div>
@@ -80,8 +81,8 @@
import { ref } from 'vue';
import { useTerminalStore } from '@/store';
import { Message } from '@arco-design/web-vue';
import useVisible from '@/hooks/visible';
import { getFileSize } from '@/utils/file';
import useVisible from '@/hooks/visible';
const { visible, setVisible } = useVisible();
const { transferManager } = useTerminalStore();
@@ -100,7 +101,7 @@
defineExpose({ open });
// 确定
const handlerOk = () => {
const handlerOk = async () => {
if (!parentPath.value) {
Message.error('请输入上传目录');
return false;
@@ -109,8 +110,9 @@
Message.error('请选择文件');
return false;
}
// 添加到上传列表
// 获取上传的文件
const files = fileList.value.map(s => s.file as File);
// 上传
transferManager.addUpload(hostId.value, parentPath.value, files);
Message.success('已开始上传, 点击右侧传输列表查看进度');
// 清空
@@ -132,23 +134,35 @@
<style lang="less" scoped>
@file-size-width: 82px;
@item-label: 104px;
.upload-container {
width: 100%;
}
.parent-wrapper {
.item-wrapper {
margin-bottom: 24px;
display: flex;
justify-content: space-between;
align-items: center;
flex-direction: column;
.parent-label {
width: 98px;
.form-item {
display: flex;
align-items: center;
}
.parent-input {
width: 386px;
.item-label {
width: @item-label;
padding-right: 8px;
display: flex;
justify-content: flex-end;
user-select: none;
&:after {
content: ':';
margin-left: 2px;
}
}
.item-input {
width: 376px;
}
}
.file-list-uploader {
@@ -160,7 +174,7 @@
:deep(.arco-upload-list) {
padding: 0 12px 0 0;
max-height: calc(100vh - 386px);
max-height: calc(100vh - 496px);
overflow-x: hidden;
overflow-y: auto;
}

View File

@@ -11,13 +11,14 @@
:hide-icon="true">
<!-- 表头 -->
<sftp-table-header class="sftp-table-header"
v-model:selected-files="selectFiles"
:selected-files="selectFiles"
:close-message="closeMessage"
:current-path="currentPath"
:session="session"
@load-file="loadFiles"
@download="downloadFiles"
@set-loading="setTableLoading" />
@set-loading="setTableLoading"
@delete-file="deleteFile"
@download="downloadFiles" />
<!-- 表格 -->
<sftp-table class="sftp-table-wrapper"
v-model:selected-files="selectFiles"
@@ -26,6 +27,7 @@
:loading="tableLoading"
@load-file="loadFiles"
@edit-file="editFile"
@delete-file="deleteFile"
@download="downloadFiles" />
</a-spin>
</template>
@@ -145,17 +147,30 @@
editorFilePath.value = '';
};
// 下载文件
const downloadFiles = (paths: Array<string>) => {
// 删除文件
const deleteFile = (paths: Array<string>) => {
if (!paths.length) {
return;
}
// 删除
selectFiles.value = [];
session.value?.remove(paths);
};
// 下载文件
const downloadFiles = (paths: Array<string>, clear: boolean) => {
if (!paths.length) {
return;
}
Message.success('已开始下载, 点击右侧传输列表查看进度');
// 映射为文件
const files = fileList.value.filter(s => paths.includes(s.path))
.map(s => {
return { ...s };
});
if (clear) {
selectFiles.value = [];
}
Message.success('已开始下载, 点击右侧传输列表查看进度');
// 添加普通文件到下载队列
const normalFiles = files.filter(s => !s.isDir);
transferManager.addDownload(props.tab.hostId as number, currentPath.value, normalFiles);
@@ -193,9 +208,9 @@
};
// 接收列表回调
const resolveList = (result: string, path: string, list: Array<SftpFile>) => {
const resolveList = (path: string, result: string, msg: string, list: Array<SftpFile>) => {
setTableLoading(false);
if (!checkResult(result, '查询失败')) {
if (!checkResult(result, msg)) {
return;
}
currentPath.value = path;
@@ -216,11 +231,11 @@
};
// 接收获取文件内容响应
const resolveSftpGetContent = (path: string, result: string, content: string) => {
const resolveSftpGetContent = (path: string, result: string, msg: string, content: string) => {
setTableLoading(false);
setEditorLoading(false);
// 检查结果
if (!checkResult(result, '加载失败')) {
if (!checkResult(result, msg)) {
return;
}
editorRef.value?.setValue(content);
@@ -237,8 +252,12 @@
};
// 接收下载文件夹展开文件响应
const resolveDownloadFlatDirectory = (currentPath: string, list: Array<SftpFile>) => {
const resolveDownloadFlatDirectory = (currentPath: string, result: string, msg: string, list: Array<SftpFile>) => {
setTableLoading(false);
// 检查结果
if (!checkResult(result, msg)) {
return;
}
transferManager.addDownload(props.tab.hostId as number, currentPath, list);
};
@@ -273,7 +292,7 @@
.sftp-container {
width: 100%;
height: calc(100vh - var(--header-height) - var(--panel-nav-height));
height: 100%;
position: relative;
.split-view {

View File

@@ -40,7 +40,7 @@ const columns = [
sortable: {
sortDirections: ['ascend', 'descend'],
},
width: 234,
width: 264,
cellClass: 'action-cell',
},
] as TableColumnData[];

View File

@@ -1,5 +1,5 @@
import type { ISftpSession, ISftpSessionResolver, ITerminalChannel, TerminalPanelTabItem } from '../types/terminal.type';
import { InputProtocol } from '../types/terminal.protocol';
import { InputProtocol } from '@/types/protocol/terminal.protocol';
import { PanelSessionType } from '../types/terminal.const';
import { Modal } from '@arco-design/web-vue';
import BaseSession from './base-session';

View File

@@ -1,5 +1,5 @@
import type { SftpTransferItem } from '../types/terminal.type';
import { TransferStatus, TransferType } from '../types/terminal.const';
import { TransferStatus } from '../types/terminal.const';
import { getFileName, openDownloadFile } from '@/utils/file';
import { saveAs } from 'file-saver';
import { getDownloadTransferUrl } from '@/api/asset/host-sftp';
@@ -8,8 +8,8 @@ import SftpTransferHandler from './sftp-transfer-handler';
// sftp 下载器实现
export default class SftpTransferDownloader extends SftpTransferHandler {
constructor(item: SftpTransferItem, client: WebSocket) {
super(TransferType.DOWNLOAD, item, client);
constructor(type: string, item: SftpTransferItem, client: WebSocket) {
super(type, item, client);
}
// 开始回调

View File

@@ -27,7 +27,7 @@ export default abstract class SftpTransferHandler implements ISftpTransferHandle
operator: TransferOperator.START,
type: this.type,
path: getPath(this.item.parentPath + '/' + this.item.name),
hostId: this.item.hostId
hostId: this.item.hostId,
}));
};
@@ -81,9 +81,14 @@ export default abstract class SftpTransferHandler implements ISftpTransferHandle
};
// 进度回调
onProgress(size: number) {
if (this.item && size) {
this.item.currentSize = size;
onProgress(totalSize: number | undefined, currentSize: number | undefined) {
if (this.item) {
if (totalSize) {
this.item.totalSize = totalSize;
}
if (currentSize) {
this.item.currentSize = currentSize;
}
}
};

View File

@@ -13,7 +13,7 @@ export default class SftpTransferManager implements ISftpTransferManager {
private run: boolean;
private progressIntervalId?: number;
private progressIntervalId?: any;
private currentItem?: SftpTransferItem;
@@ -45,9 +45,7 @@ export default class SftpTransferManager implements ISftpTransferManager {
});
this.transferList.push(...items);
// 开始传输
if (!this.run) {
this.openClient();
}
this.startTransfer(items);
}
// 添加下载任务
@@ -67,6 +65,12 @@ export default class SftpTransferManager implements ISftpTransferManager {
status: TransferStatus.WAITING,
};
}) as Array<SftpTransferItem>;
// 开始传输
this.startTransfer(items);
}
// 开始传输
startTransfer(items: Array<SftpTransferItem>) {
this.transferList.push(...items);
// 开始传输
if (!this.run) {
@@ -154,13 +158,8 @@ export default class SftpTransferManager implements ISftpTransferManager {
// 获取任务
this.currentItem = this.transferList.find(s => s.status === TransferStatus.WAITING);
if (this.currentItem) {
if (this.currentItem.type === TransferType.UPLOAD) {
// 上传
this.currentTransfer = new SftpTransferUploader(this.currentItem, this.client as WebSocket);
} else {
// 下载
this.currentTransfer = new SftpTransferDownloader(this.currentItem, this.client as WebSocket);
}
// 创建传输器
this.currentTransfer = this.createTransfer();
// 开始
this.currentTransfer?.start();
} else {
@@ -169,6 +168,20 @@ export default class SftpTransferManager implements ISftpTransferManager {
}
}
// 创建传输器
private createTransfer(): ISftpTransferHandler | undefined {
if (!this.currentItem) {
return undefined;
}
if (this.currentItem.type === TransferType.UPLOAD) {
// 上传
return new SftpTransferUploader(TransferType.UPLOAD, this.currentItem, this.client as WebSocket);
} else if (this.currentItem.type === TransferType.DOWNLOAD) {
// 下载
return new SftpTransferDownloader(TransferType.DOWNLOAD, this.currentItem, this.client as WebSocket);
}
}
// 接收消息
private async resolveMessage(message: MessageEvent) {
// 文本消息
@@ -181,7 +194,7 @@ export default class SftpTransferManager implements ISftpTransferManager {
this.currentTransfer?.onStart(data.channelId as string, data.transferToken as string);
} else if (data.type === TransferReceiver.PROGRESS) {
// 进度回调
this.currentTransfer?.onProgress(data.currentSize as number);
this.currentTransfer?.onProgress(data.totalSize, data.currentSize);
} else if (data.type === TransferReceiver.FINISH) {
// 完成回调
this.currentTransfer?.onFinish();

View File

@@ -1,5 +1,4 @@
import type { SftpTransferItem } from '../types/terminal.type';
import { TransferType } from '../types/terminal.const';
import SftpTransferHandler from './sftp-transfer-handler';
// 512 KB
@@ -12,8 +11,8 @@ export default class SftpTransferUploader extends SftpTransferHandler {
private readonly totalPart: number;
private file: File;
constructor(item: SftpTransferItem, client: WebSocket) {
super(TransferType.UPLOAD, item, client);
constructor(type: string, item: SftpTransferItem, client: WebSocket) {
super(type, item, client);
this.file = item.file;
this.currentPart = 0;
this.totalPart = Math.ceil(item.file.size / PART_SIZE);

View File

@@ -2,10 +2,12 @@ import type { UnwrapRef } from 'vue';
import type { ISearchOptions } from '@xterm/addon-search';
import { SearchAddon } from '@xterm/addon-search';
import type { TerminalPreference } from '@/store/modules/terminal/types';
import type { ISshSession, ISshSessionHandler, ITerminalChannel, TerminalPanelTabItem, XtermAddons, XtermDomRef } from '../types/terminal.type';
import type { ISshSession, ISshSessionHandler, ITerminalChannel, TerminalPanelTabItem, XtermDomRef } from '../types/terminal.type';
import type { XtermAddons } from '@/types/xterm';
import { defaultFontFamily } from '@/types/xterm';
import { useTerminalStore } from '@/store';
import { InputProtocol } from '../types/terminal.protocol';
import { fontFamilySuffix, PanelSessionType, TerminalShortcutType, TerminalStatus, } from '../types/terminal.const';
import { InputProtocol } from '@/types/protocol/terminal.protocol';
import { PanelSessionType, TerminalShortcutType, TerminalStatus } from '../types/terminal.const';
import { Terminal } from '@xterm/xterm';
import { FitAddon } from '@xterm/addon-fit';
import { WebLinksAddon } from '@xterm/addon-web-links';
@@ -44,6 +46,7 @@ export default class SshSession extends BaseSession implements ISshSession {
// 初始化
init(domRef: XtermDomRef): void {
const { preference } = useTerminalStore();
const fontFamily = preference.displaySetting.fontFamily;
// 初始化实例
this.inst = new Terminal({
...(preference.displaySetting as any),
@@ -52,7 +55,7 @@ export default class SshSession extends BaseSession implements ISshSession {
altClickMovesCursor: !!preference.interactSetting.altClickMovesCursor,
rightClickSelectsWord: !!preference.interactSetting.rightClickSelectsWord,
wordSeparator: preference.interactSetting.wordSeparator,
fontFamily: preference.displaySetting.fontFamily + fontFamilySuffix,
fontFamily: fontFamily === '_' ? defaultFontFamily : `${fontFamily}, ${defaultFontFamily}`,
scrollback: preference.sessionSetting.scrollBackLine,
allowProposedApi: true,
});
@@ -219,6 +222,11 @@ export default class SshSession extends BaseSession implements ISshSession {
this.inst.write(value);
}
// 修改大小
resize(cols: number, rows: number): void {
this.inst.resize(cols, rows);
}
// 聚焦
focus(): void {
this.inst.focus();

View File

@@ -1,5 +1,6 @@
import type { InputPayload, ITerminalChannel, ITerminalOutputProcessor, ITerminalSessionManager, Protocol, } from '../types/terminal.type';
import { format, OutputProtocol, parse } from '../types/terminal.protocol';
import type { ITerminalChannel, ITerminalOutputProcessor, ITerminalSessionManager } from '../types/terminal.type';
import type { InputPayload, Protocol } from '@/types/protocol/terminal.protocol';
import { format, OutputProtocol, parse } from '@/types/protocol/terminal.protocol';
import { sessionCloseMsg } from '../types/terminal.const';
import { getTerminalAccessToken, openHostTerminalChannel } from '@/api/asset/host-terminal';
import { Message } from '@arco-design/web-vue';

View File

@@ -1,13 +1,6 @@
import type {
ISftpSession,
ISshSession,
ITerminalChannel,
ITerminalOutputProcessor,
ITerminalSession,
ITerminalSessionManager,
OutputPayload
} from '../types/terminal.type';
import { InputProtocol } from '../types/terminal.protocol';
import type { ISftpSession, ISshSession, ITerminalChannel, ITerminalOutputProcessor, ITerminalSession, ITerminalSessionManager } from '../types/terminal.type';
import type { OutputPayload } from '@/types/protocol/terminal.protocol';
import { InputProtocol } from '@/types/protocol/terminal.protocol';
import { PanelSessionType, TerminalStatus } from '../types/terminal.const';
import { useTerminalStore } from '@/store';
import { Message } from '@arco-design/web-vue';
@@ -43,7 +36,7 @@ export default class TerminalOutputProcessor implements ITerminalOutputProcessor
});
} else {
// 未成功展示错误信息
ssh.write(`${msg || ''}\r\n输入回车重新连接...\r\n\r\n`);
ssh.write(`${msg || ''}\r\n输入回车重新连接...\r\n\r\n`);
ssh.status = TerminalStatus.CLOSED;
}
}, sftp => {
@@ -109,7 +102,7 @@ export default class TerminalOutputProcessor implements ITerminalOutputProcessor
// ssh 拼接关闭消息
ssh.write(`\r\n\r\n${msg || ''}\r\n`);
if (!isForceClose) {
ssh.write(`${msg || ''}\r\n输入回车重新连接...\r\n\r\n`);
ssh.write('输入回车重新连接...\r\n\r\n');
}
// 设置状态
ssh.status = TerminalStatus.CLOSED;
@@ -135,10 +128,10 @@ export default class TerminalOutputProcessor implements ITerminalOutputProcessor
}
// 处理 SFTP 文件列表
processSftpList({ sessionId, result, path, body }: OutputPayload): void {
processSftpList({ sessionId, result, path, msg, body }: OutputPayload): void {
// 获取会话
const session = this.sessionManager.getSession<ISftpSession>(sessionId);
session && session.resolver.resolveList(result, path, JSON.parse(body));
session && session.resolver.resolveList(path, result, msg, JSON.parse(body));
}
// 处理 SFTP 创建文件夹
@@ -177,17 +170,17 @@ export default class TerminalOutputProcessor implements ITerminalOutputProcessor
}
// 处理 SFTP 下载文件夹展开文件
processDownloadFlatDirectory({ sessionId, currentPath, body }: OutputPayload): void {
processDownloadFlatDirectory({ sessionId, currentPath, result, msg, body }: OutputPayload): void {
// 获取会话
const session = this.sessionManager.getSession<ISftpSession>(sessionId);
session && session.resolver.resolveDownloadFlatDirectory(currentPath, JSON.parse(body));
session && session.resolver.resolveDownloadFlatDirectory(currentPath, result, msg, JSON.parse(body));
}
// 处理 SFTP 获取文件内容
processSftpGetContent({ sessionId, path, result, content }: OutputPayload): void {
processSftpGetContent({ sessionId, path, result, msg, content }: OutputPayload): void {
// 获取会话
const session = this.sessionManager.getSession<ISftpSession>(sessionId);
session && session.resolver.resolveSftpGetContent(path, result, content);
session && session.resolver.resolveSftpGetContent(path, result, msg, content);
}
// 处理 SFTP 修改文件内容

View File

@@ -4,10 +4,9 @@ import TerminalTabManager from '../handler/terminal-tab-manager';
// 终端面板管理器实现
export default class TerminalPanelManager implements ITerminalPanelManager {
// 当前面板
active: number;
// 面板列表
panels: Array<TerminalTabManager<TerminalPanelTabItem>>;
public active: number;
public panels: Array<TerminalTabManager<TerminalPanelTabItem>>;
constructor() {
this.active = 0;
@@ -31,17 +30,18 @@ export default class TerminalPanelManager implements ITerminalPanelManager {
// 移除面板
removePanel(index: number) {
this.panels.splice(index, 1);
this.panels[index].clear();
this.active = index >= this.panels.length ? this.panels.length - 1 : index;
};
// 重置
reset() {
for (let panel of this.panels) {
panel.clear();
}
this.active = 0;
this.panels = [new TerminalTabManager()];
if (this.panels) {
for (let panel of this.panels) {
panel.clear();
}
}
};
}

View File

@@ -8,7 +8,7 @@ import type {
XtermDomRef
} from '../types/terminal.type';
import { sleep } from '@/utils';
import { InputProtocol } from '../types/terminal.protocol';
import { InputProtocol } from '@/types/protocol/terminal.protocol';
import { PanelSessionType } from '../types/terminal.const';
import { useDebounceFn } from '@vueuse/core';
import { addEventListen, removeEventListen } from '@/utils/event';
@@ -132,7 +132,7 @@ export default class TerminalSessionManager implements ITerminalSessionManager {
}
// 调度重置大小
private dispatchResize() {
dispatchResize() {
// 对所有已连接的会话重置大小
Object.values(this.sessions)
.filter(s => s?.type === PanelSessionType.SSH.type)

View File

@@ -56,8 +56,8 @@ export const NewConnectionType = {
// 主机额外配置项
export const ExtraSettingItems = {
SSH: 'ssh',
LABEL: 'label',
SSH: 'SSH',
LABEL: 'LABEL',
};
// 主机额外配置 ssh 认证方式
@@ -324,7 +324,7 @@ export const TransferStatus = {
// 传输类型
export const TransferType = {
UPLOAD: 'upload',
DOWNLOAD: 'download'
DOWNLOAD: 'download',
};
// 传输操作
@@ -363,9 +363,6 @@ export const openSftpChmodModalKey = Symbol();
// 打开 sftpUploadModal key
export const openSftpUploadModalKey = Symbol();
// 字体后缀 兜底
export const fontFamilySuffix = ', Courier New, Monaco, courier, monospace';
// 终端字体样式
export const fontFamilyKey = 'terminalFontFamily';

View File

@@ -1,13 +1,8 @@
import type { Terminal } from '@xterm/xterm';
import type { FitAddon } from '@xterm/addon-fit';
import type { CanvasAddon } from '@xterm/addon-canvas';
import type { WebglAddon } from '@xterm/addon-webgl';
import type { WebLinksAddon } from '@xterm/addon-web-links';
import type { ISearchOptions, SearchAddon } from '@xterm/addon-search';
import type { ImageAddon } from '@xterm/addon-image';
import type { Unicode11Addon } from '@xterm/addon-unicode11';
import type { ISearchOptions } from '@xterm/addon-search';
import type { CSSProperties } from 'vue';
import type { HostQueryResponse } from '@/api/asset/host';
import type { InputPayload, OutputPayload, Protocol } from '@/types/protocol/terminal.protocol';
// 终端 tab 元素
export interface TerminalTabItem {
@@ -81,30 +76,6 @@ export interface PanelSessionTabType {
icon: string;
}
// 终端协议
export interface Protocol {
type: string;
template: string[];
[key: string]: unknown;
}
// 终端输入消息内容
export interface InputPayload {
type?: string;
sessionId?: string;
[key: string]: unknown;
}
// 终端输出消息内容
export interface OutputPayload {
type: string;
sessionId: string;
[key: string]: string;
}
// 终端 tab 管理器定义
export interface ITerminalTabManager<T extends TerminalTabItem = TerminalTabItem> {
// 当前 tab
@@ -166,6 +137,8 @@ export interface ITerminalSessionManager {
getSession: <T extends ITerminalSession>(sessionId: string) => T;
// 关闭终端会话
closeSession: (sessionId: string) => void;
// 重置大小
dispatchResize: () => void;
// 重置
reset: () => void;
}
@@ -221,17 +194,6 @@ export interface XtermDomRef {
editorModal: any;
}
// xterm 插件
export interface XtermAddons {
fit: FitAddon;
webgl: WebglAddon;
canvas: CanvasAddon;
weblink: WebLinksAddon;
search: SearchAddon;
image: ImageAddon;
unicode: Unicode11Addon;
}
// 终端会话定义
export interface ITerminalSession {
type: string;
@@ -269,6 +231,8 @@ export interface ISshSession extends ITerminalSession {
init: (domRef: XtermDomRef) => void;
// 写入数据
write: (value: string) => void;
// 修改大小
resize: (cols: number, rows: number) => void;
// 聚焦
focus: () => void;
// 失焦
@@ -368,7 +332,7 @@ export interface ISftpSessionResolver {
// 关闭回调
onClose: (forceClose: boolean, msg: string) => void;
// 接受文件列表响应
resolveList: (result: string, path: string, list: Array<SftpFile>) => void;
resolveList: (path: string, result: string, msg: string, list: Array<SftpFile>) => void;
// 接收创建文件夹响应
resolveSftpMkdir: (result: string, msg: string) => void;
// 接收创建文件响应
@@ -380,9 +344,9 @@ export interface ISftpSessionResolver {
// 接收修改文件权限响应
resolveSftpChmod: (result: string, msg: string) => void;
// 接收下载文件夹展开文件响应
resolveDownloadFlatDirectory: (currentPath: string, list: Array<SftpFile>) => void;
resolveDownloadFlatDirectory: (currentPath: string, result: string, msg: string, list: Array<SftpFile>) => void;
// 接收获取文件内容响应
resolveSftpGetContent: (path: string, result: string, content: string) => void;
resolveSftpGetContent: (path: string, result: string, msg: string, content: string) => void;
// 接收修改文件内容响应
resolveSftpSetContent: (result: string, msg: string) => void;
}
@@ -414,7 +378,6 @@ export interface ISftpTransferManager {
cancelAllTransfer: () => void;
}
// sftp 传输处理回调定义
export interface ISftpTransferCallback {
// 下一分片回调
@@ -422,7 +385,7 @@ export interface ISftpTransferCallback {
// 开始回调
onStart: (channelId: string, token: string) => void;
// 进度回调
onProgress: (size: number) => void;
onProgress: (totalSize: number | undefined, currentSize: number | undefined) => void;
// 失败回调
onError: (msg: string | undefined) => void;
// 完成回调
@@ -475,4 +438,5 @@ export interface TransferOperatorResponse {
transferToken?: string;
success: boolean;
msg?: string;
totalSize?: number;
}