fix: Service 层移除直接持有的 *gorm.DB,引入 Repository Transaction 方法
- ReactionStore/FollowStore/EnergyStore/FavoriteStore 接口新增 Transaction 方法 - EnergyStore.Transaction 支持跨仓库事务(EnergyStore + FundStore) - ReactionRepo/FollowRepo/FavoriteRepo/EnergyRepo 实现 Transaction 方法 - ReactionRepo 新增 GetPostLikesCount 方法,消除 Service 直查 DB - ReactionService/FollowService/FavoriteService/EnergyService 移除 db 字段 - EnergyRepo 通过 SetFundStore 注入 FundStore 用于跨仓库事务 - 更新 deps_extra.go 构造函数调用
This commit is contained in:
@ -13,6 +13,7 @@ import (
|
||||
// EnergyRepo 域能数据访问
|
||||
type EnergyRepo struct {
|
||||
db *gorm.DB
|
||||
fundStore service.FundStore // 用于 Transaction 时创建事务范围的 FundStore
|
||||
}
|
||||
|
||||
// NewEnergyRepo 构造函数
|
||||
@ -20,11 +21,28 @@ func NewEnergyRepo(db *gorm.DB) *EnergyRepo {
|
||||
return &EnergyRepo{db: db}
|
||||
}
|
||||
|
||||
// SetFundStore 设置公户仓储引用(用于跨仓库事务)
|
||||
func (r *EnergyRepo) SetFundStore(s service.FundStore) {
|
||||
r.fundStore = s
|
||||
}
|
||||
|
||||
// WithTx 基于给定事务连接创建新的 EnergyRepo(确保事务内操作原子性)
|
||||
func (r *EnergyRepo) WithTx(tx *gorm.DB) service.EnergyStore {
|
||||
return &EnergyRepo{db: tx}
|
||||
}
|
||||
|
||||
// Transaction 在事务内执行业务逻辑,自动管理 EnergyStore 和 FundStore 的事务范围
|
||||
func (r *EnergyRepo) Transaction(fn func(txEnergy service.EnergyStore, txFund service.FundStore) error) error {
|
||||
return r.db.Transaction(func(tx *gorm.DB) error {
|
||||
txEnergy := r.WithTx(tx)
|
||||
var txFund service.FundStore
|
||||
if r.fundStore != nil {
|
||||
txFund = r.fundStore.WithTx(tx)
|
||||
}
|
||||
return fn(txEnergy, txFund)
|
||||
})
|
||||
}
|
||||
|
||||
// FindUserByID 查找用户(获取能量余额等)
|
||||
func (r *EnergyRepo) FindUserByID(userID uint) (*model.User, error) {
|
||||
var user model.User
|
||||
|
||||
@ -22,6 +22,13 @@ func (r *FavoriteRepo) WithTx(tx *gorm.DB) service.FavoriteStore {
|
||||
return &FavoriteRepo{db: tx}
|
||||
}
|
||||
|
||||
// Transaction 在事务内执行业务逻辑
|
||||
func (r *FavoriteRepo) Transaction(fn func(tx service.FavoriteStore) error) error {
|
||||
return r.db.Transaction(func(tx *gorm.DB) error {
|
||||
return fn(r.WithTx(tx))
|
||||
})
|
||||
}
|
||||
|
||||
// ======================== Folder CRUD ========================
|
||||
|
||||
// CreateFolder 创建收藏夹
|
||||
|
||||
@ -22,6 +22,13 @@ func (r *FollowRepo) WithTx(tx *gorm.DB) service.FollowStore {
|
||||
return &FollowRepo{db: tx}
|
||||
}
|
||||
|
||||
// Transaction 在事务内执行业务逻辑
|
||||
func (r *FollowRepo) Transaction(fn func(tx service.FollowStore) error) error {
|
||||
return r.db.Transaction(func(tx *gorm.DB) error {
|
||||
return fn(r.WithTx(tx))
|
||||
})
|
||||
}
|
||||
|
||||
// Create 创建关注
|
||||
func (r *FollowRepo) Create(follow *model.UserFollow) error {
|
||||
return r.db.Create(follow).Error
|
||||
|
||||
@ -22,6 +22,22 @@ func (r *ReactionRepo) WithTx(tx *gorm.DB) service.ReactionStore {
|
||||
return &ReactionRepo{db: tx}
|
||||
}
|
||||
|
||||
// Transaction 在事务内执行业务逻辑
|
||||
func (r *ReactionRepo) Transaction(fn func(tx service.ReactionStore) error) error {
|
||||
return r.db.Transaction(func(tx *gorm.DB) error {
|
||||
return fn(r.WithTx(tx))
|
||||
})
|
||||
}
|
||||
|
||||
// GetPostLikesCount 查询文章点赞数
|
||||
func (r *ReactionRepo) GetPostLikesCount(postID uint) (int, error) {
|
||||
var post model.Post
|
||||
if err := r.db.Select("likes_count").First(&post, postID).Error; err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return post.LikesCount, nil
|
||||
}
|
||||
|
||||
// FindLike 查找点赞记录
|
||||
func (r *ReactionRepo) FindLike(userID, postID uint) (*model.PostLike, error) {
|
||||
var like model.PostLike
|
||||
|
||||
@ -22,8 +22,9 @@ func buildDeps(db *gorm.DB, cfg *config.Config, siteSettings *config.SiteSetting
|
||||
// 域能系统
|
||||
energyRepo := repository.NewEnergyRepo(db)
|
||||
fundRepo := repository.NewFundRepo(db)
|
||||
energyService := service.NewEnergyService(db, energyRepo, nil, notificationService)
|
||||
energyService.SetFundRepo(fundRepo)
|
||||
energyRepo.SetFundStore(fundRepo) // 为跨仓库 Transaction 注入 FundStore
|
||||
energyService := service.NewEnergyService(energyRepo, nil, notificationService)
|
||||
energyService.SetFundRepo(fundRepo) // 只读查询
|
||||
|
||||
// 等级/签到/任务系统(链式注入域能服务)
|
||||
_, levelSvc, levelCtrl := buildDepsLevel(db, notificationService, authMdw)
|
||||
@ -72,18 +73,18 @@ func buildDeps(db *gorm.DB, cfg *config.Config, siteSettings *config.SiteSetting
|
||||
|
||||
// 赞/踩系统
|
||||
reactionRepo := repository.NewReactionRepo(db)
|
||||
reactionService := service.NewReactionService(db, reactionRepo)
|
||||
reactionService := service.NewReactionService(reactionRepo)
|
||||
reactionCtrl := controller.NewReactionController(reactionService)
|
||||
|
||||
// 关注系统
|
||||
followRepo := repository.NewFollowRepo(db)
|
||||
followService := service.NewFollowService(db, followRepo)
|
||||
followService := service.NewFollowService(followRepo)
|
||||
followService.SetNotifier(notificationService) // 关注通知
|
||||
followCtrl := controller.NewFollowController(followService)
|
||||
|
||||
// 收藏夹系统(需在 SpaceController 之前初始化)
|
||||
favoriteRepo := repository.NewFavoriteRepo(db)
|
||||
favoriteService := service.NewFavoriteService(db, favoriteRepo)
|
||||
favoriteService := service.NewFavoriteService(favoriteRepo)
|
||||
favoriteCtrl := controller.NewFavoriteController(favoriteService)
|
||||
|
||||
// 用户空间
|
||||
|
||||
@ -5,8 +5,6 @@ import (
|
||||
|
||||
"metazone.cc/metalab/internal/common"
|
||||
"metazone.cc/metalab/internal/model"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// AdminAdjust 后台调整用户域能
|
||||
@ -16,13 +14,10 @@ func (s *EnergyService) AdminAdjust(operatorUID uint, userIDs []uint, amount int
|
||||
mode = model.FundTypeAdminTransfer
|
||||
}
|
||||
|
||||
return s.db.Transaction(func(tx *gorm.DB) error {
|
||||
txRepo := s.repo.WithTx(tx)
|
||||
|
||||
return s.repo.Transaction(func(txRepo EnergyStore, txFundRepo FundStore) error {
|
||||
// admin_transfer:公户出账需检查余额(行锁防 TOCTOU 竞态)
|
||||
isAdminTransfer := mode == model.FundTypeAdminTransfer
|
||||
if isAdminTransfer && amount > 0 && s.fundRepo != nil {
|
||||
txFundRepo := s.fundRepo.WithTx(tx)
|
||||
if isAdminTransfer && amount > 0 && txFundRepo != nil {
|
||||
totalCost := amount * len(userIDs)
|
||||
balance, err := txFundRepo.LockAndGetBalance()
|
||||
if err != nil {
|
||||
@ -52,8 +47,7 @@ func (s *EnergyService) AdminAdjust(operatorUID uint, userIDs []uint, amount int
|
||||
}
|
||||
|
||||
// admin_transfer:公户扣款 + 公户流水(system_operation 不碰公户)
|
||||
if isAdminTransfer && s.fundRepo != nil {
|
||||
txFundRepo := s.fundRepo.WithTx(tx)
|
||||
if isAdminTransfer && txFundRepo != nil {
|
||||
totalCost := amount * len(userIDs)
|
||||
if err := txFundRepo.IncrBalance(-totalCost); err != nil {
|
||||
return fmt.Errorf("公户余额调整失败: %w", err)
|
||||
|
||||
@ -6,8 +6,6 @@ import (
|
||||
|
||||
"metazone.cc/metalab/internal/common"
|
||||
"metazone.cc/metalab/internal/model"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// Energize 赋能文章
|
||||
@ -23,19 +21,10 @@ func (s *EnergyService) Energize(energizerID uint, postID uint, amount int) (int
|
||||
var expToday time.Time
|
||||
var expTotal int
|
||||
|
||||
err := s.db.Transaction(func(tx *gorm.DB) error {
|
||||
txRepo := s.repo.WithTx(tx)
|
||||
var txFundRepo FundStore
|
||||
if s.fundRepo != nil {
|
||||
txFundRepo = s.fundRepo.WithTx(tx)
|
||||
}
|
||||
|
||||
err := s.repo.Transaction(func(txRepo EnergyStore, txFundRepo FundStore) error {
|
||||
// 1. 检查帖子存在,获取作者
|
||||
post, err := txRepo.FindPostByID(postID)
|
||||
if err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return common.ErrPostNotFound
|
||||
}
|
||||
return fmt.Errorf("查询帖子失败: %w", err)
|
||||
}
|
||||
|
||||
|
||||
@ -5,8 +5,6 @@ import (
|
||||
|
||||
"metazone.cc/metalab/internal/common"
|
||||
"metazone.cc/metalab/internal/model"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// CheckInEnergy 签到获得域能(LV0 用户不调用此方法)
|
||||
@ -27,9 +25,7 @@ func (s *EnergyService) CheckInEnergy(userID uint) error {
|
||||
// DeductOnRename 改名扣域能(首次改名免费,不调用此方法)
|
||||
// 事务包裹:扣用户域能 + 入公户 + 写流水
|
||||
func (s *EnergyService) DeductOnRename(userID uint) error {
|
||||
return s.db.Transaction(func(tx *gorm.DB) error {
|
||||
txRepo := s.repo.WithTx(tx)
|
||||
|
||||
return s.repo.Transaction(func(txRepo EnergyStore, txFundRepo FundStore) error {
|
||||
// 检查域能余额(非 owner 需 ≥ 0)
|
||||
user, err := txRepo.FindUserByID(userID)
|
||||
if err != nil {
|
||||
@ -44,8 +40,7 @@ func (s *EnergyService) DeductOnRename(userID uint) error {
|
||||
}
|
||||
|
||||
// 公户入账
|
||||
if s.fundRepo != nil {
|
||||
txFundRepo := s.fundRepo.WithTx(tx)
|
||||
if txFundRepo != nil {
|
||||
if err := txFundRepo.IncrBalance(-EnergyRename); err != nil { // EnergyRename = -60,入公户 +60
|
||||
return fmt.Errorf("公户入账失败: %w", err)
|
||||
}
|
||||
@ -73,12 +68,9 @@ func (s *EnergyService) DeductOnRename(userID uint) error {
|
||||
|
||||
// RefundOnRenameReject 改名审核被拒,从公户返还域能
|
||||
func (s *EnergyService) RefundOnRenameReject(userID uint) error {
|
||||
return s.db.Transaction(func(tx *gorm.DB) error {
|
||||
txRepo := s.repo.WithTx(tx)
|
||||
|
||||
return s.repo.Transaction(func(txRepo EnergyStore, txFundRepo FundStore) error {
|
||||
// 从公户支出(允许透支)
|
||||
if s.fundRepo != nil {
|
||||
txFundRepo := s.fundRepo.WithTx(tx)
|
||||
if txFundRepo != nil {
|
||||
if err := txFundRepo.IncrBalance(-EnergyRenameRefund); err != nil {
|
||||
return fmt.Errorf("公户出账失败: %w", err)
|
||||
}
|
||||
@ -111,16 +103,13 @@ func (s *EnergyService) RefundOnRenameReject(userID uint) error {
|
||||
// DeductOnDeletePost 删稿扣域能(扣文章作者的域能,无视负数)
|
||||
// 事务包裹:扣用户域能 + 入公户 + 写流水
|
||||
func (s *EnergyService) DeductOnDeletePost(authorUserID uint, postID uint) error {
|
||||
return s.db.Transaction(func(tx *gorm.DB) error {
|
||||
txRepo := s.repo.WithTx(tx)
|
||||
|
||||
return s.repo.Transaction(func(txRepo EnergyStore, txFundRepo FundStore) error {
|
||||
if err := txRepo.AddEnergy(authorUserID, EnergyDeletePost); err != nil {
|
||||
return fmt.Errorf("扣减删稿域能失败: %w", err)
|
||||
}
|
||||
|
||||
// 公户入账
|
||||
if s.fundRepo != nil {
|
||||
txFundRepo := s.fundRepo.WithTx(tx)
|
||||
if txFundRepo != nil {
|
||||
if err := txFundRepo.IncrBalance(-EnergyDeletePost); err != nil { // EnergyDeletePost = -20,入公户 +20
|
||||
return fmt.Errorf("公户入账失败: %w", err)
|
||||
}
|
||||
|
||||
@ -1,9 +1,5 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// expAdder EnergyService 对经验增加的最小依赖(ISP)
|
||||
type expAdder interface {
|
||||
AddExp(userID uint, delta int) (newExp int, levelUp bool, err error)
|
||||
@ -11,16 +7,15 @@ type expAdder interface {
|
||||
|
||||
// EnergyService 域能业务逻辑
|
||||
type EnergyService struct {
|
||||
db *gorm.DB
|
||||
repo EnergyStore
|
||||
fundRepo FundStore
|
||||
fundRepo FundStore // 只读查询用(GetFundBalance/GetFundLogs)
|
||||
expSvc expAdder
|
||||
notifSvc energyNotifier
|
||||
}
|
||||
|
||||
// NewEnergyService 构造函数
|
||||
func NewEnergyService(db *gorm.DB, repo EnergyStore, expSvc expAdder, notifSvc energyNotifier) *EnergyService {
|
||||
return &EnergyService{db: db, repo: repo, expSvc: expSvc, notifSvc: notifSvc}
|
||||
func NewEnergyService(repo EnergyStore, expSvc expAdder, notifSvc energyNotifier) *EnergyService {
|
||||
return &EnergyService{repo: repo, expSvc: expSvc, notifSvc: notifSvc}
|
||||
}
|
||||
|
||||
// SetExpAdder 链式注入经验服务(用于赋能获得经验)
|
||||
@ -28,7 +23,7 @@ func (s *EnergyService) SetExpAdder(svc expAdder) {
|
||||
s.expSvc = svc
|
||||
}
|
||||
|
||||
// SetFundRepo 链式注入公户仓储
|
||||
// SetFundRepo 链式注入公户仓储(只读查询)
|
||||
func (s *EnergyService) SetFundRepo(repo FundStore) {
|
||||
s.fundRepo = repo
|
||||
}
|
||||
|
||||
@ -5,8 +5,6 @@ import (
|
||||
|
||||
"metazone.cc/metalab/internal/common"
|
||||
"metazone.cc/metalab/internal/model"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// AddToFolder 将文章加入收藏夹(会先移除该文章在其他收藏夹的收藏)
|
||||
@ -20,8 +18,7 @@ func (s *FavoriteService) AddToFolder(userID, folderID, postID uint) error {
|
||||
return common.ErrPermissionDenied
|
||||
}
|
||||
|
||||
return s.db.Transaction(func(tx *gorm.DB) error {
|
||||
txRepo := s.repo.WithTx(tx)
|
||||
return s.repo.Transaction(func(txRepo FavoriteStore) error {
|
||||
|
||||
// 如果该文章已在其他收藏夹中,先移除
|
||||
existing, err := txRepo.FindItemByUserAndPost(userID, postID)
|
||||
@ -60,8 +57,7 @@ func (s *FavoriteService) RemoveFromFolder(userID, folderID, postID uint) error
|
||||
return common.ErrPermissionDenied
|
||||
}
|
||||
|
||||
return s.db.Transaction(func(tx *gorm.DB) error {
|
||||
txRepo := s.repo.WithTx(tx)
|
||||
return s.repo.Transaction(func(txRepo FavoriteStore) error {
|
||||
if err := txRepo.DeleteItem(folderID, postID); err != nil {
|
||||
return fmt.Errorf("移除收藏: %w", err)
|
||||
}
|
||||
|
||||
@ -32,6 +32,8 @@ type FavoriteStore interface {
|
||||
AggregateFavoritesByAuthor(userID uint, since string) ([]TrendPoint, error)
|
||||
// Tx
|
||||
WithTx(tx *gorm.DB) FavoriteStore
|
||||
// Transaction 在事务内执行业务逻辑,自动管理 WithTx
|
||||
Transaction(fn func(tx FavoriteStore) error) error
|
||||
}
|
||||
|
||||
// FavoriteListResult 收藏夹列表 + 收藏内容
|
||||
@ -56,13 +58,12 @@ type FavoriteStatus struct {
|
||||
|
||||
// FavoriteService 收藏夹业务逻辑
|
||||
type FavoriteService struct {
|
||||
db *gorm.DB
|
||||
repo FavoriteStore
|
||||
}
|
||||
|
||||
// NewFavoriteService 构造函数
|
||||
func NewFavoriteService(db *gorm.DB, repo FavoriteStore) *FavoriteService {
|
||||
return &FavoriteService{db: db, repo: repo}
|
||||
func NewFavoriteService(repo FavoriteStore) *FavoriteService {
|
||||
return &FavoriteService{repo: repo}
|
||||
}
|
||||
|
||||
// ensureDefaultFolder 确保用户有默认收藏夹(不存在则创建)
|
||||
@ -187,9 +188,7 @@ func (s *FavoriteService) DeleteFolder(userID, folderID uint) error {
|
||||
return fmt.Errorf("默认收藏夹不可删除")
|
||||
}
|
||||
|
||||
return s.db.Transaction(func(tx *gorm.DB) error {
|
||||
txRepo := s.repo.WithTx(tx)
|
||||
|
||||
return s.repo.Transaction(func(txRepo FavoriteStore) error {
|
||||
// 先清理 items 的 fans 计数
|
||||
items, _, _ := txRepo.ListItemsByFolder(folderID, 0, 10000)
|
||||
for _, item := range items {
|
||||
|
||||
@ -6,8 +6,6 @@ import (
|
||||
|
||||
"metazone.cc/metalab/internal/common"
|
||||
"metazone.cc/metalab/internal/model"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// FollowStatus 关注关系状态
|
||||
@ -33,14 +31,13 @@ type followNotifier interface {
|
||||
|
||||
// FollowService 关注业务逻辑
|
||||
type FollowService struct {
|
||||
db *gorm.DB
|
||||
repo FollowStore
|
||||
notifier followNotifier
|
||||
}
|
||||
|
||||
// NewFollowService 构造函数
|
||||
func NewFollowService(db *gorm.DB, repo FollowStore) *FollowService {
|
||||
return &FollowService{db: db, repo: repo}
|
||||
func NewFollowService(repo FollowStore) *FollowService {
|
||||
return &FollowService{repo: repo}
|
||||
}
|
||||
|
||||
// SetNotifier 注入通知服务
|
||||
@ -55,9 +52,7 @@ func (s *FollowService) Toggle(followerID, followeeID uint) (bool, error) {
|
||||
}
|
||||
|
||||
var isFollowing bool
|
||||
err := s.db.Transaction(func(tx *gorm.DB) error {
|
||||
txRepo := s.repo.WithTx(tx)
|
||||
|
||||
err := s.repo.Transaction(func(txRepo FollowStore) error {
|
||||
exists, err := txRepo.Exists(followerID, followeeID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("查询关注状态失败: %w", err)
|
||||
|
||||
@ -4,10 +4,7 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"metazone.cc/metalab/internal/common"
|
||||
"metazone.cc/metalab/internal/model"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// ReactionType 反应类型
|
||||
@ -21,13 +18,12 @@ const (
|
||||
|
||||
// ReactionService 赞/踩业务逻辑
|
||||
type ReactionService struct {
|
||||
db *gorm.DB
|
||||
repo ReactionStore
|
||||
}
|
||||
|
||||
// NewReactionService 构造函数
|
||||
func NewReactionService(db *gorm.DB, repo ReactionStore) *ReactionService {
|
||||
return &ReactionService{db: db, repo: repo}
|
||||
func NewReactionService(repo ReactionStore) *ReactionService {
|
||||
return &ReactionService{repo: repo}
|
||||
}
|
||||
|
||||
// ToggleLike 切换点赞(含踩互斥逻辑)
|
||||
@ -35,9 +31,7 @@ func NewReactionService(db *gorm.DB, repo ReactionStore) *ReactionService {
|
||||
func (s *ReactionService) ToggleLike(userID, postID uint) (bool, error) {
|
||||
var isLiked bool
|
||||
|
||||
err := s.db.Transaction(func(tx *gorm.DB) error {
|
||||
txRepo := s.repo.WithTx(tx)
|
||||
|
||||
err := s.repo.Transaction(func(txRepo ReactionStore) error {
|
||||
// 查当前状态
|
||||
_, likeErr := txRepo.FindLike(userID, postID)
|
||||
hasLike := likeErr == nil
|
||||
@ -104,9 +98,7 @@ func (s *ReactionService) recordLikeForAggregation(postID uint, likerID uint) {
|
||||
func (s *ReactionService) ToggleDislike(userID, postID uint) (bool, error) {
|
||||
var isDisliked bool
|
||||
|
||||
err := s.db.Transaction(func(tx *gorm.DB) error {
|
||||
txRepo := s.repo.WithTx(tx)
|
||||
|
||||
err := s.repo.Transaction(func(txRepo ReactionStore) error {
|
||||
// 查当前状态
|
||||
_, likeErr := txRepo.FindLike(userID, postID)
|
||||
hasLike := likeErr == nil
|
||||
@ -165,12 +157,9 @@ func (s *ReactionService) GetReaction(userID, postID uint) (ReactionType, error)
|
||||
|
||||
// GetPostLikesCount 查询文章点赞数(公开展示)
|
||||
func (s *ReactionService) GetPostLikesCount(postID uint) (int, error) {
|
||||
var post model.Post
|
||||
if err := s.db.Select("likes_count").First(&post, postID).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return 0, common.ErrPostNotFound
|
||||
count, err := s.repo.GetPostLikesCount(postID)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("查询文章点赞数: %w", err)
|
||||
}
|
||||
return 0, fmt.Errorf("查询文章失败: %w", err)
|
||||
}
|
||||
return post.LikesCount, nil
|
||||
return count, nil
|
||||
}
|
||||
|
||||
@ -113,6 +113,8 @@ type EnergyStore interface {
|
||||
ListAllEnergyLogs(energyType string, offset, limit int) ([]model.EnergyLog, int64, error)
|
||||
// WithTx 基于给定事务连接创建新的 EnergyStore(确保事务内操作原子性)
|
||||
WithTx(tx *gorm.DB) EnergyStore
|
||||
// Transaction 在事务内执行业务逻辑,自动管理 WithTx 和 FundStore 的事务范围
|
||||
Transaction(fn func(txEnergy EnergyStore, txFund FundStore) error) error
|
||||
}
|
||||
|
||||
// energyStore 向后兼容别名
|
||||
@ -172,10 +174,13 @@ type ReactionStore interface {
|
||||
IncrPostLikes(postID uint, delta int) error
|
||||
IncrPostDislikes(postID uint, delta int) error
|
||||
GetPostAuthorID(postID uint) (uint, error)
|
||||
GetPostLikesCount(postID uint) (int, error)
|
||||
UpsertDailyLikeSummary(authorUID uint, date string, likerUID string) error
|
||||
GetUnnotifiedSummaries(userID uint) ([]model.DailyLikeSummary, error)
|
||||
MarkSummaryNotified(id uint) error
|
||||
WithTx(tx *gorm.DB) ReactionStore
|
||||
// Transaction 在事务内执行业务逻辑,自动管理 WithTx
|
||||
Transaction(fn func(tx ReactionStore) error) error
|
||||
}
|
||||
|
||||
// FollowStore FollowService 所需的最小仓储接口(ISP)
|
||||
@ -191,6 +196,8 @@ type FollowStore interface {
|
||||
IncrFollowingCount(userID uint, delta int) error
|
||||
GetFollowListPublic(userID uint) (bool, error)
|
||||
WithTx(tx *gorm.DB) FollowStore
|
||||
// Transaction 在事务内执行业务逻辑,自动管理 WithTx
|
||||
Transaction(fn func(tx FollowStore) error) error
|
||||
}
|
||||
|
||||
// TrendPoint 趋势数据点
|
||||
|
||||
Reference in New Issue
Block a user