diff --git a/src/models/board.go b/src/models/board.go index ed20d11a..f3dc7a15 100644 --- a/src/models/board.go +++ b/src/models/board.go @@ -13,6 +13,7 @@ type Board struct { Id int64 `json:"id" gorm:"primaryKey"` GroupId int64 `json:"group_id"` Name string `json:"name"` + Ident string `json:"ident"` Tags string `json:"tags"` CreateAt int64 `json:"create_at"` CreateBy string `json:"create_by"` @@ -38,11 +39,36 @@ func (b *Board) Verify() error { return nil } +func (b *Board) CanRenameIdent(ident string) (bool, error) { + if ident == "" { + return true, nil + } + + cnt, err := Count(DB().Model(b).Where("ident=? and id <> ?", b.Ident, b.Id)) + if err != nil { + return false, err + } + + return cnt == 0, nil +} + func (b *Board) Add() error { if err := b.Verify(); err != nil { return err } + if b.Ident != "" { + // ident duplicate check + cnt, err := Count(DB().Model(b).Where("ident=?", b.Ident)) + if err != nil { + return err + } + + if cnt > 0 { + return errors.New("Ident duplicate") + } + } + now := time.Now().Unix() b.CreateAt = now b.UpdateAt = now diff --git a/src/webapi/config/i18n.go b/src/webapi/config/i18n.go index 64546bd4..9431f5db 100644 --- a/src/webapi/config/i18n.go +++ b/src/webapi/config/i18n.go @@ -30,6 +30,7 @@ var ( "Name is blank": "名称不能为空", "Name has invalid characters": "名称含有非法字符", "Dashboard already exists": "监控大盘已存在", + "Ident duplicate": "英文标识已存在", "No such dashboard": "监控大盘不存在", "AlertRule already exists": "告警规则已存在,不能重复创建", "No such AlertRule": "告警规则不存在", diff --git a/src/webapi/router/router_board.go b/src/webapi/router/router_board.go index e2877882..2a9e502c 100644 --- a/src/webapi/router/router_board.go +++ b/src/webapi/router/router_board.go @@ -6,11 +6,13 @@ import ( "github.com/didi/nightingale/v5/src/models" "github.com/gin-gonic/gin" + "github.com/google/uuid" "github.com/toolkits/pkg/ginx" ) type boardForm struct { Name string `json:"name"` + Ident string `json:"ident"` Tags string `json:"tags"` Configs string `json:"configs"` Public int `json:"public"` @@ -25,6 +27,7 @@ func boardAdd(c *gin.Context) { board := &models.Board{ GroupId: ginx.UrlParamInt64(c, "id"), Name: f.Name, + Ident: f.Ident, Tags: f.Tags, Configs: f.Configs, CreateBy: me.Username, @@ -42,7 +45,8 @@ func boardAdd(c *gin.Context) { } func boardGet(c *gin.Context) { - board, err := models.BoardGet("id = ?", ginx.UrlParamInt64(c, "bid")) + bid := ginx.UrlParamStr(c, "bid") + board, err := models.BoardGet("id = ? or ident = ?", bid, bid) ginx.Dangerous(err) if board == nil { @@ -117,12 +121,20 @@ func boardPut(c *gin.Context) { // check permission bgrwCheck(c, bo.GroupId) + can, err := bo.CanRenameIdent(f.Ident) + ginx.Dangerous(err) + + if !can { + ginx.Bomb(http.StatusOK, "Ident duplicate") + } + bo.Name = f.Name + bo.Ident = f.Ident bo.Tags = f.Tags bo.UpdateBy = me.Username bo.UpdateAt = time.Now().Unix() - err := bo.Update("name", "tags", "update_by", "update_at") + err = bo.Update("name", "ident", "tags", "update_by", "update_at") ginx.NewRender(c).Data(bo, err) } @@ -186,6 +198,10 @@ func boardClone(c *gin.Context) { UpdateBy: me.Username, } + if bo.Ident != "" { + newBoard.Ident = uuid.NewString() + } + ginx.Dangerous(newBoard.Add()) // clone payload