幸运礼物
This commit is contained in:
parent
a0ee5962df
commit
a68d465272
@ -9955,6 +9955,8 @@ type LuckyGiftMeta struct {
|
|||||||
CoinSpent int64 `protobuf:"varint,8,opt,name=coin_spent,json=coinSpent,proto3" json:"coin_spent,omitempty"`
|
CoinSpent int64 `protobuf:"varint,8,opt,name=coin_spent,json=coinSpent,proto3" json:"coin_spent,omitempty"`
|
||||||
PaidAtMs int64 `protobuf:"varint,9,opt,name=paid_at_ms,json=paidAtMs,proto3" json:"paid_at_ms,omitempty"`
|
PaidAtMs int64 `protobuf:"varint,9,opt,name=paid_at_ms,json=paidAtMs,proto3" json:"paid_at_ms,omitempty"`
|
||||||
PoolId string `protobuf:"bytes,10,opt,name=pool_id,json=poolId,proto3" json:"pool_id,omitempty"`
|
PoolId string `protobuf:"bytes,10,opt,name=pool_id,json=poolId,proto3" json:"pool_id,omitempty"`
|
||||||
|
TargetUserId int64 `protobuf:"varint,11,opt,name=target_user_id,json=targetUserId,proto3" json:"target_user_id,omitempty"`
|
||||||
|
GiftCount int32 `protobuf:"varint,12,opt,name=gift_count,json=giftCount,proto3" json:"gift_count,omitempty"`
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
}
|
}
|
||||||
@ -10059,6 +10061,20 @@ func (x *LuckyGiftMeta) GetPoolId() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *LuckyGiftMeta) GetTargetUserId() int64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.TargetUserId
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *LuckyGiftMeta) GetGiftCount() int32 {
|
||||||
|
if x != nil {
|
||||||
|
return x.GiftCount
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
type LuckyGiftTier struct {
|
type LuckyGiftTier struct {
|
||||||
state protoimpl.MessageState `protogen:"open.v1"`
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
Pool string `protobuf:"bytes,1,opt,name=pool,proto3" json:"pool,omitempty"`
|
Pool string `protobuf:"bytes,1,opt,name=pool,proto3" json:"pool,omitempty"`
|
||||||
@ -12599,7 +12615,7 @@ const file_proto_activity_v1_activity_proto_rawDesc = "" +
|
|||||||
"conditions\"\x8b\x01\n" +
|
"conditions\"\x8b\x01\n" +
|
||||||
"#UpsertAchievementDefinitionResponse\x12J\n" +
|
"#UpsertAchievementDefinitionResponse\x12J\n" +
|
||||||
"\vachievement\x18\x01 \x01(\v2(.hyapp.activity.v1.AchievementDefinitionR\vachievement\x12\x18\n" +
|
"\vachievement\x18\x01 \x01(\v2(.hyapp.activity.v1.AchievementDefinitionR\vachievement\x12\x18\n" +
|
||||||
"\acreated\x18\x02 \x01(\bR\acreated\"\xbd\x02\n" +
|
"\acreated\x18\x02 \x01(\bR\acreated\"\x82\x03\n" +
|
||||||
"\rLuckyGiftMeta\x122\n" +
|
"\rLuckyGiftMeta\x122\n" +
|
||||||
"\x04meta\x18\x01 \x01(\v2\x1e.hyapp.activity.v1.RequestMetaR\x04meta\x12\x1d\n" +
|
"\x04meta\x18\x01 \x01(\v2\x1e.hyapp.activity.v1.RequestMetaR\x04meta\x12\x1d\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
@ -12614,7 +12630,10 @@ const file_proto_activity_v1_activity_proto_rawDesc = "" +
|
|||||||
"\n" +
|
"\n" +
|
||||||
"paid_at_ms\x18\t \x01(\x03R\bpaidAtMs\x12\x17\n" +
|
"paid_at_ms\x18\t \x01(\x03R\bpaidAtMs\x12\x17\n" +
|
||||||
"\apool_id\x18\n" +
|
"\apool_id\x18\n" +
|
||||||
" \x01(\tR\x06poolId\"\xe0\x01\n" +
|
" \x01(\tR\x06poolId\x12$\n" +
|
||||||
|
"\x0etarget_user_id\x18\v \x01(\x03R\ftargetUserId\x12\x1d\n" +
|
||||||
|
"\n" +
|
||||||
|
"gift_count\x18\f \x01(\x05R\tgiftCount\"\xe0\x01\n" +
|
||||||
"\rLuckyGiftTier\x12\x12\n" +
|
"\rLuckyGiftTier\x12\x12\n" +
|
||||||
"\x04pool\x18\x01 \x01(\tR\x04pool\x12\x17\n" +
|
"\x04pool\x18\x01 \x01(\tR\x04pool\x12\x17\n" +
|
||||||
"\atier_id\x18\x02 \x01(\tR\x06tierId\x12!\n" +
|
"\atier_id\x18\x02 \x01(\tR\x06tierId\x12!\n" +
|
||||||
|
|||||||
@ -1123,6 +1123,8 @@ message LuckyGiftMeta {
|
|||||||
int64 coin_spent = 8;
|
int64 coin_spent = 8;
|
||||||
int64 paid_at_ms = 9;
|
int64 paid_at_ms = 9;
|
||||||
string pool_id = 10;
|
string pool_id = 10;
|
||||||
|
int64 target_user_id = 11;
|
||||||
|
int32 gift_count = 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
message LuckyGiftTier {
|
message LuckyGiftTier {
|
||||||
|
|||||||
@ -9492,6 +9492,184 @@ func (x *CreditTaskRewardResponse) GetGrantedAtMs() int64 {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreditLuckyGiftRewardRequest 是 activity-service 抽奖 outbox 补偿 worker 调用的钱包入账命令。
|
||||||
|
type CreditLuckyGiftRewardRequest struct {
|
||||||
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
|
CommandId string `protobuf:"bytes,1,opt,name=command_id,json=commandId,proto3" json:"command_id,omitempty"`
|
||||||
|
AppCode string `protobuf:"bytes,2,opt,name=app_code,json=appCode,proto3" json:"app_code,omitempty"`
|
||||||
|
TargetUserId int64 `protobuf:"varint,3,opt,name=target_user_id,json=targetUserId,proto3" json:"target_user_id,omitempty"`
|
||||||
|
Amount int64 `protobuf:"varint,4,opt,name=amount,proto3" json:"amount,omitempty"`
|
||||||
|
DrawId string `protobuf:"bytes,5,opt,name=draw_id,json=drawId,proto3" json:"draw_id,omitempty"`
|
||||||
|
RoomId string `protobuf:"bytes,6,opt,name=room_id,json=roomId,proto3" json:"room_id,omitempty"`
|
||||||
|
GiftId string `protobuf:"bytes,7,opt,name=gift_id,json=giftId,proto3" json:"gift_id,omitempty"`
|
||||||
|
PoolId string `protobuf:"bytes,8,opt,name=pool_id,json=poolId,proto3" json:"pool_id,omitempty"`
|
||||||
|
Reason string `protobuf:"bytes,9,opt,name=reason,proto3" json:"reason,omitempty"`
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CreditLuckyGiftRewardRequest) Reset() {
|
||||||
|
*x = CreditLuckyGiftRewardRequest{}
|
||||||
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[106]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CreditLuckyGiftRewardRequest) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*CreditLuckyGiftRewardRequest) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *CreditLuckyGiftRewardRequest) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[106]
|
||||||
|
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 CreditLuckyGiftRewardRequest.ProtoReflect.Descriptor instead.
|
||||||
|
func (*CreditLuckyGiftRewardRequest) Descriptor() ([]byte, []int) {
|
||||||
|
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{106}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CreditLuckyGiftRewardRequest) GetCommandId() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.CommandId
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CreditLuckyGiftRewardRequest) GetAppCode() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.AppCode
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CreditLuckyGiftRewardRequest) GetTargetUserId() int64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.TargetUserId
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CreditLuckyGiftRewardRequest) GetAmount() int64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.Amount
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CreditLuckyGiftRewardRequest) GetDrawId() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.DrawId
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CreditLuckyGiftRewardRequest) GetRoomId() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.RoomId
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CreditLuckyGiftRewardRequest) GetGiftId() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.GiftId
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CreditLuckyGiftRewardRequest) GetPoolId() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.PoolId
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CreditLuckyGiftRewardRequest) GetReason() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Reason
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreditLuckyGiftRewardResponse 返回幸运礼物返奖入账流水和用户 COIN 账后余额。
|
||||||
|
type CreditLuckyGiftRewardResponse struct {
|
||||||
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
|
TransactionId string `protobuf:"bytes,1,opt,name=transaction_id,json=transactionId,proto3" json:"transaction_id,omitempty"`
|
||||||
|
Balance *AssetBalance `protobuf:"bytes,2,opt,name=balance,proto3" json:"balance,omitempty"`
|
||||||
|
Amount int64 `protobuf:"varint,3,opt,name=amount,proto3" json:"amount,omitempty"`
|
||||||
|
GrantedAtMs int64 `protobuf:"varint,4,opt,name=granted_at_ms,json=grantedAtMs,proto3" json:"granted_at_ms,omitempty"`
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CreditLuckyGiftRewardResponse) Reset() {
|
||||||
|
*x = CreditLuckyGiftRewardResponse{}
|
||||||
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[107]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CreditLuckyGiftRewardResponse) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*CreditLuckyGiftRewardResponse) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *CreditLuckyGiftRewardResponse) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[107]
|
||||||
|
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 CreditLuckyGiftRewardResponse.ProtoReflect.Descriptor instead.
|
||||||
|
func (*CreditLuckyGiftRewardResponse) Descriptor() ([]byte, []int) {
|
||||||
|
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{107}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CreditLuckyGiftRewardResponse) GetTransactionId() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.TransactionId
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CreditLuckyGiftRewardResponse) GetBalance() *AssetBalance {
|
||||||
|
if x != nil {
|
||||||
|
return x.Balance
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CreditLuckyGiftRewardResponse) GetAmount() int64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.Amount
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CreditLuckyGiftRewardResponse) GetGrantedAtMs() int64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.GrantedAtMs
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
// ApplyGameCoinChangeRequest 是 game-service 唯一可以调用的钱包游戏改账入口。
|
// ApplyGameCoinChangeRequest 是 game-service 唯一可以调用的钱包游戏改账入口。
|
||||||
type ApplyGameCoinChangeRequest struct {
|
type ApplyGameCoinChangeRequest struct {
|
||||||
state protoimpl.MessageState `protogen:"open.v1"`
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
@ -9513,7 +9691,7 @@ type ApplyGameCoinChangeRequest struct {
|
|||||||
|
|
||||||
func (x *ApplyGameCoinChangeRequest) Reset() {
|
func (x *ApplyGameCoinChangeRequest) Reset() {
|
||||||
*x = ApplyGameCoinChangeRequest{}
|
*x = ApplyGameCoinChangeRequest{}
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[106]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[108]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@ -9525,7 +9703,7 @@ func (x *ApplyGameCoinChangeRequest) String() string {
|
|||||||
func (*ApplyGameCoinChangeRequest) ProtoMessage() {}
|
func (*ApplyGameCoinChangeRequest) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *ApplyGameCoinChangeRequest) ProtoReflect() protoreflect.Message {
|
func (x *ApplyGameCoinChangeRequest) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[106]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[108]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@ -9538,7 +9716,7 @@ func (x *ApplyGameCoinChangeRequest) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use ApplyGameCoinChangeRequest.ProtoReflect.Descriptor instead.
|
// Deprecated: Use ApplyGameCoinChangeRequest.ProtoReflect.Descriptor instead.
|
||||||
func (*ApplyGameCoinChangeRequest) Descriptor() ([]byte, []int) {
|
func (*ApplyGameCoinChangeRequest) Descriptor() ([]byte, []int) {
|
||||||
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{106}
|
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{108}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *ApplyGameCoinChangeRequest) GetRequestId() string {
|
func (x *ApplyGameCoinChangeRequest) GetRequestId() string {
|
||||||
@ -9637,7 +9815,7 @@ type ApplyGameCoinChangeResponse struct {
|
|||||||
|
|
||||||
func (x *ApplyGameCoinChangeResponse) Reset() {
|
func (x *ApplyGameCoinChangeResponse) Reset() {
|
||||||
*x = ApplyGameCoinChangeResponse{}
|
*x = ApplyGameCoinChangeResponse{}
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[107]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[109]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@ -9649,7 +9827,7 @@ func (x *ApplyGameCoinChangeResponse) String() string {
|
|||||||
func (*ApplyGameCoinChangeResponse) ProtoMessage() {}
|
func (*ApplyGameCoinChangeResponse) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *ApplyGameCoinChangeResponse) ProtoReflect() protoreflect.Message {
|
func (x *ApplyGameCoinChangeResponse) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[107]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[109]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@ -9662,7 +9840,7 @@ func (x *ApplyGameCoinChangeResponse) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use ApplyGameCoinChangeResponse.ProtoReflect.Descriptor instead.
|
// Deprecated: Use ApplyGameCoinChangeResponse.ProtoReflect.Descriptor instead.
|
||||||
func (*ApplyGameCoinChangeResponse) Descriptor() ([]byte, []int) {
|
func (*ApplyGameCoinChangeResponse) Descriptor() ([]byte, []int) {
|
||||||
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{107}
|
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{109}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *ApplyGameCoinChangeResponse) GetWalletTransactionId() string {
|
func (x *ApplyGameCoinChangeResponse) GetWalletTransactionId() string {
|
||||||
@ -9704,7 +9882,7 @@ type RedPacketConfig struct {
|
|||||||
|
|
||||||
func (x *RedPacketConfig) Reset() {
|
func (x *RedPacketConfig) Reset() {
|
||||||
*x = RedPacketConfig{}
|
*x = RedPacketConfig{}
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[108]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[110]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@ -9716,7 +9894,7 @@ func (x *RedPacketConfig) String() string {
|
|||||||
func (*RedPacketConfig) ProtoMessage() {}
|
func (*RedPacketConfig) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *RedPacketConfig) ProtoReflect() protoreflect.Message {
|
func (x *RedPacketConfig) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[108]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[110]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@ -9729,7 +9907,7 @@ func (x *RedPacketConfig) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use RedPacketConfig.ProtoReflect.Descriptor instead.
|
// Deprecated: Use RedPacketConfig.ProtoReflect.Descriptor instead.
|
||||||
func (*RedPacketConfig) Descriptor() ([]byte, []int) {
|
func (*RedPacketConfig) Descriptor() ([]byte, []int) {
|
||||||
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{108}
|
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{110}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *RedPacketConfig) GetAppCode() string {
|
func (x *RedPacketConfig) GetAppCode() string {
|
||||||
@ -9821,7 +9999,7 @@ type RedPacketClaim struct {
|
|||||||
|
|
||||||
func (x *RedPacketClaim) Reset() {
|
func (x *RedPacketClaim) Reset() {
|
||||||
*x = RedPacketClaim{}
|
*x = RedPacketClaim{}
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[109]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[111]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@ -9833,7 +10011,7 @@ func (x *RedPacketClaim) String() string {
|
|||||||
func (*RedPacketClaim) ProtoMessage() {}
|
func (*RedPacketClaim) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *RedPacketClaim) ProtoReflect() protoreflect.Message {
|
func (x *RedPacketClaim) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[109]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[111]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@ -9846,7 +10024,7 @@ func (x *RedPacketClaim) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use RedPacketClaim.ProtoReflect.Descriptor instead.
|
// Deprecated: Use RedPacketClaim.ProtoReflect.Descriptor instead.
|
||||||
func (*RedPacketClaim) Descriptor() ([]byte, []int) {
|
func (*RedPacketClaim) Descriptor() ([]byte, []int) {
|
||||||
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{109}
|
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{111}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *RedPacketClaim) GetAppCode() string {
|
func (x *RedPacketClaim) GetAppCode() string {
|
||||||
@ -9953,7 +10131,7 @@ type RedPacket struct {
|
|||||||
|
|
||||||
func (x *RedPacket) Reset() {
|
func (x *RedPacket) Reset() {
|
||||||
*x = RedPacket{}
|
*x = RedPacket{}
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[110]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[112]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@ -9965,7 +10143,7 @@ func (x *RedPacket) String() string {
|
|||||||
func (*RedPacket) ProtoMessage() {}
|
func (*RedPacket) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *RedPacket) ProtoReflect() protoreflect.Message {
|
func (x *RedPacket) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[110]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[112]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@ -9978,7 +10156,7 @@ func (x *RedPacket) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use RedPacket.ProtoReflect.Descriptor instead.
|
// Deprecated: Use RedPacket.ProtoReflect.Descriptor instead.
|
||||||
func (*RedPacket) Descriptor() ([]byte, []int) {
|
func (*RedPacket) Descriptor() ([]byte, []int) {
|
||||||
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{110}
|
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{112}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *RedPacket) GetAppCode() string {
|
func (x *RedPacket) GetAppCode() string {
|
||||||
@ -10124,7 +10302,7 @@ type GetRedPacketConfigRequest struct {
|
|||||||
|
|
||||||
func (x *GetRedPacketConfigRequest) Reset() {
|
func (x *GetRedPacketConfigRequest) Reset() {
|
||||||
*x = GetRedPacketConfigRequest{}
|
*x = GetRedPacketConfigRequest{}
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[111]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[113]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@ -10136,7 +10314,7 @@ func (x *GetRedPacketConfigRequest) String() string {
|
|||||||
func (*GetRedPacketConfigRequest) ProtoMessage() {}
|
func (*GetRedPacketConfigRequest) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *GetRedPacketConfigRequest) ProtoReflect() protoreflect.Message {
|
func (x *GetRedPacketConfigRequest) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[111]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[113]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@ -10149,7 +10327,7 @@ func (x *GetRedPacketConfigRequest) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use GetRedPacketConfigRequest.ProtoReflect.Descriptor instead.
|
// Deprecated: Use GetRedPacketConfigRequest.ProtoReflect.Descriptor instead.
|
||||||
func (*GetRedPacketConfigRequest) Descriptor() ([]byte, []int) {
|
func (*GetRedPacketConfigRequest) Descriptor() ([]byte, []int) {
|
||||||
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{111}
|
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{113}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *GetRedPacketConfigRequest) GetRequestId() string {
|
func (x *GetRedPacketConfigRequest) GetRequestId() string {
|
||||||
@ -10176,7 +10354,7 @@ type GetRedPacketConfigResponse struct {
|
|||||||
|
|
||||||
func (x *GetRedPacketConfigResponse) Reset() {
|
func (x *GetRedPacketConfigResponse) Reset() {
|
||||||
*x = GetRedPacketConfigResponse{}
|
*x = GetRedPacketConfigResponse{}
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[112]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[114]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@ -10188,7 +10366,7 @@ func (x *GetRedPacketConfigResponse) String() string {
|
|||||||
func (*GetRedPacketConfigResponse) ProtoMessage() {}
|
func (*GetRedPacketConfigResponse) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *GetRedPacketConfigResponse) ProtoReflect() protoreflect.Message {
|
func (x *GetRedPacketConfigResponse) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[112]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[114]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@ -10201,7 +10379,7 @@ func (x *GetRedPacketConfigResponse) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use GetRedPacketConfigResponse.ProtoReflect.Descriptor instead.
|
// Deprecated: Use GetRedPacketConfigResponse.ProtoReflect.Descriptor instead.
|
||||||
func (*GetRedPacketConfigResponse) Descriptor() ([]byte, []int) {
|
func (*GetRedPacketConfigResponse) Descriptor() ([]byte, []int) {
|
||||||
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{112}
|
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{114}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *GetRedPacketConfigResponse) GetConfig() *RedPacketConfig {
|
func (x *GetRedPacketConfigResponse) GetConfig() *RedPacketConfig {
|
||||||
@ -10235,7 +10413,7 @@ type UpdateRedPacketConfigRequest struct {
|
|||||||
|
|
||||||
func (x *UpdateRedPacketConfigRequest) Reset() {
|
func (x *UpdateRedPacketConfigRequest) Reset() {
|
||||||
*x = UpdateRedPacketConfigRequest{}
|
*x = UpdateRedPacketConfigRequest{}
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[113]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[115]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@ -10247,7 +10425,7 @@ func (x *UpdateRedPacketConfigRequest) String() string {
|
|||||||
func (*UpdateRedPacketConfigRequest) ProtoMessage() {}
|
func (*UpdateRedPacketConfigRequest) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *UpdateRedPacketConfigRequest) ProtoReflect() protoreflect.Message {
|
func (x *UpdateRedPacketConfigRequest) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[113]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[115]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@ -10260,7 +10438,7 @@ func (x *UpdateRedPacketConfigRequest) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use UpdateRedPacketConfigRequest.ProtoReflect.Descriptor instead.
|
// Deprecated: Use UpdateRedPacketConfigRequest.ProtoReflect.Descriptor instead.
|
||||||
func (*UpdateRedPacketConfigRequest) Descriptor() ([]byte, []int) {
|
func (*UpdateRedPacketConfigRequest) Descriptor() ([]byte, []int) {
|
||||||
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{113}
|
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{115}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *UpdateRedPacketConfigRequest) GetRequestId() string {
|
func (x *UpdateRedPacketConfigRequest) GetRequestId() string {
|
||||||
@ -10336,7 +10514,7 @@ type UpdateRedPacketConfigResponse struct {
|
|||||||
|
|
||||||
func (x *UpdateRedPacketConfigResponse) Reset() {
|
func (x *UpdateRedPacketConfigResponse) Reset() {
|
||||||
*x = UpdateRedPacketConfigResponse{}
|
*x = UpdateRedPacketConfigResponse{}
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[114]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[116]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@ -10348,7 +10526,7 @@ func (x *UpdateRedPacketConfigResponse) String() string {
|
|||||||
func (*UpdateRedPacketConfigResponse) ProtoMessage() {}
|
func (*UpdateRedPacketConfigResponse) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *UpdateRedPacketConfigResponse) ProtoReflect() protoreflect.Message {
|
func (x *UpdateRedPacketConfigResponse) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[114]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[116]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@ -10361,7 +10539,7 @@ func (x *UpdateRedPacketConfigResponse) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use UpdateRedPacketConfigResponse.ProtoReflect.Descriptor instead.
|
// Deprecated: Use UpdateRedPacketConfigResponse.ProtoReflect.Descriptor instead.
|
||||||
func (*UpdateRedPacketConfigResponse) Descriptor() ([]byte, []int) {
|
func (*UpdateRedPacketConfigResponse) Descriptor() ([]byte, []int) {
|
||||||
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{114}
|
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{116}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *UpdateRedPacketConfigResponse) GetConfig() *RedPacketConfig {
|
func (x *UpdateRedPacketConfigResponse) GetConfig() *RedPacketConfig {
|
||||||
@ -10395,7 +10573,7 @@ type CreateRedPacketRequest struct {
|
|||||||
|
|
||||||
func (x *CreateRedPacketRequest) Reset() {
|
func (x *CreateRedPacketRequest) Reset() {
|
||||||
*x = CreateRedPacketRequest{}
|
*x = CreateRedPacketRequest{}
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[115]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[117]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@ -10407,7 +10585,7 @@ func (x *CreateRedPacketRequest) String() string {
|
|||||||
func (*CreateRedPacketRequest) ProtoMessage() {}
|
func (*CreateRedPacketRequest) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *CreateRedPacketRequest) ProtoReflect() protoreflect.Message {
|
func (x *CreateRedPacketRequest) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[115]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[117]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@ -10420,7 +10598,7 @@ func (x *CreateRedPacketRequest) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use CreateRedPacketRequest.ProtoReflect.Descriptor instead.
|
// Deprecated: Use CreateRedPacketRequest.ProtoReflect.Descriptor instead.
|
||||||
func (*CreateRedPacketRequest) Descriptor() ([]byte, []int) {
|
func (*CreateRedPacketRequest) Descriptor() ([]byte, []int) {
|
||||||
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{115}
|
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{117}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *CreateRedPacketRequest) GetRequestId() string {
|
func (x *CreateRedPacketRequest) GetRequestId() string {
|
||||||
@ -10497,7 +10675,7 @@ type CreateRedPacketResponse struct {
|
|||||||
|
|
||||||
func (x *CreateRedPacketResponse) Reset() {
|
func (x *CreateRedPacketResponse) Reset() {
|
||||||
*x = CreateRedPacketResponse{}
|
*x = CreateRedPacketResponse{}
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[116]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[118]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@ -10509,7 +10687,7 @@ func (x *CreateRedPacketResponse) String() string {
|
|||||||
func (*CreateRedPacketResponse) ProtoMessage() {}
|
func (*CreateRedPacketResponse) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *CreateRedPacketResponse) ProtoReflect() protoreflect.Message {
|
func (x *CreateRedPacketResponse) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[116]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[118]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@ -10522,7 +10700,7 @@ func (x *CreateRedPacketResponse) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use CreateRedPacketResponse.ProtoReflect.Descriptor instead.
|
// Deprecated: Use CreateRedPacketResponse.ProtoReflect.Descriptor instead.
|
||||||
func (*CreateRedPacketResponse) Descriptor() ([]byte, []int) {
|
func (*CreateRedPacketResponse) Descriptor() ([]byte, []int) {
|
||||||
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{116}
|
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{118}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *CreateRedPacketResponse) GetPacket() *RedPacket {
|
func (x *CreateRedPacketResponse) GetPacket() *RedPacket {
|
||||||
@ -10559,7 +10737,7 @@ type ClaimRedPacketRequest struct {
|
|||||||
|
|
||||||
func (x *ClaimRedPacketRequest) Reset() {
|
func (x *ClaimRedPacketRequest) Reset() {
|
||||||
*x = ClaimRedPacketRequest{}
|
*x = ClaimRedPacketRequest{}
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[117]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[119]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@ -10571,7 +10749,7 @@ func (x *ClaimRedPacketRequest) String() string {
|
|||||||
func (*ClaimRedPacketRequest) ProtoMessage() {}
|
func (*ClaimRedPacketRequest) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *ClaimRedPacketRequest) ProtoReflect() protoreflect.Message {
|
func (x *ClaimRedPacketRequest) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[117]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[119]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@ -10584,7 +10762,7 @@ func (x *ClaimRedPacketRequest) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use ClaimRedPacketRequest.ProtoReflect.Descriptor instead.
|
// Deprecated: Use ClaimRedPacketRequest.ProtoReflect.Descriptor instead.
|
||||||
func (*ClaimRedPacketRequest) Descriptor() ([]byte, []int) {
|
func (*ClaimRedPacketRequest) Descriptor() ([]byte, []int) {
|
||||||
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{117}
|
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{119}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *ClaimRedPacketRequest) GetRequestId() string {
|
func (x *ClaimRedPacketRequest) GetRequestId() string {
|
||||||
@ -10633,7 +10811,7 @@ type ClaimRedPacketResponse struct {
|
|||||||
|
|
||||||
func (x *ClaimRedPacketResponse) Reset() {
|
func (x *ClaimRedPacketResponse) Reset() {
|
||||||
*x = ClaimRedPacketResponse{}
|
*x = ClaimRedPacketResponse{}
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[118]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[120]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@ -10645,7 +10823,7 @@ func (x *ClaimRedPacketResponse) String() string {
|
|||||||
func (*ClaimRedPacketResponse) ProtoMessage() {}
|
func (*ClaimRedPacketResponse) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *ClaimRedPacketResponse) ProtoReflect() protoreflect.Message {
|
func (x *ClaimRedPacketResponse) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[118]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[120]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@ -10658,7 +10836,7 @@ func (x *ClaimRedPacketResponse) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use ClaimRedPacketResponse.ProtoReflect.Descriptor instead.
|
// Deprecated: Use ClaimRedPacketResponse.ProtoReflect.Descriptor instead.
|
||||||
func (*ClaimRedPacketResponse) Descriptor() ([]byte, []int) {
|
func (*ClaimRedPacketResponse) Descriptor() ([]byte, []int) {
|
||||||
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{118}
|
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{120}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *ClaimRedPacketResponse) GetClaim() *RedPacketClaim {
|
func (x *ClaimRedPacketResponse) GetClaim() *RedPacketClaim {
|
||||||
@ -10702,7 +10880,7 @@ type ListRedPacketsRequest struct {
|
|||||||
|
|
||||||
func (x *ListRedPacketsRequest) Reset() {
|
func (x *ListRedPacketsRequest) Reset() {
|
||||||
*x = ListRedPacketsRequest{}
|
*x = ListRedPacketsRequest{}
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[119]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[121]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@ -10714,7 +10892,7 @@ func (x *ListRedPacketsRequest) String() string {
|
|||||||
func (*ListRedPacketsRequest) ProtoMessage() {}
|
func (*ListRedPacketsRequest) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *ListRedPacketsRequest) ProtoReflect() protoreflect.Message {
|
func (x *ListRedPacketsRequest) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[119]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[121]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@ -10727,7 +10905,7 @@ func (x *ListRedPacketsRequest) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use ListRedPacketsRequest.ProtoReflect.Descriptor instead.
|
// Deprecated: Use ListRedPacketsRequest.ProtoReflect.Descriptor instead.
|
||||||
func (*ListRedPacketsRequest) Descriptor() ([]byte, []int) {
|
func (*ListRedPacketsRequest) Descriptor() ([]byte, []int) {
|
||||||
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{119}
|
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{121}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *ListRedPacketsRequest) GetRequestId() string {
|
func (x *ListRedPacketsRequest) GetRequestId() string {
|
||||||
@ -10825,7 +11003,7 @@ type ListRedPacketsResponse struct {
|
|||||||
|
|
||||||
func (x *ListRedPacketsResponse) Reset() {
|
func (x *ListRedPacketsResponse) Reset() {
|
||||||
*x = ListRedPacketsResponse{}
|
*x = ListRedPacketsResponse{}
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[120]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[122]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@ -10837,7 +11015,7 @@ func (x *ListRedPacketsResponse) String() string {
|
|||||||
func (*ListRedPacketsResponse) ProtoMessage() {}
|
func (*ListRedPacketsResponse) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *ListRedPacketsResponse) ProtoReflect() protoreflect.Message {
|
func (x *ListRedPacketsResponse) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[120]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[122]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@ -10850,7 +11028,7 @@ func (x *ListRedPacketsResponse) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use ListRedPacketsResponse.ProtoReflect.Descriptor instead.
|
// Deprecated: Use ListRedPacketsResponse.ProtoReflect.Descriptor instead.
|
||||||
func (*ListRedPacketsResponse) Descriptor() ([]byte, []int) {
|
func (*ListRedPacketsResponse) Descriptor() ([]byte, []int) {
|
||||||
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{120}
|
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{122}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *ListRedPacketsResponse) GetPackets() []*RedPacket {
|
func (x *ListRedPacketsResponse) GetPackets() []*RedPacket {
|
||||||
@ -10887,7 +11065,7 @@ type GetRedPacketRequest struct {
|
|||||||
|
|
||||||
func (x *GetRedPacketRequest) Reset() {
|
func (x *GetRedPacketRequest) Reset() {
|
||||||
*x = GetRedPacketRequest{}
|
*x = GetRedPacketRequest{}
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[121]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[123]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@ -10899,7 +11077,7 @@ func (x *GetRedPacketRequest) String() string {
|
|||||||
func (*GetRedPacketRequest) ProtoMessage() {}
|
func (*GetRedPacketRequest) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *GetRedPacketRequest) ProtoReflect() protoreflect.Message {
|
func (x *GetRedPacketRequest) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[121]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[123]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@ -10912,7 +11090,7 @@ func (x *GetRedPacketRequest) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use GetRedPacketRequest.ProtoReflect.Descriptor instead.
|
// Deprecated: Use GetRedPacketRequest.ProtoReflect.Descriptor instead.
|
||||||
func (*GetRedPacketRequest) Descriptor() ([]byte, []int) {
|
func (*GetRedPacketRequest) Descriptor() ([]byte, []int) {
|
||||||
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{121}
|
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{123}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *GetRedPacketRequest) GetRequestId() string {
|
func (x *GetRedPacketRequest) GetRequestId() string {
|
||||||
@ -10960,7 +11138,7 @@ type GetRedPacketResponse struct {
|
|||||||
|
|
||||||
func (x *GetRedPacketResponse) Reset() {
|
func (x *GetRedPacketResponse) Reset() {
|
||||||
*x = GetRedPacketResponse{}
|
*x = GetRedPacketResponse{}
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[122]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[124]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@ -10972,7 +11150,7 @@ func (x *GetRedPacketResponse) String() string {
|
|||||||
func (*GetRedPacketResponse) ProtoMessage() {}
|
func (*GetRedPacketResponse) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *GetRedPacketResponse) ProtoReflect() protoreflect.Message {
|
func (x *GetRedPacketResponse) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[122]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[124]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@ -10985,7 +11163,7 @@ func (x *GetRedPacketResponse) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use GetRedPacketResponse.ProtoReflect.Descriptor instead.
|
// Deprecated: Use GetRedPacketResponse.ProtoReflect.Descriptor instead.
|
||||||
func (*GetRedPacketResponse) Descriptor() ([]byte, []int) {
|
func (*GetRedPacketResponse) Descriptor() ([]byte, []int) {
|
||||||
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{122}
|
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{124}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *GetRedPacketResponse) GetPacket() *RedPacket {
|
func (x *GetRedPacketResponse) GetPacket() *RedPacket {
|
||||||
@ -11013,7 +11191,7 @@ type ExpireRedPacketsRequest struct {
|
|||||||
|
|
||||||
func (x *ExpireRedPacketsRequest) Reset() {
|
func (x *ExpireRedPacketsRequest) Reset() {
|
||||||
*x = ExpireRedPacketsRequest{}
|
*x = ExpireRedPacketsRequest{}
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[123]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[125]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@ -11025,7 +11203,7 @@ func (x *ExpireRedPacketsRequest) String() string {
|
|||||||
func (*ExpireRedPacketsRequest) ProtoMessage() {}
|
func (*ExpireRedPacketsRequest) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *ExpireRedPacketsRequest) ProtoReflect() protoreflect.Message {
|
func (x *ExpireRedPacketsRequest) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[123]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[125]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@ -11038,7 +11216,7 @@ func (x *ExpireRedPacketsRequest) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use ExpireRedPacketsRequest.ProtoReflect.Descriptor instead.
|
// Deprecated: Use ExpireRedPacketsRequest.ProtoReflect.Descriptor instead.
|
||||||
func (*ExpireRedPacketsRequest) Descriptor() ([]byte, []int) {
|
func (*ExpireRedPacketsRequest) Descriptor() ([]byte, []int) {
|
||||||
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{123}
|
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{125}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *ExpireRedPacketsRequest) GetRequestId() string {
|
func (x *ExpireRedPacketsRequest) GetRequestId() string {
|
||||||
@ -11073,7 +11251,7 @@ type ExpireRedPacketsResponse struct {
|
|||||||
|
|
||||||
func (x *ExpireRedPacketsResponse) Reset() {
|
func (x *ExpireRedPacketsResponse) Reset() {
|
||||||
*x = ExpireRedPacketsResponse{}
|
*x = ExpireRedPacketsResponse{}
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[124]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[126]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@ -11085,7 +11263,7 @@ func (x *ExpireRedPacketsResponse) String() string {
|
|||||||
func (*ExpireRedPacketsResponse) ProtoMessage() {}
|
func (*ExpireRedPacketsResponse) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *ExpireRedPacketsResponse) ProtoReflect() protoreflect.Message {
|
func (x *ExpireRedPacketsResponse) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[124]
|
mi := &file_proto_wallet_v1_wallet_proto_msgTypes[126]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@ -11098,7 +11276,7 @@ func (x *ExpireRedPacketsResponse) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use ExpireRedPacketsResponse.ProtoReflect.Descriptor instead.
|
// Deprecated: Use ExpireRedPacketsResponse.ProtoReflect.Descriptor instead.
|
||||||
func (*ExpireRedPacketsResponse) Descriptor() ([]byte, []int) {
|
func (*ExpireRedPacketsResponse) Descriptor() ([]byte, []int) {
|
||||||
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{124}
|
return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{126}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *ExpireRedPacketsResponse) GetExpiredCount() int32 {
|
func (x *ExpireRedPacketsResponse) GetExpiredCount() int32 {
|
||||||
@ -12117,6 +12295,22 @@ const file_proto_wallet_v1_wallet_proto_rawDesc = "" +
|
|||||||
"\x0etransaction_id\x18\x01 \x01(\tR\rtransactionId\x127\n" +
|
"\x0etransaction_id\x18\x01 \x01(\tR\rtransactionId\x127\n" +
|
||||||
"\abalance\x18\x02 \x01(\v2\x1d.hyapp.wallet.v1.AssetBalanceR\abalance\x12\x16\n" +
|
"\abalance\x18\x02 \x01(\v2\x1d.hyapp.wallet.v1.AssetBalanceR\abalance\x12\x16\n" +
|
||||||
"\x06amount\x18\x03 \x01(\x03R\x06amount\x12\"\n" +
|
"\x06amount\x18\x03 \x01(\x03R\x06amount\x12\"\n" +
|
||||||
|
"\rgranted_at_ms\x18\x04 \x01(\x03R\vgrantedAtMs\"\x92\x02\n" +
|
||||||
|
"\x1cCreditLuckyGiftRewardRequest\x12\x1d\n" +
|
||||||
|
"\n" +
|
||||||
|
"command_id\x18\x01 \x01(\tR\tcommandId\x12\x19\n" +
|
||||||
|
"\bapp_code\x18\x02 \x01(\tR\aappCode\x12$\n" +
|
||||||
|
"\x0etarget_user_id\x18\x03 \x01(\x03R\ftargetUserId\x12\x16\n" +
|
||||||
|
"\x06amount\x18\x04 \x01(\x03R\x06amount\x12\x17\n" +
|
||||||
|
"\adraw_id\x18\x05 \x01(\tR\x06drawId\x12\x17\n" +
|
||||||
|
"\aroom_id\x18\x06 \x01(\tR\x06roomId\x12\x17\n" +
|
||||||
|
"\agift_id\x18\a \x01(\tR\x06giftId\x12\x17\n" +
|
||||||
|
"\apool_id\x18\b \x01(\tR\x06poolId\x12\x16\n" +
|
||||||
|
"\x06reason\x18\t \x01(\tR\x06reason\"\xbb\x01\n" +
|
||||||
|
"\x1dCreditLuckyGiftRewardResponse\x12%\n" +
|
||||||
|
"\x0etransaction_id\x18\x01 \x01(\tR\rtransactionId\x127\n" +
|
||||||
|
"\abalance\x18\x02 \x01(\v2\x1d.hyapp.wallet.v1.AssetBalanceR\abalance\x12\x16\n" +
|
||||||
|
"\x06amount\x18\x03 \x01(\x03R\x06amount\x12\"\n" +
|
||||||
"\rgranted_at_ms\x18\x04 \x01(\x03R\vgrantedAtMs\"\x9a\x03\n" +
|
"\rgranted_at_ms\x18\x04 \x01(\x03R\vgrantedAtMs\"\x9a\x03\n" +
|
||||||
"\x1aApplyGameCoinChangeRequest\x12\x1d\n" +
|
"\x1aApplyGameCoinChangeRequest\x12\x1d\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
@ -12280,7 +12474,7 @@ const file_proto_wallet_v1_wallet_proto_rawDesc = "" +
|
|||||||
"\x18ExpireRedPacketsResponse\x12#\n" +
|
"\x18ExpireRedPacketsResponse\x12#\n" +
|
||||||
"\rexpired_count\x18\x01 \x01(\x05R\fexpiredCount\x12'\n" +
|
"\rexpired_count\x18\x01 \x01(\x05R\fexpiredCount\x12'\n" +
|
||||||
"\x0frefunded_amount\x18\x02 \x01(\x03R\x0erefundedAmount\x12$\n" +
|
"\x0frefunded_amount\x18\x02 \x01(\x03R\x0erefundedAmount\x12$\n" +
|
||||||
"\x0eserver_time_ms\x18\x03 \x01(\x03R\fserverTimeMs2\x86-\n" +
|
"\x0eserver_time_ms\x18\x03 \x01(\x03R\fserverTimeMs2\xfe-\n" +
|
||||||
"\rWalletService\x12R\n" +
|
"\rWalletService\x12R\n" +
|
||||||
"\tDebitGift\x12!.hyapp.wallet.v1.DebitGiftRequest\x1a\".hyapp.wallet.v1.DebitGiftResponse\x12X\n" +
|
"\tDebitGift\x12!.hyapp.wallet.v1.DebitGiftRequest\x1a\".hyapp.wallet.v1.DebitGiftResponse\x12X\n" +
|
||||||
"\vGetBalances\x12#.hyapp.wallet.v1.GetBalancesRequest\x1a$.hyapp.wallet.v1.GetBalancesResponse\x12g\n" +
|
"\vGetBalances\x12#.hyapp.wallet.v1.GetBalancesRequest\x1a$.hyapp.wallet.v1.GetBalancesResponse\x12g\n" +
|
||||||
@ -12327,7 +12521,8 @@ const file_proto_wallet_v1_wallet_proto_rawDesc = "" +
|
|||||||
"\bGrantVip\x12 .hyapp.wallet.v1.GrantVipRequest\x1a!.hyapp.wallet.v1.GrantVipResponse\x12m\n" +
|
"\bGrantVip\x12 .hyapp.wallet.v1.GrantVipRequest\x1a!.hyapp.wallet.v1.GrantVipResponse\x12m\n" +
|
||||||
"\x12ListAdminVipLevels\x12*.hyapp.wallet.v1.ListAdminVipLevelsRequest\x1a+.hyapp.wallet.v1.ListAdminVipLevelsResponse\x12s\n" +
|
"\x12ListAdminVipLevels\x12*.hyapp.wallet.v1.ListAdminVipLevelsRequest\x1a+.hyapp.wallet.v1.ListAdminVipLevelsResponse\x12s\n" +
|
||||||
"\x14UpdateAdminVipLevels\x12,.hyapp.wallet.v1.UpdateAdminVipLevelsRequest\x1a-.hyapp.wallet.v1.UpdateAdminVipLevelsResponse\x12g\n" +
|
"\x14UpdateAdminVipLevels\x12,.hyapp.wallet.v1.UpdateAdminVipLevelsRequest\x1a-.hyapp.wallet.v1.UpdateAdminVipLevelsResponse\x12g\n" +
|
||||||
"\x10CreditTaskReward\x12(.hyapp.wallet.v1.CreditTaskRewardRequest\x1a).hyapp.wallet.v1.CreditTaskRewardResponse\x12p\n" +
|
"\x10CreditTaskReward\x12(.hyapp.wallet.v1.CreditTaskRewardRequest\x1a).hyapp.wallet.v1.CreditTaskRewardResponse\x12v\n" +
|
||||||
|
"\x15CreditLuckyGiftReward\x12-.hyapp.wallet.v1.CreditLuckyGiftRewardRequest\x1a..hyapp.wallet.v1.CreditLuckyGiftRewardResponse\x12p\n" +
|
||||||
"\x13ApplyGameCoinChange\x12+.hyapp.wallet.v1.ApplyGameCoinChangeRequest\x1a,.hyapp.wallet.v1.ApplyGameCoinChangeResponse\x12m\n" +
|
"\x13ApplyGameCoinChange\x12+.hyapp.wallet.v1.ApplyGameCoinChangeRequest\x1a,.hyapp.wallet.v1.ApplyGameCoinChangeResponse\x12m\n" +
|
||||||
"\x12GetRedPacketConfig\x12*.hyapp.wallet.v1.GetRedPacketConfigRequest\x1a+.hyapp.wallet.v1.GetRedPacketConfigResponse\x12v\n" +
|
"\x12GetRedPacketConfig\x12*.hyapp.wallet.v1.GetRedPacketConfigRequest\x1a+.hyapp.wallet.v1.GetRedPacketConfigResponse\x12v\n" +
|
||||||
"\x15UpdateRedPacketConfig\x12-.hyapp.wallet.v1.UpdateRedPacketConfigRequest\x1a..hyapp.wallet.v1.UpdateRedPacketConfigResponse\x12d\n" +
|
"\x15UpdateRedPacketConfig\x12-.hyapp.wallet.v1.UpdateRedPacketConfigRequest\x1a..hyapp.wallet.v1.UpdateRedPacketConfigResponse\x12d\n" +
|
||||||
@ -12349,7 +12544,7 @@ func file_proto_wallet_v1_wallet_proto_rawDescGZIP() []byte {
|
|||||||
return file_proto_wallet_v1_wallet_proto_rawDescData
|
return file_proto_wallet_v1_wallet_proto_rawDescData
|
||||||
}
|
}
|
||||||
|
|
||||||
var file_proto_wallet_v1_wallet_proto_msgTypes = make([]protoimpl.MessageInfo, 125)
|
var file_proto_wallet_v1_wallet_proto_msgTypes = make([]protoimpl.MessageInfo, 127)
|
||||||
var file_proto_wallet_v1_wallet_proto_goTypes = []any{
|
var file_proto_wallet_v1_wallet_proto_goTypes = []any{
|
||||||
(*DebitGiftRequest)(nil), // 0: hyapp.wallet.v1.DebitGiftRequest
|
(*DebitGiftRequest)(nil), // 0: hyapp.wallet.v1.DebitGiftRequest
|
||||||
(*DebitGiftResponse)(nil), // 1: hyapp.wallet.v1.DebitGiftResponse
|
(*DebitGiftResponse)(nil), // 1: hyapp.wallet.v1.DebitGiftResponse
|
||||||
@ -12457,25 +12652,27 @@ var file_proto_wallet_v1_wallet_proto_goTypes = []any{
|
|||||||
(*UpdateAdminVipLevelsResponse)(nil), // 103: hyapp.wallet.v1.UpdateAdminVipLevelsResponse
|
(*UpdateAdminVipLevelsResponse)(nil), // 103: hyapp.wallet.v1.UpdateAdminVipLevelsResponse
|
||||||
(*CreditTaskRewardRequest)(nil), // 104: hyapp.wallet.v1.CreditTaskRewardRequest
|
(*CreditTaskRewardRequest)(nil), // 104: hyapp.wallet.v1.CreditTaskRewardRequest
|
||||||
(*CreditTaskRewardResponse)(nil), // 105: hyapp.wallet.v1.CreditTaskRewardResponse
|
(*CreditTaskRewardResponse)(nil), // 105: hyapp.wallet.v1.CreditTaskRewardResponse
|
||||||
(*ApplyGameCoinChangeRequest)(nil), // 106: hyapp.wallet.v1.ApplyGameCoinChangeRequest
|
(*CreditLuckyGiftRewardRequest)(nil), // 106: hyapp.wallet.v1.CreditLuckyGiftRewardRequest
|
||||||
(*ApplyGameCoinChangeResponse)(nil), // 107: hyapp.wallet.v1.ApplyGameCoinChangeResponse
|
(*CreditLuckyGiftRewardResponse)(nil), // 107: hyapp.wallet.v1.CreditLuckyGiftRewardResponse
|
||||||
(*RedPacketConfig)(nil), // 108: hyapp.wallet.v1.RedPacketConfig
|
(*ApplyGameCoinChangeRequest)(nil), // 108: hyapp.wallet.v1.ApplyGameCoinChangeRequest
|
||||||
(*RedPacketClaim)(nil), // 109: hyapp.wallet.v1.RedPacketClaim
|
(*ApplyGameCoinChangeResponse)(nil), // 109: hyapp.wallet.v1.ApplyGameCoinChangeResponse
|
||||||
(*RedPacket)(nil), // 110: hyapp.wallet.v1.RedPacket
|
(*RedPacketConfig)(nil), // 110: hyapp.wallet.v1.RedPacketConfig
|
||||||
(*GetRedPacketConfigRequest)(nil), // 111: hyapp.wallet.v1.GetRedPacketConfigRequest
|
(*RedPacketClaim)(nil), // 111: hyapp.wallet.v1.RedPacketClaim
|
||||||
(*GetRedPacketConfigResponse)(nil), // 112: hyapp.wallet.v1.GetRedPacketConfigResponse
|
(*RedPacket)(nil), // 112: hyapp.wallet.v1.RedPacket
|
||||||
(*UpdateRedPacketConfigRequest)(nil), // 113: hyapp.wallet.v1.UpdateRedPacketConfigRequest
|
(*GetRedPacketConfigRequest)(nil), // 113: hyapp.wallet.v1.GetRedPacketConfigRequest
|
||||||
(*UpdateRedPacketConfigResponse)(nil), // 114: hyapp.wallet.v1.UpdateRedPacketConfigResponse
|
(*GetRedPacketConfigResponse)(nil), // 114: hyapp.wallet.v1.GetRedPacketConfigResponse
|
||||||
(*CreateRedPacketRequest)(nil), // 115: hyapp.wallet.v1.CreateRedPacketRequest
|
(*UpdateRedPacketConfigRequest)(nil), // 115: hyapp.wallet.v1.UpdateRedPacketConfigRequest
|
||||||
(*CreateRedPacketResponse)(nil), // 116: hyapp.wallet.v1.CreateRedPacketResponse
|
(*UpdateRedPacketConfigResponse)(nil), // 116: hyapp.wallet.v1.UpdateRedPacketConfigResponse
|
||||||
(*ClaimRedPacketRequest)(nil), // 117: hyapp.wallet.v1.ClaimRedPacketRequest
|
(*CreateRedPacketRequest)(nil), // 117: hyapp.wallet.v1.CreateRedPacketRequest
|
||||||
(*ClaimRedPacketResponse)(nil), // 118: hyapp.wallet.v1.ClaimRedPacketResponse
|
(*CreateRedPacketResponse)(nil), // 118: hyapp.wallet.v1.CreateRedPacketResponse
|
||||||
(*ListRedPacketsRequest)(nil), // 119: hyapp.wallet.v1.ListRedPacketsRequest
|
(*ClaimRedPacketRequest)(nil), // 119: hyapp.wallet.v1.ClaimRedPacketRequest
|
||||||
(*ListRedPacketsResponse)(nil), // 120: hyapp.wallet.v1.ListRedPacketsResponse
|
(*ClaimRedPacketResponse)(nil), // 120: hyapp.wallet.v1.ClaimRedPacketResponse
|
||||||
(*GetRedPacketRequest)(nil), // 121: hyapp.wallet.v1.GetRedPacketRequest
|
(*ListRedPacketsRequest)(nil), // 121: hyapp.wallet.v1.ListRedPacketsRequest
|
||||||
(*GetRedPacketResponse)(nil), // 122: hyapp.wallet.v1.GetRedPacketResponse
|
(*ListRedPacketsResponse)(nil), // 122: hyapp.wallet.v1.ListRedPacketsResponse
|
||||||
(*ExpireRedPacketsRequest)(nil), // 123: hyapp.wallet.v1.ExpireRedPacketsRequest
|
(*GetRedPacketRequest)(nil), // 123: hyapp.wallet.v1.GetRedPacketRequest
|
||||||
(*ExpireRedPacketsResponse)(nil), // 124: hyapp.wallet.v1.ExpireRedPacketsResponse
|
(*GetRedPacketResponse)(nil), // 124: hyapp.wallet.v1.GetRedPacketResponse
|
||||||
|
(*ExpireRedPacketsRequest)(nil), // 125: hyapp.wallet.v1.ExpireRedPacketsRequest
|
||||||
|
(*ExpireRedPacketsResponse)(nil), // 126: hyapp.wallet.v1.ExpireRedPacketsResponse
|
||||||
}
|
}
|
||||||
var file_proto_wallet_v1_wallet_proto_depIdxs = []int32{
|
var file_proto_wallet_v1_wallet_proto_depIdxs = []int32{
|
||||||
2, // 0: hyapp.wallet.v1.GetBalancesResponse.balances:type_name -> hyapp.wallet.v1.AssetBalance
|
2, // 0: hyapp.wallet.v1.GetBalancesResponse.balances:type_name -> hyapp.wallet.v1.AssetBalance
|
||||||
@ -12527,126 +12724,129 @@ var file_proto_wallet_v1_wallet_proto_depIdxs = []int32{
|
|||||||
99, // 46: hyapp.wallet.v1.UpdateAdminVipLevelsRequest.levels:type_name -> hyapp.wallet.v1.AdminVipLevelInput
|
99, // 46: hyapp.wallet.v1.UpdateAdminVipLevelsRequest.levels:type_name -> hyapp.wallet.v1.AdminVipLevelInput
|
||||||
89, // 47: hyapp.wallet.v1.UpdateAdminVipLevelsResponse.levels:type_name -> hyapp.wallet.v1.VipLevel
|
89, // 47: hyapp.wallet.v1.UpdateAdminVipLevelsResponse.levels:type_name -> hyapp.wallet.v1.VipLevel
|
||||||
2, // 48: hyapp.wallet.v1.CreditTaskRewardResponse.balance:type_name -> hyapp.wallet.v1.AssetBalance
|
2, // 48: hyapp.wallet.v1.CreditTaskRewardResponse.balance:type_name -> hyapp.wallet.v1.AssetBalance
|
||||||
109, // 49: hyapp.wallet.v1.RedPacket.claims:type_name -> hyapp.wallet.v1.RedPacketClaim
|
2, // 49: hyapp.wallet.v1.CreditLuckyGiftRewardResponse.balance:type_name -> hyapp.wallet.v1.AssetBalance
|
||||||
108, // 50: hyapp.wallet.v1.GetRedPacketConfigResponse.config:type_name -> hyapp.wallet.v1.RedPacketConfig
|
111, // 50: hyapp.wallet.v1.RedPacket.claims:type_name -> hyapp.wallet.v1.RedPacketClaim
|
||||||
108, // 51: hyapp.wallet.v1.UpdateRedPacketConfigResponse.config:type_name -> hyapp.wallet.v1.RedPacketConfig
|
110, // 51: hyapp.wallet.v1.GetRedPacketConfigResponse.config:type_name -> hyapp.wallet.v1.RedPacketConfig
|
||||||
110, // 52: hyapp.wallet.v1.CreateRedPacketResponse.packet:type_name -> hyapp.wallet.v1.RedPacket
|
110, // 52: hyapp.wallet.v1.UpdateRedPacketConfigResponse.config:type_name -> hyapp.wallet.v1.RedPacketConfig
|
||||||
109, // 53: hyapp.wallet.v1.ClaimRedPacketResponse.claim:type_name -> hyapp.wallet.v1.RedPacketClaim
|
112, // 53: hyapp.wallet.v1.CreateRedPacketResponse.packet:type_name -> hyapp.wallet.v1.RedPacket
|
||||||
110, // 54: hyapp.wallet.v1.ListRedPacketsResponse.packets:type_name -> hyapp.wallet.v1.RedPacket
|
111, // 54: hyapp.wallet.v1.ClaimRedPacketResponse.claim:type_name -> hyapp.wallet.v1.RedPacketClaim
|
||||||
110, // 55: hyapp.wallet.v1.GetRedPacketResponse.packet:type_name -> hyapp.wallet.v1.RedPacket
|
112, // 55: hyapp.wallet.v1.ListRedPacketsResponse.packets:type_name -> hyapp.wallet.v1.RedPacket
|
||||||
0, // 56: hyapp.wallet.v1.WalletService.DebitGift:input_type -> hyapp.wallet.v1.DebitGiftRequest
|
112, // 56: hyapp.wallet.v1.GetRedPacketResponse.packet:type_name -> hyapp.wallet.v1.RedPacket
|
||||||
3, // 57: hyapp.wallet.v1.WalletService.GetBalances:input_type -> hyapp.wallet.v1.GetBalancesRequest
|
0, // 57: hyapp.wallet.v1.WalletService.DebitGift:input_type -> hyapp.wallet.v1.DebitGiftRequest
|
||||||
5, // 58: hyapp.wallet.v1.WalletService.AdminCreditAsset:input_type -> hyapp.wallet.v1.AdminCreditAssetRequest
|
3, // 58: hyapp.wallet.v1.WalletService.GetBalances:input_type -> hyapp.wallet.v1.GetBalancesRequest
|
||||||
7, // 59: hyapp.wallet.v1.WalletService.AdminCreditCoinSellerStock:input_type -> hyapp.wallet.v1.AdminCreditCoinSellerStockRequest
|
5, // 59: hyapp.wallet.v1.WalletService.AdminCreditAsset:input_type -> hyapp.wallet.v1.AdminCreditAssetRequest
|
||||||
9, // 60: hyapp.wallet.v1.WalletService.TransferCoinFromSeller:input_type -> hyapp.wallet.v1.TransferCoinFromSellerRequest
|
7, // 60: hyapp.wallet.v1.WalletService.AdminCreditCoinSellerStock:input_type -> hyapp.wallet.v1.AdminCreditCoinSellerStockRequest
|
||||||
20, // 61: hyapp.wallet.v1.WalletService.ListResources:input_type -> hyapp.wallet.v1.ListResourcesRequest
|
9, // 61: hyapp.wallet.v1.WalletService.TransferCoinFromSeller:input_type -> hyapp.wallet.v1.TransferCoinFromSellerRequest
|
||||||
22, // 62: hyapp.wallet.v1.WalletService.GetResource:input_type -> hyapp.wallet.v1.GetResourceRequest
|
20, // 62: hyapp.wallet.v1.WalletService.ListResources:input_type -> hyapp.wallet.v1.ListResourcesRequest
|
||||||
24, // 63: hyapp.wallet.v1.WalletService.CreateResource:input_type -> hyapp.wallet.v1.CreateResourceRequest
|
22, // 63: hyapp.wallet.v1.WalletService.GetResource:input_type -> hyapp.wallet.v1.GetResourceRequest
|
||||||
25, // 64: hyapp.wallet.v1.WalletService.UpdateResource:input_type -> hyapp.wallet.v1.UpdateResourceRequest
|
24, // 64: hyapp.wallet.v1.WalletService.CreateResource:input_type -> hyapp.wallet.v1.CreateResourceRequest
|
||||||
26, // 65: hyapp.wallet.v1.WalletService.SetResourceStatus:input_type -> hyapp.wallet.v1.SetResourceStatusRequest
|
25, // 65: hyapp.wallet.v1.WalletService.UpdateResource:input_type -> hyapp.wallet.v1.UpdateResourceRequest
|
||||||
28, // 66: hyapp.wallet.v1.WalletService.ListResourceGroups:input_type -> hyapp.wallet.v1.ListResourceGroupsRequest
|
26, // 66: hyapp.wallet.v1.WalletService.SetResourceStatus:input_type -> hyapp.wallet.v1.SetResourceStatusRequest
|
||||||
30, // 67: hyapp.wallet.v1.WalletService.GetResourceGroup:input_type -> hyapp.wallet.v1.GetResourceGroupRequest
|
28, // 67: hyapp.wallet.v1.WalletService.ListResourceGroups:input_type -> hyapp.wallet.v1.ListResourceGroupsRequest
|
||||||
32, // 68: hyapp.wallet.v1.WalletService.CreateResourceGroup:input_type -> hyapp.wallet.v1.CreateResourceGroupRequest
|
30, // 68: hyapp.wallet.v1.WalletService.GetResourceGroup:input_type -> hyapp.wallet.v1.GetResourceGroupRequest
|
||||||
33, // 69: hyapp.wallet.v1.WalletService.UpdateResourceGroup:input_type -> hyapp.wallet.v1.UpdateResourceGroupRequest
|
32, // 69: hyapp.wallet.v1.WalletService.CreateResourceGroup:input_type -> hyapp.wallet.v1.CreateResourceGroupRequest
|
||||||
34, // 70: hyapp.wallet.v1.WalletService.SetResourceGroupStatus:input_type -> hyapp.wallet.v1.SetResourceGroupStatusRequest
|
33, // 70: hyapp.wallet.v1.WalletService.UpdateResourceGroup:input_type -> hyapp.wallet.v1.UpdateResourceGroupRequest
|
||||||
36, // 71: hyapp.wallet.v1.WalletService.ListGiftConfigs:input_type -> hyapp.wallet.v1.ListGiftConfigsRequest
|
34, // 71: hyapp.wallet.v1.WalletService.SetResourceGroupStatus:input_type -> hyapp.wallet.v1.SetResourceGroupStatusRequest
|
||||||
38, // 72: hyapp.wallet.v1.WalletService.ListGiftTypeConfigs:input_type -> hyapp.wallet.v1.ListGiftTypeConfigsRequest
|
36, // 72: hyapp.wallet.v1.WalletService.ListGiftConfigs:input_type -> hyapp.wallet.v1.ListGiftConfigsRequest
|
||||||
42, // 73: hyapp.wallet.v1.WalletService.CreateGiftConfig:input_type -> hyapp.wallet.v1.CreateGiftConfigRequest
|
38, // 73: hyapp.wallet.v1.WalletService.ListGiftTypeConfigs:input_type -> hyapp.wallet.v1.ListGiftTypeConfigsRequest
|
||||||
43, // 74: hyapp.wallet.v1.WalletService.UpdateGiftConfig:input_type -> hyapp.wallet.v1.UpdateGiftConfigRequest
|
42, // 74: hyapp.wallet.v1.WalletService.CreateGiftConfig:input_type -> hyapp.wallet.v1.CreateGiftConfigRequest
|
||||||
44, // 75: hyapp.wallet.v1.WalletService.SetGiftConfigStatus:input_type -> hyapp.wallet.v1.SetGiftConfigStatusRequest
|
43, // 75: hyapp.wallet.v1.WalletService.UpdateGiftConfig:input_type -> hyapp.wallet.v1.UpdateGiftConfigRequest
|
||||||
40, // 76: hyapp.wallet.v1.WalletService.UpsertGiftTypeConfig:input_type -> hyapp.wallet.v1.UpsertGiftTypeConfigRequest
|
44, // 76: hyapp.wallet.v1.WalletService.SetGiftConfigStatus:input_type -> hyapp.wallet.v1.SetGiftConfigStatusRequest
|
||||||
46, // 77: hyapp.wallet.v1.WalletService.GrantResource:input_type -> hyapp.wallet.v1.GrantResourceRequest
|
40, // 77: hyapp.wallet.v1.WalletService.UpsertGiftTypeConfig:input_type -> hyapp.wallet.v1.UpsertGiftTypeConfigRequest
|
||||||
47, // 78: hyapp.wallet.v1.WalletService.GrantResourceGroup:input_type -> hyapp.wallet.v1.GrantResourceGroupRequest
|
46, // 78: hyapp.wallet.v1.WalletService.GrantResource:input_type -> hyapp.wallet.v1.GrantResourceRequest
|
||||||
49, // 79: hyapp.wallet.v1.WalletService.ListUserResources:input_type -> hyapp.wallet.v1.ListUserResourcesRequest
|
47, // 79: hyapp.wallet.v1.WalletService.GrantResourceGroup:input_type -> hyapp.wallet.v1.GrantResourceGroupRequest
|
||||||
51, // 80: hyapp.wallet.v1.WalletService.EquipUserResource:input_type -> hyapp.wallet.v1.EquipUserResourceRequest
|
49, // 80: hyapp.wallet.v1.WalletService.ListUserResources:input_type -> hyapp.wallet.v1.ListUserResourcesRequest
|
||||||
53, // 81: hyapp.wallet.v1.WalletService.ListResourceGrants:input_type -> hyapp.wallet.v1.ListResourceGrantsRequest
|
51, // 81: hyapp.wallet.v1.WalletService.EquipUserResource:input_type -> hyapp.wallet.v1.EquipUserResourceRequest
|
||||||
56, // 82: hyapp.wallet.v1.WalletService.ListRechargeBills:input_type -> hyapp.wallet.v1.ListRechargeBillsRequest
|
53, // 82: hyapp.wallet.v1.WalletService.ListResourceGrants:input_type -> hyapp.wallet.v1.ListResourceGrantsRequest
|
||||||
59, // 83: hyapp.wallet.v1.WalletService.GetWalletOverview:input_type -> hyapp.wallet.v1.GetWalletOverviewRequest
|
56, // 83: hyapp.wallet.v1.WalletService.ListRechargeBills:input_type -> hyapp.wallet.v1.ListRechargeBillsRequest
|
||||||
62, // 84: hyapp.wallet.v1.WalletService.GetWalletValueSummary:input_type -> hyapp.wallet.v1.GetWalletValueSummaryRequest
|
59, // 84: hyapp.wallet.v1.WalletService.GetWalletOverview:input_type -> hyapp.wallet.v1.GetWalletOverviewRequest
|
||||||
65, // 85: hyapp.wallet.v1.WalletService.GetUserGiftWall:input_type -> hyapp.wallet.v1.GetUserGiftWallRequest
|
62, // 85: hyapp.wallet.v1.WalletService.GetWalletValueSummary:input_type -> hyapp.wallet.v1.GetWalletValueSummaryRequest
|
||||||
68, // 86: hyapp.wallet.v1.WalletService.ListRechargeProducts:input_type -> hyapp.wallet.v1.ListRechargeProductsRequest
|
65, // 86: hyapp.wallet.v1.WalletService.GetUserGiftWall:input_type -> hyapp.wallet.v1.GetUserGiftWallRequest
|
||||||
70, // 87: hyapp.wallet.v1.WalletService.ConfirmGooglePayment:input_type -> hyapp.wallet.v1.ConfirmGooglePaymentRequest
|
68, // 87: hyapp.wallet.v1.WalletService.ListRechargeProducts:input_type -> hyapp.wallet.v1.ListRechargeProductsRequest
|
||||||
72, // 88: hyapp.wallet.v1.WalletService.ListAdminRechargeProducts:input_type -> hyapp.wallet.v1.ListAdminRechargeProductsRequest
|
70, // 88: hyapp.wallet.v1.WalletService.ConfirmGooglePayment:input_type -> hyapp.wallet.v1.ConfirmGooglePaymentRequest
|
||||||
74, // 89: hyapp.wallet.v1.WalletService.CreateRechargeProduct:input_type -> hyapp.wallet.v1.CreateRechargeProductRequest
|
72, // 89: hyapp.wallet.v1.WalletService.ListAdminRechargeProducts:input_type -> hyapp.wallet.v1.ListAdminRechargeProductsRequest
|
||||||
75, // 90: hyapp.wallet.v1.WalletService.UpdateRechargeProduct:input_type -> hyapp.wallet.v1.UpdateRechargeProductRequest
|
74, // 90: hyapp.wallet.v1.WalletService.CreateRechargeProduct:input_type -> hyapp.wallet.v1.CreateRechargeProductRequest
|
||||||
76, // 91: hyapp.wallet.v1.WalletService.DeleteRechargeProduct:input_type -> hyapp.wallet.v1.DeleteRechargeProductRequest
|
75, // 91: hyapp.wallet.v1.WalletService.UpdateRechargeProduct:input_type -> hyapp.wallet.v1.UpdateRechargeProductRequest
|
||||||
80, // 92: hyapp.wallet.v1.WalletService.GetDiamondExchangeConfig:input_type -> hyapp.wallet.v1.GetDiamondExchangeConfigRequest
|
76, // 92: hyapp.wallet.v1.WalletService.DeleteRechargeProduct:input_type -> hyapp.wallet.v1.DeleteRechargeProductRequest
|
||||||
83, // 93: hyapp.wallet.v1.WalletService.ListWalletTransactions:input_type -> hyapp.wallet.v1.ListWalletTransactionsRequest
|
80, // 93: hyapp.wallet.v1.WalletService.GetDiamondExchangeConfig:input_type -> hyapp.wallet.v1.GetDiamondExchangeConfigRequest
|
||||||
86, // 94: hyapp.wallet.v1.WalletService.ApplyWithdrawal:input_type -> hyapp.wallet.v1.ApplyWithdrawalRequest
|
83, // 94: hyapp.wallet.v1.WalletService.ListWalletTransactions:input_type -> hyapp.wallet.v1.ListWalletTransactionsRequest
|
||||||
91, // 95: hyapp.wallet.v1.WalletService.ListVipPackages:input_type -> hyapp.wallet.v1.ListVipPackagesRequest
|
86, // 95: hyapp.wallet.v1.WalletService.ApplyWithdrawal:input_type -> hyapp.wallet.v1.ApplyWithdrawalRequest
|
||||||
93, // 96: hyapp.wallet.v1.WalletService.GetMyVip:input_type -> hyapp.wallet.v1.GetMyVipRequest
|
91, // 96: hyapp.wallet.v1.WalletService.ListVipPackages:input_type -> hyapp.wallet.v1.ListVipPackagesRequest
|
||||||
95, // 97: hyapp.wallet.v1.WalletService.PurchaseVip:input_type -> hyapp.wallet.v1.PurchaseVipRequest
|
93, // 97: hyapp.wallet.v1.WalletService.GetMyVip:input_type -> hyapp.wallet.v1.GetMyVipRequest
|
||||||
97, // 98: hyapp.wallet.v1.WalletService.GrantVip:input_type -> hyapp.wallet.v1.GrantVipRequest
|
95, // 98: hyapp.wallet.v1.WalletService.PurchaseVip:input_type -> hyapp.wallet.v1.PurchaseVipRequest
|
||||||
100, // 99: hyapp.wallet.v1.WalletService.ListAdminVipLevels:input_type -> hyapp.wallet.v1.ListAdminVipLevelsRequest
|
97, // 99: hyapp.wallet.v1.WalletService.GrantVip:input_type -> hyapp.wallet.v1.GrantVipRequest
|
||||||
102, // 100: hyapp.wallet.v1.WalletService.UpdateAdminVipLevels:input_type -> hyapp.wallet.v1.UpdateAdminVipLevelsRequest
|
100, // 100: hyapp.wallet.v1.WalletService.ListAdminVipLevels:input_type -> hyapp.wallet.v1.ListAdminVipLevelsRequest
|
||||||
104, // 101: hyapp.wallet.v1.WalletService.CreditTaskReward:input_type -> hyapp.wallet.v1.CreditTaskRewardRequest
|
102, // 101: hyapp.wallet.v1.WalletService.UpdateAdminVipLevels:input_type -> hyapp.wallet.v1.UpdateAdminVipLevelsRequest
|
||||||
106, // 102: hyapp.wallet.v1.WalletService.ApplyGameCoinChange:input_type -> hyapp.wallet.v1.ApplyGameCoinChangeRequest
|
104, // 102: hyapp.wallet.v1.WalletService.CreditTaskReward:input_type -> hyapp.wallet.v1.CreditTaskRewardRequest
|
||||||
111, // 103: hyapp.wallet.v1.WalletService.GetRedPacketConfig:input_type -> hyapp.wallet.v1.GetRedPacketConfigRequest
|
106, // 103: hyapp.wallet.v1.WalletService.CreditLuckyGiftReward:input_type -> hyapp.wallet.v1.CreditLuckyGiftRewardRequest
|
||||||
113, // 104: hyapp.wallet.v1.WalletService.UpdateRedPacketConfig:input_type -> hyapp.wallet.v1.UpdateRedPacketConfigRequest
|
108, // 104: hyapp.wallet.v1.WalletService.ApplyGameCoinChange:input_type -> hyapp.wallet.v1.ApplyGameCoinChangeRequest
|
||||||
115, // 105: hyapp.wallet.v1.WalletService.CreateRedPacket:input_type -> hyapp.wallet.v1.CreateRedPacketRequest
|
113, // 105: hyapp.wallet.v1.WalletService.GetRedPacketConfig:input_type -> hyapp.wallet.v1.GetRedPacketConfigRequest
|
||||||
117, // 106: hyapp.wallet.v1.WalletService.ClaimRedPacket:input_type -> hyapp.wallet.v1.ClaimRedPacketRequest
|
115, // 106: hyapp.wallet.v1.WalletService.UpdateRedPacketConfig:input_type -> hyapp.wallet.v1.UpdateRedPacketConfigRequest
|
||||||
119, // 107: hyapp.wallet.v1.WalletService.ListRedPackets:input_type -> hyapp.wallet.v1.ListRedPacketsRequest
|
117, // 107: hyapp.wallet.v1.WalletService.CreateRedPacket:input_type -> hyapp.wallet.v1.CreateRedPacketRequest
|
||||||
121, // 108: hyapp.wallet.v1.WalletService.GetRedPacket:input_type -> hyapp.wallet.v1.GetRedPacketRequest
|
119, // 108: hyapp.wallet.v1.WalletService.ClaimRedPacket:input_type -> hyapp.wallet.v1.ClaimRedPacketRequest
|
||||||
123, // 109: hyapp.wallet.v1.WalletService.ExpireRedPackets:input_type -> hyapp.wallet.v1.ExpireRedPacketsRequest
|
121, // 109: hyapp.wallet.v1.WalletService.ListRedPackets:input_type -> hyapp.wallet.v1.ListRedPacketsRequest
|
||||||
1, // 110: hyapp.wallet.v1.WalletService.DebitGift:output_type -> hyapp.wallet.v1.DebitGiftResponse
|
123, // 110: hyapp.wallet.v1.WalletService.GetRedPacket:input_type -> hyapp.wallet.v1.GetRedPacketRequest
|
||||||
4, // 111: hyapp.wallet.v1.WalletService.GetBalances:output_type -> hyapp.wallet.v1.GetBalancesResponse
|
125, // 111: hyapp.wallet.v1.WalletService.ExpireRedPackets:input_type -> hyapp.wallet.v1.ExpireRedPacketsRequest
|
||||||
6, // 112: hyapp.wallet.v1.WalletService.AdminCreditAsset:output_type -> hyapp.wallet.v1.AdminCreditAssetResponse
|
1, // 112: hyapp.wallet.v1.WalletService.DebitGift:output_type -> hyapp.wallet.v1.DebitGiftResponse
|
||||||
8, // 113: hyapp.wallet.v1.WalletService.AdminCreditCoinSellerStock:output_type -> hyapp.wallet.v1.AdminCreditCoinSellerStockResponse
|
4, // 113: hyapp.wallet.v1.WalletService.GetBalances:output_type -> hyapp.wallet.v1.GetBalancesResponse
|
||||||
10, // 114: hyapp.wallet.v1.WalletService.TransferCoinFromSeller:output_type -> hyapp.wallet.v1.TransferCoinFromSellerResponse
|
6, // 114: hyapp.wallet.v1.WalletService.AdminCreditAsset:output_type -> hyapp.wallet.v1.AdminCreditAssetResponse
|
||||||
21, // 115: hyapp.wallet.v1.WalletService.ListResources:output_type -> hyapp.wallet.v1.ListResourcesResponse
|
8, // 115: hyapp.wallet.v1.WalletService.AdminCreditCoinSellerStock:output_type -> hyapp.wallet.v1.AdminCreditCoinSellerStockResponse
|
||||||
23, // 116: hyapp.wallet.v1.WalletService.GetResource:output_type -> hyapp.wallet.v1.GetResourceResponse
|
10, // 116: hyapp.wallet.v1.WalletService.TransferCoinFromSeller:output_type -> hyapp.wallet.v1.TransferCoinFromSellerResponse
|
||||||
27, // 117: hyapp.wallet.v1.WalletService.CreateResource:output_type -> hyapp.wallet.v1.ResourceResponse
|
21, // 117: hyapp.wallet.v1.WalletService.ListResources:output_type -> hyapp.wallet.v1.ListResourcesResponse
|
||||||
27, // 118: hyapp.wallet.v1.WalletService.UpdateResource:output_type -> hyapp.wallet.v1.ResourceResponse
|
23, // 118: hyapp.wallet.v1.WalletService.GetResource:output_type -> hyapp.wallet.v1.GetResourceResponse
|
||||||
27, // 119: hyapp.wallet.v1.WalletService.SetResourceStatus:output_type -> hyapp.wallet.v1.ResourceResponse
|
27, // 119: hyapp.wallet.v1.WalletService.CreateResource:output_type -> hyapp.wallet.v1.ResourceResponse
|
||||||
29, // 120: hyapp.wallet.v1.WalletService.ListResourceGroups:output_type -> hyapp.wallet.v1.ListResourceGroupsResponse
|
27, // 120: hyapp.wallet.v1.WalletService.UpdateResource:output_type -> hyapp.wallet.v1.ResourceResponse
|
||||||
31, // 121: hyapp.wallet.v1.WalletService.GetResourceGroup:output_type -> hyapp.wallet.v1.GetResourceGroupResponse
|
27, // 121: hyapp.wallet.v1.WalletService.SetResourceStatus:output_type -> hyapp.wallet.v1.ResourceResponse
|
||||||
35, // 122: hyapp.wallet.v1.WalletService.CreateResourceGroup:output_type -> hyapp.wallet.v1.ResourceGroupResponse
|
29, // 122: hyapp.wallet.v1.WalletService.ListResourceGroups:output_type -> hyapp.wallet.v1.ListResourceGroupsResponse
|
||||||
35, // 123: hyapp.wallet.v1.WalletService.UpdateResourceGroup:output_type -> hyapp.wallet.v1.ResourceGroupResponse
|
31, // 123: hyapp.wallet.v1.WalletService.GetResourceGroup:output_type -> hyapp.wallet.v1.GetResourceGroupResponse
|
||||||
35, // 124: hyapp.wallet.v1.WalletService.SetResourceGroupStatus:output_type -> hyapp.wallet.v1.ResourceGroupResponse
|
35, // 124: hyapp.wallet.v1.WalletService.CreateResourceGroup:output_type -> hyapp.wallet.v1.ResourceGroupResponse
|
||||||
37, // 125: hyapp.wallet.v1.WalletService.ListGiftConfigs:output_type -> hyapp.wallet.v1.ListGiftConfigsResponse
|
35, // 125: hyapp.wallet.v1.WalletService.UpdateResourceGroup:output_type -> hyapp.wallet.v1.ResourceGroupResponse
|
||||||
39, // 126: hyapp.wallet.v1.WalletService.ListGiftTypeConfigs:output_type -> hyapp.wallet.v1.ListGiftTypeConfigsResponse
|
35, // 126: hyapp.wallet.v1.WalletService.SetResourceGroupStatus:output_type -> hyapp.wallet.v1.ResourceGroupResponse
|
||||||
45, // 127: hyapp.wallet.v1.WalletService.CreateGiftConfig:output_type -> hyapp.wallet.v1.GiftConfigResponse
|
37, // 127: hyapp.wallet.v1.WalletService.ListGiftConfigs:output_type -> hyapp.wallet.v1.ListGiftConfigsResponse
|
||||||
45, // 128: hyapp.wallet.v1.WalletService.UpdateGiftConfig:output_type -> hyapp.wallet.v1.GiftConfigResponse
|
39, // 128: hyapp.wallet.v1.WalletService.ListGiftTypeConfigs:output_type -> hyapp.wallet.v1.ListGiftTypeConfigsResponse
|
||||||
45, // 129: hyapp.wallet.v1.WalletService.SetGiftConfigStatus:output_type -> hyapp.wallet.v1.GiftConfigResponse
|
45, // 129: hyapp.wallet.v1.WalletService.CreateGiftConfig:output_type -> hyapp.wallet.v1.GiftConfigResponse
|
||||||
41, // 130: hyapp.wallet.v1.WalletService.UpsertGiftTypeConfig:output_type -> hyapp.wallet.v1.GiftTypeConfigResponse
|
45, // 130: hyapp.wallet.v1.WalletService.UpdateGiftConfig:output_type -> hyapp.wallet.v1.GiftConfigResponse
|
||||||
48, // 131: hyapp.wallet.v1.WalletService.GrantResource:output_type -> hyapp.wallet.v1.ResourceGrantResponse
|
45, // 131: hyapp.wallet.v1.WalletService.SetGiftConfigStatus:output_type -> hyapp.wallet.v1.GiftConfigResponse
|
||||||
48, // 132: hyapp.wallet.v1.WalletService.GrantResourceGroup:output_type -> hyapp.wallet.v1.ResourceGrantResponse
|
41, // 132: hyapp.wallet.v1.WalletService.UpsertGiftTypeConfig:output_type -> hyapp.wallet.v1.GiftTypeConfigResponse
|
||||||
50, // 133: hyapp.wallet.v1.WalletService.ListUserResources:output_type -> hyapp.wallet.v1.ListUserResourcesResponse
|
48, // 133: hyapp.wallet.v1.WalletService.GrantResource:output_type -> hyapp.wallet.v1.ResourceGrantResponse
|
||||||
52, // 134: hyapp.wallet.v1.WalletService.EquipUserResource:output_type -> hyapp.wallet.v1.EquipUserResourceResponse
|
48, // 134: hyapp.wallet.v1.WalletService.GrantResourceGroup:output_type -> hyapp.wallet.v1.ResourceGrantResponse
|
||||||
54, // 135: hyapp.wallet.v1.WalletService.ListResourceGrants:output_type -> hyapp.wallet.v1.ListResourceGrantsResponse
|
50, // 135: hyapp.wallet.v1.WalletService.ListUserResources:output_type -> hyapp.wallet.v1.ListUserResourcesResponse
|
||||||
57, // 136: hyapp.wallet.v1.WalletService.ListRechargeBills:output_type -> hyapp.wallet.v1.ListRechargeBillsResponse
|
52, // 136: hyapp.wallet.v1.WalletService.EquipUserResource:output_type -> hyapp.wallet.v1.EquipUserResourceResponse
|
||||||
60, // 137: hyapp.wallet.v1.WalletService.GetWalletOverview:output_type -> hyapp.wallet.v1.GetWalletOverviewResponse
|
54, // 137: hyapp.wallet.v1.WalletService.ListResourceGrants:output_type -> hyapp.wallet.v1.ListResourceGrantsResponse
|
||||||
63, // 138: hyapp.wallet.v1.WalletService.GetWalletValueSummary:output_type -> hyapp.wallet.v1.GetWalletValueSummaryResponse
|
57, // 138: hyapp.wallet.v1.WalletService.ListRechargeBills:output_type -> hyapp.wallet.v1.ListRechargeBillsResponse
|
||||||
66, // 139: hyapp.wallet.v1.WalletService.GetUserGiftWall:output_type -> hyapp.wallet.v1.GetUserGiftWallResponse
|
60, // 139: hyapp.wallet.v1.WalletService.GetWalletOverview:output_type -> hyapp.wallet.v1.GetWalletOverviewResponse
|
||||||
69, // 140: hyapp.wallet.v1.WalletService.ListRechargeProducts:output_type -> hyapp.wallet.v1.ListRechargeProductsResponse
|
63, // 140: hyapp.wallet.v1.WalletService.GetWalletValueSummary:output_type -> hyapp.wallet.v1.GetWalletValueSummaryResponse
|
||||||
71, // 141: hyapp.wallet.v1.WalletService.ConfirmGooglePayment:output_type -> hyapp.wallet.v1.ConfirmGooglePaymentResponse
|
66, // 141: hyapp.wallet.v1.WalletService.GetUserGiftWall:output_type -> hyapp.wallet.v1.GetUserGiftWallResponse
|
||||||
73, // 142: hyapp.wallet.v1.WalletService.ListAdminRechargeProducts:output_type -> hyapp.wallet.v1.ListAdminRechargeProductsResponse
|
69, // 142: hyapp.wallet.v1.WalletService.ListRechargeProducts:output_type -> hyapp.wallet.v1.ListRechargeProductsResponse
|
||||||
77, // 143: hyapp.wallet.v1.WalletService.CreateRechargeProduct:output_type -> hyapp.wallet.v1.RechargeProductResponse
|
71, // 143: hyapp.wallet.v1.WalletService.ConfirmGooglePayment:output_type -> hyapp.wallet.v1.ConfirmGooglePaymentResponse
|
||||||
77, // 144: hyapp.wallet.v1.WalletService.UpdateRechargeProduct:output_type -> hyapp.wallet.v1.RechargeProductResponse
|
73, // 144: hyapp.wallet.v1.WalletService.ListAdminRechargeProducts:output_type -> hyapp.wallet.v1.ListAdminRechargeProductsResponse
|
||||||
78, // 145: hyapp.wallet.v1.WalletService.DeleteRechargeProduct:output_type -> hyapp.wallet.v1.DeleteRechargeProductResponse
|
77, // 145: hyapp.wallet.v1.WalletService.CreateRechargeProduct:output_type -> hyapp.wallet.v1.RechargeProductResponse
|
||||||
81, // 146: hyapp.wallet.v1.WalletService.GetDiamondExchangeConfig:output_type -> hyapp.wallet.v1.GetDiamondExchangeConfigResponse
|
77, // 146: hyapp.wallet.v1.WalletService.UpdateRechargeProduct:output_type -> hyapp.wallet.v1.RechargeProductResponse
|
||||||
84, // 147: hyapp.wallet.v1.WalletService.ListWalletTransactions:output_type -> hyapp.wallet.v1.ListWalletTransactionsResponse
|
78, // 147: hyapp.wallet.v1.WalletService.DeleteRechargeProduct:output_type -> hyapp.wallet.v1.DeleteRechargeProductResponse
|
||||||
87, // 148: hyapp.wallet.v1.WalletService.ApplyWithdrawal:output_type -> hyapp.wallet.v1.ApplyWithdrawalResponse
|
81, // 148: hyapp.wallet.v1.WalletService.GetDiamondExchangeConfig:output_type -> hyapp.wallet.v1.GetDiamondExchangeConfigResponse
|
||||||
92, // 149: hyapp.wallet.v1.WalletService.ListVipPackages:output_type -> hyapp.wallet.v1.ListVipPackagesResponse
|
84, // 149: hyapp.wallet.v1.WalletService.ListWalletTransactions:output_type -> hyapp.wallet.v1.ListWalletTransactionsResponse
|
||||||
94, // 150: hyapp.wallet.v1.WalletService.GetMyVip:output_type -> hyapp.wallet.v1.GetMyVipResponse
|
87, // 150: hyapp.wallet.v1.WalletService.ApplyWithdrawal:output_type -> hyapp.wallet.v1.ApplyWithdrawalResponse
|
||||||
96, // 151: hyapp.wallet.v1.WalletService.PurchaseVip:output_type -> hyapp.wallet.v1.PurchaseVipResponse
|
92, // 151: hyapp.wallet.v1.WalletService.ListVipPackages:output_type -> hyapp.wallet.v1.ListVipPackagesResponse
|
||||||
98, // 152: hyapp.wallet.v1.WalletService.GrantVip:output_type -> hyapp.wallet.v1.GrantVipResponse
|
94, // 152: hyapp.wallet.v1.WalletService.GetMyVip:output_type -> hyapp.wallet.v1.GetMyVipResponse
|
||||||
101, // 153: hyapp.wallet.v1.WalletService.ListAdminVipLevels:output_type -> hyapp.wallet.v1.ListAdminVipLevelsResponse
|
96, // 153: hyapp.wallet.v1.WalletService.PurchaseVip:output_type -> hyapp.wallet.v1.PurchaseVipResponse
|
||||||
103, // 154: hyapp.wallet.v1.WalletService.UpdateAdminVipLevels:output_type -> hyapp.wallet.v1.UpdateAdminVipLevelsResponse
|
98, // 154: hyapp.wallet.v1.WalletService.GrantVip:output_type -> hyapp.wallet.v1.GrantVipResponse
|
||||||
105, // 155: hyapp.wallet.v1.WalletService.CreditTaskReward:output_type -> hyapp.wallet.v1.CreditTaskRewardResponse
|
101, // 155: hyapp.wallet.v1.WalletService.ListAdminVipLevels:output_type -> hyapp.wallet.v1.ListAdminVipLevelsResponse
|
||||||
107, // 156: hyapp.wallet.v1.WalletService.ApplyGameCoinChange:output_type -> hyapp.wallet.v1.ApplyGameCoinChangeResponse
|
103, // 156: hyapp.wallet.v1.WalletService.UpdateAdminVipLevels:output_type -> hyapp.wallet.v1.UpdateAdminVipLevelsResponse
|
||||||
112, // 157: hyapp.wallet.v1.WalletService.GetRedPacketConfig:output_type -> hyapp.wallet.v1.GetRedPacketConfigResponse
|
105, // 157: hyapp.wallet.v1.WalletService.CreditTaskReward:output_type -> hyapp.wallet.v1.CreditTaskRewardResponse
|
||||||
114, // 158: hyapp.wallet.v1.WalletService.UpdateRedPacketConfig:output_type -> hyapp.wallet.v1.UpdateRedPacketConfigResponse
|
107, // 158: hyapp.wallet.v1.WalletService.CreditLuckyGiftReward:output_type -> hyapp.wallet.v1.CreditLuckyGiftRewardResponse
|
||||||
116, // 159: hyapp.wallet.v1.WalletService.CreateRedPacket:output_type -> hyapp.wallet.v1.CreateRedPacketResponse
|
109, // 159: hyapp.wallet.v1.WalletService.ApplyGameCoinChange:output_type -> hyapp.wallet.v1.ApplyGameCoinChangeResponse
|
||||||
118, // 160: hyapp.wallet.v1.WalletService.ClaimRedPacket:output_type -> hyapp.wallet.v1.ClaimRedPacketResponse
|
114, // 160: hyapp.wallet.v1.WalletService.GetRedPacketConfig:output_type -> hyapp.wallet.v1.GetRedPacketConfigResponse
|
||||||
120, // 161: hyapp.wallet.v1.WalletService.ListRedPackets:output_type -> hyapp.wallet.v1.ListRedPacketsResponse
|
116, // 161: hyapp.wallet.v1.WalletService.UpdateRedPacketConfig:output_type -> hyapp.wallet.v1.UpdateRedPacketConfigResponse
|
||||||
122, // 162: hyapp.wallet.v1.WalletService.GetRedPacket:output_type -> hyapp.wallet.v1.GetRedPacketResponse
|
118, // 162: hyapp.wallet.v1.WalletService.CreateRedPacket:output_type -> hyapp.wallet.v1.CreateRedPacketResponse
|
||||||
124, // 163: hyapp.wallet.v1.WalletService.ExpireRedPackets:output_type -> hyapp.wallet.v1.ExpireRedPacketsResponse
|
120, // 163: hyapp.wallet.v1.WalletService.ClaimRedPacket:output_type -> hyapp.wallet.v1.ClaimRedPacketResponse
|
||||||
110, // [110:164] is the sub-list for method output_type
|
122, // 164: hyapp.wallet.v1.WalletService.ListRedPackets:output_type -> hyapp.wallet.v1.ListRedPacketsResponse
|
||||||
56, // [56:110] is the sub-list for method input_type
|
124, // 165: hyapp.wallet.v1.WalletService.GetRedPacket:output_type -> hyapp.wallet.v1.GetRedPacketResponse
|
||||||
56, // [56:56] is the sub-list for extension type_name
|
126, // 166: hyapp.wallet.v1.WalletService.ExpireRedPackets:output_type -> hyapp.wallet.v1.ExpireRedPacketsResponse
|
||||||
56, // [56:56] is the sub-list for extension extendee
|
112, // [112:167] is the sub-list for method output_type
|
||||||
0, // [0:56] is the sub-list for field type_name
|
57, // [57:112] is the sub-list for method input_type
|
||||||
|
57, // [57:57] is the sub-list for extension type_name
|
||||||
|
57, // [57:57] is the sub-list for extension extendee
|
||||||
|
0, // [0:57] is the sub-list for field type_name
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() { file_proto_wallet_v1_wallet_proto_init() }
|
func init() { file_proto_wallet_v1_wallet_proto_init() }
|
||||||
@ -12662,7 +12862,7 @@ func file_proto_wallet_v1_wallet_proto_init() {
|
|||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_proto_wallet_v1_wallet_proto_rawDesc), len(file_proto_wallet_v1_wallet_proto_rawDesc)),
|
RawDescriptor: unsafe.Slice(unsafe.StringData(file_proto_wallet_v1_wallet_proto_rawDesc), len(file_proto_wallet_v1_wallet_proto_rawDesc)),
|
||||||
NumEnums: 0,
|
NumEnums: 0,
|
||||||
NumMessages: 125,
|
NumMessages: 127,
|
||||||
NumExtensions: 0,
|
NumExtensions: 0,
|
||||||
NumServices: 1,
|
NumServices: 1,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1049,6 +1049,27 @@ message CreditTaskRewardResponse {
|
|||||||
int64 granted_at_ms = 4;
|
int64 granted_at_ms = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreditLuckyGiftRewardRequest 是 activity-service 抽奖 outbox 补偿 worker 调用的钱包入账命令。
|
||||||
|
message CreditLuckyGiftRewardRequest {
|
||||||
|
string command_id = 1;
|
||||||
|
string app_code = 2;
|
||||||
|
int64 target_user_id = 3;
|
||||||
|
int64 amount = 4;
|
||||||
|
string draw_id = 5;
|
||||||
|
string room_id = 6;
|
||||||
|
string gift_id = 7;
|
||||||
|
string pool_id = 8;
|
||||||
|
string reason = 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreditLuckyGiftRewardResponse 返回幸运礼物返奖入账流水和用户 COIN 账后余额。
|
||||||
|
message CreditLuckyGiftRewardResponse {
|
||||||
|
string transaction_id = 1;
|
||||||
|
AssetBalance balance = 2;
|
||||||
|
int64 amount = 3;
|
||||||
|
int64 granted_at_ms = 4;
|
||||||
|
}
|
||||||
|
|
||||||
// ApplyGameCoinChangeRequest 是 game-service 唯一可以调用的钱包游戏改账入口。
|
// ApplyGameCoinChangeRequest 是 game-service 唯一可以调用的钱包游戏改账入口。
|
||||||
message ApplyGameCoinChangeRequest {
|
message ApplyGameCoinChangeRequest {
|
||||||
string request_id = 1;
|
string request_id = 1;
|
||||||
@ -1274,6 +1295,7 @@ service WalletService {
|
|||||||
rpc ListAdminVipLevels(ListAdminVipLevelsRequest) returns (ListAdminVipLevelsResponse);
|
rpc ListAdminVipLevels(ListAdminVipLevelsRequest) returns (ListAdminVipLevelsResponse);
|
||||||
rpc UpdateAdminVipLevels(UpdateAdminVipLevelsRequest) returns (UpdateAdminVipLevelsResponse);
|
rpc UpdateAdminVipLevels(UpdateAdminVipLevelsRequest) returns (UpdateAdminVipLevelsResponse);
|
||||||
rpc CreditTaskReward(CreditTaskRewardRequest) returns (CreditTaskRewardResponse);
|
rpc CreditTaskReward(CreditTaskRewardRequest) returns (CreditTaskRewardResponse);
|
||||||
|
rpc CreditLuckyGiftReward(CreditLuckyGiftRewardRequest) returns (CreditLuckyGiftRewardResponse);
|
||||||
rpc ApplyGameCoinChange(ApplyGameCoinChangeRequest) returns (ApplyGameCoinChangeResponse);
|
rpc ApplyGameCoinChange(ApplyGameCoinChangeRequest) returns (ApplyGameCoinChangeResponse);
|
||||||
rpc GetRedPacketConfig(GetRedPacketConfigRequest) returns (GetRedPacketConfigResponse);
|
rpc GetRedPacketConfig(GetRedPacketConfigRequest) returns (GetRedPacketConfigResponse);
|
||||||
rpc UpdateRedPacketConfig(UpdateRedPacketConfigRequest) returns (UpdateRedPacketConfigResponse);
|
rpc UpdateRedPacketConfig(UpdateRedPacketConfigRequest) returns (UpdateRedPacketConfigResponse);
|
||||||
|
|||||||
@ -65,6 +65,7 @@ const (
|
|||||||
WalletService_ListAdminVipLevels_FullMethodName = "/hyapp.wallet.v1.WalletService/ListAdminVipLevels"
|
WalletService_ListAdminVipLevels_FullMethodName = "/hyapp.wallet.v1.WalletService/ListAdminVipLevels"
|
||||||
WalletService_UpdateAdminVipLevels_FullMethodName = "/hyapp.wallet.v1.WalletService/UpdateAdminVipLevels"
|
WalletService_UpdateAdminVipLevels_FullMethodName = "/hyapp.wallet.v1.WalletService/UpdateAdminVipLevels"
|
||||||
WalletService_CreditTaskReward_FullMethodName = "/hyapp.wallet.v1.WalletService/CreditTaskReward"
|
WalletService_CreditTaskReward_FullMethodName = "/hyapp.wallet.v1.WalletService/CreditTaskReward"
|
||||||
|
WalletService_CreditLuckyGiftReward_FullMethodName = "/hyapp.wallet.v1.WalletService/CreditLuckyGiftReward"
|
||||||
WalletService_ApplyGameCoinChange_FullMethodName = "/hyapp.wallet.v1.WalletService/ApplyGameCoinChange"
|
WalletService_ApplyGameCoinChange_FullMethodName = "/hyapp.wallet.v1.WalletService/ApplyGameCoinChange"
|
||||||
WalletService_GetRedPacketConfig_FullMethodName = "/hyapp.wallet.v1.WalletService/GetRedPacketConfig"
|
WalletService_GetRedPacketConfig_FullMethodName = "/hyapp.wallet.v1.WalletService/GetRedPacketConfig"
|
||||||
WalletService_UpdateRedPacketConfig_FullMethodName = "/hyapp.wallet.v1.WalletService/UpdateRedPacketConfig"
|
WalletService_UpdateRedPacketConfig_FullMethodName = "/hyapp.wallet.v1.WalletService/UpdateRedPacketConfig"
|
||||||
@ -127,6 +128,7 @@ type WalletServiceClient interface {
|
|||||||
ListAdminVipLevels(ctx context.Context, in *ListAdminVipLevelsRequest, opts ...grpc.CallOption) (*ListAdminVipLevelsResponse, error)
|
ListAdminVipLevels(ctx context.Context, in *ListAdminVipLevelsRequest, opts ...grpc.CallOption) (*ListAdminVipLevelsResponse, error)
|
||||||
UpdateAdminVipLevels(ctx context.Context, in *UpdateAdminVipLevelsRequest, opts ...grpc.CallOption) (*UpdateAdminVipLevelsResponse, error)
|
UpdateAdminVipLevels(ctx context.Context, in *UpdateAdminVipLevelsRequest, opts ...grpc.CallOption) (*UpdateAdminVipLevelsResponse, error)
|
||||||
CreditTaskReward(ctx context.Context, in *CreditTaskRewardRequest, opts ...grpc.CallOption) (*CreditTaskRewardResponse, error)
|
CreditTaskReward(ctx context.Context, in *CreditTaskRewardRequest, opts ...grpc.CallOption) (*CreditTaskRewardResponse, error)
|
||||||
|
CreditLuckyGiftReward(ctx context.Context, in *CreditLuckyGiftRewardRequest, opts ...grpc.CallOption) (*CreditLuckyGiftRewardResponse, error)
|
||||||
ApplyGameCoinChange(ctx context.Context, in *ApplyGameCoinChangeRequest, opts ...grpc.CallOption) (*ApplyGameCoinChangeResponse, error)
|
ApplyGameCoinChange(ctx context.Context, in *ApplyGameCoinChangeRequest, opts ...grpc.CallOption) (*ApplyGameCoinChangeResponse, error)
|
||||||
GetRedPacketConfig(ctx context.Context, in *GetRedPacketConfigRequest, opts ...grpc.CallOption) (*GetRedPacketConfigResponse, error)
|
GetRedPacketConfig(ctx context.Context, in *GetRedPacketConfigRequest, opts ...grpc.CallOption) (*GetRedPacketConfigResponse, error)
|
||||||
UpdateRedPacketConfig(ctx context.Context, in *UpdateRedPacketConfigRequest, opts ...grpc.CallOption) (*UpdateRedPacketConfigResponse, error)
|
UpdateRedPacketConfig(ctx context.Context, in *UpdateRedPacketConfigRequest, opts ...grpc.CallOption) (*UpdateRedPacketConfigResponse, error)
|
||||||
@ -605,6 +607,16 @@ func (c *walletServiceClient) CreditTaskReward(ctx context.Context, in *CreditTa
|
|||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *walletServiceClient) CreditLuckyGiftReward(ctx context.Context, in *CreditLuckyGiftRewardRequest, opts ...grpc.CallOption) (*CreditLuckyGiftRewardResponse, error) {
|
||||||
|
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||||
|
out := new(CreditLuckyGiftRewardResponse)
|
||||||
|
err := c.cc.Invoke(ctx, WalletService_CreditLuckyGiftReward_FullMethodName, in, out, cOpts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *walletServiceClient) ApplyGameCoinChange(ctx context.Context, in *ApplyGameCoinChangeRequest, opts ...grpc.CallOption) (*ApplyGameCoinChangeResponse, error) {
|
func (c *walletServiceClient) ApplyGameCoinChange(ctx context.Context, in *ApplyGameCoinChangeRequest, opts ...grpc.CallOption) (*ApplyGameCoinChangeResponse, error) {
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||||
out := new(ApplyGameCoinChangeResponse)
|
out := new(ApplyGameCoinChangeResponse)
|
||||||
@ -737,6 +749,7 @@ type WalletServiceServer interface {
|
|||||||
ListAdminVipLevels(context.Context, *ListAdminVipLevelsRequest) (*ListAdminVipLevelsResponse, error)
|
ListAdminVipLevels(context.Context, *ListAdminVipLevelsRequest) (*ListAdminVipLevelsResponse, error)
|
||||||
UpdateAdminVipLevels(context.Context, *UpdateAdminVipLevelsRequest) (*UpdateAdminVipLevelsResponse, error)
|
UpdateAdminVipLevels(context.Context, *UpdateAdminVipLevelsRequest) (*UpdateAdminVipLevelsResponse, error)
|
||||||
CreditTaskReward(context.Context, *CreditTaskRewardRequest) (*CreditTaskRewardResponse, error)
|
CreditTaskReward(context.Context, *CreditTaskRewardRequest) (*CreditTaskRewardResponse, error)
|
||||||
|
CreditLuckyGiftReward(context.Context, *CreditLuckyGiftRewardRequest) (*CreditLuckyGiftRewardResponse, error)
|
||||||
ApplyGameCoinChange(context.Context, *ApplyGameCoinChangeRequest) (*ApplyGameCoinChangeResponse, error)
|
ApplyGameCoinChange(context.Context, *ApplyGameCoinChangeRequest) (*ApplyGameCoinChangeResponse, error)
|
||||||
GetRedPacketConfig(context.Context, *GetRedPacketConfigRequest) (*GetRedPacketConfigResponse, error)
|
GetRedPacketConfig(context.Context, *GetRedPacketConfigRequest) (*GetRedPacketConfigResponse, error)
|
||||||
UpdateRedPacketConfig(context.Context, *UpdateRedPacketConfigRequest) (*UpdateRedPacketConfigResponse, error)
|
UpdateRedPacketConfig(context.Context, *UpdateRedPacketConfigRequest) (*UpdateRedPacketConfigResponse, error)
|
||||||
@ -893,6 +906,9 @@ func (UnimplementedWalletServiceServer) UpdateAdminVipLevels(context.Context, *U
|
|||||||
func (UnimplementedWalletServiceServer) CreditTaskReward(context.Context, *CreditTaskRewardRequest) (*CreditTaskRewardResponse, error) {
|
func (UnimplementedWalletServiceServer) CreditTaskReward(context.Context, *CreditTaskRewardRequest) (*CreditTaskRewardResponse, error) {
|
||||||
return nil, status.Error(codes.Unimplemented, "method CreditTaskReward not implemented")
|
return nil, status.Error(codes.Unimplemented, "method CreditTaskReward not implemented")
|
||||||
}
|
}
|
||||||
|
func (UnimplementedWalletServiceServer) CreditLuckyGiftReward(context.Context, *CreditLuckyGiftRewardRequest) (*CreditLuckyGiftRewardResponse, error) {
|
||||||
|
return nil, status.Error(codes.Unimplemented, "method CreditLuckyGiftReward not implemented")
|
||||||
|
}
|
||||||
func (UnimplementedWalletServiceServer) ApplyGameCoinChange(context.Context, *ApplyGameCoinChangeRequest) (*ApplyGameCoinChangeResponse, error) {
|
func (UnimplementedWalletServiceServer) ApplyGameCoinChange(context.Context, *ApplyGameCoinChangeRequest) (*ApplyGameCoinChangeResponse, error) {
|
||||||
return nil, status.Error(codes.Unimplemented, "method ApplyGameCoinChange not implemented")
|
return nil, status.Error(codes.Unimplemented, "method ApplyGameCoinChange not implemented")
|
||||||
}
|
}
|
||||||
@ -1766,6 +1782,24 @@ func _WalletService_CreditTaskReward_Handler(srv interface{}, ctx context.Contex
|
|||||||
return interceptor(ctx, in, info, handler)
|
return interceptor(ctx, in, info, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func _WalletService_CreditLuckyGiftReward_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(CreditLuckyGiftRewardRequest)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(WalletServiceServer).CreditLuckyGiftReward(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: WalletService_CreditLuckyGiftReward_FullMethodName,
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(WalletServiceServer).CreditLuckyGiftReward(ctx, req.(*CreditLuckyGiftRewardRequest))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
func _WalletService_ApplyGameCoinChange_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
func _WalletService_ApplyGameCoinChange_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
in := new(ApplyGameCoinChangeRequest)
|
in := new(ApplyGameCoinChangeRequest)
|
||||||
if err := dec(in); err != nil {
|
if err := dec(in); err != nil {
|
||||||
@ -2101,6 +2135,10 @@ var WalletService_ServiceDesc = grpc.ServiceDesc{
|
|||||||
MethodName: "CreditTaskReward",
|
MethodName: "CreditTaskReward",
|
||||||
Handler: _WalletService_CreditTaskReward_Handler,
|
Handler: _WalletService_CreditTaskReward_Handler,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
MethodName: "CreditLuckyGiftReward",
|
||||||
|
Handler: _WalletService_CreditLuckyGiftReward_Handler,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
MethodName: "ApplyGameCoinChange",
|
MethodName: "ApplyGameCoinChange",
|
||||||
Handler: _WalletService_ApplyGameCoinChange_Handler,
|
Handler: _WalletService_ApplyGameCoinChange_Handler,
|
||||||
|
|||||||
@ -60,19 +60,14 @@ App 不要展示后台 RTP 数值,不要展示实时概率,不要本地推
|
|||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `POST /api/v1/rooms/gift/send` 支持 `pool_id` 入参 | 已有 |
|
| `POST /api/v1/rooms/gift/send` 支持 `pool_id` 入参 | 已有 |
|
||||||
| 房间送礼 IM `room_gift_sent` 可携带 `pool_id` | 已有 |
|
| 房间送礼 IM `room_gift_sent` 可携带 `pool_id` | 已有 |
|
||||||
|
| `POST /api/v1/activities/lucky-gifts/check` | 已有 |
|
||||||
| `activity-service` 内部 gRPC `CheckLuckyGift` / `ExecuteLuckyGiftDraw` | 已有 |
|
| `activity-service` 内部 gRPC `CheckLuckyGift` / `ExecuteLuckyGiftDraw` | 已有 |
|
||||||
| 后台按 `pool_id` 配置多奖池 | 已有 |
|
| 后台按 `pool_id` 配置多奖池 | 已有 |
|
||||||
|
| 送礼响应直接返回抽奖结果 `data.lucky_gift` | 已有 |
|
||||||
|
| 房间 IM `lucky_gift_drawn` | 已有 |
|
||||||
|
| 中奖返奖入账并触发 `WalletBalanceChanged` | 已有 |
|
||||||
|
|
||||||
Flutter 完整体验还需要后端补齐:
|
简洁版接入清单见 [幸运礼物接口闭环Flutter对接.md](/Users/hy/Documents/hy/hyapp-server/docs/flutter对接/幸运礼物接口闭环Flutter对接.md)。
|
||||||
|
|
||||||
| 能力 | 建议 |
|
|
||||||
| --- | --- |
|
|
||||||
| App 查询某个奖池是否可抽 | 新增 HTTP `POST /api/v1/activities/lucky-gifts/check` |
|
|
||||||
| 送礼响应直接返回抽奖结果 | 在 `/rooms/gift/send` 成功 `data` 中增加 `lucky_gift` |
|
|
||||||
| 中奖房间表现 | 新增房间 IM `lucky_gift_drawn` |
|
|
||||||
| 返奖到账 | 钱包侧新增幸运礼物返奖入账后继续发 `WalletBalanceChanged` |
|
|
||||||
|
|
||||||
下面文档按最终 Flutter 契约编写;已存在字段可直接对接,标注为“建议新增”的字段需要后端继续落地。
|
|
||||||
|
|
||||||
## 客户端流程
|
## 客户端流程
|
||||||
|
|
||||||
@ -585,4 +580,3 @@ Payload 示例:
|
|||||||
6. 监听房间 IM `room_gift_sent`、`lucky_gift_drawn`,同步其他用户看到的表现。
|
6. 监听房间 IM `room_gift_sent`、`lucky_gift_drawn`,同步其他用户看到的表现。
|
||||||
7. 监听 C2C IM `WalletBalanceChanged`,更新金币余额。
|
7. 监听 C2C IM `WalletBalanceChanged`,更新金币余额。
|
||||||
8. 任意 IM 丢失、页面重进或余额不一致时,重新拉取礼物面板和钱包余额纠正状态。
|
8. 任意 IM 丢失、页面重进或余额不一致时,重新拉取礼物面板和钱包余额纠正状态。
|
||||||
|
|
||||||
|
|||||||
171
docs/flutter对接/幸运礼物接口闭环Flutter对接.md
Normal file
171
docs/flutter对接/幸运礼物接口闭环Flutter对接.md
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
# 幸运礼物 Flutter 对接
|
||||||
|
|
||||||
|
本文只描述 App 需要接入的 HTTP、送礼返回、错误处理和腾讯云 IM 自定义消息。所有接口响应都使用 gateway 业务 envelope:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": "OK",
|
||||||
|
"message": "",
|
||||||
|
"request_id": "req_xxx",
|
||||||
|
"data": {}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 1. 送礼前检查
|
||||||
|
|
||||||
|
`POST /api/v1/activities/lucky-gifts/check`
|
||||||
|
|
||||||
|
请求头:
|
||||||
|
|
||||||
|
| 参数 | 必填 | 说明 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `Authorization` | 是 | `Bearer <access_token>` |
|
||||||
|
| `X-App-Code` | 否 | 不传时使用默认 App |
|
||||||
|
|
||||||
|
请求体:
|
||||||
|
|
||||||
|
| 参数 | 类型 | 必填 | 说明 |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| `room_id` | string | 是 | 当前房间 ID |
|
||||||
|
| `gift_id` | string | 是 | 实际送出的礼物 ID,例如 `rose` |
|
||||||
|
| `pool_id` | string | 是 | 幸运礼物奖池 ID,例如 `lucky`、`super_lucky` |
|
||||||
|
|
||||||
|
返回 `data`:
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `enabled` | bool | 是否可按幸运礼物发送 |
|
||||||
|
| `reason` | string | `enabled`、`not_configured`、`disabled` |
|
||||||
|
| `room_id` | string | 请求房间 ID |
|
||||||
|
| `gift_id` | string | 请求礼物 ID |
|
||||||
|
| `pool_id` | string | 生效奖池 ID |
|
||||||
|
| `gift_price` | int | 单次抽奖价格,金币 |
|
||||||
|
| `rule_version` | int | 后端规则版本 |
|
||||||
|
| `target_rtp_ppm` | int | RTP 目标,ppm |
|
||||||
|
| `experience_pool` | string | `novice`、`intermediate`、`advanced` |
|
||||||
|
|
||||||
|
客户端处理:
|
||||||
|
|
||||||
|
- `enabled=true`:允许用户继续点击送礼。
|
||||||
|
- `enabled=false`:不要走幸运礼物送礼;可降级普通礼物或提示当前不可用。
|
||||||
|
- 检查结果只用于展示和拦截,最终仍以送礼接口为准。
|
||||||
|
|
||||||
|
## 2. 发送礼物
|
||||||
|
|
||||||
|
`POST /api/v1/rooms/gift/send`
|
||||||
|
|
||||||
|
请求体关键字段:
|
||||||
|
|
||||||
|
| 参数 | 类型 | 必填 | 说明 |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| `room_id` | string | 是 | 房间 ID |
|
||||||
|
| `target_user_id` | int/string | 是 | 收礼用户 ID |
|
||||||
|
| `gift_id` | string | 是 | 礼物 ID,例如 `rose` |
|
||||||
|
| `gift_count` | int | 是 | 数量,必须大于 0 |
|
||||||
|
| `pool_id` | string | 幸运礼物必填 | `lucky` 或 `super_lucky` |
|
||||||
|
| `client_sequence` | string | 建议 | 客户端幂等序列 |
|
||||||
|
|
||||||
|
返回 `data.lucky_gift`:
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `draw_id` | string | 抽奖 ID,客户端去重锚点 |
|
||||||
|
| `command_id` | string | 送礼命令 ID |
|
||||||
|
| `pool_id` | string | 生效奖池 |
|
||||||
|
| `gift_id` | string | 礼物 ID |
|
||||||
|
| `rule_version` | int | 抽奖规则版本 |
|
||||||
|
| `experience_pool` | string | 体验池 |
|
||||||
|
| `selected_tier_id` | string | 命中奖档 |
|
||||||
|
| `multiplier_ppm` | int | 倍率,`2000000` 表示 2 倍 |
|
||||||
|
| `base_reward_coins` | int | RTP 基础返奖 |
|
||||||
|
| `room_atmosphere_reward_coins` | int | 房间气氛池返奖 |
|
||||||
|
| `activity_subsidy_coins` | int | 活动补贴返奖 |
|
||||||
|
| `effective_reward_coins` | int | 用户实际获得金币 |
|
||||||
|
| `reward_status` | string | 初始通常为 `pending`,到账由后端 outbox 补偿 |
|
||||||
|
| `stage_feedback` | bool | 是否阶段反馈,可播放轻量中奖表现 |
|
||||||
|
| `high_multiplier` | bool | 是否高倍 |
|
||||||
|
| `created_at_ms` | int | UTC epoch ms |
|
||||||
|
|
||||||
|
客户端处理:
|
||||||
|
|
||||||
|
- `data.lucky_gift != null`:立即调用 `_applyLuckyGiftResult()`,播放中奖内容和数量 SVGA。
|
||||||
|
- `effective_reward_coins > 0`:展示中奖金额;余额不要本地相加,以 `WalletBalanceChanged` 或余额刷新为准。
|
||||||
|
- `data.lucky_gift == null`:按普通礼物表现处理。
|
||||||
|
|
||||||
|
## 3. 错误处理
|
||||||
|
|
||||||
|
| code | 场景 | 客户端处理 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `INVALID_ARGUMENT` | 参数缺失、数量非法、pool_id 缺失 | 停止提交,提示用户重试或刷新礼物面板 |
|
||||||
|
| `UNAUTHENTICATED` | token 失效 | 重新登录 |
|
||||||
|
| `INSUFFICIENT_BALANCE` | 金币不足 | 打开充值入口或提示余额不足 |
|
||||||
|
| `RULE_NOT_ACTIVE` | 幸运礼物规则未启用 | 降级普通礼物或刷新礼物配置 |
|
||||||
|
| `UPSTREAM_ERROR`/`UNAVAILABLE` | 内部服务或 IM/钱包临时不可用 | 不重复扣本地余额;允许用户稍后重试 |
|
||||||
|
| `IDEMPOTENCY_CONFLICT`/`CONFLICT` | 同一客户端命令参数变化 | 重新生成 `client_sequence` 后再提交 |
|
||||||
|
|
||||||
|
送礼失败时后端不会返回 `lucky_gift`,客户端不要播放中奖 UI。送礼成功但返奖到账延迟时,房间 IM 和钱包 IM 会继续补偿。
|
||||||
|
|
||||||
|
## 4. 房间 IM
|
||||||
|
|
||||||
|
腾讯云 IM 群自定义消息:
|
||||||
|
|
||||||
|
| 字段 | 值 |
|
||||||
|
| --- | --- |
|
||||||
|
| `MsgType` | `TIMCustomElem` |
|
||||||
|
| `Desc` | `lucky_gift_drawn` |
|
||||||
|
| `Ext` | `room_system_message` |
|
||||||
|
| `Data` | JSON 字符串 |
|
||||||
|
|
||||||
|
`Data` 示例:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"event_type": "lucky_gift_drawn",
|
||||||
|
"event_id": "lucky_gift_drawn:lucky_draw_xxx",
|
||||||
|
"draw_id": "lucky_draw_xxx",
|
||||||
|
"command_id": "cmd_xxx",
|
||||||
|
"pool_id": "super_lucky",
|
||||||
|
"room_id": "room_1",
|
||||||
|
"gift_id": "rose",
|
||||||
|
"gift_count": 1,
|
||||||
|
"user_id": 42,
|
||||||
|
"sender_user_id": 42,
|
||||||
|
"target_user_id": 99,
|
||||||
|
"coin_spent": 100,
|
||||||
|
"multiplier_ppm": 2000000,
|
||||||
|
"effective_reward_coins": 200,
|
||||||
|
"stage_feedback": true,
|
||||||
|
"high_multiplier": false,
|
||||||
|
"created_at_ms": 1760000000000
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
处理规则:
|
||||||
|
|
||||||
|
- 只处理 `Desc == "lucky_gift_drawn"` 且 `event_type == "lucky_gift_drawn"`。
|
||||||
|
- 用 `event_id` 或 `draw_id` 去重;同一抽奖不要重复播放。
|
||||||
|
- 当前用户已通过 HTTP 送礼响应播放过同一 `draw_id` 时,收到 IM 只更新状态,不重复播放。
|
||||||
|
|
||||||
|
## 5. 钱包余额 IM
|
||||||
|
|
||||||
|
中奖金币到账后,wallet-service 会写 `WalletBalanceChanged`,notice-service 通过腾讯云 IM C2C 投递。
|
||||||
|
|
||||||
|
| 字段 | 值 |
|
||||||
|
| --- | --- |
|
||||||
|
| `MsgType` | `TIMCustomElem` |
|
||||||
|
| `Desc` | `WalletBalanceChanged` |
|
||||||
|
| `Ext` | `wallet_notice` |
|
||||||
|
|
||||||
|
客户端处理:
|
||||||
|
|
||||||
|
- 只处理 `Desc == "WalletBalanceChanged"`。
|
||||||
|
- 用 `event_id` 去重。
|
||||||
|
- 当 `asset_type == "COIN"` 时,用 `available_after` 更新金币余额;字段缺失时调用 `GET /api/v1/wallet/me/balances` 刷新。
|
||||||
|
|
||||||
|
## 6. 接入顺序
|
||||||
|
|
||||||
|
1. 礼物面板拿到 `pool_id` 后调用 check。
|
||||||
|
2. check 可用后调用送礼接口,并把 `pool_id` 放入请求。
|
||||||
|
3. 送礼响应含 `data.lucky_gift` 时立即播放本机中奖 UI。
|
||||||
|
4. 房间内监听 `lucky_gift_drawn`,给其他用户同步中奖 UI。
|
||||||
|
5. 私聊监听 `WalletBalanceChanged`,更新金币余额。
|
||||||
@ -18,8 +18,11 @@
|
|||||||
| 风控计数 | done | user hour/day、device day、room hour、anchor day |
|
| 风控计数 | done | user hour/day、device day、room hour、anchor day |
|
||||||
| 房间气氛池 | done | 独立预算,不污染基础 RTP |
|
| 房间气氛池 | done | 独立预算,不污染基础 RTP |
|
||||||
| 活动预算池 | done | 独立补贴,不污染基础 RTP |
|
| 活动预算池 | done | 独立补贴,不污染基础 RTP |
|
||||||
|
| 返奖入账 | done | `activity_outbox` worker 调 `wallet-service.CreditLuckyGiftReward`,钱包 outbox 继续触发余额私信 |
|
||||||
|
| 房间中奖 IM | done | `activity_outbox` worker 投递腾讯云 IM 群消息 `lucky_gift_drawn` |
|
||||||
|
| App 检查接口 | done | gateway 暴露 `POST /api/v1/activities/lucky-gifts/check` |
|
||||||
|
|
||||||
暂不在 `activity-service` 事务内调用钱包或房间 RPC。抽奖事务只写事实和 `activity_outbox`;后续由 outbox dispatcher 或房间链路消费结果。
|
`activity-service` 抽奖事务内仍不调用钱包、房间 RPC 或腾讯云 IM。抽奖事务只写事实和 `activity_outbox`;事务外由 lucky gift worker 抢占 outbox,先幂等返奖,再投递房间中奖 IM,最后标记 draw 和 outbox 状态。
|
||||||
|
|
||||||
## Call Flow
|
## Call Flow
|
||||||
|
|
||||||
@ -27,9 +30,12 @@
|
|||||||
room-service SendGift
|
room-service SendGift
|
||||||
1. CheckLuckyGift(meta, user_id, room_id, gift_id, pool_id)
|
1. CheckLuckyGift(meta, user_id, room_id, gift_id, pool_id)
|
||||||
2. wallet-service 扣费成功
|
2. wallet-service 扣费成功
|
||||||
3. ExecuteLuckyGiftDraw(command_id, user_id, device_id, room_id, anchor_id, gift_id, pool_id, coin_spent, paid_at_ms)
|
3. ExecuteLuckyGiftDraw(command_id, user_id, target_user_id, gift_count, device_id, room_id, anchor_id, gift_id, pool_id, coin_spent, paid_at_ms)
|
||||||
4. activity-service 本地事务写 draw fact + outbox
|
4. activity-service 本地事务写 draw fact + outbox
|
||||||
5. 事务后由钱包/房间表现链路处理 reward_status=pending 的结果
|
5. lucky gift worker 幂等调用 wallet-service.CreditLuckyGiftReward
|
||||||
|
6. wallet-service 写 WalletBalanceChanged,notice-service 投递私信余额通知
|
||||||
|
7. lucky gift worker 投递房间群 IM lucky_gift_drawn
|
||||||
|
8. activity-service 标记 reward_status=granted、outbox=delivered
|
||||||
```
|
```
|
||||||
|
|
||||||
`command_id` 是抽奖幂等键。重复 `ExecuteLuckyGiftDraw` 会返回同一条 `lucky_draw_records`,不会重复消耗 RTP、奖池或预算。
|
`command_id` 是抽奖幂等键。重复 `ExecuteLuckyGiftDraw` 会返回同一条 `lucky_draw_records`,不会重复消耗 RTP、奖池或预算。
|
||||||
|
|||||||
@ -17,6 +17,13 @@ first_recharge_reward_worker:
|
|||||||
enabled: false
|
enabled: false
|
||||||
red_packet_broadcast_worker:
|
red_packet_broadcast_worker:
|
||||||
enabled: false
|
enabled: false
|
||||||
|
lucky_gift_worker:
|
||||||
|
enabled: true
|
||||||
|
worker_poll_interval: "1s"
|
||||||
|
worker_batch_size: 100
|
||||||
|
worker_lock_ttl: "30s"
|
||||||
|
worker_max_retry: 8
|
||||||
|
publish_timeout: "5s"
|
||||||
tencent_im:
|
tencent_im:
|
||||||
# Docker 本地联调全局/区域播报群;必须与 gateway/room-service 使用同一组腾讯 IM 应用配置。
|
# Docker 本地联调全局/区域播报群;必须与 gateway/room-service 使用同一组腾讯 IM 应用配置。
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|||||||
@ -17,6 +17,13 @@ first_recharge_reward_worker:
|
|||||||
enabled: true
|
enabled: true
|
||||||
red_packet_broadcast_worker:
|
red_packet_broadcast_worker:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
lucky_gift_worker:
|
||||||
|
enabled: true
|
||||||
|
worker_poll_interval: "1s"
|
||||||
|
worker_batch_size: 100
|
||||||
|
worker_lock_ttl: "30s"
|
||||||
|
worker_max_retry: 8
|
||||||
|
publish_timeout: "5s"
|
||||||
tencent_im:
|
tencent_im:
|
||||||
# 腾讯云 IM 应用配置;必须和 gateway 的 UserSig、room-service 房间群配置属于同一个 SDKAppID。
|
# 腾讯云 IM 应用配置;必须和 gateway 的 UserSig、room-service 房间群配置属于同一个 SDKAppID。
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|||||||
@ -17,6 +17,13 @@ first_recharge_reward_worker:
|
|||||||
enabled: false
|
enabled: false
|
||||||
red_packet_broadcast_worker:
|
red_packet_broadcast_worker:
|
||||||
enabled: false
|
enabled: false
|
||||||
|
lucky_gift_worker:
|
||||||
|
enabled: true
|
||||||
|
worker_poll_interval: "1s"
|
||||||
|
worker_batch_size: 100
|
||||||
|
worker_lock_ttl: "30s"
|
||||||
|
worker_max_retry: 8
|
||||||
|
publish_timeout: "5s"
|
||||||
tencent_im:
|
tencent_im:
|
||||||
# activity-service 只负责全局/区域播报群;必须与 gateway/room-service 使用同一组腾讯 IM 应用配置。
|
# activity-service 只负责全局/区域播报群;必须与 gateway/room-service 使用同一组腾讯 IM 应用配置。
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|||||||
@ -38,6 +38,9 @@ CREATE TABLE IF NOT EXISTS activity_outbox (
|
|||||||
status VARCHAR(32) NOT NULL COMMENT '业务状态',
|
status VARCHAR(32) NOT NULL COMMENT '业务状态',
|
||||||
retry_count INT NOT NULL DEFAULT 0 COMMENT '重试次数',
|
retry_count INT NOT NULL DEFAULT 0 COMMENT '重试次数',
|
||||||
next_retry_at_ms BIGINT NOT NULL COMMENT '下一次重试时间,UTC epoch ms',
|
next_retry_at_ms BIGINT NOT NULL COMMENT '下一次重试时间,UTC epoch ms',
|
||||||
|
locked_by VARCHAR(128) NOT NULL DEFAULT '' COMMENT '当前锁定 worker',
|
||||||
|
lock_until_ms BIGINT NOT NULL DEFAULT 0 COMMENT '锁过期时间,UTC epoch ms',
|
||||||
|
last_error VARCHAR(512) NOT NULL DEFAULT '' COMMENT '最后一次失败原因',
|
||||||
created_at_ms BIGINT NOT NULL COMMENT '创建时间,UTC epoch ms',
|
created_at_ms BIGINT NOT NULL COMMENT '创建时间,UTC epoch ms',
|
||||||
updated_at_ms BIGINT NOT NULL COMMENT '更新时间,UTC epoch ms',
|
updated_at_ms BIGINT NOT NULL COMMENT '更新时间,UTC epoch ms',
|
||||||
PRIMARY KEY (app_code, outbox_id),
|
PRIMARY KEY (app_code, outbox_id),
|
||||||
@ -194,6 +197,8 @@ CREATE TABLE IF NOT EXISTS lucky_draw_records (
|
|||||||
pool_snapshot_json JSON NOT NULL COMMENT '奖池快照',
|
pool_snapshot_json JSON NOT NULL COMMENT '奖池快照',
|
||||||
rtp_snapshot_json JSON NOT NULL COMMENT 'RTP 快照',
|
rtp_snapshot_json JSON NOT NULL COMMENT 'RTP 快照',
|
||||||
reward_status VARCHAR(32) NOT NULL COMMENT 'pending/granted/failed',
|
reward_status VARCHAR(32) NOT NULL COMMENT 'pending/granted/failed',
|
||||||
|
reward_transaction_id VARCHAR(128) NOT NULL DEFAULT '' COMMENT '返奖钱包交易 ID',
|
||||||
|
reward_failure_reason VARCHAR(255) NOT NULL DEFAULT '' COMMENT '返奖失败原因',
|
||||||
paid_at_ms BIGINT NOT NULL COMMENT '扣费时间,UTC epoch ms',
|
paid_at_ms BIGINT NOT NULL COMMENT '扣费时间,UTC epoch ms',
|
||||||
created_at_ms BIGINT NOT NULL COMMENT '创建时间,UTC epoch ms',
|
created_at_ms BIGINT NOT NULL COMMENT '创建时间,UTC epoch ms',
|
||||||
updated_at_ms BIGINT NOT NULL COMMENT '更新时间,UTC epoch ms',
|
updated_at_ms BIGINT NOT NULL COMMENT '更新时间,UTC epoch ms',
|
||||||
|
|||||||
@ -49,9 +49,12 @@ type App struct {
|
|||||||
healthHTTP *healthhttp.Server
|
healthHTTP *healthhttp.Server
|
||||||
mysqlRepo *mysqlstorage.Repository
|
mysqlRepo *mysqlstorage.Repository
|
||||||
broadcast *broadcastservice.Service
|
broadcast *broadcastservice.Service
|
||||||
|
luckyGift *luckygiftservice.Service
|
||||||
firstRechargeReward *firstrechargeservice.Service
|
firstRechargeReward *firstrechargeservice.Service
|
||||||
broadcastWorkerEnabled bool
|
broadcastWorkerEnabled bool
|
||||||
|
luckyGiftWorkerEnabled bool
|
||||||
workerNodeID string
|
workerNodeID string
|
||||||
|
luckyGiftWorkerOptions luckygiftservice.WorkerOptions
|
||||||
mqConsumers []*rocketmqx.Consumer
|
mqConsumers []*rocketmqx.Consumer
|
||||||
userConn *grpc.ClientConn
|
userConn *grpc.ClientConn
|
||||||
walletConn *grpc.ClientConn
|
walletConn *grpc.ClientConn
|
||||||
@ -105,10 +108,10 @@ func New(cfg config.Config) (*App, error) {
|
|||||||
sevenDayCheckInSvc := sevendaycheckinservice.New(repository, walletv1.NewWalletServiceClient(walletConn))
|
sevenDayCheckInSvc := sevendaycheckinservice.New(repository, walletv1.NewWalletServiceClient(walletConn))
|
||||||
growthSvc := growthservice.New(repository, walletv1.NewWalletServiceClient(walletConn))
|
growthSvc := growthservice.New(repository, walletv1.NewWalletServiceClient(walletConn))
|
||||||
achievementSvc := achievementservice.New(repository, walletv1.NewWalletServiceClient(walletConn))
|
achievementSvc := achievementservice.New(repository, walletv1.NewWalletServiceClient(walletConn))
|
||||||
luckyGiftSvc := luckygiftservice.New(repository)
|
var tencentClient *tencentim.RESTClient
|
||||||
var broadcastPublisher broadcastservice.Publisher
|
var broadcastPublisher broadcastservice.Publisher
|
||||||
if cfg.TencentIM.Enabled {
|
if cfg.TencentIM.Enabled {
|
||||||
tencentClient, err := tencentim.NewRESTClient(cfg.TencentIM.RESTConfig())
|
tencentClient, err = tencentim.NewRESTClient(cfg.TencentIM.RESTConfig())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = walletConn.Close()
|
_ = walletConn.Close()
|
||||||
_ = userConn.Close()
|
_ = userConn.Close()
|
||||||
@ -118,6 +121,10 @@ func New(cfg config.Config) (*App, error) {
|
|||||||
}
|
}
|
||||||
broadcastPublisher = tencentClient
|
broadcastPublisher = tencentClient
|
||||||
}
|
}
|
||||||
|
luckyGiftSvc := luckygiftservice.New(repository,
|
||||||
|
luckygiftservice.WithWallet(walletv1.NewWalletServiceClient(walletConn)),
|
||||||
|
luckygiftservice.WithRoomPublisher(tencentClient),
|
||||||
|
)
|
||||||
if cfg.Broadcast.Enabled && broadcastPublisher == nil {
|
if cfg.Broadcast.Enabled && broadcastPublisher == nil {
|
||||||
_ = walletConn.Close()
|
_ = walletConn.Close()
|
||||||
_ = userConn.Close()
|
_ = userConn.Close()
|
||||||
@ -263,9 +270,12 @@ func New(cfg config.Config) (*App, error) {
|
|||||||
healthHTTP: healthHTTP,
|
healthHTTP: healthHTTP,
|
||||||
mysqlRepo: repository,
|
mysqlRepo: repository,
|
||||||
broadcast: broadcastSvc,
|
broadcast: broadcastSvc,
|
||||||
|
luckyGift: luckyGiftSvc,
|
||||||
firstRechargeReward: firstRechargeRewardSvc,
|
firstRechargeReward: firstRechargeRewardSvc,
|
||||||
broadcastWorkerEnabled: cfg.Broadcast.Enabled,
|
broadcastWorkerEnabled: cfg.Broadcast.Enabled,
|
||||||
|
luckyGiftWorkerEnabled: cfg.LuckyGiftWorker.Enabled,
|
||||||
workerNodeID: cfg.NodeID,
|
workerNodeID: cfg.NodeID,
|
||||||
|
luckyGiftWorkerOptions: luckyGiftWorkerOptions(cfg.NodeID, cfg.LuckyGiftWorker),
|
||||||
mqConsumers: mqConsumers,
|
mqConsumers: mqConsumers,
|
||||||
userConn: userConn,
|
userConn: userConn,
|
||||||
walletConn: walletConn,
|
walletConn: walletConn,
|
||||||
@ -287,6 +297,11 @@ func (a *App) Run() error {
|
|||||||
a.broadcast.RunWorker(a.workerCtx, broadcastservice.WorkerOptions{})
|
a.broadcast.RunWorker(a.workerCtx, broadcastservice.WorkerOptions{})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
if a.luckyGiftWorkerEnabled && a.luckyGift != nil && a.workerCtx != nil {
|
||||||
|
a.workerWG.Go(func() {
|
||||||
|
a.luckyGift.RunWorker(a.workerCtx, a.luckyGiftWorkerOptions)
|
||||||
|
})
|
||||||
|
}
|
||||||
err := a.server.Serve(a.listener)
|
err := a.server.Serve(a.listener)
|
||||||
if a.workerStop != nil {
|
if a.workerStop != nil {
|
||||||
a.workerStop()
|
a.workerStop()
|
||||||
@ -481,3 +496,14 @@ func redPacketRegionIDFromWalletPayload(payload string) int64 {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func luckyGiftWorkerOptions(nodeID string, cfg config.LuckyGiftWorkerConfig) luckygiftservice.WorkerOptions {
|
||||||
|
return luckygiftservice.WorkerOptions{
|
||||||
|
WorkerID: nodeID + "-lucky-gift",
|
||||||
|
PollInterval: cfg.WorkerPollInterval,
|
||||||
|
BatchSize: cfg.WorkerBatchSize,
|
||||||
|
LockTTL: cfg.WorkerLockTTL,
|
||||||
|
MaxRetry: cfg.WorkerMaxRetry,
|
||||||
|
PublishTimeout: cfg.PublishTimeout,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -29,6 +29,8 @@ type Config struct {
|
|||||||
FirstRechargeRewardWorker FirstRechargeRewardWorkerConfig `yaml:"first_recharge_reward_worker"`
|
FirstRechargeRewardWorker FirstRechargeRewardWorkerConfig `yaml:"first_recharge_reward_worker"`
|
||||||
// RedPacketBroadcastWorker 控制红包创建事实转区域飘屏 outbox 的本地消费。
|
// RedPacketBroadcastWorker 控制红包创建事实转区域飘屏 outbox 的本地消费。
|
||||||
RedPacketBroadcastWorker RedPacketBroadcastWorkerConfig `yaml:"red_packet_broadcast_worker"`
|
RedPacketBroadcastWorker RedPacketBroadcastWorkerConfig `yaml:"red_packet_broadcast_worker"`
|
||||||
|
// LuckyGiftWorker 控制幸运礼物 draw outbox 的返奖和房间 IM 补偿。
|
||||||
|
LuckyGiftWorker LuckyGiftWorkerConfig `yaml:"lucky_gift_worker"`
|
||||||
// TencentIM 是 activity-service 发送全局/区域播报群消息的 REST 配置。
|
// TencentIM 是 activity-service 发送全局/区域播报群消息的 REST 配置。
|
||||||
TencentIM TencentIMConfig `yaml:"tencent_im"`
|
TencentIM TencentIMConfig `yaml:"tencent_im"`
|
||||||
// Broadcast 控制 IM 播报群 reconciler、outbox worker 和贵重礼物阈值。
|
// Broadcast 控制 IM 播报群 reconciler、outbox worker 和贵重礼物阈值。
|
||||||
@ -65,6 +67,16 @@ type RedPacketBroadcastWorkerConfig struct {
|
|||||||
Enabled bool `yaml:"enabled"`
|
Enabled bool `yaml:"enabled"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LuckyGiftWorkerConfig 保存幸运礼物抽奖副作用补偿策略。
|
||||||
|
type LuckyGiftWorkerConfig struct {
|
||||||
|
Enabled bool `yaml:"enabled"`
|
||||||
|
WorkerPollInterval time.Duration `yaml:"worker_poll_interval"`
|
||||||
|
WorkerBatchSize int `yaml:"worker_batch_size"`
|
||||||
|
WorkerLockTTL time.Duration `yaml:"worker_lock_ttl"`
|
||||||
|
WorkerMaxRetry int `yaml:"worker_max_retry"`
|
||||||
|
PublishTimeout time.Duration `yaml:"publish_timeout"`
|
||||||
|
}
|
||||||
|
|
||||||
// TencentIMConfig 描述 activity-service 调用腾讯云 IM REST API 的配置。
|
// TencentIMConfig 描述 activity-service 调用腾讯云 IM REST API 的配置。
|
||||||
type TencentIMConfig struct {
|
type TencentIMConfig struct {
|
||||||
Enabled bool `yaml:"enabled"`
|
Enabled bool `yaml:"enabled"`
|
||||||
@ -153,6 +165,14 @@ func Default() Config {
|
|||||||
RedPacketBroadcastWorker: RedPacketBroadcastWorkerConfig{
|
RedPacketBroadcastWorker: RedPacketBroadcastWorkerConfig{
|
||||||
Enabled: false,
|
Enabled: false,
|
||||||
},
|
},
|
||||||
|
LuckyGiftWorker: LuckyGiftWorkerConfig{
|
||||||
|
Enabled: false,
|
||||||
|
WorkerPollInterval: time.Second,
|
||||||
|
WorkerBatchSize: 100,
|
||||||
|
WorkerLockTTL: 30 * time.Second,
|
||||||
|
WorkerMaxRetry: 8,
|
||||||
|
PublishTimeout: 5 * time.Second,
|
||||||
|
},
|
||||||
TencentIM: TencentIMConfig{
|
TencentIM: TencentIMConfig{
|
||||||
Enabled: false,
|
Enabled: false,
|
||||||
AdminIdentifier: "administrator",
|
AdminIdentifier: "administrator",
|
||||||
@ -271,6 +291,21 @@ func Load(path string) (Config, error) {
|
|||||||
if cfg.Broadcast.WorkerMaxRetry <= 0 {
|
if cfg.Broadcast.WorkerMaxRetry <= 0 {
|
||||||
cfg.Broadcast.WorkerMaxRetry = 8
|
cfg.Broadcast.WorkerMaxRetry = 8
|
||||||
}
|
}
|
||||||
|
if cfg.LuckyGiftWorker.WorkerPollInterval <= 0 {
|
||||||
|
cfg.LuckyGiftWorker.WorkerPollInterval = time.Second
|
||||||
|
}
|
||||||
|
if cfg.LuckyGiftWorker.WorkerBatchSize <= 0 {
|
||||||
|
cfg.LuckyGiftWorker.WorkerBatchSize = 100
|
||||||
|
}
|
||||||
|
if cfg.LuckyGiftWorker.WorkerLockTTL <= 0 {
|
||||||
|
cfg.LuckyGiftWorker.WorkerLockTTL = 30 * time.Second
|
||||||
|
}
|
||||||
|
if cfg.LuckyGiftWorker.WorkerMaxRetry <= 0 {
|
||||||
|
cfg.LuckyGiftWorker.WorkerMaxRetry = 8
|
||||||
|
}
|
||||||
|
if cfg.LuckyGiftWorker.PublishTimeout <= 0 {
|
||||||
|
cfg.LuckyGiftWorker.PublishTimeout = 5 * time.Second
|
||||||
|
}
|
||||||
rocketMQ, err := normalizeRocketMQConfig(cfg.RocketMQ)
|
rocketMQ, err := normalizeRocketMQConfig(cfg.RocketMQ)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Config{}, err
|
return Config{}, err
|
||||||
@ -279,6 +314,9 @@ func Load(path string) (Config, error) {
|
|||||||
if (cfg.FirstRechargeRewardWorker.Enabled || cfg.RedPacketBroadcastWorker.Enabled) && !cfg.RocketMQ.WalletOutbox.Enabled {
|
if (cfg.FirstRechargeRewardWorker.Enabled || cfg.RedPacketBroadcastWorker.Enabled) && !cfg.RocketMQ.WalletOutbox.Enabled {
|
||||||
return Config{}, errors.New("wallet outbox workers require rocketmq.wallet_outbox.enabled")
|
return Config{}, errors.New("wallet outbox workers require rocketmq.wallet_outbox.enabled")
|
||||||
}
|
}
|
||||||
|
if cfg.LuckyGiftWorker.Enabled && !cfg.TencentIM.Enabled {
|
||||||
|
return Config{}, errors.New("lucky gift worker requires tencent_im.enabled")
|
||||||
|
}
|
||||||
|
|
||||||
return cfg, nil
|
return cfg, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,8 @@ const (
|
|||||||
StatusPaused = "paused"
|
StatusPaused = "paused"
|
||||||
StatusClosed = "closed"
|
StatusClosed = "closed"
|
||||||
StatusPending = "pending"
|
StatusPending = "pending"
|
||||||
|
StatusGranted = "granted"
|
||||||
|
StatusFailed = "failed"
|
||||||
|
|
||||||
PoolNovice = "novice"
|
PoolNovice = "novice"
|
||||||
PoolIntermediate = "intermediate"
|
PoolIntermediate = "intermediate"
|
||||||
@ -82,15 +84,17 @@ type CheckCommand struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type DrawCommand struct {
|
type DrawCommand struct {
|
||||||
CommandID string
|
CommandID string
|
||||||
PoolID string
|
PoolID string
|
||||||
UserID int64
|
UserID int64
|
||||||
DeviceID string
|
TargetUserID int64
|
||||||
RoomID string
|
DeviceID string
|
||||||
AnchorID string
|
RoomID string
|
||||||
GiftID string
|
AnchorID string
|
||||||
CoinSpent int64
|
GiftID string
|
||||||
PaidAtMS int64
|
GiftCount int32
|
||||||
|
CoinSpent int64
|
||||||
|
PaidAtMS int64
|
||||||
}
|
}
|
||||||
|
|
||||||
type CheckResult struct {
|
type CheckResult struct {
|
||||||
@ -157,3 +161,13 @@ type DrawQuery struct {
|
|||||||
Page int32
|
Page int32
|
||||||
PageSize int32
|
PageSize int32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DrawOutbox 是幸运礼物抽奖事务写出的异步副作用载体,worker 只消费这个持久事实。
|
||||||
|
type DrawOutbox struct {
|
||||||
|
AppCode string
|
||||||
|
OutboxID string
|
||||||
|
EventType string
|
||||||
|
PayloadJSON string
|
||||||
|
RetryCount int
|
||||||
|
CreatedAtMS int64
|
||||||
|
}
|
||||||
|
|||||||
@ -2,10 +2,17 @@ package luckygift
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"log/slog"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
walletv1 "hyapp.local/api/proto/wallet/v1"
|
||||||
"hyapp/pkg/appcode"
|
"hyapp/pkg/appcode"
|
||||||
|
"hyapp/pkg/logx"
|
||||||
|
"hyapp/pkg/tencentim"
|
||||||
"hyapp/pkg/xerr"
|
"hyapp/pkg/xerr"
|
||||||
domain "hyapp/services/activity-service/internal/domain/luckygift"
|
domain "hyapp/services/activity-service/internal/domain/luckygift"
|
||||||
)
|
)
|
||||||
@ -19,16 +26,54 @@ type Repository interface {
|
|||||||
ExecuteLuckyGiftDraw(ctx context.Context, cmd domain.DrawCommand, nowMS int64) (domain.DrawResult, error)
|
ExecuteLuckyGiftDraw(ctx context.Context, cmd domain.DrawCommand, nowMS int64) (domain.DrawResult, error)
|
||||||
ListLuckyGiftDraws(ctx context.Context, query domain.DrawQuery) ([]domain.DrawResult, int64, error)
|
ListLuckyGiftDraws(ctx context.Context, query domain.DrawQuery) ([]domain.DrawResult, int64, error)
|
||||||
GetLuckyGiftDrawSummary(ctx context.Context, query domain.DrawQuery) (domain.DrawSummary, error)
|
GetLuckyGiftDrawSummary(ctx context.Context, query domain.DrawQuery) (domain.DrawSummary, error)
|
||||||
|
ClaimPendingLuckyGiftOutbox(ctx context.Context, workerID string, nowMS int64, lockTTL time.Duration, batchSize int) ([]domain.DrawOutbox, error)
|
||||||
|
MarkLuckyGiftOutboxDelivered(ctx context.Context, event domain.DrawOutbox, nowMS int64) error
|
||||||
|
MarkLuckyGiftOutboxRetryable(ctx context.Context, event domain.DrawOutbox, retryCount int, nextRetryAtMS int64, lastErr string, nowMS int64) error
|
||||||
|
MarkLuckyGiftOutboxFailed(ctx context.Context, event domain.DrawOutbox, retryCount int, lastErr string, nowMS int64) error
|
||||||
|
MarkLuckyGiftDrawGranted(ctx context.Context, appCode string, drawID string, walletTransactionID string, nowMS int64) error
|
||||||
|
MarkLuckyGiftDrawFailed(ctx context.Context, appCode string, drawID string, failureReason string, nowMS int64) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// WalletClient 是幸运礼物返奖唯一账务依赖;实际余额变更通知继续由 wallet outbox -> notice-service 投递。
|
||||||
|
type WalletClient interface {
|
||||||
|
CreditLuckyGiftReward(ctx context.Context, req *walletv1.CreditLuckyGiftRewardRequest, opts ...grpc.CallOption) (*walletv1.CreditLuckyGiftRewardResponse, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RoomPublisher 只负责投递房间群自定义消息,不拥有房间状态。
|
||||||
|
type RoomPublisher interface {
|
||||||
|
PublishGroupCustomMessage(ctx context.Context, message tencentim.CustomGroupMessage) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Service 承载幸运礼物查询、抽奖命令和后台规则配置。
|
// Service 承载幸运礼物查询、抽奖命令和后台规则配置。
|
||||||
type Service struct {
|
type Service struct {
|
||||||
repository Repository
|
repository Repository
|
||||||
|
wallet WalletClient
|
||||||
|
publisher RoomPublisher
|
||||||
now func() time.Time
|
now func() time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(repository Repository) *Service {
|
type Option func(*Service)
|
||||||
return &Service{repository: repository, now: time.Now}
|
|
||||||
|
func WithWallet(client WalletClient) Option {
|
||||||
|
return func(s *Service) {
|
||||||
|
s.wallet = client
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithRoomPublisher(publisher RoomPublisher) Option {
|
||||||
|
return func(s *Service) {
|
||||||
|
s.publisher = publisher
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(repository Repository, options ...Option) *Service {
|
||||||
|
service := &Service{repository: repository, now: time.Now}
|
||||||
|
for _, option := range options {
|
||||||
|
if option != nil {
|
||||||
|
option(service)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return service
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) SetClock(now func() time.Time) {
|
func (s *Service) SetClock(now func() time.Time) {
|
||||||
@ -63,12 +108,131 @@ func (s *Service) Draw(ctx context.Context, cmd domain.DrawCommand) (domain.Draw
|
|||||||
if cmd.CommandID == "" || cmd.UserID <= 0 || cmd.DeviceID == "" || cmd.RoomID == "" || cmd.AnchorID == "" || cmd.GiftID == "" || cmd.CoinSpent <= 0 {
|
if cmd.CommandID == "" || cmd.UserID <= 0 || cmd.DeviceID == "" || cmd.RoomID == "" || cmd.AnchorID == "" || cmd.GiftID == "" || cmd.CoinSpent <= 0 {
|
||||||
return domain.DrawResult{}, xerr.New(xerr.InvalidArgument, "lucky gift draw command is incomplete")
|
return domain.DrawResult{}, xerr.New(xerr.InvalidArgument, "lucky gift draw command is incomplete")
|
||||||
}
|
}
|
||||||
|
if cmd.TargetUserID < 0 || cmd.GiftCount < 0 {
|
||||||
|
return domain.DrawResult{}, xerr.New(xerr.InvalidArgument, "lucky gift draw metadata is invalid")
|
||||||
|
}
|
||||||
if cmd.PaidAtMS <= 0 {
|
if cmd.PaidAtMS <= 0 {
|
||||||
cmd.PaidAtMS = s.now().UTC().UnixMilli()
|
cmd.PaidAtMS = s.now().UTC().UnixMilli()
|
||||||
}
|
}
|
||||||
return s.repository.ExecuteLuckyGiftDraw(ctx, cmd, s.now().UTC().UnixMilli())
|
return s.repository.ExecuteLuckyGiftDraw(ctx, cmd, s.now().UTC().UnixMilli())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type WorkerOptions struct {
|
||||||
|
WorkerID string
|
||||||
|
PollInterval time.Duration
|
||||||
|
BatchSize int
|
||||||
|
LockTTL time.Duration
|
||||||
|
MaxRetry int
|
||||||
|
PublishTimeout time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) RunWorker(ctx context.Context, options WorkerOptions) {
|
||||||
|
options = normalizeWorkerOptions(options)
|
||||||
|
ticker := time.NewTicker(options.PollInterval)
|
||||||
|
defer ticker.Stop()
|
||||||
|
for {
|
||||||
|
if _, err := s.ProcessPendingDrawOutbox(ctx, options); err != nil && ctx.Err() == nil {
|
||||||
|
// 批处理失败不删除 outbox;锁过期后下一轮或其他实例会继续补偿。
|
||||||
|
logx.Error(ctx, "lucky_gift_outbox_batch_failed", err, slog.String("worker_id", options.WorkerID))
|
||||||
|
}
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
case <-ticker.C:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) ProcessPendingDrawOutbox(ctx context.Context, options WorkerOptions) (int, error) {
|
||||||
|
if err := s.requireRepository(); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
options = normalizeWorkerOptions(options)
|
||||||
|
events, err := s.repository.ClaimPendingLuckyGiftOutbox(ctx, options.WorkerID, s.now().UTC().UnixMilli(), options.LockTTL, options.BatchSize)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
processed := 0
|
||||||
|
for _, event := range events {
|
||||||
|
if err := s.processDrawOutbox(ctx, event, options); err != nil {
|
||||||
|
return processed, err
|
||||||
|
}
|
||||||
|
processed++
|
||||||
|
}
|
||||||
|
return processed, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) processDrawOutbox(ctx context.Context, event domain.DrawOutbox, options WorkerOptions) error {
|
||||||
|
payload, err := decodeDrawOutboxPayload(event.PayloadJSON)
|
||||||
|
if err != nil {
|
||||||
|
return s.markOutboxFailed(ctx, event, options, err, false)
|
||||||
|
}
|
||||||
|
eventCtx := appcode.WithContext(ctx, event.AppCode)
|
||||||
|
walletTransactionID := ""
|
||||||
|
credited := false
|
||||||
|
if payload.EffectiveRewardCoins > 0 {
|
||||||
|
if s.wallet == nil {
|
||||||
|
return s.markOutboxFailed(eventCtx, event, options, fmt.Errorf("lucky gift wallet client is not configured"), false)
|
||||||
|
}
|
||||||
|
resp, err := s.wallet.CreditLuckyGiftReward(eventCtx, &walletv1.CreditLuckyGiftRewardRequest{
|
||||||
|
CommandId: "lucky_reward:" + payload.DrawID,
|
||||||
|
AppCode: event.AppCode,
|
||||||
|
TargetUserId: payload.UserID,
|
||||||
|
Amount: payload.EffectiveRewardCoins,
|
||||||
|
DrawId: payload.DrawID,
|
||||||
|
RoomId: payload.RoomID,
|
||||||
|
GiftId: payload.GiftID,
|
||||||
|
PoolId: payload.PoolID,
|
||||||
|
Reason: "lucky_gift_reward",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return s.markOutboxFailed(eventCtx, event, options, err, false)
|
||||||
|
}
|
||||||
|
walletTransactionID = resp.GetTransactionId()
|
||||||
|
credited = true
|
||||||
|
}
|
||||||
|
if s.publisher == nil {
|
||||||
|
return s.markOutboxFailed(eventCtx, event, options, fmt.Errorf("lucky gift room publisher is not configured"), credited)
|
||||||
|
}
|
||||||
|
if err := s.publishLuckyGiftDrawn(eventCtx, payload, options); err != nil {
|
||||||
|
return s.markOutboxFailed(eventCtx, event, options, err, credited)
|
||||||
|
}
|
||||||
|
nowMS := s.now().UTC().UnixMilli()
|
||||||
|
if err := s.repository.MarkLuckyGiftDrawGranted(eventCtx, event.AppCode, payload.DrawID, walletTransactionID, nowMS); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return s.repository.MarkLuckyGiftOutboxDelivered(eventCtx, event, nowMS)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) publishLuckyGiftDrawn(ctx context.Context, payload luckyGiftDrawnPayload, options WorkerOptions) error {
|
||||||
|
body, err := json.Marshal(payload)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
publishCtx, cancel := context.WithTimeout(ctx, options.PublishTimeout)
|
||||||
|
defer cancel()
|
||||||
|
return s.publisher.PublishGroupCustomMessage(publishCtx, tencentim.CustomGroupMessage{
|
||||||
|
GroupID: payload.RoomID,
|
||||||
|
EventID: payload.EventID,
|
||||||
|
Desc: "lucky_gift_drawn",
|
||||||
|
Ext: "room_system_message",
|
||||||
|
PayloadJSON: body,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) markOutboxFailed(ctx context.Context, event domain.DrawOutbox, options WorkerOptions, cause error, alreadyCredited bool) error {
|
||||||
|
nowMS := s.now().UTC().UnixMilli()
|
||||||
|
nextRetryCount := event.RetryCount + 1
|
||||||
|
if nextRetryCount >= options.MaxRetry {
|
||||||
|
if !alreadyCredited {
|
||||||
|
_ = s.repository.MarkLuckyGiftDrawFailed(ctx, event.AppCode, drawIDFromPayload(event.PayloadJSON), cause.Error(), nowMS)
|
||||||
|
}
|
||||||
|
return s.repository.MarkLuckyGiftOutboxFailed(ctx, event, nextRetryCount, cause.Error(), nowMS)
|
||||||
|
}
|
||||||
|
nextRetryAtMS := nowMS + luckyGiftBackoff(nextRetryCount).Milliseconds()
|
||||||
|
return s.repository.MarkLuckyGiftOutboxRetryable(ctx, event, nextRetryCount, nextRetryAtMS, cause.Error(), nowMS)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Service) GetConfig(ctx context.Context, poolID string) (domain.Config, error) {
|
func (s *Service) GetConfig(ctx context.Context, poolID string) (domain.Config, error) {
|
||||||
if err := s.requireRepository(); err != nil {
|
if err := s.requireRepository(); err != nil {
|
||||||
return domain.Config{}, err
|
return domain.Config{}, err
|
||||||
@ -143,3 +307,94 @@ func normalizeDrawQuery(query domain.DrawQuery) domain.DrawQuery {
|
|||||||
query.Status = strings.TrimSpace(query.Status)
|
query.Status = strings.TrimSpace(query.Status)
|
||||||
return query
|
return query
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type luckyGiftDrawnPayload struct {
|
||||||
|
EventType string `json:"event_type"`
|
||||||
|
EventID string `json:"event_id"`
|
||||||
|
AppCode string `json:"app_code"`
|
||||||
|
DrawID string `json:"draw_id"`
|
||||||
|
CommandID string `json:"command_id"`
|
||||||
|
PoolID string `json:"pool_id"`
|
||||||
|
RoomID string `json:"room_id"`
|
||||||
|
GiftID string `json:"gift_id"`
|
||||||
|
GiftCount int32 `json:"gift_count"`
|
||||||
|
UserID int64 `json:"user_id"`
|
||||||
|
SenderUserID int64 `json:"sender_user_id"`
|
||||||
|
TargetUserID int64 `json:"target_user_id"`
|
||||||
|
CoinSpent int64 `json:"coin_spent"`
|
||||||
|
RuleVersion int64 `json:"rule_version"`
|
||||||
|
ExperiencePool string `json:"experience_pool"`
|
||||||
|
SelectedTierID string `json:"selected_tier_id"`
|
||||||
|
MultiplierPPM int64 `json:"multiplier_ppm"`
|
||||||
|
BaseRewardCoins int64 `json:"base_reward_coins"`
|
||||||
|
RoomAtmosphereRewardCoins int64 `json:"room_atmosphere_reward_coins"`
|
||||||
|
ActivitySubsidyCoins int64 `json:"activity_subsidy_coins"`
|
||||||
|
EffectiveRewardCoins int64 `json:"effective_reward_coins"`
|
||||||
|
StageFeedback bool `json:"stage_feedback"`
|
||||||
|
HighMultiplier bool `json:"high_multiplier"`
|
||||||
|
CreatedAtMS int64 `json:"created_at_ms"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeDrawOutboxPayload(payloadJSON string) (luckyGiftDrawnPayload, error) {
|
||||||
|
var payload luckyGiftDrawnPayload
|
||||||
|
if err := json.Unmarshal([]byte(payloadJSON), &payload); err != nil {
|
||||||
|
return luckyGiftDrawnPayload{}, fmt.Errorf("invalid lucky gift outbox payload: %w", err)
|
||||||
|
}
|
||||||
|
if payload.EventType == "" {
|
||||||
|
payload.EventType = "lucky_gift_drawn"
|
||||||
|
}
|
||||||
|
if payload.EventID == "" && payload.DrawID != "" {
|
||||||
|
payload.EventID = "lucky_gift_drawn:" + payload.DrawID
|
||||||
|
}
|
||||||
|
if payload.SenderUserID == 0 {
|
||||||
|
payload.SenderUserID = payload.UserID
|
||||||
|
}
|
||||||
|
if payload.DrawID == "" || payload.EventID == "" || payload.RoomID == "" || payload.GiftID == "" || payload.UserID <= 0 {
|
||||||
|
return luckyGiftDrawnPayload{}, fmt.Errorf("lucky gift outbox payload is incomplete")
|
||||||
|
}
|
||||||
|
return payload, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func drawIDFromPayload(payloadJSON string) string {
|
||||||
|
payload, err := decodeDrawOutboxPayload(payloadJSON)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return payload.DrawID
|
||||||
|
}
|
||||||
|
|
||||||
|
func normalizeWorkerOptions(options WorkerOptions) WorkerOptions {
|
||||||
|
options.WorkerID = strings.TrimSpace(options.WorkerID)
|
||||||
|
if options.WorkerID == "" {
|
||||||
|
options.WorkerID = "lucky-gift-worker"
|
||||||
|
}
|
||||||
|
if options.PollInterval <= 0 {
|
||||||
|
options.PollInterval = time.Second
|
||||||
|
}
|
||||||
|
if options.BatchSize <= 0 {
|
||||||
|
options.BatchSize = 100
|
||||||
|
}
|
||||||
|
if options.BatchSize > 500 {
|
||||||
|
options.BatchSize = 500
|
||||||
|
}
|
||||||
|
if options.LockTTL <= 0 {
|
||||||
|
options.LockTTL = 30 * time.Second
|
||||||
|
}
|
||||||
|
if options.MaxRetry <= 0 {
|
||||||
|
options.MaxRetry = 8
|
||||||
|
}
|
||||||
|
if options.PublishTimeout <= 0 {
|
||||||
|
options.PublishTimeout = 5 * time.Second
|
||||||
|
}
|
||||||
|
return options
|
||||||
|
}
|
||||||
|
|
||||||
|
func luckyGiftBackoff(retryCount int) time.Duration {
|
||||||
|
if retryCount < 1 {
|
||||||
|
retryCount = 1
|
||||||
|
}
|
||||||
|
if retryCount > 6 {
|
||||||
|
retryCount = 6
|
||||||
|
}
|
||||||
|
return time.Duration(1<<retryCount) * time.Second
|
||||||
|
}
|
||||||
|
|||||||
@ -2,9 +2,14 @@ package luckygift
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
walletv1 "hyapp.local/api/proto/wallet/v1"
|
||||||
"hyapp/pkg/appcode"
|
"hyapp/pkg/appcode"
|
||||||
|
"hyapp/pkg/tencentim"
|
||||||
domain "hyapp/services/activity-service/internal/domain/luckygift"
|
domain "hyapp/services/activity-service/internal/domain/luckygift"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -38,9 +43,64 @@ func TestUpsertConfigPreservesPoolScope(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestProcessPendingDrawOutboxCreditsWalletAndPublishesRoomIM(t *testing.T) {
|
||||||
|
payload, _ := json.Marshal(map[string]any{
|
||||||
|
"event_type": "lucky_gift_drawn",
|
||||||
|
"event_id": "lucky_gift_drawn:lucky_draw_test",
|
||||||
|
"app_code": "lalu",
|
||||||
|
"draw_id": "lucky_draw_test",
|
||||||
|
"command_id": "cmd-gift",
|
||||||
|
"pool_id": "super_lucky",
|
||||||
|
"user_id": 42,
|
||||||
|
"sender_user_id": 42,
|
||||||
|
"target_user_id": 99,
|
||||||
|
"room_id": "room-1",
|
||||||
|
"gift_id": "rose",
|
||||||
|
"gift_count": 1,
|
||||||
|
"coin_spent": 100,
|
||||||
|
"effective_reward_coins": 300,
|
||||||
|
"multiplier_ppm": 3000000,
|
||||||
|
"stage_feedback": true,
|
||||||
|
"created_at_ms": 1760000000000,
|
||||||
|
})
|
||||||
|
repository := &fakeLuckyGiftRepository{
|
||||||
|
outbox: []domain.DrawOutbox{{
|
||||||
|
AppCode: "lalu",
|
||||||
|
OutboxID: "lucky_lucky_draw_test",
|
||||||
|
EventType: "LuckyGiftDrawn",
|
||||||
|
PayloadJSON: string(payload),
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
wallet := &fakeLuckyGiftWallet{}
|
||||||
|
publisher := &fakeLuckyGiftPublisher{}
|
||||||
|
service := New(repository, WithWallet(wallet), WithRoomPublisher(publisher))
|
||||||
|
service.SetClock(func() time.Time { return time.UnixMilli(1760000001000).UTC() })
|
||||||
|
|
||||||
|
processed, err := service.ProcessPendingDrawOutbox(context.Background(), WorkerOptions{WorkerID: "worker-1"})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("ProcessPendingDrawOutbox failed: %v", err)
|
||||||
|
}
|
||||||
|
if processed != 1 {
|
||||||
|
t.Fatalf("processed count mismatch: %d", processed)
|
||||||
|
}
|
||||||
|
if wallet.last == nil || wallet.last.GetDrawId() != "lucky_draw_test" || wallet.last.GetTargetUserId() != 42 || wallet.last.GetAmount() != 300 {
|
||||||
|
t.Fatalf("wallet reward request mismatch: %+v", wallet.last)
|
||||||
|
}
|
||||||
|
if publisher.last.GroupID != "room-1" || publisher.last.Desc != "lucky_gift_drawn" || publisher.last.EventID != "lucky_gift_drawn:lucky_draw_test" {
|
||||||
|
t.Fatalf("room im message mismatch: %+v", publisher.last)
|
||||||
|
}
|
||||||
|
if repository.grantedDrawID != "lucky_draw_test" || repository.deliveredOutboxID != "lucky_lucky_draw_test" {
|
||||||
|
t.Fatalf("repository settlement mismatch: granted=%s delivered=%s", repository.grantedDrawID, repository.deliveredOutboxID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type fakeLuckyGiftRepository struct {
|
type fakeLuckyGiftRepository struct {
|
||||||
getConfigCalls int
|
getConfigCalls int
|
||||||
upserted domain.Config
|
upserted domain.Config
|
||||||
|
outbox []domain.DrawOutbox
|
||||||
|
|
||||||
|
grantedDrawID string
|
||||||
|
deliveredOutboxID string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *fakeLuckyGiftRepository) GetLuckyGiftConfig(context.Context, string) (domain.Config, bool, error) {
|
func (r *fakeLuckyGiftRepository) GetLuckyGiftConfig(context.Context, string) (domain.Config, bool, error) {
|
||||||
@ -72,3 +132,47 @@ func (r *fakeLuckyGiftRepository) ListLuckyGiftDraws(context.Context, domain.Dra
|
|||||||
func (r *fakeLuckyGiftRepository) GetLuckyGiftDrawSummary(context.Context, domain.DrawQuery) (domain.DrawSummary, error) {
|
func (r *fakeLuckyGiftRepository) GetLuckyGiftDrawSummary(context.Context, domain.DrawQuery) (domain.DrawSummary, error) {
|
||||||
return domain.DrawSummary{}, nil
|
return domain.DrawSummary{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *fakeLuckyGiftRepository) ClaimPendingLuckyGiftOutbox(context.Context, string, int64, time.Duration, int) ([]domain.DrawOutbox, error) {
|
||||||
|
return r.outbox, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *fakeLuckyGiftRepository) MarkLuckyGiftOutboxDelivered(_ context.Context, event domain.DrawOutbox, _ int64) error {
|
||||||
|
r.deliveredOutboxID = event.OutboxID
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *fakeLuckyGiftRepository) MarkLuckyGiftOutboxRetryable(context.Context, domain.DrawOutbox, int, int64, string, int64) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *fakeLuckyGiftRepository) MarkLuckyGiftOutboxFailed(context.Context, domain.DrawOutbox, int, string, int64) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *fakeLuckyGiftRepository) MarkLuckyGiftDrawGranted(_ context.Context, _ string, drawID string, _ string, _ int64) error {
|
||||||
|
r.grantedDrawID = drawID
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *fakeLuckyGiftRepository) MarkLuckyGiftDrawFailed(context.Context, string, string, string, int64) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type fakeLuckyGiftWallet struct {
|
||||||
|
last *walletv1.CreditLuckyGiftRewardRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *fakeLuckyGiftWallet) CreditLuckyGiftReward(_ context.Context, req *walletv1.CreditLuckyGiftRewardRequest, _ ...grpc.CallOption) (*walletv1.CreditLuckyGiftRewardResponse, error) {
|
||||||
|
w.last = req
|
||||||
|
return &walletv1.CreditLuckyGiftRewardResponse{TransactionId: "wallet_tx_lucky", Amount: req.GetAmount()}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type fakeLuckyGiftPublisher struct {
|
||||||
|
last tencentim.CustomGroupMessage
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *fakeLuckyGiftPublisher) PublishGroupCustomMessage(_ context.Context, message tencentim.CustomGroupMessage) error {
|
||||||
|
p.last = message
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@ -556,33 +556,51 @@ func (r *Repository) applyLuckyDraw(ctx context.Context, tx *sql.Tx, input lucky
|
|||||||
coin_spent, rule_version, experience_pool, rtp_window_index, gift_rtp_window_index,
|
coin_spent, rule_version, experience_pool, rtp_window_index, gift_rtp_window_index,
|
||||||
selected_tier_id, base_reward_coins, room_atmosphere_reward_coins, activity_subsidy_coins,
|
selected_tier_id, base_reward_coins, room_atmosphere_reward_coins, activity_subsidy_coins,
|
||||||
effective_reward_coins, budget_sources_json, stage_feedback, high_multiplier,
|
effective_reward_coins, budget_sources_json, stage_feedback, high_multiplier,
|
||||||
candidate_tiers_json, pool_snapshot_json, rtp_snapshot_json, reward_status,
|
candidate_tiers_json, pool_snapshot_json, rtp_snapshot_json, reward_status, reward_transaction_id, reward_failure_reason,
|
||||||
paid_at_ms, created_at_ms, updated_at_ms
|
paid_at_ms, created_at_ms, updated_at_ms
|
||||||
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`,
|
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`,
|
||||||
input.AppCode, input.DrawID, input.Command.CommandID, input.Command.UserID, input.Command.DeviceID,
|
input.AppCode, input.DrawID, input.Command.CommandID, input.Command.UserID, input.Command.DeviceID,
|
||||||
input.Command.RoomID, input.Command.AnchorID, input.Config.GiftID, input.Command.GiftID, input.Command.CoinSpent,
|
input.Command.RoomID, input.Command.AnchorID, input.Config.GiftID, input.Command.GiftID, input.Command.CoinSpent,
|
||||||
input.Config.RuleVersion, input.ExperiencePool, input.GlobalWindow.WindowIndex, input.GiftWindow.WindowIndex,
|
input.Config.RuleVersion, input.ExperiencePool, input.GlobalWindow.WindowIndex, input.GiftWindow.WindowIndex,
|
||||||
input.Candidate.TierID, input.Candidate.BaseReward, input.Candidate.RoomReward, input.Candidate.ActivityReward,
|
input.Candidate.TierID, input.Candidate.BaseReward, input.Candidate.RoomReward, input.Candidate.ActivityReward,
|
||||||
input.Candidate.effectiveReward(), input.BudgetSourcesJSON, input.StageFeedback, input.Candidate.HighMultiplier,
|
input.Candidate.effectiveReward(), input.BudgetSourcesJSON, input.StageFeedback, input.Candidate.HighMultiplier,
|
||||||
string(candidateSnapshot), string(poolSnapshot), string(rtpSnapshot), domain.StatusPending,
|
string(candidateSnapshot), string(poolSnapshot), string(rtpSnapshot), domain.StatusPending, "", "",
|
||||||
input.Command.PaidAtMS, input.NowMS, input.NowMS,
|
input.Command.PaidAtMS, input.NowMS, input.NowMS,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if input.Candidate.effectiveReward() > 0 || input.StageFeedback || input.Candidate.Presentation {
|
if input.Candidate.effectiveReward() > 0 || input.StageFeedback || input.Candidate.Presentation {
|
||||||
payload, _ := json.Marshal(map[string]any{
|
payload, _ := json.Marshal(map[string]any{
|
||||||
"draw_id": input.DrawID,
|
"event_type": "lucky_gift_drawn",
|
||||||
"pool_id": input.Config.GiftID,
|
"event_id": "lucky_gift_drawn:" + input.DrawID,
|
||||||
"user_id": input.Command.UserID,
|
"app_code": input.AppCode,
|
||||||
"room_id": input.Command.RoomID,
|
"draw_id": input.DrawID,
|
||||||
"gift_id": input.Command.GiftID,
|
"command_id": input.Command.CommandID,
|
||||||
"effective_reward_coins": input.Candidate.effectiveReward(),
|
"pool_id": input.Config.GiftID,
|
||||||
"stage_feedback": input.StageFeedback,
|
"user_id": input.Command.UserID,
|
||||||
|
"sender_user_id": input.Command.UserID,
|
||||||
|
"target_user_id": input.Command.TargetUserID,
|
||||||
|
"room_id": input.Command.RoomID,
|
||||||
|
"gift_id": input.Command.GiftID,
|
||||||
|
"gift_count": input.Command.GiftCount,
|
||||||
|
"coin_spent": input.Command.CoinSpent,
|
||||||
|
"rule_version": input.Config.RuleVersion,
|
||||||
|
"experience_pool": input.ExperiencePool,
|
||||||
|
"selected_tier_id": input.Candidate.TierID,
|
||||||
|
"multiplier_ppm": input.Candidate.MultiplierPPM,
|
||||||
|
"base_reward_coins": input.Candidate.BaseReward,
|
||||||
|
"room_atmosphere_reward_coins": input.Candidate.RoomReward,
|
||||||
|
"activity_subsidy_coins": input.Candidate.ActivityReward,
|
||||||
|
"effective_reward_coins": input.Candidate.effectiveReward(),
|
||||||
|
"stage_feedback": input.StageFeedback,
|
||||||
|
"high_multiplier": input.Candidate.HighMultiplier,
|
||||||
|
"created_at_ms": input.NowMS,
|
||||||
})
|
})
|
||||||
if _, err := tx.ExecContext(ctx, `
|
if _, err := tx.ExecContext(ctx, `
|
||||||
INSERT INTO activity_outbox (
|
INSERT INTO activity_outbox (
|
||||||
app_code, outbox_id, event_type, payload, status, retry_count, next_retry_at_ms, created_at_ms, updated_at_ms
|
app_code, outbox_id, event_type, payload, status, retry_count, next_retry_at_ms,
|
||||||
) VALUES (?, ?, 'LuckyGiftDrawn', ?, 'pending', 0, ?, ?, ?)`,
|
locked_by, lock_until_ms, last_error, created_at_ms, updated_at_ms
|
||||||
|
) VALUES (?, ?, 'LuckyGiftDrawn', ?, 'pending', 0, ?, '', 0, '', ?, ?)`,
|
||||||
input.AppCode, "lucky_"+input.DrawID, payload, input.NowMS, input.NowMS, input.NowMS,
|
input.AppCode, "lucky_"+input.DrawID, payload, input.NowMS, input.NowMS, input.NowMS,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -591,6 +609,155 @@ func (r *Repository) applyLuckyDraw(ctx context.Context, tx *sql.Tx, input lucky
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ClaimPendingLuckyGiftOutbox 抢占幸运礼物抽奖副作用。抽奖事实已在同一事务落库,worker 只补偿钱包和房间 IM。
|
||||||
|
func (r *Repository) ClaimPendingLuckyGiftOutbox(ctx context.Context, workerID string, nowMS int64, lockTTL time.Duration, batchSize int) ([]domain.DrawOutbox, error) {
|
||||||
|
if r == nil || r.db == nil {
|
||||||
|
return nil, xerr.New(xerr.Unavailable, "mysql repository is not configured")
|
||||||
|
}
|
||||||
|
workerID = strings.TrimSpace(workerID)
|
||||||
|
if workerID == "" {
|
||||||
|
return nil, xerr.New(xerr.InvalidArgument, "worker_id is required")
|
||||||
|
}
|
||||||
|
if batchSize <= 0 {
|
||||||
|
batchSize = 100
|
||||||
|
}
|
||||||
|
if batchSize > 500 {
|
||||||
|
batchSize = 500
|
||||||
|
}
|
||||||
|
if lockTTL <= 0 {
|
||||||
|
lockTTL = 30 * time.Second
|
||||||
|
}
|
||||||
|
tx, err := r.db.BeginTx(ctx, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer func() { _ = tx.Rollback() }()
|
||||||
|
|
||||||
|
rows, err := tx.QueryContext(ctx, `
|
||||||
|
SELECT app_code, outbox_id, event_type, COALESCE(CAST(payload AS CHAR), '{}'), retry_count, created_at_ms
|
||||||
|
FROM activity_outbox
|
||||||
|
WHERE event_type = 'LuckyGiftDrawn'
|
||||||
|
AND (
|
||||||
|
(status IN ('pending', 'retryable') AND next_retry_at_ms <= ?)
|
||||||
|
OR (status = 'delivering' AND lock_until_ms <= ?)
|
||||||
|
)
|
||||||
|
ORDER BY created_at_ms ASC, outbox_id ASC
|
||||||
|
LIMIT ?
|
||||||
|
FOR UPDATE`, nowMS, nowMS, batchSize)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
events := make([]domain.DrawOutbox, 0, batchSize)
|
||||||
|
for rows.Next() {
|
||||||
|
var event domain.DrawOutbox
|
||||||
|
if err := rows.Scan(&event.AppCode, &event.OutboxID, &event.EventType, &event.PayloadJSON, &event.RetryCount, &event.CreatedAtMS); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
events = append(events, event)
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
lockUntilMS := nowMS + lockTTL.Milliseconds()
|
||||||
|
for _, event := range events {
|
||||||
|
if _, err := tx.ExecContext(ctx, `
|
||||||
|
UPDATE activity_outbox
|
||||||
|
SET status = 'delivering', locked_by = ?, lock_until_ms = ?, updated_at_ms = ?
|
||||||
|
WHERE app_code = ? AND outbox_id = ?`,
|
||||||
|
workerID, lockUntilMS, nowMS, event.AppCode, event.OutboxID,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := tx.Commit(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return events, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Repository) MarkLuckyGiftOutboxDelivered(ctx context.Context, event domain.DrawOutbox, nowMS int64) error {
|
||||||
|
if r == nil || r.db == nil {
|
||||||
|
return xerr.New(xerr.Unavailable, "mysql repository is not configured")
|
||||||
|
}
|
||||||
|
_, err := r.db.ExecContext(ctx, `
|
||||||
|
UPDATE activity_outbox
|
||||||
|
SET status = 'delivered', locked_by = '', lock_until_ms = 0, last_error = '', updated_at_ms = ?
|
||||||
|
WHERE app_code = ? AND outbox_id = ?`,
|
||||||
|
nowMS, appcode.Normalize(event.AppCode), event.OutboxID,
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Repository) MarkLuckyGiftOutboxRetryable(ctx context.Context, event domain.DrawOutbox, retryCount int, nextRetryAtMS int64, lastErr string, nowMS int64) error {
|
||||||
|
if r == nil || r.db == nil {
|
||||||
|
return xerr.New(xerr.Unavailable, "mysql repository is not configured")
|
||||||
|
}
|
||||||
|
_, err := r.db.ExecContext(ctx, `
|
||||||
|
UPDATE activity_outbox
|
||||||
|
SET status = 'retryable', retry_count = ?, next_retry_at_ms = ?, locked_by = '', lock_until_ms = 0,
|
||||||
|
last_error = ?, updated_at_ms = ?
|
||||||
|
WHERE app_code = ? AND outbox_id = ?`,
|
||||||
|
retryCount, nextRetryAtMS, trimLuckyLastError(lastErr), nowMS, appcode.Normalize(event.AppCode), event.OutboxID,
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Repository) MarkLuckyGiftOutboxFailed(ctx context.Context, event domain.DrawOutbox, retryCount int, lastErr string, nowMS int64) error {
|
||||||
|
if r == nil || r.db == nil {
|
||||||
|
return xerr.New(xerr.Unavailable, "mysql repository is not configured")
|
||||||
|
}
|
||||||
|
_, err := r.db.ExecContext(ctx, `
|
||||||
|
UPDATE activity_outbox
|
||||||
|
SET status = 'failed', retry_count = ?, locked_by = '', lock_until_ms = 0, last_error = ?, updated_at_ms = ?
|
||||||
|
WHERE app_code = ? AND outbox_id = ?`,
|
||||||
|
retryCount, trimLuckyLastError(lastErr), nowMS, appcode.Normalize(event.AppCode), event.OutboxID,
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Repository) MarkLuckyGiftDrawGranted(ctx context.Context, appCode string, drawID string, walletTransactionID string, nowMS int64) error {
|
||||||
|
if r == nil || r.db == nil {
|
||||||
|
return xerr.New(xerr.Unavailable, "mysql repository is not configured")
|
||||||
|
}
|
||||||
|
_, err := r.db.ExecContext(ctx, `
|
||||||
|
UPDATE lucky_draw_records
|
||||||
|
SET reward_status = ?, reward_transaction_id = ?, reward_failure_reason = '', updated_at_ms = ?
|
||||||
|
WHERE app_code = ? AND draw_id = ?`,
|
||||||
|
domain.StatusGranted, walletTransactionID, nowMS, appcode.Normalize(appCode), drawID,
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Repository) MarkLuckyGiftDrawFailed(ctx context.Context, appCode string, drawID string, failureReason string, nowMS int64) error {
|
||||||
|
if r == nil || r.db == nil || strings.TrimSpace(drawID) == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
_, err := r.db.ExecContext(ctx, `
|
||||||
|
UPDATE lucky_draw_records
|
||||||
|
SET reward_status = ?, reward_failure_reason = ?, updated_at_ms = ?
|
||||||
|
WHERE app_code = ? AND draw_id = ? AND reward_status = ?`,
|
||||||
|
domain.StatusFailed, trimLuckyFailureReason(failureReason), nowMS, appcode.Normalize(appCode), drawID, domain.StatusPending,
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func trimLuckyLastError(value string) string {
|
||||||
|
value = strings.TrimSpace(value)
|
||||||
|
if len(value) > 512 {
|
||||||
|
return value[:512]
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
func trimLuckyFailureReason(value string) string {
|
||||||
|
value = strings.TrimSpace(value)
|
||||||
|
if len(value) > 255 {
|
||||||
|
return value[:255]
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Repository) ListLuckyGiftDraws(ctx context.Context, query domain.DrawQuery) ([]domain.DrawResult, int64, error) {
|
func (r *Repository) ListLuckyGiftDraws(ctx context.Context, query domain.DrawQuery) ([]domain.DrawResult, int64, error) {
|
||||||
if r == nil || r.db == nil {
|
if r == nil || r.db == nil {
|
||||||
return nil, 0, xerr.New(xerr.Unavailable, "mysql repository is not configured")
|
return nil, 0, xerr.New(xerr.Unavailable, "mysql repository is not configured")
|
||||||
|
|||||||
@ -45,6 +45,15 @@ func (r *Repository) Migrate(ctx context.Context) error {
|
|||||||
if err := r.ensureLuckyDrawPoolID(ctx); err != nil {
|
if err := r.ensureLuckyDrawPoolID(ctx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := r.ensureLuckyGiftOutboxColumns(ctx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := r.ensureLuckyDrawRewardSettlementColumns(ctx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := r.ensureDefaultLuckyGiftRules(ctx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,6 +103,84 @@ func (r *Repository) ensureLuckyDrawPoolID(ctx context.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Repository) ensureLuckyGiftOutboxColumns(ctx context.Context) error {
|
||||||
|
additions := []struct {
|
||||||
|
name string
|
||||||
|
sql string
|
||||||
|
}{
|
||||||
|
{"locked_by", `ALTER TABLE activity_outbox ADD COLUMN locked_by VARCHAR(128) NOT NULL DEFAULT '' COMMENT '当前锁定 worker' AFTER next_retry_at_ms`},
|
||||||
|
{"lock_until_ms", `ALTER TABLE activity_outbox ADD COLUMN lock_until_ms BIGINT NOT NULL DEFAULT 0 COMMENT '锁过期时间,UTC epoch ms' AFTER locked_by`},
|
||||||
|
{"last_error", `ALTER TABLE activity_outbox ADD COLUMN last_error VARCHAR(512) NOT NULL DEFAULT '' COMMENT '最后一次失败原因' AFTER lock_until_ms`},
|
||||||
|
}
|
||||||
|
for _, addition := range additions {
|
||||||
|
exists, err := r.columnExists(ctx, "activity_outbox", addition.name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !exists {
|
||||||
|
if _, err := r.db.ExecContext(ctx, addition.sql); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Repository) ensureLuckyDrawRewardSettlementColumns(ctx context.Context) error {
|
||||||
|
additions := []struct {
|
||||||
|
name string
|
||||||
|
sql string
|
||||||
|
}{
|
||||||
|
{"reward_transaction_id", `ALTER TABLE lucky_draw_records ADD COLUMN reward_transaction_id VARCHAR(128) NOT NULL DEFAULT '' COMMENT '返奖钱包交易 ID' AFTER reward_status`},
|
||||||
|
{"reward_failure_reason", `ALTER TABLE lucky_draw_records ADD COLUMN reward_failure_reason VARCHAR(255) NOT NULL DEFAULT '' COMMENT '返奖失败原因' AFTER reward_transaction_id`},
|
||||||
|
}
|
||||||
|
for _, addition := range additions {
|
||||||
|
exists, err := r.columnExists(ctx, "lucky_draw_records", addition.name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !exists {
|
||||||
|
if _, err := r.db.ExecContext(ctx, addition.sql); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Repository) ensureDefaultLuckyGiftRules(ctx context.Context) error {
|
||||||
|
// 本地和 Docker 开发库通常保留 MySQL volume;这里补齐缺省 lucky/super_lucky 契约,但不覆盖后台已发布规则。
|
||||||
|
const seedNowMS int64 = 1779259000000
|
||||||
|
const seedTiersJSON = `[
|
||||||
|
{"pool":"novice","tier_id":"novice_none","reward_coins":0,"multiplier_ppm":0,"weight":0,"high_water_only":false,"enabled":true},
|
||||||
|
{"pool":"novice","tier_id":"novice_1x","reward_coins":100,"multiplier_ppm":1000000,"weight":0,"high_water_only":false,"enabled":true},
|
||||||
|
{"pool":"novice","tier_id":"novice_2x","reward_coins":200,"multiplier_ppm":2000000,"weight":0,"high_water_only":false,"enabled":true},
|
||||||
|
{"pool":"intermediate","tier_id":"intermediate_none","reward_coins":0,"multiplier_ppm":0,"weight":0,"high_water_only":false,"enabled":true},
|
||||||
|
{"pool":"intermediate","tier_id":"intermediate_1x","reward_coins":100,"multiplier_ppm":1000000,"weight":0,"high_water_only":false,"enabled":true},
|
||||||
|
{"pool":"intermediate","tier_id":"intermediate_2x","reward_coins":200,"multiplier_ppm":2000000,"weight":0,"high_water_only":false,"enabled":true},
|
||||||
|
{"pool":"advanced","tier_id":"advanced_none","reward_coins":0,"multiplier_ppm":0,"weight":0,"high_water_only":false,"enabled":true},
|
||||||
|
{"pool":"advanced","tier_id":"advanced_1x","reward_coins":100,"multiplier_ppm":1000000,"weight":0,"high_water_only":false,"enabled":true},
|
||||||
|
{"pool":"advanced","tier_id":"advanced_2x","reward_coins":200,"multiplier_ppm":2000000,"weight":0,"high_water_only":false,"enabled":true}
|
||||||
|
]`
|
||||||
|
_, err := r.db.ExecContext(ctx, `
|
||||||
|
INSERT IGNORE INTO lucky_gift_rules (
|
||||||
|
app_code, gift_id, enabled, rule_version, gift_price, target_rtp_ppm, pool_rate_ppm,
|
||||||
|
global_window_draws, gift_window_draws, novice_draw_limit, intermediate_draw_limit,
|
||||||
|
high_multiplier, high_water_pool_multiple, platform_pool_weight_ppm, room_pool_weight_ppm,
|
||||||
|
gift_pool_weight_ppm, initial_platform_pool, initial_gift_pool, initial_room_pool,
|
||||||
|
platform_reserve, gift_reserve, room_reserve, max_single_payout, user_hourly_payout_cap,
|
||||||
|
user_daily_payout_cap, device_daily_payout_cap, room_hourly_payout_cap, anchor_daily_payout_cap,
|
||||||
|
room_atmosphere_rate_ppm, room_atmosphere_initial, room_atmosphere_reserve,
|
||||||
|
activity_budget, activity_daily_limit, large_tier_enabled, tiers_json,
|
||||||
|
updated_by_admin_id, created_at_ms, updated_at_ms
|
||||||
|
) VALUES
|
||||||
|
('lalu', 'lucky', true, 1, 100, 950000, 950000, 100000, 100000, 2000, 20000, 100, 2, 200000, 300000, 500000, 9500000, 23750000, 5000000, 1000000, 1000000, 100000, 50000, 3420000, 61560000, 102600000, 68400000, 1231200000, 10000, 100000, 10000, 0, 0, true, ?, 0, ?, ?),
|
||||||
|
('lalu', 'super_lucky', true, 1, 100, 950000, 950000, 100000, 100000, 2000, 20000, 100, 2, 200000, 300000, 500000, 9500000, 23750000, 5000000, 1000000, 1000000, 100000, 50000, 3420000, 61560000, 102600000, 68400000, 1231200000, 10000, 100000, 10000, 0, 0, true, ?, 0, ?, ?)`,
|
||||||
|
seedTiersJSON, seedNowMS, seedNowMS, seedTiersJSON, seedNowMS, seedNowMS,
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Repository) columnExists(ctx context.Context, table string, column string) (bool, error) {
|
func (r *Repository) columnExists(ctx context.Context, table string, column string) (bool, error) {
|
||||||
database, err := r.currentDatabase(ctx)
|
database, err := r.currentDatabase(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -48,15 +48,17 @@ func (s *LuckyGiftServer) ExecuteLuckyGiftDraw(ctx context.Context, req *activit
|
|||||||
meta := req.GetLuckyGift()
|
meta := req.GetLuckyGift()
|
||||||
ctx = appcode.WithContext(ctx, meta.GetMeta().GetAppCode())
|
ctx = appcode.WithContext(ctx, meta.GetMeta().GetAppCode())
|
||||||
result, err := s.svc.Draw(ctx, domain.DrawCommand{
|
result, err := s.svc.Draw(ctx, domain.DrawCommand{
|
||||||
CommandID: meta.GetCommandId(),
|
CommandID: meta.GetCommandId(),
|
||||||
PoolID: meta.GetPoolId(),
|
PoolID: meta.GetPoolId(),
|
||||||
UserID: meta.GetUserId(),
|
UserID: meta.GetUserId(),
|
||||||
DeviceID: meta.GetDeviceId(),
|
TargetUserID: meta.GetTargetUserId(),
|
||||||
RoomID: meta.GetRoomId(),
|
DeviceID: meta.GetDeviceId(),
|
||||||
AnchorID: meta.GetAnchorId(),
|
RoomID: meta.GetRoomId(),
|
||||||
GiftID: meta.GetGiftId(),
|
AnchorID: meta.GetAnchorId(),
|
||||||
CoinSpent: meta.GetCoinSpent(),
|
GiftID: meta.GetGiftId(),
|
||||||
PaidAtMS: meta.GetPaidAtMs(),
|
GiftCount: meta.GetGiftCount(),
|
||||||
|
CoinSpent: meta.GetCoinSpent(),
|
||||||
|
PaidAtMS: meta.GetPaidAtMs(),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerr.ToGRPCError(err)
|
return nil, xerr.ToGRPCError(err)
|
||||||
|
|||||||
@ -99,6 +99,7 @@ func New(cfg config.Config) (*App, error) {
|
|||||||
var registrationRewardClient client.RegistrationRewardClient = client.NewGRPCRegistrationRewardClient(activityConn)
|
var registrationRewardClient client.RegistrationRewardClient = client.NewGRPCRegistrationRewardClient(activityConn)
|
||||||
var firstRechargeRewardClient client.FirstRechargeRewardClient = client.NewGRPCFirstRechargeRewardClient(activityConn)
|
var firstRechargeRewardClient client.FirstRechargeRewardClient = client.NewGRPCFirstRechargeRewardClient(activityConn)
|
||||||
var sevenDayCheckInClient client.SevenDayCheckInClient = client.NewGRPCSevenDayCheckInClient(activityConn)
|
var sevenDayCheckInClient client.SevenDayCheckInClient = client.NewGRPCSevenDayCheckInClient(activityConn)
|
||||||
|
var luckyGiftClient client.LuckyGiftClient = client.NewGRPCLuckyGiftClient(activityConn)
|
||||||
var broadcastClient client.BroadcastClient = client.NewGRPCBroadcastClient(activityConn)
|
var broadcastClient client.BroadcastClient = client.NewGRPCBroadcastClient(activityConn)
|
||||||
var gameClient client.GameClient = client.NewGRPCGameClient(gameConn)
|
var gameClient client.GameClient = client.NewGRPCGameClient(gameConn)
|
||||||
appConfigReader, err := openAppConfigReader(cfg.AppConfig)
|
appConfigReader, err := openAppConfigReader(cfg.AppConfig)
|
||||||
@ -143,6 +144,7 @@ func New(cfg config.Config) (*App, error) {
|
|||||||
handler.SetRegistrationRewardClient(registrationRewardClient)
|
handler.SetRegistrationRewardClient(registrationRewardClient)
|
||||||
handler.SetFirstRechargeRewardClient(firstRechargeRewardClient)
|
handler.SetFirstRechargeRewardClient(firstRechargeRewardClient)
|
||||||
handler.SetSevenDayCheckInClient(sevenDayCheckInClient)
|
handler.SetSevenDayCheckInClient(sevenDayCheckInClient)
|
||||||
|
handler.SetLuckyGiftClient(luckyGiftClient)
|
||||||
handler.SetBroadcastClient(broadcastClient)
|
handler.SetBroadcastClient(broadcastClient)
|
||||||
handler.SetGameClient(gameClient)
|
handler.SetGameClient(gameClient)
|
||||||
handler.SetLeaderboardWalletDB(leaderboardWalletDB)
|
handler.SetLeaderboardWalletDB(leaderboardWalletDB)
|
||||||
|
|||||||
@ -0,0 +1,25 @@
|
|||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
activityv1 "hyapp.local/api/proto/activity/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// LuckyGiftClient abstracts gateway access to activity-service lucky gift eligibility checks.
|
||||||
|
type LuckyGiftClient interface {
|
||||||
|
CheckLuckyGift(ctx context.Context, req *activityv1.CheckLuckyGiftRequest) (*activityv1.CheckLuckyGiftResponse, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type grpcLuckyGiftClient struct {
|
||||||
|
client activityv1.LuckyGiftServiceClient
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGRPCLuckyGiftClient(conn *grpc.ClientConn) LuckyGiftClient {
|
||||||
|
return &grpcLuckyGiftClient{client: activityv1.NewLuckyGiftServiceClient(conn)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *grpcLuckyGiftClient) CheckLuckyGift(ctx context.Context, req *activityv1.CheckLuckyGiftRequest) (*activityv1.CheckLuckyGiftResponse, error) {
|
||||||
|
return c.client.CheckLuckyGift(ctx, req)
|
||||||
|
}
|
||||||
@ -20,6 +20,7 @@ type Handler struct {
|
|||||||
registrationReward client.RegistrationRewardClient
|
registrationReward client.RegistrationRewardClient
|
||||||
firstRechargeReward client.FirstRechargeRewardClient
|
firstRechargeReward client.FirstRechargeRewardClient
|
||||||
sevenDayCheckIn client.SevenDayCheckInClient
|
sevenDayCheckIn client.SevenDayCheckInClient
|
||||||
|
luckyGift client.LuckyGiftClient
|
||||||
}
|
}
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
@ -33,6 +34,7 @@ type Config struct {
|
|||||||
RegistrationReward client.RegistrationRewardClient
|
RegistrationReward client.RegistrationRewardClient
|
||||||
FirstRechargeReward client.FirstRechargeRewardClient
|
FirstRechargeReward client.FirstRechargeRewardClient
|
||||||
SevenDayCheckIn client.SevenDayCheckInClient
|
SevenDayCheckIn client.SevenDayCheckInClient
|
||||||
|
LuckyGift client.LuckyGiftClient
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(config Config) *Handler {
|
func New(config Config) *Handler {
|
||||||
@ -47,6 +49,7 @@ func New(config Config) *Handler {
|
|||||||
registrationReward: config.RegistrationReward,
|
registrationReward: config.RegistrationReward,
|
||||||
firstRechargeReward: config.FirstRechargeReward,
|
firstRechargeReward: config.FirstRechargeReward,
|
||||||
sevenDayCheckIn: config.SevenDayCheckIn,
|
sevenDayCheckIn: config.SevenDayCheckIn,
|
||||||
|
luckyGift: config.LuckyGift,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,6 +62,7 @@ func (h *Handler) TaskHandlers() httproutes.TaskHandlers {
|
|||||||
GetSevenDayCheckInStatus: h.getSevenDayCheckInStatus,
|
GetSevenDayCheckInStatus: h.getSevenDayCheckInStatus,
|
||||||
SignSevenDayCheckIn: h.signSevenDayCheckIn,
|
SignSevenDayCheckIn: h.signSevenDayCheckIn,
|
||||||
ListUserLeaderboards: h.listUserLeaderboards,
|
ListUserLeaderboards: h.listUserLeaderboards,
|
||||||
|
CheckLuckyGift: h.checkLuckyGift,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,71 @@
|
|||||||
|
package activityapi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
activityv1 "hyapp.local/api/proto/activity/v1"
|
||||||
|
"hyapp/services/gateway-service/internal/auth"
|
||||||
|
"hyapp/services/gateway-service/internal/transport/http/httpkit"
|
||||||
|
)
|
||||||
|
|
||||||
|
type luckyGiftCheckRequest struct {
|
||||||
|
RoomID string `json:"room_id"`
|
||||||
|
GiftID string `json:"gift_id"`
|
||||||
|
PoolID string `json:"pool_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type luckyGiftCheckData struct {
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
Reason string `json:"reason"`
|
||||||
|
RoomID string `json:"room_id"`
|
||||||
|
GiftID string `json:"gift_id"`
|
||||||
|
PoolID string `json:"pool_id"`
|
||||||
|
GiftPrice int64 `json:"gift_price"`
|
||||||
|
RuleVersion int64 `json:"rule_version"`
|
||||||
|
TargetRTPPPM int64 `json:"target_rtp_ppm"`
|
||||||
|
ExperiencePool string `json:"experience_pool"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// checkLuckyGift 只做送礼前资格检查;扣费、抽奖和返奖都必须继续走 room-service 送礼主链路。
|
||||||
|
func (h *Handler) checkLuckyGift(writer http.ResponseWriter, request *http.Request) {
|
||||||
|
if h.luckyGift == nil {
|
||||||
|
httpkit.WriteError(writer, request, http.StatusBadGateway, httpkit.CodeUpstreamError, "upstream service error")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var body luckyGiftCheckRequest
|
||||||
|
if err := json.NewDecoder(request.Body).Decode(&body); err != nil {
|
||||||
|
httpkit.WriteError(writer, request, http.StatusBadRequest, httpkit.CodeInvalidArgument, "invalid request body")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
body.RoomID = strings.TrimSpace(body.RoomID)
|
||||||
|
body.GiftID = strings.TrimSpace(body.GiftID)
|
||||||
|
body.PoolID = strings.TrimSpace(body.PoolID)
|
||||||
|
if body.RoomID == "" || body.GiftID == "" || body.PoolID == "" {
|
||||||
|
httpkit.WriteError(writer, request, http.StatusBadRequest, httpkit.CodeInvalidArgument, "room_id, gift_id and pool_id are required")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp, err := h.luckyGift.CheckLuckyGift(request.Context(), &activityv1.CheckLuckyGiftRequest{
|
||||||
|
Meta: httpkit.ActivityMeta(request),
|
||||||
|
UserId: auth.UserIDFromContext(request.Context()),
|
||||||
|
RoomId: body.RoomID,
|
||||||
|
GiftId: body.GiftID,
|
||||||
|
PoolId: body.PoolID,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
httpkit.WriteRPCError(writer, request, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
httpkit.WriteOK(writer, request, luckyGiftCheckData{
|
||||||
|
Enabled: resp.GetEnabled(),
|
||||||
|
Reason: resp.GetReason(),
|
||||||
|
RoomID: body.RoomID,
|
||||||
|
GiftID: resp.GetGiftId(),
|
||||||
|
PoolID: resp.GetPoolId(),
|
||||||
|
GiftPrice: resp.GetGiftPrice(),
|
||||||
|
RuleVersion: resp.GetRuleVersion(),
|
||||||
|
TargetRTPPPM: resp.GetTargetRtpPpm(),
|
||||||
|
ExperiencePool: resp.GetExperiencePool(),
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -0,0 +1,64 @@
|
|||||||
|
package activityapi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
activityv1 "hyapp.local/api/proto/activity/v1"
|
||||||
|
"hyapp/pkg/appcode"
|
||||||
|
"hyapp/services/gateway-service/internal/auth"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCheckLuckyGiftForwardsEligibilityRequest(t *testing.T) {
|
||||||
|
client := &fakeLuckyGiftClient{resp: &activityv1.CheckLuckyGiftResponse{
|
||||||
|
Enabled: true,
|
||||||
|
Reason: "enabled",
|
||||||
|
GiftId: "rose",
|
||||||
|
PoolId: "super_lucky",
|
||||||
|
GiftPrice: 100,
|
||||||
|
RuleVersion: 3,
|
||||||
|
TargetRtpPpm: 600000,
|
||||||
|
ExperiencePool: "novice",
|
||||||
|
}}
|
||||||
|
handler := New(Config{LuckyGift: client})
|
||||||
|
request := httptest.NewRequest(http.MethodPost, "/api/v1/activities/lucky-gifts/check", strings.NewReader(`{"room_id":"room-1","gift_id":"rose","pool_id":"super_lucky"}`))
|
||||||
|
request = request.WithContext(auth.WithUserID(appcode.WithContext(request.Context(), "lalu"), 42))
|
||||||
|
recorder := httptest.NewRecorder()
|
||||||
|
|
||||||
|
handler.checkLuckyGift(recorder, request)
|
||||||
|
|
||||||
|
if recorder.Code != http.StatusOK {
|
||||||
|
t.Fatalf("status mismatch: %d body=%s", recorder.Code, recorder.Body.String())
|
||||||
|
}
|
||||||
|
if client.last == nil || client.last.GetUserId() != 42 || client.last.GetRoomId() != "room-1" || client.last.GetGiftId() != "rose" || client.last.GetPoolId() != "super_lucky" {
|
||||||
|
t.Fatalf("check request mismatch: %+v", client.last)
|
||||||
|
}
|
||||||
|
var envelope struct {
|
||||||
|
Code string `json:"code"`
|
||||||
|
Data struct {
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
Reason string `json:"reason"`
|
||||||
|
ExperiencePool string `json:"experience_pool"`
|
||||||
|
} `json:"data"`
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(recorder.Body.Bytes(), &envelope); err != nil {
|
||||||
|
t.Fatalf("decode response: %v", err)
|
||||||
|
}
|
||||||
|
if envelope.Code != "OK" || !envelope.Data.Enabled || envelope.Data.ExperiencePool != "novice" {
|
||||||
|
t.Fatalf("response mismatch: %+v", envelope)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type fakeLuckyGiftClient struct {
|
||||||
|
last *activityv1.CheckLuckyGiftRequest
|
||||||
|
resp *activityv1.CheckLuckyGiftResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *fakeLuckyGiftClient) CheckLuckyGift(_ context.Context, req *activityv1.CheckLuckyGiftRequest) (*activityv1.CheckLuckyGiftResponse, error) {
|
||||||
|
c.last = req
|
||||||
|
return c.resp, nil
|
||||||
|
}
|
||||||
@ -41,6 +41,7 @@ type Handler struct {
|
|||||||
registrationReward client.RegistrationRewardClient
|
registrationReward client.RegistrationRewardClient
|
||||||
firstRechargeReward client.FirstRechargeRewardClient
|
firstRechargeReward client.FirstRechargeRewardClient
|
||||||
sevenDayCheckIn client.SevenDayCheckInClient
|
sevenDayCheckIn client.SevenDayCheckInClient
|
||||||
|
luckyGift client.LuckyGiftClient
|
||||||
broadcastClient client.BroadcastClient
|
broadcastClient client.BroadcastClient
|
||||||
gameClient client.GameClient
|
gameClient client.GameClient
|
||||||
appConfigReader appapi.ConfigReader
|
appConfigReader appapi.ConfigReader
|
||||||
@ -204,6 +205,11 @@ func (h *Handler) SetSevenDayCheckInClient(sevenDayCheckIn client.SevenDayCheckI
|
|||||||
h.sevenDayCheckIn = sevenDayCheckIn
|
h.sevenDayCheckIn = sevenDayCheckIn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetLuckyGiftClient 注入 activity-service 幸运礼物资格检查 client。
|
||||||
|
func (h *Handler) SetLuckyGiftClient(luckyGift client.LuckyGiftClient) {
|
||||||
|
h.luckyGift = luckyGift
|
||||||
|
}
|
||||||
|
|
||||||
// SetBroadcastClient 注入 activity-service 播报群成员关系 client。
|
// SetBroadcastClient 注入 activity-service 播报群成员关系 client。
|
||||||
func (h *Handler) SetBroadcastClient(broadcastClient client.BroadcastClient) {
|
func (h *Handler) SetBroadcastClient(broadcastClient client.BroadcastClient) {
|
||||||
h.broadcastClient = broadcastClient
|
h.broadcastClient = broadcastClient
|
||||||
|
|||||||
@ -138,6 +138,7 @@ type TaskHandlers struct {
|
|||||||
GetSevenDayCheckInStatus http.HandlerFunc
|
GetSevenDayCheckInStatus http.HandlerFunc
|
||||||
SignSevenDayCheckIn http.HandlerFunc
|
SignSevenDayCheckIn http.HandlerFunc
|
||||||
ListUserLeaderboards http.HandlerFunc
|
ListUserLeaderboards http.HandlerFunc
|
||||||
|
CheckLuckyGift http.HandlerFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
type LevelHandlers struct {
|
type LevelHandlers struct {
|
||||||
@ -343,6 +344,7 @@ func (r routes) registerTaskRoutes() {
|
|||||||
r.profile("/activities/seven-day-checkin", http.MethodGet, h.GetSevenDayCheckInStatus)
|
r.profile("/activities/seven-day-checkin", http.MethodGet, h.GetSevenDayCheckInStatus)
|
||||||
r.profile("/activities/seven-day-checkin/sign", http.MethodPost, h.SignSevenDayCheckIn)
|
r.profile("/activities/seven-day-checkin/sign", http.MethodPost, h.SignSevenDayCheckIn)
|
||||||
r.profile("/activities/user-leaderboards", http.MethodGet, h.ListUserLeaderboards)
|
r.profile("/activities/user-leaderboards", http.MethodGet, h.ListUserLeaderboards)
|
||||||
|
r.profile("/activities/lucky-gifts/check", http.MethodPost, h.CheckLuckyGift)
|
||||||
r.profile("/tasks/tabs", http.MethodGet, h.ListTaskTabs)
|
r.profile("/tasks/tabs", http.MethodGet, h.ListTaskTabs)
|
||||||
r.profile("/tasks/claim", http.MethodPost, h.ClaimTaskReward)
|
r.profile("/tasks/claim", http.MethodPost, h.ClaimTaskReward)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -68,6 +68,7 @@ func (h *Handler) Routes(jwtVerifier *auth.Verifier) http.Handler {
|
|||||||
RegistrationReward: h.registrationReward,
|
RegistrationReward: h.registrationReward,
|
||||||
FirstRechargeReward: h.firstRechargeReward,
|
FirstRechargeReward: h.firstRechargeReward,
|
||||||
SevenDayCheckIn: h.sevenDayCheckIn,
|
SevenDayCheckIn: h.sevenDayCheckIn,
|
||||||
|
LuckyGift: h.luckyGift,
|
||||||
})
|
})
|
||||||
gameAPI := gameapi.New(gameapi.Config{
|
gameAPI := gameapi.New(gameapi.Config{
|
||||||
GameClient: h.gameClient,
|
GameClient: h.gameClient,
|
||||||
|
|||||||
@ -126,16 +126,18 @@ func (s *Service) SendGift(ctx context.Context, req *roomv1.SendGiftRequest) (*r
|
|||||||
if luckyEnabled {
|
if luckyEnabled {
|
||||||
drawResp, err := s.luckyGift.ExecuteLuckyGiftDraw(ctx, &activityv1.ExecuteLuckyGiftDrawRequest{
|
drawResp, err := s.luckyGift.ExecuteLuckyGiftDraw(ctx, &activityv1.ExecuteLuckyGiftDrawRequest{
|
||||||
LuckyGift: &activityv1.LuckyGiftMeta{
|
LuckyGift: &activityv1.LuckyGiftMeta{
|
||||||
Meta: activityMetaFromRoom(ctx, req.GetMeta()),
|
Meta: activityMetaFromRoom(ctx, req.GetMeta()),
|
||||||
CommandId: cmd.ID(),
|
CommandId: cmd.ID(),
|
||||||
UserId: cmd.ActorUserID(),
|
UserId: cmd.ActorUserID(),
|
||||||
DeviceId: luckyGiftDeviceID(cmd),
|
TargetUserId: cmd.TargetUserID,
|
||||||
RoomId: cmd.RoomID(),
|
DeviceId: luckyGiftDeviceID(cmd),
|
||||||
AnchorId: luckyGiftAnchorID(roomMeta),
|
RoomId: cmd.RoomID(),
|
||||||
GiftId: cmd.GiftID,
|
AnchorId: luckyGiftAnchorID(roomMeta),
|
||||||
CoinSpent: billing.GetCoinSpent(),
|
GiftId: cmd.GiftID,
|
||||||
PaidAtMs: now.UTC().UnixMilli(),
|
GiftCount: cmd.GiftCount,
|
||||||
PoolId: cmd.PoolID,
|
CoinSpent: billing.GetCoinSpent(),
|
||||||
|
PaidAtMs: now.UTC().UnixMilli(),
|
||||||
|
PoolId: cmd.PoolID,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -553,6 +553,27 @@ type TaskRewardReceipt struct {
|
|||||||
GrantedAtMS int64
|
GrantedAtMS int64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LuckyGiftRewardCommand 是 activity-service 用抽奖 draw_id 发起的 COIN 入账命令。
|
||||||
|
type LuckyGiftRewardCommand struct {
|
||||||
|
AppCode string
|
||||||
|
CommandID string
|
||||||
|
TargetUserID int64
|
||||||
|
Amount int64
|
||||||
|
DrawID string
|
||||||
|
RoomID string
|
||||||
|
GiftID string
|
||||||
|
PoolID string
|
||||||
|
Reason string
|
||||||
|
}
|
||||||
|
|
||||||
|
// LuckyGiftRewardReceipt 是幸运礼物返奖入账后的稳定回执。
|
||||||
|
type LuckyGiftRewardReceipt struct {
|
||||||
|
TransactionID string
|
||||||
|
Balance AssetBalance
|
||||||
|
Amount int64
|
||||||
|
GrantedAtMS int64
|
||||||
|
}
|
||||||
|
|
||||||
// GameCoinChangeCommand 是 game-service 对钱包发起的游戏专用金币改账命令。
|
// GameCoinChangeCommand 是 game-service 对钱包发起的游戏专用金币改账命令。
|
||||||
type GameCoinChangeCommand struct {
|
type GameCoinChangeCommand struct {
|
||||||
AppCode string
|
AppCode string
|
||||||
|
|||||||
@ -23,6 +23,7 @@ type Repository interface {
|
|||||||
AdminCreditCoinSellerStock(ctx context.Context, command ledger.CoinSellerStockCreditCommand) (ledger.CoinSellerStockCreditReceipt, error)
|
AdminCreditCoinSellerStock(ctx context.Context, command ledger.CoinSellerStockCreditCommand) (ledger.CoinSellerStockCreditReceipt, error)
|
||||||
TransferCoinFromSeller(ctx context.Context, command ledger.CoinSellerTransferCommand) (ledger.CoinSellerTransferReceipt, error)
|
TransferCoinFromSeller(ctx context.Context, command ledger.CoinSellerTransferCommand) (ledger.CoinSellerTransferReceipt, error)
|
||||||
CreditTaskReward(ctx context.Context, command ledger.TaskRewardCommand) (ledger.TaskRewardReceipt, error)
|
CreditTaskReward(ctx context.Context, command ledger.TaskRewardCommand) (ledger.TaskRewardReceipt, error)
|
||||||
|
CreditLuckyGiftReward(ctx context.Context, command ledger.LuckyGiftRewardCommand) (ledger.LuckyGiftRewardReceipt, error)
|
||||||
ApplyGameCoinChange(ctx context.Context, command ledger.GameCoinChangeCommand) (ledger.GameCoinChangeReceipt, error)
|
ApplyGameCoinChange(ctx context.Context, command ledger.GameCoinChangeCommand) (ledger.GameCoinChangeReceipt, error)
|
||||||
GetRedPacketConfig(ctx context.Context, appCode string) (ledger.RedPacketConfig, error)
|
GetRedPacketConfig(ctx context.Context, appCode string) (ledger.RedPacketConfig, error)
|
||||||
UpdateRedPacketConfig(ctx context.Context, config ledger.RedPacketConfig) (ledger.RedPacketConfig, error)
|
UpdateRedPacketConfig(ctx context.Context, config ledger.RedPacketConfig) (ledger.RedPacketConfig, error)
|
||||||
@ -269,6 +270,28 @@ func (s *Service) CreditTaskReward(ctx context.Context, command ledger.TaskRewar
|
|||||||
return s.repository.CreditTaskReward(ctx, command)
|
return s.repository.CreditTaskReward(ctx, command)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreditLuckyGiftReward 发放幸运礼物中奖金币;抽奖资格和金额已由 activity-service 决策,钱包只做幂等入账。
|
||||||
|
func (s *Service) CreditLuckyGiftReward(ctx context.Context, command ledger.LuckyGiftRewardCommand) (ledger.LuckyGiftRewardReceipt, error) {
|
||||||
|
if command.CommandID == "" || command.TargetUserID <= 0 || command.Amount <= 0 || command.DrawID == "" || command.RoomID == "" || command.GiftID == "" || command.PoolID == "" {
|
||||||
|
return ledger.LuckyGiftRewardReceipt{}, xerr.New(xerr.InvalidArgument, "lucky gift reward command is incomplete")
|
||||||
|
}
|
||||||
|
command.Reason = strings.TrimSpace(command.Reason)
|
||||||
|
if command.Reason == "" {
|
||||||
|
return ledger.LuckyGiftRewardReceipt{}, xerr.New(xerr.InvalidArgument, "reason is required")
|
||||||
|
}
|
||||||
|
if s.repository == nil {
|
||||||
|
return ledger.LuckyGiftRewardReceipt{}, xerr.New(xerr.Unavailable, "wallet repository is not configured")
|
||||||
|
}
|
||||||
|
command.AppCode = appcode.Normalize(command.AppCode)
|
||||||
|
command.DrawID = strings.TrimSpace(command.DrawID)
|
||||||
|
command.RoomID = strings.TrimSpace(command.RoomID)
|
||||||
|
command.GiftID = strings.TrimSpace(command.GiftID)
|
||||||
|
command.PoolID = strings.TrimSpace(command.PoolID)
|
||||||
|
ctx = appcode.WithContext(ctx, command.AppCode)
|
||||||
|
|
||||||
|
return s.repository.CreditLuckyGiftReward(ctx, command)
|
||||||
|
}
|
||||||
|
|
||||||
// ApplyGameCoinChange 是游戏平台唯一的 COIN 改账入口,方向由 op_type 控制。
|
// ApplyGameCoinChange 是游戏平台唯一的 COIN 改账入口,方向由 op_type 控制。
|
||||||
func (s *Service) ApplyGameCoinChange(ctx context.Context, command ledger.GameCoinChangeCommand) (ledger.GameCoinChangeReceipt, error) {
|
func (s *Service) ApplyGameCoinChange(ctx context.Context, command ledger.GameCoinChangeCommand) (ledger.GameCoinChangeReceipt, error) {
|
||||||
if command.CommandID == "" || command.UserID <= 0 || command.PlatformCode == "" || command.GameID == "" || command.ProviderOrderID == "" {
|
if command.CommandID == "" || command.UserID <= 0 || command.PlatformCode == "" || command.GameID == "" || command.ProviderOrderID == "" {
|
||||||
|
|||||||
@ -519,6 +519,43 @@ func TestCreditTaskRewardIsIdempotent(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestCreditLuckyGiftRewardIsIdempotent 验证幸运礼物返奖只按 draw_id 派一次,并产出余额通知事实。
|
||||||
|
func TestCreditLuckyGiftRewardIsIdempotent(t *testing.T) {
|
||||||
|
repository := mysqltest.NewRepository(t)
|
||||||
|
svc := walletservice.New(repository)
|
||||||
|
command := ledger.LuckyGiftRewardCommand{
|
||||||
|
CommandID: "lucky_reward:lucky_draw_1",
|
||||||
|
TargetUserID: 21002,
|
||||||
|
Amount: 188,
|
||||||
|
DrawID: "lucky_draw_1",
|
||||||
|
RoomID: "room-1",
|
||||||
|
GiftID: "rose",
|
||||||
|
PoolID: "super_lucky",
|
||||||
|
Reason: "lucky_gift_reward",
|
||||||
|
}
|
||||||
|
|
||||||
|
first, err := svc.CreditLuckyGiftReward(context.Background(), command)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("CreditLuckyGiftReward failed: %v", err)
|
||||||
|
}
|
||||||
|
second, err := svc.CreditLuckyGiftReward(context.Background(), command)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("CreditLuckyGiftReward retry failed: %v", err)
|
||||||
|
}
|
||||||
|
if first.TransactionID == "" || first.TransactionID != second.TransactionID || second.Balance.AvailableAmount != 188 {
|
||||||
|
t.Fatalf("lucky reward receipt mismatch: first=%+v second=%+v", first, second)
|
||||||
|
}
|
||||||
|
if got := repository.CountRows("wallet_transactions", "command_id = ? AND biz_type = ?", command.CommandID, "lucky_gift_reward"); got != 1 {
|
||||||
|
t.Fatalf("lucky reward should write one transaction, got %d", got)
|
||||||
|
}
|
||||||
|
if got := repository.CountRows("wallet_outbox", "transaction_id = ? AND event_type = ?", first.TransactionID, "WalletBalanceChanged"); got != 1 {
|
||||||
|
t.Fatalf("lucky reward should write one balance change event, got %d", got)
|
||||||
|
}
|
||||||
|
if got := repository.CountRows("wallet_outbox", "transaction_id = ? AND event_type = ?", first.TransactionID, "WalletLuckyGiftRewardCredited"); got != 1 {
|
||||||
|
t.Fatalf("lucky reward should write one reward fact event, got %d", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TestTransferCoinFromSellerMovesDedicatedAssetToPlayerCoin 验证币商专用金币和玩家普通金币不会混账。
|
// TestTransferCoinFromSellerMovesDedicatedAssetToPlayerCoin 验证币商专用金币和玩家普通金币不会混账。
|
||||||
func TestTransferCoinFromSellerMovesDedicatedAssetToPlayerCoin(t *testing.T) {
|
func TestTransferCoinFromSellerMovesDedicatedAssetToPlayerCoin(t *testing.T) {
|
||||||
repository := mysqltest.NewRepository(t)
|
repository := mysqltest.NewRepository(t)
|
||||||
|
|||||||
@ -25,6 +25,7 @@ const (
|
|||||||
bizTypeGiftDebit = "gift_debit"
|
bizTypeGiftDebit = "gift_debit"
|
||||||
bizTypeManualCredit = "manual_credit"
|
bizTypeManualCredit = "manual_credit"
|
||||||
bizTypeTaskReward = "task_reward"
|
bizTypeTaskReward = "task_reward"
|
||||||
|
bizTypeLuckyGiftReward = "lucky_gift_reward"
|
||||||
bizTypeCoinSellerTransfer = "coin_seller_transfer"
|
bizTypeCoinSellerTransfer = "coin_seller_transfer"
|
||||||
bizTypeCoinSellerStockPurchase = "coin_seller_stock_purchase"
|
bizTypeCoinSellerStockPurchase = "coin_seller_stock_purchase"
|
||||||
bizTypeCoinSellerCoinCompensation = "coin_seller_coin_compensation"
|
bizTypeCoinSellerCoinCompensation = "coin_seller_coin_compensation"
|
||||||
@ -534,6 +535,80 @@ func (r *Repository) CreditTaskReward(ctx context.Context, command ledger.TaskRe
|
|||||||
return receiptFromTaskRewardMetadata(transactionID, metadata), nil
|
return receiptFromTaskRewardMetadata(transactionID, metadata), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreditLuckyGiftReward 在同一事务里完成幸运礼物中奖 COIN 入账、交易分录和钱包 outbox。
|
||||||
|
func (r *Repository) CreditLuckyGiftReward(ctx context.Context, command ledger.LuckyGiftRewardCommand) (ledger.LuckyGiftRewardReceipt, error) {
|
||||||
|
if r == nil || r.db == nil {
|
||||||
|
return ledger.LuckyGiftRewardReceipt{}, xerr.New(xerr.Unavailable, "mysql repository is not configured")
|
||||||
|
}
|
||||||
|
ctx = contextWithCommandApp(ctx, command.AppCode)
|
||||||
|
command.AppCode = appcode.FromContext(ctx)
|
||||||
|
|
||||||
|
tx, err := r.db.BeginTx(ctx, nil)
|
||||||
|
if err != nil {
|
||||||
|
return ledger.LuckyGiftRewardReceipt{}, err
|
||||||
|
}
|
||||||
|
defer func() { _ = tx.Rollback() }()
|
||||||
|
|
||||||
|
requestHash := luckyGiftRewardRequestHash(command)
|
||||||
|
if txRow, exists, err := r.lookupTransaction(ctx, tx, command.CommandID, requestHash, bizTypeLuckyGiftReward); err != nil || exists {
|
||||||
|
if err != nil || !exists {
|
||||||
|
return ledger.LuckyGiftRewardReceipt{}, err
|
||||||
|
}
|
||||||
|
return r.receiptForLuckyGiftRewardTransaction(ctx, tx, txRow.TransactionID)
|
||||||
|
}
|
||||||
|
|
||||||
|
nowMs := time.Now().UnixMilli()
|
||||||
|
account, err := r.lockAccount(ctx, tx, command.TargetUserID, ledger.AssetCoin, true, nowMs)
|
||||||
|
if err != nil {
|
||||||
|
return ledger.LuckyGiftRewardReceipt{}, err
|
||||||
|
}
|
||||||
|
transactionID := transactionID(command.AppCode, command.CommandID)
|
||||||
|
balanceAfter := account.AvailableAmount + command.Amount
|
||||||
|
metadata := luckyGiftRewardMetadata{
|
||||||
|
AppCode: command.AppCode,
|
||||||
|
TargetUserID: command.TargetUserID,
|
||||||
|
AssetType: ledger.AssetCoin,
|
||||||
|
Amount: command.Amount,
|
||||||
|
DrawID: command.DrawID,
|
||||||
|
RoomID: command.RoomID,
|
||||||
|
GiftID: command.GiftID,
|
||||||
|
PoolID: command.PoolID,
|
||||||
|
Reason: command.Reason,
|
||||||
|
BalanceAfter: balanceAfter,
|
||||||
|
GrantedAtMS: nowMs,
|
||||||
|
}
|
||||||
|
if err := r.insertTransaction(ctx, tx, transactionID, command.CommandID, bizTypeLuckyGiftReward, requestHash, command.DrawID, metadata, nowMs); err != nil {
|
||||||
|
return ledger.LuckyGiftRewardReceipt{}, err
|
||||||
|
}
|
||||||
|
if err := r.applyAccountDelta(ctx, tx, account, command.Amount, 0, nowMs); err != nil {
|
||||||
|
return ledger.LuckyGiftRewardReceipt{}, err
|
||||||
|
}
|
||||||
|
if err := r.insertEntry(ctx, tx, walletEntry{
|
||||||
|
TransactionID: transactionID,
|
||||||
|
UserID: command.TargetUserID,
|
||||||
|
AssetType: ledger.AssetCoin,
|
||||||
|
AvailableDelta: command.Amount,
|
||||||
|
FrozenDelta: 0,
|
||||||
|
AvailableAfter: balanceAfter,
|
||||||
|
FrozenAfter: account.FrozenAmount,
|
||||||
|
RoomID: command.RoomID,
|
||||||
|
CreatedAtMS: nowMs,
|
||||||
|
}); err != nil {
|
||||||
|
return ledger.LuckyGiftRewardReceipt{}, err
|
||||||
|
}
|
||||||
|
if err := r.insertWalletOutbox(ctx, tx, []walletOutboxEvent{
|
||||||
|
balanceChangedEvent(transactionID, command.CommandID, command.TargetUserID, ledger.AssetCoin, command.Amount, 0, balanceAfter, account.FrozenAmount, account.Version+1, metadata, nowMs),
|
||||||
|
luckyGiftRewardCreditedEvent(transactionID, command.CommandID, metadata, nowMs),
|
||||||
|
}); err != nil {
|
||||||
|
return ledger.LuckyGiftRewardReceipt{}, err
|
||||||
|
}
|
||||||
|
if err := tx.Commit(); err != nil {
|
||||||
|
return ledger.LuckyGiftRewardReceipt{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return receiptFromLuckyGiftRewardMetadata(transactionID, metadata), nil
|
||||||
|
}
|
||||||
|
|
||||||
// ApplyGameCoinChange 在同一事务内完成游戏 COIN 改账、分录和 outbox。
|
// ApplyGameCoinChange 在同一事务内完成游戏 COIN 改账、分录和 outbox。
|
||||||
func (r *Repository) ApplyGameCoinChange(ctx context.Context, command ledger.GameCoinChangeCommand) (ledger.GameCoinChangeReceipt, error) {
|
func (r *Repository) ApplyGameCoinChange(ctx context.Context, command ledger.GameCoinChangeCommand) (ledger.GameCoinChangeReceipt, error) {
|
||||||
if r == nil || r.db == nil {
|
if r == nil || r.db == nil {
|
||||||
@ -1548,6 +1623,20 @@ type taskRewardMetadata struct {
|
|||||||
GrantedAtMS int64 `json:"granted_at_ms"`
|
GrantedAtMS int64 `json:"granted_at_ms"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type luckyGiftRewardMetadata struct {
|
||||||
|
AppCode string `json:"app_code"`
|
||||||
|
TargetUserID int64 `json:"target_user_id"`
|
||||||
|
AssetType string `json:"asset_type"`
|
||||||
|
Amount int64 `json:"amount"`
|
||||||
|
DrawID string `json:"draw_id"`
|
||||||
|
RoomID string `json:"room_id"`
|
||||||
|
GiftID string `json:"gift_id"`
|
||||||
|
PoolID string `json:"pool_id"`
|
||||||
|
Reason string `json:"reason"`
|
||||||
|
BalanceAfter int64 `json:"balance_after"`
|
||||||
|
GrantedAtMS int64 `json:"granted_at_ms"`
|
||||||
|
}
|
||||||
|
|
||||||
type gameCoinMetadata struct {
|
type gameCoinMetadata struct {
|
||||||
AppCode string `json:"app_code"`
|
AppCode string `json:"app_code"`
|
||||||
UserID int64 `json:"user_id"`
|
UserID int64 `json:"user_id"`
|
||||||
@ -1654,6 +1743,38 @@ func receiptFromTaskRewardMetadata(transactionID string, metadata taskRewardMeta
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Repository) receiptForLuckyGiftRewardTransaction(ctx context.Context, tx *sql.Tx, transactionID string) (ledger.LuckyGiftRewardReceipt, error) {
|
||||||
|
var metadataJSON string
|
||||||
|
if err := tx.QueryRowContext(ctx,
|
||||||
|
`SELECT COALESCE(CAST(metadata_json AS CHAR), '{}')
|
||||||
|
FROM wallet_transactions
|
||||||
|
WHERE app_code = ? AND transaction_id = ?`,
|
||||||
|
appcode.FromContext(ctx),
|
||||||
|
transactionID,
|
||||||
|
).Scan(&metadataJSON); err != nil {
|
||||||
|
return ledger.LuckyGiftRewardReceipt{}, err
|
||||||
|
}
|
||||||
|
var metadata luckyGiftRewardMetadata
|
||||||
|
if err := json.Unmarshal([]byte(metadataJSON), &metadata); err != nil {
|
||||||
|
return ledger.LuckyGiftRewardReceipt{}, err
|
||||||
|
}
|
||||||
|
return receiptFromLuckyGiftRewardMetadata(transactionID, metadata), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func receiptFromLuckyGiftRewardMetadata(transactionID string, metadata luckyGiftRewardMetadata) ledger.LuckyGiftRewardReceipt {
|
||||||
|
return ledger.LuckyGiftRewardReceipt{
|
||||||
|
TransactionID: transactionID,
|
||||||
|
Balance: ledger.AssetBalance{
|
||||||
|
AppCode: metadata.AppCode,
|
||||||
|
UserID: metadata.TargetUserID,
|
||||||
|
AssetType: metadata.AssetType,
|
||||||
|
AvailableAmount: metadata.BalanceAfter,
|
||||||
|
},
|
||||||
|
Amount: metadata.Amount,
|
||||||
|
GrantedAtMS: metadata.GrantedAtMS,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Repository) receiptForGameTransaction(ctx context.Context, tx *sql.Tx, transactionID string) (ledger.GameCoinChangeReceipt, error) {
|
func (r *Repository) receiptForGameTransaction(ctx context.Context, tx *sql.Tx, transactionID string) (ledger.GameCoinChangeReceipt, error) {
|
||||||
var metadataJSON string
|
var metadataJSON string
|
||||||
if err := tx.QueryRowContext(ctx,
|
if err := tx.QueryRowContext(ctx,
|
||||||
@ -1836,6 +1957,32 @@ func taskRewardCreditedEvent(transactionID string, commandID string, metadata ta
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func luckyGiftRewardCreditedEvent(transactionID string, commandID string, metadata luckyGiftRewardMetadata, nowMs int64) walletOutboxEvent {
|
||||||
|
return walletOutboxEvent{
|
||||||
|
EventID: eventID(transactionID, "WalletLuckyGiftRewardCredited", metadata.TargetUserID, ledger.AssetCoin),
|
||||||
|
EventType: "WalletLuckyGiftRewardCredited",
|
||||||
|
TransactionID: transactionID,
|
||||||
|
CommandID: commandID,
|
||||||
|
UserID: metadata.TargetUserID,
|
||||||
|
AssetType: ledger.AssetCoin,
|
||||||
|
AvailableDelta: metadata.Amount,
|
||||||
|
FrozenDelta: 0,
|
||||||
|
Payload: map[string]any{
|
||||||
|
"transaction_id": transactionID,
|
||||||
|
"command_id": commandID,
|
||||||
|
"user_id": metadata.TargetUserID,
|
||||||
|
"draw_id": metadata.DrawID,
|
||||||
|
"room_id": metadata.RoomID,
|
||||||
|
"gift_id": metadata.GiftID,
|
||||||
|
"pool_id": metadata.PoolID,
|
||||||
|
"amount": metadata.Amount,
|
||||||
|
"reason": metadata.Reason,
|
||||||
|
"created_at_ms": nowMs,
|
||||||
|
},
|
||||||
|
CreatedAtMS: nowMs,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func coinSellerStockCreditedEvent(transactionID string, commandID string, metadata coinSellerStockMetadata, nowMs int64) walletOutboxEvent {
|
func coinSellerStockCreditedEvent(transactionID string, commandID string, metadata coinSellerStockMetadata, nowMs int64) walletOutboxEvent {
|
||||||
eventType := "WalletCoinSellerCoinCompensated"
|
eventType := "WalletCoinSellerCoinCompensated"
|
||||||
if metadata.StockType == ledger.StockTypeUSDTPurchase {
|
if metadata.StockType == ledger.StockTypeUSDTPurchase {
|
||||||
@ -1965,6 +2112,19 @@ func taskRewardRequestHash(command ledger.TaskRewardCommand) string {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func luckyGiftRewardRequestHash(command ledger.LuckyGiftRewardCommand) string {
|
||||||
|
return stableHash(fmt.Sprintf("lucky_gift_reward|%s|%d|%d|%s|%s|%s|%s|%s",
|
||||||
|
appcode.Normalize(command.AppCode),
|
||||||
|
command.TargetUserID,
|
||||||
|
command.Amount,
|
||||||
|
strings.TrimSpace(command.DrawID),
|
||||||
|
strings.TrimSpace(command.RoomID),
|
||||||
|
strings.TrimSpace(command.GiftID),
|
||||||
|
strings.TrimSpace(command.PoolID),
|
||||||
|
strings.TrimSpace(command.Reason),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
func gameBizTypeAndDelta(opType string, coinAmount int64) (string, int64, error) {
|
func gameBizTypeAndDelta(opType string, coinAmount int64) (string, int64, error) {
|
||||||
switch ledger.NormalizeGameOpType(opType) {
|
switch ledger.NormalizeGameOpType(opType) {
|
||||||
case ledger.GameOpDebit:
|
case ledger.GameOpDebit:
|
||||||
|
|||||||
@ -651,6 +651,38 @@ func (s *Server) CreditTaskReward(ctx context.Context, req *walletv1.CreditTaskR
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreditLuckyGiftReward 处理 activity-service 幸运礼物抽奖 outbox 的中奖金币入账。
|
||||||
|
func (s *Server) CreditLuckyGiftReward(ctx context.Context, req *walletv1.CreditLuckyGiftRewardRequest) (*walletv1.CreditLuckyGiftRewardResponse, error) {
|
||||||
|
ctx = appcode.WithContext(ctx, req.GetAppCode())
|
||||||
|
receipt, err := s.svc.CreditLuckyGiftReward(ctx, ledger.LuckyGiftRewardCommand{
|
||||||
|
AppCode: req.GetAppCode(),
|
||||||
|
CommandID: req.GetCommandId(),
|
||||||
|
TargetUserID: req.GetTargetUserId(),
|
||||||
|
Amount: req.GetAmount(),
|
||||||
|
DrawID: req.GetDrawId(),
|
||||||
|
RoomID: req.GetRoomId(),
|
||||||
|
GiftID: req.GetGiftId(),
|
||||||
|
PoolID: req.GetPoolId(),
|
||||||
|
Reason: req.GetReason(),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerr.ToGRPCError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &walletv1.CreditLuckyGiftRewardResponse{
|
||||||
|
TransactionId: receipt.TransactionID,
|
||||||
|
Amount: receipt.Amount,
|
||||||
|
GrantedAtMs: receipt.GrantedAtMS,
|
||||||
|
Balance: &walletv1.AssetBalance{
|
||||||
|
AppCode: receipt.Balance.AppCode,
|
||||||
|
AssetType: receipt.Balance.AssetType,
|
||||||
|
AvailableAmount: receipt.Balance.AvailableAmount,
|
||||||
|
FrozenAmount: receipt.Balance.FrozenAmount,
|
||||||
|
Version: receipt.Balance.Version,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
// ApplyGameCoinChange 处理 game-service 发起的游戏专用金币改账。
|
// ApplyGameCoinChange 处理 game-service 发起的游戏专用金币改账。
|
||||||
func (s *Server) ApplyGameCoinChange(ctx context.Context, req *walletv1.ApplyGameCoinChangeRequest) (*walletv1.ApplyGameCoinChangeResponse, error) {
|
func (s *Server) ApplyGameCoinChange(ctx context.Context, req *walletv1.ApplyGameCoinChangeRequest) (*walletv1.ApplyGameCoinChangeResponse, error) {
|
||||||
ctx = appcode.WithContext(ctx, req.GetAppCode())
|
ctx = appcode.WithContext(ctx, req.GetAppCode())
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user