2026-05-12 19:34:47 +08:00

77 lines
2.0 KiB
Go

package service
import (
"context"
roomv1 "hyapp.local/api/proto/room/v1"
"hyapp/pkg/appcode"
"hyapp/pkg/roomid"
"hyapp/pkg/xerr"
)
const (
defaultRoomOnlineUsersPageSize = 50
maxRoomOnlineUsersPageSize = 100
)
// ListRoomOnlineUsers 分页读取房间在线用户列表。
// 该接口用于右上角在线人数弹窗,不能让客户端用完整 RoomSnapshot 做分页。
func (s *Service) ListRoomOnlineUsers(ctx context.Context, req *roomv1.ListRoomOnlineUsersRequest) (*roomv1.ListRoomOnlineUsersResponse, error) {
ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode())
roomID := req.GetRoomId()
viewerUserID := req.GetViewerUserId()
if !roomid.ValidStringID(roomID) {
return nil, xerr.New(xerr.InvalidArgument, "room_id is invalid")
}
if viewerUserID <= 0 {
return nil, xerr.New(xerr.InvalidArgument, "viewer_user_id is required")
}
presence, exists, err := s.repository.GetCurrentRoomPresence(ctx, viewerUserID)
if err != nil {
return nil, err
}
if !exists || presence.RoomID != roomID || presence.Status != roomPresenceStatusActive {
return nil, xerr.New(xerr.PermissionDenied, "viewer is not in room")
}
page := int(req.GetPage())
if page <= 0 {
page = 1
}
pageSize := int(req.GetPageSize())
if pageSize <= 0 {
pageSize = defaultRoomOnlineUsersPageSize
}
if pageSize > maxRoomOnlineUsersPageSize {
pageSize = maxRoomOnlineUsersPageSize
}
result, err := s.repository.ListRoomOnlineUsers(ctx, RoomOnlineUserQuery{
AppCode: appcode.FromContext(ctx),
RoomID: roomID,
Page: page,
PageSize: pageSize,
})
if err != nil {
return nil, err
}
users := make([]*roomv1.RoomUser, 0, len(result.Users))
for _, user := range result.Users {
users = append(users, &roomv1.RoomUser{
UserId: user.UserID,
Role: user.Role,
LastSeenAtMs: user.LastSeenAtMS,
})
}
return &roomv1.ListRoomOnlineUsersResponse{
Users: users,
Total: result.Total,
Page: int32(result.Page),
PageSize: int32(result.PageSize),
ServerTimeMs: s.clock.Now().UnixMilli(),
}, nil
}