mirror of
https://github.com/TeaOSLab/EdgeAdmin.git
synced 2025-11-02 03:40:27 +08:00
实现缓存策略部分管理功能
This commit is contained in:
56
internal/errors/error.go
Normal file
56
internal/errors/error.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package errors
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type errorObj struct {
|
||||
err error
|
||||
file string
|
||||
line int
|
||||
funcName string
|
||||
}
|
||||
|
||||
func (this *errorObj) Error() string {
|
||||
s := this.err.Error() + "\n " + this.file
|
||||
if len(this.funcName) > 0 {
|
||||
s += ":" + this.funcName + "()"
|
||||
}
|
||||
s += ":" + strconv.Itoa(this.line)
|
||||
return s
|
||||
}
|
||||
|
||||
// 新错误
|
||||
func New(errText string) error {
|
||||
ptr, file, line, ok := runtime.Caller(1)
|
||||
funcName := ""
|
||||
if ok {
|
||||
frame, _ := runtime.CallersFrames([]uintptr{ptr}).Next()
|
||||
funcName = filepath.Base(frame.Function)
|
||||
}
|
||||
return &errorObj{
|
||||
err: errors.New(errText),
|
||||
file: file,
|
||||
line: line,
|
||||
funcName: funcName,
|
||||
}
|
||||
}
|
||||
|
||||
// 包装已有错误
|
||||
func Wrap(err error) error {
|
||||
ptr, file, line, ok := runtime.Caller(1)
|
||||
funcName := ""
|
||||
if ok {
|
||||
frame, _ := runtime.CallersFrames([]uintptr{ptr}).Next()
|
||||
funcName = filepath.Base(frame.Function)
|
||||
}
|
||||
return &errorObj{
|
||||
err: err,
|
||||
file: file,
|
||||
line: line,
|
||||
funcName: funcName,
|
||||
}
|
||||
}
|
||||
22
internal/errors/error_test.go
Normal file
22
internal/errors/error_test.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package errors
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNew(t *testing.T) {
|
||||
t.Log(New("hello"))
|
||||
t.Log(Wrap(errors.New("hello")))
|
||||
t.Log(testError1())
|
||||
t.Log(Wrap(testError1()))
|
||||
t.Log(Wrap(testError2()))
|
||||
}
|
||||
|
||||
func testError1() error {
|
||||
return New("test error1")
|
||||
}
|
||||
|
||||
func testError2() error {
|
||||
return Wrap(testError1())
|
||||
}
|
||||
@@ -134,6 +134,10 @@ func (this *RPCClient) SSLPolicyRPC() pb.SSLPolicyServiceClient {
|
||||
return pb.NewSSLPolicyServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) SysSettingRPC() pb.SysSettingServiceClient {
|
||||
return pb.NewSysSettingServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
// 构造上下文
|
||||
func (this *RPCClient) Context(adminId int64) context.Context {
|
||||
ctx := context.Background()
|
||||
|
||||
@@ -2,8 +2,8 @@ package clusters
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/rpc"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"github.com/iwind/TeaGo/logs"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
@@ -48,9 +48,13 @@ func (this *ClusterHelper) BeforeAction(action *actions.ActionObject) {
|
||||
}
|
||||
|
||||
tabbar := actionutils.NewTabbar()
|
||||
tabbar.Add("当前集群:"+cluster.Name, "", "/clusters", "left long alternate arrow", false)
|
||||
tabbar.Add("集群列表", "", "/clusters", "", false)
|
||||
tabbar.Add("节点", "", "/clusters/cluster?clusterId="+clusterIdString, "server", selectedTabbar == "node")
|
||||
tabbar.Add("设置", "", "/clusters/cluster/settings?clusterId="+clusterIdString, "setting", selectedTabbar == "setting")
|
||||
{
|
||||
m := tabbar.Add("当前集群:"+cluster.Name, "", "/clusters/cluster?clusterId="+clusterIdString, "", false)
|
||||
m["right"] = true
|
||||
}
|
||||
actionutils.SetTabbar(action, tabbar)
|
||||
|
||||
// 左侧菜单
|
||||
|
||||
15
internal/web/actions/default/servers/components/cache/clean.go
vendored
Normal file
15
internal/web/actions/default/servers/components/cache/clean.go
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
package cache
|
||||
|
||||
import "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
|
||||
type CleanAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *CleanAction) Init() {
|
||||
this.Nav("", "", "")
|
||||
}
|
||||
|
||||
func (this *CleanAction) RunGet(params struct{}) {
|
||||
this.Show()
|
||||
}
|
||||
82
internal/web/actions/default/servers/components/cache/createPopup.go
vendored
Normal file
82
internal/web/actions/default/servers/components/cache/createPopup.go
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
)
|
||||
|
||||
type CreatePopupAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *CreatePopupAction) Init() {
|
||||
this.Nav("", "", "")
|
||||
}
|
||||
|
||||
func (this *CreatePopupAction) RunGet(params struct{}) {
|
||||
this.Data["types"] = serverconfigs.AllCachePolicyTypes
|
||||
this.Show()
|
||||
}
|
||||
|
||||
func (this *CreatePopupAction) RunPost(params struct {
|
||||
Name string
|
||||
Type string
|
||||
|
||||
// file
|
||||
FileDir string
|
||||
|
||||
CapacityJSON []byte
|
||||
MaxSizeJSON []byte
|
||||
MaxKeys int64
|
||||
|
||||
Description string
|
||||
IsOn bool
|
||||
|
||||
Must *actions.Must
|
||||
}) {
|
||||
params.Must.
|
||||
Field("name", params.Name).
|
||||
Require("请输入策略名称")
|
||||
|
||||
// 校验选项
|
||||
var options interface{}
|
||||
switch params.Type {
|
||||
case serverconfigs.CachePolicyTypeFile:
|
||||
params.Must.
|
||||
Field("fileDir", params.FileDir).
|
||||
Require("请输入缓存目录")
|
||||
options = &serverconfigs.HTTPFileCacheConfig{
|
||||
Dir: params.FileDir,
|
||||
}
|
||||
case serverconfigs.CachePolicyTypeMemory:
|
||||
options = &serverconfigs.HTTPMemoryCacheConfig{
|
||||
}
|
||||
default:
|
||||
this.Fail("请选择正确的缓存类型")
|
||||
}
|
||||
|
||||
optionsJSON, err := json.Marshal(options)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
_, err = this.RPC().HTTPCachePolicyRPC().CreateHTTPCachePolicy(this.AdminContext(), &pb.CreateHTTPCachePolicyRequest{
|
||||
IsOn: params.IsOn,
|
||||
Name: params.Name,
|
||||
Description: params.Description,
|
||||
CapacityJSON: params.CapacityJSON,
|
||||
MaxKeys: params.MaxKeys,
|
||||
MaxSizeJSON: params.MaxSizeJSON,
|
||||
Type: params.Type,
|
||||
OptionsJSON: optionsJSON,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Success()
|
||||
}
|
||||
32
internal/web/actions/default/servers/components/cache/delete.go
vendored
Normal file
32
internal/web/actions/default/servers/components/cache/delete.go
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
)
|
||||
|
||||
type DeleteAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *DeleteAction) RunPost(params struct {
|
||||
CachePolicyId int64
|
||||
}) {
|
||||
// 检查是否被引用
|
||||
countResp, err := this.RPC().ServerRPC().CountAllEnabledServersWithCachePolicyId(this.AdminContext(), &pb.CountAllEnabledServersWithCachePolicyIdRequest{CachePolicyId: params.CachePolicyId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
if countResp.Count > 0 {
|
||||
this.Fail("此缓存策略正在被别的服务引用,请修改后再删除。")
|
||||
}
|
||||
|
||||
_, err = this.RPC().HTTPCachePolicyRPC().DeleteHTTPCachePolicy(this.AdminContext(), &pb.DeleteHTTPCachePolicyRequest{CachePolicyId: params.CachePolicyId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Success()
|
||||
}
|
||||
@@ -1,7 +1,11 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
type IndexAction struct {
|
||||
@@ -13,6 +17,47 @@ func (this *IndexAction) Init() {
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunGet(params struct{}) {
|
||||
countResp, err := this.RPC().HTTPCachePolicyRPC().CountAllEnabledHTTPCachePolicies(this.AdminContext(), &pb.CountAllEnabledHTTPCachePoliciesRequest{})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
count := countResp.Count
|
||||
page := this.NewPage(count)
|
||||
this.Data["page"] = page.AsHTML()
|
||||
|
||||
listResp, err := this.RPC().HTTPCachePolicyRPC().ListEnabledHTTPCachePolicies(this.AdminContext(), &pb.ListEnabledHTTPCachePoliciesRequest{
|
||||
Offset: page.Offset,
|
||||
Size: page.Size,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
cachePoliciesJSON := listResp.CachePoliciesJSON
|
||||
cachePolicies := []*serverconfigs.HTTPCachePolicy{}
|
||||
err = json.Unmarshal(cachePoliciesJSON, &cachePolicies)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
this.Data["cachePolicies"] = cachePolicies
|
||||
|
||||
infos := []maps.Map{}
|
||||
for _, cachePolicy := range cachePolicies {
|
||||
countServersResp, err := this.RPC().ServerRPC().CountAllEnabledServersWithCachePolicyId(this.AdminContext(), &pb.CountAllEnabledServersWithCachePolicyIdRequest{CachePolicyId: cachePolicy.Id})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
countServers := countServersResp.Count
|
||||
|
||||
infos = append(infos, maps.Map{
|
||||
"typeName": serverconfigs.FindCachePolicyTypeName(cachePolicy.Type),
|
||||
"countServers": countServers,
|
||||
})
|
||||
}
|
||||
this.Data["infos"] = infos
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
@@ -14,6 +14,15 @@ func init() {
|
||||
Helper(componentutils.NewComponentHelper()).
|
||||
Prefix("/servers/components/cache").
|
||||
Get("", new(IndexAction)).
|
||||
GetPost("/createPopup", new(CreatePopupAction)).
|
||||
Get("/policy", new(PolicyAction)).
|
||||
GetPost("/updatePopup", new(UpdatePopupAction)).
|
||||
GetPost("/clean", new(CleanAction)).
|
||||
GetPost("/preheat", new(PreheatAction)).
|
||||
GetPost("/purge", new(PurgeAction)).
|
||||
GetPost("/stat", new(StatAction)).
|
||||
GetPost("/test", new(TestAction)).
|
||||
Post("/delete", new(DeleteAction)).
|
||||
EndAll()
|
||||
})
|
||||
}
|
||||
|
||||
15
internal/web/actions/default/servers/components/cache/policy.go
vendored
Normal file
15
internal/web/actions/default/servers/components/cache/policy.go
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
package cache
|
||||
|
||||
import "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
|
||||
type PolicyAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *PolicyAction) Init() {
|
||||
this.Nav("", "", "")
|
||||
}
|
||||
|
||||
func (this *PolicyAction) RunGet(params struct{}) {
|
||||
this.Show()
|
||||
}
|
||||
15
internal/web/actions/default/servers/components/cache/preheat.go
vendored
Normal file
15
internal/web/actions/default/servers/components/cache/preheat.go
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
package cache
|
||||
|
||||
import "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
|
||||
type PreheatAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *PreheatAction) Init() {
|
||||
this.Nav("", "", "")
|
||||
}
|
||||
|
||||
func (this *PreheatAction) RunGet(params struct{}) {
|
||||
this.Show()
|
||||
}
|
||||
15
internal/web/actions/default/servers/components/cache/purge.go
vendored
Normal file
15
internal/web/actions/default/servers/components/cache/purge.go
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
package cache
|
||||
|
||||
import "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
|
||||
type PurgeAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *PurgeAction) Init() {
|
||||
this.Nav("", "", "")
|
||||
}
|
||||
|
||||
func (this *PurgeAction) RunGet(params struct{}) {
|
||||
this.Show()
|
||||
}
|
||||
15
internal/web/actions/default/servers/components/cache/stat.go
vendored
Normal file
15
internal/web/actions/default/servers/components/cache/stat.go
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
package cache
|
||||
|
||||
import "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
|
||||
type StatAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *StatAction) Init() {
|
||||
this.Nav("", "", "")
|
||||
}
|
||||
|
||||
func (this *StatAction) RunGet(params struct{}) {
|
||||
this.Show()
|
||||
}
|
||||
15
internal/web/actions/default/servers/components/cache/test.go
vendored
Normal file
15
internal/web/actions/default/servers/components/cache/test.go
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
package cache
|
||||
|
||||
import "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
|
||||
type TestAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *TestAction) Init() {
|
||||
this.Nav("", "", "")
|
||||
}
|
||||
|
||||
func (this *TestAction) RunGet(params struct{}) {
|
||||
this.Show()
|
||||
}
|
||||
108
internal/web/actions/default/servers/components/cache/updatePopup.go
vendored
Normal file
108
internal/web/actions/default/servers/components/cache/updatePopup.go
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
)
|
||||
|
||||
type UpdatePopupAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *UpdatePopupAction) Init() {
|
||||
this.Nav("", "", "")
|
||||
}
|
||||
|
||||
func (this *UpdatePopupAction) RunGet(params struct {
|
||||
CachePolicyId int64
|
||||
}) {
|
||||
configResp, err := this.RPC().HTTPCachePolicyRPC().FindEnabledHTTPCachePolicyConfig(this.AdminContext(), &pb.FindEnabledHTTPCachePolicyConfigRequest{CachePolicyId: params.CachePolicyId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
configJSON := configResp.CachePolicyJSON
|
||||
if len(configJSON) == 0 {
|
||||
this.NotFound("cachePolicy", params.CachePolicyId)
|
||||
return
|
||||
}
|
||||
|
||||
cachePolicy := &serverconfigs.HTTPCachePolicy{}
|
||||
err = json.Unmarshal(configJSON, cachePolicy)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
this.Data["cachePolicy"] = cachePolicy
|
||||
|
||||
// 其他选项
|
||||
this.Data["types"] = serverconfigs.AllCachePolicyTypes
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
func (this *UpdatePopupAction) RunPost(params struct {
|
||||
CachePolicyId int64
|
||||
|
||||
Name string
|
||||
Type string
|
||||
|
||||
// file
|
||||
FileDir string
|
||||
|
||||
CapacityJSON []byte
|
||||
MaxSizeJSON []byte
|
||||
MaxKeys int64
|
||||
|
||||
Description string
|
||||
IsOn bool
|
||||
|
||||
Must *actions.Must
|
||||
}) {
|
||||
params.Must.
|
||||
Field("name", params.Name).
|
||||
Require("请输入策略名称")
|
||||
|
||||
// 校验选项
|
||||
var options interface{}
|
||||
switch params.Type {
|
||||
case serverconfigs.CachePolicyTypeFile:
|
||||
params.Must.
|
||||
Field("fileDir", params.FileDir).
|
||||
Require("请输入缓存目录")
|
||||
options = &serverconfigs.HTTPFileCacheConfig{
|
||||
Dir: params.FileDir,
|
||||
}
|
||||
case serverconfigs.CachePolicyTypeMemory:
|
||||
options = &serverconfigs.HTTPMemoryCacheConfig{
|
||||
}
|
||||
default:
|
||||
this.Fail("请选择正确的缓存类型")
|
||||
}
|
||||
|
||||
optionsJSON, err := json.Marshal(options)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
_, err = this.RPC().HTTPCachePolicyRPC().UpdateHTTPCachePolicy(this.AdminContext(), &pb.UpdateHTTPCachePolicyRequest{
|
||||
CachePolicyId: params.CachePolicyId,
|
||||
IsOn: params.IsOn,
|
||||
Name: params.Name,
|
||||
Description: params.Description,
|
||||
CapacityJSON: params.CapacityJSON,
|
||||
MaxKeys: params.MaxKeys,
|
||||
MaxSizeJSON: params.MaxSizeJSON,
|
||||
Type: params.Type,
|
||||
OptionsJSON: optionsJSON,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Success()
|
||||
}
|
||||
@@ -25,7 +25,7 @@ func (this *ComponentHelper) BeforeAction(action *actions.ActionObject) {
|
||||
selectedTabbar := action.Data.GetString("mainTab")
|
||||
tabbar := actionutils.NewTabbar()
|
||||
tabbar.Add("服务", "", "/servers", "", selectedTabbar == "server")
|
||||
tabbar.Add("组件", "", "/servers/components", "", selectedTabbar == "component")
|
||||
tabbar.Add("通用", "", "/servers/components", "", selectedTabbar == "component")
|
||||
actionutils.SetTabbar(action, tabbar)
|
||||
|
||||
// 创建左侧菜单
|
||||
@@ -39,11 +39,11 @@ func (this *ComponentHelper) createLeftMenus(secondMenuItem string) (items []map
|
||||
"url": "/servers/components",
|
||||
"isActive": secondMenuItem == "global",
|
||||
})
|
||||
items = append(items, maps.Map{
|
||||
/**items = append(items, maps.Map{
|
||||
"name": "分组设置",
|
||||
"url": "/servers/components/group",
|
||||
"isActive": secondMenuItem == "group",
|
||||
})
|
||||
})**/
|
||||
items = append(items, maps.Map{
|
||||
"name": "缓存策略",
|
||||
"url": "/servers/components/cache",
|
||||
|
||||
@@ -19,6 +19,6 @@ func (this *Helper) BeforeAction(action *actions.ActionObject) {
|
||||
|
||||
tabbar := actionutils.NewTabbar()
|
||||
tabbar.Add("服务", "", "/servers", "", selectedTabbar == "server")
|
||||
tabbar.Add("组件", "", "/servers/components", "", selectedTabbar == "component")
|
||||
tabbar.Add("通用", "", "/servers/components", "", selectedTabbar == "component")
|
||||
actionutils.SetTabbar(action, tabbar)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
package components
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
)
|
||||
|
||||
const (
|
||||
SettingCodeGlobalConfig = "globalConfig"
|
||||
)
|
||||
|
||||
type IndexAction struct {
|
||||
@@ -14,6 +22,48 @@ func (this *IndexAction) Init() {
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunGet(params struct{}) {
|
||||
valueJSONResp, err := this.RPC().SysSettingRPC().ReadSysSetting(this.AdminContext(), &pb.ReadSysSettingRequest{Code: SettingCodeGlobalConfig})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
valueJSON := valueJSONResp.ValueJSON
|
||||
globalConfig := &serverconfigs.GlobalConfig{}
|
||||
if len(valueJSON) > 0 {
|
||||
err = json.Unmarshal(valueJSON, globalConfig)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
this.Data["globalConfig"] = globalConfig
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunPost(params struct {
|
||||
GlobalConfigJSON []byte
|
||||
Must *actions.Must
|
||||
}) {
|
||||
if len(params.GlobalConfigJSON) == 0 {
|
||||
this.Fail("错误的配置信息,请刷新当前页面后重试")
|
||||
}
|
||||
|
||||
globalConfig := &serverconfigs.GlobalConfig{}
|
||||
err := json.Unmarshal(params.GlobalConfigJSON, globalConfig)
|
||||
if err != nil {
|
||||
this.Fail("配置校验失败:" + err.Error())
|
||||
}
|
||||
|
||||
// 修改配置
|
||||
_, err = this.RPC().SysSettingRPC().UpdateSysSetting(this.AdminContext(), &pb.UpdateSysSettingRequest{
|
||||
Code: SettingCodeGlobalConfig,
|
||||
ValueJSON: params.GlobalConfigJSON,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Success()
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ func init() {
|
||||
Helper(NewHelper()).
|
||||
Helper(componentutils.NewComponentHelper()).
|
||||
Prefix("/servers/components").
|
||||
Get("", new(IndexAction)).
|
||||
GetPost("", new(IndexAction)).
|
||||
EndAll()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ func (this *CertPopupAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
// 引入的服务
|
||||
serversResp, err := this.RPC().ServerRPC().FindAllServersWithSSLCertId(this.AdminContext(), &pb.FindAllServersWithSSLCertIdRequest{CertId: params.CertId})
|
||||
serversResp, err := this.RPC().ServerRPC().FindAllEnabledServersWithSSLCertId(this.AdminContext(), &pb.FindAllEnabledServersWithSSLCertIdRequest{CertId: params.CertId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
|
||||
@@ -13,7 +13,7 @@ func (this *DeleteAction) RunPost(params struct {
|
||||
CertId int64
|
||||
}) {
|
||||
// 是否正在被使用
|
||||
countResp, err := this.RPC().ServerRPC().CountServersWithSSLCertId(this.AdminContext(), &pb.CountServersWithSSLCertIdRequest{CertId: params.CertId})
|
||||
countResp, err := this.RPC().ServerRPC().CountAllEnabledServersWithSSLCertId(this.AdminContext(), &pb.CountAllEnabledServersWithSSLCertIdRequest{CertId: params.CertId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
|
||||
@@ -141,13 +141,14 @@ func (this *IndexAction) RunGet(params struct {
|
||||
certMaps := []maps.Map{}
|
||||
nowTime := time.Now().Unix()
|
||||
for _, certConfig := range certConfigs {
|
||||
countServersResp, err := this.RPC().ServerRPC().CountServersWithSSLCertId(this.AdminContext(), &pb.CountServersWithSSLCertIdRequest{CertId: certConfig.Id})
|
||||
countServersResp, err := this.RPC().ServerRPC().CountAllEnabledServersWithSSLCertId(this.AdminContext(), &pb.CountAllEnabledServersWithSSLCertIdRequest{CertId: certConfig.Id})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
certMaps = append(certMaps, maps.Map{
|
||||
"isOn": certConfig.IsOn,
|
||||
"beginDay": timeutil.FormatTime("Y-m-d", certConfig.TimeBeginAt),
|
||||
"endDay": timeutil.FormatTime("Y-m-d", certConfig.TimeEndAt),
|
||||
"isExpired": nowTime > certConfig.TimeEndAt,
|
||||
|
||||
@@ -48,7 +48,7 @@ func (this *SelectPopupAction) RunGet(params struct{}) {
|
||||
certMaps := []maps.Map{}
|
||||
nowTime := time.Now().Unix()
|
||||
for _, certConfig := range certConfigs {
|
||||
countServersResp, err := this.RPC().ServerRPC().CountServersWithSSLCertId(this.AdminContext(), &pb.CountServersWithSSLCertIdRequest{CertId: certConfig.Id})
|
||||
countServersResp, err := this.RPC().ServerRPC().CountAllEnabledServersWithSSLCertId(this.AdminContext(), &pb.CountAllEnabledServersWithSSLCertIdRequest{CertId: certConfig.Id})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
package ssl
|
||||
|
||||
import "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
)
|
||||
|
||||
type UpdatePopupAction struct {
|
||||
actionutils.ParentAction
|
||||
@@ -10,6 +16,114 @@ func (this *UpdatePopupAction) Init() {
|
||||
this.Nav("", "", "")
|
||||
}
|
||||
|
||||
func (this *UpdatePopupAction) RunGet(params struct{}) {
|
||||
func (this *UpdatePopupAction) RunGet(params struct {
|
||||
CertId int64
|
||||
}) {
|
||||
certConfigResp, err := this.RPC().SSLCertRPC().FindEnabledSSLCertConfig(this.AdminContext(), &pb.FindEnabledSSLCertConfigRequest{CertId: params.CertId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
certConfigJSON := certConfigResp.CertJSON
|
||||
if len(certConfigJSON) == 0 {
|
||||
this.NotFound("cert", params.CertId)
|
||||
return
|
||||
}
|
||||
|
||||
certConfig := &sslconfigs.SSLCertConfig{}
|
||||
err = json.Unmarshal(certConfigJSON, certConfig)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
this.Data["certConfig"] = certConfig
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
func (this *UpdatePopupAction) RunPost(params struct {
|
||||
CertId int64
|
||||
|
||||
Name string
|
||||
IsCA bool
|
||||
Description string
|
||||
IsOn bool
|
||||
|
||||
CertFile *actions.File
|
||||
KeyFile *actions.File
|
||||
|
||||
Must *actions.Must
|
||||
}) {
|
||||
// 查询Cert
|
||||
certConfigResp, err := this.RPC().SSLCertRPC().FindEnabledSSLCertConfig(this.AdminContext(), &pb.FindEnabledSSLCertConfigRequest{CertId: params.CertId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
certConfigJSON := certConfigResp.CertJSON
|
||||
if len(certConfigJSON) == 0 {
|
||||
this.NotFound("cert", params.CertId)
|
||||
return
|
||||
}
|
||||
|
||||
certConfig := &sslconfigs.SSLCertConfig{}
|
||||
err = json.Unmarshal(certConfigJSON, certConfig)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
// 校验参数
|
||||
params.Must.
|
||||
Field("name", params.Name).
|
||||
Require("请输入证书说明")
|
||||
|
||||
if params.CertFile != nil {
|
||||
certConfig.CertData, err = params.CertFile.Read()
|
||||
if err != nil {
|
||||
this.Fail("读取证书文件内容错误,请重新上传")
|
||||
}
|
||||
}
|
||||
|
||||
if !params.IsCA {
|
||||
if params.KeyFile != nil {
|
||||
certConfig.KeyData, err = params.KeyFile.Read()
|
||||
if err != nil {
|
||||
this.Fail("读取密钥文件内容错误,请重新上传")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 校验
|
||||
certConfig.IsCA = params.IsCA
|
||||
err = certConfig.Init()
|
||||
if err != nil {
|
||||
if params.IsCA {
|
||||
this.Fail("证书校验错误:" + err.Error())
|
||||
} else {
|
||||
this.Fail("证书或密钥校验错误:" + err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// 保存
|
||||
_, err = this.RPC().SSLCertRPC().UpdateSSLCert(this.AdminContext(), &pb.UpdateSSLCertRequest{
|
||||
CertId: params.CertId,
|
||||
IsOn: params.IsOn,
|
||||
Name: params.Name,
|
||||
Description: params.Description,
|
||||
ServerName: "",
|
||||
IsCA: params.IsCA,
|
||||
CertData: certConfig.CertData,
|
||||
KeyData: certConfig.KeyData,
|
||||
TimeBeginAt: certConfig.TimeBeginAt,
|
||||
TimeEndAt: certConfig.TimeEndAt,
|
||||
DnsNames: certConfig.DNSNames,
|
||||
CommonNames: certConfig.CommonNames,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Success()
|
||||
}
|
||||
|
||||
@@ -19,6 +19,6 @@ func (this *Helper) BeforeAction(action *actions.ActionObject) {
|
||||
|
||||
tabbar := actionutils.NewTabbar()
|
||||
tabbar.Add("服务", "", "/servers", "", selectedTabbar == "server")
|
||||
tabbar.Add("组件", "", "/servers/components", "", selectedTabbar == "component")
|
||||
tabbar.Add("通用", "", "/servers/components", "", selectedTabbar == "component")
|
||||
actionutils.SetTabbar(action, tabbar)
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
this.Data["webId"] = webConfig.Id
|
||||
this.Data["cacheConfig"] = webConfig.CacheRef
|
||||
this.Data["cacheConfig"] = webConfig.CacheRefs
|
||||
|
||||
// 所有缓存策略
|
||||
cachePoliciesResp, err := this.RPC().HTTPCachePolicyRPC().FindAllEnabledHTTPCachePolicies(this.AdminContext(), &pb.FindAllEnabledHTTPCachePoliciesRequest{})
|
||||
|
||||
@@ -25,7 +25,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
this.Data["webId"] = webConfig.Id
|
||||
this.Data["cacheConfig"] = webConfig.CacheRef
|
||||
this.Data["cacheConfig"] = webConfig.CacheRefs
|
||||
|
||||
// 所有缓存策略
|
||||
cachePoliciesResp, err := this.RPC().HTTPCachePolicyRPC().FindAllEnabledHTTPCachePolicies(this.AdminContext(), &pb.FindAllEnabledHTTPCachePoliciesRequest{})
|
||||
|
||||
@@ -100,7 +100,7 @@ func (this *LocationHelper) createMenus(serverIdString string, locationIdString
|
||||
"name": "缓存",
|
||||
"url": "/servers/server/settings/locations/cache?serverId=" + serverIdString + "&locationId=" + locationIdString,
|
||||
"isActive": secondMenuItem == "cache",
|
||||
"isOn": locationConfig != nil && locationConfig.Web != nil && locationConfig.Web.CacheRef != nil && locationConfig.Web.CacheRef.IsPrior,
|
||||
"isOn": locationConfig != nil && locationConfig.Web != nil && len(locationConfig.Web.CacheRefs) > 0,
|
||||
})
|
||||
menuItems = append(menuItems, maps.Map{
|
||||
"name": "访问控制",
|
||||
|
||||
@@ -78,12 +78,16 @@ func (this *ServerHelper) createLeftMenu(action *actions.ActionObject) {
|
||||
// TABBAR
|
||||
selectedTabbar, _ := action.Data["mainTab"]
|
||||
tabbar := actionutils.NewTabbar()
|
||||
tabbar.Add("当前服务:"+server.Name, "", "/servers", "left long alternate arrow", false)
|
||||
tabbar.Add("服务首页", "", "/servers", "", false)
|
||||
//tabbar.Add("看板", "", "/servers/server/board?serverId="+serverIdString, "dashboard", selectedTabbar == "board")
|
||||
tabbar.Add("日志", "", "/servers/server/log?serverId="+serverIdString, "history", selectedTabbar == "log")
|
||||
//tabbar.Add("统计", "", "/servers/server/stat?serverId="+serverIdString, "chart area", selectedTabbar == "stat")
|
||||
tabbar.Add("设置", "", "/servers/server/settings?serverId="+serverIdString, "setting", selectedTabbar == "setting")
|
||||
tabbar.Add("删除", "", "/servers/server/delete?serverId="+serverIdString, "trash", selectedTabbar == "delete")
|
||||
{
|
||||
m := tabbar.Add("当前服务:"+server.Name, "", "/servers/server?serverId="+serverIdString, "", false)
|
||||
m["right"] = true
|
||||
}
|
||||
|
||||
actionutils.SetTabbar(action, tabbar)
|
||||
|
||||
@@ -207,7 +211,7 @@ func (this *ServerHelper) createSettingsMenu(secondMenuItem string, serverIdStri
|
||||
"name": "缓存",
|
||||
"url": "/servers/server/settings/cache?serverId=" + serverIdString,
|
||||
"isActive": secondMenuItem == "cache",
|
||||
"isOn": serverConfig.Web != nil && serverConfig.Web.CacheRef != nil && serverConfig.Web.CacheRef.IsOn,
|
||||
"isOn": serverConfig.Web != nil && len(serverConfig.Web.CacheRefs) > 0,
|
||||
})
|
||||
menuItems = append(menuItems, maps.Map{
|
||||
"name": "访问控制",
|
||||
|
||||
47
web/public/js/components/common/time-duration-box.js
Normal file
47
web/public/js/components/common/time-duration-box.js
Normal file
@@ -0,0 +1,47 @@
|
||||
Vue.component("time-duration-box", {
|
||||
props: ["v-name", "v-value", "v-count", "v-unit"],
|
||||
data: function () {
|
||||
let v = this.vValue
|
||||
if (v == null) {
|
||||
v = {
|
||||
count: this.vCount,
|
||||
unit: this.vUnit
|
||||
}
|
||||
}
|
||||
if (typeof (v["count"]) != "number") {
|
||||
v["count"] = -1
|
||||
}
|
||||
return {
|
||||
"size": v,
|
||||
countString: (v.count >= 0) ? v.count.toString() : ""
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
"countString": function (newValue) {
|
||||
let value = newValue.trim()
|
||||
if (value.length == 0) {
|
||||
this.size.count = -1
|
||||
return
|
||||
}
|
||||
let count = parseInt(value)
|
||||
if (!isNaN(count)) {
|
||||
this.size.count = count
|
||||
}
|
||||
}
|
||||
},
|
||||
template: `<div class="ui fields inline">
|
||||
<input type="hidden" :name="vName" :value="JSON.stringify(size)"/>
|
||||
<div class="ui field">
|
||||
<input type="text" v-model="countString" maxlength="11" size="11"/>
|
||||
</div>
|
||||
<div class="ui field">
|
||||
<select class="ui dropdown" v-model="size.unit">
|
||||
<option value="ms">毫秒</option>
|
||||
<option value="second">秒</option>
|
||||
<option value="minute">分钟</option>
|
||||
<option value="hour">小时</option>
|
||||
<option value="day">天</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>`
|
||||
})
|
||||
50
web/public/js/components/server/http-cache-cond-box.js
Normal file
50
web/public/js/components/server/http-cache-cond-box.js
Normal file
@@ -0,0 +1,50 @@
|
||||
Vue.component("http-cache-cond-box", {
|
||||
template: `<div>
|
||||
<table class="ui table definition selectable">
|
||||
<tr>
|
||||
<td>匹配条件</td>
|
||||
<td><http-request-conds-box></http-request-conds-box></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>缓存有效期</td>
|
||||
<td>
|
||||
<time-duration-box :name="'lifeJSON'" :v-count="3600" :v-unit="'second'"></time-duration-box>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>状态码列表</td>
|
||||
<td>
|
||||
<values-box name="statusList" size="3" maxlength="3" :values="['200']"></values-box>
|
||||
<p class="comment">允许缓存的HTTP状态码列表。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>跳过的Cache-Control值</td>
|
||||
<td>
|
||||
<values-box name="skipResponseCacheControlValues" size="10" maxlength="100" :values="['private', 'no-cache', 'no-store']"></values-box>
|
||||
<p class="comment">当响应的Cache-Control为这些值时不缓存响应内容,而且不区分大小写。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>跳过Set-Cookie</td>
|
||||
<td>
|
||||
<div class="ui checkbox">
|
||||
<input type="checkbox" name="skipResponseSetCookie" value="1" checked="checked"/>
|
||||
<label></label>
|
||||
</div>
|
||||
<p class="comment">选中后,当响应的Header中有Set-Cookie时不缓存响应内容。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>支持请求no-cache刷新</td>
|
||||
<td>
|
||||
<div class="ui checkbox">
|
||||
<input type="checkbox" name="enableRequestCachePragma" value="1"/>
|
||||
<label></label>
|
||||
</div>
|
||||
<p class="comment">选中后,当请求的Header中含有Pragma: no-cache或Cache-Control: no-cache时,会跳过缓存直接读取源内容。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>`
|
||||
})
|
||||
@@ -68,8 +68,13 @@ Vue.component("http-gzip-box", {
|
||||
<p class="comment">0表示不限制,内容长度从文件尺寸或Content-Length中获取。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>匹配条件</td>
|
||||
<td>
|
||||
<http-request-conds-box :v-conds="gzip.conds"></http-request-conds-box>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<http-request-conds-tbody v-show="isOn() && advancedVisible" :v-conds="gzip.conds"></http-request-conds-tbody>
|
||||
</table>
|
||||
</div>`
|
||||
})
|
||||
82
web/public/js/components/server/http-request-conds-box.js
Normal file
82
web/public/js/components/server/http-request-conds-box.js
Normal file
@@ -0,0 +1,82 @@
|
||||
Vue.component("http-request-conds-box", {
|
||||
props: ["v-conds"],
|
||||
data: function () {
|
||||
let conds = this.vConds
|
||||
if (conds == null) {
|
||||
conds = {
|
||||
isOn: true,
|
||||
connector: "or",
|
||||
groups: []
|
||||
}
|
||||
}
|
||||
return {
|
||||
conds: conds,
|
||||
components: window.REQUEST_COND_COMPONENTS
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
addGroup: function () {
|
||||
let that = this
|
||||
teaweb.popup("/servers/server/settings/conds/addGroupPopup", {
|
||||
height: "30em",
|
||||
callback: function (resp) {
|
||||
that.conds.groups.push(resp.data.group)
|
||||
}
|
||||
})
|
||||
},
|
||||
updateGroup: function (groupIndex, group) {
|
||||
window.UPDATING_COND_GROUP = group
|
||||
let that = this
|
||||
teaweb.popup("/servers/server/settings/conds/addGroupPopup", {
|
||||
height: "30em",
|
||||
callback: function (resp) {
|
||||
Vue.set(that.conds.groups, groupIndex, resp.data.group)
|
||||
}
|
||||
})
|
||||
},
|
||||
removeGroup: function (groupIndex) {
|
||||
let that = this
|
||||
teaweb.confirm("确定要删除这一组条件吗?", function () {
|
||||
that.conds.groups.$remove(groupIndex)
|
||||
})
|
||||
},
|
||||
typeName: function (cond) {
|
||||
let c = this.components.$find(function (k, v) {
|
||||
return v.type == cond.type
|
||||
})
|
||||
if (c != null) {
|
||||
return c.name;
|
||||
}
|
||||
return cond.param + " " + cond.operator
|
||||
}
|
||||
},
|
||||
template: `<div>
|
||||
<input type="hidden" name="condsJSON" :value="JSON.stringify(conds)"/>
|
||||
<div v-if="conds.groups.length > 0">
|
||||
<table class="ui table">
|
||||
<tr v-for="(group, groupIndex) in conds.groups">
|
||||
<td style="background: white">
|
||||
<var v-for="(cond, index) in group.conds" style="font-style: normal;display: inline-block; margin-bottom:0.5em">
|
||||
<span class="ui label tiny">
|
||||
<var v-if="cond.type.length == 0" style="font-style: normal">{{cond.param}} <var>{{cond.operator}}</var></var>
|
||||
<var v-if="cond.type.length > 0" style="font-style: normal">{{typeName(cond)}}: </var>
|
||||
{{cond.value}}
|
||||
</span>
|
||||
|
||||
<var v-if="index < group.conds.length - 1"> {{group.connector}} </var>
|
||||
</var>
|
||||
</td>
|
||||
<td style="width: 5em; background: white">
|
||||
<a href="" title="修改" @click.prevent="updateGroup(groupIndex, group)"><i class="icon pencil small"></i></a> <a href="" title="删除" @click.prevent="removeGroup(groupIndex)"><i class="icon remove"></i></a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="ui divider"></div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button class="ui button tiny" type="button" @click.prevent="addGroup()">+</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>`
|
||||
})
|
||||
@@ -1,87 +0,0 @@
|
||||
Vue.component("http-request-conds-tbody", {
|
||||
props: ["v-conds"],
|
||||
data: function () {
|
||||
let conds = this.vConds
|
||||
if (conds == null) {
|
||||
conds = {
|
||||
isOn: true,
|
||||
connector: "or",
|
||||
groups: []
|
||||
}
|
||||
}
|
||||
return {
|
||||
conds: conds,
|
||||
components: window.REQUEST_COND_COMPONENTS
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
addGroup: function () {
|
||||
let that = this
|
||||
teaweb.popup("/servers/server/settings/conds/addGroupPopup", {
|
||||
height: "30em",
|
||||
callback: function (resp) {
|
||||
that.conds.groups.push(resp.data.group)
|
||||
}
|
||||
})
|
||||
},
|
||||
updateGroup: function (groupIndex, group) {
|
||||
window.UPDATING_COND_GROUP = group
|
||||
let that = this
|
||||
teaweb.popup("/servers/server/settings/conds/addGroupPopup", {
|
||||
height: "30em",
|
||||
callback: function (resp) {
|
||||
Vue.set(that.conds.groups, groupIndex, resp.data.group)
|
||||
}
|
||||
})
|
||||
},
|
||||
removeGroup: function (groupIndex) {
|
||||
let that = this
|
||||
teaweb.confirm("确定要删除这一组条件吗?", function () {
|
||||
that.conds.groups.$remove(groupIndex)
|
||||
})
|
||||
},
|
||||
typeName: function (cond) {
|
||||
let c = this.components.$find(function (k, v) {
|
||||
return v.type == cond.type
|
||||
})
|
||||
if (c != null) {
|
||||
return c.name;
|
||||
}
|
||||
return cond.param + " " + cond.operator
|
||||
}
|
||||
},
|
||||
template: `<tbody>
|
||||
<tr>
|
||||
<td>匹配条件</td>
|
||||
<td>
|
||||
<input type="hidden" name="condsJSON" :value="JSON.stringify(conds)"/>
|
||||
<div class="margin"></div>
|
||||
<div v-if="conds.groups.length > 0">
|
||||
<table class="ui table">
|
||||
<tr v-for="(group, groupIndex) in conds.groups">
|
||||
<td style="background: white">
|
||||
<var v-for="(cond, index) in group.conds" style="font-style: normal;display: inline-block; margin-bottom:0.5em">
|
||||
<span class="ui label tiny">
|
||||
<var v-if="cond.type.length == 0" style="font-style: normal">{{cond.param}} <var>{{cond.operator}}</var></var>
|
||||
<var v-if="cond.type.length > 0" style="font-style: normal">{{typeName(cond)}}: </var>
|
||||
{{cond.value}}
|
||||
</span>
|
||||
|
||||
<var v-if="index < group.conds.length - 1"> {{group.connector}} </var>
|
||||
</var>
|
||||
</td>
|
||||
<td style="width: 5em; background: white">
|
||||
<a href="" title="修改" @click.prevent="updateGroup(groupIndex, group)"><i class="icon pencil small"></i></a> <a href="" title="删除" @click.prevent="removeGroup(groupIndex)"><i class="icon remove"></i></a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="ui divider"></div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button class="ui button tiny" type="button" @click.prevent="addGroup()">+</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>`
|
||||
})
|
||||
@@ -207,10 +207,6 @@ label[for] {
|
||||
label.blue {
|
||||
color: #2185d0 !important;
|
||||
}
|
||||
td .label.tiny {
|
||||
padding: 2px;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
/** Menu **/
|
||||
.first-menu .menu.text {
|
||||
margin-top: 0 !important;
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"sources":["@layout_popup.less"],"names":[],"mappings":"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","file":"@layout_popup.css"}
|
||||
{"version":3,"sources":["@layout_popup.less"],"names":[],"mappings":"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","file":"@layout_popup.css"}
|
||||
@@ -251,8 +251,6 @@ label.blue {
|
||||
}
|
||||
|
||||
td .label.tiny {
|
||||
padding: 2px;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
/** Menu **/
|
||||
|
||||
74
web/views/@default/servers/components/cache/createPopup.html
vendored
Normal file
74
web/views/@default/servers/components/cache/createPopup.html
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
{$layout "layout_popup"}
|
||||
|
||||
<h3>创建缓存策略</h3>
|
||||
|
||||
<form class="ui form" data-tea-action="$" data-tea-success="success">
|
||||
<table class="ui table definition selectable">
|
||||
<tr>
|
||||
<td class="title">策略名称 *</td>
|
||||
<td><input type="text" name="name" maxlength="100" ref="focus"/> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>缓存类型 *</td>
|
||||
<td>
|
||||
<select class="ui dropdown auto-width" name="type" v-model="policyType">
|
||||
<option v-for="type in types" :value="type.type">{{type.name}}</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- 文件缓存选项 -->
|
||||
<tbody v-if="policyType == 'file'">
|
||||
<tr>
|
||||
<td>缓存目录 *</td>
|
||||
<td>
|
||||
<input type="text" name="fileDir" maxlength="500"/>
|
||||
<p class="comment">存放文件缓存的目录,通常填写绝对路径。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
|
||||
<tr>
|
||||
<td>缓存最大容量</td>
|
||||
<td>
|
||||
<size-capacity-box :v-name="'capacityJSON'" :v-count="0" :v-unit="'gb'"></size-capacity-box>
|
||||
<p class="comment">允许缓存的最大内容长度,如果为0表示没有限制。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><more-options-indicator></more-options-indicator></td>
|
||||
</tr>
|
||||
<tbody v-show="moreOptionsVisible">
|
||||
<tr>
|
||||
<td>最大内容长度</td>
|
||||
<td>
|
||||
<size-capacity-box :v-name="'maxSizeJSON'" :v-count="32" :v-unit="'mb'"></size-capacity-box>
|
||||
<p class="comment">允许缓存的最大内容长度,如果为0表示没有限制。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>容纳Key数量</td>
|
||||
<td>
|
||||
<input type="text" name="maxKeys" maxlength="10" style="width:10em"/>
|
||||
<p class="comment">可以容纳多少数量的Key,0表示不限制。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>描述</td>
|
||||
<td>
|
||||
<textarea maxlength="200" name="description" rows="3"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>是否启用</td>
|
||||
<td>
|
||||
<div class="ui checkbox">
|
||||
<input type="checkbox" name="isOn" value="1" checked="checked"/>
|
||||
<label></label>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<submit-btn></submit-btn>
|
||||
</form>
|
||||
5
web/views/@default/servers/components/cache/createPopup.js
vendored
Normal file
5
web/views/@default/servers/components/cache/createPopup.js
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
Tea.context(function () {
|
||||
this.success = NotifyPopup
|
||||
|
||||
this.policyType = this.types[0].type
|
||||
})
|
||||
@@ -2,5 +2,38 @@
|
||||
{$template "/left_menu"}
|
||||
|
||||
<div class="right-box">
|
||||
<p class="ui message">此功能暂未开放敬请期待。</p>
|
||||
<second-menu>
|
||||
<menu-item href="/servers/components/cache" code="index">列表</menu-item>
|
||||
<span class="item">|</span>
|
||||
<a href="" class="item" @click.prevent="createPolicy()">[创建]</a>
|
||||
</second-menu>
|
||||
|
||||
<p class="comment" v-if="cachePolicies.length == 0">暂时还没有缓存策略。</p>
|
||||
<table class="ui table selectable" v-if="cachePolicies.length > 0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>策略名称</th>
|
||||
<th>策略类型</th>
|
||||
<th>容量</th>
|
||||
<th>引用服务</th>
|
||||
<th>状态</th>
|
||||
<th class="three op">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr v-for="(policy, index) in cachePolicies">
|
||||
<td>{{policy.name}}</td>
|
||||
<td>{{infos[index].typeName}} <span class="small">({{policy.type}})</span></td>
|
||||
<td>
|
||||
<span v-if="policy.capacity != null && policy.capacity.count > 0">{{policy.capacity.count}}{{policy.capacity.unit.toUpperCase()}}</span>
|
||||
<span v-else class="disabled">不限</span>
|
||||
</td>
|
||||
<td>{{infos[index].countServers}}</td>
|
||||
<td><label-on :v-is-on="policy.isOn"></label-on></td>
|
||||
<td>
|
||||
<a :href="'/servers/components/cache/policy?cachePolicyId=' + policy.id">详情</a> <a href="" @click.prevent="updatePolicy(policy.id)">修改</a> <a href="" @click.prevent="deletePolicy(policy.id)">删除</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div class="page" v-html="page"></div>
|
||||
</div>
|
||||
37
web/views/@default/servers/components/cache/index.js
vendored
Normal file
37
web/views/@default/servers/components/cache/index.js
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
Tea.context(function () {
|
||||
// 创建策略
|
||||
this.createPolicy = function () {
|
||||
teaweb.popup("/servers/components/cache/createPopup", {
|
||||
height: "27em",
|
||||
callback: function () {
|
||||
teaweb.success("保存成功", function () {
|
||||
window.location.reload()
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 修改策略
|
||||
this.updatePolicy = function (policyId) {
|
||||
teaweb.popup("/servers/components/cache/updatePopup?cachePolicyId=" + policyId, {
|
||||
height: "27em",
|
||||
callback: function () {
|
||||
teaweb.success("保存成功", function () {
|
||||
window.location.reload()
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 删除策略
|
||||
this.deletePolicy = function (policyId) {
|
||||
let that = this
|
||||
teaweb.confirm("确定要删除此缓存策略吗?", function () {
|
||||
that.$post("/servers/components/cache/delete")
|
||||
.params({
|
||||
cachePolicyId: policyId
|
||||
})
|
||||
.refresh()
|
||||
})
|
||||
}
|
||||
})
|
||||
76
web/views/@default/servers/components/cache/updatePopup.html
vendored
Normal file
76
web/views/@default/servers/components/cache/updatePopup.html
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
{$layout "layout_popup"}
|
||||
|
||||
<h3>修改缓存策略</h3>
|
||||
|
||||
<form class="ui form" data-tea-action="$" data-tea-success="success">
|
||||
<input type="hidden" name="cachePolicyId" :value="cachePolicy.id"/>
|
||||
<table class="ui table definition selectable">
|
||||
<tr>
|
||||
<td class="title">策略名称 *</td>
|
||||
<td><input type="text" name="name" maxlength="100" ref="focus" v-model="cachePolicy.name"/> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>缓存类型 *</td>
|
||||
<td>
|
||||
<select class="ui dropdown auto-width" name="type" v-model="policyType">
|
||||
<option v-for="type in types" :value="type.type">{{type.name}}</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- 文件缓存选项 -->
|
||||
<tbody v-if="policyType == 'file'">
|
||||
<tr>
|
||||
<td>缓存目录 *</td>
|
||||
<td>
|
||||
<input type="text" name="fileDir" maxlength="500" v-model="cachePolicy.options.dir"/>
|
||||
<p class="comment">存放文件缓存的目录,通常填写绝对路径。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
|
||||
<tr>
|
||||
<td>缓存最大容量</td>
|
||||
<td>
|
||||
<size-capacity-box :v-name="'capacityJSON'" :v-value="cachePolicy.capacity" :v-count="0" :v-unit="'gb'"></size-capacity-box>
|
||||
<p class="comment">允许缓存的最大内容长度,如果为0表示没有限制。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><more-options-indicator></more-options-indicator></td>
|
||||
</tr>
|
||||
<tbody v-show="moreOptionsVisible">
|
||||
<tr>
|
||||
<td>最大内容长度</td>
|
||||
<td>
|
||||
<size-capacity-box :v-value="cachePolicy.maxSize" :v-name="'maxSizeJSON'" :v-count="32" :v-unit="'mb'"></size-capacity-box>
|
||||
<p class="comment">允许缓存的最大内容长度,如果为0表示没有限制。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>容纳Key数量</td>
|
||||
<td>
|
||||
<input type="text" name="maxKeys" maxlength="10" style="width:10em" v-model="cachePolicy.maxKeys"/>
|
||||
<p class="comment">可以容纳多少数量的Key,0表示不限制。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>描述</td>
|
||||
<td>
|
||||
<textarea maxlength="200" name="description" rows="3" v-model="cachePolicy.description"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>是否启用</td>
|
||||
<td>
|
||||
<div class="ui checkbox">
|
||||
<input type="checkbox" name="isOn" value="1" v-model="cachePolicy.isOn"/>
|
||||
<label></label>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<submit-btn></submit-btn>
|
||||
</form>
|
||||
5
web/views/@default/servers/components/cache/updatePopup.js
vendored
Normal file
5
web/views/@default/servers/components/cache/updatePopup.js
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
Tea.context(function () {
|
||||
this.success = NotifyPopup
|
||||
|
||||
this.policyType = this.cachePolicy.type
|
||||
})
|
||||
@@ -2,5 +2,24 @@
|
||||
{$template "/left_menu"}
|
||||
|
||||
<div class="right-box">
|
||||
<p class="ui message">此功能暂未开放敬请期待。</p>
|
||||
<form class="ui form" data-tea-action="$" data-tea-success="success">
|
||||
<input type="hidden" name="globalConfigJSON" :value="JSON.stringify(globalConfig)"/>
|
||||
<table class="ui table selectable definition">
|
||||
<tr>
|
||||
<td colspan="2">HTTP/HTTPS通用设置</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="title">是否严格匹配域名</td>
|
||||
<td>
|
||||
<div class="ui checkbox">
|
||||
<input type="checkbox" name="matchDomainStrictly" value="1" v-model="globalConfig.httpAll.matchDomainStrictly"/>
|
||||
<label></label>
|
||||
</div>
|
||||
<p class="comment">如果选择了严格匹配域名,则没有在Edge里绑定过的域名访问时都会返回404。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<submit-btn>保存</submit-btn>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
3
web/views/@default/servers/components/index.js
Normal file
3
web/views/@default/servers/components/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
Tea.context(function () {
|
||||
this.success = NotifyReloadSuccess("保存成功")
|
||||
})
|
||||
@@ -8,7 +8,7 @@
|
||||
</tr>
|
||||
<tr v-if="info.description.length > 0">
|
||||
<td>详细说明</td>
|
||||
<td>{{info.decription}}</td>
|
||||
<td>{{info.description}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>证书状态</td>
|
||||
|
||||
@@ -45,7 +45,8 @@
|
||||
<td>{{certInfos[index].endDay}}</td>
|
||||
<td>{{certInfos[index].countServers}}</td>
|
||||
<td nowrap="">
|
||||
<span class="ui label red tiny basic" v-if="certInfos[index].isExpired">已过期</span>
|
||||
<span class="ui label red tiny basic" v-if="!certInfos[index].isOn">未启用</span>
|
||||
<span class="ui label red tiny basic" v-else-if="certInfos[index].isExpired">已过期</span>
|
||||
<span class="ui label green tiny basic" v-else>有效中</span>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
@@ -30,4 +30,16 @@ Tea.context(function () {
|
||||
width: "48em"
|
||||
})
|
||||
}
|
||||
|
||||
// 修改证书
|
||||
this.updateCert = function (certId) {
|
||||
teaweb.popup("/servers/components/ssl/updatePopup?certId=" + certId, {
|
||||
height: "28em",
|
||||
callback: function () {
|
||||
teaweb.success("上传成功", function () {
|
||||
window.location.reload()
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
60
web/views/@default/servers/components/ssl/updatePopup.html
Normal file
60
web/views/@default/servers/components/ssl/updatePopup.html
Normal file
@@ -0,0 +1,60 @@
|
||||
{$layout "layout_popup"}
|
||||
|
||||
<h3>修改证书</h3>
|
||||
|
||||
<form class="ui form" data-tea-action="$" data-tea-success="success">
|
||||
<input type="hidden" name="certId" :value="certConfig.id"/>
|
||||
<table class="ui table definition selectable">
|
||||
<tr>
|
||||
<td class="title">证书说明 *</td>
|
||||
<td>
|
||||
<input type="text" name="name" maxlength="100" ref="focus" v-model="certConfig.name"/>
|
||||
<p class="comment">可以简单说明证书的用途。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>证书类型</td>
|
||||
<td>
|
||||
<select class="ui dropdown auto-width" name="isCA" v-model="isCA">
|
||||
<option value="0">加密证书</option>
|
||||
<option value="1">CA证书</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>选择证书文件</td>
|
||||
<td>
|
||||
<input type="file" name="certFile" accept="application/x-pem-file, application/pkcs10, application/x-pkcs12, application/x-x509-user-cert, application/x-x509-ca-cert, application/pkix-cert"/>
|
||||
<p class="comment">内容中通常含有"-----BEGIN CERTIFICATE-----"类似的信息。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-show="isCA == 0">
|
||||
<td>选择私钥文件</td>
|
||||
<td>
|
||||
<input type="file" name="keyFile" accept="application/pkcs8"/>
|
||||
<p class="comment">内容中通常含有"-----BEGIN RSA PRIVATE KEY-----"类似的信息。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><more-options-indicator></more-options-indicator></td>
|
||||
</tr>
|
||||
<tbody v-show="moreOptionsVisible">
|
||||
<tr>
|
||||
<td>详细说明</td>
|
||||
<td>
|
||||
<textarea rows="3" name="description" maxlength="200" v-model="certConfig.description"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>是否启用</td>
|
||||
<td>
|
||||
<div class="ui checkbox">
|
||||
<input type="checkbox" name="isOn" value="1" v-model="certConfig.isOn"/>
|
||||
<label></label>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<submit-btn></submit-btn>
|
||||
</form>
|
||||
4
web/views/@default/servers/components/ssl/updatePopup.js
Normal file
4
web/views/@default/servers/components/ssl/updatePopup.js
Normal file
@@ -0,0 +1,4 @@
|
||||
Tea.context(function () {
|
||||
this.success = NotifyPopup
|
||||
this.isCA = this.certConfig.isCA ? 1 : 0
|
||||
})
|
||||
@@ -24,7 +24,7 @@
|
||||
<td>选择证书文件 *</td>
|
||||
<td>
|
||||
<input type="file" name="certFile" accept="application/x-pem-file, application/pkcs10, application/x-pkcs12, application/x-x509-user-cert, application/x-x509-ca-cert, application/pkix-cert"/>
|
||||
<p class="comment">内容中通常含有"-----BEGIN CERTIFICATE-----"类似的信息。</p
|
||||
<p class="comment">内容中通常含有"-----BEGIN CERTIFICATE-----"类似的信息。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-show="isCA == 0">
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<th>服务名称</th>
|
||||
<th>服务类型</th>
|
||||
<th>部署集群</th>
|
||||
<th>运行节点数</th>
|
||||
<th>运行中节点数</th>
|
||||
<th>未运行节点数</th>
|
||||
<th>端口</th>
|
||||
<th>状态</th>
|
||||
@@ -24,8 +24,8 @@
|
||||
<td><span class="disabled">[暂无]</span></td>
|
||||
<td>
|
||||
<span v-if="server.ports.length == 0">-</span>
|
||||
<div v-for="port in server.ports" class="ui label small">
|
||||
{{port.portRange}}<span class="small">({{port.protocol}})</span>
|
||||
<div v-for="port in server.ports">
|
||||
<div class="ui label tiny" style="margin-bottom:0.5em">{{port.portRange}}<span class="small">({{port.protocol}})</span></div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
@@ -1,94 +1,5 @@
|
||||
{$layout}
|
||||
|
||||
{$template "/left_menu"}
|
||||
|
||||
<div class="right-box">
|
||||
<table class="ui table selectable definition">
|
||||
<tr>
|
||||
<td class="title">服务名称</td>
|
||||
<td>
|
||||
{{server.name}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>部署的集群</td>
|
||||
<td>
|
||||
{{server.cluster.name}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>服务类型</td>
|
||||
<td>
|
||||
{{serverType.name}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>绑定端口</td>
|
||||
<td>
|
||||
<span v-if="server.ports.length == 0">-</span>
|
||||
<div v-for="port in server.ports" class="ui label small">
|
||||
{{port.portRange}}<span class="small">({{port.protocol}})</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- 证书 -->
|
||||
<!--<tbody v-if="tlsProtocolName.length > 0">
|
||||
<tr>
|
||||
<td>{{tlsProtocolName}}证书</td>
|
||||
<td>
|
||||
<input type="file" name="tlsCertFile"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{tlsProtocolName}}密钥</td>
|
||||
<td>
|
||||
<input type="file" name="tlsKeyFile"/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>-->
|
||||
|
||||
<!-- 域名 -->
|
||||
<tr>
|
||||
<td>绑定域名</td>
|
||||
<td>
|
||||
<div v-for="serverName in server.serverNames" class="ui label small">
|
||||
<em v-if="serverName.type != 'full'">{{serverName.type}}</em> {{serverName.name}}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- 源服务器地址 -->
|
||||
<tr v-if="serverType.code == 'httpProxy' || serverType.code == 'tcpProxy' || serverType.code == 'udpProxy'">
|
||||
<td>源站地址</td>
|
||||
<td>
|
||||
<div v-if="server.origins.length > 0">
|
||||
<div v-for="(origin, index) in server.origins" class="ui label small">
|
||||
{{origin.addr.protocol}}://{{origin.addr.host}}:{{origin.addr.portRange}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Web Server -->
|
||||
<!--<tr v-if="serverType == 'httpWeb'">
|
||||
<td>Web目录</td>
|
||||
<td>
|
||||
<input type="text" name="webRoot"/>
|
||||
</td>
|
||||
</tr>-->
|
||||
|
||||
<tr>
|
||||
<td colspan="2"><more-options-indicator></more-options-indicator></td>
|
||||
</tr>
|
||||
<tbody v-show="moreOptionsVisible">
|
||||
<tr>
|
||||
<td>描述</td>
|
||||
<td>
|
||||
<span v-if="server.description.length == 0">-</span>
|
||||
<span v-if="server.description.length > 0">{{server.description}}</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
Reference in New Issue
Block a user