支持 square/squarenovel/squaresteps/squarehealth 实例与 category 筛选;音乐增加免登录 grouped/track;订阅套餐按 package_name 区分;补 migration 0030/0031 与 OpenAPI。 Co-authored-by: Cursor <cursoragent@cursor.com>
101 lines
3.8 KiB
Go
101 lines
3.8 KiB
Go
package logic
|
|
|
|
import (
|
|
"context"
|
|
|
|
friendentity "spark-server/internal/module/friend/entity"
|
|
"spark-server/internal/module/square/entity"
|
|
userentity "spark-server/internal/module/user/entity"
|
|
"spark-server/internal/pkg/media"
|
|
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
// Repository persists square data. Model implements it.
|
|
type Repository interface {
|
|
CreatePost(ctx context.Context, post *entity.Post, audience []int64) error
|
|
CreateBotPost(ctx context.Context, post *entity.Post) error
|
|
GetPost(ctx context.Context, id int64) (*entity.Post, error)
|
|
ListPublicFeed(ctx context.Context, channel entity.Channel, q entity.FeedListQuery) ([]*entity.Post, error)
|
|
ListByAuthor(ctx context.Context, channel entity.Channel, authorID, cursor int64, limit int) ([]*entity.Post, error)
|
|
SoftDeletePost(ctx context.Context, userID, postID int64) (*entity.Post, error)
|
|
SoftDeleteExpiredBotPosts(ctx context.Context, nowMS int64, limit int) ([]*entity.Post, error)
|
|
ListAudience(ctx context.Context, postIDs []int64) (map[int64][]int64, error)
|
|
ListLikes(ctx context.Context, postIDs []int64) (map[int64][]*entity.Like, error)
|
|
AddLike(ctx context.Context, like *entity.Like) (created bool, err error)
|
|
RemoveLike(ctx context.Context, postID, userID int64) error
|
|
ListComments(ctx context.Context, postIDs []int64) (map[int64][]*entity.Comment, error)
|
|
GetComment(ctx context.Context, id int64) (*entity.Comment, error)
|
|
AddComment(ctx context.Context, c *entity.Comment) error
|
|
SoftDeleteComment(ctx context.Context, id int64) error
|
|
CreateNotices(ctx context.Context, rows []*entity.Notice) error
|
|
ListNotices(ctx context.Context, userID int64, channel entity.Channel, cursor int64, limit int) ([]*entity.Notice, error)
|
|
MarkNoticesRead(ctx context.Context, userID int64, channel entity.Channel, cursor int64) error
|
|
GetNoticeState(ctx context.Context, userID int64, channel entity.Channel) (*entity.NoticeState, error)
|
|
LatestNoticeID(ctx context.Context, userID int64, channel entity.Channel) (int64, error)
|
|
AdvanceNoticeRead(ctx context.Context, userID int64, channel entity.Channel, noticeID int64) error
|
|
ListAllByAuthor(ctx context.Context, authorID int64) ([]*entity.Post, error)
|
|
PurgeUser(ctx context.Context, userID int64) error
|
|
}
|
|
|
|
// Friends is the friend graph used for audience and block checks.
|
|
type Friends interface {
|
|
AreFriends(ctx context.Context, a, b int64) (bool, error)
|
|
ListBlockedPeerIDs(ctx context.Context, userID int64) ([]int64, error)
|
|
Relation(ctx context.Context, userID, peerID int64) (*friendentity.Relation, error)
|
|
BlockedEither(ctx context.Context, a, b int64) (bool, error)
|
|
}
|
|
|
|
// Users loads profile cards.
|
|
type Users interface {
|
|
Get(ctx context.Context, id int64) (*userentity.User, error)
|
|
}
|
|
|
|
// Objects deletes square media. Nil skips GC.
|
|
type Objects interface {
|
|
Delete(ctx context.Context, key string) error
|
|
}
|
|
|
|
// IDGen issues Snowflake ids.
|
|
type IDGen interface {
|
|
NextID() (int64, error)
|
|
}
|
|
|
|
// Service is the square use-case layer.
|
|
type Service struct {
|
|
repo Repository
|
|
friends Friends
|
|
users Users
|
|
objects Objects
|
|
ids IDGen
|
|
burst *burst
|
|
media media.Policy
|
|
log *zap.Logger
|
|
}
|
|
|
|
func NewService(repo Repository, friends Friends, users Users, objects Objects, ids IDGen) *Service {
|
|
return &Service{repo: repo, friends: friends, users: users, objects: objects, ids: ids, burst: newBurst(), log: zap.NewNop()}
|
|
}
|
|
|
|
// ConfigureMedia sets user-path media detection (bots compress via squarebot MediaCompressor).
|
|
func (s *Service) ConfigureMedia(p media.Policy, log *zap.Logger) {
|
|
if s == nil {
|
|
return
|
|
}
|
|
s.media = p
|
|
if log != nil {
|
|
s.log = log
|
|
}
|
|
}
|
|
|
|
func (s *Service) ready() bool {
|
|
return s != nil && s.repo != nil && s.friends != nil && s.users != nil && s.ids != nil
|
|
}
|
|
|
|
func normalizeChannel(ch entity.Channel) entity.Channel {
|
|
if ch == "" {
|
|
return entity.ChannelSquare
|
|
}
|
|
return ch
|
|
}
|