fix: Cronjob backup supports multiple selections (#8691)

Refs #8669 #8694
This commit is contained in:
ssongliu 2025-05-16 14:30:14 +08:00 committed by GitHub
parent f9ccd10cc9
commit c7c3572ecd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 89 additions and 34 deletions

View file

@ -27,12 +27,17 @@ func (u *CronjobService) handleApp(cronjob model.Cronjob, startTime time.Time, t
if cronjob.AppID == "all" {
apps, _ = appInstallRepo.ListBy(context.Background())
} else {
itemID, _ := strconv.Atoi(cronjob.AppID)
app, err := appInstallRepo.GetFirst(repo.WithByID(uint(itemID)))
appIds := strings.Split(cronjob.AppID, ",")
var idItems []uint
for i := 0; i < len(appIds); i++ {
itemID, _ := strconv.Atoi(appIds[i])
idItems = append(idItems, uint(itemID))
}
appItems, err := appInstallRepo.ListBy(context.Background(), repo.WithByIDs(idItems))
if err != nil {
return err
}
apps = append(apps, app)
apps = appItems
}
if len(apps) == 0 {
return errors.New("no such app in database!")
@ -108,7 +113,6 @@ func (u *CronjobService) handleWebsite(cronjob model.Cronjob, startTime time.Tim
u.removeExpiredBackup(cronjob, accountMap, record)
return nil
}, nil, int(cronjob.RetryTimes), time.Duration(cronjob.Timeout)*time.Second)
return nil
}
return nil
}
@ -327,23 +331,26 @@ func loadDbsForJob(cronjob model.Cronjob) []DatabaseHelper {
}
return dbs
}
itemID, _ := strconv.Atoi(cronjob.DBName)
if cronjob.DBType == "mysql" || cronjob.DBType == "mariadb" {
mysqlItem, _ := mysqlRepo.Get(repo.WithByID(uint(itemID)))
dbs = append(dbs, DatabaseHelper{
ID: mysqlItem.ID,
DBType: cronjob.DBType,
Database: mysqlItem.MysqlName,
Name: mysqlItem.Name,
})
} else {
pgItem, _ := postgresqlRepo.Get(repo.WithByID(uint(itemID)))
dbs = append(dbs, DatabaseHelper{
ID: pgItem.ID,
DBType: cronjob.DBType,
Database: pgItem.PostgresqlName,
Name: pgItem.Name,
})
dbNames := strings.Split(cronjob.DBName, ",")
for _, name := range dbNames {
itemID, _ := strconv.Atoi(name)
if cronjob.DBType == "mysql" || cronjob.DBType == "mariadb" {
mysqlItem, _ := mysqlRepo.Get(repo.WithByID(uint(itemID)))
dbs = append(dbs, DatabaseHelper{
ID: mysqlItem.ID,
DBType: cronjob.DBType,
Database: mysqlItem.MysqlName,
Name: mysqlItem.Name,
})
} else {
pgItem, _ := postgresqlRepo.Get(repo.WithByID(uint(itemID)))
dbs = append(dbs, DatabaseHelper{
ID: pgItem.ID,
DBType: cronjob.DBType,
Database: pgItem.PostgresqlName,
Name: pgItem.Name,
})
}
}
return dbs
}
@ -354,11 +361,13 @@ func loadWebsForJob(cronjob model.Cronjob) []model.Website {
weblist, _ = websiteRepo.List()
return weblist
}
itemID, _ := strconv.Atoi(cronjob.Website)
webItem, _ := websiteRepo.GetFirst(repo.WithByID(uint(itemID)))
if webItem.ID != 0 {
weblist = append(weblist, webItem)
websites := strings.Split(cronjob.Website, ",")
var idItems []uint
for i := 0; i < len(websites); i++ {
itemID, _ := strconv.Atoi(websites[i])
idItems = append(idItems, uint(itemID))
}
weblist, _ = websiteRepo.GetBy(repo.WithByIDs(idItems))
return weblist
}

View file

