- 修复 Admin 改名路径未扣域能(非审核路径补充 HasCompletedTask + DeductOnRename) - 赋能按钮改为 Modal 弹窗(轻赋/重赋选择 + 每日上限提示) - EnergyInfo API 增加 daily_energize_exp/daily_exp_cap_reached 返回值 - "我的域能" TAB 增加经验值和等级展示 - Energize 事务修复:导出 EnergyStore + WithTx 方法确保 DB 操作原子性 - Studio 写文章页新增 LV0 锁止横幅 + 禁用提交按钮
145 lines
4.5 KiB
Go
145 lines
4.5 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 获取用户当日通过赋能获得的经验值
|
||
func (r *EnergyRepo) GetDailyEnergizeExp(userID uint, date time.Time) (*model.DailyExpSummary, error) {
|
||
var s model.DailyExpSummary
|
||
err := r.db.Where("user_id = ? AND date = ?", userID, date).First(&s).Error
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
return &s, 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
|
||
}
|