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 45799d1623c1e6a660fc0f09a589ed0f0d8e3e17 Author: LinkinStars <linkins...@foxmail.com> AuthorDate: Wed Aug 14 12:31:03 2024 +0800 fix(badge): fix badge init data --- internal/entity/badge_entity.go | 8 +- internal/migrations/init.go | 20 +++ internal/migrations/init_data.go | 156 +++++++++++++++++ internal/migrations/v22.go | 268 +++-------------------------- internal/repo/badge/badge_event_rule.go | 155 ++++++++--------- internal/service/content/answer_service.go | 6 +- 6 files changed, 285 insertions(+), 328 deletions(-) diff --git a/internal/entity/badge_entity.go b/internal/entity/badge_entity.go index 5177c93c..a370e275 100644 --- a/internal/entity/badge_entity.go +++ b/internal/entity/badge_entity.go @@ -47,14 +47,14 @@ type Badge struct { 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"` + Description string `xorm:"not null 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"` + Collect string `xorm:"not null default '' VARCHAR(128) collect"` + Handler string `xorm:"not null default '' VARCHAR(128) handler"` + Param string `xorm:"not null TEXT param"` } // TableName badge table name diff --git a/internal/migrations/init.go b/internal/migrations/init.go index 0b4d1ce3..b74e3688 100644 --- a/internal/migrations/init.go +++ b/internal/migrations/init.go @@ -80,6 +80,7 @@ func (m *Mentor) InitDB() error { m.do("init site info privilege rank", m.initSiteInfoPrivilegeRank) m.do("init site info write", m.initSiteInfoWrite) m.do("init default content", m.initDefaultContent) + m.do("init default badges", m.initDefaultBadges) return m.err } @@ -432,3 +433,22 @@ func (m *Mentor) initDefaultContent() { return } } + +func (m *Mentor) initDefaultBadges() { + uniqueIDRepo := unique.NewUniqueIDRepo(&data.Data{DB: m.engine}) + + _, m.err = m.engine.Context(m.ctx).Insert(defaultBadgeGroupTable) + if m.err != nil { + return + } + for _, badge := range defaultBadgeTable { + badge.ID, m.err = uniqueIDRepo.GenUniqueIDStr(m.ctx, new(entity.Badge).TableName()) + if m.err != nil { + return + } + if _, m.err = m.engine.Context(m.ctx).Insert(badge); m.err != nil { + return + } + } + return +} diff --git a/internal/migrations/init_data.go b/internal/migrations/init_data.go index f9a09f52..50a5651b 100644 --- a/internal/migrations/init_data.go +++ b/internal/migrations/init_data.go @@ -347,4 +347,160 @@ var ( {ID: 129, Key: "rank.question.undeleted", Value: `-1`}, {ID: 130, Key: "rank.tag.undeleted", Value: `-1`}, } + + defaultBadgeGroupTable = []*entity.BadgeGroup{ + {ID: "1", Name: "badge.default_badge_groups.getting_started.name"}, + {ID: "2", Name: "badge.default_badge_groups.community.name"}, + {ID: "3", Name: "badge.default_badge_groups.posting.name"}, + } + + defaultBadgeTable = []*entity.Badge{ + { + Name: "badge.default_badges.autobiographer.name", + Icon: "person-badge-fill", + Description: "badge.default_badges.autobiographer.desc", + Status: entity.BadgeStatusActive, + BadgeGroupID: 1, + Level: entity.BadgeLevelBronze, + Single: entity.BadgeSingleAward, + Handler: "FirstUpdateUserProfile", + }, + { + Name: "badge.default_badges.editor.name", + Icon: "pencil-fill", + Description: "badge.default_badges.editor.desc", + Status: entity.BadgeStatusActive, + BadgeGroupID: 1, + Level: entity.BadgeLevelBronze, + Single: entity.BadgeSingleAward, + Handler: "FirstPostEdit", + }, + { + Name: "badge.default_badges.first_flag.name", + Icon: "flag-fill", + Description: "badge.default_badges.first_flag.desc", + Status: entity.BadgeStatusActive, + BadgeGroupID: 1, + Level: entity.BadgeLevelBronze, + Single: entity.BadgeSingleAward, + Handler: "FirstFlaggedPost", + }, + { + Name: "badge.default_badges.first_upvote.name", + Icon: "hand-thumbs-up-fill", + Description: "badge.default_badges.first_upvote.desc", + Status: entity.BadgeStatusActive, + BadgeGroupID: 1, + Level: entity.BadgeLevelBronze, + Single: entity.BadgeSingleAward, + Handler: "FirstVotedPost", + }, + { + Name: "badge.default_badges.first_reaction.name", + Icon: "emoji-smile-fill", + Description: "badge.default_badges.first_reaction.desc", + Status: entity.BadgeStatusActive, + BadgeGroupID: 1, + Level: entity.BadgeLevelBronze, + Single: entity.BadgeSingleAward, + Handler: "FirstReactedPost", + }, + { + Name: "badge.default_badges.first_share.name", + Icon: "share-fill", + Description: "badge.default_badges.first_share.desc", + Status: entity.BadgeStatusActive, + BadgeGroupID: 1, + Level: entity.BadgeLevelBronze, + Single: entity.BadgeSingleAward, + Handler: "FirstSharedPost", + }, + { + Name: "badge.default_badges.scholar.name", + Icon: "check-circle-fill", + Description: "badge.default_badges.scholar.desc", + Status: entity.BadgeStatusActive, + BadgeGroupID: 1, + Level: entity.BadgeLevelBronze, + Single: entity.BadgeSingleAward, + Handler: "FirstAcceptAnswer", + }, + { + Name: "badge.default_badges.solved.name", + Icon: "check-square-fill", + Description: "badge.default_badges.solved.desc", + Status: entity.BadgeStatusActive, + BadgeGroupID: 2, + Level: entity.BadgeLevelBronze, + Single: entity.BadgeSingleAward, + Handler: "ReachAnswerAcceptedAmount", + Param: `{"amount":"1"}`, + }, + { + Name: "badge.default_badges.nice_answer.name", + Icon: "chat-square-text-fill", + Description: "badge.default_badges.nice_answer.desc", + Status: entity.BadgeStatusActive, + BadgeGroupID: 3, + Level: entity.BadgeLevelBronze, + Single: entity.BadgeMultiAward, + Handler: "ReachAnswerVote", + Param: `{"amount":"10"}`, + }, + { + Name: "badge.default_badges.good_answer.name", + Icon: "chat-square-text-fill", + Description: "badge.default_badges.good_answer.desc", + Status: entity.BadgeStatusActive, + BadgeGroupID: 3, + Level: entity.BadgeLevelSilver, + Single: entity.BadgeMultiAward, + Handler: "ReachAnswerVote", + Param: `{"amount":"25"}`, + }, + { + Name: "badge.default_badges.great_answer.name", + Icon: "chat-square-text-fill", + Description: "badge.default_badges.great_answer.desc", + Status: entity.BadgeStatusActive, + BadgeGroupID: 3, + Level: entity.BadgeLevelGold, + Single: entity.BadgeMultiAward, + Handler: "ReachAnswerVote", + Param: `{"amount":"50"}`, + }, + { + Name: "badge.default_badges.nice_question.name", + Icon: "question-circle-fill", + Description: "badge.default_badges.nice_question.desc", + Status: entity.BadgeStatusActive, + BadgeGroupID: 3, + Level: entity.BadgeLevelBronze, + Single: entity.BadgeMultiAward, + Handler: "ReachQuestionVote", + Param: `{"amount":"10"}`, + }, + { + Name: "badge.default_badges.good_question.name", + Icon: "question-circle-fill", + Description: "badge.default_badges.good_question.desc", + Status: entity.BadgeStatusActive, + BadgeGroupID: 3, + Level: entity.BadgeLevelSilver, + Single: entity.BadgeMultiAward, + Handler: "ReachQuestionVote", + Param: `{"amount":"25"}`, + }, + { + Name: "badge.default_badges.great_question.name", + Icon: "question-circle-fill", + Description: "badge.default_badges.great_question.desc", + Status: entity.BadgeStatusActive, + BadgeGroupID: 3, + Level: entity.BadgeLevelGold, + Single: entity.BadgeMultiAward, + Handler: "ReachQuestionVote", + Param: `{"amount":"50"}`, + }, + } ) diff --git a/internal/migrations/v22.go b/internal/migrations/v22.go index d3d81d84..ab7185e3 100644 --- a/internal/migrations/v22.go +++ b/internal/migrations/v22.go @@ -21,265 +21,51 @@ package migrations import ( "context" + "fmt" "github.com/apache/incubator-answer/internal/base/data" "github.com/apache/incubator-answer/internal/entity" "github.com/apache/incubator-answer/internal/repo/unique" - "time" "xorm.io/xorm" ) -var ( - defaultBadgeGroupTable = []*entity.BadgeGroup{ - {ID: "1", Name: "badge.default_badge_groups.getting_started.name"}, - {ID: "2", Name: "badge.default_badge_groups.community.name"}, - {ID: "3", Name: "badge.default_badge_groups.posting.name"}, - } - - defaultBadgeTable = []*entity.Badge{ - { - CreatedAt: time.Now(), - UpdatedAt: time.Now(), - Name: "badge.default_badges.autobiographer.name", - Icon: "person-badge-fill", - AwardCount: 0, - Description: "badge.default_badges.autobiographer.desc", - Status: entity.BadgeStatusActive, - BadgeGroupID: 1, - Level: entity.BadgeLevelBronze, - Single: entity.BadgeSingleAward, - Collect: "", - Handler: "", - Param: "", - }, - { - CreatedAt: time.Now(), - UpdatedAt: time.Now(), - Name: "badge.default_badges.editor.name", - Icon: "pencil-fill", - AwardCount: 0, - Description: "badge.default_badges.editor.desc", - Status: entity.BadgeStatusActive, - BadgeGroupID: 1, - Level: entity.BadgeLevelBronze, - Single: entity.BadgeSingleAward, - Collect: "question", - Handler: "FirstQuestion", - Param: "", - }, - { - CreatedAt: time.Now(), - UpdatedAt: time.Now(), - Name: "badge.default_badges.first_flag.name", - Icon: "flag-fill", - AwardCount: 0, - Description: "badge.default_badges.first_flag.desc", - Status: entity.BadgeStatusActive, - BadgeGroupID: 1, - Level: entity.BadgeLevelBronze, - Single: entity.BadgeSingleAward, - Collect: "", - Handler: "", - Param: "", - }, - { - CreatedAt: time.Now(), - UpdatedAt: time.Now(), - Name: "badge.default_badges.first_upvote.name", - Icon: "hand-thumbs-up-fill", - AwardCount: 0, - Description: "badge.default_badges.first_upvote.desc", - Status: entity.BadgeStatusActive, - BadgeGroupID: 1, - Level: entity.BadgeLevelBronze, - Single: entity.BadgeSingleAward, - Collect: "", - Handler: "", - Param: "", - }, - { - CreatedAt: time.Now(), - UpdatedAt: time.Now(), - Name: "badge.default_badges.first_reaction.name", - Icon: "emoji-smile-fill", - AwardCount: 0, - Description: "badge.default_badges.first_reaction.desc", - Status: entity.BadgeStatusActive, - BadgeGroupID: 1, - Level: entity.BadgeLevelBronze, - Single: entity.BadgeSingleAward, - Collect: "", - Handler: "", - Param: "", - }, - { - CreatedAt: time.Now(), - UpdatedAt: time.Now(), - Name: "badge.default_badges.first_share.name", - Icon: "share-fill", - AwardCount: 0, - Description: "badge.default_badges.first_share.desc", - Status: entity.BadgeStatusActive, - BadgeGroupID: 1, - Level: entity.BadgeLevelBronze, - Single: entity.BadgeSingleAward, - Collect: "", - Handler: "", - Param: "", - }, - { - CreatedAt: time.Now(), - UpdatedAt: time.Now(), - Name: "badge.default_badges.scholar.name", - Icon: "check-circle-fill", - AwardCount: 0, - Description: "badge.default_badges.scholar.desc", - Status: entity.BadgeStatusActive, - BadgeGroupID: 1, - Level: entity.BadgeLevelBronze, - Single: entity.BadgeSingleAward, - Collect: "", - Handler: "", - Param: "", - }, - { - CreatedAt: time.Now(), - UpdatedAt: time.Now(), - Name: "badge.default_badges.solved.name", - Icon: "check-square-fill", - AwardCount: 0, - Description: "badge.default_badges.solved.desc", - Status: entity.BadgeStatusActive, - BadgeGroupID: 2, - Level: entity.BadgeLevelBronze, - Single: entity.BadgeSingleAward, - Collect: "", - Handler: "", - Param: "", - }, - { - CreatedAt: time.Now(), - UpdatedAt: time.Now(), - Name: "badge.default_badges.nice_answer.name", - Icon: "chat-square-text-fill", - AwardCount: 0, - Description: "badge.default_badges.nice_answer.desc", - Status: entity.BadgeStatusActive, - BadgeGroupID: 3, - Level: entity.BadgeLevelBronze, - Single: entity.BadgeMultiAward, - Collect: "", - Handler: "", - Param: "", - }, - { - CreatedAt: time.Now(), - UpdatedAt: time.Now(), - Name: "badge.default_badges.good_answer.name", - Icon: "chat-square-text-fill", - AwardCount: 0, - Description: "badge.default_badges.good_answer.desc", - Status: entity.BadgeStatusActive, - BadgeGroupID: 3, - Level: entity.BadgeLevelSilver, - Single: entity.BadgeMultiAward, - Collect: "", - Handler: "", - Param: "", - }, - { - CreatedAt: time.Now(), - UpdatedAt: time.Now(), - Name: "badge.default_badges.great_answer.name", - Icon: "chat-square-text-fill", - AwardCount: 0, - Description: "badge.default_badges.great_answer.desc", - Status: entity.BadgeStatusActive, - BadgeGroupID: 3, - Level: entity.BadgeLevelGold, - Single: entity.BadgeMultiAward, - Collect: "", - Handler: "", - Param: "", - }, - { - CreatedAt: time.Now(), - UpdatedAt: time.Now(), - Name: "badge.default_badges.nice_question.name", - Icon: "question-circle-fill", - AwardCount: 0, - Description: "badge.default_badges.nice_question.desc", - Status: entity.BadgeStatusActive, - BadgeGroupID: 3, - Level: entity.BadgeLevelBronze, - Single: entity.BadgeMultiAward, - Collect: "", - Handler: "", - Param: "", - }, - { - CreatedAt: time.Now(), - UpdatedAt: time.Now(), - Name: "badge.default_badges.good_question.name", - Icon: "question-circle-fill", - AwardCount: 0, - Description: "badge.default_badges.good_question.desc", - Status: entity.BadgeStatusActive, - BadgeGroupID: 3, - Level: entity.BadgeLevelSilver, - Single: entity.BadgeSingleAward, - Collect: "", - Handler: "", - Param: "", - }, - { - CreatedAt: time.Now(), - UpdatedAt: time.Now(), - Name: "badge.default_badges.great_question.name", - Icon: "question-circle-fill", - AwardCount: 0, - Description: "badge.default_badges.great_question.desc", - Status: entity.BadgeStatusActive, - BadgeGroupID: 3, - Level: entity.BadgeLevelGold, - Single: entity.BadgeMultiAward, - Collect: "", - Handler: "", - Param: "", - }, - } -) - func addBadges(ctx context.Context, x *xorm.Engine) (err error) { uniqueIDRepo := unique.NewUniqueIDRepo(&data.Data{DB: x}) - // create table - err = x.Context(ctx).Sync(new(entity.Badge)) - if err != nil { - return - } - err = x.Context(ctx).Sync(new(entity.BadgeGroup)) + err = x.Context(ctx).Sync(new(entity.Badge), new(entity.BadgeGroup), new(entity.BadgeAward)) if err != nil { - return + return fmt.Errorf("sync table failed: %w", err) } - err = x.Context(ctx).Sync(new(entity.BadgeAward)) - if err != nil { - return + for _, badgeGroup := range defaultBadgeGroupTable { + exist, err := x.Context(ctx).Get(&entity.BadgeGroup{ID: badgeGroup.ID}) + if err != nil { + return err + } + if exist { + _, err = x.Context(ctx).ID(badgeGroup.ID).Update(badgeGroup) + } else { + _, err = x.Context(ctx).Insert(badgeGroup) + } + if err != nil { + return fmt.Errorf("insert badge group failed: %w", err) + } } - // insert default data - _, err = x.Context(ctx).Insert(defaultBadgeGroupTable) - if err != nil { - return - } for _, badge := range defaultBadgeTable { - badge.ID, err = uniqueIDRepo.GenUniqueIDStr(ctx, new(entity.Badge).TableName()) + exist, err := x.Context(ctx).Get(&entity.Badge{Name: badge.Name}) if err != nil { - return + return err + } + if exist { + continue } - _, err = x.Context(ctx).Insert(badge) + badge.ID, err = uniqueIDRepo.GenUniqueIDStr(ctx, new(entity.Badge).TableName()) if err != nil { - return + return err + } + + if _, err := x.Context(ctx).Insert(badge); err != nil { + return err } } return diff --git a/internal/repo/badge/badge_event_rule.go b/internal/repo/badge/badge_event_rule.go index f912c2bb..f107203e 100644 --- a/internal/repo/badge/badge_event_rule.go +++ b/internal/repo/badge/badge_event_rule.go @@ -86,91 +86,87 @@ func (br *eventRuleRepo) HandleEventWithRule(ctx context.Context, msg *schema.Ev // FirstUpdateUserProfile first update user profile func (br *eventRuleRepo) FirstUpdateUserProfile(ctx context.Context, event *schema.EventMsg) (awards []*entity.BadgeAward, err error) { - b := br.getBadgeByHandler(ctx, "FirstUpdateUserProfile") - if b == nil { - return nil, nil - } - bean := &entity.User{ID: event.UserID} - exist, err := br.data.DB.Context(ctx).Get(bean) - if err != nil { - return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() - } - if !exist { - return nil, nil - } - if len(bean.Bio) > 0 { - return append(awards, br.createBadgeAward(event.UserID, b.ID, entity.BadgeOnceAwardKey)), nil + badges := br.getBadgesByHandler(ctx, "FirstUpdateUserProfile") + for _, b := range badges { + bean := &entity.User{ID: event.UserID} + exist, err := br.data.DB.Context(ctx).Get(bean) + if err != nil { + return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() + } + if !exist { + continue + } + if len(bean.Bio) > 0 { + awards = append(awards, br.createBadgeAward(event.UserID, "", b)) + } } - return nil, nil + return awards, nil } // FirstPostEdit first post edit func (br *eventRuleRepo) FirstPostEdit(ctx context.Context, event *schema.EventMsg) (awards []*entity.BadgeAward, err error) { - b := br.getBadgeByHandler(ctx, "FirstPostEdit") - if b == nil { - return nil, nil + badges := br.getBadgesByHandler(ctx, "FirstPostEdit") + for _, b := range badges { + awards = append(awards, br.createBadgeAward(event.UserID, event.GetObjectID(), b)) } - return append(awards, br.createBadgeAward(event.UserID, b.ID, event.GetObjectID())), nil + return awards, nil } // FirstFlaggedPost first flagged post. func (br *eventRuleRepo) FirstFlaggedPost(ctx context.Context, event *schema.EventMsg) (awards []*entity.BadgeAward, err error) { - b := br.getBadgeByHandler(ctx, "FirstFlaggedPost") - if b == nil { - return nil, nil + badges := br.getBadgesByHandler(ctx, "FirstFlaggedPost") + for _, b := range badges { + awards = append(awards, br.createBadgeAward(event.UserID, event.GetObjectID(), b)) } - return append(awards, br.createBadgeAward(event.UserID, b.ID, event.GetObjectID())), nil + return awards, nil } // FirstVotedPost first voted post func (br *eventRuleRepo) FirstVotedPost(ctx context.Context, event *schema.EventMsg) (awards []*entity.BadgeAward, err error) { - b := br.getBadgeByHandler(ctx, "FirstVotedPost") - if b == nil { - return nil, nil + badges := br.getBadgesByHandler(ctx, "FirstVotedPost") + for _, b := range badges { + awards = append(awards, br.createBadgeAward(event.UserID, event.GetObjectID(), b)) } - return append(awards, br.createBadgeAward(event.UserID, b.ID, event.GetObjectID())), nil + return awards, nil } // FirstReactedPost first reacted post func (br *eventRuleRepo) FirstReactedPost(ctx context.Context, event *schema.EventMsg) (awards []*entity.BadgeAward, err error) { - b := br.getBadgeByHandler(ctx, "FirstReactedPost") - if b == nil { - return nil, nil + badges := br.getBadgesByHandler(ctx, "FirstReactedPost") + for _, b := range badges { + awards = append(awards, br.createBadgeAward(event.UserID, event.GetObjectID(), b)) } - return append(awards, br.createBadgeAward(event.UserID, b.ID, event.GetObjectID())), nil + return awards, nil } // FirstSharedPost first shared post func (br *eventRuleRepo) FirstSharedPost(ctx context.Context, event *schema.EventMsg) (awards []*entity.BadgeAward, err error) { - b := br.getBadgeByHandler(ctx, "FirstSharedPost") - if b == nil { - return nil, nil + badges := br.getBadgesByHandler(ctx, "FirstSharedPost") + for _, b := range badges { + awards = append(awards, br.createBadgeAward(event.UserID, event.GetObjectID(), b)) } - return append(awards, br.createBadgeAward(event.UserID, b.ID, event.GetObjectID())), nil + return awards, nil } // FirstAcceptAnswer user first accept answer func (br *eventRuleRepo) FirstAcceptAnswer(ctx context.Context, event *schema.EventMsg) (awards []*entity.BadgeAward, err error) { - b := br.getBadgeByHandler(ctx, "FirstAcceptAnswer") - if b == nil { - return nil, nil + badges := br.getBadgesByHandler(ctx, "FirstAcceptAnswer") + for _, b := range badges { + awards = append(awards, br.createBadgeAward(event.UserID, event.GetObjectID(), b)) } - return append(awards, br.createBadgeAward(event.UserID, b.ID, event.GetObjectID())), nil + return awards, nil } // ReachAnswerAcceptedAmount reach answer accepted amount func (br *eventRuleRepo) ReachAnswerAcceptedAmount(ctx context.Context, event *schema.EventMsg) (awards []*entity.BadgeAward, err error) { - b := br.getBadgeByHandler(ctx, "ReachAnswerAcceptedAmount") - if b == nil { - return nil, nil - } + badges := br.getBadgesByHandler(ctx, "ReachAnswerAcceptedAmount") if len(event.AnswerUserID) == 0 { return nil, nil } @@ -185,79 +181,76 @@ func (br *eventRuleRepo) ReachAnswerAcceptedAmount(ctx context.Context, return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() } - // get badge requirement - requirement := b.GetIntParam("amount") - if requirement == 0 || amount < requirement { - return nil, nil + for _, b := range badges { + // get badge requirement + requirement := b.GetIntParam("amount") + if requirement == 0 || amount < requirement { + continue + } + awards = append(awards, br.createBadgeAward(event.AnswerUserID, event.AnswerID, b)) } - - return append(awards, br.createBadgeAward(event.UserID, b.ID, event.GetObjectID())), nil + return awards, nil } // ReachAnswerVote reach answer vote func (br *eventRuleRepo) ReachAnswerVote(ctx context.Context, event *schema.EventMsg) (awards []*entity.BadgeAward, err error) { - b := br.getBadgeByHandler(ctx, "ReachAnswerVote") - if b == nil { - return nil, nil - } - + badges := br.getBadgesByHandler(ctx, "ReachAnswerVote") // 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 + for _, b := range badges { + // get badge requirement + requirement := b.GetIntParam("amount") + if requirement == 0 || int64(amount) < requirement { + continue + } + awards = append(awards, br.createBadgeAward(event.AnswerUserID, event.AnswerID, b)) } - - return append(awards, br.createBadgeAward(event.AnswerUserID, b.ID, event.AnswerID)), nil + return awards, nil } // ReachQuestionVote reach question vote func (br *eventRuleRepo) ReachQuestionVote(ctx context.Context, event *schema.EventMsg) (awards []*entity.BadgeAward, err error) { - b := br.getBadgeByHandler(ctx, "ReachQuestionVote") - if b == nil { - return nil, nil - } - + badges := br.getBadgesByHandler(ctx, "ReachQuestionVote") // 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 + for _, b := range badges { + // get badge requirement + requirement := b.GetIntParam("amount") + if requirement == 0 || int64(amount) < requirement { + continue + } + awards = append(awards, br.createBadgeAward(event.QuestionUserID, event.QuestionID, b)) } - - return append(awards, br.createBadgeAward(event.QuestionUserID, b.ID, event.QuestionID)), nil + return awards, nil } -func (br *eventRuleRepo) getBadgeByHandler(ctx context.Context, handler string) (b *entity.Badge) { - b = &entity.Badge{Handler: handler} - exist, err := br.data.DB.Context(ctx).Get(b) +func (br *eventRuleRepo) getBadgesByHandler(ctx context.Context, handler string) (badges []*entity.Badge) { + badges = make([]*entity.Badge, 0) + err := br.data.DB.Context(ctx).Where("handler = ?", handler).Find(&badges) if err != nil { log.Errorf("error getting badge by handler %s: %v", handler, err) return nil } - if !exist { - log.Errorf("badge not found by handler %s", handler) - return nil - } - return b + return badges } -func (br *eventRuleRepo) createBadgeAward(userID, badgeID, awardKey string) (awards *entity.BadgeAward) { +func (br *eventRuleRepo) createBadgeAward(userID, awardKey string, badge *entity.Badge) (awards *entity.BadgeAward) { + if badge.Single == entity.BadgeSingleAward { + awardKey = entity.BadgeOnceAwardKey + } return &entity.BadgeAward{ UserID: userID, - BadgeID: badgeID, + BadgeID: badge.ID, AwardKey: awardKey, } } diff --git a/internal/service/content/answer_service.go b/internal/service/content/answer_service.go index 5674a79b..496f7546 100644 --- a/internal/service/content/answer_service.go +++ b/internal/service/content/answer_service.go @@ -446,8 +446,10 @@ func (as *AnswerService) AcceptAnswer(ctx context.Context, req *schema.AcceptAns oldAnswerInfo.ID = uid.DeShortID(oldAnswerInfo.ID) } - as.eventQueueService.Send(ctx, schema.NewEvent(constant.EventQuestionAccept, req.UserID). - QID(questionInfo.ID, questionInfo.UserID).AID(req.AnswerID, req.UserID)) + if acceptedAnswerInfo != nil { + as.eventQueueService.Send(ctx, schema.NewEvent(constant.EventQuestionAccept, req.UserID). + QID(questionInfo.ID, questionInfo.UserID).AID(acceptedAnswerInfo.ID, acceptedAnswerInfo.UserID)) + } as.updateAnswerRank(ctx, req.UserID, questionInfo, acceptedAnswerInfo, oldAnswerInfo) return nil