Add HTTP /v1 MVC, TCP send path, groups with server-side member-avatar collage, object-storage upload, and friends/favorites around the architecture-v3 layout. Co-authored-by: Cursor <cursoragent@cursor.com>
152 lines
3.9 KiB
Go
152 lines
3.9 KiB
Go
package model
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"spark-server/internal/module/friend/entity"
|
|
"spark-server/internal/pkg/errs"
|
|
)
|
|
|
|
func (m *MemoryRepo) GetRemark(_ context.Context, userID, friendID int64) (string, error) {
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
return m.remarks[remarkKey{UserID: userID, FriendID: friendID}], nil
|
|
}
|
|
|
|
func (m *MemoryRepo) ListRemarks(_ context.Context, userID int64, friendIDs []int64) (map[int64]string, error) {
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
out := make(map[int64]string, len(friendIDs))
|
|
for _, id := range friendIDs {
|
|
if s := m.remarks[remarkKey{UserID: userID, FriendID: id}]; s != "" {
|
|
out[id] = s
|
|
}
|
|
}
|
|
return out, nil
|
|
}
|
|
|
|
func (m *MemoryRepo) SetRemark(_ context.Context, userID, friendID int64, remark string) error {
|
|
if userID <= 0 || friendID <= 0 {
|
|
return errs.ErrInvalidArgument
|
|
}
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
key := remarkKey{UserID: userID, FriendID: friendID}
|
|
if remark == "" {
|
|
delete(m.remarks, key)
|
|
return nil
|
|
}
|
|
m.remarks[key] = remark
|
|
return nil
|
|
}
|
|
|
|
func (m *MemoryRepo) IsBlocked(_ context.Context, userID, targetID int64) (bool, error) {
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
_, ok := m.blocks[blockKey{UserID: userID, BlockedID: targetID}]
|
|
return ok, nil
|
|
}
|
|
|
|
func (m *MemoryRepo) BlockedEither(_ context.Context, a, b int64) (bool, error) {
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
_, ab := m.blocks[blockKey{UserID: a, BlockedID: b}]
|
|
_, ba := m.blocks[blockKey{UserID: b, BlockedID: a}]
|
|
return ab || ba, nil
|
|
}
|
|
|
|
func (m *MemoryRepo) CreateBlock(_ context.Context, b *entity.Block) error {
|
|
if b == nil || b.UserID <= 0 || b.BlockedID <= 0 {
|
|
return errs.ErrInvalidArgument
|
|
}
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
now := b.CreatedAt
|
|
if now.IsZero() {
|
|
now = time.Now()
|
|
}
|
|
m.blocks[blockKey{UserID: b.UserID, BlockedID: b.BlockedID}] = now
|
|
delete(m.relations, pairOf(b.UserID, b.BlockedID))
|
|
delete(m.remarks, remarkKey{UserID: b.UserID, FriendID: b.BlockedID})
|
|
delete(m.remarks, remarkKey{UserID: b.BlockedID, FriendID: b.UserID})
|
|
m.rejectPendingLocked(b.UserID, b.BlockedID, now)
|
|
return nil
|
|
}
|
|
|
|
func (m *MemoryRepo) DeleteBlock(_ context.Context, userID, blockedID int64) error {
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
delete(m.blocks, blockKey{UserID: userID, BlockedID: blockedID})
|
|
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 in.Relation == nil {
|
|
return errs.ErrInvalidArgument
|
|
}
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
now := in.Relation.CreatedAt
|
|
if now.IsZero() {
|
|
now = time.Now()
|
|
in.Relation.CreatedAt = now
|
|
}
|
|
key := pairKey{Small: in.Relation.UserSmall, Big: in.Relation.UserBig}
|
|
if _, ok := m.relations[key]; !ok {
|
|
cp := *in.Relation
|
|
m.relations[key] = &cp
|
|
}
|
|
for _, id := range in.Requests {
|
|
if req := m.requests[id]; req != nil {
|
|
req.Status = entity.RequestAccepted
|
|
req.UpdatedAt = now
|
|
}
|
|
}
|
|
for i := range in.Remarks {
|
|
r := in.Remarks[i]
|
|
if r.Text == "" {
|
|
continue
|
|
}
|
|
m.remarks[remarkKey{UserID: r.UserID, FriendID: r.FriendID}] = r.Text
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (m *MemoryRepo) DeleteFriend(_ context.Context, a, b int64) error {
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
key := pairOf(a, b)
|
|
if _, ok := m.relations[key]; !ok {
|
|
return errs.ErrNotFound
|
|
}
|
|
delete(m.relations, key)
|
|
delete(m.remarks, remarkKey{UserID: a, FriendID: b})
|
|
delete(m.remarks, remarkKey{UserID: b, FriendID: a})
|
|
return nil
|
|
}
|
|
|
|
func (m *MemoryRepo) rejectPendingLocked(a, b int64, at time.Time) {
|
|
for _, req := range m.requests {
|
|
if req.Status != entity.RequestPending {
|
|
continue
|
|
}
|
|
pair := (req.FromUser == a && req.ToUser == b) || (req.FromUser == b && req.ToUser == a)
|
|
if pair {
|
|
req.Status = entity.RequestRejected
|
|
req.UpdatedAt = at
|
|
}
|
|
}
|
|
}
|