This is an automated email from the ASF dual-hosted git repository.
kumfo pushed a commit to branch feat/1.4.0/badge
in repository https://gitbox.apache.org/repos/asf/incubator-answer.git
The following commit(s) were added to refs/heads/feat/1.4.0/badge by this push:
new 61db21e0 feat(badge): fixed user's badge award list and add recent
user badges
61db21e0 is described below
commit 61db21e0d376a22a3b1e32a32a3d1578eb1106d4
Author: kumfo <[email protected]>
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
+}