mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-03-13 17:24:44 +08:00
parent
f196d029cb
commit
63ae17372d
@ -14,8 +14,8 @@ import (
|
||||
)
|
||||
|
||||
// @Tags App
|
||||
// @Summary List app installed
|
||||
// @Description 获取已安装应用列表
|
||||
// @Summary Page app installed
|
||||
// @Description 分页获取已安装应用列表
|
||||
// @Accept json
|
||||
// @Param request body request.AppInstalledSearch true "request"
|
||||
// @Success 200
|
||||
@ -47,6 +47,22 @@ func (b *BaseApi) SearchAppInstalled(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags App
|
||||
// @Summary List app installed
|
||||
// @Description 获取已安装应用列表
|
||||
// @Accept json
|
||||
// @Success 200 array dto.AppInstallInfo
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /apps/installed/list [get]
|
||||
func (b *BaseApi) ListAppInstalled(c *gin.Context) {
|
||||
list, err := appInstallService.GetInstallList()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, list)
|
||||
}
|
||||
|
||||
// @Tags App
|
||||
// @Summary Check app installed
|
||||
// @Description 检查应用安装情况
|
||||
|
@ -132,3 +132,9 @@ var AppToolMap = map[string]string{
|
||||
"mysql": "phpmyadmin",
|
||||
"redis": "redis-commander",
|
||||
}
|
||||
|
||||
type AppInstallInfo struct {
|
||||
ID uint `json:"id"`
|
||||
Key string `json:"key"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ type CronjobCreate struct {
|
||||
|
||||
Script string `json:"script"`
|
||||
ContainerName string `json:"containerName"`
|
||||
AppID string `json:"appID"`
|
||||
Website string `json:"website"`
|
||||
ExclusionRules string `json:"exclusionRules"`
|
||||
DBName string `json:"dbName"`
|
||||
@ -36,6 +37,7 @@ type CronjobUpdate struct {
|
||||
|
||||
Script string `json:"script"`
|
||||
ContainerName string `json:"containerName"`
|
||||
AppID string `json:"appID"`
|
||||
Website string `json:"website"`
|
||||
ExclusionRules string `json:"exclusionRules"`
|
||||
DBName string `json:"dbName"`
|
||||
@ -79,6 +81,7 @@ type CronjobInfo struct {
|
||||
|
||||
Script string `json:"script"`
|
||||
ContainerName string `json:"containerName"`
|
||||
AppID string `json:"appID"`
|
||||
Website string `json:"website"`
|
||||
ExclusionRules string `json:"exclusionRules"`
|
||||
DBName string `json:"dbName"`
|
||||
|
@ -18,6 +18,7 @@ type Cronjob struct {
|
||||
ContainerName string `gorm:"type:varchar(64)" json:"containerName"`
|
||||
Script string `gorm:"longtext" json:"script"`
|
||||
Website string `gorm:"type:varchar(64)" json:"website"`
|
||||
AppID string `gorm:"type:varchar(64)" json:"appID"`
|
||||
DBName string `gorm:"type:varchar(64)" json:"dbName"`
|
||||
URL string `gorm:"type:varchar(256)" json:"url"`
|
||||
SourceDir string `gorm:"type:varchar(256)" json:"sourceDir"`
|
||||
|
@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/1Panel-dev/1Panel/backend/i18n"
|
||||
"math"
|
||||
"os"
|
||||
"path"
|
||||
@ -12,6 +11,8 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/i18n"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
@ -54,12 +55,26 @@ type IAppInstallService interface {
|
||||
ChangeAppPort(req request.PortUpdate) error
|
||||
GetDefaultConfigByKey(key string) (string, error)
|
||||
DeleteCheck(installId uint) ([]dto.AppResource, error)
|
||||
|
||||
GetInstallList() ([]dto.AppInstallInfo, error)
|
||||
}
|
||||
|
||||
func NewIAppInstalledService() IAppInstallService {
|
||||
return &AppInstallService{}
|
||||
}
|
||||
|
||||
func (a *AppInstallService) GetInstallList() ([]dto.AppInstallInfo, error) {
|
||||
var datas []dto.AppInstallInfo
|
||||
appInstalls, err := appInstallRepo.ListBy()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, install := range appInstalls {
|
||||
datas = append(datas, dto.AppInstallInfo{ID: install.ID, Key: install.App.Key, Name: install.Name})
|
||||
}
|
||||
return datas, nil
|
||||
}
|
||||
|
||||
func (a *AppInstallService) Page(req request.AppInstalledSearch) (int64, []response.AppInstalledDTO, error) {
|
||||
var (
|
||||
opts []repo.DBOption
|
||||
|
@ -46,7 +46,7 @@ func (u *CronjobService) SearchWithPage(search dto.SearchWithPage) (int64, inter
|
||||
if err := copier.Copy(&item, &cronjob); err != nil {
|
||||
return 0, nil, errors.WithMessage(constant.ErrStructTransform, err.Error())
|
||||
}
|
||||
if item.Type == "website" || item.Type == "database" || item.Type == "directory" {
|
||||
if item.Type == "app" || item.Type == "website" || item.Type == "database" || item.Type == "directory" {
|
||||
backup, _ := backupRepo.Get(commonRepo.WithByID(uint(item.TargetDirID)))
|
||||
if len(backup.Type) != 0 {
|
||||
item.TargetDir = backup.Type
|
||||
@ -103,7 +103,7 @@ func (u *CronjobService) CleanRecord(req dto.CronjobClean) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if req.CleanData && (cronjob.Type == "database" || cronjob.Type == "website" || cronjob.Type == "directory") {
|
||||
if req.CleanData && (cronjob.Type == "app" || cronjob.Type == "database" || cronjob.Type == "website" || cronjob.Type == "directory") {
|
||||
cronjob.RetainCopies = 0
|
||||
backup, err := backupRepo.Get(commonRepo.WithByID(uint(cronjob.TargetDirID)))
|
||||
if err != nil {
|
||||
|
@ -47,9 +47,7 @@ func (u *CronjobService) HandleJob(cronjob *model.Cronjob) {
|
||||
case "ntp":
|
||||
err = u.handleNtpSync()
|
||||
u.HandleRmExpired("LOCAL", "", "", cronjob, nil)
|
||||
case "website":
|
||||
record.File, err = u.handleBackup(cronjob, record.StartTime)
|
||||
case "database":
|
||||
case "website", "database", "app":
|
||||
record.File, err = u.handleBackup(cronjob, record.StartTime)
|
||||
case "directory":
|
||||
if len(cronjob.SourceDir) == 0 {
|
||||
@ -120,6 +118,9 @@ func (u *CronjobService) handleBackup(cronjob *model.Cronjob, startTime time.Tim
|
||||
case "database":
|
||||
paths, err := u.handleDatabase(*cronjob, backup, startTime)
|
||||
return strings.Join(paths, ","), err
|
||||
case "app":
|
||||
paths, err := u.handleApp(*cronjob, backup, startTime)
|
||||
return strings.Join(paths, ","), err
|
||||
case "website":
|
||||
paths, err := u.handleWebsite(*cronjob, backup, startTime)
|
||||
return strings.Join(paths, ","), err
|
||||
@ -221,7 +222,7 @@ func handleTar(sourceDir, targetDir, name, exclusionRules string) error {
|
||||
path = sourceDir
|
||||
}
|
||||
|
||||
commands := fmt.Sprintf("tar --warning=no-file-changed -zcf %s %s %s", targetDir+"/"+name, excludeRules, path)
|
||||
commands := fmt.Sprintf("tar -zcf %s %s %s", targetDir+"/"+name, excludeRules, path)
|
||||
global.LOG.Debug(commands)
|
||||
stdout, err := cmd.ExecWithTimeOut(commands, 24*time.Hour)
|
||||
if err != nil {
|
||||
@ -396,6 +397,84 @@ func (u *CronjobService) handleCutWebsiteLog(cronjob *model.Cronjob, startTime t
|
||||
return strings.Join(filePaths, ","), nil
|
||||
}
|
||||
|
||||
func (u *CronjobService) handleApp(cronjob model.Cronjob, backup model.BackupAccount, startTime time.Time) ([]string, error) {
|
||||
var paths []string
|
||||
localDir, err := loadLocalDir()
|
||||
if err != nil {
|
||||
return paths, err
|
||||
}
|
||||
|
||||
var applist []model.AppInstall
|
||||
if cronjob.AppID == "all" {
|
||||
applist, err = appInstallRepo.ListBy()
|
||||
if err != nil {
|
||||
return paths, err
|
||||
}
|
||||
} else {
|
||||
itemID, _ := (strconv.Atoi(cronjob.AppID))
|
||||
app, err := appInstallRepo.GetFirst(commonRepo.WithByID(uint(itemID)))
|
||||
if err != nil {
|
||||
return paths, err
|
||||
}
|
||||
applist = append(applist, app)
|
||||
}
|
||||
|
||||
var client cloud_storage.CloudStorageClient
|
||||
if backup.Type != "LOCAL" {
|
||||
client, err = NewIBackupService().NewClient(&backup)
|
||||
if err != nil {
|
||||
return paths, err
|
||||
}
|
||||
}
|
||||
|
||||
for _, app := range applist {
|
||||
var record model.BackupRecord
|
||||
record.Type = "app"
|
||||
record.Name = app.App.Key
|
||||
record.DetailName = app.Name
|
||||
record.Source = "LOCAL"
|
||||
record.BackupType = backup.Type
|
||||
backupDir := path.Join(localDir, fmt.Sprintf("app/%s/%s", app.App.Key, app.Name))
|
||||
record.FileDir = backupDir
|
||||
itemFileDir := strings.TrimPrefix(backupDir, localDir+"/")
|
||||
if !cronjob.KeepLocal && backup.Type != "LOCAL" {
|
||||
record.Source = backup.Type
|
||||
record.FileDir = strings.TrimPrefix(backupDir, localDir+"/")
|
||||
}
|
||||
record.FileName = fmt.Sprintf("app_%s_%s.tar.gz", app.Name, startTime.Format("20060102150405"))
|
||||
if err := handleAppBackup(&app, backupDir, record.FileName); err != nil {
|
||||
return paths, err
|
||||
}
|
||||
record.Name = app.Name
|
||||
if err := backupRepo.CreateRecord(&record); err != nil {
|
||||
global.LOG.Errorf("save backup record failed, err: %v", err)
|
||||
return paths, err
|
||||
}
|
||||
if backup.Type != "LOCAL" {
|
||||
if !cronjob.KeepLocal {
|
||||
defer func() {
|
||||
_ = os.RemoveAll(fmt.Sprintf("%s/%s", backupDir, record.FileName))
|
||||
}()
|
||||
}
|
||||
if len(backup.BackupPath) != 0 {
|
||||
itemPath := strings.TrimPrefix(backup.BackupPath, "/")
|
||||
itemPath = strings.TrimSuffix(itemPath, "/") + "/"
|
||||
itemFileDir = itemPath + itemFileDir
|
||||
}
|
||||
if _, err = client.Upload(backupDir+"/"+record.FileName, itemFileDir+"/"+record.FileName); err != nil {
|
||||
return paths, err
|
||||
}
|
||||
}
|
||||
if backup.Type == "LOCAL" || cronjob.KeepLocal {
|
||||
paths = append(paths, fmt.Sprintf("%s/%s", record.FileDir, record.FileName))
|
||||
} else {
|
||||
paths = append(paths, fmt.Sprintf("%s/%s", itemFileDir, record.FileName))
|
||||
}
|
||||
}
|
||||
u.HandleRmExpired(backup.Type, backup.BackupPath, localDir, &cronjob, client)
|
||||
return paths, nil
|
||||
}
|
||||
|
||||
func (u *CronjobService) handleWebsite(cronjob model.Cronjob, backup model.BackupAccount, startTime time.Time) ([]string, error) {
|
||||
var paths []string
|
||||
localDir, err := loadLocalDir()
|
||||
|
@ -572,9 +572,9 @@ var UpdateCronjobWithDb = &gormigrate.Migration{
|
||||
}
|
||||
|
||||
var AddTableFirewall = &gormigrate.Migration{
|
||||
ID: "20230821-add-table-firewall",
|
||||
ID: "20230823-add-table-firewall",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
if err := tx.AutoMigrate(&model.Firewall{}, model.SnapshotStatus{}); err != nil {
|
||||
if err := tx.AutoMigrate(&model.Firewall{}, model.SnapshotStatus{}, &model.Cronjob{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
@ -29,6 +29,7 @@ func (a *AppRouter) InitAppRouter(Router *gin.RouterGroup) {
|
||||
appRouter.GET("/installed/conninfo/:key", baseApi.LoadConnInfo)
|
||||
appRouter.GET("/installed/delete/check/:appInstallId", baseApi.DeleteCheck)
|
||||
appRouter.POST("/installed/search", baseApi.SearchAppInstalled)
|
||||
appRouter.GET("/installed/list", baseApi.ListAppInstalled)
|
||||
appRouter.POST("/installed/op", baseApi.OperateInstalled)
|
||||
appRouter.POST("/installed/sync", baseApi.SyncInstalled)
|
||||
appRouter.POST("/installed/port/change", baseApi.ChangeAppPort)
|
||||
|
@ -460,6 +460,34 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/apps/installed/list": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "获取已安装应用列表",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"App"
|
||||
],
|
||||
"summary": "List app installed",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/dto.AppInstallInfo"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/apps/installed/loadport/:key": {
|
||||
"get": {
|
||||
"security": [
|
||||
@ -689,14 +717,14 @@ const docTemplate = `{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "获取已安装应用列表",
|
||||
"description": "分页获取已安装应用列表",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"App"
|
||||
],
|
||||
"summary": "List app installed",
|
||||
"summary": "Page app installed",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "request",
|
||||
@ -11580,6 +11608,20 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.AppInstallInfo": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"key": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.AppResource": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -12213,6 +12255,9 @@ const docTemplate = `{
|
||||
"type"
|
||||
],
|
||||
"properties": {
|
||||
"appID": {
|
||||
"type": "string"
|
||||
},
|
||||
"containerName": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -12295,6 +12340,9 @@ const docTemplate = `{
|
||||
"specType"
|
||||
],
|
||||
"properties": {
|
||||
"appID": {
|
||||
"type": "string"
|
||||
},
|
||||
"containerName": {
|
||||
"type": "string"
|
||||
},
|
||||
|
@ -453,6 +453,34 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/apps/installed/list": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "获取已安装应用列表",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"App"
|
||||
],
|
||||
"summary": "List app installed",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/dto.AppInstallInfo"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/apps/installed/loadport/:key": {
|
||||
"get": {
|
||||
"security": [
|
||||
@ -682,14 +710,14 @@
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "获取已安装应用列表",
|
||||
"description": "分页获取已安装应用列表",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"App"
|
||||
],
|
||||
"summary": "List app installed",
|
||||
"summary": "Page app installed",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "request",
|
||||
@ -11573,6 +11601,20 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.AppInstallInfo": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"key": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.AppResource": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -12206,6 +12248,9 @@
|
||||
"type"
|
||||
],
|
||||
"properties": {
|
||||
"appID": {
|
||||
"type": "string"
|
||||
},
|
||||
"containerName": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -12288,6 +12333,9 @@
|
||||
"specType"
|
||||
],
|
||||
"properties": {
|
||||
"appID": {
|
||||
"type": "string"
|
||||
},
|
||||
"containerName": {
|
||||
"type": "string"
|
||||
},
|
||||
|
@ -28,6 +28,15 @@ definitions:
|
||||
oldRule:
|
||||
$ref: '#/definitions/dto.AddrRuleOperate'
|
||||
type: object
|
||||
dto.AppInstallInfo:
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
key:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
type: object
|
||||
dto.AppResource:
|
||||
properties:
|
||||
name:
|
||||
@ -449,6 +458,8 @@ definitions:
|
||||
type: object
|
||||
dto.CronjobCreate:
|
||||
properties:
|
||||
appID:
|
||||
type: string
|
||||
containerName:
|
||||
type: string
|
||||
day:
|
||||
@ -505,6 +516,8 @@ definitions:
|
||||
type: object
|
||||
dto.CronjobUpdate:
|
||||
properties:
|
||||
appID:
|
||||
type: string
|
||||
containerName:
|
||||
type: string
|
||||
day:
|
||||
@ -4177,6 +4190,23 @@ paths:
|
||||
formatEN: Application param update [installId]
|
||||
formatZH: 忽略应用 [installId] 版本升级
|
||||
paramKeys: []
|
||||
/apps/installed/list:
|
||||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 获取已安装应用列表
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
items:
|
||||
$ref: '#/definitions/dto.AppInstallInfo'
|
||||
type: array
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: List app installed
|
||||
tags:
|
||||
- App
|
||||
/apps/installed/loadport/:key:
|
||||
get:
|
||||
consumes:
|
||||
@ -4325,7 +4355,7 @@ paths:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 获取已安装应用列表
|
||||
description: 分页获取已安装应用列表
|
||||
parameters:
|
||||
- description: request
|
||||
in: body
|
||||
@ -4338,7 +4368,7 @@ paths:
|
||||
description: OK
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: List app installed
|
||||
summary: Page app installed
|
||||
tags:
|
||||
- App
|
||||
/apps/installed/sync:
|
||||
|
@ -116,6 +116,12 @@ export namespace App {
|
||||
app: App;
|
||||
}
|
||||
|
||||
export interface AppInstalledInfo {
|
||||
id: number;
|
||||
key: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface CheckInstalled {
|
||||
name: string;
|
||||
version: string;
|
||||
|
@ -15,6 +15,7 @@ export namespace Cronjob {
|
||||
script: string;
|
||||
inContainer: boolean;
|
||||
containerName: string;
|
||||
appID: string;
|
||||
website: string;
|
||||
exclusionRules: string;
|
||||
dbName: string;
|
||||
|
@ -42,6 +42,10 @@ export const SearchAppInstalled = (search: App.AppInstallSearch) => {
|
||||
return http.post<ResPage<App.AppInstalled>>('apps/installed/search', search);
|
||||
};
|
||||
|
||||
export const ListAppInstalled = () => {
|
||||
return http.get<Array<App.AppInstalledInfo>>('apps/installed/list');
|
||||
};
|
||||
|
||||
export const GetAppPort = (key: string) => {
|
||||
return http.get<number>(`apps/installed/loadport/${key}`);
|
||||
};
|
||||
|
@ -689,6 +689,7 @@ const message = {
|
||||
containerCheckBox: 'In container (no need to enter the container command)',
|
||||
containerName: 'Container name',
|
||||
ntp: 'Time synchronization',
|
||||
app: 'Backup app',
|
||||
website: 'Backup website',
|
||||
rulesHelper:
|
||||
'When there are multiple compression exclusion rules, they need to be displayed with line breaks. For example: \n*.log \n*.sql',
|
||||
|
@ -665,6 +665,7 @@ const message = {
|
||||
containerCheckBox: '在容器中執行(無需再輸入進入容器命令)',
|
||||
containerName: '容器名稱',
|
||||
ntp: '時間同步',
|
||||
app: '備份應用',
|
||||
website: '備份網站',
|
||||
rulesHelper: '當存在多個壓縮排除規則時,需要換行顯示,例:\n*.log \n*.sql',
|
||||
lastRecordTime: '上次執行時間',
|
||||
|
@ -665,6 +665,7 @@ const message = {
|
||||
containerCheckBox: '在容器中执行(无需再输入进入容器命令)',
|
||||
containerName: '容器名称',
|
||||
ntp: '时间同步',
|
||||
app: '备份应用',
|
||||
website: '备份网站',
|
||||
rulesHelper: '当存在多个压缩排除规则时,需要换行显示,例:\n*.log \n*.sql',
|
||||
lastRecordTime: '上次执行时间',
|
||||
|
@ -19,6 +19,7 @@
|
||||
v-model="dialogData.rowData!.type"
|
||||
>
|
||||
<el-option value="shell" :label="$t('cronjob.shell')" />
|
||||
<el-option value="app" :label="$t('cronjob.app')" />
|
||||
<el-option value="website" :label="$t('cronjob.website')" />
|
||||
<el-option value="database" :label="$t('cronjob.database')" />
|
||||
<el-option value="directory" :label="$t('cronjob.directory')" />
|
||||
@ -118,6 +119,17 @@
|
||||
</span>
|
||||
</el-form-item>
|
||||
|
||||
<div v-if="dialogData.rowData!.type === 'app'">
|
||||
<el-form-item :label="$t('cronjob.app')" prop="appID">
|
||||
<el-select class="selectClass" clearable v-model="dialogData.rowData!.appID">
|
||||
<el-option :label="$t('commons.table.all')" value="all" />
|
||||
<div v-for="item in appOptions" :key="item.id">
|
||||
<el-option :label="item.key + ' [' + item.name + ']'" :value="item.id + ''" />
|
||||
</div>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
<div v-if="dialogData.rowData!.type === 'database'">
|
||||
<el-form-item :label="$t('cronjob.database')" prop="dbName">
|
||||
<el-select class="selectClass" clearable v-model="dialogData.rowData!.dbName">
|
||||
@ -237,6 +249,7 @@ import { MsgError, MsgSuccess } from '@/utils/message';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { listContainer } from '@/api/modules/container';
|
||||
import { Database } from '@/api/interface/database';
|
||||
import { ListAppInstalled } from '@/api/modules/app';
|
||||
const router = useRouter();
|
||||
|
||||
interface DialogProps {
|
||||
@ -264,6 +277,7 @@ const acceptParams = (params: DialogProps): void => {
|
||||
drawerVisiable.value = true;
|
||||
checkMysqlInstalled();
|
||||
loadBackups();
|
||||
loadAppInstalls();
|
||||
loadWebsites();
|
||||
loadContainers();
|
||||
};
|
||||
@ -282,6 +296,7 @@ const localDirID = ref();
|
||||
const containerOptions = ref();
|
||||
const websiteOptions = ref();
|
||||
const backupOptions = ref();
|
||||
const appOptions = ref();
|
||||
|
||||
const mysqlInfo = reactive({
|
||||
isExist: false,
|
||||
@ -417,6 +432,11 @@ const changeType = () => {
|
||||
dialogData.value.rowData.hour = 1;
|
||||
dialogData.value.rowData.minute = 30;
|
||||
break;
|
||||
case 'app':
|
||||
dialogData.value.rowData.specType = 'perDay';
|
||||
dialogData.value.rowData.hour = 2;
|
||||
dialogData.value.rowData.minute = 30;
|
||||
break;
|
||||
case 'database':
|
||||
dialogData.value.rowData.specType = 'perDay';
|
||||
dialogData.value.rowData.hour = 2;
|
||||
@ -459,6 +479,11 @@ const loadBackups = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
const loadAppInstalls = async () => {
|
||||
const res = await ListAppInstalled();
|
||||
appOptions.value = res.data || [];
|
||||
};
|
||||
|
||||
const loadWebsites = async () => {
|
||||
const res = await GetWebsiteOptions();
|
||||
websiteOptions.value = res.data || [];
|
||||
@ -476,6 +501,7 @@ const checkMysqlInstalled = async () => {
|
||||
|
||||
function isBackup() {
|
||||
return (
|
||||
dialogData.value.rowData!.type === 'app' ||
|
||||
dialogData.value.rowData!.type === 'website' ||
|
||||
dialogData.value.rowData!.type === 'database' ||
|
||||
dialogData.value.rowData!.type === 'directory'
|
||||
|
@ -177,6 +177,17 @@
|
||||
{{ $t('file.download') }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item class="description" v-if="dialogData.rowData!.type === 'app'">
|
||||
<template #label>
|
||||
<span class="status-label">{{ $t('cronjob.app') }}</span>
|
||||
</template>
|
||||
<span v-if="dialogData.rowData!.appID !== 'all'" class="status-count">
|
||||
{{ dialogData.rowData!.appID }}
|
||||
</span>
|
||||
<span v-else class="status-count">
|
||||
{{ $t('commons.table.all') }}
|
||||
</span>
|
||||
</el-form-item>
|
||||
<el-form-item class="description" v-if="dialogData.rowData!.type === 'website'">
|
||||
<template #label>
|
||||
<span class="status-label">{{ $t('cronjob.website') }}</span>
|
||||
@ -228,10 +239,7 @@
|
||||
<span class="status-count">{{ dialogData.rowData!.retainCopies }}</span>
|
||||
</el-form-item>
|
||||
</el-row>
|
||||
<el-form-item
|
||||
class="description"
|
||||
v-if="dialogData.rowData!.type === 'website' || dialogData.rowData!.type === 'directory'"
|
||||
>
|
||||
<el-form-item class="description" v-if=" dialogData.rowData!.type === 'directory'">
|
||||
<template #label>
|
||||
<span class="status-label">{{ $t('cronjob.exclusionRules') }}</span>
|
||||
</template>
|
||||
@ -375,6 +383,7 @@ import { javascript } from '@codemirror/lang-javascript';
|
||||
import { oneDark } from '@codemirror/theme-one-dark';
|
||||
import { MsgError, MsgInfo, MsgSuccess } from '@/utils/message';
|
||||
import { loadDBOptions } from '@/api/modules/database';
|
||||
import { ListAppInstalled } from '@/api/modules/app';
|
||||
|
||||
const loading = ref();
|
||||
const refresh = ref(false);
|
||||
@ -415,6 +424,16 @@ const acceptParams = async (params: DialogProps): Promise<void> => {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dialogData.value.rowData.type === 'app') {
|
||||
const res = await ListAppInstalled();
|
||||
let itemApps = res.data || [];
|
||||
for (const item of itemApps) {
|
||||
if (item.id == dialogData.value.rowData.appID) {
|
||||
dialogData.value.rowData.appID = item.key + ' [' + item.name + ']';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
search();
|
||||
timer = setInterval(() => {
|
||||
search();
|
||||
@ -572,6 +591,10 @@ const onDownload = async (record: any, backupID: number) => {
|
||||
MsgInfo(i18n.global.t('cronjob.allOptionHelper', [i18n.global.t('database.database')]));
|
||||
return;
|
||||
}
|
||||
if (dialogData.value.rowData.app === 'all') {
|
||||
MsgInfo(i18n.global.t('cronjob.allOptionHelper', [i18n.global.t('app.app')]));
|
||||
return;
|
||||
}
|
||||
if (dialogData.value.rowData.website === 'all') {
|
||||
MsgInfo(i18n.global.t('cronjob.allOptionHelper', [i18n.global.t('website.website')]));
|
||||
return;
|
||||
@ -652,6 +675,7 @@ const cleanRecord = async () => {
|
||||
|
||||
function isBackup() {
|
||||
return (
|
||||
dialogData.value.rowData!.type === 'app' ||
|
||||
dialogData.value.rowData!.type === 'website' ||
|
||||
dialogData.value.rowData!.type === 'database' ||
|
||||
dialogData.value.rowData!.type === 'directory'
|
||||
|
Loading…
x
Reference in New Issue
Block a user