mirror of
				https://github.com/TeaOSLab/EdgeAdmin.git
				synced 2025-11-04 13:10:26 +08:00 
			
		
		
		
	实现基本的域名、记录管理
This commit is contained in:
		@@ -158,7 +158,7 @@ func AllModuleMaps() []maps.Map {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	if teaconst.IsPlus {
 | 
						if teaconst.IsPlus {
 | 
				
			||||||
		m = append(m, maps.Map{
 | 
							m = append(m, maps.Map{
 | 
				
			||||||
			"name": "域名服务器",
 | 
								"name": "域名服务",
 | 
				
			||||||
			"code": AdminModuleCodeNS,
 | 
								"code": AdminModuleCodeNS,
 | 
				
			||||||
			"url":  "/ns",
 | 
								"url":  "/ns",
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -360,6 +360,14 @@ func (this *RPCClient) NSNodeRPC() pb.NSNodeServiceClient {
 | 
				
			|||||||
	return pb.NewNSNodeServiceClient(this.pickConn())
 | 
						return pb.NewNSNodeServiceClient(this.pickConn())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *RPCClient) NSDomainRPC() pb.NSDomainServiceClient {
 | 
				
			||||||
 | 
						return pb.NewNSDomainServiceClient(this.pickConn())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *RPCClient) NSRecordRPC() pb.NSRecordServiceClient {
 | 
				
			||||||
 | 
						return pb.NewNSRecordServiceClient(this.pickConn())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Context 构造Admin上下文
 | 
					// Context 构造Admin上下文
 | 
				
			||||||
func (this *RPCClient) Context(adminId int64) context.Context {
 | 
					func (this *RPCClient) Context(adminId int64) context.Context {
 | 
				
			||||||
	ctx := context.Background()
 | 
						ctx := context.Background()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -37,6 +37,8 @@ func FailPage(action actions.ActionWrapper, err error) {
 | 
				
			|||||||
	<div style="background: #eee; border: 1px #ccc solid; padding: 10px; font-size: 12px; line-height: 1.8">
 | 
						<div style="background: #eee; border: 1px #ccc solid; padding: 10px; font-size: 12px; line-height: 1.8">
 | 
				
			||||||
	` + teaconst.ErrServer + `
 | 
						` + teaconst.ErrServer + `
 | 
				
			||||||
	<div>可以通过查看 <strong><em>$安装目录/logs/run.log</em></strong> 日志文件查看具体的错误提示。</div>
 | 
						<div>可以通过查看 <strong><em>$安装目录/logs/run.log</em></strong> 日志文件查看具体的错误提示。</div>
 | 
				
			||||||
 | 
						<hr style="border-top: 1px #ccc solid"/>
 | 
				
			||||||
 | 
						<div style="color: red">Error: ` + err.Error() + `</pre>
 | 
				
			||||||
	</div>
 | 
						</div>
 | 
				
			||||||
	</body>
 | 
						</body>
 | 
				
			||||||
</html>`)
 | 
					</html>`)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,6 +15,7 @@ func init() {
 | 
				
			|||||||
			Prefix("/ns/clusters").
 | 
								Prefix("/ns/clusters").
 | 
				
			||||||
			Get("", new(IndexAction)).
 | 
								Get("", new(IndexAction)).
 | 
				
			||||||
			GetPost("/create", new(CreateAction)).
 | 
								GetPost("/create", new(CreateAction)).
 | 
				
			||||||
 | 
								Post("/options", new(OptionsAction)).
 | 
				
			||||||
			EndAll()
 | 
								EndAll()
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										88
									
								
								internal/web/actions/default/ns/clusters/logs/index.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								internal/web/actions/default/ns/clusters/logs/index.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,88 @@
 | 
				
			|||||||
 | 
					package logs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/maps"
 | 
				
			||||||
 | 
						timeutil "github.com/iwind/TeaGo/utils/time"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type IndexAction struct {
 | 
				
			||||||
 | 
						actionutils.ParentAction
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *IndexAction) Init() {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *IndexAction) RunGet(params struct {
 | 
				
			||||||
 | 
						DayFrom string
 | 
				
			||||||
 | 
						DayTo   string
 | 
				
			||||||
 | 
						Keyword string
 | 
				
			||||||
 | 
						Level   string
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
 | 
						this.Data["dayFrom"] = params.DayFrom
 | 
				
			||||||
 | 
						this.Data["dayTo"] = params.DayTo
 | 
				
			||||||
 | 
						this.Data["keyword"] = params.Keyword
 | 
				
			||||||
 | 
						this.Data["level"] = params.Level
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						countResp, err := this.RPC().NodeLogRPC().CountNodeLogs(this.AdminContext(), &pb.CountNodeLogsRequest{
 | 
				
			||||||
 | 
							NodeId:  0,
 | 
				
			||||||
 | 
							Role:    nodeconfigs.NodeRoleDNS,
 | 
				
			||||||
 | 
							DayFrom: params.DayFrom,
 | 
				
			||||||
 | 
							DayTo:   params.DayTo,
 | 
				
			||||||
 | 
							Keyword: params.Keyword,
 | 
				
			||||||
 | 
							Level:   params.Level,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						count := countResp.Count
 | 
				
			||||||
 | 
						page := this.NewPage(count)
 | 
				
			||||||
 | 
						this.Data["page"] = page.AsHTML()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						logsResp, err := this.RPC().NodeLogRPC().ListNodeLogs(this.AdminContext(), &pb.ListNodeLogsRequest{
 | 
				
			||||||
 | 
							NodeId:  0,
 | 
				
			||||||
 | 
							Role:    nodeconfigs.NodeRoleDNS,
 | 
				
			||||||
 | 
							DayFrom: params.DayFrom,
 | 
				
			||||||
 | 
							DayTo:   params.DayTo,
 | 
				
			||||||
 | 
							Keyword: params.Keyword,
 | 
				
			||||||
 | 
							Level:   params.Level,
 | 
				
			||||||
 | 
							Offset:  page.Offset,
 | 
				
			||||||
 | 
							Size:    page.Size,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						logs := []maps.Map{}
 | 
				
			||||||
 | 
						for _, log := range logsResp.NodeLogs {
 | 
				
			||||||
 | 
							// 节点信息
 | 
				
			||||||
 | 
							nodeResp, err := this.RPC().NSNodeRPC().FindEnabledNSNode(this.AdminContext(), &pb.FindEnabledNSNodeRequest{NsNodeId: log.NodeId})
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							node := nodeResp.NsNode
 | 
				
			||||||
 | 
							if node == nil || node.NsCluster == nil {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							logs = append(logs, maps.Map{
 | 
				
			||||||
 | 
								"tag":         log.Tag,
 | 
				
			||||||
 | 
								"description": log.Description,
 | 
				
			||||||
 | 
								"createdTime": timeutil.FormatTime("Y-m-d H:i:s", log.CreatedAt),
 | 
				
			||||||
 | 
								"level":       log.Level,
 | 
				
			||||||
 | 
								"isToday":     timeutil.FormatTime("Y-m-d", log.CreatedAt) == timeutil.Format("Y-m-d"),
 | 
				
			||||||
 | 
								"count":       log.Count,
 | 
				
			||||||
 | 
								"node": maps.Map{
 | 
				
			||||||
 | 
									"id": node.Id,
 | 
				
			||||||
 | 
									"cluster": maps.Map{
 | 
				
			||||||
 | 
										"id":   node.NsCluster.Id,
 | 
				
			||||||
 | 
										"name": node.NsCluster.Name,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									"name": node.Name,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						this.Data["logs"] = logs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Show()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										19
									
								
								internal/web/actions/default/ns/clusters/logs/init.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								internal/web/actions/default/ns/clusters/logs/init.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					package logs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func init() {
 | 
				
			||||||
 | 
						TeaGo.BeforeStart(func(server *TeaGo.Server) {
 | 
				
			||||||
 | 
							server.
 | 
				
			||||||
 | 
								Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeNS)).
 | 
				
			||||||
 | 
								Data("teaMenu", "ns").
 | 
				
			||||||
 | 
								Data("teaSubMenu", "log").
 | 
				
			||||||
 | 
								Prefix("/ns/clusters/logs").
 | 
				
			||||||
 | 
								Get("", new(IndexAction)).
 | 
				
			||||||
 | 
								EndAll()
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										30
									
								
								internal/web/actions/default/ns/clusters/options.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								internal/web/actions/default/ns/clusters/options.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					package clusters
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/maps"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type OptionsAction struct {
 | 
				
			||||||
 | 
						actionutils.ParentAction
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *OptionsAction) RunPost(params struct{}) {
 | 
				
			||||||
 | 
						clustersResp, err := this.RPC().NSClusterRPC().FindAllEnabledNSClusters(this.AdminContext(), &pb.FindAllEnabledNSClustersRequest{})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						clusterMaps := []maps.Map{}
 | 
				
			||||||
 | 
						for _, cluster := range clustersResp.NsClusters {
 | 
				
			||||||
 | 
							clusterMaps = append(clusterMaps, maps.Map{
 | 
				
			||||||
 | 
								"id":   cluster.Id,
 | 
				
			||||||
 | 
								"name": cluster.Name,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						this.Data["clusters"] = clusterMaps
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Success()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										62
									
								
								internal/web/actions/default/ns/domains/create.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								internal/web/actions/default/ns/domains/create.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
				
			|||||||
 | 
					// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package domains
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"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"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type CreateAction struct {
 | 
				
			||||||
 | 
						actionutils.ParentAction
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *CreateAction) Init() {
 | 
				
			||||||
 | 
						this.Nav("", "", "create")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *CreateAction) RunGet(params struct{}) {
 | 
				
			||||||
 | 
						this.Show()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *CreateAction) RunPost(params struct {
 | 
				
			||||||
 | 
						Name      string
 | 
				
			||||||
 | 
						ClusterId int64
 | 
				
			||||||
 | 
						UserId    int64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Must *actions.Must
 | 
				
			||||||
 | 
						CSRF *actionutils.CSRF
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
 | 
						var domainId int64
 | 
				
			||||||
 | 
						defer func() {
 | 
				
			||||||
 | 
							this.CreateLogInfo("创建域名 %d", domainId)
 | 
				
			||||||
 | 
						}()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						params.Must.
 | 
				
			||||||
 | 
							Field("name", params.Name).
 | 
				
			||||||
 | 
							Require("请输入域名").
 | 
				
			||||||
 | 
							Expect(func() (message string, success bool) {
 | 
				
			||||||
 | 
								success = domainutils.ValidateDomainFormat(params.Name)
 | 
				
			||||||
 | 
								if !success {
 | 
				
			||||||
 | 
									message = "请输入正确的域名"
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}).
 | 
				
			||||||
 | 
							Field("clusterId", params.ClusterId).
 | 
				
			||||||
 | 
							Gt(0, "请选择所属集群")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						createResp, err := this.RPC().NSDomainRPC().CreateNSDomain(this.AdminContext(), &pb.CreateNSDomainRequest{
 | 
				
			||||||
 | 
							NsClusterId: params.ClusterId,
 | 
				
			||||||
 | 
							UserId:      params.UserId,
 | 
				
			||||||
 | 
							Name:        params.Name,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						domainId = createResp.NsDomainId
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Success()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										26
									
								
								internal/web/actions/default/ns/domains/delete.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								internal/web/actions/default/ns/domains/delete.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package domains
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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 {
 | 
				
			||||||
 | 
						DomainId int64
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
 | 
						defer this.CreateLogInfo("删除域名 %d", params.DomainId)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, err := this.RPC().NSDomainRPC().DeleteNSDomain(this.AdminContext(), &pb.DeleteNSDomainRequest{NsDomainId: params.DomainId})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Success()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										61
									
								
								internal/web/actions/default/ns/domains/domain.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								internal/web/actions/default/ns/domains/domain.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
				
			|||||||
 | 
					// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package domains
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/maps"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type DomainAction struct {
 | 
				
			||||||
 | 
						actionutils.ParentAction
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *DomainAction) Init() {
 | 
				
			||||||
 | 
						this.Nav("", "", "index")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *DomainAction) RunGet(params struct {
 | 
				
			||||||
 | 
						DomainId int64
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
 | 
						// 域名信息
 | 
				
			||||||
 | 
						domainResp, err := this.RPC().NSDomainRPC().FindEnabledNSDomain(this.AdminContext(), &pb.FindEnabledNSDomainRequest{NsDomainId: params.DomainId})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						domain := domainResp.NsDomain
 | 
				
			||||||
 | 
						if domain == nil {
 | 
				
			||||||
 | 
							this.NotFound("nsDomain", params.DomainId)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var clusterMap maps.Map
 | 
				
			||||||
 | 
						if domain.NsCluster != nil {
 | 
				
			||||||
 | 
							clusterMap = maps.Map{
 | 
				
			||||||
 | 
								"id":   domain.NsCluster.Id,
 | 
				
			||||||
 | 
								"name": domain.NsCluster.Name,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 用户信息
 | 
				
			||||||
 | 
						var userMap maps.Map
 | 
				
			||||||
 | 
						if domain.User != nil {
 | 
				
			||||||
 | 
							userMap = maps.Map{
 | 
				
			||||||
 | 
								"id":       domain.User.Id,
 | 
				
			||||||
 | 
								"username": domain.User.Username,
 | 
				
			||||||
 | 
								"fullname": domain.User.Fullname,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Data["domain"] = maps.Map{
 | 
				
			||||||
 | 
							"id":      domain.Id,
 | 
				
			||||||
 | 
							"name":    domain.Name,
 | 
				
			||||||
 | 
							"isOn":    domain.IsOn,
 | 
				
			||||||
 | 
							"cluster": clusterMap,
 | 
				
			||||||
 | 
							"user":    userMap,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Show()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,81 @@
 | 
				
			|||||||
 | 
					// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package records
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/dnsconfigs"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/actions"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/maps"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type CreatePopupAction struct {
 | 
				
			||||||
 | 
						actionutils.ParentAction
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *CreatePopupAction) Init() {
 | 
				
			||||||
 | 
						this.Nav("", "", "")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *CreatePopupAction) RunGet(params struct {
 | 
				
			||||||
 | 
						DomainId int64
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
 | 
						// 域名信息
 | 
				
			||||||
 | 
						domainResp, err := this.RPC().NSDomainRPC().FindEnabledNSDomain(this.AdminContext(), &pb.FindEnabledNSDomainRequest{NsDomainId: params.DomainId})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						domain := domainResp.NsDomain
 | 
				
			||||||
 | 
						if domain == nil {
 | 
				
			||||||
 | 
							this.NotFound("nsDomain", params.DomainId)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						this.Data["domain"] = maps.Map{
 | 
				
			||||||
 | 
							"id":   domain.Id,
 | 
				
			||||||
 | 
							"name": domain.Name,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 类型
 | 
				
			||||||
 | 
						this.Data["types"] = dnsconfigs.FindAllRecordTypeDefinitions()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// TTL
 | 
				
			||||||
 | 
						this.Data["ttlValues"] = dnsconfigs.FindAllRecordTTL()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Show()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *CreatePopupAction) RunPost(params struct {
 | 
				
			||||||
 | 
						DomainId    int64
 | 
				
			||||||
 | 
						Name        string
 | 
				
			||||||
 | 
						Type        string
 | 
				
			||||||
 | 
						Value       string
 | 
				
			||||||
 | 
						Ttl         int32
 | 
				
			||||||
 | 
						Description string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Must *actions.Must
 | 
				
			||||||
 | 
						CSRF *actionutils.CSRF
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
 | 
						var recordId int64
 | 
				
			||||||
 | 
						defer func() {
 | 
				
			||||||
 | 
							this.CreateLogInfo("创建域名记录 %d", recordId)
 | 
				
			||||||
 | 
						}()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						createResp, err := this.RPC().NSRecordRPC().CreateNSRecord(this.AdminContext(), &pb.CreateNSRecordRequest{
 | 
				
			||||||
 | 
							NsDomainId:  params.DomainId,
 | 
				
			||||||
 | 
							Description: params.Description,
 | 
				
			||||||
 | 
							Name:        params.Name,
 | 
				
			||||||
 | 
							Type:        params.Type,
 | 
				
			||||||
 | 
							Value:       params.Value,
 | 
				
			||||||
 | 
							Ttl:         params.Ttl,
 | 
				
			||||||
 | 
							NsRouteIds:  nil, // TODO 等待实现
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						recordId = createResp.NsRecordId
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Success()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										26
									
								
								internal/web/actions/default/ns/domains/records/delete.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								internal/web/actions/default/ns/domains/records/delete.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package records
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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 {
 | 
				
			||||||
 | 
						RecordId int64
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
 | 
						defer this.CreateLogInfo("删除域名记录 %d", params.RecordId)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, err := this.RPC().NSRecordRPC().DeleteNSRecord(this.AdminContext(), &pb.DeleteNSRecordRequest{NsRecordId: params.RecordId})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Success()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										96
									
								
								internal/web/actions/default/ns/domains/records/index.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								internal/web/actions/default/ns/domains/records/index.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,96 @@
 | 
				
			|||||||
 | 
					// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package records
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/maps"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type IndexAction struct {
 | 
				
			||||||
 | 
						actionutils.ParentAction
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *IndexAction) Init() {
 | 
				
			||||||
 | 
						this.Nav("", "", "record")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *IndexAction) RunGet(params struct {
 | 
				
			||||||
 | 
						DomainId int64
 | 
				
			||||||
 | 
						Type     string
 | 
				
			||||||
 | 
						Keyword  string
 | 
				
			||||||
 | 
						RouteId  int64 // TODO
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
 | 
						this.Data["type"] = params.Type
 | 
				
			||||||
 | 
						this.Data["keyword"] = params.Keyword
 | 
				
			||||||
 | 
						this.Data["routeId"] = params.RouteId
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 域名信息
 | 
				
			||||||
 | 
						domainResp, err := this.RPC().NSDomainRPC().FindEnabledNSDomain(this.AdminContext(), &pb.FindEnabledNSDomainRequest{NsDomainId: params.DomainId})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						domain := domainResp.NsDomain
 | 
				
			||||||
 | 
						if domain == nil {
 | 
				
			||||||
 | 
							this.NotFound("nsDomain", params.DomainId)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						this.Data["domain"] = maps.Map{
 | 
				
			||||||
 | 
							"id":   domain.Id,
 | 
				
			||||||
 | 
							"name": domain.Name,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 记录
 | 
				
			||||||
 | 
						countResp, err := this.RPC().NSRecordRPC().CountAllEnabledNSRecords(this.AdminContext(), &pb.CountAllEnabledNSRecordsRequest{
 | 
				
			||||||
 | 
							NsDomainId: params.DomainId,
 | 
				
			||||||
 | 
							Type:       params.Type,
 | 
				
			||||||
 | 
							NsRouteId:  params.RouteId,
 | 
				
			||||||
 | 
							Keyword:    params.Keyword,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						count := countResp.Count
 | 
				
			||||||
 | 
						page := this.NewPage(count)
 | 
				
			||||||
 | 
						this.Data["page"] = page.AsHTML()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						recordsResp, err := this.RPC().NSRecordRPC().ListEnabledNSRecords(this.AdminContext(), &pb.ListEnabledNSRecordsRequest{
 | 
				
			||||||
 | 
							NsDomainId: params.DomainId,
 | 
				
			||||||
 | 
							Type:       params.Type,
 | 
				
			||||||
 | 
							NsRouteId:  params.RouteId,
 | 
				
			||||||
 | 
							Keyword:    params.Keyword,
 | 
				
			||||||
 | 
							Offset:     page.Offset,
 | 
				
			||||||
 | 
							Size:       page.Size,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						var recordMaps = []maps.Map{}
 | 
				
			||||||
 | 
						for _, record := range recordsResp.NsRecords {
 | 
				
			||||||
 | 
							routeMaps := []maps.Map{}
 | 
				
			||||||
 | 
							for _, route := range record.NsRoutes {
 | 
				
			||||||
 | 
								routeMaps = append(routeMaps, maps.Map{
 | 
				
			||||||
 | 
									"id":   route.Id,
 | 
				
			||||||
 | 
									"name": route.Name,
 | 
				
			||||||
 | 
								})
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							recordMaps = append(recordMaps, maps.Map{
 | 
				
			||||||
 | 
								"id":          record.Id,
 | 
				
			||||||
 | 
								"name":        record.Name,
 | 
				
			||||||
 | 
								"type":        record.Type,
 | 
				
			||||||
 | 
								"value":       record.Value,
 | 
				
			||||||
 | 
								"ttl":         record.Ttl,
 | 
				
			||||||
 | 
								"weight":      record.Weight,
 | 
				
			||||||
 | 
								"description": record.Description,
 | 
				
			||||||
 | 
								"routes":      routeMaps,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						this.Data["records"] = recordMaps
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Show()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,98 @@
 | 
				
			|||||||
 | 
					// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package records
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/dnsconfigs"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/actions"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/maps"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type UpdatePopupAction struct {
 | 
				
			||||||
 | 
						actionutils.ParentAction
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *UpdatePopupAction) Init() {
 | 
				
			||||||
 | 
						this.Nav("", "", "")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *UpdatePopupAction) RunGet(params struct {
 | 
				
			||||||
 | 
						RecordId int64
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
 | 
						recordResp, err := this.RPC().NSRecordRPC().FindEnabledNSRecord(this.AdminContext(), &pb.FindEnabledNSRecordRequest{NsRecordId: params.RecordId})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						record := recordResp.NsRecord
 | 
				
			||||||
 | 
						if record == nil {
 | 
				
			||||||
 | 
							this.NotFound("nsRecord", params.RecordId)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Data["record"] = maps.Map{
 | 
				
			||||||
 | 
							"id":          record.Id,
 | 
				
			||||||
 | 
							"name":        record.Name,
 | 
				
			||||||
 | 
							"type":        record.Type,
 | 
				
			||||||
 | 
							"value":       record.Value,
 | 
				
			||||||
 | 
							"ttl":         record.Ttl,
 | 
				
			||||||
 | 
							"weight":      record.Weight,
 | 
				
			||||||
 | 
							"description": record.Description,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 域名信息
 | 
				
			||||||
 | 
						domainResp, err := this.RPC().NSDomainRPC().FindEnabledNSDomain(this.AdminContext(), &pb.FindEnabledNSDomainRequest{NsDomainId: record.NsDomain.Id})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						domain := domainResp.NsDomain
 | 
				
			||||||
 | 
						if domain == nil {
 | 
				
			||||||
 | 
							this.NotFound("nsDomain", record.NsDomain.Id)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						this.Data["domain"] = maps.Map{
 | 
				
			||||||
 | 
							"id":   domain.Id,
 | 
				
			||||||
 | 
							"name": domain.Name,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 类型
 | 
				
			||||||
 | 
						this.Data["types"] = dnsconfigs.FindAllRecordTypeDefinitions()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// TTL
 | 
				
			||||||
 | 
						this.Data["ttlValues"] = dnsconfigs.FindAllRecordTTL()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Show()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *UpdatePopupAction) RunPost(params struct {
 | 
				
			||||||
 | 
						RecordId    int64
 | 
				
			||||||
 | 
						Name        string
 | 
				
			||||||
 | 
						Type        string
 | 
				
			||||||
 | 
						Value       string
 | 
				
			||||||
 | 
						Ttl         int32
 | 
				
			||||||
 | 
						Description string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Must *actions.Must
 | 
				
			||||||
 | 
						CSRF *actionutils.CSRF
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
 | 
						this.CreateLogInfo("修改域名记录 %d", params.RecordId)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, err := this.RPC().NSRecordRPC().UpdateNSRecord(this.AdminContext(), &pb.UpdateNSRecordRequest{
 | 
				
			||||||
 | 
							NsRecordId:  params.RecordId,
 | 
				
			||||||
 | 
							Description: params.Description,
 | 
				
			||||||
 | 
							Name:        params.Name,
 | 
				
			||||||
 | 
							Type:        params.Type,
 | 
				
			||||||
 | 
							Value:       params.Value,
 | 
				
			||||||
 | 
							Ttl:         params.Ttl,
 | 
				
			||||||
 | 
							NsRouteIds:  nil, // TODO 等待实现
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Success()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										96
									
								
								internal/web/actions/default/ns/domains/update.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								internal/web/actions/default/ns/domains/update.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,96 @@
 | 
				
			|||||||
 | 
					// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package domains
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"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"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type UpdateAction struct {
 | 
				
			||||||
 | 
						actionutils.ParentAction
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *UpdateAction) Init() {
 | 
				
			||||||
 | 
						this.Nav("", "", "update")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *UpdateAction) RunGet(params struct {
 | 
				
			||||||
 | 
						DomainId int64
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
 | 
						// 域名信息
 | 
				
			||||||
 | 
						domainResp, err := this.RPC().NSDomainRPC().FindEnabledNSDomain(this.AdminContext(), &pb.FindEnabledNSDomainRequest{NsDomainId: params.DomainId})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						domain := domainResp.NsDomain
 | 
				
			||||||
 | 
						if domain == nil {
 | 
				
			||||||
 | 
							this.NotFound("nsDomain", params.DomainId)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var clusterId = int64(0)
 | 
				
			||||||
 | 
						if domain.NsCluster != nil {
 | 
				
			||||||
 | 
							clusterId = domain.NsCluster.Id
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 用户信息
 | 
				
			||||||
 | 
						var userId = int64(0)
 | 
				
			||||||
 | 
						if domain.User != nil {
 | 
				
			||||||
 | 
							userId = domain.User.Id
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Data["domain"] = maps.Map{
 | 
				
			||||||
 | 
							"id":        domain.Id,
 | 
				
			||||||
 | 
							"name":      domain.Name,
 | 
				
			||||||
 | 
							"isOn":      domain.IsOn,
 | 
				
			||||||
 | 
							"clusterId": clusterId,
 | 
				
			||||||
 | 
							"userId":    userId,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Show()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *UpdateAction) RunPost(params struct {
 | 
				
			||||||
 | 
						DomainId  int64
 | 
				
			||||||
 | 
						Name      string
 | 
				
			||||||
 | 
						ClusterId int64
 | 
				
			||||||
 | 
						UserId    int64
 | 
				
			||||||
 | 
						IsOn      bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Must *actions.Must
 | 
				
			||||||
 | 
						CSRF *actionutils.CSRF
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
 | 
						this.CreateLogInfo("修改域名 %d", params.DomainId)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						params.Must.
 | 
				
			||||||
 | 
							Field("name", params.Name).
 | 
				
			||||||
 | 
							Require("请输入域名").
 | 
				
			||||||
 | 
							Expect(func() (message string, success bool) {
 | 
				
			||||||
 | 
								success = domainutils.ValidateDomainFormat(params.Name)
 | 
				
			||||||
 | 
								if !success {
 | 
				
			||||||
 | 
									message = "请输入正确的域名"
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}).
 | 
				
			||||||
 | 
							Field("clusterId", params.ClusterId).
 | 
				
			||||||
 | 
							Gt(0, "请选择所属集群")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, err := this.RPC().NSDomainRPC().UpdateNSDomain(this.AdminContext(), &pb.UpdateNSDomainRequest{
 | 
				
			||||||
 | 
							NsDomainId:  params.DomainId,
 | 
				
			||||||
 | 
							NsClusterId: params.ClusterId,
 | 
				
			||||||
 | 
							UserId:      params.UserId,
 | 
				
			||||||
 | 
							Name:        params.Name,
 | 
				
			||||||
 | 
							IsOn:        params.IsOn,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Success()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -2,6 +2,8 @@ package ns
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/maps"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type IndexAction struct {
 | 
					type IndexAction struct {
 | 
				
			||||||
@@ -9,9 +11,80 @@ type IndexAction struct {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (this *IndexAction) Init() {
 | 
					func (this *IndexAction) Init() {
 | 
				
			||||||
 | 
						this.FirstMenu("index")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (this *IndexAction) RunGet(params struct{}) {
 | 
					func (this *IndexAction) RunGet(params struct {
 | 
				
			||||||
 | 
						ClusterId int64
 | 
				
			||||||
 | 
						UserId    int64
 | 
				
			||||||
 | 
						Keyword   string
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
 | 
						this.Data["clusterId"] = params.ClusterId
 | 
				
			||||||
 | 
						this.Data["userId"] = params.UserId
 | 
				
			||||||
 | 
						this.Data["keyword"] = params.Keyword
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 集群数量
 | 
				
			||||||
 | 
						countClustersResp, err := this.RPC().NSClusterRPC().CountAllEnabledNSClusters(this.AdminContext(), &pb.CountAllEnabledNSClustersRequest{})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						this.Data["countClusters"] = countClustersResp.Count
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 分页
 | 
				
			||||||
 | 
						countResp, err := this.RPC().NSDomainRPC().CountAllEnabledNSDomains(this.AdminContext(), &pb.CountAllEnabledNSDomainsRequest{
 | 
				
			||||||
 | 
							UserId:      params.UserId,
 | 
				
			||||||
 | 
							NsClusterId: params.ClusterId,
 | 
				
			||||||
 | 
							Keyword:     params.Keyword,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						page := this.NewPage(countResp.Count)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 列表
 | 
				
			||||||
 | 
						domainsResp, err := this.RPC().NSDomainRPC().ListEnabledNSDomains(this.AdminContext(), &pb.ListEnabledNSDomainsRequest{
 | 
				
			||||||
 | 
							UserId:      params.UserId,
 | 
				
			||||||
 | 
							NsClusterId: params.ClusterId,
 | 
				
			||||||
 | 
							Keyword:     params.Keyword,
 | 
				
			||||||
 | 
							Offset:      page.Offset,
 | 
				
			||||||
 | 
							Size:        page.Size,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						domainMaps := []maps.Map{}
 | 
				
			||||||
 | 
						for _, domain := range domainsResp.NsDomains {
 | 
				
			||||||
 | 
							// 集群信息
 | 
				
			||||||
 | 
							var clusterMap maps.Map
 | 
				
			||||||
 | 
							if domain.NsCluster != nil {
 | 
				
			||||||
 | 
								clusterMap = maps.Map{
 | 
				
			||||||
 | 
									"id":   domain.NsCluster.Id,
 | 
				
			||||||
 | 
									"name": domain.NsCluster.Name,
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// 用户信息
 | 
				
			||||||
 | 
							var userMap maps.Map
 | 
				
			||||||
 | 
							if domain.User != nil {
 | 
				
			||||||
 | 
								userMap = maps.Map{
 | 
				
			||||||
 | 
									"id":       domain.User.Id,
 | 
				
			||||||
 | 
									"username": domain.User.Username,
 | 
				
			||||||
 | 
									"fullname": domain.User.Fullname,
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							domainMaps = append(domainMaps, maps.Map{
 | 
				
			||||||
 | 
								"id":      domain.Id,
 | 
				
			||||||
 | 
								"name":    domain.Name,
 | 
				
			||||||
 | 
								"isOn":    domain.IsOn,
 | 
				
			||||||
 | 
								"cluster": clusterMap,
 | 
				
			||||||
 | 
								"user":    userMap,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						this.Data["domains"] = domainMaps
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	this.Show()
 | 
						this.Show()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,6 +2,8 @@ package ns
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/ns/domains"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/ns/domains/records"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
 | 
				
			||||||
	"github.com/iwind/TeaGo"
 | 
						"github.com/iwind/TeaGo"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -14,6 +16,20 @@ func init() {
 | 
				
			|||||||
			Prefix("/ns").
 | 
								Prefix("/ns").
 | 
				
			||||||
			Get("", new(IndexAction)).
 | 
								Get("", new(IndexAction)).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// 域名相关
 | 
				
			||||||
 | 
								Prefix("/ns/domains").
 | 
				
			||||||
 | 
								GetPost("/create", new(domains.CreateAction)).
 | 
				
			||||||
 | 
								Post("/delete", new(domains.DeleteAction)).
 | 
				
			||||||
 | 
								Get("/domain", new(domains.DomainAction)).
 | 
				
			||||||
 | 
								GetPost("/update", new(domains.UpdateAction)).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// 记录相关
 | 
				
			||||||
 | 
								Prefix("/ns/domains/records").
 | 
				
			||||||
 | 
								Get("", new(records.IndexAction)).
 | 
				
			||||||
 | 
								GetPost("/createPopup", new(records.CreatePopupAction)).
 | 
				
			||||||
 | 
								GetPost("/updatePopup", new(records.UpdatePopupAction)).
 | 
				
			||||||
 | 
								Post("/delete", new(records.DeleteAction)).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			EndAll()
 | 
								EndAll()
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										19
									
								
								internal/web/actions/default/ns/users/init.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								internal/web/actions/default/ns/users/init.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					package users
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func init() {
 | 
				
			||||||
 | 
						TeaGo.BeforeStart(func(server *TeaGo.Server) {
 | 
				
			||||||
 | 
							server.
 | 
				
			||||||
 | 
								Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeNS)).
 | 
				
			||||||
 | 
								Data("teaMenu", "ns").
 | 
				
			||||||
 | 
								Data("teaSubMenu", "domain").
 | 
				
			||||||
 | 
								Prefix("/ns/users").
 | 
				
			||||||
 | 
								Post("/options", new(OptionsAction)).
 | 
				
			||||||
 | 
								EndAll()
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										34
									
								
								internal/web/actions/default/ns/users/options.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								internal/web/actions/default/ns/users/options.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					package users
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/maps"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type OptionsAction struct {
 | 
				
			||||||
 | 
						actionutils.ParentAction
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *OptionsAction) RunPost(params struct{}) {
 | 
				
			||||||
 | 
						usersResp, err := this.RPC().UserRPC().ListEnabledUsers(this.AdminContext(), &pb.ListEnabledUsersRequest{
 | 
				
			||||||
 | 
							Offset: 0,
 | 
				
			||||||
 | 
							Size:   10000, // TODO 改进 <ns-user-selector> 组件
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						userMaps := []maps.Map{}
 | 
				
			||||||
 | 
						for _, user := range usersResp.Users {
 | 
				
			||||||
 | 
							userMaps = append(userMaps, maps.Map{
 | 
				
			||||||
 | 
								"id":       user.Id,
 | 
				
			||||||
 | 
								"fullname": user.Fullname,
 | 
				
			||||||
 | 
								"username": user.Username,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						this.Data["users"] = userMaps
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Success()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -27,7 +27,11 @@ func (this *IndexAction) RunGet(params struct {
 | 
				
			|||||||
	page := this.NewPage(count)
 | 
						page := this.NewPage(count)
 | 
				
			||||||
	this.Data["page"] = page.AsHTML()
 | 
						this.Data["page"] = page.AsHTML()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	usersResp, err := this.RPC().UserRPC().ListEnabledUsers(this.AdminContext(), &pb.ListEnabledUsersRequest{Keyword: params.Keyword})
 | 
						usersResp, err := this.RPC().UserRPC().ListEnabledUsers(this.AdminContext(), &pb.ListEnabledUsersRequest{
 | 
				
			||||||
 | 
							Keyword: params.Keyword,
 | 
				
			||||||
 | 
							Offset:  page.Offset,
 | 
				
			||||||
 | 
							Size:    page.Size,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		this.ErrorPage(err)
 | 
							this.ErrorPage(err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -220,7 +220,7 @@ func (this *userMustAuth) modules(adminId int64) []maps.Map {
 | 
				
			|||||||
		{
 | 
							{
 | 
				
			||||||
			"code":     "ns",
 | 
								"code":     "ns",
 | 
				
			||||||
			"module":   configloaders.AdminModuleCodeNS,
 | 
								"module":   configloaders.AdminModuleCodeNS,
 | 
				
			||||||
			"name":     "域名服务器",
 | 
								"name":     "域名服务",
 | 
				
			||||||
			"subtitle": "域名列表",
 | 
								"subtitle": "域名列表",
 | 
				
			||||||
			"icon":     "cubes",
 | 
								"icon":     "cubes",
 | 
				
			||||||
			"isOn":     teaconst.IsPlus,
 | 
								"isOn":     teaconst.IsPlus,
 | 
				
			||||||
@@ -232,7 +232,7 @@ func (this *userMustAuth) modules(adminId int64) []maps.Map {
 | 
				
			|||||||
				},
 | 
									},
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					"name": "节点日志",
 | 
										"name": "节点日志",
 | 
				
			||||||
					"url":  "/ns/logs",
 | 
										"url":  "/ns/clusters/logs",
 | 
				
			||||||
					"code": "log",
 | 
										"code": "log",
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -37,6 +37,8 @@ import (
 | 
				
			|||||||
	_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/ns/clusters"
 | 
						_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/ns/clusters"
 | 
				
			||||||
	_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/ns/clusters/cluster"
 | 
						_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/ns/clusters/cluster"
 | 
				
			||||||
	_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/ns/clusters/cluster/settings"
 | 
						_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/ns/clusters/cluster/settings"
 | 
				
			||||||
 | 
						_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/ns/clusters/logs"
 | 
				
			||||||
 | 
						_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/ns/users"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers"
 | 
						_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers"
 | 
				
			||||||
	_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/certs"
 | 
						_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/certs"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,6 +2,6 @@ Vue.component("not-found-box", {
 | 
				
			|||||||
	props: ["message"],
 | 
						props: ["message"],
 | 
				
			||||||
	template: `<div style="text-align: center; margin-top: 5em;">
 | 
						template: `<div style="text-align: center; margin-top: 5em;">
 | 
				
			||||||
	<div style="font-size: 2em; margin-bottom: 1em"><i class="icon exclamation triangle large grey"></i></div>
 | 
						<div style="font-size: 2em; margin-bottom: 1em"><i class="icon exclamation triangle large grey"></i></div>
 | 
				
			||||||
	<p class="comment">{{message}}</p>
 | 
						<p class="comment">{{message}}<slot></slot></p>
 | 
				
			||||||
</div>`
 | 
					</div>`
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
							
								
								
									
										28
									
								
								web/public/js/components/ns/ns-cluster-selector.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								web/public/js/components/ns/ns-cluster-selector.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
				
			|||||||
 | 
					Vue.component("ns-cluster-selector", {
 | 
				
			||||||
 | 
						mounted: function () {
 | 
				
			||||||
 | 
							let that = this
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Tea.action("/ns/clusters/options")
 | 
				
			||||||
 | 
								.post()
 | 
				
			||||||
 | 
								.success(function (resp) {
 | 
				
			||||||
 | 
									that.clusters = resp.data.clusters
 | 
				
			||||||
 | 
								})
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						props: ["v-cluster-id"],
 | 
				
			||||||
 | 
						data: function () {
 | 
				
			||||||
 | 
							let clusterId = this.vClusterId
 | 
				
			||||||
 | 
							if (clusterId == null) {
 | 
				
			||||||
 | 
								clusterId = 0
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return {
 | 
				
			||||||
 | 
								clusters: [],
 | 
				
			||||||
 | 
								clusterId: clusterId
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						template: `<div>
 | 
				
			||||||
 | 
						<select class="ui dropdown auto-width" name="clusterId" v-model="clusterId">
 | 
				
			||||||
 | 
							<option value="0">[选择集群]</option>
 | 
				
			||||||
 | 
							<option v-for="cluster in clusters" :value="cluster.id">{{cluster.name}}</option>
 | 
				
			||||||
 | 
						</select>
 | 
				
			||||||
 | 
					</div>`
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
							
								
								
									
										28
									
								
								web/public/js/components/ns/ns-user-selector.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								web/public/js/components/ns/ns-user-selector.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
				
			|||||||
 | 
					Vue.component("ns-user-selector", {
 | 
				
			||||||
 | 
						mounted: function () {
 | 
				
			||||||
 | 
							let that = this
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Tea.action("/ns/users/options")
 | 
				
			||||||
 | 
								.post()
 | 
				
			||||||
 | 
								.success(function (resp) {
 | 
				
			||||||
 | 
									that.users = resp.data.users
 | 
				
			||||||
 | 
								})
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						props: ["v-user-id"],
 | 
				
			||||||
 | 
						data: function () {
 | 
				
			||||||
 | 
							let userId = this.vUserId
 | 
				
			||||||
 | 
							if (userId == null) {
 | 
				
			||||||
 | 
								userId = 0
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return {
 | 
				
			||||||
 | 
								users: [],
 | 
				
			||||||
 | 
								userId: userId
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						template: `<div>
 | 
				
			||||||
 | 
						<select class="ui dropdown auto-width" name="userId" v-model="userId">
 | 
				
			||||||
 | 
							<option value="0">[选择用户]</option>
 | 
				
			||||||
 | 
							<option v-for="user in users" :value="user.id">{{user.fullname}} ({{user.username}})</option>
 | 
				
			||||||
 | 
						</select>
 | 
				
			||||||
 | 
					</div>`
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
							
								
								
									
										5
									
								
								web/views/@default/ns/@menu.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								web/views/@default/ns/@menu.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					<first-menu>
 | 
				
			||||||
 | 
					    <menu-item href="/ns" code="index">域名列表</menu-item>
 | 
				
			||||||
 | 
					    <menu-item href="/ns/domains/create" code="create">添加域名</menu-item>
 | 
				
			||||||
 | 
					</first-menu>
 | 
				
			||||||
 | 
					<div class="margin"></div>
 | 
				
			||||||
							
								
								
									
										5
									
								
								web/views/@default/ns/clusters/logs/index.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								web/views/@default/ns/clusters/logs/index.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					pre.log-box {
 | 
				
			||||||
 | 
					  margin: 0;
 | 
				
			||||||
 | 
					  padding: 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					/*# sourceMappingURL=index.css.map */
 | 
				
			||||||
							
								
								
									
										1
									
								
								web/views/@default/ns/clusters/logs/index.css.map
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								web/views/@default/ns/clusters/logs/index.css.map
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					{"version":3,"sources":["index.less"],"names":[],"mappings":"AAAA,GAAG;EACF,SAAA;EACA,UAAA","file":"index.css"}
 | 
				
			||||||
							
								
								
									
										62
									
								
								web/views/@default/ns/clusters/logs/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								web/views/@default/ns/clusters/logs/index.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
				
			|||||||
 | 
					{$layout}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{$var "header"}
 | 
				
			||||||
 | 
					<!-- datepicker -->
 | 
				
			||||||
 | 
					<script type="text/javascript" src="/js/moment.min.js"></script>
 | 
				
			||||||
 | 
					<script type="text/javascript" src="/js/pikaday.js"></script>
 | 
				
			||||||
 | 
					<link rel="stylesheet" href="/js/pikaday.css"/>
 | 
				
			||||||
 | 
					<link rel="stylesheet" href="/js/pikaday.theme.css"/>
 | 
				
			||||||
 | 
					<link rel="stylesheet" href="/js/pikaday.triangle.css"/>
 | 
				
			||||||
 | 
					{$end}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="margin"></div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<form method="get" action="/ns/clusters/logs" class="ui form" autocomplete="off">
 | 
				
			||||||
 | 
					    <div class="ui fields inline">
 | 
				
			||||||
 | 
					        <div class="ui field">
 | 
				
			||||||
 | 
					            <input type="text" name="dayFrom" placeholder="开始日期" v-model="dayFrom" value="" style="width:8em" id="day-from-picker"/>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="ui field">
 | 
				
			||||||
 | 
					            <input type="text" name="dayTo" placeholder="结束日期" v-model="dayTo" value="" style="width:8em" id="day-to-picker"/>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="ui field">
 | 
				
			||||||
 | 
					            <select class="ui dropdown" name="level" v-model="level">
 | 
				
			||||||
 | 
					                <option value="">[级别]</option>
 | 
				
			||||||
 | 
					                <option value="error">错误</option>
 | 
				
			||||||
 | 
					                <option value="warning">警告</option>
 | 
				
			||||||
 | 
					                <option value="info">信息</option>
 | 
				
			||||||
 | 
					            </select>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="ui field">
 | 
				
			||||||
 | 
					            <input type="text" name="keyword" style="width:10em" v-model="keyword" placeholder="关键词"/>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="ui field">
 | 
				
			||||||
 | 
					            <button type="submit" class="ui button">查询</button>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="ui field" v-if="dayFrom.length > 0 || dayTo.length > 0 || keyword.length > 0 || level.length > 0">
 | 
				
			||||||
 | 
					            <a href="/ns/clusters/logs">[清除条件]</a>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</form>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<p class="comment" v-if="logs.length == 0">暂时还没有日志。</p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<table class="ui table selectable celled" v-if="logs.length > 0">
 | 
				
			||||||
 | 
					    <thead>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					            <th>集群</th>
 | 
				
			||||||
 | 
					            <th>节点</th>
 | 
				
			||||||
 | 
					            <th>信息</th>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					    </thead>
 | 
				
			||||||
 | 
					    <tr v-for="log in logs">
 | 
				
			||||||
 | 
					        <td nowrap=""><link-icon :href="'/ns/clusters/cluster?clusterId=' + log.node.cluster.id">{{log.node.cluster.name}}</link-icon></td>
 | 
				
			||||||
 | 
					        <td nowrap=""><link-icon :href="'/ns/clusters/cluster/node?clusterId=' + log.node.cluster.id + '&nodeId=' + log.node.id">{{log.node.name}}</link-icon></td>
 | 
				
			||||||
 | 
					        <td>
 | 
				
			||||||
 | 
					            <pre class="log-box"><span :class="{red:log.level == 'error', orange:log.level == 'warning'}"><span v-if="!log.isToday">[{{log.createdTime}}]</span><strong v-if="log.isToday">[{{log.createdTime}}]</strong>[{{log.tag}}]{{log.description}}</span>   <span v-if="log.count > 0" class="ui label tiny" :class="{red:log.level == 'error', orange:log.level == 'warning'}">共{{log.count}}条</span></pre>
 | 
				
			||||||
 | 
					        </td>
 | 
				
			||||||
 | 
					    </tr>
 | 
				
			||||||
 | 
					</table>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="page" v-html="page"></div>
 | 
				
			||||||
							
								
								
									
										6
									
								
								web/views/@default/ns/clusters/logs/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								web/views/@default/ns/clusters/logs/index.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					Tea.context(function () {
 | 
				
			||||||
 | 
						this.$delay(function () {
 | 
				
			||||||
 | 
							teaweb.datepicker("day-from-picker")
 | 
				
			||||||
 | 
							teaweb.datepicker("day-to-picker")
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
							
								
								
									
										4
									
								
								web/views/@default/ns/clusters/logs/index.less
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								web/views/@default/ns/clusters/logs/index.less
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					pre.log-box {
 | 
				
			||||||
 | 
						margin: 0;
 | 
				
			||||||
 | 
						padding: 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										7
									
								
								web/views/@default/ns/domains/@domain_menu.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								web/views/@default/ns/domains/@domain_menu.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					<first-menu>
 | 
				
			||||||
 | 
					    <menu-item href="/ns">所有域名</menu-item>
 | 
				
			||||||
 | 
					    <span class="item disabled">|</span>
 | 
				
			||||||
 | 
					    <menu-item :href="'/ns/domains/domain?domainId=' + domain.id" code="index">详情<span class="grey small">({{domain.name}})</span></menu-item>
 | 
				
			||||||
 | 
					    <menu-item :href="'/ns/domains/records?domainId=' + domain.id" code="record">记录</menu-item>
 | 
				
			||||||
 | 
					    <menu-item :href="'/ns/domains/update?domainId=' + domain.id" code="update">修改</menu-item>
 | 
				
			||||||
 | 
					</first-menu>
 | 
				
			||||||
							
								
								
									
										27
									
								
								web/views/@default/ns/domains/create.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								web/views/@default/ns/domains/create.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					{$layout}
 | 
				
			||||||
 | 
					{$template "../menu"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<form class="ui form" data-tea-action="$" data-tea-success="success">
 | 
				
			||||||
 | 
					    <csrf-token></csrf-token>
 | 
				
			||||||
 | 
					    <table class="ui table definition selectable">
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					            <td>域名 *</td>
 | 
				
			||||||
 | 
					            <td>
 | 
				
			||||||
 | 
					                <input type="text" name="name" maxlength="255" ref="focus"/>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					            <td class="title">所属集群 *</td>
 | 
				
			||||||
 | 
					            <td>
 | 
				
			||||||
 | 
					                <ns-cluster-selector></ns-cluster-selector>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					            <td>所属用户</td>
 | 
				
			||||||
 | 
					            <td>
 | 
				
			||||||
 | 
					                <ns-user-selector></ns-user-selector>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					    </table>
 | 
				
			||||||
 | 
					    <submit-btn></submit-btn>
 | 
				
			||||||
 | 
					</form>
 | 
				
			||||||
							
								
								
									
										3
									
								
								web/views/@default/ns/domains/create.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								web/views/@default/ns/domains/create.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					Tea.context(function () {
 | 
				
			||||||
 | 
						this.success = NotifySuccess("保存成功", "/ns")
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
							
								
								
									
										30
									
								
								web/views/@default/ns/domains/domain.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								web/views/@default/ns/domains/domain.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					{$layout}
 | 
				
			||||||
 | 
					{$template "domain_menu"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<table class="ui table definition selectable">
 | 
				
			||||||
 | 
					    <tr>
 | 
				
			||||||
 | 
					        <td class="title">域名</td>
 | 
				
			||||||
 | 
					        <td>{{domain.name}}</td>
 | 
				
			||||||
 | 
					    </tr>
 | 
				
			||||||
 | 
					    <tr>
 | 
				
			||||||
 | 
					        <td>状态</td>
 | 
				
			||||||
 | 
					        <td>
 | 
				
			||||||
 | 
					            <label-on :v-is-on="domain.isOn"></label-on>
 | 
				
			||||||
 | 
					        </td>
 | 
				
			||||||
 | 
					    </tr>
 | 
				
			||||||
 | 
					    <tr>
 | 
				
			||||||
 | 
					        <td>所属集群</td>
 | 
				
			||||||
 | 
					        <td>
 | 
				
			||||||
 | 
					            {{domain.cluster.name}}<link-icon :href="'/ns/clusters/cluster?clusterId=' + domain.cluster.id"></link-icon>
 | 
				
			||||||
 | 
					        </td>
 | 
				
			||||||
 | 
					    </tr>
 | 
				
			||||||
 | 
					    <tr>
 | 
				
			||||||
 | 
					        <td>所属用户</td>
 | 
				
			||||||
 | 
					        <td>
 | 
				
			||||||
 | 
					            <span v-if="domain.user != null">
 | 
				
			||||||
 | 
					                {{domain.user.fullname}} ({{domain.user.username}})
 | 
				
			||||||
 | 
					            </span>
 | 
				
			||||||
 | 
					            <span v-else class="disabled">-</span>
 | 
				
			||||||
 | 
					        </td>
 | 
				
			||||||
 | 
					    </tr>
 | 
				
			||||||
 | 
					</table>
 | 
				
			||||||
							
								
								
									
										48
									
								
								web/views/@default/ns/domains/records/createPopup.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								web/views/@default/ns/domains/records/createPopup.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
				
			|||||||
 | 
					{$layout "layout_popup"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<h3>创建记录</h3>
 | 
				
			||||||
 | 
					<form class="ui form" data-tea-action="$" data-tea-success="success">
 | 
				
			||||||
 | 
					    <csrf-token></csrf-token>
 | 
				
			||||||
 | 
					    <input type="hidden" name="domainId" :value="domain.id"/>
 | 
				
			||||||
 | 
					    <table class="ui table definition selectable">
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					            <td class="title">记录名</td>
 | 
				
			||||||
 | 
					            <td>
 | 
				
			||||||
 | 
					                <div class="ui input right labeled">
 | 
				
			||||||
 | 
					                    <input type="text" name="name" ref="focus"/>
 | 
				
			||||||
 | 
					                    <span class="ui label">.{{domain.name}}</span>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					            <td>记录类型</td>
 | 
				
			||||||
 | 
					            <td>
 | 
				
			||||||
 | 
					                <select class="ui dropdown auto-width" name="type" v-model="type" @change="changeType">
 | 
				
			||||||
 | 
					                    <option v-for="t in types" :value="t.type">{{t.type}}</option>
 | 
				
			||||||
 | 
					                </select>
 | 
				
			||||||
 | 
					                <p class="comment">{{typeDescription}}</p>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					            <td>记录值</td>
 | 
				
			||||||
 | 
					            <td>
 | 
				
			||||||
 | 
					                <input type="text" name="value" maxlength="1024"/>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					            <td>TTL</td>
 | 
				
			||||||
 | 
					            <td>
 | 
				
			||||||
 | 
					                <select class="ui dropdown auto-width" name="ttl">
 | 
				
			||||||
 | 
					                    <option v-for="v in ttlValues" :value="v.value">{{v.name}}</option>
 | 
				
			||||||
 | 
					                </select>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					            <td>备注</td>
 | 
				
			||||||
 | 
					            <td>
 | 
				
			||||||
 | 
					                <textarea rows="2" name="description"></textarea>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					    </table>
 | 
				
			||||||
 | 
					    <submit-btn></submit-btn>
 | 
				
			||||||
 | 
					</form>
 | 
				
			||||||
							
								
								
									
										15
									
								
								web/views/@default/ns/domains/records/createPopup.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								web/views/@default/ns/domains/records/createPopup.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					Tea.context(function () {
 | 
				
			||||||
 | 
						this.type = "A"
 | 
				
			||||||
 | 
						this.typeDescription = ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.changeType = function () {
 | 
				
			||||||
 | 
							let that = this
 | 
				
			||||||
 | 
							this.types.forEach(function (v) {
 | 
				
			||||||
 | 
								if (v.type == that.type) {
 | 
				
			||||||
 | 
									that.typeDescription = v.description
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.changeType()
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
							
								
								
									
										37
									
								
								web/views/@default/ns/domains/records/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								web/views/@default/ns/domains/records/index.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					{$layout}
 | 
				
			||||||
 | 
					{$template "../domain_menu"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<second-menu>
 | 
				
			||||||
 | 
					    <menu-item @click.prevent="createRecord">[创建记录]</menu-item>
 | 
				
			||||||
 | 
					</second-menu>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<p class="comment" v-if="records.length == 0">暂时还没有记录。</p>
 | 
				
			||||||
 | 
					<table class="ui table selectable celled" v-if="records.length > 0">
 | 
				
			||||||
 | 
					    <thead>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					            <th>记录名</th>
 | 
				
			||||||
 | 
					            <th>记录类型</th>
 | 
				
			||||||
 | 
					            <th>记录值</th>
 | 
				
			||||||
 | 
					            <th>TTL</th>
 | 
				
			||||||
 | 
					            <th>线路</th>
 | 
				
			||||||
 | 
					            <th>备注</th>
 | 
				
			||||||
 | 
					            <th class="two op">操作</th>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					    </thead>
 | 
				
			||||||
 | 
					    <tr v-for="record in records">
 | 
				
			||||||
 | 
					        <td>{{record.name}}</td>
 | 
				
			||||||
 | 
					        <td>{{record.type}}</td>
 | 
				
			||||||
 | 
					        <td>{{record.value}}</td>
 | 
				
			||||||
 | 
					        <td>{{formatTTL(record.ttl)}}</td>
 | 
				
			||||||
 | 
					        <td>
 | 
				
			||||||
 | 
					            <span class="ui label basic text tiny" v-for="route in record.routes">{{route.name}}</span>
 | 
				
			||||||
 | 
					        </td>
 | 
				
			||||||
 | 
					        <td>{{record.description}}</td>
 | 
				
			||||||
 | 
					        <td>
 | 
				
			||||||
 | 
					            <a href="" @click.prevent="updateRecord(record.id)">修改</a>  
 | 
				
			||||||
 | 
					            <a href="" @click.prevent="deleteRecord(record.id)">删除</a>
 | 
				
			||||||
 | 
					        </td>
 | 
				
			||||||
 | 
					    </tr>
 | 
				
			||||||
 | 
					</table>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="page" v-html="page"></div>
 | 
				
			||||||
							
								
								
									
										50
									
								
								web/views/@default/ns/domains/records/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								web/views/@default/ns/domains/records/index.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,50 @@
 | 
				
			|||||||
 | 
					Tea.context(function () {
 | 
				
			||||||
 | 
						this.createRecord = function () {
 | 
				
			||||||
 | 
							teaweb.popup("/ns/domains/records/createPopup?domainId=" + this.domain.id, {
 | 
				
			||||||
 | 
								callback: function () {
 | 
				
			||||||
 | 
									teaweb.success("保存成功", function () {
 | 
				
			||||||
 | 
										teaweb.reload()
 | 
				
			||||||
 | 
									})
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.updateRecord = function (recordId) {
 | 
				
			||||||
 | 
							teaweb.popup("/ns/domains/records/updatePopup?recordId=" + recordId, {
 | 
				
			||||||
 | 
								callback: function () {
 | 
				
			||||||
 | 
									teaweb.success("保存成功", function () {
 | 
				
			||||||
 | 
										teaweb.reload()
 | 
				
			||||||
 | 
									})
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.deleteRecord = function (recordId) {
 | 
				
			||||||
 | 
							let that = this
 | 
				
			||||||
 | 
							teaweb.confirm("确定要删除此记录吗?", function () {
 | 
				
			||||||
 | 
								that.$post(".delete")
 | 
				
			||||||
 | 
									.params({
 | 
				
			||||||
 | 
										recordId: recordId
 | 
				
			||||||
 | 
									})
 | 
				
			||||||
 | 
									.success(function () {
 | 
				
			||||||
 | 
										teaweb.reload()
 | 
				
			||||||
 | 
									})
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.formatTTL = function (ttl) {
 | 
				
			||||||
 | 
							if (ttl % 86400 == 0) {
 | 
				
			||||||
 | 
								let days = ttl / 86400
 | 
				
			||||||
 | 
								return days + "天"
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (ttl % 3600 == 0) {
 | 
				
			||||||
 | 
								let hours = ttl / 3600
 | 
				
			||||||
 | 
								return hours + "小时"
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (ttl % 60 == 0) {
 | 
				
			||||||
 | 
								let minutes = ttl / 60
 | 
				
			||||||
 | 
								return minutes + "分钟"
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return ttl + "秒"
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
							
								
								
									
										48
									
								
								web/views/@default/ns/domains/records/updatePopup.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								web/views/@default/ns/domains/records/updatePopup.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
				
			|||||||
 | 
					{$layout "layout_popup"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<h3>创建记录</h3>
 | 
				
			||||||
 | 
					<form class="ui form" data-tea-action="$" data-tea-success="success">
 | 
				
			||||||
 | 
					    <csrf-token></csrf-token>
 | 
				
			||||||
 | 
					    <input type="hidden" name="recordId" :value="record.id"/>
 | 
				
			||||||
 | 
					    <table class="ui table definition selectable">
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					            <td class="title">记录名</td>
 | 
				
			||||||
 | 
					            <td>
 | 
				
			||||||
 | 
					                <div class="ui input right labeled">
 | 
				
			||||||
 | 
					                    <input type="text" name="name" ref="focus" v-model="record.name"/>
 | 
				
			||||||
 | 
					                    <span class="ui label">.{{domain.name}}</span>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					            <td>记录类型</td>
 | 
				
			||||||
 | 
					            <td>
 | 
				
			||||||
 | 
					                <select class="ui dropdown auto-width" name="type" v-model="type" @change="changeType">
 | 
				
			||||||
 | 
					                    <option v-for="t in types" :value="t.type">{{t.type}}</option>
 | 
				
			||||||
 | 
					                </select>
 | 
				
			||||||
 | 
					                <p class="comment">{{typeDescription}}</p>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					            <td>记录值</td>
 | 
				
			||||||
 | 
					            <td>
 | 
				
			||||||
 | 
					                <input type="text" name="value" maxlength="1024" v-model="record.value"/>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					            <td>TTL</td>
 | 
				
			||||||
 | 
					            <td>
 | 
				
			||||||
 | 
					                <select class="ui dropdown auto-width" name="ttl" v-model="record.ttl">
 | 
				
			||||||
 | 
					                    <option v-for="v in ttlValues" :value="v.value">{{v.name}}</option>
 | 
				
			||||||
 | 
					                </select>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					            <td>备注</td>
 | 
				
			||||||
 | 
					            <td>
 | 
				
			||||||
 | 
					                <textarea rows="2" name="description" v-model="record.description"></textarea>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					    </table>
 | 
				
			||||||
 | 
					    <submit-btn></submit-btn>
 | 
				
			||||||
 | 
					</form>
 | 
				
			||||||
							
								
								
									
										15
									
								
								web/views/@default/ns/domains/records/updatePopup.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								web/views/@default/ns/domains/records/updatePopup.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					Tea.context(function () {
 | 
				
			||||||
 | 
						this.type = this.record.type
 | 
				
			||||||
 | 
						this.typeDescription = ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.changeType = function () {
 | 
				
			||||||
 | 
							let that = this
 | 
				
			||||||
 | 
							this.types.forEach(function (v) {
 | 
				
			||||||
 | 
								if (v.type == that.type) {
 | 
				
			||||||
 | 
									that.typeDescription = v.description
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.changeType()
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
							
								
								
									
										39
									
								
								web/views/@default/ns/domains/update.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								web/views/@default/ns/domains/update.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
				
			|||||||
 | 
					{$layout}
 | 
				
			||||||
 | 
					{$template "domain_menu"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<form class="ui form" data-tea-action="$" data-tea-success="success">
 | 
				
			||||||
 | 
					    <csrf-token></csrf-token>
 | 
				
			||||||
 | 
					    <input type="hidden" name="domainId" :value="domain.id"/>
 | 
				
			||||||
 | 
					    <table class="ui table definition selectable">
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					            <td>域名 *</td>
 | 
				
			||||||
 | 
					            <td>
 | 
				
			||||||
 | 
					                <input type="text" name="name" maxlength="255" ref="focus" v-model="domain.name"/>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					            <td class="title">所属集群 *</td>
 | 
				
			||||||
 | 
					            <td>
 | 
				
			||||||
 | 
					                <ns-cluster-selector :v-cluster-id="domain.clusterId"></ns-cluster-selector>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					            <td>所属用户</td>
 | 
				
			||||||
 | 
					            <td>
 | 
				
			||||||
 | 
					                <ns-user-selector :v-user-id="domain.userId"></ns-user-selector>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					            <td colspan="2"><more-options-indicator></more-options-indicator></td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        <tbody v-show="moreOptionsVisible">
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <td>是否启用</td>
 | 
				
			||||||
 | 
					                <td>
 | 
				
			||||||
 | 
					                    <checkbox name="isOn" value="1" v-model="domain.isOn"></checkbox>
 | 
				
			||||||
 | 
					                </td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					        </tbody>
 | 
				
			||||||
 | 
					    </table>
 | 
				
			||||||
 | 
					    <submit-btn></submit-btn>
 | 
				
			||||||
 | 
					</form>
 | 
				
			||||||
							
								
								
									
										3
									
								
								web/views/@default/ns/domains/update.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								web/views/@default/ns/domains/update.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					Tea.context(function () {
 | 
				
			||||||
 | 
						this.success = NotifySuccess("保存成功", "/ns/domains/domain?domainId=" + this.domain.id)
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
@@ -1 +1,61 @@
 | 
				
			|||||||
{$layout}
 | 
					{$layout}
 | 
				
			||||||
 | 
					{$template "menu"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div v-if="countClusters == 0">
 | 
				
			||||||
 | 
					    <not-found-box>
 | 
				
			||||||
 | 
					        暂时还没有集群,请先 <a href="/ns/clusters">创建集群</a>。
 | 
				
			||||||
 | 
					    </not-found-box>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div v-if="countClusters > 0">
 | 
				
			||||||
 | 
					    <form class="ui form" method="get" action="/ns">
 | 
				
			||||||
 | 
					        <div class="ui fields inline">
 | 
				
			||||||
 | 
					            <div class="ui field">
 | 
				
			||||||
 | 
					                <ns-cluster-selector :v-cluster-id="clusterId"></ns-cluster-selector>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="ui field">
 | 
				
			||||||
 | 
					                <ns-user-selector :v-user-id="userId"></ns-user-selector>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="ui field">
 | 
				
			||||||
 | 
					                <input type="text" name="keyword" v-model="keyword" placeholder="域名、备注..."/>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="ui field">
 | 
				
			||||||
 | 
					                <button class="ui button" type="submit">搜索</button>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </form>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <div v-if="domains.length == 0">
 | 
				
			||||||
 | 
					        <div class="margin"></div>
 | 
				
			||||||
 | 
					        <p class="comment">暂时还没有域名。</p>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <!-- 域名列表 -->
 | 
				
			||||||
 | 
					    <table class="ui table selectable celled" v-if="domains.length > 0">
 | 
				
			||||||
 | 
					        <thead>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <th>域名</th>
 | 
				
			||||||
 | 
					                <th>集群</th>
 | 
				
			||||||
 | 
					                <th>用户</th>
 | 
				
			||||||
 | 
					                <th class="two wide">状态</th>
 | 
				
			||||||
 | 
					                <th class="two op">操作</th>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					        </thead>
 | 
				
			||||||
 | 
					        <tr v-for="domain in domains">
 | 
				
			||||||
 | 
					            <td>{{domain.name}}</td>
 | 
				
			||||||
 | 
					            <td>
 | 
				
			||||||
 | 
					                {{domain.cluster.name}}<link-icon :href="'/ns/clusters/cluster?clusterId=' + domain.cluster.id"></link-icon>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
 | 
					            <td>
 | 
				
			||||||
 | 
					                <span v-if="domain.user != null">
 | 
				
			||||||
 | 
					                    {{domain.user.fullname}} ({{domain.user.username}})
 | 
				
			||||||
 | 
					                </span>
 | 
				
			||||||
 | 
					                <span v-else class="disabled">-</span>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
 | 
					            <td><label-on :v-is-on="domain.isOn"></label-on></td>
 | 
				
			||||||
 | 
					            <td>
 | 
				
			||||||
 | 
					                <a :href="'/ns/domains/domain?domainId=' + domain.id">详情</a>   <a href="" @click.prevent="deleteDomain(domain.id)">删除</a>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					    </table>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
							
								
								
									
										14
									
								
								web/views/@default/ns/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								web/views/@default/ns/index.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					Tea.context(function () {
 | 
				
			||||||
 | 
						this.deleteDomain = function (domainId) {
 | 
				
			||||||
 | 
							let that = this
 | 
				
			||||||
 | 
							teaweb.confirm("确定要删除此域名吗?", function () {
 | 
				
			||||||
 | 
								that.$post("/ns/domains/delete")
 | 
				
			||||||
 | 
									.params({
 | 
				
			||||||
 | 
										domainId: domainId
 | 
				
			||||||
 | 
									})
 | 
				
			||||||
 | 
									.success(function () {
 | 
				
			||||||
 | 
										teaweb.reload()
 | 
				
			||||||
 | 
									})
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
@@ -22,7 +22,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
					<first-menu>
 | 
										<first-menu>
 | 
				
			||||||
						<menu-item><more-options-indicator>选择省份/自治区</more-options-indicator></menu-item>
 | 
											<menu-item><more-options-indicator>选择省份/自治区</more-options-indicator></menu-item>
 | 
				
			||||||
						<div class="item right" v-if="moreOptionsVisible">
 | 
											<div class="item right" v-show="moreOptionsVisible">
 | 
				
			||||||
							<div class="ui checkbox" @click.prevent="checkAll">
 | 
												<div class="ui checkbox" @click.prevent="checkAll">
 | 
				
			||||||
								<input type="checkbox" v-model="isCheckingAll"/>
 | 
													<input type="checkbox" v-model="isCheckingAll"/>
 | 
				
			||||||
								<label>全选</label>
 | 
													<label>全选</label>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,7 +25,7 @@
 | 
				
			|||||||
		<tr>
 | 
							<tr>
 | 
				
			||||||
			<td colspan="2"><more-options-indicator></more-options-indicator></td>
 | 
								<td colspan="2"><more-options-indicator></more-options-indicator></td>
 | 
				
			||||||
		</tr>
 | 
							</tr>
 | 
				
			||||||
		<tbody v-if="moreOptionsVisible">
 | 
							<tbody v-show="moreOptionsVisible">
 | 
				
			||||||
			<tr>
 | 
								<tr>
 | 
				
			||||||
				<td>子条件之间关系</td>
 | 
									<td>子条件之间关系</td>
 | 
				
			||||||
				<td>
 | 
									<td>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,7 +28,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
					<first-menu>
 | 
										<first-menu>
 | 
				
			||||||
						<menu-item><more-options-indicator>选择省份/自治区</more-options-indicator></menu-item>
 | 
											<menu-item><more-options-indicator>选择省份/自治区</more-options-indicator></menu-item>
 | 
				
			||||||
						<div class="item right" v-if="moreOptionsVisible">
 | 
											<div class="item right" v-show="moreOptionsVisible">
 | 
				
			||||||
							<div class="ui checkbox" @click.prevent="checkAll">
 | 
												<div class="ui checkbox" @click.prevent="checkAll">
 | 
				
			||||||
								<input type="checkbox" v-model="isCheckingAll"/>
 | 
													<input type="checkbox" v-model="isCheckingAll"/>
 | 
				
			||||||
								<label>全选</label>
 | 
													<label>全选</label>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user