package notification import ( "context" "gorm.io/gorm" "gorm.io/gorm/clause" "github.com/break/junhong_cmp_fiber/internal/model" "github.com/break/junhong_cmp_fiber/pkg/constants" ) // Repository 提供站内通知幂等写入能力。 type Repository struct { db *gorm.DB } // NewRepository 创建站内通知持久化 Adapter。 func NewRepository(db *gorm.DB) *Repository { return &Repository{db: db} } // DB 返回通知 Repository 使用的数据库连接。 func (r *Repository) DB() *gorm.DB { return r.db } // WithTx 返回绑定指定事务的通知 Repository。 func (r *Repository) WithTx(tx *gorm.DB) *Repository { return &Repository{db: tx} } // CreateIdempotent 以事件、接收人类型和接收人 ID 唯一键幂等写入通知。 func (r *Repository) CreateIdempotent(ctx context.Context, notification *model.Notification) (bool, error) { result := r.db.WithContext(ctx).Clauses(clause.OnConflict{ Columns: []clause.Column{{Name: "event_id"}, {Name: "recipient_kind"}, {Name: "recipient_id"}}, DoNothing: true, }).Create(notification) return result.RowsAffected == 1, result.Error } // FindByEventRecipient 按事件键与接收人回查既有通知,用于幂等冲突时返回既有行而不是重复投放。 func (r *Repository) FindByEventRecipient(ctx context.Context, eventID, recipientKind string, recipientID uint) (*model.Notification, error) { var notification model.Notification if err := r.db.WithContext(ctx). Where("event_id = ? AND recipient_kind = ? AND recipient_id = ?", eventID, recipientKind, recipientID). Take(¬ification).Error; err != nil { return nil, err } return ¬ification, nil } // IsActiveAccount 判断明确后台账号是否仍启用且未软删除。 func (r *Repository) IsActiveAccount(ctx context.Context, accountID uint) (bool, error) { var count int64 err := r.db.WithContext(ctx).Model(&model.Account{}). Where("id = ? AND status = ?", accountID, constants.StatusEnabled). Count(&count).Error return count == 1, err } // IsActivePersonalCustomer 判断明确个人客户是否仍启用且未软删除。 func (r *Repository) IsActivePersonalCustomer(ctx context.Context, customerID uint) (bool, error) { var count int64 err := r.db.WithContext(ctx).Model(&model.PersonalCustomer{}). Where("id = ? AND status = ?", customerID, constants.StatusEnabled). Count(&count).Error return count == 1, err }