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
                                }

Reply via email to