diff --git a/internal/rpc/rpc_client.go b/internal/rpc/rpc_client.go
index 5482c58f..eb7ef065 100644
--- a/internal/rpc/rpc_client.go
+++ b/internal/rpc/rpc_client.go
@@ -75,6 +75,10 @@ func (this *RPCClient) NodeRegionRPC() pb.NodeRegionServiceClient {
return pb.NewNodeRegionServiceClient(this.pickConn())
}
+func (this *RPCClient) NodePriceItemRPC() pb.NodePriceItemServiceClient {
+ return pb.NewNodePriceItemServiceClient(this.pickConn())
+}
+
func (this *RPCClient) NodeIPAddressRPC() pb.NodeIPAddressServiceClient {
return pb.NewNodeIPAddressServiceClient(this.pickConn())
}
diff --git a/internal/web/actions/default/clusters/regions/index.go b/internal/web/actions/default/clusters/regions/index.go
index 764d1fca..bb9fe74b 100644
--- a/internal/web/actions/default/clusters/regions/index.go
+++ b/internal/web/actions/default/clusters/regions/index.go
@@ -11,7 +11,7 @@ type IndexAction struct {
}
func (this *IndexAction) Init() {
- this.Nav("", "", "")
+ this.Nav("", "", "region")
}
func (this *IndexAction) RunGet(params struct{}) {
diff --git a/internal/web/actions/default/clusters/regions/init.go b/internal/web/actions/default/clusters/regions/init.go
index 3408aad4..24c8bf6a 100644
--- a/internal/web/actions/default/clusters/regions/init.go
+++ b/internal/web/actions/default/clusters/regions/init.go
@@ -19,6 +19,8 @@ func init() {
Post("/delete", new(DeleteAction)).
Post("/sort", new(SortAction)).
GetPost("/selectPopup", new(SelectPopupAction)).
+ GetPost("/prices", new(PricesAction)).
+ GetPost("/updatePricePopup", new(UpdatePricePopupAction)).
EndAll()
})
}
diff --git a/internal/web/actions/default/clusters/regions/items/createPopup.go b/internal/web/actions/default/clusters/regions/items/createPopup.go
new file mode 100644
index 00000000..badaf18e
--- /dev/null
+++ b/internal/web/actions/default/clusters/regions/items/createPopup.go
@@ -0,0 +1,50 @@
+package items
+
+import (
+ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
+ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/regions/regionutils"
+ "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 {
+ Name string
+ BitsFrom int64
+ BitsTo int64
+
+ Must *actions.Must
+ CSRF *actionutils.CSRF
+}) {
+ params.Must.
+ Field("name", params.Name).
+ Require("请输入名称").
+ Field("bitsFrom", params.BitsFrom).
+ Gte(0, "请输入不小于0的整数").
+ Field("bitsTo", params.BitsTo).
+ Gte(0, "请输入不小于0的整数")
+
+ createResp, err := this.RPC().NodePriceItemRPC().CreateNodePriceItem(this.AdminContext(), &pb.CreateNodePriceItemRequest{
+ Name: params.Name,
+ Type: regionutils.PriceTypeTraffic,
+ BitsFrom: params.BitsFrom * 1000 * 1000,
+ BitsTo: params.BitsTo * 1000 * 1000,
+ })
+ if err != nil {
+ this.ErrorPage(err)
+ return
+ }
+ defer this.CreateLogInfo("创建流量价格项目", createResp.NodePriceItemId)
+ this.Success()
+}
diff --git a/internal/web/actions/default/clusters/regions/items/delete.go b/internal/web/actions/default/clusters/regions/items/delete.go
new file mode 100644
index 00000000..81fd965a
--- /dev/null
+++ b/internal/web/actions/default/clusters/regions/items/delete.go
@@ -0,0 +1,24 @@
+package items
+
+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 {
+ ItemId int64
+}) {
+ defer this.CreateLogInfo("删除流量价格项目 %d", params.ItemId)
+
+ _, err := this.RPC().NodePriceItemRPC().DeleteNodePriceItem(this.AdminContext(), &pb.DeleteNodePriceItemRequest{NodePriceItemId: params.ItemId})
+ if err != nil {
+ this.ErrorPage(err)
+ return
+ }
+
+ this.Success()
+}
diff --git a/internal/web/actions/default/clusters/regions/items/init.go b/internal/web/actions/default/clusters/regions/items/init.go
new file mode 100644
index 00000000..a18c92e6
--- /dev/null
+++ b/internal/web/actions/default/clusters/regions/items/init.go
@@ -0,0 +1,21 @@
+package items
+
+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.AdminModuleCodeNode)).
+ Data("teaMenu", "clusters").
+ Data("teaSubMenu", "region").
+ Prefix("/clusters/regions/items").
+ GetPost("/createPopup", new(CreatePopupAction)).
+ GetPost("/updatePopup", new(UpdatePopupAction)).
+ Post("/delete", new(DeleteAction)).
+ EndAll()
+ })
+}
diff --git a/internal/web/actions/default/clusters/regions/items/updatePopup.go b/internal/web/actions/default/clusters/regions/items/updatePopup.go
new file mode 100644
index 00000000..515f99a1
--- /dev/null
+++ b/internal/web/actions/default/clusters/regions/items/updatePopup.go
@@ -0,0 +1,73 @@
+package items
+
+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 {
+ ItemId int64
+}) {
+ itemResp, err := this.RPC().NodePriceItemRPC().FindEnabledNodePriceItem(this.AdminContext(), &pb.FindEnabledNodePriceItemRequest{NodePriceItemId: params.ItemId})
+ if err != nil {
+ this.ErrorPage(err)
+ return
+ }
+ item := itemResp.NodePriceItem
+ if item == nil {
+ this.NotFound("nodePriceItem", params.ItemId)
+ return
+ }
+
+ this.Data["item"] = maps.Map{
+ "id": item.Id,
+ "name": item.Name,
+ "bitsFrom": item.BitsFrom,
+ "bitsTo": item.BitsTo,
+ }
+
+ this.Show()
+}
+
+func (this *UpdatePopupAction) RunPost(params struct {
+ ItemId int64
+ Name string
+ BitsFrom int64
+ BitsTo int64
+
+ Must *actions.Must
+ CSRF *actionutils.CSRF
+}) {
+ defer this.CreateLogInfo("修改流量价格项目", params.ItemId)
+
+ params.Must.
+ Field("name", params.Name).
+ Require("请输入名称").
+ Field("bitsFrom", params.BitsFrom).
+ Gte(0, "请输入不小于0的整数").
+ Field("bitsTo", params.BitsTo).
+ Gte(0, "请输入不小于0的整数")
+
+ _, err := this.RPC().NodePriceItemRPC().UpdateNodePriceItem(this.AdminContext(), &pb.UpdateNodePriceItemRequest{
+ NodePriceItemId: params.ItemId,
+ Name: params.Name,
+ BitsFrom: params.BitsFrom * 1000 * 1000,
+ BitsTo: params.BitsTo * 1000 * 1000,
+ })
+ if err != nil {
+ this.ErrorPage(err)
+ return
+ }
+
+ this.Success()
+}
diff --git a/internal/web/actions/default/clusters/regions/prices.go b/internal/web/actions/default/clusters/regions/prices.go
new file mode 100644
index 00000000..8235d2cd
--- /dev/null
+++ b/internal/web/actions/default/clusters/regions/prices.go
@@ -0,0 +1,84 @@
+package regions
+
+import (
+ "encoding/json"
+ "fmt"
+ "github.com/TeaOSLab/EdgeAdmin/internal/utils/numberutils"
+ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
+ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/regions/regionutils"
+ "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
+ "github.com/iwind/TeaGo/maps"
+)
+
+type PricesAction struct {
+ actionutils.ParentAction
+}
+
+func (this *PricesAction) Init() {
+ this.Nav("", "", "price")
+}
+
+func (this *PricesAction) RunGet(params struct{}) {
+ // 所有价格项目
+ itemsResp, err := this.RPC().NodePriceItemRPC().FindAllEnabledAndOnNodePriceItems(this.AdminContext(), &pb.FindAllEnabledAndOnNodePriceItemsRequest{Type: regionutils.PriceTypeTraffic})
+ if err != nil {
+ this.ErrorPage(err)
+ return
+ }
+ itemMaps := []maps.Map{}
+ for _, item := range itemsResp.NodePriceItems {
+
+ itemMaps = append(itemMaps, maps.Map{
+ "id": item.Id,
+ "name": item.Name,
+ "bitsFromString": this.formatBits(item.BitsFrom),
+ "bitsToString": this.formatBits(item.BitsTo),
+ })
+ }
+ this.Data["items"] = itemMaps
+
+ // 所有区域
+ regionsResp, err := this.RPC().NodeRegionRPC().FindAllEnabledNodeRegions(this.AdminContext(), &pb.FindAllEnabledNodeRegionsRequest{})
+ if err != nil {
+ this.ErrorPage(err)
+ return
+ }
+ regionMaps := []maps.Map{}
+ for _, region := range regionsResp.NodeRegions {
+ pricesMap := map[string]float32{}
+ if len(region.PricesJSON) > 0 {
+ err = json.Unmarshal(region.PricesJSON, &pricesMap)
+ if err != nil {
+ this.ErrorPage(err)
+ return
+ }
+ }
+ regionMaps = append(regionMaps, maps.Map{
+ "id": region.Id,
+ "isOn": region.IsOn,
+ "name": region.Name,
+ "prices": pricesMap,
+ })
+ }
+ this.Data["regions"] = regionMaps
+
+ this.Show()
+}
+
+func (this *PricesAction) formatBits(bits int64) string {
+ sizeHuman := ""
+ if bits < 1000 {
+ sizeHuman = numberutils.FormatInt64(bits) + "BPS"
+ } else if bits < 1_000_000 {
+ sizeHuman = fmt.Sprintf("%.2fKBPS", float64(bits)/1000)
+ } else if bits < 1_000_000_000 {
+ sizeHuman = fmt.Sprintf("%.2fMBPS", float64(bits)/1000/1000)
+ } else if bits < 1_000_000_000_000 {
+ sizeHuman = fmt.Sprintf("%.2fGBPS", float64(bits)/1000/1000/1000)
+ } else if bits < 1_000_000_000_000_000 {
+ sizeHuman = fmt.Sprintf("%.2fTBPS", float64(bits)/1000/1000/1000/1000)
+ } else {
+ sizeHuman = fmt.Sprintf("%.2fPTBPS", float64(bits)/1000/1000/1000/1000/1000)
+ }
+ return sizeHuman
+}
diff --git a/internal/web/actions/default/clusters/regions/regionutils/consts.go b/internal/web/actions/default/clusters/regions/regionutils/consts.go
new file mode 100644
index 00000000..a7841773
--- /dev/null
+++ b/internal/web/actions/default/clusters/regions/regionutils/consts.go
@@ -0,0 +1,5 @@
+package regionutils
+
+const (
+ PriceTypeTraffic = "traffic"
+)
diff --git a/internal/web/actions/default/clusters/regions/updatePricePopup.go b/internal/web/actions/default/clusters/regions/updatePricePopup.go
new file mode 100644
index 00000000..68549cea
--- /dev/null
+++ b/internal/web/actions/default/clusters/regions/updatePricePopup.go
@@ -0,0 +1,94 @@
+package regions
+
+import (
+ "encoding/json"
+ "github.com/TeaOSLab/EdgeAdmin/internal/utils/numberutils"
+ "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 UpdatePricePopupAction struct {
+ actionutils.ParentAction
+}
+
+func (this *UpdatePricePopupAction) Init() {
+ this.Nav("", "", "")
+}
+
+func (this *UpdatePricePopupAction) RunGet(params struct {
+ RegionId int64
+ ItemId int64
+}) {
+ // 区域
+ regionResp, err := this.RPC().NodeRegionRPC().FindEnabledNodeRegion(this.AdminContext(), &pb.FindEnabledNodeRegionRequest{NodeRegionId: params.RegionId})
+ if err != nil {
+ this.ErrorPage(err)
+ return
+ }
+ region := regionResp.NodeRegion
+ if region == nil {
+ this.NotFound("nodeRegion", params.RegionId)
+ return
+ }
+ this.Data["region"] = maps.Map{
+ "id": region.Id,
+ "isOn": region.IsOn,
+ "name": region.Name,
+ }
+
+ // 当前价格
+ pricesMap := map[string]float32{}
+ if len(region.PricesJSON) > 0 {
+ err = json.Unmarshal(region.PricesJSON, &pricesMap)
+ if err != nil {
+ this.ErrorPage(err)
+ return
+ }
+ }
+ this.Data["price"] = pricesMap[numberutils.FormatInt64(params.ItemId)]
+
+ // 价格项
+ itemResp, err := this.RPC().NodePriceItemRPC().FindEnabledNodePriceItem(this.AdminContext(), &pb.FindEnabledNodePriceItemRequest{NodePriceItemId: params.ItemId})
+ if err != nil {
+ this.ErrorPage(err)
+ return
+ }
+ item := itemResp.NodePriceItem
+ if item == nil {
+ this.NotFound("nodePriceItem", params.ItemId)
+ return
+ }
+
+ this.Data["item"] = maps.Map{
+ "id": item.Id,
+ "name": item.Name,
+ "bitsFrom": item.BitsFrom,
+ "bitsTo": item.BitsTo,
+ }
+
+ this.Show()
+}
+
+func (this *UpdatePricePopupAction) RunPost(params struct {
+ RegionId int64
+ ItemId int64
+ Price float32
+
+ Must *actions.Must
+ CSRF *actionutils.CSRF
+}) {
+ defer this.CreateLogInfo("修改区域 %d-价格项 %d 的价格", params.RegionId, params.ItemId)
+
+ _, err := this.RPC().NodeRegionRPC().UpdateNodeRegionPrice(this.AdminContext(), &pb.UpdateNodeRegionPriceRequest{
+ NodeRegionId: params.RegionId,
+ NodeItemId: params.ItemId,
+ Price: params.Price,
+ })
+ if err != nil {
+ this.ErrorPage(err)
+ return
+ }
+ this.Success()
+}
diff --git a/internal/web/import.go b/internal/web/import.go
index 8be05c47..46d96209 100644
--- a/internal/web/import.go
+++ b/internal/web/import.go
@@ -11,6 +11,7 @@ import (
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings"
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/grants"
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/regions"
+ _ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/regions/items"
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/csrf"
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/dashboard"
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/db"
diff --git a/web/views/@default/clusters/regions/@menu.html b/web/views/@default/clusters/regions/@menu.html
new file mode 100644
index 00000000..199ce0d4
--- /dev/null
+++ b/web/views/@default/clusters/regions/@menu.html
@@ -0,0 +1,6 @@
+
暂时还没有区域。
-| diff --git a/web/views/@default/clusters/regions/items/createPopup.html b/web/views/@default/clusters/regions/items/createPopup.html new file mode 100644 index 00000000..9ec3aeaa --- /dev/null +++ b/web/views/@default/clusters/regions/items/createPopup.html @@ -0,0 +1,36 @@ +{$layout "layout_popup"} + + |
|---|
| 区域\范围 | +
+ {{item.name}}
+
+
+ + {{item.bitsFromString}}-{{item.bitsToString}} + |
+ + [+添加价格项] + | +
|---|---|---|
| {{region.name}} | ++ ¥{{region.prices[item.id.toString()]}}元/GB + + [设置] + | ++ |