mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-19 08:19:15 +08:00
feat: 完成网站备份功能
This commit is contained in:
parent
1f717bea0e
commit
7b21bcbe7f
@ -61,6 +61,25 @@ func (b *BaseApi) DeleteBackup(c *gin.Context) {
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
func (b *BaseApi) SearchBackupRecords(c *gin.Context) {
|
||||
var req dto.RecordSearch
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
total, list, err := backupService.SearchRecordsWithPage(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, dto.PageResult{
|
||||
Items: list,
|
||||
Total: total,
|
||||
})
|
||||
}
|
||||
|
||||
func (b *BaseApi) DownloadRecord(c *gin.Context) {
|
||||
var req dto.DownloadRecord
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
|
@ -1,16 +0,0 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/shirou/gopsutil/net"
|
||||
)
|
||||
|
||||
func TestCopu(t *testing.T) {
|
||||
fmt.Println(net.IOCounters(false))
|
||||
fmt.Println(net.IOCounters(true))
|
||||
}
|
||||
|
||||
// [{"name":"all","bytesSent":15498384367,"bytesRecv":18415197440,"packetsSent":11608058,"packetsRecv":12976591,"errin":0,"errout":21,"dropin":0,"dropout":1181,"fifoin":0,"fifoout":0}] <nil>
|
||||
// [{"name":"lo0","bytesSent":12947010452,"bytesRecv":12947010452,"packetsSent":6519135,"packetsRecv":6519135,"errin":0,"errout":0,"dropin":0,"dropout":0,"fifoin":0,"fifoout":0} {"name":"gif0","bytesSent":0,"bytesRecv":0,"packetsSent":0,"packetsRecv":0,"errin":0,"errout":0,"dropin":0,"dropout":0,"fifoin":0,"fifoout":0} {"name":"stf0","bytesSent":0,"bytesRecv":0,"packetsSent":0,"packetsRecv":0,"errin":0,"errout":0,"dropin":0,"dropout":0,"fifoin":0,"fifoout":0} {"name":"ap1","bytesSent":0,"bytesRecv":0,"packetsSent":0,"packetsRecv":0,"errin":0,"errout":0,"dropin":0,"dropout":0,"fifoin":0,"fifoout":0} {"name":"en0","bytesSent":2531548007,"bytesRecv":5443547837,"packetsSent":5019082,"packetsRecv":6374381,"errin":0,"errout":0,"dropin":0,"dropout":1065,"fifoin":0,"fifoout":0} {"name":"en1","bytesSent":0,"bytesRecv":0,"packetsSent":0,"packetsRecv":0,"errin":0,"errout":0,"dropin":0,"dropout":0,"fifoin":0,"fifoout":0} {"name":"en2","bytesSent":0,"bytesRecv":0,"packetsSent":0,"packetsRecv":0,"errin":0,"errout":0,"dropin":0,"dropout":0,"fifoin":0,"fifoout":0} {"name":"bridge0","bytesSent":0,"bytesRecv":0,"packetsSent":0,"packetsRecv":0,"errin":0,"errout":0,"dropin":0,"dropout":0,"fifoin":0,"fifoout":0} {"name":"awdl0","bytesSent":103717,"bytesRecv":157244,"packetsSent":412,"packetsRecv":460,"errin":0,"errout":0,"dropin":0,"dropout":0,"fifoin":0,"fifoout":0} {"name":"llw0","bytesSent":0,"bytesRecv":0,"packetsSent":0,"packetsRecv":0,"errin":0,"errout":0,"dropin":0,"dropout":0,"fifoin":0,"fifoout":0} {"name":"utun0","bytesSent":21810,"bytesRecv":0,"packetsSent":121,"packetsRecv":0,"errin":0,"errout":0,"dropin":0,"dropout":0,"fifoin":0,"fifoout":0} {"name":"utun1","bytesSent":21810,"bytesRecv":0,"packetsSent":121,"packetsRecv":0,"errin":0,"errout":0,"dropin":0,"dropout":0,"fifoin":0,"fifoout":0} {"name":"utun2","bytesSent":21810,"bytesRecv":0,"packetsSent":121,"packetsRecv":0,"errin":0,"errout":0,"dropin":0,"dropout":0,"fifoin":0,"fifoout":0} {"name":"en5","bytesSent":6093969,"bytesRecv":6264468,"packetsSent":47985,"packetsRecv":48051,"errin":0,"errout":21,"dropin":0,"dropout":116,"fifoin":0,"fifoout":0} {"name":"utun3","bytesSent":13576933,"bytesRecv":18231580,"packetsSent":21129,"packetsRecv":34612,"errin":0,"errout":0,"dropin":0,"dropout":0,"fifoin":0,"fifoout":0}] <nil>
|
@ -146,25 +146,6 @@ func (b *BaseApi) ListDBName(c *gin.Context) {
|
||||
helper.SuccessWithData(c, list)
|
||||
}
|
||||
|
||||
func (b *BaseApi) SearchDBBackups(c *gin.Context) {
|
||||
var req dto.SearchBackupsWithPage
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
total, list, err := mysqlService.SearchBackupsWithPage(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, dto.PageResult{
|
||||
Items: list,
|
||||
Total: total,
|
||||
})
|
||||
}
|
||||
|
||||
func (b *BaseApi) BackupMysql(c *gin.Context) {
|
||||
var req dto.BackupDB
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
|
@ -38,6 +38,19 @@ func (b *BaseApi) CreateWebsite(c *gin.Context) {
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
func (b *BaseApi) BackupWebsite(c *gin.Context) {
|
||||
id, err := helper.GetParamID(c)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := websiteService.Backup(id); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
func (b *BaseApi) DeleteWebSite(c *gin.Context) {
|
||||
var req dto.WebSiteDel
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
|
@ -24,6 +24,13 @@ type BackupSearch struct {
|
||||
DetailName string `json:"detailName"`
|
||||
}
|
||||
|
||||
type RecordSearch struct {
|
||||
PageInfo
|
||||
Type string `json:"type" validate:"required"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
DetailName string `json:"detailName"`
|
||||
}
|
||||
|
||||
type BackupRecords struct {
|
||||
ID uint `json:"id"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
|
@ -112,12 +112,6 @@ type SearchDBWithPage struct {
|
||||
MysqlName string `json:"mysqlName" validate:"required"`
|
||||
}
|
||||
|
||||
type SearchBackupsWithPage struct {
|
||||
PageInfo
|
||||
MysqlName string `json:"mysqlName" validate:"required"`
|
||||
DBName string `json:"dbName" validate:"required"`
|
||||
}
|
||||
|
||||
type BackupDB struct {
|
||||
MysqlName string `json:"mysqlName" validate:"required"`
|
||||
DBName string `json:"dbName" validate:"required"`
|
||||
|
@ -2,7 +2,10 @@ package repo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
@ -96,3 +99,48 @@ func (a AppInstallRepo) BatchUpdateBy(maps map[string]interface{}, opts ...DBOpt
|
||||
}
|
||||
return db.Debug().Updates(&maps).Error
|
||||
}
|
||||
|
||||
type RootInfo struct {
|
||||
ID uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Port int64 `json:"port"`
|
||||
Password string `json:"password"`
|
||||
ContainerName string `json:"containerName"`
|
||||
Param string `json:"param"`
|
||||
Env string `json:"env"`
|
||||
Key string `json:"key"`
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
func (u *AppInstallRepo) LoadBaseInfoByKey(key string) (*RootInfo, error) {
|
||||
var (
|
||||
app model.App
|
||||
appInstall model.AppInstall
|
||||
info RootInfo
|
||||
)
|
||||
if err := global.DB.Where("key = ?", key).First(&app).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := global.DB.Where("app_id = ?", app.ID).First(&appInstall).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
envMap := make(map[string]interface{})
|
||||
if err := json.Unmarshal([]byte(appInstall.Env), &envMap); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
password, ok := envMap["PANEL_DB_ROOT_PASSWORD"].(string)
|
||||
if ok {
|
||||
info.Password = password
|
||||
}
|
||||
port, ok := envMap["PANEL_APP_PORT_HTTP"].(float64)
|
||||
if ok {
|
||||
info.Port = int64(port)
|
||||
}
|
||||
info.ID = appInstall.ID
|
||||
info.ContainerName = appInstall.ContainerName
|
||||
info.Name = appInstall.Name
|
||||
info.Env = appInstall.Env
|
||||
info.Param = appInstall.Param
|
||||
info.Version = appInstall.Version
|
||||
return &info, nil
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package repo
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
"gorm.io/gorm"
|
||||
@ -26,6 +27,16 @@ func (a AppInstallResourceRpo) GetBy(opts ...DBOption) ([]model.AppInstallResour
|
||||
return resources, err
|
||||
}
|
||||
|
||||
func (a AppInstallResourceRpo) GetFirst(opts ...DBOption) (model.AppInstallResource, error) {
|
||||
db := global.DB.Model(&model.AppInstallResource{})
|
||||
var resources model.AppInstallResource
|
||||
for _, opt := range opts {
|
||||
db = opt(db)
|
||||
}
|
||||
err := db.First(&resources).Error
|
||||
return resources, err
|
||||
}
|
||||
|
||||
func (a AppInstallResourceRpo) Create(ctx context.Context, resource *model.AppInstallResource) error {
|
||||
db := getTx(ctx).Model(&model.AppInstallResource{})
|
||||
return db.Create(&resource).Error
|
||||
|
@ -2,8 +2,6 @@ package repo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
@ -20,7 +18,6 @@ type IMysqlRepo interface {
|
||||
Create(ctx context.Context, mysql *model.DatabaseMysql) error
|
||||
Delete(ctx context.Context, opts ...DBOption) error
|
||||
Update(id uint, vars map[string]interface{}) error
|
||||
LoadBaseInfoByKey(key string) (*RootInfo, error)
|
||||
UpdateDatabaseInfo(id uint, vars map[string]interface{}) error
|
||||
}
|
||||
|
||||
@ -60,55 +57,6 @@ func (u *MysqlRepo) Page(page, size int, opts ...DBOption) (int64, []model.Datab
|
||||
return count, users, err
|
||||
}
|
||||
|
||||
type RootInfo struct {
|
||||
ID uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Port int64 `json:"port"`
|
||||
Password string `json:"password"`
|
||||
ContainerName string `json:"containerName"`
|
||||
Param string `json:"param"`
|
||||
Env string `json:"env"`
|
||||
Key string `json:"key"`
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
func (u *MysqlRepo) LoadBaseInfoByKey(key string) (*RootInfo, error) {
|
||||
var (
|
||||
app model.App
|
||||
appInstall model.AppInstall
|
||||
info RootInfo
|
||||
)
|
||||
if err := global.DB.Where("key = ?", key).First(&app).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := global.DB.Where("app_id = ?", app.ID).First(&appInstall).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
envMap := make(map[string]interface{})
|
||||
if err := json.Unmarshal([]byte(appInstall.Env), &envMap); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
password, ok := envMap["PANEL_DB_ROOT_PASSWORD"].(string)
|
||||
if ok {
|
||||
info.Password = password
|
||||
} else {
|
||||
return nil, errors.New("error password in db")
|
||||
}
|
||||
port, ok := envMap["PANEL_APP_PORT_HTTP"].(float64)
|
||||
if ok {
|
||||
info.Port = int64(port)
|
||||
} else {
|
||||
return nil, errors.New("error port in db")
|
||||
}
|
||||
info.ID = appInstall.ID
|
||||
info.ContainerName = appInstall.ContainerName
|
||||
info.Name = appInstall.Name
|
||||
info.Env = appInstall.Env
|
||||
info.Param = appInstall.Param
|
||||
info.Version = appInstall.Version
|
||||
return &info, nil
|
||||
}
|
||||
|
||||
func (u *MysqlRepo) Create(ctx context.Context, mysql *model.DatabaseMysql) error {
|
||||
return getTx(ctx).Create(mysql).Error
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ package service
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/repo"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
@ -11,6 +10,8 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/repo"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
@ -247,7 +248,7 @@ func (a AppInstallService) ChangeAppPort(req dto.PortUpdate) error {
|
||||
files []string
|
||||
newFiles []string
|
||||
)
|
||||
app, err := mysqlRepo.LoadBaseInfoByKey(req.Key)
|
||||
app, err := appInstallRepo.LoadBaseInfoByKey(req.Key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ type BackupService struct{}
|
||||
|
||||
type IBackupService interface {
|
||||
List() ([]dto.BackupInfo, error)
|
||||
SearchRecordWithPage(search dto.BackupSearch) (int64, []dto.BackupRecords, error)
|
||||
SearchRecordsWithPage(search dto.RecordSearch) (int64, []dto.BackupRecords, error)
|
||||
DownloadRecord(info dto.DownloadRecord) (string, error)
|
||||
Create(backupDto dto.BackupOperate) error
|
||||
GetBuckets(backupDto dto.ForBuckets) ([]interface{}, error)
|
||||
@ -45,7 +45,7 @@ func (u *BackupService) List() ([]dto.BackupInfo, error) {
|
||||
return dtobas, err
|
||||
}
|
||||
|
||||
func (u *BackupService) SearchRecordWithPage(search dto.BackupSearch) (int64, []dto.BackupRecords, error) {
|
||||
func (u *BackupService) SearchRecordsWithPage(search dto.RecordSearch) (int64, []dto.BackupRecords, error) {
|
||||
total, records, err := backupRepo.PageRecord(
|
||||
search.Page, search.PageSize,
|
||||
commonRepo.WithOrderBy("created_at desc"),
|
||||
|
@ -78,10 +78,6 @@ func (u *CronjobService) HandleBackup(cronjob *model.Cronjob, startTime time.Tim
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
app, err := mysqlRepo.LoadBaseInfoByKey("mysql")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if cronjob.KeepLocal || cronjob.Type != "LOCAL" {
|
||||
localDir, err := loadLocalDir()
|
||||
if err != nil {
|
||||
@ -93,6 +89,10 @@ func (u *CronjobService) HandleBackup(cronjob *model.Cronjob, startTime time.Tim
|
||||
}
|
||||
|
||||
if cronjob.Type == "database" {
|
||||
app, err := appInstallRepo.LoadBaseInfoByKey("mysql")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
fileName = fmt.Sprintf("db_%s_%s.sql.gz", cronjob.DBName, time.Now().Format("20060102150405"))
|
||||
backupDir = fmt.Sprintf("database/mysql/%s/%s", app.Name, cronjob.DBName)
|
||||
err = backupMysql(backup.Type, baseDir, backupDir, app.Name, cronjob.DBName, fileName)
|
||||
|
@ -33,7 +33,6 @@ type MysqlService struct{}
|
||||
type IMysqlService interface {
|
||||
SearchWithPage(search dto.PageInfo) (int64, interface{}, error)
|
||||
ListDBName() ([]string, error)
|
||||
SearchBackupsWithPage(search dto.SearchBackupsWithPage) (int64, interface{}, error)
|
||||
Create(mysqlDto dto.MysqlDBCreate) error
|
||||
ChangeInfo(info dto.ChangeDBInfo) error
|
||||
UpdateVariables(updatas []dto.MysqlVariablesUpdate) error
|
||||
@ -137,7 +136,7 @@ func (u *MysqlService) UpFile(mysqlName string, files []*multipart.FileHeader) e
|
||||
}
|
||||
|
||||
func (u *MysqlService) RecoverByUpload(req dto.UploadRecover) error {
|
||||
app, err := mysqlRepo.LoadBaseInfoByKey("mysql")
|
||||
app, err := appInstallRepo.LoadBaseInfoByKey("mysql")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -223,26 +222,11 @@ func (u *MysqlService) ListDBName() ([]string, error) {
|
||||
return dbNames, err
|
||||
}
|
||||
|
||||
func (u *MysqlService) SearchBackupsWithPage(search dto.SearchBackupsWithPage) (int64, interface{}, error) {
|
||||
app, err := mysqlRepo.LoadBaseInfoByKey("mysql")
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
searchDto := dto.BackupSearch{
|
||||
Type: "database-mysql",
|
||||
PageInfo: search.PageInfo,
|
||||
Name: app.Name,
|
||||
DetailName: search.DBName,
|
||||
}
|
||||
|
||||
return NewIBackupService().SearchRecordWithPage(searchDto)
|
||||
}
|
||||
|
||||
func (u *MysqlService) Create(mysqlDto dto.MysqlDBCreate) error {
|
||||
if mysqlDto.Username == "root" {
|
||||
return errors.New("Cannot set root as user name")
|
||||
}
|
||||
app, err := mysqlRepo.LoadBaseInfoByKey("mysql")
|
||||
app, err := appInstallRepo.LoadBaseInfoByKey("mysql")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -289,7 +273,7 @@ func (u *MysqlService) Backup(db dto.BackupDB) error {
|
||||
}
|
||||
|
||||
func (u *MysqlService) Recover(db dto.RecoverDB) error {
|
||||
app, err := mysqlRepo.LoadBaseInfoByKey("mysql")
|
||||
app, err := appInstallRepo.LoadBaseInfoByKey("mysql")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -314,7 +298,7 @@ func (u *MysqlService) Recover(db dto.RecoverDB) error {
|
||||
}
|
||||
|
||||
func (u *MysqlService) Delete(ids []uint) error {
|
||||
app, err := mysqlRepo.LoadBaseInfoByKey("mysql")
|
||||
app, err := appInstallRepo.LoadBaseInfoByKey("mysql")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -349,7 +333,7 @@ func (u *MysqlService) ChangeInfo(info dto.ChangeDBInfo) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
app, err := mysqlRepo.LoadBaseInfoByKey("mysql")
|
||||
app, err := appInstallRepo.LoadBaseInfoByKey("mysql")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -417,7 +401,7 @@ func (u *MysqlService) ChangeInfo(info dto.ChangeDBInfo) error {
|
||||
}
|
||||
|
||||
func (u *MysqlService) UpdateConfByFile(info dto.MysqlConfUpdateByFile) error {
|
||||
app, err := mysqlRepo.LoadBaseInfoByKey("mysql")
|
||||
app, err := appInstallRepo.LoadBaseInfoByKey("mysql")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -437,7 +421,7 @@ func (u *MysqlService) UpdateConfByFile(info dto.MysqlConfUpdateByFile) error {
|
||||
}
|
||||
|
||||
func (u *MysqlService) UpdateVariables(updatas []dto.MysqlVariablesUpdate) error {
|
||||
app, err := mysqlRepo.LoadBaseInfoByKey("mysql")
|
||||
app, err := appInstallRepo.LoadBaseInfoByKey("mysql")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -479,7 +463,7 @@ func (u *MysqlService) UpdateVariables(updatas []dto.MysqlVariablesUpdate) error
|
||||
|
||||
func (u *MysqlService) LoadBaseInfo() (*dto.DBBaseInfo, error) {
|
||||
var data dto.DBBaseInfo
|
||||
app, err := mysqlRepo.LoadBaseInfoByKey("mysql")
|
||||
app, err := appInstallRepo.LoadBaseInfoByKey("mysql")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -502,7 +486,7 @@ func (u *MysqlService) LoadBaseInfo() (*dto.DBBaseInfo, error) {
|
||||
}
|
||||
|
||||
func (u *MysqlService) LoadVariables() (*dto.MysqlVariables, error) {
|
||||
app, err := mysqlRepo.LoadBaseInfoByKey("mysql")
|
||||
app, err := appInstallRepo.LoadBaseInfoByKey("mysql")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -520,7 +504,7 @@ func (u *MysqlService) LoadVariables() (*dto.MysqlVariables, error) {
|
||||
}
|
||||
|
||||
func (u *MysqlService) LoadStatus() (*dto.MysqlStatus, error) {
|
||||
app, err := mysqlRepo.LoadBaseInfoByKey("mysql")
|
||||
app, err := appInstallRepo.LoadBaseInfoByKey("mysql")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -604,7 +588,7 @@ func excuteSql(containerName, password, command string) error {
|
||||
}
|
||||
|
||||
func backupMysql(backupType, baseDir, backupDir, mysqlName, dbName, fileName string) error {
|
||||
app, err := mysqlRepo.LoadBaseInfoByKey("mysql")
|
||||
app, err := appInstallRepo.LoadBaseInfoByKey("mysql")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ func NewIRedisService() IRedisService {
|
||||
}
|
||||
|
||||
func (u *RedisService) UpdateConf(req dto.RedisConfUpdate) error {
|
||||
redisInfo, err := mysqlRepo.LoadBaseInfoByKey("redis")
|
||||
redisInfo, err := appInstallRepo.LoadBaseInfoByKey("redis")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -70,7 +70,7 @@ func (u *RedisService) UpdateConf(req dto.RedisConfUpdate) error {
|
||||
}
|
||||
|
||||
func (u *RedisService) UpdatePersistenceConf(req dto.RedisConfPersistenceUpdate) error {
|
||||
redisInfo, err := mysqlRepo.LoadBaseInfoByKey("redis")
|
||||
redisInfo, err := appInstallRepo.LoadBaseInfoByKey("redis")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -97,7 +97,7 @@ func (u *RedisService) UpdatePersistenceConf(req dto.RedisConfPersistenceUpdate)
|
||||
}
|
||||
|
||||
func (u *RedisService) LoadStatus() (*dto.RedisStatus, error) {
|
||||
redisInfo, err := mysqlRepo.LoadBaseInfoByKey("redis")
|
||||
redisInfo, err := appInstallRepo.LoadBaseInfoByKey("redis")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -125,7 +125,7 @@ func (u *RedisService) LoadStatus() (*dto.RedisStatus, error) {
|
||||
}
|
||||
|
||||
func (u *RedisService) LoadConf() (*dto.RedisConf, error) {
|
||||
redisInfo, err := mysqlRepo.LoadBaseInfoByKey("redis")
|
||||
redisInfo, err := appInstallRepo.LoadBaseInfoByKey("redis")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -150,7 +150,7 @@ func (u *RedisService) LoadConf() (*dto.RedisConf, error) {
|
||||
}
|
||||
|
||||
func (u *RedisService) LoadPersistenceConf() (*dto.RedisPersistence, error) {
|
||||
redisInfo, err := mysqlRepo.LoadBaseInfoByKey("redis")
|
||||
redisInfo, err := appInstallRepo.LoadBaseInfoByKey("redis")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -169,7 +169,7 @@ func (u *RedisService) LoadPersistenceConf() (*dto.RedisPersistence, error) {
|
||||
}
|
||||
|
||||
func (u *RedisService) Backup() error {
|
||||
redisInfo, err := mysqlRepo.LoadBaseInfoByKey("redis")
|
||||
redisInfo, err := appInstallRepo.LoadBaseInfoByKey("redis")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -214,7 +214,7 @@ func (u *RedisService) Backup() error {
|
||||
}
|
||||
|
||||
func (u *RedisService) Recover(req dto.RedisBackupRecover) error {
|
||||
redisInfo, err := mysqlRepo.LoadBaseInfoByKey("redis")
|
||||
redisInfo, err := appInstallRepo.LoadBaseInfoByKey("redis")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -254,7 +254,7 @@ func (u *RedisService) SearchBackupListWithPage(req dto.PageInfo) (int64, interf
|
||||
list []dto.DatabaseFileRecords
|
||||
backDatas []dto.DatabaseFileRecords
|
||||
)
|
||||
redisInfo, err := mysqlRepo.LoadBaseInfoByKey("redis")
|
||||
redisInfo, err := appInstallRepo.LoadBaseInfoByKey("redis")
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
|
@ -1,13 +1,15 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type NginxService struct {
|
||||
@ -57,7 +59,7 @@ func (n NginxService) GetStatus() (dto.NginxStatus, error) {
|
||||
}
|
||||
res, err := cmd.Exec(fmt.Sprintf("docker exec -i %s curl http://127.0.0.1/nginx_status", nginxInstall.ContainerName))
|
||||
if err != nil {
|
||||
return dto.NginxStatus{}, err
|
||||
return dto.NginxStatus{}, errors.New(res)
|
||||
}
|
||||
var status dto.NginxStatus
|
||||
resArray := strings.Split(res, " ")
|
||||
|
@ -5,16 +5,21 @@ import (
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
||||
"github.com/pkg/errors"
|
||||
"gorm.io/gorm"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
||||
"github.com/pkg/errors"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type WebsiteService struct {
|
||||
@ -101,6 +106,101 @@ func (w WebsiteService) CreateWebsite(create dto.WebSiteCreate) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w WebsiteService) Backup(id uint) error {
|
||||
website, err := websiteRepo.GetFirst(commonRepo.WithByID(id))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
app, err := appInstallRepo.GetFirst(commonRepo.WithByID(website.AppInstallID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resource, err := appInstallResourceRepo.GetFirst(appInstallResourceRepo.WithAppInstallId(website.AppInstallID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mysqlInfo, err := appInstallRepo.LoadBaseInfoByKey(resource.Key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
nginxInfo, err := appInstallRepo.LoadBaseInfoByKey("nginx")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
db, err := mysqlRepo.Get(commonRepo.WithByID(resource.ResourceId))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
localDir, err := loadLocalDir()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
name := fmt.Sprintf("%s_%s", website.PrimaryDomain, time.Now().Format("20060102150405"))
|
||||
backupDir := fmt.Sprintf("website/%s/%s", website.PrimaryDomain, name)
|
||||
fullDir := fmt.Sprintf("%s/%s", localDir, backupDir)
|
||||
if _, err := os.Stat(fullDir); err != nil && os.IsNotExist(err) {
|
||||
if err = os.MkdirAll(fullDir, os.ModePerm); err != nil {
|
||||
if err != nil {
|
||||
return fmt.Errorf("mkdir %s failed, err: %v", fullDir, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
nginxConfFile := fmt.Sprintf("%s/nginx/%s/conf/conf.d/%s.conf", constant.AppInstallDir, nginxInfo.Name, website.PrimaryDomain)
|
||||
src, err := os.OpenFile(nginxConfFile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0775)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer src.Close()
|
||||
out, err := os.Create(fmt.Sprintf("%s/%s.conf", fullDir, website.PrimaryDomain))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer out.Close()
|
||||
_, _ = io.Copy(out, src)
|
||||
|
||||
if website.Type == "deployment" {
|
||||
dbFile := fmt.Sprintf("%s/%s.sql", fullDir, website.PrimaryDomain)
|
||||
outfile, _ := os.OpenFile(dbFile, os.O_RDWR|os.O_CREATE, 0755)
|
||||
cmd := exec.Command("docker", "exec", mysqlInfo.ContainerName, "mysqldump", "-uroot", "-p"+mysqlInfo.Password, db.Name)
|
||||
cmd.Stdout = outfile
|
||||
_ = cmd.Run()
|
||||
_ = cmd.Wait()
|
||||
|
||||
websiteDir := fmt.Sprintf("%s/%s/%s", constant.AppInstallDir, app.App.Key, app.Name)
|
||||
if err := handleTar(websiteDir, fullDir, fmt.Sprintf("%s.web.tar.gz", website.PrimaryDomain), ""); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
websiteDir := fmt.Sprintf("%s/nginx/%s/www/%s", constant.AppInstallDir, nginxInfo.Name, website.PrimaryDomain)
|
||||
if err := handleTar(websiteDir, fullDir, fmt.Sprintf("%s.web.tar.gz", website.PrimaryDomain), ""); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
tarDir := fmt.Sprintf("%s/website/%s", localDir, website.PrimaryDomain)
|
||||
tarName := fmt.Sprintf("%s.tar.gz", name)
|
||||
itemDir := strings.ReplaceAll(fullDir[strings.LastIndex(fullDir, "/"):], "/", "")
|
||||
aheadDir := strings.ReplaceAll(fullDir, itemDir, "")
|
||||
tarcmd := exec.Command("tar", "zcvf", fullDir+".tar.gz", "-C", aheadDir, itemDir)
|
||||
stdout, err := tarcmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return errors.New(string(stdout))
|
||||
}
|
||||
|
||||
record := &model.BackupRecord{
|
||||
Type: "website-" + website.Type,
|
||||
Name: website.PrimaryDomain,
|
||||
DetailName: "",
|
||||
Source: "LOCAL",
|
||||
BackupType: "LOCAL",
|
||||
FileDir: tarDir,
|
||||
FileName: tarName,
|
||||
}
|
||||
if err := backupRepo.CreateRecord(record); err != nil {
|
||||
global.LOG.Errorf("save backup record failed, err: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w WebsiteService) UpdateWebsite(req dto.WebSiteUpdate) error {
|
||||
website, err := websiteRepo.GetFirst(commonRepo.WithByID(req.ID))
|
||||
if err != nil {
|
||||
|
@ -25,6 +25,7 @@ func (s *BackupRouter) InitBackupRouter(Router *gin.RouterGroup) {
|
||||
baRouter.POST("/buckets", baseApi.ListBuckets)
|
||||
withRecordRouter.POST("", baseApi.CreateBackup)
|
||||
withRecordRouter.POST("/del", baseApi.DeleteBackup)
|
||||
withRecordRouter.POST("/record/search", baseApi.SearchBackupRecords)
|
||||
withRecordRouter.POST("/record/download", baseApi.DownloadRecord)
|
||||
withRecordRouter.POST("/record/del", baseApi.DeleteBackupRecord)
|
||||
withRecordRouter.PUT(":id", baseApi.UpdateBackup)
|
||||
|
@ -28,7 +28,6 @@ func (s *DatabaseRouter) InitDatabaseRouter(Router *gin.RouterGroup) {
|
||||
cmdRouter.POST("/uplist/upload/:mysqlName", baseApi.UploadMysqlFiles)
|
||||
withRecordRouter.POST("/recover/byupload", baseApi.RecoverMysqlByUpload)
|
||||
withRecordRouter.POST("/recover", baseApi.RecoverMysql)
|
||||
withRecordRouter.POST("/backups/search", baseApi.SearchDBBackups)
|
||||
withRecordRouter.POST("/del", baseApi.DeleteMysql)
|
||||
withRecordRouter.POST("/variables/update", baseApi.UpdateMysqlVariables)
|
||||
withRecordRouter.POST("/conf/update/byfile", baseApi.UpdateMysqlConfByFile)
|
||||
|
@ -16,6 +16,7 @@ func (a *WebsiteRouter) InitWebsiteRouter(Router *gin.RouterGroup) {
|
||||
baseApi := v1.ApiGroupApp.BaseApi
|
||||
{
|
||||
groupRouter.POST("", baseApi.CreateWebsite)
|
||||
groupRouter.POST("/backup/:id", baseApi.BackupWebsite)
|
||||
groupRouter.POST("/update", baseApi.UpdateWebSite)
|
||||
groupRouter.GET("/:id", baseApi.GetWebSite)
|
||||
groupRouter.GET("/:id/nginx", baseApi.GetWebSiteNginx)
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { ReqPage } from '.';
|
||||
|
||||
export namespace Backup {
|
||||
export interface BackupInfo {
|
||||
id: number;
|
||||
@ -31,4 +33,9 @@ export namespace Backup {
|
||||
credential: string;
|
||||
vars: string;
|
||||
}
|
||||
export interface SearchBackupRecord extends ReqPage {
|
||||
type: string;
|
||||
name: string;
|
||||
detailName: string;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import http from '@/api';
|
||||
import { Backup } from '../interface/backup';
|
||||
import { ResPage } from '../interface';
|
||||
|
||||
export const getBackupList = () => {
|
||||
return http.get<Array<Backup.BackupInfo>>(`/backups/search`);
|
||||
@ -23,6 +24,9 @@ export const downloadBackupRecord = (params: Backup.RecordDownload) => {
|
||||
export const deleteBackupRecord = (params: { ids: number[] }) => {
|
||||
return http.post(`/backups/record/del`, params);
|
||||
};
|
||||
export const searchBackupRecords = (params: Backup.SearchBackupRecord) => {
|
||||
return http.post<ResPage<Backup.RecordInfo>>(`/backups/record/search`, params);
|
||||
};
|
||||
|
||||
export const listBucket = (params: Backup.ForBucket) => {
|
||||
return http.post(`/backups/buckets`, params);
|
||||
|
@ -1,6 +1,5 @@
|
||||
import http from '@/api';
|
||||
import { ReqPage, ResPage } from '../interface';
|
||||
import { Backup } from '../interface/backup';
|
||||
import { Database } from '../interface/database';
|
||||
import { File } from '@/api/interface/file';
|
||||
|
||||
@ -23,9 +22,6 @@ export const recover = (params: Database.Recover) => {
|
||||
export const recoverByUpload = (params: Database.RecoverByUpload) => {
|
||||
return http.post(`/databases/recover/byupload`, params);
|
||||
};
|
||||
export const searchBackupRecords = (params: Database.SearchBackupRecord) => {
|
||||
return http.post<ResPage<Backup.RecordInfo>>(`/databases/backups/search`, params);
|
||||
};
|
||||
|
||||
export const addMysqlDB = (params: Database.MysqlDBCreate) => {
|
||||
return http.post(`/databases`, params);
|
||||
|
@ -11,6 +11,10 @@ export const CreateWebsite = (req: WebSite.WebSiteCreateReq) => {
|
||||
return http.post<any>(`/websites`, req);
|
||||
};
|
||||
|
||||
export const BackupWebsite = (id: number) => {
|
||||
return http.post(`/websites/backup/${id}`);
|
||||
};
|
||||
|
||||
export const UpdateWebsite = (req: WebSite.WebSiteUpdateReq) => {
|
||||
return http.post<any>(`/websites/update`, req);
|
||||
};
|
||||
|
@ -2,7 +2,7 @@
|
||||
<el-card v-loading="loading">
|
||||
<el-row :gutter="5">
|
||||
<el-col :span="2">
|
||||
<el-button @click="sync" type="primary" plain="true">{{ $t('app.sync') }}</el-button>
|
||||
<el-button @click="sync" type="primary" :plain="true">{{ $t('app.sync') }}</el-button>
|
||||
</el-col>
|
||||
<el-col :span="22">
|
||||
<div style="float: right">
|
||||
|
@ -4,7 +4,7 @@
|
||||
<template #toolbar>
|
||||
<el-row>
|
||||
<el-col :span="18">
|
||||
<el-button @click="sync" type="primary" plain="true">{{ $t('app.sync') }}</el-button>
|
||||
<el-button @click="sync" type="primary" :plain="true">{{ $t('app.sync') }}</el-button>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<div style="float: right">
|
||||
|
@ -36,10 +36,10 @@ import ComplexTable from '@/components/complex-table/index.vue';
|
||||
import { reactive, ref } from 'vue';
|
||||
import { dateFromat } from '@/utils/util';
|
||||
import { useDeleteData } from '@/hooks/use-delete-data';
|
||||
import { backup, recover, searchBackupRecords } from '@/api/modules/database';
|
||||
import { backup, recover } from '@/api/modules/database';
|
||||
import i18n from '@/lang';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { deleteBackupRecord, downloadBackupRecord } from '@/api/modules/backup';
|
||||
import { deleteBackupRecord, downloadBackupRecord, searchBackupRecords } from '@/api/modules/backup';
|
||||
import { Backup } from '@/api/interface/backup';
|
||||
|
||||
const selects = ref<any>([]);
|
||||
@ -69,8 +69,9 @@ const search = async () => {
|
||||
let params = {
|
||||
page: paginationConfig.currentPage,
|
||||
pageSize: paginationConfig.pageSize,
|
||||
mysqlName: mysqlName.value,
|
||||
dbName: dbName.value,
|
||||
type: 'database-mysql',
|
||||
name: mysqlName.value,
|
||||
detailName: dbName.value,
|
||||
};
|
||||
const res = await searchBackupRecords(params);
|
||||
data.value = res.data.items || [];
|
||||
|
144
frontend/src/views/website/website/backup/index.vue
Normal file
144
frontend/src/views/website/website/backup/index.vue
Normal file
@ -0,0 +1,144 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-dialog v-model="backupVisiable" :destroy-on-close="true" :close-on-click-modal="false" width="50%">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>{{ $t('database.backup') }} - {{ websiteName }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<ComplexTable :pagination-config="paginationConfig" v-model:selects="selects" @search="search" :data="data">
|
||||
<template #toolbar>
|
||||
<el-button type="primary" @click="onBackup()">
|
||||
{{ $t('database.backup') }}
|
||||
</el-button>
|
||||
<el-button type="danger" 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')" prop="fileName" show-overflow-tooltip />
|
||||
<el-table-column :label="$t('database.source')" prop="backupType" />
|
||||
<el-table-column
|
||||
prop="createdAt"
|
||||
:label="$t('commons.table.date')"
|
||||
:formatter="dateFromat"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
|
||||
<fu-table-operations :buttons="buttons" :label="$t('commons.table.operate')" fix />
|
||||
</ComplexTable>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import ComplexTable from '@/components/complex-table/index.vue';
|
||||
import { reactive, ref } from 'vue';
|
||||
import { dateFromat } from '@/utils/util';
|
||||
import { useDeleteData } from '@/hooks/use-delete-data';
|
||||
import i18n from '@/lang';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { deleteBackupRecord, downloadBackupRecord, searchBackupRecords } from '@/api/modules/backup';
|
||||
import { Backup } from '@/api/interface/backup';
|
||||
import { BackupWebsite } from '@/api/modules/website';
|
||||
|
||||
const selects = ref<any>([]);
|
||||
|
||||
const data = ref();
|
||||
const paginationConfig = reactive({
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
});
|
||||
|
||||
const backupVisiable = ref(false);
|
||||
const websiteName = ref();
|
||||
const websiteID = ref();
|
||||
const websiteType = ref();
|
||||
|
||||
interface DialogProps {
|
||||
id: string;
|
||||
type: string;
|
||||
name: string;
|
||||
}
|
||||
const acceptParams = (params: DialogProps): void => {
|
||||
websiteName.value = params.name;
|
||||
websiteID.value = params.id;
|
||||
websiteType.value = params.type;
|
||||
backupVisiable.value = true;
|
||||
search();
|
||||
};
|
||||
|
||||
const search = async () => {
|
||||
let params = {
|
||||
page: paginationConfig.currentPage,
|
||||
pageSize: paginationConfig.pageSize,
|
||||
type: 'website-' + websiteType.value,
|
||||
name: websiteName.value,
|
||||
detailName: '',
|
||||
};
|
||||
const res = await searchBackupRecords(params);
|
||||
data.value = res.data.items || [];
|
||||
paginationConfig.total = res.data.total;
|
||||
};
|
||||
|
||||
const onBackup = async () => {
|
||||
await BackupWebsite(websiteID.value);
|
||||
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
|
||||
search();
|
||||
};
|
||||
|
||||
const onDownload = async (row: Backup.RecordInfo) => {
|
||||
let params = {
|
||||
source: row.source,
|
||||
fileDir: row.fileDir,
|
||||
fileName: row.fileName,
|
||||
};
|
||||
const res = await downloadBackupRecord(params);
|
||||
const downloadUrl = window.URL.createObjectURL(new Blob([res]));
|
||||
const a = document.createElement('a');
|
||||
a.style.display = 'none';
|
||||
a.href = downloadUrl;
|
||||
a.download = row.fileName;
|
||||
const event = new MouseEvent('click');
|
||||
a.dispatchEvent(event);
|
||||
};
|
||||
|
||||
const onBatchDelete = async (row: Backup.RecordInfo | null) => {
|
||||
let ids: Array<number> = [];
|
||||
if (row) {
|
||||
ids.push(row.id);
|
||||
} else {
|
||||
selects.value.forEach((item: Backup.RecordInfo) => {
|
||||
ids.push(item.id);
|
||||
});
|
||||
}
|
||||
await useDeleteData(deleteBackupRecord, { ids: ids }, 'commons.msg.delete', true);
|
||||
search();
|
||||
};
|
||||
|
||||
const buttons = [
|
||||
{
|
||||
label: i18n.global.t('commons.button.delete'),
|
||||
click: (row: Backup.RecordInfo) => {
|
||||
onBatchDelete(row);
|
||||
},
|
||||
},
|
||||
// {
|
||||
// label: i18n.global.t('commons.button.recover'),
|
||||
// click: (row: Backup.RecordInfo) => {
|
||||
// onRecover(row);
|
||||
// },
|
||||
// },
|
||||
{
|
||||
label: i18n.global.t('commons.button.download'),
|
||||
click: (row: Backup.RecordInfo) => {
|
||||
onDownload(row);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
</script>
|
@ -57,7 +57,7 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import LayoutContent from '@/layout/layout-content.vue';
|
||||
import BackupRecords from '@/views/database/mysql/backup/index.vue';
|
||||
import BackupRecords from '@/views/website/website/backup/index.vue';
|
||||
import UploadDialog from '@/views/database/mysql/upload/index.vue';
|
||||
import ComplexTable from '@/components/complex-table/index.vue';
|
||||
import { onMounted, reactive, ref } from '@vue/runtime-core';
|
||||
@ -110,13 +110,7 @@ const openConfig = (id: number) => {
|
||||
|
||||
const uploadRef = ref();
|
||||
const dialogBackupRef = ref();
|
||||
const onOpenBackupDialog = async (dbName: string) => {
|
||||
let params = {
|
||||
mysqlName: 'test',
|
||||
dbName: dbName,
|
||||
};
|
||||
dialogBackupRef.value!.acceptParams(params);
|
||||
};
|
||||
|
||||
const buttons = [
|
||||
{
|
||||
label: i18n.global.t('website.config'),
|
||||
@ -127,7 +121,12 @@ const buttons = [
|
||||
{
|
||||
label: i18n.global.t('database.backupList'),
|
||||
click: (row: WebSite.WebSite) => {
|
||||
onOpenBackupDialog(row.primaryDomain);
|
||||
let params = {
|
||||
id: row.id,
|
||||
type: row.type,
|
||||
name: row.primaryDomain,
|
||||
};
|
||||
dialogBackupRef.value!.acceptParams(params);
|
||||
},
|
||||
},
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user