448 lines
16 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package ledger
import (
"strings"
)
const (
// VipProgramTypeLegacyTimed 保持 Lalu 现有的剩余时间累加会员语义。
VipProgramTypeLegacyTimed = "legacy_timed"
// VipProgramTypeTieredPrivilegeV1 是 Fami P1 的九级权益体系。
VipProgramTypeTieredPrivilegeV1 = "tiered_privilege_v1"
// VipExpiryPolicyExtendRemaining 从当前有效截止时间继续累加购买时长。
VipExpiryPolicyExtendRemaining = "extend_remaining"
// VipExpiryPolicyReplaceFromNow 表示高级购买立即丢弃低级剩余时间,并从当前时刻重新计时。
VipExpiryPolicyReplaceFromNow = "replace_from_now"
// VipDowngradePurchasePolicyReject 禁止有效会员购买更低等级。
VipDowngradePurchasePolicyReject = "reject"
// VipBenefitInheritanceTargetOnly 仅使用目标等级显式配置的权益集合。
VipBenefitInheritanceTargetOnly = "target_only"
// VipGrantModeDirectMembership 将后台赠送直接写为真实会员。
VipGrantModeDirectMembership = "direct_membership"
// VipGrantModeTrialCard 将后台赠送写入可自由佩戴的背包体验卡。
VipGrantModeTrialCard = "trial_card"
// VipTrialCardResourceType 使体验卡复用通用背包和单选装备链路。
VipTrialCardResourceType = "vip_trial_card"
// VipEffectiveSourceNone 表示没有有效付费会员或已佩戴体验卡。
VipEffectiveSourceNone = "none"
// VipEffectiveSourcePaid 表示最终权益来自真实购买会员。
VipEffectiveSourcePaid = "paid"
// VipEffectiveSourceTrial 表示最终权益来自当前佩戴体验卡。
VipEffectiveSourceTrial = "trial"
// VipTrialCardStatusActive 表示卡片未被撤销;是否过期仍以 ExpiresAtMS 判定。
VipTrialCardStatusActive = "active"
// VipTrialCardStatusRevoked 表示后台已撤销卡片及对应背包权益。
VipTrialCardStatusRevoked = "revoked"
// VipBenefitTypeDecoration 表示需要下发或佩戴资源的视觉权益。
VipBenefitTypeDecoration = "decoration"
// VipBenefitTypeFunction 表示由 owner service 执行的功能权限。
VipBenefitTypeFunction = "function"
// VipExecutionScopeWallet 表示权益由 wallet-service 执行,例如金币返现。
VipExecutionScopeWallet = "wallet"
// VipExecutionScopeRoom 表示权益由 Room Cell 所在 room-service 执行。
VipExecutionScopeRoom = "room"
// VipExecutionScopeUser 表示权益由用户资料或访客 owner 执行。
VipExecutionScopeUser = "user"
// VipExecutionScopeNotice 表示权益由通知投递链路执行。
VipExecutionScopeNotice = "notice"
// 以下编码是 P1 跨服务权限契约;数据库、钱包投影和各 owner service 必须使用同一稳定值。
VipBenefitCodeBadgeIdentity = "vip_badge_identity"
VipBenefitCodeMedal = "vip_medal"
VipBenefitCodeAvatarFrame = "avatar_frame"
VipBenefitCodeTitle = "vip_title"
VipBenefitCodeChatBubble = "chat_bubble"
VipBenefitCodeGift = "vip_gift"
VipBenefitCodeEntryEffect = "entry_effect"
VipBenefitCodeVisitorHistory = "visitor_history"
VipBenefitCodeVoiceWave = "voice_wave"
VipBenefitCodeProfileCard = "profile_card"
VipBenefitCodeCustomRoomBackground = "custom_room_background"
VipBenefitCodeRoomImageMessage = "room_image_message"
VipBenefitCodeAnimatedAvatar = "animated_avatar"
VipBenefitCodeAnimatedRoomCover = "animated_room_cover"
VipBenefitCodeMicSkin = "mic_skin"
VipBenefitCodeRoomBorder = "room_border"
VipBenefitCodeVehicle = "vehicle"
VipBenefitCodeColoredRoomName = "colored_room_name"
VipBenefitCodeColoredNickname = "colored_nickname"
VipBenefitCodeColoredID = "colored_id"
VipBenefitCodeGiftTraySkin = "gift_tray_skin"
VipBenefitCodeHideProfileData = "hide_profile_data"
VipBenefitCodeCustomAvatarFrame = "custom_avatar_frame"
VipBenefitCodeLeaderboardInvisible = "leaderboard_invisible"
VipBenefitCodeDailyCoinRebate = "daily_coin_rebate"
VipBenefitCodeCustomProfileCard = "custom_profile_card"
VipBenefitCodeAnonymousProfileVisit = "anonymous_profile_visit"
VipBenefitCodeCustomGift = "custom_gift"
VipBenefitCodeRoomEntryNotice = "room_entry_notice"
VipBenefitCodeCustomPrettyID = "custom_pretty_id"
VipBenefitCodeCustomVehicle = "custom_vehicle"
VipBenefitCodeAntiKick = "anti_kick"
VipBenefitCodeAntiMute = "anti_mute"
VipBenefitCodeOnlineGlobalNotice = "online_global_notice"
// VipDailyCoinRebateStatusClaimable 表示返现仍处于当天手动领取窗口。
VipDailyCoinRebateStatusClaimable = "claimable"
// VipDailyCoinRebateStatusClaimed 表示金币已经原子入账WalletTransactionID 必须非空。
VipDailyCoinRebateStatusClaimed = "claimed"
// VipDailyCoinRebateStatusExpired 是查询层对超过 UTC 日终但未领取记录的只读投影。
VipDailyCoinRebateStatusExpired = "expired"
// VipDailyCoinRebateRunStatusRunning 表示批任务仍需沿 last_user_id 继续分页。
VipDailyCoinRebateRunStatusRunning = "running"
// VipDailyCoinRebateRunStatusCompleted 表示当日所有候选会员已经扫描完成。
VipDailyCoinRebateRunStatusCompleted = "completed"
)
// VipProgramConfig 是某 App 当前 VIP 状态机的完整规则,不允许调用方再按 app_code 猜规则。
type VipProgramConfig struct {
AppCode string
ProgramType string
LevelCount int32
SameLevelExpiryPolicy string
UpgradeExpiryPolicy string
DowngradePurchasePolicy string
BenefitInheritancePolicy string
GrantMode string
TrialCardEnabled bool
Status string
ConfigVersion int64
UpdatedByAdminID int64
CreatedAtMS int64
UpdatedAtMS int64
}
// VipBenefit 是可跨服务投影和执行的权益事实ResourceID=0 表示纯功能或尚未绑定资源。
type VipBenefit struct {
BenefitCode string
Name string
BenefitType string
UnlockLevel int32
Status string
TrialEnabled bool
ResourceID int64
ResourceType string
ExecutionScope string
AutoEquip bool
SortOrder int32
MetadataJSON string
CreatedAtMS int64
UpdatedAtMS int64
}
// VipRewardItem 是 VIP 资源组权益的轻量展示投影。
type VipRewardItem struct {
ResourceID int64
ResourceCode string
ResourceType string
Name string
Quantity int64
ExpiresAtMS int64
AssetURL string
PreviewURL string
AnimationURL string
}
// VipLevel 是可购买 VIP 等级配置。
type VipLevel struct {
Level int32
Name string
Status string
PriceCoin int64
DurationMS int64
RewardResourceGroupID int64
RequiredRechargeCoinAmount int64
UserRechargeCoinAmount int64
RechargeGateRequired bool
PurchaseLockedReason string
RewardItems []VipRewardItem
CanPurchase bool
SortOrder int32
CreatedAtMS int64
UpdatedAtMS int64
Benefits []VipBenefit
ConfigVersion int64
}
// UserVip 是用户当前会员状态。是否有效以 ExpiresAtMS 和当前时间判断。
type UserVip struct {
UserID int64
Level int32
Name string
Active bool
StartedAtMS int64
ExpiresAtMS int64
UpdatedAtMS int64
ProgramType string
ConfigVersion int64
}
// VipTrialCard 把通用背包 entitlement 投影为 VIP 体验卡;装备切换只改变 Equipped
// DurationMS、EffectiveAtMS 和 ExpiresAtMS 始终保留发卡时的绝对计时事实。
type VipTrialCard struct {
TrialCardID string
EntitlementID string
ResourceID int64
UserID int64
Level int32
Name string
Status string
Equipped bool
DurationMS int64
EffectiveAtMS int64
ExpiresAtMS int64
RemainingDurationMS int64
GrantSource string
SourceGrantID string
CreatedAtMS int64
UpdatedAtMS int64
}
// VipUserSettings 是用户可关闭的 VIP 展示偏好。默认值必须由 wallet owner 统一构造,
// 不能让 room/gateway 因为数据库尚未物化记录而各自猜不同默认值。
type VipUserSettings struct {
AppCode string
UserID int64
RoomEntryNoticeEnabled bool
OnlineGlobalNoticeEnabled bool
UpdatedAtMS int64
}
// DefaultVipUserSettings 返回尚未物化时的产品默认两项通知均开启UpdatedAtMS=0。
func DefaultVipUserSettings(appCode string, userID int64) VipUserSettings {
return VipUserSettings{
AppCode: appCode, UserID: userID,
RoomEntryNoticeEnabled: true, OnlineGlobalNoticeEnabled: true,
}
}
// AllowsBenefitSetting 只处理用户可关闭的两项权益;其它权益不受偏好表影响。
func (settings VipUserSettings) AllowsBenefitSetting(benefitCode string) bool {
switch strings.ToLower(strings.TrimSpace(benefitCode)) {
case VipBenefitCodeRoomEntryNotice:
return settings.RoomEntryNoticeEnabled
case VipBenefitCodeOnlineGlobalNotice:
return settings.OnlineGlobalNoticeEnabled
default:
return true
}
}
// VipState 是调用方唯一应消费的合并状态。EffectiveBenefits 已按真实/体验来源过滤,
// 尤其不会向体验卡返回 TrialEnabled=false 的金币返现资格;可关闭通知还需结合 UserSettings。
type VipState struct {
PaidVip UserVip
EquippedTrialCard *VipTrialCard
EffectiveVip UserVip
EffectiveSource string
EffectiveBenefits []VipBenefit
EvaluatedAtMS int64
ProgramConfig VipProgramConfig
UserSettings VipUserSettings
}
// PurchaseVipCommand 是 App 购买或升级 VIP 的账务命令。
type PurchaseVipCommand struct {
AppCode string
CommandID string
UserID int64
Level int32
}
// PurchaseVipReceipt 是购买 VIP 成功后的稳定回执。
type PurchaseVipReceipt struct {
OrderID string
TransactionID string
Vip UserVip
CoinSpent int64
CoinBalanceAfter int64
RewardItems []VipRewardItem
State VipState
}
// GrantVipCommand 是活动或后台发放 VIP 的统一入口命令。
type GrantVipCommand struct {
AppCode string
CommandID string
TargetUserID int64
Level int32
GrantSource string
OperatorUserID int64
Reason string
}
// GrantVipReceipt 是赠送 VIP 成功后的稳定回执。
type GrantVipReceipt struct {
TransactionID string
Vip UserVip
RewardItems []VipRewardItem
State VipState
}
// GrantVipTrialCardCommand 是直接按等级和绝对时长发放体验卡的幂等命令。
// ResourceID=0 表示按 level 解析同 App 预置资源;非 0 时也必须匹配该等级的 vip_trial_card。
type GrantVipTrialCardCommand struct {
AppCode string
CommandID string
TargetUserID int64
Level int32
DurationMS int64
ResourceID int64
GrantSource string
OperatorUserID int64
Reason string
}
// GrantVipTrialCardReceipt 返回新卡和重新计算后的有效 VIP 状态;发卡本身不自动佩戴。
type GrantVipTrialCardReceipt struct {
TrialCard VipTrialCard
State VipState
ServerTimeMS int64
}
// EquipVipTrialCardCommand 以 entitlement 精确选择背包实例,避免同资源多卡时佩戴错对象。
type EquipVipTrialCardCommand struct {
AppCode string
RequestID string
UserID int64
EntitlementID string
}
// UnequipVipTrialCardCommand 只清理 vip_trial_card 类型的装备事实,不回收或暂停任一卡片。
type UnequipVipTrialCardCommand struct {
AppCode string
RequestID string
UserID int64
}
// CheckVipBenefitResult 是 owner service 执行单项特权时使用的服务端判断结果。
type CheckVipBenefitResult struct {
Allowed bool
Benefit VipBenefit
State VipState
DenialReason string
EvaluatedAtMS int64
}
// AdminVipLevelCommand 是后台保存 VIP 等级配置的完整事实输入。
type AdminVipLevelCommand struct {
Level int32
Name string
Status string
PriceCoin int64
DurationMS int64
RewardResourceGroupID int64
RequiredRechargeCoinAmount int64
SortOrder int32
Benefits []VipBenefit
}
// AdminVipProgramConfigCommand 是后台保存 App 级 VIP 策略的审计输入。
type AdminVipProgramConfigCommand struct {
Config VipProgramConfig
OperatorUserID int64
}
// UpdateVipUserSettingsCommand 使用指针表达 partial updatenil 字段必须保留数据库原值。
type UpdateVipUserSettingsCommand struct {
AppCode string
UserID int64
RoomEntryNoticeEnabled *bool
OnlineGlobalNoticeEnabled *bool
}
// VipDailyCoinRebateRun 是单 App、单 UTC 日唯一的配置快照与分页游标。
// LevelAmounts 只在创建 run 时从 active daily_coin_rebate 权益解析,后续分页禁止回读新配置。
type VipDailyCoinRebateRun struct {
RunID string
TaskDay string
DayStartMS int64
DayEndMS int64
ConfigVersion int64
LevelAmounts map[int32]int64
LevelAmountsJSON string
Status string
LastUserID int64
ScannedCount int64
CreatedCount int64
CreatedAtMS int64
UpdatedAtMS int64
CompletedAtMS int64
}
// VipDailyCoinRebate 是日切时生成、当天手动领取的付费 VIP 返现事实。
type VipDailyCoinRebate struct {
RebateID string
UserID int64
TaskDay string
VipLevel int32
VipName string
CoinAmount int64
Status string
AvailableAtMS int64
ExpiresAtMS int64
ConfigVersion int64
ClaimedAtMS int64
WalletTransactionID string
CreatedAtMS int64
UpdatedAtMS int64
}
// ProcessVipDailyCoinRebateBatchCommand 由 cron 适配器构造NowMS 仅由 wallet-service 注入,
// repository 不信任调度方的本地时钟。
type ProcessVipDailyCoinRebateBatchCommand struct {
AppCode string
TaskDay string
BatchSize int
NowMS int64
}
// ProcessVipDailyCoinRebateBatchResult 返回本页计数与持久 run调度方据 HasMore 继续触发。
type ProcessVipDailyCoinRebateBatchResult struct {
Run VipDailyCoinRebateRun
ScannedCount int
CreatedCount int
HasMore bool
}
// ListVipDailyCoinRebateStatusesQuery 是用户侧返现历史分页查询;状态在读取时按 NowMS 投影。
type ListVipDailyCoinRebateStatusesQuery struct {
AppCode string
UserID int64
Page int
PageSize int
RebateIDs []string
NowMS int64
}
// ClaimVipDailyCoinRebateCommand 只包含调用方可控主键;金额、等级和窗口全部从锁内返现行读取。
type ClaimVipDailyCoinRebateCommand struct {
AppCode string
CommandID string
UserID int64
RebateID string
NowMS int64
}
// ClaimVipDailyCoinRebateReceipt 是幂等稳定回执;同 command 重放必须返回同一交易和账后余额。
type ClaimVipDailyCoinRebateReceipt struct {
Rebate VipDailyCoinRebate
TransactionID string
CoinBalance AssetBalance
}
func NormalizeVipGrantSource(source string) string {
switch strings.ToLower(strings.TrimSpace(source)) {
case VipGrantSourcePurchase:
return VipGrantSourcePurchase
case VipGrantSourceActivity:
return VipGrantSourceActivity
case VipGrantSourceAdmin:
return VipGrantSourceAdmin
case VipGrantSourceManagerCenter:
return VipGrantSourceManagerCenter
default:
return ""
}
}