mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-03-14 01:34:47 +08:00
feat: 优化文件复制粘贴逻辑 (#796)
This commit is contained in:
parent
4377575206
commit
6e3923d0da
30
frontend/package-lock.json
generated
30
frontend/package-lock.json
generated
@ -18,7 +18,7 @@
|
|||||||
"echarts": "^5.3.0",
|
"echarts": "^5.3.0",
|
||||||
"echarts-liquidfill": "^3.1.0",
|
"echarts-liquidfill": "^3.1.0",
|
||||||
"element-plus": "^2.2.32",
|
"element-plus": "^2.2.32",
|
||||||
"fit2cloud-ui-plus": "^1.0.4",
|
"fit2cloud-ui-plus": "^1.0.7",
|
||||||
"js-base64": "^3.7.2",
|
"js-base64": "^3.7.2",
|
||||||
"js-md5": "^0.7.3",
|
"js-md5": "^0.7.3",
|
||||||
"md-editor-v3": "^2.7.2",
|
"md-editor-v3": "^2.7.2",
|
||||||
@ -4315,9 +4315,9 @@
|
|||||||
"integrity": "sha512-g6RQ9zCOV+U5QVHW9OpFR7rdk/V7xfopNXnyAamdpFgCHgZ1sjI8VuR1+zG2YG/TZk+tQ8mpNkug4P8FU0fuOA=="
|
"integrity": "sha512-g6RQ9zCOV+U5QVHW9OpFR7rdk/V7xfopNXnyAamdpFgCHgZ1sjI8VuR1+zG2YG/TZk+tQ8mpNkug4P8FU0fuOA=="
|
||||||
},
|
},
|
||||||
"node_modules/element-plus": {
|
"node_modules/element-plus": {
|
||||||
"version": "2.2.32",
|
"version": "2.3.4",
|
||||||
"resolved": "https://registry.npmmirror.com/element-plus/-/element-plus-2.2.32.tgz",
|
"resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.3.4.tgz",
|
||||||
"integrity": "sha512-DTJMhYOy6MApbmh6z/95hPTK5WrBiNHGzV4IN+uEkup1WoimQ+Qyt8RxKdTe/X1LWEJ8YgWv/Cl8P4ocrt5z5g==",
|
"integrity": "sha512-SQr0J9z7N4z48WYk/l9NE2tizl8Q7j2OhqlpTc42k4pGncry3+rVX6dsmcsglFynn6vt3NzYxWJqmLFyDKQq+g==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ctrl/tinycolor": "^3.4.1",
|
"@ctrl/tinycolor": "^3.4.1",
|
||||||
"@element-plus/icons-vue": "^2.0.6",
|
"@element-plus/icons-vue": "^2.0.6",
|
||||||
@ -5380,12 +5380,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/fit2cloud-ui-plus": {
|
"node_modules/fit2cloud-ui-plus": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/fit2cloud-ui-plus/-/fit2cloud-ui-plus-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/fit2cloud-ui-plus/-/fit2cloud-ui-plus-1.0.7.tgz",
|
||||||
"integrity": "sha512-TDalWK0mfVIiaLLLsdUUukJVDklDPYVGVqAZPUu++tSpfJ9Q35isVVsk4U26G/Lxh00wVM0gTIZiQ3sSOGbGqA==",
|
"integrity": "sha512-BdoFwaFFk0QTWVrNklqWCNV80ow4edqAdPVSbCuZwLD2ZTwqKkNX3RBhOtTItwxKKC7k9j3Ww1049EU+QDgXUA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@element-plus/icons-vue": "^1.1.4",
|
"@element-plus/icons-vue": "^1.1.4",
|
||||||
"element-plus": "^2.2.14",
|
"element-plus": "^2.3.3",
|
||||||
"github-markdown-css": "^5.1.0",
|
"github-markdown-css": "^5.1.0",
|
||||||
"prism-theme-vars": "^0.2.3",
|
"prism-theme-vars": "^0.2.3",
|
||||||
"prismjs": "^1.28.0",
|
"prismjs": "^1.28.0",
|
||||||
@ -14140,9 +14140,9 @@
|
|||||||
"integrity": "sha512-g6RQ9zCOV+U5QVHW9OpFR7rdk/V7xfopNXnyAamdpFgCHgZ1sjI8VuR1+zG2YG/TZk+tQ8mpNkug4P8FU0fuOA=="
|
"integrity": "sha512-g6RQ9zCOV+U5QVHW9OpFR7rdk/V7xfopNXnyAamdpFgCHgZ1sjI8VuR1+zG2YG/TZk+tQ8mpNkug4P8FU0fuOA=="
|
||||||
},
|
},
|
||||||
"element-plus": {
|
"element-plus": {
|
||||||
"version": "2.2.32",
|
"version": "2.3.4",
|
||||||
"resolved": "https://registry.npmmirror.com/element-plus/-/element-plus-2.2.32.tgz",
|
"resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.3.4.tgz",
|
||||||
"integrity": "sha512-DTJMhYOy6MApbmh6z/95hPTK5WrBiNHGzV4IN+uEkup1WoimQ+Qyt8RxKdTe/X1LWEJ8YgWv/Cl8P4ocrt5z5g==",
|
"integrity": "sha512-SQr0J9z7N4z48WYk/l9NE2tizl8Q7j2OhqlpTc42k4pGncry3+rVX6dsmcsglFynn6vt3NzYxWJqmLFyDKQq+g==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ctrl/tinycolor": "^3.4.1",
|
"@ctrl/tinycolor": "^3.4.1",
|
||||||
"@element-plus/icons-vue": "^2.0.6",
|
"@element-plus/icons-vue": "^2.0.6",
|
||||||
@ -14837,12 +14837,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fit2cloud-ui-plus": {
|
"fit2cloud-ui-plus": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/fit2cloud-ui-plus/-/fit2cloud-ui-plus-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/fit2cloud-ui-plus/-/fit2cloud-ui-plus-1.0.7.tgz",
|
||||||
"integrity": "sha512-TDalWK0mfVIiaLLLsdUUukJVDklDPYVGVqAZPUu++tSpfJ9Q35isVVsk4U26G/Lxh00wVM0gTIZiQ3sSOGbGqA==",
|
"integrity": "sha512-BdoFwaFFk0QTWVrNklqWCNV80ow4edqAdPVSbCuZwLD2ZTwqKkNX3RBhOtTItwxKKC7k9j3Ww1049EU+QDgXUA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@element-plus/icons-vue": "^1.1.4",
|
"@element-plus/icons-vue": "^1.1.4",
|
||||||
"element-plus": "^2.2.14",
|
"element-plus": "^2.3.3",
|
||||||
"github-markdown-css": "^5.1.0",
|
"github-markdown-css": "^5.1.0",
|
||||||
"prism-theme-vars": "^0.2.3",
|
"prism-theme-vars": "^0.2.3",
|
||||||
"prismjs": "^1.28.0",
|
"prismjs": "^1.28.0",
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
"echarts": "^5.3.0",
|
"echarts": "^5.3.0",
|
||||||
"echarts-liquidfill": "^3.1.0",
|
"echarts-liquidfill": "^3.1.0",
|
||||||
"element-plus": "^2.2.32",
|
"element-plus": "^2.2.32",
|
||||||
"fit2cloud-ui-plus": "^1.0.4",
|
"fit2cloud-ui-plus": "^1.0.7",
|
||||||
"js-base64": "^3.7.2",
|
"js-base64": "^3.7.2",
|
||||||
"js-md5": "^0.7.3",
|
"js-md5": "^0.7.3",
|
||||||
"md-editor-v3": "^2.7.2",
|
"md-editor-v3": "^2.7.2",
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div class="complex-table__body">
|
<div class="complex-table__body">
|
||||||
<fu-table v-bind="$attrs" @selection-change="handleSelectionChange">
|
<fu-table v-bind="$attrs" ref="tableRef" @selection-change="handleSelectionChange">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</fu-table>
|
</fu-table>
|
||||||
</div>
|
</div>
|
||||||
@ -52,6 +52,7 @@ defineProps({
|
|||||||
});
|
});
|
||||||
const emit = defineEmits(['search', 'update:selects']);
|
const emit = defineEmits(['search', 'update:selects']);
|
||||||
const condition = ref({});
|
const condition = ref({});
|
||||||
|
const tableRef = ref();
|
||||||
function search(conditions: any, e: any) {
|
function search(conditions: any, e: any) {
|
||||||
if (conditions) {
|
if (conditions) {
|
||||||
condition.value = conditions;
|
condition.value = conditions;
|
||||||
@ -62,6 +63,13 @@ function search(conditions: any, e: any) {
|
|||||||
function handleSelectionChange(row: any) {
|
function handleSelectionChange(row: any) {
|
||||||
emit('update:selects', row);
|
emit('update:selects', row);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function clearSelects() {
|
||||||
|
tableRef.value.refElTable.clearSelection();
|
||||||
|
}
|
||||||
|
defineExpose({
|
||||||
|
clearSelects,
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
@ -798,6 +798,8 @@ const message = {
|
|||||||
language: 'Language',
|
language: 'Language',
|
||||||
eol: 'End Of Line',
|
eol: 'End Of Line',
|
||||||
copyDir: 'Copy Dir',
|
copyDir: 'Copy Dir',
|
||||||
|
paste: 'Paste',
|
||||||
|
cancel: 'Cancel',
|
||||||
},
|
},
|
||||||
setting: {
|
setting: {
|
||||||
all: 'All',
|
all: 'All',
|
||||||
|
@ -805,6 +805,8 @@ const message = {
|
|||||||
language: '语言',
|
language: '语言',
|
||||||
eol: '行尾符',
|
eol: '行尾符',
|
||||||
copyDir: '复制路径',
|
copyDir: '复制路径',
|
||||||
|
paste: '粘贴',
|
||||||
|
cancel: '取消',
|
||||||
},
|
},
|
||||||
setting: {
|
setting: {
|
||||||
all: '全部',
|
all: '全部',
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
<el-dropdown @command="handleCreate">
|
<el-dropdown @command="handleCreate">
|
||||||
<el-button type="primary">
|
<el-button type="primary">
|
||||||
{{ $t('commons.button.create') }}
|
{{ $t('commons.button.create') }}
|
||||||
<el-icon class="el-icon--right"><arrow-down /></el-icon>
|
<el-icon><arrow-down /></el-icon>
|
||||||
</el-button>
|
</el-button>
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu>
|
<el-dropdown-menu>
|
||||||
@ -74,6 +74,16 @@
|
|||||||
{{ $t('commons.button.delete') }}
|
{{ $t('commons.button.delete') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-button-group>
|
</el-button-group>
|
||||||
|
<el-button-group class="copy-button" v-if="moveOpen">
|
||||||
|
<el-tooltip class="box-item" effect="dark" :content="$t('file.paste')" placement="bottom">
|
||||||
|
<el-button plain @click="openPaste">{{ $t('file.paste') }}</el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip class="box-item" effect="dark" :content="$t('file.cancel')" placement="bottom">
|
||||||
|
<el-button plain class="close" @click="closeMove">
|
||||||
|
<el-icon class="close-icon"><Close /></el-icon>
|
||||||
|
</el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
</el-button-group>
|
||||||
<div class="search search-button">
|
<div class="search search-button">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="req.search"
|
v-model="req.search"
|
||||||
@ -95,6 +105,7 @@
|
|||||||
<ComplexTable
|
<ComplexTable
|
||||||
:pagination-config="paginationConfig"
|
:pagination-config="paginationConfig"
|
||||||
v-model:selects="selects"
|
v-model:selects="selects"
|
||||||
|
ref="tableRef"
|
||||||
:data="data"
|
:data="data"
|
||||||
@search="search"
|
@search="search"
|
||||||
>
|
>
|
||||||
@ -153,7 +164,7 @@
|
|||||||
<FileRename ref="renameRef" @close="search" />
|
<FileRename ref="renameRef" @close="search" />
|
||||||
<Upload ref="uploadRef" @close="search" />
|
<Upload ref="uploadRef" @close="search" />
|
||||||
<Wget ref="wgetRef" @close="closeWget" />
|
<Wget ref="wgetRef" @close="closeWget" />
|
||||||
<Move ref="moveRef" @close="search" />
|
<Move ref="moveRef" @close="closeMovePage" />
|
||||||
<Download ref="downloadRef" @close="search" />
|
<Download ref="downloadRef" @close="search" />
|
||||||
<Process :open="processPage.open" @close="closeProcess" />
|
<Process :open="processPage.open" @close="closeProcess" />
|
||||||
<!-- <Detail ref="detailRef" /> -->
|
<!-- <Detail ref="detailRef" /> -->
|
||||||
@ -197,6 +208,7 @@ interface FilePaths {
|
|||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const data = ref();
|
const data = ref();
|
||||||
|
const tableRef = ref();
|
||||||
let selects = ref<any>([]);
|
let selects = ref<any>([]);
|
||||||
|
|
||||||
// origin data
|
// origin data
|
||||||
@ -222,7 +234,7 @@ const codeReq = reactive({ path: '', expand: false, page: 1, pageSize: 100 });
|
|||||||
const fileUpload = reactive({ path: '' });
|
const fileUpload = reactive({ path: '' });
|
||||||
const fileRename = reactive({ path: '', oldName: '' });
|
const fileRename = reactive({ path: '', oldName: '' });
|
||||||
const fileWget = reactive({ path: '' });
|
const fileWget = reactive({ path: '' });
|
||||||
const fileMove = reactive({ oldPaths: [''], type: '' });
|
const fileMove = reactive({ oldPaths: [''], type: '', path: '' });
|
||||||
const fileDownload = reactive({ paths: [''], name: '' });
|
const fileDownload = reactive({ paths: [''], name: '' });
|
||||||
const processPage = reactive({ open: false });
|
const processPage = reactive({ open: false });
|
||||||
|
|
||||||
@ -240,6 +252,8 @@ const downloadRef = ref();
|
|||||||
const pathRef = ref();
|
const pathRef = ref();
|
||||||
const breadCrumbRef = ref();
|
const breadCrumbRef = ref();
|
||||||
|
|
||||||
|
const moveOpen = ref(false);
|
||||||
|
|
||||||
// editablePath
|
// editablePath
|
||||||
const { searchableStatus, searchablePath, searchableInputRef, searchableInputBlur } = useSearchable(paths);
|
const { searchableStatus, searchablePath, searchableInputRef, searchableInputBlur } = useSearchable(paths);
|
||||||
|
|
||||||
@ -500,6 +514,13 @@ const closeWget = (submit: Boolean) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const closeMovePage = (submit: Boolean) => {
|
||||||
|
if (submit) {
|
||||||
|
search();
|
||||||
|
closeMove();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const openProcess = () => {
|
const openProcess = () => {
|
||||||
processPage.open = true;
|
processPage.open = true;
|
||||||
};
|
};
|
||||||
@ -521,6 +542,18 @@ const openMove = (type: string) => {
|
|||||||
oldpaths.push(s['path']);
|
oldpaths.push(s['path']);
|
||||||
}
|
}
|
||||||
fileMove.oldPaths = oldpaths;
|
fileMove.oldPaths = oldpaths;
|
||||||
|
moveOpen.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeMove = () => {
|
||||||
|
selects.value = [];
|
||||||
|
tableRef.value.clearSelects();
|
||||||
|
fileMove.oldPaths = [];
|
||||||
|
moveOpen.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const openPaste = () => {
|
||||||
|
fileMove.path = req.path;
|
||||||
moveRef.value.acceptParams(fileMove);
|
moveRef.value.acceptParams(fileMove);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -635,4 +668,14 @@ onMounted(() => {
|
|||||||
display: inline;
|
display: inline;
|
||||||
width: 20%;
|
width: 20%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.copy-button {
|
||||||
|
margin-left: 10px;
|
||||||
|
.close {
|
||||||
|
width: 10px;
|
||||||
|
.close-icon {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,11 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-drawer
|
<el-drawer v-model="open" :destroy-on-close="true" :close-on-click-modal="false" size="40%">
|
||||||
v-model="open"
|
|
||||||
:destroy-on-close="true"
|
|
||||||
:close-on-click-modal="false"
|
|
||||||
:before-close="handleClose"
|
|
||||||
size="40%"
|
|
||||||
>
|
|
||||||
<template #header>
|
<template #header>
|
||||||
<DrawerHeader :header="title" :back="handleClose" />
|
<DrawerHeader :header="title" :back="handleClose" />
|
||||||
</template>
|
</template>
|
||||||
@ -29,7 +23,7 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
<el-button @click="handleClose" :disabled="loading">{{ $t('commons.button.cancel') }}</el-button>
|
<el-button @click="handleClose(false)" :disabled="loading">{{ $t('commons.button.cancel') }}</el-button>
|
||||||
<el-button type="primary" @click="submit(fileForm)" :disabled="loading">
|
<el-button type="primary" @click="submit(fileForm)" :disabled="loading">
|
||||||
{{ $t('commons.button.confirm') }}
|
{{ $t('commons.button.confirm') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
@ -51,6 +45,7 @@ import { MsgSuccess } from '@/utils/message';
|
|||||||
interface MoveProps {
|
interface MoveProps {
|
||||||
oldPaths: Array<string>;
|
oldPaths: Array<string>;
|
||||||
type: string;
|
type: string;
|
||||||
|
path: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const fileForm = ref<FormInstance>();
|
const fileForm = ref<FormInstance>();
|
||||||
@ -78,12 +73,12 @@ const rules = reactive<FormRules>({
|
|||||||
|
|
||||||
const em = defineEmits(['close']);
|
const em = defineEmits(['close']);
|
||||||
|
|
||||||
const handleClose = () => {
|
const handleClose = (search: boolean) => {
|
||||||
open.value = false;
|
open.value = false;
|
||||||
if (fileForm.value) {
|
if (fileForm.value) {
|
||||||
fileForm.value.resetFields();
|
fileForm.value.resetFields();
|
||||||
}
|
}
|
||||||
em('close', open);
|
em('close', search);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getPath = (path: string) => {
|
const getPath = (path: string) => {
|
||||||
@ -104,8 +99,7 @@ const submit = async (formEl: FormInstance | undefined) => {
|
|||||||
} else {
|
} else {
|
||||||
MsgSuccess(i18n.global.t('file.copySuccess'));
|
MsgSuccess(i18n.global.t('file.copySuccess'));
|
||||||
}
|
}
|
||||||
|
handleClose(true);
|
||||||
handleClose();
|
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
@ -116,6 +110,7 @@ const submit = async (formEl: FormInstance | undefined) => {
|
|||||||
const acceptParams = (props: MoveProps) => {
|
const acceptParams = (props: MoveProps) => {
|
||||||
addForm.oldPaths = props.oldPaths;
|
addForm.oldPaths = props.oldPaths;
|
||||||
addForm.type = props.type;
|
addForm.type = props.type;
|
||||||
|
addForm.newPath = props.path;
|
||||||
type.value = props.type;
|
type.value = props.type;
|
||||||
open.value = true;
|
open.value = true;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user