diff --git a/internal/rpc/rpc_client.go b/internal/rpc/rpc_client.go index 2b1e2b52..f3d961af 100644 --- a/internal/rpc/rpc_client.go +++ b/internal/rpc/rpc_client.go @@ -368,6 +368,10 @@ func (this *RPCClient) NSRecordRPC() pb.NSRecordServiceClient { return pb.NewNSRecordServiceClient(this.pickConn()) } +func (this *RPCClient) NSRouteRPC() pb.NSRouteServiceClient { + return pb.NewNSRouteServiceClient(this.pickConn()) +} + // Context 构造Admin上下文 func (this *RPCClient) Context(adminId int64) context.Context { ctx := context.Background() diff --git a/internal/tasks/task_authority.go b/internal/tasks/task_authority.go index d6afd22f..0431e772 100644 --- a/internal/tasks/task_authority.go +++ b/internal/tasks/task_authority.go @@ -6,6 +6,7 @@ import ( teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const" "github.com/TeaOSLab/EdgeAdmin/internal/events" "github.com/TeaOSLab/EdgeAdmin/internal/rpc" + "github.com/TeaOSLab/EdgeAdmin/internal/setup" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/iwind/TeaGo/Tea" "github.com/iwind/TeaGo/logs" @@ -34,7 +35,7 @@ func (this *AuthorityTask) Start() { } // 初始化的时候先获取一次 - timeout := time.NewTimer(5 * time.Second) + timeout := time.NewTimer(3 * time.Second) <-timeout.C err := this.Loop() if err != nil { @@ -51,6 +52,11 @@ func (this *AuthorityTask) Start() { } func (this *AuthorityTask) Loop() error { + // 如果还没有安装直接返回 + if !setup.IsConfigured() { + return nil + } + rpcClient, err := rpc.SharedRPC() if err != nil { return err diff --git a/internal/tasks/task_sync_api_nodes.go b/internal/tasks/task_sync_api_nodes.go index 7763103e..5909a0f2 100644 --- a/internal/tasks/task_sync_api_nodes.go +++ b/internal/tasks/task_sync_api_nodes.go @@ -4,6 +4,7 @@ import ( "github.com/TeaOSLab/EdgeAdmin/internal/configs" "github.com/TeaOSLab/EdgeAdmin/internal/events" "github.com/TeaOSLab/EdgeAdmin/internal/rpc" + "github.com/TeaOSLab/EdgeAdmin/internal/setup" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/iwind/TeaGo/Tea" "github.com/iwind/TeaGo/logs" @@ -42,6 +43,11 @@ func (this *SyncAPINodesTask) Start() { } func (this *SyncAPINodesTask) Loop() error { + // 如果还没有安装直接返回 + if !setup.IsConfigured() { + return nil + } + // 获取所有可用的节点 rpcClient, err := rpc.SharedRPC() if err != nil { diff --git a/internal/tasks/task_sync_cluster.go b/internal/tasks/task_sync_cluster.go index ff8c1480..f1e2543c 100644 --- a/internal/tasks/task_sync_cluster.go +++ b/internal/tasks/task_sync_cluster.go @@ -20,7 +20,7 @@ func init() { }) } -// 自动同步集群任务 +// SyncClusterTask 自动同步集群任务 type SyncClusterTask struct { } diff --git a/internal/web/actions/default/ns/clusters/cluster/createNode.go b/internal/web/actions/default/ns/clusters/cluster/createNode.go index 8ce1ff37..7de50cb1 100644 --- a/internal/web/actions/default/ns/clusters/cluster/createNode.go +++ b/internal/web/actions/default/ns/clusters/cluster/createNode.go @@ -41,10 +41,18 @@ func (this *CreateNodeAction) RunPost(params struct { this.Fail("请至少添加一个IP地址") } - // TODO 检查cluster + // 检查cluster if params.ClusterId <= 0 { this.Fail("请选择所在集群") } + clusterResp, err := this.RPC().NSClusterRPC().FindEnabledNSCluster(this.AdminContext(), &pb.FindEnabledNSClusterRequest{NsClusterId: params.ClusterId}) + if err != nil { + this.ErrorPage(err) + return + } + if clusterResp.NsCluster == nil { + this.Fail("选择的集群不存在") + } // IP地址 ipAddresses := []maps.Map{} diff --git a/internal/web/actions/default/ns/clusters/cluster/node/update.go b/internal/web/actions/default/ns/clusters/cluster/node/update.go index a87ff565..3116ab90 100644 --- a/internal/web/actions/default/ns/clusters/cluster/node/update.go +++ b/internal/web/actions/default/ns/clusters/cluster/node/update.go @@ -113,10 +113,18 @@ func (this *UpdateAction) RunPost(params struct { Field("name", params.Name). Require("请输入节点名称") - // TODO 检查cluster + // 检查cluster if params.ClusterId <= 0 { this.Fail("请选择所在集群") } + clusterResp, err := this.RPC().NSClusterRPC().FindEnabledNSCluster(this.AdminContext(), &pb.FindEnabledNSClusterRequest{NsClusterId: params.ClusterId}) + if err != nil { + this.ErrorPage(err) + return + } + if clusterResp.NsCluster == nil { + this.Fail("选择的集群不存在") + } // IP地址 ipAddresses := []maps.Map{} @@ -132,7 +140,7 @@ func (this *UpdateAction) RunPost(params struct { } // 保存 - _, err := this.RPC().NSNodeRPC().UpdateNSNode(this.AdminContext(), &pb.UpdateNSNodeRequest{ + _, err = this.RPC().NSNodeRPC().UpdateNSNode(this.AdminContext(), &pb.UpdateNSNodeRequest{ NsNodeId: params.NodeId, Name: params.Name, NsClusterId: params.ClusterId, diff --git a/internal/web/actions/default/ns/domains/records/createPopup.go b/internal/web/actions/default/ns/domains/records/createPopup.go index d52707ca..d1e25d2e 100644 --- a/internal/web/actions/default/ns/domains/records/createPopup.go +++ b/internal/web/actions/default/ns/domains/records/createPopup.go @@ -53,6 +53,7 @@ func (this *CreatePopupAction) RunPost(params struct { Value string Ttl int32 Description string + RouteIds []int64 Must *actions.Must CSRF *actionutils.CSRF @@ -69,7 +70,7 @@ func (this *CreatePopupAction) RunPost(params struct { Type: params.Type, Value: params.Value, Ttl: params.Ttl, - NsRouteIds: nil, // TODO 等待实现 + NsRouteIds: params.RouteIds, }) if err != nil { this.ErrorPage(err) diff --git a/internal/web/actions/default/ns/domains/records/index.go b/internal/web/actions/default/ns/domains/records/index.go index 9cee4922..3124ef1b 100644 --- a/internal/web/actions/default/ns/domains/records/index.go +++ b/internal/web/actions/default/ns/domains/records/index.go @@ -4,6 +4,7 @@ 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/maps" ) @@ -20,7 +21,7 @@ func (this *IndexAction) RunGet(params struct { DomainId int64 Type string Keyword string - RouteId int64 // TODO + RouteId int64 }) { this.Data["type"] = params.Type this.Data["keyword"] = params.Keyword @@ -92,5 +93,8 @@ func (this *IndexAction) RunGet(params struct { } this.Data["records"] = recordMaps + // 所有记录类型 + this.Data["types"] = dnsconfigs.FindAllRecordTypeDefinitions() + this.Show() } diff --git a/internal/web/actions/default/ns/domains/records/updatePopup.go b/internal/web/actions/default/ns/domains/records/updatePopup.go index ab09394b..ecb4caca 100644 --- a/internal/web/actions/default/ns/domains/records/updatePopup.go +++ b/internal/web/actions/default/ns/domains/records/updatePopup.go @@ -32,6 +32,11 @@ func (this *UpdatePopupAction) RunGet(params struct { return } + routeIds := []int64{} + for _, route := range record.NsRoutes { + routeIds = append(routeIds, route.Id) + } + this.Data["record"] = maps.Map{ "id": record.Id, "name": record.Name, @@ -40,6 +45,7 @@ func (this *UpdatePopupAction) RunGet(params struct { "ttl": record.Ttl, "weight": record.Weight, "description": record.Description, + "routeIds": routeIds, } // 域名信息 @@ -74,6 +80,7 @@ func (this *UpdatePopupAction) RunPost(params struct { Value string Ttl int32 Description string + RouteIds []int64 Must *actions.Must CSRF *actionutils.CSRF @@ -87,7 +94,7 @@ func (this *UpdatePopupAction) RunPost(params struct { Type: params.Type, Value: params.Value, Ttl: params.Ttl, - NsRouteIds: nil, // TODO 等待实现 + NsRouteIds: params.RouteIds, }) if err != nil { this.ErrorPage(err) diff --git a/internal/web/actions/default/ns/routes/createPopup.go b/internal/web/actions/default/ns/routes/createPopup.go new file mode 100644 index 00000000..27b45808 --- /dev/null +++ b/internal/web/actions/default/ns/routes/createPopup.go @@ -0,0 +1,63 @@ +// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved. + +package clusters + +import ( + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/iwind/TeaGo/actions" +) + +type CreatePopupAction struct { + actionutils.ParentAction +} + +func (this *CreatePopupAction) Init() { +} + +func (this *CreatePopupAction) RunGet(params struct { + ClusterId int64 + DomainId int64 + UserId int64 +}) { + this.Data["clusterId"] = params.ClusterId + this.Data["domainId"] = params.DomainId + this.Data["userId"] = params.UserId + + this.Show() +} + +func (this *CreatePopupAction) RunPost(params struct { + ClusterId int64 + DomainId int64 + UserId int64 + + Name string + RangesJSON []byte + + Must *actions.Must + CSRF *actionutils.CSRF +}) { + var routeId = int64(0) + defer func() { + this.CreateLogInfo("创建域名服务线路 %d", routeId) + }() + + params.Must.Field("name", params.Name). + Require("请输入线路名称") + + createResp, err := this.RPC().NSRouteRPC().CreateNSRoute(this.AdminContext(), &pb.CreateNSRouteRequest{ + NsClusterId: params.ClusterId, + NsDomainId: params.DomainId, + UserId: params.UserId, + Name: params.Name, + RangesJSON: params.RangesJSON, + }) + if err != nil { + this.ErrorPage(err) + return + } + routeId = createResp.NsRouteId + + this.Success() +} diff --git a/internal/web/actions/default/ns/routes/delete.go b/internal/web/actions/default/ns/routes/delete.go new file mode 100644 index 00000000..839ad131 --- /dev/null +++ b/internal/web/actions/default/ns/routes/delete.go @@ -0,0 +1,26 @@ +// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved. + +package clusters + +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 { + RouteId int64 +}) { + defer this.CreateLogInfo("删除域名服务线路 %d", params.RouteId) + + _, err := this.RPC().NSRouteRPC().DeleteNSRoute(this.AdminContext(), &pb.DeleteNSRouteRequest{NsRouteId: params.RouteId}) + if err != nil { + this.ErrorPage(err) + return + } + + this.Success() +} diff --git a/internal/web/actions/default/ns/routes/index.go b/internal/web/actions/default/ns/routes/index.go new file mode 100644 index 00000000..a7a055e4 --- /dev/null +++ b/internal/web/actions/default/ns/routes/index.go @@ -0,0 +1,41 @@ +// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved. + +package clusters + +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("", "", "index") +} + +func (this *IndexAction) RunGet(params struct{}) { + routesResp, err := this.RPC().NSRouteRPC().FindAllEnabledNSRoutes(this.AdminContext(), &pb.FindAllEnabledNSRoutesRequest{ + NsClusterId: 0, + NsDomainId: 0, + UserId: 0, + }) + if err != nil { + this.ErrorPage(err) + return + } + + routeMaps := []maps.Map{} + for _, route := range routesResp.NsRoutes { + routeMaps = append(routeMaps, maps.Map{ + "id": route.Id, + "name": route.Name, + "isOn": route.IsOn, + }) + } + this.Data["routes"] = routeMaps + + this.Show() +} diff --git a/internal/web/actions/default/ns/routes/init.go b/internal/web/actions/default/ns/routes/init.go new file mode 100644 index 00000000..3beeaa73 --- /dev/null +++ b/internal/web/actions/default/ns/routes/init.go @@ -0,0 +1,25 @@ +package clusters + +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", "route"). + Prefix("/ns/routes"). + Get("", new(IndexAction)). + Get("/route", new(RouteAction)). + GetPost("/createPopup", new(CreatePopupAction)). + GetPost("/updatePopup", new(UpdatePopupAction)). + Post("/delete", new(DeleteAction)). + Post("/sort", new(SortAction)). + Post("/options", new(OptionsAction)). + EndAll() + }) +} diff --git a/internal/web/actions/default/ns/routes/options.go b/internal/web/actions/default/ns/routes/options.go new file mode 100644 index 00000000..d54aa114 --- /dev/null +++ b/internal/web/actions/default/ns/routes/options.go @@ -0,0 +1,40 @@ +// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved. + +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 { + ClusterId int64 + DomainId int64 + UserId int64 +}) { + routesResp, err := this.RPC().NSRouteRPC().FindAllEnabledNSRoutes(this.AdminContext(), &pb.FindAllEnabledNSRoutesRequest{ + NsClusterId: params.ClusterId, + NsDomainId: params.DomainId, + UserId: params.UserId, + }) + if err != nil { + this.ErrorPage(err) + return + } + + routeMaps := []maps.Map{} + for _, route := range routesResp.NsRoutes { + routeMaps = append(routeMaps, maps.Map{ + "id": route.Id, + "name": route.Name, + }) + } + this.Data["routes"] = routeMaps + + this.Success() +} diff --git a/internal/web/actions/default/ns/routes/route.go b/internal/web/actions/default/ns/routes/route.go new file mode 100644 index 00000000..03cc8a6c --- /dev/null +++ b/internal/web/actions/default/ns/routes/route.go @@ -0,0 +1,17 @@ +// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved. + +package clusters + +import "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + +type RouteAction struct { + actionutils.ParentAction +} + +func (this *RouteAction) Init() { + this.Nav("", "", "") +} + +func (this *RouteAction) RunGet(params struct{}) { + this.Show() +} diff --git a/internal/web/actions/default/ns/routes/sort.go b/internal/web/actions/default/ns/routes/sort.go new file mode 100644 index 00000000..6ca0338c --- /dev/null +++ b/internal/web/actions/default/ns/routes/sort.go @@ -0,0 +1,26 @@ +// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved. + +package clusters + +import ( + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" +) + +type SortAction struct { + actionutils.ParentAction +} + +func (this *SortAction) RunPost(params struct { + RouteIds []int64 +}) { + defer this.CreateLogInfo("对线路进行排序") + + _, err := this.RPC().NSRouteRPC().UpdateNSRouteOrders(this.AdminContext(), &pb.UpdateNSRouteOrdersRequest{NsRouteIds: params.RouteIds}) + if err != nil { + this.ErrorPage(err) + return + } + + this.Success() +} diff --git a/internal/web/actions/default/ns/routes/updatePopup.go b/internal/web/actions/default/ns/routes/updatePopup.go new file mode 100644 index 00000000..760809e9 --- /dev/null +++ b/internal/web/actions/default/ns/routes/updatePopup.go @@ -0,0 +1,78 @@ +// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved. + +package clusters + +import ( + "encoding/json" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "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 { + RouteId int64 +}) { + routeResp, err := this.RPC().NSRouteRPC().FindEnabledNSRoute(this.AdminContext(), &pb.FindEnabledNSRouteRequest{NsRouteId: params.RouteId}) + if err != nil { + this.ErrorPage(err) + return + } + route := routeResp.NsRoute + if route == nil { + this.NotFound("nsRoute", params.RouteId) + return + } + + rangeMaps := []maps.Map{} + if len(route.RangesJSON) > 0 { + err = json.Unmarshal([]byte(route.RangesJSON), &rangeMaps) + if err != nil { + this.ErrorPage(err) + return + } + } + + this.Data["route"] = maps.Map{ + "id": route.Id, + "name": route.Name, + "isOn": route.IsOn, + "ranges": rangeMaps, + } + + this.Show() +} + +func (this *UpdatePopupAction) RunPost(params struct { + RouteId int64 + Name string + RangesJSON []byte + + Must *actions.Must + CSRF *actionutils.CSRF +}) { + defer this.CreateLogInfo("修改域名线路 %d", params.RouteId) + + params.Must.Field("name", params.Name). + Require("请输入线路名称") + + _, err := this.RPC().NSRouteRPC().UpdateNSRoute(this.AdminContext(), &pb.UpdateNSRouteRequest{ + NsRouteId: params.RouteId, + Name: params.Name, + RangesJSON: params.RangesJSON, + }) + if err != nil { + this.ErrorPage(err) + return + } + + this.Success() +} diff --git a/internal/web/helpers/user_must_auth.go b/internal/web/helpers/user_must_auth.go index c330833d..b8e2ba03 100644 --- a/internal/web/helpers/user_must_auth.go +++ b/internal/web/helpers/user_must_auth.go @@ -230,6 +230,11 @@ func (this *userMustAuth) modules(adminId int64) []maps.Map { "url": "/ns/clusters", "code": "cluster", }, + { + "name": "线路管理", + "url": "/ns/routes", + "code": "route", + }, { "name": "节点日志", "url": "/ns/clusters/logs", diff --git a/internal/web/import.go b/internal/web/import.go index b0bd52fd..2ceec7ea 100644 --- a/internal/web/import.go +++ b/internal/web/import.go @@ -38,8 +38,10 @@ import ( _ "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/logs" + _ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/ns/routes" _ "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/certs" _ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components" @@ -95,6 +97,8 @@ import ( _ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/settings/web" _ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/settings/websocket" _ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/stat" + + // 设置相关 _ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings" _ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/authority" _ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/authority/nodes" diff --git a/web/public/js/components/ns/ns-route-ranges-box.js b/web/public/js/components/ns/ns-route-ranges-box.js new file mode 100644 index 00000000..3d6dbe94 --- /dev/null +++ b/web/public/js/components/ns/ns-route-ranges-box.js @@ -0,0 +1,103 @@ +Vue.component("ns-route-ranges-box", { + props: ["v-ranges"], + data: function () { + let ranges = this.vRanges + if (ranges == null) { + ranges = [] + } + return { + ranges: ranges, + isAdding: false, + + // IP范围 + ipRangeFrom: "", + ipRangeTo: "" + } + }, + methods: { + add: function () { + this.isAdding = true + let that = this + setTimeout(function () { + that.$refs.ipRangeFrom.focus() + }, 100) + }, + remove: function (index) { + this.ranges.$remove(index) + }, + cancelIPRange: function () { + this.isAdding = false + this.ipRangeFrom = "" + this.ipRangeTo = "" + }, + confirmIPRange: function () { + // 校验IP + let that = this + this.ipRangeFrom = this.ipRangeFrom.trim() + if (!this.validateIP(this.ipRangeFrom)) { + teaweb.warn("开始IP填写错误", function () { + that.$refs.ipRangeFrom.focus() + }) + return + } + + this.ipRangeTo = this.ipRangeTo.trim() + if (!this.validateIP(this.ipRangeTo)) { + teaweb.warn("结束IP填写错误", function () { + that.$refs.ipRangeTo.focus() + }) + return + } + + this.ranges.push({ + type: "ipRange", + ipFrom: this.ipRangeFrom, + ipTo: this.ipRangeTo + }) + this.cancelIPRange() + }, + validateIP: function (ip) { + if (!ip.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/)) { + return false + } + let pieces = ip.split(".") + let isOk = true + pieces.forEach(function (v) { + let v1 = parseInt(v) + if (v1 > 255) { + isOk = false + } + }) + return isOk + } + }, + template: `
+ +
+
+ IP范围: + {{range.ipFrom}} - {{range.ipTo}}   +
+
+
+ + +
+
+
+ +
+
-
+
+ +
+
+   + +
+
+
+ + +
` +}) \ No newline at end of file diff --git a/web/public/js/components/ns/ns-route-selector.js b/web/public/js/components/ns/ns-route-selector.js new file mode 100644 index 00000000..868c7ffd --- /dev/null +++ b/web/public/js/components/ns/ns-route-selector.js @@ -0,0 +1,30 @@ +// 选择单一线路 +Vue.component("ns-route-selector", { + props: ["v-route-id"], + mounted: function () { + let that = this + Tea.action("/ns/routes/options") + .post() + .success(function (resp) { + that.routes = resp.data.routes + }) + }, + data: function () { + let routeId = this.vRouteId + if (routeId == null) { + routeId = 0 + } + return { + routeId: routeId, + routes: [] + } + }, + template: `
+
+ +
+
` +}) \ No newline at end of file diff --git a/web/public/js/components/ns/ns-routes-selector.js b/web/public/js/components/ns/ns-routes-selector.js new file mode 100644 index 00000000..02205574 --- /dev/null +++ b/web/public/js/components/ns/ns-routes-selector.js @@ -0,0 +1,84 @@ +// 选择多个线路 +Vue.component("ns-routes-selector", { + props: ["v-route-ids"], + mounted: function () { + let that = this + + let routeIds = this.vRouteIds + if (routeIds == null) { + routeIds = [] + } + + Tea.action("/ns/routes/options") + .post() + .success(function (resp) { + that.allRoutes = resp.data.routes + that.allRoutes.forEach(function (v) { + v.isChecked = (routeIds.$contains(v.id)) + }) + }) + }, + data: function () { + return { + routeId: 0, + allRoutes: [], + routes: [], + isAdding: false + } + } + , + methods: { + add: function () { + this.isAdding = true + this.routes = this.allRoutes.$findAll(function (k, v) { + return !v.isChecked + }) + this.routeId = 0 + }, + cancel: function () { + this.isAdding = false + }, + confirm: function () { + if (this.routeId == 0) { + return + } + + let that = this + this.routes.forEach(function (v) { + if (v.id == that.routeId) { + v.isChecked = true + } + }) + this.cancel() + }, + remove: function (index) { + this.allRoutes[index].isChecked = false + Vue.set(this.allRoutes, index, this.allRoutes[index]) + } + } + , + template: `
+
+
+ + {{route.name}}   +
+
+
+
+
+
+ +
+
+ +   +
+
+
+ +
` +}) \ No newline at end of file diff --git a/web/views/@default/ns/domains/records/createPopup.html b/web/views/@default/ns/domains/records/createPopup.html index 3bbc84ce..6364b1e0 100644 --- a/web/views/@default/ns/domains/records/createPopup.html +++ b/web/views/@default/ns/domains/records/createPopup.html @@ -37,6 +37,12 @@ + + 线路 + + + + 备注 diff --git a/web/views/@default/ns/domains/records/index.html b/web/views/@default/ns/domains/records/index.html index 7822b34b..7da4a068 100644 --- a/web/views/@default/ns/domains/records/index.html +++ b/web/views/@default/ns/domains/records/index.html @@ -5,6 +5,27 @@ [创建记录] +
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+

暂时还没有记录。

@@ -24,7 +45,9 @@ + + + +
{{record.value}} {{formatTTL(record.ttl)}} - {{route.name}} +
+ {{route.name}} +
{{record.description}} diff --git a/web/views/@default/ns/domains/records/updatePopup.html b/web/views/@default/ns/domains/records/updatePopup.html index c2dede0b..50fe17e0 100644 --- a/web/views/@default/ns/domains/records/updatePopup.html +++ b/web/views/@default/ns/domains/records/updatePopup.html @@ -1,6 +1,6 @@ {$layout "layout_popup"} -

创建记录

+

修改记录

@@ -37,6 +37,12 @@
线路 + +
备注 diff --git a/web/views/@default/ns/routes/@menu.html b/web/views/@default/ns/routes/@menu.html new file mode 100644 index 00000000..2e0a2708 --- /dev/null +++ b/web/views/@default/ns/routes/@menu.html @@ -0,0 +1,4 @@ + + [创建线路] + +
\ No newline at end of file diff --git a/web/views/@default/ns/routes/createPopup.html b/web/views/@default/ns/routes/createPopup.html new file mode 100644 index 00000000..98e89577 --- /dev/null +++ b/web/views/@default/ns/routes/createPopup.html @@ -0,0 +1,26 @@ +{$layout "layout_popup"} + +

创建线路

+ + + + + + + + + + + + + + + +
线路名称 * + +
IP范围 + +
+ + + \ No newline at end of file diff --git a/web/views/@default/ns/routes/index.html b/web/views/@default/ns/routes/index.html new file mode 100644 index 00000000..19a7ccb4 --- /dev/null +++ b/web/views/@default/ns/routes/index.html @@ -0,0 +1,34 @@ +{$layout} +{$template "menu"} + +
+

暂时还没有线路。

+
+ +
+ + + + + + + + + + + + + + + + + +
线路名称状态操作
{{route.name}} + + + 修改   + 删除 +
+ +

可以拖动左侧的排序。

+
\ No newline at end of file diff --git a/web/views/@default/ns/routes/index.js b/web/views/@default/ns/routes/index.js new file mode 100644 index 00000000..f54991d6 --- /dev/null +++ b/web/views/@default/ns/routes/index.js @@ -0,0 +1,49 @@ +Tea.context(function () { + this.$delay(function () { + let that = this + sortTable(function (ids) { + that.$post(".sort") + .params({ + routeIds: ids + }) + .success(function () { + teaweb.successToast("排序保存成功") + }) + }) + }) + + this.createRoute = function () { + teaweb.popup("/ns/routes/createPopup", { + width: "42em", + callback: function () { + teaweb.success("保存成功", function () { + teaweb.reload() + }) + } + }) + } + + this.updateRoute = function (routeId) { + teaweb.popup("/ns/routes/updatePopup?routeId=" + routeId, { + width: "42em", + callback: function () { + teaweb.success("保存成功", function () { + teaweb.reload() + }) + } + }) + } + + this.deleteRoute = function (routeId) { + let that = this + teaweb.confirm("确定要删除此线路吗?", function () { + that.$post(".delete") + .params({ + routeId: routeId + }) + .success(function () { + teaweb.reload() + }) + }) + } +}) \ No newline at end of file diff --git a/web/views/@default/ns/routes/updatePopup.html b/web/views/@default/ns/routes/updatePopup.html new file mode 100644 index 00000000..3bf6bb02 --- /dev/null +++ b/web/views/@default/ns/routes/updatePopup.html @@ -0,0 +1,34 @@ +{$layout "layout_popup"} + +

修改线路

+
+ + + + + + + + + + + + + + + + + + + + +
线路名称 * + +
IP范围 + +
是否启用 + +
+ + +
\ No newline at end of file