fix: 应用删除增加强制删除选项

This commit is contained in:
zhengkunwang223 2022-12-21 11:32:52 +08:00 committed by zhengkunwang223
parent 1a06571bec
commit a6239a7359
8 changed files with 137 additions and 18 deletions

View File

@ -35,10 +35,12 @@ type AppBackupDelete struct {
}
type AppInstalledOperate struct {
InstallId uint `json:"installId" validate:"required"`
BackupId uint `json:"backupId"`
DetailId uint `json:"detailId"`
Operate constant.AppOperate `json:"operate" validate:"required"`
InstallId uint `json:"installId" validate:"required"`
BackupId uint `json:"backupId"`
DetailId uint `json:"detailId"`
Operate constant.AppOperate `json:"operate" validate:"required"`
ForceDelete bool `json:"forceDelete"`
DeleteBackup bool `json:"deleteBackup"`
}
type PortUpdate struct {

View File

@ -143,7 +143,7 @@ func (a AppInstallService) Operate(req request.AppInstalledOperate) error {
install.Status = constant.Running
case constant.Delete:
tx, ctx := getTxAndContext()
if err := deleteAppInstall(ctx, install); err != nil {
if err := deleteAppInstall(ctx, install, req.ForceDelete, req.DeleteBackup); err != nil {
tx.Rollback()
return err
}

View File

@ -156,7 +156,7 @@ func createLink(ctx context.Context, app model.App, appInstall *model.AppInstall
return nil
}
func deleteAppInstall(ctx context.Context, install model.AppInstall) error {
func deleteAppInstall(ctx context.Context, install model.AppInstall, forceDelete bool, deleteBackup bool) error {
op := files.NewFileOp()
appDir := install.GetPath()
dir, _ := os.Stat(appDir)
@ -169,19 +169,20 @@ func deleteAppInstall(ctx context.Context, install model.AppInstall) error {
return err
}
}
if err := appInstallRepo.Delete(ctx, install); err != nil {
return err
}
if err := deleteLink(ctx, &install); err != nil {
if err := deleteLink(ctx, &install); err != nil && !forceDelete {
return err
}
backups, _ := appInstallBackupRepo.GetBy(appInstallBackupRepo.WithAppInstallID(install.ID))
for _, backup := range backups {
_ = op.DeleteDir(backup.Path)
}
if err := appInstallBackupRepo.Delete(ctx, appInstallBackupRepo.WithAppInstallID(install.ID)); err != nil {
return err
if deleteBackup {
backups, _ := appInstallBackupRepo.GetBy(appInstallBackupRepo.WithAppInstallID(install.ID))
for _, backup := range backups {
_ = op.DeleteDir(backup.Path)
}
if err := appInstallBackupRepo.Delete(ctx, appInstallBackupRepo.WithAppInstallID(install.ID)); err != nil {
return err
}
}
return nil
}

View File

@ -263,7 +263,7 @@ func (w WebsiteService) DeleteWebsite(req request.WebsiteDelete) error {
return err
}
if !reflect.DeepEqual(model.AppInstall{}, appInstall) {
if err := deleteAppInstall(ctx, appInstall); err != nil {
if err := deleteAppInstall(ctx, appInstall, req.ForceDelete, true); err != nil {
return err
}
}

View File

@ -108,6 +108,8 @@ export namespace App {
operate: string;
backupId?: number;
detailId?: number;
forceDelete?: boolean;
deleteBackup?: boolean;
}
export interface AppInstalledSearch {

View File

@ -789,6 +789,10 @@ export default {
database: '数据库',
defaultConfig: '默认配置',
defaultConfigHelper: '已恢复为默认配置保存后生效',
forceDelete: '强制删除',
forceDeleteHelper: '强制删除会忽略删除过程中碰到的问题最终删除元数据',
deleteBackup: '删除备份',
deleteBackupHelper: '同时删除应用备份',
},
website: {
website: '网站',

View File

@ -0,0 +1,105 @@
<template>
<el-dialog
v-model="open"
:title="$t('commons.button.delete') + ' - ' + appInstallName"
width="30%"
:close-on-click-modal="false"
:before-close="handleClose"
>
<el-form ref="deleteForm" label-position="left">
<el-form-item>
<el-checkbox v-model="deleteReq.forceDelete" :label="$t('app.forceDelete')" />
</el-form-item>
<div class="helper">
<span class="input-help">
{{ $t('app.forceDeleteHelper') }}
</span>
</div>
<el-form-item>
<el-checkbox v-model="deleteReq.deleteBackup" :label="$t('app.deleteBackup')" />
</el-form-item>
<div class="helper">
<span class="input-help">
{{ $t('app.deleteBackupHelper') }}
</span>
</div>
<br />
<span v-html="deleteHelper"></span>
<el-form-item>
<el-input v-model="deleteInfo" :placeholder="appInstallName" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="handleClose" :loading="loading">
{{ $t('commons.button.cancel') }}
</el-button>
<el-button type="primary" @click="submit" :loading="loading" :disabled="deleteInfo != appInstallName">
{{ $t('commons.button.confirm') }}
</el-button>
</span>
</template>
</el-dialog>
</template>
<script lang="ts" setup>
import { ElMessage, FormInstance } from 'element-plus';
import { ref } from 'vue';
import { App } from '@/api/interface/app';
import { InstalledOp } from '@/api/modules/app';
import i18n from '@/lang';
let deleteReq = ref({
operate: 'delete',
installId: 0,
deleteBackup: false,
forceDelete: false,
});
let open = ref(false);
let loading = ref(false);
let deleteHelper = ref('');
let deleteInfo = ref('');
let appInstallName = ref('');
const deleteForm = ref<FormInstance>();
const em = defineEmits(['close']);
const handleClose = () => {
open.value = false;
em('close', open);
};
const acceptParams = async (app: App.AppInstalled) => {
deleteReq.value = {
operate: 'delete',
installId: 0,
deleteBackup: false,
forceDelete: false,
};
deleteReq.value.installId = app.id;
deleteHelper.value = i18n.global.t('website.deleteConfirmHelper', [app.name]);
appInstallName.value = app.name;
open.value = true;
};
const submit = async () => {
loading.value = true;
InstalledOp(deleteReq.value)
.then(() => {
handleClose();
ElMessage.success(i18n.global.t('commons.msg.deleteSuccess'));
})
.finally(() => {
loading.value = false;
});
};
defineExpose({
acceptParams,
});
</script>
<style lang="scss">
.helper {
margin-top: -20px;
}
</style>

View File

@ -109,6 +109,7 @@
</el-dialog>
<Backups ref="backupRef" @close="search"></Backups>
<AppResources ref="checkRef"></AppResources>
<AppDelete ref="deleteRef" @close="search"></AppDelete>
</el-card>
</template>
@ -127,8 +128,9 @@ import i18n from '@/lang';
import { ElMessage, ElMessageBox } from 'element-plus';
import Backups from './backups.vue';
import AppResources from './check/index.vue';
import AppDelete from './delete/index.vue';
import { App } from '@/api/interface/app';
import { useDeleteData } from '@/hooks/use-delete-data';
// import { useDeleteData } from '@/hooks/use-delete-data';
import Status from '@/components/status/index.vue';
let data = ref<any>();
@ -148,6 +150,7 @@ let operateReq = reactive({
let versions = ref<App.VersionDetail[]>();
const backupRef = ref();
const checkRef = ref();
const deleteRef = ref();
let searchName = ref('');
const sync = () => {
@ -192,8 +195,10 @@ const openOperate = (row: any, op: string) => {
if (res.data && res.data.length > 0) {
checkRef.value.acceptParams({ items: items });
} else {
await useDeleteData(InstalledOp, operateReq, 'app.deleteWarn');
search();
deleteRef.value.acceptParams(row);
// await useDeleteData(InstalledOp, operateReq, 'app.deleteWarn');
// search();
}
});
} else {