mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-31 14:08:06 +08:00
feat: s3 定时备份适配
This commit is contained in:
parent
c5e9a2e085
commit
49f0fb10a8
@ -171,3 +171,16 @@ func (b *BaseApi) TargetDownload(c *gin.Context) {
|
||||
}
|
||||
c.File(filePath)
|
||||
}
|
||||
|
||||
func (b *BaseApi) HandleOnce(c *gin.Context) {
|
||||
id, err := helper.GetParamID(c)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := cronjobService.HandleOnce(id); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import "time"
|
||||
type Cronjob struct {
|
||||
BaseModel
|
||||
|
||||
Name string `gorm:"type:varchar(64);not null" json:"name"`
|
||||
Name string `gorm:"type:varchar(64);not null;unique" json:"name"`
|
||||
Type string `gorm:"type:varchar(64);not null" json:"type"`
|
||||
SpecType string `gorm:"type:varchar(64);not null" json:"specType"`
|
||||
Spec string `gorm:"type:varchar(64);not null" json:"spec"`
|
||||
|
@ -25,7 +25,6 @@ import (
|
||||
const (
|
||||
errRecord = "errRecord"
|
||||
errHandle = "errHandle"
|
||||
noRecord = "noRecord"
|
||||
)
|
||||
|
||||
type CronjobService struct{}
|
||||
@ -34,6 +33,7 @@ type ICronjobService interface {
|
||||
SearchWithPage(search dto.SearchWithPage) (int64, interface{}, error)
|
||||
SearchRecords(search dto.SearchRecord) (int64, interface{}, error)
|
||||
Create(cronjobDto dto.CronjobCreate) error
|
||||
HandleOnce(id uint) error
|
||||
Save(id uint, req dto.CronjobUpdate) error
|
||||
UpdateStatus(id uint, status string) error
|
||||
Delete(ids []uint) error
|
||||
@ -143,6 +143,15 @@ func (u *CronjobService) Download(down dto.CronjobDownload) (string, error) {
|
||||
return name, nil
|
||||
}
|
||||
|
||||
func (u *CronjobService) HandleOnce(id uint) error {
|
||||
cronjob, _ := cronjobRepo.Get(commonRepo.WithByID(id))
|
||||
if cronjob.ID == 0 {
|
||||
return constant.ErrRecordNotFound
|
||||
}
|
||||
u.HandleJob(&cronjob)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *CronjobService) Create(cronjobDto dto.CronjobCreate) error {
|
||||
cronjob, _ := cronjobRepo.Get(commonRepo.WithByName(cronjobDto.Name))
|
||||
if cronjob.ID != 0 {
|
||||
@ -165,24 +174,7 @@ func (u *CronjobService) Create(cronjobDto dto.CronjobCreate) error {
|
||||
|
||||
func (u *CronjobService) StartJob(cronjob *model.Cronjob) error {
|
||||
global.Cron.Remove(cron.EntryID(cronjob.EntryID))
|
||||
var (
|
||||
entryID int
|
||||
err error
|
||||
)
|
||||
switch cronjob.Type {
|
||||
case "shell":
|
||||
entryID, err = u.AddShellJob(cronjob)
|
||||
case "curl":
|
||||
entryID, err = u.AddCurlJob(cronjob)
|
||||
case "directory":
|
||||
entryID, err = u.AddDirectoryJob(cronjob)
|
||||
case "website":
|
||||
entryID, err = u.AddWebSiteJob(cronjob)
|
||||
case "database":
|
||||
entryID, err = u.AddDatabaseJob(cronjob)
|
||||
default:
|
||||
entryID, err = u.AddShellJob(cronjob)
|
||||
}
|
||||
entryID, err := u.AddCronJob(cronjob)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -244,23 +236,9 @@ func (u *CronjobService) UpdateStatus(id uint, status string) error {
|
||||
return cronjobRepo.Update(cronjob.ID, map[string]interface{}{"status": status})
|
||||
}
|
||||
|
||||
func (u *CronjobService) AddShellJob(cronjob *model.Cronjob) (int, error) {
|
||||
func (u *CronjobService) AddCronJob(cronjob *model.Cronjob) (int, error) {
|
||||
addFunc := func() {
|
||||
record := cronjobRepo.StartRecords(cronjob.ID, "")
|
||||
|
||||
cmd := exec.Command(cronjob.Script)
|
||||
stdout, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
record.Records = errHandle
|
||||
cronjobRepo.EndRecords(record, constant.StatusFailed, err.Error(), errHandle)
|
||||
return
|
||||
}
|
||||
record.Records, err = mkdirAndWriteFile(cronjob, record.StartTime, stdout)
|
||||
if err != nil {
|
||||
record.Records = errRecord
|
||||
global.LOG.Errorf("save file %s failed, err: %v", record.Records, err)
|
||||
}
|
||||
cronjobRepo.EndRecords(record, constant.StatusSuccess, "", record.Records)
|
||||
u.HandleJob(cronjob)
|
||||
}
|
||||
global.LOG.Infof("add %s job %s successful", cronjob.Type, cronjob.Name)
|
||||
entryID, err := global.Cron.AddFunc(cronjob.Spec, addFunc)
|
||||
@ -270,9 +248,26 @@ func (u *CronjobService) AddShellJob(cronjob *model.Cronjob) (int, error) {
|
||||
return int(entryID), nil
|
||||
}
|
||||
|
||||
func (u *CronjobService) AddCurlJob(cronjob *model.Cronjob) (int, error) {
|
||||
addFunc := func() {
|
||||
func (u *CronjobService) HandleJob(cronjob *model.Cronjob) {
|
||||
var (
|
||||
message []byte
|
||||
err error
|
||||
)
|
||||
record := cronjobRepo.StartRecords(cronjob.ID, "")
|
||||
switch cronjob.Type {
|
||||
case "shell":
|
||||
cmd := exec.Command(cronjob.Script)
|
||||
message, err = cmd.CombinedOutput()
|
||||
case "website":
|
||||
message, err = tarWithExclude(cronjob, record.StartTime)
|
||||
case "database":
|
||||
message, err = tarWithExclude(cronjob, record.StartTime)
|
||||
case "directory":
|
||||
if len(cronjob.SourceDir) == 0 {
|
||||
return
|
||||
}
|
||||
message, err = tarWithExclude(cronjob, record.StartTime)
|
||||
case "curl":
|
||||
if len(cronjob.URL) == 0 {
|
||||
return
|
||||
}
|
||||
@ -287,30 +282,8 @@ func (u *CronjobService) AddCurlJob(cronjob *model.Cronjob) (int, error) {
|
||||
cronjobRepo.EndRecords(record, constant.StatusFailed, err.Error(), errHandle)
|
||||
}
|
||||
defer response.Body.Close()
|
||||
stdout, _ := ioutil.ReadAll(response.Body)
|
||||
|
||||
record.Records, err = mkdirAndWriteFile(cronjob, record.StartTime, stdout)
|
||||
if err != nil {
|
||||
record.Records = errRecord
|
||||
global.LOG.Errorf("save file %s failed, err: %v", record.Records, err)
|
||||
message, _ = ioutil.ReadAll(response.Body)
|
||||
}
|
||||
cronjobRepo.EndRecords(record, constant.StatusSuccess, "", record.Records)
|
||||
}
|
||||
global.LOG.Infof("add %s job %s successful", cronjob.Type, cronjob.Name)
|
||||
entryID, err := global.Cron.AddFunc(cronjob.Spec, addFunc)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int(entryID), nil
|
||||
}
|
||||
|
||||
func (u *CronjobService) AddDirectoryJob(cronjob *model.Cronjob) (int, error) {
|
||||
addFunc := func() {
|
||||
record := cronjobRepo.StartRecords(cronjob.ID, "")
|
||||
if len(cronjob.SourceDir) == 0 {
|
||||
return
|
||||
}
|
||||
message, err := tarWithExclude(cronjob, record.StartTime)
|
||||
if err != nil {
|
||||
record.Records = errHandle
|
||||
cronjobRepo.EndRecords(record, constant.StatusFailed, err.Error(), errHandle)
|
||||
@ -323,72 +296,6 @@ func (u *CronjobService) AddDirectoryJob(cronjob *model.Cronjob) (int, error) {
|
||||
}
|
||||
cronjobRepo.EndRecords(record, constant.StatusSuccess, "", record.Records)
|
||||
}
|
||||
global.LOG.Infof("add %s job %s successful", cronjob.Type, cronjob.Name)
|
||||
entryID, err := global.Cron.AddFunc(cronjob.Spec, addFunc)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int(entryID), nil
|
||||
}
|
||||
|
||||
func (u *CronjobService) AddWebSiteJob(cronjob *model.Cronjob) (int, error) {
|
||||
addFunc := func() {
|
||||
record := cronjobRepo.StartRecords(cronjob.ID, "")
|
||||
if len(cronjob.URL) == 0 {
|
||||
return
|
||||
}
|
||||
message, err := tarWithExclude(cronjob, record.StartTime)
|
||||
if err != nil {
|
||||
record.Records = errHandle
|
||||
cronjobRepo.EndRecords(record, constant.StatusFailed, err.Error(), errHandle)
|
||||
return
|
||||
}
|
||||
if len(message) == 0 {
|
||||
record.Records = noRecord
|
||||
cronjobRepo.EndRecords(record, constant.StatusSuccess, "", record.Records)
|
||||
return
|
||||
}
|
||||
record.Records, err = mkdirAndWriteFile(cronjob, record.StartTime, message)
|
||||
if err != nil {
|
||||
record.Records = errRecord
|
||||
global.LOG.Errorf("save file %s failed, err: %v", record.Records, err)
|
||||
}
|
||||
cronjobRepo.EndRecords(record, constant.StatusSuccess, "", record.Records)
|
||||
}
|
||||
global.LOG.Infof("add %s job %s successful", cronjob.Type, cronjob.Name)
|
||||
entryID, err := global.Cron.AddFunc(cronjob.Spec, addFunc)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int(entryID), nil
|
||||
}
|
||||
|
||||
func (u *CronjobService) AddDatabaseJob(cronjob *model.Cronjob) (int, error) {
|
||||
addFunc := func() {
|
||||
record := cronjobRepo.StartRecords(cronjob.ID, "")
|
||||
if len(cronjob.URL) == 0 {
|
||||
return
|
||||
}
|
||||
message, err := tarWithExclude(cronjob, record.StartTime)
|
||||
if err != nil {
|
||||
record.Records = errHandle
|
||||
cronjobRepo.EndRecords(record, constant.StatusFailed, err.Error(), errHandle)
|
||||
return
|
||||
}
|
||||
record.Records, err = mkdirAndWriteFile(cronjob, record.StartTime, message)
|
||||
if err != nil {
|
||||
record.Records = errRecord
|
||||
global.LOG.Errorf("save file %s failed, err: %v", record.Records, err)
|
||||
}
|
||||
cronjobRepo.EndRecords(record, constant.StatusSuccess, "", record.Records)
|
||||
}
|
||||
global.LOG.Infof("add %s job %s successful", cronjob.Type, cronjob.Name)
|
||||
entryID, err := global.Cron.AddFunc(cronjob.Spec, addFunc)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int(entryID), nil
|
||||
}
|
||||
|
||||
func mkdirAndWriteFile(cronjob *model.Cronjob, startTime time.Time, msg []byte) (string, error) {
|
||||
dir := fmt.Sprintf("%s%s/%s-%v", constant.TaskDir, cronjob.Type, cronjob.Name, cronjob.ID)
|
||||
@ -451,7 +358,7 @@ func tarWithExclude(cronjob *model.Cronjob, startTime time.Time) ([]byte, error)
|
||||
}
|
||||
}
|
||||
if backType, ok := varMaps["type"].(string); ok {
|
||||
rmOverdueCloud(backType, targetdir, cronjob, backClient)
|
||||
rmExpiredRecords(backType, targetdir, cronjob, backClient)
|
||||
}
|
||||
return stdout, nil
|
||||
}
|
||||
@ -493,7 +400,7 @@ func loadTargetInfo(cronjob *model.Cronjob) (map[string]interface{}, string, err
|
||||
return varMap, dir, nil
|
||||
}
|
||||
|
||||
func rmOverdueCloud(backType, path string, cronjob *model.Cronjob, backClient cloud_storage.CloudStorageClient) {
|
||||
func rmExpiredRecords(backType, path string, cronjob *model.Cronjob, backClient cloud_storage.CloudStorageClient) {
|
||||
timeNow := time.Now()
|
||||
timeZero := time.Date(timeNow.Year(), timeNow.Month(), timeNow.Day(), 0, 0, 0, 0, timeNow.Location())
|
||||
timeStart := timeZero.AddDate(0, 0, -int(cronjob.RetainDays)+1)
|
||||
@ -544,7 +451,7 @@ func rmOverdueCloud(backType, path string, cronjob *model.Cronjob, backClient cl
|
||||
_ = os.Remove(path + "/" + file.Name())
|
||||
}
|
||||
}
|
||||
_ = cronjobRepo.DeleteRecord(cronjobRepo.WithByStartDate(timeStart))
|
||||
_ = cronjobRepo.DeleteRecord(cronjobRepo.WithByJobID(int(cronjob.ID)), cronjobRepo.WithByStartDate(timeStart))
|
||||
}
|
||||
|
||||
func loadSpec(cronjob model.Cronjob) string {
|
||||
|
@ -18,7 +18,8 @@ func (s *CronjobRouter) InitCronjobRouter(Router *gin.RouterGroup) {
|
||||
withRecordRouter.POST("/del", baseApi.DeleteCronjob)
|
||||
withRecordRouter.PUT(":id", baseApi.UpdateCronjob)
|
||||
withRecordRouter.POST("/status", baseApi.UpdateCronjobStatus)
|
||||
withRecordRouter.POST("/download", baseApi.TargetDownload)
|
||||
cmdRouter.POST("/handle/:id", baseApi.HandleOnce)
|
||||
cmdRouter.POST("/download", baseApi.TargetDownload)
|
||||
cmdRouter.POST("/search", baseApi.SearchCronjob)
|
||||
cmdRouter.POST("/search/records", baseApi.SearchJobRecords)
|
||||
cmdRouter.POST("/search/detail", baseApi.LoadRecordDetail)
|
||||
|
40
backend/utils/cloud_storage/client/minio_test.go
Normal file
40
backend/utils/cloud_storage/client/minio_test.go
Normal file
@ -0,0 +1,40 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/app/model"
|
||||
"github.com/1Panel-dev/1Panel/constant"
|
||||
"github.com/1Panel-dev/1Panel/global"
|
||||
"github.com/1Panel-dev/1Panel/init/db"
|
||||
"github.com/1Panel-dev/1Panel/init/log"
|
||||
"github.com/1Panel-dev/1Panel/init/viper"
|
||||
)
|
||||
|
||||
func TestMinio(t *testing.T) {
|
||||
viper.Init()
|
||||
log.Init()
|
||||
db.Init()
|
||||
|
||||
var backup model.BackupAccount
|
||||
if err := global.DB.Where("id = ?", 3).First(&backup).Error; err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
varMap := make(map[string]interface{})
|
||||
if err := json.Unmarshal([]byte(backup.Vars), &varMap); err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
varMap["type"] = backup.Type
|
||||
varMap["bucket"] = backup.Bucket
|
||||
switch backup.Type {
|
||||
case constant.Sftp:
|
||||
varMap["password"] = backup.Credential
|
||||
case constant.OSS, constant.S3, constant.MinIo:
|
||||
varMap["secretKey"] = backup.Credential
|
||||
}
|
||||
client, _ := NewMinIoClient(varMap)
|
||||
_, _ = client.ListObjects("directory/directory-test-minio/")
|
||||
}
|
@ -187,7 +187,7 @@ func (s3C *s3Client) ListObjects(prefix string) ([]interface{}, error) {
|
||||
Prefix: &prefix,
|
||||
}, func(p *s3.ListObjectsOutput, last bool) (shouldContinue bool) {
|
||||
for _, obj := range p.Contents {
|
||||
result = append(result, obj)
|
||||
result = append(result, *obj.Key)
|
||||
}
|
||||
return true
|
||||
}); err != nil {
|
||||
|
44
backend/utils/cloud_storage/client/sftp_test.go
Normal file
44
backend/utils/cloud_storage/client/sftp_test.go
Normal file
@ -0,0 +1,44 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/app/model"
|
||||
"github.com/1Panel-dev/1Panel/constant"
|
||||
"github.com/1Panel-dev/1Panel/global"
|
||||
"github.com/1Panel-dev/1Panel/init/db"
|
||||
"github.com/1Panel-dev/1Panel/init/log"
|
||||
"github.com/1Panel-dev/1Panel/init/viper"
|
||||
)
|
||||
|
||||
func TestCronS(t *testing.T) {
|
||||
viper.Init()
|
||||
log.Init()
|
||||
db.Init()
|
||||
|
||||
var backup model.BackupAccount
|
||||
if err := global.DB.Where("id = ?", 5).First(&backup).Error; err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
varMap := make(map[string]interface{})
|
||||
if err := json.Unmarshal([]byte(backup.Vars), &varMap); err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
varMap["type"] = backup.Type
|
||||
varMap["bucket"] = backup.Bucket
|
||||
switch backup.Type {
|
||||
case constant.Sftp:
|
||||
varMap["password"] = backup.Credential
|
||||
case constant.OSS, constant.S3, constant.MinIo:
|
||||
varMap["secretKey"] = backup.Credential
|
||||
}
|
||||
client, err := NewS3Client(varMap)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
_, _ = client.ListObjects("directory/directory-test-s3")
|
||||
}
|
@ -33,3 +33,7 @@ export const updateStatus = (params: Cronjob.UpdateStatus) => {
|
||||
export const download = (params: Cronjob.Download) => {
|
||||
return http.download<BlobPart>(`cronjobs/download`, params, { responseType: 'blob' });
|
||||
};
|
||||
|
||||
export const handleOnce = (params: number) => {
|
||||
return http.post(`cronjobs/handle/${params}`);
|
||||
};
|
||||
|
@ -1,9 +1,9 @@
|
||||
@font-face {
|
||||
font-family: "panel"; /* Project id 3575356 */
|
||||
src: url('iconfont.woff2?t=1663584463212') format('woff2'),
|
||||
url('iconfont.woff?t=1663584463212') format('woff'),
|
||||
url('iconfont.ttf?t=1663584463212') format('truetype'),
|
||||
url('iconfont.svg?t=1663584463212#panel') format('svg');
|
||||
src: url('iconfont.woff2?t=1664421291278') format('woff2'),
|
||||
url('iconfont.woff?t=1664421291278') format('woff'),
|
||||
url('iconfont.ttf?t=1664421291278') format('truetype'),
|
||||
url('iconfont.svg?t=1664421291278#panel') format('svg');
|
||||
}
|
||||
|
||||
.panel {
|
||||
@ -14,12 +14,16 @@
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.p-taolun:before {
|
||||
content: "\e602";
|
||||
.p-star:before {
|
||||
content: "\e60f";
|
||||
}
|
||||
|
||||
.p-StarStar:before {
|
||||
content: "\e635";
|
||||
.p-aws:before {
|
||||
content: "\e600";
|
||||
}
|
||||
|
||||
.p-taolun:before {
|
||||
content: "\e602";
|
||||
}
|
||||
|
||||
.p-bug:before {
|
||||
@ -38,10 +42,6 @@
|
||||
content: "\e607";
|
||||
}
|
||||
|
||||
.p-s3:before {
|
||||
content: "\e8e4";
|
||||
}
|
||||
|
||||
.p-minio:before {
|
||||
content: "\e63c";
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
@ -5,6 +5,20 @@
|
||||
"css_prefix_text": "p-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "974125",
|
||||
"name": "star",
|
||||
"font_class": "star",
|
||||
"unicode": "e60f",
|
||||
"unicode_decimal": 58895
|
||||
},
|
||||
{
|
||||
"icon_id": "32101973",
|
||||
"name": "Amazon_Web_Services_Logo",
|
||||
"font_class": "aws",
|
||||
"unicode": "e600",
|
||||
"unicode_decimal": 58880
|
||||
},
|
||||
{
|
||||
"icon_id": "1760690",
|
||||
"name": "讨论",
|
||||
@ -12,13 +26,6 @@
|
||||
"unicode": "e602",
|
||||
"unicode_decimal": 58882
|
||||
},
|
||||
{
|
||||
"icon_id": "5192988",
|
||||
"name": "Star Star",
|
||||
"font_class": "StarStar",
|
||||
"unicode": "e635",
|
||||
"unicode_decimal": 58933
|
||||
},
|
||||
{
|
||||
"icon_id": "6642940",
|
||||
"name": "bug",
|
||||
@ -47,13 +54,6 @@
|
||||
"unicode": "e607",
|
||||
"unicode_decimal": 58887
|
||||
},
|
||||
{
|
||||
"icon_id": "17895439",
|
||||
"name": "Amazon S3上传",
|
||||
"font_class": "s3",
|
||||
"unicode": "e8e4",
|
||||
"unicode_decimal": 59620
|
||||
},
|
||||
{
|
||||
"icon_id": "20290513",
|
||||
"name": "minio",
|
||||
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 48 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -18,6 +18,7 @@ export default {
|
||||
login: 'Login',
|
||||
close: 'Close',
|
||||
view: 'View',
|
||||
handle: 'Handle',
|
||||
expand: 'Expand',
|
||||
log: 'Log',
|
||||
saveAndEnable: 'Save and enable',
|
||||
@ -244,6 +245,8 @@ export default {
|
||||
commands: 'Command',
|
||||
backups: 'Backup Account',
|
||||
settings: 'Panel Setting',
|
||||
cronjobs: 'Cronjob',
|
||||
status: ' Update status',
|
||||
auth: 'User',
|
||||
login: ' login',
|
||||
logout: ' logout',
|
||||
|
@ -18,6 +18,7 @@ export default {
|
||||
login: '登录',
|
||||
close: '关闭',
|
||||
view: '详情',
|
||||
handle: '执行',
|
||||
expand: '展开',
|
||||
log: '日志',
|
||||
saveAndEnable: '保存并启用',
|
||||
@ -241,6 +242,8 @@ export default {
|
||||
commands: '快捷命令',
|
||||
backups: '备份账号',
|
||||
settings: '面板设置',
|
||||
cronjobs: '计划任务',
|
||||
status: '状态修改',
|
||||
auth: '用户',
|
||||
post: '创建',
|
||||
put: '更新',
|
||||
|
@ -89,6 +89,10 @@ export function getRandomStr(e: number): string {
|
||||
return n;
|
||||
}
|
||||
|
||||
export function loadZero(i: number) {
|
||||
return i < 10 ? '0' + i : '' + i;
|
||||
}
|
||||
|
||||
export function computeSize(size: number): string {
|
||||
const num = 1024.0;
|
||||
|
||||
|
@ -73,11 +73,10 @@
|
||||
import ComplexTable from '@/components/complex-table/index.vue';
|
||||
import OperatrDialog from '@/views/cronjob/operate/index.vue';
|
||||
import RecordDialog from '@/views/cronjob/record/index.vue';
|
||||
import { loadZero } from '@/views/cronjob/options';
|
||||
import { loadZero } from '@/utils/util';
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { deleteCronjob, getCronjobPage, updateStatus } from '@/api/modules/cronjob';
|
||||
import { deleteCronjob, getCronjobPage, handleOnce, updateStatus } from '@/api/modules/cronjob';
|
||||
import { loadBackupName } from '@/views/setting/helper';
|
||||
import { loadWeek } from './options';
|
||||
import i18n from '@/lang';
|
||||
import { Cronjob } from '@/api/interface/cronjob';
|
||||
import { useDeleteData } from '@/hooks/use-delete-data';
|
||||
@ -97,6 +96,15 @@ const logSearch = reactive({
|
||||
page: 1,
|
||||
pageSize: 5,
|
||||
});
|
||||
const weekOptions = [
|
||||
{ label: i18n.global.t('cronjob.monday'), value: 1 },
|
||||
{ label: i18n.global.t('cronjob.tuesday'), value: 2 },
|
||||
{ label: i18n.global.t('cronjob.wednesday'), value: 3 },
|
||||
{ label: i18n.global.t('cronjob.thursday'), value: 4 },
|
||||
{ label: i18n.global.t('cronjob.friday'), value: 5 },
|
||||
{ label: i18n.global.t('cronjob.saturday'), value: 6 },
|
||||
{ label: i18n.global.t('cronjob.sunday'), value: 7 },
|
||||
];
|
||||
|
||||
const search = async () => {
|
||||
logSearch.page = paginationConfig.currentPage;
|
||||
@ -158,8 +166,20 @@ const onChangeStatus = async (row: Cronjob.CronjobInfo) => {
|
||||
search();
|
||||
}
|
||||
};
|
||||
const onHandle = async (row: Cronjob.CronjobInfo) => {
|
||||
await handleOnce(row.id);
|
||||
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
|
||||
search();
|
||||
};
|
||||
|
||||
const buttons = [
|
||||
{
|
||||
label: i18n.global.t('commons.button.handle'),
|
||||
icon: 'Pointer',
|
||||
click: (row: Cronjob.CronjobInfo) => {
|
||||
onHandle(row);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: i18n.global.t('commons.button.edit'),
|
||||
icon: 'Edit',
|
||||
@ -189,6 +209,14 @@ const onOpenRecordDialog = async (rowData: Partial<Cronjob.CronjobInfo> = {}) =>
|
||||
dialogRecordRef.value!.acceptParams(params);
|
||||
};
|
||||
|
||||
function loadWeek(i: number) {
|
||||
for (const week of weekOptions) {
|
||||
if (week.value === i) {
|
||||
return week.label;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
onMounted(() => {
|
||||
search();
|
||||
});
|
||||
|
@ -145,7 +145,6 @@
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { Rules } from '@/global/form-rules';
|
||||
import { loadBackupName } from '@/views/setting/helper';
|
||||
import { typeOptions, specOptions, weekOptions } from '@/views/cronjob/options';
|
||||
import FileList from '@/components/file-list/index.vue';
|
||||
import { getBackupList } from '@/api/modules/backup';
|
||||
import i18n from '@/lang';
|
||||
@ -222,6 +221,31 @@ const varifySpec = (rule: any, value: any, callback: any) => {
|
||||
}
|
||||
callback();
|
||||
};
|
||||
const typeOptions = [
|
||||
{ label: i18n.global.t('cronjob.shell'), value: 'shell' },
|
||||
{ label: i18n.global.t('cronjob.website'), value: 'website' },
|
||||
{ label: i18n.global.t('cronjob.database'), value: 'database' },
|
||||
{ label: i18n.global.t('cronjob.directory'), value: 'directory' },
|
||||
{ label: i18n.global.t('cronjob.curl') + ' URL', value: 'curl' },
|
||||
];
|
||||
|
||||
const specOptions = [
|
||||
{ label: i18n.global.t('cronjob.perMonth'), value: 'perMonth' },
|
||||
{ label: i18n.global.t('cronjob.perWeek'), value: 'perWeek' },
|
||||
{ label: i18n.global.t('cronjob.perNDay'), value: 'perNDay' },
|
||||
{ label: i18n.global.t('cronjob.perNHour'), value: 'perNHour' },
|
||||
{ label: i18n.global.t('cronjob.perHour'), value: 'perHour' },
|
||||
{ label: i18n.global.t('cronjob.perNMinute'), value: 'perNMinute' },
|
||||
];
|
||||
const weekOptions = [
|
||||
{ label: i18n.global.t('cronjob.monday'), value: 1 },
|
||||
{ label: i18n.global.t('cronjob.tuesday'), value: 2 },
|
||||
{ label: i18n.global.t('cronjob.wednesday'), value: 3 },
|
||||
{ label: i18n.global.t('cronjob.thursday'), value: 4 },
|
||||
{ label: i18n.global.t('cronjob.friday'), value: 5 },
|
||||
{ label: i18n.global.t('cronjob.saturday'), value: 6 },
|
||||
{ label: i18n.global.t('cronjob.sunday'), value: 7 },
|
||||
];
|
||||
const rules = reactive({
|
||||
name: [Rules.requiredInput, Rules.name],
|
||||
type: [Rules.requiredSelect],
|
||||
@ -265,8 +289,9 @@ function isBackup() {
|
||||
dialogData.value.rowData!.type === 'directory'
|
||||
);
|
||||
}
|
||||
|
||||
function hasScript() {
|
||||
return dialogData.value.rowData!.type === 'shell' || dialogData.value.rowData!.type === 'sync';
|
||||
return dialogData.value.rowData!.type === 'shell';
|
||||
}
|
||||
function changeName(isChangeType: boolean, type: string) {
|
||||
if (isChangeType) {
|
||||
|
@ -1,41 +0,0 @@
|
||||
import i18n from '@/lang';
|
||||
|
||||
export const typeOptions = [
|
||||
{ label: i18n.global.t('cronjob.shell'), value: 'shell' },
|
||||
{ label: i18n.global.t('cronjob.website'), value: 'website' },
|
||||
{ label: i18n.global.t('cronjob.database'), value: 'database' },
|
||||
{ label: i18n.global.t('cronjob.directory'), value: 'directory' },
|
||||
{ label: i18n.global.t('cronjob.syncDate'), value: 'sync' },
|
||||
// { label: i18n.global.t('cronjob.releaseMemory'), value: 'release' },
|
||||
{ label: i18n.global.t('cronjob.curl') + ' URL', value: 'curl' },
|
||||
];
|
||||
|
||||
export const specOptions = [
|
||||
{ label: i18n.global.t('cronjob.perMonth'), value: 'perMonth' },
|
||||
{ label: i18n.global.t('cronjob.perWeek'), value: 'perWeek' },
|
||||
{ label: i18n.global.t('cronjob.perNDay'), value: 'perNDay' },
|
||||
{ label: i18n.global.t('cronjob.perNHour'), value: 'perNHour' },
|
||||
{ label: i18n.global.t('cronjob.perHour'), value: 'perHour' },
|
||||
{ label: i18n.global.t('cronjob.perNMinute'), value: 'perNMinute' },
|
||||
];
|
||||
|
||||
export const weekOptions = [
|
||||
{ label: i18n.global.t('cronjob.monday'), value: 1 },
|
||||
{ label: i18n.global.t('cronjob.tuesday'), value: 2 },
|
||||
{ label: i18n.global.t('cronjob.wednesday'), value: 3 },
|
||||
{ label: i18n.global.t('cronjob.thursday'), value: 4 },
|
||||
{ label: i18n.global.t('cronjob.friday'), value: 5 },
|
||||
{ label: i18n.global.t('cronjob.saturday'), value: 6 },
|
||||
{ label: i18n.global.t('cronjob.sunday'), value: 7 },
|
||||
];
|
||||
export const loadWeek = (i: number) => {
|
||||
for (const week of weekOptions) {
|
||||
if (week.value === i) {
|
||||
return week.label;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
};
|
||||
export const loadZero = (i: number) => {
|
||||
return i < 10 ? '0' + i : '' + i;
|
||||
};
|
@ -59,35 +59,35 @@
|
||||
dialogData.rowData?.specType === 'perWeek'
|
||||
"
|
||||
>
|
||||
{{ $t('cronjob.' + dialogData.rowData?.specType) }}
|
||||
{{ $t('cronjob.' + dialogData.rowData?.specType) }}
|
||||
</span>
|
||||
<span v-else>{{ $t('cronjob.per') }}</span>
|
||||
<span v-if="dialogData.rowData?.specType === 'perMonth'">
|
||||
{{ dialogData.rowData?.day }}{{ $t('cronjob.day') }}
|
||||
{{ dialogData.rowData?.day }}{{ $t('cronjob.day') }}
|
||||
{{ loadZero(dialogData.rowData?.hour) }} :
|
||||
{{ loadZero(dialogData.rowData?.minute) }}
|
||||
</span>
|
||||
<span v-if="dialogData.rowData?.specType === 'perWeek'">
|
||||
{{ loadWeek(dialogData.rowData?.week) }}
|
||||
{{ loadWeek(dialogData.rowData?.week) }}
|
||||
{{ loadZero(dialogData.rowData?.hour) }} :
|
||||
{{ loadZero(dialogData.rowData?.minute) }}
|
||||
</span>
|
||||
<span v-if="dialogData.rowData?.specType === 'perNDay'">
|
||||
{{ dialogData.rowData?.day }}{{ $t('cronjob.day1') }},
|
||||
{{ dialogData.rowData?.day }}{{ $t('cronjob.day1') }},
|
||||
{{ loadZero(dialogData.rowData?.hour) }} :
|
||||
{{ loadZero(dialogData.rowData?.minute) }}
|
||||
</span>
|
||||
<span v-if="dialogData.rowData?.specType === 'perNHour'">
|
||||
{{ dialogData.rowData?.hour }}{{ $t('cronjob.hour') }},
|
||||
{{ dialogData.rowData?.hour }}{{ $t('cronjob.hour') }},
|
||||
{{ loadZero(dialogData.rowData?.minute) }}
|
||||
</span>
|
||||
<span v-if="dialogData.rowData?.specType === 'perHour'">
|
||||
{{ loadZero(dialogData.rowData?.minute) }}
|
||||
{{ loadZero(dialogData.rowData?.minute) }}
|
||||
</span>
|
||||
<span v-if="dialogData.rowData?.specType === 'perNMinute'">
|
||||
{{ dialogData.rowData?.minute }}{{ $t('cronjob.minute') }}
|
||||
{{ dialogData.rowData?.minute }}{{ $t('cronjob.minute') }}
|
||||
</span>
|
||||
{{ $t('cronjob.handle') }}
|
||||
{{ $t('cronjob.handle') }}
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8" v-if="hasScript()">
|
||||
@ -233,7 +233,7 @@
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
import { Cronjob } from '@/api/interface/cronjob';
|
||||
import { loadZero, loadWeek } from '@/views/cronjob/options';
|
||||
import { loadZero } from '@/utils/util';
|
||||
import { loadBackupName } from '@/views/setting/helper';
|
||||
import { searchRecords, getRecordDetail, download } from '@/api/modules/cronjob';
|
||||
import { dateFromat, dateFromatForName } from '@/utils/util';
|
||||
@ -314,6 +314,15 @@ const shortcuts = [
|
||||
},
|
||||
},
|
||||
];
|
||||
const weekOptions = [
|
||||
{ label: i18n.global.t('cronjob.monday'), value: 1 },
|
||||
{ label: i18n.global.t('cronjob.tuesday'), value: 2 },
|
||||
{ label: i18n.global.t('cronjob.wednesday'), value: 3 },
|
||||
{ label: i18n.global.t('cronjob.thursday'), value: 4 },
|
||||
{ label: i18n.global.t('cronjob.friday'), value: 5 },
|
||||
{ label: i18n.global.t('cronjob.saturday'), value: 6 },
|
||||
{ label: i18n.global.t('cronjob.sunday'), value: 7 },
|
||||
];
|
||||
const timeRangeLoad = ref<Array<any>>([new Date(new Date().setHours(0, 0, 0, 0)), new Date()]);
|
||||
const searchInfo = reactive({
|
||||
page: 1,
|
||||
@ -388,6 +397,14 @@ function isBackup() {
|
||||
function hasScript() {
|
||||
return dialogData.value.rowData!.type === 'shell' || dialogData.value.rowData!.type === 'sync';
|
||||
}
|
||||
function loadWeek(i: number) {
|
||||
for (const week of weekOptions) {
|
||||
if (week.value === i) {
|
||||
return week.label;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
acceptParams,
|
||||
|
@ -25,7 +25,7 @@
|
||||
<el-link @click="toTalk">
|
||||
<span>{{ $t('setting.chat') }}</span>
|
||||
</el-link>
|
||||
<svg-icon style="font-size: 9px; margin-left: 15px" iconName="p-StarStar"></svg-icon>
|
||||
<svg-icon style="font-size: 9px; margin-left: 15px" iconName="p-star"></svg-icon>
|
||||
<el-link @click="toGithubStar">
|
||||
<span>{{ $t('setting.star') }}</span>
|
||||
</el-link>
|
||||
|
@ -14,9 +14,7 @@
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<svg-icon style="font-size: 7px" :iconName="loadIconName(item.type)"></svg-icon>
|
||||
<span style="font-size: 16px; font-weight: 500">
|
||||
{{ loadBackupName(item.type) }}
|
||||
</span>
|
||||
<span style="font-size: 16px; font-weight: 500"> {{ loadBackupName(item.type) }}</span>
|
||||
<div style="float: right">
|
||||
<el-button @click="onEdit(item)">{{ $t('commons.button.edit') }}</el-button>
|
||||
<el-button @click="onBatchDelete(item)">
|
||||
@ -299,7 +297,7 @@ const loadIconName = (type: string) => {
|
||||
return 'p-oss';
|
||||
break;
|
||||
case 'S3':
|
||||
return 'p-s3';
|
||||
return 'p-aws';
|
||||
break;
|
||||
case 'SFTP':
|
||||
return 'p-SFTP';
|
||||
|
Loading…
x
Reference in New Issue
Block a user