mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-18 22:22:59 +08:00
fix: 解决计划任务备份文件失效仍能下载的问题
This commit is contained in:
parent
fb286d2def
commit
4a974b7e0a
@ -175,7 +175,7 @@ func (b *BaseApi) DownloadRecord(c *gin.Context) {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
c.File(filePath)
|
||||
helper.SuccessWithData(c, filePath)
|
||||
}
|
||||
|
||||
// @Tags Backup Account
|
||||
|
@ -198,7 +198,7 @@ func (b *BaseApi) TargetDownload(c *gin.Context) {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
c.File(filePath)
|
||||
helper.SuccessWithData(c, filePath)
|
||||
}
|
||||
|
||||
// @Tags Cronjob
|
||||
|
@ -445,6 +445,28 @@ func (b *BaseApi) Download(c *gin.Context) {
|
||||
c.File(filePath)
|
||||
}
|
||||
|
||||
// @Tags File
|
||||
// @Summary Download file with path
|
||||
// @Description 下载指定文件
|
||||
// @Accept json
|
||||
// @Param request body request.FilePath true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /files/download/bypath [post]
|
||||
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"下载文件 [path]","formatEN":"Download file [path]"}
|
||||
func (b *BaseApi) DownloadFile(c *gin.Context) {
|
||||
var req dto.FilePath
|
||||
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
|
||||
}
|
||||
c.File(req.Path)
|
||||
}
|
||||
|
||||
// @Tags File
|
||||
// @Summary Load file size
|
||||
// @Description 获取文件夹大小
|
||||
|
@ -24,7 +24,7 @@ type ICronjobRepo interface {
|
||||
Update(id uint, vars map[string]interface{}) error
|
||||
Delete(opts ...DBOption) error
|
||||
DeleteRecord(opts ...DBOption) error
|
||||
StartRecords(cronjobID uint, targetPath string) model.JobRecords
|
||||
StartRecords(cronjobID uint, fromLocal bool, targetPath string) model.JobRecords
|
||||
EndRecords(record model.JobRecords, status, message, records string)
|
||||
}
|
||||
|
||||
@ -112,10 +112,11 @@ func (c *CronjobRepo) WithByJobID(id int) DBOption {
|
||||
}
|
||||
}
|
||||
|
||||
func (u *CronjobRepo) StartRecords(cronjobID uint, targetPath string) model.JobRecords {
|
||||
func (u *CronjobRepo) StartRecords(cronjobID uint, fromLocal bool, targetPath string) model.JobRecords {
|
||||
var record model.JobRecords
|
||||
record.StartTime = time.Now()
|
||||
record.CronjobID = cronjobID
|
||||
record.FromLocal = fromLocal
|
||||
record.Status = constant.StatusWaiting
|
||||
if err := global.DB.Create(&record).Error; err != nil {
|
||||
global.LOG.Errorf("create record status failed, err: %v", err)
|
||||
|
@ -2,17 +2,14 @@ package service
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"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/cloud_storage"
|
||||
"github.com/jinzhu/copier"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/robfig/cron/v3"
|
||||
@ -92,69 +89,28 @@ func (u *CronjobService) Download(down dto.CronjobDownload) (string, error) {
|
||||
if cronjob.ID == 0 {
|
||||
return "", constant.ErrRecordNotFound
|
||||
}
|
||||
|
||||
global.LOG.Infof("start to download records %s from %s", cronjob.Type, backup.Type)
|
||||
varMap := make(map[string]interface{})
|
||||
if err := json.Unmarshal([]byte(backup.Vars), &varMap); err != nil {
|
||||
if backup.Type == "LOCAL" {
|
||||
if _, err := os.Stat(record.File); err != nil && os.IsNotExist(err) {
|
||||
return "", constant.ErrRecordNotFound
|
||||
}
|
||||
return record.File, nil
|
||||
}
|
||||
if record.FromLocal {
|
||||
local, _ := loadLocalDir()
|
||||
if _, err := os.Stat(local + "/" + record.File); err == nil {
|
||||
return local + "/" + record.File, nil
|
||||
}
|
||||
}
|
||||
client, err := NewIBackupService().NewClient(&backup)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
varMap["type"] = backup.Type
|
||||
if backup.Type != "LOCAL" {
|
||||
varMap["bucket"] = backup.Bucket
|
||||
switch backup.Type {
|
||||
case constant.Sftp:
|
||||
varMap["username"] = backup.AccessKey
|
||||
varMap["password"] = backup.Credential
|
||||
case constant.OSS, constant.S3, constant.MinIo:
|
||||
varMap["accessKey"] = backup.AccessKey
|
||||
varMap["secretKey"] = backup.Credential
|
||||
}
|
||||
backClient, err := cloud_storage.NewCloudStorageClient(varMap)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("new cloud storage client failed, err: %v", err)
|
||||
}
|
||||
global.LOG.Info("new backup client successful")
|
||||
commonDir := fmt.Sprintf("%s/%s/", cronjob.Type, cronjob.Name)
|
||||
name := fmt.Sprintf("%s%s.tar.gz", commonDir, record.StartTime.Format("20060102150405"))
|
||||
if cronjob.Type == "database" {
|
||||
name = fmt.Sprintf("%s%s.gz", commonDir, record.StartTime.Format("20060102150405"))
|
||||
}
|
||||
tempPath := fmt.Sprintf("%s/download/%s", constant.DataDir, commonDir)
|
||||
if _, err := os.Stat(tempPath); err != nil && os.IsNotExist(err) {
|
||||
if err = os.MkdirAll(tempPath, os.ModePerm); err != nil {
|
||||
global.LOG.Errorf("mkdir %s failed, err: %v", tempPath, err)
|
||||
}
|
||||
}
|
||||
|
||||
global.LOG.Infof("download records %s from %s to %s", name, commonDir, tempPath)
|
||||
targetPath := tempPath + strings.ReplaceAll(name, commonDir, "")
|
||||
if _, err = os.Stat(targetPath); err != nil && os.IsNotExist(err) {
|
||||
isOK, err := backClient.Download(name, targetPath)
|
||||
if !isOK {
|
||||
return "", fmt.Errorf("cloud storage download failed, err: %v", err)
|
||||
}
|
||||
}
|
||||
return targetPath, nil
|
||||
}
|
||||
if _, ok := varMap["dir"]; !ok {
|
||||
return "", errors.New("load local backup dir failed")
|
||||
}
|
||||
global.LOG.Infof("record is save in local dir %s", varMap["dir"])
|
||||
|
||||
switch cronjob.Type {
|
||||
case "website":
|
||||
return fmt.Sprintf("%v/website/%s/website_%s_%s.tar.gz", varMap["dir"], cronjob.Website, cronjob.Website, record.StartTime.Format("20060102150405")), nil
|
||||
case "database":
|
||||
mysqlInfo, err := appInstallRepo.LoadBaseInfo("mysql", "")
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("load mysqlInfo failed, err: %v", err)
|
||||
}
|
||||
return fmt.Sprintf("%v/database/mysql/%s/%s/db_%s_%s.sql.gz", varMap["dir"], mysqlInfo.Name, cronjob.DBName, cronjob.DBName, record.StartTime.Format("20060102150405")), nil
|
||||
case "directory":
|
||||
return fmt.Sprintf("%v/%s/%s/directory%s_%s.tar.gz", varMap["dir"], cronjob.Type, cronjob.Name, strings.ReplaceAll(cronjob.SourceDir, "/", "_"), record.StartTime.Format("20060102150405")), nil
|
||||
default:
|
||||
return "", fmt.Errorf("not support type %s", cronjob.Type)
|
||||
tempPath := fmt.Sprintf("%s/download/%s", constant.DataDir, record.File)
|
||||
isOK, _ := client.Download(record.File, tempPath)
|
||||
if !isOK || err != nil {
|
||||
return "", constant.ErrRecordNotFound
|
||||
}
|
||||
return tempPath, nil
|
||||
}
|
||||
|
||||
func (u *CronjobService) HandleOnce(id uint) error {
|
||||
|
@ -22,8 +22,7 @@ func (u *CronjobService) HandleJob(cronjob *model.Cronjob) {
|
||||
message []byte
|
||||
err error
|
||||
)
|
||||
record := cronjobRepo.StartRecords(cronjob.ID, "")
|
||||
record.FromLocal = cronjob.KeepLocal
|
||||
record := cronjobRepo.StartRecords(cronjob.ID, cronjob.KeepLocal, "")
|
||||
go func() {
|
||||
switch cronjob.Type {
|
||||
case "shell":
|
||||
@ -135,7 +134,10 @@ func (u *CronjobService) HandleBackup(cronjob *model.Cronjob, startTime time.Tim
|
||||
}
|
||||
}
|
||||
|
||||
fullPath := fmt.Sprintf("%s/%s", record.FileDir, fileName)
|
||||
fullPath := fmt.Sprintf("%s/%s", backupDir, fileName)
|
||||
if backup.Type != "LOCAL" {
|
||||
fullPath = fmt.Sprintf("%s/%s", itemFileDir, fileName)
|
||||
}
|
||||
if backup.Type == "LOCAL" {
|
||||
u.HandleRmExpired(backup.Type, backupDir, cronjob, nil)
|
||||
return fullPath, nil
|
||||
|
@ -32,6 +32,7 @@ func (f *FileRouter) InitFileRouter(Router *gin.RouterGroup) {
|
||||
fileRouter.POST("/wget", baseApi.WgetFile)
|
||||
fileRouter.POST("/move", baseApi.MoveFile)
|
||||
fileRouter.POST("/download", baseApi.Download)
|
||||
fileRouter.POST("/download/bypath", baseApi.DownloadFile)
|
||||
fileRouter.POST("/size", baseApi.Size)
|
||||
fileRouter.GET("/ws", baseApi.Ws)
|
||||
fileRouter.GET("/keys", baseApi.Keys)
|
||||
|
@ -62,6 +62,25 @@ var doc = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/apps/checkupdate": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "获取应用更新版本",
|
||||
"tags": [
|
||||
"App"
|
||||
],
|
||||
"summary": "Get app list update",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/apps/detail/:appId/:version": {
|
||||
"get": {
|
||||
"security": [
|
||||
@ -470,6 +489,48 @@ var doc = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/apps/installed/params/update": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "修改应用参数",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"App"
|
||||
],
|
||||
"summary": "Change app params",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "request",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/request.AppInstalledUpdate"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"x-panel-log": {
|
||||
"BeforeFuntions": [],
|
||||
"bodyKeys": [
|
||||
"installId"
|
||||
],
|
||||
"formatEN": "Application param update [installId]",
|
||||
"formatZH": "应用参数修改 [installId]",
|
||||
"paramKeys": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"/apps/installed/port/change": {
|
||||
"post": {
|
||||
"security": [
|
||||
@ -683,6 +744,20 @@ var doc = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/auth/demo": {
|
||||
"get": {
|
||||
"description": "判断是否为demo环境",
|
||||
"tags": [
|
||||
"Auth"
|
||||
],
|
||||
"summary": "Check System isDemo",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/auth/init": {
|
||||
"post": {
|
||||
"description": "初始化用户",
|
||||
@ -3899,6 +3974,43 @@ var doc = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/files/chunkupload": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "分片上传文件",
|
||||
"tags": [
|
||||
"File"
|
||||
],
|
||||
"summary": "ChunkUpload file",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "file",
|
||||
"description": "request",
|
||||
"name": "file",
|
||||
"in": "formData",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"x-panel-log": {
|
||||
"BeforeFuntions": [],
|
||||
"bodyKeys": [
|
||||
"path"
|
||||
],
|
||||
"formatEN": "Upload file [path]",
|
||||
"formatZH": "上传文件 [path]",
|
||||
"paramKeys": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"/files/compress": {
|
||||
"post": {
|
||||
"security": [
|
||||
@ -4112,6 +4224,48 @@ var doc = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/files/download/bypath": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "下载指定文件",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"File"
|
||||
],
|
||||
"summary": "Download file with path",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "request",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/request.FilePath"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"x-panel-log": {
|
||||
"BeforeFuntions": [],
|
||||
"bodyKeys": [
|
||||
"path"
|
||||
],
|
||||
"formatEN": "Download file [path]",
|
||||
"formatZH": "下载文件 [path]",
|
||||
"paramKeys": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"/files/loadfile": {
|
||||
"post": {
|
||||
"security": [
|
||||
@ -8623,8 +8777,7 @@ var doc = `{
|
||||
"dto.ComposeCreate": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"from",
|
||||
"name"
|
||||
"from"
|
||||
],
|
||||
"properties": {
|
||||
"file": {
|
||||
@ -8860,9 +9013,7 @@ var doc = `{
|
||||
],
|
||||
"properties": {
|
||||
"day": {
|
||||
"type": "integer",
|
||||
"maximum": 31,
|
||||
"minimum": 1
|
||||
"type": "integer"
|
||||
},
|
||||
"dbName": {
|
||||
"type": "string"
|
||||
@ -8871,17 +9022,13 @@ var doc = `{
|
||||
"type": "string"
|
||||
},
|
||||
"hour": {
|
||||
"type": "integer",
|
||||
"maximum": 23,
|
||||
"minimum": 0
|
||||
"type": "integer"
|
||||
},
|
||||
"keepLocal": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"minute": {
|
||||
"type": "integer",
|
||||
"maximum": 59,
|
||||
"minimum": 0
|
||||
"type": "integer"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
@ -8942,9 +9089,7 @@ var doc = `{
|
||||
],
|
||||
"properties": {
|
||||
"day": {
|
||||
"type": "integer",
|
||||
"maximum": 31,
|
||||
"minimum": 1
|
||||
"type": "integer"
|
||||
},
|
||||
"dbName": {
|
||||
"type": "string"
|
||||
@ -8953,9 +9098,7 @@ var doc = `{
|
||||
"type": "string"
|
||||
},
|
||||
"hour": {
|
||||
"type": "integer",
|
||||
"maximum": 23,
|
||||
"minimum": 0
|
||||
"type": "integer"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
@ -8964,9 +9107,7 @@ var doc = `{
|
||||
"type": "boolean"
|
||||
},
|
||||
"minute": {
|
||||
"type": "integer",
|
||||
"maximum": 59,
|
||||
"minimum": 0
|
||||
"type": "integer"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
@ -9060,15 +9201,9 @@ var doc = `{
|
||||
},
|
||||
"dto.DaemonJsonUpdateByFile": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"path"
|
||||
],
|
||||
"properties": {
|
||||
"file": {
|
||||
"type": "string"
|
||||
},
|
||||
"path": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -9254,6 +9389,12 @@ var doc = `{
|
||||
"restart",
|
||||
"stop"
|
||||
]
|
||||
},
|
||||
"stopService": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"stopSocket": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -11042,6 +11183,22 @@ var doc = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"request.AppInstalledUpdate": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"installId",
|
||||
"params"
|
||||
],
|
||||
"properties": {
|
||||
"installId": {
|
||||
"type": "integer"
|
||||
},
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"request.AppSearch": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
@ -11284,6 +11441,17 @@ var doc = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"request.FilePath": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"path"
|
||||
],
|
||||
"properties": {
|
||||
"path": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"request.FilePathCheck": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
@ -12042,7 +12210,22 @@ var doc = `{
|
||||
"response.AppParam": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"label": {
|
||||
"edit": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"key": {
|
||||
"type": "string"
|
||||
},
|
||||
"labelEn": {
|
||||
"type": "string"
|
||||
},
|
||||
"labelZh": {
|
||||
"type": "string"
|
||||
},
|
||||
"rule": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"value": {}
|
||||
@ -12185,6 +12368,9 @@ var doc = `{
|
||||
"appInstallId": {
|
||||
"type": "integer"
|
||||
},
|
||||
"appName": {
|
||||
"type": "string"
|
||||
},
|
||||
"createdAt": {
|
||||
"type": "string"
|
||||
},
|
||||
|
@ -48,6 +48,25 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/apps/checkupdate": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "获取应用更新版本",
|
||||
"tags": [
|
||||
"App"
|
||||
],
|
||||
"summary": "Get app list update",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/apps/detail/:appId/:version": {
|
||||
"get": {
|
||||
"security": [
|
||||
@ -456,6 +475,48 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/apps/installed/params/update": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "修改应用参数",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"App"
|
||||
],
|
||||
"summary": "Change app params",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "request",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/request.AppInstalledUpdate"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"x-panel-log": {
|
||||
"BeforeFuntions": [],
|
||||
"bodyKeys": [
|
||||
"installId"
|
||||
],
|
||||
"formatEN": "Application param update [installId]",
|
||||
"formatZH": "应用参数修改 [installId]",
|
||||
"paramKeys": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"/apps/installed/port/change": {
|
||||
"post": {
|
||||
"security": [
|
||||
@ -669,6 +730,20 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/auth/demo": {
|
||||
"get": {
|
||||
"description": "判断是否为demo环境",
|
||||
"tags": [
|
||||
"Auth"
|
||||
],
|
||||
"summary": "Check System isDemo",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/auth/init": {
|
||||
"post": {
|
||||
"description": "初始化用户",
|
||||
@ -3885,6 +3960,43 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/files/chunkupload": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "分片上传文件",
|
||||
"tags": [
|
||||
"File"
|
||||
],
|
||||
"summary": "ChunkUpload file",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "file",
|
||||
"description": "request",
|
||||
"name": "file",
|
||||
"in": "formData",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"x-panel-log": {
|
||||
"BeforeFuntions": [],
|
||||
"bodyKeys": [
|
||||
"path"
|
||||
],
|
||||
"formatEN": "Upload file [path]",
|
||||
"formatZH": "上传文件 [path]",
|
||||
"paramKeys": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"/files/compress": {
|
||||
"post": {
|
||||
"security": [
|
||||
@ -4098,6 +4210,48 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/files/download/bypath": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "下载指定文件",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"File"
|
||||
],
|
||||
"summary": "Download file with path",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "request",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/request.FilePath"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"x-panel-log": {
|
||||
"BeforeFuntions": [],
|
||||
"bodyKeys": [
|
||||
"path"
|
||||
],
|
||||
"formatEN": "Download file [path]",
|
||||
"formatZH": "下载文件 [path]",
|
||||
"paramKeys": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"/files/loadfile": {
|
||||
"post": {
|
||||
"security": [
|
||||
@ -8609,8 +8763,7 @@
|
||||
"dto.ComposeCreate": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"from",
|
||||
"name"
|
||||
"from"
|
||||
],
|
||||
"properties": {
|
||||
"file": {
|
||||
@ -8846,9 +8999,7 @@
|
||||
],
|
||||
"properties": {
|
||||
"day": {
|
||||
"type": "integer",
|
||||
"maximum": 31,
|
||||
"minimum": 1
|
||||
"type": "integer"
|
||||
},
|
||||
"dbName": {
|
||||
"type": "string"
|
||||
@ -8857,17 +9008,13 @@
|
||||
"type": "string"
|
||||
},
|
||||
"hour": {
|
||||
"type": "integer",
|
||||
"maximum": 23,
|
||||
"minimum": 0
|
||||
"type": "integer"
|
||||
},
|
||||
"keepLocal": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"minute": {
|
||||
"type": "integer",
|
||||
"maximum": 59,
|
||||
"minimum": 0
|
||||
"type": "integer"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
@ -8928,9 +9075,7 @@
|
||||
],
|
||||
"properties": {
|
||||
"day": {
|
||||
"type": "integer",
|
||||
"maximum": 31,
|
||||
"minimum": 1
|
||||
"type": "integer"
|
||||
},
|
||||
"dbName": {
|
||||
"type": "string"
|
||||
@ -8939,9 +9084,7 @@
|
||||
"type": "string"
|
||||
},
|
||||
"hour": {
|
||||
"type": "integer",
|
||||
"maximum": 23,
|
||||
"minimum": 0
|
||||
"type": "integer"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
@ -8950,9 +9093,7 @@
|
||||
"type": "boolean"
|
||||
},
|
||||
"minute": {
|
||||
"type": "integer",
|
||||
"maximum": 59,
|
||||
"minimum": 0
|
||||
"type": "integer"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
@ -9046,15 +9187,9 @@
|
||||
},
|
||||
"dto.DaemonJsonUpdateByFile": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"path"
|
||||
],
|
||||
"properties": {
|
||||
"file": {
|
||||
"type": "string"
|
||||
},
|
||||
"path": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -9240,6 +9375,12 @@
|
||||
"restart",
|
||||
"stop"
|
||||
]
|
||||
},
|
||||
"stopService": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"stopSocket": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -11028,6 +11169,22 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"request.AppInstalledUpdate": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"installId",
|
||||
"params"
|
||||
],
|
||||
"properties": {
|
||||
"installId": {
|
||||
"type": "integer"
|
||||
},
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"request.AppSearch": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
@ -11270,6 +11427,17 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"request.FilePath": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"path"
|
||||
],
|
||||
"properties": {
|
||||
"path": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"request.FilePathCheck": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
@ -12028,7 +12196,22 @@
|
||||
"response.AppParam": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"label": {
|
||||
"edit": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"key": {
|
||||
"type": "string"
|
||||
},
|
||||
"labelEn": {
|
||||
"type": "string"
|
||||
},
|
||||
"labelZh": {
|
||||
"type": "string"
|
||||
},
|
||||
"rule": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"value": {}
|
||||
@ -12171,6 +12354,9 @@
|
||||
"appInstallId": {
|
||||
"type": "integer"
|
||||
},
|
||||
"appName": {
|
||||
"type": "string"
|
||||
},
|
||||
"createdAt": {
|
||||
"type": "string"
|
||||
},
|
||||
|
@ -152,7 +152,6 @@ definitions:
|
||||
type: integer
|
||||
required:
|
||||
- from
|
||||
- name
|
||||
type: object
|
||||
dto.ComposeOperation:
|
||||
properties:
|
||||
@ -294,22 +293,16 @@ definitions:
|
||||
dto.CronjobCreate:
|
||||
properties:
|
||||
day:
|
||||
maximum: 31
|
||||
minimum: 1
|
||||
type: integer
|
||||
dbName:
|
||||
type: string
|
||||
exclusionRules:
|
||||
type: string
|
||||
hour:
|
||||
maximum: 23
|
||||
minimum: 0
|
||||
type: integer
|
||||
keepLocal:
|
||||
type: boolean
|
||||
minute:
|
||||
maximum: 59
|
||||
minimum: 0
|
||||
type: integer
|
||||
name:
|
||||
type: string
|
||||
@ -352,24 +345,18 @@ definitions:
|
||||
dto.CronjobUpdate:
|
||||
properties:
|
||||
day:
|
||||
maximum: 31
|
||||
minimum: 1
|
||||
type: integer
|
||||
dbName:
|
||||
type: string
|
||||
exclusionRules:
|
||||
type: string
|
||||
hour:
|
||||
maximum: 23
|
||||
minimum: 0
|
||||
type: integer
|
||||
id:
|
||||
type: integer
|
||||
keepLocal:
|
||||
type: boolean
|
||||
minute:
|
||||
maximum: 59
|
||||
minimum: 0
|
||||
type: integer
|
||||
name:
|
||||
type: string
|
||||
@ -439,10 +426,6 @@ definitions:
|
||||
properties:
|
||||
file:
|
||||
type: string
|
||||
path:
|
||||
type: string
|
||||
required:
|
||||
- path
|
||||
type: object
|
||||
dto.DashboardBase:
|
||||
properties:
|
||||
@ -564,6 +547,10 @@ definitions:
|
||||
- restart
|
||||
- stop
|
||||
type: string
|
||||
stopService:
|
||||
type: boolean
|
||||
stopSocket:
|
||||
type: boolean
|
||||
required:
|
||||
- operation
|
||||
type: object
|
||||
@ -1752,6 +1739,17 @@ definitions:
|
||||
- page
|
||||
- pageSize
|
||||
type: object
|
||||
request.AppInstalledUpdate:
|
||||
properties:
|
||||
installId:
|
||||
type: integer
|
||||
params:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
required:
|
||||
- installId
|
||||
- params
|
||||
type: object
|
||||
request.AppSearch:
|
||||
properties:
|
||||
name:
|
||||
@ -1914,6 +1912,13 @@ definitions:
|
||||
showHidden:
|
||||
type: boolean
|
||||
type: object
|
||||
request.FilePath:
|
||||
properties:
|
||||
path:
|
||||
type: string
|
||||
required:
|
||||
- path
|
||||
type: object
|
||||
request.FilePathCheck:
|
||||
properties:
|
||||
path:
|
||||
@ -2421,7 +2426,17 @@ definitions:
|
||||
type: object
|
||||
response.AppParam:
|
||||
properties:
|
||||
label:
|
||||
edit:
|
||||
type: boolean
|
||||
key:
|
||||
type: string
|
||||
labelEn:
|
||||
type: string
|
||||
labelZh:
|
||||
type: string
|
||||
rule:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
value: {}
|
||||
type: object
|
||||
@ -2515,6 +2530,8 @@ definitions:
|
||||
type: string
|
||||
appInstallId:
|
||||
type: integer
|
||||
appName:
|
||||
type: string
|
||||
createdAt:
|
||||
type: string
|
||||
defaultServer:
|
||||
@ -2628,6 +2645,17 @@ paths:
|
||||
summary: Search app by key
|
||||
tags:
|
||||
- App
|
||||
/apps/checkupdate:
|
||||
get:
|
||||
description: 获取应用更新版本
|
||||
responses:
|
||||
"200":
|
||||
description: ""
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Get app list update
|
||||
tags:
|
||||
- App
|
||||
/apps/detail/:appId/:version:
|
||||
get:
|
||||
consumes:
|
||||
@ -2887,6 +2915,33 @@ paths:
|
||||
summary: Search params by appInstallId
|
||||
tags:
|
||||
- App
|
||||
/apps/installed/params/update:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 修改应用参数
|
||||
parameters:
|
||||
- description: request
|
||||
in: body
|
||||
name: request
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/request.AppInstalledUpdate'
|
||||
responses:
|
||||
"200":
|
||||
description: ""
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Change app params
|
||||
tags:
|
||||
- App
|
||||
x-panel-log:
|
||||
BeforeFuntions: []
|
||||
bodyKeys:
|
||||
- installId
|
||||
formatEN: Application param update [installId]
|
||||
formatZH: 应用参数修改 [installId]
|
||||
paramKeys: []
|
||||
/apps/installed/port/change:
|
||||
post:
|
||||
consumes:
|
||||
@ -3022,6 +3077,15 @@ paths:
|
||||
summary: Load captcha
|
||||
tags:
|
||||
- Auth
|
||||
/auth/demo:
|
||||
get:
|
||||
description: 判断是否为demo环境
|
||||
responses:
|
||||
"200":
|
||||
description: ""
|
||||
summary: Check System isDemo
|
||||
tags:
|
||||
- Auth
|
||||
/auth/init:
|
||||
post:
|
||||
consumes:
|
||||
@ -5065,6 +5129,30 @@ paths:
|
||||
formatEN: Check whether file [path] exists
|
||||
formatZH: 检测文件 [path] 是否存在
|
||||
paramKeys: []
|
||||
/files/chunkupload:
|
||||
post:
|
||||
description: 分片上传文件
|
||||
parameters:
|
||||
- description: request
|
||||
in: formData
|
||||
name: file
|
||||
required: true
|
||||
type: file
|
||||
responses:
|
||||
"200":
|
||||
description: ""
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: ChunkUpload file
|
||||
tags:
|
||||
- File
|
||||
x-panel-log:
|
||||
BeforeFuntions: []
|
||||
bodyKeys:
|
||||
- path
|
||||
formatEN: Upload file [path]
|
||||
formatZH: 上传文件 [path]
|
||||
paramKeys: []
|
||||
/files/compress:
|
||||
post:
|
||||
consumes:
|
||||
@ -5202,6 +5290,33 @@ paths:
|
||||
formatEN: Download file [name]
|
||||
formatZH: 下载文件 [name]
|
||||
paramKeys: []
|
||||
/files/download/bypath:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 下载指定文件
|
||||
parameters:
|
||||
- description: request
|
||||
in: body
|
||||
name: request
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/request.FilePath'
|
||||
responses:
|
||||
"200":
|
||||
description: ""
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Download file with path
|
||||
tags:
|
||||
- File
|
||||
x-panel-log:
|
||||
BeforeFuntions: []
|
||||
bodyKeys:
|
||||
- path
|
||||
formatEN: Download file [path]
|
||||
formatZH: 下载文件 [path]
|
||||
paramKeys: []
|
||||
/files/loadfile:
|
||||
post:
|
||||
consumes:
|
||||
|
@ -6,7 +6,7 @@ export const searchContainer = (params: Container.ContainerSearch) => {
|
||||
return http.post<ResPage<Container.ContainerInfo>>(`/containers/search`, params);
|
||||
};
|
||||
export const createContainer = (params: Container.ContainerCreate) => {
|
||||
return http.post(`/containers`, params);
|
||||
return http.post(`/containers`, params, 1200000);
|
||||
};
|
||||
export const logContainer = (params: Container.ContainerLogSearch) => {
|
||||
return http.post<string>(`/containers/search/log`, params);
|
||||
@ -38,10 +38,10 @@ export const imagePush = (params: Container.ImagePush) => {
|
||||
return http.post<string>(`/containers/image/push`, params);
|
||||
};
|
||||
export const imageLoad = (params: Container.ImageLoad) => {
|
||||
return http.post(`/containers/image/load`, params);
|
||||
return http.post(`/containers/image/load`, params, 1200000);
|
||||
};
|
||||
export const imageSave = (params: Container.ImageSave) => {
|
||||
return http.post(`/containers/image/save`, params);
|
||||
return http.post(`/containers/image/save`, params, 1200000);
|
||||
};
|
||||
export const imageTag = (params: Container.ImageTag) => {
|
||||
return http.post(`/containers/image/tag`, params);
|
||||
@ -117,13 +117,13 @@ export const searchCompose = (params: SearchWithPage) => {
|
||||
return http.post<ResPage<Container.ComposeInfo>>(`/containers/compose/search`, params);
|
||||
};
|
||||
export const upCompose = (params: Container.ComposeCreate) => {
|
||||
return http.post(`/containers/compose`, params);
|
||||
return http.post(`/containers/compose`, params, 600000);
|
||||
};
|
||||
export const composeOperator = (params: Container.ComposeOpration) => {
|
||||
return http.post(`/containers/compose/operate`, params);
|
||||
};
|
||||
export const composeUpdate = (params: Container.ComposeUpdate) => {
|
||||
return http.post(`/containers/compose/update`, params);
|
||||
return http.post(`/containers/compose/update`, params, 600000);
|
||||
};
|
||||
|
||||
// docker
|
||||
|
@ -31,7 +31,7 @@ export const updateStatus = (params: Cronjob.UpdateStatus) => {
|
||||
};
|
||||
|
||||
export const download = (params: Cronjob.Download) => {
|
||||
return http.download<BlobPart>(`cronjobs/download`, params, { responseType: 'blob' });
|
||||
return http.post<string>(`cronjobs/download`, params);
|
||||
};
|
||||
|
||||
export const handleOnce = (id: number) => {
|
||||
|
@ -79,6 +79,10 @@ export const DownloadFile = (params: File.FileDownload) => {
|
||||
return http.download<BlobPart>('files/download', params, { responseType: 'blob', timeout: 20000 });
|
||||
};
|
||||
|
||||
export const DownloadByPath = (path: string) => {
|
||||
return http.download<BlobPart>('files/download/bypath', { path: path }, { responseType: 'blob', timeout: 40000 });
|
||||
};
|
||||
|
||||
export const ComputeDirSize = (params: File.DirSizeReq) => {
|
||||
return http.post<File.DirSizeRes>('files/size', params);
|
||||
};
|
||||
|
@ -63,7 +63,7 @@ export const handleRecoverByUpload = (params: Backup.Recover) => {
|
||||
return http.post(`/settings/backup/recover/byupload`, params, 400000);
|
||||
};
|
||||
export const downloadBackupRecord = (params: Backup.RecordDownload) => {
|
||||
return http.download<BlobPart>(`/settings/backup/record/download`, params, { responseType: 'blob' });
|
||||
return http.post<string>(`/settings/backup/record/download`, params);
|
||||
};
|
||||
export const deleteBackupRecord = (params: { ids: number[] }) => {
|
||||
return http.post(`/settings/backup/record/del`, params);
|
||||
|
@ -58,6 +58,7 @@ import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||
import { deleteBackupRecord, downloadBackupRecord, searchBackupRecords } from '@/api/modules/setting';
|
||||
import { Backup } from '@/api/interface/backup';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { DownloadByPath } from '@/api/modules/files';
|
||||
|
||||
const selects = ref<any>([]);
|
||||
const loading = ref();
|
||||
@ -145,14 +146,16 @@ const onDownload = async (row: Backup.RecordInfo) => {
|
||||
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);
|
||||
await downloadBackupRecord(params).then(async (res) => {
|
||||
const file = await DownloadByPath(res.data);
|
||||
const downloadUrl = window.URL.createObjectURL(new Blob([file]));
|
||||
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) => {
|
||||
|
@ -283,7 +283,7 @@ import { searchRecords, download, handleOnce, updateStatus } from '@/api/modules
|
||||
import { dateFormat } from '@/utils/util';
|
||||
import i18n from '@/lang';
|
||||
import { ElMessageBox } from 'element-plus';
|
||||
import { LoadFile } from '@/api/modules/files';
|
||||
import { DownloadByPath, LoadFile } from '@/api/modules/files';
|
||||
import LayoutContent from '@/layout/layout-content.vue';
|
||||
import { Codemirror } from 'vue-codemirror';
|
||||
import { javascript } from '@codemirror/lang-javascript';
|
||||
@ -472,17 +472,19 @@ const onDownload = async (record: any, backupID: number) => {
|
||||
recordID: record.id,
|
||||
backupAccountID: backupID,
|
||||
};
|
||||
const res = await download(params);
|
||||
const downloadUrl = window.URL.createObjectURL(new Blob([res]));
|
||||
const a = document.createElement('a');
|
||||
a.style.display = 'none';
|
||||
a.href = downloadUrl;
|
||||
if (record.file && record.file.indexOf('/') !== -1) {
|
||||
let pathItem = record.file.split('/');
|
||||
a.download = pathItem[pathItem.length - 1];
|
||||
}
|
||||
const event = new MouseEvent('click');
|
||||
a.dispatchEvent(event);
|
||||
await download(params).then(async (res) => {
|
||||
const file = await DownloadByPath(res.data);
|
||||
const downloadUrl = window.URL.createObjectURL(new Blob([file]));
|
||||
const a = document.createElement('a');
|
||||
a.style.display = 'none';
|
||||
a.href = downloadUrl;
|
||||
if (record.file && record.file.indexOf('/') !== -1) {
|
||||
let pathItem = record.file.split('/');
|
||||
a.download = pathItem[pathItem.length - 1];
|
||||
}
|
||||
const event = new MouseEvent('click');
|
||||
a.dispatchEvent(event);
|
||||
});
|
||||
};
|
||||
|
||||
const nextPage = async () => {
|
||||
|
Loading…
Reference in New Issue
Block a user