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 203062dd feat(badge): badge award
203062dd is described below
commit 203062dd985e0f4909cfde3cd7a69a0965b86ff4
Author: kumfo <[email protected]>
AuthorDate: Fri Aug 9 10:33:03 2024 +0800
feat(badge): badge award
---
internal/entity/badge_award_entity.go | 2 +-
internal/entity/badge_entity.go | 2 +-
internal/migrations/v22.go | 28 ++++----
internal/repo/badge/badge_repo.go | 6 ++
internal/repo/badge_award/badge_award_repo.go | 55 ++++++++++++----
internal/service/badge/badge_service.go | 5 +-
.../service/badge_award/badge_award_service.go | 77 +++++++++++++++++-----
7 files changed, 129 insertions(+), 46 deletions(-)
diff --git a/internal/entity/badge_award_entity.go
b/internal/entity/badge_award_entity.go
index 26369394..310c85a7 100644
--- a/internal/entity/badge_award_entity.go
+++ b/internal/entity/badge_award_entity.go
@@ -29,7 +29,7 @@ type BadgeAward struct {
UserID string `json:"user_id" xorm:"not null index
BIGINT(20) user_id"`
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 int8 `json:"badge_group_id" xorm:"not null index
BIGINT(20) badge_group_id"`
+ 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"`
}
diff --git a/internal/entity/badge_entity.go b/internal/entity/badge_entity.go
index da6cd4dd..d2c426fa 100644
--- a/internal/entity/badge_entity.go
+++ b/internal/entity/badge_entity.go
@@ -46,7 +46,7 @@ type Badge struct {
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"`
+ 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"`
diff --git a/internal/migrations/v22.go b/internal/migrations/v22.go
index de15cea6..19ec1ce0 100644
--- a/internal/migrations/v22.go
+++ b/internal/migrations/v22.go
@@ -44,7 +44,7 @@ var (
AwardCount: 0,
Description:
"badge.default_badges.autobiographer.desc",
Status: entity.BadgeStatusActive,
- BadgeGroupId: 1,
+ BadgeGroupID: 1,
Level: entity.BadgeLevelBronze,
Single: entity.BadgeSingleAward,
Collect: "",
@@ -59,7 +59,7 @@ var (
AwardCount: 0,
Description: "badge.default_badges.editor.desc",
Status: entity.BadgeStatusActive,
- BadgeGroupId: 1,
+ BadgeGroupID: 1,
Level: entity.BadgeLevelBronze,
Single: entity.BadgeSingleAward,
Collect: "question",
@@ -74,7 +74,7 @@ var (
AwardCount: 0,
Description: "badge.default_badges.first_flag.desc",
Status: entity.BadgeStatusActive,
- BadgeGroupId: 1,
+ BadgeGroupID: 1,
Level: entity.BadgeLevelBronze,
Single: entity.BadgeSingleAward,
Collect: "",
@@ -89,7 +89,7 @@ var (
AwardCount: 0,
Description: "badge.default_badges.first_upvote.desc",
Status: entity.BadgeStatusActive,
- BadgeGroupId: 1,
+ BadgeGroupID: 1,
Level: entity.BadgeLevelBronze,
Single: entity.BadgeSingleAward,
Collect: "",
@@ -104,7 +104,7 @@ var (
AwardCount: 0,
Description:
"badge.default_badges.first_reaction.desc",
Status: entity.BadgeStatusActive,
- BadgeGroupId: 1,
+ BadgeGroupID: 1,
Level: entity.BadgeLevelBronze,
Single: entity.BadgeSingleAward,
Collect: "",
@@ -119,7 +119,7 @@ var (
AwardCount: 0,
Description: "badge.default_badges.first_share.desc",
Status: entity.BadgeStatusActive,
- BadgeGroupId: 1,
+ BadgeGroupID: 1,
Level: entity.BadgeLevelBronze,
Single: entity.BadgeSingleAward,
Collect: "",
@@ -134,7 +134,7 @@ var (
AwardCount: 0,
Description: "badge.default_badges.scholar.desc",
Status: entity.BadgeStatusActive,
- BadgeGroupId: 1,
+ BadgeGroupID: 1,
Level: entity.BadgeLevelBronze,
Single: entity.BadgeSingleAward,
Collect: "",
@@ -149,7 +149,7 @@ var (
AwardCount: 0,
Description: "badge.default_badges.solved.desc",
Status: entity.BadgeStatusActive,
- BadgeGroupId: 2,
+ BadgeGroupID: 2,
Level: entity.BadgeLevelBronze,
Single: entity.BadgeSingleAward,
Collect: "",
@@ -164,7 +164,7 @@ var (
AwardCount: 0,
Description: "badge.default_badges.nice_answer.desc",
Status: entity.BadgeStatusActive,
- BadgeGroupId: 3,
+ BadgeGroupID: 3,
Level: entity.BadgeLevelBronze,
Single: entity.BadgeMultiAward,
Collect: "",
@@ -179,7 +179,7 @@ var (
AwardCount: 0,
Description: "badge.default_badges.good_answer.desc",
Status: entity.BadgeStatusActive,
- BadgeGroupId: 3,
+ BadgeGroupID: 3,
Level: entity.BadgeLevelSilver,
Single: entity.BadgeMultiAward,
Collect: "",
@@ -194,7 +194,7 @@ var (
AwardCount: 0,
Description: "badge.default_badges.great_answer.desc",
Status: entity.BadgeStatusActive,
- BadgeGroupId: 3,
+ BadgeGroupID: 3,
Level: entity.BadgeLevelGold,
Single: entity.BadgeMultiAward,
Collect: "",
@@ -209,7 +209,7 @@ var (
AwardCount: 0,
Description: "badge.default_badges.nice_question.desc",
Status: entity.BadgeStatusActive,
- BadgeGroupId: 3,
+ BadgeGroupID: 3,
Level: entity.BadgeLevelBronze,
Single: entity.BadgeMultiAward,
Collect: "",
@@ -224,7 +224,7 @@ var (
AwardCount: 0,
Description: "badge.default_badges.good_question.desc",
Status: entity.BadgeStatusActive,
- BadgeGroupId: 3,
+ BadgeGroupID: 3,
Level: entity.BadgeLevelSilver,
Single: entity.BadgeSingleAward,
Collect: "",
@@ -239,7 +239,7 @@ var (
AwardCount: 0,
Description:
"badge.default_badges.great_question.desc",
Status: entity.BadgeStatusActive,
- BadgeGroupId: 3,
+ BadgeGroupID: 3,
Level: entity.BadgeLevelGold,
Single: entity.BadgeMultiAward,
Collect: "",
diff --git a/internal/repo/badge/badge_repo.go
b/internal/repo/badge/badge_repo.go
index 5030f0da..d4d2f992 100644
--- a/internal/repo/badge/badge_repo.go
+++ b/internal/repo/badge/badge_repo.go
@@ -109,3 +109,9 @@ func (r *badgeRepo) ListInactivated(ctx context.Context)
(badges []*entity.Badge
}
return
}
+
+// UpdateAwardCount updates the award count of a badge
+func (r *badgeRepo) UpdateAwardCount(ctx context.Context, id string, count
int64) (err error) {
+ _, err = r.data.DB.Context(ctx).Where("id = ?", id).Incr("award_count",
count).Update(&entity.Badge{})
+ return
+}
diff --git a/internal/repo/badge_award/badge_award_repo.go
b/internal/repo/badge_award/badge_award_repo.go
index 85d3ceac..92807d1d 100644
--- a/internal/repo/badge_award/badge_award_repo.go
+++ b/internal/repo/badge_award/badge_award_repo.go
@@ -28,7 +28,6 @@ import (
"github.com/apache/incubator-answer/internal/service/badge_award"
"github.com/apache/incubator-answer/internal/service/unique"
"github.com/segmentfault/pacman/errors"
- "time"
)
type badgeAwardRepo struct {
@@ -43,10 +42,36 @@ func NewBadgeAwardRepo(data *data.Data, uniqueIDRepo
unique.UniqueIDRepo) badge_
}
}
-func (r *badgeAwardRepo) Award(ctx context.Context, badgeID string, userID
string, awardKey string, force bool, createdAt time.Time) {
- return
-}
-func (r *badgeAwardRepo) CheckIsAward(ctx context.Context, badgeID string,
userID string, awardKey string) (isAward bool) {
+func (r *badgeAwardRepo) Add(ctx context.Context, badgeAward
*entity.BadgeAward) (err error) {
+ badgeAward.ID, err = r.uniqueIDRepo.GenUniqueIDStr(ctx,
entity.BadgeAward{}.TableName())
+ if err != nil {
+ return
+ }
+ _, err = r.data.DB.Context(ctx).Insert(badgeAward)
+ return
+}
+func (r *badgeAwardRepo) CheckIsAward(ctx context.Context, badgeID string,
userID string, awardKey string, singleOrMulti int8) (isAward bool) {
+ isAward = false
+ if singleOrMulti == entity.BadgeSingleAward {
+ _, exists, err := r.GetByUserIdAndBadgeId(ctx, userID, badgeID)
+ if err != nil {
+ err =
errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
+ return
+ }
+ if exists {
+ return true
+ }
+ } else {
+ _, exists, err := r.GetByUserIdAndBadgeIdAndObjectId(ctx,
userID, badgeID, awardKey)
+ if err != nil {
+ err =
errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
+ return
+ }
+ if exists {
+ return true
+ }
+ }
+
return
}
func (r *badgeAwardRepo) CountByUserIdAndBadgeLevel(ctx context.Context,
userID string, badgeLevel entity.BadgeLevel) (awardCount int64) {
@@ -62,13 +87,13 @@ func (r *badgeAwardRepo) CountByUserIdAndBadgeId(ctx
context.Context, userID str
}
return
}
-func (r *badgeAwardRepo) CountByObjectId(ctx context.Context, objectID string)
(awardCount int64) {
+func (r *badgeAwardRepo) CountByObjectId(ctx context.Context, awardKey string)
(awardCount int64) {
return
}
-func (r *badgeAwardRepo) CountByObjectIdAndBadgeId(ctx context.Context,
objectID string, badgeID string) (awardCount int64) {
+func (r *badgeAwardRepo) CountByObjectIdAndBadgeId(ctx context.Context,
awardKey string, badgeID string) (awardCount int64) {
return
}
-func (r *badgeAwardRepo) CountBadgesByUserIdAndObjectId(ctx context.Context,
userID string, objectID string, badgeID string) (awardCount int64) {
+func (r *badgeAwardRepo) CountBadgesByUserIdAndObjectId(ctx context.Context,
userID string, awardKey string, badgeID string) (awardCount int64) {
return
}
func (r *badgeAwardRepo) SumUserEarnedGroupByBadgeID(ctx context.Context,
userID string) (earnedCounts []*entity.BadgeEarnedCount, err error) {
@@ -92,10 +117,10 @@ func (r *badgeAwardRepo) ListPagedByBadgeId(ctx
context.Context, badgeID string,
func (r *badgeAwardRepo) ListPagedByBadgeIdAndUserId(ctx context.Context,
badgeID string, userID string, page int, pageSize int) (badgeAwards
[]*entity.BadgeAward, total int64, err error) {
return
}
-func (r *badgeAwardRepo) ListPagedByObjectId(ctx context.Context, badgeID
string, objectID string, page int, pageSize int) (badgeAwards
[]*entity.BadgeAward, total int64, err error) {
+func (r *badgeAwardRepo) ListPagedByObjectId(ctx context.Context, badgeID
string, awardKey string, page int, pageSize int) (badgeAwards
[]*entity.BadgeAward, total int64, err error) {
return
}
-func (r *badgeAwardRepo) ListPagedByObjectIdAndUserId(ctx context.Context,
badgeID string, objectID string, userID string, page int, pageSize int)
(badgeAwards []*entity.BadgeAward, total int64, err error) {
+func (r *badgeAwardRepo) ListPagedByObjectIdAndUserId(ctx context.Context,
badgeID string, awardKey string, userID string, page int, pageSize int)
(badgeAwards []*entity.BadgeAward, total int64, err error) {
return
}
func (r *badgeAwardRepo) ListTagPagedByBadgeId(ctx context.Context, badgeIDs
[]string, page int, pageSize int, filterUserID string) (badgeAwards
[]*entity.BadgeAward, total int64, err error) {
@@ -113,9 +138,15 @@ func (r *badgeAwardRepo) ListNewestEarnedByLevel(ctx
context.Context, userID str
func (r *badgeAwardRepo) ListNewestByUserIdAndLevel(ctx context.Context,
userID string, level int, page int, pageSize int) (badgeAwards
[]*entity.BadgeAward, total int64, err error) {
return
}
-func (r *badgeAwardRepo) GetByUserIdAndBadgeId(ctx context.Context, userID
string, badgeID string) (badgeAward *entity.BadgeAward) {
+
+// GetByUserIdAndBadgeId get badge award by user id and badge id
+func (r *badgeAwardRepo) GetByUserIdAndBadgeId(ctx context.Context, userID
string, badgeID string) (badgeAward *entity.BadgeAward, exists bool, err error)
{
+ exists, err = r.data.DB.Context(ctx).Where("user_id = ? AND badge_id =
? AND is_badge_deleted = 0", userID, badgeID).Get(&badgeAward)
return
}
-func (r *badgeAwardRepo) GetByUserIdAndBadgeIdAndObjectId(ctx context.Context,
userID string, badgeID string, objectID string) (badgeAward *entity.BadgeAward)
{
+
+// GetByUserIdAndBadgeIdAndObjectId get badge award by user id, badge id and
object id
+func (r *badgeAwardRepo) GetByUserIdAndBadgeIdAndObjectId(ctx context.Context,
userID string, badgeID string, awardKey string) (badgeAward *entity.BadgeAward,
exists bool, err error) {
+ exists, err = r.data.DB.Context(ctx).Where("user_id = ? AND badge_id =
? AND award_key = ? AND is_badge_deleted = 0", userID, badgeID,
awardKey).Get(&badgeAward)
return
}
diff --git a/internal/service/badge/badge_service.go
b/internal/service/badge/badge_service.go
index 16087f9c..faf97b11 100644
--- a/internal/service/badge/badge_service.go
+++ b/internal/service/badge/badge_service.go
@@ -37,11 +37,14 @@ import (
type BadgeRepo interface {
GetByID(ctx context.Context, id string) (badge *entity.Badge, exists
bool, err error)
GetByIDs(ctx context.Context, ids []string) (badges []*entity.Badge,
err error)
+
ListByLevel(ctx context.Context, level entity.BadgeLevel)
([]*entity.Badge, error)
ListByGroup(ctx context.Context, groupID int64) ([]*entity.Badge, error)
ListByLevelAndGroup(ctx context.Context, level entity.BadgeLevel,
groupID int64) ([]*entity.Badge, error)
ListActivated(ctx context.Context) ([]*entity.Badge, error)
ListInactivated(ctx context.Context) ([]*entity.Badge, error)
+
+ UpdateAwardCount(ctx context.Context, id string, count int64) error
}
type BadgeService struct {
@@ -109,7 +112,7 @@ func (b *BadgeService) ListByGroup(ctx context.Context,
userID string) (resp []*
}
}
- badgesMap[badge.BadgeGroupId] =
append(badgesMap[badge.BadgeGroupId], &schema.BadgeListInfo{
+ badgesMap[badge.BadgeGroupID] =
append(badgesMap[badge.BadgeGroupID], &schema.BadgeListInfo{
ID: uid.EnShortID(badge.ID),
Name: translator.Tr(handler.GetLangByCtx(ctx),
badge.Name),
Icon: badge.Icon,
diff --git a/internal/service/badge_award/badge_award_service.go
b/internal/service/badge_award/badge_award_service.go
index d94258b4..2c7c5ffa 100644
--- a/internal/service/badge_award/badge_award_service.go
+++ b/internal/service/badge_award/badge_award_service.go
@@ -21,66 +21,64 @@ package badge_award
import (
"context"
+ "github.com/apache/incubator-answer/internal/base/reason"
"github.com/apache/incubator-answer/internal/entity"
"github.com/apache/incubator-answer/internal/schema"
- answercommon
"github.com/apache/incubator-answer/internal/service/answer_common"
+ "github.com/apache/incubator-answer/internal/service/badge"
"github.com/apache/incubator-answer/internal/service/object_info"
- questioncommon
"github.com/apache/incubator-answer/internal/service/question_common"
usercommon
"github.com/apache/incubator-answer/internal/service/user_common"
"github.com/jinzhu/copier"
+ "github.com/segmentfault/pacman/errors"
"github.com/segmentfault/pacman/log"
"time"
)
type BadgeAwardRepo interface {
- Award(ctx context.Context, badgeID string, userID string, awardKey
string, force bool, createdAt time.Time)
- CheckIsAward(ctx context.Context, badgeID string, userID string,
awardKey string) bool
+ Add(ctx context.Context, badgeAward *entity.BadgeAward) (err error)
+ CheckIsAward(ctx context.Context, badgeID string, userID string,
awardKey string, singleOrMulti int8) bool
CountByUserIdAndBadgeLevel(ctx context.Context, userID string,
badgeLevel entity.BadgeLevel) (awardCount int64)
CountByUserId(ctx context.Context, userID string) (awardCount int64)
CountByUserIdAndBadgeId(ctx context.Context, userID string, badgeID
string) (awardCount int64)
- CountByObjectId(ctx context.Context, objectID string) (awardCount int64)
- CountByObjectIdAndBadgeId(ctx context.Context, objectID string, badgeID
string) (awardCount int64)
- CountBadgesByUserIdAndObjectId(ctx context.Context, userID string,
objectID string, badgeID string) (awardCount int64)
+ CountByObjectId(ctx context.Context, awardKey string) (awardCount int64)
+ CountByObjectIdAndBadgeId(ctx context.Context, awardKey string, badgeID
string) (awardCount int64)
+ CountBadgesByUserIdAndObjectId(ctx context.Context, userID string,
awardKey string, badgeID string) (awardCount int64)
SumUserEarnedGroupByBadgeID(ctx context.Context, userID string)
(earnedCounts []*entity.BadgeEarnedCount, err error)
ListAllByUserId(ctx context.Context, userID string) (badgeAwards
[]*entity.BadgeAward)
ListPagedByBadgeId(ctx context.Context, badgeID string, page int,
pageSize int) (badgeAwardList []*entity.BadgeAward, total int64, err error)
ListPagedByBadgeIdAndUserId(ctx context.Context, badgeID string, userID
string, page int, pageSize int) (badgeAwards []*entity.BadgeAward, total int64,
err error)
- ListPagedByObjectId(ctx context.Context, badgeID string, objectID
string, page int, pageSize int) (badgeAwards []*entity.BadgeAward, total int64,
err error)
- ListPagedByObjectIdAndUserId(ctx context.Context, badgeID string,
objectID string, userID string, page int, pageSize int) (badgeAwards
[]*entity.BadgeAward, total int64, err error)
+ ListPagedByObjectId(ctx context.Context, badgeID string, awardKey
string, page int, pageSize int) (badgeAwards []*entity.BadgeAward, total int64,
err error)
+ ListPagedByObjectIdAndUserId(ctx context.Context, badgeID string,
awardKey string, userID string, page int, pageSize int) (badgeAwards
[]*entity.BadgeAward, total int64, err error)
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)
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)
- GetByUserIdAndBadgeId(ctx context.Context, userID string, badgeID
string) (badgeAward *entity.BadgeAward)
- GetByUserIdAndBadgeIdAndObjectId(ctx context.Context, userID string,
badgeID string, objectID string) (badgeAward *entity.BadgeAward)
+ GetByUserIdAndBadgeId(ctx context.Context, userID string, badgeID
string) (badgeAward *entity.BadgeAward, exists bool, err error)
+ GetByUserIdAndBadgeIdAndObjectId(ctx context.Context, userID string,
badgeID string, awardKey string) (badgeAward *entity.BadgeAward, exists bool,
err error)
}
type BadgeAwardService struct {
badgeAwardRepo BadgeAwardRepo
+ badgeRepo badge.BadgeRepo
userCommon *usercommon.UserCommon
objectInfoService *object_info.ObjService
- questionRepo questioncommon.QuestionRepo
- answerRepo answercommon.AnswerRepo
}
func NewBadgeAwardService(
badgeAwardRepo BadgeAwardRepo,
+ badgeRepo badge.BadgeRepo,
userCommon *usercommon.UserCommon,
objectInfoService *object_info.ObjService,
- questionRepo questioncommon.QuestionRepo,
- answerRepo answercommon.AnswerRepo,
) *BadgeAwardService {
return &BadgeAwardService{
badgeAwardRepo: badgeAwardRepo,
+ badgeRepo: badgeRepo,
userCommon: userCommon,
objectInfoService: objectInfoService,
- questionRepo: questionRepo,
- answerRepo: answerRepo,
}
}
@@ -140,3 +138,48 @@ func (b *BadgeAwardService) GetBadgeAwardList(
return
}
+
+// Award award badge
+func (b *BadgeAwardService) Award(ctx context.Context, badgeID string, userID
string, awardKey string, force bool, createdAt time.Time) (err error) {
+ var (
+ badgeData *entity.Badge
+ exists, awarded bool
+ )
+
+ badgeData, exists, err = b.badgeRepo.GetByID(ctx, badgeID)
+ if err != nil {
+ return
+ }
+
+ if !exists || badgeData.Status == entity.BadgeStatusInactive {
+ err = errors.BadRequest(reason.BadgeObjectNotFound)
+ return
+ }
+
+ awarded = b.badgeAwardRepo.CheckIsAward(ctx, badgeID, userID, awardKey,
badgeData.Single)
+ if !force && awarded {
+ return
+ }
+
+ if createdAt.IsZero() {
+ createdAt = time.Now()
+ }
+
+ err = b.badgeAwardRepo.Add(ctx, &entity.BadgeAward{
+ CreatedAt: createdAt,
+ UpdatedAt: createdAt,
+ UserID: userID,
+ BadgeID: badgeID,
+ AwardKey: awardKey,
+ BadgeGroupID: badgeData.BadgeGroupID,
+ IsBadgeDeleted: 0,
+ })
+ if err != nil {
+ return
+ }
+
+ // increment badge award count
+ err = b.badgeRepo.UpdateAwardCount(ctx, badgeID, 1)
+
+ return
+}