jcloud/dashboard/src2/components/BackupFilesUploader.vue

148 lines
5.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div>
<div class="mt-2 space-y-2">
<FileUploader
v-for="file in files"
:fileTypes="file.ext"
:key="file.type"
:type="file.type"
@success="onFileUpload(file, $event)"
:fileValidator="f => databaseBackupChecker(f, file.type)"
:s3="true"
>
<template
v-slot="{
file: fileObj,
uploading,
progress,
error,
success,
openFileSelector
}"
>
<ListItem
class="border-b"
:title="fileObj ? fileObj.name : file.title"
>
<template #subtitle>
<span
class="text-base"
:class="error ? 'text-red-500' : 'text-gray-600'"
>
{{
uploading
? `上传中 ${progress}%`
: success
? formatBytes(fileObj.size)
: error
? error
: file.description
}}
</span>
</template>
<template #actions>
<Button
:loading="uploading"
loadingText="上传中..."
@click="openFileSelector()"
v-if="!success"
>
上传
</Button>
<GreenCheckIcon class="w-5" v-if="success" />
</template>
</ListItem>
</template>
</FileUploader>
</div>
</div>
</template>
<script>
import FileUploader from './FileUploader.vue';
export default {
name: 'BackupFilesUploader',
components: { FileUploader },
emits: ['update:backupFiles'],
props: ['backupFiles'],
data() {
return {
files: [
{
icon: '<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M5.33325 9.33333V22.6667C5.33325 25.6133 10.1093 28 15.9999 28C21.8906 28 26.6666 25.6133 26.6666 22.6667V9.33333M5.33325 9.33333C5.33325 12.28 10.1093 14.6667 15.9999 14.6667C21.8906 14.6667 26.6666 12.28 26.6666 9.33333M5.33325 9.33333C5.33325 6.38667 10.1093 4 15.9999 4C21.8906 4 26.6666 6.38667 26.6666 9.33333M26.6666 16C26.6666 18.9467 21.8906 21.3333 15.9999 21.3333C10.1093 21.3333 5.33325 18.9467 5.33325 16" stroke="#1F272E" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>',
type: 'database',
ext: 'application/x-gzip,application/sql,.sql',
title: '数据库备份',
description:
'上传数据库备份文件。通常文件名以 .sql.gz 或 .sql 结尾',
file: null
},
{
icon: '<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M9.39111 6.3913H26.3476V22.2174C26.3476 25.9478 23.2955 29 19.565 29H9.39111V6.3913Z" stroke="#1F272E" stroke-width="1.5" stroke-miterlimit="10"/><path d="M13.9131 13.1739H21.8261" stroke="#1F272E" stroke-width="1.5" stroke-miterlimit="10"/><path d="M13.9131 17.6957H21.8261" stroke="#1F272E" stroke-width="1.5" stroke-miterlimit="10"/><path d="M13.9131 22.2173H19.8479" stroke="#1F272E" stroke-width="1.5" stroke-miterlimit="10"/><path d="M22.9565 6.3913V3H6V25.6087H9.3913" stroke="#1F272E" stroke-width="1.5" stroke-miterlimit="10"/></svg>',
type: 'public',
ext: 'application/x-tar',
title: '公共文件',
description:
'上传公共文件备份。通常文件名以 -files.tar 结尾',
file: null
},
{
icon: '<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M8.39111 6.3913H25.3476V22.2174C25.3476 25.9478 22.2955 29 18.565 29H8.39111V6.3913Z" stroke="#1F272E" stroke-width="1.5" stroke-miterlimit="10"/><path d="M21.9565 6.3913V3H5V25.6087H8.3913" stroke="#1F272E" stroke-width="1.5" stroke-miterlimit="10"/></svg>',
type: 'private',
ext: 'application/x-tar',
title: '私有文件',
description:
'上传私有文件备份。通常文件名以 -private-files.tar 结尾',
file: null
},
{
icon: '<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M8.39111 6.3913H25.3476V22.2174C25.3476 25.9478 22.2955 29 18.565 29H8.39111V6.3913Z" stroke="#1F272E" stroke-width="1.5" stroke-miterlimit="10"/><path d="M21.9565 6.3913V3H5V25.6087H8.3913" stroke="#1F272E" stroke-width="1.5" stroke-miterlimit="10"/></svg>',
type: 'config',
ext: 'application/json',
title: '站点配置如备份已加密则必需',
description:
'上传站点配置文件通常文件名以 -site_config_backup.json 结尾',
file: null
}
]
};
},
methods: {
onFileUpload(file, data) {
let backupFiles = Object.assign({}, this.backupFiles);
backupFiles[file.type] = data;
this.$emit('update:backupFiles', backupFiles);
},
async databaseBackupChecker(file, type) {
if (type === 'database') {
// valid strings are "database.sql.gz", "database.sql", "database.sql (1).gz", "database.sql (2).gz"
if (!/\.sql( \(\d\))?\.gz$|\.sql$/.test(file.name)) {
throw new Error(
'数据库备份文件应以"database.sql.gz""database.sql"结尾'
);
}
if (
![
'application/x-gzip',
'application/gzip',
'application/sql'
].includes(file.type)
) {
throw new Error('无效的数据库备份文件');
}
}
if (['public', 'private'].includes(type)) {
if (file.type != 'application/x-tar') {
throw new Error(`无效的${type === 'public' ? '公共' : '私有'}文件备份文件`);
}
}
if (type === 'config') {
if (file.type != 'application/json') {
throw new Error(`无效的站点配置文件`);
}
}
}
}
};
</script>