spark-server/internal/module/friend/logic/service.go
2026-09-18 17:51:42 +08:00

75 lines
2.9 KiB
Go

package logic
import (
"context"
"spark-server/internal/module/friend/entity"
msgentity "spark-server/internal/module/message/entity"
userentity "spark-server/internal/module/user/entity"
)
// Repository is friend persistence. Model implements it; do not split this by table.
type Repository interface {
GetRelation(ctx context.Context, userID, friendID int64) (*entity.Relation, error)
ListFriends(ctx context.Context, userID int64, limit int) ([]*entity.Relation, error)
ListFriendIDs(ctx context.Context, userID int64) ([]int64, error)
ListBlockedPeerIDs(ctx context.Context, userID int64) ([]int64, error)
GetRequest(ctx context.Context, id int64) (*entity.Request, error)
GetRequestByPair(ctx context.Context, from, to int64) (*entity.Request, error)
UpsertRequest(ctx context.Context, req *entity.Request) error
ListIncoming(ctx context.Context, toUserID int64, status entity.RequestStatus, limit int) ([]*entity.Request, error)
SetRemark(ctx context.Context, userID, friendID int64, remark string) error
SetPinned(ctx context.Context, userID, friendID int64, pinned bool) error
SetBlocked(ctx context.Context, userID, friendID int64, blocked bool) error
IsBlocked(ctx context.Context, userID, targetID int64) (bool, error)
BlockedEither(ctx context.Context, a, b int64) (bool, error)
CreateReport(ctx context.Context, r *entity.Report) error
AcceptFriend(ctx context.Context, in entity.AcceptParams) error
DeleteFriend(ctx context.Context, a, b int64) error
}
// UserFinder resolves accounts by uid / email / spark_id / qrcode ticket.
type UserFinder interface {
Get(ctx context.Context, id int64) (*userentity.User, error)
GetByEmail(ctx context.Context, email string) (*userentity.User, error)
GetBySparkID(ctx context.Context, sparkID string) (*userentity.User, error)
GetByQRCode(ctx context.Context, qrcode string) (*userentity.User, error)
}
// IDGen issues Snowflake ids for requests, reports, and system messages.
type IDGen interface {
NextID() (int64, error)
}
// Greeter writes the "became friends" system message. Nil skips greeting.
type Greeter interface {
BecameFriends(ctx context.Context, userA, userB int64) error
}
// P2PChats opens (or reuses) the 1:1 conversation for a pair.
type P2PChats interface {
EnsureP2P(ctx context.Context, userA, userB int64) (int64, error)
UpdateLastMsg(ctx context.Context, conversationID, msgID, atMS int64) error
}
// Messages persists a row in messages.
type Messages interface {
Create(ctx context.Context, m *msgentity.Message) error
}
// Service is the friend use-case layer (HTTP and TCP share it).
type Service struct {
repo Repository
users UserFinder
ids IDGen
greeter Greeter
}
func NewService(repo Repository, users UserFinder, ids IDGen, greeter Greeter) *Service {
return &Service{repo: repo, users: users, ids: ids, greeter: greeter}
}
func (s *Service) ready() bool {
return s != nil && s.repo != nil && s.users != nil && s.ids != nil
}