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 }