mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-31 14:08:06 +08:00
feat: 增加文件解压功能
This commit is contained in:
parent
20129c7d0b
commit
245f5fb68a
@ -90,3 +90,17 @@ func (b *BaseApi) CompressFile(c *gin.Context) {
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
func (b *BaseApi) DeCompressFile(c *gin.Context) {
|
||||
var req dto.FileDeCompress
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
err := fileService.DeCompress(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
@ -38,3 +38,9 @@ type FileCompress struct {
|
||||
Name string
|
||||
Replace bool
|
||||
}
|
||||
|
||||
type FileDeCompress struct {
|
||||
Dst string
|
||||
Type string
|
||||
Path string
|
||||
}
|
||||
|
@ -85,6 +85,11 @@ func (f FileService) Compress(c dto.FileCompress) error {
|
||||
return fo.Compress(c.Files, c.Dst, c.Name, files.CompressType(c.Type))
|
||||
}
|
||||
|
||||
func (f FileService) DeCompress(c dto.FileDeCompress) error {
|
||||
fo := files.NewFileOp()
|
||||
return fo.Decompress(c.Path, c.Dst, files.CompressType(c.Type))
|
||||
}
|
||||
|
||||
func getUuid() string {
|
||||
b := make([]byte, 16)
|
||||
io.ReadFull(rand.Reader, b)
|
||||
|
@ -21,6 +21,7 @@ func (f *FileRouter) InitFileRouter(Router *gin.RouterGroup) {
|
||||
fileRouter.POST("/del", baseApi.DeleteFile)
|
||||
fileRouter.POST("/mode", baseApi.ChangeFileMode)
|
||||
fileRouter.POST("/compress", baseApi.CompressFile)
|
||||
fileRouter.POST("/decompress", baseApi.DeCompressFile)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -49,4 +49,10 @@ export namespace File {
|
||||
name: string;
|
||||
replace: boolean;
|
||||
}
|
||||
|
||||
export interface FileDeCompress {
|
||||
path: string;
|
||||
dst: string;
|
||||
type: string;
|
||||
}
|
||||
}
|
||||
|
@ -24,3 +24,6 @@ export const ChangeFileMode = (form: File.FileCreate) => {
|
||||
export const CompressFile = (form: File.FileCompress) => {
|
||||
return http.post<File.FileCompress>('files/compress', form);
|
||||
};
|
||||
export const DeCompressFile = (form: File.FileDeCompress) => {
|
||||
return http.post<File.FileCompress>('files/decompress', form);
|
||||
};
|
||||
|
17
frontend/src/global/mimetype.ts
Normal file
17
frontend/src/global/mimetype.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import { CompressType } from '@/enums/files';
|
||||
|
||||
export const Mimetypes = new Map([
|
||||
['application/zip', CompressType.Zip],
|
||||
['application/x-zip', CompressType.Zip],
|
||||
['application/x-zip-compressed', CompressType.Zip],
|
||||
['application/x-tar', CompressType.Tar],
|
||||
['application/x-bzip2', CompressType.Bz2],
|
||||
['application/gzip', CompressType.TarGz],
|
||||
['application/x-gzip', CompressType.TarGz],
|
||||
['application/x-gunzip', CompressType.TarGz],
|
||||
['application/gzipped', CompressType.TarGz],
|
||||
['application/gzip-compressed', CompressType.TarGz],
|
||||
['application/x-gzip-compressed', CompressType.TarGz],
|
||||
['gzip/document', CompressType.TarGz],
|
||||
['application/x-xz', CompressType.Xz],
|
||||
]);
|
@ -33,7 +33,6 @@ export default {
|
||||
sureLogOut: '您是否确认退出登录?',
|
||||
createSuccess: '新建成功',
|
||||
updateSuccess: '更新成功',
|
||||
compressSuccess: '压缩成功',
|
||||
},
|
||||
login: {
|
||||
captchaHelper: '请输入验证码',
|
||||
@ -190,5 +189,8 @@ export default {
|
||||
compressType: '压缩格式',
|
||||
compressDst: '压缩路径',
|
||||
replace: '覆盖已存在的文件',
|
||||
compressSuccess: '压缩成功',
|
||||
deCompressSuccess: '解压成功',
|
||||
deCompressDst: '解压路径',
|
||||
},
|
||||
};
|
||||
|
@ -110,10 +110,10 @@ const submit = async (formEl: FormInstance | undefined) => {
|
||||
let addItem = {};
|
||||
Object.assign(addItem, form.value);
|
||||
addItem['name'] = form.value.name + extension.value;
|
||||
|
||||
loading.value = true;
|
||||
CompressFile(addItem as File.FileCompress)
|
||||
.then(() => {
|
||||
ElMessage.success(i18n.global.t('commons.msg.compressSuccess'));
|
||||
ElMessage.success(i18n.global.t('file.compressSuccess'));
|
||||
handleClose();
|
||||
})
|
||||
.finally(() => {
|
107
frontend/src/views/file-management/decompress/index.vue
Normal file
107
frontend/src/views/file-management/decompress/index.vue
Normal file
@ -0,0 +1,107 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="open"
|
||||
:title="$t('file.deCompress')"
|
||||
:before-close="handleClose"
|
||||
width="30%"
|
||||
@open="onOpen"
|
||||
v-loading="loading"
|
||||
>
|
||||
<el-form ref="fileForm" label-position="left" :model="form" label-width="100px" :rules="rules">
|
||||
<el-form-item :label="$t('file.name')">
|
||||
<el-input v-model="name" disabled></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('file.deCompressDst')" prop="dst">
|
||||
<el-input v-model="form.dst"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="handleClose">{{ $t('commons.button.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="submit(fileForm)">{{ $t('commons.button.confirm') }}</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import i18n from '@/lang';
|
||||
import { reactive, ref, toRefs } from 'vue';
|
||||
import { File } from '@/api/interface/file';
|
||||
import { ElMessage, FormInstance, FormRules } from 'element-plus';
|
||||
import { Rules } from '@/global/form-rues';
|
||||
import { DeCompressFile } from '@/api/modules/files';
|
||||
import { Mimetypes } from '@/global/mimetype';
|
||||
|
||||
const props = defineProps({
|
||||
open: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
dst: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
path: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
mimeType: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
|
||||
const rules = reactive<FormRules>({
|
||||
dst: [Rules.required],
|
||||
});
|
||||
|
||||
const { open, dst, path, name, mimeType } = toRefs(props);
|
||||
const fileForm = ref<FormInstance>();
|
||||
let loading = ref(false);
|
||||
let form = ref<File.FileDeCompress>({ type: 'zip', dst: '', path: '' });
|
||||
|
||||
const em = defineEmits(['close']);
|
||||
|
||||
const handleClose = () => {
|
||||
em('close', open);
|
||||
};
|
||||
|
||||
const getFileType = (mime: string): string => {
|
||||
if (Mimetypes.get(mime) != undefined) {
|
||||
return String(Mimetypes.get(mime));
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
const onOpen = () => {
|
||||
form.value = {
|
||||
dst: dst.value,
|
||||
type: getFileType(mimeType.value),
|
||||
path: path.value,
|
||||
};
|
||||
};
|
||||
|
||||
const submit = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return;
|
||||
await formEl.validate((valid) => {
|
||||
if (!valid) {
|
||||
return;
|
||||
}
|
||||
loading.value = true;
|
||||
DeCompressFile(form.value)
|
||||
.then(() => {
|
||||
ElMessage.success(i18n.global.t('file.deCompressSuccess'));
|
||||
handleClose();
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
</script>
|
@ -96,8 +96,8 @@
|
||||
/>
|
||||
</ComplexTable>
|
||||
</el-col>
|
||||
<CreateFile :open="openCreate" :file="fileCreate" @close="closeCreate"></CreateFile>
|
||||
<ChangeRole :open="openModePage" :file="modeForm" @close="closeMode"></ChangeRole>
|
||||
<CreateFile :open="filePage.open" :file="filePage.createForm" @close="closeCreate"></CreateFile>
|
||||
<ChangeRole :open="modePage.open" :file="modePage.modeForm" @close="closeMode"></ChangeRole>
|
||||
<Compress
|
||||
:open="compressPage.open"
|
||||
:files="compressPage.files"
|
||||
@ -105,6 +105,14 @@
|
||||
:name="compressPage.name"
|
||||
@close="closeCompress"
|
||||
></Compress>
|
||||
<Decompress
|
||||
:open="deCompressPage.open"
|
||||
:dst="deCompressPage.dst"
|
||||
:path="deCompressPage.path"
|
||||
:name="deCompressPage.name"
|
||||
:mimeType="deCompressPage.mimeType"
|
||||
@close="closeDeCompress"
|
||||
></Decompress>
|
||||
</el-row>
|
||||
</LayoutContent>
|
||||
</template>
|
||||
@ -119,9 +127,10 @@ import { dateFromat } from '@/utils/util';
|
||||
import { File } from '@/api/interface/file';
|
||||
import BreadCrumbs from '@/components/bread-crumbs/index.vue';
|
||||
import BreadCrumbItem from '@/components/bread-crumbs/bread-crumbs-item.vue';
|
||||
import CreateFile from './create.vue';
|
||||
import ChangeRole from './change-role.vue';
|
||||
import Compress from './compress.vue';
|
||||
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';
|
||||
import { useDeleteData } from '@/hooks/use-delete-data';
|
||||
|
||||
let data = ref();
|
||||
@ -132,12 +141,11 @@ let treeLoading = ref(false);
|
||||
let paths = ref<string[]>([]);
|
||||
let fileTree = ref<File.FileTree[]>([]);
|
||||
let expandKeys = ref<string[]>([]);
|
||||
let openCreate = ref(false);
|
||||
let fileCreate = ref<File.FileCreate>({ path: '/', isDir: false, mode: 0o755 });
|
||||
let openModePage = ref(false);
|
||||
let modeForm = ref<File.FileCreate>({ path: '/', isDir: false, mode: 0o755 });
|
||||
|
||||
let filePage = reactive({ open: false, createForm: { path: '/', isDir: false, mode: 0o755 } });
|
||||
let modePage = reactive({ open: false, modeForm: { path: '/', isDir: false, mode: 0o755 } });
|
||||
let compressPage = reactive({ open: false, files: [''], name: '', dst: '' });
|
||||
let deCompressPage = reactive({ open: false, path: '', name: '', dst: '', mimeType: '' });
|
||||
|
||||
const defaultProps = {
|
||||
children: 'children',
|
||||
@ -234,12 +242,12 @@ const loadNode = (node: any, resolve: (data: File.FileTree[]) => void) => {
|
||||
};
|
||||
|
||||
const handleCreate = (commnad: string) => {
|
||||
fileCreate.value.path = req.path;
|
||||
fileCreate.value.isDir = false;
|
||||
filePage.createForm.path = req.path;
|
||||
filePage.createForm.isDir = false;
|
||||
if (commnad === 'dir') {
|
||||
fileCreate.value.isDir = true;
|
||||
filePage.createForm.isDir = true;
|
||||
}
|
||||
openCreate.value = true;
|
||||
filePage.open = true;
|
||||
};
|
||||
|
||||
const delFile = async (row: File.File | null) => {
|
||||
@ -248,17 +256,17 @@ const delFile = async (row: File.File | null) => {
|
||||
};
|
||||
|
||||
const closeCreate = () => {
|
||||
openCreate.value = false;
|
||||
filePage.open = false;
|
||||
search(req);
|
||||
};
|
||||
|
||||
const openMode = (item: File.File) => {
|
||||
modeForm.value = item;
|
||||
openModePage.value = true;
|
||||
modePage.modeForm = item;
|
||||
modePage.open = true;
|
||||
};
|
||||
|
||||
const closeMode = () => {
|
||||
openModePage.value = false;
|
||||
modePage.open = false;
|
||||
search(req);
|
||||
};
|
||||
|
||||
@ -273,10 +281,26 @@ const closeCompress = () => {
|
||||
compressPage.open = false;
|
||||
search(req);
|
||||
};
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
search(req);
|
||||
});
|
||||
|
||||
//TODO button增加v-if判断
|
||||
//openDeCompress 增加是否可以解压判断
|
||||
const buttons = [
|
||||
{
|
||||
label: i18n.global.t('file.open'),
|
||||
@ -287,9 +311,13 @@ const buttons = [
|
||||
click: openMode,
|
||||
},
|
||||
{
|
||||
label: i18n.global.t('file.zip'),
|
||||
label: i18n.global.t('file.compress'),
|
||||
click: openCompress,
|
||||
},
|
||||
{
|
||||
label: i18n.global.t('file.deCompress'),
|
||||
click: openDeCompress,
|
||||
},
|
||||
{
|
||||
label: i18n.global.t('file.rename'),
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user