This is an automated email from the ASF dual-hosted git repository. robin0716 pushed a commit to branch develop/robin in repository https://gitbox.apache.org/repos/asf/incubator-answer.git
commit 3ed0e59c48ed5cdd41435faccc85fdaea85c6690 Author: kumfo <ku...@sifou.com> AuthorDate: Mon Aug 12 15:33:04 2024 +0800 feat(badge): fixed user's badge award list and add recent user badges --- docs/docs.go | 103 +++++++++++++++++++++++-- docs/swagger.json | 103 +++++++++++++++++++++++-- docs/swagger.yaml | 70 +++++++++++++++-- internal/controller/badge_controller.go | 35 ++++++++- internal/entity/badge_award_entity.go | 21 ++++- internal/repo/badge_award/badge_award_repo.go | 25 +++++- internal/router/answer_api_router.go | 3 +- internal/schema/badge_schema.go | 95 +++++++++++++++-------- internal/service/badge/badge_award_service.go | 107 ++++++++++++++++++++++---- 9 files changed, 489 insertions(+), 73 deletions(-) diff --git a/docs/docs.go b/docs/docs.go index 79e23a85..ecc62169 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -2326,6 +2326,12 @@ const docTemplate = `{ "name": "badge_id", "in": "query", "required": true + }, + { + "type": "string", + "description": "only list the award by username", + "name": "username", + "in": "query" } ], "responses": { @@ -2370,9 +2376,61 @@ const docTemplate = `{ "summary": "get user badge award list", "parameters": [ { - "type": "integer", - "description": "user id", - "name": "user_id", + "type": "string", + "description": "user name", + "name": "username", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.GetUserBadgeAwardListResp" + } + } + } + } + ] + } + } + } + } + }, + "/answer/api/v1/badge/user/awards/recent": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get user badge award list", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "api-badge" + ], + "summary": "get user badge award list", + "parameters": [ + { + "type": "string", + "description": "user name", + "name": "username", "in": "query", "required": true } @@ -7565,21 +7623,31 @@ const docTemplate = `{ "type": "object", "properties": { "award_count": { + "description": "badge award count", "type": "integer" }, "earned": { + "description": "badge earned count", "type": "boolean" }, "icon": { + "description": "badge icon", "type": "string" }, "id": { + "description": "badge id", "type": "string" }, "level": { - "$ref": "#/definitions/entity.BadgeLevel" + "description": "badge level", + "allOf": [ + { + "$ref": "#/definitions/entity.BadgeLevel" + } + ] }, "name": { + "description": "badge name", "type": "string" } } @@ -7839,27 +7907,39 @@ const docTemplate = `{ "type": "object", "properties": { "award_count": { + "description": "badge award count", "type": "integer" }, "description": { + "description": "badge description", "type": "string" }, "earned_count": { + "description": "badge earned count", "type": "integer" }, "icon": { + "description": "badge icon", "type": "string" }, "id": { + "description": "badge id", "type": "string" }, "is_single": { + "description": "badge is single or multiple", "type": "boolean" }, "level": { - "$ref": "#/definitions/entity.BadgeLevel" + "description": "badge level", + "allOf": [ + { + "$ref": "#/definitions/entity.BadgeLevel" + } + ] }, "name": { + "description": "badge name", "type": "string" } } @@ -7868,12 +7948,14 @@ const docTemplate = `{ "type": "object", "properties": { "badges": { + "description": "badge list info", "type": "array", "items": { "$ref": "#/definitions/schema.BadgeListInfo" } }, "group_name": { + "description": "badge group name", "type": "string" } } @@ -8790,18 +8872,27 @@ const docTemplate = `{ "type": "object", "properties": { "earned_count": { + "description": "badge award count", "type": "integer" }, "icon": { + "description": "badge icon", "type": "string" }, "id": { + "description": "badge id", "type": "string" }, "level": { - "$ref": "#/definitions/entity.BadgeLevel" + "description": "badge level", + "allOf": [ + { + "$ref": "#/definitions/entity.BadgeLevel" + } + ] }, "name": { + "description": "badge name", "type": "string" } } diff --git a/docs/swagger.json b/docs/swagger.json index 07aabfea..1412f179 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -2296,6 +2296,12 @@ "name": "badge_id", "in": "query", "required": true + }, + { + "type": "string", + "description": "only list the award by username", + "name": "username", + "in": "query" } ], "responses": { @@ -2340,9 +2346,61 @@ "summary": "get user badge award list", "parameters": [ { - "type": "integer", - "description": "user id", - "name": "user_id", + "type": "string", + "description": "user name", + "name": "username", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.GetUserBadgeAwardListResp" + } + } + } + } + ] + } + } + } + } + }, + "/answer/api/v1/badge/user/awards/recent": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get user badge award list", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "api-badge" + ], + "summary": "get user badge award list", + "parameters": [ + { + "type": "string", + "description": "user name", + "name": "username", "in": "query", "required": true } @@ -7535,21 +7593,31 @@ "type": "object", "properties": { "award_count": { + "description": "badge award count", "type": "integer" }, "earned": { + "description": "badge earned count", "type": "boolean" }, "icon": { + "description": "badge icon", "type": "string" }, "id": { + "description": "badge id", "type": "string" }, "level": { - "$ref": "#/definitions/entity.BadgeLevel" + "description": "badge level", + "allOf": [ + { + "$ref": "#/definitions/entity.BadgeLevel" + } + ] }, "name": { + "description": "badge name", "type": "string" } } @@ -7809,27 +7877,39 @@ "type": "object", "properties": { "award_count": { + "description": "badge award count", "type": "integer" }, "description": { + "description": "badge description", "type": "string" }, "earned_count": { + "description": "badge earned count", "type": "integer" }, "icon": { + "description": "badge icon", "type": "string" }, "id": { + "description": "badge id", "type": "string" }, "is_single": { + "description": "badge is single or multiple", "type": "boolean" }, "level": { - "$ref": "#/definitions/entity.BadgeLevel" + "description": "badge level", + "allOf": [ + { + "$ref": "#/definitions/entity.BadgeLevel" + } + ] }, "name": { + "description": "badge name", "type": "string" } } @@ -7838,12 +7918,14 @@ "type": "object", "properties": { "badges": { + "description": "badge list info", "type": "array", "items": { "$ref": "#/definitions/schema.BadgeListInfo" } }, "group_name": { + "description": "badge group name", "type": "string" } } @@ -8760,18 +8842,27 @@ "type": "object", "properties": { "earned_count": { + "description": "badge award count", "type": "integer" }, "icon": { + "description": "badge icon", "type": "string" }, "id": { + "description": "badge id", "type": "string" }, "level": { - "$ref": "#/definitions/entity.BadgeLevel" + "description": "badge level", + "allOf": [ + { + "$ref": "#/definitions/entity.BadgeLevel" + } + ] }, "name": { + "description": "badge name", "type": "string" } } diff --git a/docs/swagger.yaml b/docs/swagger.yaml index c8c5a560..e2fc6682 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -355,16 +355,23 @@ definitions: schema.BadgeListInfo: properties: award_count: + description: badge award count type: integer earned: + description: badge earned count type: boolean icon: + description: badge icon type: string id: + description: badge id type: string level: - $ref: '#/definitions/entity.BadgeLevel' + allOf: + - $ref: '#/definitions/entity.BadgeLevel' + description: badge level name: + description: badge name type: string type: object schema.CloseQuestionReq: @@ -541,29 +548,40 @@ definitions: schema.GetBadgeInfoResp: properties: award_count: + description: badge award count type: integer description: + description: badge description type: string earned_count: + description: badge earned count type: integer icon: + description: badge icon type: string id: + description: badge id type: string is_single: + description: badge is single or multiple type: boolean level: - $ref: '#/definitions/entity.BadgeLevel' + allOf: + - $ref: '#/definitions/entity.BadgeLevel' + description: badge level name: + description: badge name type: string type: object schema.GetBadgeListResp: properties: badges: + description: badge list info items: $ref: '#/definitions/schema.BadgeListInfo' type: array group_name: + description: badge group name type: string type: object schema.GetCommentPersonalWithPageResp: @@ -1206,14 +1224,20 @@ definitions: schema.GetUserBadgeAwardListResp: properties: earned_count: + description: badge award count type: integer icon: + description: badge icon type: string id: + description: badge id type: string level: - $ref: '#/definitions/entity.BadgeLevel' + allOf: + - $ref: '#/definitions/entity.BadgeLevel' + description: badge level name: + description: badge name type: string type: object schema.GetUserNotificationConfigResp: @@ -4197,6 +4221,10 @@ paths: name: badge_id required: true type: string + - description: only list the award by username + in: query + name: username + type: string produces: - application/json responses: @@ -4220,11 +4248,41 @@ paths: - application/json description: get user badge award list parameters: - - description: user id + - description: user name in: query - name: user_id + name: username required: true - type: integer + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/handler.RespBody' + - properties: + data: + items: + $ref: '#/definitions/schema.GetUserBadgeAwardListResp' + type: array + type: object + security: + - ApiKeyAuth: [] + summary: get user badge award list + tags: + - api-badge + /answer/api/v1/badge/user/awards/recent: + get: + consumes: + - application/json + description: get user badge award list + parameters: + - description: user name + in: query + name: username + required: true + type: string produces: - application/json responses: diff --git a/internal/controller/badge_controller.go b/internal/controller/badge_controller.go index 7eb42da0..65b59407 100644 --- a/internal/controller/badge_controller.go +++ b/internal/controller/badge_controller.go @@ -87,6 +87,7 @@ func (b *BadgeController) GetBadgeInfo(ctx *gin.Context) { // @Param page query int false "page" // @Param page_size query int false "page size" // @Param badge_id query string true "badge id" +// @Param username query string false "only list the award by username" // @Success 200 {object} handler.RespBody{data=schema.GetBadgeInfoResp} // @Router /answer/api/v1/badge/awards/page [get] func (b *BadgeController) GetBadgeAwardList(ctx *gin.Context) { @@ -95,7 +96,6 @@ func (b *BadgeController) GetBadgeAwardList(ctx *gin.Context) { return } req.BadgeID = uid.DeShortID(req.BadgeID) - req.UserID = middleware.GetLoginUserIDFromContext(ctx) resp, total, err := b.badgeAwardService.GetBadgeAwardList(ctx, req) if err != nil { @@ -105,17 +105,17 @@ func (b *BadgeController) GetBadgeAwardList(ctx *gin.Context) { handler.HandleResponse(ctx, nil, pager.NewPageModel(total, resp)) } -// GetBadgeAwardListByUsername get user badge award list +// GetAllBadgeAwardListByUsername get user badge award list // @Summary get user badge award list // @Description get user badge award list // @Tags api-badge // @Accept json // @Produce json // @Security ApiKeyAuth -// @Param user_id query int true "user id" +// @Param username query string true "user name" // @Success 200 {object} handler.RespBody{data=[]schema.GetUserBadgeAwardListResp} // @Router /answer/api/v1/badge/user/awards [get] -func (b *BadgeController) GetBadgeAwardListByUsername(ctx *gin.Context) { +func (b *BadgeController) GetAllBadgeAwardListByUsername(ctx *gin.Context) { req := &schema.GetUserBadgeAwardListReq{} if handler.BindAndCheck(ctx, req) { return @@ -129,3 +129,30 @@ func (b *BadgeController) GetBadgeAwardListByUsername(ctx *gin.Context) { handler.HandleResponse(ctx, nil, pager.NewPageModel(total, resp)) } + +// GetRecentBadgeAwardListByUsername get user badge award list +// @Summary get user badge award list +// @Description get user badge award list +// @Tags api-badge +// @Accept json +// @Produce json +// @Security ApiKeyAuth +// @Param username query string true "user name" +// @Success 200 {object} handler.RespBody{data=[]schema.GetUserBadgeAwardListResp} +// @Router /answer/api/v1/badge/user/awards/recent [get] +func (b *BadgeController) GetRecentBadgeAwardListByUsername(ctx *gin.Context) { + req := &schema.GetUserBadgeAwardListReq{} + if handler.BindAndCheck(ctx, req) { + return + } + + req.Limit = 10 + + resp, total, err := b.badgeAwardService.GetUserRecentBadgeAwardList(ctx, req) + if err != nil { + handler.HandleResponse(ctx, err, nil) + return + } + + handler.HandleResponse(ctx, nil, pager.NewPageModel(total, resp)) +} diff --git a/internal/entity/badge_award_entity.go b/internal/entity/badge_award_entity.go index 17649734..1d421623 100644 --- a/internal/entity/badge_award_entity.go +++ b/internal/entity/badge_award_entity.go @@ -21,6 +21,11 @@ package entity import "time" +const ( + IsBadgeNotDeleted = 0 + IsBadgeDeleted = 1 +) + // BadgeAward badge_award type BadgeAward struct { ID string `json:"id" xorm:"id"` @@ -30,7 +35,7 @@ type BadgeAward struct { BadgeID string `json:"badge_id" xorm:"not null index BIGINT(20) badge_id"` AwardKey string `json:"award_key" xorm:"not null index VARCHAR(64) award_key"` BadgeGroupID int64 `json:"badge_group_id" xorm:"not null index BIGINT(20) badge_group_id"` - IsBadgeDeleted int8 `json:"is_badge_deleted" xorm:"not null index TINYINT(1) s_badge_deleted"` + IsBadgeDeleted int8 `json:"is_badge_deleted" xorm:"not null index TINYINT(1) is_badge_deleted"` } // TableName badge_award table name @@ -47,3 +52,17 @@ type BadgeEarnedCount struct { func (BadgeEarnedCount) TableName() string { return "badge_award" } + +type BadgeAwardRecent struct { + Created time.Time `xorm:"created"` + UserID string `xorm:"user_id"` + BadgeID string `xorm:"badge_id"` + AwardKey string `xorm:"award_key"` + EarnedCount int64 `xorm:"earned_count"` + IsBadgeDeleted int8 `xorm:"is_badge_deleted"` +} + +// TableName badge_award table name +func (BadgeAwardRecent) TableName() string { + return "badge_award" +} diff --git a/internal/repo/badge_award/badge_award_repo.go b/internal/repo/badge_award/badge_award_repo.go index 8860a5b1..5a5d56cd 100644 --- a/internal/repo/badge_award/badge_award_repo.go +++ b/internal/repo/badge_award/badge_award_repo.go @@ -108,13 +108,21 @@ func (r *badgeAwardRepo) ListAllByUserId(ctx context.Context, userID string) (ba func (r *badgeAwardRepo) ListPagedByBadgeId(ctx context.Context, badgeID string, page int, pageSize int) (badgeAwardList []*entity.BadgeAward, total int64, err error) { session := r.data.DB.Context(ctx) session.Where("badge_id = ?", badgeID) - total, err = pager.Help(page, pageSize, &badgeAwardList, &entity.Question{}, session) + total, err = pager.Help(page, pageSize, &badgeAwardList, &entity.BadgeAward{}, session) if err != nil { err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() } return } -func (r *badgeAwardRepo) ListPagedByBadgeIdAndUserId(ctx context.Context, badgeID string, userID string, page int, pageSize int) (badgeAwards []*entity.BadgeAward, total int64, err error) { + +// ListPagedByBadgeIdAndUserId list badge awards by badge id and user id +func (r *badgeAwardRepo) ListPagedByBadgeIdAndUserId(ctx context.Context, badgeID string, userID string, page int, pageSize int) (badgeAwardList []*entity.BadgeAward, total int64, err error) { + session := r.data.DB.Context(ctx) + session.Where("badge_id = ? AND user_id = ?", badgeID, userID) + total, err = pager.Help(page, pageSize, &badgeAwardList, &entity.Question{}, session) + if err != nil { + err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() + } return } func (r *badgeAwardRepo) ListPagedByObjectId(ctx context.Context, badgeID string, awardKey string, page int, pageSize int) (badgeAwards []*entity.BadgeAward, total int64, err error) { @@ -132,6 +140,19 @@ func (r *badgeAwardRepo) ListTagPagedByBadgeIdAndUserId(ctx context.Context, bad func (r *badgeAwardRepo) ListPagedLatest(ctx context.Context, page int, pageSize int) (badgeAwards []*entity.BadgeAward, total int64, err error) { return } + +// ListNewestEarned list newest earned badge awards +func (r *badgeAwardRepo) ListNewestEarned(ctx context.Context, userID string, limit int) (badgeAwards []*entity.BadgeAwardRecent, err error) { + badgeAwards = make([]*entity.BadgeAwardRecent, 0) + err = r.data.DB.Context(ctx). + Select("user_id, badge_id, max(created_at) created,count(*) earned_count"). + Where("user_id = ? AND is_badge_deleted = ? ", userID, entity.IsBadgeNotDeleted). + GroupBy("badge_id"). + OrderBy("created desc"). + Limit(limit).Find(&badgeAwards) + return +} + func (r *badgeAwardRepo) ListNewestEarnedByLevel(ctx context.Context, userID string, level entity.BadgeLevel, num int) (badgeAwards []*entity.BadgeAward, total int64, err error) { return } diff --git a/internal/router/answer_api_router.go b/internal/router/answer_api_router.go index 63dec5fa..f343d7d1 100644 --- a/internal/router/answer_api_router.go +++ b/internal/router/answer_api_router.go @@ -194,7 +194,8 @@ func (a *AnswerAPIRouter) RegisterUnAuthAnswerAPIRouter(r *gin.RouterGroup) { // badges r.GET("/badge", a.badgeController.GetBadgeInfo) r.GET("/badge/awards/page", a.badgeController.GetBadgeAwardList) - r.GET("/badge/user/awards", a.badgeController.GetBadgeAwardListByUsername) + r.GET("/badge/user/awards/recent", a.badgeController.GetRecentBadgeAwardListByUsername) + r.GET("/badge/user/awards", a.badgeController.GetAllBadgeAwardListByUsername) r.GET("/badges", a.badgeController.GetBadgeList) } diff --git a/internal/schema/badge_schema.go b/internal/schema/badge_schema.go index 0555a99b..cae2aa66 100644 --- a/internal/schema/badge_schema.go +++ b/internal/schema/badge_schema.go @@ -23,28 +23,44 @@ import "github.com/apache/incubator-answer/internal/entity" // BadgeListInfo get badge list response type BadgeListInfo struct { - ID string `json:"id" ` - Name string `json:"name" ` - Icon string `json:"icon" ` - AwardCount int `json:"award_count" ` - Earned bool `json:"earned" ` - Level entity.BadgeLevel `json:"level" ` + // badge id + ID string `json:"id" ` + // badge name + Name string `json:"name" ` + // badge icon + Icon string `json:"icon" ` + // badge award count + AwardCount int `json:"award_count" ` + // badge earned count + Earned bool `json:"earned" ` + // badge level + Level entity.BadgeLevel `json:"level" ` } type GetBadgeListResp struct { - Badges []*BadgeListInfo `json:"badges" ` - GroupName string `json:"group_name" ` + // badge list info + Badges []*BadgeListInfo `json:"badges" ` + // badge group name + GroupName string `json:"group_name" ` } type GetBadgeInfoResp struct { - ID string `json:"id" ` - Name string `json:"name" ` - Description string `json:"description" ` - Icon string `json:"icon" ` - AwardCount int `json:"award_count" ` - EarnedCount int64 `json:"earned_count" ` - IsSingle bool `json:"is_single" ` - Level entity.BadgeLevel `json:"level" ` + // badge id + ID string `json:"id" ` + // badge name + Name string `json:"name" ` + // badge description + Description string `json:"description" ` + // badge icon + Icon string `json:"icon" ` + // badge award count + AwardCount int `json:"award_count" ` + // badge earned count + EarnedCount int64 `json:"earned_count" ` + // badge is single or multiple + IsSingle bool `json:"is_single" ` + // badge level + Level entity.BadgeLevel `json:"level" ` } type GetBadgeAwardWithPageReq struct { @@ -54,29 +70,48 @@ type GetBadgeAwardWithPageReq struct { PageSize int `validate:"omitempty,min=1" form:"page_size"` // badge id BadgeID string `validate:"required" form:"badge_id"` + // username + Username string `validate:"omitempty,gt=0,lte=100" form:"username"` // user id UserID string `json:"-"` } type GetBadgeAwardWithPageResp struct { - CreatedAt int64 `json:"created_at"` - ObjectID string `json:"object_id"` - QuestionID string `json:"question_id"` - AnswerID string `json:"answer_id"` - CommentID string `json:"comment_id"` - ObjectType string `json:"object_type" enums:"question,answer,comment"` - UrlTitle string `json:"url_title"` + // created time + CreatedAt int64 `json:"created_at"` + // object id + ObjectID string `json:"object_id"` + // question id + QuestionID string `json:"question_id"` + // answer id + AnswerID string `json:"answer_id"` + // comment id + CommentID string `json:"comment_id"` + // object type + ObjectType string `json:"object_type" enums:"question,answer,comment"` + // url title + UrlTitle string `json:"url_title"` + // author user info AuthorUserInfo UserBasicInfo `json:"author_user_info"` } type GetUserBadgeAwardListReq struct { - Username string `validate:"omitempty,gt=0,lte=100" form:"username"` - UserID string `json:"-"` + // username + Username string `validate:"required,gt=0,lte=100" form:"username"` + // user id + UserID string `json:"-"` + Limit int `json:"-"` } + type GetUserBadgeAwardListResp struct { - ID string `json:"id" ` - Name string `json:"name" ` - Icon string `json:"icon" ` - EarnedCount int64 `json:"earned_count" ` - Level entity.BadgeLevel `json:"level" ` + // badge id + ID string `json:"id" ` + // badge name + Name string `json:"name" ` + // badge icon + Icon string `json:"icon" ` + // badge award count + EarnedCount int64 `json:"earned_count" ` + // badge level + Level entity.BadgeLevel `json:"level" ` } diff --git a/internal/service/badge/badge_award_service.go b/internal/service/badge/badge_award_service.go index c13c5658..0ad299ba 100644 --- a/internal/service/badge/badge_award_service.go +++ b/internal/service/badge/badge_award_service.go @@ -28,6 +28,7 @@ import ( "github.com/apache/incubator-answer/internal/schema" "github.com/apache/incubator-answer/internal/service/object_info" usercommon "github.com/apache/incubator-answer/internal/service/user_common" + "github.com/apache/incubator-answer/pkg/uid" "github.com/gin-gonic/gin" "github.com/jinzhu/copier" "github.com/segmentfault/pacman/errors" @@ -56,6 +57,7 @@ type BadgeAwardRepo interface { ListTagPagedByBadgeId(ctx context.Context, badgeIDs []string, page int, pageSize int, filterUserID string) (badgeAwards []*entity.BadgeAward, total int64, err error) ListTagPagedByBadgeIdAndUserId(ctx context.Context, badgeIDs []string, userID string, page int, pageSize int) (badgeAwards []*entity.BadgeAward, total int64, err error) ListPagedLatest(ctx context.Context, page int, pageSize int) (badgeAwards []*entity.BadgeAward, total int64, err error) + ListNewestEarned(ctx context.Context, userID string, limit int) (badgeAwards []*entity.BadgeAwardRecent, err error) ListNewestEarnedByLevel(ctx context.Context, userID string, level entity.BadgeLevel, num int) (badgeAwards []*entity.BadgeAward, total int64, err error) ListNewestByUserIdAndLevel(ctx context.Context, userID string, level int, page int, pageSize int) (badgeAwards []*entity.BadgeAward, total int64, err error) @@ -86,13 +88,20 @@ func NewBadgeAwardService( // GetBadgeAwardList get badge award list func (b *BadgeAwardService) GetBadgeAwardList( - ctx context.Context, req *schema.GetBadgeAwardWithPageReq, + ctx context.Context, + req *schema.GetBadgeAwardWithPageReq, ) (resp []*schema.GetBadgeAwardWithPageResp, total int64, err error) { var ( badgeAwardList []*entity.BadgeAward ) - badgeAwardList, total, err = b.badgeAwardRepo.ListPagedByBadgeId(ctx, req.BadgeID, req.Page, req.PageSize) + req.UserID, err = b.validateUserByUsername(ctx, req.Username) + if err != nil { + badgeAwardList, total, err = b.badgeAwardRepo.ListPagedByBadgeId(ctx, req.BadgeID, req.Page, req.PageSize) + } else { + badgeAwardList, total, err = b.badgeAwardRepo.ListPagedByBadgeIdAndUserId(ctx, req.BadgeID, req.UserID, req.Page, req.PageSize) + } + if err != nil { return } @@ -197,33 +206,66 @@ func (b *BadgeAwardService) GetUserBadgeAwardList( ) { var ( earnedCounts []*entity.BadgeEarnedCount - userInfo *schema.UserBasicInfo - exist bool ) - // validate user exists or not - if len(req.Username) > 0 { - userInfo, exist, err = b.userCommon.GetUserBasicInfoByUserName(ctx, req.Username) - if err != nil { + req.UserID, err = b.validateUserByUsername(ctx, req.Username) + if err != nil { + return + } + + earnedCounts, err = b.badgeAwardRepo.SumUserEarnedGroupByBadgeID(ctx, req.UserID) + if err != nil { + return + } + total = int64(len(earnedCounts)) + resp = make([]*schema.GetUserBadgeAwardListResp, total) + + for i, earnedCount := range earnedCounts { + badge, exists, e := b.badgeRepo.GetByID(ctx, earnedCount.BadgeID) + if e != nil { + err = e return } - if !exist { - err = errors.BadRequest(reason.UserNotFound) - return + if !exists { + continue + } + resp[i] = &schema.GetUserBadgeAwardListResp{ + ID: uid.EnShortID(badge.ID), + Name: translator.Tr(handler.GetLangByCtx(ctx), badge.Name), + Icon: badge.Icon, + EarnedCount: earnedCount.EarnedCount, + Level: badge.Level, } - req.UserID = userInfo.ID } - if len(req.UserID) == 0 { - err = errors.BadRequest(reason.UserNotFound) + + return +} + +// GetUserRecentBadgeAwardList get user badge award list +func (b *BadgeAwardService) GetUserRecentBadgeAwardList( + ctx *gin.Context, + req *schema.GetUserBadgeAwardListReq, +) ( + resp []*schema.GetUserBadgeAwardListResp, + total int64, + err error, +) { + var ( + earnedCounts []*entity.BadgeAwardRecent + ) + + req.UserID, err = b.validateUserByUsername(ctx, req.Username) + if err != nil { return } - earnedCounts, err = b.badgeAwardRepo.SumUserEarnedGroupByBadgeID(ctx, req.UserID) + earnedCounts, err = b.badgeAwardRepo.ListNewestEarned(ctx, req.UserID, req.Limit) if err != nil { return } + total = int64(len(earnedCounts)) - resp = make([]*schema.GetUserBadgeAwardListResp, 0, total) + resp = make([]*schema.GetUserBadgeAwardListResp, total) for i, earnedCount := range earnedCounts { badge, exists, e := b.badgeRepo.GetByID(ctx, earnedCount.BadgeID) @@ -235,7 +277,7 @@ func (b *BadgeAwardService) GetUserBadgeAwardList( continue } resp[i] = &schema.GetUserBadgeAwardListResp{ - ID: badge.ID, + ID: uid.EnShortID(badge.ID), Name: translator.Tr(handler.GetLangByCtx(ctx), badge.Name), Icon: badge.Icon, EarnedCount: earnedCount.EarnedCount, @@ -245,3 +287,34 @@ func (b *BadgeAwardService) GetUserBadgeAwardList( return } + +// validate user + +type userReq struct { + UserID string + Username string +} + +func (b *BadgeAwardService) validateUserByUsername(ctx context.Context, userName string) (userID string, err error) { + var ( + userInfo *schema.UserBasicInfo + exist bool + ) + // validate user exists or not + if len(userName) > 0 { + userInfo, exist, err = b.userCommon.GetUserBasicInfoByUserName(ctx, userName) + if err != nil { + return + } + if !exist { + err = errors.BadRequest(reason.UserNotFound) + return + } + userID = userInfo.ID + } + if len(userID) == 0 { + err = errors.BadRequest(reason.UserNotFound) + return + } + return +}