mirror of
				https://github.com/TeaOSLab/EdgeAdmin.git
				synced 2025-11-04 05:00:25 +08:00 
			
		
		
		
	增加刷新、预热缓存任务管理
This commit is contained in:
		@@ -219,6 +219,14 @@ func (this *RPCClient) HTTPCachePolicyRPC() pb.HTTPCachePolicyServiceClient {
 | 
			
		||||
	return pb.NewHTTPCachePolicyServiceClient(this.pickConn())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *RPCClient) HTTPCacheTaskRPC() pb.HTTPCacheTaskServiceClient {
 | 
			
		||||
	return pb.NewHTTPCacheTaskServiceClient(this.pickConn())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *RPCClient) HTTPCacheTaskKeyRPC() pb.HTTPCacheTaskKeyServiceClient {
 | 
			
		||||
	return pb.NewHTTPCacheTaskKeyServiceClient(this.pickConn())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *RPCClient) HTTPFirewallPolicyRPC() pb.HTTPFirewallPolicyServiceClient {
 | 
			
		||||
	return pb.NewHTTPFirewallPolicyServiceClient(this.pickConn())
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										28
									
								
								internal/web/actions/default/servers/components/cache/batch/deleteTask.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								internal/web/actions/default/servers/components/cache/batch/deleteTask.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
 | 
			
		||||
 | 
			
		||||
package cache
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type DeleteTaskAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *DeleteTaskAction) RunPost(params struct {
 | 
			
		||||
	TaskId int64
 | 
			
		||||
}) {
 | 
			
		||||
	defer this.CreateLogInfo("删除缓存任务 %d", params.TaskId)
 | 
			
		||||
 | 
			
		||||
	_, err := this.RPC().HTTPCacheTaskRPC().DeleteHTTPCacheTask(this.AdminContext(), &pb.DeleteHTTPCacheTaskRequest{
 | 
			
		||||
		HttpCacheTaskId: params.TaskId,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Success()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										96
									
								
								internal/web/actions/default/servers/components/cache/batch/fetch.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								internal/web/actions/default/servers/components/cache/batch/fetch.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,96 @@
 | 
			
		||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
 | 
			
		||||
 | 
			
		||||
package cache
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/cache/cacheutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
	"github.com/iwind/TeaGo/actions"
 | 
			
		||||
	"github.com/iwind/TeaGo/lists"
 | 
			
		||||
	"github.com/iwind/TeaGo/maps"
 | 
			
		||||
	"github.com/iwind/TeaGo/types"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type FetchAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *FetchAction) Init() {
 | 
			
		||||
	this.Nav("", "", "fetch")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *FetchAction) RunGet(params struct{}) {
 | 
			
		||||
	// 初始化菜单数据
 | 
			
		||||
	err := InitMenu(this.Parent())
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *FetchAction) RunPost(params struct {
 | 
			
		||||
	Keys string
 | 
			
		||||
 | 
			
		||||
	Must *actions.Must
 | 
			
		||||
	CSRF *actionutils.CSRF
 | 
			
		||||
}) {
 | 
			
		||||
	defer this.CreateLogInfo("批量预热缓存Key")
 | 
			
		||||
 | 
			
		||||
	if len(params.Keys) == 0 {
 | 
			
		||||
		this.Fail("请输入要预热的Key列表")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 检查Key
 | 
			
		||||
	var realKeys = []string{}
 | 
			
		||||
	for _, key := range strings.Split(params.Keys, "\n") {
 | 
			
		||||
		key = strings.TrimSpace(key)
 | 
			
		||||
		if len(key) == 0 {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		if lists.ContainsString(realKeys, key) {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		realKeys = append(realKeys, key)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(realKeys) == 0 {
 | 
			
		||||
		this.Fail("请输入要预热的Key列表")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 校验Key
 | 
			
		||||
	validateResp, err := this.RPC().HTTPCacheTaskKeyRPC().ValidateHTTPCacheTaskKeys(this.AdminContext(), &pb.ValidateHTTPCacheTaskKeysRequest{Keys: realKeys})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var failKeyMaps = []maps.Map{}
 | 
			
		||||
	if len(validateResp.FailKeys) > 0 {
 | 
			
		||||
		for _, key := range validateResp.FailKeys {
 | 
			
		||||
			failKeyMaps = append(failKeyMaps, maps.Map{
 | 
			
		||||
				"key":    key.Key,
 | 
			
		||||
				"reason": cacheutils.KeyFailReason(key.ReasonCode),
 | 
			
		||||
			})
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["failKeys"] = failKeyMaps
 | 
			
		||||
	if len(failKeyMaps) > 0 {
 | 
			
		||||
		this.Fail("有" + types.String(len(failKeyMaps)) + "个Key无法完成操作,请删除后重试")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 提交任务
 | 
			
		||||
	_, err = this.RPC().HTTPCacheTaskRPC().CreateHTTPCacheTask(this.AdminContext(), &pb.CreateHTTPCacheTaskRequest{
 | 
			
		||||
		Type:    "fetch",
 | 
			
		||||
		KeyType: "key",
 | 
			
		||||
		Keys:    realKeys,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Success()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										97
									
								
								internal/web/actions/default/servers/components/cache/batch/index.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								internal/web/actions/default/servers/components/cache/batch/index.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,97 @@
 | 
			
		||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
 | 
			
		||||
 | 
			
		||||
package cache
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/cache/cacheutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
	"github.com/iwind/TeaGo/actions"
 | 
			
		||||
	"github.com/iwind/TeaGo/lists"
 | 
			
		||||
	"github.com/iwind/TeaGo/maps"
 | 
			
		||||
	"github.com/iwind/TeaGo/types"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type IndexAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *IndexAction) Init() {
 | 
			
		||||
	this.Nav("", "", "purge")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *IndexAction) RunGet(params struct{}) {
 | 
			
		||||
	// 初始化菜单数据
 | 
			
		||||
	err := InitMenu(this.Parent())
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *IndexAction) RunPost(params struct {
 | 
			
		||||
	KeyType string
 | 
			
		||||
	Keys    string
 | 
			
		||||
 | 
			
		||||
	Must *actions.Must
 | 
			
		||||
	CSRF *actionutils.CSRF
 | 
			
		||||
}) {
 | 
			
		||||
	defer this.CreateLogInfo("批量刷新缓存Key")
 | 
			
		||||
 | 
			
		||||
	if len(params.Keys) == 0 {
 | 
			
		||||
		this.Fail("请输入要刷新的Key列表")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 检查Key
 | 
			
		||||
	var realKeys = []string{}
 | 
			
		||||
	for _, key := range strings.Split(params.Keys, "\n") {
 | 
			
		||||
		key = strings.TrimSpace(key)
 | 
			
		||||
		if len(key) == 0 {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		if lists.ContainsString(realKeys, key) {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		realKeys = append(realKeys, key)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(realKeys) == 0 {
 | 
			
		||||
		this.Fail("请输入要刷新的Key列表")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 校验Key
 | 
			
		||||
	validateResp, err := this.RPC().HTTPCacheTaskKeyRPC().ValidateHTTPCacheTaskKeys(this.AdminContext(), &pb.ValidateHTTPCacheTaskKeysRequest{Keys: realKeys})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var failKeyMaps = []maps.Map{}
 | 
			
		||||
	if len(validateResp.FailKeys) > 0 {
 | 
			
		||||
		for _, key := range validateResp.FailKeys {
 | 
			
		||||
			failKeyMaps = append(failKeyMaps, maps.Map{
 | 
			
		||||
				"key":    key.Key,
 | 
			
		||||
				"reason": cacheutils.KeyFailReason(key.ReasonCode),
 | 
			
		||||
			})
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["failKeys"] = failKeyMaps
 | 
			
		||||
	if len(failKeyMaps) > 0 {
 | 
			
		||||
		this.Fail("有" + types.String(len(failKeyMaps)) + "个Key无法完成操作,请删除后重试")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 提交任务
 | 
			
		||||
	_, err = this.RPC().HTTPCacheTaskRPC().CreateHTTPCacheTask(this.AdminContext(), &pb.CreateHTTPCacheTaskRequest{
 | 
			
		||||
		Type:    "purge",
 | 
			
		||||
		KeyType: params.KeyType,
 | 
			
		||||
		Keys:    realKeys,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Success()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								internal/web/actions/default/servers/components/cache/batch/init.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								internal/web/actions/default/servers/components/cache/batch/init.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
package cache
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
 | 
			
		||||
	"github.com/iwind/TeaGo"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	TeaGo.BeforeStart(func(server *TeaGo.Server) {
 | 
			
		||||
		server.
 | 
			
		||||
			Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeServer)).
 | 
			
		||||
			Data("teaMenu", "servers").
 | 
			
		||||
			Data("teaSubMenu", "cacheBatch").
 | 
			
		||||
			Prefix("/servers/components/cache/batch").
 | 
			
		||||
			GetPost("", new(IndexAction)).
 | 
			
		||||
			GetPost("/fetch", new(FetchAction)).
 | 
			
		||||
			Get("/tasks", new(TasksAction)).
 | 
			
		||||
			Get("/task", new(TaskAction)).
 | 
			
		||||
			Post("/deleteTask", new(DeleteTaskAction)).
 | 
			
		||||
			Post("/resetTask", new(ResetTaskAction)).
 | 
			
		||||
			EndAll()
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										26
									
								
								internal/web/actions/default/servers/components/cache/batch/resetTask.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								internal/web/actions/default/servers/components/cache/batch/resetTask.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
 | 
			
		||||
 | 
			
		||||
package cache
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type ResetTaskAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *ResetTaskAction) RunPost(params struct {
 | 
			
		||||
	TaskId int64
 | 
			
		||||
}) {
 | 
			
		||||
	this.CreateLogInfo("重置缓存任务 %d 状态", params.TaskId)
 | 
			
		||||
 | 
			
		||||
	_, err := this.RPC().HTTPCacheTaskRPC().ResetHTTPCacheTask(this.AdminContext(), &pb.ResetHTTPCacheTaskRequest{HttpCacheTaskId: params.TaskId})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Success()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										104
									
								
								internal/web/actions/default/servers/components/cache/batch/task.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								internal/web/actions/default/servers/components/cache/batch/task.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,104 @@
 | 
			
		||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
 | 
			
		||||
 | 
			
		||||
package cache
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
	"github.com/iwind/TeaGo/maps"
 | 
			
		||||
	timeutil "github.com/iwind/TeaGo/utils/time"
 | 
			
		||||
	"sort"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type TaskAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *TaskAction) Init() {
 | 
			
		||||
	this.Nav("", "", "task")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *TaskAction) RunGet(params struct {
 | 
			
		||||
	TaskId int64
 | 
			
		||||
}) {
 | 
			
		||||
	// 初始化菜单数据
 | 
			
		||||
	err := InitMenu(this.Parent())
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	taskResp, err := this.RPC().HTTPCacheTaskRPC().FindEnabledHTTPCacheTask(this.AdminContext(), &pb.FindEnabledHTTPCacheTaskRequest{HttpCacheTaskId: params.TaskId})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	var task = taskResp.HttpCacheTask
 | 
			
		||||
	if task == nil {
 | 
			
		||||
		this.NotFound("HTTPCacheTask", params.TaskId)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 用户
 | 
			
		||||
	var userMap = maps.Map{"id": 0, "username": "", "fullname": ""}
 | 
			
		||||
	if task.User != nil {
 | 
			
		||||
		userMap = maps.Map{
 | 
			
		||||
			"id":       task.User.Id,
 | 
			
		||||
			"username": task.User.Username,
 | 
			
		||||
			"fullname": task.User.Fullname,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// keys
 | 
			
		||||
	var keyMaps = []maps.Map{}
 | 
			
		||||
	for _, key := range task.HttpCacheTaskKeys {
 | 
			
		||||
		// 错误信息
 | 
			
		||||
		var errorMaps = []maps.Map{}
 | 
			
		||||
 | 
			
		||||
		if len(key.ErrorsJSON) > 0 {
 | 
			
		||||
			var m = map[int64]string{}
 | 
			
		||||
			err = json.Unmarshal(key.ErrorsJSON, &m)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				this.ErrorPage(err)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			for nodeId, errString := range m {
 | 
			
		||||
				errorMaps = append(errorMaps, maps.Map{
 | 
			
		||||
					"nodeId": nodeId,
 | 
			
		||||
					"error":  errString,
 | 
			
		||||
				})
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// 错误信息排序
 | 
			
		||||
		if len(errorMaps) > 0 {
 | 
			
		||||
			sort.Slice(errorMaps, func(i, j int) bool {
 | 
			
		||||
				var m1 = errorMaps[i]
 | 
			
		||||
				var m2 = errorMaps[j]
 | 
			
		||||
 | 
			
		||||
				return m1.GetInt64("nodeId") < m2.GetInt64("nodeId")
 | 
			
		||||
			})
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		keyMaps = append(keyMaps, maps.Map{
 | 
			
		||||
			"key":    key.Key,
 | 
			
		||||
			"isDone": key.IsDone,
 | 
			
		||||
			"errors": errorMaps,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Data["task"] = maps.Map{
 | 
			
		||||
		"id":          task.Id,
 | 
			
		||||
		"type":        task.Type,
 | 
			
		||||
		"keyType":     task.KeyType,
 | 
			
		||||
		"createdTime": timeutil.FormatTime("Y-m-d H:i:s", task.CreatedAt),
 | 
			
		||||
		"doneTime":    timeutil.FormatTime("Y-m-d H:i:s", task.DoneAt),
 | 
			
		||||
		"isDone":      task.IsDone,
 | 
			
		||||
		"isOk":        task.IsOk,
 | 
			
		||||
		"keys":        keyMaps,
 | 
			
		||||
		"user":        userMap,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										72
									
								
								internal/web/actions/default/servers/components/cache/batch/tasks.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								internal/web/actions/default/servers/components/cache/batch/tasks.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,72 @@
 | 
			
		||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
 | 
			
		||||
 | 
			
		||||
package cache
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
	"github.com/iwind/TeaGo/maps"
 | 
			
		||||
	timeutil "github.com/iwind/TeaGo/utils/time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type TasksAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *TasksAction) Init() {
 | 
			
		||||
	this.Nav("", "", "task")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *TasksAction) RunGet(params struct{}) {
 | 
			
		||||
	// 初始化菜单数据
 | 
			
		||||
	err := InitMenu(this.Parent())
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 任务数量
 | 
			
		||||
	countResp, err := this.RPC().HTTPCacheTaskRPC().CountHTTPCacheTasks(this.AdminContext(), &pb.CountHTTPCacheTasksRequest{})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	var count = countResp.Count
 | 
			
		||||
	var page = this.NewPage(count)
 | 
			
		||||
	this.Data["page"] = page.AsHTML()
 | 
			
		||||
 | 
			
		||||
	// 任务列表
 | 
			
		||||
	var taskMaps = []maps.Map{}
 | 
			
		||||
	tasksResp, err := this.RPC().HTTPCacheTaskRPC().ListHTTPCacheTasks(this.AdminContext(), &pb.ListHTTPCacheTasksRequest{
 | 
			
		||||
		Offset: page.Offset,
 | 
			
		||||
		Size:   page.Size,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	for _, task := range tasksResp.HttpCacheTasks {
 | 
			
		||||
		var userMap = maps.Map{"id": 0, "username": "", "fullname": ""}
 | 
			
		||||
		if task.User != nil {
 | 
			
		||||
			userMap = maps.Map{
 | 
			
		||||
				"id":       task.User.Id,
 | 
			
		||||
				"username": task.User.Username,
 | 
			
		||||
				"fullname": task.User.Fullname,
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		taskMaps = append(taskMaps, maps.Map{
 | 
			
		||||
			"id":          task.Id,
 | 
			
		||||
			"type":        task.Type,
 | 
			
		||||
			"keyType":     task.KeyType,
 | 
			
		||||
			"isDone":      task.IsDone,
 | 
			
		||||
			"isOk":        task.IsOk,
 | 
			
		||||
			"createdTime": timeutil.FormatTime("Y-m-d H:i:s", task.CreatedAt),
 | 
			
		||||
			"description": task.Description,
 | 
			
		||||
			"user":        userMap,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Data["tasks"] = taskMaps
 | 
			
		||||
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								internal/web/actions/default/servers/components/cache/batch/utils.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								internal/web/actions/default/servers/components/cache/batch/utils.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
 | 
			
		||||
 | 
			
		||||
package cache
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/rpc"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func InitMenu(parent *actionutils.ParentAction) error {
 | 
			
		||||
	rpcClient, err := rpc.SharedRPC()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	countTasksResp, err := rpcClient.HTTPCacheTaskRPC().CountDoingHTTPCacheTasks(parent.AdminContext(), &pb.CountDoingHTTPCacheTasksRequest{})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	parent.Data["countDoingTasks"] = countTasksResp.Count
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
@@ -8,7 +8,7 @@ import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// 查找缓存策略名称并忽略错误
 | 
			
		||||
// FindCachePolicyNameWithoutError 查找缓存策略名称并忽略错误
 | 
			
		||||
func FindCachePolicyNameWithoutError(parent *actionutils.ParentAction, cachePolicyId int64) string {
 | 
			
		||||
	policy, err := FindCachePolicy(parent, cachePolicyId)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
@@ -20,7 +20,7 @@ func FindCachePolicyNameWithoutError(parent *actionutils.ParentAction, cachePoli
 | 
			
		||||
	return policy.Name
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 查找缓存策略配置
 | 
			
		||||
// FindCachePolicy 查找缓存策略配置
 | 
			
		||||
func FindCachePolicy(parent *actionutils.ParentAction, cachePolicyId int64) (*serverconfigs.HTTPCachePolicy, error) {
 | 
			
		||||
	resp, err := parent.RPC().HTTPCachePolicyRPC().FindEnabledHTTPCachePolicyConfig(parent.AdminContext(), &pb.FindEnabledHTTPCachePolicyConfigRequest{HttpCachePolicyId: cachePolicyId})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
@@ -36,3 +36,20 @@ func FindCachePolicy(parent *actionutils.ParentAction, cachePolicyId int64) (*se
 | 
			
		||||
	}
 | 
			
		||||
	return config, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// KeyFailReason Key相关失败原因
 | 
			
		||||
func KeyFailReason(reasonCode string) string {
 | 
			
		||||
	switch reasonCode {
 | 
			
		||||
	case "requireKey":
 | 
			
		||||
		return "空的Key"
 | 
			
		||||
	case "requireDomain":
 | 
			
		||||
		return "找不到Key对应的域名"
 | 
			
		||||
	case "requireServer":
 | 
			
		||||
		return "找不到Key对应的网站服务"
 | 
			
		||||
	case "requireUser":
 | 
			
		||||
		return "该域名不属于当前用户"
 | 
			
		||||
	case "requireClusterId":
 | 
			
		||||
		return "该网站没有部署到集群"
 | 
			
		||||
	}
 | 
			
		||||
	return "未知错误"
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,8 +3,7 @@ package cache
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/nodes/nodeutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/messageconfigs"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/cache/cacheutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
	"github.com/iwind/TeaGo/actions"
 | 
			
		||||
	"github.com/iwind/TeaGo/lists"
 | 
			
		||||
@@ -15,15 +14,15 @@ import (
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type PreheatAction struct {
 | 
			
		||||
type FetchAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *PreheatAction) Init() {
 | 
			
		||||
	this.Nav("", "", "preheat")
 | 
			
		||||
func (this *FetchAction) Init() {
 | 
			
		||||
	this.Nav("", "", "fetch")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *PreheatAction) RunGet(params struct {
 | 
			
		||||
func (this *FetchAction) RunGet(params struct {
 | 
			
		||||
	CachePolicyId int64
 | 
			
		||||
}) {
 | 
			
		||||
	// 默认的集群ID
 | 
			
		||||
@@ -50,7 +49,7 @@ func (this *PreheatAction) RunGet(params struct {
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *PreheatAction) RunPost(params struct {
 | 
			
		||||
func (this *FetchAction) RunPost(params struct {
 | 
			
		||||
	CachePolicyId int64
 | 
			
		||||
	ClusterId     int64
 | 
			
		||||
	Keys          string
 | 
			
		||||
@@ -92,27 +91,38 @@ func (this *PreheatAction) RunPost(params struct {
 | 
			
		||||
		realKeys = append(realKeys, key)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 发送命令
 | 
			
		||||
	msg := &messageconfigs.PreheatCacheMessage{
 | 
			
		||||
		CachePolicyJSON: cachePolicyJSON,
 | 
			
		||||
		Keys:            realKeys,
 | 
			
		||||
	}
 | 
			
		||||
	results, err := nodeutils.SendMessageToCluster(this.AdminContext(), params.ClusterId, messageconfigs.MessageCodePreheatCache, msg, 300)
 | 
			
		||||
	// 校验Key
 | 
			
		||||
	// 这里暂时不校验服务ID
 | 
			
		||||
	validateResp, err := this.RPC().HTTPCacheTaskKeyRPC().ValidateHTTPCacheTaskKeys(this.AdminContext(), &pb.ValidateHTTPCacheTaskKeysRequest{Keys: realKeys})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	isAllOk := true
 | 
			
		||||
	for _, result := range results {
 | 
			
		||||
		if !result.IsOK {
 | 
			
		||||
			isAllOk = false
 | 
			
		||||
			break
 | 
			
		||||
	var failKeyMaps = []maps.Map{}
 | 
			
		||||
	if len(validateResp.FailKeys) > 0 {
 | 
			
		||||
		for _, key := range validateResp.FailKeys {
 | 
			
		||||
			failKeyMaps = append(failKeyMaps, maps.Map{
 | 
			
		||||
				"key":    key.Key,
 | 
			
		||||
				"reason": cacheutils.KeyFailReason(key.ReasonCode),
 | 
			
		||||
			})
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["failKeys"] = failKeyMaps
 | 
			
		||||
	if len(failKeyMaps) > 0 {
 | 
			
		||||
		this.Fail("有" + types.String(len(failKeyMaps)) + "个Key无法完成操作,请删除后重试")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Data["isAllOk"] = isAllOk
 | 
			
		||||
	this.Data["results"] = results
 | 
			
		||||
	// 提交任务
 | 
			
		||||
	_, err = this.RPC().HTTPCacheTaskRPC().CreateHTTPCacheTask(this.AdminContext(), &pb.CreateHTTPCacheTaskRequest{
 | 
			
		||||
		Type:    "fetch",
 | 
			
		||||
		KeyType: "key",
 | 
			
		||||
		Keys:    realKeys,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Success()
 | 
			
		||||
}
 | 
			
		||||
@@ -19,7 +19,7 @@ func init() {
 | 
			
		||||
			Get("/policy", new(PolicyAction)).
 | 
			
		||||
			GetPost("/update", new(UpdateAction)).
 | 
			
		||||
			GetPost("/clean", new(CleanAction)).
 | 
			
		||||
			GetPost("/preheat", new(PreheatAction)).
 | 
			
		||||
			GetPost("/fetch", new(FetchAction)).
 | 
			
		||||
			GetPost("/purge", new(PurgeAction)).
 | 
			
		||||
			GetPost("/stat", new(StatAction)).
 | 
			
		||||
			GetPost("/test", new(TestAction)).
 | 
			
		||||
 
 | 
			
		||||
@@ -3,8 +3,7 @@ package cache
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/nodes/nodeutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/messageconfigs"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/cache/cacheutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
	"github.com/iwind/TeaGo/actions"
 | 
			
		||||
	"github.com/iwind/TeaGo/lists"
 | 
			
		||||
@@ -53,7 +52,7 @@ func (this *PurgeAction) RunGet(params struct {
 | 
			
		||||
func (this *PurgeAction) RunPost(params struct {
 | 
			
		||||
	CachePolicyId int64
 | 
			
		||||
	ClusterId     int64
 | 
			
		||||
	Type          string
 | 
			
		||||
	KeyType       string
 | 
			
		||||
	Keys          string
 | 
			
		||||
	Must          *actions.Must
 | 
			
		||||
}) {
 | 
			
		||||
@@ -91,33 +90,37 @@ func (this *PurgeAction) RunPost(params struct {
 | 
			
		||||
		}
 | 
			
		||||
		realKeys = append(realKeys, key)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 发送命令
 | 
			
		||||
	msg := &messageconfigs.PurgeCacheMessage{
 | 
			
		||||
		CachePolicyJSON: cachePolicyJSON,
 | 
			
		||||
		Keys:            realKeys,
 | 
			
		||||
	}
 | 
			
		||||
	if params.Type == "prefix" {
 | 
			
		||||
		msg.Type = messageconfigs.PurgeCacheMessageTypeDir
 | 
			
		||||
	} else {
 | 
			
		||||
		msg.Type = messageconfigs.PurgeCacheMessageTypeFile
 | 
			
		||||
	}
 | 
			
		||||
	results, err := nodeutils.SendMessageToCluster(this.AdminContext(), params.ClusterId, messageconfigs.MessageCodePurgeCache, msg, 10)
 | 
			
		||||
	// 校验Key
 | 
			
		||||
	validateResp, err := this.RPC().HTTPCacheTaskKeyRPC().ValidateHTTPCacheTaskKeys(this.AdminContext(), &pb.ValidateHTTPCacheTaskKeysRequest{Keys: realKeys})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	isAllOk := true
 | 
			
		||||
	for _, result := range results {
 | 
			
		||||
		if !result.IsOK {
 | 
			
		||||
			isAllOk = false
 | 
			
		||||
			break
 | 
			
		||||
	var failKeyMaps = []maps.Map{}
 | 
			
		||||
	if len(validateResp.FailKeys) > 0 {
 | 
			
		||||
		for _, key := range validateResp.FailKeys {
 | 
			
		||||
			failKeyMaps = append(failKeyMaps, maps.Map{
 | 
			
		||||
				"key":    key.Key,
 | 
			
		||||
				"reason": cacheutils.KeyFailReason(key.ReasonCode),
 | 
			
		||||
			})
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["failKeys"] = failKeyMaps
 | 
			
		||||
	if len(failKeyMaps) > 0 {
 | 
			
		||||
		this.Fail("有" + types.String(len(failKeyMaps)) + "个Key无法完成操作,请删除后重试")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Data["isAllOk"] = isAllOk
 | 
			
		||||
	this.Data["results"] = results
 | 
			
		||||
	// 提交任务
 | 
			
		||||
	_, err = this.RPC().HTTPCacheTaskRPC().CreateHTTPCacheTask(this.AdminContext(), &pb.CreateHTTPCacheTaskRequest{
 | 
			
		||||
		Type:    "purge",
 | 
			
		||||
		KeyType: params.KeyType,
 | 
			
		||||
		Keys:    realKeys,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Success()
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,25 +5,26 @@ package cache
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/nodes/nodeutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/messageconfigs"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/cache/cacheutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
	"github.com/iwind/TeaGo/actions"
 | 
			
		||||
	"github.com/iwind/TeaGo/lists"
 | 
			
		||||
	"github.com/iwind/TeaGo/maps"
 | 
			
		||||
	"github.com/iwind/TeaGo/types"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type PreheatAction struct {
 | 
			
		||||
type FetchAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *PreheatAction) Init() {
 | 
			
		||||
	this.Nav("", "setting", "preheat")
 | 
			
		||||
func (this *FetchAction) Init() {
 | 
			
		||||
	this.Nav("", "setting", "fetch")
 | 
			
		||||
	this.SecondMenu("cache")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *PreheatAction) RunGet(params struct {
 | 
			
		||||
func (this *FetchAction) RunGet(params struct {
 | 
			
		||||
	ServerId int64
 | 
			
		||||
}) {
 | 
			
		||||
	webConfig, err := dao.SharedHTTPWebDAO.FindWebConfigWithServerId(this.AdminContext(), params.ServerId)
 | 
			
		||||
@@ -38,7 +39,7 @@ func (this *PreheatAction) RunGet(params struct {
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *PreheatAction) RunPost(params struct {
 | 
			
		||||
func (this *FetchAction) RunPost(params struct {
 | 
			
		||||
	ServerId int64
 | 
			
		||||
	WebId    int64
 | 
			
		||||
	Keys     string
 | 
			
		||||
@@ -117,27 +118,38 @@ func (this *PreheatAction) RunPost(params struct {
 | 
			
		||||
		realKeys = append(realKeys, key)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 发送命令
 | 
			
		||||
	msg := &messageconfigs.PreheatCacheMessage{
 | 
			
		||||
		CachePolicyJSON: cachePolicyJSON,
 | 
			
		||||
		Keys:            realKeys,
 | 
			
		||||
	}
 | 
			
		||||
	results, err := nodeutils.SendMessageToCluster(this.AdminContext(), clusterId, messageconfigs.MessageCodePreheatCache, msg, 300)
 | 
			
		||||
 | 
			
		||||
	// 校验Key
 | 
			
		||||
	validateResp, err := this.RPC().HTTPCacheTaskKeyRPC().ValidateHTTPCacheTaskKeys(this.AdminContext(), &pb.ValidateHTTPCacheTaskKeysRequest{Keys: realKeys})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	isAllOk := true
 | 
			
		||||
	for _, result := range results {
 | 
			
		||||
		if !result.IsOK {
 | 
			
		||||
			isAllOk = false
 | 
			
		||||
			break
 | 
			
		||||
	var failKeyMaps = []maps.Map{}
 | 
			
		||||
	if len(validateResp.FailKeys) > 0 {
 | 
			
		||||
		for _, key := range validateResp.FailKeys {
 | 
			
		||||
			failKeyMaps = append(failKeyMaps, maps.Map{
 | 
			
		||||
				"key":    key.Key,
 | 
			
		||||
				"reason": cacheutils.KeyFailReason(key.ReasonCode),
 | 
			
		||||
			})
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["failKeys"] = failKeyMaps
 | 
			
		||||
	if len(failKeyMaps) > 0 {
 | 
			
		||||
		this.Fail("有" + types.String(len(failKeyMaps)) + "个Key无法完成操作,请删除后重试")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Data["isAllOk"] = isAllOk
 | 
			
		||||
	this.Data["results"] = results
 | 
			
		||||
	// 提交任务
 | 
			
		||||
	_, err = this.RPC().HTTPCacheTaskRPC().CreateHTTPCacheTask(this.AdminContext(), &pb.CreateHTTPCacheTaskRequest{
 | 
			
		||||
		Type:    "fetch",
 | 
			
		||||
		KeyType: "key",
 | 
			
		||||
		Keys:    realKeys,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Success()
 | 
			
		||||
}
 | 
			
		||||
@@ -15,7 +15,7 @@ func init() {
 | 
			
		||||
			Prefix("/servers/groups/group/settings/cache").
 | 
			
		||||
			GetPost("", new(IndexAction)).
 | 
			
		||||
			GetPost("/purge", new(PurgeAction)).
 | 
			
		||||
			GetPost("/preheat", new(PreheatAction)).
 | 
			
		||||
			GetPost("/fetch", new(FetchAction)).
 | 
			
		||||
			EndAll()
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,12 +5,13 @@ package cache
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/nodes/nodeutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/messageconfigs"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/cache/cacheutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
	"github.com/iwind/TeaGo/actions"
 | 
			
		||||
	"github.com/iwind/TeaGo/lists"
 | 
			
		||||
	"github.com/iwind/TeaGo/maps"
 | 
			
		||||
	"github.com/iwind/TeaGo/types"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -41,7 +42,7 @@ func (this *PurgeAction) RunGet(params struct {
 | 
			
		||||
func (this *PurgeAction) RunPost(params struct {
 | 
			
		||||
	ServerId int64
 | 
			
		||||
	WebId    int64
 | 
			
		||||
	Type     string
 | 
			
		||||
	KeyType  string
 | 
			
		||||
	Keys     string
 | 
			
		||||
 | 
			
		||||
	Must *actions.Must
 | 
			
		||||
@@ -118,32 +119,37 @@ func (this *PurgeAction) RunPost(params struct {
 | 
			
		||||
		realKeys = append(realKeys, key)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 发送命令
 | 
			
		||||
	msg := &messageconfigs.PurgeCacheMessage{
 | 
			
		||||
		CachePolicyJSON: cachePolicyJSON,
 | 
			
		||||
		Keys:            realKeys,
 | 
			
		||||
	}
 | 
			
		||||
	if params.Type == "prefix" {
 | 
			
		||||
		msg.Type = messageconfigs.PurgeCacheMessageTypeDir
 | 
			
		||||
	} else {
 | 
			
		||||
		msg.Type = messageconfigs.PurgeCacheMessageTypeFile
 | 
			
		||||
	}
 | 
			
		||||
	results, err := nodeutils.SendMessageToCluster(this.AdminContext(), clusterId, messageconfigs.MessageCodePurgeCache, msg, 10)
 | 
			
		||||
	// 校验Key
 | 
			
		||||
	validateResp, err := this.RPC().HTTPCacheTaskKeyRPC().ValidateHTTPCacheTaskKeys(this.AdminContext(), &pb.ValidateHTTPCacheTaskKeysRequest{Keys: realKeys})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	isAllOk := true
 | 
			
		||||
	for _, result := range results {
 | 
			
		||||
		if !result.IsOK {
 | 
			
		||||
			isAllOk = false
 | 
			
		||||
			break
 | 
			
		||||
	var failKeyMaps = []maps.Map{}
 | 
			
		||||
	if len(validateResp.FailKeys) > 0 {
 | 
			
		||||
		for _, key := range validateResp.FailKeys {
 | 
			
		||||
			failKeyMaps = append(failKeyMaps, maps.Map{
 | 
			
		||||
				"key":    key.Key,
 | 
			
		||||
				"reason": cacheutils.KeyFailReason(key.ReasonCode),
 | 
			
		||||
			})
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["failKeys"] = failKeyMaps
 | 
			
		||||
	if len(failKeyMaps) > 0 {
 | 
			
		||||
		this.Fail("有" + types.String(len(failKeyMaps)) + "个Key无法完成操作,请删除后重试")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Data["isAllOk"] = isAllOk
 | 
			
		||||
	this.Data["results"] = results
 | 
			
		||||
	// 提交任务
 | 
			
		||||
	_, err = this.RPC().HTTPCacheTaskRPC().CreateHTTPCacheTask(this.AdminContext(), &pb.CreateHTTPCacheTaskRequest{
 | 
			
		||||
		Type:    "purge",
 | 
			
		||||
		KeyType: params.KeyType,
 | 
			
		||||
		Keys:    realKeys,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Success()
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,25 +5,26 @@ package cache
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/nodes/nodeutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/messageconfigs"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/cache/cacheutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
	"github.com/iwind/TeaGo/actions"
 | 
			
		||||
	"github.com/iwind/TeaGo/lists"
 | 
			
		||||
	"github.com/iwind/TeaGo/maps"
 | 
			
		||||
	"github.com/iwind/TeaGo/types"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type PreheatAction struct {
 | 
			
		||||
type FetchAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *PreheatAction) Init() {
 | 
			
		||||
	this.Nav("", "setting", "preheat")
 | 
			
		||||
func (this *FetchAction) Init() {
 | 
			
		||||
	this.Nav("", "setting", "fetch")
 | 
			
		||||
	this.SecondMenu("cache")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *PreheatAction) RunGet(params struct {
 | 
			
		||||
func (this *FetchAction) RunGet(params struct {
 | 
			
		||||
	ServerId int64
 | 
			
		||||
}) {
 | 
			
		||||
	webConfig, err := dao.SharedHTTPWebDAO.FindWebConfigWithServerId(this.AdminContext(), params.ServerId)
 | 
			
		||||
@@ -38,7 +39,7 @@ func (this *PreheatAction) RunGet(params struct {
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *PreheatAction) RunPost(params struct {
 | 
			
		||||
func (this *FetchAction) RunPost(params struct {
 | 
			
		||||
	ServerId int64
 | 
			
		||||
	WebId    int64
 | 
			
		||||
	Keys     string
 | 
			
		||||
@@ -117,27 +118,37 @@ func (this *PreheatAction) RunPost(params struct {
 | 
			
		||||
		realKeys = append(realKeys, key)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 发送命令
 | 
			
		||||
	msg := &messageconfigs.PreheatCacheMessage{
 | 
			
		||||
		CachePolicyJSON: cachePolicyJSON,
 | 
			
		||||
		Keys:            realKeys,
 | 
			
		||||
	}
 | 
			
		||||
	results, err := nodeutils.SendMessageToCluster(this.AdminContext(), clusterId, messageconfigs.MessageCodePreheatCache, msg, 300)
 | 
			
		||||
	// 校验Key
 | 
			
		||||
	validateResp, err := this.RPC().HTTPCacheTaskKeyRPC().ValidateHTTPCacheTaskKeys(this.AdminContext(), &pb.ValidateHTTPCacheTaskKeysRequest{Keys: realKeys})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	isAllOk := true
 | 
			
		||||
	for _, result := range results {
 | 
			
		||||
		if !result.IsOK {
 | 
			
		||||
			isAllOk = false
 | 
			
		||||
			break
 | 
			
		||||
	var failKeyMaps = []maps.Map{}
 | 
			
		||||
	if len(validateResp.FailKeys) > 0 {
 | 
			
		||||
		for _, key := range validateResp.FailKeys {
 | 
			
		||||
			failKeyMaps = append(failKeyMaps, maps.Map{
 | 
			
		||||
				"key":    key.Key,
 | 
			
		||||
				"reason": cacheutils.KeyFailReason(key.ReasonCode),
 | 
			
		||||
			})
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["failKeys"] = failKeyMaps
 | 
			
		||||
	if len(failKeyMaps) > 0 {
 | 
			
		||||
		this.Fail("有" + types.String(len(failKeyMaps)) + "个Key无法完成操作,请删除后重试")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Data["isAllOk"] = isAllOk
 | 
			
		||||
	this.Data["results"] = results
 | 
			
		||||
	// 提交任务
 | 
			
		||||
	_, err = this.RPC().HTTPCacheTaskRPC().CreateHTTPCacheTask(this.AdminContext(), &pb.CreateHTTPCacheTaskRequest{
 | 
			
		||||
		Type:    "fetch",
 | 
			
		||||
		KeyType: "key",
 | 
			
		||||
		Keys:    realKeys,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Success()
 | 
			
		||||
}
 | 
			
		||||
@@ -16,7 +16,7 @@ func init() {
 | 
			
		||||
			GetPost("", new(IndexAction)).
 | 
			
		||||
			GetPost("/createPopup", new(CreatePopupAction)).
 | 
			
		||||
			GetPost("/purge", new(PurgeAction)).
 | 
			
		||||
			GetPost("/preheat", new(PreheatAction)).
 | 
			
		||||
			GetPost("/fetch", new(FetchAction)).
 | 
			
		||||
			Post("/updateRefs", new(UpdateRefsAction)).
 | 
			
		||||
			EndAll()
 | 
			
		||||
	})
 | 
			
		||||
 
 | 
			
		||||
@@ -5,12 +5,13 @@ package cache
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/nodes/nodeutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/messageconfigs"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/cache/cacheutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
	"github.com/iwind/TeaGo/actions"
 | 
			
		||||
	"github.com/iwind/TeaGo/lists"
 | 
			
		||||
	"github.com/iwind/TeaGo/maps"
 | 
			
		||||
	"github.com/iwind/TeaGo/types"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -41,7 +42,7 @@ func (this *PurgeAction) RunGet(params struct {
 | 
			
		||||
func (this *PurgeAction) RunPost(params struct {
 | 
			
		||||
	ServerId int64
 | 
			
		||||
	WebId    int64
 | 
			
		||||
	Type     string
 | 
			
		||||
	KeyType  string
 | 
			
		||||
	Keys     string
 | 
			
		||||
 | 
			
		||||
	Must *actions.Must
 | 
			
		||||
@@ -118,32 +119,37 @@ func (this *PurgeAction) RunPost(params struct {
 | 
			
		||||
		realKeys = append(realKeys, key)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 发送命令
 | 
			
		||||
	msg := &messageconfigs.PurgeCacheMessage{
 | 
			
		||||
		CachePolicyJSON: cachePolicyJSON,
 | 
			
		||||
		Keys:            realKeys,
 | 
			
		||||
	}
 | 
			
		||||
	if params.Type == "prefix" {
 | 
			
		||||
		msg.Type = messageconfigs.PurgeCacheMessageTypeDir
 | 
			
		||||
	} else {
 | 
			
		||||
		msg.Type = messageconfigs.PurgeCacheMessageTypeFile
 | 
			
		||||
	}
 | 
			
		||||
	results, err := nodeutils.SendMessageToCluster(this.AdminContext(), clusterId, messageconfigs.MessageCodePurgeCache, msg, 10)
 | 
			
		||||
	// 校验Key
 | 
			
		||||
	validateResp, err := this.RPC().HTTPCacheTaskKeyRPC().ValidateHTTPCacheTaskKeys(this.AdminContext(), &pb.ValidateHTTPCacheTaskKeysRequest{Keys: realKeys})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	isAllOk := true
 | 
			
		||||
	for _, result := range results {
 | 
			
		||||
		if !result.IsOK {
 | 
			
		||||
			isAllOk = false
 | 
			
		||||
			break
 | 
			
		||||
	var failKeyMaps = []maps.Map{}
 | 
			
		||||
	if len(validateResp.FailKeys) > 0 {
 | 
			
		||||
		for _, key := range validateResp.FailKeys {
 | 
			
		||||
			failKeyMaps = append(failKeyMaps, maps.Map{
 | 
			
		||||
				"key":    key.Key,
 | 
			
		||||
				"reason": cacheutils.KeyFailReason(key.ReasonCode),
 | 
			
		||||
			})
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["failKeys"] = failKeyMaps
 | 
			
		||||
	if len(failKeyMaps) > 0 {
 | 
			
		||||
		this.Fail("有" + types.String(len(failKeyMaps)) + "个Key无法完成操作,请删除后重试")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Data["isAllOk"] = isAllOk
 | 
			
		||||
	this.Data["results"] = results
 | 
			
		||||
	// 提交任务
 | 
			
		||||
	_, err = this.RPC().HTTPCacheTaskRPC().CreateHTTPCacheTask(this.AdminContext(), &pb.CreateHTTPCacheTaskRequest{
 | 
			
		||||
		Type:    "purge",
 | 
			
		||||
		KeyType: params.KeyType,
 | 
			
		||||
		Keys:    realKeys,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Success()
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -34,11 +34,26 @@ func FindAllMenuMaps(nodeLogsType string, countUnreadNodeLogs int64, countUnread
 | 
			
		||||
					"url":  "/servers/certs",
 | 
			
		||||
					"code": "cert",
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					"name": "服务分组",
 | 
			
		||||
					"url":  "/servers/groups",
 | 
			
		||||
					"code": "group",
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					"name": "-",
 | 
			
		||||
					"url":  "",
 | 
			
		||||
					"code": "",
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					"name": "缓存策略",
 | 
			
		||||
					"url":  "/servers/components/cache",
 | 
			
		||||
					"code": "cache",
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					"name": "刷新预热",
 | 
			
		||||
					"url":  "/servers/components/cache/batch",
 | 
			
		||||
					"code": "cacheBatch",
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					"name": "-",
 | 
			
		||||
					"url":  "",
 | 
			
		||||
@@ -60,11 +75,6 @@ func FindAllMenuMaps(nodeLogsType string, countUnreadNodeLogs int64, countUnread
 | 
			
		||||
					"url":  "",
 | 
			
		||||
					"code": "",
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					"name": "服务分组",
 | 
			
		||||
					"url":  "/servers/groups",
 | 
			
		||||
					"code": "group",
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					"name": "统计指标",
 | 
			
		||||
					"url":  "/servers/metrics",
 | 
			
		||||
 
 | 
			
		||||
@@ -333,7 +333,7 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio
 | 
			
		||||
	<table class="ui table definition selectable">
 | 
			
		||||
		<tbody>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td class="title">是否启用</td>
 | 
			
		||||
				<td class="title">启用</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<div class="ui checkbox">
 | 
			
		||||
						<input type="checkbox" name="isOn" value="1" v-model="config.isOn"/>
 | 
			
		||||
@@ -402,7 +402,7 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio
 | 
			
		||||
		<prior-checkbox :v-config="config" v-if="!vIsParent"></prior-checkbox>
 | 
			
		||||
		<tbody v-show="vIsParent || config.isPrior">
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td class="title">是否启用</td>
 | 
			
		||||
				<td class="title">启用</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<checkbox name="isOn" value="1" v-model="config.isOn"></checkbox>
 | 
			
		||||
				</td>
 | 
			
		||||
@@ -1356,7 +1356,7 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio
 | 
			
		||||
				<td class="color-border">PURGE Key *</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<input type="text" maxlength="200" v-model="cacheConfig.purgeKey"/>
 | 
			
		||||
					<p class="comment"><a href="" @click.prevent="generatePurgeKey">[随机生成]</a>。需要在PURGE方法调用时加入<code-label>Edge-Purge-Key: {{cacheConfig.purgeKey}}</code-label> Header。只能包含字符、数字、下划线。</p>
 | 
			
		||||
					<p class="comment"><a href="" @click.prevent="generatePurgeKey">[随机生成]</a>。需要在PURGE方法调用时加入<code-label>X-Edge-Purge-Key: {{cacheConfig.purgeKey}}</code-label> Header。只能包含字符、数字、下划线。</p>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
		</tbody>
 | 
			
		||||
@@ -1552,7 +1552,7 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio
 | 
			
		||||
		<prior-checkbox :v-config="websocketRef" v-if="vIsLocation || vIsGroup"></prior-checkbox>
 | 
			
		||||
		<tbody v-show="((!vIsLocation && !vIsGroup) || websocketRef.isPrior)">
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td class="title">是否启用配置</td>
 | 
			
		||||
				<td class="title">启用配置</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<div class="ui checkbox">
 | 
			
		||||
						<input type="checkbox" v-model="websocketRef.isOn"/>
 | 
			
		||||
@@ -2356,7 +2356,7 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio
 | 
			
		||||
					<prior-checkbox :v-config="shutdownConfig" v-if="vIsLocation"></prior-checkbox>
 | 
			
		||||
					<tbody v-show="!vIsLocation || shutdownConfig.isPrior">
 | 
			
		||||
						<tr>
 | 
			
		||||
							<td class="title">是否开启</td>
 | 
			
		||||
							<td class="title">开启</td>
 | 
			
		||||
							<td>
 | 
			
		||||
								<div class="ui checkbox">
 | 
			
		||||
									<input type="checkbox" value="1" v-model="shutdownConfig.isOn" />
 | 
			
		||||
@@ -2407,7 +2407,7 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio
 | 
			
		||||
		<prior-checkbox :v-config="config" v-if="vIsLocation || vIsGroup"></prior-checkbox>
 | 
			
		||||
		<tbody v-show="(!vIsLocation && !vIsGroup) || config.isPrior">
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td class="title">是否启用</td>
 | 
			
		||||
				<td class="title">启用</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<div class="ui checkbox">
 | 
			
		||||
						<input type="checkbox" value="1" v-model="config.isOn"/>
 | 
			
		||||
@@ -2516,7 +2516,7 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio
 | 
			
		||||
		<prior-checkbox :v-config="charsetConfig" v-if="vIsLocation || vIsGroup"></prior-checkbox>
 | 
			
		||||
		<tbody v-show="(!vIsLocation && !vIsGroup) || charsetConfig.isPrior">
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td class="title">是否启用</td>
 | 
			
		||||
				<td class="title">启用</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<div class="ui checkbox">
 | 
			
		||||
						<input type="checkbox" v-model="charsetConfig.isOn"/>
 | 
			
		||||
@@ -2558,7 +2558,7 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio
 | 
			
		||||
		<prior-checkbox :v-config="expiresTime"></prior-checkbox>
 | 
			
		||||
		<tbody v-show="expiresTime.isPrior">
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td class="title">是否启用</td>
 | 
			
		||||
				<td class="title">启用</td>
 | 
			
		||||
				<td><checkbox v-model="expiresTime.isOn"></checkbox>
 | 
			
		||||
					<p class="comment">启用后,将会在响应的Header中添加<code-label>Expires</code-label>字段,浏览器据此会将内容缓存在客户端;同时,在管理后台执行清理缓存时,也将无法清理客户端已有的缓存。</p>
 | 
			
		||||
				</td>
 | 
			
		||||
@@ -2872,7 +2872,7 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio
 | 
			
		||||
		<prior-checkbox :v-config="reverseProxyRef" v-if="vIsLocation || vIsGroup"></prior-checkbox>
 | 
			
		||||
		<tbody v-show="(!vIsLocation && !vIsGroup) || reverseProxyRef.isPrior">
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td class="title">是否启用反向代理</td>
 | 
			
		||||
				<td class="title">启用反向代理</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<div class="ui checkbox">
 | 
			
		||||
						<input type="checkbox" v-model="reverseProxyRef.isOn"/>
 | 
			
		||||
@@ -3377,7 +3377,7 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio
 | 
			
		||||
		<prior-checkbox :v-config="fastcgiRef" v-if="vIsLocation"></prior-checkbox>
 | 
			
		||||
		<tbody v-show="(!this.vIsLocation || this.fastcgiRef.isPrior)">
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td class="title">是否启用配置</td>
 | 
			
		||||
				<td class="title">启用配置</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<div class="ui checkbox">
 | 
			
		||||
						<input type="checkbox" v-model="fastcgiRef.isOn"/>
 | 
			
		||||
@@ -3868,7 +3868,7 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio
 | 
			
		||||
	
 | 
			
		||||
	<table class="ui table selectable" v-show="isEditing">
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td class="title">是否启用</td>
 | 
			
		||||
			<td class="title">启用</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<checkbox v-model="config.isOn"></checkbox>
 | 
			
		||||
				<p class="comment">启用后,WAF将会尝试自动检测并阻止SYN Flood攻击。此功能需要节点已安装并启用Firewalld。</p>
 | 
			
		||||
@@ -4178,7 +4178,7 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td>是否自动下线</td>
 | 
			
		||||
			<td>自动下线</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<div class="ui checkbox">
 | 
			
		||||
					<input type="checkbox" value="1" v-model="healthCheck.autoDown"/>
 | 
			
		||||
 
 | 
			
		||||
@@ -1318,7 +1318,7 @@ Vue.component("ns-recursion-config-box", {
 | 
			
		||||
	<table class="ui table definition selectable">
 | 
			
		||||
		<tbody>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td class="title">是否启用</td>
 | 
			
		||||
				<td class="title">启用</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<div class="ui checkbox">
 | 
			
		||||
						<input type="checkbox" name="isOn" value="1" v-model="config.isOn"/>
 | 
			
		||||
@@ -1408,7 +1408,7 @@ Vue.component("ns-access-log-ref-box", {
 | 
			
		||||
		<prior-checkbox :v-config="config" v-if="!vIsParent"></prior-checkbox>
 | 
			
		||||
		<tbody v-show="vIsParent || config.isPrior">
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td class="title">是否启用</td>
 | 
			
		||||
				<td class="title">启用</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<checkbox name="isOn" value="1" v-model="config.isOn"></checkbox>
 | 
			
		||||
				</td>
 | 
			
		||||
@@ -4250,7 +4250,7 @@ Vue.component("http-cache-config-box", {
 | 
			
		||||
				<td class="color-border">PURGE Key *</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<input type="text" maxlength="200" v-model="cacheConfig.purgeKey"/>
 | 
			
		||||
					<p class="comment"><a href="" @click.prevent="generatePurgeKey">[随机生成]</a>。需要在PURGE方法调用时加入<code-label>Edge-Purge-Key: {{cacheConfig.purgeKey}}</code-label> Header。只能包含字符、数字、下划线。</p>
 | 
			
		||||
					<p class="comment"><a href="" @click.prevent="generatePurgeKey">[随机生成]</a>。需要在PURGE方法调用时加入<code-label>X-Edge-Purge-Key: {{cacheConfig.purgeKey}}</code-label> Header。只能包含字符、数字、下划线。</p>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
		</tbody>
 | 
			
		||||
@@ -5089,7 +5089,7 @@ Vue.component("http-websocket-box", {
 | 
			
		||||
		<prior-checkbox :v-config="websocketRef" v-if="vIsLocation || vIsGroup"></prior-checkbox>
 | 
			
		||||
		<tbody v-show="((!vIsLocation && !vIsGroup) || websocketRef.isPrior)">
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td class="title">是否启用配置</td>
 | 
			
		||||
				<td class="title">启用配置</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<div class="ui checkbox">
 | 
			
		||||
						<input type="checkbox" v-model="websocketRef.isOn"/>
 | 
			
		||||
@@ -7096,7 +7096,7 @@ Vue.component("http-pages-and-shutdown-box", {
 | 
			
		||||
					<prior-checkbox :v-config="shutdownConfig" v-if="vIsLocation"></prior-checkbox>
 | 
			
		||||
					<tbody v-show="!vIsLocation || shutdownConfig.isPrior">
 | 
			
		||||
						<tr>
 | 
			
		||||
							<td class="title">是否开启</td>
 | 
			
		||||
							<td class="title">开启</td>
 | 
			
		||||
							<td>
 | 
			
		||||
								<div class="ui checkbox">
 | 
			
		||||
									<input type="checkbox" value="1" v-model="shutdownConfig.isOn" />
 | 
			
		||||
@@ -7294,7 +7294,7 @@ Vue.component("http-compression-config-box", {
 | 
			
		||||
		<prior-checkbox :v-config="config" v-if="vIsLocation || vIsGroup"></prior-checkbox>
 | 
			
		||||
		<tbody v-show="(!vIsLocation && !vIsGroup) || config.isPrior">
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td class="title">是否启用</td>
 | 
			
		||||
				<td class="title">启用</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<div class="ui checkbox">
 | 
			
		||||
						<input type="checkbox" value="1" v-model="config.isOn"/>
 | 
			
		||||
@@ -7489,7 +7489,7 @@ Vue.component("http-charsets-box", {
 | 
			
		||||
		<prior-checkbox :v-config="charsetConfig" v-if="vIsLocation || vIsGroup"></prior-checkbox>
 | 
			
		||||
		<tbody v-show="(!vIsLocation && !vIsGroup) || charsetConfig.isPrior">
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td class="title">是否启用</td>
 | 
			
		||||
				<td class="title">启用</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<div class="ui checkbox">
 | 
			
		||||
						<input type="checkbox" v-model="charsetConfig.isOn"/>
 | 
			
		||||
@@ -7570,7 +7570,7 @@ Vue.component("http-expires-time-config-box", {
 | 
			
		||||
		<prior-checkbox :v-config="expiresTime"></prior-checkbox>
 | 
			
		||||
		<tbody v-show="expiresTime.isPrior">
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td class="title">是否启用</td>
 | 
			
		||||
				<td class="title">启用</td>
 | 
			
		||||
				<td><checkbox v-model="expiresTime.isOn"></checkbox>
 | 
			
		||||
					<p class="comment">启用后,将会在响应的Header中添加<code-label>Expires</code-label>字段,浏览器据此会将内容缓存在客户端;同时,在管理后台执行清理缓存时,也将无法清理客户端已有的缓存。</p>
 | 
			
		||||
				</td>
 | 
			
		||||
@@ -8431,7 +8431,7 @@ Vue.component("reverse-proxy-box", {
 | 
			
		||||
		<prior-checkbox :v-config="reverseProxyRef" v-if="vIsLocation || vIsGroup"></prior-checkbox>
 | 
			
		||||
		<tbody v-show="(!vIsLocation && !vIsGroup) || reverseProxyRef.isPrior">
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td class="title">是否启用反向代理</td>
 | 
			
		||||
				<td class="title">启用反向代理</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<div class="ui checkbox">
 | 
			
		||||
						<input type="checkbox" v-model="reverseProxyRef.isOn"/>
 | 
			
		||||
@@ -9548,7 +9548,7 @@ Vue.component("http-fastcgi-box", {
 | 
			
		||||
		<prior-checkbox :v-config="fastcgiRef" v-if="vIsLocation"></prior-checkbox>
 | 
			
		||||
		<tbody v-show="(!this.vIsLocation || this.fastcgiRef.isPrior)">
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td class="title">是否启用配置</td>
 | 
			
		||||
				<td class="title">启用配置</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<div class="ui checkbox">
 | 
			
		||||
						<input type="checkbox" v-model="fastcgiRef.isOn"/>
 | 
			
		||||
@@ -11063,7 +11063,7 @@ Vue.component("firewall-syn-flood-config-box", {
 | 
			
		||||
	
 | 
			
		||||
	<table class="ui table selectable" v-show="isEditing">
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td class="title">是否启用</td>
 | 
			
		||||
			<td class="title">启用</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<checkbox v-model="config.isOn"></checkbox>
 | 
			
		||||
				<p class="comment">启用后,WAF将会尝试自动检测并阻止SYN Flood攻击。此功能需要节点已安装并启用Firewalld。</p>
 | 
			
		||||
@@ -12675,7 +12675,7 @@ Vue.component("health-check-config-box", {
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td>是否自动下线</td>
 | 
			
		||||
			<td>自动下线</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<div class="ui checkbox">
 | 
			
		||||
					<input type="checkbox" value="1" v-model="healthCheck.autoDown"/>
 | 
			
		||||
 
 | 
			
		||||
@@ -215,7 +215,7 @@ Vue.component("health-check-config-box", {
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td>是否自动下线</td>
 | 
			
		||||
			<td>自动下线</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<div class="ui checkbox">
 | 
			
		||||
					<input type="checkbox" value="1" v-model="healthCheck.autoDown"/>
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,7 @@ Vue.component("ns-access-log-ref-box", {
 | 
			
		||||
		<prior-checkbox :v-config="config" v-if="!vIsParent"></prior-checkbox>
 | 
			
		||||
		<tbody v-show="vIsParent || config.isPrior">
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td class="title">是否启用</td>
 | 
			
		||||
				<td class="title">启用</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<checkbox name="isOn" value="1" v-model="config.isOn"></checkbox>
 | 
			
		||||
				</td>
 | 
			
		||||
 
 | 
			
		||||
@@ -98,7 +98,7 @@ Vue.component("ns-recursion-config-box", {
 | 
			
		||||
	<table class="ui table definition selectable">
 | 
			
		||||
		<tbody>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td class="title">是否启用</td>
 | 
			
		||||
				<td class="title">启用</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<div class="ui checkbox">
 | 
			
		||||
						<input type="checkbox" name="isOn" value="1" v-model="config.isOn"/>
 | 
			
		||||
 
 | 
			
		||||
@@ -56,7 +56,7 @@ Vue.component("firewall-syn-flood-config-box", {
 | 
			
		||||
	
 | 
			
		||||
	<table class="ui table selectable" v-show="isEditing">
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td class="title">是否启用</td>
 | 
			
		||||
			<td class="title">启用</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<checkbox v-model="config.isOn"></checkbox>
 | 
			
		||||
				<p class="comment">启用后,WAF将会尝试自动检测并阻止SYN Flood攻击。此功能需要节点已安装并启用Firewalld。</p>
 | 
			
		||||
 
 | 
			
		||||
@@ -125,7 +125,7 @@ Vue.component("http-cache-config-box", {
 | 
			
		||||
				<td class="color-border">PURGE Key *</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<input type="text" maxlength="200" v-model="cacheConfig.purgeKey"/>
 | 
			
		||||
					<p class="comment"><a href="" @click.prevent="generatePurgeKey">[随机生成]</a>。需要在PURGE方法调用时加入<code-label>Edge-Purge-Key: {{cacheConfig.purgeKey}}</code-label> Header。只能包含字符、数字、下划线。</p>
 | 
			
		||||
					<p class="comment"><a href="" @click.prevent="generatePurgeKey">[随机生成]</a>。需要在PURGE方法调用时加入<code-label>X-Edge-Purge-Key: {{cacheConfig.purgeKey}}</code-label> Header。只能包含字符、数字、下划线。</p>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
		</tbody>
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,7 @@ Vue.component("http-charsets-box", {
 | 
			
		||||
		<prior-checkbox :v-config="charsetConfig" v-if="vIsLocation || vIsGroup"></prior-checkbox>
 | 
			
		||||
		<tbody v-show="(!vIsLocation && !vIsGroup) || charsetConfig.isPrior">
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td class="title">是否启用</td>
 | 
			
		||||
				<td class="title">启用</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<div class="ui checkbox">
 | 
			
		||||
						<input type="checkbox" v-model="charsetConfig.isOn"/>
 | 
			
		||||
 
 | 
			
		||||
@@ -148,7 +148,7 @@ Vue.component("http-compression-config-box", {
 | 
			
		||||
		<prior-checkbox :v-config="config" v-if="vIsLocation || vIsGroup"></prior-checkbox>
 | 
			
		||||
		<tbody v-show="(!vIsLocation && !vIsGroup) || config.isPrior">
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td class="title">是否启用</td>
 | 
			
		||||
				<td class="title">启用</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<div class="ui checkbox">
 | 
			
		||||
						<input type="checkbox" value="1" v-model="config.isOn"/>
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,7 @@ Vue.component("http-expires-time-config-box", {
 | 
			
		||||
		<prior-checkbox :v-config="expiresTime"></prior-checkbox>
 | 
			
		||||
		<tbody v-show="expiresTime.isPrior">
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td class="title">是否启用</td>
 | 
			
		||||
				<td class="title">启用</td>
 | 
			
		||||
				<td><checkbox v-model="expiresTime.isOn"></checkbox>
 | 
			
		||||
					<p class="comment">启用后,将会在响应的Header中添加<code-label>Expires</code-label>字段,浏览器据此会将内容缓存在客户端;同时,在管理后台执行清理缓存时,也将无法清理客户端已有的缓存。</p>
 | 
			
		||||
				</td>
 | 
			
		||||
 
 | 
			
		||||
@@ -61,7 +61,7 @@ Vue.component("http-fastcgi-box", {
 | 
			
		||||
		<prior-checkbox :v-config="fastcgiRef" v-if="vIsLocation"></prior-checkbox>
 | 
			
		||||
		<tbody v-show="(!this.vIsLocation || this.fastcgiRef.isPrior)">
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td class="title">是否启用配置</td>
 | 
			
		||||
				<td class="title">启用配置</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<div class="ui checkbox">
 | 
			
		||||
						<input type="checkbox" v-model="fastcgiRef.isOn"/>
 | 
			
		||||
 
 | 
			
		||||
@@ -114,7 +114,7 @@ Vue.component("http-pages-and-shutdown-box", {
 | 
			
		||||
					<prior-checkbox :v-config="shutdownConfig" v-if="vIsLocation"></prior-checkbox>
 | 
			
		||||
					<tbody v-show="!vIsLocation || shutdownConfig.isPrior">
 | 
			
		||||
						<tr>
 | 
			
		||||
							<td class="title">是否开启</td>
 | 
			
		||||
							<td class="title">开启</td>
 | 
			
		||||
							<td>
 | 
			
		||||
								<div class="ui checkbox">
 | 
			
		||||
									<input type="checkbox" value="1" v-model="shutdownConfig.isOn" />
 | 
			
		||||
 
 | 
			
		||||
@@ -80,7 +80,7 @@ Vue.component("http-websocket-box", {
 | 
			
		||||
		<prior-checkbox :v-config="websocketRef" v-if="vIsLocation || vIsGroup"></prior-checkbox>
 | 
			
		||||
		<tbody v-show="((!vIsLocation && !vIsGroup) || websocketRef.isPrior)">
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td class="title">是否启用配置</td>
 | 
			
		||||
				<td class="title">启用配置</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<div class="ui checkbox">
 | 
			
		||||
						<input type="checkbox" v-model="websocketRef.isOn"/>
 | 
			
		||||
 
 | 
			
		||||
@@ -158,7 +158,7 @@ Vue.component("reverse-proxy-box", {
 | 
			
		||||
		<prior-checkbox :v-config="reverseProxyRef" v-if="vIsLocation || vIsGroup"></prior-checkbox>
 | 
			
		||||
		<tbody v-show="(!vIsLocation && !vIsGroup) || reverseProxyRef.isPrior">
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td class="title">是否启用反向代理</td>
 | 
			
		||||
				<td class="title">启用反向代理</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<div class="ui checkbox">
 | 
			
		||||
						<input type="checkbox" v-model="reverseProxyRef.isOn"/>
 | 
			
		||||
 
 | 
			
		||||
@@ -55,7 +55,7 @@
 | 
			
		||||
                    </td>
 | 
			
		||||
                </tr>
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <td>是否启用</td>
 | 
			
		||||
                    <td>启用节点</td>
 | 
			
		||||
                    <td>
 | 
			
		||||
                        <div class="ui checkbox">
 | 
			
		||||
                            <input type="checkbox" name="isOn" value="1" v-model="node.isOn"/>
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,6 @@
 | 
			
		||||
	<menu-item :href="'/servers/components/cache/stat?cachePolicyId=' + cachePolicyId" code="stat">统计</menu-item>
 | 
			
		||||
	<menu-item :href="'/servers/components/cache/clean?cachePolicyId=' + cachePolicyId" code="clean">清理</menu-item>
 | 
			
		||||
	<menu-item :href="'/servers/components/cache/purge?cachePolicyId=' + cachePolicyId" code="purge">删除</menu-item>
 | 
			
		||||
	<menu-item :href="'/servers/components/cache/preheat?cachePolicyId=' + cachePolicyId" code="preheat">预热</menu-item>
 | 
			
		||||
	<menu-item :href="'/servers/components/cache/fetch?cachePolicyId=' + cachePolicyId" code="fetch">预热</menu-item>
 | 
			
		||||
	<menu-item :href="'/servers/components/cache/update?cachePolicyId=' + cachePolicyId" code="update">修改</menu-item>
 | 
			
		||||
</second-menu>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								web/views/@default/servers/components/cache/batch/@menu.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								web/views/@default/servers/components/cache/batch/@menu.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
<first-menu>
 | 
			
		||||
    <menu-item href="." code="purge">刷新缓存</menu-item>
 | 
			
		||||
    <menu-item href=".fetch" code="fetch">预热缓存</menu-item>
 | 
			
		||||
    <span class="item disabled">|</span>
 | 
			
		||||
    <menu-item href=".tasks" code="task">所有任务<span v-if="countDoingTasks > 0" class="grey">({{countDoingTasks}})</span></menu-item>
 | 
			
		||||
</first-menu>
 | 
			
		||||
							
								
								
									
										28
									
								
								web/views/@default/servers/components/cache/batch/fetch.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								web/views/@default/servers/components/cache/batch/fetch.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
{$template "menu"}
 | 
			
		||||
 | 
			
		||||
<form method="post" class="ui form" data-tea-action="$" data-tea-before="before" data-tea-success="success" data-tea-fail="fail" data-tea-done="done" data-tea-timeout="3600">
 | 
			
		||||
    <csrf-token></csrf-token>
 | 
			
		||||
    <table class="ui table definition selectable">
 | 
			
		||||
        <tr>
 | 
			
		||||
            <td>要预热的Key列表</td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <textarea name="keys" rows="10" ref="focus"></textarea>
 | 
			
		||||
                <p class="comment">每行一个Key。</p>
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tr>
 | 
			
		||||
            <td class="title">操作结果</td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <div v-if="isRequesting">数据发送中...</div>
 | 
			
		||||
                <span class="red" v-if="!isRequesting && !isOk && message.length > 0">失败:{{message}}</span>
 | 
			
		||||
                <div v-if="!isRequesting && !isOk && failKeys.length > 0" class="fail-keys-box">
 | 
			
		||||
                    <div v-for="failKey in failKeys">
 | 
			
		||||
                        <span class="red">{{failKey.key}}: {{failKey.reason}}</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
    </table>
 | 
			
		||||
    <submit-btn v-if="!isRequesting">提交</submit-btn>
 | 
			
		||||
</form>
 | 
			
		||||
@@ -2,22 +2,28 @@ Tea.context(function () {
 | 
			
		||||
	this.isRequesting = false
 | 
			
		||||
	this.isOk = false
 | 
			
		||||
	this.message = ""
 | 
			
		||||
	this.results = []
 | 
			
		||||
	this.failKeys = []
 | 
			
		||||
 | 
			
		||||
	this.before = function () {
 | 
			
		||||
		this.isRequesting = true
 | 
			
		||||
		this.isOk = false
 | 
			
		||||
		this.message = ""
 | 
			
		||||
		this.results = []
 | 
			
		||||
		this.failKeys = []
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.success = function (resp) {
 | 
			
		||||
		this.isOk = true
 | 
			
		||||
		this.results = resp.data.results
 | 
			
		||||
 | 
			
		||||
		let f = NotifyReloadSuccess("任务提交成功")
 | 
			
		||||
		f()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.fail = function (resp) {
 | 
			
		||||
		this.message = resp.message
 | 
			
		||||
 | 
			
		||||
		if (resp.data.failKeys != null) {
 | 
			
		||||
			this.failKeys = resp.data.failKeys
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.done = function () {
 | 
			
		||||
							
								
								
									
										8
									
								
								web/views/@default/servers/components/cache/batch/index.css
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								web/views/@default/servers/components/cache/batch/index.css
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
.fail-keys-box {
 | 
			
		||||
  max-height: 10em;
 | 
			
		||||
  overflow-y: auto;
 | 
			
		||||
}
 | 
			
		||||
.fail-keys-box::-webkit-scrollbar {
 | 
			
		||||
  width: 6px;
 | 
			
		||||
}
 | 
			
		||||
/*# sourceMappingURL=index.css.map */
 | 
			
		||||
							
								
								
									
										1
									
								
								web/views/@default/servers/components/cache/batch/index.css.map
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								web/views/@default/servers/components/cache/batch/index.css.map
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
{"version":3,"sources":["index.less"],"names":[],"mappings":"AAAA;EACC,gBAAA;EACA,gBAAA;;AAGD,cAAc;EACb,UAAA","file":"index.css"}
 | 
			
		||||
							
								
								
									
										41
									
								
								web/views/@default/servers/components/cache/batch/index.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								web/views/@default/servers/components/cache/batch/index.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
{$template "menu"}
 | 
			
		||||
 | 
			
		||||
<div class="margin"></div>
 | 
			
		||||
 | 
			
		||||
<form method="post" class="ui form" data-tea-action="$" data-tea-before="before" data-tea-success="success" data-tea-fail="fail" data-tea-done="done" data-tea-timeout="300">
 | 
			
		||||
    <csrf-token></csrf-token>
 | 
			
		||||
    <table class="ui table definition selectable">
 | 
			
		||||
        <tr>
 | 
			
		||||
            <td class="title">缓存Key类型</td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <radio name="keyType" :v-value="'key'" v-model="keyType">根据Key</radio>  
 | 
			
		||||
                <radio name="keyType" :v-value="'prefix'" v-model="keyType">根据前缀</radio>
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tr>
 | 
			
		||||
            <td>
 | 
			
		||||
                <span v-if="keyType == 'key'">要刷新的Key列表</span>
 | 
			
		||||
                <span v-if="keyType == 'prefix'">要刷新的Key前缀列表</span>
 | 
			
		||||
            </td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <textarea name="keys" rows="10" ref="keysBox"></textarea>
 | 
			
		||||
                <p class="comment" v-if="keyType == 'key'">每行一个Key,比如是一个完整的URL<code-label>https://example.com/hello/world.html</code-label>。</p>
 | 
			
		||||
                <p class="comment" v-if="keyType == 'prefix'">每行一个Key前缀,比如是一个URL前缀<code-label>https://example.com/hello/</code-label>。</p>
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tr>
 | 
			
		||||
            <td>操作结果</td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <div v-if="isRequesting">数据发送中...</div>
 | 
			
		||||
                <span class="red" v-if="!isRequesting && !isOk && message.length > 0">失败:{{message}}</span>
 | 
			
		||||
                <div v-if="!isRequesting && !isOk && failKeys.length > 0" class="fail-keys-box">
 | 
			
		||||
                    <div v-for="failKey in failKeys">
 | 
			
		||||
                        <span class="red">{{failKey.key}}: {{failKey.reason}}</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
    </table>
 | 
			
		||||
    <submit-btn v-if="!isRequesting">提交</submit-btn>
 | 
			
		||||
</form>
 | 
			
		||||
							
								
								
									
										43
									
								
								web/views/@default/servers/components/cache/batch/index.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								web/views/@default/servers/components/cache/batch/index.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
			
		||||
Tea.context(function () {
 | 
			
		||||
	this.isRequesting = false
 | 
			
		||||
	this.isOk = false
 | 
			
		||||
	this.message = ""
 | 
			
		||||
	this.failKeys = []
 | 
			
		||||
 | 
			
		||||
	this.$delay(function () {
 | 
			
		||||
		this.$refs.keysBox.focus()
 | 
			
		||||
		this.$watch("keyType", function () {
 | 
			
		||||
			this.$refs.keysBox.focus()
 | 
			
		||||
		})
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	this.before = function () {
 | 
			
		||||
		this.isRequesting = true
 | 
			
		||||
		this.isOk = false
 | 
			
		||||
		this.message = ""
 | 
			
		||||
		this.failKeys = []
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.success = function () {
 | 
			
		||||
		this.isOk = true
 | 
			
		||||
		let f = NotifyReloadSuccess("任务提交成功")
 | 
			
		||||
		f()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.fail = function (resp) {
 | 
			
		||||
		this.message = resp.message
 | 
			
		||||
 | 
			
		||||
		if (resp.data.failKeys != null) {
 | 
			
		||||
			this.failKeys = resp.data.failKeys
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.done = function () {
 | 
			
		||||
		this.isRequesting = false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * 操作类型
 | 
			
		||||
	 */
 | 
			
		||||
	this.keyType = "key" // key | prefix
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										8
									
								
								web/views/@default/servers/components/cache/batch/index.less
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								web/views/@default/servers/components/cache/batch/index.less
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
.fail-keys-box {
 | 
			
		||||
	max-height: 10em;
 | 
			
		||||
	overflow-y: auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.fail-keys-box::-webkit-scrollbar {
 | 
			
		||||
	width: 6px;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										94
									
								
								web/views/@default/servers/components/cache/batch/task.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								web/views/@default/servers/components/cache/batch/task.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,94 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
{$template "menu"}
 | 
			
		||||
 | 
			
		||||
<second-menu>
 | 
			
		||||
    <menu-item href=".tasks">所有任务</menu-item>
 | 
			
		||||
    <span class="disabled item" style="padding: 0">»</span>
 | 
			
		||||
    <span class="item">任务详情</span>
 | 
			
		||||
</second-menu>
 | 
			
		||||
 | 
			
		||||
<table class="ui table definition selectable">
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td class="title">任务编号</td>
 | 
			
		||||
        <td>{{task.id}}</td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td>任务类型</td>
 | 
			
		||||
        <td>
 | 
			
		||||
            <span v-if="task.type == 'purge'">刷新</span>
 | 
			
		||||
            <span v-if="task.type == 'fetch'">预热</span>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td>Key类型</td>
 | 
			
		||||
        <td>
 | 
			
		||||
            <span v-if="task.keyType == 'key'">URL</span>
 | 
			
		||||
            <span v-if="task.keyType == 'prefix'">前缀</span>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td>创建时间</td>
 | 
			
		||||
        <td>
 | 
			
		||||
            {{task.createdTime}}
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td>完成时间</td>
 | 
			
		||||
        <td>
 | 
			
		||||
            <span v-if="task.isDone">{{task.doneTime}}</span>
 | 
			
		||||
            <span v-else class="disabled">尚未完成</span>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td>所属用户</td>
 | 
			
		||||
        <td>
 | 
			
		||||
            <span v-if="task.user != null && task.user.id > 0"><user-link :v-user="task.user"></user-link></span>
 | 
			
		||||
            <span v-else="" class="disabled">-</span>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td>任务状态</td>
 | 
			
		||||
        <td>
 | 
			
		||||
            <span v-if="task.isOk" class="green">已完成</span>
 | 
			
		||||
            <a :href="'/servers/components/cache/batch/task?taskId=' + task.id" v-else-if="task.isDone" class="red"><span class="red">失败</span></a>
 | 
			
		||||
            <span v-else-if="!task.isDone" class="grey">等待执行</span>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td>操作</td>
 | 
			
		||||
        <td>
 | 
			
		||||
            <a href="" @click.prevent="deleteTask(task.id)">[删除]</a>    
 | 
			
		||||
            <a href="" @click.prevent="resetTask(task.id)">[重置状态]</a>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
</table>
 | 
			
		||||
 | 
			
		||||
<h4>要操作的缓存Key</h4>
 | 
			
		||||
<table class="ui table selectable celled">
 | 
			
		||||
    <thead>
 | 
			
		||||
        <tr>
 | 
			
		||||
            <th>
 | 
			
		||||
                <span v-if="task.keyType == 'key'">URL</span>
 | 
			
		||||
                <span v-if="task.keyType == 'prefix'">前缀</span>
 | 
			
		||||
            </th>
 | 
			
		||||
            <th class="width5">状态</th>
 | 
			
		||||
        </tr>
 | 
			
		||||
    </thead>
 | 
			
		||||
    <tbody v-for="key in task.keys">
 | 
			
		||||
        <tr>
 | 
			
		||||
            <td>{{key.key}}
 | 
			
		||||
 | 
			
		||||
                <div v-if="key.errors.length > 0" style="margin-top: 0.5em">
 | 
			
		||||
                    <a :href="'/clusters/cluster/node?nodeId=' + err.nodeId" v-for="err in key.errors" class="ui label basic tiny red">
 | 
			
		||||
                        节点{{err.nodeId}}:{{err.error}}
 | 
			
		||||
                    </a>
 | 
			
		||||
                </div>
 | 
			
		||||
            </td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <span v-if="key.isDone && key.errors.length == 0" class="green">完成</span>
 | 
			
		||||
                <span v-if="key.isDone && key.errors.length > 0" class="red">失败</span>
 | 
			
		||||
                <span v-if="!key.isDone" class="grey">未执行</span>
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
    </tbody>
 | 
			
		||||
</table>
 | 
			
		||||
							
								
								
									
										23
									
								
								web/views/@default/servers/components/cache/batch/task.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								web/views/@default/servers/components/cache/batch/task.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
Tea.context(function () {
 | 
			
		||||
	this.deleteTask = function (taskId) {
 | 
			
		||||
		teaweb.confirm("确定要删除此任务吗?", function () {
 | 
			
		||||
			this.$post(".deleteTask")
 | 
			
		||||
				.params({
 | 
			
		||||
					taskId: taskId
 | 
			
		||||
				})
 | 
			
		||||
				.success(function () {
 | 
			
		||||
					window.location = Tea.url(".tasks")
 | 
			
		||||
				})
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.resetTask = function (taskId) {
 | 
			
		||||
		teaweb.confirm("确定要重置任务状态吗?", function () {
 | 
			
		||||
			this.$post(".resetTask")
 | 
			
		||||
				.params({
 | 
			
		||||
					taskId: taskId
 | 
			
		||||
				})
 | 
			
		||||
				.refresh()
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										48
									
								
								web/views/@default/servers/components/cache/batch/tasks.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								web/views/@default/servers/components/cache/batch/tasks.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
{$template "menu"}
 | 
			
		||||
 | 
			
		||||
<p class="comment" v-if="tasks.length == 0">暂时还没有任务。</p>
 | 
			
		||||
 | 
			
		||||
<table class="ui table selectable celled" v-if="tasks.length > 0">
 | 
			
		||||
    <thead>
 | 
			
		||||
        <tr>
 | 
			
		||||
            <th style="width: 7em">任务编号</th>
 | 
			
		||||
            <th>任务类型</th>
 | 
			
		||||
            <th>Key类型</th>
 | 
			
		||||
            <th>创建时间</th>
 | 
			
		||||
            <th class="four wide">所属用户</th>
 | 
			
		||||
            <th class="two wide">任务状态</th>
 | 
			
		||||
            <th class="two op">操作</th>
 | 
			
		||||
        </tr>
 | 
			
		||||
    </thead>
 | 
			
		||||
    <tbody v-for="task in tasks">
 | 
			
		||||
        <tr>
 | 
			
		||||
            <td><a :href="'/servers/components/cache/batch/task?taskId=' + task.id">{{task.id}}</a></td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <span v-if="task.type == 'purge'">刷新</span>
 | 
			
		||||
                <span v-if="task.type == 'fetch'">预热</span>
 | 
			
		||||
            </td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <span v-if="task.keyType == 'key'">URL</span>
 | 
			
		||||
                <span v-if="task.keyType == 'prefix'">前缀</span>
 | 
			
		||||
            </td>
 | 
			
		||||
            <td>{{task.createdTime}}</td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <span v-if="task.user != null && task.user.id > 0"><user-link :v-user="task.user"></user-link></span>
 | 
			
		||||
                <span v-if="task.description.length > 0" class="grey">{{task.description}}</span>
 | 
			
		||||
                <span v-else="" class="disabled">-</span>
 | 
			
		||||
            </td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <span v-if="task.isOk" class="green">已完成</span>
 | 
			
		||||
                <a :href="'/servers/components/cache/batch/task?taskId=' + task.id" v-else-if="task.isDone" class="red"><span class="red">失败</span></a>
 | 
			
		||||
                <span v-else-if="!task.isDone" class="grey">等待执行</span>
 | 
			
		||||
            </td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <a :href="'/servers/components/cache/batch/task?taskId=' + task.id">详情</a>  
 | 
			
		||||
                <a href="" @click.prevent="deleteTask(task.id)">删除</a>
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
    </tbody>
 | 
			
		||||
</table>
 | 
			
		||||
 | 
			
		||||
<page-box></page-box>
 | 
			
		||||
							
								
								
									
										11
									
								
								web/views/@default/servers/components/cache/batch/tasks.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								web/views/@default/servers/components/cache/batch/tasks.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
Tea.context(function () {
 | 
			
		||||
	this.deleteTask = function (taskId) {
 | 
			
		||||
		teaweb.confirm("确定要删除此任务吗?", function () {
 | 
			
		||||
			this.$post(".deleteTask")
 | 
			
		||||
				.params({
 | 
			
		||||
					taskId: taskId
 | 
			
		||||
				})
 | 
			
		||||
				.refresh()
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
})
 | 
			
		||||
@@ -1,15 +1,8 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
{$template "policy_menu"}
 | 
			
		||||
 | 
			
		||||
<h3>选择集群</h3>
 | 
			
		||||
<select class="ui dropdown auto-width" v-model="clusterId">
 | 
			
		||||
    <option v-for="cluster in clusters" :value="cluster.id">{{cluster.name}}</option>
 | 
			
		||||
</select>
 | 
			
		||||
<div class="ui divider"></div>
 | 
			
		||||
 | 
			
		||||
<form method="post" class="ui form" data-tea-action="$" data-tea-before="before" data-tea-success="success" data-tea-fail="fail" data-tea-done="done" data-tea-timeout="3600">
 | 
			
		||||
    <input type="hidden" name="cachePolicyId" :value="cachePolicyId"/>
 | 
			
		||||
    <input type="hidden" name="clusterId" :value="clusterId"/>
 | 
			
		||||
    <table class="ui table definition selectable">
 | 
			
		||||
        <tr>
 | 
			
		||||
            <td>Key列表</td>
 | 
			
		||||
@@ -23,9 +16,10 @@
 | 
			
		||||
            <td>
 | 
			
		||||
                <div v-if="isRequesting">数据发送中...</div>
 | 
			
		||||
                <span class="red" v-if="!isRequesting && !isOk && message.length > 0">失败:{{message}}</span>
 | 
			
		||||
                <div v-if="!isRequesting && isOk">
 | 
			
		||||
                    <span v-if="results.length == 0" class="red">此集群下没有任何可用的节点。</span>
 | 
			
		||||
                    <div class="ui label tiny" v-for="one in results" :class="{green:one.isOk, red:!one.isOk}" style="margin-bottom: 0.5em">{{one.nodeName}}:{{one.message}}</div>
 | 
			
		||||
                <div v-if="!isRequesting && !isOk && failKeys.length > 0" class="fail-keys-box">
 | 
			
		||||
                    <div v-for="failKey in failKeys">
 | 
			
		||||
                        <span class="red">{{failKey.key}}: {{failKey.reason}}</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
@@ -2,22 +2,28 @@ Tea.context(function () {
 | 
			
		||||
	this.isRequesting = false
 | 
			
		||||
	this.isOk = false
 | 
			
		||||
	this.message = ""
 | 
			
		||||
	this.results = []
 | 
			
		||||
	this.failKeys = []
 | 
			
		||||
 | 
			
		||||
	this.before = function () {
 | 
			
		||||
		this.isRequesting = true
 | 
			
		||||
		this.isOk = false
 | 
			
		||||
		this.message = ""
 | 
			
		||||
		this.results = []
 | 
			
		||||
		this.failKeys = []
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.success = function (resp) {
 | 
			
		||||
		this.isOk = true
 | 
			
		||||
		this.results = resp.data.results
 | 
			
		||||
 | 
			
		||||
		let f = NotifyReloadSuccess("任务提交成功")
 | 
			
		||||
		f()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.fail = function (resp) {
 | 
			
		||||
		this.message = resp.message
 | 
			
		||||
 | 
			
		||||
		if (resp.data.failKeys != null) {
 | 
			
		||||
			this.failKeys = resp.data.failKeys
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.done = function () {
 | 
			
		||||
@@ -1,34 +1,26 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
{$template "policy_menu"}
 | 
			
		||||
 | 
			
		||||
<h3>选择集群</h3>
 | 
			
		||||
<select class="ui dropdown auto-width" v-model="clusterId">
 | 
			
		||||
    <option v-for="cluster in clusters" :value="cluster.id">{{cluster.name}}</option>
 | 
			
		||||
</select>
 | 
			
		||||
<div class="ui divider"></div>
 | 
			
		||||
 | 
			
		||||
<h3>批量删除</h3>
 | 
			
		||||
<p class="comment">可以在这里批量删除一组Key。</p>
 | 
			
		||||
<form method="post" class="ui form" data-tea-action="$" data-tea-before="before" data-tea-success="success" data-tea-fail="fail" data-tea-done="done" data-tea-timeout="300">
 | 
			
		||||
    <input type="hidden" name="cachePolicyId" :value="cachePolicyId"/>
 | 
			
		||||
    <input type="hidden" name="clusterId" :value="clusterId"/>
 | 
			
		||||
    <table class="ui table definition selectable">
 | 
			
		||||
        <tr>
 | 
			
		||||
            <td class="title">操作类型</td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <radio name="type" :v-value="'key'" v-model="type">根据Key</radio>  
 | 
			
		||||
                <radio name="type" :v-value="'prefix'" v-model="type">根据前缀</radio>
 | 
			
		||||
                <radio name="keyType" :v-value="'key'" v-model="keyType">根据Key</radio>  
 | 
			
		||||
                <radio name="keyType" :v-value="'prefix'" v-model="keyType">根据前缀</radio>
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tr>
 | 
			
		||||
            <td>
 | 
			
		||||
                <span v-if="type == 'key'">Key列表</span>
 | 
			
		||||
                <span v-if="type == 'prefix'">Key前缀列表</span>
 | 
			
		||||
                <span v-if="keyType == 'key'">Key列表</span>
 | 
			
		||||
                <span v-if="keyType == 'prefix'">Key前缀列表</span>
 | 
			
		||||
            </td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <textarea name="keys" rows="10" ref="focus"></textarea>
 | 
			
		||||
                <p class="comment" v-if="type == 'key'">每行一个Key,比如是一个完整的URL<code-label>https://example.com/hello/world.html</code-label>。</p>
 | 
			
		||||
                <p class="comment" v-if="type == 'prefix'">每行一个Key前缀,比如是一个URL前缀<code-label>https://example.com/hello/</code-label>。</p>
 | 
			
		||||
                <textarea name="keys" rows="10" ref="keysBox"></textarea>
 | 
			
		||||
                <p class="comment" v-if="keyType == 'key'">每行一个Key,比如是一个完整的URL<code-label>https://example.com/hello/world.html</code-label>。</p>
 | 
			
		||||
                <p class="comment" v-if="keyType == 'prefix'">每行一个Key前缀,比如是一个URL前缀<code-label>https://example.com/hello/</code-label>。</p>
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tr>
 | 
			
		||||
@@ -36,9 +28,10 @@
 | 
			
		||||
            <td>
 | 
			
		||||
                <div v-if="isRequesting">数据发送中...</div>
 | 
			
		||||
                <span class="red" v-if="!isRequesting && !isOk && message.length > 0">失败:{{message}}</span>
 | 
			
		||||
                <div v-if="!isRequesting && isOk">
 | 
			
		||||
                    <span v-if="results.length == 0" class="red">此集群下没有任何可用的节点。</span>
 | 
			
		||||
                    <div class="ui label tiny" v-for="one in results" :class="{green:one.isOk, red:!one.isOk}" style="margin-bottom: 0.5em">{{one.nodeName}}:{{one.message}}</div>
 | 
			
		||||
                <div v-if="!isRequesting && !isOk && failKeys.length > 0" class="fail-keys-box">
 | 
			
		||||
                    <div v-for="failKey in failKeys">
 | 
			
		||||
                        <span class="red">{{failKey.key}}: {{failKey.reason}}</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,31 +1,35 @@
 | 
			
		||||
Tea.context(function () {
 | 
			
		||||
	if (this.clusterId == null) {
 | 
			
		||||
		if (this.clusters.length > 0) {
 | 
			
		||||
			this.clusterId = this.clusters[0].id
 | 
			
		||||
		} else {
 | 
			
		||||
			this.clusterId = 0
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.isRequesting = false
 | 
			
		||||
	this.isOk = false
 | 
			
		||||
	this.message = ""
 | 
			
		||||
	this.results = []
 | 
			
		||||
	this.failKeys = []
 | 
			
		||||
 | 
			
		||||
	this.$delay(function () {
 | 
			
		||||
		this.$refs.keysBox.focus()
 | 
			
		||||
		this.$watch("keyType", function () {
 | 
			
		||||
			this.$refs.keysBox.focus()
 | 
			
		||||
		})
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	this.before = function () {
 | 
			
		||||
		this.isRequesting = true
 | 
			
		||||
		this.isOk = false
 | 
			
		||||
		this.message = ""
 | 
			
		||||
		this.results = []
 | 
			
		||||
		this.failKeys = []
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.success = function (resp) {
 | 
			
		||||
	this.success = function () {
 | 
			
		||||
		this.isOk = true
 | 
			
		||||
		this.results = resp.data.results
 | 
			
		||||
		let f = NotifyReloadSuccess("任务提交成功")
 | 
			
		||||
		f()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.fail = function (resp) {
 | 
			
		||||
		this.message = resp.message
 | 
			
		||||
 | 
			
		||||
		if (resp.data.failKeys != null) {
 | 
			
		||||
			this.failKeys = resp.data.failKeys
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.done = function () {
 | 
			
		||||
@@ -35,5 +39,5 @@ Tea.context(function () {
 | 
			
		||||
	/**
 | 
			
		||||
	 * 操作类型
 | 
			
		||||
	 */
 | 
			
		||||
	this.type = "key" // key | prefix
 | 
			
		||||
	this.keyType = "key" // key | prefix
 | 
			
		||||
})
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
<first-menu>
 | 
			
		||||
    <menu-item :href="'.?serverId=' + serverId" code="index">设置</menu-item>
 | 
			
		||||
    <menu-item :href="'.purge?serverId=' + serverId" code="purge">清理</menu-item>
 | 
			
		||||
    <menu-item :href="'.preheat?serverId=' + serverId" code="preheat">预热</menu-item>
 | 
			
		||||
    <menu-item :href="'.fetch?serverId=' + serverId" code="fetch">预热</menu-item>
 | 
			
		||||
</first-menu>
 | 
			
		||||
@@ -26,9 +26,10 @@
 | 
			
		||||
                    <td>
 | 
			
		||||
                        <div v-if="isRequesting">数据发送中...</div>
 | 
			
		||||
                        <span class="red" v-if="!isRequesting && !isOk && message.length > 0">失败:{{message}}</span>
 | 
			
		||||
                        <div v-if="!isRequesting && isOk">
 | 
			
		||||
                            <span v-if="results.length == 0" class="red">此集群下没有任何可用的节点。</span>
 | 
			
		||||
                            <div class="ui label tiny" v-for="one in results" :class="{green:one.isOk, red:!one.isOk}" style="margin-bottom: 0.5em">{{one.nodeName}}:{{one.message}}</div>
 | 
			
		||||
                        <div v-if="!isRequesting && !isOk && failKeys.length > 0" class="fail-keys-box">
 | 
			
		||||
                            <div v-for="failKey in failKeys">
 | 
			
		||||
                                <span class="red">{{failKey.key}}: {{failKey.reason}}</span>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </td>
 | 
			
		||||
                </tr>
 | 
			
		||||
@@ -1,31 +1,29 @@
 | 
			
		||||
Tea.context(function () {
 | 
			
		||||
	if (this.clusterId == null) {
 | 
			
		||||
		if (this.clusters.length > 0) {
 | 
			
		||||
			this.clusterId = this.clusters[0].id
 | 
			
		||||
		} else {
 | 
			
		||||
			this.clusterId = 0
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.isRequesting = false
 | 
			
		||||
	this.isOk = false
 | 
			
		||||
	this.message = ""
 | 
			
		||||
	this.results = []
 | 
			
		||||
	this.failKeys = []
 | 
			
		||||
 | 
			
		||||
	this.before = function () {
 | 
			
		||||
		this.isRequesting = true
 | 
			
		||||
		this.isOk = false
 | 
			
		||||
		this.message = ""
 | 
			
		||||
		this.results = []
 | 
			
		||||
		this.failKeys = []
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.success = function (resp) {
 | 
			
		||||
		this.isOk = true
 | 
			
		||||
		this.results = resp.data.results
 | 
			
		||||
 | 
			
		||||
		let f = NotifyReloadSuccess("任务提交成功")
 | 
			
		||||
		f()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.fail = function (resp) {
 | 
			
		||||
		this.message = resp.message
 | 
			
		||||
 | 
			
		||||
		if (resp.data.failKeys != null) {
 | 
			
		||||
			this.failKeys = resp.data.failKeys
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.done = function () {
 | 
			
		||||
@@ -18,19 +18,19 @@
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <td class="title">操作类型</td>
 | 
			
		||||
                    <td>
 | 
			
		||||
                        <radio name="type" :v-value="'key'" v-model="type">根据Key</radio>  
 | 
			
		||||
                        <radio name="type" :v-value="'prefix'" v-model="type">根据前缀</radio>
 | 
			
		||||
                        <radio name="keyType" :v-value="'key'" v-model="keyType">根据Key</radio>  
 | 
			
		||||
                        <radio name="keyType" :v-value="'prefix'" v-model="keyType">根据前缀</radio>
 | 
			
		||||
                    </td>
 | 
			
		||||
                </tr>
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <td>
 | 
			
		||||
                        <span v-if="type == 'key'">Key列表</span>
 | 
			
		||||
                        <span v-if="type == 'prefix'">Key前缀列表</span>
 | 
			
		||||
                        <span v-if="keyType == 'key'">Key列表</span>
 | 
			
		||||
                        <span v-if="keyType == 'prefix'">Key前缀列表</span>
 | 
			
		||||
                    </td>
 | 
			
		||||
                    <td>
 | 
			
		||||
                        <textarea name="keys" rows="10" ref="focus"></textarea>
 | 
			
		||||
                        <p class="comment" v-if="type == 'key'">每行一个Key,比如是一个完整的URL<code-label>https://example.com/hello/world.html</code-label>。</p>
 | 
			
		||||
                        <p class="comment" v-if="type == 'prefix'">每行一个Key前缀,比如是一个URL前缀<code-label>https://example.com/hello/</code-label>。</p>
 | 
			
		||||
                        <textarea name="keys" rows="10" ref="keysBox"></textarea>
 | 
			
		||||
                        <p class="comment" v-if="keyType == 'key'">每行一个Key,比如是一个完整的URL<code-label>https://example.com/hello/world.html</code-label>。</p>
 | 
			
		||||
                        <p class="comment" v-if="keyType == 'prefix'">每行一个Key前缀,比如是一个URL前缀<code-label>https://example.com/hello/</code-label>。</p>
 | 
			
		||||
                    </td>
 | 
			
		||||
                </tr>
 | 
			
		||||
                <tr>
 | 
			
		||||
@@ -38,9 +38,10 @@
 | 
			
		||||
                    <td>
 | 
			
		||||
                        <div v-if="isRequesting">数据发送中...</div>
 | 
			
		||||
                        <span class="red" v-if="!isRequesting && !isOk && message.length > 0">失败:{{message}}</span>
 | 
			
		||||
                        <div v-if="!isRequesting && isOk">
 | 
			
		||||
                            <span v-if="results.length == 0" class="red">此集群下没有任何可用的节点。</span>
 | 
			
		||||
                            <div class="ui label tiny" v-for="one in results" :class="{green:one.isOk, red:!one.isOk}" style="margin-bottom: 0.5em">{{one.nodeName}}:{{one.message}}</div>
 | 
			
		||||
                        <div v-if="!isRequesting && !isOk && failKeys.length > 0" class="fail-keys-box">
 | 
			
		||||
                            <div v-for="failKey in failKeys">
 | 
			
		||||
                                <span class="red">{{failKey.key}}: {{failKey.reason}}</span>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </td>
 | 
			
		||||
                </tr>
 | 
			
		||||
 
 | 
			
		||||
@@ -2,22 +2,34 @@ Tea.context(function () {
 | 
			
		||||
	this.isRequesting = false
 | 
			
		||||
	this.isOk = false
 | 
			
		||||
	this.message = ""
 | 
			
		||||
	this.results = []
 | 
			
		||||
	this.failKeys = []
 | 
			
		||||
 | 
			
		||||
	this.$delay(function () {
 | 
			
		||||
		this.$refs.keysBox.focus()
 | 
			
		||||
		this.$watch("keyType", function () {
 | 
			
		||||
			this.$refs.keysBox.focus()
 | 
			
		||||
		})
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	this.before = function () {
 | 
			
		||||
		this.isRequesting = true
 | 
			
		||||
		this.isOk = false
 | 
			
		||||
		this.message = ""
 | 
			
		||||
		this.results = []
 | 
			
		||||
		this.failKeys = []
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.success = function (resp) {
 | 
			
		||||
	this.success = function () {
 | 
			
		||||
		this.isOk = true
 | 
			
		||||
		this.results = resp.data.results
 | 
			
		||||
		let f = NotifyReloadSuccess("任务提交成功")
 | 
			
		||||
		f()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.fail = function (resp) {
 | 
			
		||||
		this.message = resp.message
 | 
			
		||||
 | 
			
		||||
		if (resp.data.failKeys != null) {
 | 
			
		||||
			this.failKeys = resp.data.failKeys
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.done = function () {
 | 
			
		||||
@@ -27,5 +39,5 @@ Tea.context(function () {
 | 
			
		||||
	/**
 | 
			
		||||
	 * 操作类型
 | 
			
		||||
	 */
 | 
			
		||||
	this.type = "key" // key | prefix
 | 
			
		||||
	this.keyType = "key" // key | prefix
 | 
			
		||||
})
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
<first-menu>
 | 
			
		||||
    <menu-item :href="'.?serverId=' + serverId" code="index">设置</menu-item>
 | 
			
		||||
    <menu-item :href="'.purge?serverId=' + serverId" code="purge">清理</menu-item>
 | 
			
		||||
    <menu-item :href="'.preheat?serverId=' + serverId" code="preheat">预热</menu-item>
 | 
			
		||||
    <menu-item :href="'.fetch?serverId=' + serverId" code="fetch">预热</menu-item>
 | 
			
		||||
</first-menu>
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
 | 
			
		||||
    <div class="margin"></div>
 | 
			
		||||
    <div v-show="webConfig.cache == null || !webConfig.cache.isOn">
 | 
			
		||||
        <p class="comment">没有开启缓存,不需要清理。</p>
 | 
			
		||||
        <p class="comment">没有开启缓存,暂时无法预热缓存。</p>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div v-show="webConfig.cache != null && webConfig.cache.isOn">
 | 
			
		||||
        <p class="comment">可以在这里批量预热一组Key。</p>
 | 
			
		||||
@@ -27,9 +27,10 @@
 | 
			
		||||
                    <td>
 | 
			
		||||
                        <div v-if="isRequesting">数据发送中...</div>
 | 
			
		||||
                        <span class="red" v-if="!isRequesting && !isOk && message.length > 0">失败:{{message}}</span>
 | 
			
		||||
                        <div v-if="!isRequesting && isOk">
 | 
			
		||||
                            <span v-if="results.length == 0" class="red">此集群下没有任何可用的节点。</span>
 | 
			
		||||
                            <div class="ui label tiny" v-for="one in results" :class="{green:one.isOk, red:!one.isOk}" style="margin-bottom: 0.5em">{{one.nodeName}}:{{one.message}}</div>
 | 
			
		||||
                        <div v-if="!isRequesting && !isOk && failKeys.length > 0" class="fail-keys-box">
 | 
			
		||||
                            <div v-for="failKey in failKeys">
 | 
			
		||||
                                <span class="red">{{failKey.key}}: {{failKey.reason}}</span>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </td>
 | 
			
		||||
                </tr>
 | 
			
		||||
							
								
								
									
										32
									
								
								web/views/@default/servers/server/settings/cache/fetch.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								web/views/@default/servers/server/settings/cache/fetch.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
			
		||||
Tea.context(function () {
 | 
			
		||||
	this.isRequesting = false
 | 
			
		||||
	this.isOk = false
 | 
			
		||||
	this.message = ""
 | 
			
		||||
	this.failKeys = []
 | 
			
		||||
 | 
			
		||||
	this.before = function () {
 | 
			
		||||
		this.isRequesting = true
 | 
			
		||||
		this.isOk = false
 | 
			
		||||
		this.message = ""
 | 
			
		||||
		this.failKeys = []
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.success = function (resp) {
 | 
			
		||||
		this.isOk = true
 | 
			
		||||
 | 
			
		||||
		let f = NotifyReloadSuccess("任务提交成功")
 | 
			
		||||
		f()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.fail = function (resp) {
 | 
			
		||||
		this.message = resp.message
 | 
			
		||||
 | 
			
		||||
		if (resp.data.failKeys != null) {
 | 
			
		||||
			this.failKeys = resp.data.failKeys
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.done = function () {
 | 
			
		||||
		this.isRequesting = false
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
@@ -19,19 +19,19 @@
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <td class="title">操作类型</td>
 | 
			
		||||
                    <td>
 | 
			
		||||
                        <radio name="type" :v-value="'key'" v-model="type">根据Key</radio>  
 | 
			
		||||
                        <radio name="type" :v-value="'prefix'" v-model="type">根据前缀</radio>
 | 
			
		||||
                        <radio name="keyType" :v-value="'key'" v-model="keyType">根据Key</radio>  
 | 
			
		||||
                        <radio name="keyType" :v-value="'prefix'" v-model="keyType">根据前缀</radio>
 | 
			
		||||
                    </td>
 | 
			
		||||
                </tr>
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <td>
 | 
			
		||||
                        <span v-if="type == 'key'">Key列表</span>
 | 
			
		||||
                        <span v-if="type == 'prefix'">Key前缀列表</span>
 | 
			
		||||
                        <span v-if="keyType == 'key'">Key列表</span>
 | 
			
		||||
                        <span v-if="keyType == 'prefix'">Key前缀列表</span>
 | 
			
		||||
                    </td>
 | 
			
		||||
                    <td>
 | 
			
		||||
                        <textarea name="keys" rows="10" ref="focus"></textarea>
 | 
			
		||||
                        <p class="comment" v-if="type == 'key'">每行一个Key,比如是一个完整的URL<code-label>https://example.com/hello/world.html</code-label>。</p>
 | 
			
		||||
                        <p class="comment" v-if="type == 'prefix'">每行一个Key前缀,比如是一个URL前缀<code-label>https://example.com/hello/</code-label>。</p>
 | 
			
		||||
                        <textarea name="keys" rows="10" ref="keysBox"></textarea>
 | 
			
		||||
                        <p class="comment" v-if="keyType == 'key'">每行一个Key,比如是一个完整的URL<code-label>https://example.com/hello/world.html</code-label>。</p>
 | 
			
		||||
                        <p class="comment" v-if="keyType == 'prefix'">每行一个Key前缀,比如是一个URL前缀<code-label>https://example.com/hello/</code-label>。</p>
 | 
			
		||||
                    </td>
 | 
			
		||||
                </tr>
 | 
			
		||||
                <tr>
 | 
			
		||||
@@ -39,9 +39,10 @@
 | 
			
		||||
                    <td>
 | 
			
		||||
                        <div v-if="isRequesting">数据发送中...</div>
 | 
			
		||||
                        <span class="red" v-if="!isRequesting && !isOk && message.length > 0">失败:{{message}}</span>
 | 
			
		||||
                        <div v-if="!isRequesting && isOk">
 | 
			
		||||
                            <span v-if="results.length == 0" class="red">此集群下没有任何可用的节点。</span>
 | 
			
		||||
                            <div class="ui label tiny" v-for="one in results" :class="{green:one.isOk, red:!one.isOk}" style="margin-bottom: 0.5em">{{one.nodeName}}:{{one.message}}</div>
 | 
			
		||||
                        <div v-if="!isRequesting && !isOk && failKeys.length > 0" class="fail-keys-box">
 | 
			
		||||
                            <div v-for="failKey in failKeys">
 | 
			
		||||
                                <span class="red">{{failKey.key}}: {{failKey.reason}}</span>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </td>
 | 
			
		||||
                </tr>
 | 
			
		||||
 
 | 
			
		||||
@@ -2,22 +2,34 @@ Tea.context(function () {
 | 
			
		||||
	this.isRequesting = false
 | 
			
		||||
	this.isOk = false
 | 
			
		||||
	this.message = ""
 | 
			
		||||
	this.results = []
 | 
			
		||||
	this.failKeys = []
 | 
			
		||||
 | 
			
		||||
	this.$delay(function () {
 | 
			
		||||
		this.$refs.keysBox.focus()
 | 
			
		||||
		this.$watch("keyType", function () {
 | 
			
		||||
			this.$refs.keysBox.focus()
 | 
			
		||||
		})
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	this.before = function () {
 | 
			
		||||
		this.isRequesting = true
 | 
			
		||||
		this.isOk = false
 | 
			
		||||
		this.message = ""
 | 
			
		||||
		this.results = []
 | 
			
		||||
		this.failKeys = []
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.success = function (resp) {
 | 
			
		||||
	this.success = function () {
 | 
			
		||||
		this.isOk = true
 | 
			
		||||
		this.results = resp.data.results
 | 
			
		||||
		let f = NotifyReloadSuccess("任务提交成功")
 | 
			
		||||
		f()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.fail = function (resp) {
 | 
			
		||||
		this.message = resp.message
 | 
			
		||||
 | 
			
		||||
		if (resp.data.failKeys != null) {
 | 
			
		||||
			this.failKeys = resp.data.failKeys
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.done = function () {
 | 
			
		||||
@@ -27,5 +39,5 @@ Tea.context(function () {
 | 
			
		||||
	/**
 | 
			
		||||
	 * 操作类型
 | 
			
		||||
	 */
 | 
			
		||||
	this.type = "key" // key | prefix
 | 
			
		||||
	this.keyType = "key" // key | prefix
 | 
			
		||||
})
 | 
			
		||||
@@ -56,7 +56,7 @@
 | 
			
		||||
                    <td class="title">已绑定的域名</td>
 | 
			
		||||
                    <td>
 | 
			
		||||
                        <server-name-box :v-server-names="serverNames"></server-name-box>
 | 
			
		||||
                        <p class="comment">终端用户可以通过这些域名访问当前网站服务。</p>
 | 
			
		||||
                        <p class="comment">用户可以通过这些域名访问当前网站服务。</p>
 | 
			
		||||
                    </td>
 | 
			
		||||
                </tr>
 | 
			
		||||
            </table>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user