🔨 sftp 文件列表.
This commit is contained in:
@@ -26,7 +26,7 @@ export function readFileText(e: File, encoding = 'UTF-8'): Promise<string> {
|
|||||||
/**
|
/**
|
||||||
* 解析路径类型
|
* 解析路径类型
|
||||||
*/
|
*/
|
||||||
type PathAnalysis = {
|
export interface PathAnalysis {
|
||||||
name: string;
|
name: string;
|
||||||
path: string;
|
path: string;
|
||||||
}
|
}
|
||||||
@@ -34,23 +34,19 @@ type PathAnalysis = {
|
|||||||
/**
|
/**
|
||||||
* 获取解析路径
|
* 获取解析路径
|
||||||
*/
|
*/
|
||||||
export function getPathAnalysis(analysisPath: string, paths: PathAnalysis[] = []): PathAnalysis[] {
|
export function getPathAnalysis(path: string, paths: PathAnalysis[] = []): PathAnalysis[] {
|
||||||
const lastSymbol = analysisPath.lastIndexOf('/');
|
const lastSeparatorIndex = path.lastIndexOf('/');
|
||||||
if (lastSymbol === -1) {
|
if (lastSeparatorIndex === -1) {
|
||||||
paths.unshift({
|
|
||||||
name: '/',
|
|
||||||
path: '/'
|
|
||||||
});
|
|
||||||
return paths;
|
return paths;
|
||||||
}
|
}
|
||||||
const name = analysisPath.substring(lastSymbol, analysisPath.length);
|
const name = path.substring(lastSeparatorIndex, path.length);
|
||||||
if (!isEmptyStr(name) && name !== '/') {
|
if (!isEmptyStr(name) && name !== '/') {
|
||||||
paths.unshift({
|
paths.unshift({
|
||||||
name: name.substring(1, name.length),
|
name: name.substring(1, name.length),
|
||||||
path: analysisPath
|
path: path
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return getPathAnalysis(analysisPath.substring(0, lastSymbol), paths);
|
return getPathAnalysis(path.substring(0, lastSeparatorIndex), paths);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -58,7 +54,7 @@ export function getPathAnalysis(analysisPath: string, paths: PathAnalysis[] = []
|
|||||||
*/
|
*/
|
||||||
export function getPath(path: string) {
|
export function getPath(path: string) {
|
||||||
return path.replace(new RegExp('\\\\+', 'g'), '/')
|
return path.replace(new RegExp('\\\\+', 'g'), '/')
|
||||||
.replace(new RegExp('/+', 'g'), '/');
|
.replace(new RegExp('/+', 'g'), '/');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -11,27 +11,68 @@
|
|||||||
content-class="terminal-tooltip-content"
|
content-class="terminal-tooltip-content"
|
||||||
arrow-class="terminal-tooltip-content"
|
arrow-class="terminal-tooltip-content"
|
||||||
content="返回上级">
|
content="返回上级">
|
||||||
<span class="click-icon-wrapper header-action-icon mr4">
|
<span class="click-icon-wrapper header-action-icon mr4"
|
||||||
|
@click="backParentPath">
|
||||||
<icon-left />
|
<icon-left />
|
||||||
</span>
|
</span>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<!-- 当前路径 -->
|
<!-- 当前路径 -->
|
||||||
<div class="sftp-path-wrapper">
|
<div class="sftp-path-wrapper"
|
||||||
<a-breadcrumb>
|
@click="setPathEditable(true)">
|
||||||
<!-- 分隔符 -->
|
<!-- 路径输入框 -->
|
||||||
<template #separator>
|
<div v-if="pathEditable">
|
||||||
<icon-right />
|
<a-input v-model="pathInput"
|
||||||
</template>
|
placeholder="文件夹路径"
|
||||||
<a-breadcrumb-item class="sftp-path-unit">/</a-breadcrumb-item>
|
allow-clear
|
||||||
<a-breadcrumb-item class="sftp-path-unit">root</a-breadcrumb-item>
|
@press-enter="doChangePath" />
|
||||||
<a-breadcrumb-item class="sftp-path-unit">orion</a-breadcrumb-item>
|
</div>
|
||||||
<a-breadcrumb-item class="sftp-path-unit">space</a-breadcrumb-item>
|
<!-- 路径视图 -->
|
||||||
<a-breadcrumb-item class="sftp-path-unit">logs</a-breadcrumb-item>
|
<a-breadcrumb v-else>
|
||||||
|
<!-- 根目录 -->
|
||||||
|
<a-breadcrumb-item class="sftp-path-unit"
|
||||||
|
@click.stop="loadFileList('/')">
|
||||||
|
<icon-home />
|
||||||
|
</a-breadcrumb-item>
|
||||||
|
<!-- 子目录 -->
|
||||||
|
<a-breadcrumb-item class="sftp-path-unit"
|
||||||
|
v-for="path in analysisPaths"
|
||||||
|
@click.stop="loadFileList(path.path)">
|
||||||
|
{{ path.name }}
|
||||||
|
</a-breadcrumb-item>
|
||||||
</a-breadcrumb>
|
</a-breadcrumb>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 右侧操作 -->
|
<!-- 路径编辑模式-右侧操作 -->
|
||||||
<a-space class="sftp-table-header-right">
|
<a-space v-if="pathEditable" class="sftp-table-header-right">
|
||||||
|
<!-- 进入 -->
|
||||||
|
<a-tooltip position="top"
|
||||||
|
:mini="true"
|
||||||
|
:overlay-inverse="true"
|
||||||
|
:auto-fix-position="false"
|
||||||
|
content-class="terminal-tooltip-content"
|
||||||
|
arrow-class="terminal-tooltip-content"
|
||||||
|
content="进入">
|
||||||
|
<span class="click-icon-wrapper header-action-icon"
|
||||||
|
@click="doChangePath">
|
||||||
|
<icon-right />
|
||||||
|
</span>
|
||||||
|
</a-tooltip>
|
||||||
|
<!-- 取消 -->
|
||||||
|
<a-tooltip position="top"
|
||||||
|
:mini="true"
|
||||||
|
:overlay-inverse="true"
|
||||||
|
:auto-fix-position="false"
|
||||||
|
content-class="terminal-tooltip-content"
|
||||||
|
arrow-class="terminal-tooltip-content"
|
||||||
|
content="取消">
|
||||||
|
<span class="click-icon-wrapper header-action-icon"
|
||||||
|
@click="setPathEditable(false)">
|
||||||
|
<icon-stop />
|
||||||
|
</span>
|
||||||
|
</a-tooltip>
|
||||||
|
</a-space>
|
||||||
|
<!-- 非路径编辑模式-右侧操作 -->
|
||||||
|
<a-space v-else class="sftp-table-header-right">
|
||||||
<!-- 刷新 -->
|
<!-- 刷新 -->
|
||||||
<a-tooltip position="top"
|
<a-tooltip position="top"
|
||||||
:mini="true"
|
:mini="true"
|
||||||
@@ -40,7 +81,8 @@
|
|||||||
content-class="terminal-tooltip-content"
|
content-class="terminal-tooltip-content"
|
||||||
arrow-class="terminal-tooltip-content"
|
arrow-class="terminal-tooltip-content"
|
||||||
content="刷新">
|
content="刷新">
|
||||||
<span class="click-icon-wrapper header-action-icon">
|
<span class="click-icon-wrapper header-action-icon"
|
||||||
|
@click="loadFileList">
|
||||||
<icon-refresh />
|
<icon-refresh />
|
||||||
</span>
|
</span>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
@@ -51,9 +93,11 @@
|
|||||||
:auto-fix-position="false"
|
:auto-fix-position="false"
|
||||||
content-class="terminal-tooltip-content"
|
content-class="terminal-tooltip-content"
|
||||||
arrow-class="terminal-tooltip-content"
|
arrow-class="terminal-tooltip-content"
|
||||||
content="显示隐藏文件">
|
:content="showHiddenFile ? '不显示隐藏文件' : '显示隐藏文件'">
|
||||||
<span class="click-icon-wrapper header-action-icon">
|
<span class="click-icon-wrapper header-action-icon"
|
||||||
<icon-eye />
|
@click="toggleShowHiddenFile">
|
||||||
|
<icon-eye-invisible v-if="showHiddenFile" />
|
||||||
|
<icon-eye v-else />
|
||||||
</span>
|
</span>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<!-- 创建文件 -->
|
<!-- 创建文件 -->
|
||||||
@@ -64,7 +108,8 @@
|
|||||||
content-class="terminal-tooltip-content"
|
content-class="terminal-tooltip-content"
|
||||||
arrow-class="terminal-tooltip-content"
|
arrow-class="terminal-tooltip-content"
|
||||||
content="创建文件">
|
content="创建文件">
|
||||||
<span class="click-icon-wrapper header-action-icon">
|
<span class="click-icon-wrapper header-action-icon"
|
||||||
|
@click="createFile">
|
||||||
<icon-drive-file />
|
<icon-drive-file />
|
||||||
</span>
|
</span>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
@@ -76,23 +121,25 @@
|
|||||||
content-class="terminal-tooltip-content"
|
content-class="terminal-tooltip-content"
|
||||||
arrow-class="terminal-tooltip-content"
|
arrow-class="terminal-tooltip-content"
|
||||||
content="创建文件夹">
|
content="创建文件夹">
|
||||||
<span class="click-icon-wrapper header-action-icon">
|
<span class="click-icon-wrapper header-action-icon"
|
||||||
|
@click="createDir">
|
||||||
<icon-folder-add />
|
<icon-folder-add />
|
||||||
</span>
|
</span>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<!-- 删除 -->
|
<!-- 删除选中文件 -->
|
||||||
<a-tooltip position="top"
|
<a-tooltip position="top"
|
||||||
:mini="true"
|
:mini="true"
|
||||||
:overlay-inverse="true"
|
:overlay-inverse="true"
|
||||||
:auto-fix-position="false"
|
:auto-fix-position="false"
|
||||||
content-class="terminal-tooltip-content"
|
content-class="terminal-tooltip-content"
|
||||||
arrow-class="terminal-tooltip-content"
|
arrow-class="terminal-tooltip-content"
|
||||||
content="删除">
|
content="删除选中文件">
|
||||||
<span class="click-icon-wrapper header-action-icon">
|
<span class="click-icon-wrapper header-action-icon"
|
||||||
|
@click="deleteSelectFiles">
|
||||||
<icon-delete />
|
<icon-delete />
|
||||||
</span>
|
</span>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<!-- 复制 -->
|
<!-- 复制 FIXME 不行就删除 -->
|
||||||
<a-tooltip position="top"
|
<a-tooltip position="top"
|
||||||
:mini="true"
|
:mini="true"
|
||||||
:overlay-inverse="true"
|
:overlay-inverse="true"
|
||||||
@@ -100,11 +147,11 @@
|
|||||||
content-class="terminal-tooltip-content"
|
content-class="terminal-tooltip-content"
|
||||||
arrow-class="terminal-tooltip-content"
|
arrow-class="terminal-tooltip-content"
|
||||||
content="复制">
|
content="复制">
|
||||||
<span class="click-icon-wrapper header-action-icon">
|
<span v-if="false" class="click-icon-wrapper header-action-icon">
|
||||||
<icon-copy />
|
<icon-copy />
|
||||||
</span>
|
</span>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<!-- 移动 -->
|
<!-- 移动 FIXME 不行就删除 -->
|
||||||
<a-tooltip position="top"
|
<a-tooltip position="top"
|
||||||
:mini="true"
|
:mini="true"
|
||||||
:overlay-inverse="true"
|
:overlay-inverse="true"
|
||||||
@@ -124,7 +171,8 @@
|
|||||||
content-class="terminal-tooltip-content"
|
content-class="terminal-tooltip-content"
|
||||||
arrow-class="terminal-tooltip-content"
|
arrow-class="terminal-tooltip-content"
|
||||||
content="上传">
|
content="上传">
|
||||||
<span class="click-icon-wrapper header-action-icon">
|
<span class="click-icon-wrapper header-action-icon"
|
||||||
|
@click="uploadFile">
|
||||||
<icon-upload />
|
<icon-upload />
|
||||||
</span>
|
</span>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
@@ -136,7 +184,8 @@
|
|||||||
content-class="terminal-tooltip-content"
|
content-class="terminal-tooltip-content"
|
||||||
arrow-class="terminal-tooltip-content"
|
arrow-class="terminal-tooltip-content"
|
||||||
content="下载">
|
content="下载">
|
||||||
<span class="click-icon-wrapper header-action-icon">
|
<span class="click-icon-wrapper header-action-icon"
|
||||||
|
@click="downloadFile">
|
||||||
<icon-download />
|
<icon-download />
|
||||||
</span>
|
</span>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
@@ -151,6 +200,91 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import type { PathAnalysis } from '@/utils/file';
|
||||||
|
import type { ISftpSession } from '../../types/terminal.type';
|
||||||
|
import { ref, watch } from 'vue';
|
||||||
|
import { getParentPath, getPathAnalysis } from '@/utils/file';
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
currentPath: string;
|
||||||
|
session: ISftpSession | undefined,
|
||||||
|
selectedFiles: Array<string>
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const emits = defineEmits(['loadFile']);
|
||||||
|
|
||||||
|
const showHiddenFile = ref(false);
|
||||||
|
const analysisPaths = ref<Array<PathAnalysis>>([]);
|
||||||
|
const pathEditable = ref(false);
|
||||||
|
const pathInput = ref('');
|
||||||
|
|
||||||
|
// 监听路径变化
|
||||||
|
watch(() => props.currentPath, (path) => {
|
||||||
|
if (path) {
|
||||||
|
analysisPaths.value = getPathAnalysis(path);
|
||||||
|
} else {
|
||||||
|
analysisPaths.value = [];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 返回上级目录
|
||||||
|
const backParentPath = () => {
|
||||||
|
loadFileList(getParentPath(props.currentPath));
|
||||||
|
};
|
||||||
|
|
||||||
|
// 设置命令编辑模式
|
||||||
|
const setPathEditable = (editable: boolean) => {
|
||||||
|
pathEditable.value = editable;
|
||||||
|
pathInput.value = editable ? props.currentPath : '';
|
||||||
|
};
|
||||||
|
|
||||||
|
// 执行修改目录
|
||||||
|
const doChangePath = () => {
|
||||||
|
loadFileList(pathInput.value);
|
||||||
|
setPathEditable(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 加载文件列表
|
||||||
|
const loadFileList = (path: string = props.currentPath) => {
|
||||||
|
emits('loadFile', path);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 设置是否显示隐藏文件
|
||||||
|
const toggleShowHiddenFile = () => {
|
||||||
|
showHiddenFile.value = !showHiddenFile.value;
|
||||||
|
// 设置显示状态并且刷新
|
||||||
|
if (props.session) {
|
||||||
|
props.session.setShowHiddenFile(showHiddenFile.value);
|
||||||
|
loadFileList();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 创建文件
|
||||||
|
const createFile = () => {
|
||||||
|
// openModal(true, "props.currentPath")
|
||||||
|
};
|
||||||
|
|
||||||
|
// 创建文件夹
|
||||||
|
const createDir = () => {
|
||||||
|
// openModal(false, "props.currentPath")
|
||||||
|
};
|
||||||
|
|
||||||
|
// 删除选中文件
|
||||||
|
const deleteSelectFiles = () => {
|
||||||
|
// confirm
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// 上传文件
|
||||||
|
const uploadFile = () => {
|
||||||
|
// openModal("props.currentPath")
|
||||||
|
};
|
||||||
|
|
||||||
|
// 下载文件
|
||||||
|
const downloadFile = () => {
|
||||||
|
};
|
||||||
|
|
||||||
|
// FIXME 图标宽度提成变量
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-table row-key="name"
|
<a-table row-key="path"
|
||||||
class="sftp-table"
|
class="sftp-table"
|
||||||
label-align="left"
|
label-align="left"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
<!-- 修改时间/操作 -->
|
<!-- 修改时间/操作 -->
|
||||||
<template #modifyTime="{ record }">
|
<template #modifyTime="{ record }">
|
||||||
<!-- 修改时间 -->
|
<!-- 修改时间 -->
|
||||||
<span v-if="editName !== record.name">{{ dateFormat(new Date(record.modifyTime)) }}</span>
|
<span v-if="editRowName !== record.name">{{ dateFormat(new Date(record.modifyTime)) }}</span>
|
||||||
<!-- 操作 -->
|
<!-- 操作 -->
|
||||||
<a-space v-else>
|
<a-space v-else>
|
||||||
<!-- 复制路径 -->
|
<!-- 复制路径 -->
|
||||||
@@ -67,10 +67,10 @@
|
|||||||
content-class="terminal-tooltip-content"
|
content-class="terminal-tooltip-content"
|
||||||
arrow-class="terminal-tooltip-content"
|
arrow-class="terminal-tooltip-content"
|
||||||
content="删除">
|
content="删除">
|
||||||
<span class="click-icon-wrapper row-action-icon"
|
<span class="click-icon-wrapper row-action-icon"
|
||||||
@click="deleteFile(record.path)">
|
@click="deleteFile(record.path)">
|
||||||
<icon-delete />
|
<icon-delete />
|
||||||
</span>
|
</span>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<!-- 下载 -->
|
<!-- 下载 -->
|
||||||
<a-tooltip position="top"
|
<a-tooltip position="top"
|
||||||
@@ -79,10 +79,10 @@
|
|||||||
content-class="terminal-tooltip-content"
|
content-class="terminal-tooltip-content"
|
||||||
arrow-class="terminal-tooltip-content"
|
arrow-class="terminal-tooltip-content"
|
||||||
content="下载">
|
content="下载">
|
||||||
<span class="click-icon-wrapper row-action-icon"
|
<span class="click-icon-wrapper row-action-icon"
|
||||||
@click="downloadFile(record.path)">
|
@click="downloadFile(record.path)">
|
||||||
<icon-download />
|
<icon-download />
|
||||||
</span>
|
</span>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<!-- 移动 -->
|
<!-- 移动 -->
|
||||||
<a-tooltip position="top"
|
<a-tooltip position="top"
|
||||||
@@ -91,10 +91,10 @@
|
|||||||
content-class="terminal-tooltip-content"
|
content-class="terminal-tooltip-content"
|
||||||
arrow-class="terminal-tooltip-content"
|
arrow-class="terminal-tooltip-content"
|
||||||
content="移动">
|
content="移动">
|
||||||
<span class="click-icon-wrapper row-action-icon"
|
<span class="click-icon-wrapper row-action-icon"
|
||||||
@click="moveFile(record.path)">
|
@click="moveFile(record.path)">
|
||||||
<icon-paste />
|
<icon-paste />
|
||||||
</span>
|
</span>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<!-- 提权 -->
|
<!-- 提权 -->
|
||||||
<a-tooltip position="top"
|
<a-tooltip position="top"
|
||||||
@@ -103,10 +103,10 @@
|
|||||||
content-class="terminal-tooltip-content"
|
content-class="terminal-tooltip-content"
|
||||||
arrow-class="terminal-tooltip-content"
|
arrow-class="terminal-tooltip-content"
|
||||||
content="提权">
|
content="提权">
|
||||||
<span class="click-icon-wrapper row-action-icon"
|
<span class="click-icon-wrapper row-action-icon"
|
||||||
@click="chmodFile(record.path)">
|
@click="chmodFile(record.path, record.attr)">
|
||||||
<icon-user-group />
|
<icon-user-group />
|
||||||
</span>
|
</span>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</a-space>
|
</a-space>
|
||||||
</template>
|
</template>
|
||||||
@@ -129,20 +129,37 @@
|
|||||||
import useCopy from '@/hooks/copy';
|
import useCopy from '@/hooks/copy';
|
||||||
import { FILE_TYPE } from '../../types/terminal.const';
|
import { FILE_TYPE } from '../../types/terminal.const';
|
||||||
|
|
||||||
|
import type { ISftpSession } from '../../types/terminal.type';
|
||||||
|
import useLoading from '@/hooks/loading';
|
||||||
|
import { useCacheStore } from '@/store';
|
||||||
|
import { computed } from 'vue/dist/vue';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
|
session: ISftpSession | undefined;
|
||||||
list: Array<SftpFile>;
|
list: Array<SftpFile>;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
|
selectedFiles: Array<string>;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
const emits = defineEmits(['update:selectedFiles']);
|
||||||
|
|
||||||
const rowSelection = useRowSelection({ width: 40 });
|
const rowSelection = useRowSelection({ width: 40 });
|
||||||
const { copy } = useCopy();
|
const { copy } = useCopy();
|
||||||
|
|
||||||
const selectedKeys = ref<Array<string>>([]);
|
const selectedKeys = computed({
|
||||||
const editName = ref<string>('');
|
get() {
|
||||||
|
return props.selectedFiles;
|
||||||
|
},
|
||||||
|
set(e) {
|
||||||
|
emits('update:selectedFiles', e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const editRowName = ref<string>('');
|
||||||
|
|
||||||
// 设置选中状态
|
// 设置选中状态
|
||||||
const setEditable = (record: TableData) => {
|
const setEditable = (record: TableData) => {
|
||||||
editName.value = record.name;
|
editRowName.value = record.name;
|
||||||
record.hover = true;
|
record.hover = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -150,8 +167,8 @@
|
|||||||
const unsetEditable = (record: TableData) => {
|
const unsetEditable = (record: TableData) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
// 等待后如果还是当前行 但是未被选中则代表已经被失焦
|
// 等待后如果还是当前行 但是未被选中则代表已经被失焦
|
||||||
if (record.name === editName.value && !record.hover) {
|
if (record.name === editRowName.value && !record.hover) {
|
||||||
editName.value = '';
|
editRowName.value = '';
|
||||||
}
|
}
|
||||||
}, 20);
|
}, 20);
|
||||||
record.hover = false;
|
record.hover = false;
|
||||||
@@ -159,6 +176,7 @@
|
|||||||
|
|
||||||
// 删除文件
|
// 删除文件
|
||||||
const deleteFile = (path: string) => {
|
const deleteFile = (path: string) => {
|
||||||
|
// confirm
|
||||||
};
|
};
|
||||||
|
|
||||||
// 下载文件
|
// 下载文件
|
||||||
@@ -167,10 +185,13 @@
|
|||||||
|
|
||||||
// 移动文件
|
// 移动文件
|
||||||
const moveFile = (path: string) => {
|
const moveFile = (path: string) => {
|
||||||
|
// openModal('path')
|
||||||
};
|
};
|
||||||
|
|
||||||
// 文件提权
|
// 文件提权
|
||||||
const chmodFile = (path: string) => {
|
const chmodFile = (path: string, attr: string) => {
|
||||||
|
// openModal('path','mod')
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 格式化文件类型
|
// 格式化文件类型
|
||||||
|
|||||||
@@ -6,11 +6,18 @@
|
|||||||
:disabled="!editView">
|
:disabled="!editView">
|
||||||
<!-- 左侧面板表格 -->
|
<!-- 左侧面板表格 -->
|
||||||
<template #first>
|
<template #first>
|
||||||
|
<!-- FIXME spin -->
|
||||||
<div class="sftp-table-container">
|
<div class="sftp-table-container">
|
||||||
<!-- 表头 -->
|
<!-- 表头 -->
|
||||||
<sftp-table-header class="sftp-table-header" />
|
<sftp-table-header class="sftp-table-header"
|
||||||
|
:current-path="currentPath"
|
||||||
|
:session="session"
|
||||||
|
:selected-files="selectFiles"
|
||||||
|
@load-file="loadFiles" />
|
||||||
<!-- 表格 -->
|
<!-- 表格 -->
|
||||||
<sftp-table class="sftp-table-wrapper"
|
<sftp-table class="sftp-table-wrapper"
|
||||||
|
v-model:selected-files="selectFiles"
|
||||||
|
:session="session"
|
||||||
:list="fileList"
|
:list="fileList"
|
||||||
:loading="tableLoading" />
|
:loading="tableLoading" />
|
||||||
</div>
|
</div>
|
||||||
@@ -48,19 +55,25 @@
|
|||||||
const session = ref<ISftpSession>();
|
const session = ref<ISftpSession>();
|
||||||
const currentPath = ref<string>('');
|
const currentPath = ref<string>('');
|
||||||
const fileList = ref<Array<SftpFile>>(mockData);
|
const fileList = ref<Array<SftpFile>>(mockData);
|
||||||
|
const selectFiles = ref<Array<string>>([]);
|
||||||
const splitSize = ref(1);
|
const splitSize = ref(1);
|
||||||
const editView = ref(true);
|
const editView = ref(true);
|
||||||
|
|
||||||
// 连接成功回调
|
// 连接成功回调
|
||||||
const connectCallback = () => {
|
const connectCallback = () => {
|
||||||
|
loadFiles(undefined);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 加载文件列表
|
||||||
|
const loadFiles = (path: string | undefined) => {
|
||||||
setTableLoading(true);
|
setTableLoading(true);
|
||||||
session.value?.list(undefined);
|
session.value?.list(path);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 接收列表回调
|
// 接收列表回调
|
||||||
const resolveList = (result: string, path: string, list: Array<SftpFile>) => {
|
const resolveList = (result: string, path: string, list: Array<SftpFile>) => {
|
||||||
const success = !!Number.parseInt(result);
|
const success = !!Number.parseInt(result);
|
||||||
setLoading(false);
|
setTableLoading(false);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
Message.error('查询失败');
|
Message.error('查询失败');
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ export default class SftpSession implements ISftpSession {
|
|||||||
|
|
||||||
public resolver: ISftpSessionResolver;
|
public resolver: ISftpSessionResolver;
|
||||||
|
|
||||||
|
private showHiddenFile: boolean;
|
||||||
|
|
||||||
private readonly channel: ITerminalChannel;
|
private readonly channel: ITerminalChannel;
|
||||||
|
|
||||||
constructor(hostId: number,
|
constructor(hostId: number,
|
||||||
@@ -21,6 +23,7 @@ export default class SftpSession implements ISftpSession {
|
|||||||
this.sessionId = sessionId;
|
this.sessionId = sessionId;
|
||||||
this.channel = channel;
|
this.channel = channel;
|
||||||
this.connected = false;
|
this.connected = false;
|
||||||
|
this.showHiddenFile = false;
|
||||||
this.resolver = undefined as unknown as ISftpSessionResolver;
|
this.resolver = undefined as unknown as ISftpSessionResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,10 +39,16 @@ export default class SftpSession implements ISftpSession {
|
|||||||
this.resolver.connectCallback();
|
this.resolver.connectCallback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 设置显示隐藏文件
|
||||||
|
setShowHiddenFile(show: boolean): void {
|
||||||
|
this.showHiddenFile = show;
|
||||||
|
}
|
||||||
|
|
||||||
// 查询文件列表
|
// 查询文件列表
|
||||||
list(path: string | undefined) {
|
list(path: string | undefined) {
|
||||||
this.channel.send(InputProtocol.SFTP_LIST, {
|
this.channel.send(InputProtocol.SFTP_LIST, {
|
||||||
sessionId: this.sessionId,
|
sessionId: this.sessionId,
|
||||||
|
showHiddenFile: ~~this.showHiddenFile,
|
||||||
path
|
path
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ export const InputProtocol = {
|
|||||||
// SFTP 文件列表
|
// SFTP 文件列表
|
||||||
SFTP_LIST: {
|
SFTP_LIST: {
|
||||||
type: 'ls',
|
type: 'ls',
|
||||||
template: ['type', 'sessionId', 'path']
|
template: ['type', 'sessionId', 'showHiddenFile', 'path']
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -295,6 +295,8 @@ export interface ISftpSession extends ITerminalSession {
|
|||||||
|
|
||||||
// 初始化
|
// 初始化
|
||||||
init: (resolver: ISftpSessionResolver) => void;
|
init: (resolver: ISftpSessionResolver) => void;
|
||||||
|
// 设置显示隐藏文件
|
||||||
|
setShowHiddenFile: (show: boolean) => void;
|
||||||
// 查询文件列表
|
// 查询文件列表
|
||||||
list: (path: string | undefined) => void;
|
list: (path: string | undefined) => void;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user