mirror of
				https://github.com/TeaOSLab/EdgeAdmin.git
				synced 2025-11-04 13:10:26 +08:00 
			
		
		
		
	实现节点分组管理
This commit is contained in:
		@@ -82,6 +82,10 @@ func (this *RPCClient) NodeClusterRPC() pb.NodeClusterServiceClient {
 | 
				
			|||||||
	return pb.NewNodeClusterServiceClient(this.pickConn())
 | 
						return pb.NewNodeClusterServiceClient(this.pickConn())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *RPCClient) NodeGroupRPC() pb.NodeGroupServiceClient {
 | 
				
			||||||
 | 
						return pb.NewNodeGroupServiceClient(this.pickConn())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (this *RPCClient) NodeIPAddressRPC() pb.NodeIPAddressServiceClient {
 | 
					func (this *RPCClient) NodeIPAddressRPC() pb.NodeIPAddressServiceClient {
 | 
				
			||||||
	return pb.NewNodeIPAddressServiceClient(this.pickConn())
 | 
						return pb.NewNodeIPAddressServiceClient(this.pickConn())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,44 @@
 | 
				
			|||||||
 | 
					package groups
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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() {
 | 
				
			||||||
 | 
						this.Nav("", "", "")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *CreatePopupAction) RunGet(params struct{}) {
 | 
				
			||||||
 | 
						this.Show()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *CreatePopupAction) RunPost(params struct {
 | 
				
			||||||
 | 
						ClusterId int64
 | 
				
			||||||
 | 
						Name      string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Must *actions.Must
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
 | 
						if params.ClusterId <= 0 {
 | 
				
			||||||
 | 
							this.Fail("请选择集群")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						params.Must.
 | 
				
			||||||
 | 
							Field("name", params.Name).
 | 
				
			||||||
 | 
							Require("请输入分组名称")
 | 
				
			||||||
 | 
						_, err := this.RPC().NodeGroupRPC().CreateNodeGroup(this.AdminContext(), &pb.CreateNodeGroupRequest{
 | 
				
			||||||
 | 
							ClusterId: params.ClusterId,
 | 
				
			||||||
 | 
							Name:      params.Name,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Success()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,33 @@
 | 
				
			|||||||
 | 
					package groups
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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 {
 | 
				
			||||||
 | 
						GroupId int64
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
 | 
						// 检查是否正在使用
 | 
				
			||||||
 | 
						countResp, err := this.RPC().NodeRPC().CountAllEnabledNodesWithGroupId(this.AdminContext(), &pb.CountAllEnabledNodesWithGroupIdRequest{GroupId: params.GroupId})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if countResp.Count > 0 {
 | 
				
			||||||
 | 
							this.Fail("此分组正在被使用不能删除,请修改节点后再删除")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, err = this.RPC().NodeGroupRPC().DeleteNodeGroup(this.AdminContext(), &pb.DeleteNodeGroupRequest{GroupId: params.GroupId})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Success()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,47 @@
 | 
				
			|||||||
 | 
					package groups
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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("", "node", "group")
 | 
				
			||||||
 | 
						this.SecondMenu("nodes")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *IndexAction) RunGet(params struct {
 | 
				
			||||||
 | 
						ClusterId int64
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
 | 
						groupsResp, err := this.RPC().NodeGroupRPC().FindAllEnabledNodeGroupsWithClusterId(this.AdminContext(), &pb.FindAllEnabledNodeGroupsWithClusterIdRequest{
 | 
				
			||||||
 | 
							ClusterId: params.ClusterId,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						groupMaps := []maps.Map{}
 | 
				
			||||||
 | 
						for _, group := range groupsResp.Groups {
 | 
				
			||||||
 | 
							countResp, err := this.RPC().NodeRPC().CountAllEnabledNodesWithGroupId(this.AdminContext(), &pb.CountAllEnabledNodesWithGroupIdRequest{GroupId: group.Id})
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								this.ErrorPage(err)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							countNodes := countResp.Count
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							groupMaps = append(groupMaps, maps.Map{
 | 
				
			||||||
 | 
								"id":         group.Id,
 | 
				
			||||||
 | 
								"name":       group.Name,
 | 
				
			||||||
 | 
								"countNodes": countNodes,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						this.Data["groups"] = groupMaps
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Show()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										22
									
								
								internal/web/actions/default/clusters/cluster/groups/sort.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								internal/web/actions/default/clusters/cluster/groups/sort.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					package groups
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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 {
 | 
				
			||||||
 | 
						GroupIds []int64
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
 | 
						_, err := this.RPC().NodeGroupRPC().UpdateNodeGroupOrders(this.AdminContext(), &pb.UpdateNodeGroupOrdersRequest{GroupIds: params.GroupIds})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Success()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,59 @@
 | 
				
			|||||||
 | 
					package groups
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"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 {
 | 
				
			||||||
 | 
						GroupId int64
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
 | 
						groupResp, err := this.RPC().NodeGroupRPC().FindEnabledNodeGroup(this.AdminContext(), &pb.FindEnabledNodeGroupRequest{GroupId: params.GroupId})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						group := groupResp.Group
 | 
				
			||||||
 | 
						if group == nil {
 | 
				
			||||||
 | 
							this.NotFound("nodeGroup", params.GroupId)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Data["group"] = maps.Map{
 | 
				
			||||||
 | 
							"id":   group.Id,
 | 
				
			||||||
 | 
							"name": group.Name,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Show()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *UpdatePopupAction) RunPost(params struct {
 | 
				
			||||||
 | 
						GroupId int64
 | 
				
			||||||
 | 
						Name    string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Must *actions.Must
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
 | 
						params.Must.
 | 
				
			||||||
 | 
							Field("name", params.Name).
 | 
				
			||||||
 | 
							Require("请输入分组名称")
 | 
				
			||||||
 | 
						_, err := this.RPC().NodeGroupRPC().UpdateNodeGroup(this.AdminContext(), &pb.UpdateNodeGroupRequest{
 | 
				
			||||||
 | 
							GroupId: params.GroupId,
 | 
				
			||||||
 | 
							Name:    params.Name,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Success()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -25,14 +25,17 @@ func (this *IndexAction) RunGet(params struct {
 | 
				
			|||||||
	ClusterId      int64
 | 
						ClusterId      int64
 | 
				
			||||||
	InstalledState int
 | 
						InstalledState int
 | 
				
			||||||
	ActiveState    int
 | 
						ActiveState    int
 | 
				
			||||||
 | 
						Keyword        string
 | 
				
			||||||
}) {
 | 
					}) {
 | 
				
			||||||
	this.Data["installState"] = params.InstalledState
 | 
						this.Data["installState"] = params.InstalledState
 | 
				
			||||||
	this.Data["activeState"] = params.ActiveState
 | 
						this.Data["activeState"] = params.ActiveState
 | 
				
			||||||
 | 
						this.Data["keyword"] = params.Keyword
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	countResp, err := this.RPC().NodeRPC().CountAllEnabledNodesMatch(this.AdminContext(), &pb.CountAllEnabledNodesMatchRequest{
 | 
						countResp, err := this.RPC().NodeRPC().CountAllEnabledNodesMatch(this.AdminContext(), &pb.CountAllEnabledNodesMatchRequest{
 | 
				
			||||||
		ClusterId:    params.ClusterId,
 | 
							ClusterId:    params.ClusterId,
 | 
				
			||||||
		InstallState: types.Int32(params.InstalledState),
 | 
							InstallState: types.Int32(params.InstalledState),
 | 
				
			||||||
		ActiveState:  types.Int32(params.ActiveState),
 | 
							ActiveState:  types.Int32(params.ActiveState),
 | 
				
			||||||
 | 
							Keyword:      params.Keyword,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		this.ErrorPage(err)
 | 
							this.ErrorPage(err)
 | 
				
			||||||
@@ -48,6 +51,7 @@ func (this *IndexAction) RunGet(params struct {
 | 
				
			|||||||
		ClusterId:    params.ClusterId,
 | 
							ClusterId:    params.ClusterId,
 | 
				
			||||||
		InstallState: types.Int32(params.InstalledState),
 | 
							InstallState: types.Int32(params.InstalledState),
 | 
				
			||||||
		ActiveState:  types.Int32(params.ActiveState),
 | 
							ActiveState:  types.Int32(params.ActiveState),
 | 
				
			||||||
 | 
							Keyword:      params.Keyword,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	nodeMaps := []maps.Map{}
 | 
						nodeMaps := []maps.Map{}
 | 
				
			||||||
	for _, node := range nodesResp.Nodes {
 | 
						for _, node := range nodesResp.Nodes {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package cluster
 | 
					package cluster
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/groups"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node"
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node"
 | 
				
			||||||
	clusters "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/clusterutils"
 | 
						clusters "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/clusterutils"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
 | 
				
			||||||
@@ -34,6 +35,14 @@ func init() {
 | 
				
			|||||||
			Get("/node/logs", new(node.LogsAction)).
 | 
								Get("/node/logs", new(node.LogsAction)).
 | 
				
			||||||
			Post("/node/start", new(node.StartAction)).
 | 
								Post("/node/start", new(node.StartAction)).
 | 
				
			||||||
			Post("/node/stop", new(node.StopAction)).
 | 
								Post("/node/stop", new(node.StopAction)).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// 分组相关
 | 
				
			||||||
 | 
								Get("/groups", new(groups.IndexAction)).
 | 
				
			||||||
 | 
								GetPost("/groups/createPopup", new(groups.CreatePopupAction)).
 | 
				
			||||||
 | 
								GetPost("/groups/updatePopup", new(groups.UpdatePopupAction)).
 | 
				
			||||||
 | 
								Post("/groups/delete", new(groups.DeleteAction)).
 | 
				
			||||||
 | 
								Post("/groups/sort", new(groups.SortAction)).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			EndAll()
 | 
								EndAll()
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,7 +13,8 @@ type UpgradeRemoteAction struct {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (this *UpgradeRemoteAction) Init() {
 | 
					func (this *UpgradeRemoteAction) Init() {
 | 
				
			||||||
	this.Nav("", "", "")
 | 
						this.Nav("", "node", "install")
 | 
				
			||||||
 | 
						this.SecondMenu("nodes")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (this *UpgradeRemoteAction) RunGet(params struct {
 | 
					func (this *UpgradeRemoteAction) RunGet(params struct {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,4 +2,5 @@
 | 
				
			|||||||
	<menu-item :href="'/clusters/cluster?clusterId=' + clusterId" code="index">节点列表</menu-item>
 | 
						<menu-item :href="'/clusters/cluster?clusterId=' + clusterId" code="index">节点列表</menu-item>
 | 
				
			||||||
	<menu-item :href="'/clusters/cluster/createNode?clusterId=' + clusterId" code="create">创建节点</menu-item>
 | 
						<menu-item :href="'/clusters/cluster/createNode?clusterId=' + clusterId" code="create">创建节点</menu-item>
 | 
				
			||||||
	<menu-item :href="'/clusters/cluster/installManual?clusterId=' + clusterId" code="install">安装升级</menu-item>
 | 
						<menu-item :href="'/clusters/cluster/installManual?clusterId=' + clusterId" code="install">安装升级</menu-item>
 | 
				
			||||||
 | 
						<menu-item :href="'/clusters/cluster/groups?clusterId=' + clusterId" code="group">节点分组</menu-item>
 | 
				
			||||||
</second-menu>
 | 
					</second-menu>
 | 
				
			||||||
							
								
								
									
										15
									
								
								web/views/@default/clusters/cluster/groups/createPopup.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								web/views/@default/clusters/cluster/groups/createPopup.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					{$layout "layout_popup"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<h3>创建分组</h3>
 | 
				
			||||||
 | 
					<form class="ui form" data-tea-action="$" data-tea-success="success">
 | 
				
			||||||
 | 
						<input type="hidden" name="clusterId" :value="clusterId"/>
 | 
				
			||||||
 | 
						<table class="ui table definition selectable">
 | 
				
			||||||
 | 
							<tr>
 | 
				
			||||||
 | 
								<td>分组名称 *</td>
 | 
				
			||||||
 | 
								<td>
 | 
				
			||||||
 | 
									<input type="text" name="name" maxlength="50" ref="focus"/>
 | 
				
			||||||
 | 
								</td>
 | 
				
			||||||
 | 
							</tr>
 | 
				
			||||||
 | 
						</table>
 | 
				
			||||||
 | 
						<submit-btn></submit-btn>
 | 
				
			||||||
 | 
					</form>
 | 
				
			||||||
@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					Tea.context(function () {
 | 
				
			||||||
 | 
						this.success = NotifyPopup
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
							
								
								
									
										36
									
								
								web/views/@default/clusters/cluster/groups/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								web/views/@default/clusters/cluster/groups/index.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					{$layout}
 | 
				
			||||||
 | 
					{$template "../menu"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<first-menu style="margin-top:-1em">
 | 
				
			||||||
 | 
						<a href="" class="item" @click.prevent="createGroup()">[创建分组]</a>
 | 
				
			||||||
 | 
					</first-menu>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<p class="comment" v-if="groups.length == 0">暂时还没有分组。</p>
 | 
				
			||||||
 | 
					<div v-show="groups.length > 0">
 | 
				
			||||||
 | 
						<div class="margin"></div>
 | 
				
			||||||
 | 
						<table class="ui table selectable" id="sortable-table">
 | 
				
			||||||
 | 
							<thead>
 | 
				
			||||||
 | 
								<tr>
 | 
				
			||||||
 | 
									<th style="width:3em"></th>
 | 
				
			||||||
 | 
									<th>分组名称</th>
 | 
				
			||||||
 | 
									<th>节点数</th>
 | 
				
			||||||
 | 
									<th class="two op">操作</th>
 | 
				
			||||||
 | 
								</tr>
 | 
				
			||||||
 | 
							</thead>
 | 
				
			||||||
 | 
							<tbody v-for="group in groups" :data-group-id="group.id">
 | 
				
			||||||
 | 
								<tr>
 | 
				
			||||||
 | 
									<td style="text-align: center;"><i class="icon bars handle grey"></i> </td>
 | 
				
			||||||
 | 
									<td>{{group.name}}</td>
 | 
				
			||||||
 | 
									<td>
 | 
				
			||||||
 | 
										<span v-if="group.countNodes.length > 0">{{group.countNodes}}</span>
 | 
				
			||||||
 | 
										<span v-else class="disabled">0</span>
 | 
				
			||||||
 | 
									</td>
 | 
				
			||||||
 | 
									<td>
 | 
				
			||||||
 | 
										<a href="" @click.prevent="updateGroup(group.id)">修改</a>   <a href="" @click.prevent="deleteGroup(group.id)">删除</a>
 | 
				
			||||||
 | 
									</td>
 | 
				
			||||||
 | 
								</tr>
 | 
				
			||||||
 | 
							</tbody>
 | 
				
			||||||
 | 
						</table>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<p v-if="groups.length > 0" class="comment">可以拖动左侧的<i class="icon bars"></i>排序。</p>
 | 
				
			||||||
							
								
								
									
										53
									
								
								web/views/@default/clusters/cluster/groups/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								web/views/@default/clusters/cluster/groups/index.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
				
			|||||||
 | 
					Tea.context(function () {
 | 
				
			||||||
 | 
						this.$delay(function () {
 | 
				
			||||||
 | 
							let that = this
 | 
				
			||||||
 | 
							sortTable(function () {
 | 
				
			||||||
 | 
								let groupIds = []
 | 
				
			||||||
 | 
								document.querySelectorAll("*[data-group-id]").forEach(function (element) {
 | 
				
			||||||
 | 
									groupIds.push(element.getAttribute("data-group-id"))
 | 
				
			||||||
 | 
								})
 | 
				
			||||||
 | 
								that.$post("/clusters/cluster/groups/sort")
 | 
				
			||||||
 | 
									.params({
 | 
				
			||||||
 | 
										groupIds: groupIds
 | 
				
			||||||
 | 
									})
 | 
				
			||||||
 | 
									.success(function () {
 | 
				
			||||||
 | 
										teaweb.successToast("保存成功")
 | 
				
			||||||
 | 
									})
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.createGroup = function () {
 | 
				
			||||||
 | 
							teaweb.popup("/clusters/cluster/groups/createPopup?clusterId=" + this.clusterId, {
 | 
				
			||||||
 | 
								callback: function () {
 | 
				
			||||||
 | 
									teaweb.success("保存成功", function () {
 | 
				
			||||||
 | 
										teaweb.reload()
 | 
				
			||||||
 | 
									})
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.updateGroup = function (groupId) {
 | 
				
			||||||
 | 
							teaweb.popup("/clusters/cluster/groups/updatePopup?groupId=" + groupId, {
 | 
				
			||||||
 | 
								callback: function () {
 | 
				
			||||||
 | 
									teaweb.success("保存成功", function () {
 | 
				
			||||||
 | 
										teaweb.reload()
 | 
				
			||||||
 | 
									})
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.deleteGroup = function (groupId) {
 | 
				
			||||||
 | 
							let that = this
 | 
				
			||||||
 | 
							teaweb.confirm("确定要删除这个分组吗?", function () {
 | 
				
			||||||
 | 
								that.$post("/clusters/cluster/groups/delete")
 | 
				
			||||||
 | 
									.params({
 | 
				
			||||||
 | 
										groupId: groupId
 | 
				
			||||||
 | 
									})
 | 
				
			||||||
 | 
									.success(function () {
 | 
				
			||||||
 | 
										teaweb.success("删除成功", function () {
 | 
				
			||||||
 | 
											teaweb.reload()
 | 
				
			||||||
 | 
										})
 | 
				
			||||||
 | 
									})
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
							
								
								
									
										15
									
								
								web/views/@default/clusters/cluster/groups/updatePopup.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								web/views/@default/clusters/cluster/groups/updatePopup.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					{$layout "layout_popup"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<h3>修改分组</h3>
 | 
				
			||||||
 | 
					<form class="ui form" data-tea-action="$" data-tea-success="success">
 | 
				
			||||||
 | 
						<input type="hidden" name="groupId" :value="group.id"/>
 | 
				
			||||||
 | 
						<table class="ui table definition selectable">
 | 
				
			||||||
 | 
							<tr>
 | 
				
			||||||
 | 
								<td>分组名称 *</td>
 | 
				
			||||||
 | 
								<td>
 | 
				
			||||||
 | 
									<input type="text" name="name" maxlength="50" ref="focus" v-model="group.name"/>
 | 
				
			||||||
 | 
								</td>
 | 
				
			||||||
 | 
							</tr>
 | 
				
			||||||
 | 
						</table>
 | 
				
			||||||
 | 
						<submit-btn></submit-btn>
 | 
				
			||||||
 | 
					</form>
 | 
				
			||||||
@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					Tea.context(function () {
 | 
				
			||||||
 | 
						this.success = NotifyPopup
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
@@ -25,6 +25,9 @@
 | 
				
			|||||||
				<option value="2">不在线</option>
 | 
									<option value="2">不在线</option>
 | 
				
			||||||
			</select>
 | 
								</select>
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
 | 
							<div class="ui field">
 | 
				
			||||||
 | 
								<input type="text" name="keyword" placeholder="关键词" v-model="keyword" style="width:10em"/>
 | 
				
			||||||
 | 
							</div>
 | 
				
			||||||
		<div class="ui field">
 | 
							<div class="ui field">
 | 
				
			||||||
			<button class="ui button" type="submit">搜索</button>
 | 
								<button class="ui button" type="submit">搜索</button>
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,7 +10,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	<!-- 未安装 -->
 | 
						<!-- 未安装 -->
 | 
				
			||||||
	<div v-if="!node.isInstalled">
 | 
						<div v-if="!node.isInstalled">
 | 
				
			||||||
		<h3>方法1:自动安装</h3>
 | 
							<h3>方法1:通过SSH自动安装</h3>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		<div v-if="installStatus != null && (installStatus.isRunning || installStatus.isFinished)"
 | 
							<div v-if="installStatus != null && (installStatus.isRunning || installStatus.isFinished)"
 | 
				
			||||||
			 class="ui segment installing-box">
 | 
								 class="ui segment installing-box">
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user