兼容百顺游戏

This commit is contained in:
zhx 2026-05-23 15:12:17 +08:00
parent d1a7facf10
commit 17d777610c
15 changed files with 321 additions and 36 deletions

View File

@ -1669,6 +1669,102 @@ func (x *SetGameStatusRequest) GetStatus() string {
return "" return ""
} }
type DeleteCatalogRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
Meta *RequestMeta `protobuf:"bytes,1,opt,name=meta,proto3" json:"meta,omitempty"`
GameId string `protobuf:"bytes,2,opt,name=game_id,json=gameId,proto3" json:"game_id,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *DeleteCatalogRequest) Reset() {
*x = DeleteCatalogRequest{}
mi := &file_proto_game_v1_game_proto_msgTypes[21]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *DeleteCatalogRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*DeleteCatalogRequest) ProtoMessage() {}
func (x *DeleteCatalogRequest) ProtoReflect() protoreflect.Message {
mi := &file_proto_game_v1_game_proto_msgTypes[21]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use DeleteCatalogRequest.ProtoReflect.Descriptor instead.
func (*DeleteCatalogRequest) Descriptor() ([]byte, []int) {
return file_proto_game_v1_game_proto_rawDescGZIP(), []int{21}
}
func (x *DeleteCatalogRequest) GetMeta() *RequestMeta {
if x != nil {
return x.Meta
}
return nil
}
func (x *DeleteCatalogRequest) GetGameId() string {
if x != nil {
return x.GameId
}
return ""
}
type DeleteCatalogResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
ServerTimeMs int64 `protobuf:"varint,1,opt,name=server_time_ms,json=serverTimeMs,proto3" json:"server_time_ms,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *DeleteCatalogResponse) Reset() {
*x = DeleteCatalogResponse{}
mi := &file_proto_game_v1_game_proto_msgTypes[22]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *DeleteCatalogResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*DeleteCatalogResponse) ProtoMessage() {}
func (x *DeleteCatalogResponse) ProtoReflect() protoreflect.Message {
mi := &file_proto_game_v1_game_proto_msgTypes[22]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use DeleteCatalogResponse.ProtoReflect.Descriptor instead.
func (*DeleteCatalogResponse) Descriptor() ([]byte, []int) {
return file_proto_game_v1_game_proto_rawDescGZIP(), []int{22}
}
func (x *DeleteCatalogResponse) GetServerTimeMs() int64 {
if x != nil {
return x.ServerTimeMs
}
return 0
}
var File_proto_game_v1_game_proto protoreflect.FileDescriptor var File_proto_game_v1_game_proto protoreflect.FileDescriptor
const file_proto_game_v1_game_proto_rawDesc = "" + const file_proto_game_v1_game_proto_rawDesc = "" +
@ -1828,7 +1924,12 @@ const file_proto_game_v1_game_proto_rawDesc = "" +
"\x14SetGameStatusRequest\x12.\n" + "\x14SetGameStatusRequest\x12.\n" +
"\x04meta\x18\x01 \x01(\v2\x1a.hyapp.game.v1.RequestMetaR\x04meta\x12\x17\n" + "\x04meta\x18\x01 \x01(\v2\x1a.hyapp.game.v1.RequestMetaR\x04meta\x12\x17\n" +
"\agame_id\x18\x02 \x01(\tR\x06gameId\x12\x16\n" + "\agame_id\x18\x02 \x01(\tR\x06gameId\x12\x16\n" +
"\x06status\x18\x03 \x01(\tR\x06status2\xb3\x01\n" + "\x06status\x18\x03 \x01(\tR\x06status\"_\n" +
"\x14DeleteCatalogRequest\x12.\n" +
"\x04meta\x18\x01 \x01(\v2\x1a.hyapp.game.v1.RequestMetaR\x04meta\x12\x17\n" +
"\agame_id\x18\x02 \x01(\tR\x06gameId\"=\n" +
"\x15DeleteCatalogResponse\x12$\n" +
"\x0eserver_time_ms\x18\x01 \x01(\x03R\fserverTimeMs2\xb3\x01\n" +
"\x0eGameAppService\x12N\n" + "\x0eGameAppService\x12N\n" +
"\tListGames\x12\x1f.hyapp.game.v1.ListGamesRequest\x1a .hyapp.game.v1.ListGamesResponse\x12Q\n" + "\tListGames\x12\x1f.hyapp.game.v1.ListGamesRequest\x1a .hyapp.game.v1.ListGamesResponse\x12Q\n" +
"\n" + "\n" +
@ -1836,13 +1937,14 @@ const file_proto_game_v1_game_proto_rawDesc = "" +
"\x13GameCallbackService\x12Q\n" + "\x13GameCallbackService\x12Q\n" +
"\x0eHandleCallback\x12\x1e.hyapp.game.v1.CallbackRequest\x1a\x1f.hyapp.game.v1.CallbackResponse2t\n" + "\x0eHandleCallback\x12\x1e.hyapp.game.v1.CallbackRequest\x1a\x1f.hyapp.game.v1.CallbackResponse2t\n" +
"\x0fGameCronService\x12a\n" + "\x0fGameCronService\x12a\n" +
"\x1cProcessLevelEventOutboxBatch\x12\x1f.hyapp.game.v1.CronBatchRequest\x1a .hyapp.game.v1.CronBatchResponse2\xc9\x03\n" + "\x1cProcessLevelEventOutboxBatch\x12\x1f.hyapp.game.v1.CronBatchRequest\x1a .hyapp.game.v1.CronBatchResponse2\xa5\x04\n" +
"\x10GameAdminService\x12Z\n" + "\x10GameAdminService\x12Z\n" +
"\rListPlatforms\x12#.hyapp.game.v1.ListPlatformsRequest\x1a$.hyapp.game.v1.ListPlatformsResponse\x12W\n" + "\rListPlatforms\x12#.hyapp.game.v1.ListPlatformsRequest\x1a$.hyapp.game.v1.ListPlatformsResponse\x12W\n" +
"\x0eUpsertPlatform\x12$.hyapp.game.v1.UpsertPlatformRequest\x1a\x1f.hyapp.game.v1.PlatformResponse\x12T\n" + "\x0eUpsertPlatform\x12$.hyapp.game.v1.UpsertPlatformRequest\x1a\x1f.hyapp.game.v1.PlatformResponse\x12T\n" +
"\vListCatalog\x12!.hyapp.game.v1.ListCatalogRequest\x1a\".hyapp.game.v1.ListCatalogResponse\x12T\n" + "\vListCatalog\x12!.hyapp.game.v1.ListCatalogRequest\x1a\".hyapp.game.v1.ListCatalogResponse\x12T\n" +
"\rUpsertCatalog\x12#.hyapp.game.v1.UpsertCatalogRequest\x1a\x1e.hyapp.game.v1.CatalogResponse\x12T\n" + "\rUpsertCatalog\x12#.hyapp.game.v1.UpsertCatalogRequest\x1a\x1e.hyapp.game.v1.CatalogResponse\x12T\n" +
"\rSetGameStatus\x12#.hyapp.game.v1.SetGameStatusRequest\x1a\x1e.hyapp.game.v1.CatalogResponseB&Z$hyapp.local/api/proto/game/v1;gamev1b\x06proto3" "\rSetGameStatus\x12#.hyapp.game.v1.SetGameStatusRequest\x1a\x1e.hyapp.game.v1.CatalogResponse\x12Z\n" +
"\rDeleteCatalog\x12#.hyapp.game.v1.DeleteCatalogRequest\x1a$.hyapp.game.v1.DeleteCatalogResponseB&Z$hyapp.local/api/proto/game/v1;gamev1b\x06proto3"
var ( var (
file_proto_game_v1_game_proto_rawDescOnce sync.Once file_proto_game_v1_game_proto_rawDescOnce sync.Once
@ -1856,7 +1958,7 @@ func file_proto_game_v1_game_proto_rawDescGZIP() []byte {
return file_proto_game_v1_game_proto_rawDescData return file_proto_game_v1_game_proto_rawDescData
} }
var file_proto_game_v1_game_proto_msgTypes = make([]protoimpl.MessageInfo, 23) var file_proto_game_v1_game_proto_msgTypes = make([]protoimpl.MessageInfo, 25)
var file_proto_game_v1_game_proto_goTypes = []any{ var file_proto_game_v1_game_proto_goTypes = []any{
(*RequestMeta)(nil), // 0: hyapp.game.v1.RequestMeta (*RequestMeta)(nil), // 0: hyapp.game.v1.RequestMeta
(*GamePlatform)(nil), // 1: hyapp.game.v1.GamePlatform (*GamePlatform)(nil), // 1: hyapp.game.v1.GamePlatform
@ -1879,16 +1981,18 @@ var file_proto_game_v1_game_proto_goTypes = []any{
(*UpsertCatalogRequest)(nil), // 18: hyapp.game.v1.UpsertCatalogRequest (*UpsertCatalogRequest)(nil), // 18: hyapp.game.v1.UpsertCatalogRequest
(*CatalogResponse)(nil), // 19: hyapp.game.v1.CatalogResponse (*CatalogResponse)(nil), // 19: hyapp.game.v1.CatalogResponse
(*SetGameStatusRequest)(nil), // 20: hyapp.game.v1.SetGameStatusRequest (*SetGameStatusRequest)(nil), // 20: hyapp.game.v1.SetGameStatusRequest
nil, // 21: hyapp.game.v1.CallbackRequest.HeadersEntry (*DeleteCatalogRequest)(nil), // 21: hyapp.game.v1.DeleteCatalogRequest
nil, // 22: hyapp.game.v1.CallbackRequest.QueryEntry (*DeleteCatalogResponse)(nil), // 22: hyapp.game.v1.DeleteCatalogResponse
nil, // 23: hyapp.game.v1.CallbackRequest.HeadersEntry
nil, // 24: hyapp.game.v1.CallbackRequest.QueryEntry
} }
var file_proto_game_v1_game_proto_depIdxs = []int32{ var file_proto_game_v1_game_proto_depIdxs = []int32{
0, // 0: hyapp.game.v1.ListGamesRequest.meta:type_name -> hyapp.game.v1.RequestMeta 0, // 0: hyapp.game.v1.ListGamesRequest.meta:type_name -> hyapp.game.v1.RequestMeta
3, // 1: hyapp.game.v1.ListGamesResponse.games:type_name -> hyapp.game.v1.AppGame 3, // 1: hyapp.game.v1.ListGamesResponse.games:type_name -> hyapp.game.v1.AppGame
0, // 2: hyapp.game.v1.LaunchGameRequest.meta:type_name -> hyapp.game.v1.RequestMeta 0, // 2: hyapp.game.v1.LaunchGameRequest.meta:type_name -> hyapp.game.v1.RequestMeta
0, // 3: hyapp.game.v1.CallbackRequest.meta:type_name -> hyapp.game.v1.RequestMeta 0, // 3: hyapp.game.v1.CallbackRequest.meta:type_name -> hyapp.game.v1.RequestMeta
21, // 4: hyapp.game.v1.CallbackRequest.headers:type_name -> hyapp.game.v1.CallbackRequest.HeadersEntry 23, // 4: hyapp.game.v1.CallbackRequest.headers:type_name -> hyapp.game.v1.CallbackRequest.HeadersEntry
22, // 5: hyapp.game.v1.CallbackRequest.query:type_name -> hyapp.game.v1.CallbackRequest.QueryEntry 24, // 5: hyapp.game.v1.CallbackRequest.query:type_name -> hyapp.game.v1.CallbackRequest.QueryEntry
0, // 6: hyapp.game.v1.CronBatchRequest.meta:type_name -> hyapp.game.v1.RequestMeta 0, // 6: hyapp.game.v1.CronBatchRequest.meta:type_name -> hyapp.game.v1.RequestMeta
0, // 7: hyapp.game.v1.ListPlatformsRequest.meta:type_name -> hyapp.game.v1.RequestMeta 0, // 7: hyapp.game.v1.ListPlatformsRequest.meta:type_name -> hyapp.game.v1.RequestMeta
1, // 8: hyapp.game.v1.ListPlatformsResponse.platforms:type_name -> hyapp.game.v1.GamePlatform 1, // 8: hyapp.game.v1.ListPlatformsResponse.platforms:type_name -> hyapp.game.v1.GamePlatform
@ -1901,29 +2005,32 @@ var file_proto_game_v1_game_proto_depIdxs = []int32{
2, // 15: hyapp.game.v1.UpsertCatalogRequest.game:type_name -> hyapp.game.v1.GameCatalogItem 2, // 15: hyapp.game.v1.UpsertCatalogRequest.game:type_name -> hyapp.game.v1.GameCatalogItem
2, // 16: hyapp.game.v1.CatalogResponse.game:type_name -> hyapp.game.v1.GameCatalogItem 2, // 16: hyapp.game.v1.CatalogResponse.game:type_name -> hyapp.game.v1.GameCatalogItem
0, // 17: hyapp.game.v1.SetGameStatusRequest.meta:type_name -> hyapp.game.v1.RequestMeta 0, // 17: hyapp.game.v1.SetGameStatusRequest.meta:type_name -> hyapp.game.v1.RequestMeta
4, // 18: hyapp.game.v1.GameAppService.ListGames:input_type -> hyapp.game.v1.ListGamesRequest 0, // 18: hyapp.game.v1.DeleteCatalogRequest.meta:type_name -> hyapp.game.v1.RequestMeta
6, // 19: hyapp.game.v1.GameAppService.LaunchGame:input_type -> hyapp.game.v1.LaunchGameRequest 4, // 19: hyapp.game.v1.GameAppService.ListGames:input_type -> hyapp.game.v1.ListGamesRequest
8, // 20: hyapp.game.v1.GameCallbackService.HandleCallback:input_type -> hyapp.game.v1.CallbackRequest 6, // 20: hyapp.game.v1.GameAppService.LaunchGame:input_type -> hyapp.game.v1.LaunchGameRequest
10, // 21: hyapp.game.v1.GameCronService.ProcessLevelEventOutboxBatch:input_type -> hyapp.game.v1.CronBatchRequest 8, // 21: hyapp.game.v1.GameCallbackService.HandleCallback:input_type -> hyapp.game.v1.CallbackRequest
12, // 22: hyapp.game.v1.GameAdminService.ListPlatforms:input_type -> hyapp.game.v1.ListPlatformsRequest 10, // 22: hyapp.game.v1.GameCronService.ProcessLevelEventOutboxBatch:input_type -> hyapp.game.v1.CronBatchRequest
14, // 23: hyapp.game.v1.GameAdminService.UpsertPlatform:input_type -> hyapp.game.v1.UpsertPlatformRequest 12, // 23: hyapp.game.v1.GameAdminService.ListPlatforms:input_type -> hyapp.game.v1.ListPlatformsRequest
16, // 24: hyapp.game.v1.GameAdminService.ListCatalog:input_type -> hyapp.game.v1.ListCatalogRequest 14, // 24: hyapp.game.v1.GameAdminService.UpsertPlatform:input_type -> hyapp.game.v1.UpsertPlatformRequest
18, // 25: hyapp.game.v1.GameAdminService.UpsertCatalog:input_type -> hyapp.game.v1.UpsertCatalogRequest 16, // 25: hyapp.game.v1.GameAdminService.ListCatalog:input_type -> hyapp.game.v1.ListCatalogRequest
20, // 26: hyapp.game.v1.GameAdminService.SetGameStatus:input_type -> hyapp.game.v1.SetGameStatusRequest 18, // 26: hyapp.game.v1.GameAdminService.UpsertCatalog:input_type -> hyapp.game.v1.UpsertCatalogRequest
5, // 27: hyapp.game.v1.GameAppService.ListGames:output_type -> hyapp.game.v1.ListGamesResponse 20, // 27: hyapp.game.v1.GameAdminService.SetGameStatus:input_type -> hyapp.game.v1.SetGameStatusRequest
7, // 28: hyapp.game.v1.GameAppService.LaunchGame:output_type -> hyapp.game.v1.LaunchGameResponse 21, // 28: hyapp.game.v1.GameAdminService.DeleteCatalog:input_type -> hyapp.game.v1.DeleteCatalogRequest
9, // 29: hyapp.game.v1.GameCallbackService.HandleCallback:output_type -> hyapp.game.v1.CallbackResponse 5, // 29: hyapp.game.v1.GameAppService.ListGames:output_type -> hyapp.game.v1.ListGamesResponse
11, // 30: hyapp.game.v1.GameCronService.ProcessLevelEventOutboxBatch:output_type -> hyapp.game.v1.CronBatchResponse 7, // 30: hyapp.game.v1.GameAppService.LaunchGame:output_type -> hyapp.game.v1.LaunchGameResponse
13, // 31: hyapp.game.v1.GameAdminService.ListPlatforms:output_type -> hyapp.game.v1.ListPlatformsResponse 9, // 31: hyapp.game.v1.GameCallbackService.HandleCallback:output_type -> hyapp.game.v1.CallbackResponse
15, // 32: hyapp.game.v1.GameAdminService.UpsertPlatform:output_type -> hyapp.game.v1.PlatformResponse 11, // 32: hyapp.game.v1.GameCronService.ProcessLevelEventOutboxBatch:output_type -> hyapp.game.v1.CronBatchResponse
17, // 33: hyapp.game.v1.GameAdminService.ListCatalog:output_type -> hyapp.game.v1.ListCatalogResponse 13, // 33: hyapp.game.v1.GameAdminService.ListPlatforms:output_type -> hyapp.game.v1.ListPlatformsResponse
19, // 34: hyapp.game.v1.GameAdminService.UpsertCatalog:output_type -> hyapp.game.v1.CatalogResponse 15, // 34: hyapp.game.v1.GameAdminService.UpsertPlatform:output_type -> hyapp.game.v1.PlatformResponse
19, // 35: hyapp.game.v1.GameAdminService.SetGameStatus:output_type -> hyapp.game.v1.CatalogResponse 17, // 35: hyapp.game.v1.GameAdminService.ListCatalog:output_type -> hyapp.game.v1.ListCatalogResponse
27, // [27:36] is the sub-list for method output_type 19, // 36: hyapp.game.v1.GameAdminService.UpsertCatalog:output_type -> hyapp.game.v1.CatalogResponse
18, // [18:27] is the sub-list for method input_type 19, // 37: hyapp.game.v1.GameAdminService.SetGameStatus:output_type -> hyapp.game.v1.CatalogResponse
18, // [18:18] is the sub-list for extension type_name 22, // 38: hyapp.game.v1.GameAdminService.DeleteCatalog:output_type -> hyapp.game.v1.DeleteCatalogResponse
18, // [18:18] is the sub-list for extension extendee 29, // [29:39] is the sub-list for method output_type
0, // [0:18] is the sub-list for field type_name 19, // [19:29] is the sub-list for method input_type
19, // [19:19] is the sub-list for extension type_name
19, // [19:19] is the sub-list for extension extendee
0, // [0:19] is the sub-list for field type_name
} }
func init() { file_proto_game_v1_game_proto_init() } func init() { file_proto_game_v1_game_proto_init() }
@ -1937,7 +2044,7 @@ func file_proto_game_v1_game_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_proto_game_v1_game_proto_rawDesc), len(file_proto_game_v1_game_proto_rawDesc)), RawDescriptor: unsafe.Slice(unsafe.StringData(file_proto_game_v1_game_proto_rawDesc), len(file_proto_game_v1_game_proto_rawDesc)),
NumEnums: 0, NumEnums: 0,
NumMessages: 23, NumMessages: 25,
NumExtensions: 0, NumExtensions: 0,
NumServices: 4, NumServices: 4,
}, },

