package model import ( "context" "time" "spark-server/internal/module/friend/entity" "spark-server/internal/pkg/errs" ) func (m *MemoryRepo) SetRemark(_ context.Context, userID, friendID int64, remark string) error { return m.updateFriendEdge(userID, friendID, func(rel *entity.Relation) { rel.Remark = remark rel.UpdatedAt = time.Now() }) } func (m *MemoryRepo) SetPinned(_ context.Context, userID, friendID int64, pinned bool) error { return m.updateFriendEdge(userID, friendID, func(rel *entity.Relation) { rel.Pinned = pinned rel.UpdatedAt = time.Now() }) } func (m *MemoryRepo) updateFriendEdge(userID, friendID int64, fn func(*entity.Relation)) error { if userID <= 0 || friendID <= 0 { return errs.ErrInvalidArgument } m.mu.Lock() defer m.mu.Unlock() rel, ok := m.relations[edgeKey{UserID: userID, FriendID: friendID}] if !ok || rel.Status != entity.StatusFriend { return errs.ErrNotFound } fn(rel) return nil } func (m *MemoryRepo) IsBlocked(_ context.Context, userID, targetID int64) (bool, error) { m.mu.Lock() defer m.mu.Unlock() rel, ok := m.relations[edgeKey{UserID: userID, FriendID: targetID}] return ok && rel.Blocked, nil } func (m *MemoryRepo) BlockedEither(_ context.Context, a, b int64) (bool, error) { m.mu.Lock() defer m.mu.Unlock() ab := m.relations[edgeKey{UserID: a, FriendID: b}] ba := m.relations[edgeKey{UserID: b, FriendID: a}] return (ab != nil && ab.Blocked) || (ba != nil && ba.Blocked), nil } func (m *MemoryRepo) SetBlocked(_ context.Context, userID, friendID int64, blocked bool) error { if userID <= 0 || friendID <= 0 { return errs.ErrInvalidArgument } m.mu.Lock() defer m.mu.Unlock() now := time.Now() key := edgeKey{UserID: userID, FriendID: friendID} rel, ok := m.relations[key] if !ok { if !blocked { return nil } m.relations[key] = &entity.Relation{ UserID: userID, FriendID: friendID, Status: entity.StatusNone, Blocked: true, CreatedAt: now, UpdatedAt: now, } m.rejectPendingLocked(userID, friendID, now) return nil } rel.Blocked = blocked rel.UpdatedAt = now if blocked { m.rejectPendingLocked(userID, friendID, now) } return nil } func (m *MemoryRepo) CreateReport(_ context.Context, r *entity.Report) error { if r == nil || r.UserID <= 0 || r.TargetID <= 0 { return errs.ErrInvalidArgument } m.mu.Lock() defer m.mu.Unlock() cp := *r m.reports = append(m.reports, &cp) return nil } func (m *MemoryRepo) AcceptFriend(_ context.Context, in entity.AcceptParams) error { if len(in.Edges) == 0 { return errs.ErrInvalidArgument } m.mu.Lock() defer m.mu.Unlock() now := time.Now() for _, e := range in.Edges { if e == nil || e.UserID <= 0 || e.FriendID <= 0 { return errs.ErrInvalidArgument } if e.CreatedAt.IsZero() { e.CreatedAt = now } if e.UpdatedAt.IsZero() { e.UpdatedAt = e.CreatedAt } key := edgeKey{UserID: e.UserID, FriendID: e.FriendID} if cur, ok := m.relations[key]; ok { cur.Status = entity.StatusFriend cur.UpdatedAt = e.UpdatedAt if e.Remark != "" { cur.Remark = e.Remark } if e.Source != 0 { cur.Source = e.Source } continue } cp := *e m.relations[key] = &cp } for _, id := range in.Requests { if req := m.requests[id]; req != nil { req.Status = entity.RequestAccepted req.UpdatedAt = now } } return nil } func (m *MemoryRepo) DeleteFriend(_ context.Context, a, b int64) error { m.mu.Lock() defer m.mu.Unlock() _, ab := m.relations[edgeKey{UserID: a, FriendID: b}] _, ba := m.relations[edgeKey{UserID: b, FriendID: a}] if !ab && !ba { return errs.ErrNotFound } delete(m.relations, edgeKey{UserID: a, FriendID: b}) delete(m.relations, edgeKey{UserID: b, FriendID: a}) return nil }