1
0
mirror of https://github.com/1Panel-dev/1Panel.git synced 2025-02-09 10:00:06 +08:00

341 lines
11 KiB
Vue
Raw Normal View History

2022-08-17 17:46:49 +08:00
<template>
2022-08-30 17:59:59 +08:00
<LayoutContent>
2022-08-19 16:02:58 +08:00
<el-row :gutter="20">
2022-08-24 17:34:21 +08:00
<el-col :span="5">
<el-scrollbar height="800px">
<el-tree
:data="fileTree"
:props="defaultProps"
:load="loadNode"
lazy
v-loading="treeLoading"
node-key="id"
:default-expanded-keys="expandKeys"
2022-08-25 18:48:03 +08:00
@node-click="clickNode"
2022-08-24 17:34:21 +08:00
>
<template #default="{ node }">
<el-icon v-if="node.expanded"><FolderOpened /></el-icon>
<el-icon v-else><Folder /></el-icon>
<span class="custom-tree-node">
<span>{{ node.data.name }}</span>
</span>
</template>
</el-tree>
</el-scrollbar>
2022-08-19 16:02:58 +08:00
</el-col>
2022-08-24 17:34:21 +08:00
<el-col :span="19">
2022-08-19 16:02:58 +08:00
<div class="path">
<BreadCrumbs>
<BreadCrumbItem @click="jump(-1)" :right="paths.length == 0">root</BreadCrumbItem>
<BreadCrumbItem
v-for="(item, key) in paths"
:key="key"
@click="jump(key)"
:right="key == paths.length - 1"
>{{ item }}</BreadCrumbItem
>
</BreadCrumbs>
2022-08-19 16:02:58 +08:00
</div>
2022-08-24 11:10:50 +08:00
<ComplexTable
:pagination-config="paginationConfig"
v-model:selects="selects"
:data="data"
2022-08-24 17:34:21 +08:00
v-loading="loading"
2022-08-24 11:10:50 +08:00
>
2022-08-19 16:02:58 +08:00
<template #toolbar>
2022-08-25 17:54:52 +08:00
<el-dropdown split-button type="primary" @command="handleCreate">
2022-08-19 16:02:58 +08:00
{{ $t('commons.button.create') }}
<template #dropdown>
<el-dropdown-menu>
2022-08-25 17:54:52 +08:00
<el-dropdown-item command="dir">
2022-08-19 16:02:58 +08:00
<svg-icon iconName="p-file-folder"></svg-icon>{{ $t('file.dir') }}
</el-dropdown-item>
2022-08-25 17:54:52 +08:00
<el-dropdown-item command="file">
2022-08-19 16:02:58 +08:00
<svg-icon iconName="p-file-normal"></svg-icon>{{ $t('file.file') }}
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
<el-button type="primary" plain> {{ $t('file.upload') }}</el-button>
<el-button type="primary" plain> {{ $t('file.search') }}</el-button>
<el-button type="primary" plain> {{ $t('file.remoteFile') }}</el-button>
<el-button type="primary" plain> {{ $t('file.sync') }}</el-button>
<el-button type="primary" plain> {{ $t('file.terminal') }}</el-button>
<el-button type="primary" plain> {{ $t('file.shareList') }}</el-button>
</template>
<el-table-column :label="$t('commons.table.name')" min-width="250" fix show-overflow-tooltip>
2022-08-19 16:02:58 +08:00
<template #default="{ row }">
<svg-icon v-if="row.isDir" className="table-icon" iconName="p-file-folder"></svg-icon>
<svg-icon v-else className="table-icon" iconName="p-file-normal"></svg-icon>
<el-link :underline="false" @click="open(row)">{{ row.name }}</el-link>
<span v-if="row.isSymlink"> -> {{ row.linkPath }}</span>
2022-08-19 16:02:58 +08:00
</template>
</el-table-column>
<el-table-column :label="$t('file.mode')" prop="mode">
<template #default="{ row }">
<el-link :underline="false" @click="openMode(row)">{{ row.mode }}</el-link>
</template>
</el-table-column>
2022-08-24 11:10:50 +08:00
<el-table-column :label="$t('file.user')" prop="user"> </el-table-column>
<el-table-column :label="$t('file.group')" prop="group"> </el-table-column>
2022-08-19 16:02:58 +08:00
<el-table-column :label="$t('file.size')" prop="size"> </el-table-column>
2022-08-24 11:10:50 +08:00
<el-table-column
:label="$t('file.updateTime')"
prop="modTime"
:formatter="dateFromat"
2022-08-25 18:48:03 +08:00
min-width="100"
2022-08-24 11:10:50 +08:00
>
2022-08-19 16:02:58 +08:00
</el-table-column>
<fu-table-operations
2022-08-24 11:10:50 +08:00
:ellipsis="1"
2022-08-19 16:02:58 +08:00
:buttons="buttons"
:label="$t('commons.table.operate')"
fixed="right"
fix
/>
</ComplexTable>
</el-col>
2022-08-31 13:59:02 +08:00
<CreateFile :open="filePage.open" :file="filePage.createForm" @close="closeCreate"></CreateFile>
<ChangeRole :open="modePage.open" :file="modePage.modeForm" @close="closeMode"></ChangeRole>
2022-08-30 17:59:59 +08:00
<Compress
:open="compressPage.open"
:files="compressPage.files"
:dst="compressPage.dst"
:name="compressPage.name"
@close="closeCompress"
></Compress>
2022-08-31 13:59:02 +08:00
<Decompress
:open="deCompressPage.open"
:dst="deCompressPage.dst"
:path="deCompressPage.path"
:name="deCompressPage.name"
:mimeType="deCompressPage.mimeType"
@close="closeDeCompress"
></Decompress>
2022-08-19 16:02:58 +08:00
</el-row>
</LayoutContent>
2022-08-17 17:46:49 +08:00
</template>
2022-08-19 16:02:58 +08:00
<script setup lang="ts">
2022-08-25 18:48:03 +08:00
import { onMounted, reactive, ref } from '@vue/runtime-core';
2022-08-19 16:02:58 +08:00
import LayoutContent from '@/layout/layout-content.vue';
import ComplexTable from '@/components/complex-table/index.vue';
import i18n from '@/lang';
2022-08-25 18:48:03 +08:00
import { GetFilesList, GetFilesTree, DeleteFile } from '@/api/modules/files';
2022-08-19 16:02:58 +08:00
import { dateFromat } from '@/utils/util';
2022-08-24 11:10:50 +08:00
import { File } from '@/api/interface/file';
import BreadCrumbs from '@/components/bread-crumbs/index.vue';
import BreadCrumbItem from '@/components/bread-crumbs/bread-crumbs-item.vue';
2022-08-31 13:59:02 +08:00
import CreateFile from './create/index.vue';
import ChangeRole from './change-role/index.vue';
import Compress from './compress/index.vue';
import Decompress from './decompress/index.vue';
2022-08-25 18:48:03 +08:00
import { useDeleteData } from '@/hooks/use-delete-data';
2022-08-24 17:34:21 +08:00
2022-08-19 16:02:58 +08:00
let data = ref();
let selects = ref<any>([]);
2022-08-24 11:10:50 +08:00
let req = reactive({ path: '/', expand: true });
2022-08-30 17:59:59 +08:00
let loading = ref(false);
let treeLoading = ref(false);
2022-08-24 11:10:50 +08:00
let paths = ref<string[]>([]);
2022-08-24 17:34:21 +08:00
let fileTree = ref<File.FileTree[]>([]);
let expandKeys = ref<string[]>([]);
2022-08-24 17:34:21 +08:00
2022-08-31 13:59:02 +08:00
let filePage = reactive({ open: false, createForm: { path: '/', isDir: false, mode: 0o755 } });
let modePage = reactive({ open: false, modeForm: { path: '/', isDir: false, mode: 0o755 } });
2022-08-30 17:59:59 +08:00
let compressPage = reactive({ open: false, files: [''], name: '', dst: '' });
2022-08-31 13:59:02 +08:00
let deCompressPage = reactive({ open: false, path: '', name: '', dst: '', mimeType: '' });
2022-08-30 17:59:59 +08:00
2022-08-24 17:34:21 +08:00
const defaultProps = {
children: 'children',
label: 'name',
id: 'id',
2022-08-24 17:34:21 +08:00
};
2022-08-19 16:02:58 +08:00
const paginationConfig = reactive({
page: 1,
pageSize: 5,
total: 0,
});
2022-08-24 17:34:21 +08:00
const search = async (req: File.ReqFile) => {
2022-08-24 11:10:50 +08:00
loading.value = true;
2022-08-24 17:34:21 +08:00
await GetFilesList(req)
2022-08-24 11:10:50 +08:00
.then((res) => {
data.value = res.data.items;
req.path = res.data.path;
const pathArray = req.path.split('/');
paths.value = [];
for (const p of pathArray) {
if (p != '') {
paths.value.push(p);
}
}
2022-08-24 11:10:50 +08:00
})
.finally(() => {
loading.value = false;
});
};
const open = async (row: File.File) => {
if (row.isDir) {
const name = row.name;
paths.value.push(name);
if (req.path === '/') {
req.path = req.path + name;
} else {
req.path = req.path + '/' + name;
}
search(req);
2022-08-24 11:10:50 +08:00
}
};
const jump = async (index: number) => {
let path = '/';
if (index != -1) {
const jPaths = paths.value.slice(0, index + 1);
for (let i in jPaths) {
path = path + '/' + jPaths[i];
}
}
req.path = path;
search(req);
2022-08-19 16:02:58 +08:00
};
2022-08-24 17:34:21 +08:00
const getTree = async (req: File.ReqFile, node: File.FileTree | null) => {
treeLoading.value = true;
await GetFilesTree(req)
.then((res) => {
if (node) {
if (res.data.length > 0) {
node.children = res.data[0].children;
}
} else {
fileTree.value = res.data;
expandKeys.value = [];
expandKeys.value.push(fileTree.value[0].id);
2022-08-24 17:34:21 +08:00
}
})
.finally(() => {
treeLoading.value = false;
});
};
2022-08-19 16:02:58 +08:00
2022-08-25 18:48:03 +08:00
const clickNode = async (node: any) => {
if (node.path) {
req.path = node.path;
search(req);
}
};
2022-08-24 17:34:21 +08:00
const loadNode = (node: any, resolve: (data: File.FileTree[]) => void) => {
if (!node.hasChildNodes) {
if (node.data.path) {
req.path = node.data.path;
getTree(req, node.data);
} else {
getTree(req, null);
}
}
resolve([]);
};
2022-08-25 17:54:52 +08:00
const handleCreate = (commnad: string) => {
2022-08-31 13:59:02 +08:00
filePage.createForm.path = req.path;
filePage.createForm.isDir = false;
2022-08-25 17:54:52 +08:00
if (commnad === 'dir') {
2022-08-31 13:59:02 +08:00
filePage.createForm.isDir = true;
2022-08-25 17:54:52 +08:00
}
2022-08-31 13:59:02 +08:00
filePage.open = true;
2022-08-25 17:54:52 +08:00
};
2022-08-25 18:48:03 +08:00
const delFile = async (row: File.File | null) => {
await useDeleteData(DeleteFile, row as File.FileDelete, 'commons.msg.delete', loading.value);
2022-08-25 18:48:03 +08:00
search(req);
};
const closeCreate = () => {
2022-08-31 13:59:02 +08:00
filePage.open = false;
2022-08-25 17:54:52 +08:00
search(req);
};
const openMode = (item: File.File) => {
2022-08-31 13:59:02 +08:00
modePage.modeForm = item;
modePage.open = true;
};
const closeMode = () => {
2022-08-31 13:59:02 +08:00
modePage.open = false;
search(req);
};
2022-08-30 17:59:59 +08:00
const openCompress = (item: File.File) => {
compressPage.open = true;
compressPage.files = [item.path];
compressPage.name = item.name;
compressPage.dst = req.path;
};
const closeCompress = () => {
compressPage.open = false;
search(req);
};
2022-08-31 13:59:02 +08:00
const openDeCompress = (item: File.File) => {
deCompressPage.open = true;
deCompressPage.name = item.name;
deCompressPage.path = item.path;
deCompressPage.dst = req.path;
deCompressPage.mimeType = item.mimeType;
};
const closeDeCompress = () => {
deCompressPage.open = false;
search(req);
};
2022-08-25 18:48:03 +08:00
onMounted(() => {
search(req);
});
2022-08-31 13:59:02 +08:00
//TODO button增加v-if判断
//openDeCompress 增加是否可以解压判断
const buttons = [
{
label: i18n.global.t('file.open'),
click: open,
},
{
label: i18n.global.t('file.mode'),
click: openMode,
},
{
2022-08-31 13:59:02 +08:00
label: i18n.global.t('file.compress'),
2022-08-30 17:59:59 +08:00
click: openCompress,
},
2022-08-31 13:59:02 +08:00
{
label: i18n.global.t('file.deCompress'),
click: openDeCompress,
},
{
label: i18n.global.t('file.rename'),
},
{
label: i18n.global.t('commons.button.delete'),
2022-08-25 18:48:03 +08:00
click: delFile,
},
{
label: i18n.global.t('file.info'),
},
];
2022-08-19 16:02:58 +08:00
</script>
<style>
.path {
height: 30px;
margin-bottom: 5px;
}
</style>