jcloud/dashboard/src2/components/site/SiteDatabaseRestoreFromURLDialog.vue
2025-04-12 17:39:38 +08:00

156 lines
3.6 KiB
Vue

<template>
<Dialog
:options="{
title: '从现有站点恢复'
}"
v-model="showRestoreDialog"
>
<template #body-content>
<div
class="mb-6 flex items-center rounded border border-gray-200 bg-gray-100 p-4 text-sm text-gray-600"
>
<i-lucide-alert-triangle class="mr-4 inline-block h-6 w-6" />
<div>
此操作将用备份中的<b>数据</b><b>应用</b>替换您站点中的当前内容
</div>
</div>
<div class="space-y-4">
<FormControl label="站点URL" v-model="siteURL" />
<FormControl label="邮箱" v-model="email" />
<FormControl label="密码" type="password" v-model="password" />
<div class="flex text-base" v-if="$resources.getBackupLinks.data">
<GreenCheckIcon class="mr-2 w-4" />
找到来自 {{ fetchedBackupFileTimestamp }} 的最新备份
</div>
<Button
v-else
@click="$resources.getBackupLinks.submit()"
:loading="$resources.getBackupLinks.loading"
>
获取备份
</Button>
</div>
<div class="mt-3">
<FormControl
label="跳过失败的补丁(如果有任何补丁失败)"
type="checkbox"
v-model="skipFailingPatches"
/>
</div>
<ErrorMessage
class="mt-2"
:message="
$resources.restoreBackup.error || $resources.getBackupLinks.error
"
/>
</template>
<template #actions>
<Button
class="w-full"
label="恢复"
variant="solid"
theme="red"
:loading="$resources.restoreBackup.loading"
:disabled="!$resources.getBackupLinks.data"
@click="$resources.restoreBackup.submit"
/>
</template>
</Dialog>
</template>
<script>
import { date } from '../../utils/format';
import { DashboardError } from '../../utils/error';
export default {
name: 'SiteDatabaseRestoreDialog',
props: {
site: {
type: String,
required: true
}
},
data() {
return {
siteURL: '',
email: '',
password: '',
selectedFiles: {
database: null,
public: null,
private: null
},
showRestoreDialog: true,
skipFailingPatches: false
};
},
resources: {
getBackupLinks() {
return {
url: 'jcloud.api.site.get_backup_links',
params: {
url: this.siteURL,
email: this.email,
password: this.password
},
validate() {
if (!this.siteURL) {
throw new DashboardError('站点URL是必填项');
}
if (!this.email) {
throw new DashboardError('邮箱是必填项');
}
if (!this.password) {
throw new DashboardError('密码是必填项');
}
},
onSuccess(remoteFiles) {
for (let file of remoteFiles) {
this.selectedFiles[file.type] = file.remote_file;
}
}
};
},
restoreBackup() {
return {
url: 'jcloud.api.site.restore',
params: {
name: this.site,
files: this.selectedFiles,
skip_failing_patches: this.skipFailingPatches
},
validate() {
if (!this.selectedFiles.database) {
throw new DashboardError(
'从站点获取备份时出错'
);
}
},
onSuccess() {
this.siteURL = '';
this.email = '';
this.password = '';
this.showRestoreDialog = false;
this.$router.push({
name: 'Site Jobs',
params: { name: this.site }
});
}
};
}
},
computed: {
fetchedBackupFileTimestamp() {
if (!this.$resources.getBackupLinks.data) return '';
let backup = this.$resources.getBackupLinks.data[0];
let timestamp_string = backup.file_name
.split('-')[0]
.split('_')
.join('T');
return date(timestamp_string);
}
}
};
</script>