This commit is contained in:
IT 老营长 @云轩领航-创始人 2025-03-15 13:16:15 +08:00
parent 1308ebda7b
commit f1ab27b595
9 changed files with 175 additions and 24 deletions

View File

@ -11,23 +11,27 @@ import (
type Cluster struct {
Table
travel travel.Travel
order string `data:"1"`
fields string `data:"title,content,space,total,stock,price"`
payfor string `name:"payfor" help:"购买" style:"notice" role:"leader"`
scanService string `name:"scanService" help:"扫描"`
modify string `name:"modify title content price" style:"danger"`
travel travel.Travel
order string `data:"1"`
fields string `data:"title,content,space,total,stock,price,cluster_status"`
payfor string `name:"payfor" help:"购买" style:"notice" role:"leader"`
modify string `name:"modify title content price" style:"danger"`
}
func (s Cluster) Scan(m *ice.Message, arg ...string) {
m.Cmd(s.travel, s.travel.Concurrent, ice.GetTypeMod(s.travel), ice.GetTypeKey(s.travel)).Table(func(value ice.Maps) {
s.InsertIfNeed(m, web.SPACE, value[web.SPACE])
})
m.Cmd("").Table(func(value ice.Maps) { s.ScanService(m.Options(value)) })
m.ProcessRefresh()
}
func (s Cluster) List(m *ice.Message, arg ...string) {
if len(arg) == 1 {
s.Select(m)
if len(arg) < 2 {
if m.IsTech() {
s.Select(m)
} else {
s.Select(m, model.STATUS, kit.Format(ClusterOnline))
}
} else {
s.SelectDetail(m, model.UID, arg[1])
}
@ -35,20 +39,20 @@ func (s Cluster) List(m *ice.Message, arg ...string) {
if m.IsTech() {
m.EchoInfoButton("请扫描集群", s.Scan)
} else {
m.Echo("请联系平台管理员部署集群").Action()
m.Echo("请联系平台管理员部署集群").Action()
}
} else {
if m.Display(""); m.IsTech() {
m.Table(func(value ice.Maps) {
if kit.Int(value[model.STOCK]) > 0 {
m.PushButton(s.Payfor, s.ScanService, s.Modify)
if ClusterStatus(kit.Int(value[model.CLUSTER_STATUS])) == ClusterOnline && kit.Int(value[model.STOCK]) > 0 {
m.PushButton(s.Payfor, s.ScanService, s.Offline, s.Modify)
} else {
m.PushButton(s.ScanService, s.Modify)
m.PushButton(s.ScanService, s.Online, s.Modify)
}
}).Action(s.Scan)
} else if s.IsLeader(m) {
m.Table(func(value ice.Maps) {
if kit.Int(value[model.STOCK]) > 0 {
if ClusterStatus(kit.Int(value[model.CLUSTER_STATUS])) == ClusterOnline && kit.Int(value[model.STOCK]) > 0 {
m.PushButton(s.Payfor)
} else {
m.PushButton()
@ -69,9 +73,31 @@ func (s Cluster) ScanService(m *ice.Message, arg ...string) {
m.Cmdy(Gateway{}, s.Scan, arg, kit.Dict(model.CLUSTER_UID, m.Option(model.UID))).ProcessRefresh()
s.Update(m, m.AppendSimple(model.TOTAL, model.STOCK), m.OptionSimple(model.UID)...)
}
func (s Cluster) Offline(m *ice.Message, arg ...string) {
s.Update(m, []string{model.STATUS, kit.Format(ClusterOffline)})
s.RecordEventWithName(m, "")
}
func (s Cluster) Online(m *ice.Message, arg ...string) {
s.Update(m, []string{model.STATUS, kit.Format(ClusterOnline)})
s.RecordEventWithName(m, "")
}
func (s Cluster) Modify(m *ice.Message, arg ...string) {
s.Update(m, s.TransPrice(m, arg), m.OptionSimple(model.UID)...)
s.Update(m, s.TransPrice(m, arg))
s.RecordEventWithName(m, "")
}
func init() { ice.TeamCtxCmd(Cluster{}) }
type ClusterStatus int
const (
ClusterOffline ClusterStatus = iota
ClusterOnline
)
var ClusterStatusList = map[ClusterStatus]string{
ClusterOffline: "offline",
ClusterOnline: "online",
}
func (s ClusterStatus) String() string { return ClusterStatusList[s] }

View File

@ -20,6 +20,10 @@ func (s Table) Inputs(m *ice.Message, arg ...string) {
s.InputsListRole(m, UserCloudRoleList, arg...)
case model.CLOUD_TYPE:
s.InputsList(m, CloudTypeList, arg...)
case model.GATEWAY_UID:
m.Cmdy(Gateway{}, m.Option(model.CLOUD_UID)).Cut(model.UID, model.TITLE)
m.RenameAppend(model.UID, arg[0], model.TITLE, model.NAME)
m.DisplayInputKeyNameIconTitle()
default:
s.Table.Inputs(m, arg...)
}
@ -31,6 +35,10 @@ func (s Table) RewriteAppend(m *ice.Message, arg ...string) *ice.Message {
value = UserCloudRole(kit.Int(value)).String()
case model.CLOUD_TYPE:
value = CloudType(kit.Int(value)).String()
case model.CLUSTER_STATUS:
value = ClusterStatus(kit.Int(value)).String()
case model.TEMPLATE_STATUS:
value = TemplateStatus(kit.Int(value)).String()
case model.PRICE:
value = kit.Format("%.2f", kit.Float(value)/100)
}

View File

@ -29,12 +29,18 @@ func (s Gateway) List(m *ice.Message, arg ...string) {
if s.ValueList(m, arg); s.IsLeader(m) {
m.PushAction(s.CreateProject, s.ScanProject, s.Open, s.Modify)
} else if s.IsWorker(m) {
m.PushAction(s.CreateProject, s.ScanProject)
m.PushAction(s.CreateProject)
} else {
m.PushAction()
}
if m.Action(); m.Length() == 0 {
m.Echo("请到「云集群」购买主机")
if m.SetResult(); s.IsLeader(m) {
m.Echo("请到「云集群」购买主机")
} else if s.IsWorker(m) {
m.Echo("请联系「管理员」购买主机")
} else {
m.Echo("请等待「管理员」购买主机")
}
} else {
s.Fields(m, model.UID, s.KeyAS(s.cluster, model.SPACE)).SelectJoin(m, s.cluster, s.Keys(s.cluster, model.SPACE)).Display("")
}

View File

@ -8,6 +8,7 @@ const (
INFO = "info"
TYPE = "type"
ROLE = "role"
STATUS = "status"
TOTAL = "total"
STOCK = "stock"
PRICE = "price"
@ -20,6 +21,8 @@ const (
CLOUD_TYPE = "cloud_type"
CLUSTER_UID = "cluster_uid"
CLUSTER_SPACE = "cluster_space"
CLUSTER_STATUS = "cluster_status"
TEMPLATE_STATUS = "template_status"
GATEWAY_UID = "gateway_uid"
GATEWAY_SPACE = "gateway_space"
PROJECT_UID = "project_uid"
@ -36,10 +39,11 @@ type Cloud struct {
}
type Cluster struct {
db.ModelContent
Space string `gorm:"type:varchar(64);index"`
Total int
Stock int
Price int
Space string `gorm:"type:varchar(64);index"`
Total int `gorm:"default:0"`
Stock int `gorm:"default:0"`
Price int `gorm:"default:0"`
Status uint8 `gorm:"default:0"`
}
type Gateway struct {
db.ModelContent
@ -47,6 +51,12 @@ type Gateway struct {
CloudUID string `gorm:"type:char(32);index"`
ClusterUID string `gorm:"type:char(32);index"`
}
type Template struct {
db.ModelNameInfo
Repos string `gorm:"type:varchar(255)"`
Binary string `gorm:"type:varchar(255)"`
Status uint8 `gorm:"default:0"`
}
type Project struct {
db.ModelNameInfo
Repos string `gorm:"type:varchar(255)"`
@ -62,4 +72,6 @@ type Product struct {
ProjectUID string `gorm:"type:char(32);index"`
}
func init() { db.CmdModels("", &UserCloud{}, &Cloud{}, &Cluster{}, &Gateway{}, &Project{}, &Product{}) }
func init() {
db.CmdModels("", &UserCloud{}, &Cloud{}, &Cluster{}, &Gateway{}, &Template{}, &Project{}, &Product{})
}

View File

@ -1,9 +1,14 @@
{
"portal": "系统运维",
"cluster": "云集群", "gateway": "云主机", "project": "云项目", "product": "云服务",
"cluster": "云集群", "gateway": "云主机", "template": "云模板", "project": "云项目", "product": "云服务",
"scanService": "扫描", "offline": "下架", "online": "上架",
"style": {
"offline": "danger"
},
"icons": {
"cluster": "https://img.icons8.com/officel/80/activity-grid.png",
"gateway": "https://img.icons8.com/officel/80/activity-grid.png",
"template": "https://img.icons8.com/officel/80/activity-grid.png",
"project": "https://img.icons8.com/officel/80/activity-grid.png",
"product": "https://img.icons8.com/officel/80/activity-grid.png"
},
@ -13,6 +18,10 @@
"cloud_name": "系统名称",
"cloud_type": "系统类型",
"cloud_space": "集群空间",
"cluster_status": "集群状态",
"cluster_space": "集群空间",
"template_status": "模板状态",
"gateway_uid": "云主机",
"gateway_title": "云主机",
"gateway_space": "主机空间",
"project_name": "项目名称",

View File

@ -16,7 +16,7 @@ type product struct {
cluster Cluster
gateway Gateway
project project
order string `data:"4"`
order string `data:"5"`
fields string `data:"name,icon,index,project_uid"`
open string `name:"open" style:"notice" role:"void"`
}

View File

@ -15,7 +15,7 @@ type project struct {
Table
cluster Cluster
gateway Gateway
order string `data:"3"`
order string `data:"4"`
fields string `data:"name,repos,binary,gateway_uid"`
create string `name:"create name* repos binary" style:"notice" role:"worker"`
scanProduct string `name:"scanProduct" help:"扫描" role:"worker"`

81
src/operation/template.go Normal file
View File

@ -0,0 +1,81 @@
package operation
import (
"shylinux.com/x/ice"
kit "shylinux.com/x/toolkits"
"shylinux.com/x/operation/src/operation/model"
)
type template struct {
Table
order string `data:"3"`
fields string `data:"name,info,repos,binary,template_status"`
create string `name:"create name* info repos* binary*"`
modify string `name:"modify name* info repos* binary*" style:"danger"`
install string `name:"install gateway_uid* name*" style:"notice" role:"worker"`
}
func (s template) Create(m *ice.Message, arg ...string) {
s.Insert(m, arg...)
}
func (s template) List(m *ice.Message, arg ...string) {
if m.IsTech() {
if len(arg) < 2 {
s.Select(m)
} else {
s.SelectDetail(m, model.UID, arg[1])
}
m.Table(func(value ice.Maps) {
if TemplateStatus(kit.Int(value[model.TEMPLATE_STATUS])) == TemplateOffline {
m.PushButton(s.Online, s.Modify)
} else {
m.PushButton(s.Install, s.Offline, s.Modify)
}
})
if m.Length() == 0 {
s.Button(m, "")
}
} else {
if len(arg) < 2 {
s.Select(m, model.STATUS, kit.Format(TemplateOnline))
} else {
s.SelectDetail(m, model.UID, arg[1])
}
if m.PushAction(s.Install).Action(); m.Length() == 0 {
m.Echo("请等待「平台管理员」创建模板")
}
}
m.Display("")
}
func (s template) Install(m *ice.Message, arg ...string) {
m.Cmdy(project{}, s.Create, m.OptionSimple("name,repos,binary"))
}
func (s template) Offline(m *ice.Message, arg ...string) {
s.Update(m, []string{model.STATUS, kit.Format(TemplateOffline)})
s.RecordEventWithName(m, "")
}
func (s template) Online(m *ice.Message, arg ...string) {
s.Update(m, []string{model.STATUS, kit.Format(TemplateOnline)})
s.RecordEventWithName(m, "")
}
func (s template) Modify(m *ice.Message, arg ...string) {
s.Update(m, arg)
s.RecordEventWithName(m, "")
}
func init() { ice.TeamCtxCmd(template{}) }
type TemplateStatus int
const (
TemplateOffline TemplateStatus = iota
TemplateOnline
)
var TemplateStatusList = map[TemplateStatus]string{
TemplateOffline: "offline",
TemplateOnline: "online",
}
func (s TemplateStatus) String() string { return TemplateStatusList[s] }

View File

@ -0,0 +1,9 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg) {
can.onimport.myView(can, msg, function(value) { return [
{view: html.TITLE, list: [value.name, can.onimport.titleAction(can, value)]},
{view: html.STATUS, list: [value.uid.slice(0, 6), can.onimport.timeView(can, value)]},
{view: html.OUTPUT, list: [value.info||value.binary||value.repos]},
] })
},
})