This is an automated email from the ASF dual-hosted git repository.

linkinstar 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 98d93b1f feat(badge): add badge checking rule
98d93b1f is described below

commit 98d93b1f98b4c4d44492f1a2f4fd0b350fc6d2fb
Author: LinkinStars <[email protected]>
AuthorDate: Mon Aug 12 16:34:16 2024 +0800

    feat(badge): add badge checking rule
---
 internal/entity/badge_entity.go               | 43 +++++++++++++--------
 internal/migrations/init.go                   |  2 +-
 internal/migrations/v22.go                    |  2 +-
 internal/repo/badge/badge_event_rule.go       | 55 +++++++++++++++++++++++++--
 internal/schema/event_schema.go               |  7 ++++
 internal/service/badge/badge_event_handler.go |  2 -
 6 files changed, 87 insertions(+), 24 deletions(-)

diff --git a/internal/entity/badge_entity.go b/internal/entity/badge_entity.go
index d2c426fa..96babcb9 100644
--- a/internal/entity/badge_entity.go
+++ b/internal/entity/badge_entity.go
@@ -19,7 +19,10 @@
 
 package entity
 
-import "time"
+import (
+       "github.com/tidwall/gjson"
+       "time"
+)
 
 type BadgeLevel int
 
@@ -38,23 +41,31 @@ const (
 
 // Badge badge
 type Badge struct {
-       ID           string     `json:"id" xorm:"id"`
-       CreatedAt    time.Time  `json:"created_at" xorm:"created not null 
default CURRENT_TIMESTAMP TIMESTAMP created_at"`
-       UpdatedAt    time.Time  `json:"updated_at" xorm:"updated not null 
default CURRENT_TIMESTAMP TIMESTAMP updated_at"`
-       Name         string     `json:"name" xorm:"not null default '' 
VARCHAR(256) name"`
-       Icon         string     `json:"icon" xorm:"not null default '' 
VARCHAR(1024) icon"`
-       AwardCount   int        `json:"award_count" xorm:"not null default 0 
INT(11) award_count"`
-       Description  string     `json:"description" xorm:"not null default '' 
MEDIUMTEXT description"`
-       Status       int8       `json:"status" xorm:"not null default 1 INT(11) 
status"`
-       BadgeGroupID int64      `json:"badge_group_id" xorm:"not null default 0 
BIGINT(20) badge_group_id"`
-       Level        BadgeLevel `json:"level" xorm:"not null default 1 
TINYINT(4) level"`
-       Single       int8       `json:"single" xorm:"not null default 1 
TINYINT(4) single"`
-       Collect      string     `json:"collect" xorm:"not null default '' 
VARCHAR(64) collect"`
-       Handler      string     `json:"handler" xorm:"not null default '' 
VARCHAR(64) handler"`
-       Param        string     `json:"param" xorm:"not null default '' 
VARCHAR(128) param"`
+       ID           string     `xorm:"not null pk autoincr BIGINT(20) id"`
+       CreatedAt    time.Time  `xorm:"created not null default 
CURRENT_TIMESTAMP TIMESTAMP created_at"`
+       UpdatedAt    time.Time  `xorm:"updated not null default 
CURRENT_TIMESTAMP TIMESTAMP updated_at"`
+       Name         string     `xorm:"not null default '' VARCHAR(256) name"`
+       Icon         string     `xorm:"not null default '' VARCHAR(1024) icon"`
+       AwardCount   int        `xorm:"not null default 0 INT(11) award_count"`
+       Description  string     `xorm:"not null default '' MEDIUMTEXT 
description"`
+       Status       int8       `xorm:"not null default 1 INT(11) status"`
+       BadgeGroupID int64      `xorm:"not null default 0 BIGINT(20) 
badge_group_id"`
+       Level        BadgeLevel `xorm:"not null default 1 TINYINT(4) level"`
+       Single       int8       `xorm:"not null default 1 TINYINT(4) single"`
+       Collect      string     `xorm:"not null default '' VARCHAR(64) collect"`
+       Handler      string     `xorm:"not null default '' VARCHAR(64) handler"`
+       Param        string     `xorm:"not null default '' TEXT param"`
 }
 
 // TableName badge table name
-func (Badge) TableName() string {
+func (b *Badge) TableName() string {
        return "badge"
 }
+
+func (b *Badge) GetIntParam(key string) int64 {
+       return gjson.Get(b.Param, key).Int()
+}
+
+func (b *Badge) GetStringParam(key string) string {
+       return gjson.Get(b.Param, key).String()
+}
diff --git a/internal/migrations/init.go b/internal/migrations/init.go
index 40e9a91a..0b4d1ce3 100644
--- a/internal/migrations/init.go
+++ b/internal/migrations/init.go
@@ -136,7 +136,7 @@ func (m *Mentor) initBadge() {
        }
 
        for _, badge := range defaultBadgeTable {
-               badge.ID, m.err = uniqueIDRepo.GenUniqueIDStr(m.ctx, 
entity.Badge{}.TableName())
+               badge.ID, m.err = uniqueIDRepo.GenUniqueIDStr(m.ctx, 
new(entity.Badge).TableName())
                if m.err != nil {
                        return
                }
diff --git a/internal/migrations/v22.go b/internal/migrations/v22.go
index 19ec1ce0..f5793d4a 100644
--- a/internal/migrations/v22.go
+++ b/internal/migrations/v22.go
@@ -273,7 +273,7 @@ func addBadges(ctx context.Context, x *xorm.Engine) (err 
error) {
                return
        }
        for _, badge := range defaultBadgeTable {
-               badge.ID, err = uniqueIDRepo.GenUniqueIDStr(ctx, 
entity.Badge{}.TableName())
+               badge.ID, err = uniqueIDRepo.GenUniqueIDStr(ctx, 
new(entity.Badge).TableName())
                if err != nil {
                        return
                }
diff --git a/internal/repo/badge/badge_event_rule.go 
b/internal/repo/badge/badge_event_rule.go
index d6c0d826..41d56686 100644
--- a/internal/repo/badge/badge_event_rule.go
+++ b/internal/repo/badge/badge_event_rule.go
@@ -29,6 +29,7 @@ import (
        "github.com/apache/incubator-answer/internal/service/badge"
        "github.com/segmentfault/pacman/errors"
        "github.com/segmentfault/pacman/log"
+       "strconv"
 )
 
 // eventRuleRepo event rule repo
@@ -170,6 +171,26 @@ func (br *eventRuleRepo) ReachAnswerAcceptedAmount(ctx 
context.Context,
        if b == nil {
                return nil, nil
        }
+       if len(event.AnswerUserID) == 0 {
+               return nil, nil
+       }
+
+       // count user's accepted answer amount
+       amount, err := br.data.DB.Context(ctx).Count(&entity.Answer{
+               UserID:   event.AnswerUserID,
+               Accepted: schema.AnswerAcceptedEnable,
+               Status:   entity.AnswerStatusAvailable,
+       })
+       if err != nil {
+               return nil, 
errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
+       }
+
+       // get badge requirement
+       requirement := b.GetIntParam("amount")
+       if requirement == 0 || amount < requirement {
+               return nil, nil
+       }
+
        return append(awards, br.createBadgeAward(event.UserID, b.ID, 
event.GetObjectID())), nil
 }
 
@@ -180,7 +201,20 @@ func (br *eventRuleRepo) ReachAnswerVote(ctx 
context.Context,
        if b == nil {
                return nil, nil
        }
-       return append(awards, br.createBadgeAward(event.UserID, b.ID, 
event.GetObjectID())), nil
+
+       // get vote amount
+       amount, _ := strconv.Atoi(event.GetExtra("vote_up_amount"))
+       if amount == 0 {
+               return nil, nil
+       }
+
+       // get badge requirement
+       requirement := b.GetIntParam("amount")
+       if requirement == 0 || int64(amount) < requirement {
+               return nil, nil
+       }
+
+       return append(awards, br.createBadgeAward(event.AnswerUserID, b.ID, 
event.AnswerID)), nil
 }
 
 // ReachQuestionVote reach question vote
@@ -190,7 +224,20 @@ func (br *eventRuleRepo) ReachQuestionVote(ctx 
context.Context,
        if b == nil {
                return nil, nil
        }
-       return append(awards, br.createBadgeAward(event.UserID, b.ID, 
event.GetObjectID())), nil
+
+       // get vote amount
+       amount, _ := strconv.Atoi(event.GetExtra("vote_up_amount"))
+       if amount == 0 {
+               return nil, nil
+       }
+
+       // get badge requirement
+       requirement := b.GetIntParam("amount")
+       if requirement == 0 || int64(amount) < requirement {
+               return nil, nil
+       }
+
+       return append(awards, br.createBadgeAward(event.QuestionUserID, b.ID, 
event.QuestionID)), nil
 }
 
 func (br *eventRuleRepo) getBadgeByHandler(ctx context.Context, handler 
string) (b *entity.Badge) {
@@ -207,10 +254,10 @@ func (br *eventRuleRepo) getBadgeByHandler(ctx 
context.Context, handler string)
        return b
 }
 
-func (br *eventRuleRepo) createBadgeAward(userID, badgeID, objectID string) 
(awards *entity.BadgeAward) {
+func (br *eventRuleRepo) createBadgeAward(userID, badgeID, awardKey string) 
(awards *entity.BadgeAward) {
        return &entity.BadgeAward{
                UserID:   userID,
                BadgeID:  badgeID,
-               AwardKey: objectID,
+               AwardKey: awardKey,
        }
 }
diff --git a/internal/schema/event_schema.go b/internal/schema/event_schema.go
index 17be9627..fd8e06dd 100644
--- a/internal/schema/event_schema.go
+++ b/internal/schema/event_schema.go
@@ -69,6 +69,13 @@ func (e *EventMsg) AddExtra(key, value string) *EventMsg {
        return e
 }
 
+func (e *EventMsg) GetExtra(key string) string {
+       if v, ok := e.ExtraInfo[key]; ok {
+               return v
+       }
+       return ""
+}
+
 func (e *EventMsg) GetObjectID() string {
        if len(e.CommentID) > 0 {
                return e.CommentID
diff --git a/internal/service/badge/badge_event_handler.go 
b/internal/service/badge/badge_event_handler.go
index d6758baf..09331197 100644
--- a/internal/service/badge/badge_event_handler.go
+++ b/internal/service/badge/badge_event_handler.go
@@ -60,8 +60,6 @@ func NewBadgeEventService(
 }
 
 func (ns *BadgeEventService) Handler(ctx context.Context, msg 
*schema.EventMsg) error {
-       log.Debugf("received badge event %+v", msg)
-
        awards := ns.eventRuleRepo.HandleEventWithRule(ctx, msg)
        if len(awards) == 0 {
                return nil

Reply via email to