feat: add VIP badge card resources
This commit is contained in:
parent
6a0ae4793b
commit
0d8e6f599b
@ -4,31 +4,40 @@ import "time"
|
|||||||
|
|
||||||
// VipLevelConfig stores the operator-managed 30-day VIP level configuration.
|
// VipLevelConfig stores the operator-managed 30-day VIP level configuration.
|
||||||
type VipLevelConfig struct {
|
type VipLevelConfig struct {
|
||||||
ID int64 `gorm:"column:id;primaryKey"`
|
ID int64 `gorm:"column:id;primaryKey"`
|
||||||
SysOrigin string `gorm:"column:sys_origin;size:32;uniqueIndex:uk_vip_level_config,priority:1;index:idx_vip_level_config_sys_origin,priority:1"`
|
SysOrigin string `gorm:"column:sys_origin;size:32;uniqueIndex:uk_vip_level_config,priority:1;index:idx_vip_level_config_sys_origin,priority:1"`
|
||||||
Level int `gorm:"column:level;uniqueIndex:uk_vip_level_config,priority:2"`
|
Level int `gorm:"column:level;uniqueIndex:uk_vip_level_config,priority:2"`
|
||||||
LevelCode string `gorm:"column:level_code;size:16"`
|
LevelCode string `gorm:"column:level_code;size:16"`
|
||||||
DisplayName string `gorm:"column:display_name;size:64"`
|
DisplayName string `gorm:"column:display_name;size:64"`
|
||||||
Enabled bool `gorm:"column:enabled"`
|
Enabled bool `gorm:"column:enabled"`
|
||||||
DurationDays int `gorm:"column:duration_days"`
|
DurationDays int `gorm:"column:duration_days"`
|
||||||
PriceGold int64 `gorm:"column:price_gold"`
|
PriceGold int64 `gorm:"column:price_gold"`
|
||||||
BadgeResourceID int64 `gorm:"column:badge_resource_id"`
|
BadgeResourceID int64 `gorm:"column:badge_resource_id"`
|
||||||
BadgeName string `gorm:"column:badge_name;size:128"`
|
BadgeName string `gorm:"column:badge_name;size:128"`
|
||||||
BadgeURL string `gorm:"column:badge_url;size:512"`
|
BadgeURL string `gorm:"column:badge_url;size:512"`
|
||||||
AvatarFrameResourceID int64 `gorm:"column:avatar_frame_resource_id"`
|
ShortBadgeResourceID int64 `gorm:"column:short_badge_resource_id"`
|
||||||
AvatarFrameName string `gorm:"column:avatar_frame_name;size:128"`
|
ShortBadgeName string `gorm:"column:short_badge_name;size:128"`
|
||||||
AvatarFrameURL string `gorm:"column:avatar_frame_url;size:512"`
|
ShortBadgeURL string `gorm:"column:short_badge_url;size:512"`
|
||||||
EntryEffectResourceID int64 `gorm:"column:entry_effect_resource_id"`
|
AvatarFrameResourceID int64 `gorm:"column:avatar_frame_resource_id"`
|
||||||
EntryEffectName string `gorm:"column:entry_effect_name;size:128"`
|
AvatarFrameName string `gorm:"column:avatar_frame_name;size:128"`
|
||||||
EntryEffectURL string `gorm:"column:entry_effect_url;size:512"`
|
AvatarFrameURL string `gorm:"column:avatar_frame_url;size:512"`
|
||||||
ChatBubbleResourceID int64 `gorm:"column:chat_bubble_resource_id"`
|
EntryEffectResourceID int64 `gorm:"column:entry_effect_resource_id"`
|
||||||
ChatBubbleName string `gorm:"column:chat_bubble_name;size:128"`
|
EntryEffectName string `gorm:"column:entry_effect_name;size:128"`
|
||||||
ChatBubbleURL string `gorm:"column:chat_bubble_url;size:512"`
|
EntryEffectURL string `gorm:"column:entry_effect_url;size:512"`
|
||||||
FloatPictureResourceID int64 `gorm:"column:float_picture_resource_id"`
|
ChatBubbleResourceID int64 `gorm:"column:chat_bubble_resource_id"`
|
||||||
FloatPictureName string `gorm:"column:float_picture_name;size:128"`
|
ChatBubbleName string `gorm:"column:chat_bubble_name;size:128"`
|
||||||
FloatPictureURL string `gorm:"column:float_picture_url;size:512"`
|
ChatBubbleURL string `gorm:"column:chat_bubble_url;size:512"`
|
||||||
CreateTime time.Time `gorm:"column:create_time"`
|
FloatPictureResourceID int64 `gorm:"column:float_picture_resource_id"`
|
||||||
UpdateTime time.Time `gorm:"column:update_time"`
|
FloatPictureName string `gorm:"column:float_picture_name;size:128"`
|
||||||
|
FloatPictureURL string `gorm:"column:float_picture_url;size:512"`
|
||||||
|
BackgroundCardResourceID int64 `gorm:"column:background_card_resource_id"`
|
||||||
|
BackgroundCardName string `gorm:"column:background_card_name;size:128"`
|
||||||
|
BackgroundCardURL string `gorm:"column:background_card_url;size:512"`
|
||||||
|
EffectImageResourceID int64 `gorm:"column:effect_image_resource_id"`
|
||||||
|
EffectImageName string `gorm:"column:effect_image_name;size:128"`
|
||||||
|
EffectImageURL string `gorm:"column:effect_image_url;size:512"`
|
||||||
|
CreateTime time.Time `gorm:"column:create_time"`
|
||||||
|
UpdateTime time.Time `gorm:"column:update_time"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// TableName returns the VIP level config table name.
|
// TableName returns the VIP level config table name.
|
||||||
@ -36,32 +45,41 @@ func (VipLevelConfig) TableName() string { return "vip_level_config" }
|
|||||||
|
|
||||||
// UserVipState stores the single active VIP state for a user.
|
// UserVipState stores the single active VIP state for a user.
|
||||||
type UserVipState struct {
|
type UserVipState struct {
|
||||||
ID int64 `gorm:"column:id;primaryKey"`
|
ID int64 `gorm:"column:id;primaryKey"`
|
||||||
SysOrigin string `gorm:"column:sys_origin;size:32;uniqueIndex:uk_user_vip_state,priority:1;index:idx_user_vip_state_lookup,priority:1"`
|
SysOrigin string `gorm:"column:sys_origin;size:32;uniqueIndex:uk_user_vip_state,priority:1;index:idx_user_vip_state_lookup,priority:1"`
|
||||||
UserID int64 `gorm:"column:user_id;uniqueIndex:uk_user_vip_state,priority:2;index:idx_user_vip_state_lookup,priority:2"`
|
UserID int64 `gorm:"column:user_id;uniqueIndex:uk_user_vip_state,priority:2;index:idx_user_vip_state_lookup,priority:2"`
|
||||||
Level int `gorm:"column:level"`
|
Level int `gorm:"column:level"`
|
||||||
LevelCode string `gorm:"column:level_code;size:16"`
|
LevelCode string `gorm:"column:level_code;size:16"`
|
||||||
DisplayName string `gorm:"column:display_name;size:64"`
|
DisplayName string `gorm:"column:display_name;size:64"`
|
||||||
Status string `gorm:"column:status;size:32;index:idx_user_vip_state_lookup,priority:3"`
|
Status string `gorm:"column:status;size:32;index:idx_user_vip_state_lookup,priority:3"`
|
||||||
StartAt time.Time `gorm:"column:start_at"`
|
StartAt time.Time `gorm:"column:start_at"`
|
||||||
ExpireAt time.Time `gorm:"column:expire_at;index:idx_user_vip_expire"`
|
ExpireAt time.Time `gorm:"column:expire_at;index:idx_user_vip_expire"`
|
||||||
BadgeResourceID int64 `gorm:"column:badge_resource_id"`
|
BadgeResourceID int64 `gorm:"column:badge_resource_id"`
|
||||||
BadgeName string `gorm:"column:badge_name;size:128"`
|
BadgeName string `gorm:"column:badge_name;size:128"`
|
||||||
BadgeURL string `gorm:"column:badge_url;size:512"`
|
BadgeURL string `gorm:"column:badge_url;size:512"`
|
||||||
AvatarFrameResourceID int64 `gorm:"column:avatar_frame_resource_id"`
|
ShortBadgeResourceID int64 `gorm:"column:short_badge_resource_id"`
|
||||||
AvatarFrameName string `gorm:"column:avatar_frame_name;size:128"`
|
ShortBadgeName string `gorm:"column:short_badge_name;size:128"`
|
||||||
AvatarFrameURL string `gorm:"column:avatar_frame_url;size:512"`
|
ShortBadgeURL string `gorm:"column:short_badge_url;size:512"`
|
||||||
EntryEffectResourceID int64 `gorm:"column:entry_effect_resource_id"`
|
AvatarFrameResourceID int64 `gorm:"column:avatar_frame_resource_id"`
|
||||||
EntryEffectName string `gorm:"column:entry_effect_name;size:128"`
|
AvatarFrameName string `gorm:"column:avatar_frame_name;size:128"`
|
||||||
EntryEffectURL string `gorm:"column:entry_effect_url;size:512"`
|
AvatarFrameURL string `gorm:"column:avatar_frame_url;size:512"`
|
||||||
ChatBubbleResourceID int64 `gorm:"column:chat_bubble_resource_id"`
|
EntryEffectResourceID int64 `gorm:"column:entry_effect_resource_id"`
|
||||||
ChatBubbleName string `gorm:"column:chat_bubble_name;size:128"`
|
EntryEffectName string `gorm:"column:entry_effect_name;size:128"`
|
||||||
ChatBubbleURL string `gorm:"column:chat_bubble_url;size:512"`
|
EntryEffectURL string `gorm:"column:entry_effect_url;size:512"`
|
||||||
FloatPictureResourceID int64 `gorm:"column:float_picture_resource_id"`
|
ChatBubbleResourceID int64 `gorm:"column:chat_bubble_resource_id"`
|
||||||
FloatPictureName string `gorm:"column:float_picture_name;size:128"`
|
ChatBubbleName string `gorm:"column:chat_bubble_name;size:128"`
|
||||||
FloatPictureURL string `gorm:"column:float_picture_url;size:512"`
|
ChatBubbleURL string `gorm:"column:chat_bubble_url;size:512"`
|
||||||
CreateTime time.Time `gorm:"column:create_time"`
|
FloatPictureResourceID int64 `gorm:"column:float_picture_resource_id"`
|
||||||
UpdateTime time.Time `gorm:"column:update_time"`
|
FloatPictureName string `gorm:"column:float_picture_name;size:128"`
|
||||||
|
FloatPictureURL string `gorm:"column:float_picture_url;size:512"`
|
||||||
|
BackgroundCardResourceID int64 `gorm:"column:background_card_resource_id"`
|
||||||
|
BackgroundCardName string `gorm:"column:background_card_name;size:128"`
|
||||||
|
BackgroundCardURL string `gorm:"column:background_card_url;size:512"`
|
||||||
|
EffectImageResourceID int64 `gorm:"column:effect_image_resource_id"`
|
||||||
|
EffectImageName string `gorm:"column:effect_image_name;size:128"`
|
||||||
|
EffectImageURL string `gorm:"column:effect_image_url;size:512"`
|
||||||
|
CreateTime time.Time `gorm:"column:create_time"`
|
||||||
|
UpdateTime time.Time `gorm:"column:update_time"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// TableName returns the user VIP state table name.
|
// TableName returns the user VIP state table name.
|
||||||
|
|||||||
@ -105,7 +105,7 @@ func (s *Service) PageUserStates(
|
|||||||
Find(&rows).Error; err != nil {
|
Find(&rows).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resourceIDs := make([]int64, 0, len(rows)*5)
|
resourceIDs := make([]int64, 0, len(rows)*8)
|
||||||
for idx := range rows {
|
for idx := range rows {
|
||||||
resourceIDs = appendResourceIDsFromState(resourceIDs, &rows[idx])
|
resourceIDs = appendResourceIDsFromState(resourceIDs, &rows[idx])
|
||||||
}
|
}
|
||||||
@ -133,26 +133,35 @@ func (s *Service) PageUserOrders(ctx context.Context, user AuthUser, cursor int,
|
|||||||
|
|
||||||
func (s *Service) expireDueStates(ctx context.Context, sysOrigin string, now time.Time) error {
|
func (s *Service) expireDueStates(ctx context.Context, sysOrigin string, now time.Time) error {
|
||||||
updates := map[string]any{
|
updates := map[string]any{
|
||||||
"level": 0,
|
"level": 0,
|
||||||
"level_code": "",
|
"level_code": "",
|
||||||
"display_name": "",
|
"display_name": "",
|
||||||
"status": statusExpired,
|
"status": statusExpired,
|
||||||
"badge_resource_id": 0,
|
"badge_resource_id": 0,
|
||||||
"badge_name": "",
|
"badge_name": "",
|
||||||
"badge_url": "",
|
"badge_url": "",
|
||||||
"avatar_frame_resource_id": 0,
|
"short_badge_resource_id": 0,
|
||||||
"avatar_frame_name": "",
|
"short_badge_name": "",
|
||||||
"avatar_frame_url": "",
|
"short_badge_url": "",
|
||||||
"entry_effect_resource_id": 0,
|
"avatar_frame_resource_id": 0,
|
||||||
"entry_effect_name": "",
|
"avatar_frame_name": "",
|
||||||
"entry_effect_url": "",
|
"avatar_frame_url": "",
|
||||||
"chat_bubble_resource_id": 0,
|
"entry_effect_resource_id": 0,
|
||||||
"chat_bubble_name": "",
|
"entry_effect_name": "",
|
||||||
"chat_bubble_url": "",
|
"entry_effect_url": "",
|
||||||
"float_picture_resource_id": 0,
|
"chat_bubble_resource_id": 0,
|
||||||
"float_picture_name": "",
|
"chat_bubble_name": "",
|
||||||
"float_picture_url": "",
|
"chat_bubble_url": "",
|
||||||
"update_time": now,
|
"float_picture_resource_id": 0,
|
||||||
|
"float_picture_name": "",
|
||||||
|
"float_picture_url": "",
|
||||||
|
"background_card_resource_id": 0,
|
||||||
|
"background_card_name": "",
|
||||||
|
"background_card_url": "",
|
||||||
|
"effect_image_resource_id": 0,
|
||||||
|
"effect_image_name": "",
|
||||||
|
"effect_image_url": "",
|
||||||
|
"update_time": now,
|
||||||
}
|
}
|
||||||
return s.db.WithContext(ctx).
|
return s.db.WithContext(ctx).
|
||||||
Model(&model.UserVipState{}).
|
Model(&model.UserVipState{}).
|
||||||
|
|||||||
@ -477,6 +477,9 @@ func applyPlanToState(state *model.UserVipState, plan purchasePlan, now time.Tim
|
|||||||
state.BadgeResourceID = plan.TargetConfig.BadgeResourceID
|
state.BadgeResourceID = plan.TargetConfig.BadgeResourceID
|
||||||
state.BadgeName = ""
|
state.BadgeName = ""
|
||||||
state.BadgeURL = ""
|
state.BadgeURL = ""
|
||||||
|
state.ShortBadgeResourceID = plan.TargetConfig.ShortBadgeResourceID
|
||||||
|
state.ShortBadgeName = ""
|
||||||
|
state.ShortBadgeURL = ""
|
||||||
state.AvatarFrameResourceID = plan.TargetConfig.AvatarFrameResourceID
|
state.AvatarFrameResourceID = plan.TargetConfig.AvatarFrameResourceID
|
||||||
state.AvatarFrameName = ""
|
state.AvatarFrameName = ""
|
||||||
state.AvatarFrameURL = ""
|
state.AvatarFrameURL = ""
|
||||||
@ -489,6 +492,12 @@ func applyPlanToState(state *model.UserVipState, plan purchasePlan, now time.Tim
|
|||||||
state.FloatPictureResourceID = plan.TargetConfig.FloatPictureResourceID
|
state.FloatPictureResourceID = plan.TargetConfig.FloatPictureResourceID
|
||||||
state.FloatPictureName = ""
|
state.FloatPictureName = ""
|
||||||
state.FloatPictureURL = ""
|
state.FloatPictureURL = ""
|
||||||
|
state.BackgroundCardResourceID = plan.TargetConfig.BackgroundCardResourceID
|
||||||
|
state.BackgroundCardName = ""
|
||||||
|
state.BackgroundCardURL = ""
|
||||||
|
state.EffectImageResourceID = plan.TargetConfig.EffectImageResourceID
|
||||||
|
state.EffectImageName = ""
|
||||||
|
state.EffectImageURL = ""
|
||||||
state.UpdateTime = now
|
state.UpdateTime = now
|
||||||
if state.CreateTime.IsZero() {
|
if state.CreateTime.IsZero() {
|
||||||
state.CreateTime = now
|
state.CreateTime = now
|
||||||
@ -503,6 +512,9 @@ func expireState(state *model.UserVipState, now time.Time) {
|
|||||||
state.BadgeResourceID = 0
|
state.BadgeResourceID = 0
|
||||||
state.BadgeName = ""
|
state.BadgeName = ""
|
||||||
state.BadgeURL = ""
|
state.BadgeURL = ""
|
||||||
|
state.ShortBadgeResourceID = 0
|
||||||
|
state.ShortBadgeName = ""
|
||||||
|
state.ShortBadgeURL = ""
|
||||||
state.AvatarFrameResourceID = 0
|
state.AvatarFrameResourceID = 0
|
||||||
state.AvatarFrameName = ""
|
state.AvatarFrameName = ""
|
||||||
state.AvatarFrameURL = ""
|
state.AvatarFrameURL = ""
|
||||||
@ -515,6 +527,12 @@ func expireState(state *model.UserVipState, now time.Time) {
|
|||||||
state.FloatPictureResourceID = 0
|
state.FloatPictureResourceID = 0
|
||||||
state.FloatPictureName = ""
|
state.FloatPictureName = ""
|
||||||
state.FloatPictureURL = ""
|
state.FloatPictureURL = ""
|
||||||
|
state.BackgroundCardResourceID = 0
|
||||||
|
state.BackgroundCardName = ""
|
||||||
|
state.BackgroundCardURL = ""
|
||||||
|
state.EffectImageResourceID = 0
|
||||||
|
state.EffectImageName = ""
|
||||||
|
state.EffectImageURL = ""
|
||||||
state.UpdateTime = now
|
state.UpdateTime = now
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -643,10 +661,12 @@ func (s *Service) alignVIPResourceExpireAt(ctx context.Context, userID int64, re
|
|||||||
func vipGrantResourcesFromConfig(config model.VipLevelConfig) []vipGrantResource {
|
func vipGrantResourcesFromConfig(config model.VipLevelConfig) []vipGrantResource {
|
||||||
return compactVIPGrantResources([]vipGrantResource{
|
return compactVIPGrantResources([]vipGrantResource{
|
||||||
{ResourceID: config.BadgeResourceID, Badge: true},
|
{ResourceID: config.BadgeResourceID, Badge: true},
|
||||||
|
{ResourceID: config.ShortBadgeResourceID, Badge: true},
|
||||||
{ResourceID: config.AvatarFrameResourceID, PropsType: vipPropsTypeAvatarFrame},
|
{ResourceID: config.AvatarFrameResourceID, PropsType: vipPropsTypeAvatarFrame},
|
||||||
{ResourceID: config.EntryEffectResourceID, PropsType: vipPropsTypeRide},
|
{ResourceID: config.EntryEffectResourceID, PropsType: vipPropsTypeRide},
|
||||||
{ResourceID: config.ChatBubbleResourceID, PropsType: vipPropsTypeChatBubble},
|
{ResourceID: config.ChatBubbleResourceID, PropsType: vipPropsTypeChatBubble},
|
||||||
{ResourceID: config.FloatPictureResourceID, PropsType: vipPropsTypeFloatPicture},
|
{ResourceID: config.FloatPictureResourceID, PropsType: vipPropsTypeFloatPicture},
|
||||||
|
{ResourceID: config.BackgroundCardResourceID, PropsType: vipPropsTypeDataCard},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -656,10 +676,12 @@ func vipGrantResourcesFromState(state *model.UserVipState) []vipGrantResource {
|
|||||||
}
|
}
|
||||||
return compactVIPGrantResources([]vipGrantResource{
|
return compactVIPGrantResources([]vipGrantResource{
|
||||||
{ResourceID: state.BadgeResourceID, Badge: true},
|
{ResourceID: state.BadgeResourceID, Badge: true},
|
||||||
|
{ResourceID: state.ShortBadgeResourceID, Badge: true},
|
||||||
{ResourceID: state.AvatarFrameResourceID, PropsType: vipPropsTypeAvatarFrame},
|
{ResourceID: state.AvatarFrameResourceID, PropsType: vipPropsTypeAvatarFrame},
|
||||||
{ResourceID: state.EntryEffectResourceID, PropsType: vipPropsTypeRide},
|
{ResourceID: state.EntryEffectResourceID, PropsType: vipPropsTypeRide},
|
||||||
{ResourceID: state.ChatBubbleResourceID, PropsType: vipPropsTypeChatBubble},
|
{ResourceID: state.ChatBubbleResourceID, PropsType: vipPropsTypeChatBubble},
|
||||||
{ResourceID: state.FloatPictureResourceID, PropsType: vipPropsTypeFloatPicture},
|
{ResourceID: state.FloatPictureResourceID, PropsType: vipPropsTypeFloatPicture},
|
||||||
|
{ResourceID: state.BackgroundCardResourceID, PropsType: vipPropsTypeDataCard},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -120,11 +120,15 @@ func normalizeSaveLevels(levels []VipLevelPayload) ([]VipLevelPayload, error) {
|
|||||||
item.DisplayName = levelDisplayName(item.Level)
|
item.DisplayName = levelDisplayName(item.Level)
|
||||||
}
|
}
|
||||||
item.DurationDays = vipDurationDay
|
item.DurationDays = vipDurationDay
|
||||||
item.Badge = normalizeResource(item.Badge)
|
item.LongBadge = normalizeResource(firstResource(item.LongBadge, item.Badge))
|
||||||
|
item.Badge = item.LongBadge
|
||||||
|
item.ShortBadge = normalizeResource(item.ShortBadge)
|
||||||
item.AvatarFrame = normalizeResource(item.AvatarFrame)
|
item.AvatarFrame = normalizeResource(item.AvatarFrame)
|
||||||
item.EntryEffect = normalizeResource(item.EntryEffect)
|
item.EntryEffect = normalizeResource(item.EntryEffect)
|
||||||
item.ChatBubble = normalizeResource(item.ChatBubble)
|
item.ChatBubble = normalizeResource(item.ChatBubble)
|
||||||
item.FloatPicture = normalizeResource(item.FloatPicture)
|
item.FloatPicture = normalizeResource(item.FloatPicture)
|
||||||
|
item.BackgroundCard = normalizeResource(item.BackgroundCard)
|
||||||
|
item.EffectImage = normalizeResource(item.EffectImage)
|
||||||
normalized = append(normalized, item)
|
normalized = append(normalized, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,6 +163,16 @@ func normalizeResource(resource VipResourcePayload) VipResourcePayload {
|
|||||||
return resource
|
return resource
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func firstResource(preferred VipResourcePayload, fallback VipResourcePayload) VipResourcePayload {
|
||||||
|
if preferred.ResourceID.Int64() > 0 || strings.TrimSpace(preferred.Name) != "" ||
|
||||||
|
strings.TrimSpace(preferred.URL) != "" || strings.TrimSpace(preferred.SourceURL) != "" ||
|
||||||
|
strings.TrimSpace(preferred.ResourceURL) != "" || strings.TrimSpace(preferred.Cover) != "" ||
|
||||||
|
strings.TrimSpace(preferred.CoverURL) != "" {
|
||||||
|
return preferred
|
||||||
|
}
|
||||||
|
return fallback
|
||||||
|
}
|
||||||
|
|
||||||
func applyLevelPayloadToConfig(row *model.VipLevelConfig, item VipLevelPayload, now time.Time) {
|
func applyLevelPayloadToConfig(row *model.VipLevelConfig, item VipLevelPayload, now time.Time) {
|
||||||
row.Level = item.Level
|
row.Level = item.Level
|
||||||
row.LevelCode = levelCode(item.Level)
|
row.LevelCode = levelCode(item.Level)
|
||||||
@ -166,9 +180,12 @@ func applyLevelPayloadToConfig(row *model.VipLevelConfig, item VipLevelPayload,
|
|||||||
row.Enabled = item.Enabled
|
row.Enabled = item.Enabled
|
||||||
row.DurationDays = vipDurationDay
|
row.DurationDays = vipDurationDay
|
||||||
row.PriceGold = item.PriceGold
|
row.PriceGold = item.PriceGold
|
||||||
row.BadgeResourceID = item.Badge.ResourceID.Int64()
|
row.BadgeResourceID = item.LongBadge.ResourceID.Int64()
|
||||||
row.BadgeName = ""
|
row.BadgeName = ""
|
||||||
row.BadgeURL = ""
|
row.BadgeURL = ""
|
||||||
|
row.ShortBadgeResourceID = item.ShortBadge.ResourceID.Int64()
|
||||||
|
row.ShortBadgeName = ""
|
||||||
|
row.ShortBadgeURL = ""
|
||||||
row.AvatarFrameResourceID = item.AvatarFrame.ResourceID.Int64()
|
row.AvatarFrameResourceID = item.AvatarFrame.ResourceID.Int64()
|
||||||
row.AvatarFrameName = ""
|
row.AvatarFrameName = ""
|
||||||
row.AvatarFrameURL = ""
|
row.AvatarFrameURL = ""
|
||||||
@ -181,6 +198,12 @@ func applyLevelPayloadToConfig(row *model.VipLevelConfig, item VipLevelPayload,
|
|||||||
row.FloatPictureResourceID = item.FloatPicture.ResourceID.Int64()
|
row.FloatPictureResourceID = item.FloatPicture.ResourceID.Int64()
|
||||||
row.FloatPictureName = ""
|
row.FloatPictureName = ""
|
||||||
row.FloatPictureURL = ""
|
row.FloatPictureURL = ""
|
||||||
|
row.BackgroundCardResourceID = item.BackgroundCard.ResourceID.Int64()
|
||||||
|
row.BackgroundCardName = ""
|
||||||
|
row.BackgroundCardURL = ""
|
||||||
|
row.EffectImageResourceID = item.EffectImage.ResourceID.Int64()
|
||||||
|
row.EffectImageName = ""
|
||||||
|
row.EffectImageURL = ""
|
||||||
row.UpdateTime = now
|
row.UpdateTime = now
|
||||||
if row.CreateTime.IsZero() {
|
if row.CreateTime.IsZero() {
|
||||||
row.CreateTime = now
|
row.CreateTime = now
|
||||||
|
|||||||
@ -166,30 +166,46 @@ func TestApplyPlanToStateKeepsOnlyResourceIDsAndPayloadUsesLookup(t *testing.T)
|
|||||||
ExpireAt: now.AddDate(0, 0, vipDurationDay),
|
ExpireAt: now.AddDate(0, 0, vipDurationDay),
|
||||||
DurationDays: vipDurationDay,
|
DurationDays: vipDurationDay,
|
||||||
TargetConfig: model.VipLevelConfig{
|
TargetConfig: model.VipLevelConfig{
|
||||||
Level: 3,
|
Level: 3,
|
||||||
DisplayName: "VIP 3",
|
DisplayName: "VIP 3",
|
||||||
AvatarFrameResourceID: 11,
|
BadgeResourceID: 10,
|
||||||
AvatarFrameName: "frame",
|
BadgeName: "long badge",
|
||||||
AvatarFrameURL: "https://example.com/frame.svga",
|
BadgeURL: "https://example.com/long.png",
|
||||||
EntryEffectResourceID: 12,
|
ShortBadgeResourceID: 15,
|
||||||
EntryEffectName: "ride",
|
ShortBadgeName: "short badge",
|
||||||
EntryEffectURL: "https://example.com/ride.svga",
|
ShortBadgeURL: "https://example.com/short.png",
|
||||||
ChatBubbleResourceID: 13,
|
AvatarFrameResourceID: 11,
|
||||||
ChatBubbleName: "bubble",
|
AvatarFrameName: "frame",
|
||||||
ChatBubbleURL: "https://example.com/bubble.svga",
|
AvatarFrameURL: "https://example.com/frame.svga",
|
||||||
FloatPictureResourceID: 14,
|
EntryEffectResourceID: 12,
|
||||||
FloatPictureName: "float",
|
EntryEffectName: "ride",
|
||||||
FloatPictureURL: "https://example.com/float.svga",
|
EntryEffectURL: "https://example.com/ride.svga",
|
||||||
|
ChatBubbleResourceID: 13,
|
||||||
|
ChatBubbleName: "bubble",
|
||||||
|
ChatBubbleURL: "https://example.com/bubble.svga",
|
||||||
|
FloatPictureResourceID: 14,
|
||||||
|
FloatPictureName: "float",
|
||||||
|
FloatPictureURL: "https://example.com/float.svga",
|
||||||
|
BackgroundCardResourceID: 16,
|
||||||
|
BackgroundCardName: "profile card",
|
||||||
|
BackgroundCardURL: "https://example.com/card.pag",
|
||||||
|
EffectImageResourceID: 17,
|
||||||
|
EffectImageName: "effect image",
|
||||||
|
EffectImageURL: "https://example.com/effect.svga",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
state := &model.UserVipState{UserID: 1001, SysOrigin: "LIKEI"}
|
state := &model.UserVipState{UserID: 1001, SysOrigin: "LIKEI"}
|
||||||
applyPlanToState(state, plan, now)
|
applyPlanToState(state, plan, now)
|
||||||
|
|
||||||
if state.AvatarFrameResourceID != plan.TargetConfig.AvatarFrameResourceID ||
|
if state.BadgeResourceID != plan.TargetConfig.BadgeResourceID ||
|
||||||
|
state.ShortBadgeResourceID != plan.TargetConfig.ShortBadgeResourceID ||
|
||||||
|
state.AvatarFrameResourceID != plan.TargetConfig.AvatarFrameResourceID ||
|
||||||
state.EntryEffectResourceID != plan.TargetConfig.EntryEffectResourceID ||
|
state.EntryEffectResourceID != plan.TargetConfig.EntryEffectResourceID ||
|
||||||
state.ChatBubbleResourceID != plan.TargetConfig.ChatBubbleResourceID ||
|
state.ChatBubbleResourceID != plan.TargetConfig.ChatBubbleResourceID ||
|
||||||
state.FloatPictureResourceID != plan.TargetConfig.FloatPictureResourceID {
|
state.FloatPictureResourceID != plan.TargetConfig.FloatPictureResourceID ||
|
||||||
|
state.BackgroundCardResourceID != plan.TargetConfig.BackgroundCardResourceID ||
|
||||||
|
state.EffectImageResourceID != plan.TargetConfig.EffectImageResourceID {
|
||||||
t.Fatalf("state resource ids were not copied from target config")
|
t.Fatalf("state resource ids were not copied from target config")
|
||||||
}
|
}
|
||||||
if state.AvatarFrameName != "" || state.AvatarFrameURL != "" {
|
if state.AvatarFrameName != "" || state.AvatarFrameURL != "" {
|
||||||
@ -197,15 +213,24 @@ func TestApplyPlanToStateKeepsOnlyResourceIDsAndPayloadUsesLookup(t *testing.T)
|
|||||||
}
|
}
|
||||||
|
|
||||||
payload := statePayloadFromModelWithResources(state, now, vipResourceLookup{
|
payload := statePayloadFromModelWithResources(state, now, vipResourceLookup{
|
||||||
|
10: {ID: 10, Name: "long badge", Cover: "https://example.com/long.png", SourceURL: "https://example.com/long.svga"},
|
||||||
11: {ID: 11, Name: "frame", Cover: "https://example.com/frame.png", SourceURL: "https://example.com/frame.svga"},
|
11: {ID: 11, Name: "frame", Cover: "https://example.com/frame.png", SourceURL: "https://example.com/frame.svga"},
|
||||||
12: {ID: 12, Name: "ride", Cover: "https://example.com/ride.png", SourceURL: "https://example.com/ride.svga"},
|
12: {ID: 12, Name: "ride", Cover: "https://example.com/ride.png", SourceURL: "https://example.com/ride.svga"},
|
||||||
13: {ID: 13, Name: "bubble", Cover: "https://example.com/bubble.png", SourceURL: "https://example.com/bubble.svga"},
|
13: {ID: 13, Name: "bubble", Cover: "https://example.com/bubble.png", SourceURL: "https://example.com/bubble.svga"},
|
||||||
14: {ID: 14, Name: "float", Cover: "https://example.com/float.png", SourceURL: "https://example.com/float.svga"},
|
14: {ID: 14, Name: "float", Cover: "https://example.com/float.png", SourceURL: "https://example.com/float.svga"},
|
||||||
|
15: {ID: 15, Name: "short badge", Cover: "https://example.com/short.png", SourceURL: "https://example.com/short.svga"},
|
||||||
|
16: {ID: 16, Name: "profile card", Cover: "https://example.com/card.png", SourceURL: "https://example.com/card.pag"},
|
||||||
|
17: {ID: 17, Name: "effect image", Cover: "https://example.com/effect.png", SourceURL: "https://example.com/effect.svga"},
|
||||||
})
|
})
|
||||||
if payload.AvatarFrame.Cover != "https://example.com/frame.png" ||
|
if payload.LongBadge.Cover != "https://example.com/long.png" ||
|
||||||
|
payload.Badge.Cover != "https://example.com/long.png" ||
|
||||||
|
payload.ShortBadge.Cover != "https://example.com/short.png" ||
|
||||||
|
payload.AvatarFrame.Cover != "https://example.com/frame.png" ||
|
||||||
payload.EntryEffect.Cover != "https://example.com/ride.png" ||
|
payload.EntryEffect.Cover != "https://example.com/ride.png" ||
|
||||||
payload.ChatBubble.Cover != "https://example.com/bubble.png" ||
|
payload.ChatBubble.Cover != "https://example.com/bubble.png" ||
|
||||||
payload.FloatPicture.Cover != "https://example.com/float.png" {
|
payload.FloatPicture.Cover != "https://example.com/float.png" ||
|
||||||
|
payload.BackgroundCard.Cover != "https://example.com/card.png" ||
|
||||||
|
payload.EffectImage.Cover != "https://example.com/effect.png" {
|
||||||
t.Fatalf("state payload covers were not loaded from resource lookup")
|
t.Fatalf("state payload covers were not loaded from resource lookup")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -239,16 +264,19 @@ func TestMapWalletPurchaseErrorGatewayFailure(t *testing.T) {
|
|||||||
|
|
||||||
func TestVIPGrantResourcesFromConfigMapsBackpackTypes(t *testing.T) {
|
func TestVIPGrantResourcesFromConfigMapsBackpackTypes(t *testing.T) {
|
||||||
config := model.VipLevelConfig{
|
config := model.VipLevelConfig{
|
||||||
BadgeResourceID: 10,
|
BadgeResourceID: 10,
|
||||||
AvatarFrameResourceID: 11,
|
ShortBadgeResourceID: 15,
|
||||||
EntryEffectResourceID: 12,
|
AvatarFrameResourceID: 11,
|
||||||
ChatBubbleResourceID: 13,
|
EntryEffectResourceID: 12,
|
||||||
FloatPictureResourceID: 14,
|
ChatBubbleResourceID: 13,
|
||||||
|
FloatPictureResourceID: 14,
|
||||||
|
BackgroundCardResourceID: 16,
|
||||||
|
EffectImageResourceID: 17,
|
||||||
}
|
}
|
||||||
|
|
||||||
resources := vipGrantResourcesFromConfig(config)
|
resources := vipGrantResourcesFromConfig(config)
|
||||||
if len(resources) != 5 {
|
if len(resources) != 7 {
|
||||||
t.Fatalf("resources len = %d, want 5", len(resources))
|
t.Fatalf("resources len = %d, want 7", len(resources))
|
||||||
}
|
}
|
||||||
assertGrant := func(index int, resourceID int64, propsType string, badge bool) {
|
assertGrant := func(index int, resourceID int64, propsType string, badge bool) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
@ -258,10 +286,12 @@ func TestVIPGrantResourcesFromConfigMapsBackpackTypes(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
assertGrant(0, 10, "", true)
|
assertGrant(0, 10, "", true)
|
||||||
assertGrant(1, 11, vipPropsTypeAvatarFrame, false)
|
assertGrant(1, 15, "", true)
|
||||||
assertGrant(2, 12, vipPropsTypeRide, false)
|
assertGrant(2, 11, vipPropsTypeAvatarFrame, false)
|
||||||
assertGrant(3, 13, vipPropsTypeChatBubble, false)
|
assertGrant(3, 12, vipPropsTypeRide, false)
|
||||||
assertGrant(4, 14, vipPropsTypeFloatPicture, false)
|
assertGrant(4, 13, vipPropsTypeChatBubble, false)
|
||||||
|
assertGrant(5, 14, vipPropsTypeFloatPicture, false)
|
||||||
|
assertGrant(6, 16, vipPropsTypeDataCard, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVIPGrantDaysUntilCeilsPartialDay(t *testing.T) {
|
func TestVIPGrantDaysUntilCeilsPartialDay(t *testing.T) {
|
||||||
|
|||||||
@ -54,7 +54,7 @@ func compactResourceIDs(resourceIDs []int64) []int64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func resourceIDsFromConfigRows(rows []model.VipLevelConfig) []int64 {
|
func resourceIDsFromConfigRows(rows []model.VipLevelConfig) []int64 {
|
||||||
ids := make([]int64, 0, len(rows)*5)
|
ids := make([]int64, 0, len(rows)*8)
|
||||||
for _, row := range rows {
|
for _, row := range rows {
|
||||||
ids = appendResourceIDsFromConfig(ids, row)
|
ids = appendResourceIDsFromConfig(ids, row)
|
||||||
}
|
}
|
||||||
@ -62,7 +62,7 @@ func resourceIDsFromConfigRows(rows []model.VipLevelConfig) []int64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func resourceIDsFromConfigMap(configs map[int]model.VipLevelConfig) []int64 {
|
func resourceIDsFromConfigMap(configs map[int]model.VipLevelConfig) []int64 {
|
||||||
ids := make([]int64, 0, len(configs)*5)
|
ids := make([]int64, 0, len(configs)*8)
|
||||||
for _, row := range configs {
|
for _, row := range configs {
|
||||||
ids = appendResourceIDsFromConfig(ids, row)
|
ids = appendResourceIDsFromConfig(ids, row)
|
||||||
}
|
}
|
||||||
@ -73,10 +73,13 @@ func appendResourceIDsFromConfig(ids []int64, row model.VipLevelConfig) []int64
|
|||||||
return append(
|
return append(
|
||||||
ids,
|
ids,
|
||||||
row.BadgeResourceID,
|
row.BadgeResourceID,
|
||||||
|
row.ShortBadgeResourceID,
|
||||||
row.AvatarFrameResourceID,
|
row.AvatarFrameResourceID,
|
||||||
row.EntryEffectResourceID,
|
row.EntryEffectResourceID,
|
||||||
row.ChatBubbleResourceID,
|
row.ChatBubbleResourceID,
|
||||||
row.FloatPictureResourceID,
|
row.FloatPictureResourceID,
|
||||||
|
row.BackgroundCardResourceID,
|
||||||
|
row.EffectImageResourceID,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,9 +90,12 @@ func appendResourceIDsFromState(ids []int64, row *model.UserVipState) []int64 {
|
|||||||
return append(
|
return append(
|
||||||
ids,
|
ids,
|
||||||
row.BadgeResourceID,
|
row.BadgeResourceID,
|
||||||
|
row.ShortBadgeResourceID,
|
||||||
row.AvatarFrameResourceID,
|
row.AvatarFrameResourceID,
|
||||||
row.EntryEffectResourceID,
|
row.EntryEffectResourceID,
|
||||||
row.ChatBubbleResourceID,
|
row.ChatBubbleResourceID,
|
||||||
row.FloatPictureResourceID,
|
row.FloatPictureResourceID,
|
||||||
|
row.BackgroundCardResourceID,
|
||||||
|
row.EffectImageResourceID,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,6 +40,7 @@ const (
|
|||||||
vipPropsTypeRide = "RIDE"
|
vipPropsTypeRide = "RIDE"
|
||||||
vipPropsTypeChatBubble = "CHAT_BUBBLE"
|
vipPropsTypeChatBubble = "CHAT_BUBBLE"
|
||||||
vipPropsTypeFloatPicture = "FLOAT_PICTURE"
|
vipPropsTypeFloatPicture = "FLOAT_PICTURE"
|
||||||
|
vipPropsTypeDataCard = "DATA_CARD"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AppError = common.AppError
|
type AppError = common.AppError
|
||||||
@ -82,19 +83,23 @@ type ConfigResponse struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type VipLevelPayload struct {
|
type VipLevelPayload struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
Level int `json:"level"`
|
Level int `json:"level"`
|
||||||
LevelCode string `json:"levelCode"`
|
LevelCode string `json:"levelCode"`
|
||||||
DisplayName string `json:"displayName"`
|
DisplayName string `json:"displayName"`
|
||||||
Enabled bool `json:"enabled"`
|
Enabled bool `json:"enabled"`
|
||||||
DurationDays int `json:"durationDays"`
|
DurationDays int `json:"durationDays"`
|
||||||
PriceGold int64 `json:"priceGold"`
|
PriceGold int64 `json:"priceGold"`
|
||||||
Badge VipResourcePayload `json:"badge"`
|
Badge VipResourcePayload `json:"badge"`
|
||||||
AvatarFrame VipResourcePayload `json:"avatarFrame"`
|
LongBadge VipResourcePayload `json:"longBadge"`
|
||||||
EntryEffect VipResourcePayload `json:"entryEffect"`
|
ShortBadge VipResourcePayload `json:"shortBadge"`
|
||||||
ChatBubble VipResourcePayload `json:"chatBubble"`
|
AvatarFrame VipResourcePayload `json:"avatarFrame"`
|
||||||
FloatPicture VipResourcePayload `json:"floatPicture"`
|
EntryEffect VipResourcePayload `json:"entryEffect"`
|
||||||
UpdateTime string `json:"updateTime,omitempty"`
|
ChatBubble VipResourcePayload `json:"chatBubble"`
|
||||||
|
FloatPicture VipResourcePayload `json:"floatPicture"`
|
||||||
|
BackgroundCard VipResourcePayload `json:"backgroundCard"`
|
||||||
|
EffectImage VipResourcePayload `json:"effectImage"`
|
||||||
|
UpdateTime string `json:"updateTime,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type VipResourcePayload struct {
|
type VipResourcePayload struct {
|
||||||
@ -183,21 +188,25 @@ type VipLevelHomePayload struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type UserVipStatePayload struct {
|
type UserVipStatePayload struct {
|
||||||
UserID int64 `json:"userId"`
|
UserID int64 `json:"userId"`
|
||||||
SysOrigin string `json:"sysOrigin"`
|
SysOrigin string `json:"sysOrigin"`
|
||||||
Active bool `json:"active"`
|
Active bool `json:"active"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
Level int `json:"level"`
|
Level int `json:"level"`
|
||||||
LevelCode string `json:"levelCode"`
|
LevelCode string `json:"levelCode"`
|
||||||
DisplayName string `json:"displayName"`
|
DisplayName string `json:"displayName"`
|
||||||
StartAt string `json:"startAt,omitempty"`
|
StartAt string `json:"startAt,omitempty"`
|
||||||
ExpireAt string `json:"expireAt,omitempty"`
|
ExpireAt string `json:"expireAt,omitempty"`
|
||||||
Badge VipResourcePayload `json:"badge,omitempty"`
|
Badge VipResourcePayload `json:"badge,omitempty"`
|
||||||
AvatarFrame VipResourcePayload `json:"avatarFrame,omitempty"`
|
LongBadge VipResourcePayload `json:"longBadge,omitempty"`
|
||||||
EntryEffect VipResourcePayload `json:"entryEffect,omitempty"`
|
ShortBadge VipResourcePayload `json:"shortBadge,omitempty"`
|
||||||
ChatBubble VipResourcePayload `json:"chatBubble,omitempty"`
|
AvatarFrame VipResourcePayload `json:"avatarFrame,omitempty"`
|
||||||
FloatPicture VipResourcePayload `json:"floatPicture,omitempty"`
|
EntryEffect VipResourcePayload `json:"entryEffect,omitempty"`
|
||||||
UpdateTime string `json:"updateTime,omitempty"`
|
ChatBubble VipResourcePayload `json:"chatBubble,omitempty"`
|
||||||
|
FloatPicture VipResourcePayload `json:"floatPicture,omitempty"`
|
||||||
|
BackgroundCard VipResourcePayload `json:"backgroundCard,omitempty"`
|
||||||
|
EffectImage VipResourcePayload `json:"effectImage,omitempty"`
|
||||||
|
UpdateTime string `json:"updateTime,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type VipOrderPayload struct {
|
type VipOrderPayload struct {
|
||||||
@ -356,19 +365,23 @@ func payloadFromConfigWithResources(row model.VipLevelConfig, resources vipResou
|
|||||||
code = levelCode(row.Level)
|
code = levelCode(row.Level)
|
||||||
}
|
}
|
||||||
return VipLevelPayload{
|
return VipLevelPayload{
|
||||||
ID: row.ID,
|
ID: row.ID,
|
||||||
Level: row.Level,
|
Level: row.Level,
|
||||||
LevelCode: code,
|
LevelCode: code,
|
||||||
DisplayName: displayName,
|
DisplayName: displayName,
|
||||||
Enabled: row.Enabled,
|
Enabled: row.Enabled,
|
||||||
DurationDays: duration,
|
DurationDays: duration,
|
||||||
PriceGold: row.PriceGold,
|
PriceGold: row.PriceGold,
|
||||||
Badge: resourcePayloadWithLookup(row.BadgeResourceID, row.BadgeName, row.BadgeURL, "", resources),
|
Badge: resourcePayloadWithLookup(row.BadgeResourceID, row.BadgeName, row.BadgeURL, "", resources),
|
||||||
AvatarFrame: resourcePayloadWithLookup(row.AvatarFrameResourceID, row.AvatarFrameName, row.AvatarFrameURL, "", resources),
|
LongBadge: resourcePayloadWithLookup(row.BadgeResourceID, row.BadgeName, row.BadgeURL, "", resources),
|
||||||
EntryEffect: resourcePayloadWithLookup(row.EntryEffectResourceID, row.EntryEffectName, row.EntryEffectURL, "", resources),
|
ShortBadge: resourcePayloadWithLookup(row.ShortBadgeResourceID, row.ShortBadgeName, row.ShortBadgeURL, "", resources),
|
||||||
ChatBubble: resourcePayloadWithLookup(row.ChatBubbleResourceID, row.ChatBubbleName, row.ChatBubbleURL, "", resources),
|
AvatarFrame: resourcePayloadWithLookup(row.AvatarFrameResourceID, row.AvatarFrameName, row.AvatarFrameURL, "", resources),
|
||||||
FloatPicture: resourcePayloadWithLookup(row.FloatPictureResourceID, row.FloatPictureName, row.FloatPictureURL, "", resources),
|
EntryEffect: resourcePayloadWithLookup(row.EntryEffectResourceID, row.EntryEffectName, row.EntryEffectURL, "", resources),
|
||||||
UpdateTime: formatTime(row.UpdateTime),
|
ChatBubble: resourcePayloadWithLookup(row.ChatBubbleResourceID, row.ChatBubbleName, row.ChatBubbleURL, "", resources),
|
||||||
|
FloatPicture: resourcePayloadWithLookup(row.FloatPictureResourceID, row.FloatPictureName, row.FloatPictureURL, "", resources),
|
||||||
|
BackgroundCard: resourcePayloadWithLookup(row.BackgroundCardResourceID, row.BackgroundCardName, row.BackgroundCardURL, "", resources),
|
||||||
|
EffectImage: resourcePayloadWithLookup(row.EffectImageResourceID, row.EffectImageName, row.EffectImageURL, "", resources),
|
||||||
|
UpdateTime: formatTime(row.UpdateTime),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -402,10 +415,14 @@ func statePayloadFromModelWithResources(row *model.UserVipState, now time.Time,
|
|||||||
return payload
|
return payload
|
||||||
}
|
}
|
||||||
payload.Badge = resourcePayloadWithLookup(row.BadgeResourceID, row.BadgeName, row.BadgeURL, "", resources)
|
payload.Badge = resourcePayloadWithLookup(row.BadgeResourceID, row.BadgeName, row.BadgeURL, "", resources)
|
||||||
|
payload.LongBadge = payload.Badge
|
||||||
|
payload.ShortBadge = resourcePayloadWithLookup(row.ShortBadgeResourceID, row.ShortBadgeName, row.ShortBadgeURL, "", resources)
|
||||||
payload.AvatarFrame = resourcePayloadWithLookup(row.AvatarFrameResourceID, row.AvatarFrameName, row.AvatarFrameURL, "", resources)
|
payload.AvatarFrame = resourcePayloadWithLookup(row.AvatarFrameResourceID, row.AvatarFrameName, row.AvatarFrameURL, "", resources)
|
||||||
payload.EntryEffect = resourcePayloadWithLookup(row.EntryEffectResourceID, row.EntryEffectName, row.EntryEffectURL, "", resources)
|
payload.EntryEffect = resourcePayloadWithLookup(row.EntryEffectResourceID, row.EntryEffectName, row.EntryEffectURL, "", resources)
|
||||||
payload.ChatBubble = resourcePayloadWithLookup(row.ChatBubbleResourceID, row.ChatBubbleName, row.ChatBubbleURL, "", resources)
|
payload.ChatBubble = resourcePayloadWithLookup(row.ChatBubbleResourceID, row.ChatBubbleName, row.ChatBubbleURL, "", resources)
|
||||||
payload.FloatPicture = resourcePayloadWithLookup(row.FloatPictureResourceID, row.FloatPictureName, row.FloatPictureURL, "", resources)
|
payload.FloatPicture = resourcePayloadWithLookup(row.FloatPictureResourceID, row.FloatPictureName, row.FloatPictureURL, "", resources)
|
||||||
|
payload.BackgroundCard = resourcePayloadWithLookup(row.BackgroundCardResourceID, row.BackgroundCardName, row.BackgroundCardURL, "", resources)
|
||||||
|
payload.EffectImage = resourcePayloadWithLookup(row.EffectImageResourceID, row.EffectImageName, row.EffectImageURL, "", resources)
|
||||||
return payload
|
return payload
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
253
migrations/042_vip_badge_card_effect_resources.sql
Normal file
253
migrations/042_vip_badge_card_effect_resources.sql
Normal file
@ -0,0 +1,253 @@
|
|||||||
|
SET @current_schema := DATABASE();
|
||||||
|
|
||||||
|
SET @add_vip_level_short_badge_resource_id_sql := IF(
|
||||||
|
NOT EXISTS (
|
||||||
|
SELECT 1 FROM information_schema.columns
|
||||||
|
WHERE table_schema = @current_schema
|
||||||
|
AND table_name = 'vip_level_config'
|
||||||
|
AND column_name = 'short_badge_resource_id'
|
||||||
|
),
|
||||||
|
'ALTER TABLE `vip_level_config` ADD COLUMN `short_badge_resource_id` bigint NOT NULL DEFAULT 0 COMMENT ''短徽章资源ID'' AFTER `badge_url`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE add_vip_level_short_badge_resource_id_stmt FROM @add_vip_level_short_badge_resource_id_sql;
|
||||||
|
EXECUTE add_vip_level_short_badge_resource_id_stmt;
|
||||||
|
DEALLOCATE PREPARE add_vip_level_short_badge_resource_id_stmt;
|
||||||
|
|
||||||
|
SET @add_vip_level_short_badge_name_sql := IF(
|
||||||
|
NOT EXISTS (
|
||||||
|
SELECT 1 FROM information_schema.columns
|
||||||
|
WHERE table_schema = @current_schema
|
||||||
|
AND table_name = 'vip_level_config'
|
||||||
|
AND column_name = 'short_badge_name'
|
||||||
|
),
|
||||||
|
'ALTER TABLE `vip_level_config` ADD COLUMN `short_badge_name` varchar(128) NOT NULL DEFAULT '''' COMMENT ''短徽章名称'' AFTER `short_badge_resource_id`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE add_vip_level_short_badge_name_stmt FROM @add_vip_level_short_badge_name_sql;
|
||||||
|
EXECUTE add_vip_level_short_badge_name_stmt;
|
||||||
|
DEALLOCATE PREPARE add_vip_level_short_badge_name_stmt;
|
||||||
|
|
||||||
|
SET @add_vip_level_short_badge_url_sql := IF(
|
||||||
|
NOT EXISTS (
|
||||||
|
SELECT 1 FROM information_schema.columns
|
||||||
|
WHERE table_schema = @current_schema
|
||||||
|
AND table_name = 'vip_level_config'
|
||||||
|
AND column_name = 'short_badge_url'
|
||||||
|
),
|
||||||
|
'ALTER TABLE `vip_level_config` ADD COLUMN `short_badge_url` varchar(512) NOT NULL DEFAULT '''' COMMENT ''短徽章资源URL'' AFTER `short_badge_name`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE add_vip_level_short_badge_url_stmt FROM @add_vip_level_short_badge_url_sql;
|
||||||
|
EXECUTE add_vip_level_short_badge_url_stmt;
|
||||||
|
DEALLOCATE PREPARE add_vip_level_short_badge_url_stmt;
|
||||||
|
|
||||||
|
SET @add_vip_level_background_card_resource_id_sql := IF(
|
||||||
|
NOT EXISTS (
|
||||||
|
SELECT 1 FROM information_schema.columns
|
||||||
|
WHERE table_schema = @current_schema
|
||||||
|
AND table_name = 'vip_level_config'
|
||||||
|
AND column_name = 'background_card_resource_id'
|
||||||
|
),
|
||||||
|
'ALTER TABLE `vip_level_config` ADD COLUMN `background_card_resource_id` bigint NOT NULL DEFAULT 0 COMMENT ''背景卡资源ID'' AFTER `float_picture_url`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE add_vip_level_background_card_resource_id_stmt FROM @add_vip_level_background_card_resource_id_sql;
|
||||||
|
EXECUTE add_vip_level_background_card_resource_id_stmt;
|
||||||
|
DEALLOCATE PREPARE add_vip_level_background_card_resource_id_stmt;
|
||||||
|
|
||||||
|
SET @add_vip_level_background_card_name_sql := IF(
|
||||||
|
NOT EXISTS (
|
||||||
|
SELECT 1 FROM information_schema.columns
|
||||||
|
WHERE table_schema = @current_schema
|
||||||
|
AND table_name = 'vip_level_config'
|
||||||
|
AND column_name = 'background_card_name'
|
||||||
|
),
|
||||||
|
'ALTER TABLE `vip_level_config` ADD COLUMN `background_card_name` varchar(128) NOT NULL DEFAULT '''' COMMENT ''背景卡名称'' AFTER `background_card_resource_id`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE add_vip_level_background_card_name_stmt FROM @add_vip_level_background_card_name_sql;
|
||||||
|
EXECUTE add_vip_level_background_card_name_stmt;
|
||||||
|
DEALLOCATE PREPARE add_vip_level_background_card_name_stmt;
|
||||||
|
|
||||||
|
SET @add_vip_level_background_card_url_sql := IF(
|
||||||
|
NOT EXISTS (
|
||||||
|
SELECT 1 FROM information_schema.columns
|
||||||
|
WHERE table_schema = @current_schema
|
||||||
|
AND table_name = 'vip_level_config'
|
||||||
|
AND column_name = 'background_card_url'
|
||||||
|
),
|
||||||
|
'ALTER TABLE `vip_level_config` ADD COLUMN `background_card_url` varchar(512) NOT NULL DEFAULT '''' COMMENT ''背景卡资源URL'' AFTER `background_card_name`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE add_vip_level_background_card_url_stmt FROM @add_vip_level_background_card_url_sql;
|
||||||
|
EXECUTE add_vip_level_background_card_url_stmt;
|
||||||
|
DEALLOCATE PREPARE add_vip_level_background_card_url_stmt;
|
||||||
|
|
||||||
|
SET @add_vip_level_effect_image_resource_id_sql := IF(
|
||||||
|
NOT EXISTS (
|
||||||
|
SELECT 1 FROM information_schema.columns
|
||||||
|
WHERE table_schema = @current_schema
|
||||||
|
AND table_name = 'vip_level_config'
|
||||||
|
AND column_name = 'effect_image_resource_id'
|
||||||
|
),
|
||||||
|
'ALTER TABLE `vip_level_config` ADD COLUMN `effect_image_resource_id` bigint NOT NULL DEFAULT 0 COMMENT ''动效图资源ID'' AFTER `background_card_url`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE add_vip_level_effect_image_resource_id_stmt FROM @add_vip_level_effect_image_resource_id_sql;
|
||||||
|
EXECUTE add_vip_level_effect_image_resource_id_stmt;
|
||||||
|
DEALLOCATE PREPARE add_vip_level_effect_image_resource_id_stmt;
|
||||||
|
|
||||||
|
SET @add_vip_level_effect_image_name_sql := IF(
|
||||||
|
NOT EXISTS (
|
||||||
|
SELECT 1 FROM information_schema.columns
|
||||||
|
WHERE table_schema = @current_schema
|
||||||
|
AND table_name = 'vip_level_config'
|
||||||
|
AND column_name = 'effect_image_name'
|
||||||
|
),
|
||||||
|
'ALTER TABLE `vip_level_config` ADD COLUMN `effect_image_name` varchar(128) NOT NULL DEFAULT '''' COMMENT ''动效图名称'' AFTER `effect_image_resource_id`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE add_vip_level_effect_image_name_stmt FROM @add_vip_level_effect_image_name_sql;
|
||||||
|
EXECUTE add_vip_level_effect_image_name_stmt;
|
||||||
|
DEALLOCATE PREPARE add_vip_level_effect_image_name_stmt;
|
||||||
|
|
||||||
|
SET @add_vip_level_effect_image_url_sql := IF(
|
||||||
|
NOT EXISTS (
|
||||||
|
SELECT 1 FROM information_schema.columns
|
||||||
|
WHERE table_schema = @current_schema
|
||||||
|
AND table_name = 'vip_level_config'
|
||||||
|
AND column_name = 'effect_image_url'
|
||||||
|
),
|
||||||
|
'ALTER TABLE `vip_level_config` ADD COLUMN `effect_image_url` varchar(512) NOT NULL DEFAULT '''' COMMENT ''动效图资源URL'' AFTER `effect_image_name`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE add_vip_level_effect_image_url_stmt FROM @add_vip_level_effect_image_url_sql;
|
||||||
|
EXECUTE add_vip_level_effect_image_url_stmt;
|
||||||
|
DEALLOCATE PREPARE add_vip_level_effect_image_url_stmt;
|
||||||
|
|
||||||
|
SET @add_user_vip_short_badge_resource_id_sql := IF(
|
||||||
|
NOT EXISTS (
|
||||||
|
SELECT 1 FROM information_schema.columns
|
||||||
|
WHERE table_schema = @current_schema
|
||||||
|
AND table_name = 'user_vip_state'
|
||||||
|
AND column_name = 'short_badge_resource_id'
|
||||||
|
),
|
||||||
|
'ALTER TABLE `user_vip_state` ADD COLUMN `short_badge_resource_id` bigint NOT NULL DEFAULT 0 COMMENT ''当前短徽章资源ID'' AFTER `badge_url`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE add_user_vip_short_badge_resource_id_stmt FROM @add_user_vip_short_badge_resource_id_sql;
|
||||||
|
EXECUTE add_user_vip_short_badge_resource_id_stmt;
|
||||||
|
DEALLOCATE PREPARE add_user_vip_short_badge_resource_id_stmt;
|
||||||
|
|
||||||
|
SET @add_user_vip_short_badge_name_sql := IF(
|
||||||
|
NOT EXISTS (
|
||||||
|
SELECT 1 FROM information_schema.columns
|
||||||
|
WHERE table_schema = @current_schema
|
||||||
|
AND table_name = 'user_vip_state'
|
||||||
|
AND column_name = 'short_badge_name'
|
||||||
|
),
|
||||||
|
'ALTER TABLE `user_vip_state` ADD COLUMN `short_badge_name` varchar(128) NOT NULL DEFAULT '''' COMMENT ''当前短徽章名称'' AFTER `short_badge_resource_id`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE add_user_vip_short_badge_name_stmt FROM @add_user_vip_short_badge_name_sql;
|
||||||
|
EXECUTE add_user_vip_short_badge_name_stmt;
|
||||||
|
DEALLOCATE PREPARE add_user_vip_short_badge_name_stmt;
|
||||||
|
|
||||||
|
SET @add_user_vip_short_badge_url_sql := IF(
|
||||||
|
NOT EXISTS (
|
||||||
|
SELECT 1 FROM information_schema.columns
|
||||||
|
WHERE table_schema = @current_schema
|
||||||
|
AND table_name = 'user_vip_state'
|
||||||
|
AND column_name = 'short_badge_url'
|
||||||
|
),
|
||||||
|
'ALTER TABLE `user_vip_state` ADD COLUMN `short_badge_url` varchar(512) NOT NULL DEFAULT '''' COMMENT ''当前短徽章资源URL'' AFTER `short_badge_name`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE add_user_vip_short_badge_url_stmt FROM @add_user_vip_short_badge_url_sql;
|
||||||
|
EXECUTE add_user_vip_short_badge_url_stmt;
|
||||||
|
DEALLOCATE PREPARE add_user_vip_short_badge_url_stmt;
|
||||||
|
|
||||||
|
SET @add_user_vip_background_card_resource_id_sql := IF(
|
||||||
|
NOT EXISTS (
|
||||||
|
SELECT 1 FROM information_schema.columns
|
||||||
|
WHERE table_schema = @current_schema
|
||||||
|
AND table_name = 'user_vip_state'
|
||||||
|
AND column_name = 'background_card_resource_id'
|
||||||
|
),
|
||||||
|
'ALTER TABLE `user_vip_state` ADD COLUMN `background_card_resource_id` bigint NOT NULL DEFAULT 0 COMMENT ''当前背景卡资源ID'' AFTER `float_picture_url`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE add_user_vip_background_card_resource_id_stmt FROM @add_user_vip_background_card_resource_id_sql;
|
||||||
|
EXECUTE add_user_vip_background_card_resource_id_stmt;
|
||||||
|
DEALLOCATE PREPARE add_user_vip_background_card_resource_id_stmt;
|
||||||
|
|
||||||
|
SET @add_user_vip_background_card_name_sql := IF(
|
||||||
|
NOT EXISTS (
|
||||||
|
SELECT 1 FROM information_schema.columns
|
||||||
|
WHERE table_schema = @current_schema
|
||||||
|
AND table_name = 'user_vip_state'
|
||||||
|
AND column_name = 'background_card_name'
|
||||||
|
),
|
||||||
|
'ALTER TABLE `user_vip_state` ADD COLUMN `background_card_name` varchar(128) NOT NULL DEFAULT '''' COMMENT ''当前背景卡名称'' AFTER `background_card_resource_id`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE add_user_vip_background_card_name_stmt FROM @add_user_vip_background_card_name_sql;
|
||||||
|
EXECUTE add_user_vip_background_card_name_stmt;
|
||||||
|
DEALLOCATE PREPARE add_user_vip_background_card_name_stmt;
|
||||||
|
|
||||||
|
SET @add_user_vip_background_card_url_sql := IF(
|
||||||
|
NOT EXISTS (
|
||||||
|
SELECT 1 FROM information_schema.columns
|
||||||
|
WHERE table_schema = @current_schema
|
||||||
|
AND table_name = 'user_vip_state'
|
||||||
|
AND column_name = 'background_card_url'
|
||||||
|
),
|
||||||
|
'ALTER TABLE `user_vip_state` ADD COLUMN `background_card_url` varchar(512) NOT NULL DEFAULT '''' COMMENT ''当前背景卡资源URL'' AFTER `background_card_name`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE add_user_vip_background_card_url_stmt FROM @add_user_vip_background_card_url_sql;
|
||||||
|
EXECUTE add_user_vip_background_card_url_stmt;
|
||||||
|
DEALLOCATE PREPARE add_user_vip_background_card_url_stmt;
|
||||||
|
|
||||||
|
SET @add_user_vip_effect_image_resource_id_sql := IF(
|
||||||
|
NOT EXISTS (
|
||||||
|
SELECT 1 FROM information_schema.columns
|
||||||
|
WHERE table_schema = @current_schema
|
||||||
|
AND table_name = 'user_vip_state'
|
||||||
|
AND column_name = 'effect_image_resource_id'
|
||||||
|
),
|
||||||
|
'ALTER TABLE `user_vip_state` ADD COLUMN `effect_image_resource_id` bigint NOT NULL DEFAULT 0 COMMENT ''当前动效图资源ID'' AFTER `background_card_url`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE add_user_vip_effect_image_resource_id_stmt FROM @add_user_vip_effect_image_resource_id_sql;
|
||||||
|
EXECUTE add_user_vip_effect_image_resource_id_stmt;
|
||||||
|
DEALLOCATE PREPARE add_user_vip_effect_image_resource_id_stmt;
|
||||||
|
|
||||||
|
SET @add_user_vip_effect_image_name_sql := IF(
|
||||||
|
NOT EXISTS (
|
||||||
|
SELECT 1 FROM information_schema.columns
|
||||||
|
WHERE table_schema = @current_schema
|
||||||
|
AND table_name = 'user_vip_state'
|
||||||
|
AND column_name = 'effect_image_name'
|
||||||
|
),
|
||||||
|
'ALTER TABLE `user_vip_state` ADD COLUMN `effect_image_name` varchar(128) NOT NULL DEFAULT '''' COMMENT ''当前动效图名称'' AFTER `effect_image_resource_id`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE add_user_vip_effect_image_name_stmt FROM @add_user_vip_effect_image_name_sql;
|
||||||
|
EXECUTE add_user_vip_effect_image_name_stmt;
|
||||||
|
DEALLOCATE PREPARE add_user_vip_effect_image_name_stmt;
|
||||||
|
|
||||||
|
SET @add_user_vip_effect_image_url_sql := IF(
|
||||||
|
NOT EXISTS (
|
||||||
|
SELECT 1 FROM information_schema.columns
|
||||||
|
WHERE table_schema = @current_schema
|
||||||
|
AND table_name = 'user_vip_state'
|
||||||
|
AND column_name = 'effect_image_url'
|
||||||
|
),
|
||||||
|
'ALTER TABLE `user_vip_state` ADD COLUMN `effect_image_url` varchar(512) NOT NULL DEFAULT '''' COMMENT ''当前动效图资源URL'' AFTER `effect_image_name`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE add_user_vip_effect_image_url_stmt FROM @add_user_vip_effect_image_url_sql;
|
||||||
|
EXECUTE add_user_vip_effect_image_url_stmt;
|
||||||
|
DEALLOCATE PREPARE add_user_vip_effect_image_url_stmt;
|
||||||
Loading…
x
Reference in New Issue
Block a user