package model import ( "context" "time" "spark-server/internal/pkg/errs" ) type followKey struct { UserID int64 TargetID int64 } // UserFollow maps table t_user_follows (one directed follow per row). type UserFollow struct { ID int64 `gorm:"column:id;primaryKey;autoIncrement;comment:行 id,表内自增"` UserID int64 `gorm:"column:user_id;comment:关注人 user_id"` TargetID int64 `gorm:"column:target_id;comment:被关注人 user_id"` CreatedAt time.Time `gorm:"column:created_at;comment:关注时间"` } func (UserFollow) TableName() string { return "t_user_follows" } func (m *Repo) PutFollow(ctx context.Context, userID, targetID int64) error { if userID <= 0 || targetID <= 0 || userID == targetID { return errs.ErrInvalidArgument } db, err := m.session(ctx) if err != nil { return err } row := UserFollow{UserID: userID, TargetID: targetID, CreatedAt: time.Now()} err = db.Where("user_id = ? AND target_id = ?", userID, targetID). Attrs(row).FirstOrCreate(&row).Error return mapDBErr(err) } func (m *Repo) DeleteFollow(ctx context.Context, userID, targetID int64) error { if userID <= 0 || targetID <= 0 { return errs.ErrInvalidArgument } db, err := m.session(ctx) if err != nil { return err } err = db.Where("user_id = ? AND target_id = ?", userID, targetID).Delete(&UserFollow{}).Error return mapDBErr(err) } func (m *Repo) HasFollow(ctx context.Context, userID, targetID int64) (bool, error) { if userID <= 0 || targetID <= 0 { return false, nil } db, err := m.session(ctx) if err != nil { return false, err } var n int64 err = db.Model(&UserFollow{}).Where("user_id = ? AND target_id = ?", userID, targetID).Count(&n).Error if err != nil { return false, mapDBErr(err) } return n > 0, nil } func (m *MemoryRepo) PutFollow(_ context.Context, userID, targetID int64) error { if userID <= 0 || targetID <= 0 || userID == targetID { return errs.ErrInvalidArgument } m.mu.Lock() defer m.mu.Unlock() if m.follows == nil { m.follows = make(map[followKey]struct{}) } m.follows[followKey{UserID: userID, TargetID: targetID}] = struct{}{} return nil } func (m *MemoryRepo) DeleteFollow(_ context.Context, userID, targetID int64) error { if userID <= 0 || targetID <= 0 { return errs.ErrInvalidArgument } m.mu.Lock() defer m.mu.Unlock() delete(m.follows, followKey{UserID: userID, TargetID: targetID}) return nil } func (m *MemoryRepo) HasFollow(_ context.Context, userID, targetID int64) (bool, error) { if userID <= 0 || targetID <= 0 { return false, nil } m.mu.Lock() defer m.mu.Unlock() _, ok := m.follows[followKey{UserID: userID, TargetID: targetID}] return ok, nil }