266 lines
9.0 KiB
Go
266 lines
9.0 KiB
Go
package systemconfig
|
|
|
|
import (
|
|
"math"
|
|
"strings"
|
|
)
|
|
|
|
// 热区悬浮放大倍数:与前端 BANNER_HOTSPOT_DEFAULT_HOVER_SCALE 保持一致。
|
|
const defaultBannerHotspotHoverScale = 1.06
|
|
const maxBannerHotspotHoverScale = 1.5
|
|
|
|
func normalizeAnnouncements(items []string) []string {
|
|
normalized := make([]string, 0, len(items))
|
|
for _, item := range items {
|
|
item = strings.TrimSpace(item)
|
|
if item != "" {
|
|
normalized = append(normalized, item)
|
|
}
|
|
}
|
|
if len(normalized) == 0 {
|
|
return defaultHomeAnnouncements()
|
|
}
|
|
return normalized
|
|
}
|
|
|
|
func normalizeHomeBanners(items []HomeBannerItem) []HomeBannerItem {
|
|
normalized := make([]HomeBannerItem, 0, len(items))
|
|
for _, item := range items {
|
|
item.Eyebrow = strings.TrimSpace(item.Eyebrow)
|
|
item.Title = strings.TrimSpace(item.Title)
|
|
item.Badge = strings.TrimSpace(item.Badge)
|
|
item.Pill = strings.TrimSpace(item.Pill)
|
|
item.Tone = strings.TrimSpace(item.Tone)
|
|
// 旧结构只有一张图,两端共用,避免历史配置升级后丢图
|
|
legacyImageURL := strings.TrimSpace(item.ImageURL)
|
|
item.ImageURL = ""
|
|
item.PC = normalizeBannerVisual(item.PC, legacyImageURL)
|
|
item.Mobile = normalizeBannerVisual(item.Mobile, legacyImageURL)
|
|
if item.Title == "" && item.PC.ImageURL == "" && item.Mobile.ImageURL == "" {
|
|
continue
|
|
}
|
|
if item.Tone != "green" && item.Tone != "orange" && item.Tone != "gold" {
|
|
item.Tone = "blue"
|
|
}
|
|
normalized = append(normalized, item)
|
|
}
|
|
if len(normalized) == 0 {
|
|
return defaultHomeBanners()
|
|
}
|
|
return normalized
|
|
}
|
|
|
|
func normalizeBannerVisual(visual HomeBannerVisual, legacyImageURL string) HomeBannerVisual {
|
|
visual.ImageURL = strings.TrimSpace(visual.ImageURL)
|
|
if visual.ImageURL == "" {
|
|
visual.ImageURL = legacyImageURL
|
|
}
|
|
visual.Alt = strings.TrimSpace(visual.Alt)
|
|
visual.Action = normalizeBannerAction(visual.Action)
|
|
hotspots := make([]HomeBannerHotspot, 0, len(visual.Hotspots))
|
|
for _, hotspot := range visual.Hotspots {
|
|
item, ok := normalizeBannerHotspot(hotspot)
|
|
if !ok {
|
|
continue
|
|
}
|
|
hotspots = append(hotspots, item)
|
|
}
|
|
visual.Hotspots = hotspots
|
|
return visual
|
|
}
|
|
|
|
// normalizeBannerHotspot 收敛热区坐标:宽高为 0 的热区无意义直接丢弃,其余保证不越界。
|
|
func normalizeBannerHotspot(hotspot HomeBannerHotspot) (HomeBannerHotspot, bool) {
|
|
width := clampBannerPercent(hotspot.Width, 100)
|
|
height := clampBannerPercent(hotspot.Height, 100)
|
|
if width <= 0 || height <= 0 {
|
|
return HomeBannerHotspot{}, false
|
|
}
|
|
hotspot.ID = strings.TrimSpace(hotspot.ID)
|
|
hotspot.Label = strings.TrimSpace(hotspot.Label)
|
|
hotspot.ImageURL = strings.TrimSpace(hotspot.ImageURL)
|
|
hotspot.HoverScale = normalizeHotspotHoverScale(hotspot.HoverScale)
|
|
hotspot.Width = width
|
|
hotspot.Height = height
|
|
hotspot.X = clampBannerPercent(hotspot.X, 100-width)
|
|
hotspot.Y = clampBannerPercent(hotspot.Y, 100-height)
|
|
hotspot.Action = normalizeBannerAction(hotspot.Action)
|
|
return hotspot, true
|
|
}
|
|
|
|
// normalizeHotspotHoverScale 悬浮放大倍数:缺失/非法回落默认值,上限 1.5 防止热区盖住整张图。
|
|
func normalizeHotspotHoverScale(value float64) float64 {
|
|
if value <= 0 {
|
|
return defaultBannerHotspotHoverScale
|
|
}
|
|
if value > maxBannerHotspotHoverScale {
|
|
value = maxBannerHotspotHoverScale
|
|
} else if value < 1 {
|
|
value = 1
|
|
}
|
|
return math.Round(value*100) / 100
|
|
}
|
|
|
|
// normalizeBannerAction 目标缺失的跳转会变成「点了没反应」的死热区,统一退化为 none。
|
|
func normalizeBannerAction(action HomeBannerAction) HomeBannerAction {
|
|
action.Type = strings.TrimSpace(action.Type)
|
|
action.Target = strings.TrimSpace(action.Target)
|
|
switch action.Type {
|
|
case "route", "link":
|
|
if action.Target == "" {
|
|
return HomeBannerAction{Type: "none"}
|
|
}
|
|
case "preview":
|
|
action.Target = ""
|
|
action.OpenNewTab = false
|
|
case "none":
|
|
action.Target = ""
|
|
action.OpenNewTab = false
|
|
default:
|
|
return HomeBannerAction{Type: "none"}
|
|
}
|
|
return action
|
|
}
|
|
|
|
func clampBannerPercent(value float64, max float64) float64 {
|
|
if value < 0 {
|
|
value = 0
|
|
}
|
|
if value > max {
|
|
value = max
|
|
}
|
|
return math.Round(value*100) / 100
|
|
}
|
|
|
|
func normalizeOrderAgreements(agreements *OrderAgreementsDTO) {
|
|
defaults := DefaultOrderAgreements()
|
|
agreements.VirtualAssetPurchase.Title = strings.TrimSpace(agreements.VirtualAssetPurchase.Title)
|
|
agreements.VirtualAssetPurchase.Content = strings.TrimSpace(agreements.VirtualAssetPurchase.Content)
|
|
agreements.RenterAgreement.Title = strings.TrimSpace(agreements.RenterAgreement.Title)
|
|
agreements.RenterAgreement.Content = strings.TrimSpace(agreements.RenterAgreement.Content)
|
|
if agreements.VirtualAssetPurchase.Title == "" {
|
|
agreements.VirtualAssetPurchase.Title = defaults.VirtualAssetPurchase.Title
|
|
}
|
|
if agreements.VirtualAssetPurchase.Content == "" {
|
|
agreements.VirtualAssetPurchase.Content = defaults.VirtualAssetPurchase.Content
|
|
}
|
|
if agreements.RenterAgreement.Title == "" {
|
|
agreements.RenterAgreement.Title = defaults.RenterAgreement.Title
|
|
}
|
|
if agreements.RenterAgreement.Content == "" {
|
|
agreements.RenterAgreement.Content = defaults.RenterAgreement.Content
|
|
}
|
|
}
|
|
|
|
func normalizeListingPublishAgreements(agreements *ListingPublishAgreementsDTO) {
|
|
defaults := DefaultListingPublishAgreements()
|
|
agreements.VirtualAssetSale.Title = strings.TrimSpace(agreements.VirtualAssetSale.Title)
|
|
agreements.VirtualAssetSale.Content = strings.TrimSpace(agreements.VirtualAssetSale.Content)
|
|
agreements.SellerAgreement.Title = strings.TrimSpace(agreements.SellerAgreement.Title)
|
|
agreements.SellerAgreement.Content = strings.TrimSpace(agreements.SellerAgreement.Content)
|
|
if agreements.VirtualAssetSale.Title == "" {
|
|
agreements.VirtualAssetSale.Title = defaults.VirtualAssetSale.Title
|
|
}
|
|
if agreements.VirtualAssetSale.Content == "" {
|
|
agreements.VirtualAssetSale.Content = defaults.VirtualAssetSale.Content
|
|
}
|
|
if agreements.SellerAgreement.Title == "" {
|
|
agreements.SellerAgreement.Title = defaults.SellerAgreement.Title
|
|
}
|
|
if agreements.SellerAgreement.Content == "" {
|
|
agreements.SellerAgreement.Content = defaults.SellerAgreement.Content
|
|
}
|
|
}
|
|
|
|
func normalizePostRentalNotice(notice *PostRentalNoticeDTO) {
|
|
defaults := DefaultPostRentalNotice()
|
|
notice.Title = strings.TrimSpace(notice.Title)
|
|
notice.Content = strings.TrimSpace(notice.Content)
|
|
if notice.Title == "" {
|
|
notice.Title = defaults.Title
|
|
}
|
|
if notice.Content == "" {
|
|
notice.Content = defaults.Content
|
|
}
|
|
}
|
|
|
|
func normalizePublishOptions(options *PublishOptionsDTO) {
|
|
defaults := DefaultPublishOptions()
|
|
if len(options.ServerOptions) == 0 {
|
|
options.ServerOptions = defaults.ServerOptions
|
|
}
|
|
if len(options.FaceOptions) == 0 {
|
|
options.FaceOptions = defaults.FaceOptions
|
|
}
|
|
if len(options.RankOptions) == 0 {
|
|
options.RankOptions = defaults.RankOptions
|
|
}
|
|
if len(options.InsuranceOptions) == 0 {
|
|
options.InsuranceOptions = defaults.InsuranceOptions
|
|
}
|
|
if len(options.LevelOptions) == 0 {
|
|
options.LevelOptions = defaults.LevelOptions
|
|
}
|
|
if len(options.LoginMethodOptions) == 0 {
|
|
options.LoginMethodOptions = defaults.LoginMethodOptions
|
|
}
|
|
if len(options.RegionOptions) == 0 {
|
|
options.RegionOptions = defaults.RegionOptions
|
|
}
|
|
if len(options.SkinGroups) == 0 {
|
|
options.SkinGroups = defaults.SkinGroups
|
|
}
|
|
if len(options.QuantityItems) == 0 {
|
|
options.QuantityItems = defaults.QuantityItems
|
|
}
|
|
if len(options.ScreenshotSlots) == 0 {
|
|
options.ScreenshotSlots = defaults.ScreenshotSlots
|
|
}
|
|
if len(options.BanRecordOptions) == 0 {
|
|
options.BanRecordOptions = defaults.BanRecordOptions
|
|
}
|
|
if len(options.BanEvidenceOptions) == 0 {
|
|
options.BanEvidenceOptions = defaults.BanEvidenceOptions
|
|
}
|
|
if options.FireLevelMin <= 0 {
|
|
options.FireLevelMin = defaults.FireLevelMin
|
|
}
|
|
if options.PriceConfig.DepositPlaceholder == "" {
|
|
options.PriceConfig.DepositPlaceholder = defaults.PriceConfig.DepositPlaceholder
|
|
}
|
|
if options.PriceConfig.DepositHint == "" {
|
|
options.PriceConfig.DepositHint = defaults.PriceConfig.DepositHint
|
|
}
|
|
if options.PriceConfig.PricePlaceholder == "" {
|
|
options.PriceConfig.PricePlaceholder = defaults.PriceConfig.PricePlaceholder
|
|
}
|
|
if options.PriceConfig.RatioDescription == "" {
|
|
options.PriceConfig.RatioDescription = defaults.PriceConfig.RatioDescription
|
|
}
|
|
if options.DepositRecommend.BaseAmount <= 0 {
|
|
options.DepositRecommend.BaseAmount = defaults.DepositRecommend.BaseAmount
|
|
}
|
|
if len(options.DepositRecommend.SkinGroupRules) == 0 {
|
|
options.DepositRecommend.SkinGroupRules = defaults.DepositRecommend.SkinGroupRules
|
|
}
|
|
if len(options.RatioConfig.InsuranceBaseRatios) == 0 {
|
|
options.RatioConfig.InsuranceBaseRatios = defaults.RatioConfig.InsuranceBaseRatios
|
|
}
|
|
if len(options.RatioConfig.ConfigItems) == 0 {
|
|
options.RatioConfig.ConfigItems = defaults.RatioConfig.ConfigItems
|
|
}
|
|
if len(options.RatioConfig.CoinCorrections) == 0 {
|
|
options.RatioConfig.CoinCorrections = defaults.RatioConfig.CoinCorrections
|
|
}
|
|
}
|
|
|
|
func normalizeSalePriceConfig(config *PublishSalePriceConfig) {
|
|
defaults := DefaultSalePriceConfig()
|
|
if len(config.FixedMarkupRules) == 0 {
|
|
config.FixedMarkupRules = defaults.FixedMarkupRules
|
|
}
|
|
if len(config.RatioAdjustmentRules) == 0 {
|
|
config.RatioAdjustmentRules = defaults.RatioAdjustmentRules
|
|
}
|
|
}
|