mirror of
				https://github.com/TeaOSLab/EdgeAdmin.git
				synced 2025-11-04 05:00:25 +08:00 
			
		
		
		
	区域设置中增加节点快速设置区域的功能
This commit is contained in:
		@@ -11,7 +11,7 @@ type IndexAction struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *IndexAction) Init() {
 | 
			
		||||
	this.Nav("", "", "region")
 | 
			
		||||
	this.Nav("", "", "index")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *IndexAction) RunGet(params struct{}) {
 | 
			
		||||
@@ -20,7 +20,7 @@ func (this *IndexAction) RunGet(params struct{}) {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	regionMaps := []maps.Map{}
 | 
			
		||||
	var regionMaps = []maps.Map{}
 | 
			
		||||
	for _, region := range regionsResp.NodeRegions {
 | 
			
		||||
		countNodesResp, err := this.RPC().NodeRPC().CountAllEnabledNodesWithNodeRegionId(this.AdminContext(), &pb.CountAllEnabledNodesWithNodeRegionIdRequest{NodeRegionId: region.Id})
 | 
			
		||||
		if err != nil {
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,13 @@ func init() {
 | 
			
		||||
			GetPost("/updatePopup", new(UpdatePopupAction)).
 | 
			
		||||
			Post("/delete", new(DeleteAction)).
 | 
			
		||||
			Post("/sort", new(SortAction)).
 | 
			
		||||
			Get("/nodes", new(NodesAction)).
 | 
			
		||||
			GetPost("/updateNodeRegionPopup", new(UpdateNodeRegionPopupAction)).
 | 
			
		||||
 | 
			
		||||
			//
 | 
			
		||||
			GetPost("/selectPopup", new(SelectPopupAction)).
 | 
			
		||||
 | 
			
		||||
			//
 | 
			
		||||
			EndAll()
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										92
									
								
								internal/web/actions/default/clusters/regions/nodes.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								internal/web/actions/default/clusters/regions/nodes.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,92 @@
 | 
			
		||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
 | 
			
		||||
 | 
			
		||||
package regions
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
	"github.com/iwind/TeaGo/maps"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type NodesAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *NodesAction) Init() {
 | 
			
		||||
	this.Nav("", "", "node")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *NodesAction) RunGet(params struct {
 | 
			
		||||
	RegionId int64
 | 
			
		||||
}) {
 | 
			
		||||
	this.Data["regionId"] = params.RegionId
 | 
			
		||||
 | 
			
		||||
	// 所有区域
 | 
			
		||||
	regionsResp, err := this.RPC().NodeRegionRPC().FindAllAvailableNodeRegions(this.AdminContext(), &pb.FindAllAvailableNodeRegionsRequest{})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	var regionMaps = []maps.Map{}
 | 
			
		||||
	for _, region := range regionsResp.NodeRegions {
 | 
			
		||||
		regionMaps = append(regionMaps, maps.Map{
 | 
			
		||||
			"id":   region.Id,
 | 
			
		||||
			"name": region.Name,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["regions"] = regionMaps
 | 
			
		||||
 | 
			
		||||
	// 节点数量
 | 
			
		||||
	countResp, err := this.RPC().NodeRPC().CountAllNodeRegionInfo(this.AdminContext(), &pb.CountAllNodeRegionInfoRequest{NodeRegionId: params.RegionId})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	var page = this.NewPage(countResp.Count)
 | 
			
		||||
	this.Data["page"] = page.AsHTML()
 | 
			
		||||
 | 
			
		||||
	// 节点列表
 | 
			
		||||
	var hasNodesWithoutRegion = false
 | 
			
		||||
	nodesResp, err := this.RPC().NodeRPC().ListNodeRegionInfo(this.AdminContext(), &pb.ListNodeRegionInfoRequest{
 | 
			
		||||
		NodeRegionId: params.RegionId,
 | 
			
		||||
		Offset:       page.Offset,
 | 
			
		||||
		Size:         page.Size,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	var nodeMaps = []maps.Map{}
 | 
			
		||||
	for _, node := range nodesResp.InfoList {
 | 
			
		||||
		// region
 | 
			
		||||
		var regionMap maps.Map
 | 
			
		||||
		if node.NodeRegion != nil {
 | 
			
		||||
			regionMap = maps.Map{
 | 
			
		||||
				"id":   node.NodeRegion.Id,
 | 
			
		||||
				"name": node.NodeRegion.Name,
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			hasNodesWithoutRegion = true
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// cluster
 | 
			
		||||
		var clusterMap maps.Map
 | 
			
		||||
		if node.NodeCluster != nil {
 | 
			
		||||
			clusterMap = maps.Map{
 | 
			
		||||
				"id":   node.NodeCluster.Id,
 | 
			
		||||
				"name": node.NodeCluster.Name,
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		nodeMaps = append(nodeMaps, maps.Map{
 | 
			
		||||
			"id":      node.Id,
 | 
			
		||||
			"name":    node.Name,
 | 
			
		||||
			"region":  regionMap,
 | 
			
		||||
			"cluster": clusterMap,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["nodes"] = nodeMaps
 | 
			
		||||
	this.Data["hasNodesWithoutRegion"] = hasNodesWithoutRegion
 | 
			
		||||
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,97 @@
 | 
			
		||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
 | 
			
		||||
 | 
			
		||||
package regions
 | 
			
		||||
 | 
			
		||||
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 UpdateNodeRegionPopupAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *UpdateNodeRegionPopupAction) Init() {
 | 
			
		||||
	this.Nav("", "", "")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *UpdateNodeRegionPopupAction) RunGet(params struct {
 | 
			
		||||
	NodeId   int64
 | 
			
		||||
	RegionId int64
 | 
			
		||||
}) {
 | 
			
		||||
	// node
 | 
			
		||||
	nodeResp, err := this.RPC().NodeRPC().FindEnabledNode(this.AdminContext(), &pb.FindEnabledNodeRequest{NodeId: params.NodeId})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	var node = nodeResp.Node
 | 
			
		||||
	if node == nil {
 | 
			
		||||
		this.NotFound("node", params.NodeId)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["node"] = maps.Map{
 | 
			
		||||
		"id":   node.Id,
 | 
			
		||||
		"name": node.Name,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// region
 | 
			
		||||
	this.Data["region"] = maps.Map{
 | 
			
		||||
		"id":   0,
 | 
			
		||||
		"name": "",
 | 
			
		||||
	}
 | 
			
		||||
	if params.RegionId > 0 {
 | 
			
		||||
		regionResp, err := this.RPC().NodeRegionRPC().FindEnabledNodeRegion(this.AdminContext(), &pb.FindEnabledNodeRegionRequest{NodeRegionId: params.RegionId})
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			this.ErrorPage(err)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		var region = regionResp.NodeRegion
 | 
			
		||||
		if region != nil {
 | 
			
		||||
			this.Data["region"] = maps.Map{
 | 
			
		||||
				"id":   region.Id,
 | 
			
		||||
				"name": region.Name,
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// all regions
 | 
			
		||||
	regionsResp, err := this.RPC().NodeRegionRPC().FindAllAvailableNodeRegions(this.AdminContext(), &pb.FindAllAvailableNodeRegionsRequest{})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	var regionMaps = []maps.Map{}
 | 
			
		||||
	for _, region := range regionsResp.NodeRegions {
 | 
			
		||||
		regionMaps = append(regionMaps, maps.Map{
 | 
			
		||||
			"id":   region.Id,
 | 
			
		||||
			"name": region.Name,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["regions"] = regionMaps
 | 
			
		||||
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *UpdateNodeRegionPopupAction) RunPost(params struct {
 | 
			
		||||
	NodeId   int64
 | 
			
		||||
	RegionId int64
 | 
			
		||||
 | 
			
		||||
	Must *actions.Must
 | 
			
		||||
	CSRF *actionutils.CSRF
 | 
			
		||||
}) {
 | 
			
		||||
	defer this.CreateLogInfo("修改节点 %d 区域到 %d", params.RegionId)
 | 
			
		||||
 | 
			
		||||
	_, err := this.RPC().NodeRPC().UpdateNodeRegionInfo(this.AdminContext(), &pb.UpdateNodeRegionInfoRequest{
 | 
			
		||||
		NodeId:       params.NodeId,
 | 
			
		||||
		NodeRegionId: params.RegionId,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Success()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										4
									
								
								web/views/@default/clusters/regions/@menu.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								web/views/@default/clusters/regions/@menu.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
<first-menu>
 | 
			
		||||
    <menu-item href="." code="index">区域</menu-item>
 | 
			
		||||
    <menu-item href=".nodes" code="node">节点</menu-item>
 | 
			
		||||
</first-menu>
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
{$template "menu"}
 | 
			
		||||
 | 
			
		||||
<second-menu>
 | 
			
		||||
    <menu-item @click.prevent="createRegion()">[创建区域]</menu-item>
 | 
			
		||||
@@ -20,7 +21,9 @@
 | 
			
		||||
    <tbody v-for="region in regions" :v-id="region.id">
 | 
			
		||||
        <tr>
 | 
			
		||||
            <td style="text-align: center;"><i class="icon bars handle grey"></i> </td>
 | 
			
		||||
            <td :class="{disabled: !region.isOn}">{{region.name}}</td>
 | 
			
		||||
            <td :class="{disabled: !region.isOn}">
 | 
			
		||||
                <a :href="'/clusters/regions/nodes?regionId=' + region.id">{{region.name}}</a>
 | 
			
		||||
            </td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <span v-if="region.description.length > 0">{{region.description}}</span>
 | 
			
		||||
                <span v-else class="disabled">-</span>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										58
									
								
								web/views/@default/clusters/regions/nodes.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								web/views/@default/clusters/regions/nodes.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
{$template "menu"}
 | 
			
		||||
 | 
			
		||||
<form class="ui form" method="get" action="/clusters/regions/nodes" v-show="regions.length > 0">
 | 
			
		||||
    <div class="margin"></div>
 | 
			
		||||
    <div class="ui fields inline">
 | 
			
		||||
        <div class="ui field">
 | 
			
		||||
            <select class="ui dropdown" name="regionId" v-model="regionId">
 | 
			
		||||
                <option value="0">[所有区域]</option>
 | 
			
		||||
                <option v-for="region in regions" :value="region.id">{{region.name}}</option>
 | 
			
		||||
            </select>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="ui field">
 | 
			
		||||
            <button type="submit" class="ui button">搜索</button>
 | 
			
		||||
             
 | 
			
		||||
            <a href="/clusters/regions/nodes" v-if="regionId > 0">[清除条件]</a>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</form>
 | 
			
		||||
 | 
			
		||||
<div v-if="nodes.length == 0">
 | 
			
		||||
    <p class="comment"><span v-if="regionId > 0">当前区域下</span>暂时还没有节点。</p>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<div v-if="nodes.length > 0">
 | 
			
		||||
    <div class="margin"></div>
 | 
			
		||||
    <table class="ui table selectable celled">
 | 
			
		||||
        <thead>
 | 
			
		||||
            <tr>
 | 
			
		||||
                <th>节点</th>
 | 
			
		||||
                <th style="width: 30%">集群</th>
 | 
			
		||||
                <th style="width: 30%">区域</th>
 | 
			
		||||
                <th class="one op">操作</th>
 | 
			
		||||
            </tr>
 | 
			
		||||
        </thead>
 | 
			
		||||
        <tr v-for="node in nodes" v-if="node.cluster != null">
 | 
			
		||||
            <td>
 | 
			
		||||
                <link-icon :href="'/clusters/cluster/node/detail?clusterId=' + node.cluster.id + '&nodeId=' + node.id">{{node.name}}</link-icon>
 | 
			
		||||
            </td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <span v-if="node.cluster != null">{{node.cluster.name}}</span>
 | 
			
		||||
                <span v-else class="disabled">-</span>
 | 
			
		||||
            </td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <span v-if="node.region != null">{{node.region.name}}</span>
 | 
			
		||||
                <span v-else class="disabled">尚未设置</span>
 | 
			
		||||
            </td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <a href="" v-if="node.region == null" @click.prevent="updateNodeRegion(node)">设置</a>
 | 
			
		||||
                <a href="" v-if="node.region != null" @click.prevent="updateNodeRegion(node)">修改</a>
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
    </table>
 | 
			
		||||
 | 
			
		||||
    <p class="comment" v-if="hasNodesWithoutRegion">已经将未设置区域的节点排在了表格最前面。</p>
 | 
			
		||||
 | 
			
		||||
    <page-box></page-box>
 | 
			
		||||
</div>
 | 
			
		||||
							
								
								
									
										12
									
								
								web/views/@default/clusters/regions/nodes.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								web/views/@default/clusters/regions/nodes.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
Tea.context(function () {
 | 
			
		||||
	this.updateNodeRegion = function (node) {
 | 
			
		||||
		let nodeId = node.id
 | 
			
		||||
		let regionId = (node.region ? node.region.id : 0)
 | 
			
		||||
 | 
			
		||||
		teaweb.popup(Tea.url(".updateNodeRegionPopup", { nodeId: nodeId, regionId: regionId }), {
 | 
			
		||||
			callback: function () {
 | 
			
		||||
				teaweb.successRefresh("保存成功")
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
})
 | 
			
		||||
@@ -0,0 +1,28 @@
 | 
			
		||||
{$layout "layout_popup"}
 | 
			
		||||
 | 
			
		||||
<h3 v-if="region.id > 0">修改节点区域</h3>
 | 
			
		||||
<h3 v-if="region == null || region.id == 0">设置节点区域</h3>
 | 
			
		||||
 | 
			
		||||
<form class="ui form" data-tea-action="$" data-tea-success="success">
 | 
			
		||||
    <csrf-token></csrf-token>
 | 
			
		||||
 | 
			
		||||
    <input type="hidden" name="nodeId" :value="node.id"/>
 | 
			
		||||
 | 
			
		||||
    <table class="ui table definition selectable">
 | 
			
		||||
        <tr>
 | 
			
		||||
            <td class="title">节点</td>
 | 
			
		||||
            <td>{{node.name}}</td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tr>
 | 
			
		||||
            <td>区域 *</td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <select class="ui dropdown auto-width" name="regionId" v-model="region.id">
 | 
			
		||||
                    <option value="0">[选择区域]</option>
 | 
			
		||||
                    <option v-for="r in regions" :value="r.id">{{r.name}}</option>
 | 
			
		||||
                </select>
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
    </table>
 | 
			
		||||
    <submit-btn></submit-btn>
 | 
			
		||||
</form>
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user