This repository has been archived on 2026-06-21. You can view files and clone it, but cannot push or open issues or pull requests.
Files
MetaLab/internal/repository/energy_repo.go
Victor_Jay 5248e91a3d fix: First 改 Find 消除 record not found 日志噪音
- GetDailyEnergizeExp 用 Find + Limit(1) 替代 First,空结果不触发 GORM ErrRecordNotFound
- 移除不再需要的 errors 导入
- 数据库检查确认三张表均存在,daily_exp_summaries 为空属正常状态
2026-06-01 12:49:26 +08:00

149 lines
4.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package repository
import (
"time"
"metazone.cc/metalab/internal/model"
"metazone.cc/metalab/internal/service"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)
// EnergyRepo 域能数据访问
type EnergyRepo struct {
db *gorm.DB
}
// NewEnergyRepo 构造函数
func NewEnergyRepo(db *gorm.DB) *EnergyRepo {
return &EnergyRepo{db: db}
}
// WithTx 基于给定事务连接创建新的 EnergyRepo确保事务内操作原子性
func (r *EnergyRepo) WithTx(tx *gorm.DB) service.EnergyStore {
return &EnergyRepo{db: tx}
}
// FindUserByID 查找用户(获取能量余额等)
func (r *EnergyRepo) FindUserByID(userID uint) (*model.User, error) {
var user model.User
err := r.db.First(&user, userID).Error
if err != nil {
return nil, err
}
return &user, nil
}
// FindPostByID 查找帖子
func (r *EnergyRepo) FindPostByID(postID uint) (*model.Post, error) {
var post model.Post
err := r.db.First(&post, postID).Error
if err != nil {
return nil, err
}
return &post, nil
}
// AddEnergy 原子增减用户域能余额amount 可为正负)
func (r *EnergyRepo) AddEnergy(userID uint, amount int) error {
return r.db.Model(&model.User{}).
Where("uid = ?", userID).
UpdateColumn("energy", gorm.Expr("energy + ?", amount)).Error
}
// IncrPostEnergy 原子增减文章累计被赋能域能
func (r *EnergyRepo) IncrPostEnergy(postID uint, amount int) error {
return r.db.Model(&model.Post{}).
Where("id = ?", postID).
UpdateColumn("total_energy_received", gorm.Expr("total_energy_received + ?", amount)).Error
}
// CreateEnergyLog 创建域能流水
func (r *EnergyRepo) CreateEnergyLog(log *model.EnergyLog) error {
return r.db.Create(log).Error
}
// SumUserPostEnergy 统计某用户对某文章累计赋能总量(用于 ≤ 20 检查)
func (r *EnergyRepo) SumUserPostEnergy(userID, postID uint) (int, error) {
var total int
err := r.db.Model(&model.PostEnergizeLog{}).
Where("user_id = ? AND post_id = ?", userID, postID).
Select("COALESCE(SUM(amount), 0)").
Scan(&total).Error
return total, err
}
// CreateEnergizeLog 创建赋能记录
func (r *EnergyRepo) CreateEnergizeLog(log *model.PostEnergizeLog) error {
return r.db.Create(log).Error
}
// GetDailyEnergizeExp 获取用户当日通过赋能获得的经验值
// 无记录时返回 nil, nil调用方当作 exp=0 处理)
func (r *EnergyRepo) GetDailyEnergizeExp(userID uint, date time.Time) (*model.DailyExpSummary, error) {
var summaries []model.DailyExpSummary
err := r.db.Where("user_id = ? AND date = ?", userID, date).Limit(1).Find(&summaries).Error
if err != nil {
return nil, err
}
if len(summaries) == 0 {
return nil, nil
}
return &summaries[0], nil
}
// UpsertDailyExp 创建或更新每日经验汇总
func (r *EnergyRepo) UpsertDailyExp(summary *model.DailyExpSummary) error {
return r.db.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "user_id"}, {Name: "date"}},
DoUpdates: clause.AssignmentColumns([]string{"exp_earned", "updated_at"}),
}).Create(summary).Error
}
// AddDailyExp 原子增加每日赋能经验值
func (r *EnergyRepo) AddDailyExp(userID uint, date time.Time, delta int) error {
return r.db.Model(&model.DailyExpSummary{}).
Where("user_id = ? AND date = ?", userID, date).
UpdateColumn("exp_earned", gorm.Expr("exp_earned + ?", delta)).Error
}
// ListEnergyLogsByUser 分页查询用户域能流水(近 N 天)
func (r *EnergyRepo) ListEnergyLogsByUser(userID uint, days int, offset, limit int) ([]model.EnergyLog, error) {
var logs []model.EnergyLog
query := r.db.Where("user_id = ?", userID).Order("created_at DESC")
if days > 0 {
since := time.Now().AddDate(0, 0, -days)
query = query.Where("created_at >= ?", since)
}
err := query.Offset(offset).Limit(limit).Find(&logs).Error
return logs, err
}
// CountEnergyLogsByUser 统计用户域能流水总数
func (r *EnergyRepo) CountEnergyLogsByUser(userID uint, days int) (int64, error) {
var count int64
query := r.db.Model(&model.EnergyLog{}).Where("user_id = ?", userID)
if days > 0 {
since := time.Now().AddDate(0, 0, -days)
query = query.Where("created_at >= ?", since)
}
err := query.Count(&count).Error
return count, err
}
// ListAllEnergyLogs 查询全部域能流水(后台,支持筛选)
func (r *EnergyRepo) ListAllEnergyLogs(energyType string, offset, limit int) ([]model.EnergyLog, int64, error) {
query := r.db.Model(&model.EnergyLog{})
if energyType != "" {
query = query.Where("type = ?", energyType)
}
var total int64
if err := query.Count(&total).Error; err != nil {
return nil, 0, err
}
var logs []model.EnergyLog
err := query.Order("created_at DESC").Offset(offset).Limit(limit).Find(&logs).Error
return logs, total, err
}