对接
This commit is contained in:
@@ -2,6 +2,8 @@ package live
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -22,6 +24,7 @@ var (
|
||||
ErrCategoryDisabled = kratoserrors.BadRequest("LIVE_CATEGORY_DISABLED", "category is disabled")
|
||||
ErrRoomCategoryLocked = kratoserrors.BadRequest("LIVE_ROOM_CATEGORY_LOCKED", "live room category cannot be changed while broadcasting")
|
||||
ErrRoomInvalidArgument = kratoserrors.BadRequest("LIVE_ROOM_INVALID_ARGUMENT", "invalid live room data")
|
||||
ErrRoomNotLive = kratoserrors.BadRequest("LIVE_ROOM_NOT_LIVE", "live room is not broadcasting")
|
||||
ErrAnchorNotFound = kratoserrors.BadRequest("LIVE_ANCHOR_NOT_FOUND", "anchor user not found")
|
||||
)
|
||||
|
||||
@@ -37,23 +40,26 @@ type Category struct {
|
||||
}
|
||||
|
||||
type Room struct {
|
||||
ID uint
|
||||
Name string
|
||||
CategoryID uint
|
||||
CategoryName string
|
||||
CoverURL string
|
||||
Intro string
|
||||
Sort int
|
||||
AnchorUserID uint
|
||||
AnchorName string
|
||||
AnchorAvatar string
|
||||
StreamURL string
|
||||
ReplayURL string
|
||||
Enabled bool
|
||||
Status string
|
||||
ViewerCount int
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
ID uint
|
||||
Name string
|
||||
CategoryID uint
|
||||
CategoryName string
|
||||
CoverURL string
|
||||
Intro string
|
||||
Sort int
|
||||
AnchorUserID uint
|
||||
AnchorName string
|
||||
AnchorAvatar string
|
||||
StreamURL string
|
||||
ReplayURL string
|
||||
Enabled bool
|
||||
Status string
|
||||
ViewerCount int
|
||||
ViewerCountText string
|
||||
LikeCount int
|
||||
StartedAt *time.Time
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
||||
type CategoryFilter struct {
|
||||
@@ -62,12 +68,13 @@ type CategoryFilter struct {
|
||||
}
|
||||
|
||||
type RoomFilter struct {
|
||||
Name string
|
||||
AnchorName string
|
||||
CategoryID uint
|
||||
Status string
|
||||
Enabled *bool
|
||||
CreatedAt []time.Time
|
||||
Name string
|
||||
AnchorName string
|
||||
CategoryID uint
|
||||
Status string
|
||||
Enabled *bool
|
||||
CategoryEnabled *bool
|
||||
CreatedAt []time.Time
|
||||
}
|
||||
|
||||
type ListOptions struct {
|
||||
@@ -174,6 +181,17 @@ func (uc *RoomUsecase) listByRuntimeStatus(ctx context.Context, filter RoomFilte
|
||||
matched = append(matched, room)
|
||||
}
|
||||
}
|
||||
if strings.EqualFold(options.OrderBy, "viewer_count_asc") || strings.EqualFold(options.OrderBy, "viewer_count_desc") {
|
||||
sort.SliceStable(matched, func(i, j int) bool {
|
||||
if matched[i].ViewerCount == matched[j].ViewerCount {
|
||||
return matched[i].ID < matched[j].ID
|
||||
}
|
||||
if strings.EqualFold(options.OrderBy, "viewer_count_asc") {
|
||||
return matched[i].ViewerCount < matched[j].ViewerCount
|
||||
}
|
||||
return matched[i].ViewerCount > matched[j].ViewerCount
|
||||
})
|
||||
}
|
||||
total := int64(len(matched))
|
||||
if options.Offset >= len(matched) {
|
||||
return []*Room{}, total, nil
|
||||
@@ -196,6 +214,32 @@ func (uc *RoomUsecase) Get(ctx context.Context, id uint) (*Room, error) {
|
||||
return uc.attachRuntime(ctx, []*Room{room})[0], nil
|
||||
}
|
||||
|
||||
func (uc *RoomUsecase) GetPublic(ctx context.Context, id uint) (*Room, error) {
|
||||
room, err := uc.Get(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !room.Enabled || room.Status != RoomStatusLive {
|
||||
return nil, ErrRoomNotLive
|
||||
}
|
||||
category, err := uc.repo.GetCategory(ctx, room.CategoryID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !category.Enabled {
|
||||
return nil, ErrRoomNotLive
|
||||
}
|
||||
return room, nil
|
||||
}
|
||||
|
||||
func (uc *RoomUsecase) IsLive(ctx context.Context, id uint) (bool, error) {
|
||||
room, err := uc.Get(ctx, id)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return room.Enabled && room.Status == RoomStatusLive, nil
|
||||
}
|
||||
|
||||
func (uc *RoomUsecase) Create(ctx context.Context, room *Room) (*Room, error) {
|
||||
if err := validateRoom(room); err != nil {
|
||||
return nil, err
|
||||
@@ -258,17 +302,41 @@ func (uc *RoomUsecase) attachRuntime(ctx context.Context, rooms []*Room) []*Room
|
||||
for _, room := range rooms {
|
||||
if !room.Enabled {
|
||||
room.Status = RoomStatusDisabled
|
||||
room.ViewerCountText = formatViewerCount(room.ViewerCount)
|
||||
continue
|
||||
}
|
||||
room.Status = RoomStatusOffline
|
||||
if stream := byID[roomStreamID(room.ID)]; stream != nil && stream.PublisherOnline {
|
||||
room.Status = RoomStatusLive
|
||||
room.ViewerCount = stream.SubscriberCount
|
||||
room.LikeCount = stream.LikeCount
|
||||
if !stream.StartedAt.IsZero() {
|
||||
startedAt := stream.StartedAt
|
||||
room.StartedAt = &startedAt
|
||||
}
|
||||
}
|
||||
room.ViewerCountText = formatViewerCount(room.ViewerCount)
|
||||
}
|
||||
return rooms
|
||||
}
|
||||
|
||||
func formatViewerCount(value int) string {
|
||||
if value < 1000 {
|
||||
if value < 0 {
|
||||
value = 0
|
||||
}
|
||||
return formatUint(uint(value))
|
||||
}
|
||||
if value >= 10000 {
|
||||
return formatDecimal(float64(value)/10000, "w")
|
||||
}
|
||||
return formatDecimal(float64(value)/1000, "k")
|
||||
}
|
||||
|
||||
func formatDecimal(value float64, suffix string) string {
|
||||
return fmt.Sprintf("%.1f%s", value, suffix)
|
||||
}
|
||||
|
||||
func roomStreamID(id uint) string { return "room-" + formatUint(id) }
|
||||
|
||||
func formatUint(value uint) string {
|
||||
|
||||
Reference in New Issue
Block a user