feat: 增加文件解压功能

This commit is contained in:
zhengkunwang223 2022-08-31 13:59:02 +08:00
parent 20129c7d0b
commit 245f5fb68a
13 changed files with 210 additions and 21 deletions

View file

@ -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)
}

View file

@ -38,3 +38,9 @@ type FileCompress struct {
Name string
Replace bool
}
type FileDeCompress struct {
Dst string
Type string
Path string
}

View file

@ -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)

View file

@ -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)
}
}

View file

@ -49,4 +49,10 @@ export namespace File {
name: string;
replace: boolean;
}
export interface FileDeCompress {
path: string;
dst: string;
type: string;
}
}

View file

@ -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);
};

View 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],
]);

View file

@ -33,7 +33,6 @@ export default {
sureLogOut: '您是否确认退出登录?',
createSuccess: '新建成功',
updateSuccess: '更新成功',
compressSuccess: '压缩成功',
},
login: {
captchaHelper: '请输入验证码',
@ -190,5 +189,8 @@ export default {
compressType: '压缩格式',
compressDst: '压缩路径',
replace: '覆盖已存在的文件',
compressSuccess: '压缩成功',
deCompressSuccess: '解压成功',
deCompressDst: '解压路径',
},
};

View file

@ -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(() => {

View 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>

View file

@ -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 buttonv-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'),
},