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 5293f4f3 feat(badge): user's badge award list
5293f4f3 is described below
commit 5293f4f3eaf397ad67bca83bfc5806aac62e1cc3
Author: kumfo <[email protected]>
AuthorDate: Fri Aug 9 15:00:46 2024 +0800
feat(badge): user's badge award list
---
docs/docs.go | 72 +++++++++++++++++++++++++++
docs/swagger.json | 72 +++++++++++++++++++++++++++
docs/swagger.yaml | 43 ++++++++++++++++
internal/controller/badge_controller.go | 25 ++++++++++
internal/entity/badge_award_entity.go | 2 +-
internal/router/answer_api_router.go | 1 +
internal/schema/badge_schema.go | 12 +++++
internal/service/badge/badge_award_service.go | 69 +++++++++++++++++++++++--
internal/service/badge/badge_service.go | 8 +--
9 files changed, 296 insertions(+), 8 deletions(-)
diff --git a/docs/docs.go b/docs/docs.go
index e1946590..79e23a85 100644
--- a/docs/docs.go
+++ b/docs/docs.go
@@ -2350,6 +2350,58 @@ const docTemplate = `{
}
}
},
+ "/answer/api/v1/badge/user/awards": {
+ "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": "integer",
+ "description": "user id",
+ "name": "user_id",
+ "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/badges": {
"get": {
"security": [
@@ -8734,6 +8786,26 @@ const docTemplate = `{
}
}
},
+ "schema.GetUserBadgeAwardListResp": {
+ "type": "object",
+ "properties": {
+ "earned_count": {
+ "type": "integer"
+ },
+ "icon": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "level": {
+ "$ref": "#/definitions/entity.BadgeLevel"
+ },
+ "name": {
+ "type": "string"
+ }
+ }
+ },
"schema.GetUserNotificationConfigResp": {
"type": "object",
"properties": {
diff --git a/docs/swagger.json b/docs/swagger.json
index 0a3bf6c7..07aabfea 100644
--- a/docs/swagger.json
+++ b/docs/swagger.json
@@ -2320,6 +2320,58 @@
}
}
},
+ "/answer/api/v1/badge/user/awards": {
+ "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": "integer",
+ "description": "user id",
+ "name": "user_id",
+ "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/badges": {
"get": {
"security": [
@@ -8704,6 +8756,26 @@
}
}
},
+ "schema.GetUserBadgeAwardListResp": {
+ "type": "object",
+ "properties": {
+ "earned_count": {
+ "type": "integer"
+ },
+ "icon": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "level": {
+ "$ref": "#/definitions/entity.BadgeLevel"
+ },
+ "name": {
+ "type": "string"
+ }
+ }
+ },
"schema.GetUserNotificationConfigResp": {
"type": "object",
"properties": {
diff --git a/docs/swagger.yaml b/docs/swagger.yaml
index 777445b3..c8c5a560 100644
--- a/docs/swagger.yaml
+++ b/docs/swagger.yaml
@@ -1203,6 +1203,19 @@ definitions:
activation_url:
type: string
type: object
+ schema.GetUserBadgeAwardListResp:
+ properties:
+ earned_count:
+ type: integer
+ icon:
+ type: string
+ id:
+ type: string
+ level:
+ $ref: '#/definitions/entity.BadgeLevel'
+ name:
+ type: string
+ type: object
schema.GetUserNotificationConfigResp:
properties:
all_new_question:
@@ -4201,6 +4214,36 @@ paths:
summary: get badge award list
tags:
- api-badge
+ /answer/api/v1/badge/user/awards:
+ get:
+ consumes:
+ - application/json
+ description: get user badge award list
+ parameters:
+ - description: user id
+ in: query
+ name: user_id
+ required: true
+ type: integer
+ 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/badges:
get:
consumes:
diff --git a/internal/controller/badge_controller.go
b/internal/controller/badge_controller.go
index d7ecc3fa..7eb42da0 100644
--- a/internal/controller/badge_controller.go
+++ b/internal/controller/badge_controller.go
@@ -104,3 +104,28 @@ func (b *BadgeController) GetBadgeAwardList(ctx
*gin.Context) {
}
handler.HandleResponse(ctx, nil, pager.NewPageModel(total, resp))
}
+
+// GetBadgeAwardListByUsername 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"
+// @Success 200 {object}
handler.RespBody{data=[]schema.GetUserBadgeAwardListResp}
+// @Router /answer/api/v1/badge/user/awards [get]
+func (b *BadgeController) GetBadgeAwardListByUsername(ctx *gin.Context) {
+ req := &schema.GetUserBadgeAwardListReq{}
+ if handler.BindAndCheck(ctx, req) {
+ return
+ }
+
+ resp, total, err := b.badgeAwardService.GetUserBadgeAwardList(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 310c85a7..17649734 100644
--- a/internal/entity/badge_award_entity.go
+++ b/internal/entity/badge_award_entity.go
@@ -40,7 +40,7 @@ func (BadgeAward) TableName() string {
type BadgeEarnedCount struct {
BadgeID string `xorm:"badge_id"`
- EarnedCount int `xorm:"earned_count"`
+ EarnedCount int64 `xorm:"earned_count"`
}
// TableName badge_award table name
diff --git a/internal/router/answer_api_router.go
b/internal/router/answer_api_router.go
index c7d4c38e..63dec5fa 100644
--- a/internal/router/answer_api_router.go
+++ b/internal/router/answer_api_router.go
@@ -194,6 +194,7 @@ 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("/badges", a.badgeController.GetBadgeList)
}
diff --git a/internal/schema/badge_schema.go b/internal/schema/badge_schema.go
index 06d92ecc..0555a99b 100644
--- a/internal/schema/badge_schema.go
+++ b/internal/schema/badge_schema.go
@@ -68,3 +68,15 @@ type GetBadgeAwardWithPageResp struct {
UrlTitle string `json:"url_title"`
AuthorUserInfo UserBasicInfo `json:"author_user_info"`
}
+
+type GetUserBadgeAwardListReq struct {
+ Username string `validate:"omitempty,gt=0,lte=100" form:"username"`
+ UserID string `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" `
+}
diff --git a/internal/service/badge/badge_award_service.go
b/internal/service/badge/badge_award_service.go
index 229b09a5..c13c5658 100644
--- a/internal/service/badge/badge_award_service.go
+++ b/internal/service/badge/badge_award_service.go
@@ -21,11 +21,14 @@ package badge
import (
"context"
+ "github.com/apache/incubator-answer/internal/base/handler"
"github.com/apache/incubator-answer/internal/base/reason"
+ "github.com/apache/incubator-answer/internal/base/translator"
"github.com/apache/incubator-answer/internal/entity"
"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/gin-gonic/gin"
"github.com/jinzhu/copier"
"github.com/segmentfault/pacman/errors"
"github.com/segmentfault/pacman/log"
@@ -61,9 +64,9 @@ type BadgeAwardRepo interface {
}
type BadgeAwardService struct {
- badgeAwardRepo BadgeAwardRepo
- badgeRepo BadgeRepo
- userCommon *usercommon.UserCommon
+ badgeAwardRepo BadgeAwardRepo
+ badgeRepo BadgeRepo
+ userCommon *usercommon.UserCommon
objectInfoService *object_info.ObjService
}
@@ -182,3 +185,63 @@ func (b *BadgeAwardService) Award(ctx context.Context,
badgeID string, userID st
return
}
+
+// GetUserBadgeAwardList get user badge award list
+func (b *BadgeAwardService) GetUserBadgeAwardList(
+ ctx *gin.Context,
+ req *schema.GetUserBadgeAwardListReq,
+) (
+ resp []*schema.GetUserBadgeAwardListResp,
+ total int64,
+ err error,
+) {
+ 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 {
+ return
+ }
+ if !exist {
+ err = errors.BadRequest(reason.UserNotFound)
+ return
+ }
+ req.UserID = userInfo.ID
+ }
+ if len(req.UserID) == 0 {
+ err = errors.BadRequest(reason.UserNotFound)
+ return
+ }
+
+ earnedCounts, err = b.badgeAwardRepo.SumUserEarnedGroupByBadgeID(ctx,
req.UserID)
+ if err != nil {
+ return
+ }
+ total = int64(len(earnedCounts))
+ resp = make([]*schema.GetUserBadgeAwardListResp, 0, total)
+
+ for i, earnedCount := range earnedCounts {
+ badge, exists, e := b.badgeRepo.GetByID(ctx,
earnedCount.BadgeID)
+ if e != nil {
+ err = e
+ return
+ }
+ if !exists {
+ continue
+ }
+ resp[i] = &schema.GetUserBadgeAwardListResp{
+ ID: badge.ID,
+ Name: translator.Tr(handler.GetLangByCtx(ctx),
badge.Name),
+ Icon: badge.Icon,
+ EarnedCount: earnedCount.EarnedCount,
+ Level: badge.Level,
+ }
+ }
+
+ return
+}
diff --git a/internal/service/badge/badge_service.go
b/internal/service/badge/badge_service.go
index 366dd338..32a54a8d 100644
--- a/internal/service/badge/badge_service.go
+++ b/internal/service/badge/badge_service.go
@@ -46,9 +46,9 @@ type BadgeRepo interface {
}
type BadgeService struct {
- badgeRepo BadgeRepo
- badgeGroupRepo BadgeGroupRepo
- badgeAwardRepo BadgeAwardRepo
+ badgeRepo BadgeRepo
+ badgeGroupRepo BadgeGroupRepo
+ badgeAwardRepo BadgeAwardRepo
badgeEventService *BadgeEventService
}
@@ -103,7 +103,7 @@ func (b *BadgeService) ListByGroup(ctx context.Context,
userID string) (resp []*
earned := false
if len(earnedCounts) > 0 {
for _, earnedCount := range earnedCounts {
- if badge.ID == earnedCount.BadgeID {
+ if badge.ID == earnedCount.BadgeID &&
earnedCount.EarnedCount > 0 {
earned = true
break
}