- GetDailyEnergizeExp 用 Find + Limit(1) 替代 First,空结果不触发 GORM ErrRecordNotFound - 移除不再需要的 errors 导入 - 数据库检查确认三张表均存在,daily_exp_summaries 为空属正常状态
149 lines
4.6 KiB
Go
149 lines
4.6 KiB
Go
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
|
||
}
|