538 lines
21 KiB
Go
538 lines
21 KiB
Go
package grpc
|
||
|
||
import (
|
||
"context"
|
||
"time"
|
||
|
||
walletv1 "hyapp.local/api/proto/wallet/v1"
|
||
"hyapp/pkg/appcode"
|
||
"hyapp/pkg/xerr"
|
||
"hyapp/services/wallet-service/internal/domain/ledger"
|
||
)
|
||
|
||
// ListVipPackages 返回当前 VIP 和可购买包列表。
|
||
func (s *Server) ListVipPackages(ctx context.Context, req *walletv1.ListVipPackagesRequest) (*walletv1.ListVipPackagesResponse, error) {
|
||
ctx = appcode.WithContext(ctx, req.GetAppCode())
|
||
state, levels, err := s.svc.ListVipPackages(ctx, req.GetUserId())
|
||
if err != nil {
|
||
return nil, xerr.ToGRPCError(err)
|
||
}
|
||
resp := &walletv1.ListVipPackagesResponse{
|
||
CurrentVip: vipToProto(state.EffectiveVip),
|
||
Packages: make([]*walletv1.VipLevel, 0, len(levels)),
|
||
State: vipStateToProto(state),
|
||
ProgramConfig: vipProgramConfigToProto(state.ProgramConfig),
|
||
}
|
||
for _, level := range levels {
|
||
resp.Packages = append(resp.Packages, vipLevelToProto(level))
|
||
}
|
||
return resp, nil
|
||
}
|
||
|
||
// GetMyVip 返回当前登录用户 VIP 状态。
|
||
func (s *Server) GetMyVip(ctx context.Context, req *walletv1.GetMyVipRequest) (*walletv1.GetMyVipResponse, error) {
|
||
ctx = appcode.WithContext(ctx, req.GetAppCode())
|
||
state, err := s.svc.GetVipState(ctx, req.GetUserId())
|
||
if err != nil {
|
||
return nil, xerr.ToGRPCError(err)
|
||
}
|
||
// 旧 vip 字段保留为最终生效投影,付费会员原始事实由 state.paid_vip 明确返回。
|
||
return &walletv1.GetMyVipResponse{Vip: vipToProto(state.EffectiveVip), State: vipStateToProto(state)}, nil
|
||
}
|
||
|
||
// GetVipProgramConfig 返回按 App 隔离的状态机配置和最高等级权益目录。
|
||
func (s *Server) GetVipProgramConfig(ctx context.Context, req *walletv1.GetVipProgramConfigRequest) (*walletv1.GetVipProgramConfigResponse, error) {
|
||
ctx = appcode.WithContext(ctx, req.GetAppCode())
|
||
config, benefits, err := s.svc.GetVipProgramConfig(ctx)
|
||
if err != nil {
|
||
return nil, xerr.ToGRPCError(err)
|
||
}
|
||
return &walletv1.GetVipProgramConfigResponse{
|
||
Config: vipProgramConfigToProto(config),
|
||
Benefits: vipBenefitsToProto(benefits),
|
||
ServerTimeMs: time.Now().UnixMilli(),
|
||
}, nil
|
||
}
|
||
|
||
// CheckVipBenefit 供权益 owner 精确判断单项能力,不允许调用方退化成等级比较。
|
||
func (s *Server) CheckVipBenefit(ctx context.Context, req *walletv1.CheckVipBenefitRequest) (*walletv1.CheckVipBenefitResponse, error) {
|
||
ctx = appcode.WithContext(ctx, req.GetAppCode())
|
||
result, err := s.svc.CheckVipBenefit(ctx, req.GetUserId(), req.GetBenefitCode())
|
||
if err != nil {
|
||
return nil, xerr.ToGRPCError(err)
|
||
}
|
||
return &walletv1.CheckVipBenefitResponse{
|
||
Allowed: result.Allowed,
|
||
Benefit: vipBenefitToProto(result.Benefit),
|
||
State: vipStateToProto(result.State),
|
||
DenialReason: result.DenialReason,
|
||
EvaluatedAtMs: result.EvaluatedAtMS,
|
||
}, nil
|
||
}
|
||
|
||
// PurchaseVip 购买、续期或升级 VIP。
|
||
func (s *Server) PurchaseVip(ctx context.Context, req *walletv1.PurchaseVipRequest) (*walletv1.PurchaseVipResponse, error) {
|
||
ctx = appcode.WithContext(ctx, req.GetAppCode())
|
||
receipt, err := s.svc.PurchaseVip(ctx, ledger.PurchaseVipCommand{
|
||
AppCode: req.GetAppCode(),
|
||
CommandID: req.GetCommandId(),
|
||
UserID: req.GetUserId(),
|
||
Level: req.GetLevel(),
|
||
})
|
||
if err != nil {
|
||
return nil, xerr.ToGRPCError(err)
|
||
}
|
||
return &walletv1.PurchaseVipResponse{
|
||
OrderId: receipt.OrderID,
|
||
TransactionId: receipt.TransactionID,
|
||
Vip: vipToProto(receipt.Vip),
|
||
CoinSpent: receipt.CoinSpent,
|
||
CoinBalanceAfter: receipt.CoinBalanceAfter,
|
||
RewardItems: vipRewardItemsToProto(receipt.RewardItems),
|
||
State: vipStateToProto(receipt.State),
|
||
}, nil
|
||
}
|
||
|
||
// GrantVip 统一处理活动和后台赠送 VIP。
|
||
func (s *Server) GrantVip(ctx context.Context, req *walletv1.GrantVipRequest) (*walletv1.GrantVipResponse, error) {
|
||
ctx = appcode.WithContext(ctx, req.GetAppCode())
|
||
receipt, err := s.svc.GrantVip(ctx, ledger.GrantVipCommand{
|
||
AppCode: req.GetAppCode(),
|
||
CommandID: req.GetCommandId(),
|
||
TargetUserID: req.GetTargetUserId(),
|
||
Level: req.GetLevel(),
|
||
GrantSource: req.GetGrantSource(),
|
||
OperatorUserID: req.GetOperatorUserId(),
|
||
Reason: req.GetReason(),
|
||
})
|
||
if err != nil {
|
||
return nil, xerr.ToGRPCError(err)
|
||
}
|
||
return &walletv1.GrantVipResponse{
|
||
TransactionId: receipt.TransactionID,
|
||
Vip: vipToProto(receipt.Vip),
|
||
RewardItems: vipRewardItemsToProto(receipt.RewardItems),
|
||
ServerTimeMs: time.Now().UnixMilli(),
|
||
State: vipStateToProto(receipt.State),
|
||
}, nil
|
||
}
|
||
|
||
// GrantVipTrialCard 发卡但不自动佩戴,resource_id 省略时由钱包按 level 解析同 App 预置资源。
|
||
func (s *Server) GrantVipTrialCard(ctx context.Context, req *walletv1.GrantVipTrialCardRequest) (*walletv1.GrantVipTrialCardResponse, error) {
|
||
ctx = appcode.WithContext(ctx, req.GetAppCode())
|
||
resourceID := int64(0)
|
||
if req.ResourceId != nil {
|
||
resourceID = req.GetResourceId()
|
||
}
|
||
receipt, err := s.svc.GrantVipTrialCard(ctx, ledger.GrantVipTrialCardCommand{
|
||
AppCode: req.GetAppCode(),
|
||
CommandID: req.GetCommandId(),
|
||
TargetUserID: req.GetTargetUserId(),
|
||
Level: req.GetLevel(),
|
||
DurationMS: req.GetDurationMs(),
|
||
ResourceID: resourceID,
|
||
GrantSource: req.GetGrantSource(),
|
||
OperatorUserID: req.GetOperatorUserId(),
|
||
Reason: req.GetReason(),
|
||
})
|
||
if err != nil {
|
||
return nil, xerr.ToGRPCError(err)
|
||
}
|
||
return &walletv1.GrantVipTrialCardResponse{
|
||
TrialCard: vipTrialCardToProto(receipt.TrialCard),
|
||
State: vipStateToProto(receipt.State),
|
||
ServerTimeMs: receipt.ServerTimeMS,
|
||
}, nil
|
||
}
|
||
|
||
// EquipVipTrialCard 精确佩戴一个 entitlement;同类型旧装备仅解除指针,库存与到期时间保持不变。
|
||
func (s *Server) EquipVipTrialCard(ctx context.Context, req *walletv1.EquipVipTrialCardRequest) (*walletv1.EquipVipTrialCardResponse, error) {
|
||
ctx = appcode.WithContext(ctx, req.GetAppCode())
|
||
card, state, err := s.svc.EquipVipTrialCard(ctx, ledger.EquipVipTrialCardCommand{
|
||
AppCode: req.GetAppCode(),
|
||
RequestID: req.GetRequestId(),
|
||
UserID: req.GetUserId(),
|
||
EntitlementID: req.GetEntitlementId(),
|
||
})
|
||
if err != nil {
|
||
return nil, xerr.ToGRPCError(err)
|
||
}
|
||
return &walletv1.EquipVipTrialCardResponse{
|
||
TrialCard: vipTrialCardToProto(card),
|
||
State: vipStateToProto(state),
|
||
ServerTimeMs: time.Now().UnixMilli(),
|
||
}, nil
|
||
}
|
||
|
||
// UnequipVipTrialCard 卸下当前体验卡并返回回落后的最终 VIP 状态。
|
||
func (s *Server) UnequipVipTrialCard(ctx context.Context, req *walletv1.UnequipVipTrialCardRequest) (*walletv1.UnequipVipTrialCardResponse, error) {
|
||
ctx = appcode.WithContext(ctx, req.GetAppCode())
|
||
unequipped, state, err := s.svc.UnequipVipTrialCard(ctx, ledger.UnequipVipTrialCardCommand{
|
||
AppCode: req.GetAppCode(),
|
||
RequestID: req.GetRequestId(),
|
||
UserID: req.GetUserId(),
|
||
})
|
||
if err != nil {
|
||
return nil, xerr.ToGRPCError(err)
|
||
}
|
||
return &walletv1.UnequipVipTrialCardResponse{
|
||
Unequipped: unequipped,
|
||
State: vipStateToProto(state),
|
||
ServerTimeMs: time.Now().UnixMilli(),
|
||
}, nil
|
||
}
|
||
|
||
// ListAdminVipLevels 返回后台 VIP 配置。
|
||
func (s *Server) ListAdminVipLevels(ctx context.Context, req *walletv1.ListAdminVipLevelsRequest) (*walletv1.ListAdminVipLevelsResponse, error) {
|
||
ctx = appcode.WithContext(ctx, req.GetAppCode())
|
||
config, levels, err := s.svc.ListAdminVipLevels(ctx)
|
||
if err != nil {
|
||
return nil, xerr.ToGRPCError(err)
|
||
}
|
||
resp := &walletv1.ListAdminVipLevelsResponse{Levels: make([]*walletv1.VipLevel, 0, len(levels)), ServerTimeMs: time.Now().UnixMilli(), ProgramConfig: vipProgramConfigToProto(config)}
|
||
for _, level := range levels {
|
||
resp.Levels = append(resp.Levels, vipLevelToProto(level))
|
||
}
|
||
return resp, nil
|
||
}
|
||
|
||
// UpdateAdminVipLevels 保存后台 VIP 配置。
|
||
func (s *Server) UpdateAdminVipLevels(ctx context.Context, req *walletv1.UpdateAdminVipLevelsRequest) (*walletv1.UpdateAdminVipLevelsResponse, error) {
|
||
ctx = appcode.WithContext(ctx, req.GetAppCode())
|
||
commands := make([]ledger.AdminVipLevelCommand, 0, len(req.GetLevels()))
|
||
for _, item := range req.GetLevels() {
|
||
if item == nil {
|
||
continue
|
||
}
|
||
commands = append(commands, ledger.AdminVipLevelCommand{
|
||
Level: item.GetLevel(),
|
||
Name: item.GetName(),
|
||
Status: item.GetStatus(),
|
||
PriceCoin: item.GetPriceCoin(),
|
||
DurationMS: item.GetDurationMs(),
|
||
RewardResourceGroupID: item.GetRewardResourceGroupId(),
|
||
RequiredRechargeCoinAmount: item.GetRequiredRechargeCoinAmount(),
|
||
SortOrder: item.GetSortOrder(),
|
||
Benefits: vipBenefitsFromProto(item.GetBenefits()),
|
||
})
|
||
}
|
||
config, levels, err := s.svc.UpdateAdminVipLevels(ctx, commands, req.GetOperatorUserId())
|
||
if err != nil {
|
||
return nil, xerr.ToGRPCError(err)
|
||
}
|
||
resp := &walletv1.UpdateAdminVipLevelsResponse{Levels: make([]*walletv1.VipLevel, 0, len(levels)), ServerTimeMs: time.Now().UnixMilli(), ProgramConfig: vipProgramConfigToProto(config)}
|
||
for _, level := range levels {
|
||
resp.Levels = append(resp.Levels, vipLevelToProto(level))
|
||
}
|
||
return resp, nil
|
||
}
|
||
|
||
// UpdateAdminVipProgramConfig 保存 App 级策略,审计操作者只接受请求外层的服务端身份字段。
|
||
func (s *Server) UpdateAdminVipProgramConfig(ctx context.Context, req *walletv1.UpdateAdminVipProgramConfigRequest) (*walletv1.UpdateAdminVipProgramConfigResponse, error) {
|
||
ctx = appcode.WithContext(ctx, req.GetAppCode())
|
||
config := vipProgramConfigFromProto(req.GetConfig())
|
||
config.AppCode = req.GetAppCode()
|
||
updated, err := s.svc.UpdateAdminVipProgramConfig(ctx, ledger.AdminVipProgramConfigCommand{
|
||
Config: config,
|
||
OperatorUserID: req.GetOperatorUserId(),
|
||
})
|
||
if err != nil {
|
||
return nil, xerr.ToGRPCError(err)
|
||
}
|
||
return &walletv1.UpdateAdminVipProgramConfigResponse{Config: vipProgramConfigToProto(updated), ServerTimeMs: time.Now().UnixMilli()}, nil
|
||
}
|
||
|
||
// UpdateMyVipSettings 保留 proto optional 的 partial update 语义;未提交字段不能被零值 false 覆盖。
|
||
func (s *Server) UpdateMyVipSettings(ctx context.Context, req *walletv1.UpdateMyVipSettingsRequest) (*walletv1.UpdateMyVipSettingsResponse, error) {
|
||
ctx = appcode.WithContext(ctx, req.GetAppCode())
|
||
var roomEntryNoticeEnabled *bool
|
||
if req.RoomEntryNoticeEnabled != nil {
|
||
value := req.GetRoomEntryNoticeEnabled()
|
||
roomEntryNoticeEnabled = &value
|
||
}
|
||
var onlineGlobalNoticeEnabled *bool
|
||
if req.OnlineGlobalNoticeEnabled != nil {
|
||
value := req.GetOnlineGlobalNoticeEnabled()
|
||
onlineGlobalNoticeEnabled = &value
|
||
}
|
||
settings, err := s.svc.UpdateVipUserSettings(ctx, ledger.UpdateVipUserSettingsCommand{
|
||
AppCode: req.GetAppCode(), UserID: req.GetUserId(),
|
||
RoomEntryNoticeEnabled: roomEntryNoticeEnabled, OnlineGlobalNoticeEnabled: onlineGlobalNoticeEnabled,
|
||
})
|
||
if err != nil {
|
||
return nil, xerr.ToGRPCError(err)
|
||
}
|
||
return &walletv1.UpdateMyVipSettingsResponse{
|
||
Settings: vipUserSettingsToProto(settings), ServerTimeMs: time.Now().UTC().UnixMilli(),
|
||
}, nil
|
||
}
|
||
|
||
// GetMyCurrentVipDailyCoinRebate 返回当前 UTC 日可领取/已领取事实;未生成以 found=false 表达。
|
||
func (s *Server) GetMyCurrentVipDailyCoinRebate(ctx context.Context, req *walletv1.GetMyCurrentVipDailyCoinRebateRequest) (*walletv1.GetMyCurrentVipDailyCoinRebateResponse, error) {
|
||
ctx = appcode.WithContext(ctx, req.GetAppCode())
|
||
rebate, found, err := s.svc.GetMyCurrentVipDailyCoinRebate(ctx, req.GetUserId())
|
||
if err != nil {
|
||
return nil, xerr.ToGRPCError(err)
|
||
}
|
||
response := &walletv1.GetMyCurrentVipDailyCoinRebateResponse{Found: found, ServerTimeMs: time.Now().UTC().UnixMilli()}
|
||
if found {
|
||
response.Rebate = vipDailyCoinRebateToProto(rebate)
|
||
}
|
||
return response, nil
|
||
}
|
||
|
||
// ListMyVipDailyCoinRebateStatuses 同时支持历史分页和通知按 rebate_ids 精确恢复;repository 始终附加 user_id 条件。
|
||
func (s *Server) ListMyVipDailyCoinRebateStatuses(ctx context.Context, req *walletv1.ListMyVipDailyCoinRebateStatusesRequest) (*walletv1.ListMyVipDailyCoinRebateStatusesResponse, error) {
|
||
ctx = appcode.WithContext(ctx, req.GetAppCode())
|
||
items, total, err := s.svc.ListMyVipDailyCoinRebateStatuses(ctx, ledger.ListVipDailyCoinRebateStatusesQuery{
|
||
AppCode: req.GetAppCode(), UserID: req.GetUserId(), Page: int(req.GetPage()),
|
||
PageSize: int(req.GetPageSize()), RebateIDs: append([]string(nil), req.GetRebateIds()...),
|
||
})
|
||
if err != nil {
|
||
return nil, xerr.ToGRPCError(err)
|
||
}
|
||
response := &walletv1.ListMyVipDailyCoinRebateStatusesResponse{
|
||
Rebates: make([]*walletv1.VipDailyCoinRebate, 0, len(items)), Total: total,
|
||
ServerTimeMs: time.Now().UTC().UnixMilli(),
|
||
}
|
||
for _, item := range items {
|
||
response.Rebates = append(response.Rebates, vipDailyCoinRebateToProto(item))
|
||
}
|
||
return response, nil
|
||
}
|
||
|
||
// ClaimVipDailyCoinRebate 不接收金额;wallet owner 从锁内返现行读取并返回稳定账后余额。
|
||
func (s *Server) ClaimVipDailyCoinRebate(ctx context.Context, req *walletv1.ClaimVipDailyCoinRebateRequest) (*walletv1.ClaimVipDailyCoinRebateResponse, error) {
|
||
ctx = appcode.WithContext(ctx, req.GetAppCode())
|
||
receipt, err := s.svc.ClaimVipDailyCoinRebate(ctx, ledger.ClaimVipDailyCoinRebateCommand{
|
||
AppCode: req.GetAppCode(), CommandID: req.GetCommandId(), UserID: req.GetUserId(), RebateID: req.GetRebateId(),
|
||
})
|
||
if err != nil {
|
||
return nil, xerr.ToGRPCError(err)
|
||
}
|
||
return &walletv1.ClaimVipDailyCoinRebateResponse{
|
||
Rebate: vipDailyCoinRebateToProto(receipt.Rebate), TransactionId: receipt.TransactionID,
|
||
CoinBalance: balanceToProto(receipt.CoinBalance), ServerTimeMs: time.Now().UTC().UnixMilli(),
|
||
}, nil
|
||
}
|
||
|
||
func vipToProto(vip ledger.UserVip) *walletv1.UserVip {
|
||
return &walletv1.UserVip{
|
||
UserId: vip.UserID,
|
||
Level: vip.Level,
|
||
Name: vip.Name,
|
||
Active: vip.Active,
|
||
StartedAtMs: vip.StartedAtMS,
|
||
ExpiresAtMs: vip.ExpiresAtMS,
|
||
UpdatedAtMs: vip.UpdatedAtMS,
|
||
ProgramType: vip.ProgramType,
|
||
ConfigVersion: vip.ConfigVersion,
|
||
}
|
||
}
|
||
|
||
func vipDailyCoinRebateRunToProto(run ledger.VipDailyCoinRebateRun) *walletv1.VipDailyCoinRebateRun {
|
||
return &walletv1.VipDailyCoinRebateRun{
|
||
RunId: run.RunID, TaskDay: run.TaskDay, DayStartMs: run.DayStartMS, DayEndMs: run.DayEndMS,
|
||
ConfigVersion: run.ConfigVersion, LevelAmountsJson: run.LevelAmountsJSON, Status: run.Status,
|
||
LastUserId: run.LastUserID, ScannedCount: run.ScannedCount, CreatedCount: run.CreatedCount,
|
||
CreatedAtMs: run.CreatedAtMS, UpdatedAtMs: run.UpdatedAtMS, CompletedAtMs: run.CompletedAtMS,
|
||
}
|
||
}
|
||
|
||
func vipDailyCoinRebateToProto(rebate ledger.VipDailyCoinRebate) *walletv1.VipDailyCoinRebate {
|
||
if rebate.RebateID == "" {
|
||
return nil
|
||
}
|
||
return &walletv1.VipDailyCoinRebate{
|
||
RebateId: rebate.RebateID, UserId: rebate.UserID, TaskDay: rebate.TaskDay,
|
||
VipLevel: rebate.VipLevel, VipName: rebate.VipName, CoinAmount: rebate.CoinAmount,
|
||
Status: rebate.Status, AvailableAtMs: rebate.AvailableAtMS, ExpiresAtMs: rebate.ExpiresAtMS,
|
||
ConfigVersion: rebate.ConfigVersion, ClaimedAtMs: rebate.ClaimedAtMS,
|
||
WalletTransactionId: rebate.WalletTransactionID, CreatedAtMs: rebate.CreatedAtMS, UpdatedAtMs: rebate.UpdatedAtMS,
|
||
}
|
||
}
|
||
|
||
func vipUserSettingsToProto(settings ledger.VipUserSettings) *walletv1.VipUserSettings {
|
||
return &walletv1.VipUserSettings{
|
||
AppCode: settings.AppCode, UserId: settings.UserID,
|
||
RoomEntryNoticeEnabled: settings.RoomEntryNoticeEnabled,
|
||
OnlineGlobalNoticeEnabled: settings.OnlineGlobalNoticeEnabled,
|
||
UpdatedAtMs: settings.UpdatedAtMS,
|
||
}
|
||
}
|
||
|
||
func vipLevelToProto(level ledger.VipLevel) *walletv1.VipLevel {
|
||
return &walletv1.VipLevel{
|
||
Level: level.Level,
|
||
Name: level.Name,
|
||
Status: level.Status,
|
||
PriceCoin: level.PriceCoin,
|
||
DurationMs: level.DurationMS,
|
||
RewardResourceGroupId: level.RewardResourceGroupID,
|
||
RewardItems: vipRewardItemsToProto(level.RewardItems),
|
||
CanPurchase: level.CanPurchase,
|
||
SortOrder: level.SortOrder,
|
||
RechargeGateRequired: level.RechargeGateRequired,
|
||
RequiredRechargeCoinAmount: level.RequiredRechargeCoinAmount,
|
||
UserRechargeCoinAmount: level.UserRechargeCoinAmount,
|
||
PurchaseLockedReason: level.PurchaseLockedReason,
|
||
CreatedAtMs: level.CreatedAtMS,
|
||
UpdatedAtMs: level.UpdatedAtMS,
|
||
Benefits: vipBenefitsToProto(level.Benefits),
|
||
ConfigVersion: level.ConfigVersion,
|
||
}
|
||
}
|
||
|
||
func vipProgramConfigToProto(config ledger.VipProgramConfig) *walletv1.VipProgramConfig {
|
||
return &walletv1.VipProgramConfig{
|
||
AppCode: config.AppCode,
|
||
ProgramType: config.ProgramType,
|
||
LevelCount: config.LevelCount,
|
||
SameLevelExpiryPolicy: config.SameLevelExpiryPolicy,
|
||
UpgradeExpiryPolicy: config.UpgradeExpiryPolicy,
|
||
DowngradePurchasePolicy: config.DowngradePurchasePolicy,
|
||
BenefitInheritancePolicy: config.BenefitInheritancePolicy,
|
||
GrantMode: config.GrantMode,
|
||
TrialCardEnabled: config.TrialCardEnabled,
|
||
Status: config.Status,
|
||
ConfigVersion: config.ConfigVersion,
|
||
UpdatedByAdminId: config.UpdatedByAdminID,
|
||
CreatedAtMs: config.CreatedAtMS,
|
||
UpdatedAtMs: config.UpdatedAtMS,
|
||
}
|
||
}
|
||
|
||
func vipProgramConfigFromProto(config *walletv1.VipProgramConfig) ledger.VipProgramConfig {
|
||
if config == nil {
|
||
return ledger.VipProgramConfig{}
|
||
}
|
||
return ledger.VipProgramConfig{
|
||
AppCode: config.GetAppCode(),
|
||
ProgramType: config.GetProgramType(),
|
||
LevelCount: config.GetLevelCount(),
|
||
SameLevelExpiryPolicy: config.GetSameLevelExpiryPolicy(),
|
||
UpgradeExpiryPolicy: config.GetUpgradeExpiryPolicy(),
|
||
DowngradePurchasePolicy: config.GetDowngradePurchasePolicy(),
|
||
BenefitInheritancePolicy: config.GetBenefitInheritancePolicy(),
|
||
GrantMode: config.GetGrantMode(),
|
||
TrialCardEnabled: config.GetTrialCardEnabled(),
|
||
Status: config.GetStatus(),
|
||
}
|
||
}
|
||
|
||
func vipBenefitToProto(benefit ledger.VipBenefit) *walletv1.VipBenefit {
|
||
if benefit.BenefitCode == "" {
|
||
return nil
|
||
}
|
||
return &walletv1.VipBenefit{
|
||
BenefitCode: benefit.BenefitCode,
|
||
Name: benefit.Name,
|
||
BenefitType: benefit.BenefitType,
|
||
UnlockLevel: benefit.UnlockLevel,
|
||
Status: benefit.Status,
|
||
TrialEnabled: benefit.TrialEnabled,
|
||
ResourceId: benefit.ResourceID,
|
||
ResourceType: benefit.ResourceType,
|
||
ExecutionScope: benefit.ExecutionScope,
|
||
AutoEquip: benefit.AutoEquip,
|
||
SortOrder: benefit.SortOrder,
|
||
MetadataJson: benefit.MetadataJSON,
|
||
CreatedAtMs: benefit.CreatedAtMS,
|
||
UpdatedAtMs: benefit.UpdatedAtMS,
|
||
}
|
||
}
|
||
|
||
func vipBenefitsToProto(benefits []ledger.VipBenefit) []*walletv1.VipBenefit {
|
||
items := make([]*walletv1.VipBenefit, 0, len(benefits))
|
||
for _, benefit := range benefits {
|
||
if item := vipBenefitToProto(benefit); item != nil {
|
||
items = append(items, item)
|
||
}
|
||
}
|
||
return items
|
||
}
|
||
|
||
func vipBenefitsFromProto(benefits []*walletv1.VipBenefit) []ledger.VipBenefit {
|
||
items := make([]ledger.VipBenefit, 0, len(benefits))
|
||
for _, benefit := range benefits {
|
||
if benefit == nil {
|
||
continue
|
||
}
|
||
items = append(items, ledger.VipBenefit{
|
||
BenefitCode: benefit.GetBenefitCode(),
|
||
Name: benefit.GetName(),
|
||
BenefitType: benefit.GetBenefitType(),
|
||
UnlockLevel: benefit.GetUnlockLevel(),
|
||
Status: benefit.GetStatus(),
|
||
TrialEnabled: benefit.GetTrialEnabled(),
|
||
ResourceID: benefit.GetResourceId(),
|
||
ResourceType: benefit.GetResourceType(),
|
||
ExecutionScope: benefit.GetExecutionScope(),
|
||
AutoEquip: benefit.GetAutoEquip(),
|
||
SortOrder: benefit.GetSortOrder(),
|
||
MetadataJSON: benefit.GetMetadataJson(),
|
||
})
|
||
}
|
||
return items
|
||
}
|
||
|
||
func vipTrialCardToProto(card ledger.VipTrialCard) *walletv1.VipTrialCard {
|
||
if card.TrialCardID == "" {
|
||
return nil
|
||
}
|
||
return &walletv1.VipTrialCard{
|
||
TrialCardId: card.TrialCardID,
|
||
EntitlementId: card.EntitlementID,
|
||
ResourceId: card.ResourceID,
|
||
UserId: card.UserID,
|
||
Level: card.Level,
|
||
Name: card.Name,
|
||
Status: card.Status,
|
||
Equipped: card.Equipped,
|
||
DurationMs: card.DurationMS,
|
||
EffectiveAtMs: card.EffectiveAtMS,
|
||
ExpiresAtMs: card.ExpiresAtMS,
|
||
RemainingDurationMs: card.RemainingDurationMS,
|
||
GrantSource: card.GrantSource,
|
||
SourceGrantId: card.SourceGrantID,
|
||
CreatedAtMs: card.CreatedAtMS,
|
||
UpdatedAtMs: card.UpdatedAtMS,
|
||
}
|
||
}
|
||
|
||
func vipStateToProto(state ledger.VipState) *walletv1.VipState {
|
||
return &walletv1.VipState{
|
||
PaidVip: vipToProto(state.PaidVip),
|
||
EquippedTrialCard: func() *walletv1.VipTrialCard {
|
||
if state.EquippedTrialCard == nil {
|
||
return nil
|
||
}
|
||
return vipTrialCardToProto(*state.EquippedTrialCard)
|
||
}(),
|
||
EffectiveVip: vipToProto(state.EffectiveVip),
|
||
EffectiveSource: state.EffectiveSource,
|
||
EffectiveBenefits: vipBenefitsToProto(state.EffectiveBenefits),
|
||
EvaluatedAtMs: state.EvaluatedAtMS,
|
||
ProgramConfig: vipProgramConfigToProto(state.ProgramConfig),
|
||
UserSettings: vipUserSettingsToProto(state.UserSettings),
|
||
}
|
||
}
|
||
|
||
func vipRewardItemsToProto(items []ledger.VipRewardItem) []*walletv1.VipRewardItem {
|
||
resp := make([]*walletv1.VipRewardItem, 0, len(items))
|
||
for _, item := range items {
|
||
resp = append(resp, &walletv1.VipRewardItem{
|
||
ResourceId: item.ResourceID,
|
||
ResourceCode: item.ResourceCode,
|
||
ResourceType: item.ResourceType,
|
||
Name: item.Name,
|
||
Quantity: item.Quantity,
|
||
ExpiresAtMs: item.ExpiresAtMS,
|
||
AssetUrl: item.AssetURL,
|
||
PreviewUrl: item.PreviewURL,
|
||
AnimationUrl: item.AnimationURL,
|
||
})
|
||
}
|
||
return resp
|
||
}
|