🔨 修改文件传输逻辑.

This commit is contained in:
lijiahangmax
2025-06-30 22:12:28 +08:00
parent 5dcd8cbad2
commit 4468a429dd
18 changed files with 110 additions and 122 deletions

View File

@@ -48,12 +48,13 @@
import type { ISftpSession } from '@/views/terminal/interfaces'; import type { ISftpSession } from '@/views/terminal/interfaces';
import useVisible from '@/hooks/visible'; import useVisible from '@/hooks/visible';
import { nextTick, ref } from 'vue'; import { nextTick, ref } from 'vue';
import { useTerminalStore } from '@/store';
import { permission10toString } from '@/utils/file'; import { permission10toString } from '@/utils/file';
import { TerminalSessionTypes } from '@/views/terminal/types/const';
const props = defineProps<{
session?: ISftpSession;
}>();
const { visible, setVisible } = useVisible(); const { visible, setVisible } = useVisible();
const { sessionManager } = useTerminalStore();
const sessionKey = ref(); const sessionKey = ref();
const modRef = ref(); const modRef = ref();
@@ -92,10 +93,9 @@
if (error) { if (error) {
return false; return false;
} }
// 获取会话 // 提权
const session = sessionManager.getSession<ISftpSession>(sessionKey.value); if (props.session) {
if (session?.type === TerminalSessionTypes.SFTP.type) { props.session.chmod(formModel.value.path, formModel.value.mod);
session.chmod(formModel.value.path, formModel.value.mod);
} }
} catch (e) { } catch (e) {
return false; return false;

View File

@@ -33,13 +33,13 @@
import type { ISftpSession } from '@/views/terminal/interfaces'; import type { ISftpSession } from '@/views/terminal/interfaces';
import useVisible from '@/hooks/visible'; import useVisible from '@/hooks/visible';
import { nextTick, ref } from 'vue'; import { nextTick, ref } from 'vue';
import { useTerminalStore } from '@/store';
import { TerminalSessionTypes } from '@/views/terminal/types/const'; const props = defineProps<{
session?: ISftpSession;
}>();
const { visible, setVisible } = useVisible(); const { visible, setVisible } = useVisible();
const { sessionManager } = useTerminalStore();
const sessionKey = ref();
const touch = ref(false); const touch = ref(false);
const pathRef = ref(); const pathRef = ref();
const formRef = ref(); const formRef = ref();
@@ -48,8 +48,7 @@
}); });
// 打开新增 // 打开新增
const open = (key: string, path: string, isTouch: boolean) => { const open = (path: string, isTouch: boolean) => {
sessionKey.value = key;
if (path === '/') { if (path === '/') {
formModel.value.path = path; formModel.value.path = path;
} else { } else {
@@ -73,15 +72,13 @@
if (error) { if (error) {
return false; return false;
} }
// 获取会话 if (props.session) {
const session = sessionManager.getSession<ISftpSession>(sessionKey.value);
if (session?.type === TerminalSessionTypes.SFTP.type) {
if (touch.value) { if (touch.value) {
// 创建文件 // 创建文件
session.touch(formModel.value.path); props.session.touch(formModel.value.path);
} else { } else {
// 创建文件夹 // 创建文件夹
session.mkdir(formModel.value.path); props.session.mkdir(formModel.value.path);
} }
} }
} catch (e) { } catch (e) {

View File

@@ -41,11 +41,12 @@
import type { ISftpSession } from '@/views/terminal/interfaces'; import type { ISftpSession } from '@/views/terminal/interfaces';
import useVisible from '@/hooks/visible'; import useVisible from '@/hooks/visible';
import { nextTick, ref } from 'vue'; import { nextTick, ref } from 'vue';
import { useTerminalStore } from '@/store';
import { TerminalSessionTypes } from '@/views/terminal/types/const'; const props = defineProps<{
session?: ISftpSession;
}>();
const { visible, setVisible } = useVisible(); const { visible, setVisible } = useVisible();
const { sessionManager } = useTerminalStore();
const sessionKey = ref(); const sessionKey = ref();
const targetRef = ref(); const targetRef = ref();
@@ -77,10 +78,9 @@
if (error) { if (error) {
return false; return false;
} }
// 获取会话 // 移动文件
const session = sessionManager.getSession<ISftpSession>(sessionKey.value); if (props.session) {
if (session?.type === TerminalSessionTypes.SFTP.type) { props.session.move(formModel.value.path, formModel.value.target);
session.move(formModel.value.path, formModel.value.target);
} }
} catch (e) { } catch (e) {
return false; return false;

View File

@@ -135,7 +135,7 @@
arrow-class="terminal-tooltip-content" arrow-class="terminal-tooltip-content"
content="创建文件"> content="创建文件">
<a-button class="header-action-icon icon-button" <a-button class="header-action-icon icon-button"
@click="createFile"> @click="createFile(true)">
<icon-drive-file /> <icon-drive-file />
</a-button> </a-button>
</a-tooltip> </a-tooltip>
@@ -148,7 +148,7 @@
arrow-class="terminal-tooltip-content" arrow-class="terminal-tooltip-content"
content="创建文件夹"> content="创建文件夹">
<a-button class="header-action-icon icon-button" <a-button class="header-action-icon icon-button"
@click="createDir"> @click="createFile(false)">
<icon-folder-add /> <icon-folder-add />
</a-button> </a-button>
</a-tooltip> </a-tooltip>
@@ -174,7 +174,7 @@
arrow-class="terminal-tooltip-content" arrow-class="terminal-tooltip-content"
content="上传"> content="上传">
<a-button class="header-action-icon icon-button" <a-button class="header-action-icon icon-button"
@click="openSftpUploadModal"> @click="openUpload">
<icon-upload /> <icon-upload />
</a-button> </a-button>
</a-tooltip> </a-tooltip>
@@ -204,9 +204,8 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { PathAnalysis } from '@/utils/file'; import type { PathAnalysis } from '@/utils/file';
import type { ISftpSession } from '@/views/terminal/interfaces'; import type { ISftpSession } from '@/views/terminal/interfaces';
import { inject, nextTick, ref, watch } from 'vue'; import { nextTick, ref, watch } from 'vue';
import { getParentPath, getPathAnalysis } from '@/utils/file'; import { getParentPath, getPathAnalysis } from '@/utils/file';
import { openSftpCreateModalKey, openSftpUploadModalKey } from '@/views/terminal/types/const';
import { useTerminalStore } from '@/store'; import { useTerminalStore } from '@/store';
const props = defineProps<{ const props = defineProps<{
@@ -216,7 +215,7 @@
selectedFiles: Array<string>; selectedFiles: Array<string>;
}>(); }>();
const emits = defineEmits(['loadFile', 'download', 'deleteFile', 'setLoading']); const emits = defineEmits(['loadFile', 'createFile', 'upload', 'download', 'deleteFile', 'setLoading']);
const showHiddenFile = ref(false); const showHiddenFile = ref(false);
const analysisPaths = ref<Array<PathAnalysis>>([]); const analysisPaths = ref<Array<PathAnalysis>>([]);
@@ -224,10 +223,6 @@
const pathInput = ref(''); const pathInput = ref('');
const pathInputRef = ref(); const pathInputRef = ref();
const openSftpCreateModal = inject(openSftpCreateModalKey) as (sessionKey: string, path: string, isTouch: boolean) => void;
const openSftpUploadModal = inject(openSftpUploadModalKey) as () => void;
// 监听路径变化 // 监听路径变化
watch(() => props.currentPath, (path) => { watch(() => props.currentPath, (path) => {
if (path) { if (path) {
@@ -284,13 +279,8 @@
}; };
// 创建文件 // 创建文件
const createFile = () => { const createFile = (isTouch: boolean) => {
openSftpCreateModal(props.session?.sessionKey as string, props.currentPath, true); emits('createFile', isTouch);
};
// 创建文件夹
const createDir = () => {
openSftpCreateModal(props.session?.sessionKey as string, props.currentPath, false);
}; };
// 删除选中文件 // 删除选中文件
@@ -298,6 +288,11 @@
emits('deleteFile', [...props.selectedFiles]); emits('deleteFile', [...props.selectedFiles]);
}; };
// 上传文件
const openUpload = () => {
emits('upload');
};
// 下载文件 // 下载文件
const downloadFile = () => { const downloadFile = () => {
emits('download', [...props.selectedFiles], true); emits('download', [...props.selectedFiles], true);

View File

@@ -144,13 +144,13 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { TableData } from '@arco-design/web-vue'; import type { TableData } from '@arco-design/web-vue';
import type { SftpFile, ISftpSession } from '@/views/terminal/interfaces'; import type { SftpFile, ISftpSession } from '@/views/terminal/interfaces';
import { ref, computed, watch, inject } from 'vue'; import { ref, computed, watch } from 'vue';
import { useRowSelection } from '@/hooks/table'; import { useRowSelection } from '@/hooks/table';
import { dateFormat } from '@/utils'; import { dateFormat } from '@/utils';
import { setAutoFocus } from '@/utils/dom'; import { setAutoFocus } from '@/utils/dom';
import { copy } from '@/hooks/copy'; import { copy } from '@/hooks/copy';
import { sftpColumns } from '@/views/terminal/types/table.columns'; import { sftpColumns } from '@/views/terminal/types/table.columns';
import { FILE_TYPE, openSftpChmodModalKey, openSftpMoveModalKey } from '@/views/terminal/types/const'; import { FILE_TYPE } from '@/views/terminal/types/const';
const props = defineProps<{ const props = defineProps<{
session?: ISftpSession; session?: ISftpSession;
@@ -160,10 +160,7 @@
selectedFiles: Array<string>; selectedFiles: Array<string>;
}>(); }>();
const emits = defineEmits(['update:selectedFiles', 'loadFile', 'editFile', 'deleteFile', 'download']); const emits = defineEmits(['update:selectedFiles', 'loadFile', 'moveFile', 'chmodFile', 'editFile', 'deleteFile', 'download']);
const openSftpMoveModal = inject(openSftpMoveModalKey) as (sessionKey: string, path: string) => void;
const openSftpChmodModal = inject(openSftpChmodModalKey) as (sessionKey: string, path: string, permission: number) => void;
const rowSelection = useRowSelection({ width: 40 }); const rowSelection = useRowSelection({ width: 40 });
@@ -249,7 +246,7 @@
if (!props.session?.state.connected) { if (!props.session?.state.connected) {
return; return;
} }
openSftpMoveModal(props.session?.sessionKey as string, path); emits('moveFile', path);
}; };
// 文件提权 // 文件提权
@@ -258,7 +255,7 @@
if (!props.session?.state.connected) { if (!props.session?.state.connected) {
return; return;
} }
openSftpChmodModal(props.session?.sessionKey as string, path, permission); emits('chmodFile', path, permission);
}; };
// 格式化文件类型 // 格式化文件类型

View File

@@ -80,6 +80,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { FileItem } from '@arco-design/web-vue'; import type { FileItem } from '@arco-design/web-vue';
import type { ITerminalSession } from '@/views/terminal/interfaces';
import { ref } from 'vue'; import { ref } from 'vue';
import { useTerminalStore } from '@/store'; import { useTerminalStore } from '@/store';
import { Message } from '@arco-design/web-vue'; import { Message } from '@arco-design/web-vue';
@@ -87,22 +88,21 @@
import useVisible from '@/hooks/visible'; import useVisible from '@/hooks/visible';
import useLoading from '@/hooks/loading'; import useLoading from '@/hooks/loading';
const props = defineProps<{
session?: ITerminalSession;
}>();
const emits = defineEmits(['closed']); const emits = defineEmits(['closed']);
const { visible, setVisible } = useVisible(); const { visible, setVisible } = useVisible();
const { loading, setLoading } = useLoading(); const { loading, setLoading } = useLoading();
const { transferManager } = useTerminalStore(); const { transferManager } = useTerminalStore();
const hostId = ref();
const parentPath = ref(''); const parentPath = ref('');
const compressUpload = ref(false);
const fileList = ref<FileItem[]>([]); const fileList = ref<FileItem[]>([]);
// 打开 // 打开
const open = (host: number, parent: string) => { const open = (parent: string) => {
hostId.value = host;
parentPath.value = parent; parentPath.value = parent;
compressUpload.value = false;
setVisible(true); setVisible(true);
}; };
@@ -121,7 +121,7 @@
// 获取上传的文件 // 获取上传的文件
const files = fileList.value.map(s => s.file as File); const files = fileList.value.map(s => s.file as File);
// 普通上传 // 普通上传
await transferManager.sftp.addUpload(hostId.value, parentPath.value, files); await transferManager.sftp.addUpload(props.session as ITerminalSession, parentPath.value, files);
// 清空 // 清空
handlerClear(); handlerClear();
return true; return true;

View File

@@ -17,7 +17,9 @@
:session="session" :session="session"
@load-file="loadFiles" @load-file="loadFiles"
@set-loading="setTableLoading" @set-loading="setTableLoading"
@create-file="openCreate"
@delete-file="deleteFile" @delete-file="deleteFile"
@upload="openUpload"
@download="downloadFiles" /> @download="downloadFiles" />
<!-- 表格 --> <!-- 表格 -->
<sftp-table class="sftp-table-wrapper" <sftp-table class="sftp-table-wrapper"
@@ -27,6 +29,8 @@
:loading="tableLoading" :loading="tableLoading"
:editor-loading="editorLoading" :editor-loading="editorLoading"
@load-file="loadFiles" @load-file="loadFiles"
@chmod-file="openChmod"
@move-file="openMove"
@edit-file="editFile" @edit-file="editFile"
@delete-file="deleteFile" @delete-file="deleteFile"
@download="downloadFiles" /> @download="downloadFiles" />
@@ -48,13 +52,13 @@
</template> </template>
</a-split> </a-split>
<!-- 创建文件模态框 --> <!-- 创建文件模态框 -->
<sftp-create-modal ref="createModal" /> <sftp-create-modal ref="createModal" :session="session" />
<!-- 移动文件模态框 --> <!-- 移动文件模态框 -->
<sftp-move-modal ref="moveModal" /> <sftp-move-modal ref="moveModal" :session="session" />
<!-- 文件提权模态框 --> <!-- 文件提权模态框 -->
<sftp-chmod-modal ref="chmodModal" /> <sftp-chmod-modal ref="chmodModal" :session="session" />
<!-- 文件上传模态框 --> <!-- 文件上传模态框 -->
<sftp-upload-modal ref="uploadModal" /> <sftp-upload-modal ref="uploadModal" :session="session" />
</div> </div>
</template> </template>
@@ -66,11 +70,10 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { ISftpSession, SftpFile, TerminalSessionTabItem } from '@/views/terminal/interfaces'; import type { ISftpSession, SftpFile, TerminalSessionTabItem } from '@/views/terminal/interfaces';
import { onMounted, onUnmounted, provide, ref } from 'vue'; import { onMounted, onUnmounted, ref } from 'vue';
import { useTerminalStore } from '@/store'; import { useTerminalStore } from '@/store';
import { Message } from '@arco-design/web-vue'; import { Message } from '@arco-design/web-vue';
import useLoading from '@/hooks/loading'; import useLoading from '@/hooks/loading';
import { openSftpCreateModalKey, openSftpMoveModalKey, openSftpChmodModalKey, openSftpUploadModalKey } from '@/views/terminal/types/const';
import { getSftpFileContent, setSftpFileContent } from '@/api/terminal/terminal-sftp'; import { getSftpFileContent, setSftpFileContent } from '@/api/terminal/terminal-sftp';
import { isString } from '@/utils/is'; import { isString } from '@/utils/is';
import SftpTableHeader from './sftp-table-header.vue'; import SftpTableHeader from './sftp-table-header.vue';
@@ -105,26 +108,6 @@
const chmodModal = ref(); const chmodModal = ref();
const uploadModal = ref(); const uploadModal = ref();
// 暴露打开创建模态框
provide(openSftpCreateModalKey, (sessionKey: string, path: string, isTouch: boolean) => {
createModal.value?.open(sessionKey, path, isTouch);
});
// 暴露打开移动模态框
provide(openSftpMoveModalKey, (sessionKey: string, path: string) => {
moveModal.value?.open(sessionKey, path);
});
// 暴露打开提权模态框
provide(openSftpChmodModalKey, (sessionKey: string, path: string, permission: number) => {
chmodModal.value?.open(sessionKey, path, permission);
});
// 暴露打开上传模态框
provide(openSftpUploadModalKey, () => {
uploadModal.value?.open(props.item.hostId, currentPath.value);
});
// 编辑文件 // 编辑文件
const editFile = (name: string, path: string) => { const editFile = (name: string, path: string) => {
setEditorLoading(true); setEditorLoading(true);
@@ -149,6 +132,26 @@
editorFilePath.value = ''; editorFilePath.value = '';
}; };
// 打开创建文件
const openCreate = (isTouch: boolean) => {
createModal.value.open(currentPath.value, isTouch);
};
// 打开文件移动
const openMove = (path: string) => {
moveModal.value.open(path);
};
// 打开文件提权
const openChmod = (path: string, permission: number) => {
chmodModal.value.open(path, permission);
};
// 打开文件上传
const openUpload = () => {
uploadModal.value.open(currentPath.value);
};
// 删除文件 // 删除文件
const deleteFile = (paths: Array<string>) => { const deleteFile = (paths: Array<string>) => {
if (!paths.length) { if (!paths.length) {
@@ -174,7 +177,7 @@
} }
// 添加普通文件到下载队列 // 添加普通文件到下载队列
const normalFiles = files.filter(s => !s.isDir); const normalFiles = files.filter(s => !s.isDir);
await transferManager.sftp.addDownload(props.item.hostId as number, currentPath.value, normalFiles); await transferManager.sftp.addDownload(session.value as ISftpSession, currentPath.value, normalFiles);
// 将文件夹展开普通文件 // 将文件夹展开普通文件
const directoryPaths = files.filter(s => s.isDir).map(s => s.path); const directoryPaths = files.filter(s => s.isDir).map(s => s.path);
if (directoryPaths.length) { if (directoryPaths.length) {
@@ -282,7 +285,7 @@
if (!checkResult(result, msg)) { if (!checkResult(result, msg)) {
return; return;
} }
transferManager.sftp.addDownload(props.item.hostId as number, currentPath, list); transferManager.sftp.addDownload(session.value as ISftpSession, currentPath, list);
}; };
// 初始化会话 // 初始化会话

View File

@@ -17,7 +17,9 @@
</div> </div>
</ssh-context-menu> </ssh-context-menu>
<!-- 上传文件模态框 --> <!-- 上传文件模态框 -->
<sftp-upload-modal ref="uploadModal" @closed="focus" /> <sftp-upload-modal ref="uploadModal"
:session="session"
@closed="focus" />
</div> </div>
</template> </template>

View File

@@ -35,6 +35,7 @@ export interface GuacdInitConfig {
export interface SessionHostInfo { export interface SessionHostInfo {
title: string; title: string;
name: string; name: string;
logId: number;
hostId: number; hostId: number;
address: string; address: string;
port: number; port: number;

View File

@@ -1,4 +1,4 @@
import type { IRdpSession, SftpFile } from '@/views/terminal/interfaces'; import type { IRdpSession, ITerminalSession, SftpFile } from '@/views/terminal/interfaces';
import type { Reactive } from 'vue'; import type { Reactive } from 'vue';
import type Guacamole from 'guacamole-common-js'; import type Guacamole from 'guacamole-common-js';
@@ -43,9 +43,9 @@ export interface ITransferManager {
// SFTP 文件传输管理器定义 // SFTP 文件传输管理器定义
export interface ISftpTransferManager extends ITransferManager { export interface ISftpTransferManager extends ITransferManager {
// 添加上传任务 // 添加上传任务
addUpload: (hostId: number, parentPath: string, files: Array<File>) => Promise<void>; addUpload: (session: ITerminalSession, parentPath: string, files: Array<File>) => Promise<void>;
// 添加下载任务 // 添加下载任务
addDownload: (hostId: number, currentPath: string, files: Array<SftpFile>) => Promise<void>; addDownload: (session: ITerminalSession, currentPath: string, files: Array<SftpFile>) => Promise<void>;
} }
// RDP 文件传输管理器定义 // RDP 文件传输管理器定义

View File

@@ -1,4 +1,4 @@
import type { ITerminalChannel, ITerminalSession } from '@/views/terminal/interfaces'; import type { ITerminalChannel, ITerminalSession, SessionHostInfo } from '@/views/terminal/interfaces';
import type { InputPayload, OutputPayload, Protocol } from '@/views/terminal/types/protocol'; import type { InputPayload, OutputPayload, Protocol } from '@/views/terminal/types/protocol';
import { format, InputProtocol, OutputProtocol, parse } from '@/views/terminal/types/protocol'; import { format, InputProtocol, OutputProtocol, parse } from '@/views/terminal/types/protocol';
import { TerminalCloseCode, TerminalMessages } from '../../types/const'; import { TerminalCloseCode, TerminalMessages } from '../../types/const';
@@ -66,11 +66,11 @@ export default abstract class BaseTerminalChannel<T extends ITerminalSession> im
// 处理设置信息 // 处理设置信息
processSetInfo({ info }: OutputPayload) { processSetInfo({ info }: OutputPayload) {
const data = JSON.parse(info); const data = JSON.parse(info) as SessionHostInfo;
if (data) { if (data) {
this.session.info.address = data.address; Object.keys(data).forEach(k => {
this.session.info.port = data.port; (this.session.info[k as keyof SessionHostInfo] as any) = data[k as keyof SessionHostInfo];
this.session.info.username = data.username; });
} }
}; };

View File

@@ -211,7 +211,7 @@ export default class SshSessionHandler implements ISshSessionHandler {
// 上传文件 // 上传文件
uploadFile(): void { uploadFile(): void {
this.session.config.uploadModal.open(this.session.info.hostId, '/'); this.session.config.uploadModal.open('/');
} }
// ctrl + c // ctrl + c

View File

@@ -18,9 +18,9 @@ export default abstract class BaseSession<State extends ReactiveSessionState, Ch
protected constructor(item: TerminalSessionTabItem, state: Partial<State>) { protected constructor(item: TerminalSessionTabItem, state: Partial<State>) {
this.type = item.type; this.type = item.type;
this.info = { this.info = {
hostId: item.hostId,
title: item.title, title: item.title,
name: item.name, name: item.name,
hostId: item.hostId,
address: item.address, address: item.address,
} as SessionHostInfo; } as SessionHostInfo;
this.panelIndex = item.panelIndex; this.panelIndex = item.panelIndex;

View File

@@ -1,17 +1,20 @@
import type { ISetTransferClient, FileTransferItem } from '@/views/terminal/interfaces'; import type { FileTransferItem, ISetTransferClient, ITerminalSession } from '@/views/terminal/interfaces';
import { TransferOperator, TransferStatus, TerminalMessages, TransferSource } from '../../types/const'; import { TerminalMessages, TransferOperator, TransferSource, TransferStatus } from '../../types/const';
import { getPath } from '@/utils/file'; import { getPath } from '@/utils/file';
import BaseFileTransferTask from './base-file-transfer-task'; import BaseFileTransferTask from './base-file-transfer-task';
// sftp 传输任务一定义 // sftp 传输任务基类
export default abstract class SftpBaseTransferTask extends BaseFileTransferTask implements ISetTransferClient<WebSocket> { export default abstract class SftpBaseTransferTask extends BaseFileTransferTask implements ISetTransferClient<WebSocket> {
protected client?: WebSocket; protected client?: WebSocket;
protected logId: number;
protected constructor(type: string, protected constructor(type: string,
hostId: number, session: ITerminalSession,
fileItem: FileTransferItem) { fileItem: FileTransferItem) {
super(type, TransferSource.SFTP, hostId, undefined as unknown as string, fileItem, {}); super(type, TransferSource.SFTP, session.info.hostId, session.sessionKey, fileItem, {});
this.logId = session.info.logId;
} }
// 设置传输客户端 // 设置传输客户端
@@ -25,6 +28,7 @@ export default abstract class SftpBaseTransferTask extends BaseFileTransferTask
// 发送开始信息 // 发送开始信息
this.client?.send(JSON.stringify({ this.client?.send(JSON.stringify({
operator: TransferOperator.START, operator: TransferOperator.START,
logId: this.logId,
type: this.type, type: this.type,
hostId: this.hostId, hostId: this.hostId,
path: getPath(this.fileItem.parentPath + '/' + this.fileItem.name), path: getPath(this.fileItem.parentPath + '/' + this.fileItem.name),

View File

@@ -1,4 +1,4 @@
import type { FileTransferItem, IFileDownloadTask } from '@/views/terminal/interfaces'; import type { FileTransferItem, IFileDownloadTask, ITerminalSession } from '@/views/terminal/interfaces';
import { TransferStatus, TerminalMessages } from '../../types/const'; import { TransferStatus, TerminalMessages } from '../../types/const';
import { getFileName, openDownloadFile } from '@/utils/file'; import { getFileName, openDownloadFile } from '@/utils/file';
import { saveAs } from 'file-saver'; import { saveAs } from 'file-saver';
@@ -8,8 +8,8 @@ import SftpBaseTransferTask from './sftp-base-transfer-task';
// sftp 下载任务实现 // sftp 下载任务实现
export default class SftpFileDownloadTask extends SftpBaseTransferTask implements IFileDownloadTask { export default class SftpFileDownloadTask extends SftpBaseTransferTask implements IFileDownloadTask {
constructor(type: string, hostId: number, fileItem: FileTransferItem) { constructor(type: string, session: ITerminalSession, fileItem: FileTransferItem) {
super(type, hostId, fileItem); super(type, session, fileItem);
} }
// 开始回调 // 开始回调

View File

@@ -1,4 +1,4 @@
import type { FileTransferItem, IFileUploadTask } from '@/views/terminal/interfaces'; import type { FileTransferItem, IFileUploadTask, ITerminalSession } from '@/views/terminal/interfaces';
import { closeFileReader } from '@/utils/file'; import { closeFileReader } from '@/utils/file';
import SftpBaseTransferTask from './sftp-base-transfer-task'; import SftpBaseTransferTask from './sftp-base-transfer-task';
@@ -11,8 +11,8 @@ export default class SftpFileUploadTask extends SftpBaseTransferTask implements
private currentPart: number; private currentPart: number;
private readonly totalPart: number; private readonly totalPart: number;
constructor(type: string, hostId: number, fileItem: FileTransferItem) { constructor(type: string, session: ITerminalSession, fileItem: FileTransferItem) {
super(type, hostId, fileItem); super(type, session, fileItem);
this.currentPart = 0; this.currentPart = 0;
this.totalPart = Math.ceil(fileItem.size / PART_SIZE); this.totalPart = Math.ceil(fileItem.size / PART_SIZE);
} }

View File

@@ -2,6 +2,7 @@ import type {
FileTransferTaskType, FileTransferTaskType,
ISetTransferClient, ISetTransferClient,
ISftpTransferManager, ISftpTransferManager,
ITerminalSession,
MaybeFileTransferTask, MaybeFileTransferTask,
SftpFile, SftpFile,
TransferOperatorResponse TransferOperatorResponse
@@ -28,11 +29,11 @@ export default class SftpTransferManager extends BaseTransferManager implements
} }
// 添加上传任务 // 添加上传任务
async addUpload(hostId: number, parentPath: string, files: Array<File>) { async addUpload(session: ITerminalSession, parentPath: string, files: Array<File>) {
Message.info(TerminalMessages.fileUploading); Message.info(TerminalMessages.fileUploading);
// 创建任务 // 创建任务
for (let file of files) { for (let file of files) {
const task = new SftpFileUploadTask(TransferType.UPLOAD, hostId, { const task = new SftpFileUploadTask(TransferType.UPLOAD, session, {
name: file.webkitRelativePath || file.name, name: file.webkitRelativePath || file.name,
parentPath: parentPath, parentPath: parentPath,
size: file.size, size: file.size,
@@ -45,12 +46,12 @@ export default class SftpTransferManager extends BaseTransferManager implements
} }
// 添加下载任务 // 添加下载任务
async addDownload(hostId: number, currentPath: string, files: Array<SftpFile>) { async addDownload(session: ITerminalSession, currentPath: string, files: Array<SftpFile>) {
Message.info(TerminalMessages.fileDownloading); Message.info(TerminalMessages.fileDownloading);
let pathIndex = currentPath === '/' ? 1 : currentPath.length + 1; let pathIndex = currentPath === '/' ? 1 : currentPath.length + 1;
for (let file of files) { for (let file of files) {
// 创建任务 // 创建任务
const task = new SftpFileDownloadTask(TransferType.DOWNLOAD, hostId, { const task = new SftpFileDownloadTask(TransferType.DOWNLOAD, session, {
name: file.path.substring(pathIndex), name: file.path.substring(pathIndex),
parentPath: currentPath, parentPath: currentPath,
size: file.size, size: file.size,

View File

@@ -494,18 +494,6 @@ export const PathBookmarkType = {
// 打开 extraModal key // 打开 extraModal key
export const openExtraModalKey = Symbol(); export const openExtraModalKey = Symbol();
// 打开 sftpCreateModal key
export const openSftpCreateModalKey = Symbol();
// 打开 sftpMoveModal key
export const openSftpMoveModalKey = Symbol();
// 打开 sftpChmodModal key
export const openSftpChmodModalKey = Symbol();
// 打开 sftpUploadModal key
export const openSftpUploadModalKey = Symbol();
// 终端字体样式 // 终端字体样式
export const fontFamilyKey = 'terminalFontFamily'; export const fontFamilyKey = 'terminalFontFamily';