feat: 用户徽章与等级体系,积分经济管理重构
- 新增徽章系统:badge 服务与 handler、管理端配置页、BadgeChip/LevelBadge 展示组件 - 新增等级模型:model/level 及前端 levels 元数据 - 管理端经济模块拆分为 points/badges/levels 独立页面,EconomySettings 迁入设置 - 积分、签到、评论等服务适配等级与徽章逻辑
This commit is contained in:
@@ -23,12 +23,19 @@ var (
|
||||
// CommentService 评论服务
|
||||
type CommentService struct {
|
||||
db *gorm.DB
|
||||
setting *SettingService
|
||||
}
|
||||
|
||||
func NewCommentService(db *gorm.DB) *CommentService {
|
||||
return &CommentService{db: db}
|
||||
}
|
||||
|
||||
// WithSetting 注入站点设置(回复奖励规则;未注入时奖励关闭)
|
||||
func (s *CommentService) WithSetting(setting *SettingService) *CommentService {
|
||||
s.setting = setting
|
||||
return s
|
||||
}
|
||||
|
||||
// CommentNode 评论树节点:嵌入 model.Comment 使 JSON 字段拍平,replies 为空时省略
|
||||
type CommentNode struct {
|
||||
model.Comment
|
||||
@@ -84,7 +91,7 @@ func (s *CommentService) ListFloorPaged(postID, boardID, viewerID uint, actor *A
|
||||
if err := base.Session(&gorm.Session{}).
|
||||
Where("parent_id IS NULL").
|
||||
Order("created_at ASC").
|
||||
Preload("User").
|
||||
Preload("User").Preload("User.Badges.Badge").
|
||||
Offset((page - 1) * size).
|
||||
Limit(size).
|
||||
Find(&roots).Error; err != nil {
|
||||
@@ -100,7 +107,7 @@ func (s *CommentService) ListFloorPaged(postID, boardID, viewerID uint, actor *A
|
||||
}
|
||||
replyQ := applyCommentListVisibility(s.db.Unscoped().Where("root_id IN (?)", rootIDs), boardID, viewerID, actor)
|
||||
var replies []model.Comment
|
||||
if err := replyQ.Order("created_at ASC").Preload("User").Find(&replies).Error; err != nil {
|
||||
if err := replyQ.Order("created_at ASC").Preload("User").Preload("User.Badges.Badge").Find(&replies).Error; err != nil {
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
|
||||
@@ -355,9 +362,19 @@ func (s *CommentService) Create(userID, postID uint, content string, parentID *u
|
||||
// 仅已发布评论立即计入评论数;待审评论通过审核时才 +1
|
||||
if comment.Status == model.ContentStatusPublished {
|
||||
s.db.Model(&post).UpdateColumn("comment_count", gorm.Expr("comment_count + 1"))
|
||||
// 回复奖励(可配置;待审不发且过审不补发,防拒审刷分)
|
||||
if s.setting != nil {
|
||||
if rules, err := s.setting.PointsRules(); err == nil {
|
||||
s.db.Transaction(func(tx *gorm.DB) error {
|
||||
RewardIfConfigured(tx, userID, rules.ReplyReward, rules.ReplyDailyCap,
|
||||
model.PointReasonReplyReward, "comment", comment.ID, "回复奖励:"+post.Title)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
// 预加载用户
|
||||
s.db.Preload("User").First(comment, comment.ID)
|
||||
s.db.Preload("User").Preload("User.Badges.Badge").First(comment, comment.ID)
|
||||
return comment, parent, nil
|
||||
}
|
||||
|
||||
@@ -648,7 +665,7 @@ func (s *CommentService) Update(actor *Actor, commentID, userID uint, content st
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := s.db.Preload("User").First(&comment, comment.ID).Error; err != nil {
|
||||
if err := s.db.Preload("User").Preload("User.Badges.Badge").First(&comment, comment.ID).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
node := toCommentNode(comment, nil, false, userID, nil)
|
||||
|
||||
Reference in New Issue
Block a user