mirror of
				https://github.com/TeaOSLab/EdgeAdmin.git
				synced 2025-11-04 05:00:25 +08:00 
			
		
		
		
	单个节点支持多个DNS线路
This commit is contained in:
		@@ -76,8 +76,8 @@ func (this *CreateNodeAction) RunPost(params struct {
 | 
			
		||||
	SshHost         string
 | 
			
		||||
	SshPort         int
 | 
			
		||||
 | 
			
		||||
	DnsDomainId int64
 | 
			
		||||
	DnsRoute    string
 | 
			
		||||
	DnsDomainId   int64
 | 
			
		||||
	DnsRoutesJSON []byte
 | 
			
		||||
 | 
			
		||||
	Must *actions.Must
 | 
			
		||||
}) {
 | 
			
		||||
@@ -94,6 +94,13 @@ func (this *CreateNodeAction) RunPost(params struct {
 | 
			
		||||
		this.Fail("请选择所在集群")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dnsRouteCodes := []string{}
 | 
			
		||||
	err := json.Unmarshal(params.DnsRoutesJSON, &dnsRouteCodes)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// TODO 检查登录授权
 | 
			
		||||
	loginInfo := &pb.NodeLogin{
 | 
			
		||||
		Id:   0,
 | 
			
		||||
@@ -113,7 +120,7 @@ func (this *CreateNodeAction) RunPost(params struct {
 | 
			
		||||
		GroupId:     params.GroupId,
 | 
			
		||||
		Login:       loginInfo,
 | 
			
		||||
		DnsDomainId: params.DnsDomainId,
 | 
			
		||||
		DnsRoute:    params.DnsRoute,
 | 
			
		||||
		DnsRoutes:   dnsRouteCodes,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
 
 | 
			
		||||
@@ -97,6 +97,12 @@ func (this *IndexAction) RunGet(params struct {
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// DNS
 | 
			
		||||
		dnsRouteNames := []string{}
 | 
			
		||||
		for _, route := range node.DnsRoutes {
 | 
			
		||||
			dnsRouteNames = append(dnsRouteNames, route.Name)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		nodeMaps = append(nodeMaps, maps.Map{
 | 
			
		||||
			"id":          node.Id,
 | 
			
		||||
			"name":        node.Name,
 | 
			
		||||
@@ -122,9 +128,10 @@ func (this *IndexAction) RunGet(params struct {
 | 
			
		||||
				"id":   node.Cluster.Id,
 | 
			
		||||
				"name": node.Cluster.Name,
 | 
			
		||||
			},
 | 
			
		||||
			"isSynced":    isSynced,
 | 
			
		||||
			"ipAddresses": ipAddresses,
 | 
			
		||||
			"group":       groupMap,
 | 
			
		||||
			"isSynced":      isSynced,
 | 
			
		||||
			"ipAddresses":   ipAddresses,
 | 
			
		||||
			"group":         groupMap,
 | 
			
		||||
			"dnsRouteNames": dnsRouteNames,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["nodes"] = nodeMaps
 | 
			
		||||
 
 | 
			
		||||
@@ -70,6 +70,21 @@ func (this *NodeAction) RunGet(params struct {
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// DNS相关
 | 
			
		||||
	dnsInfoResp, err := this.RPC().NodeRPC().FindEnabledNodeDNS(this.AdminContext(), &pb.FindEnabledNodeDNSRequest{NodeId: params.NodeId})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	dnsRouteMaps := []maps.Map{}
 | 
			
		||||
	for _, dnsInfo := range dnsInfoResp.Node.Routes {
 | 
			
		||||
		dnsRouteMaps = append(dnsRouteMaps, maps.Map{
 | 
			
		||||
			"name": dnsInfo.Name,
 | 
			
		||||
			"code": dnsInfo.Code,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["dnsRoutes"] = dnsRouteMaps
 | 
			
		||||
 | 
			
		||||
	// 登录信息
 | 
			
		||||
	var loginMap maps.Map = nil
 | 
			
		||||
	if node.Login != nil {
 | 
			
		||||
 
 | 
			
		||||
@@ -60,6 +60,38 @@ func (this *UpdateAction) RunGet(params struct {
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// DNS相关
 | 
			
		||||
	dnsInfoResp, err := this.RPC().NodeRPC().FindEnabledNodeDNS(this.AdminContext(), &pb.FindEnabledNodeDNSRequest{NodeId: params.NodeId})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	dnsRouteMaps := []maps.Map{}
 | 
			
		||||
	for _, dnsInfo := range dnsInfoResp.Node.Routes {
 | 
			
		||||
		dnsRouteMaps = append(dnsRouteMaps, maps.Map{
 | 
			
		||||
			"name": dnsInfo.Name,
 | 
			
		||||
			"code": dnsInfo.Code,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["dnsRoutes"] = dnsRouteMaps
 | 
			
		||||
	this.Data["allDNSRoutes"] = []maps.Map{}
 | 
			
		||||
	this.Data["dnsDomainId"] = dnsInfoResp.Node.DnsDomainId
 | 
			
		||||
	if dnsInfoResp.Node.DnsDomainId > 0 {
 | 
			
		||||
		routesMaps := []maps.Map{}
 | 
			
		||||
		routesResp, err := this.RPC().DNSDomainRPC().FindAllDNSDomainRoutes(this.AdminContext(), &pb.FindAllDNSDomainRoutesRequest{DnsDomainId: dnsInfoResp.Node.DnsDomainId})
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			this.ErrorPage(err)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		for _, route := range routesResp.Routes {
 | 
			
		||||
			routesMaps = append(routesMaps, maps.Map{
 | 
			
		||||
				"name": route.Name,
 | 
			
		||||
				"code": route.Code,
 | 
			
		||||
			})
 | 
			
		||||
		}
 | 
			
		||||
		this.Data["allDNSRoutes"] = routesMaps
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 登录信息
 | 
			
		||||
	var loginMap maps.Map = nil
 | 
			
		||||
	if node.Login != nil {
 | 
			
		||||
@@ -152,6 +184,9 @@ func (this *UpdateAction) RunPost(params struct {
 | 
			
		||||
	MaxCPU          int32
 | 
			
		||||
	IsOn            bool
 | 
			
		||||
 | 
			
		||||
	DnsDomainId   int64
 | 
			
		||||
	DnsRoutesJSON []byte
 | 
			
		||||
 | 
			
		||||
	Must *actions.Must
 | 
			
		||||
}) {
 | 
			
		||||
	// 创建日志
 | 
			
		||||
@@ -170,6 +205,13 @@ func (this *UpdateAction) RunPost(params struct {
 | 
			
		||||
		this.Fail("请选择所在集群")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dnsRouteCodes := []string{}
 | 
			
		||||
	err := json.Unmarshal(params.DnsRoutesJSON, &dnsRouteCodes)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// TODO 检查登录授权
 | 
			
		||||
	loginInfo := &pb.NodeLogin{
 | 
			
		||||
		Id:   params.LoginId,
 | 
			
		||||
@@ -183,14 +225,16 @@ func (this *UpdateAction) RunPost(params struct {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 保存
 | 
			
		||||
	_, err := this.RPC().NodeRPC().UpdateNode(this.AdminContext(), &pb.UpdateNodeRequest{
 | 
			
		||||
		NodeId:    params.NodeId,
 | 
			
		||||
		GroupId:   params.GroupId,
 | 
			
		||||
		Name:      params.Name,
 | 
			
		||||
		ClusterId: params.ClusterId,
 | 
			
		||||
		Login:     loginInfo,
 | 
			
		||||
		MaxCPU:    params.MaxCPU,
 | 
			
		||||
		IsOn:      params.IsOn,
 | 
			
		||||
	_, err = this.RPC().NodeRPC().UpdateNode(this.AdminContext(), &pb.UpdateNodeRequest{
 | 
			
		||||
		NodeId:      params.NodeId,
 | 
			
		||||
		GroupId:     params.GroupId,
 | 
			
		||||
		Name:        params.Name,
 | 
			
		||||
		ClusterId:   params.ClusterId,
 | 
			
		||||
		Login:       loginInfo,
 | 
			
		||||
		MaxCPU:      params.MaxCPU,
 | 
			
		||||
		IsOn:        params.IsOn,
 | 
			
		||||
		DnsDomainId: params.DnsDomainId,
 | 
			
		||||
		DnsRoutes:   dnsRouteCodes,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,6 @@ package clusters
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/grants/grantutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
	"github.com/iwind/TeaGo/maps"
 | 
			
		||||
@@ -55,20 +54,16 @@ func (this *IndexAction) RunGet(params struct{}) {
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// grant
 | 
			
		||||
			var grantMap maps.Map = nil
 | 
			
		||||
			if cluster.GrantId > 0 {
 | 
			
		||||
				grantResp, err := this.RPC().NodeGrantRPC().FindEnabledGrant(this.AdminContext(), &pb.FindEnabledGrantRequest{GrantId: cluster.GrantId})
 | 
			
		||||
			// DNS
 | 
			
		||||
			dnsDomainName := ""
 | 
			
		||||
			if cluster.DnsDomainId > 0 {
 | 
			
		||||
				dnsInfoResp, err := this.RPC().NodeClusterRPC().FindEnabledNodeClusterDNS(this.AdminContext(), &pb.FindEnabledNodeClusterDNSRequest{NodeClusterId: cluster.Id})
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					this.ErrorPage(err)
 | 
			
		||||
					return
 | 
			
		||||
				}
 | 
			
		||||
				if grantResp.Grant != nil {
 | 
			
		||||
					grantMap = maps.Map{
 | 
			
		||||
						"id":         grantResp.Grant.Id,
 | 
			
		||||
						"name":       grantResp.Grant.Name,
 | 
			
		||||
						"methodName": grantutils.FindGrantMethodName(grantResp.Grant.Method),
 | 
			
		||||
					}
 | 
			
		||||
				if dnsInfoResp.Domain != nil {
 | 
			
		||||
					dnsDomainName = dnsInfoResp.Domain.Name
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
@@ -76,9 +71,11 @@ func (this *IndexAction) RunGet(params struct{}) {
 | 
			
		||||
				"id":               cluster.Id,
 | 
			
		||||
				"name":             cluster.Name,
 | 
			
		||||
				"installDir":       cluster.InstallDir,
 | 
			
		||||
				"grant":            grantMap,
 | 
			
		||||
				"countAllNodes":    countNodesResp.Count,
 | 
			
		||||
				"countActiveNodes": countActiveNodesResp.Count,
 | 
			
		||||
				"dnsDomainId":      cluster.DnsDomainId,
 | 
			
		||||
				"dnsName":          cluster.DnsName,
 | 
			
		||||
				"dnsDomainName":    dnsDomainName,
 | 
			
		||||
			})
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -67,16 +67,31 @@ func (this *ClusterAction) RunGet(params struct {
 | 
			
		||||
	}
 | 
			
		||||
	nodeMaps := []maps.Map{}
 | 
			
		||||
	for _, node := range nodesResp.Nodes {
 | 
			
		||||
		nodeMaps = append(nodeMaps, maps.Map{
 | 
			
		||||
			"id":     node.Id,
 | 
			
		||||
			"name":   node.Name,
 | 
			
		||||
			"ipAddr": node.IpAddr,
 | 
			
		||||
			"route": maps.Map{
 | 
			
		||||
				"name": node.Route.Name,
 | 
			
		||||
				"code": node.Route.Code,
 | 
			
		||||
			},
 | 
			
		||||
			"clusterId": node.ClusterId,
 | 
			
		||||
		})
 | 
			
		||||
		if len(node.Routes) > 0 {
 | 
			
		||||
			for _, route := range node.Routes {
 | 
			
		||||
				nodeMaps = append(nodeMaps, maps.Map{
 | 
			
		||||
					"id":     node.Id,
 | 
			
		||||
					"name":   node.Name,
 | 
			
		||||
					"ipAddr": node.IpAddr,
 | 
			
		||||
					"route": maps.Map{
 | 
			
		||||
						"name": route.Name,
 | 
			
		||||
						"code": route.Code,
 | 
			
		||||
					},
 | 
			
		||||
					"clusterId": node.ClusterId,
 | 
			
		||||
				})
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			nodeMaps = append(nodeMaps, maps.Map{
 | 
			
		||||
				"id":     node.Id,
 | 
			
		||||
				"name":   node.Name,
 | 
			
		||||
				"ipAddr": node.IpAddr,
 | 
			
		||||
				"route": maps.Map{
 | 
			
		||||
					"name": "",
 | 
			
		||||
					"code": "",
 | 
			
		||||
				},
 | 
			
		||||
				"clusterId": node.ClusterId,
 | 
			
		||||
			})
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["nodes"] = nodeMaps
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,9 @@
 | 
			
		||||
package domainutils
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
	"github.com/iwind/TeaGo/lists"
 | 
			
		||||
	"github.com/iwind/TeaGo/maps"
 | 
			
		||||
	"regexp"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
@@ -16,3 +19,30 @@ func ValidateDomainFormat(domain string) bool {
 | 
			
		||||
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 转换线路列表
 | 
			
		||||
func ConvertRoutesToMaps(routes []*pb.DNSRoute) []maps.Map {
 | 
			
		||||
	result := []maps.Map{}
 | 
			
		||||
	for _, route := range routes {
 | 
			
		||||
		result = append(result, maps.Map{
 | 
			
		||||
			"name": route.Name,
 | 
			
		||||
			"code": route.Code,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	return result
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 筛选线路
 | 
			
		||||
func FilterRoutes(routes []*pb.DNSRoute, allRoutes []*pb.DNSRoute) []*pb.DNSRoute {
 | 
			
		||||
	routeCodes := []string{}
 | 
			
		||||
	for _, route := range allRoutes {
 | 
			
		||||
		routeCodes = append(routeCodes, route.Code)
 | 
			
		||||
	}
 | 
			
		||||
	result := []*pb.DNSRoute{}
 | 
			
		||||
	for _, route := range routes {
 | 
			
		||||
		if lists.ContainsString(routeCodes, route.Code) {
 | 
			
		||||
			result = append(result, route)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return result
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,10 @@
 | 
			
		||||
package issues
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/dns/domains/domainutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
	"github.com/iwind/TeaGo/actions"
 | 
			
		||||
	"github.com/iwind/TeaGo/maps"
 | 
			
		||||
@@ -33,12 +35,12 @@ func (this *UpdateNodePopupAction) RunGet(params struct {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["ipAddr"] = dnsInfo.IpAddr
 | 
			
		||||
	this.Data["route"] = dnsInfo.Route.Code
 | 
			
		||||
	this.Data["routes"] = domainutils.ConvertRoutesToMaps(dnsInfo.Routes)
 | 
			
		||||
	this.Data["domainId"] = dnsInfo.DnsDomainId
 | 
			
		||||
	this.Data["domainName"] = dnsInfo.DnsDomainName
 | 
			
		||||
 | 
			
		||||
	// 读取所有线路
 | 
			
		||||
	routeMaps := []maps.Map{}
 | 
			
		||||
	allRouteMaps := []maps.Map{}
 | 
			
		||||
	if dnsInfo.DnsDomainId > 0 {
 | 
			
		||||
		routesResp, err := this.RPC().DNSDomainRPC().FindAllDNSDomainRoutes(this.AdminContext(), &pb.FindAllDNSDomainRoutesRequest{DnsDomainId: dnsInfo.DnsDomainId})
 | 
			
		||||
		if err != nil {
 | 
			
		||||
@@ -47,37 +49,26 @@ func (this *UpdateNodePopupAction) RunGet(params struct {
 | 
			
		||||
		}
 | 
			
		||||
		if len(routesResp.Routes) > 0 {
 | 
			
		||||
			for _, route := range routesResp.Routes {
 | 
			
		||||
				routeMaps = append(routeMaps, maps.Map{
 | 
			
		||||
				allRouteMaps = append(allRouteMaps, maps.Map{
 | 
			
		||||
					"name": route.Name,
 | 
			
		||||
					"code": route.Code,
 | 
			
		||||
				})
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["routes"] = routeMaps
 | 
			
		||||
 | 
			
		||||
	// 是否包含现有线路
 | 
			
		||||
	if len(routeMaps) > 0 {
 | 
			
		||||
		isRouteValid := false
 | 
			
		||||
		for _, route := range routeMaps {
 | 
			
		||||
			if route.GetString("code") == dnsInfo.Route.Code {
 | 
			
		||||
				isRouteValid = true
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if !isRouteValid {
 | 
			
		||||
			this.Data["route"] = routeMaps[0].GetString("code")
 | 
			
		||||
			// 筛选
 | 
			
		||||
			this.Data["routes"] = domainutils.ConvertRoutesToMaps(domainutils.FilterRoutes(dnsInfo.Routes, routesResp.Routes))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["allRoutes"] = allRouteMaps
 | 
			
		||||
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *UpdateNodePopupAction) RunPost(params struct {
 | 
			
		||||
	NodeId   int64
 | 
			
		||||
	IpAddr   string
 | 
			
		||||
	DomainId int64
 | 
			
		||||
	Route    string
 | 
			
		||||
	NodeId        int64
 | 
			
		||||
	IpAddr        string
 | 
			
		||||
	DomainId      int64
 | 
			
		||||
	DnsRoutesJSON []byte
 | 
			
		||||
 | 
			
		||||
	Must *actions.Must
 | 
			
		||||
	CSRF *actionutils.CSRF
 | 
			
		||||
@@ -85,6 +76,13 @@ func (this *UpdateNodePopupAction) RunPost(params struct {
 | 
			
		||||
	// 操作日志
 | 
			
		||||
	this.CreateLog(oplogs.LevelInfo, "修改节点 %d 的DNS设置", params.NodeId)
 | 
			
		||||
 | 
			
		||||
	routes := []string{}
 | 
			
		||||
	err := json.Unmarshal(params.DnsRoutesJSON, &routes)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	params.Must.
 | 
			
		||||
		Field("ipAddr", params.IpAddr).
 | 
			
		||||
		Require("请输入IP地址")
 | 
			
		||||
@@ -94,11 +92,11 @@ func (this *UpdateNodePopupAction) RunPost(params struct {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 执行修改
 | 
			
		||||
	_, err := this.RPC().NodeRPC().UpdateNodeDNS(this.AdminContext(), &pb.UpdateNodeDNSRequest{
 | 
			
		||||
	_, err = this.RPC().NodeRPC().UpdateNodeDNS(this.AdminContext(), &pb.UpdateNodeDNSRequest{
 | 
			
		||||
		NodeId:      params.NodeId,
 | 
			
		||||
		IpAddr:      params.IpAddr,
 | 
			
		||||
		DnsDomainId: params.DomainId,
 | 
			
		||||
		Route:       params.Route,
 | 
			
		||||
		Routes:      routes,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										79
									
								
								web/public/js/components/dns/dns-route-selector.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								web/public/js/components/dns/dns-route-selector.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,79 @@
 | 
			
		||||
Vue.component("dns-route-selector", {
 | 
			
		||||
	props: ["v-all-routes", "v-routes"],
 | 
			
		||||
	data: function () {
 | 
			
		||||
		let routes = this.vRoutes
 | 
			
		||||
		if (routes == null) {
 | 
			
		||||
			routes = []
 | 
			
		||||
		}
 | 
			
		||||
		return {
 | 
			
		||||
			routes: routes,
 | 
			
		||||
			routeCodes: routes.$map(function (k, v) {
 | 
			
		||||
				return v.code
 | 
			
		||||
			}),
 | 
			
		||||
			isAdding: false,
 | 
			
		||||
			routeCode: ""
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		add: function () {
 | 
			
		||||
			this.isAdding = true
 | 
			
		||||
		},
 | 
			
		||||
		cancel: function () {
 | 
			
		||||
			this.isAdding = false
 | 
			
		||||
		},
 | 
			
		||||
		confirm: function () {
 | 
			
		||||
			if (this.routeCode.length == 0) {
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			if (this.routeCodes.$contains(this.routeCode)) {
 | 
			
		||||
				teaweb.warn("已经添加过此线路,不能重复添加")
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			let that = this
 | 
			
		||||
			let route = this.vAllRoutes.$find(function (k, v) {
 | 
			
		||||
				return v.code == that.routeCode
 | 
			
		||||
			})
 | 
			
		||||
			if (route == null) {
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			this.routeCodes.push(this.routeCode)
 | 
			
		||||
			this.routes.push(route)
 | 
			
		||||
 | 
			
		||||
			this.routeCode = ""
 | 
			
		||||
			this.isAdding = false
 | 
			
		||||
		},
 | 
			
		||||
		remove: function (route) {
 | 
			
		||||
			this.routeCodes.$removeValue(route.code)
 | 
			
		||||
			this.routes.$removeIf(function (k, v) {
 | 
			
		||||
				return v.code == route.code
 | 
			
		||||
			})
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
	template: `<div>
 | 
			
		||||
	<input type="hidden" name="dnsRoutesJSON" :value="JSON.stringify(routeCodes)"/>
 | 
			
		||||
	<div v-if="routes.length > 0">
 | 
			
		||||
		<tiny-label v-for="route in routes" :key="route.code">
 | 
			
		||||
			{{route.name}} <a href="" @click.prevent="remove(route)"><i class="icon remove"></i></a>
 | 
			
		||||
		</tiny-label>
 | 
			
		||||
		<div class="ui divider"></div>
 | 
			
		||||
	</div>
 | 
			
		||||
	<button type="button" class="ui button small" @click.prevent="add" v-if="!isAdding">+</button>
 | 
			
		||||
	<div v-if="isAdding">
 | 
			
		||||
		<div class="ui fields inline">
 | 
			
		||||
			<div class="ui field">
 | 
			
		||||
				<select class="ui dropdown auto-width" v-model="routeCode">
 | 
			
		||||
					<option value="">[请选择]</option>
 | 
			
		||||
					<option v-for="route in vAllRoutes" :value="route.code">{{route.name}}</option>
 | 
			
		||||
				</select>
 | 
			
		||||
			</div>
 | 
			
		||||
			<div class="ui field">
 | 
			
		||||
				<button class="ui button tiny" type="button" @click.prevent="confirm">确定</button>
 | 
			
		||||
			</div>
 | 
			
		||||
			<div class="ui field">
 | 
			
		||||
				<a href="" @click.prevent="cancel()"><i class="icon remove"></i></a>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
</div>`
 | 
			
		||||
})
 | 
			
		||||
@@ -18,4 +18,8 @@ form .fields {
 | 
			
		||||
.link.grey:hover {
 | 
			
		||||
  color: #4183c4 !important;
 | 
			
		||||
}
 | 
			
		||||
table th.center,
 | 
			
		||||
table td.center {
 | 
			
		||||
  text-align: center !important;
 | 
			
		||||
}
 | 
			
		||||
/*# sourceMappingURL=@layout_override.css.map */
 | 
			
		||||
@@ -1 +1 @@
 | 
			
		||||
{"version":3,"sources":["@layout_override.less"],"names":[],"mappings":"AACA,GAAG,OAAO,SAAU,MAAK,MAAM,QAAS,OAAM;AAAS,GAAG,OAAO,SAAU,MAAK,MAAM,QAAS,QAAO;EACrG,oCAAA;;AAGD,GAAG,OAAO,SAAU,MAAK,QAAS,OAAM;AAAS,GAAG,OAAO,SAAU,MAAK,QAAS,QAAO;EACzF,oCAAA;;AAGD,GAAG,MAAM;EACR,kCAAA;;AAID,IACC;EACC,2BAAA;;AAKF,KAAK;EACJ,sBAAA;;AAGD,KAAK,KAAK;EACT,yBAAA","file":"@layout_override.css"}
 | 
			
		||||
{"version":3,"sources":["@layout_override.less"],"names":[],"mappings":"AACA,GAAG,OAAO,SAAU,MAAK,MAAM,QAAS,OAAM;AAAS,GAAG,OAAO,SAAU,MAAK,MAAM,QAAS,QAAO;EACrG,oCAAA;;AAGD,GAAG,OAAO,SAAU,MAAK,QAAS,OAAM;AAAS,GAAG,OAAO,SAAU,MAAK,QAAS,QAAO;EACzF,oCAAA;;AAGD,GAAG,MAAM;EACR,kCAAA;;AAID,IACC;EACC,2BAAA;;AAKF,KAAK;EACJ,sBAAA;;AAGD,KAAK,KAAK;EACT,yBAAA;;AAID,KACC,GAAE;AADH,KACY,GAAE;EACZ,6BAAA","file":"@layout_override.css"}
 | 
			
		||||
@@ -26,3 +26,10 @@ form {
 | 
			
		||||
.link.grey:hover {
 | 
			
		||||
	color: #4183c4 !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// table
 | 
			
		||||
table {
 | 
			
		||||
	th.center, td.center {
 | 
			
		||||
		text-align: center !important;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@
 | 
			
		||||
 | 
			
		||||
<p class="comment" v-if="nodes.length == 0">暂时还没有节点。</p>
 | 
			
		||||
 | 
			
		||||
<table class="ui table selectable" v-if="nodes.length > 0">
 | 
			
		||||
<table class="ui table selectable celled" v-if="nodes.length > 0">
 | 
			
		||||
	<thead>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<th>节点名称</th>
 | 
			
		||||
 
 | 
			
		||||
@@ -23,10 +23,7 @@
 | 
			
		||||
				<td>DNS线路</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<input type="hidden" name="dnsDomainId" :value="dnsDomainId"/>
 | 
			
		||||
					<select class="ui dropdown auto-width" name="dnsRoute">
 | 
			
		||||
						<option value="">[请选择]</option>
 | 
			
		||||
						<option v-for="route in dnsRoutes" :value="route.code">{{route.name}}</option>
 | 
			
		||||
					</select>
 | 
			
		||||
					<dns-route-selector :v-all-routes="dnsRoutes"></dns-route-selector>
 | 
			
		||||
					<p class="comment">可用线路是根据集群设置的域名获取的,注意DNS服务商可能对这些线路有所限制。</p>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
 
 | 
			
		||||
@@ -8,12 +8,12 @@
 | 
			
		||||
<p class="comment" v-if="groups.length == 0">暂时还没有分组。</p>
 | 
			
		||||
<div v-show="groups.length > 0">
 | 
			
		||||
	<div class="margin"></div>
 | 
			
		||||
	<table class="ui table selectable" id="sortable-table">
 | 
			
		||||
	<table class="ui table selectable celled" id="sortable-table">
 | 
			
		||||
		<thead>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<th style="width:3em"></th>
 | 
			
		||||
				<th>分组名称</th>
 | 
			
		||||
				<th>节点数</th>
 | 
			
		||||
				<th class="center">节点数</th>
 | 
			
		||||
				<th class="two op">操作</th>
 | 
			
		||||
			</tr>
 | 
			
		||||
		</thead>
 | 
			
		||||
@@ -21,7 +21,7 @@
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td style="text-align: center;"><i class="icon bars handle grey"></i> </td>
 | 
			
		||||
				<td>{{group.name}}</td>
 | 
			
		||||
				<td>
 | 
			
		||||
				<td class="center">
 | 
			
		||||
					<span v-if="group.countNodes.length > 0">{{group.countNodes}}</span>
 | 
			
		||||
					<span v-else class="disabled">0</span>
 | 
			
		||||
				</td>
 | 
			
		||||
 
 | 
			
		||||
@@ -45,23 +45,24 @@
 | 
			
		||||
 | 
			
		||||
<p class="comment" v-if="nodes.length == 0">暂时还没有节点。</p>
 | 
			
		||||
 | 
			
		||||
<table class="ui table selectable" v-if="nodes.length > 0">
 | 
			
		||||
<table class="ui table selectable celled" v-if="nodes.length > 0">
 | 
			
		||||
	<thead>
 | 
			
		||||
	<tr>
 | 
			
		||||
		<th class="one wide">ID</th>
 | 
			
		||||
		<th class="one wide center">ID</th>
 | 
			
		||||
		<th>节点名称</th>
 | 
			
		||||
		<th class="two wide">所属分组</th>
 | 
			
		||||
		<th class="three wide">IP</th>
 | 
			
		||||
		<th class="two wide">CPU</th>
 | 
			
		||||
		<th class="two wide">内存</th>
 | 
			
		||||
		<th style="width:10em">IP</th>
 | 
			
		||||
		<th>DNS线路</th>
 | 
			
		||||
		<th style="width:5em" class="center">CPU</th>
 | 
			
		||||
		<th style="width:5em" class="center">内存</th>
 | 
			
		||||
		<!--<th>流量</th>
 | 
			
		||||
		<th>连接数</th>-->
 | 
			
		||||
		<th class="two wide">状态</th>
 | 
			
		||||
		<th class="two wide center">状态</th>
 | 
			
		||||
		<th class="two op">操作</th>
 | 
			
		||||
	</tr>
 | 
			
		||||
	</thead>
 | 
			
		||||
	<tr v-for="node in nodes">
 | 
			
		||||
		<td nowrap="">{{node.id}}</td>
 | 
			
		||||
		<td nowrap="" class="center">{{node.id}}</td>
 | 
			
		||||
		<td>{{node.name}}</td>
 | 
			
		||||
		<td>
 | 
			
		||||
			<span v-if="node.group != null" class="ui label tiny">{{node.group.name}}</span>
 | 
			
		||||
@@ -79,14 +80,20 @@
 | 
			
		||||
			</div>
 | 
			
		||||
		</td>
 | 
			
		||||
		<td>
 | 
			
		||||
			<div v-if="node.dnsRouteNames.length > 0">
 | 
			
		||||
				<div v-for="routeName in node.dnsRouteNames" style="margin-bottom: 0.4em">{{routeName}}</div>
 | 
			
		||||
			</div>
 | 
			
		||||
			<span v-else class="disabled">-</span>
 | 
			
		||||
		</td>
 | 
			
		||||
		<td class="center">
 | 
			
		||||
			<span v-if="node.status.isActive" :class="{red:node.status.cpuUsage > 0.80}">{{node.status.cpuUsageText}}</span>
 | 
			
		||||
			<span v-else class="disabled">-</span>
 | 
			
		||||
		</td>
 | 
			
		||||
		<td>
 | 
			
		||||
		<td class="center">
 | 
			
		||||
			<span v-if="node.status.isActive" :class="{red:node.status.memUsage > 0.80}">{{node.status.memUsageText}}</span>
 | 
			
		||||
			<span v-else class="disabled">-</span>
 | 
			
		||||
		</td>
 | 
			
		||||
		<td>
 | 
			
		||||
		<td class="center">
 | 
			
		||||
			<div v-if="!node.isUp">
 | 
			
		||||
				<span class="red">健康问题</span>
 | 
			
		||||
			</div>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
 | 
			
		||||
	<div v-if="nodes.length > 0">
 | 
			
		||||
		<h3>所有未安装节点</h3>
 | 
			
		||||
		<table class="ui table selectable">
 | 
			
		||||
		<table class="ui table selectable celled">
 | 
			
		||||
			<thead>
 | 
			
		||||
				<tr>
 | 
			
		||||
					<th>节点名</th>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
 | 
			
		||||
	<div v-if="nodes.length > 0">
 | 
			
		||||
		<h3>所有未安装节点</h3>
 | 
			
		||||
		<table class="ui table selectable">
 | 
			
		||||
		<table class="ui table selectable celled">
 | 
			
		||||
			<thead>
 | 
			
		||||
				<tr>
 | 
			
		||||
					<th>节点名</th>
 | 
			
		||||
 
 | 
			
		||||
@@ -29,6 +29,12 @@
 | 
			
		||||
				</div>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tr v-if="dnsRoutes.length > 0">
 | 
			
		||||
			<td>DNS线路</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<span class="ui label tiny" v-for="route in dnsRoutes">{{route.name}}</span>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td>所属分组</td>
 | 
			
		||||
			<td>
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,13 @@
 | 
			
		||||
					<p class="comment">用于访问节点和域名解析等。</p>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
			<tr v-if="allDNSRoutes.length > 0">
 | 
			
		||||
				<td>DNS线路</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<input type="hidden" name="dnsDomainId" :value="dnsDomainId"/>
 | 
			
		||||
					<dns-route-selector :v-all-routes="allDNSRoutes" :v-routes="dnsRoutes"></dns-route-selector>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td>所属集群</td>
 | 
			
		||||
				<td>
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@
 | 
			
		||||
 | 
			
		||||
<form method="post" class="ui form" v-if="!isRequesting">
 | 
			
		||||
	<p>成功节点:<span class="green">{{countSuccess}}</span>   失败节点:<span class="red">{{countFail}}</span></p>
 | 
			
		||||
	<table class="ui table selectable">
 | 
			
		||||
	<table class="ui table selectable celled">
 | 
			
		||||
		<thead>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<th>节点</th>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
 | 
			
		||||
	<div v-if="nodes.length > 0">
 | 
			
		||||
		<h3>所有需要升级的节点</h3>
 | 
			
		||||
		<table class="ui table selectable">
 | 
			
		||||
		<table class="ui table selectable celled">
 | 
			
		||||
			<thead>
 | 
			
		||||
				<tr>
 | 
			
		||||
					<th>节点名</th>
 | 
			
		||||
 
 | 
			
		||||
@@ -3,28 +3,28 @@
 | 
			
		||||
 | 
			
		||||
<div class="ui message" v-if="grants.length == 0">暂时还没有认证信息。</div>
 | 
			
		||||
 | 
			
		||||
<table class="ui table selectable" v-if="grants.length > 0">
 | 
			
		||||
<table class="ui table selectable celled" v-if="grants.length > 0">
 | 
			
		||||
	<thead>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<th>ID</th>
 | 
			
		||||
			<th class="center">ID</th>
 | 
			
		||||
			<th>名称</th>
 | 
			
		||||
			<th>类型</th>
 | 
			
		||||
			<th>集群数</th>
 | 
			
		||||
			<th>节点数</th>
 | 
			
		||||
			<th class="center">集群数</th>
 | 
			
		||||
			<th class="center">节点数</th>
 | 
			
		||||
			<th class="two op">操作</th>
 | 
			
		||||
		</tr>
 | 
			
		||||
	</thead>
 | 
			
		||||
	<tr v-for="grant in grants">
 | 
			
		||||
		<td>{{grant.id}}</td>
 | 
			
		||||
		<td class="center">{{grant.id}}</td>
 | 
			
		||||
		<td>{{grant.name}}</td>
 | 
			
		||||
		<td>
 | 
			
		||||
			<span class="ui label tiny">{{grant.method.name}}</span>
 | 
			
		||||
		</td>
 | 
			
		||||
		<td>
 | 
			
		||||
		<td class="center">
 | 
			
		||||
			<span v-if="grant.countClusters > 0">{{grant.countClusters}}</span>
 | 
			
		||||
			<span v-else class="disabled">0</span>
 | 
			
		||||
		</td>
 | 
			
		||||
		<td>
 | 
			
		||||
		<td class="center">
 | 
			
		||||
			<span v-if="grant.countNodes > 0">{{grant.countNodes}}</span>
 | 
			
		||||
			<span v-else class="disabled">0</span>
 | 
			
		||||
		</td>
 | 
			
		||||
 
 | 
			
		||||
@@ -3,28 +3,31 @@
 | 
			
		||||
 | 
			
		||||
<p class="comment" v-if="clusters.length == 0">暂时还没有集群。</p>
 | 
			
		||||
 | 
			
		||||
<table class="ui table selectable" v-if="clusters.length > 0">
 | 
			
		||||
<table class="ui table selectable celled" v-if="clusters.length > 0">
 | 
			
		||||
	<thead>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<th>集群名称</th>
 | 
			
		||||
			<th>节点数量</th>
 | 
			
		||||
			<th>在线节点数量</th>
 | 
			
		||||
			<th>默认认证</th>
 | 
			
		||||
			<th class="center">节点数量</th>
 | 
			
		||||
			<th class="center">在线节点数量</th>
 | 
			
		||||
			<th>DNS域名</th>
 | 
			
		||||
			<th class="two op">操作</th>
 | 
			
		||||
		</tr>
 | 
			
		||||
	</thead>
 | 
			
		||||
	<tr v-for="cluster in clusters">
 | 
			
		||||
		<td>{{cluster.name}}</td>
 | 
			
		||||
		<td>
 | 
			
		||||
		<td class="center">
 | 
			
		||||
			<a :href="'/clusters/cluster?clusterId=' + cluster.id" v-if="cluster.countAllNodes > 0"><span :class="{red:cluster.countAllNodes > cluster.countActiveNodes}">{{cluster.countAllNodes}}</span></a>
 | 
			
		||||
			<span class="disabled" v-else="">-</span>
 | 
			
		||||
		</td>
 | 
			
		||||
		<td>
 | 
			
		||||
		<td class="center">
 | 
			
		||||
			<a :href="'/clusters/cluster?clusterId=' + cluster.id + '&activeState=1'" v-if="cluster.countActiveNodes > 0"><span class="green">{{cluster.countActiveNodes}}</span></a>
 | 
			
		||||
			<span class="disabled" v-else>-</span>
 | 
			
		||||
		</td>
 | 
			
		||||
		<td>
 | 
			
		||||
			<span v-if="cluster.grant != null">{{cluster.grant.name}}<span class="small">({{cluster.grant.methodName}})</span></span>
 | 
			
		||||
			<span v-if="cluster.dnsName.length > 0">
 | 
			
		||||
				<var>{{cluster.dnsName}}</var>.<span v-if="cluster.dnsDomainName.length > 0">{{cluster.dnsDomainName}}</span><span v-else class="disabled">主域名</span>
 | 
			
		||||
				<span v-if="cluster.dnsDomainId > 0"><link-icon :href="'/dns/clusters/cluster?clusterId=' + cluster.id"></link-icon></span>
 | 
			
		||||
			</span>
 | 
			
		||||
			<span v-else class="disabled">-</span>
 | 
			
		||||
		</td>
 | 
			
		||||
		<td>
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@
 | 
			
		||||
 | 
			
		||||
<p class="comment" v-if="nodes.length == 0">暂时还没有数据库节点。</p>
 | 
			
		||||
 | 
			
		||||
<table class="ui table selectable" v-if="nodes.length > 0">
 | 
			
		||||
<table class="ui table selectable celled" v-if="nodes.length > 0">
 | 
			
		||||
	<thead>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<th>节点名称</th>
 | 
			
		||||
 
 | 
			
		||||
@@ -46,7 +46,7 @@
 | 
			
		||||
 | 
			
		||||
<h3>节点DNS解析记录 <span>  ({{nodes.length}}个)</span></h3>
 | 
			
		||||
<p class="comment" v-if="nodes.length == 0">暂时没有需要设置的DNS记录。</p>
 | 
			
		||||
<table class="ui table selectable" v-if="nodes.length > 0">
 | 
			
		||||
<table class="ui table selectable celled" v-if="nodes.length > 0">
 | 
			
		||||
	<thead>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<th>节点</th>
 | 
			
		||||
@@ -80,7 +80,7 @@
 | 
			
		||||
 | 
			
		||||
<h3>代理服务解析记录 <span>  ({{servers.length}}个)</span></h3>
 | 
			
		||||
<p class="comment" v-if="servers.length == 0">暂时没有需要设置的DNS记录。</p>
 | 
			
		||||
<table class="ui table selectable" v-if="servers.length > 0">
 | 
			
		||||
<table class="ui table selectable celled" v-if="servers.length > 0">
 | 
			
		||||
	<thead>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<th>服务</th>
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,7 @@ Tea.context(function () {
 | 
			
		||||
 | 
			
		||||
	this.updateNode = function (nodeId) {
 | 
			
		||||
		teaweb.popup("/dns/issues/updateNodePopup?nodeId=" + nodeId, {
 | 
			
		||||
			height: "26em",
 | 
			
		||||
			callback: function () {
 | 
			
		||||
				teaweb.success("保存成功", function () {
 | 
			
		||||
					teaweb.reload()
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@
 | 
			
		||||
<div class="margin"></div>
 | 
			
		||||
 | 
			
		||||
<p class="comment" v-if="clusters.length == 0">暂时还没有集群。</p>
 | 
			
		||||
<table class="ui table selectable" v-if="clusters.length > 0">
 | 
			
		||||
<table class="ui table selectable celled" v-if="clusters.length > 0">
 | 
			
		||||
	<thead>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<th>集群</th>
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,7 @@
 | 
			
		||||
	<p class="comment">暂时没有发现问题。</p>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<table class="ui table selectable" v-if="issues.length > 0">
 | 
			
		||||
<table class="ui table selectable celled" v-if="issues.length > 0">
 | 
			
		||||
	<thead>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<th style="width: 50%">问题对象</th>
 | 
			
		||||
 
 | 
			
		||||
@@ -24,11 +24,11 @@
 | 
			
		||||
		<tr v-if="domainId > 0">
 | 
			
		||||
			<td>线路</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<p class="comment" v-if="routes.length == 0">没有可选的线路。</p>
 | 
			
		||||
				<select class="ui dropdown auto-width" name="route" v-if="routes.length > 0" v-model="route">
 | 
			
		||||
					<option v-for="route in routes" :value="route.code">{{route.name}}</option>
 | 
			
		||||
				</select>
 | 
			
		||||
				<p class="comment" v-if="routes.length > 0">当前节点IP对应的线路。</p>
 | 
			
		||||
				<p class="comment" v-if="allRoutes.length == 0">没有可选的线路。</p>
 | 
			
		||||
				<div v-if="allRoutes.length > 0">
 | 
			
		||||
					<dns-route-selector :v-all-routes="allRoutes" :v-routes="routes"></dns-route-selector>
 | 
			
		||||
					<p class="comment">当前节点IP对应的线路。</p>
 | 
			
		||||
				</div>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
	</table>
 | 
			
		||||
 
 | 
			
		||||
@@ -6,12 +6,12 @@
 | 
			
		||||
 | 
			
		||||
<p class="comment" v-if="providers.length == 0">暂时还没有第三方DNS服务商。</p>
 | 
			
		||||
 | 
			
		||||
<table class="ui table selectable" v-if="providers.length > 0">
 | 
			
		||||
<table class="ui table selectable celled" v-if="providers.length > 0">
 | 
			
		||||
	<thead>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<th>账号说明</th>
 | 
			
		||||
			<th>服务商</th>
 | 
			
		||||
			<th>域名</th>
 | 
			
		||||
			<th class="center">域名</th>
 | 
			
		||||
			<th>数据更新时间</th>
 | 
			
		||||
			<th class="two op">操作</th>
 | 
			
		||||
		</tr>
 | 
			
		||||
@@ -19,9 +19,9 @@
 | 
			
		||||
	<tr v-for="(provider, index) in providers">
 | 
			
		||||
		<td>{{provider.name}}</td>
 | 
			
		||||
		<td>{{provider.typeName}}</td>
 | 
			
		||||
		<td>
 | 
			
		||||
			<span v-if="provider.countDomains == 0" class="disabled">0个域名</span>
 | 
			
		||||
			<span v-else>{{provider.countDomains}}个域名</span>
 | 
			
		||||
		<td class="center">
 | 
			
		||||
			<span v-if="provider.countDomains == 0" class="disabled">0</span>
 | 
			
		||||
			<span v-else>{{provider.countDomains}}</span>
 | 
			
		||||
		</td>
 | 
			
		||||
		<td>
 | 
			
		||||
			<span v-if="provider.dataUpdatedTime.length > 0">{{provider.dataUpdatedTime}}</span>
 | 
			
		||||
 
 | 
			
		||||
@@ -48,7 +48,7 @@
 | 
			
		||||
<h3>管理的域名 <a href="" @click.prevent="createDomain()">[添加域名]</a> </h3>
 | 
			
		||||
<p class="comment" v-if="domains.length == 0">暂时还没有可以管理的域名。</p>
 | 
			
		||||
 | 
			
		||||
<table class="ui table selectable" v-if="domains.length > 0">
 | 
			
		||||
<table class="ui table selectable celled" v-if="domains.length > 0">
 | 
			
		||||
	<thead>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<th>域名</th>
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@
 | 
			
		||||
	</second-menu>
 | 
			
		||||
 | 
			
		||||
	<p class="comment" v-if="cachePolicies == null || cachePolicies.length == 0">暂时还没有缓存策略。</p>
 | 
			
		||||
	<table class="ui table selectable" v-if="cachePolicies != null && cachePolicies.length > 0">
 | 
			
		||||
	<table class="ui table selectable celled" v-if="cachePolicies != null && cachePolicies.length > 0">
 | 
			
		||||
		<thead>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<th>策略名称</th>
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@
 | 
			
		||||
	<p class="comment" v-if="groups.length == 0">暂时还没有分组。</p>
 | 
			
		||||
	<div v-show="groups.length > 0">
 | 
			
		||||
		<div class="margin"></div>
 | 
			
		||||
		<table class="ui table selectable" id="sortable-table">
 | 
			
		||||
		<table class="ui table selectable celled" id="sortable-table">
 | 
			
		||||
			<thead>
 | 
			
		||||
				<tr>
 | 
			
		||||
					<th style="width:3em"></th>
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@
 | 
			
		||||
	<p class="comment" v-if="libraries.length == 0">暂时还没有IP库。</p>
 | 
			
		||||
	<div v-if="libraries.length > 0">
 | 
			
		||||
		<div class="margin"></div>
 | 
			
		||||
		<table class="ui table selectable">
 | 
			
		||||
		<table class="ui table selectable celled">
 | 
			
		||||
			<thead>
 | 
			
		||||
				<tr>
 | 
			
		||||
					<th>文件名</th>
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@
 | 
			
		||||
	</second-menu>
 | 
			
		||||
 | 
			
		||||
	<p class="comment" v-if="certs.length == 0">暂时还没有相关的证书。</p>
 | 
			
		||||
	<table class="ui table selectable" v-if="certs.length > 0">
 | 
			
		||||
	<table class="ui table selectable celled" v-if="certs.length > 0">
 | 
			
		||||
		<thead>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<th>证书说明</th>
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
<h3>选择证书</h3>
 | 
			
		||||
<p class="comment" v-if="certs.length == 0">暂时还没有相关的证书。</p>
 | 
			
		||||
<table class="ui table selectable" v-if="certs.length > 0">
 | 
			
		||||
<table class="ui table selectable celled" v-if="certs.length > 0">
 | 
			
		||||
	<thead>
 | 
			
		||||
	<tr>
 | 
			
		||||
		<th>证书说明</th>
 | 
			
		||||
 
 | 
			
		||||
@@ -27,7 +27,7 @@
 | 
			
		||||
 | 
			
		||||
	<h3 style="padding-top:0.8em">规则集<a href="" @click.prevent="createSet(group.id)">[添加规则集]</a> </h3>
 | 
			
		||||
	<p class="comment" v-if="sets == null || sets.length == 0">暂时还没有规则。</p>
 | 
			
		||||
	<table class="ui table selectable" id="sortable-table" v-if="sets != null && sets.length > 0">
 | 
			
		||||
	<table class="ui table selectable celled" id="sortable-table" v-if="sets != null && sets.length > 0">
 | 
			
		||||
		<thead>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<th style="width:3em"></th>
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@
 | 
			
		||||
 | 
			
		||||
	<p class="comment" v-if="groups.length == 0">暂时还没有规则分组。</p>
 | 
			
		||||
 | 
			
		||||
	<table class="ui table selectable" v-if="groups.length > 0" id="sortable-table">
 | 
			
		||||
	<table class="ui table selectable celled" v-if="groups.length > 0" id="sortable-table">
 | 
			
		||||
		<thead>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<th style="width:3em"></th>
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@
 | 
			
		||||
 | 
			
		||||
	<p class="comment" v-if="policies.length == 0">暂时还没有WAF策略。</p>
 | 
			
		||||
 | 
			
		||||
	<table class="ui table selectable" v-if="policies.length > 0">
 | 
			
		||||
	<table class="ui table selectable celled" v-if="policies.length > 0">
 | 
			
		||||
		<thead>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<th>策略名称</th>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
 | 
			
		||||
	<p class="comment" v-if="items.length == 0">暂时还没有IP。</p>
 | 
			
		||||
 | 
			
		||||
	<table class="ui table selectable" v-if="items.length > 0">
 | 
			
		||||
	<table class="ui table selectable celled" v-if="items.length > 0">
 | 
			
		||||
		<thead>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<th>IP</th>
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,7 @@
 | 
			
		||||
 | 
			
		||||
<p class="ui message" v-if="servers.length == 0">暂时还没有服务。</p>
 | 
			
		||||
 | 
			
		||||
<table class="ui table selectable" v-if="servers.length > 0">
 | 
			
		||||
<table class="ui table selectable celled" v-if="servers.length > 0">
 | 
			
		||||
	<thead>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<th>服务名称</th>
 | 
			
		||||
@@ -32,7 +32,7 @@
 | 
			
		||||
			<th>部署集群</th>
 | 
			
		||||
			<th>域名</th>
 | 
			
		||||
			<th>端口</th>
 | 
			
		||||
			<th class="two wide">状态</th>
 | 
			
		||||
			<th class="two wide center">状态</th>
 | 
			
		||||
			<th class="two op">操作</th>
 | 
			
		||||
		</tr>
 | 
			
		||||
	</thead>
 | 
			
		||||
@@ -65,7 +65,7 @@
 | 
			
		||||
				<tiny-label>{{port.portRange}}<span class="small">({{port.protocol}})</span></tiny-label>
 | 
			
		||||
			</div>
 | 
			
		||||
		</td>
 | 
			
		||||
		<td>
 | 
			
		||||
		<td class="center">
 | 
			
		||||
			<label-on :v-is-on="server.isOn"></label-on>
 | 
			
		||||
		</td>
 | 
			
		||||
		<td>
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@
 | 
			
		||||
 | 
			
		||||
	<p class="comment" v-if="locations.length == 0">暂时还没有路径规则。</p>
 | 
			
		||||
 | 
			
		||||
	<table class="ui table selectable" v-if="locations.length > 0" id="sortable-table">
 | 
			
		||||
	<table class="ui table selectable celled" v-if="locations.length > 0" id="sortable-table">
 | 
			
		||||
		<thead>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<th style="width:1em"></th>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user