1
0
mirror of https://github.com/1Panel-dev/1Panel.git synced 2025-03-14 01:34:47 +08:00

feat: 网站应用创建可以选择存量数据库,删除应用增加删除数据库选项

This commit is contained in:
zhengkunwang223 2023-03-06 17:24:00 +08:00 committed by zhengkunwang223
parent a1c3fa644c
commit e1518e842f
12 changed files with 52 additions and 21 deletions

View File

@ -45,6 +45,7 @@ type AppInstalledOperate struct {
Operate constant.AppOperate `json:"operate" validate:"required"`
ForceDelete bool `json:"forceDelete"`
DeleteBackup bool `json:"deleteBackup"`
DeleteDB bool `json:"deleteDB"`
}
type PortUpdate struct {

View File

@ -33,7 +33,6 @@ type IAppService interface {
GetApp(key string) (*response.AppDTO, error)
GetAppDetail(appId uint, version string) (response.AppDetailDTO, error)
Install(ctx context.Context, req request.AppInstallCreate) (*model.AppInstall, error)
//SyncInstalled(installId uint) error
SyncAppList() error
}

View File

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

View File

@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"fmt"
"github.com/1Panel-dev/1Panel/backend/app/repo"
"math"
"os"
"path"
@ -88,6 +89,14 @@ func createLink(ctx context.Context, app model.App, appInstall *model.AppInstall
if err != nil {
return err
}
iMysqlRepo := repo.NewIMysqlRepo()
oldMysqlDb, _ := iMysqlRepo.Get(commonRepo.WithByName(dbConfig.DbName))
resourceId := oldMysqlDb.ID
if oldMysqlDb.ID > 0 {
if oldMysqlDb.Username != dbConfig.DbUser || oldMysqlDb.Password != dbConfig.Password {
return buserr.New(constant.ErrDbUserNotValid)
}
} else {
var createMysql dto.MysqlDBCreate
createMysql.Name = dbConfig.DbName
createMysql.Username = dbConfig.DbUser
@ -98,8 +107,11 @@ func createLink(ctx context.Context, app model.App, appInstall *model.AppInstall
if err != nil {
return err
}
resourceId = mysqldb.ID
}
var installResource model.AppInstallResource
installResource.ResourceId = mysqldb.ID
installResource.ResourceId = resourceId
installResource.AppInstallId = appInstall.ID
installResource.LinkId = dbInstall.ID
installResource.Key = dbInstall.App.Key
@ -110,7 +122,7 @@ func createLink(ctx context.Context, app model.App, appInstall *model.AppInstall
return nil
}
func deleteAppInstall(ctx context.Context, install model.AppInstall, deleteBackup bool, forceDelete bool) error {
func deleteAppInstall(ctx context.Context, install model.AppInstall, deleteBackup bool, forceDelete bool, deleteDB bool) error {
op := files.NewFileOp()
appDir := install.GetPath()
dir, _ := os.Stat(appDir)
@ -126,7 +138,7 @@ func deleteAppInstall(ctx context.Context, install model.AppInstall, deleteBacku
if err := appInstallRepo.Delete(ctx, install); err != nil && !forceDelete {
return err
}
if err := deleteLink(ctx, &install); err != nil && !forceDelete {
if err := deleteLink(ctx, &install, deleteDB); err != nil && !forceDelete {
return err
}
uploadDir := fmt.Sprintf("%s/1panel/uploads/app/%s/%s", global.CONF.System.BaseDir, install.App.Key, install.Name)
@ -149,14 +161,14 @@ func deleteAppInstall(ctx context.Context, install model.AppInstall, deleteBacku
return nil
}
func deleteLink(ctx context.Context, install *model.AppInstall) error {
func deleteLink(ctx context.Context, install *model.AppInstall, deleteDB bool) error {
resources, _ := appInstallResourceRepo.GetBy(appInstallResourceRepo.WithAppInstallId(install.ID))
if len(resources) == 0 {
return nil
}
for _, re := range resources {
mysqlService := NewIMysqlService()
if re.Key == "mysql" {
if re.Key == "mysql" && deleteDB {
database, _ := mysqlRepo.Get(commonRepo.WithByID(re.ResourceId))
if reflect.DeepEqual(database, model.DatabaseMysql{}) {
continue

View File

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

View File

@ -57,6 +57,7 @@ var (
ErrFileToLarge = "ErrFileToLarge"
ErrNotInstall = "ErrNotInstall"
ErrPortInOtherApp = "ErrPortInOtherApp"
ErrDbUserNotValid = "ErrDbUserNotValid"
)
//website

View File

@ -23,6 +23,7 @@ ErrAppLimit: "App exceeds install limit"
ErrAppRequired: "{{ .detail }} app is required"
ErrNotInstall: "App not installed"
ErrPortInOtherApp: "{{ .port }} port already in use by {{ .apps }}"
ErrDbUserNotValid: "Stock database, username and password do not match"
#file
ErrFileCanNotRead: "File can not read"

View File

@ -23,6 +23,7 @@ ErrAppLimit: "应用超出安装数量限制"
ErrAppRequired: "请先安装 {{ .detail }} 应用"
ErrNotInstall: "应用未安装"
ErrPortInOtherApp: "{{ .port }} 端口已被 {{ .apps }}占用!"
ErrDbUserNotValid: "存量数据库,用户名密码不匹配!"
#file
ErrFileCanNotRead: "此文件不支持预览"

View File

@ -863,6 +863,7 @@ export default {
all: 'All',
version: 'Version',
detail: 'Details',
params: 'Param',
install: 'Install',
author: 'Author',
source: 'Source',
@ -905,7 +906,9 @@ export default {
forceDeleteHelper:
'Forced deletion will ignore errors generated during the deletion process and eventually delete metadata',
deleteBackup: 'Delete backup',
deleteBackupHelper: 'Delete application backup at the same time',
deleteBackupHelper: 'Also delete the application backup',
deleteDB: 'Delete Database',
deleteDBHelper: 'Also delete the database',
noService: 'No {0}',
toInstall: 'to install',
param: 'parameter configuration',

View File

@ -866,7 +866,8 @@ export default {
installed: '已安装',
all: '全部',
version: '版本',
detail: '参数',
detail: '详情',
params: '参数',
install: '安装',
author: '作者',
source: '来源',
@ -907,6 +908,8 @@ export default {
forceDeleteHelper: '强制删除会忽略删除过程中产生的错误并最终删除元数据',
deleteBackup: '删除备份',
deleteBackupHelper: '同时删除应用备份',
deleteDB: '删除数据库',
deleteDBHelper: '同时删除与应用关联的数据库',
noService: '{0}',
toInstall: '去安装',
param: '参数配置',

View File

@ -2,7 +2,7 @@
<el-dialog
v-model="open"
:title="$t('commons.button.delete') + ' - ' + appInstallName"
width="30%"
width="40%"
:close-on-click-modal="false"
:before-close="handleClose"
>
@ -19,6 +19,12 @@
{{ $t('app.deleteBackupHelper') }}
</span>
</el-form-item>
<el-form-item v-if="appType === 'website'">
<el-checkbox v-model="deleteReq.deleteDB" :label="$t('app.deleteDB')" />
<span class="input-help">
{{ $t('app.deleteDBHelper') }}
</span>
</el-form-item>
<el-form-item>
<span v-html="deleteHelper"></span>
<el-input v-model="deleteInfo" :placeholder="appInstallName" />
@ -50,12 +56,14 @@ let deleteReq = ref({
installId: 0,
deleteBackup: false,
forceDelete: false,
deleteDB: true,
});
let open = ref(false);
let loading = ref(false);
let deleteHelper = ref('');
let deleteInfo = ref('');
let appInstallName = ref('');
let appType = ref('');
const deleteForm = ref<FormInstance>();
const em = defineEmits(['close']);
@ -71,9 +79,11 @@ const acceptParams = async (app: App.AppInstalled) => {
installId: 0,
deleteBackup: false,
forceDelete: false,
deleteDB: true,
};
deleteInfo.value = '';
deleteReq.value.installId = app.id;
appType.value = app.app.type;
deleteHelper.value = i18n.global.t('website.deleteConfirmHelper', [app.name]);
appInstallName.value = app.name;
open.value = true;

View File

@ -348,7 +348,7 @@ const buttons = [
},
},
{
label: i18n.global.t('app.detail'),
label: i18n.global.t('app.params'),
click: (row: any) => {
openParam(row.id);
},