mirror of
https://github.com/TeaOSLab/EdgeAdmin.git
synced 2025-11-03 20:40:26 +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