@ -30,6 +30,10 @@ export namespace Cronjob {
files: Array<Item>;
sourceDir: string;
websiteList: Array<string>;
appIdList: Array<string>;
dbNameList: Array<string>;
sourceAccounts: Array<string>;
downloadAccount: string;
sourceAccountIDs: string;

View file

@ -217,9 +217,17 @@
<LayoutCol v-if="isWebsite()">
<el-form-item
:label="form.type === 'website' ? $t('cronjob.website') : $t('menu.website')"
prop="website"
prop="websiteList"
>
<el-select v-model="form.website">
<el-select
v-model="form.websiteList"
multiple
@change="
form.websiteList = form.websiteList.includes('all')
? ['all']
: form.websiteList
"
>
<el-option
:disabled="websiteOptions.length === 0"
:label="$t('commons.table.all')"
@ -243,8 +251,17 @@
</el-form-item>
</LayoutCol>
<LayoutCol v-if="form.type === 'app'">
<el-form-item :label="$t('cronjob.app')" prop="appID">
<el-select clearable v-model="form.appID">
<el-form-item :label="$t('cronjob.app')" prop="appIdList">
<el-select
clearable
v-model="form.appIdList"
multiple
@change="
form.appIdList = form.appIdList.includes('all')
? ['all']
: form.appIdList
"
>
<el-option
:disabled="appOptions.length === 0"
:label="$t('commons.table.all')"
@ -271,8 +288,17 @@
</el-form-item>
</LayoutCol>
<LayoutCol v-if="form.type === 'database'">
<el-form-item :label="$t('cronjob.database')" prop="dbName">
<el-select clearable v-model="form.dbName">
<el-form-item :label="$t('cronjob.database')" prop="dbNameList">
<el-select
clearable
v-model="form.dbNameList"
multiple
@change="
form.dbNameList = form.dbNameList.includes('all')
? ['all']
: form.dbNameList
"
>
<el-option
:disabled="dbInfo.dbs.length === 0"
:label="$t('commons.table.all')"
@ -716,6 +742,10 @@ const form = reactive<Cronjob.CronjobInfo>({
downloadAccountID: 0,
sourceAccountItems: [],
websiteList: [],
appIdList: [],
dbNameList: [],
retainCopies: 7,
retryTimes: 0,
timeout: 300,
@ -770,10 +800,13 @@ const search = async () => {
form.scriptID = res.data.scriptID;
form.appID = res.data.appID;
form.appIdList = res.data.appID.split(',') || [];
form.website = res.data.website;
form.websiteList = res.data.website.split(',') || [];
form.exclusionRules = res.data.exclusionRules;
form.dbType = res.data.dbType;
form.dbName = res.data.dbName;
form.dbNameList = res.data.dbName.split(',') || [];
form.url = res.data.url;
form.isDir = res.data.isDir;
@ -986,9 +1019,9 @@ const rules = reactive({
script: [{ validator: verifyScript, trigger: 'blur', required: true }],
scriptID: [Rules.requiredSelect],
containerName: [Rules.requiredSelect],
appID: [Rules.requiredSelect],
website: [Rules.requiredSelect],
dbName: [Rules.requiredSelect],
websiteList: [Rules.requiredSelect],
appIdList: [Rules.requiredSelect],
dbNameList: [Rules.requiredSelect],
url: [Rules.requiredInput],
files: [{ validator: verifyFiles, trigger: 'blur', required: true }],
sourceDir: [Rules.requiredInput],
@ -1241,6 +1274,15 @@ const onSubmit = async (formEl: FormInstance | undefined) => {
form.containerName = '';
}
form.timeout = transferTimeToSecond(form.timeoutItem + form.timeoutUint);
if (form.appIdList) {
form.appID = form.appIdList.join(',');
}
if (form.websiteList) {
form.website = form.websiteList.join(',');
}
if (form.dbNameList) {
form.dbName = form.dbNameList.join(',');
}
form.alertCount = form.hasAlert && isProductPro.value ? form.alertCount : 0;
form.alertTitle =