2026-05-16 08:12:42 +08:00

115 lines
3.1 KiB
Go

package roomclient
import (
"context"
"fmt"
"strings"
"time"
"hyapp-admin-server/internal/appctx"
roomv1 "hyapp.local/api/proto/room/v1"
"google.golang.org/grpc"
)
type Client interface {
CloseRoom(ctx context.Context, req CloseRoomRequest) (*CloseRoomResult, error)
ReopenRoom(ctx context.Context, req ReopenRoomRequest) (*CloseRoomResult, error)
}
type CloseRoomRequest struct {
RequestID string
RoomID string
ActorUserID int64
Reason string
}
type CloseRoomResult struct {
Applied bool
RoomVersion int64
ServerTimeMs int64
RoomStatus string
OnlineUserNum int
}
type ReopenRoomRequest struct {
RequestID string
RoomID string
ActorUserID int64
}
type GRPCClient struct {
client roomv1.RoomCommandServiceClient
}
func NewGRPC(conn grpc.ClientConnInterface) *GRPCClient {
return &GRPCClient{client: roomv1.NewRoomCommandServiceClient(conn)}
}
func (c *GRPCClient) CloseRoom(ctx context.Context, req CloseRoomRequest) (*CloseRoomResult, error) {
return c.setRoomLifecycle(ctx, req.RequestID, req.RoomID, req.ActorUserID, firstNonEmpty(req.Reason, "admin_closed"))
}
func (c *GRPCClient) ReopenRoom(ctx context.Context, req ReopenRoomRequest) (*CloseRoomResult, error) {
return c.setRoomLifecycle(ctx, req.RequestID, req.RoomID, req.ActorUserID, "admin_reopen")
}
func (c *GRPCClient) setRoomLifecycle(ctx context.Context, rawRequestID string, rawRoomID string, actorUserID int64, rawReason string) (*CloseRoomResult, error) {
if c == nil || c.client == nil {
return nil, fmt.Errorf("room service client is not configured")
}
roomID := strings.TrimSpace(rawRoomID)
reason := strings.TrimSpace(rawReason)
if roomID == "" || actorUserID <= 0 || reason == "" {
return nil, fmt.Errorf("room lifecycle request is incomplete")
}
requestID := strings.TrimSpace(rawRequestID)
if requestID == "" {
requestID = fmt.Sprintf("admin-room-lifecycle-%s-%d", roomID, time.Now().UnixMilli())
}
resp, err := c.client.CloseRoom(ctx, &roomv1.CloseRoomRequest{
Meta: &roomv1.RequestMeta{
RequestId: requestID,
CommandId: commandID(requestID, reason, roomID),
ActorUserId: actorUserID,
RoomId: roomID,
AppCode: appctx.FromContext(ctx),
SentAtMs: time.Now().UnixMilli(),
},
Reason: reason,
})
if err != nil {
return nil, err
}
result := resp.GetResult()
room := resp.GetRoom()
return &CloseRoomResult{
Applied: result.GetApplied(),
RoomVersion: result.GetRoomVersion(),
ServerTimeMs: result.GetServerTimeMs(),
RoomStatus: room.GetStatus(),
OnlineUserNum: len(room.GetOnlineUsers()),
}, nil
}
func commandID(requestID string, reason string, roomID string) string {
base := strings.TrimSpace(requestID)
if base == "" {
base = fmt.Sprintf("admin-room-lifecycle-%d", time.Now().UnixMilli())
}
value := base + ":" + strings.TrimSpace(reason) + ":" + strings.TrimSpace(roomID)
if len(value) <= 128 {
return value
}
return value[:128]
}
func firstNonEmpty(values ...string) string {
for _, value := range values {
if strings.TrimSpace(value) != "" {
return value
}
}
return ""
}