owpengram-server/internal/app/groupcalls/service.go

121 lines
4.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Package groupcalls 实现超级群语音聊天group call的信令业务层
// ID/access_hash 分配与 store 编排。权限admin/成员资格)由 rpc 层校验,
// version 单调性与并发串行化由 store 层事务保证。
package groupcalls
import (
"context"
"crypto/rand"
"encoding/binary"
"fmt"
"telesrv/internal/domain"
"telesrv/internal/store"
)
// Service 是群通话业务服务。
type Service struct {
store store.GroupCallStore
}
// NewService 创建群通话服务。
func NewService(st store.GroupCallStore) *Service {
return &Service{store: st}
}
// Create 分配 id/access_hash 并建会。
func (s *Service) Create(ctx context.Context, channelID, creatorUserID int64, title string, now int) (domain.GroupCall, error) {
id, err := randomPositiveInt64()
if err != nil {
return domain.GroupCall{}, err
}
accessHash, err := randomPositiveInt64()
if err != nil {
return domain.GroupCall{}, err
}
return s.store.CreateGroupCall(ctx, domain.GroupCall{
ID: id,
AccessHash: accessHash,
ChannelID: channelID,
CreatorUserID: creatorUserID,
Title: title,
Version: 1,
CreatedAt: now,
})
}
func (s *Service) Get(ctx context.Context, callID int64) (domain.GroupCall, bool, error) {
return s.store.GetGroupCall(ctx, callID)
}
func (s *Service) Join(ctx context.Context, req domain.JoinGroupCallRequest) (domain.GroupCallMutation, error) {
return s.store.JoinGroupCall(ctx, req)
}
func (s *Service) Leave(ctx context.Context, callID, userID int64, now int) (domain.GroupCallMutation, error) {
return s.store.LeaveGroupCall(ctx, callID, userID, now)
}
func (s *Service) Discard(ctx context.Context, callID int64, now int) (domain.GroupCall, []domain.GroupCallParticipant, error) {
return s.store.DiscardGroupCall(ctx, callID, now)
}
func (s *Service) Touch(ctx context.Context, callID, userID int64, now int) ([]int64, bool, error) {
return s.store.TouchParticipant(ctx, callID, userID, now)
}
func (s *Service) Participant(ctx context.Context, callID, userID int64) (domain.GroupCallParticipant, bool, error) {
return s.store.GetParticipant(ctx, callID, userID)
}
func (s *Service) Participants(ctx context.Context, callID int64, offset string, limit int) (domain.GroupCallParticipantPage, error) {
return s.store.ListParticipants(ctx, callID, offset, limit)
}
func (s *Service) UpdateParticipant(ctx context.Context, callID, userID int64, update domain.GroupCallParticipantUpdate) (domain.GroupCallMutation, bool, error) {
return s.store.UpdateParticipant(ctx, callID, userID, update)
}
func (s *Service) SetTitle(ctx context.Context, callID int64, title string) (domain.GroupCall, bool, error) {
return s.store.SetGroupCallTitle(ctx, callID, title)
}
func (s *Service) SetJoinMuted(ctx context.Context, callID int64, joinMuted bool) (domain.GroupCall, bool, error) {
return s.store.SetGroupCallJoinMuted(ctx, callID, joinMuted)
}
func (s *Service) SetStartedMessageID(ctx context.Context, callID int64, msgID int) error {
return s.store.SetStartedMessageID(ctx, callID, msgID)
}
func (s *Service) SweepStale(ctx context.Context, checkOlderThan, now, limit int) ([]domain.GroupCallMutation, error) {
return s.store.SweepStaleParticipants(ctx, checkOlderThan, now, limit)
}
func (s *Service) ResetAllParticipants(ctx context.Context, now int) ([]domain.GroupCall, error) {
return s.store.ResetAllParticipants(ctx, now)
}
func (s *Service) NextRaiseHandRating(ctx context.Context, callID int64) (int64, error) {
return s.store.NextRaiseHandRating(ctx, callID)
}
func (s *Service) SetParticipantOverride(ctx context.Context, callID, setterUserID, targetUserID int64, override domain.GroupCallParticipantOverride, clear bool) error {
return s.store.SetParticipantOverride(ctx, callID, setterUserID, targetUserID, override, clear)
}
func (s *Service) ParticipantOverride(ctx context.Context, callID, setterUserID, targetUserID int64) (domain.GroupCallParticipantOverride, bool, error) {
return s.store.GetParticipantOverride(ctx, callID, setterUserID, targetUserID)
}
func randomPositiveInt64() (int64, error) {
var buf [8]byte
if _, err := rand.Read(buf[:]); err != nil {
return 0, fmt.Errorf("groupcalls: random id: %w", err)
}
v := int64(binary.BigEndian.Uint64(buf[:]) >> 1)
if v == 0 {
v = 1
}
return v, nil
}