diff --git a/backend/app/api/v1/group.go b/backend/app/api/v1/group.go index 0964269d5..d8027fe11 100644 --- a/backend/app/api/v1/group.go +++ b/backend/app/api/v1/group.go @@ -12,13 +12,13 @@ import ( // @Summary Create group // @Description 创建系统组 // @Accept json -// @Param request body dto.GroupOperate true "request" +// @Param request body dto.GroupCreate true "request" // @Success 200 // @Security ApiKeyAuth // @Router /hosts/group [post] // @x-panel-log {"bodyKeys":["name","type"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建组 [name][type]","formatEN":"create group [name][type]"} func (b *BaseApi) CreateGroup(c *gin.Context) { - var req dto.GroupOperate + var req dto.GroupCreate if err := c.ShouldBindJSON(&req); err != nil { helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) return @@ -42,7 +42,7 @@ func (b *BaseApi) CreateGroup(c *gin.Context) { // @Success 200 // @Security ApiKeyAuth // @Router /hosts/group/del [post] -// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"groups","output_colume":"name","output_value":"name"}],"formatZH":"删除组 [name]","formatEN":"delete group [name]"} +// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"groups","output_colume":"name","output_value":"name"},{"input_colume":"id","input_value":"id","isList":false,"db":"groups","output_colume":"type","output_value":"type"}],"formatZH":"删除组 [type][name]","formatEN":"delete group [type][name]"} func (b *BaseApi) DeleteGroup(c *gin.Context) { var req dto.OperateByID if err := c.ShouldBindJSON(&req); err != nil { @@ -65,13 +65,13 @@ func (b *BaseApi) DeleteGroup(c *gin.Context) { // @Summary Update group // @Description 更新系统组 // @Accept json -// @Param request body dto.GroupOperate true "request" +// @Param request body dto.GroupUpdate true "request" // @Success 200 // @Security ApiKeyAuth // @Router /hosts/group/update [post] // @x-panel-log {"bodyKeys":["name","type"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新组 [name][type]","formatEN":"update group [name][type]"} func (b *BaseApi) UpdateGroup(c *gin.Context) { - var req dto.GroupOperate + var req dto.GroupUpdate if err := c.ShouldBindJSON(&req); err != nil { helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) return @@ -80,8 +80,7 @@ func (b *BaseApi) UpdateGroup(c *gin.Context) { helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) return } - - if err := groupService.Update(req.ID, req.Name); err != nil { + if err := groupService.Update(req); err != nil { helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) return } diff --git a/backend/app/api/v1/host.go b/backend/app/api/v1/host.go index 155f2d73c..b8a820eae 100644 --- a/backend/app/api/v1/host.go +++ b/backend/app/api/v1/host.go @@ -215,7 +215,7 @@ func (b *BaseApi) UpdateHost(c *gin.Context) { upMap := make(map[string]interface{}) upMap["name"] = req.Name - upMap["group_belong"] = req.GroupBelong + upMap["group_id"] = req.GroupID upMap["addr"] = req.Addr upMap["port"] = req.Port upMap["user"] = req.User @@ -251,7 +251,7 @@ func (b *BaseApi) UpdateHostGroup(c *gin.Context) { } upMap := make(map[string]interface{}) - upMap["group_belong"] = req.Group + upMap["group_id"] = req.GroupID if err := hostService.Update(req.ID, upMap); err != nil { helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) return diff --git a/backend/app/dto/group.go b/backend/app/dto/group.go index c5e0aa54d..387d492a2 100644 --- a/backend/app/dto/group.go +++ b/backend/app/dto/group.go @@ -1,6 +1,6 @@ package dto -type GroupOperate struct { +type GroupCreate struct { ID uint `json:"id"` Name string `json:"name" validate:"required"` Type string `json:"type" validate:"required"` @@ -10,8 +10,15 @@ type GroupSearch struct { Type string `json:"type" validate:"required"` } -type GroupInfo struct { - ID uint `json:"id"` - Name string `json:"name"` - Type string `json:"type"` +type GroupUpdate struct { + ID uint `json:"id"` + Name string `json:"name"` + IsDefault bool `json:"isDefault"` +} + +type GroupInfo struct { + ID uint `json:"id"` + Name string `json:"name"` + Type string `json:"type"` + IsDefault bool `json:"isDefault"` } diff --git a/backend/app/dto/host.go b/backend/app/dto/host.go index 8f07e3101..a9854a7ac 100644 --- a/backend/app/dto/host.go +++ b/backend/app/dto/host.go @@ -5,15 +5,15 @@ import ( ) type HostOperate struct { - ID uint `json:"id"` - GroupBelong string `json:"groupBelong" validate:"required"` - Name string `json:"name"` - Addr string `json:"addr" validate:"required,ip"` - Port uint `json:"port" validate:"required,number,max=65535,min=1"` - User string `json:"user" validate:"required"` - AuthMode string `json:"authMode" validate:"oneof=password key"` - PrivateKey string `json:"privateKey"` - Password string `json:"password"` + ID uint `json:"id"` + GroupID uint `json:"groupID"` + Name string `json:"name"` + Addr string `json:"addr" validate:"required,ip"` + Port uint `json:"port" validate:"required,number,max=65535,min=1"` + User string `json:"user" validate:"required"` + AuthMode string `json:"authMode" validate:"oneof=password key"` + PrivateKey string `json:"privateKey"` + Password string `json:"password"` Description string `json:"description"` } @@ -29,8 +29,8 @@ type HostConnTest struct { type SearchHostWithPage struct { PageInfo - Group string `json:"group"` - Info string `json:"info"` + GroupID uint `json:"groupID"` + Info string `json:"info"` } type SearchForTree struct { @@ -38,13 +38,14 @@ type SearchForTree struct { } type ChangeHostGroup struct { - ID uint `json:"id" validate:"required"` - Group string `json:"group" validate:"required"` + ID uint `json:"id" validate:"required"` + GroupID uint `json:"groupID" validate:"required"` } type HostInfo struct { ID uint `json:"id"` CreatedAt time.Time `json:"createdAt"` + GroupID uint `json:"groupID"` GroupBelong string `json:"groupBelong"` Name string `json:"name"` Addr string `json:"addr"` diff --git a/backend/app/model/group.go b/backend/app/model/group.go index 8a9fe00b1..1479e035a 100644 --- a/backend/app/model/group.go +++ b/backend/app/model/group.go @@ -2,6 +2,7 @@ package model type Group struct { BaseModel - Name string `gorm:"type:varchar(64);not null" json:"name"` - Type string `gorm:"type:varchar(16);not null" json:"type"` + IsDefault bool `json:"isDefault"` + Name string `gorm:"type:varchar(64);not null" json:"name"` + Type string `gorm:"type:varchar(16);not null" json:"type"` } diff --git a/backend/app/model/host.go b/backend/app/model/host.go index 46f52dfaa..b25a57b82 100644 --- a/backend/app/model/host.go +++ b/backend/app/model/host.go @@ -2,14 +2,14 @@ package model type Host struct { BaseModel - GroupBelong string `gorm:"type:varchar(64);not null" json:"groupBelong"` - Name string `gorm:"type:varchar(64);not null" json:"name"` - Addr string `gorm:"type:varchar(16);not null" json:"addr"` - Port int `gorm:"type:varchar(5);not null" json:"port"` - User string `gorm:"type:varchar(64);not null" json:"user"` - AuthMode string `gorm:"type:varchar(16);not null" json:"authMode"` - Password string `gorm:"type:varchar(64)" json:"password"` - PrivateKey string `gorm:"type:varchar(256)" json:"privateKey"` + GroupID uint `gorm:"type:decimal;not null" json:"group_id"` + Name string `gorm:"type:varchar(64);not null" json:"name"` + Addr string `gorm:"type:varchar(16);not null" json:"addr"` + Port int `gorm:"type:decimal;not null" json:"port"` + User string `gorm:"type:varchar(64);not null" json:"user"` + AuthMode string `gorm:"type:varchar(16);not null" json:"authMode"` + Password string `gorm:"type:varchar(64)" json:"password"` + PrivateKey string `gorm:"type:varchar(256)" json:"privateKey"` Description string `gorm:"type:varchar(256)" json:"description"` } diff --git a/backend/app/repo/common.go b/backend/app/repo/common.go index 262101567..b7563eb6a 100644 --- a/backend/app/repo/common.go +++ b/backend/app/repo/common.go @@ -16,6 +16,7 @@ type ICommonRepo interface { WithByName(name string) DBOption WithByType(tp string) DBOption WithOrderBy(orderStr string) DBOption + WithByGroupID(groupID uint) DBOption WithLikeName(name string) DBOption WithIdsIn(ids []uint) DBOption WithByDate(startTime, endTime time.Time) DBOption @@ -54,6 +55,15 @@ func (c *CommonRepo) WithByType(tp string) DBOption { } } +func (c *CommonRepo) WithByGroupID(groupID uint) DBOption { + return func(g *gorm.DB) *gorm.DB { + if groupID == 0 { + return g + } + return g.Where("group_id = ?", groupID) + } +} + func (c *CommonRepo) WithByStatus(status string) DBOption { return func(g *gorm.DB) *gorm.DB { if len(status) == 0 { diff --git a/backend/app/repo/group.go b/backend/app/repo/group.go index 092d37db8..4a4baff90 100644 --- a/backend/app/repo/group.go +++ b/backend/app/repo/group.go @@ -11,10 +11,11 @@ type GroupRepo struct{} type IGroupRepo interface { Get(opts ...DBOption) (model.Group, error) GetList(opts ...DBOption) ([]model.Group, error) - WithByType(groupType string) DBOption Create(group *model.Group) error Update(id uint, vars map[string]interface{}) error Delete(opts ...DBOption) error + CancelDefault() error + WithByIsDefault(isDefault bool) DBOption } func NewIGroupRepo() IGroupRepo { @@ -41,12 +42,6 @@ func (u *GroupRepo) GetList(opts ...DBOption) ([]model.Group, error) { return groups, err } -func (c *GroupRepo) WithByType(groupType string) DBOption { - return func(g *gorm.DB) *gorm.DB { - return g.Where("type = ?", groupType) - } -} - func (u *GroupRepo) Create(group *model.Group) error { return global.DB.Create(group).Error } @@ -55,6 +50,12 @@ func (u *GroupRepo) Update(id uint, vars map[string]interface{}) error { return global.DB.Model(&model.Group{}).Where("id = ?", id).Updates(vars).Error } +func (u *GroupRepo) WithByIsDefault(isDefault bool) DBOption { + return func(g *gorm.DB) *gorm.DB { + return g.Where("is_default = ?", isDefault) + } +} + func (u *GroupRepo) Delete(opts ...DBOption) error { db := global.DB for _, opt := range opts { @@ -62,3 +63,7 @@ func (u *GroupRepo) Delete(opts ...DBOption) error { } return db.Delete(&model.Group{}).Error } + +func (w GroupRepo) CancelDefault() error { + return global.DB.Model(&model.Group{}).Where("`is_default` = 1").Updates(map[string]interface{}{"is_default": 0}).Error +} diff --git a/backend/app/repo/host.go b/backend/app/repo/host.go index 8a5389d31..2edc7c5e7 100644 --- a/backend/app/repo/host.go +++ b/backend/app/repo/host.go @@ -16,9 +16,7 @@ type IHostRepo interface { WithByPort(port uint) DBOption WithByUser(user string) DBOption WithByAddr(addr string) DBOption - WithByGroup(group string) DBOption Create(host *model.Host) error - ChangeGroup(oldGroup, newGroup string) error Update(id uint, vars map[string]interface{}) error Delete(opts ...DBOption) error } @@ -97,10 +95,6 @@ func (u *HostRepo) Create(host *model.Host) error { return global.DB.Create(host).Error } -func (u *HostRepo) ChangeGroup(oldGroup, newGroup string) error { - return global.DB.Model(&model.Host{}).Where("group_belong = ?", oldGroup).Updates(map[string]interface{}{"group_belong": newGroup}).Error -} - func (u *HostRepo) Update(id uint, vars map[string]interface{}) error { return global.DB.Model(&model.Host{}).Where("id = ?", id).Updates(vars).Error } diff --git a/backend/app/service/group.go b/backend/app/service/group.go index 41ba9f2a4..9247eb161 100644 --- a/backend/app/service/group.go +++ b/backend/app/service/group.go @@ -2,6 +2,7 @@ package service import ( "github.com/1Panel-dev/1Panel/backend/app/dto" + "github.com/1Panel-dev/1Panel/backend/buserr" "github.com/1Panel-dev/1Panel/backend/constant" "github.com/jinzhu/copier" "github.com/pkg/errors" @@ -11,8 +12,8 @@ type GroupService struct{} type IGroupService interface { List(req dto.GroupSearch) ([]dto.GroupInfo, error) - Create(groupDto dto.GroupOperate) error - Update(id uint, name string) error + Create(req dto.GroupCreate) error + Update(req dto.GroupUpdate) error Delete(id uint) error } @@ -21,7 +22,7 @@ func NewIGroupService() IGroupService { } func (u *GroupService) List(req dto.GroupSearch) ([]dto.GroupInfo, error) { - groups, err := groupRepo.GetList(groupRepo.WithByType(req.Type)) + groups, err := groupRepo.GetList(commonRepo.WithByType(req.Type)) if err != nil { return nil, constant.ErrRecordNotFound } @@ -36,12 +37,12 @@ func (u *GroupService) List(req dto.GroupSearch) ([]dto.GroupInfo, error) { return dtoUsers, err } -func (u *GroupService) Create(groupDto dto.GroupOperate) error { - group, _ := groupRepo.Get(commonRepo.WithByName(groupDto.Name), commonRepo.WithByName(groupDto.Name)) +func (u *GroupService) Create(req dto.GroupCreate) error { + group, _ := groupRepo.Get(commonRepo.WithByName(req.Name), commonRepo.WithByName(req.Name)) if group.ID != 0 { return constant.ErrRecordExist } - if err := copier.Copy(&group, &groupDto); err != nil { + if err := copier.Copy(&group, &req); err != nil { return errors.WithMessage(constant.ErrStructTransform, err.Error()) } if err := groupRepo.Create(&group); err != nil { @@ -55,22 +56,30 @@ func (u *GroupService) Delete(id uint) error { if group.ID == 0 { return constant.ErrRecordNotFound } - if err := hostRepo.ChangeGroup(group.Name, "default"); err != nil { - return err + switch group.Type { + case "website": + websites, _ := websiteRepo.GetBy(commonRepo.WithByGroupID(id)) + if len(websites) > 0 { + return buserr.New(constant.ErrGroupIsUsed) + } + case "host": + hosts, _ := hostRepo.GetList(commonRepo.WithByGroupID(id)) + if len(hosts) > 0 { + return buserr.New(constant.ErrGroupIsUsed) + } } return groupRepo.Delete(commonRepo.WithByID(id)) } -func (u *GroupService) Update(id uint, name string) error { - group, _ := groupRepo.Get(commonRepo.WithByID(id)) - if group.ID == 0 { - return constant.ErrRecordNotFound +func (u *GroupService) Update(req dto.GroupUpdate) error { + if req.IsDefault { + if err := groupRepo.CancelDefault(); err != nil { + return err + } } - upMap := make(map[string]interface{}) - upMap["name"] = name - if err := hostRepo.ChangeGroup(group.Name, name); err != nil { - return err - } - return groupRepo.Update(id, upMap) + upMap["name"] = req.Name + upMap["is_default"] = req.IsDefault + + return groupRepo.Update(req.ID, upMap) } diff --git a/backend/app/service/host.go b/backend/app/service/host.go index 81e9f0656..6ad56e7be 100644 --- a/backend/app/service/host.go +++ b/backend/app/service/host.go @@ -65,7 +65,7 @@ func (u *HostService) GetHostInfo(id uint) (*model.Host, error) { } func (u *HostService) SearchWithPage(search dto.SearchHostWithPage) (int64, interface{}, error) { - total, hosts, err := hostRepo.Page(search.Page, search.PageSize, hostRepo.WithByInfo(search.Info), hostRepo.WithByGroup(search.Group)) + total, hosts, err := hostRepo.Page(search.Page, search.PageSize, hostRepo.WithByInfo(search.Info), commonRepo.WithByGroupID(search.GroupID)) if err != nil { return 0, nil, err } @@ -75,6 +75,8 @@ func (u *HostService) SearchWithPage(search dto.SearchHostWithPage) (int64, inte if err := copier.Copy(&item, &host); err != nil { return 0, nil, errors.WithMessage(constant.ErrStructTransform, err.Error()) } + group, _ := groupRepo.Get(commonRepo.WithByID(host.GroupID)) + item.GroupBelong = group.Name dtoHosts = append(dtoHosts, item) } return total, dtoHosts, err @@ -85,7 +87,7 @@ func (u *HostService) SearchForTree(search dto.SearchForTree) ([]dto.HostTree, e if err != nil { return nil, err } - groups, err := groupRepo.GetList() + groups, err := groupRepo.GetList(commonRepo.WithByType("host")) if err != nil { return nil, err } @@ -99,11 +101,13 @@ func (u *HostService) SearchForTree(search dto.SearchForTree) ([]dto.HostTree, e if len(host.Name) != 0 { label = fmt.Sprintf("%s - %s@%s:%d", host.Name, host.User, host.Addr, host.Port) } - if host.GroupBelong == group.Name { + if host.GroupID == group.ID { data.Children = append(data.Children, dto.TreeChild{ID: host.ID, Label: label}) } } - datas = append(datas, data) + if len(data.Children) != 0 { + datas = append(datas, data) + } } return datas, err } @@ -113,6 +117,14 @@ func (u *HostService) Create(req dto.HostOperate) (*dto.HostInfo, error) { if err := copier.Copy(&host, &req); err != nil { return nil, errors.WithMessage(constant.ErrStructTransform, err.Error()) } + if req.GroupID == 0 { + group, err := groupRepo.Get(groupRepo.WithByIsDefault(true)) + if err != nil { + return nil, errors.New("get default group failed") + } + host.GroupID = group.ID + req.GroupID = group.ID + } var sameHostID uint if req.Addr == "127.0.0.1" { hostSame, _ := hostRepo.Get(hostRepo.WithByAddr(req.Addr)) @@ -125,7 +137,7 @@ func (u *HostService) Create(req dto.HostOperate) (*dto.HostInfo, error) { host.ID = sameHostID upMap := make(map[string]interface{}) upMap["name"] = req.Name - upMap["group_belong"] = req.GroupBelong + upMap["group_id"] = req.GroupID upMap["addr"] = req.Addr upMap["port"] = req.Port upMap["user"] = req.User diff --git a/backend/init/migration/migrations/init.go b/backend/init/migration/migrations/init.go index 1adf6a779..884e79c89 100644 --- a/backend/init/migration/migrations/init.go +++ b/backend/init/migration/migrations/init.go @@ -39,7 +39,7 @@ var AddTableHost = &gormigrate.Migration{ return err } host := model.Host{ - Name: "localhost", Addr: "127.0.0.1", User: "root", Port: 22, GroupBelong: "default", + Name: "localhost", Addr: "127.0.0.1", User: "root", Port: 22, GroupID: group.ID, } if err := tx.Create(&host).Error; err != nil { return err diff --git a/cmd/server/docs/docs.go b/cmd/server/docs/docs.go index 03099dcc5..e0a104c4c 100644 --- a/cmd/server/docs/docs.go +++ b/cmd/server/docs/docs.go @@ -164,39 +164,6 @@ var doc = `{ } } }, - "/apps/installed": { - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "获取已安装应用列表", - "consumes": [ - "application/json" - ], - "tags": [ - "App" - ], - "summary": "List app installed", - "parameters": [ - { - "description": "request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/request.AppInstalledSearch" - } - } - ], - "responses": { - "200": { - "description": "" - } - } - } - }, "/apps/installed/:appInstallId/versions": { "get": { "security": [ @@ -231,93 +198,6 @@ var doc = `{ } } }, - "/apps/installed/backups": { - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "查询已安装备份列表分页", - "consumes": [ - "application/json" - ], - "tags": [ - "App" - ], - "summary": "Page installed backups", - "parameters": [ - { - "description": "request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/request.AppBackupSearch" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/dto.PageResult" - } - } - } - } - }, - "/apps/installed/backups/del": { - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "删除应用备份记录", - "consumes": [ - "application/json" - ], - "tags": [ - "App" - ], - "summary": "Delete app backup record", - "parameters": [ - { - "description": "request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/request.AppBackupDelete" - } - } - ], - "responses": { - "200": { - "description": "" - } - }, - "x-panel-log": { - "BeforeFuntions": [ - { - "db": "app_install_backups", - "input_colume": "id", - "input_value": "ids", - "isList": true, - "output_colume": "name", - "output_value": "names" - } - ], - "bodyKeys": [ - "ids" - ], - "formatEN": "Deleting an Application Backup [names]", - "formatZH": "删除应用备份 [names]", - "paramKeys": [] - } - } - }, "/apps/installed/check/:key": { "get": { "security": [ @@ -634,6 +514,39 @@ var doc = `{ } } }, + "/apps/installed/search": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "获取已安装应用列表", + "consumes": [ + "application/json" + ], + "tags": [ + "App" + ], + "summary": "List app installed", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.AppInstalledSearch" + } + } + ], + "responses": { + "200": { + "description": "" + } + } + } + }, "/apps/installed/sync": { "post": { "security": [ @@ -4946,7 +4859,7 @@ var doc = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.GroupOperate" + "$ref": "#/definitions/dto.GroupCreate" } } ], @@ -5007,13 +4920,21 @@ var doc = `{ "isList": false, "output_colume": "name", "output_value": "name" + }, + { + "db": "groups", + "input_colume": "id", + "input_value": "id", + "isList": false, + "output_colume": "type", + "output_value": "type" } ], "bodyKeys": [ "id" ], - "formatEN": "delete group [name]", - "formatZH": "删除组 [name]", + "formatEN": "delete group [type][name]", + "formatZH": "删除组 [type][name]", "paramKeys": [] } } @@ -5076,7 +4997,7 @@ var doc = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.GroupOperate" + "$ref": "#/definitions/dto.GroupUpdate" } } ], @@ -8549,12 +8470,12 @@ var doc = `{ "dto.ChangeHostGroup": { "type": "object", "required": [ - "group", + "groupID", "id" ], "properties": { - "group": { - "type": "string" + "groupID": { + "type": "integer" }, "id": { "type": "integer" @@ -9353,7 +9274,7 @@ var doc = `{ } } }, - "dto.GroupOperate": { + "dto.GroupCreate": { "type": "object", "required": [ "name", @@ -9382,6 +9303,20 @@ var doc = `{ } } }, + "dto.GroupUpdate": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "isDefault": { + "type": "boolean" + }, + "name": { + "type": "string" + } + } + }, "dto.HostConnTest": { "type": "object", "required": [ @@ -9434,6 +9369,9 @@ var doc = `{ "groupBelong": { "type": "string" }, + "groupID": { + "type": "integer" + }, "id": { "type": "integer" }, @@ -9452,7 +9390,6 @@ var doc = `{ "type": "object", "required": [ "addr", - "groupBelong", "port", "user" ], @@ -9470,8 +9407,8 @@ var doc = `{ "description": { "type": "string" }, - "groupBelong": { - "type": "string" + "groupID": { + "type": "integer" }, "id": { "type": "integer" @@ -10270,8 +10207,8 @@ var doc = `{ "pageSize" ], "properties": { - "group": { - "type": "string" + "groupID": { + "type": "integer" }, "info": { "type": "string" @@ -10744,12 +10681,6 @@ var doc = `{ "appId": { "type": "integer" }, - "backups": { - "type": "array", - "items": { - "$ref": "#/definitions/model.AppInstallBackup" - } - }, "containerName": { "type": "string" }, @@ -10797,35 +10728,6 @@ var doc = `{ } } }, - "model.AppInstallBackup": { - "type": "object", - "properties": { - "app_detail_id": { - "type": "integer" - }, - "app_install_id": { - "type": "integer" - }, - "createdAt": { - "type": "string" - }, - "id": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "param": { - "type": "string" - }, - "path": { - "type": "string" - }, - "updatedAt": { - "type": "string" - } - } - }, "model.Tag": { "type": "object", "properties": { @@ -11019,35 +10921,6 @@ var doc = `{ } } }, - "request.AppBackupDelete": { - "type": "object", - "properties": { - "ids": { - "type": "array", - "items": { - "type": "integer" - } - } - } - }, - "request.AppBackupSearch": { - "type": "object", - "required": [ - "page", - "pageSize" - ], - "properties": { - "appInstallID": { - "type": "integer" - }, - "page": { - "type": "integer" - }, - "pageSize": { - "type": "integer" - } - } - }, "request.AppInstallCreate": { "type": "object", "required": [ diff --git a/cmd/server/docs/swagger.json b/cmd/server/docs/swagger.json index a3fc60f14..d60cda85a 100644 --- a/cmd/server/docs/swagger.json +++ b/cmd/server/docs/swagger.json @@ -150,39 +150,6 @@ } } }, - "/apps/installed": { - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "获取已安装应用列表", - "consumes": [ - "application/json" - ], - "tags": [ - "App" - ], - "summary": "List app installed", - "parameters": [ - { - "description": "request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/request.AppInstalledSearch" - } - } - ], - "responses": { - "200": { - "description": "" - } - } - } - }, "/apps/installed/:appInstallId/versions": { "get": { "security": [ @@ -217,93 +184,6 @@ } } }, - "/apps/installed/backups": { - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "查询已安装备份列表分页", - "consumes": [ - "application/json" - ], - "tags": [ - "App" - ], - "summary": "Page installed backups", - "parameters": [ - { - "description": "request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/request.AppBackupSearch" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/dto.PageResult" - } - } - } - } - }, - "/apps/installed/backups/del": { - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "删除应用备份记录", - "consumes": [ - "application/json" - ], - "tags": [ - "App" - ], - "summary": "Delete app backup record", - "parameters": [ - { - "description": "request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/request.AppBackupDelete" - } - } - ], - "responses": { - "200": { - "description": "" - } - }, - "x-panel-log": { - "BeforeFuntions": [ - { - "db": "app_install_backups", - "input_colume": "id", - "input_value": "ids", - "isList": true, - "output_colume": "name", - "output_value": "names" - } - ], - "bodyKeys": [ - "ids" - ], - "formatEN": "Deleting an Application Backup [names]", - "formatZH": "删除应用备份 [names]", - "paramKeys": [] - } - } - }, "/apps/installed/check/:key": { "get": { "security": [ @@ -620,6 +500,39 @@ } } }, + "/apps/installed/search": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "获取已安装应用列表", + "consumes": [ + "application/json" + ], + "tags": [ + "App" + ], + "summary": "List app installed", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.AppInstalledSearch" + } + } + ], + "responses": { + "200": { + "description": "" + } + } + } + }, "/apps/installed/sync": { "post": { "security": [ @@ -4932,7 +4845,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.GroupOperate" + "$ref": "#/definitions/dto.GroupCreate" } } ], @@ -4993,13 +4906,21 @@ "isList": false, "output_colume": "name", "output_value": "name" + }, + { + "db": "groups", + "input_colume": "id", + "input_value": "id", + "isList": false, + "output_colume": "type", + "output_value": "type" } ], "bodyKeys": [ "id" ], - "formatEN": "delete group [name]", - "formatZH": "删除组 [name]", + "formatEN": "delete group [type][name]", + "formatZH": "删除组 [type][name]", "paramKeys": [] } } @@ -5062,7 +4983,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.GroupOperate" + "$ref": "#/definitions/dto.GroupUpdate" } } ], @@ -8535,12 +8456,12 @@ "dto.ChangeHostGroup": { "type": "object", "required": [ - "group", + "groupID", "id" ], "properties": { - "group": { - "type": "string" + "groupID": { + "type": "integer" }, "id": { "type": "integer" @@ -9339,7 +9260,7 @@ } } }, - "dto.GroupOperate": { + "dto.GroupCreate": { "type": "object", "required": [ "name", @@ -9368,6 +9289,20 @@ } } }, + "dto.GroupUpdate": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "isDefault": { + "type": "boolean" + }, + "name": { + "type": "string" + } + } + }, "dto.HostConnTest": { "type": "object", "required": [ @@ -9420,6 +9355,9 @@ "groupBelong": { "type": "string" }, + "groupID": { + "type": "integer" + }, "id": { "type": "integer" }, @@ -9438,7 +9376,6 @@ "type": "object", "required": [ "addr", - "groupBelong", "port", "user" ], @@ -9456,8 +9393,8 @@ "description": { "type": "string" }, - "groupBelong": { - "type": "string" + "groupID": { + "type": "integer" }, "id": { "type": "integer" @@ -10256,8 +10193,8 @@ "pageSize" ], "properties": { - "group": { - "type": "string" + "groupID": { + "type": "integer" }, "info": { "type": "string" @@ -10730,12 +10667,6 @@ "appId": { "type": "integer" }, - "backups": { - "type": "array", - "items": { - "$ref": "#/definitions/model.AppInstallBackup" - } - }, "containerName": { "type": "string" }, @@ -10783,35 +10714,6 @@ } } }, - "model.AppInstallBackup": { - "type": "object", - "properties": { - "app_detail_id": { - "type": "integer" - }, - "app_install_id": { - "type": "integer" - }, - "createdAt": { - "type": "string" - }, - "id": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "param": { - "type": "string" - }, - "path": { - "type": "string" - }, - "updatedAt": { - "type": "string" - } - } - }, "model.Tag": { "type": "object", "properties": { @@ -11005,35 +10907,6 @@ } } }, - "request.AppBackupDelete": { - "type": "object", - "properties": { - "ids": { - "type": "array", - "items": { - "type": "integer" - } - } - } - }, - "request.AppBackupSearch": { - "type": "object", - "required": [ - "page", - "pageSize" - ], - "properties": { - "appInstallID": { - "type": "integer" - }, - "page": { - "type": "integer" - }, - "pageSize": { - "type": "integer" - } - } - }, "request.AppInstallCreate": { "type": "object", "required": [ diff --git a/cmd/server/docs/swagger.yaml b/cmd/server/docs/swagger.yaml index 27de7219c..c5b4bfa4d 100644 --- a/cmd/server/docs/swagger.yaml +++ b/cmd/server/docs/swagger.yaml @@ -61,12 +61,12 @@ definitions: type: object dto.ChangeHostGroup: properties: - group: - type: string + groupID: + type: integer id: type: integer required: - - group + - groupID - id type: object dto.CleanLog: @@ -608,7 +608,7 @@ definitions: - type - vars type: object - dto.GroupOperate: + dto.GroupCreate: properties: id: type: integer @@ -627,6 +627,15 @@ definitions: required: - type type: object + dto.GroupUpdate: + properties: + id: + type: integer + isDefault: + type: boolean + name: + type: string + type: object dto.HostConnTest: properties: addr: @@ -663,6 +672,8 @@ definitions: type: string groupBelong: type: string + groupID: + type: integer id: type: integer name: @@ -683,8 +694,8 @@ definitions: type: string description: type: string - groupBelong: - type: string + groupID: + type: integer id: type: integer name: @@ -701,7 +712,6 @@ definitions: type: string required: - addr - - groupBelong - port - user type: object @@ -1217,8 +1227,8 @@ definitions: type: object dto.SearchHostWithPage: properties: - group: - type: string + groupID: + type: integer info: type: string page: @@ -1532,10 +1542,6 @@ definitions: type: integer appId: type: integer - backups: - items: - $ref: '#/definitions/model.AppInstallBackup' - type: array containerName: type: string createdAt: @@ -1567,25 +1573,6 @@ definitions: version: type: string type: object - model.AppInstallBackup: - properties: - app_detail_id: - type: integer - app_install_id: - type: integer - createdAt: - type: string - id: - type: integer - name: - type: string - param: - type: string - path: - type: string - updatedAt: - type: string - type: object model.Tag: properties: createdAt: @@ -1713,25 +1700,6 @@ definitions: $ref: '#/definitions/model.Website' type: array type: object - request.AppBackupDelete: - properties: - ids: - items: - type: integer - type: array - type: object - request.AppBackupSearch: - properties: - appInstallID: - type: integer - page: - type: integer - pageSize: - type: integer - required: - - page - - pageSize - type: object request.AppInstallCreate: properties: appDetailId: @@ -2721,26 +2689,6 @@ paths: formatEN: Install app [appKey]-[name] formatZH: 安装应用 [appKey]-[name] paramKeys: [] - /apps/installed: - post: - consumes: - - application/json - description: 获取已安装应用列表 - parameters: - - description: request - in: body - name: request - required: true - schema: - $ref: '#/definitions/request.AppInstalledSearch' - responses: - "200": - description: "" - security: - - ApiKeyAuth: [] - summary: List app installed - tags: - - App /apps/installed/:appInstallId/versions: get: consumes: @@ -2762,61 +2710,6 @@ paths: summary: Search app update version by install id tags: - App - /apps/installed/backups: - post: - consumes: - - application/json - description: 查询已安装备份列表分页 - parameters: - - description: request - in: body - name: request - required: true - schema: - $ref: '#/definitions/request.AppBackupSearch' - responses: - "200": - description: OK - schema: - $ref: '#/definitions/dto.PageResult' - security: - - ApiKeyAuth: [] - summary: Page installed backups - tags: - - App - /apps/installed/backups/del: - post: - consumes: - - application/json - description: 删除应用备份记录 - parameters: - - description: request - in: body - name: request - required: true - schema: - $ref: '#/definitions/request.AppBackupDelete' - responses: - "200": - description: "" - security: - - ApiKeyAuth: [] - summary: Delete app backup record - tags: - - App - x-panel-log: - BeforeFuntions: - - db: app_install_backups - input_colume: id - input_value: ids - isList: true - output_colume: name - output_value: names - bodyKeys: - - ids - formatEN: Deleting an Application Backup [names] - formatZH: 删除应用备份 [names] - paramKeys: [] /apps/installed/check/:key: get: consumes: @@ -3018,6 +2911,26 @@ paths: formatEN: Application port update [key]-[name] => [port] formatZH: 应用端口修改 [key]-[name] => [port] paramKeys: [] + /apps/installed/search: + post: + consumes: + - application/json + description: 获取已安装应用列表 + parameters: + - description: request + in: body + name: request + required: true + schema: + $ref: '#/definitions/request.AppInstalledSearch' + responses: + "200": + description: "" + security: + - ApiKeyAuth: [] + summary: List app installed + tags: + - App /apps/installed/sync: post: description: 同步已安装应用列表 @@ -5758,7 +5671,7 @@ paths: name: request required: true schema: - $ref: '#/definitions/dto.GroupOperate' + $ref: '#/definitions/dto.GroupCreate' responses: "200": description: "" @@ -5803,10 +5716,16 @@ paths: isList: false output_colume: name output_value: name + - db: groups + input_colume: id + input_value: id + isList: false + output_colume: type + output_value: type bodyKeys: - id - formatEN: delete group [name] - formatZH: 删除组 [name] + formatEN: delete group [type][name] + formatZH: 删除组 [type][name] paramKeys: [] /hosts/group/search: post: @@ -5841,7 +5760,7 @@ paths: name: request required: true schema: - $ref: '#/definitions/dto.GroupOperate' + $ref: '#/definitions/dto.GroupUpdate' responses: "200": description: "" diff --git a/frontend/components.d.ts b/frontend/components.d.ts index cad4b1ef6..193ef3c0c 100644 --- a/frontend/components.d.ts +++ b/frontend/components.d.ts @@ -73,6 +73,8 @@ declare module 'vue' { FileList: typeof import('./src/components/file-list/index.vue')['default'] FileRole: typeof import('./src/components/file-role/index.vue')['default'] Footer: typeof import('./src/components/app-layout/footer/index.vue')['default'] + Gropu: typeof import('./src/components/gropu/index.vue')['default'] + Group: typeof import('./src/components/group/index.vue')['default'] InfiniteScroll: typeof import('element-plus/es')['ElInfiniteScroll'] Loading: typeof import('element-plus/es')['ElLoadingDirective'] Logo: typeof import('./src/components/app-layout/menu/components/Logo.vue')['default'] diff --git a/frontend/src/api/interface/group.ts b/frontend/src/api/interface/group.ts index 4038e664d..4d925361f 100644 --- a/frontend/src/api/interface/group.ts +++ b/frontend/src/api/interface/group.ts @@ -3,12 +3,18 @@ export namespace Group { id: number; name: string; type: string; + isDefault: boolean; } - export interface GroupOperate { + export interface GroupCreate { id: number; name: string; type: string; } + export interface GroupUpdate { + id: number; + name: string; + isDefault: boolean; + } export interface GroupSearch { type: string; } diff --git a/frontend/src/api/interface/host.ts b/frontend/src/api/interface/host.ts index 4023dbae6..a81d6061a 100644 --- a/frontend/src/api/interface/host.ts +++ b/frontend/src/api/interface/host.ts @@ -12,6 +12,7 @@ export namespace Host { } export interface Host extends CommonModel { name: string; + groupID: number; groupBelong: string; addr: string; port: number; @@ -22,7 +23,7 @@ export namespace Host { export interface HostOperate { id: number; name: string; - groupBelong: string; + groupID: number; addr: string; port: number; user: string; @@ -42,13 +43,13 @@ export namespace Host { } export interface GroupChange { id: number; - group: string; + groupID: number; } export interface ReqSearch { info?: string; } export interface SearchWithPage extends ReqPage { - group: string; + groupID: number; info?: string; } } diff --git a/frontend/src/api/modules/host.ts b/frontend/src/api/modules/host.ts index 8e7997f1d..f335bbeaa 100644 --- a/frontend/src/api/modules/host.ts +++ b/frontend/src/api/modules/host.ts @@ -33,16 +33,16 @@ export const deleteHost = (params: { ids: number[] }) => { }; // group -export const getGroupList = (params: Group.GroupSearch) => { +export const GetGroupList = (params: Group.GroupSearch) => { return http.post>(`/hosts/group/search`, params); }; -export const addGroup = (params: Group.GroupOperate) => { - return http.post(`/hosts/group`, params); +export const CreateGroup = (params: Group.GroupCreate) => { + return http.post(`/hosts/group`, params); }; -export const editGroup = (params: Group.GroupOperate) => { +export const UpdateGroup = (params: Group.GroupUpdate) => { return http.post(`/hosts/group/update`, params); }; -export const deleteGroup = (id: number) => { +export const DeleteGroup = (id: number) => { return http.post(`/hosts/group/del`, { id: id }); }; diff --git a/frontend/src/components/backup/index.vue b/frontend/src/components/backup/index.vue index 5bf341dbe..d8fd7530b 100644 --- a/frontend/src/components/backup/index.vue +++ b/frontend/src/components/backup/index.vue @@ -108,7 +108,6 @@ const onBackup = async () => { loading.value = true; await handleBackup(params) .then(() => { - console.log(loading.value); loading.value = false; MsgSuccess(i18n.global.t('commons.msg.operationSuccess')); search(); diff --git a/frontend/src/views/host/terminal/host/group/index.vue b/frontend/src/components/group/index.vue similarity index 59% rename from frontend/src/views/host/terminal/host/group/index.vue rename to frontend/src/components/group/index.vue index abaf5223b..0660259dd 100644 --- a/frontend/src/views/host/terminal/host/group/index.vue +++ b/frontend/src/components/group/index.vue @@ -1,10 +1,10 @@