View File

@ -182,6 +182,15 @@ message SetGameStatusRequest {
string status = 3; string status = 3;
} }
message DeleteCatalogRequest {
RequestMeta meta = 1;
string game_id = 2;
}
message DeleteCatalogResponse {
int64 server_time_ms = 1;
}
service GameAppService { service GameAppService {
rpc ListGames(ListGamesRequest) returns (ListGamesResponse); rpc ListGames(ListGamesRequest) returns (ListGamesResponse);
rpc LaunchGame(LaunchGameRequest) returns (LaunchGameResponse); rpc LaunchGame(LaunchGameRequest) returns (LaunchGameResponse);
@ -202,4 +211,5 @@ service GameAdminService {
rpc ListCatalog(ListCatalogRequest) returns (ListCatalogResponse); rpc ListCatalog(ListCatalogRequest) returns (ListCatalogResponse);
rpc UpsertCatalog(UpsertCatalogRequest) returns (CatalogResponse); rpc UpsertCatalog(UpsertCatalogRequest) returns (CatalogResponse);
rpc SetGameStatus(SetGameStatusRequest) returns (CatalogResponse); rpc SetGameStatus(SetGameStatusRequest) returns (CatalogResponse);
rpc DeleteCatalog(DeleteCatalogRequest) returns (DeleteCatalogResponse);
} }

View File

@ -372,6 +372,7 @@ const (
GameAdminService_ListCatalog_FullMethodName = "/hyapp.game.v1.GameAdminService/ListCatalog" GameAdminService_ListCatalog_FullMethodName = "/hyapp.game.v1.GameAdminService/ListCatalog"
GameAdminService_UpsertCatalog_FullMethodName = "/hyapp.game.v1.GameAdminService/UpsertCatalog" GameAdminService_UpsertCatalog_FullMethodName = "/hyapp.game.v1.GameAdminService/UpsertCatalog"
GameAdminService_SetGameStatus_FullMethodName = "/hyapp.game.v1.GameAdminService/SetGameStatus" GameAdminService_SetGameStatus_FullMethodName = "/hyapp.game.v1.GameAdminService/SetGameStatus"
GameAdminService_DeleteCatalog_FullMethodName = "/hyapp.game.v1.GameAdminService/DeleteCatalog"
) )
// GameAdminServiceClient is the client API for GameAdminService service. // GameAdminServiceClient is the client API for GameAdminService service.
@ -383,6 +384,7 @@ type GameAdminServiceClient interface {
ListCatalog(ctx context.Context, in *ListCatalogRequest, opts ...grpc.CallOption) (*ListCatalogResponse, error) ListCatalog(ctx context.Context, in *ListCatalogRequest, opts ...grpc.CallOption) (*ListCatalogResponse, error)
UpsertCatalog(ctx context.Context, in *UpsertCatalogRequest, opts ...grpc.CallOption) (*CatalogResponse, error) UpsertCatalog(ctx context.Context, in *UpsertCatalogRequest, opts ...grpc.CallOption) (*CatalogResponse, error)
SetGameStatus(ctx context.Context, in *SetGameStatusRequest, opts ...grpc.CallOption) (*CatalogResponse, error) SetGameStatus(ctx context.Context, in *SetGameStatusRequest, opts ...grpc.CallOption) (*CatalogResponse, error)
DeleteCatalog(ctx context.Context, in *DeleteCatalogRequest, opts ...grpc.CallOption) (*DeleteCatalogResponse, error)
} }
type gameAdminServiceClient struct { type gameAdminServiceClient struct {
@ -443,6 +445,16 @@ func (c *gameAdminServiceClient) SetGameStatus(ctx context.Context, in *SetGameS
return out, nil return out, nil
} }
func (c *gameAdminServiceClient) DeleteCatalog(ctx context.Context, in *DeleteCatalogRequest, opts ...grpc.CallOption) (*DeleteCatalogResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(DeleteCatalogResponse)
err := c.cc.Invoke(ctx, GameAdminService_DeleteCatalog_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
// GameAdminServiceServer is the server API for GameAdminService service. // GameAdminServiceServer is the server API for GameAdminService service.
// All implementations must embed UnimplementedGameAdminServiceServer // All implementations must embed UnimplementedGameAdminServiceServer
// for forward compatibility. // for forward compatibility.
@ -452,6 +464,7 @@ type GameAdminServiceServer interface {
ListCatalog(context.Context, *ListCatalogRequest) (*ListCatalogResponse, error) ListCatalog(context.Context, *ListCatalogRequest) (*ListCatalogResponse, error)
UpsertCatalog(context.Context, *UpsertCatalogRequest) (*CatalogResponse, error) UpsertCatalog(context.Context, *UpsertCatalogRequest) (*CatalogResponse, error)
SetGameStatus(context.Context, *SetGameStatusRequest) (*CatalogResponse, error) SetGameStatus(context.Context, *SetGameStatusRequest) (*CatalogResponse, error)
DeleteCatalog(context.Context, *DeleteCatalogRequest) (*DeleteCatalogResponse, error)
mustEmbedUnimplementedGameAdminServiceServer() mustEmbedUnimplementedGameAdminServiceServer()
} }
@ -477,6 +490,9 @@ func (UnimplementedGameAdminServiceServer) UpsertCatalog(context.Context, *Upser
func (UnimplementedGameAdminServiceServer) SetGameStatus(context.Context, *SetGameStatusRequest) (*CatalogResponse, error) { func (UnimplementedGameAdminServiceServer) SetGameStatus(context.Context, *SetGameStatusRequest) (*CatalogResponse, error) {
return nil, status.Error(codes.Unimplemented, "method SetGameStatus not implemented") return nil, status.Error(codes.Unimplemented, "method SetGameStatus not implemented")
} }
func (UnimplementedGameAdminServiceServer) DeleteCatalog(context.Context, *DeleteCatalogRequest) (*DeleteCatalogResponse, error) {
return nil, status.Error(codes.Unimplemented, "method DeleteCatalog not implemented")
}
func (UnimplementedGameAdminServiceServer) mustEmbedUnimplementedGameAdminServiceServer() {} func (UnimplementedGameAdminServiceServer) mustEmbedUnimplementedGameAdminServiceServer() {}
func (UnimplementedGameAdminServiceServer) testEmbeddedByValue() {} func (UnimplementedGameAdminServiceServer) testEmbeddedByValue() {}
@ -588,6 +604,24 @@ func _GameAdminService_SetGameStatus_Handler(srv interface{}, ctx context.Contex
return interceptor(ctx, in, info, handler) return interceptor(ctx, in, info, handler)
} }
func _GameAdminService_DeleteCatalog_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(DeleteCatalogRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(GameAdminServiceServer).DeleteCatalog(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: GameAdminService_DeleteCatalog_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(GameAdminServiceServer).DeleteCatalog(ctx, req.(*DeleteCatalogRequest))
}
return interceptor(ctx, in, info, handler)
}
// GameAdminService_ServiceDesc is the grpc.ServiceDesc for GameAdminService service. // GameAdminService_ServiceDesc is the grpc.ServiceDesc for GameAdminService service.
// It's only intended for direct use with grpc.RegisterService, // It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy) // and not to be introspected or modified (even as a copy)
@ -615,6 +649,10 @@ var GameAdminService_ServiceDesc = grpc.ServiceDesc{
MethodName: "SetGameStatus", MethodName: "SetGameStatus",
Handler: _GameAdminService_SetGameStatus_Handler, Handler: _GameAdminService_SetGameStatus_Handler,
}, },
{
MethodName: "DeleteCatalog",
Handler: _GameAdminService_DeleteCatalog_Handler,
},
}, },
Streams: []grpc.StreamDesc{}, Streams: []grpc.StreamDesc{},
Metadata: "proto/game/v1/game.proto", Metadata: "proto/game/v1/game.proto",

