fix: 封装导入备份组件
This commit is contained in:
@@ -20,7 +20,7 @@ import (
|
|||||||
// @Param request body request.AppInstalledSearch true "request"
|
// @Param request body request.AppInstalledSearch true "request"
|
||||||
// @Success 200
|
// @Success 200
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /apps/installed [post]
|
// @Router /apps/installed/search [post]
|
||||||
func (b *BaseApi) SearchAppInstalled(c *gin.Context) {
|
func (b *BaseApi) SearchAppInstalled(c *gin.Context) {
|
||||||
var req request.AppInstalledSearch
|
var req request.AppInstalledSearch
|
||||||
if err := c.ShouldBindJSON(&req); err != nil {
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
@@ -151,31 +151,6 @@ func (b *BaseApi) SyncInstalled(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, "")
|
helper.SuccessWithData(c, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Tags App
|
|
||||||
// @Summary Page installed backups
|
|
||||||
// @Description 查询已安装备份列表分页
|
|
||||||
// @Accept json
|
|
||||||
// @Param request body request.AppBackupSearch true "request"
|
|
||||||
// @Success 200 {object} dto.PageResult
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Router /apps/installed/backups [post]
|
|
||||||
func (b *BaseApi) SearchInstalledBackup(c *gin.Context) {
|
|
||||||
var req request.AppBackupSearch
|
|
||||||
if err := c.ShouldBindJSON(&req); err != nil {
|
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
total, list, err := appInstallService.PageInstallBackups(req)
|
|
||||||
if err != nil {
|
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
helper.SuccessWithData(c, dto.PageResult{
|
|
||||||
Items: list,
|
|
||||||
Total: total,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Tags App
|
// @Tags App
|
||||||
// @Summary Operate installed app
|
// @Summary Operate installed app
|
||||||
// @Description 操作已安装应用
|
// @Description 操作已安装应用
|
||||||
@@ -198,28 +173,6 @@ func (b *BaseApi) OperateInstalled(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, nil)
|
helper.SuccessWithData(c, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Tags App
|
|
||||||
// @Summary Delete app backup record
|
|
||||||
// @Description 删除应用备份记录
|
|
||||||
// @Accept json
|
|
||||||
// @Param request body request.AppBackupDelete true "request"
|
|
||||||
// @Success 200
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Router /apps/installed/backups/del [post]
|
|
||||||
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"ids","isList":true,"db":"app_install_backups","output_colume":"name","output_value":"names"}],"formatZH":"删除应用备份 [names]","formatEN":"Deleting an Application Backup [names]"}
|
|
||||||
func (b *BaseApi) DeleteAppBackup(c *gin.Context) {
|
|
||||||
var req request.AppBackupDelete
|
|
||||||
if err := c.ShouldBindJSON(&req); err != nil {
|
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err := appInstallService.DeleteBackup(req); err != nil {
|
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
helper.SuccessWithData(c, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Tags App
|
// @Tags App
|
||||||
// @Summary Search app service by key
|
// @Summary Search app service by key
|
||||||
// @Description 通过 key 获取应用 service
|
// @Description 通过 key 获取应用 service
|
||||||
|
@@ -354,6 +354,11 @@ func (b *BaseApi) RecoverByUpload(c *gin.Context) {
|
|||||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
case "app":
|
||||||
|
if err := backupService.AppRecover(req); err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
case "website":
|
case "website":
|
||||||
if err := backupService.WebsiteRecover(req); err != nil {
|
if err := backupService.WebsiteRecover(req); err != nil {
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
|
@@ -44,6 +44,35 @@ func (b *BaseApi) ListFiles(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, files)
|
helper.SuccessWithData(c, files)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags File
|
||||||
|
// @Summary Page file
|
||||||
|
// @Description 分页获取上传文件
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.SearchUploadWithPage true "request"
|
||||||
|
// @Success 200 {anrry} response.FileInfo
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Router /files/upload/search [post]
|
||||||
|
func (b *BaseApi) SearchUploadWithPage(c *gin.Context) {
|
||||||
|
var req request.SearchUploadWithPage
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := global.VALID.Struct(req); err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
total, files, err := fileService.SearchUploadWithPage(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, dto.PageResult{
|
||||||
|
Items: files,
|
||||||
|
Total: total,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// @Tags File
|
// @Tags File
|
||||||
// @Summary Load files tree
|
// @Summary Load files tree
|
||||||
// @Description 加载文件树
|
// @Description 加载文件树
|
||||||
|
@@ -1,11 +1,19 @@
|
|||||||
package request
|
package request
|
||||||
|
|
||||||
import "github.com/1Panel-dev/1Panel/backend/utils/files"
|
import (
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
||||||
|
)
|
||||||
|
|
||||||
type FileOption struct {
|
type FileOption struct {
|
||||||
files.FileOption
|
files.FileOption
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SearchUploadWithPage struct {
|
||||||
|
dto.PageInfo
|
||||||
|
Path string `json:"path" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
type FileCreate struct {
|
type FileCreate struct {
|
||||||
Path string `json:"path" validate:"required"`
|
Path string `json:"path" validate:"required"`
|
||||||
Content string `json:"content"`
|
Content string `json:"content"`
|
||||||
|
@@ -1,11 +1,19 @@
|
|||||||
package response
|
package response
|
||||||
|
|
||||||
import "github.com/1Panel-dev/1Panel/backend/utils/files"
|
import (
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
||||||
|
)
|
||||||
|
|
||||||
type FileInfo struct {
|
type FileInfo struct {
|
||||||
files.FileInfo
|
files.FileInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type UploadInfo struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Size int `json:"size"`
|
||||||
|
CreatedAt string `json:"createdAt"`
|
||||||
|
}
|
||||||
|
|
||||||
type FileTree struct {
|
type FileTree struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
@@ -1,8 +1,9 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
|
||||||
"path"
|
"path"
|
||||||
|
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AppInstall struct {
|
type AppInstall struct {
|
||||||
@@ -22,7 +23,6 @@ type AppInstall struct {
|
|||||||
HttpPort int `json:"httpPort" gorm:"type:integer;not null"`
|
HttpPort int `json:"httpPort" gorm:"type:integer;not null"`
|
||||||
HttpsPort int `json:"httpsPort" gorm:"type:integer;not null"`
|
HttpsPort int `json:"httpsPort" gorm:"type:integer;not null"`
|
||||||
App App `json:"app" gorm:"-:migration"`
|
App App `json:"app" gorm:"-:migration"`
|
||||||
Backups []AppInstallBackup `json:"backups" gorm:"-:migration"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *AppInstall) GetPath() string {
|
func (i *AppInstall) GetPath() string {
|
||||||
|
@@ -1,11 +0,0 @@
|
|||||||
package model
|
|
||||||
|
|
||||||
type AppInstallBackup struct {
|
|
||||||
BaseModel
|
|
||||||
Name string `gorm:"type:varchar(64);not null" json:"name"`
|
|
||||||
Path string `gorm:"type:varchar(64);not null" json:"path"`
|
|
||||||
Param string `gorm:"type:longtext;" json:"param"`
|
|
||||||
AppDetailId uint `gorm:"type:integer;not null" json:"app_detail_id"`
|
|
||||||
AppInstallId uint `gorm:"type:integer;not null" json:"app_install_id"`
|
|
||||||
AppDetail AppDetail `json:"-" gorm:"-:migration"`
|
|
||||||
}
|
|
@@ -1,49 +0,0 @@
|
|||||||
package repo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
"gorm.io/gorm/clause"
|
|
||||||
)
|
|
||||||
|
|
||||||
type AppInstallBackupRepo struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a AppInstallBackupRepo) WithAppInstallID(appInstallID uint) DBOption {
|
|
||||||
return func(db *gorm.DB) *gorm.DB {
|
|
||||||
return db.Where("app_install_id = ?", appInstallID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a AppInstallBackupRepo) Create(ctx context.Context, backup model.AppInstallBackup) error {
|
|
||||||
return getTx(ctx).Omit(clause.Associations).Create(&backup).Error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a AppInstallBackupRepo) Delete(ctx context.Context, opts ...DBOption) error {
|
|
||||||
return getTx(ctx, opts...).Omit(clause.Associations).Delete(&model.AppInstallBackup{}).Error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a AppInstallBackupRepo) GetBy(opts ...DBOption) ([]model.AppInstallBackup, error) {
|
|
||||||
var backups []model.AppInstallBackup
|
|
||||||
if err := getDb(opts...).Preload("AppDetail").Find(&backups); err != nil {
|
|
||||||
return backups, nil
|
|
||||||
}
|
|
||||||
return backups, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a AppInstallBackupRepo) GetFirst(opts ...DBOption) (model.AppInstallBackup, error) {
|
|
||||||
var backup model.AppInstallBackup
|
|
||||||
db := getDb(opts...).Model(&model.AppInstallBackup{})
|
|
||||||
err := db.Preload("AppDetail").First(&backup).Error
|
|
||||||
return backup, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a AppInstallBackupRepo) Page(page, size int, opts ...DBOption) (int64, []model.AppInstallBackup, error) {
|
|
||||||
var backups []model.AppInstallBackup
|
|
||||||
db := getDb(opts...).Model(&model.AppInstallBackup{})
|
|
||||||
count := int64(0)
|
|
||||||
db = db.Count(&count)
|
|
||||||
err := db.Limit(size).Offset(size * (page - 1)).Preload("AppDetail").Find(&backups).Error
|
|
||||||
return count, backups, err
|
|
||||||
}
|
|
@@ -8,7 +8,6 @@ type RepoGroup struct {
|
|||||||
AppDetailRepo
|
AppDetailRepo
|
||||||
AppInstallRepo
|
AppInstallRepo
|
||||||
AppInstallResourceRpo
|
AppInstallResourceRpo
|
||||||
AppInstallBackupRepo
|
|
||||||
ImageRepoRepo
|
ImageRepoRepo
|
||||||
ComposeTemplateRepo
|
ComposeTemplateRepo
|
||||||
MysqlRepo
|
MysqlRepo
|
||||||
|
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/global"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"gorm.io/gorm/clause"
|
"gorm.io/gorm/clause"
|
||||||
)
|
)
|
||||||
@@ -20,6 +21,7 @@ type IWebsiteRepo interface {
|
|||||||
GetFirst(opts ...DBOption) (model.Website, error)
|
GetFirst(opts ...DBOption) (model.Website, error)
|
||||||
GetBy(opts ...DBOption) ([]model.Website, error)
|
GetBy(opts ...DBOption) ([]model.Website, error)
|
||||||
Save(ctx context.Context, app *model.Website) error
|
Save(ctx context.Context, app *model.Website) error
|
||||||
|
SaveWithoutCtx(app *model.Website) error
|
||||||
DeleteBy(ctx context.Context, opts ...DBOption) error
|
DeleteBy(ctx context.Context, opts ...DBOption) error
|
||||||
Create(ctx context.Context, app *model.Website) error
|
Create(ctx context.Context, app *model.Website) error
|
||||||
}
|
}
|
||||||
@@ -108,6 +110,10 @@ func (w *WebsiteRepo) Save(ctx context.Context, app *model.Website) error {
|
|||||||
return getTx(ctx).Omit(clause.Associations).Save(app).Error
|
return getTx(ctx).Omit(clause.Associations).Save(app).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *WebsiteRepo) SaveWithoutCtx(website *model.Website) error {
|
||||||
|
return global.DB.Save(website).Error
|
||||||
|
}
|
||||||
|
|
||||||
func (w *WebsiteRepo) DeleteBy(ctx context.Context, opts ...DBOption) error {
|
func (w *WebsiteRepo) DeleteBy(ctx context.Context, opts ...DBOption) error {
|
||||||
return getTx(ctx, opts...).Delete(&model.Website{}).Error
|
return getTx(ctx, opts...).Delete(&model.Website{}).Error
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@@ -23,7 +22,6 @@ import (
|
|||||||
"github.com/1Panel-dev/1Panel/backend/utils/common"
|
"github.com/1Panel-dev/1Panel/backend/utils/common"
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/compose"
|
"github.com/1Panel-dev/1Panel/backend/utils/compose"
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/docker"
|
"github.com/1Panel-dev/1Panel/backend/utils/docker"
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -96,9 +94,6 @@ func (a AppInstallService) CheckExist(key string) (*response.AppInstalledCheck,
|
|||||||
res.AppInstallID = appInstall.ID
|
res.AppInstallID = appInstall.ID
|
||||||
res.IsExist = true
|
res.IsExist = true
|
||||||
res.InstallPath = path.Join(constant.AppInstallDir, app.Key, appInstall.Name)
|
res.InstallPath = path.Join(constant.AppInstallDir, app.Key, appInstall.Name)
|
||||||
if len(appInstall.Backups) > 0 {
|
|
||||||
res.LastBackupAt = appInstall.Backups[0].CreatedAt.Format("2006-01-02 15:04:05")
|
|
||||||
}
|
|
||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
@@ -224,34 +219,6 @@ func (a AppInstallService) SyncAll() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a AppInstallService) PageInstallBackups(req request.AppBackupSearch) (int64, []model.AppInstallBackup, error) {
|
|
||||||
return appInstallBackupRepo.Page(req.Page, req.PageSize, appInstallBackupRepo.WithAppInstallID(req.AppInstallID))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a AppInstallService) DeleteBackup(req request.AppBackupDelete) error {
|
|
||||||
backups, err := appInstallBackupRepo.GetBy(commonRepo.WithIdsIn(req.Ids))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fileOp := files.NewFileOp()
|
|
||||||
|
|
||||||
var errStr strings.Builder
|
|
||||||
for _, backup := range backups {
|
|
||||||
dst := path.Join(backup.Path, backup.Name)
|
|
||||||
if err := fileOp.DeleteFile(dst); err != nil {
|
|
||||||
errStr.WriteString(err.Error())
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if err := appInstallBackupRepo.Delete(context.TODO(), commonRepo.WithIdsIn(req.Ids)); err != nil {
|
|
||||||
errStr.WriteString(err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if errStr.String() != "" {
|
|
||||||
return errors.New(errStr.String())
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a AppInstallService) GetServices(key string) ([]response.AppService, error) {
|
func (a AppInstallService) GetServices(key string) ([]response.AppService, error) {
|
||||||
app, err := appRepo.GetFirst(appRepo.WithKey(key))
|
app, err := appRepo.GetFirst(appRepo.WithKey(key))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@@ -3,6 +3,7 @@ package service
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
@@ -128,15 +129,23 @@ func deleteAppInstall(ctx context.Context, install model.AppInstall, deleteBacku
|
|||||||
if err := deleteLink(ctx, &install); err != nil && !forceDelete {
|
if err := deleteLink(ctx, &install); err != nil && !forceDelete {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if deleteBackup {
|
uploadDir := fmt.Sprintf("%s/1panel/uploads/app/%s/%s", global.CONF.System.BaseDir, install.App.Key, install.Name)
|
||||||
backups, _ := appInstallBackupRepo.GetBy(appInstallBackupRepo.WithAppInstallID(install.ID))
|
if _, err := os.Stat(uploadDir); err == nil {
|
||||||
for _, backup := range backups {
|
_ = os.RemoveAll(uploadDir)
|
||||||
_ = op.DeleteDir(backup.Path)
|
|
||||||
}
|
}
|
||||||
if err := appInstallBackupRepo.Delete(ctx, appInstallBackupRepo.WithAppInstallID(install.ID)); err != nil && !forceDelete {
|
if deleteBackup {
|
||||||
|
localDir, err := loadLocalDir()
|
||||||
|
if err != nil && !forceDelete {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
backupDir := fmt.Sprintf("%s/app/%s/%s", localDir, install.App.Key, install.Name)
|
||||||
|
if _, err := os.Stat(backupDir); err == nil {
|
||||||
|
_ = os.RemoveAll(backupDir)
|
||||||
}
|
}
|
||||||
|
global.LOG.Infof("delete app %s-%s backups successful", install.App.Key, install.Name)
|
||||||
|
}
|
||||||
|
_ = backupRepo.DeleteRecord(ctx, commonRepo.WithByType("app"), commonRepo.WithByName(install.App.Key), backupRepo.WithByDetailName(install.Name))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -41,7 +41,6 @@ type IBackupService interface {
|
|||||||
|
|
||||||
WebsiteBackup(db dto.CommonBackup) error
|
WebsiteBackup(db dto.CommonBackup) error
|
||||||
WebsiteRecover(req dto.CommonRecover) error
|
WebsiteRecover(req dto.CommonRecover) error
|
||||||
WebsiteRecoverByUpload(req dto.CommonRecover) error
|
|
||||||
|
|
||||||
AppBackup(db dto.CommonBackup) error
|
AppBackup(db dto.CommonBackup) error
|
||||||
AppRecover(req dto.CommonRecover) error
|
AppRecover(req dto.CommonRecover) error
|
||||||
|
@@ -6,7 +6,6 @@ import (
|
|||||||
"io/fs"
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -16,9 +15,7 @@ import (
|
|||||||
"github.com/1Panel-dev/1Panel/backend/global"
|
"github.com/1Panel-dev/1Panel/backend/global"
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/compose"
|
"github.com/1Panel-dev/1Panel/backend/utils/compose"
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
||||||
"github.com/joho/godotenv"
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"gopkg.in/yaml.v3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (u *BackupService) AppBackup(req dto.CommonBackup) error {
|
func (u *BackupService) AppBackup(req dto.CommonBackup) error {
|
||||||
@@ -82,12 +79,6 @@ func (u *BackupService) AppRecover(req dto.CommonRecover) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type AppInfo struct {
|
|
||||||
AppDetailId uint `json:"appDetailId"`
|
|
||||||
Param string `json:"param"`
|
|
||||||
Version string `json:"version"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func handleAppBackup(install *model.AppInstall, backupDir, fileName string) error {
|
func handleAppBackup(install *model.AppInstall, backupDir, fileName string) error {
|
||||||
fileOp := files.NewFileOp()
|
fileOp := files.NewFileOp()
|
||||||
tmpDir := fmt.Sprintf("%s/%s", backupDir, strings.ReplaceAll(fileName, ".tar.gz", ""))
|
tmpDir := fmt.Sprintf("%s/%s", backupDir, strings.ReplaceAll(fileName, ".tar.gz", ""))
|
||||||
@@ -100,11 +91,7 @@ func handleAppBackup(install *model.AppInstall, backupDir, fileName string) erro
|
|||||||
_ = os.RemoveAll(tmpDir)
|
_ = os.RemoveAll(tmpDir)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
var appInfo AppInfo
|
remarkInfo, _ := json.Marshal(install)
|
||||||
appInfo.Param = install.Param
|
|
||||||
appInfo.AppDetailId = install.AppDetailId
|
|
||||||
appInfo.Version = install.Version
|
|
||||||
remarkInfo, _ := json.Marshal(appInfo)
|
|
||||||
remarkInfoPath := fmt.Sprintf("%s/app.json", tmpDir)
|
remarkInfoPath := fmt.Sprintf("%s/app.json", tmpDir)
|
||||||
if err := fileOp.SaveFile(remarkInfoPath, string(remarkInfo), fs.ModePerm); err != nil {
|
if err := fileOp.SaveFile(remarkInfoPath, string(remarkInfo), fs.ModePerm); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -114,6 +101,22 @@ func handleAppBackup(install *model.AppInstall, backupDir, fileName string) erro
|
|||||||
if err := fileOp.Compress([]string{appPath}, tmpDir, "app.tar.gz", files.TarGz); err != nil {
|
if err := fileOp.Compress([]string{appPath}, tmpDir, "app.tar.gz", files.TarGz); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resource, _ := appInstallResourceRepo.GetFirst(appInstallResourceRepo.WithAppInstallId(install.ID))
|
||||||
|
if resource.ID != 0 {
|
||||||
|
mysqlInfo, err := appInstallRepo.LoadBaseInfo(constant.AppMysql, "")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
db, err := mysqlRepo.Get(commonRepo.WithByID(resource.ResourceId))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := handleMysqlBackup(mysqlInfo, tmpDir, db.Name, fmt.Sprintf("%s.sql.gz", install.Name)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if err := fileOp.Compress([]string{tmpDir}, backupDir, fileName, files.TarGz); err != nil {
|
if err := fileOp.Compress([]string{tmpDir}, backupDir, fileName, files.TarGz); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -123,17 +126,30 @@ func handleAppBackup(install *model.AppInstall, backupDir, fileName string) erro
|
|||||||
func handleAppRecover(install *model.AppInstall, recoverFile string, isRollback bool) error {
|
func handleAppRecover(install *model.AppInstall, recoverFile string, isRollback bool) error {
|
||||||
isOk := false
|
isOk := false
|
||||||
fileOp := files.NewFileOp()
|
fileOp := files.NewFileOp()
|
||||||
if err := fileOp.Decompress(recoverFile, path.Dir(recoverFile), files.TarGz); err != nil {
|
if err := handleUnTar(recoverFile, path.Dir(recoverFile)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
tmpPath := strings.ReplaceAll(recoverFile, ".tar.gz", "")
|
tmpPath := strings.ReplaceAll(recoverFile, ".tar.gz", "")
|
||||||
defer func() {
|
defer func() {
|
||||||
|
_, _ = compose.Up(install.GetComposePath())
|
||||||
_ = os.RemoveAll(strings.ReplaceAll(recoverFile, ".tar.gz", ""))
|
_ = os.RemoveAll(strings.ReplaceAll(recoverFile, ".tar.gz", ""))
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if !fileOp.Stat(tmpPath+"/app.json") || !fileOp.Stat(tmpPath+"/app.tar.gz") {
|
if !fileOp.Stat(tmpPath+"/app.json") || !fileOp.Stat(tmpPath+"/app.tar.gz") {
|
||||||
return errors.New("the wrong recovery package does not have app.json or app.tar.gz files")
|
return errors.New("the wrong recovery package does not have app.json or app.tar.gz files")
|
||||||
}
|
}
|
||||||
|
var oldInstall model.AppInstall
|
||||||
|
appjson, err := os.ReadFile(tmpPath + "/app.json")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(appjson, &oldInstall); err != nil {
|
||||||
|
return fmt.Errorf("unmarshal app.json failed, err: %v", err)
|
||||||
|
}
|
||||||
|
if oldInstall.App.Key != install.App.Key || oldInstall.Name != install.Name || oldInstall.Version != install.Version || oldInstall.ID != install.ID {
|
||||||
|
return errors.New("the current backup file does not match the application")
|
||||||
|
}
|
||||||
|
|
||||||
if !isRollback {
|
if !isRollback {
|
||||||
rollbackFile := fmt.Sprintf("%s/original/app/%s_%s.tar.gz", global.CONF.System.BaseDir, install.Name, time.Now().Format("20060102150405"))
|
rollbackFile := fmt.Sprintf("%s/original/app/%s_%s.tar.gz", global.CONF.System.BaseDir, install.Name, time.Now().Format("20060102150405"))
|
||||||
if err := handleAppBackup(install, path.Dir(rollbackFile), path.Base(rollbackFile)); err != nil {
|
if err := handleAppBackup(install, path.Dir(rollbackFile), path.Base(rollbackFile)); err != nil {
|
||||||
@@ -143,6 +159,7 @@ func handleAppRecover(install *model.AppInstall, recoverFile string, isRollback
|
|||||||
if !isOk {
|
if !isOk {
|
||||||
if err := handleAppRecover(install, rollbackFile, true); err != nil {
|
if err := handleAppRecover(install, rollbackFile, true); err != nil {
|
||||||
global.LOG.Errorf("rollback app %s from %s failed, err: %v", install.Name, rollbackFile, err)
|
global.LOG.Errorf("rollback app %s from %s failed, err: %v", install.Name, rollbackFile, err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
global.LOG.Infof("rollback app %s from %s successful", install.Name, rollbackFile)
|
global.LOG.Infof("rollback app %s from %s successful", install.Name, rollbackFile)
|
||||||
_ = os.RemoveAll(rollbackFile)
|
_ = os.RemoveAll(rollbackFile)
|
||||||
@@ -152,65 +169,26 @@ func handleAppRecover(install *model.AppInstall, recoverFile string, isRollback
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
appjson, err := os.ReadFile(tmpPath + "/" + "app.json")
|
resource, _ := appInstallResourceRepo.GetFirst(appInstallResourceRepo.WithAppInstallId(install.ID))
|
||||||
|
if resource.ID != 0 && install.App.Key != "mysql" {
|
||||||
|
mysqlInfo, err := appInstallRepo.LoadBaseInfo(resource.Key, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
var appInfo AppInfo
|
db, err := mysqlRepo.Get(commonRepo.WithByID(resource.ResourceId))
|
||||||
_ = json.Unmarshal(appjson, &appInfo)
|
|
||||||
|
|
||||||
if err := fileOp.Decompress(tmpPath+"/app.tar.gz", fmt.Sprintf("%s/%s", constant.AppInstallDir, install.App.Key), files.TarGz); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
composeContent, err := os.ReadFile(install.GetComposePath())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
install.DockerCompose = string(composeContent)
|
if err := handleMysqlRecover(mysqlInfo, tmpPath, db.Name, fmt.Sprintf("%s.sql.gz", install.Name), true); err != nil {
|
||||||
envContent, err := os.ReadFile(fmt.Sprintf("%s/%s/%s/.env", constant.AppInstallDir, install.App.Key, install.Name))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
install.Env = string(envContent)
|
|
||||||
envMaps, err := godotenv.Unmarshal(string(envContent))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
install.HttpPort = 0
|
|
||||||
httpPort, ok := envMaps["PANEL_APP_PORT_HTTP"]
|
|
||||||
if ok {
|
|
||||||
httpPortN, _ := strconv.Atoi(httpPort)
|
|
||||||
install.HttpPort = httpPortN
|
|
||||||
}
|
|
||||||
install.HttpsPort = 0
|
|
||||||
httpsPort, ok := envMaps["PANEL_APP_PORT_HTTPS"]
|
|
||||||
if ok {
|
|
||||||
httpsPortN, _ := strconv.Atoi(httpsPort)
|
|
||||||
install.HttpsPort = httpsPortN
|
|
||||||
}
|
}
|
||||||
|
|
||||||
composeMap := make(map[string]interface{})
|
if err := handleUnTar(tmpPath+"/app.tar.gz", fmt.Sprintf("%s/%s", constant.AppInstallDir, install.App.Key)); err != nil {
|
||||||
if err := yaml.Unmarshal(composeContent, &composeMap); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
servicesMap := composeMap["services"].(map[string]interface{})
|
|
||||||
for k, v := range servicesMap {
|
|
||||||
install.ServiceName = k
|
|
||||||
value := v.(map[string]interface{})
|
|
||||||
install.ContainerName = value["container_name"].(string)
|
|
||||||
}
|
|
||||||
|
|
||||||
install.Param = appInfo.Param
|
oldInstall.Status = constant.Running
|
||||||
if out, err := compose.Up(install.GetComposePath()); err != nil {
|
|
||||||
install.Message = err.Error()
|
|
||||||
if len(out) != 0 {
|
|
||||||
install.Message = out
|
|
||||||
}
|
|
||||||
return errors.New(out)
|
|
||||||
}
|
|
||||||
install.AppDetailId = appInfo.AppDetailId
|
|
||||||
install.Version = appInfo.Version
|
|
||||||
install.Status = constant.Running
|
|
||||||
if err := appInstallRepo.Save(install); err != nil {
|
if err := appInstallRepo.Save(install); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@@ -152,6 +152,7 @@ func handleMysqlRecover(mysqlInfo *repo.RootInfo, recoverDir, dbName, fileName s
|
|||||||
if !isOk {
|
if !isOk {
|
||||||
if err := handleMysqlRecover(mysqlInfo, path.Dir(rollbackFile), dbName, path.Base(rollbackFile), true); err != nil {
|
if err := handleMysqlRecover(mysqlInfo, path.Dir(rollbackFile), dbName, path.Base(rollbackFile), true); err != nil {
|
||||||
global.LOG.Errorf("rollback mysql db %s from %s failed, err: %v", dbName, rollbackFile, err)
|
global.LOG.Errorf("rollback mysql db %s from %s failed, err: %v", dbName, rollbackFile, err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
global.LOG.Infof("rollback mysql db %s from %s successful", dbName, rollbackFile)
|
global.LOG.Infof("rollback mysql db %s from %s successful", dbName, rollbackFile)
|
||||||
_ = os.RemoveAll(rollbackFile)
|
_ = os.RemoveAll(rollbackFile)
|
||||||
|
@@ -113,7 +113,6 @@ func handleRedisRecover(redisInfo *repo.RootInfo, recoverFile string, isRollback
|
|||||||
global.LOG.Infof("appendonly in redis conf is %s", appendonly)
|
global.LOG.Infof("appendonly in redis conf is %s", appendonly)
|
||||||
isOk := false
|
isOk := false
|
||||||
if !isRollback {
|
if !isRollback {
|
||||||
defer func() {
|
|
||||||
suffix := "tar.gz"
|
suffix := "tar.gz"
|
||||||
if appendonly != "yes" {
|
if appendonly != "yes" {
|
||||||
suffix = "rdb"
|
suffix = "rdb"
|
||||||
@@ -126,6 +125,7 @@ func handleRedisRecover(redisInfo *repo.RootInfo, recoverFile string, isRollback
|
|||||||
if !isOk {
|
if !isOk {
|
||||||
if err := handleRedisRecover(redisInfo, rollbackFile, true); err != nil {
|
if err := handleRedisRecover(redisInfo, rollbackFile, true); err != nil {
|
||||||
global.LOG.Errorf("rollback redis from %s failed, err: %v", rollbackFile, err)
|
global.LOG.Errorf("rollback redis from %s failed, err: %v", rollbackFile, err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
global.LOG.Infof("rollback redis from %s successful", rollbackFile)
|
global.LOG.Infof("rollback redis from %s successful", rollbackFile)
|
||||||
_ = os.RemoveAll(rollbackFile)
|
_ = os.RemoveAll(rollbackFile)
|
||||||
@@ -133,7 +133,6 @@ func handleRedisRecover(redisInfo *repo.RootInfo, recoverFile string, isRollback
|
|||||||
_ = os.RemoveAll(rollbackFile)
|
_ = os.RemoveAll(rollbackFile)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}()
|
|
||||||
}
|
}
|
||||||
composeDir := fmt.Sprintf("%s/redis/%s", constant.AppInstallDir, redisInfo.Name)
|
composeDir := fmt.Sprintf("%s/redis/%s", constant.AppInstallDir, redisInfo.Name)
|
||||||
if _, err := compose.Down(composeDir + "/docker-compose.yml"); err != nil {
|
if _, err := compose.Down(composeDir + "/docker-compose.yml"); err != nil {
|
||||||
|
@@ -52,34 +52,6 @@ func (u *BackupService) WebsiteBackup(req dto.CommonBackup) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *BackupService) WebsiteRecoverByUpload(req dto.CommonRecover) error {
|
|
||||||
if err := handleUnTar(req.File, path.Dir(req.File)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
tmpDir := strings.ReplaceAll(req.File, ".tar.gz", "")
|
|
||||||
webJson, err := os.ReadFile(fmt.Sprintf("%s/website.json", tmpDir))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
var websiteInfo WebsiteInfo
|
|
||||||
if err := json.Unmarshal(webJson, &websiteInfo); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if websiteInfo.WebsiteName != req.Name {
|
|
||||||
return errors.New("the uploaded file does not match the selected website and cannot be recovered")
|
|
||||||
}
|
|
||||||
|
|
||||||
website, err := websiteRepo.GetFirst(websiteRepo.WithDomain(req.Name))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := handleWebsiteRecover(&website, tmpDir, false); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *BackupService) WebsiteRecover(req dto.CommonRecover) error {
|
func (u *BackupService) WebsiteRecover(req dto.CommonRecover) error {
|
||||||
website, err := websiteRepo.GetFirst(websiteRepo.WithDomain(req.Name))
|
website, err := websiteRepo.GetFirst(websiteRepo.WithDomain(req.Name))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -98,23 +70,35 @@ func (u *BackupService) WebsiteRecover(req dto.CommonRecover) error {
|
|||||||
|
|
||||||
func handleWebsiteRecover(website *model.Website, recoverFile string, isRollback bool) error {
|
func handleWebsiteRecover(website *model.Website, recoverFile string, isRollback bool) error {
|
||||||
fileOp := files.NewFileOp()
|
fileOp := files.NewFileOp()
|
||||||
fileDir := strings.ReplaceAll(recoverFile, ".tar.gz", "")
|
tmpPath := strings.ReplaceAll(recoverFile, ".tar.gz", "")
|
||||||
if err := fileOp.Decompress(recoverFile, path.Dir(recoverFile), files.TarGz); err != nil {
|
if err := handleUnTar(recoverFile, path.Dir(recoverFile)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
_ = os.RemoveAll(fileDir)
|
_ = os.RemoveAll(tmpPath)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
itemDir := fmt.Sprintf("%s/%s", fileDir, website.Alias)
|
temPathWithName := tmpPath + "/" + website.Alias
|
||||||
if !fileOp.Stat(itemDir+".conf") || !fileOp.Stat(itemDir+".web.tar.gz") {
|
if !fileOp.Stat(tmpPath+"/website.json") || !fileOp.Stat(temPathWithName+".conf") || !fileOp.Stat(temPathWithName+".web.tar.gz") {
|
||||||
return errors.New("the wrong recovery package does not have .conf or .web.tar.gz files")
|
return errors.New("the wrong recovery package does not have .conf or .web.tar.gz files")
|
||||||
}
|
}
|
||||||
if website.Type == constant.Deployment {
|
if website.Type == constant.Deployment {
|
||||||
if !fileOp.Stat(itemDir+".sql.gz") || !fileOp.Stat(itemDir+".app.tar.gz") {
|
if !fileOp.Stat(temPathWithName + ".app.tar.gz") {
|
||||||
return errors.New("the wrong recovery package does not have .sql.gz or .app.tar.gz files")
|
return errors.New("the wrong recovery package does not have .app.tar.gz files")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var oldWebsite model.Website
|
||||||
|
websiteJson, err := os.ReadFile(tmpPath + "/website.json")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(websiteJson, &oldWebsite); err != nil {
|
||||||
|
return fmt.Errorf("unmarshal app.json failed, err: %v", err)
|
||||||
|
}
|
||||||
|
if oldWebsite.Alias != website.Alias || oldWebsite.Type != website.Type || oldWebsite.ID != website.ID {
|
||||||
|
return errors.New("the current backup file does not match the application")
|
||||||
|
}
|
||||||
|
|
||||||
isOk := false
|
isOk := false
|
||||||
if !isRollback {
|
if !isRollback {
|
||||||
rollbackFile := fmt.Sprintf("%s/original/website/%s_%s.tar.gz", global.CONF.System.BaseDir, website.Alias, time.Now().Format("20060102150405"))
|
rollbackFile := fmt.Sprintf("%s/original/website/%s_%s.tar.gz", global.CONF.System.BaseDir, website.Alias, time.Now().Format("20060102150405"))
|
||||||
@@ -125,6 +109,7 @@ func handleWebsiteRecover(website *model.Website, recoverFile string, isRollback
|
|||||||
if !isOk {
|
if !isOk {
|
||||||
if err := handleWebsiteRecover(website, rollbackFile, true); err != nil {
|
if err := handleWebsiteRecover(website, rollbackFile, true); err != nil {
|
||||||
global.LOG.Errorf("rollback website %s from %s failed, err: %v", website.Alias, rollbackFile, err)
|
global.LOG.Errorf("rollback website %s from %s failed, err: %v", website.Alias, rollbackFile, err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
global.LOG.Infof("rollback website %s from %s successful", website.Alias, rollbackFile)
|
global.LOG.Infof("rollback website %s from %s successful", website.Alias, rollbackFile)
|
||||||
_ = os.RemoveAll(rollbackFile)
|
_ = os.RemoveAll(rollbackFile)
|
||||||
@@ -139,31 +124,16 @@ func handleWebsiteRecover(website *model.Website, recoverFile string, isRollback
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
nginxConfPath := fmt.Sprintf("%s/openresty/%s/conf/conf.d", constant.AppInstallDir, nginxInfo.Name)
|
nginxConfPath := fmt.Sprintf("%s/openresty/%s/conf/conf.d", constant.AppInstallDir, nginxInfo.Name)
|
||||||
if err := fileOp.CopyFile(fmt.Sprintf("%s/%s.conf", fileDir, website.Alias), nginxConfPath); err != nil {
|
if err := fileOp.CopyFile(fmt.Sprintf("%s/%s.conf", tmpPath, website.Alias), nginxConfPath); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if website.Type == constant.Deployment {
|
if website.Type == constant.Deployment {
|
||||||
mysqlInfo, err := appInstallRepo.LoadBaseInfo(constant.AppMysql, "")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
resource, err := appInstallResourceRepo.GetFirst(appInstallResourceRepo.WithAppInstallId(website.AppInstallID))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
db, err := mysqlRepo.Get(commonRepo.WithByID(resource.ResourceId))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := handleMysqlRecover(mysqlInfo, fileDir, db.Name, fmt.Sprintf("%s.sql.gz", website.Alias), isRollback); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
app, err := appInstallRepo.GetFirst(commonRepo.WithByID(website.AppInstallID))
|
app, err := appInstallRepo.GetFirst(commonRepo.WithByID(website.AppInstallID))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := handleAppRecover(&app, fmt.Sprintf("%s/%s.app.tar.gz", fileDir, website.Alias), isRollback); err != nil {
|
if err := handleAppRecover(&app, fmt.Sprintf("%s/%s.app.tar.gz", tmpPath, website.Alias), true); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err := compose.Restart(fmt.Sprintf("%s/%s/%s/docker-compose.yml", constant.AppInstallDir, app.App.Key, app.Name)); err != nil {
|
if _, err := compose.Restart(fmt.Sprintf("%s/%s/%s/docker-compose.yml", constant.AppInstallDir, app.App.Key, app.Name)); err != nil {
|
||||||
@@ -171,7 +141,7 @@ func handleWebsiteRecover(website *model.Website, recoverFile string, isRollback
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
siteDir := fmt.Sprintf("%s/openresty/%s/www/sites", constant.AppInstallDir, nginxInfo.Name)
|
siteDir := fmt.Sprintf("%s/openresty/%s/www/sites", constant.AppInstallDir, nginxInfo.Name)
|
||||||
if err := fileOp.Decompress(fmt.Sprintf("%s/%s.web.tar.gz", fileDir, website.Alias), siteDir, files.TarGz); err != nil {
|
if err := handleUnTar(fmt.Sprintf("%s/%s.web.tar.gz", tmpPath, website.Alias), siteDir); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
stdout, err := cmd.Execf("docker exec -i %s nginx -s reload", nginxInfo.ContainerName)
|
stdout, err := cmd.Execf("docker exec -i %s nginx -s reload", nginxInfo.ContainerName)
|
||||||
@@ -179,12 +149,10 @@ func handleWebsiteRecover(website *model.Website, recoverFile string, isRollback
|
|||||||
return errors.New(string(stdout))
|
return errors.New(string(stdout))
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
if err := websiteRepo.SaveWithoutCtx(&oldWebsite); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
type WebsiteInfo struct {
|
|
||||||
WebsiteName string `json:"websiteName"`
|
|
||||||
WebsiteType string `json:"websiteType"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleWebsiteBackup(website *model.Website, backupDir, fileName string) error {
|
func handleWebsiteBackup(website *model.Website, backupDir, fileName string) error {
|
||||||
@@ -199,14 +167,11 @@ func handleWebsiteBackup(website *model.Website, backupDir, fileName string) err
|
|||||||
_ = os.RemoveAll(tmpDir)
|
_ = os.RemoveAll(tmpDir)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
var websiteInfo WebsiteInfo
|
remarkInfo, _ := json.Marshal(website)
|
||||||
websiteInfo.WebsiteType = website.Type
|
|
||||||
websiteInfo.WebsiteName = website.PrimaryDomain
|
|
||||||
remarkInfo, _ := json.Marshal(websiteInfo)
|
|
||||||
if err := fileOp.SaveFile(tmpDir+"/website.json", string(remarkInfo), fs.ModePerm); err != nil {
|
if err := fileOp.SaveFile(tmpDir+"/website.json", string(remarkInfo), fs.ModePerm); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
global.LOG.Info("put websitejson into tmp dir successful")
|
global.LOG.Info("put website.json into tmp dir successful")
|
||||||
|
|
||||||
nginxInfo, err := appInstallRepo.LoadBaseInfo(constant.AppOpenresty, "")
|
nginxInfo, err := appInstallRepo.LoadBaseInfo(constant.AppOpenresty, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -219,21 +184,6 @@ func handleWebsiteBackup(website *model.Website, backupDir, fileName string) err
|
|||||||
global.LOG.Info("put openresty conf into tmp dir successful")
|
global.LOG.Info("put openresty conf into tmp dir successful")
|
||||||
|
|
||||||
if website.Type == constant.Deployment {
|
if website.Type == constant.Deployment {
|
||||||
mysqlInfo, err := appInstallRepo.LoadBaseInfo(constant.AppMysql, "")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
resource, err := appInstallResourceRepo.GetFirst(appInstallResourceRepo.WithAppInstallId(website.AppInstallID))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
db, err := mysqlRepo.Get(commonRepo.WithByID(resource.ResourceId))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := handleMysqlBackup(mysqlInfo, tmpDir, db.Name, fmt.Sprintf("%s.sql.gz", website.Alias)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
app, err := appInstallRepo.GetFirst(commonRepo.WithByID(website.AppInstallID))
|
app, err := appInstallRepo.GetFirst(commonRepo.WithByID(website.AppInstallID))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -241,13 +191,13 @@ func handleWebsiteBackup(website *model.Website, backupDir, fileName string) err
|
|||||||
if err := handleAppBackup(&app, tmpDir, fmt.Sprintf("%s.app.tar.gz", website.Alias)); err != nil {
|
if err := handleAppBackup(&app, tmpDir, fmt.Sprintf("%s.app.tar.gz", website.Alias)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
global.LOG.Info("put app tar into tmp dir successful")
|
global.LOG.Info("put app.tar.gz into tmp dir successful")
|
||||||
}
|
}
|
||||||
websiteDir := fmt.Sprintf("%s/openresty/%s/www/sites/%s", constant.AppInstallDir, nginxInfo.Name, website.Alias)
|
websiteDir := fmt.Sprintf("%s/openresty/%s/www/sites/%s", constant.AppInstallDir, nginxInfo.Name, website.Alias)
|
||||||
if err := fileOp.Compress([]string{websiteDir}, tmpDir, fmt.Sprintf("%s.web.tar.gz", website.Alias), files.TarGz); err != nil {
|
if err := fileOp.Compress([]string{websiteDir}, tmpDir, fmt.Sprintf("%s.web.tar.gz", website.Alias), files.TarGz); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
global.LOG.Info("put website tar into tmp dir successful, now start to tar tmp dir")
|
global.LOG.Info("put web.tar.gz into tmp dir successful, now start to tar tmp dir")
|
||||||
if err := fileOp.Compress([]string{tmpDir}, backupDir, fileName, files.TarGz); err != nil {
|
if err := fileOp.Compress([]string{tmpDir}, backupDir, fileName, files.TarGz); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@@ -161,7 +161,7 @@ func (u *MysqlService) Delete(ctx context.Context, req dto.MysqlDBDelete) error
|
|||||||
}
|
}
|
||||||
global.LOG.Info("execute delete database sql successful, now start to drop uploads and records")
|
global.LOG.Info("execute delete database sql successful, now start to drop uploads and records")
|
||||||
|
|
||||||
uploadDir := fmt.Sprintf("%s/uploads/database/mysql/%s/%s", constant.DataDir, app.Name, db.Name)
|
uploadDir := fmt.Sprintf("%s/1panel/uploads/database/mysql/%s/%s", global.CONF.System.BaseDir, app.Name, db.Name)
|
||||||
if _, err := os.Stat(uploadDir); err == nil {
|
if _, err := os.Stat(uploadDir); err == nil {
|
||||||
_ = os.RemoveAll(uploadDir)
|
_ = os.RemoveAll(uploadDir)
|
||||||
}
|
}
|
||||||
|
@@ -46,7 +46,6 @@ var ServiceGroupApp = new(ServiceGroup)
|
|||||||
var (
|
var (
|
||||||
commonRepo = repo.RepoGroupApp.CommonRepo
|
commonRepo = repo.RepoGroupApp.CommonRepo
|
||||||
|
|
||||||
appInstallBackupRepo = repo.RepoGroupApp.AppInstallBackupRepo
|
|
||||||
appRepo = repo.RepoGroupApp.AppRepo
|
appRepo = repo.RepoGroupApp.AppRepo
|
||||||
appTagRepo = repo.RepoGroupApp.AppTagRepo
|
appTagRepo = repo.RepoGroupApp.AppTagRepo
|
||||||
appDetailRepo = repo.RepoGroupApp.AppDetailRepo
|
appDetailRepo = repo.RepoGroupApp.AppDetailRepo
|
||||||
|
@@ -2,16 +2,17 @@ package service
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/dto/response"
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/buserr"
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/app/dto/response"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/buserr"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/global"
|
"github.com/1Panel-dev/1Panel/backend/global"
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/common"
|
"github.com/1Panel-dev/1Panel/backend/utils/common"
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
||||||
@@ -35,6 +36,37 @@ func (f FileService) GetFileList(op request.FileOption) (response.FileInfo, erro
|
|||||||
return fileInfo, nil
|
return fileInfo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f FileService) SearchUploadWithPage(req request.SearchUploadWithPage) (int64, interface{}, error) {
|
||||||
|
var (
|
||||||
|
files []response.UploadInfo
|
||||||
|
backDatas []response.UploadInfo
|
||||||
|
)
|
||||||
|
|
||||||
|
_ = filepath.Walk(req.Path, func(path string, info os.FileInfo, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if !info.IsDir() {
|
||||||
|
files = append(files, response.UploadInfo{
|
||||||
|
CreatedAt: info.ModTime().Format("2006-01-02 15:04:05"),
|
||||||
|
Size: int(info.Size()),
|
||||||
|
Name: info.Name(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
total, start, end := len(files), (req.Page-1)*req.PageSize, req.Page*req.PageSize
|
||||||
|
if start > total {
|
||||||
|
backDatas = make([]response.UploadInfo, 0)
|
||||||
|
} else {
|
||||||
|
if end >= total {
|
||||||
|
end = total
|
||||||
|
}
|
||||||
|
backDatas = files[start:end]
|
||||||
|
}
|
||||||
|
return int64(total), backDatas, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (f FileService) GetFileTree(op request.FileOption) ([]response.FileTree, error) {
|
func (f FileService) GetFileTree(op request.FileOption) ([]response.FileTree, error) {
|
||||||
var treeArray []response.FileTree
|
var treeArray []response.FileTree
|
||||||
info, err := files.NewFileInfo(op.FileOption)
|
info, err := files.NewFileInfo(op.FileOption)
|
||||||
|
@@ -15,6 +15,7 @@ import (
|
|||||||
"github.com/1Panel-dev/1Panel/backend/app/dto/response"
|
"github.com/1Panel-dev/1Panel/backend/app/dto/response"
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/repo"
|
"github.com/1Panel-dev/1Panel/backend/app/repo"
|
||||||
"github.com/1Panel-dev/1Panel/backend/buserr"
|
"github.com/1Panel-dev/1Panel/backend/buserr"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/global"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||||
@@ -257,18 +258,23 @@ func (w WebsiteService) DeleteWebsite(ctx context.Context, req request.WebsiteDe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if req.DeleteBackup {
|
|
||||||
backups, _ := backupRepo.ListRecord(backupRepo.WithByType("website-"+website.Type), commonRepo.WithByName(website.PrimaryDomain))
|
uploadDir := fmt.Sprintf("%s/1panel/uploads/website/%s", global.CONF.System.BaseDir, website.Alias)
|
||||||
if len(backups) > 0 {
|
if _, err := os.Stat(uploadDir); err == nil {
|
||||||
fileOp := files.NewFileOp()
|
_ = os.RemoveAll(uploadDir)
|
||||||
for _, b := range backups {
|
|
||||||
_ = fileOp.DeleteDir(b.FileDir)
|
|
||||||
}
|
}
|
||||||
if err := backupRepo.DeleteRecord(ctx, backupRepo.WithByType("website-"+website.Type), commonRepo.WithByName(website.PrimaryDomain)); err != nil {
|
if req.DeleteBackup {
|
||||||
|
localDir, err := loadLocalDir()
|
||||||
|
if err != nil && !req.ForceDelete {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
backupDir := fmt.Sprintf("%s/website/%s", localDir, website.Alias)
|
||||||
|
if _, err := os.Stat(backupDir); err == nil {
|
||||||
|
_ = os.RemoveAll(backupDir)
|
||||||
}
|
}
|
||||||
|
global.LOG.Infof("delete website %s backups successful", website.Alias)
|
||||||
}
|
}
|
||||||
|
_ = backupRepo.DeleteRecord(ctx, commonRepo.WithByType("website"), commonRepo.WithByName(website.Alias))
|
||||||
|
|
||||||
if err := websiteRepo.DeleteBy(ctx, commonRepo.WithByID(req.ID)); err != nil {
|
if err := websiteRepo.DeleteBy(ctx, commonRepo.WithByID(req.ID)); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@@ -178,7 +178,7 @@ var AddTableCronjob = &gormigrate.Migration{
|
|||||||
var AddTableApp = &gormigrate.Migration{
|
var AddTableApp = &gormigrate.Migration{
|
||||||
ID: "20200921-add-table-app",
|
ID: "20200921-add-table-app",
|
||||||
Migrate: func(tx *gorm.DB) error {
|
Migrate: func(tx *gorm.DB) error {
|
||||||
return tx.AutoMigrate(&model.App{}, &model.AppDetail{}, &model.Tag{}, &model.AppTag{}, &model.AppInstall{}, &model.AppInstallResource{}, &model.AppInstallBackup{})
|
return tx.AutoMigrate(&model.App{}, &model.AppDetail{}, &model.Tag{}, &model.AppTag{}, &model.AppInstall{}, &model.AppInstallResource{})
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -29,8 +29,6 @@ func (a *AppRouter) InitAppRouter(Router *gin.RouterGroup) {
|
|||||||
appRouter.POST("/installed/search", baseApi.SearchAppInstalled)
|
appRouter.POST("/installed/search", baseApi.SearchAppInstalled)
|
||||||
appRouter.POST("/installed/op", baseApi.OperateInstalled)
|
appRouter.POST("/installed/op", baseApi.OperateInstalled)
|
||||||
appRouter.POST("/installed/sync", baseApi.SyncInstalled)
|
appRouter.POST("/installed/sync", baseApi.SyncInstalled)
|
||||||
appRouter.POST("/installed/backups", baseApi.SearchInstalledBackup)
|
|
||||||
appRouter.POST("/installed/backups/del", baseApi.DeleteAppBackup)
|
|
||||||
appRouter.POST("/installed/port/change", baseApi.ChangeAppPort)
|
appRouter.POST("/installed/port/change", baseApi.ChangeAppPort)
|
||||||
appRouter.GET("/services/:key", baseApi.GetServices)
|
appRouter.GET("/services/:key", baseApi.GetServices)
|
||||||
appRouter.GET("/installed/conf/:key", baseApi.GetDefaultConfig)
|
appRouter.GET("/installed/conf/:key", baseApi.GetDefaultConfig)
|
||||||
|
@@ -15,6 +15,7 @@ func (f *FileRouter) InitFileRouter(Router *gin.RouterGroup) {
|
|||||||
baseApi := v1.ApiGroupApp.BaseApi
|
baseApi := v1.ApiGroupApp.BaseApi
|
||||||
{
|
{
|
||||||
fileRouter.POST("/search", baseApi.ListFiles)
|
fileRouter.POST("/search", baseApi.ListFiles)
|
||||||
|
fileRouter.POST("/upload/search", baseApi.SearchUploadWithPage)
|
||||||
fileRouter.POST("/tree", baseApi.GetFileTree)
|
fileRouter.POST("/tree", baseApi.GetFileTree)
|
||||||
fileRouter.POST("", baseApi.CreateFile)
|
fileRouter.POST("", baseApi.CreateFile)
|
||||||
fileRouter.POST("/del", baseApi.DeleteFile)
|
fileRouter.POST("/del", baseApi.DeleteFile)
|
||||||
|
@@ -3117,49 +3117,6 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/databases/backup": {
|
|
||||||
"post": {
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"ApiKeyAuth": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "备份 mysql 数据库",
|
|
||||||
"consumes": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
"Database Mysql"
|
|
||||||
],
|
|
||||||
"summary": "Backup mysql database",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"description": "request",
|
|
||||||
"name": "request",
|
|
||||||
"in": "body",
|
|
||||||
"required": true,
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/dto.BackupDB"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"x-panel-log": {
|
|
||||||
"BeforeFuntions": [],
|
|
||||||
"bodyKeys": [
|
|
||||||
"mysqlName",
|
|
||||||
"dbName"
|
|
||||||
],
|
|
||||||
"formatEN": "backup mysql database [mysqlName][dbName]",
|
|
||||||
"formatZH": "备份 mysql 数据库 [mysqlName][dbName]",
|
|
||||||
"paramKeys": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/databases/baseinfo": {
|
"/databases/baseinfo": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -3499,121 +3456,6 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/databases/recover": {
|
|
||||||
"post": {
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"ApiKeyAuth": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Mysql 数据库恢复",
|
|
||||||
"consumes": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
"Database Mysql"
|
|
||||||
],
|
|
||||||
"summary": "Recover mysql database",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"description": "request",
|
|
||||||
"name": "request",
|
|
||||||
"in": "body",
|
|
||||||
"required": true,
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/dto.RecoverDB"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"x-panel-log": {
|
|
||||||
"BeforeFuntions": [],
|
|
||||||
"bodyKeys": [
|
|
||||||
"mysqlName",
|
|
||||||
"dbName",
|
|
||||||
"backupName"
|
|
||||||
],
|
|
||||||
"formatEN": "恢复 mysql 数据库 [mysqlName][dbName] [backupName]",
|
|
||||||
"formatZH": "恢复 mysql 数据库 [mysqlName][dbName] [backupName]",
|
|
||||||
"paramKeys": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/databases/recover/byupload": {
|
|
||||||
"post": {
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"ApiKeyAuth": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Mysql 数据库从上传文件恢复",
|
|
||||||
"consumes": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
"Database Mysql"
|
|
||||||
],
|
|
||||||
"summary": "Recover mysql database by upload file",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"description": "request",
|
|
||||||
"name": "request",
|
|
||||||
"in": "body",
|
|
||||||
"required": true,
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/dto.UploadRecover"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"x-panel-log": {
|
|
||||||
"BeforeFuntions": [],
|
|
||||||
"bodyKeys": [
|
|
||||||
"fileDir",
|
|
||||||
"fileName",
|
|
||||||
"mysqlName",
|
|
||||||
"dbName"
|
|
||||||
],
|
|
||||||
"formatEN": "mysql database recover [fileDir]/[fileName] from [mysqlName][dbName]",
|
|
||||||
"formatZH": "mysql 数据库从 [fileDir]/[fileName] 恢复 [mysqlName][dbName]",
|
|
||||||
"paramKeys": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/databases/redis/backup": {
|
|
||||||
"post": {
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"ApiKeyAuth": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "备份 redis 数据库",
|
|
||||||
"tags": [
|
|
||||||
"Database Redis"
|
|
||||||
],
|
|
||||||
"summary": "Backup redis",
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"x-panel-log": {
|
|
||||||
"BeforeFuntions": [],
|
|
||||||
"bodyKeys": [],
|
|
||||||
"formatEN": "backup redis database",
|
|
||||||
"formatZH": "备份 redis 数据库",
|
|
||||||
"paramKeys": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/databases/redis/backup/search": {
|
"/databases/redis/backup/search": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -3854,35 +3696,6 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/databases/redis/recover": {
|
|
||||||
"post": {
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"ApiKeyAuth": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "恢复 redis 数据库",
|
|
||||||
"tags": [
|
|
||||||
"Database Redis"
|
|
||||||
],
|
|
||||||
"summary": "Recover redis",
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"x-panel-log": {
|
|
||||||
"BeforeFuntions": [],
|
|
||||||
"bodyKeys": [
|
|
||||||
"fileDir",
|
|
||||||
"fileName"
|
|
||||||
],
|
|
||||||
"formatEN": "redis database recover from [fileDir]/[fileName]",
|
|
||||||
"formatZH": "redis 数据库从 [fileDir]/[fileName] 恢复",
|
|
||||||
"paramKeys": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/databases/redis/status": {
|
"/databases/redis/status": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -4711,6 +4524,42 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/files/upload/search": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "分页获取上传文件",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"File"
|
||||||
|
],
|
||||||
|
"summary": "Page file",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/request.SearchUploadWithPage"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"type": "anrry"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/files/wget": {
|
"/files/wget": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -5046,7 +4895,7 @@ var doc = `{
|
|||||||
"in": "body",
|
"in": "body",
|
||||||
"required": true,
|
"required": true,
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/dto.OperateByID"
|
"$ref": "#/definitions/dto.BatchDeleteReq"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -5060,17 +4909,17 @@ var doc = `{
|
|||||||
{
|
{
|
||||||
"db": "hosts",
|
"db": "hosts",
|
||||||
"input_colume": "id",
|
"input_colume": "id",
|
||||||
"input_value": "id",
|
"input_value": "ids",
|
||||||
"isList": false,
|
"isList": true,
|
||||||
"output_colume": "addr",
|
"output_colume": "addr",
|
||||||
"output_value": "addr"
|
"output_value": "addrs"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"bodyKeys": [
|
"bodyKeys": [
|
||||||
"id"
|
"ids"
|
||||||
],
|
],
|
||||||
"formatEN": "delete host [addr]",
|
"formatEN": "delete host [addrs]",
|
||||||
"formatZH": "删除主机 [addr]",
|
"formatZH": "删除主机 [addrs]",
|
||||||
"paramKeys": []
|
"paramKeys": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5255,14 +5104,14 @@ var doc = `{
|
|||||||
"ApiKeyAuth": []
|
"ApiKeyAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "加载主机树",
|
"description": "获取主机列表分页",
|
||||||
"consumes": [
|
"consumes": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"Host"
|
"Host"
|
||||||
],
|
],
|
||||||
"summary": "Load host tree",
|
"summary": "Page host",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"description": "request",
|
"description": "request",
|
||||||
@@ -5270,7 +5119,7 @@ var doc = `{
|
|||||||
"in": "body",
|
"in": "body",
|
||||||
"required": true,
|
"required": true,
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/dto.SearchForTree"
|
"$ref": "#/definitions/dto.SearchHostWithPage"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -5351,21 +5200,21 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/hosts/update": {
|
"/hosts/tree": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
{
|
{
|
||||||
"ApiKeyAuth": []
|
"ApiKeyAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "更新主机",
|
"description": "加载主机树",
|
||||||
"consumes": [
|
"consumes": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"Host"
|
"Host"
|
||||||
],
|
],
|
||||||
"summary": "Update host",
|
"summary": "Load host tree",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"description": "request",
|
"description": "request",
|
||||||
@@ -5373,7 +5222,43 @@ var doc = `{
|
|||||||
"in": "body",
|
"in": "body",
|
||||||
"required": true,
|
"required": true,
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/dto.HostOperate"
|
"$ref": "#/definitions/dto.SearchForTree"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"type": "anrry"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/hosts/update": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "切换分组",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Host"
|
||||||
|
],
|
||||||
|
"summary": "Update host group",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/dto.ChangeHostGroup"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -5383,13 +5268,22 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"x-panel-log": {
|
"x-panel-log": {
|
||||||
"BeforeFuntions": [],
|
"BeforeFuntions": [
|
||||||
"bodyKeys": [
|
{
|
||||||
"name",
|
"db": "hosts",
|
||||||
"addr"
|
"input_colume": "id",
|
||||||
|
"input_value": "id",
|
||||||
|
"isList": false,
|
||||||
|
"output_colume": "addr",
|
||||||
|
"output_value": "addr"
|
||||||
|
}
|
||||||
],
|
],
|
||||||
"formatEN": "update host [name][addr]",
|
"bodyKeys": [
|
||||||
"formatZH": "更新主机信息 [name][addr]",
|
"id",
|
||||||
|
"group"
|
||||||
|
],
|
||||||
|
"formatEN": "change host [addr] group =\u003e [group]",
|
||||||
|
"formatZH": "切换主机[addr]分组 =\u003e [group]",
|
||||||
"paramKeys": []
|
"paramKeys": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5724,6 +5618,50 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/settings/backup/": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "备份系统数据",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Backup Account"
|
||||||
|
],
|
||||||
|
"summary": "Backup system data",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/dto.CommonBackup"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-panel-log": {
|
||||||
|
"BeforeFuntions": [],
|
||||||
|
"bodyKeys": [
|
||||||
|
"type",
|
||||||
|
"name",
|
||||||
|
"detailName"
|
||||||
|
],
|
||||||
|
"formatEN": "backup [type] data [name][detailName]",
|
||||||
|
"formatZH": "备份 [type] 数据 [name][detailName]",
|
||||||
|
"paramKeys": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/settings/backup/del": {
|
"/settings/backup/del": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -5902,6 +5840,96 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/settings/backup/recover": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "恢复系统数据",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Backup Account"
|
||||||
|
],
|
||||||
|
"summary": "Recover system data",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/dto.CommonRecover"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-panel-log": {
|
||||||
|
"BeforeFuntions": [],
|
||||||
|
"bodyKeys": [
|
||||||
|
"type",
|
||||||
|
"name",
|
||||||
|
"detailName",
|
||||||
|
"file"
|
||||||
|
],
|
||||||
|
"formatEN": "recover [type] data [name][detailName] from [file]",
|
||||||
|
"formatZH": "从 [file] 恢复 [type] 数据 [name][detailName]",
|
||||||
|
"paramKeys": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/settings/backup/recover/byupload": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "从上传恢复系统数据",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Backup Account"
|
||||||
|
],
|
||||||
|
"summary": "Recover system data by upload",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/dto.CommonRecover"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-panel-log": {
|
||||||
|
"BeforeFuntions": [],
|
||||||
|
"bodyKeys": [
|
||||||
|
"type",
|
||||||
|
"name",
|
||||||
|
"detailName",
|
||||||
|
"file"
|
||||||
|
],
|
||||||
|
"formatEN": "recover [type] data [name][detailName] from [file]",
|
||||||
|
"formatZH": "从 [file] 恢复 [type] 数据 [name][detailName]",
|
||||||
|
"paramKeys": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/settings/backup/search": {
|
"/settings/backup/search": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -7098,57 +7126,6 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/websites/backup": {
|
|
||||||
"post": {
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"ApiKeyAuth": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "备份网站",
|
|
||||||
"consumes": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
"Website"
|
|
||||||
],
|
|
||||||
"summary": "Backup website",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"description": "request",
|
|
||||||
"name": "request",
|
|
||||||
"in": "body",
|
|
||||||
"required": true,
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/request.WebsiteResourceReq"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"x-panel-log": {
|
|
||||||
"BeforeFuntions": [
|
|
||||||
{
|
|
||||||
"db": "websites",
|
|
||||||
"input_colume": "id",
|
|
||||||
"input_value": "id",
|
|
||||||
"isList": false,
|
|
||||||
"output_colume": "primary_domain",
|
|
||||||
"output_value": "domain"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"bodyKeys": [
|
|
||||||
"id"
|
|
||||||
],
|
|
||||||
"formatEN": "Backup website [domain]",
|
|
||||||
"formatZH": "备份网站 [domain]",
|
|
||||||
"paramKeys": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/websites/check": {
|
"/websites/check": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -8033,93 +8010,6 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/websites/recover": {
|
|
||||||
"post": {
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"ApiKeyAuth": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "从备份恢复网站",
|
|
||||||
"consumes": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
"Website"
|
|
||||||
],
|
|
||||||
"summary": "Recover website",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"description": "request",
|
|
||||||
"name": "request",
|
|
||||||
"in": "body",
|
|
||||||
"required": true,
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/request.WebsiteRecover"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"x-panel-log": {
|
|
||||||
"BeforeFuntions": [],
|
|
||||||
"bodyKeys": [
|
|
||||||
"websiteName",
|
|
||||||
"backupName"
|
|
||||||
],
|
|
||||||
"formatEN": "[websiteName] recover from backups [backupName]",
|
|
||||||
"formatZH": "[websiteName] 从备份恢复 [backupName]",
|
|
||||||
"paramKeys": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/websites/recover/byupload": {
|
|
||||||
"post": {
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"ApiKeyAuth": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "从上传恢复网站",
|
|
||||||
"consumes": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
"Website"
|
|
||||||
],
|
|
||||||
"summary": "Recover website by upload",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"description": "request",
|
|
||||||
"name": "request",
|
|
||||||
"in": "body",
|
|
||||||
"required": true,
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/request.WebsiteRecoverByFile"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"x-panel-log": {
|
|
||||||
"BeforeFuntions": [],
|
|
||||||
"bodyKeys": [
|
|
||||||
"websiteName",
|
|
||||||
"fileDir",
|
|
||||||
"fileName"
|
|
||||||
],
|
|
||||||
"formatEN": "[websiteName] recover from uploads [fileDir]/[fileName]",
|
|
||||||
"formatZH": "[websiteName] 从上传恢复 [fileDir]/[fileName]",
|
|
||||||
"paramKeys": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/websites/search": {
|
"/websites/search": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -8565,21 +8455,6 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"definitions": {
|
"definitions": {
|
||||||
"dto.BackupDB": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"dbName",
|
|
||||||
"mysqlName"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"dbName": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"mysqlName": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dto.BackupOperate": {
|
"dto.BackupOperate": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
@@ -8671,6 +8546,21 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"dto.ChangeHostGroup": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"group",
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"group": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"dto.CleanLog": {
|
"dto.CleanLog": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
@@ -8718,6 +8608,55 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"dto.CommonBackup": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"detailName": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"app",
|
||||||
|
"mysql",
|
||||||
|
"redis",
|
||||||
|
"website"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dto.CommonRecover": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"detailName": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"file": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"app",
|
||||||
|
"mysql",
|
||||||
|
"redis",
|
||||||
|
"website"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"dto.ComposeCreate": {
|
"dto.ComposeCreate": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
@@ -10183,25 +10122,6 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dto.RecoverDB": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"backupName",
|
|
||||||
"dbName",
|
|
||||||
"mysqlName"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"backupName": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"dbName": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"mysqlName": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dto.RedisConf": {
|
"dto.RedisConf": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -10343,6 +10263,27 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"dto.SearchHostWithPage": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"page",
|
||||||
|
"pageSize"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"group": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"info": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"page": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"pageSize": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"dto.SearchLgLogWithPage": {
|
"dto.SearchLgLogWithPage": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
@@ -10608,27 +10549,6 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dto.UploadRecover": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"dbName",
|
|
||||||
"mysqlName"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"dbName": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"fileDir": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"fileName": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"mysqlName": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dto.UserLoginInfo": {
|
"dto.UserLoginInfo": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -11565,6 +11485,25 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"request.SearchUploadWithPage": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"page",
|
||||||
|
"pageSize",
|
||||||
|
"path"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"page": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"pageSize": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"path": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"request.WebsiteAcmeAccountCreate": {
|
"request.WebsiteAcmeAccountCreate": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
@@ -11890,48 +11829,6 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"request.WebsiteRecover": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"backupName",
|
|
||||||
"type",
|
|
||||||
"websiteName"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"backupName": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"websiteName": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"request.WebsiteRecoverByFile": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"fileDir",
|
|
||||||
"fileName",
|
|
||||||
"type",
|
|
||||||
"websiteName"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"fileDir": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"fileName": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"websiteName": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"request.WebsiteResourceReq": {
|
"request.WebsiteResourceReq": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
|
@@ -3103,49 +3103,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/databases/backup": {
|
|
||||||
"post": {
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"ApiKeyAuth": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "备份 mysql 数据库",
|
|
||||||
"consumes": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
"Database Mysql"
|
|
||||||
],
|
|
||||||
"summary": "Backup mysql database",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"description": "request",
|
|
||||||
"name": "request",
|
|
||||||
"in": "body",
|
|
||||||
"required": true,
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/dto.BackupDB"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"x-panel-log": {
|
|
||||||
"BeforeFuntions": [],
|
|
||||||
"bodyKeys": [
|
|
||||||
"mysqlName",
|
|
||||||
"dbName"
|
|
||||||
],
|
|
||||||
"formatEN": "backup mysql database [mysqlName][dbName]",
|
|
||||||
"formatZH": "备份 mysql 数据库 [mysqlName][dbName]",
|
|
||||||
"paramKeys": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/databases/baseinfo": {
|
"/databases/baseinfo": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -3485,121 +3442,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/databases/recover": {
|
|
||||||
"post": {
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"ApiKeyAuth": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Mysql 数据库恢复",
|
|
||||||
"consumes": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
"Database Mysql"
|
|
||||||
],
|
|
||||||
"summary": "Recover mysql database",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"description": "request",
|
|
||||||
"name": "request",
|
|
||||||
"in": "body",
|
|
||||||
"required": true,
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/dto.RecoverDB"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"x-panel-log": {
|
|
||||||
"BeforeFuntions": [],
|
|
||||||
"bodyKeys": [
|
|
||||||
"mysqlName",
|
|
||||||
"dbName",
|
|
||||||
"backupName"
|
|
||||||
],
|
|
||||||
"formatEN": "恢复 mysql 数据库 [mysqlName][dbName] [backupName]",
|
|
||||||
"formatZH": "恢复 mysql 数据库 [mysqlName][dbName] [backupName]",
|
|
||||||
"paramKeys": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/databases/recover/byupload": {
|
|
||||||
"post": {
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"ApiKeyAuth": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Mysql 数据库从上传文件恢复",
|
|
||||||
"consumes": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
"Database Mysql"
|
|
||||||
],
|
|
||||||
"summary": "Recover mysql database by upload file",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"description": "request",
|
|
||||||
"name": "request",
|
|
||||||
"in": "body",
|
|
||||||
"required": true,
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/dto.UploadRecover"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"x-panel-log": {
|
|
||||||
"BeforeFuntions": [],
|
|
||||||
"bodyKeys": [
|
|
||||||
"fileDir",
|
|
||||||
"fileName",
|
|
||||||
"mysqlName",
|
|
||||||
"dbName"
|
|
||||||
],
|
|
||||||
"formatEN": "mysql database recover [fileDir]/[fileName] from [mysqlName][dbName]",
|
|
||||||
"formatZH": "mysql 数据库从 [fileDir]/[fileName] 恢复 [mysqlName][dbName]",
|
|
||||||
"paramKeys": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/databases/redis/backup": {
|
|
||||||
"post": {
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"ApiKeyAuth": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "备份 redis 数据库",
|
|
||||||
"tags": [
|
|
||||||
"Database Redis"
|
|
||||||
],
|
|
||||||
"summary": "Backup redis",
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"x-panel-log": {
|
|
||||||
"BeforeFuntions": [],
|
|
||||||
"bodyKeys": [],
|
|
||||||
"formatEN": "backup redis database",
|
|
||||||
"formatZH": "备份 redis 数据库",
|
|
||||||
"paramKeys": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/databases/redis/backup/search": {
|
"/databases/redis/backup/search": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -3840,35 +3682,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/databases/redis/recover": {
|
|
||||||
"post": {
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"ApiKeyAuth": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "恢复 redis 数据库",
|
|
||||||
"tags": [
|
|
||||||
"Database Redis"
|
|
||||||
],
|
|
||||||
"summary": "Recover redis",
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"x-panel-log": {
|
|
||||||
"BeforeFuntions": [],
|
|
||||||
"bodyKeys": [
|
|
||||||
"fileDir",
|
|
||||||
"fileName"
|
|
||||||
],
|
|
||||||
"formatEN": "redis database recover from [fileDir]/[fileName]",
|
|
||||||
"formatZH": "redis 数据库从 [fileDir]/[fileName] 恢复",
|
|
||||||
"paramKeys": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/databases/redis/status": {
|
"/databases/redis/status": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -4697,6 +4510,42 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/files/upload/search": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "分页获取上传文件",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"File"
|
||||||
|
],
|
||||||
|
"summary": "Page file",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/request.SearchUploadWithPage"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"type": "anrry"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/files/wget": {
|
"/files/wget": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -5032,7 +4881,7 @@
|
|||||||
"in": "body",
|
"in": "body",
|
||||||
"required": true,
|
"required": true,
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/dto.OperateByID"
|
"$ref": "#/definitions/dto.BatchDeleteReq"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -5046,17 +4895,17 @@
|
|||||||
{
|
{
|
||||||
"db": "hosts",
|
"db": "hosts",
|
||||||
"input_colume": "id",
|
"input_colume": "id",
|
||||||
"input_value": "id",
|
"input_value": "ids",
|
||||||
"isList": false,
|
"isList": true,
|
||||||
"output_colume": "addr",
|
"output_colume": "addr",
|
||||||
"output_value": "addr"
|
"output_value": "addrs"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"bodyKeys": [
|
"bodyKeys": [
|
||||||
"id"
|
"ids"
|
||||||
],
|
],
|
||||||
"formatEN": "delete host [addr]",
|
"formatEN": "delete host [addrs]",
|
||||||
"formatZH": "删除主机 [addr]",
|
"formatZH": "删除主机 [addrs]",
|
||||||
"paramKeys": []
|
"paramKeys": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5241,14 +5090,14 @@
|
|||||||
"ApiKeyAuth": []
|
"ApiKeyAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "加载主机树",
|
"description": "获取主机列表分页",
|
||||||
"consumes": [
|
"consumes": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"Host"
|
"Host"
|
||||||
],
|
],
|
||||||
"summary": "Load host tree",
|
"summary": "Page host",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"description": "request",
|
"description": "request",
|
||||||
@@ -5256,7 +5105,7 @@
|
|||||||
"in": "body",
|
"in": "body",
|
||||||
"required": true,
|
"required": true,
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/dto.SearchForTree"
|
"$ref": "#/definitions/dto.SearchHostWithPage"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -5337,21 +5186,21 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/hosts/update": {
|
"/hosts/tree": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
{
|
{
|
||||||
"ApiKeyAuth": []
|
"ApiKeyAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "更新主机",
|
"description": "加载主机树",
|
||||||
"consumes": [
|
"consumes": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"Host"
|
"Host"
|
||||||
],
|
],
|
||||||
"summary": "Update host",
|
"summary": "Load host tree",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"description": "request",
|
"description": "request",
|
||||||
@@ -5359,7 +5208,43 @@
|
|||||||
"in": "body",
|
"in": "body",
|
||||||
"required": true,
|
"required": true,
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/dto.HostOperate"
|
"$ref": "#/definitions/dto.SearchForTree"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"type": "anrry"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/hosts/update": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "切换分组",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Host"
|
||||||
|
],
|
||||||
|
"summary": "Update host group",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/dto.ChangeHostGroup"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -5369,13 +5254,22 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"x-panel-log": {
|
"x-panel-log": {
|
||||||
"BeforeFuntions": [],
|
"BeforeFuntions": [
|
||||||
"bodyKeys": [
|
{
|
||||||
"name",
|
"db": "hosts",
|
||||||
"addr"
|
"input_colume": "id",
|
||||||
|
"input_value": "id",
|
||||||
|
"isList": false,
|
||||||
|
"output_colume": "addr",
|
||||||
|
"output_value": "addr"
|
||||||
|
}
|
||||||
],
|
],
|
||||||
"formatEN": "update host [name][addr]",
|
"bodyKeys": [
|
||||||
"formatZH": "更新主机信息 [name][addr]",
|
"id",
|
||||||
|
"group"
|
||||||
|
],
|
||||||
|
"formatEN": "change host [addr] group =\u003e [group]",
|
||||||
|
"formatZH": "切换主机[addr]分组 =\u003e [group]",
|
||||||
"paramKeys": []
|
"paramKeys": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5710,6 +5604,50 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/settings/backup/": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "备份系统数据",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Backup Account"
|
||||||
|
],
|
||||||
|
"summary": "Backup system data",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/dto.CommonBackup"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-panel-log": {
|
||||||
|
"BeforeFuntions": [],
|
||||||
|
"bodyKeys": [
|
||||||
|
"type",
|
||||||
|
"name",
|
||||||
|
"detailName"
|
||||||
|
],
|
||||||
|
"formatEN": "backup [type] data [name][detailName]",
|
||||||
|
"formatZH": "备份 [type] 数据 [name][detailName]",
|
||||||
|
"paramKeys": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/settings/backup/del": {
|
"/settings/backup/del": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -5888,6 +5826,96 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/settings/backup/recover": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "恢复系统数据",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Backup Account"
|
||||||
|
],
|
||||||
|
"summary": "Recover system data",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/dto.CommonRecover"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-panel-log": {
|
||||||
|
"BeforeFuntions": [],
|
||||||
|
"bodyKeys": [
|
||||||
|
"type",
|
||||||
|
"name",
|
||||||
|
"detailName",
|
||||||
|
"file"
|
||||||
|
],
|
||||||
|
"formatEN": "recover [type] data [name][detailName] from [file]",
|
||||||
|
"formatZH": "从 [file] 恢复 [type] 数据 [name][detailName]",
|
||||||
|
"paramKeys": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/settings/backup/recover/byupload": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "从上传恢复系统数据",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Backup Account"
|
||||||
|
],
|
||||||
|
"summary": "Recover system data by upload",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/dto.CommonRecover"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-panel-log": {
|
||||||
|
"BeforeFuntions": [],
|
||||||
|
"bodyKeys": [
|
||||||
|
"type",
|
||||||
|
"name",
|
||||||
|
"detailName",
|
||||||
|
"file"
|
||||||
|
],
|
||||||
|
"formatEN": "recover [type] data [name][detailName] from [file]",
|
||||||
|
"formatZH": "从 [file] 恢复 [type] 数据 [name][detailName]",
|
||||||
|
"paramKeys": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/settings/backup/search": {
|
"/settings/backup/search": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -7084,57 +7112,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/websites/backup": {
|
|
||||||
"post": {
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"ApiKeyAuth": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "备份网站",
|
|
||||||
"consumes": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
"Website"
|
|
||||||
],
|
|
||||||
"summary": "Backup website",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"description": "request",
|
|
||||||
"name": "request",
|
|
||||||
"in": "body",
|
|
||||||
"required": true,
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/request.WebsiteResourceReq"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"x-panel-log": {
|
|
||||||
"BeforeFuntions": [
|
|
||||||
{
|
|
||||||
"db": "websites",
|
|
||||||
"input_colume": "id",
|
|
||||||
"input_value": "id",
|
|
||||||
"isList": false,
|
|
||||||
"output_colume": "primary_domain",
|
|
||||||
"output_value": "domain"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"bodyKeys": [
|
|
||||||
"id"
|
|
||||||
],
|
|
||||||
"formatEN": "Backup website [domain]",
|
|
||||||
"formatZH": "备份网站 [domain]",
|
|
||||||
"paramKeys": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/websites/check": {
|
"/websites/check": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -8019,93 +7996,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/websites/recover": {
|
|
||||||
"post": {
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"ApiKeyAuth": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "从备份恢复网站",
|
|
||||||
"consumes": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
"Website"
|
|
||||||
],
|
|
||||||
"summary": "Recover website",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"description": "request",
|
|
||||||
"name": "request",
|
|
||||||
"in": "body",
|
|
||||||
"required": true,
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/request.WebsiteRecover"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"x-panel-log": {
|
|
||||||
"BeforeFuntions": [],
|
|
||||||
"bodyKeys": [
|
|
||||||
"websiteName",
|
|
||||||
"backupName"
|
|
||||||
],
|
|
||||||
"formatEN": "[websiteName] recover from backups [backupName]",
|
|
||||||
"formatZH": "[websiteName] 从备份恢复 [backupName]",
|
|
||||||
"paramKeys": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/websites/recover/byupload": {
|
|
||||||
"post": {
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"ApiKeyAuth": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "从上传恢复网站",
|
|
||||||
"consumes": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
"Website"
|
|
||||||
],
|
|
||||||
"summary": "Recover website by upload",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"description": "request",
|
|
||||||
"name": "request",
|
|
||||||
"in": "body",
|
|
||||||
"required": true,
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/request.WebsiteRecoverByFile"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"x-panel-log": {
|
|
||||||
"BeforeFuntions": [],
|
|
||||||
"bodyKeys": [
|
|
||||||
"websiteName",
|
|
||||||
"fileDir",
|
|
||||||
"fileName"
|
|
||||||
],
|
|
||||||
"formatEN": "[websiteName] recover from uploads [fileDir]/[fileName]",
|
|
||||||
"formatZH": "[websiteName] 从上传恢复 [fileDir]/[fileName]",
|
|
||||||
"paramKeys": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/websites/search": {
|
"/websites/search": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -8551,21 +8441,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"definitions": {
|
"definitions": {
|
||||||
"dto.BackupDB": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"dbName",
|
|
||||||
"mysqlName"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"dbName": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"mysqlName": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dto.BackupOperate": {
|
"dto.BackupOperate": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
@@ -8657,6 +8532,21 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"dto.ChangeHostGroup": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"group",
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"group": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"dto.CleanLog": {
|
"dto.CleanLog": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
@@ -8704,6 +8594,55 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"dto.CommonBackup": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"detailName": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"app",
|
||||||
|
"mysql",
|
||||||
|
"redis",
|
||||||
|
"website"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dto.CommonRecover": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"detailName": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"file": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"app",
|
||||||
|
"mysql",
|
||||||
|
"redis",
|
||||||
|
"website"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"dto.ComposeCreate": {
|
"dto.ComposeCreate": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
@@ -10169,25 +10108,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dto.RecoverDB": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"backupName",
|
|
||||||
"dbName",
|
|
||||||
"mysqlName"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"backupName": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"dbName": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"mysqlName": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dto.RedisConf": {
|
"dto.RedisConf": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -10329,6 +10249,27 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"dto.SearchHostWithPage": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"page",
|
||||||
|
"pageSize"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"group": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"info": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"page": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"pageSize": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"dto.SearchLgLogWithPage": {
|
"dto.SearchLgLogWithPage": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
@@ -10594,27 +10535,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dto.UploadRecover": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"dbName",
|
|
||||||
"mysqlName"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"dbName": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"fileDir": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"fileName": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"mysqlName": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dto.UserLoginInfo": {
|
"dto.UserLoginInfo": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -11551,6 +11471,25 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"request.SearchUploadWithPage": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"page",
|
||||||
|
"pageSize",
|
||||||
|
"path"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"page": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"pageSize": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"path": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"request.WebsiteAcmeAccountCreate": {
|
"request.WebsiteAcmeAccountCreate": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
@@ -11876,48 +11815,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"request.WebsiteRecover": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"backupName",
|
|
||||||
"type",
|
|
||||||
"websiteName"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"backupName": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"websiteName": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"request.WebsiteRecoverByFile": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"fileDir",
|
|
||||||
"fileName",
|
|
||||||
"type",
|
|
||||||
"websiteName"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"fileDir": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"fileName": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"websiteName": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"request.WebsiteResourceReq": {
|
"request.WebsiteResourceReq": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
|
@@ -1,15 +1,5 @@
|
|||||||
basePath: /api/v1
|
basePath: /api/v1
|
||||||
definitions:
|
definitions:
|
||||||
dto.BackupDB:
|
|
||||||
properties:
|
|
||||||
dbName:
|
|
||||||
type: string
|
|
||||||
mysqlName:
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- dbName
|
|
||||||
- mysqlName
|
|
||||||
type: object
|
|
||||||
dto.BackupOperate:
|
dto.BackupOperate:
|
||||||
properties:
|
properties:
|
||||||
accessKey:
|
accessKey:
|
||||||
@@ -69,6 +59,16 @@ definitions:
|
|||||||
required:
|
required:
|
||||||
- value
|
- value
|
||||||
type: object
|
type: object
|
||||||
|
dto.ChangeHostGroup:
|
||||||
|
properties:
|
||||||
|
group:
|
||||||
|
type: string
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
required:
|
||||||
|
- group
|
||||||
|
- id
|
||||||
|
type: object
|
||||||
dto.CleanLog:
|
dto.CleanLog:
|
||||||
properties:
|
properties:
|
||||||
logType:
|
logType:
|
||||||
@@ -100,6 +100,40 @@ definitions:
|
|||||||
- command
|
- command
|
||||||
- name
|
- name
|
||||||
type: object
|
type: object
|
||||||
|
dto.CommonBackup:
|
||||||
|
properties:
|
||||||
|
detailName:
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
type:
|
||||||
|
enum:
|
||||||
|
- app
|
||||||
|
- mysql
|
||||||
|
- redis
|
||||||
|
- website
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- type
|
||||||
|
type: object
|
||||||
|
dto.CommonRecover:
|
||||||
|
properties:
|
||||||
|
detailName:
|
||||||
|
type: string
|
||||||
|
file:
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
type:
|
||||||
|
enum:
|
||||||
|
- app
|
||||||
|
- mysql
|
||||||
|
- redis
|
||||||
|
- website
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- type
|
||||||
|
type: object
|
||||||
dto.ComposeCreate:
|
dto.ComposeCreate:
|
||||||
properties:
|
properties:
|
||||||
file:
|
file:
|
||||||
@@ -1089,19 +1123,6 @@ definitions:
|
|||||||
- pageSize
|
- pageSize
|
||||||
- type
|
- type
|
||||||
type: object
|
type: object
|
||||||
dto.RecoverDB:
|
|
||||||
properties:
|
|
||||||
backupName:
|
|
||||||
type: string
|
|
||||||
dbName:
|
|
||||||
type: string
|
|
||||||
mysqlName:
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- backupName
|
|
||||||
- dbName
|
|
||||||
- mysqlName
|
|
||||||
type: object
|
|
||||||
dto.RedisConf:
|
dto.RedisConf:
|
||||||
properties:
|
properties:
|
||||||
containerName:
|
containerName:
|
||||||
@@ -1194,6 +1215,20 @@ definitions:
|
|||||||
info:
|
info:
|
||||||
type: string
|
type: string
|
||||||
type: object
|
type: object
|
||||||
|
dto.SearchHostWithPage:
|
||||||
|
properties:
|
||||||
|
group:
|
||||||
|
type: string
|
||||||
|
info:
|
||||||
|
type: string
|
||||||
|
page:
|
||||||
|
type: integer
|
||||||
|
pageSize:
|
||||||
|
type: integer
|
||||||
|
required:
|
||||||
|
- page
|
||||||
|
- pageSize
|
||||||
|
type: object
|
||||||
dto.SearchLgLogWithPage:
|
dto.SearchLgLogWithPage:
|
||||||
properties:
|
properties:
|
||||||
ip:
|
ip:
|
||||||
@@ -1369,20 +1404,6 @@ definitions:
|
|||||||
releaseNote:
|
releaseNote:
|
||||||
type: string
|
type: string
|
||||||
type: object
|
type: object
|
||||||
dto.UploadRecover:
|
|
||||||
properties:
|
|
||||||
dbName:
|
|
||||||
type: string
|
|
||||||
fileDir:
|
|
||||||
type: string
|
|
||||||
fileName:
|
|
||||||
type: string
|
|
||||||
mysqlName:
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- dbName
|
|
||||||
- mysqlName
|
|
||||||
type: object
|
|
||||||
dto.UserLoginInfo:
|
dto.UserLoginInfo:
|
||||||
properties:
|
properties:
|
||||||
mfaSecret:
|
mfaSecret:
|
||||||
@@ -2003,6 +2024,19 @@ definitions:
|
|||||||
port:
|
port:
|
||||||
type: integer
|
type: integer
|
||||||
type: object
|
type: object
|
||||||
|
request.SearchUploadWithPage:
|
||||||
|
properties:
|
||||||
|
page:
|
||||||
|
type: integer
|
||||||
|
pageSize:
|
||||||
|
type: integer
|
||||||
|
path:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- page
|
||||||
|
- pageSize
|
||||||
|
- path
|
||||||
|
type: object
|
||||||
request.WebsiteAcmeAccountCreate:
|
request.WebsiteAcmeAccountCreate:
|
||||||
properties:
|
properties:
|
||||||
email:
|
email:
|
||||||
@@ -2221,35 +2255,6 @@ definitions:
|
|||||||
required:
|
required:
|
||||||
- id
|
- id
|
||||||
type: object
|
type: object
|
||||||
request.WebsiteRecover:
|
|
||||||
properties:
|
|
||||||
backupName:
|
|
||||||
type: string
|
|
||||||
type:
|
|
||||||
type: string
|
|
||||||
websiteName:
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- backupName
|
|
||||||
- type
|
|
||||||
- websiteName
|
|
||||||
type: object
|
|
||||||
request.WebsiteRecoverByFile:
|
|
||||||
properties:
|
|
||||||
fileDir:
|
|
||||||
type: string
|
|
||||||
fileName:
|
|
||||||
type: string
|
|
||||||
type:
|
|
||||||
type: string
|
|
||||||
websiteName:
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- fileDir
|
|
||||||
- fileName
|
|
||||||
- type
|
|
||||||
- websiteName
|
|
||||||
type: object
|
|
||||||
request.WebsiteResourceReq:
|
request.WebsiteResourceReq:
|
||||||
properties:
|
properties:
|
||||||
id:
|
id:
|
||||||
@@ -4593,34 +4598,6 @@ paths:
|
|||||||
formatEN: create mysql database [name]
|
formatEN: create mysql database [name]
|
||||||
formatZH: 创建 mysql 数据库 [name]
|
formatZH: 创建 mysql 数据库 [name]
|
||||||
paramKeys: []
|
paramKeys: []
|
||||||
/databases/backup:
|
|
||||||
post:
|
|
||||||
consumes:
|
|
||||||
- application/json
|
|
||||||
description: 备份 mysql 数据库
|
|
||||||
parameters:
|
|
||||||
- description: request
|
|
||||||
in: body
|
|
||||||
name: request
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/dto.BackupDB'
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: ""
|
|
||||||
security:
|
|
||||||
- ApiKeyAuth: []
|
|
||||||
summary: Backup mysql database
|
|
||||||
tags:
|
|
||||||
- Database Mysql
|
|
||||||
x-panel-log:
|
|
||||||
BeforeFuntions: []
|
|
||||||
bodyKeys:
|
|
||||||
- mysqlName
|
|
||||||
- dbName
|
|
||||||
formatEN: backup mysql database [mysqlName][dbName]
|
|
||||||
formatZH: 备份 mysql 数据库 [mysqlName][dbName]
|
|
||||||
paramKeys: []
|
|
||||||
/databases/baseinfo:
|
/databases/baseinfo:
|
||||||
get:
|
get:
|
||||||
description: 获取 mysql 基础信息
|
description: 获取 mysql 基础信息
|
||||||
@@ -4837,82 +4814,6 @@ paths:
|
|||||||
summary: List mysql database names
|
summary: List mysql database names
|
||||||
tags:
|
tags:
|
||||||
- Database Mysql
|
- Database Mysql
|
||||||
/databases/recover:
|
|
||||||
post:
|
|
||||||
consumes:
|
|
||||||
- application/json
|
|
||||||
description: Mysql 数据库恢复
|
|
||||||
parameters:
|
|
||||||
- description: request
|
|
||||||
in: body
|
|
||||||
name: request
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/dto.RecoverDB'
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: ""
|
|
||||||
security:
|
|
||||||
- ApiKeyAuth: []
|
|
||||||
summary: Recover mysql database
|
|
||||||
tags:
|
|
||||||
- Database Mysql
|
|
||||||
x-panel-log:
|
|
||||||
BeforeFuntions: []
|
|
||||||
bodyKeys:
|
|
||||||
- mysqlName
|
|
||||||
- dbName
|
|
||||||
- backupName
|
|
||||||
formatEN: 恢复 mysql 数据库 [mysqlName][dbName] [backupName]
|
|
||||||
formatZH: 恢复 mysql 数据库 [mysqlName][dbName] [backupName]
|
|
||||||
paramKeys: []
|
|
||||||
/databases/recover/byupload:
|
|
||||||
post:
|
|
||||||
consumes:
|
|
||||||
- application/json
|
|
||||||
description: Mysql 数据库从上传文件恢复
|
|
||||||
parameters:
|
|
||||||
- description: request
|
|
||||||
in: body
|
|
||||||
name: request
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/dto.UploadRecover'
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: ""
|
|
||||||
security:
|
|
||||||
- ApiKeyAuth: []
|
|
||||||
summary: Recover mysql database by upload file
|
|
||||||
tags:
|
|
||||||
- Database Mysql
|
|
||||||
x-panel-log:
|
|
||||||
BeforeFuntions: []
|
|
||||||
bodyKeys:
|
|
||||||
- fileDir
|
|
||||||
- fileName
|
|
||||||
- mysqlName
|
|
||||||
- dbName
|
|
||||||
formatEN: mysql database recover [fileDir]/[fileName] from [mysqlName][dbName]
|
|
||||||
formatZH: mysql 数据库从 [fileDir]/[fileName] 恢复 [mysqlName][dbName]
|
|
||||||
paramKeys: []
|
|
||||||
/databases/redis/backup:
|
|
||||||
post:
|
|
||||||
description: 备份 redis 数据库
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: ""
|
|
||||||
security:
|
|
||||||
- ApiKeyAuth: []
|
|
||||||
summary: Backup redis
|
|
||||||
tags:
|
|
||||||
- Database Redis
|
|
||||||
x-panel-log:
|
|
||||||
BeforeFuntions: []
|
|
||||||
bodyKeys: []
|
|
||||||
formatEN: backup redis database
|
|
||||||
formatZH: 备份 redis 数据库
|
|
||||||
paramKeys: []
|
|
||||||
/databases/redis/backup/search:
|
/databases/redis/backup/search:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
@@ -5065,25 +4966,6 @@ paths:
|
|||||||
formatEN: redis database persistence configuration update
|
formatEN: redis database persistence configuration update
|
||||||
formatZH: redis 数据库持久化配置更新
|
formatZH: redis 数据库持久化配置更新
|
||||||
paramKeys: []
|
paramKeys: []
|
||||||
/databases/redis/recover:
|
|
||||||
post:
|
|
||||||
description: 恢复 redis 数据库
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: ""
|
|
||||||
security:
|
|
||||||
- ApiKeyAuth: []
|
|
||||||
summary: Recover redis
|
|
||||||
tags:
|
|
||||||
- Database Redis
|
|
||||||
x-panel-log:
|
|
||||||
BeforeFuntions: []
|
|
||||||
bodyKeys:
|
|
||||||
- fileDir
|
|
||||||
- fileName
|
|
||||||
formatEN: redis database recover from [fileDir]/[fileName]
|
|
||||||
formatZH: redis 数据库从 [fileDir]/[fileName] 恢复
|
|
||||||
paramKeys: []
|
|
||||||
/databases/redis/status:
|
/databases/redis/status:
|
||||||
get:
|
get:
|
||||||
description: 获取 redis 状态信息
|
description: 获取 redis 状态信息
|
||||||
@@ -5610,6 +5492,28 @@ paths:
|
|||||||
formatEN: Upload file [path]
|
formatEN: Upload file [path]
|
||||||
formatZH: 上传文件 [path]
|
formatZH: 上传文件 [path]
|
||||||
paramKeys: []
|
paramKeys: []
|
||||||
|
/files/upload/search:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 分页获取上传文件
|
||||||
|
parameters:
|
||||||
|
- description: request
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/request.SearchUploadWithPage'
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
type: anrry
|
||||||
|
security:
|
||||||
|
- ApiKeyAuth: []
|
||||||
|
summary: Page file
|
||||||
|
tags:
|
||||||
|
- File
|
||||||
/files/wget:
|
/files/wget:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
@@ -5821,7 +5725,7 @@ paths:
|
|||||||
name: request
|
name: request
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/dto.OperateByID'
|
$ref: '#/definitions/dto.BatchDeleteReq'
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: ""
|
description: ""
|
||||||
@@ -5834,14 +5738,14 @@ paths:
|
|||||||
BeforeFuntions:
|
BeforeFuntions:
|
||||||
- db: hosts
|
- db: hosts
|
||||||
input_colume: id
|
input_colume: id
|
||||||
input_value: id
|
input_value: ids
|
||||||
isList: false
|
isList: true
|
||||||
output_colume: addr
|
output_colume: addr
|
||||||
output_value: addr
|
output_value: addrs
|
||||||
bodyKeys:
|
bodyKeys:
|
||||||
- id
|
- ids
|
||||||
formatEN: delete host [addr]
|
formatEN: delete host [addrs]
|
||||||
formatZH: 删除主机 [addr]
|
formatZH: 删除主机 [addrs]
|
||||||
paramKeys: []
|
paramKeys: []
|
||||||
/hosts/group:
|
/hosts/group:
|
||||||
post:
|
post:
|
||||||
@@ -5958,14 +5862,14 @@ paths:
|
|||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
- application/json
|
- application/json
|
||||||
description: 加载主机树
|
description: 获取主机列表分页
|
||||||
parameters:
|
parameters:
|
||||||
- description: request
|
- description: request
|
||||||
in: body
|
in: body
|
||||||
name: request
|
name: request
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/dto.SearchForTree'
|
$ref: '#/definitions/dto.SearchHostWithPage'
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: OK
|
description: OK
|
||||||
@@ -5973,7 +5877,7 @@ paths:
|
|||||||
type: anrry
|
type: anrry
|
||||||
security:
|
security:
|
||||||
- ApiKeyAuth: []
|
- ApiKeyAuth: []
|
||||||
summary: Load host tree
|
summary: Page host
|
||||||
tags:
|
tags:
|
||||||
- Host
|
- Host
|
||||||
/hosts/test/byid/:id:
|
/hosts/test/byid/:id:
|
||||||
@@ -6017,33 +5921,61 @@ paths:
|
|||||||
summary: Test host conn by info
|
summary: Test host conn by info
|
||||||
tags:
|
tags:
|
||||||
- Host
|
- Host
|
||||||
/hosts/update:
|
/hosts/tree:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
- application/json
|
- application/json
|
||||||
description: 更新主机
|
description: 加载主机树
|
||||||
parameters:
|
parameters:
|
||||||
- description: request
|
- description: request
|
||||||
in: body
|
in: body
|
||||||
name: request
|
name: request
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/dto.HostOperate'
|
$ref: '#/definitions/dto.SearchForTree'
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
type: anrry
|
||||||
|
security:
|
||||||
|
- ApiKeyAuth: []
|
||||||
|
summary: Load host tree
|
||||||
|
tags:
|
||||||
|
- Host
|
||||||
|
/hosts/update:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 切换分组
|
||||||
|
parameters:
|
||||||
|
- description: request
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/dto.ChangeHostGroup'
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: ""
|
description: ""
|
||||||
security:
|
security:
|
||||||
- ApiKeyAuth: []
|
- ApiKeyAuth: []
|
||||||
summary: Update host
|
summary: Update host group
|
||||||
tags:
|
tags:
|
||||||
- Host
|
- Host
|
||||||
x-panel-log:
|
x-panel-log:
|
||||||
BeforeFuntions: []
|
BeforeFuntions:
|
||||||
|
- db: hosts
|
||||||
|
input_colume: id
|
||||||
|
input_value: id
|
||||||
|
isList: false
|
||||||
|
output_colume: addr
|
||||||
|
output_value: addr
|
||||||
bodyKeys:
|
bodyKeys:
|
||||||
- name
|
- id
|
||||||
- addr
|
- group
|
||||||
formatEN: update host [name][addr]
|
formatEN: change host [addr] group => [group]
|
||||||
formatZH: 更新主机信息 [name][addr]
|
formatZH: 切换主机[addr]分组 => [group]
|
||||||
paramKeys: []
|
paramKeys: []
|
||||||
/logs/clean:
|
/logs/clean:
|
||||||
post:
|
post:
|
||||||
@@ -6252,6 +6184,35 @@ paths:
|
|||||||
formatEN: create backup account [type]
|
formatEN: create backup account [type]
|
||||||
formatZH: 创建备份账号 [type]
|
formatZH: 创建备份账号 [type]
|
||||||
paramKeys: []
|
paramKeys: []
|
||||||
|
/settings/backup/:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 备份系统数据
|
||||||
|
parameters:
|
||||||
|
- description: request
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/dto.CommonBackup'
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: ""
|
||||||
|
security:
|
||||||
|
- ApiKeyAuth: []
|
||||||
|
summary: Backup system data
|
||||||
|
tags:
|
||||||
|
- Backup Account
|
||||||
|
x-panel-log:
|
||||||
|
BeforeFuntions: []
|
||||||
|
bodyKeys:
|
||||||
|
- type
|
||||||
|
- name
|
||||||
|
- detailName
|
||||||
|
formatEN: backup [type] data [name][detailName]
|
||||||
|
formatZH: 备份 [type] 数据 [name][detailName]
|
||||||
|
paramKeys: []
|
||||||
/settings/backup/del:
|
/settings/backup/del:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
@@ -6366,6 +6327,66 @@ paths:
|
|||||||
summary: Page backup records
|
summary: Page backup records
|
||||||
tags:
|
tags:
|
||||||
- Backup Account
|
- Backup Account
|
||||||
|
/settings/backup/recover:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 恢复系统数据
|
||||||
|
parameters:
|
||||||
|
- description: request
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/dto.CommonRecover'
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: ""
|
||||||
|
security:
|
||||||
|
- ApiKeyAuth: []
|
||||||
|
summary: Recover system data
|
||||||
|
tags:
|
||||||
|
- Backup Account
|
||||||
|
x-panel-log:
|
||||||
|
BeforeFuntions: []
|
||||||
|
bodyKeys:
|
||||||
|
- type
|
||||||
|
- name
|
||||||
|
- detailName
|
||||||
|
- file
|
||||||
|
formatEN: recover [type] data [name][detailName] from [file]
|
||||||
|
formatZH: 从 [file] 恢复 [type] 数据 [name][detailName]
|
||||||
|
paramKeys: []
|
||||||
|
/settings/backup/recover/byupload:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 从上传恢复系统数据
|
||||||
|
parameters:
|
||||||
|
- description: request
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/dto.CommonRecover'
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: ""
|
||||||
|
security:
|
||||||
|
- ApiKeyAuth: []
|
||||||
|
summary: Recover system data by upload
|
||||||
|
tags:
|
||||||
|
- Backup Account
|
||||||
|
x-panel-log:
|
||||||
|
BeforeFuntions: []
|
||||||
|
bodyKeys:
|
||||||
|
- type
|
||||||
|
- name
|
||||||
|
- detailName
|
||||||
|
- file
|
||||||
|
formatEN: recover [type] data [name][detailName] from [file]
|
||||||
|
formatZH: 从 [file] 恢复 [type] 数据 [name][detailName]
|
||||||
|
paramKeys: []
|
||||||
/settings/backup/search:
|
/settings/backup/search:
|
||||||
get:
|
get:
|
||||||
description: 获取备份账号列表
|
description: 获取备份账号列表
|
||||||
@@ -7126,39 +7147,6 @@ paths:
|
|||||||
summary: Page website acme accounts
|
summary: Page website acme accounts
|
||||||
tags:
|
tags:
|
||||||
- Website Acme
|
- Website Acme
|
||||||
/websites/backup:
|
|
||||||
post:
|
|
||||||
consumes:
|
|
||||||
- application/json
|
|
||||||
description: 备份网站
|
|
||||||
parameters:
|
|
||||||
- description: request
|
|
||||||
in: body
|
|
||||||
name: request
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/request.WebsiteResourceReq'
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: ""
|
|
||||||
security:
|
|
||||||
- ApiKeyAuth: []
|
|
||||||
summary: Backup website
|
|
||||||
tags:
|
|
||||||
- Website
|
|
||||||
x-panel-log:
|
|
||||||
BeforeFuntions:
|
|
||||||
- db: websites
|
|
||||||
input_colume: id
|
|
||||||
input_value: id
|
|
||||||
isList: false
|
|
||||||
output_colume: primary_domain
|
|
||||||
output_value: domain
|
|
||||||
bodyKeys:
|
|
||||||
- id
|
|
||||||
formatEN: Backup website [domain]
|
|
||||||
formatZH: 备份网站 [domain]
|
|
||||||
paramKeys: []
|
|
||||||
/websites/check:
|
/websites/check:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
@@ -7723,63 +7711,6 @@ paths:
|
|||||||
summary: List website names
|
summary: List website names
|
||||||
tags:
|
tags:
|
||||||
- Website
|
- Website
|
||||||
/websites/recover:
|
|
||||||
post:
|
|
||||||
consumes:
|
|
||||||
- application/json
|
|
||||||
description: 从备份恢复网站
|
|
||||||
parameters:
|
|
||||||
- description: request
|
|
||||||
in: body
|
|
||||||
name: request
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/request.WebsiteRecover'
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: ""
|
|
||||||
security:
|
|
||||||
- ApiKeyAuth: []
|
|
||||||
summary: Recover website
|
|
||||||
tags:
|
|
||||||
- Website
|
|
||||||
x-panel-log:
|
|
||||||
BeforeFuntions: []
|
|
||||||
bodyKeys:
|
|
||||||
- websiteName
|
|
||||||
- backupName
|
|
||||||
formatEN: '[websiteName] recover from backups [backupName]'
|
|
||||||
formatZH: '[websiteName] 从备份恢复 [backupName]'
|
|
||||||
paramKeys: []
|
|
||||||
/websites/recover/byupload:
|
|
||||||
post:
|
|
||||||
consumes:
|
|
||||||
- application/json
|
|
||||||
description: 从上传恢复网站
|
|
||||||
parameters:
|
|
||||||
- description: request
|
|
||||||
in: body
|
|
||||||
name: request
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/request.WebsiteRecoverByFile'
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: ""
|
|
||||||
security:
|
|
||||||
- ApiKeyAuth: []
|
|
||||||
summary: Recover website by upload
|
|
||||||
tags:
|
|
||||||
- Website
|
|
||||||
x-panel-log:
|
|
||||||
BeforeFuntions: []
|
|
||||||
bodyKeys:
|
|
||||||
- websiteName
|
|
||||||
- fileDir
|
|
||||||
- fileName
|
|
||||||
formatEN: '[websiteName] recover from uploads [fileDir]/[fileName]'
|
|
||||||
formatZH: '[websiteName] 从上传恢复 [fileDir]/[fileName]'
|
|
||||||
paramKeys: []
|
|
||||||
/websites/search:
|
/websites/search:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
|
1
frontend/components.d.ts
vendored
1
frontend/components.d.ts
vendored
@@ -83,6 +83,7 @@ declare module 'vue' {
|
|||||||
SubItem: typeof import('./src/components/app-layout/menu/components/sub-item.vue')['default']
|
SubItem: typeof import('./src/components/app-layout/menu/components/sub-item.vue')['default']
|
||||||
SvgIcon: typeof import('./src/components/svg-icon/svg-icon.vue')['default']
|
SvgIcon: typeof import('./src/components/svg-icon/svg-icon.vue')['default']
|
||||||
TableSetting: typeof import('./src/components/table-setting/index.vue')['default']
|
TableSetting: typeof import('./src/components/table-setting/index.vue')['default']
|
||||||
|
Upload: typeof import('./src/components/upload/index.vue')['default']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -126,21 +126,6 @@ export namespace App {
|
|||||||
config?: Object;
|
config?: Object;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AppBackupReq extends ReqPage {
|
|
||||||
appInstallId: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AppBackupDelReq {
|
|
||||||
ids: number[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AppBackup extends CommonModel {
|
|
||||||
name: string;
|
|
||||||
path: string;
|
|
||||||
appInstallId: string;
|
|
||||||
appDetail: AppDetail;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface VersionDetail {
|
export interface VersionDetail {
|
||||||
version: string;
|
version: string;
|
||||||
detailId: number;
|
detailId: number;
|
||||||
|
@@ -5,17 +5,6 @@ export namespace Database {
|
|||||||
mysqlName: string;
|
mysqlName: string;
|
||||||
dbName: string;
|
dbName: string;
|
||||||
}
|
}
|
||||||
export interface Recover {
|
|
||||||
mysqlName: string;
|
|
||||||
dbName: string;
|
|
||||||
backupName: string;
|
|
||||||
}
|
|
||||||
export interface RecoverByUpload {
|
|
||||||
mysqlName: string;
|
|
||||||
dbName: string;
|
|
||||||
fileName: string;
|
|
||||||
fileDir: string;
|
|
||||||
}
|
|
||||||
export interface MysqlDBInfo {
|
export interface MysqlDBInfo {
|
||||||
id: number;
|
id: number;
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
|
@@ -30,6 +30,15 @@ export namespace File {
|
|||||||
containSub?: boolean;
|
containSub?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface SearchUploadInfo extends ReqPage {
|
||||||
|
path: string;
|
||||||
|
}
|
||||||
|
export interface UploadInfo {
|
||||||
|
name: string;
|
||||||
|
size: number;
|
||||||
|
createdAt: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface FileTree {
|
export interface FileTree {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
|
@@ -34,18 +34,6 @@ export namespace Website {
|
|||||||
websiteGroupId: number;
|
websiteGroupId: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface WebSiteRecover {
|
|
||||||
websiteName: string;
|
|
||||||
type: string;
|
|
||||||
backupName: string;
|
|
||||||
}
|
|
||||||
export interface WebsiteRecoverByUpload {
|
|
||||||
websiteName: string;
|
|
||||||
type: string;
|
|
||||||
fileDir: string;
|
|
||||||
fileName: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface WebSiteDel {
|
export interface WebSiteDel {
|
||||||
id: number;
|
id: number;
|
||||||
deleteApp: boolean;
|
deleteApp: boolean;
|
||||||
@@ -267,10 +255,6 @@ export namespace Website {
|
|||||||
id: number;
|
id: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BackupReq {
|
|
||||||
id: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface NginxUpdate {
|
export interface NginxUpdate {
|
||||||
id: number;
|
id: number;
|
||||||
content: string;
|
content: string;
|
||||||
|
@@ -66,14 +66,6 @@ export const GetAppService = (key: string | undefined) => {
|
|||||||
return http.get<App.AppService[]>(`apps/services/${key}`);
|
return http.get<App.AppService[]>(`apps/services/${key}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const GetAppBackups = (info: App.AppBackupReq) => {
|
|
||||||
return http.post<ResPage<App.AppBackup>>('apps/installed/backups', info);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const DelAppBackups = (req: App.AppBackupDelReq) => {
|
|
||||||
return http.post<any>('apps/installed/backups/del', req);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const GetAppUpdateVersions = (id: number) => {
|
export const GetAppUpdateVersions = (id: number) => {
|
||||||
return http.get<any>(`apps/installed/${id}/versions`);
|
return http.get<any>(`apps/installed/${id}/versions`);
|
||||||
};
|
};
|
||||||
|
@@ -1,11 +1,16 @@
|
|||||||
import { File } from '@/api/interface/file';
|
import { File } from '@/api/interface/file';
|
||||||
import http from '@/api';
|
import http from '@/api';
|
||||||
import { AxiosRequestConfig } from 'axios';
|
import { AxiosRequestConfig } from 'axios';
|
||||||
|
import { ResPage } from '../interface';
|
||||||
|
|
||||||
export const GetFilesList = (params: File.ReqFile) => {
|
export const GetFilesList = (params: File.ReqFile) => {
|
||||||
return http.post<File.File>('files/search', params, 200000);
|
return http.post<File.File>('files/search', params, 200000);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const GetUploadList = (params: File.SearchUploadInfo) => {
|
||||||
|
return http.post<ResPage<File.UploadInfo>>('files/upload/search', params);
|
||||||
|
};
|
||||||
|
|
||||||
export const GetFilesTree = (params: File.ReqFile) => {
|
export const GetFilesTree = (params: File.ReqFile) => {
|
||||||
return http.post<File.FileTree[]>('files/tree', params);
|
return http.post<File.FileTree[]>('files/tree', params);
|
||||||
};
|
};
|
||||||
|
@@ -27,7 +27,9 @@
|
|||||||
</template>
|
</template>
|
||||||
<el-table-column type="selection" fix />
|
<el-table-column type="selection" fix />
|
||||||
<el-table-column :label="$t('commons.table.name')" prop="fileName" show-overflow-tooltip />
|
<el-table-column :label="$t('commons.table.name')" prop="fileName" show-overflow-tooltip />
|
||||||
<el-table-column :label="$t('database.source')" prop="backupType" />
|
<el-table-column :label="$t('database.source')" prop="backupType">
|
||||||
|
<template #default="{ row }">{{ $t('setting.' + row.source) }}</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
prop="createdAt"
|
prop="createdAt"
|
||||||
:label="$t('commons.table.date')"
|
:label="$t('commons.table.date')"
|
||||||
|
252
frontend/src/components/upload/index.vue
Normal file
252
frontend/src/components/upload/index.vue
Normal file
@@ -0,0 +1,252 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-drawer v-model="upVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
|
||||||
|
<template #header>
|
||||||
|
<DrawerHeader :header="$t('commons.button.import')" :resource="title" :back="handleClose" />
|
||||||
|
</template>
|
||||||
|
<div v-loading="loading">
|
||||||
|
<el-upload
|
||||||
|
ref="uploadRef"
|
||||||
|
drag
|
||||||
|
:on-change="fileOnChange"
|
||||||
|
:before-upload="beforeAvatarUpload"
|
||||||
|
class="upload-demo"
|
||||||
|
:auto-upload="false"
|
||||||
|
>
|
||||||
|
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
|
||||||
|
<div class="el-upload__text">
|
||||||
|
{{ $t('database.dropHelper') }}
|
||||||
|
<em>{{ $t('database.clickHelper') }}</em>
|
||||||
|
</div>
|
||||||
|
<template #tip>
|
||||||
|
<div v-if="type === 'mysql'" class="el-upload__tip">
|
||||||
|
<span class="input-help">{{ $t('database.supportUpType') }}</span>
|
||||||
|
<span class="input-help">
|
||||||
|
{{ $t('database.zipFormat') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div v-else class="el-upload__tip">
|
||||||
|
<span class="input-help">{{ $t('website.supportUpType') }}</span>
|
||||||
|
<span class="input-help">
|
||||||
|
{{ $t('website.zipFormat') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-upload>
|
||||||
|
<el-button v-if="uploaderFiles.length === 1" icon="Upload" @click="onSubmit">
|
||||||
|
{{ $t('commons.button.upload') }}
|
||||||
|
</el-button>
|
||||||
|
|
||||||
|
<el-divider />
|
||||||
|
<ComplexTable :pagination-config="paginationConfig" v-model:selects="selects" :data="data">
|
||||||
|
<template #toolbar>
|
||||||
|
<el-button
|
||||||
|
style="margin-left: 10px"
|
||||||
|
plain
|
||||||
|
:disabled="selects.length === 0"
|
||||||
|
@click="onBatchDelete(null)"
|
||||||
|
>
|
||||||
|
{{ $t('commons.button.delete') }}
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
<el-table-column type="selection" fix />
|
||||||
|
<el-table-column :label="$t('commons.table.name')" show-overflow-tooltip prop="name" />
|
||||||
|
<el-table-column :label="$t('file.size')" prop="size">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ computeSize(row.size) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column :label="$t('commons.table.createdAt')" min-width="80" fix>
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ row.createdAt }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<fu-table-operations
|
||||||
|
width="300px"
|
||||||
|
:buttons="buttons"
|
||||||
|
:ellipsis="10"
|
||||||
|
:label="$t('commons.table.operate')"
|
||||||
|
fix
|
||||||
|
/>
|
||||||
|
</ComplexTable>
|
||||||
|
</div>
|
||||||
|
</el-drawer>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import ComplexTable from '@/components/complex-table/index.vue';
|
||||||
|
import { reactive, ref } from 'vue';
|
||||||
|
import { computeSize } from '@/utils/util';
|
||||||
|
import { useDeleteData } from '@/hooks/use-delete-data';
|
||||||
|
import { handleRecoverByUpload } from '@/api/modules/setting';
|
||||||
|
import i18n from '@/lang';
|
||||||
|
import { UploadFile, UploadFiles, UploadInstance, UploadProps } from 'element-plus';
|
||||||
|
import { File } from '@/api/interface/file';
|
||||||
|
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||||
|
import { BatchDeleteFile, GetUploadList, UploadFileData } from '@/api/modules/files';
|
||||||
|
import { loadBaseDir } from '@/api/modules/setting';
|
||||||
|
import { MsgError, MsgSuccess } from '@/utils/message';
|
||||||
|
|
||||||
|
const loading = ref();
|
||||||
|
const selects = ref<any>([]);
|
||||||
|
const baseDir = ref();
|
||||||
|
|
||||||
|
const data = ref();
|
||||||
|
const title = ref();
|
||||||
|
const paginationConfig = reactive({
|
||||||
|
currentPage: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
const upVisiable = ref(false);
|
||||||
|
const type = ref();
|
||||||
|
const name = ref();
|
||||||
|
const detailName = ref();
|
||||||
|
interface DialogProps {
|
||||||
|
type: string;
|
||||||
|
name: string;
|
||||||
|
detailName: string;
|
||||||
|
}
|
||||||
|
const acceptParams = async (params: DialogProps): Promise<void> => {
|
||||||
|
type.value = params.type;
|
||||||
|
name.value = params.name;
|
||||||
|
detailName.value = params.detailName;
|
||||||
|
|
||||||
|
const pathRes = await loadBaseDir();
|
||||||
|
if (type.value === 'mysql') {
|
||||||
|
title.value = name.value + ' [ ' + detailName.value + ' ]';
|
||||||
|
baseDir.value = `${pathRes.data}/uploads/database/mysql/${name.value}/${detailName.value}/`;
|
||||||
|
}
|
||||||
|
if (type.value === 'website' || type.value === 'app') {
|
||||||
|
title.value = name.value;
|
||||||
|
baseDir.value = `${pathRes.data}/uploads/${type.value}/${name.value}/`;
|
||||||
|
}
|
||||||
|
upVisiable.value = true;
|
||||||
|
search();
|
||||||
|
};
|
||||||
|
|
||||||
|
const search = async () => {
|
||||||
|
let params = {
|
||||||
|
page: paginationConfig.currentPage,
|
||||||
|
pageSize: paginationConfig.pageSize,
|
||||||
|
path: baseDir.value,
|
||||||
|
};
|
||||||
|
const res = await GetUploadList(params);
|
||||||
|
data.value = res.data.items || [];
|
||||||
|
paginationConfig.total = res.data.total;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onRecover = async (row: File.File) => {
|
||||||
|
let params = {
|
||||||
|
type: type.value,
|
||||||
|
name: name.value,
|
||||||
|
detailName: detailName.value,
|
||||||
|
file: baseDir.value + row.name,
|
||||||
|
};
|
||||||
|
loading.value = true;
|
||||||
|
await handleRecoverByUpload(params)
|
||||||
|
.then(() => {
|
||||||
|
loading.value = false;
|
||||||
|
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const uploaderFiles = ref<UploadFiles>([]);
|
||||||
|
const uploadRef = ref<UploadInstance>();
|
||||||
|
|
||||||
|
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
|
||||||
|
if (type.value === 'app' || type.value === 'website') {
|
||||||
|
if (rawFile.name.endsWith('.tar.gz')) {
|
||||||
|
MsgError(i18n.global.t('database.unSupportType'));
|
||||||
|
return false;
|
||||||
|
} else if (rawFile.size / 1024 / 1024 > 50) {
|
||||||
|
MsgError(i18n.global.t('database.unSupportSize'));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
rawFile.name.endsWith('.sql') ||
|
||||||
|
rawFile.name.endsWith('.gz') ||
|
||||||
|
rawFile.name.endsWith('.zip') ||
|
||||||
|
rawFile.name.endsWith('.tgz')
|
||||||
|
) {
|
||||||
|
MsgError(i18n.global.t('database.unSupportType'));
|
||||||
|
return false;
|
||||||
|
} else if (rawFile.size / 1024 / 1024 > 10) {
|
||||||
|
MsgError(i18n.global.t('database.unSupportSize'));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const fileOnChange = (_uploadFile: UploadFile, uploadFiles: UploadFiles) => {
|
||||||
|
uploaderFiles.value = uploadFiles;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
uploaderFiles.value = [];
|
||||||
|
uploadRef.value!.clearFiles();
|
||||||
|
upVisiable.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onSubmit = () => {
|
||||||
|
const formData = new FormData();
|
||||||
|
if (uploaderFiles.value.length !== 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (uploaderFiles.value[0]!.raw != undefined) {
|
||||||
|
formData.append('file', uploaderFiles.value[0]!.raw);
|
||||||
|
}
|
||||||
|
formData.append('path', baseDir.value);
|
||||||
|
loading.value = true;
|
||||||
|
UploadFileData(formData, {})
|
||||||
|
.then(() => {
|
||||||
|
loading.value = false;
|
||||||
|
uploadRef.value?.clearFiles();
|
||||||
|
uploaderFiles.value = [];
|
||||||
|
MsgSuccess(i18n.global.t('file.uploadSuccess'));
|
||||||
|
search();
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onBatchDelete = async (row: File.File | null) => {
|
||||||
|
let files: Array<string> = [];
|
||||||
|
if (row) {
|
||||||
|
files.push(baseDir.value + row.name);
|
||||||
|
} else {
|
||||||
|
selects.value.forEach((item: File.File) => {
|
||||||
|
files.push(baseDir.value + item.name);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
await useDeleteData(BatchDeleteFile, { paths: files, isDir: false }, 'commons.msg.delete');
|
||||||
|
search();
|
||||||
|
};
|
||||||
|
|
||||||
|
const buttons = [
|
||||||
|
{
|
||||||
|
label: i18n.global.t('commons.button.recover'),
|
||||||
|
click: (row: File.File) => {
|
||||||
|
onRecover(row);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: i18n.global.t('commons.button.delete'),
|
||||||
|
click: (row: File.File) => {
|
||||||
|
onBatchDelete(row);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
acceptParams,
|
||||||
|
});
|
||||||
|
</script>
|
@@ -922,8 +922,9 @@ export default {
|
|||||||
type: 'Type',
|
type: 'Type',
|
||||||
static: 'Static',
|
static: 'Static',
|
||||||
deployment: 'Deployment',
|
deployment: 'Deployment',
|
||||||
supportUpType: 'Only support tar.gz files',
|
supportUpType: 'Only .tar.gz files within 50 MB are supported',
|
||||||
zipFormat: 'tar.gz compressed package structure: test.tar.gz compressed package must contain website.json file',
|
zipFormat:
|
||||||
|
'.tar.gz compressed package structure: test.tar.gz compressed package must contain website.json file',
|
||||||
proxy: 'Reverse Proxy',
|
proxy: 'Reverse Proxy',
|
||||||
alias: 'Path Name',
|
alias: 'Path Name',
|
||||||
remark: 'Remark',
|
remark: 'Remark',
|
||||||
|
@@ -296,6 +296,8 @@ export default {
|
|||||||
unSupportType: '不支持当前文件类型!',
|
unSupportType: '不支持当前文件类型!',
|
||||||
unSupportSize: '上传文件超过 10M,请确认!',
|
unSupportSize: '上传文件超过 10M,请确认!',
|
||||||
selectFile: '选择文件',
|
selectFile: '选择文件',
|
||||||
|
dropHelper: '将上传文件拖拽到此处,或者',
|
||||||
|
clickHelper: '点击上传',
|
||||||
supportUpType: '仅支持 10M 以内 sql、zip、sql.gz、(tar.gz gz tgz) 文件',
|
supportUpType: '仅支持 10M 以内 sql、zip、sql.gz、(tar.gz gz tgz) 文件',
|
||||||
zipFormat: 'zip、tar.gz 压缩包结构:test.zip 或 test.tar.gz 压缩包内,必需包含 test.sql',
|
zipFormat: 'zip、tar.gz 压缩包结构:test.zip 或 test.tar.gz 压缩包内,必需包含 test.sql',
|
||||||
|
|
||||||
@@ -930,8 +932,8 @@ export default {
|
|||||||
type: '类型',
|
type: '类型',
|
||||||
static: '静态网站',
|
static: '静态网站',
|
||||||
deployment: '一键部署',
|
deployment: '一键部署',
|
||||||
supportUpType: '仅支持 tar.gz 文件',
|
supportUpType: '仅支持 50M 以内 .tar.gz 文件',
|
||||||
zipFormat: 'tar.gz 压缩包结构:test.tar.gz 压缩包内,必需包含 website.json 文件',
|
zipFormat: '.tar.gz 压缩包结构:test.tar.gz 压缩包内,必需包含 website.json 文件',
|
||||||
proxy: '反向代理',
|
proxy: '反向代理',
|
||||||
alias: '代号',
|
alias: '代号',
|
||||||
remark: '备注',
|
remark: '备注',
|
||||||
|
@@ -89,6 +89,17 @@
|
|||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
<el-button
|
||||||
|
class="h-button"
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
round
|
||||||
|
size="small"
|
||||||
|
@click="openUploads(installed.app.key, installed.name)"
|
||||||
|
v-if="mode === 'installed'"
|
||||||
|
>
|
||||||
|
{{ $t('database.loadBackup') }}
|
||||||
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
class="h-button"
|
class="h-button"
|
||||||
type="primary"
|
type="primary"
|
||||||
@@ -145,6 +156,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</LayoutContent>
|
</LayoutContent>
|
||||||
<Backups ref="backupRef" @close="search" />
|
<Backups ref="backupRef" @close="search" />
|
||||||
|
<Uploads ref="uploadRef" />
|
||||||
<AppResources ref="checkRef" />
|
<AppResources ref="checkRef" />
|
||||||
<AppDelete ref="deleteRef" @close="search" />
|
<AppDelete ref="deleteRef" @close="search" />
|
||||||
<AppParams ref="appParamRef" />
|
<AppParams ref="appParamRef" />
|
||||||
@@ -164,6 +176,7 @@ import { onMounted, onUnmounted, reactive, ref } from 'vue';
|
|||||||
import i18n from '@/lang';
|
import i18n from '@/lang';
|
||||||
import { ElMessageBox } from 'element-plus';
|
import { ElMessageBox } from 'element-plus';
|
||||||
import Backups from '@/components/backup/index.vue';
|
import Backups from '@/components/backup/index.vue';
|
||||||
|
import Uploads from '@/components/upload/index.vue';
|
||||||
import AppResources from './check/index.vue';
|
import AppResources from './check/index.vue';
|
||||||
import AppDelete from './delete/index.vue';
|
import AppDelete from './delete/index.vue';
|
||||||
import AppParams from './detail/index.vue';
|
import AppParams from './detail/index.vue';
|
||||||
@@ -189,6 +202,7 @@ let operateReq = reactive({
|
|||||||
detailId: 0,
|
detailId: 0,
|
||||||
});
|
});
|
||||||
const backupRef = ref();
|
const backupRef = ref();
|
||||||
|
const uploadRef = ref();
|
||||||
const checkRef = ref();
|
const checkRef = ref();
|
||||||
const deleteRef = ref();
|
const deleteRef = ref();
|
||||||
const appParamRef = ref();
|
const appParamRef = ref();
|
||||||
@@ -350,6 +364,15 @@ const openBackups = (key: string, name: string) => {
|
|||||||
backupRef.value.acceptParams(params);
|
backupRef.value.acceptParams(params);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const openUploads = (key: string, name: string) => {
|
||||||
|
let params = {
|
||||||
|
type: 'app',
|
||||||
|
name: key,
|
||||||
|
detailName: name,
|
||||||
|
};
|
||||||
|
uploadRef.value.acceptParams(params);
|
||||||
|
};
|
||||||
|
|
||||||
const openParam = (installId: number) => {
|
const openParam = (installId: number) => {
|
||||||
appParamRef.value.acceptParams({ id: installId });
|
appParamRef.value.acceptParams({ id: installId });
|
||||||
};
|
};
|
||||||
|
@@ -155,11 +155,11 @@ import DeleteDialog from '@/views/database/mysql/delete/index.vue';
|
|||||||
import PasswordDialog from '@/views/database/mysql/password/index.vue';
|
import PasswordDialog from '@/views/database/mysql/password/index.vue';
|
||||||
import RootPasswordDialog from '@/views/database/mysql/root-password/index.vue';
|
import RootPasswordDialog from '@/views/database/mysql/root-password/index.vue';
|
||||||
import RemoteAccessDialog from '@/views/database/mysql/remote/index.vue';
|
import RemoteAccessDialog from '@/views/database/mysql/remote/index.vue';
|
||||||
import UploadDialog from '@/views/database/mysql/upload/index.vue';
|
|
||||||
import AppResources from '@/views/database/mysql/check/index.vue';
|
import AppResources from '@/views/database/mysql/check/index.vue';
|
||||||
import Setting from '@/views/database/mysql/setting/index.vue';
|
import Setting from '@/views/database/mysql/setting/index.vue';
|
||||||
import AppStatus from '@/components/app-status/index.vue';
|
import AppStatus from '@/components/app-status/index.vue';
|
||||||
import Backups from '@/components/backup/index.vue';
|
import Backups from '@/components/backup/index.vue';
|
||||||
|
import UploadDialog from '@/components/upload/index.vue';
|
||||||
import { dateFormat } from '@/utils/util';
|
import { dateFormat } from '@/utils/util';
|
||||||
import { reactive, ref } from 'vue';
|
import { reactive, ref } from 'vue';
|
||||||
import { deleteCheckMysqlDB, loadRemoteAccess, searchMysqlDBs, updateMysqlDescription } from '@/api/modules/database';
|
import { deleteCheckMysqlDB, loadRemoteAccess, searchMysqlDBs, updateMysqlDescription } from '@/api/modules/database';
|
||||||
@@ -350,8 +350,9 @@ const buttons = [
|
|||||||
label: i18n.global.t('database.loadBackup'),
|
label: i18n.global.t('database.loadBackup'),
|
||||||
click: (row: Database.MysqlDBInfo) => {
|
click: (row: Database.MysqlDBInfo) => {
|
||||||
let params = {
|
let params = {
|
||||||
mysqlName: mysqlName.value,
|
type: 'mysql',
|
||||||
dbName: row.name,
|
name: mysqlName.value,
|
||||||
|
detailName: row.name,
|
||||||
};
|
};
|
||||||
uploadRef.value!.acceptParams(params);
|
uploadRef.value!.acceptParams(params);
|
||||||
},
|
},
|
||||||
|
@@ -1,210 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div v-loading="loading">
|
|
||||||
<el-drawer v-model="upVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
|
|
||||||
<template #header>
|
|
||||||
<DrawerHeader :header="$t('commons.button.import')" :back="handleClose" />
|
|
||||||
</template>
|
|
||||||
<el-upload
|
|
||||||
ref="uploadRef"
|
|
||||||
:on-change="fileOnChange"
|
|
||||||
:before-upload="beforeAvatarUpload"
|
|
||||||
class="upload-demo"
|
|
||||||
:auto-upload="false"
|
|
||||||
>
|
|
||||||
<template #trigger>
|
|
||||||
<el-button type="primary" plain>{{ $t('database.selectFile') }}</el-button>
|
|
||||||
</template>
|
|
||||||
</el-upload>
|
|
||||||
<div style="margin-left: 10px">
|
|
||||||
<span class="input-help">{{ $t('database.supportUpType') }}</span>
|
|
||||||
<span class="input-help">
|
|
||||||
{{ $t('database.zipFormat') }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<el-button style="margin-top: 10px" v-if="uploaderFiles.length === 1" icon="Upload" @click="onSubmit">
|
|
||||||
{{ $t('commons.button.upload') }}
|
|
||||||
</el-button>
|
|
||||||
<el-divider />
|
|
||||||
<ComplexTable :pagination-config="paginationConfig" v-model:selects="selects" :data="data">
|
|
||||||
<template #toolbar>
|
|
||||||
<el-button
|
|
||||||
style="margin-left: 10px"
|
|
||||||
plain
|
|
||||||
:disabled="selects.length === 0"
|
|
||||||
@click="onBatchDelete(null)"
|
|
||||||
>
|
|
||||||
{{ $t('commons.button.delete') }}
|
|
||||||
</el-button>
|
|
||||||
</template>
|
|
||||||
<el-table-column type="selection" fix />
|
|
||||||
<el-table-column :label="$t('commons.table.name')" show-overflow-tooltip prop="name" />
|
|
||||||
<el-table-column :label="$t('file.size')" prop="size">
|
|
||||||
<template #default="{ row }">
|
|
||||||
{{ computeSize(row.size) }}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column :label="$t('commons.table.createdAt')" min-width="80" fix>
|
|
||||||
<template #default="{ row }">
|
|
||||||
{{ dateFormatSimple(row.modTime) }}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<fu-table-operations
|
|
||||||
width="300px"
|
|
||||||
:buttons="buttons"
|
|
||||||
:ellipsis="10"
|
|
||||||
:label="$t('commons.table.operate')"
|
|
||||||
fix
|
|
||||||
/>
|
|
||||||
</ComplexTable>
|
|
||||||
</el-drawer>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import ComplexTable from '@/components/complex-table/index.vue';
|
|
||||||
import { reactive, ref } from 'vue';
|
|
||||||
import { computeSize, dateFormatSimple } from '@/utils/util';
|
|
||||||
import { useDeleteData } from '@/hooks/use-delete-data';
|
|
||||||
import { handleRecoverByUpload } from '@/api/modules/setting';
|
|
||||||
import i18n from '@/lang';
|
|
||||||
import { UploadFile, UploadFiles, UploadInstance, UploadProps } from 'element-plus';
|
|
||||||
import { File } from '@/api/interface/file';
|
|
||||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
|
||||||
import { BatchDeleteFile, GetFilesList, UploadFileData } from '@/api/modules/files';
|
|
||||||
import { loadBaseDir } from '@/api/modules/setting';
|
|
||||||
import { MsgError, MsgSuccess } from '@/utils/message';
|
|
||||||
|
|
||||||
const loading = ref();
|
|
||||||
const selects = ref<any>([]);
|
|
||||||
const baseDir = ref();
|
|
||||||
|
|
||||||
const data = ref();
|
|
||||||
const paginationConfig = reactive({
|
|
||||||
currentPage: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
total: 0,
|
|
||||||
});
|
|
||||||
|
|
||||||
const upVisiable = ref(false);
|
|
||||||
const mysqlName = ref();
|
|
||||||
const dbName = ref();
|
|
||||||
interface DialogProps {
|
|
||||||
mysqlName: string;
|
|
||||||
dbName: string;
|
|
||||||
}
|
|
||||||
const acceptParams = async (params: DialogProps): Promise<void> => {
|
|
||||||
mysqlName.value = params.mysqlName;
|
|
||||||
dbName.value = params.dbName;
|
|
||||||
|
|
||||||
const pathRes = await loadBaseDir();
|
|
||||||
baseDir.value = `${pathRes.data}/uploads/database/mysql/${mysqlName.value}/${dbName.value}/`;
|
|
||||||
upVisiable.value = true;
|
|
||||||
search();
|
|
||||||
};
|
|
||||||
|
|
||||||
const search = async () => {
|
|
||||||
let params = {
|
|
||||||
page: paginationConfig.currentPage,
|
|
||||||
pageSize: paginationConfig.pageSize,
|
|
||||||
path: baseDir.value,
|
|
||||||
expand: true,
|
|
||||||
};
|
|
||||||
const res = await GetFilesList(params);
|
|
||||||
data.value = res.data.items || [];
|
|
||||||
paginationConfig.total = res.data.itemTotal;
|
|
||||||
};
|
|
||||||
|
|
||||||
const onRecover = async (row: File.File) => {
|
|
||||||
let params = {
|
|
||||||
type: 'mysql',
|
|
||||||
name: mysqlName.value,
|
|
||||||
detailName: dbName.value,
|
|
||||||
file: baseDir.value + '/' + row.name,
|
|
||||||
};
|
|
||||||
loading.value = true;
|
|
||||||
await handleRecoverByUpload(params)
|
|
||||||
.then(() => {
|
|
||||||
loading.value = false;
|
|
||||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
loading.value = false;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const uploaderFiles = ref<UploadFiles>([]);
|
|
||||||
const uploadRef = ref<UploadInstance>();
|
|
||||||
|
|
||||||
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
|
|
||||||
if (
|
|
||||||
rawFile.name.endsWith('.sql') ||
|
|
||||||
rawFile.name.endsWith('.gz') ||
|
|
||||||
rawFile.name.endsWith('.zip') ||
|
|
||||||
rawFile.name.endsWith('.tgz')
|
|
||||||
) {
|
|
||||||
MsgError(i18n.global.t('database.unSupportType'));
|
|
||||||
return false;
|
|
||||||
} else if (rawFile.size / 1024 / 1024 > 10) {
|
|
||||||
MsgError(i18n.global.t('database.unSupportSize'));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
const fileOnChange = (_uploadFile: UploadFile, uploadFiles: UploadFiles) => {
|
|
||||||
uploaderFiles.value = uploadFiles;
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleClose = () => {
|
|
||||||
uploadRef.value!.clearFiles();
|
|
||||||
upVisiable.value = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
const onSubmit = () => {
|
|
||||||
const formData = new FormData();
|
|
||||||
if (uploaderFiles.value.length !== 1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (uploaderFiles.value[0]!.raw != undefined) {
|
|
||||||
formData.append('file', uploaderFiles.value[0]!.raw);
|
|
||||||
}
|
|
||||||
formData.append('path', baseDir.value);
|
|
||||||
UploadFileData(formData, {}).then(() => {
|
|
||||||
MsgSuccess(i18n.global.t('file.uploadSuccess'));
|
|
||||||
handleClose();
|
|
||||||
search();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const onBatchDelete = async (row: File.File | null) => {
|
|
||||||
let files: Array<string> = [];
|
|
||||||
if (row) {
|
|
||||||
files.push(baseDir.value + row.name);
|
|
||||||
} else {
|
|
||||||
selects.value.forEach((item: File.File) => {
|
|
||||||
files.push(baseDir.value + item.name);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
await useDeleteData(BatchDeleteFile, { paths: files, isDir: false }, 'commons.msg.delete');
|
|
||||||
search();
|
|
||||||
};
|
|
||||||
|
|
||||||
const buttons = [
|
|
||||||
{
|
|
||||||
label: i18n.global.t('commons.button.recover'),
|
|
||||||
click: (row: File.File) => {
|
|
||||||
onRecover(row);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: i18n.global.t('commons.button.delete'),
|
|
||||||
click: (row: File.File) => {
|
|
||||||
onBatchDelete(row);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
defineExpose({
|
|
||||||
acceptParams,
|
|
||||||
});
|
|
||||||
</script>
|
|
@@ -1,21 +1,30 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<div>
|
||||||
<el-drawer v-model="open" :before-close="handleClose" size="40%">
|
<el-drawer v-model="open" :before-close="handleClose" size="40%">
|
||||||
<template #header>
|
<template #header>
|
||||||
<DrawerHeader :header="$t('file.upload')" :back="handleClose" />
|
<DrawerHeader :header="$t('file.upload')" :back="handleClose" />
|
||||||
</template>
|
</template>
|
||||||
<el-upload
|
<el-upload
|
||||||
action="#"
|
action="#"
|
||||||
|
drag
|
||||||
:auto-upload="false"
|
:auto-upload="false"
|
||||||
ref="uploadRef"
|
ref="uploadRef"
|
||||||
:multiple="true"
|
:multiple="true"
|
||||||
:on-change="fileOnChange"
|
:on-change="fileOnChange"
|
||||||
v-loading="loading"
|
v-loading="loading"
|
||||||
>
|
>
|
||||||
<template #trigger>
|
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
|
||||||
<el-button type="primary">{{ $t('file.selectFile') }}</el-button>
|
<div class="el-upload__text">
|
||||||
</template>
|
{{ $t('database.dropHelper') }}
|
||||||
|
<em>{{ $t('database.clickHelper') }}</em>
|
||||||
|
</div>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
<el-progress v-if="loading" :text-inside="true" :stroke-width="26" :percentage="uploadPrecent"></el-progress>
|
<el-progress
|
||||||
|
v-if="loading"
|
||||||
|
:text-inside="true"
|
||||||
|
:stroke-width="26"
|
||||||
|
:percentage="uploadPrecent"
|
||||||
|
></el-progress>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
<el-button @click="handleClose" :disabled="loading">{{ $t('commons.button.cancel') }}</el-button>
|
<el-button @click="handleClose" :disabled="loading">{{ $t('commons.button.cancel') }}</el-button>
|
||||||
@@ -25,6 +34,7 @@
|
|||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
@@ -152,7 +152,7 @@
|
|||||||
import LayoutContent from '@/layout/layout-content.vue';
|
import LayoutContent from '@/layout/layout-content.vue';
|
||||||
import RouterButton from '@/components/router-button/index.vue';
|
import RouterButton from '@/components/router-button/index.vue';
|
||||||
import Backups from '@/components/backup/index.vue';
|
import Backups from '@/components/backup/index.vue';
|
||||||
import UploadDialog from '@/views/website/website/upload/index.vue';
|
import UploadDialog from '@/components/upload/index.vue';
|
||||||
import DefaultServer from '@/views/website/website/default/index.vue';
|
import DefaultServer from '@/views/website/website/default/index.vue';
|
||||||
import ComplexTable from '@/components/complex-table/index.vue';
|
import ComplexTable from '@/components/complex-table/index.vue';
|
||||||
import { onMounted, reactive, ref } from '@vue/runtime-core';
|
import { onMounted, reactive, ref } from '@vue/runtime-core';
|
||||||
@@ -323,8 +323,9 @@ const buttons = [
|
|||||||
label: i18n.global.t('database.loadBackup'),
|
label: i18n.global.t('database.loadBackup'),
|
||||||
click: (row: Website.Website) => {
|
click: (row: Website.Website) => {
|
||||||
let params = {
|
let params = {
|
||||||
websiteName: row.primaryDomain,
|
type: 'website',
|
||||||
websiteType: row.type,
|
name: row.primaryDomain,
|
||||||
|
detailName: '',
|
||||||
};
|
};
|
||||||
uploadRef.value!.acceptParams(params);
|
uploadRef.value!.acceptParams(params);
|
||||||
},
|
},
|
||||||
|
@@ -1,207 +0,0 @@
|
|||||||
<template>
|
|
||||||
<el-drawer :close-on-click-modal="false" v-model="upVisiable" size="50%">
|
|
||||||
<template #header>
|
|
||||||
<Header :header="$t('commons.button.import')" :resource="websiteName" :back="handleClose"></Header>
|
|
||||||
</template>
|
|
||||||
<div v-loading="loading">
|
|
||||||
<el-upload
|
|
||||||
ref="uploadRef"
|
|
||||||
:on-change="fileOnChange"
|
|
||||||
:before-upload="beforeAvatarUpload"
|
|
||||||
class="upload-demo"
|
|
||||||
:auto-upload="false"
|
|
||||||
>
|
|
||||||
<template #trigger>
|
|
||||||
<el-button type="primary" plain>{{ $t('database.selectFile') }}</el-button>
|
|
||||||
</template>
|
|
||||||
<el-button style="margin-left: 10px" icon="Upload" @click="onSubmit">
|
|
||||||
{{ $t('commons.button.upload') }}
|
|
||||||
</el-button>
|
|
||||||
</el-upload>
|
|
||||||
<div style="margin-left: 10px">
|
|
||||||
<span class="input-help">{{ $t('website.supportUpType') }}</span>
|
|
||||||
<span class="input-help">
|
|
||||||
{{ $t('website.zipFormat') }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<el-divider />
|
|
||||||
<ComplexTable :pagination-config="paginationConfig" v-model:selects="selects" :data="data">
|
|
||||||
<template #toolbar>
|
|
||||||
<el-button
|
|
||||||
style="margin-left: 10px"
|
|
||||||
plain
|
|
||||||
:disabled="selects.length === 0"
|
|
||||||
@click="onBatchDelete(null)"
|
|
||||||
>
|
|
||||||
{{ $t('commons.button.delete') }}
|
|
||||||
</el-button>
|
|
||||||
</template>
|
|
||||||
<el-table-column type="selection" fix />
|
|
||||||
<el-table-column :label="$t('commons.table.name')" show-overflow-tooltip prop="name" />
|
|
||||||
<el-table-column :label="$t('file.size')" prop="size">
|
|
||||||
<template #default="{ row }">
|
|
||||||
{{ computeSize(row.size) }}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column :label="$t('commons.table.createdAt')" min-width="80" fix>
|
|
||||||
<template #default="{ row }">
|
|
||||||
{{ dateFormatSimple(row.modTime) }}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<fu-table-operations
|
|
||||||
width="300px"
|
|
||||||
:buttons="buttons"
|
|
||||||
:ellipsis="10"
|
|
||||||
:label="$t('commons.table.operate')"
|
|
||||||
fix
|
|
||||||
/>
|
|
||||||
</ComplexTable>
|
|
||||||
</div>
|
|
||||||
</el-drawer>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import ComplexTable from '@/components/complex-table/index.vue';
|
|
||||||
import { reactive, ref } from 'vue';
|
|
||||||
import { computeSize, dateFormatSimple } from '@/utils/util';
|
|
||||||
import { useDeleteData } from '@/hooks/use-delete-data';
|
|
||||||
import i18n from '@/lang';
|
|
||||||
import { UploadFile, UploadFiles, UploadInstance, UploadProps } from 'element-plus';
|
|
||||||
import { File } from '@/api/interface/file';
|
|
||||||
import { BatchDeleteFile, GetFilesList, UploadFileData } from '@/api/modules/files';
|
|
||||||
import { handleRecoverByUpload, loadBaseDir } from '@/api/modules/setting';
|
|
||||||
import Header from '@/components/drawer-header/index.vue';
|
|
||||||
import { MsgError, MsgSuccess } from '@/utils/message';
|
|
||||||
|
|
||||||
const selects = ref<any>([]);
|
|
||||||
const baseDir = ref();
|
|
||||||
const loading = ref(false);
|
|
||||||
|
|
||||||
const data = ref();
|
|
||||||
const paginationConfig = reactive({
|
|
||||||
currentPage: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
total: 0,
|
|
||||||
});
|
|
||||||
|
|
||||||
const upVisiable = ref(false);
|
|
||||||
const websiteName = ref();
|
|
||||||
const websiteType = ref();
|
|
||||||
|
|
||||||
interface DialogProps {
|
|
||||||
websiteName: string;
|
|
||||||
websiteType: string;
|
|
||||||
}
|
|
||||||
const acceptParams = async (params: DialogProps): Promise<void> => {
|
|
||||||
websiteName.value = params.websiteName;
|
|
||||||
websiteType.value = params.websiteType;
|
|
||||||
upVisiable.value = true;
|
|
||||||
const pathRes = await loadBaseDir();
|
|
||||||
baseDir.value = `${pathRes.data}/uploads/website/${websiteName.value}`;
|
|
||||||
search();
|
|
||||||
};
|
|
||||||
|
|
||||||
const search = async () => {
|
|
||||||
let params = {
|
|
||||||
page: paginationConfig.currentPage,
|
|
||||||
pageSize: paginationConfig.pageSize,
|
|
||||||
path: baseDir.value,
|
|
||||||
expand: true,
|
|
||||||
};
|
|
||||||
const res = await GetFilesList(params);
|
|
||||||
data.value = res.data.items || [];
|
|
||||||
paginationConfig.total = res.data.itemTotal;
|
|
||||||
};
|
|
||||||
|
|
||||||
const onRecover = async (row: File.File) => {
|
|
||||||
let params = {
|
|
||||||
name: websiteName.value,
|
|
||||||
detailName: '',
|
|
||||||
type: 'website',
|
|
||||||
file: baseDir.value + '/' + row.name,
|
|
||||||
};
|
|
||||||
loading.value = true;
|
|
||||||
await handleRecoverByUpload(params)
|
|
||||||
.then(() => {
|
|
||||||
loading.value = false;
|
|
||||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
loading.value = false;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const uploaderFiles = ref<UploadFiles>([]);
|
|
||||||
const uploadRef = ref<UploadInstance>();
|
|
||||||
|
|
||||||
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
|
|
||||||
if (rawFile.name.endsWith('.tar.gz')) {
|
|
||||||
MsgError(i18n.global.t('database.unSupportType'));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
const fileOnChange = (_uploadFile: UploadFile, uploadFiles: UploadFiles) => {
|
|
||||||
uploaderFiles.value = uploadFiles;
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleClose = () => {
|
|
||||||
uploadRef.value!.clearFiles();
|
|
||||||
upVisiable.value = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
const onSubmit = () => {
|
|
||||||
const formData = new FormData();
|
|
||||||
if (uploaderFiles.value.length !== 1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (uploaderFiles.value[0]!.raw != undefined) {
|
|
||||||
formData.append('file', uploaderFiles.value[0]!.raw);
|
|
||||||
}
|
|
||||||
formData.append('path', baseDir.value + '/');
|
|
||||||
loading.value = true;
|
|
||||||
UploadFileData(formData, {})
|
|
||||||
.then(() => {
|
|
||||||
loading.value = false;
|
|
||||||
MsgSuccess(i18n.global.t('file.uploadSuccess'));
|
|
||||||
handleClose();
|
|
||||||
search();
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
loading.value = false;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const onBatchDelete = async (row: File.File | null) => {
|
|
||||||
let files: Array<string> = [];
|
|
||||||
if (row) {
|
|
||||||
files.push(baseDir.value + '/' + row.name);
|
|
||||||
} else {
|
|
||||||
selects.value.forEach((item: File.File) => {
|
|
||||||
files.push(baseDir.value + '/' + item.name);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
await useDeleteData(BatchDeleteFile, { isDir: false, paths: files }, 'commons.msg.delete');
|
|
||||||
search();
|
|
||||||
};
|
|
||||||
|
|
||||||
const buttons = [
|
|
||||||
{
|
|
||||||
label: i18n.global.t('commons.button.recover'),
|
|
||||||
click: (row: File.File) => {
|
|
||||||
onRecover(row);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: i18n.global.t('commons.button.delete'),
|
|
||||||
click: (row: File.File) => {
|
|
||||||
onBatchDelete(row);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
defineExpose({
|
|
||||||
acceptParams,
|
|
||||||
});
|
|
||||||
</script>
|
|
Reference in New Issue
Block a user