From def6c11dbfaac24301ba1c1b8aa268cf55550d22 Mon Sep 17 00:00:00 2001 From: chenyifan01 Date: Sun, 9 Oct 2022 18:07:57 +0800 Subject: [PATCH] #2908 1.medal-> badge 2.add badge user management 3.add badge in user profile --- models/badge.go | 137 +++++++++++++++++++++++ models/{medal_category.go => badge_category.go} | 38 +++---- models/badge_user.go | 140 ++++++++++++++++++++++++ models/medal.go | 103 ----------------- models/models.go | 6 +- models/user.go | 21 ++++ models/user_medal.go | 10 -- routers/badge/badge.go | 98 +++++++++++++++++ routers/{medal => badge}/category.go | 18 +-- routers/medal/medal.go | 46 -------- routers/routes/routes.go | 18 ++- routers/user/profile.go | 16 +++ services/admin/operate_log/operate_log.go | 4 +- services/badge/badge.go | 64 +++++++++++ services/badge/category.go | 64 +++++++++++ services/badge/user.go | 104 ++++++++++++++++++ services/medal/category.go | 64 ----------- services/medal/medal.go | 64 ----------- 18 files changed, 690 insertions(+), 325 deletions(-) create mode 100644 models/badge.go rename models/{medal_category.go => badge_category.go} (59%) create mode 100644 models/badge_user.go delete mode 100644 models/medal.go delete mode 100644 models/user_medal.go create mode 100644 routers/badge/badge.go rename routers/{medal => badge}/category.go (62%) delete mode 100644 routers/medal/medal.go create mode 100644 services/badge/badge.go create mode 100644 services/badge/category.go create mode 100644 services/badge/user.go delete mode 100644 services/medal/category.go delete mode 100644 services/medal/medal.go diff --git a/models/badge.go b/models/badge.go new file mode 100644 index 000000000..20e3ea66a --- /dev/null +++ b/models/badge.go @@ -0,0 +1,137 @@ +package models + +import ( + "code.gitea.io/gitea/modules/timeutil" + "xorm.io/builder" +) + +type Badge struct { + ID int64 `xorm:"pk autoincr"` + Name string + LightedIcon string `xorm:"varchar(2048)"` + GreyedIcon string `xorm:"varchar(2048)"` + Url string `xorm:"varchar(2048)"` + CategoryId int64 + CreatedUnix timeutil.TimeStamp `xorm:"created"` + UpdatedUnix timeutil.TimeStamp `xorm:"updated"` + DeletedAt timeutil.TimeStamp `xorm:"deleted"` +} + +func (m *Badge) ToUserShow() *Badge4UserShow { + return &Badge4UserShow{ + Name: m.Name, + LightedIcon: m.LightedIcon, + GreyedIcon: m.GreyedIcon, + Url: m.Url, + } +} + +type GetBadgeOpts struct { + BadgeType BadgeType +} + +type BadgeAndCategory struct { + Badge Badge `xorm:"extends"` + Category BadgeCategory `xorm:"extends"` +} + +func (*BadgeAndCategory) TableName() string { + return "badge" +} + +func (m *BadgeAndCategory) ToShow() *Badge4AdminShow { + return &Badge4AdminShow{ + ID: m.Badge.ID, + Name: m.Badge.Name, + LightedIcon: m.Badge.LightedIcon, + GreyedIcon: m.Badge.GreyedIcon, + Url: m.Badge.Url, + CategoryName: m.Category.Name, + CategoryId: m.Category.ID, + CreatedUnix: m.Badge.CreatedUnix, + UpdatedUnix: m.Badge.UpdatedUnix, + } +} + +type Badge4AdminShow struct { + ID int64 + Name string + LightedIcon string + GreyedIcon string + Url string + CategoryName string + CategoryId int64 + CreatedUnix timeutil.TimeStamp + UpdatedUnix timeutil.TimeStamp +} + +func (m Badge4AdminShow) ToDTO() Badge { + return Badge{ + Name: m.Name, + LightedIcon: m.LightedIcon, + GreyedIcon: m.GreyedIcon, + Url: m.Url, + CategoryId: m.CategoryId, + } +} + +type Badge4UserShow struct { + Name string + LightedIcon string + GreyedIcon string + Url string +} + +type BadgeShowWithStatus struct { + Badge *Badge4UserShow + IsLighted bool +} + +type UserAllBadgeInCategory struct { + CategoryName string + CategoryId int64 + LightedNum int + Badges []*BadgeShowWithStatus +} + +func GetBadgeList(opts GetBadgeOpts) ([]*BadgeAndCategory, error) { + var cond = builder.NewCond() + if opts.BadgeType > 0 { + cond = cond.And(builder.Eq{"badge_category.type": opts.BadgeType}) + } + + r := make([]*BadgeAndCategory, 0) + if err := x.Join("INNER", "badge_category", "badge_category.ID = badge.category_id").Where(cond).OrderBy("badge.created_unix desc").Find(&r); err != nil { + return nil, err + } + return r, nil +} + +func AddBadge(m Badge) (int64, error) { + return x.Insert(&m) +} + +func UpdateBadgeById(id int64, param Badge) (int64, error) { + return x.ID(id).Update(¶m) +} + +func DelBadge(id int64) (int64, error) { + return x.ID(id).Delete(&Badge{}) +} + +func GetBadgeById(id int64) (*Badge, error) { + m := &Badge{} + has, err := x.ID(id).Get(m) + if err != nil { + return nil, err + } else if !has { + return nil, &ErrRecordNotExist{} + } + return m, nil +} + +func GetBadgeByCategoryId(categoryId int64) ([]*Badge, error) { + r := make([]*Badge, 0) + err := x.Where("category_id = ?", categoryId).Find(&r) + return r, err +} diff --git a/models/medal_category.go b/models/badge_category.go similarity index 59% rename from models/medal_category.go rename to models/badge_category.go index 3c8769650..e8f90f6c1 100644 --- a/models/medal_category.go +++ b/models/badge_category.go @@ -2,25 +2,25 @@ package models import "code.gitea.io/gitea/modules/timeutil" -type MedalType int +type BadgeType int const ( - CustomizeMedal = iota + 1 - SystemMedal + CustomizeBadge = iota + 1 + SystemBadge ) -type MedalCategory struct { +type BadgeCategory struct { ID int64 `xorm:"pk autoincr"` Name string Position int64 - Type MedalType + Type BadgeType CreatedUnix timeutil.TimeStamp `xorm:"created"` UpdatedUnix timeutil.TimeStamp `xorm:"updated"` DeletedAt timeutil.TimeStamp `xorm:"deleted"` } -func (m *MedalCategory) ToShow() *MedalCategory4Show { - return &MedalCategory4Show{ +func (m *BadgeCategory) ToShow() *BadgeCategory4Show { + return &BadgeCategory4Show{ ID: m.ID, Name: m.Name, Position: m.Position, @@ -29,16 +29,16 @@ func (m *MedalCategory) ToShow() *MedalCategory4Show { } } -type MedalCategory4Show struct { +type BadgeCategory4Show struct { ID int64 `xorm:"pk autoincr"` Name string Position int64 - Type MedalType + Type BadgeType CreatedUnix timeutil.TimeStamp `xorm:"created"` } -func (m MedalCategory4Show) ToDTO() MedalCategory { - return MedalCategory{ +func (m BadgeCategory4Show) ToDTO() BadgeCategory { + return BadgeCategory{ ID: m.ID, Name: m.Name, Position: m.Position, @@ -47,28 +47,28 @@ func (m MedalCategory4Show) ToDTO() MedalCategory { } } -func GetMedalCategoryList() ([]*MedalCategory, error) { - r := make([]*MedalCategory, 0) +func GetBadgeCategoryList() ([]*BadgeCategory, error) { + r := make([]*BadgeCategory, 0) if err := x.OrderBy("position asc,created_unix desc").Find(&r); err != nil { return nil, err } return r, nil } -func AddMedalCategory(m MedalCategory) (int64, error) { +func AddBadgeCategory(m BadgeCategory) (int64, error) { return x.Insert(&m) } -func UpdateMedalCategoryById(id int64, param MedalCategory) (int64, error) { +func UpdateBadgeCategoryById(id int64, param BadgeCategory) (int64, error) { return x.ID(id).Update(¶m) } -func DelMedalCategory(id int64) (int64, error) { - return x.ID(id).Delete(&MedalCategory{}) +func DelBadgeCategory(id int64) (int64, error) { + return x.ID(id).Delete(&BadgeCategory{}) } -func GetMedalCategoryById(id int64) (*MedalCategory, error) { - m := &MedalCategory{} +func GetBadgeCategoryById(id int64) (*BadgeCategory, error) { + m := &BadgeCategory{} has, err := x.ID(id).Get(m) if err != nil { return nil, err diff --git a/models/badge_user.go b/models/badge_user.go new file mode 100644 index 000000000..b2428ab1a --- /dev/null +++ b/models/badge_user.go @@ -0,0 +1,140 @@ +package models + +import ( + "code.gitea.io/gitea/modules/timeutil" + "xorm.io/builder" +) + +const ( + ActionAddBadgeUser = 1 + ActionDelBadgeUser = 2 +) + +type BadgeUser struct { + ID int64 `xorm:"pk autoincr"` + UserId int64 `xorm:"unique(user_id,badge_id)"` + BadgeId int64 `xorm:"index"` + CreatedUnix timeutil.TimeStamp `xorm:"created index"` +} + +type BadgeUserLog struct { + ID int64 `xorm:"pk autoincr"` + UserId int64 `xorm:"index"` + BadgeId int64 `xorm:"index"` + Action int + CreatedUnix timeutil.TimeStamp `xorm:"created index"` +} + +type BadgeUserDetail struct { + BadgeUser BadgeUser `xorm:"extends"` + User User `xorm:"extends"` +} + +func (*BadgeUserDetail) TableName() string { + return "badge_user" +} + +func (m *BadgeUserDetail) ToShow() *BadgeUser4SHow { + return &BadgeUser4SHow{ + ID: m.BadgeUser.ID, + UserId: m.BadgeUser.UserId, + Name: m.User.Name, + Avatar: m.User.RelAvatarLink(), + Email: m.User.Email, + CreatedUnix: m.BadgeUser.CreatedUnix, + } +} + +type BadgeUser4SHow struct { + ID int64 + UserId int64 + Name string + Avatar string + Email string + CreatedUnix timeutil.TimeStamp +} + +type AddBadgeUsersReq struct { + BadgeId int64 + Users string +} +type DelBadgeUserReq struct { + ID int64 +} + +type GetUserBadgesOpts struct { + CategoryId int64 + ListOptions +} + +func AddBadgeUser(m BadgeUser) (int64, error) { + sess := x.NewSession() + defer sess.Close() + sess.Begin() + n, err := sess.Insert(&m) + if err != nil || n == 0 { + return 0, err + } + _, err = sess.Insert(&BadgeUserLog{ + UserId: m.UserId, + BadgeId: m.BadgeId, + Action: ActionAddBadgeUser, + }) + if err != nil { + sess.Rollback() + return 0, err + } + return n, sess.Commit() +} + +func DelBadgeUser(id int64) (int64, error) { + m := BadgeUser{} + has, err := x.ID(id).Get(&m) + if err != nil { + return 0, err + } + if !has { + return 0, ErrRecordNotExist{} + } + sess := x.NewSession() + defer sess.Close() + sess.Begin() + n, err := x.ID(m.ID).Delete(&BadgeUser{}) + if err != nil || n == 0 { + return 0, err + } + _, err = sess.Insert(&BadgeUserLog{ + UserId: m.UserId, + BadgeId: m.BadgeId, + Action: ActionDelBadgeUser, + }) + if err != nil { + sess.Rollback() + return 0, err + } + return n, sess.Commit() +} + +func GetBadgeUsers(badgeId int64, opts ListOptions) ([]BadgeUserDetail, error) { + if opts.Page <= 0 { + opts.Page = 1 + } + m := make([]BadgeUserDetail, 0) + err := x.Join("LEFT", "public.user", "public.user.ID = badge_user.user_id").Where("badge_user.badge_id = ?", badgeId).OrderBy("badge_user.created_unix desc").Limit(opts.PageSize, (opts.Page-1)*opts.PageSize).Find(&m) + if err != nil { + return nil, err + } + return m, nil +} + +func GetUserBadges(userId int64, opts GetUserBadgesOpts) ([]*Badge, error) { + cond := builder.NewCond() + cond = cond.And(builder.Eq{"badge_user.user_id": userId}) + if opts.CategoryId > 0 { + cond = cond.And(builder.Eq{"badge.category_id": opts.CategoryId}) + } + + r := make([]*Badge, 0) + err := x.Join("INNER", "badge_user", "badge_user.badge_id = badge.id").Where(cond).OrderBy("badge_user.created_unix desc").Limit(opts.PageSize, (opts.Page-1)*opts.PageSize).Find(&r) + return r, err +} diff --git a/models/medal.go b/models/medal.go deleted file mode 100644 index d2508b3b1..000000000 --- a/models/medal.go +++ /dev/null @@ -1,103 +0,0 @@ -package models - -import ( - "code.gitea.io/gitea/modules/timeutil" - "xorm.io/builder" -) - -type Medal struct { - ID int64 `xorm:"pk autoincr"` - Name string - LightedIcon string `xorm:"varchar(2048)"` - GreyedIcon string `xorm:"varchar(2048)"` - Url string `xorm:"varchar(2048)"` - CategoryId int64 - CreatedUnix timeutil.TimeStamp `xorm:"created"` - UpdatedUnix timeutil.TimeStamp `xorm:"updated"` - DeletedAt timeutil.TimeStamp `xorm:"deleted"` -} - -type GetMedalOpts struct { - MedalType MedalType -} - -type MedalAndCategory struct { - Medal Medal `xorm:"extends"` - Category MedalCategory `xorm:"extends"` -} - -func (*MedalAndCategory) TableName() string { - return "medal" -} - -func (m *MedalAndCategory) ToShow() *Medal4Show { - return &Medal4Show{ - ID: m.Medal.ID, - Name: m.Medal.Name, - LightedIcon: m.Medal.LightedIcon, - GreyedIcon: m.Medal.GreyedIcon, - Url: m.Medal.Url, - CategoryName: m.Category.Name, - CategoryId: m.Category.ID, - CreatedUnix: m.Medal.CreatedUnix, - UpdatedUnix: m.Medal.UpdatedUnix, - } -} - -type Medal4Show struct { - ID int64 - Name string - LightedIcon string - GreyedIcon string - Url string - CategoryName string - CategoryId int64 - CreatedUnix timeutil.TimeStamp - UpdatedUnix timeutil.TimeStamp -} - -func (m Medal4Show) ToDTO() Medal { - return Medal{ - Name: m.Name, - LightedIcon: m.LightedIcon, - GreyedIcon: m.GreyedIcon, - Url: m.Url, - CategoryId: m.CategoryId, - } -} - -func GetMedalList(opts GetMedalOpts) ([]*MedalAndCategory, error) { - var cond = builder.NewCond() - if opts.MedalType > 0 { - cond = cond.And(builder.Eq{"medal_category.type": opts.MedalType}) - } - - r := make([]*MedalAndCategory, 0) - if err := x.Join("INNER", "medal_category", "medal_category.ID = medal.category_id").Where(cond).OrderBy("medal.created_unix desc").Find(&r); err != nil { - return nil, err - } - return r, nil -} - -func AddMedal(m Medal) (int64, error) { - return x.Insert(&m) -} - -func UpdateMedalById(id int64, param Medal) (int64, error) { - return x.ID(id).Update(¶m) -} - -func DelMedal(id int64) (int64, error) { - return x.ID(id).Delete(&Medal{}) -} - -func GetMedalById(id int64) (*Medal, error) { - m := &Medal{} - has, err := x.ID(id).Get(m) - if err != nil { - return nil, err - } else if !has { - return nil, &ErrRecordNotExist{} - } - return m, nil -} diff --git a/models/models.go b/models/models.go index 910bfde65..ff64bfad2 100755 --- a/models/models.go +++ b/models/models.go @@ -161,8 +161,10 @@ func init() { new(CloudbrainSpec), new(CloudbrainTemp), new(DatasetReference), - new(MedalCategory), - new(Medal), + new(BadgeCategory), + new(Badge), + new(BadgeUser), + new(BadgeUserLog), ) tablesStatistic = append(tablesStatistic, diff --git a/models/user.go b/models/user.go index f40eb699f..b21858e37 100755 --- a/models/user.go +++ b/models/user.go @@ -2184,3 +2184,24 @@ func GetBlockChainUnSuccessUsers() ([]*User, error) { Find(&users) return users, err } + +//GetUserIdsByUserNames Get userIDs in batches through username paging, this method will ignore errors +func GetUserIdsByUserNames(names []string) []int64 { + pageSize := 200 + length := len(names) + r := make([]int64, 0, length) + for i := 0; i < length; i = i + pageSize { + if length-i < 200 { + pageSize = length - i + } + userNameTemp := names[i : i+pageSize] + t := make([]int64, 0, length) + err := x.Table("public.user").Cols("id").In("name", userNameTemp).Find(&t) + if err != nil { + continue + } + r = append(r, t...) + + } + return r +} diff --git a/models/user_medal.go b/models/user_medal.go deleted file mode 100644 index a4421df13..000000000 --- a/models/user_medal.go +++ /dev/null @@ -1,10 +0,0 @@ -package models - -import "code.gitea.io/gitea/modules/timeutil" - -type UserMedal struct { - ID int64 `xorm:"pk autoincr"` - UserId int64 `xorm:"index"` - MedalId int64 `xorm:"index"` - CreatedUnix timeutil.TimeStamp `xorm:"created"` -} diff --git a/routers/badge/badge.go b/routers/badge/badge.go new file mode 100644 index 000000000..c62c1ee74 --- /dev/null +++ b/routers/badge/badge.go @@ -0,0 +1,98 @@ +package badge + +import ( + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/routers/response" + "code.gitea.io/gitea/services/badge" + "errors" + "net/http" + "strings" +) + +func GetCustomizeBadgeList(ctx *context.Context) { + r, err := badge.GetBadgeList(models.GetBadgeOpts{BadgeType: models.CustomizeBadge}) + if err != nil { + log.Error("GetCustomizeBadgeList error.%v", err) + ctx.JSON(http.StatusOK, response.ServerError(err.Error())) + return + } + m := make(map[string]interface{}) + m["List"] = r + ctx.JSON(http.StatusOK, response.SuccessWithData(m)) +} + +func OperateBadge(ctx *context.Context, category models.Badge4AdminShow) { + action := ctx.Params(":action") + + var err error + switch action { + case "edit": + err = badge.EditBadge(category, ctx.User) + case "new": + err = badge.AddBadge(category, ctx.User) + case "del": + err = badge.DelBadge(category.ID, ctx.User) + default: + err = errors.New("action type error") + } + + if err != nil { + log.Error("OperateBadge error ,%v", err) + ctx.JSON(http.StatusOK, response.ServerError(err.Error())) + return + } + ctx.JSON(http.StatusOK, response.Success()) +} + +func GetBadgeUsers(ctx *context.Context) { + page := ctx.QueryInt("page") + badgeId := ctx.QueryInt64("badge") + r, err := badge.GetBadgeUsers(badgeId, models.ListOptions{PageSize: 20, Page: page}) + if err != nil { + log.Error("GetBadgeUsers error.%v", err) + ctx.JSON(http.StatusOK, response.ServerError(err.Error())) + return + } + m := make(map[string]interface{}) + m["List"] = r + ctx.JSON(http.StatusOK, response.SuccessWithData(m)) +} + +func AddOperateBadgeUsers(ctx *context.Context, req models.AddBadgeUsersReq) { + userStr := req.Users + if userStr == "" { + ctx.JSON(http.StatusOK, response.Success()) + return + } + userStr = strings.ReplaceAll(userStr, " ", "") + userStr = strings.ReplaceAll(userStr, "\r", "") + userNames := strings.Split(userStr, "\n") + n, err := badge.AddBadgeUsers(req.BadgeId, userNames) + if err != nil { + log.Error("AddOperateBadgeUsers error.%v", err) + ctx.JSON(http.StatusOK, response.ServerError(err.Error())) + return + } + m := make(map[string]interface{}) + m["Total"] = len(userNames) + m["Success"] = n + ctx.JSON(http.StatusOK, response.SuccessWithData(m)) +} + +func DelBadgeUsers(ctx *context.Context, req models.DelBadgeUserReq) { + id := req.ID + if id <= 0 { + ctx.JSON(http.StatusOK, response.Success()) + return + } + + err := badge.DelBadgeUser(id) + if err != nil { + log.Error("DelBadgeUsers error.%v", err) + ctx.JSON(http.StatusOK, response.ServerError(err.Error())) + return + } + ctx.JSON(http.StatusOK, response.Success()) +} diff --git a/routers/medal/category.go b/routers/badge/category.go similarity index 62% rename from routers/medal/category.go rename to routers/badge/category.go index b010af586..a386f8fc5 100644 --- a/routers/medal/category.go +++ b/routers/badge/category.go @@ -1,17 +1,17 @@ -package medal +package badge import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/routers/response" - "code.gitea.io/gitea/services/medal" + "code.gitea.io/gitea/services/badge" "errors" "net/http" ) -func GetCategoryList(ctx *context.Context) { - r, err := medal.GetMedalCategoryList() +func GetBadgeCategoryList(ctx *context.Context) { + r, err := badge.GetBadgeCategoryList() if err != nil { log.Error("GetCategoryList error.%v", err) ctx.JSON(http.StatusOK, response.ServerError(err.Error())) @@ -22,23 +22,23 @@ func GetCategoryList(ctx *context.Context) { ctx.JSON(http.StatusOK, response.SuccessWithData(m)) } -func OperateMedalCategory(ctx *context.Context, category models.MedalCategory4Show) { +func OperateBadgeCategory(ctx *context.Context, category models.BadgeCategory4Show) { action := ctx.Params(":action") var err error switch action { case "edit": - err = medal.EditMedalCategory(category, ctx.User) + err = badge.EditBadgeCategory(category, ctx.User) case "new": - err = medal.AddMedalCategory(category, ctx.User) + err = badge.AddBadgeCategory(category, ctx.User) case "del": - err = medal.DelMedalCategory(category.ID, ctx.User) + err = badge.DelBadgeCategory(category.ID, ctx.User) default: err = errors.New("action type error") } if err != nil { - log.Error("OperateMedalCategory error ,%v", err) + log.Error("OperateBadgeCategory error ,%v", err) ctx.JSON(http.StatusOK, response.ServerError(err.Error())) return } diff --git a/routers/medal/medal.go b/routers/medal/medal.go deleted file mode 100644 index d0625a2b4..000000000 --- a/routers/medal/medal.go +++ /dev/null @@ -1,46 +0,0 @@ -package medal - -import ( - "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/log" - "code.gitea.io/gitea/routers/response" - "code.gitea.io/gitea/services/medal" - "errors" - "net/http" -) - -func GetCustomizeMedalList(ctx *context.Context) { - r, err := medal.GetMedalList(models.GetMedalOpts{MedalType: models.CustomizeMedal}) - if err != nil { - log.Error("GetCategoryList error.%v", err) - ctx.JSON(http.StatusOK, response.ServerError(err.Error())) - return - } - m := make(map[string]interface{}) - m["List"] = r - ctx.JSON(http.StatusOK, response.SuccessWithData(m)) -} - -func OperateMedal(ctx *context.Context, category models.Medal4Show) { - action := ctx.Params(":action") - - var err error - switch action { - case "edit": - err = medal.EditMedal(category, ctx.User) - case "new": - err = medal.AddMedal(category, ctx.User) - case "del": - err = medal.DelMedal(category.ID, ctx.User) - default: - err = errors.New("action type error") - } - - if err != nil { - log.Error("OperateCustomizeMedal error ,%v", err) - ctx.JSON(http.StatusOK, response.ServerError(err.Error())) - return - } - ctx.JSON(http.StatusOK, response.Success()) -} diff --git a/routers/routes/routes.go b/routers/routes/routes.go index 5830edfdc..14f2d0f74 100755 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -6,7 +6,7 @@ package routes import ( "bytes" - "code.gitea.io/gitea/routers/medal" + "code.gitea.io/gitea/routers/badge" "code.gitea.io/gitea/routers/reward/point" "code.gitea.io/gitea/routers/task" "code.gitea.io/gitea/services/reward" @@ -663,15 +663,21 @@ func RegisterRoutes(m *macaron.Macaron) { m.Post("/^:action(new|edit|del)$", bindIgnErr(models.TaskConfigWithLimit{}), task.OperateTaskConfig) }) - m.Group("/medal", func() { + m.Group("/badge", func() { m.Group("/category", func() { - m.Get("/list", medal.GetCategoryList) - m.Post("/^:action(new|edit|del)$", bindIgnErr(models.MedalCategory4Show{}), medal.OperateMedalCategory) + m.Get("/list", badge.GetBadgeCategoryList) + m.Post("/^:action(new|edit|del)$", bindIgnErr(models.BadgeCategory4Show{}), badge.OperateBadgeCategory) }) m.Group("/customize", func() { - m.Get("/list", medal.GetCustomizeMedalList) + m.Get("/list", badge.GetCustomizeBadgeList) + + }) + m.Group("/users", func() { + m.Get("", badge.GetBadgeUsers) + m.Post("/add", bindIgnErr(models.AddBadgeUsersReq{}), badge.AddOperateBadgeUsers) + m.Post("/del", bindIgnErr(models.DelBadgeUserReq{}), badge.DelBadgeUsers) }) - m.Post("/^:action(new|edit|del)$", bindIgnErr(models.Medal4Show{}), medal.OperateMedal) + m.Post("/^:action(new|edit|del)$", bindIgnErr(models.Badge4AdminShow{}), badge.OperateBadge) }) }, operationReq) diff --git a/routers/user/profile.go b/routers/user/profile.go index 42cdfd1a8..1d275c191 100755 --- a/routers/user/profile.go +++ b/routers/user/profile.go @@ -6,6 +6,7 @@ package user import ( + "code.gitea.io/gitea/services/badge" "errors" "fmt" "path" @@ -90,10 +91,18 @@ func Profile(ctx *context.Context) { return } + // Show user badges + badges, err := badge.GetUserBadges(ctxUser.ID, models.ListOptions{Page: 1, PageSize: 5}) + if err != nil { + ctx.ServerError("GetUserBadges", err) + return + } + ctx.Data["Title"] = ctxUser.DisplayName() ctx.Data["PageIsUserProfile"] = true ctx.Data["Owner"] = ctxUser ctx.Data["OpenIDs"] = openIDs + ctx.Data["RecentBadges"] = badges ctx.Data["EnableHeatmap"] = setting.Service.EnableUserHeatmap ctx.Data["HeatmapUser"] = ctxUser.Name showPrivate := ctx.IsSigned && (ctx.User.IsAdmin || ctx.User.ID == ctxUser.ID) @@ -297,6 +306,13 @@ func Profile(ctx *context.Context) { } total = int(count) + case "badge": + allBadges, err := badge.GetUserAllBadges(ctxUser.ID) + if err != nil { + ctx.ServerError("GetUserAllBadges", err) + return + } + ctx.Data["AllBadges"] = allBadges default: ctx.ServerError("tab error", errors.New("tab error")) return diff --git a/services/admin/operate_log/operate_log.go b/services/admin/operate_log/operate_log.go index 7f966db0c..f52950351 100644 --- a/services/admin/operate_log/operate_log.go +++ b/services/admin/operate_log/operate_log.go @@ -7,8 +7,8 @@ import ( type LogBizType string const ( - MedalCategoryOperate LogBizType = "MedalCategoryOperate" - MedalOperate LogBizType = "MedalOperate" + BadgeCategoryOperate LogBizType = "BadgeCategoryOperate" + BadgeOperate LogBizType = "BadgeOperate" ) func Log(log models.AdminOperateLog) error { diff --git a/services/badge/badge.go b/services/badge/badge.go new file mode 100644 index 000000000..83c3581b5 --- /dev/null +++ b/services/badge/badge.go @@ -0,0 +1,64 @@ +package badge + +import ( + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/services/admin/operate_log" + "errors" +) + +func GetBadgeList(opts models.GetBadgeOpts) ([]*models.Badge4AdminShow, error) { + list, err := models.GetBadgeList(opts) + if err != nil { + return nil, err + } + if len(list) == 0 { + return nil, nil + } + r := make([]*models.Badge4AdminShow, len(list)) + for i := 0; i < len(list); i++ { + r[i] = list[i].ToShow() + } + + return r, nil +} + +func AddBadge(m models.Badge4AdminShow, doer *models.User) error { + _, err := models.AddBadge(m.ToDTO()) + if err != nil { + return err + } + operate_log.Log4Add(operate_log.BadgeOperate, m, doer.ID, "新增了勋章") + return nil +} + +func EditBadge(m models.Badge4AdminShow, doer *models.User) error { + if m.ID == 0 { + log.Error(" EditBadge param error") + return errors.New("param error") + } + old, err := models.GetBadgeById(m.ID) + if err != nil { + return err + } + _, err = models.UpdateBadgeById(m.ID, m.ToDTO()) + if err != nil { + return err + } + operate_log.Log4Edit(operate_log.BadgeOperate, old, m.ToDTO(), doer.ID, "修改了勋章") + return err +} + +func DelBadge(id int64, doer *models.User) error { + if id == 0 { + log.Error(" DelBadge param error") + return errors.New("param error") + } + old, err := models.GetBadgeById(id) + if err != nil { + return err + } + _, err = models.DelBadge(id) + operate_log.Log4Del(operate_log.BadgeOperate, old, doer.ID, "删除了勋章") + return err +} diff --git a/services/badge/category.go b/services/badge/category.go new file mode 100644 index 000000000..316e654a7 --- /dev/null +++ b/services/badge/category.go @@ -0,0 +1,64 @@ +package badge + +import ( + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/services/admin/operate_log" + "errors" +) + +func GetBadgeCategoryList() ([]*models.BadgeCategory4Show, error) { + list, err := models.GetBadgeCategoryList() + if err != nil { + return nil, err + } + if len(list) == 0 { + return nil, nil + } + r := make([]*models.BadgeCategory4Show, len(list)) + for i := 0; i < len(list); i++ { + r[i] = list[i].ToShow() + } + + return r, nil +} + +func AddBadgeCategory(m models.BadgeCategory4Show, doer *models.User) error { + _, err := models.AddBadgeCategory(m.ToDTO()) + if err != nil { + return err + } + operate_log.Log4Add(operate_log.BadgeCategoryOperate, m, doer.ID, "新增了勋章分类") + return nil +} + +func EditBadgeCategory(m models.BadgeCategory4Show, doer *models.User) error { + if m.ID == 0 { + log.Error(" EditBadgeCategory param error") + return errors.New("param error") + } + old, err := models.GetBadgeCategoryById(m.ID) + if err != nil { + return err + } + _, err = models.UpdateBadgeCategoryById(m.ID, m.ToDTO()) + if err != nil { + return err + } + operate_log.Log4Edit(operate_log.BadgeCategoryOperate, old, m.ToDTO(), doer.ID, "修改了勋章分类") + return err +} + +func DelBadgeCategory(id int64, doer *models.User) error { + if id == 0 { + log.Error(" DelBadgeCategory param error") + return errors.New("param error") + } + old, err := models.GetBadgeCategoryById(id) + if err != nil { + return err + } + _, err = models.DelBadgeCategory(id) + operate_log.Log4Del(operate_log.BadgeCategoryOperate, old, doer.ID, "删除了勋章分类") + return err +} diff --git a/services/badge/user.go b/services/badge/user.go new file mode 100644 index 000000000..ccc112f01 --- /dev/null +++ b/services/badge/user.go @@ -0,0 +1,104 @@ +package badge + +import ( + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/log" +) + +func GetBadgeUsers(badgeId int64, opts models.ListOptions) ([]*models.BadgeUser4SHow, error) { + list, err := models.GetBadgeUsers(badgeId, opts) + if err != nil { + return nil, err + } + if len(list) == 0 { + return nil, nil + } + r := make([]*models.BadgeUser4SHow, len(list)) + for i := 0; i < len(list); i++ { + r[i] = list[i].ToShow() + } + + return r, nil +} + +func AddBadgeUsers(badgeId int64, userNames []string) (int, error) { + userIds := models.GetUserIdsByUserNames(userNames) + if len(userIds) == 0 { + return 0, nil + } + successCount := 0 + for _, v := range userIds { + m := models.BadgeUser{ + UserId: v, + BadgeId: badgeId, + } + _, err := models.AddBadgeUser(m) + if err != nil { + log.Error("AddBadgeUser err in loop, m=%+v. e=%v", m, err) + continue + } + successCount++ + } + return successCount, nil +} + +func DelBadgeUser(id int64) error { + _, err := models.DelBadgeUser(id) + return err +} + +//GetUserBadges Only Returns badges the user has earned +func GetUserBadges(userId int64, opts models.ListOptions) ([]*models.Badge4UserShow, error) { + badges, err := models.GetUserBadges(userId, models.GetUserBadgesOpts{ListOptions: opts}) + if err != nil { + return nil, err + } + r := make([]*models.Badge4UserShow, len(badges)) + for i, v := range badges { + r[i] = v.ToUserShow() + } + return r, nil +} + +func GetUserAllBadges(userId int64) ([]models.UserAllBadgeInCategory, error) { + categoryList, err := models.GetBadgeCategoryList() + if err != nil { + return nil, err + } + r := make([]models.UserAllBadgeInCategory, len(categoryList)) + for i, v := range categoryList { + badges, err := models.GetBadgeByCategoryId(v.ID) + userBadgeMap, err := getUserBadgesMap(userId, v.ID, 100, 1) + if err != nil { + return nil, err + } + t := models.UserAllBadgeInCategory{ + CategoryName: v.Name, + CategoryId: v.ID, + LightedNum: len(userBadgeMap), + } + bArray := make([]*models.BadgeShowWithStatus, len(badges)) + for j, v := range badges { + b := &models.BadgeShowWithStatus{Badge: v.ToUserShow()} + if _, has := userBadgeMap[v.ID]; has { + b.IsLighted = true + } + bArray[j] = b + } + t.Badges = bArray + r[i] = t + } + return r, nil +} + +func getUserBadgesMap(userId, categoryId int64, pageSize, page int) (map[int64]*models.Badge, error) { + userBadges, err := models.GetUserBadges(userId, models.GetUserBadgesOpts{ListOptions: models.ListOptions{PageSize: pageSize, Page: page}, CategoryId: categoryId}) + if err != nil { + return nil, err + } + m := make(map[int64]*models.Badge, 0) + for _, v := range userBadges { + m[v.ID] = v + } + return m, nil +} diff --git a/services/medal/category.go b/services/medal/category.go deleted file mode 100644 index 50f1b804e..000000000 --- a/services/medal/category.go +++ /dev/null @@ -1,64 +0,0 @@ -package medal - -import ( - "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/log" - "code.gitea.io/gitea/services/admin/operate_log" - "errors" -) - -func GetMedalCategoryList() ([]*models.MedalCategory4Show, error) { - list, err := models.GetMedalCategoryList() - if err != nil { - return nil, err - } - if len(list) == 0 { - return nil, nil - } - r := make([]*models.MedalCategory4Show, len(list)) - for i := 0; i < len(list); i++ { - r[i] = list[i].ToShow() - } - - return r, nil -} - -func AddMedalCategory(m models.MedalCategory4Show, doer *models.User) error { - _, err := models.AddMedalCategory(m.ToDTO()) - if err != nil { - return err - } - operate_log.Log4Add(operate_log.MedalCategoryOperate, m, doer.ID, "新增了勋章分类") - return nil -} - -func EditMedalCategory(m models.MedalCategory4Show, doer *models.User) error { - if m.ID == 0 { - log.Error(" EditMedalCategory param error") - return errors.New("param error") - } - old, err := models.GetMedalCategoryById(m.ID) - if err != nil { - return err - } - _, err = models.UpdateMedalCategoryById(m.ID, m.ToDTO()) - if err != nil { - return err - } - operate_log.Log4Edit(operate_log.MedalCategoryOperate, old, m.ToDTO(), doer.ID, "修改了勋章分类") - return err -} - -func DelMedalCategory(id int64, doer *models.User) error { - if id == 0 { - log.Error(" DelMedalCategory param error") - return errors.New("param error") - } - old, err := models.GetMedalCategoryById(id) - if err != nil { - return err - } - _, err = models.DelMedalCategory(id) - operate_log.Log4Del(operate_log.MedalCategoryOperate, old, doer.ID, "删除了勋章分类") - return err -} diff --git a/services/medal/medal.go b/services/medal/medal.go deleted file mode 100644 index 967d7011f..000000000 --- a/services/medal/medal.go +++ /dev/null @@ -1,64 +0,0 @@ -package medal - -import ( - "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/log" - "code.gitea.io/gitea/services/admin/operate_log" - "errors" -) - -func GetMedalList(opts models.GetMedalOpts) ([]*models.Medal4Show, error) { - list, err := models.GetMedalList(opts) - if err != nil { - return nil, err - } - if len(list) == 0 { - return nil, nil - } - r := make([]*models.Medal4Show, len(list)) - for i := 0; i < len(list); i++ { - r[i] = list[i].ToShow() - } - - return r, nil -} - -func AddMedal(m models.Medal4Show, doer *models.User) error { - _, err := models.AddMedal(m.ToDTO()) - if err != nil { - return err - } - operate_log.Log4Add(operate_log.MedalOperate, m, doer.ID, "新增了勋章") - return nil -} - -func EditMedal(m models.Medal4Show, doer *models.User) error { - if m.ID == 0 { - log.Error(" EditMedal param error") - return errors.New("param error") - } - old, err := models.GetMedalById(m.ID) - if err != nil { - return err - } - _, err = models.UpdateMedalById(m.ID, m.ToDTO()) - if err != nil { - return err - } - operate_log.Log4Edit(operate_log.MedalOperate, old, m.ToDTO(), doer.ID, "修改了勋章") - return err -} - -func DelMedal(id int64, doer *models.User) error { - if id == 0 { - log.Error(" DelMedal param error") - return errors.New("param error") - } - old, err := models.GetMedalById(id) - if err != nil { - return err - } - _, err = models.DelMedal(id) - operate_log.Log4Del(operate_log.MedalOperate, old, doer.ID, "删除了勋章") - return err -}