2026-05-29 11:59:57 +08:00

62 lines
2.0 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 service
import (
"context"
roomv1 "hyapp.local/api/proto/room/v1"
"hyapp/pkg/appcode"
"hyapp/pkg/roomid"
"hyapp/pkg/xerr"
"hyapp/services/room-service/internal/room/state"
)
// GetRoomSnapshot 返回房间页主动同步所需的完整 Room Cell 快照。
// 该查询只读,不刷新 presence、不写 command log也不隐式 JoinRoom。
func (s *Service) GetRoomSnapshot(ctx context.Context, req *roomv1.GetRoomSnapshotRequest) (*roomv1.GetRoomSnapshotResponse, error) {
ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode())
roomID := req.GetRoomId()
viewerUserID := req.GetViewerUserId()
if !roomid.ValidStringID(roomID) {
// 快照查询同样受腾讯 IM GroupID 和 RTC strRoomId 格式约束,避免脏 room_id 进入恢复路径。
return nil, xerr.New(xerr.InvalidArgument, "room_id is invalid")
}
if viewerUserID <= 0 {
// viewer_user_id 必须来自 gateway 鉴权room-service 不接受匿名读取完整 presence。
return nil, xerr.New(xerr.InvalidArgument, "viewer_user_id is required")
}
closed, err := s.isRoomClosed(ctx, roomID)
if err != nil {
return nil, err
}
if closed {
return nil, xerr.New(xerr.RoomClosed, "room closed")
}
snapshot, err := s.currentSnapshot(ctx, roomID)
if err != nil {
return nil, err
}
if snapshot == nil || snapshot.GetRoomId() == "" {
return nil, xerr.New(xerr.NotFound, "room not found")
}
if snapshot.GetStatus() != state.RoomStatusActive {
return nil, xerr.New(xerr.RoomClosed, "room closed")
}
if snapshotUserBanned(snapshot, viewerUserID, s.clock.Now().UnixMilli()) || findProtoUser(snapshot, viewerUserID) == nil {
// 完整快照包含在线用户、麦位和房管集合,必须要求 viewer 仍在业务 presence 内。
return nil, xerr.New(xerr.PermissionDenied, "viewer is not in room")
}
followed, err := s.repository.IsRoomFollowed(ctx, viewerUserID, roomID)
if err != nil {
return nil, err
}
return &roomv1.GetRoomSnapshotResponse{
Room: snapshot,
ServerTimeMs: s.clock.Now().UnixMilli(),
IsFollowed: followed,
}, nil
}