feat: 实现积分与等级系统 + 签到功能 + 下拉菜单优化
- User 模型增加 exp 字段,等级规则 Lv0-Lv6 - 新增签到记录(UserCheckIn)与任务记录(UserTask)模型,唯一索引防重 - 自动签到:AuthMiddleware 验证会话后,基于 Asia/Shanghai 自然日自动签到 +5 经验 - 手动签到:下拉菜单"签到"按钮兜底,已签到显示"今日已签到"并禁用 - 首次任务经验:上传头像/设置用户名/设置个性签名各 +10,审核通过与直接更新均触发 - 经验值变动后自动比对等级,升级时通过通知系统发送"恭喜提升至 LvX" - 下拉菜单重构:顶部头像+用户名+LvX 等级标签,菜单项增加左侧图标,优化布局样式 - 新增 API:POST /api/level/checkin、GET /api/level/info
This commit is contained in:
@ -33,29 +33,36 @@ type siteSettingsChecker interface {
|
||||
IsAuditTypeEnabled(auditType string, defaultVal bool) bool
|
||||
}
|
||||
|
||||
// auditNotifier 审核服务所需的通知接口(ISP:审核通过/拒绝时发送通知)
|
||||
// auditNotifier AuditService 所需的通知接口(ISP:审核通过/拒绝时发送通知)
|
||||
type auditNotifier interface {
|
||||
NotifyAuditApproved(userID uint, auditType string, relatedID uint)
|
||||
NotifyAuditRejected(userID uint, auditType, reason string, relatedID uint)
|
||||
}
|
||||
|
||||
// auditTaskCompleter 审核通过时触发首次任务奖励的接口
|
||||
type auditTaskCompleter interface {
|
||||
CompleteTask(userID uint, taskType string) (newExp int, levelUp bool, err error)
|
||||
}
|
||||
|
||||
// AuditService 审核业务逻辑
|
||||
type AuditService struct {
|
||||
auditRepo auditRepo
|
||||
userRepo userProfileStore
|
||||
settings siteSettingsChecker
|
||||
defaultCfg config.AuditConfig
|
||||
notifier auditNotifier
|
||||
auditRepo auditRepo
|
||||
userRepo userProfileStore
|
||||
settings siteSettingsChecker
|
||||
defaultCfg config.AuditConfig
|
||||
notifier auditNotifier
|
||||
levelSvc auditTaskCompleter
|
||||
}
|
||||
|
||||
// NewAuditService 构造函数
|
||||
func NewAuditService(auditRepo auditRepo, userRepo userProfileStore, settings siteSettingsChecker, cfg config.AuditConfig, notifier auditNotifier) *AuditService {
|
||||
func NewAuditService(auditRepo auditRepo, userRepo userProfileStore, settings siteSettingsChecker, cfg config.AuditConfig, notifier auditNotifier, levelSvc auditTaskCompleter) *AuditService {
|
||||
return &AuditService{
|
||||
auditRepo: auditRepo,
|
||||
userRepo: userRepo,
|
||||
settings: settings,
|
||||
defaultCfg: cfg,
|
||||
notifier: notifier,
|
||||
levelSvc: levelSvc,
|
||||
}
|
||||
}
|
||||
|
||||
@ -220,7 +227,23 @@ func (s *AuditService) applyApproval(submission *model.AuditSubmission) error {
|
||||
case model.AuditTypeBio:
|
||||
user.Bio = submission.NewValue
|
||||
}
|
||||
return s.userRepo.Update(user)
|
||||
if err := s.userRepo.Update(user); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 触发首次任务奖励(静默失败不影响主流程)
|
||||
if s.levelSvc != nil {
|
||||
switch submission.AuditType {
|
||||
case model.AuditTypeUsername:
|
||||
_, _, _ = s.levelSvc.CompleteTask(submission.UserID, "username")
|
||||
case model.AuditTypeAvatar:
|
||||
_, _, _ = s.levelSvc.CompleteTask(submission.UserID, "avatar")
|
||||
case model.AuditTypeBio:
|
||||
_, _, _ = s.levelSvc.CompleteTask(submission.UserID, "bio")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// List 分页查询审核列表
|
||||
|
||||
Reference in New Issue
Block a user