View File

@ -15,6 +15,7 @@ type Client interface {
ListCatalog(ctx context.Context, req *gamev1.ListCatalogRequest) (*gamev1.ListCatalogResponse, error) ListCatalog(ctx context.Context, req *gamev1.ListCatalogRequest) (*gamev1.ListCatalogResponse, error)
UpsertCatalog(ctx context.Context, req *gamev1.UpsertCatalogRequest) (*gamev1.CatalogResponse, error) UpsertCatalog(ctx context.Context, req *gamev1.UpsertCatalogRequest) (*gamev1.CatalogResponse, error)
SetGameStatus(ctx context.Context, req *gamev1.SetGameStatusRequest) (*gamev1.CatalogResponse, error) SetGameStatus(ctx context.Context, req *gamev1.SetGameStatusRequest) (*gamev1.CatalogResponse, error)
DeleteCatalog(ctx context.Context, req *gamev1.DeleteCatalogRequest) (*gamev1.DeleteCatalogResponse, error)
} }
type GRPCClient struct { type GRPCClient struct {
@ -44,3 +45,7 @@ func (c *GRPCClient) UpsertCatalog(ctx context.Context, req *gamev1.UpsertCatalo
func (c *GRPCClient) SetGameStatus(ctx context.Context, req *gamev1.SetGameStatusRequest) (*gamev1.CatalogResponse, error) { func (c *GRPCClient) SetGameStatus(ctx context.Context, req *gamev1.SetGameStatusRequest) (*gamev1.CatalogResponse, error) {
return c.client.SetGameStatus(ctx, req) return c.client.SetGameStatus(ctx, req)
} }
func (c *GRPCClient) DeleteCatalog(ctx context.Context, req *gamev1.DeleteCatalogRequest) (*gamev1.DeleteCatalogResponse, error) {
return c.client.DeleteCatalog(ctx, req)
}

View File

@ -146,6 +146,24 @@ func (h *Handler) SetGameStatus(c *gin.Context) {
response.OK(c, item) response.OK(c, item)
} }
// DeleteCatalog 删除后台游戏目录记录,同时由 game-service 清理展示规则;历史订单和启动会话保留用于审计。
func (h *Handler) DeleteCatalog(c *gin.Context) {
gameID := strings.TrimSpace(c.Param("game_id"))
if gameID == "" {
response.BadRequest(c, "游戏 ID 参数不正确")
return
}
if _, err := h.game.DeleteCatalog(c.Request.Context(), &gamev1.DeleteCatalogRequest{
Meta: requestMeta(c),
GameId: gameID,
}); err != nil {
response.BadRequest(c, err.Error())
return
}
h.auditLog(c, "delete-game-catalog", "game_catalog", gameID, "deleted")
response.OK(c, gin.H{"gameId": gameID})
}
func (h *Handler) auditLog(c *gin.Context, action string, resource string, resourceID string, detail string) { func (h *Handler) auditLog(c *gin.Context, action string, resource string, resourceID string, detail string) {
shared.OperationLogWithResourceID(c, h.audit, action, resource, resourceID, "success", detail) shared.OperationLogWithResourceID(c, h.audit, action, resource, resourceID, "success", detail)
} }

View File

@ -19,4 +19,5 @@ func RegisterRoutes(protected *gin.RouterGroup, h *Handler) {
protected.POST("/admin/game/games", middleware.RequirePermission("game:create"), h.CreateCatalog) protected.POST("/admin/game/games", middleware.RequirePermission("game:create"), h.CreateCatalog)
protected.PATCH("/admin/game/games/:game_id", middleware.RequirePermission("game:update"), h.UpdateCatalog) protected.PATCH("/admin/game/games/:game_id", middleware.RequirePermission("game:update"), h.UpdateCatalog)
protected.PATCH("/admin/game/games/:game_id/status", middleware.RequirePermission("game:status"), h.SetGameStatus) protected.PATCH("/admin/game/games/:game_id/status", middleware.RequirePermission("game:status"), h.SetGameStatus)
protected.DELETE("/admin/game/games/:game_id", middleware.RequireAnyPermission("game:delete", "game:update"), h.DeleteCatalog)
} }

View File

@ -83,6 +83,7 @@ var defaultPermissions = []model.Permission{
{Name: "游戏创建", Code: "game:create", Kind: "button"}, {Name: "游戏创建", Code: "game:create", Kind: "button"},
{Name: "游戏更新", Code: "game:update", Kind: "button"}, {Name: "游戏更新", Code: "game:update", Kind: "button"},
{Name: "游戏状态", Code: "game:status", Kind: "button"}, {Name: "游戏状态", Code: "game:status", Kind: "button"},
{Name: "游戏删除", Code: "game:delete", Kind: "button"},
{Name: "每日任务查看", Code: "daily-task:view", Kind: "menu"}, {Name: "每日任务查看", Code: "daily-task:view", Kind: "menu"},
{Name: "每日任务创建", Code: "daily-task:create", Kind: "button"}, {Name: "每日任务创建", Code: "daily-task:create", Kind: "button"},
{Name: "每日任务更新", Code: "daily-task:update", Kind: "button"}, {Name: "每日任务更新", Code: "daily-task:update", Kind: "button"},
@ -478,7 +479,7 @@ func defaultRolePermissionCodes(code string) []string {
"coin-seller:view", "coin-seller:create", "coin-seller:update", "coin-seller:stock-credit", "coin-seller:view", "coin-seller:create", "coin-seller:update", "coin-seller:stock-credit",
"coin-ledger:view", "coin-adjustment:view", "coin-adjustment:create", "payment-bill:view", "payment-product:view", "payment-product:create", "payment-product:update", "payment-product:delete", "coin-ledger:view", "coin-adjustment:view", "coin-adjustment:create", "payment-bill:view", "payment-product:view", "payment-product:create", "payment-product:update", "payment-product:delete",
"lucky-gift:view", "lucky-gift:update", "lucky-gift:view", "lucky-gift:update",
"game:view", "game:create", "game:update", "game:status", "game:view", "game:create", "game:update", "game:status", "game:delete",
"daily-task:view", "daily-task:create", "daily-task:update", "daily-task:status", "daily-task:view", "daily-task:create", "daily-task:update", "daily-task:status",
"achievement:view", "achievement:create", "achievement:update", "achievement:view", "achievement:create", "achievement:update",
"seven-day-checkin:view", "seven-day-checkin:update", "seven-day-checkin:view", "seven-day-checkin:update",
@ -558,7 +559,7 @@ func defaultRolePermissionMigrationCodes(code string) []string {
"coin-seller:view", "coin-seller:create", "coin-seller:update", "coin-seller:stock-credit", "coin-seller:view", "coin-seller:create", "coin-seller:update", "coin-seller:stock-credit",
"coin-ledger:view", "coin-adjustment:view", "coin-adjustment:create", "payment-bill:view", "payment-product:view", "payment-product:create", "payment-product:update", "payment-product:delete", "coin-ledger:view", "coin-adjustment:view", "coin-adjustment:create", "payment-bill:view", "payment-product:view", "payment-product:create", "payment-product:update", "payment-product:delete",
"lucky-gift:view", "lucky-gift:update", "lucky-gift:view", "lucky-gift:update",
"game:view", "game:create", "game:update", "game:status", "game:view", "game:create", "game:update", "game:status", "game:delete",
"daily-task:view", "daily-task:create", "daily-task:update", "daily-task:status", "daily-task:view", "daily-task:create", "daily-task:update", "daily-task:status",
"achievement:view", "achievement:create", "achievement:update", "achievement:view", "achievement:create", "achievement:update",
"seven-day-checkin:view", "seven-day-checkin:update", "seven-day-checkin:view", "seven-day-checkin:update",

View File

@ -17,6 +17,7 @@ INSERT INTO admin_permissions (name, code, kind, description, created_at_ms, upd
('游戏创建', 'game:create', 'button', '', @now_ms, @now_ms), ('游戏创建', 'game:create', 'button', '', @now_ms, @now_ms),
('游戏更新', 'game:update', 'button', '', @now_ms, @now_ms), ('游戏更新', 'game:update', 'button', '', @now_ms, @now_ms),
('游戏状态', 'game:status', 'button', '', @now_ms, @now_ms), ('游戏状态', 'game:status', 'button', '', @now_ms, @now_ms),
('游戏删除', 'game:delete', 'button', '', @now_ms, @now_ms),
('每日任务查看', 'daily-task:view', 'menu', '', @now_ms, @now_ms), ('每日任务查看', 'daily-task:view', 'menu', '', @now_ms, @now_ms),
('每日任务创建', 'daily-task:create', 'button', '', @now_ms, @now_ms), ('每日任务创建', 'daily-task:create', 'button', '', @now_ms, @now_ms),
('每日任务更新', 'daily-task:update', 'button', '', @now_ms, @now_ms), ('每日任务更新', 'daily-task:update', 'button', '', @now_ms, @now_ms),

View File

@ -46,6 +46,7 @@ type Repository interface {
ListCatalog(ctx context.Context, query ListCatalogQuery) ([]gamedomain.CatalogItem, string, error) ListCatalog(ctx context.Context, query ListCatalogQuery) ([]gamedomain.CatalogItem, string, error)
UpsertCatalog(ctx context.Context, item gamedomain.CatalogItem) (gamedomain.CatalogItem, error) UpsertCatalog(ctx context.Context, item gamedomain.CatalogItem) (gamedomain.CatalogItem, error)
SetGameStatus(ctx context.Context, appCode string, gameID string, status string, nowMs int64) (gamedomain.CatalogItem, error) SetGameStatus(ctx context.Context, appCode string, gameID string, status string, nowMs int64) (gamedomain.CatalogItem, error)
DeleteCatalog(ctx context.Context, appCode string, gameID string) error
} }
// WalletClient 是 game-service 调 wallet-service 的最小改账依赖。 // WalletClient 是 game-service 调 wallet-service 的最小改账依赖。

View File

@ -1113,6 +1113,9 @@ func (f *fakeRepository) UpsertCatalog(context.Context, gamedomain.CatalogItem)
func (f *fakeRepository) SetGameStatus(context.Context, string, string, string, int64) (gamedomain.CatalogItem, error) { func (f *fakeRepository) SetGameStatus(context.Context, string, string, string, int64) (gamedomain.CatalogItem, error) {
return gamedomain.CatalogItem{}, nil return gamedomain.CatalogItem{}, nil
} }
func (f *fakeRepository) DeleteCatalog(context.Context, string, string) error {
return nil
}
type fakeWallet struct { type fakeWallet struct {
lastApply *walletv1.ApplyGameCoinChangeRequest lastApply *walletv1.ApplyGameCoinChangeRequest

View File

@ -818,6 +818,34 @@ func (r *Repository) SetGameStatus(ctx context.Context, appCode string, gameID s
return r.getCatalog(ctx, appCode, gameID) return r.getCatalog(ctx, appCode, gameID)
} }
func (r *Repository) DeleteCatalog(ctx context.Context, appCode string, gameID string) error {
app := appcode.Normalize(appCode)
id := strings.TrimSpace(gameID)
if id == "" {
return xerr.New(xerr.InvalidArgument, "game_id is required")
}
tx, err := r.db.BeginTx(ctx, nil)
if err != nil {
return err
}
defer tx.Rollback()
result, err := tx.ExecContext(ctx, `DELETE FROM game_catalog WHERE app_code = ? AND game_id = ?`, app, id)
if err != nil {
return err
}
affected, err := result.RowsAffected()
if err != nil {
return err
}
if affected == 0 {
return xerr.New(xerr.NotFound, "game not found")
}
if _, err := tx.ExecContext(ctx, `DELETE FROM game_display_rules WHERE app_code = ? AND game_id = ?`, app, id); err != nil {
return err
}
return tx.Commit()
}
func (r *Repository) getCatalog(ctx context.Context, appCode string, gameID string) (gamedomain.CatalogItem, error) { func (r *Repository) getCatalog(ctx context.Context, appCode string, gameID string) (gamedomain.CatalogItem, error) {
row := r.db.QueryRowContext(ctx, row := r.db.QueryRowContext(ctx,
`SELECT app_code, game_id, platform_code, provider_game_id, game_name, category, icon_url, cover_url, `SELECT app_code, game_id, platform_code, provider_game_id, game_name, category, icon_url, cover_url,

View File

@ -108,3 +108,59 @@ func TestUpsertCatalogCreatesDefaultVoiceRoomDisplayRule(t *testing.T) {
t.Fatalf("display rule mismatch: scene=%s visible=%v enabled=%v sort=%d", scene, visible, enabled, sortOrder) t.Fatalf("display rule mismatch: scene=%s visible=%v enabled=%v sort=%d", scene, visible, enabled, sortOrder)
} }
} }
func TestDeleteCatalogRemovesGameAndDisplayRule(t *testing.T) {
caller := mysqlschema.CallerFile(t, 1)
schema := mysqlschema.New(t, mysqlschema.Config{
InitDBPath: mysqlschema.InitDBPath(t, caller, "../../../deploy/mysql/initdb/001_game_service.sql"),
DatabasePrefix: "hy_game_test",
})
ctx := appcode.WithContext(context.Background(), "lalu")
repo, err := Open(ctx, schema.DSN)
if err != nil {
t.Fatalf("open repository failed: %v", err)
}
t.Cleanup(func() { _ = repo.Close() })
item := gamedomain.CatalogItem{
AppCode: "lalu",
GameID: "delete_game_001",
PlatformCode: "demo",
ProviderGameID: "provider_delete_001",
GameName: "Delete Game",
Category: "casino",
LaunchMode: gamedomain.LaunchModeH5Popup,
Orientation: "portrait",
Status: gamedomain.StatusActive,
SortOrder: 80,
}
if _, err := repo.UpsertCatalog(ctx, item); err != nil {
t.Fatalf("upsert catalog failed: %v", err)
}
if err := repo.DeleteCatalog(ctx, "lalu", item.GameID); err != nil {
t.Fatalf("delete catalog failed: %v", err)
}
var gameCount int
if err := repo.db.QueryRowContext(ctx,
`SELECT COUNT(*) FROM game_catalog WHERE app_code = ? AND game_id = ?`,
"lalu", item.GameID,
).Scan(&gameCount); err != nil {
t.Fatalf("query catalog count failed: %v", err)
}
if gameCount != 0 {
t.Fatalf("game_catalog count = %d, want 0", gameCount)
}
var ruleCount int
if err := repo.db.QueryRowContext(ctx,
`SELECT COUNT(*) FROM game_display_rules WHERE app_code = ? AND game_id = ?`,
"lalu", item.GameID,
).Scan(&ruleCount); err != nil {
t.Fatalf("query display rule count failed: %v", err)
}
if ruleCount != 0 {
t.Fatalf("game_display_rules count = %d, want 0", ruleCount)
}
}

View File

@ -171,6 +171,14 @@ func (s *Server) SetGameStatus(ctx context.Context, req *gamev1.SetGameStatusReq
return &gamev1.CatalogResponse{Game: catalogToProto(item), ServerTimeMs: time.Now().UnixMilli()}, nil return &gamev1.CatalogResponse{Game: catalogToProto(item), ServerTimeMs: time.Now().UnixMilli()}, nil
} }
func (s *Server) DeleteCatalog(ctx context.Context, req *gamev1.DeleteCatalogRequest) (*gamev1.DeleteCatalogResponse, error) {
ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode())
if err := s.svcRepository().DeleteCatalog(ctx, req.GetMeta().GetAppCode(), req.GetGameId()); err != nil {
return nil, xerr.ToGRPCError(err)
}
return &gamev1.DeleteCatalogResponse{ServerTimeMs: time.Now().UnixMilli()}, nil
}
func (s *Server) svcRepository() gameservice.Repository { func (s *Server) svcRepository() gameservice.Repository {
if s == nil || s.svc == nil || s.svc.Repository() == nil { if s == nil || s.svc == nil || s.svc.Repository() == nil {
return unavailableRepository{} return unavailableRepository{}
@ -237,6 +245,9 @@ func (unavailableRepository) UpsertCatalog(context.Context, gamedomain.CatalogIt
func (unavailableRepository) SetGameStatus(context.Context, string, string, string, int64) (gamedomain.CatalogItem, error) { func (unavailableRepository) SetGameStatus(context.Context, string, string, string, int64) (gamedomain.CatalogItem, error) {
return gamedomain.CatalogItem{}, xerr.New(xerr.Unavailable, "game repository is not configured") return gamedomain.CatalogItem{}, xerr.New(xerr.Unavailable, "game repository is not configured")
} }
func (unavailableRepository) DeleteCatalog(context.Context, string, string) error {
return xerr.New(xerr.Unavailable, "game repository is not configured")
}
func appGameToProto(item gamedomain.AppGame) *gamev1.AppGame { func appGameToProto(item gamedomain.AppGame) *gamev1.AppGame {
return &gamev1.AppGame{ return &gamev1.AppGame{

View File

@ -22,9 +22,10 @@ function copyProxyHeaders(req) {
for (const [key, value] of Object.entries(req.headers)) { for (const [key, value] of Object.entries(req.headers)) {
if (!value) continue; if (!value) continue;
const lower = key.toLowerCase(); const lower = key.toLowerCase();
if (["host", "origin", "referer", "connection", "content-length"].includes(lower)) continue; if (["host", "origin", "referer", "connection", "content-length", "accept-encoding"].includes(lower)) continue;
headers.set(key, Array.isArray(value) ? value.join(", ") : value); headers.set(key, Array.isArray(value) ? value.join(", ") : value);
} }
headers.set("Accept-Encoding", "identity");
return headers; return headers;
} }

View File

@ -203,12 +203,16 @@
} catch { } catch {
payload = { message: text }; payload = { message: text };
} }
if (!response.ok || payload.code !== 0) { if (!response.ok || !isSuccessCode(payload.code)) {
throw new Error(payload.message || response.statusText || `HTTP ${response.status}`); throw new Error(payload.message || response.statusText || `HTTP ${response.status}`);
} }
return payload.data; return payload.data;
} }
function isSuccessCode(code) {
return code === undefined || code === null || code === 0 || code === "0" || code === 200 || code === "200" || code === "OK";
}
function saveToken(data) { function saveToken(data) {
const accessToken = data?.access_token || data?.token?.access_token || ""; const accessToken = data?.access_token || data?.token?.access_token || "";
if (!accessToken) { if (!accessToken) {