房间机器人
This commit is contained in:
parent
72e1fb920d
commit
f465c12d39
@ -13,6 +13,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Client interface {
|
type Client interface {
|
||||||
|
ListGameRobots(ctx context.Context, req ListGameRobotsRequest) (ListGameRobotsResult, error)
|
||||||
ListRoomRobots(ctx context.Context, req ListRoomRobotsRequest) (ListRoomRobotsResult, error)
|
ListRoomRobots(ctx context.Context, req ListRoomRobotsRequest) (ListRoomRobotsResult, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,32 +34,60 @@ type ListRoomRobotsRequest struct {
|
|||||||
Cursor string
|
Cursor string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ListGameRobotsRequest struct {
|
||||||
|
GameID string
|
||||||
|
Status string
|
||||||
|
PageSize int32
|
||||||
|
Cursor string
|
||||||
|
}
|
||||||
|
|
||||||
type ListRoomRobotsResult struct {
|
type ListRoomRobotsResult struct {
|
||||||
Robots []Robot
|
Robots []Robot
|
||||||
NextCursor string
|
NextCursor string
|
||||||
ServerTimeMS int64
|
ServerTimeMS int64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ListGameRobotsResult struct {
|
||||||
|
Robots []Robot
|
||||||
|
NextCursor string
|
||||||
|
ServerTimeMS int64
|
||||||
|
}
|
||||||
|
|
||||||
type GRPCClient struct {
|
type GRPCClient struct {
|
||||||
client robotv1.RoomRobotServiceClient
|
gameClient robotv1.GameRobotServiceClient
|
||||||
|
roomClient robotv1.RoomRobotServiceClient
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGRPC(conn grpc.ClientConnInterface) *GRPCClient {
|
func NewGRPC(conn grpc.ClientConnInterface) *GRPCClient {
|
||||||
return &GRPCClient{client: robotv1.NewRoomRobotServiceClient(conn)}
|
return &GRPCClient{
|
||||||
|
gameClient: robotv1.NewGameRobotServiceClient(conn),
|
||||||
|
roomClient: robotv1.NewRoomRobotServiceClient(conn),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *GRPCClient) ListGameRobots(ctx context.Context, req ListGameRobotsRequest) (ListGameRobotsResult, error) {
|
||||||
|
if c == nil || c.gameClient == nil {
|
||||||
|
return ListGameRobotsResult{}, fmt.Errorf("game robot service client is not configured")
|
||||||
|
}
|
||||||
|
resp, err := c.gameClient.ListGameRobots(ctx, &robotv1.ListGameRobotsRequest{
|
||||||
|
Meta: requestMeta(ctx, "admin-game-robots"),
|
||||||
|
GameId: strings.TrimSpace(req.GameID),
|
||||||
|
Status: strings.TrimSpace(req.Status),
|
||||||
|
PageSize: req.PageSize,
|
||||||
|
Cursor: strings.TrimSpace(req.Cursor),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return ListGameRobotsResult{}, err
|
||||||
|
}
|
||||||
|
return ListGameRobotsResult{Robots: robotsFromProto(resp.GetRobots()), NextCursor: resp.GetNextCursor(), ServerTimeMS: resp.GetServerTimeMs()}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GRPCClient) ListRoomRobots(ctx context.Context, req ListRoomRobotsRequest) (ListRoomRobotsResult, error) {
|
func (c *GRPCClient) ListRoomRobots(ctx context.Context, req ListRoomRobotsRequest) (ListRoomRobotsResult, error) {
|
||||||
if c == nil || c.client == nil {
|
if c == nil || c.roomClient == nil {
|
||||||
return ListRoomRobotsResult{}, fmt.Errorf("robot service client is not configured")
|
return ListRoomRobotsResult{}, fmt.Errorf("robot service client is not configured")
|
||||||
}
|
}
|
||||||
resp, err := c.client.ListRoomRobots(ctx, &robotv1.ListRoomRobotsRequest{
|
resp, err := c.roomClient.ListRoomRobots(ctx, &robotv1.ListRoomRobotsRequest{
|
||||||
Meta: &robotv1.RequestMeta{
|
Meta: requestMeta(ctx, "admin-room-robots"),
|
||||||
RequestId: fmt.Sprintf("admin-room-robots-%d", time.Now().UnixMilli()),
|
|
||||||
Caller: "admin-server",
|
|
||||||
AppCode: appctx.FromContext(ctx),
|
|
||||||
SentAtMs: time.Now().UnixMilli(),
|
|
||||||
ActorUserId: 0,
|
|
||||||
},
|
|
||||||
RoomScene: strings.TrimSpace(req.RoomScene),
|
RoomScene: strings.TrimSpace(req.RoomScene),
|
||||||
Status: strings.TrimSpace(req.Status),
|
Status: strings.TrimSpace(req.Status),
|
||||||
PageSize: req.PageSize,
|
PageSize: req.PageSize,
|
||||||
@ -67,8 +96,22 @@ func (c *GRPCClient) ListRoomRobots(ctx context.Context, req ListRoomRobotsReque
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return ListRoomRobotsResult{}, err
|
return ListRoomRobotsResult{}, err
|
||||||
}
|
}
|
||||||
items := make([]Robot, 0, len(resp.GetRobots()))
|
return ListRoomRobotsResult{Robots: robotsFromProto(resp.GetRobots()), NextCursor: resp.GetNextCursor(), ServerTimeMS: resp.GetServerTimeMs()}, nil
|
||||||
for _, item := range resp.GetRobots() {
|
}
|
||||||
|
|
||||||
|
func requestMeta(ctx context.Context, prefix string) *robotv1.RequestMeta {
|
||||||
|
return &robotv1.RequestMeta{
|
||||||
|
RequestId: fmt.Sprintf("%s-%d", prefix, time.Now().UnixMilli()),
|
||||||
|
Caller: "admin-server",
|
||||||
|
AppCode: appctx.FromContext(ctx),
|
||||||
|
SentAtMs: time.Now().UnixMilli(),
|
||||||
|
ActorUserId: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func robotsFromProto(source []*robotv1.Robot) []Robot {
|
||||||
|
items := make([]Robot, 0, len(source))
|
||||||
|
for _, item := range source {
|
||||||
items = append(items, Robot{
|
items = append(items, Robot{
|
||||||
UserID: item.GetUserId(),
|
UserID: item.GetUserId(),
|
||||||
Status: item.GetStatus(),
|
Status: item.GetStatus(),
|
||||||
@ -79,5 +122,5 @@ func (c *GRPCClient) ListRoomRobots(ctx context.Context, req ListRoomRobotsReque
|
|||||||
UsedCount: item.GetUsedCount(),
|
UsedCount: item.GetUsedCount(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return ListRoomRobotsResult{Robots: items, NextCursor: resp.GetNextCursor(), ServerTimeMS: resp.GetServerTimeMs()}, nil
|
return items
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,8 +11,6 @@ import (
|
|||||||
"hyapp-admin-server/internal/modules/shared"
|
"hyapp-admin-server/internal/modules/shared"
|
||||||
)
|
)
|
||||||
|
|
||||||
const defaultRoomRobotScene = "voice"
|
|
||||||
|
|
||||||
type RobotRoom struct {
|
type RobotRoom struct {
|
||||||
AppCode string `json:"appCode"`
|
AppCode string `json:"appCode"`
|
||||||
RoomID string `json:"roomId"`
|
RoomID string `json:"roomId"`
|
||||||
@ -89,10 +87,9 @@ func (s *Service) ListAvailableRoomRobots(ctx context.Context) ([]AvailableRoomR
|
|||||||
if s.robotClient == nil || s.roomClient == nil {
|
if s.robotClient == nil || s.roomClient == nil {
|
||||||
return nil, fmt.Errorf("robot or room service client is not configured")
|
return nil, fmt.Errorf("robot or room service client is not configured")
|
||||||
}
|
}
|
||||||
result, err := s.robotClient.ListRoomRobots(ctx, robotclient.ListRoomRobotsRequest{
|
result, err := s.robotClient.ListGameRobots(ctx, robotclient.ListGameRobotsRequest{
|
||||||
RoomScene: defaultRoomRobotScene,
|
Status: "active",
|
||||||
Status: "active",
|
PageSize: 200,
|
||||||
PageSize: 200,
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -103,20 +100,26 @@ func (s *Service) ListAvailableRoomRobots(ctx context.Context) ([]AvailableRoomR
|
|||||||
userIDs = append(userIDs, item.UserID)
|
userIDs = append(userIDs, item.UserID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 全站机器人是后台统一维护的机器人账号池;房间机器人下拉只把这批账号交给 room-service 做占用过滤,
|
||||||
|
// 避免新增了全站机器人却因为旧的 room-scene 专用池为空而无法选择房主机器人。
|
||||||
available, err := s.roomClient.FilterAvailableRoomRobots(ctx, userIDs)
|
available, err := s.roomClient.FilterAvailableRoomRobots(ctx, userIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
allowed := make(map[int64]bool, len(available.AvailableUserIDs))
|
|
||||||
for _, userID := range available.AvailableUserIDs {
|
|
||||||
allowed[userID] = true
|
|
||||||
}
|
|
||||||
owners, err := s.queryRoomOwners(ctx, available.AvailableUserIDs)
|
owners, err := s.queryRoomOwners(ctx, available.AvailableUserIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
items := make([]AvailableRoomRobot, 0, len(available.AvailableUserIDs))
|
return availableRoomRobotsFromGamePool(result.Robots, available.AvailableUserIDs, owners), nil
|
||||||
for _, robot := range result.Robots {
|
}
|
||||||
|
|
||||||
|
func availableRoomRobotsFromGamePool(robots []robotclient.Robot, availableUserIDs []int64, owners map[int64]RoomOwner) []AvailableRoomRobot {
|
||||||
|
allowed := make(map[int64]bool, len(availableUserIDs))
|
||||||
|
for _, userID := range availableUserIDs {
|
||||||
|
allowed[userID] = true
|
||||||
|
}
|
||||||
|
items := make([]AvailableRoomRobot, 0, len(availableUserIDs))
|
||||||
|
for _, robot := range robots {
|
||||||
if !allowed[robot.UserID] {
|
if !allowed[robot.UserID] {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -129,7 +132,7 @@ func (s *Service) ListAvailableRoomRobots(ctx context.Context) ([]AvailableRoomR
|
|||||||
User: owners[robot.UserID],
|
User: owners[robot.UserID],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return items, nil
|
return items
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) CreateRobotRoom(ctx context.Context, req createRobotRoomRequest, actor shared.Actor) (RobotRoom, error) {
|
func (s *Service) CreateRobotRoom(ctx context.Context, req createRobotRoomRequest, actor shared.Actor) (RobotRoom, error) {
|
||||||
|
|||||||
@ -3,6 +3,8 @@ package roomadmin
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"hyapp-admin-server/internal/integration/robotclient"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNormalizeRoomListSortKeepsOnlyContributionSort(t *testing.T) {
|
func TestNormalizeRoomListSortKeepsOnlyContributionSort(t *testing.T) {
|
||||||
@ -74,3 +76,26 @@ func TestRobotRoomProfileFromOwnerRequiresNameAndAvatar(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAvailableRoomRobotsFromGamePoolKeepsOnlyRoomAvailableUsers(t *testing.T) {
|
||||||
|
robots := []robotclient.Robot{
|
||||||
|
{UserID: 101, Status: "active", LastUsedAtMS: 1000, UsedCount: 2},
|
||||||
|
{UserID: 102, Status: "active", LastUsedAtMS: 2000, UsedCount: 3},
|
||||||
|
{UserID: 103, Status: "active", LastUsedAtMS: 3000, UsedCount: 4},
|
||||||
|
}
|
||||||
|
owners := map[int64]RoomOwner{
|
||||||
|
101: {UserID: "101", Username: "Robot A"},
|
||||||
|
103: {UserID: "103", Username: "Robot C"},
|
||||||
|
}
|
||||||
|
|
||||||
|
items := availableRoomRobotsFromGamePool(robots, []int64{103, 101}, owners)
|
||||||
|
if len(items) != 2 {
|
||||||
|
t.Fatalf("available robots length mismatch: got %d want 2", len(items))
|
||||||
|
}
|
||||||
|
if items[0].UserID != "101" || items[0].User.Username != "Robot A" || items[0].UsedCount != 2 {
|
||||||
|
t.Fatalf("first available robot mismatch: %+v", items[0])
|
||||||
|
}
|
||||||
|
if items[1].UserID != "103" || items[1].User.Username != "Robot C" || items[1].LastUsedAtMS != 3000 {
|
||||||
|
t.Fatalf("second available robot mismatch: %+v", items[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user