package listing import ( "encoding/json" "strings" "time" "hfb_sys/backend/internal/auditlog" ) type ListingDTO struct { ID uint64 `json:"id"` ListingNo string `json:"listing_no"` AccountID uint64 `json:"account_id"` OwnerID uint64 `json:"owner_id"` OwnerPhone string `json:"owner_phone,omitempty"` OwnerNickname string `json:"owner_nickname,omitempty"` SourceChannel string `json:"source_channel,omitempty"` IsExternalUpload bool `json:"is_external_upload"` Title string `json:"title"` Description string `json:"description"` GameName string `json:"game_name"` ServerRegion string `json:"server_region"` LoginPlatform string `json:"login_platform"` RankLevel string `json:"rank_level"` HafCoinAmount int64 `json:"haf_coin_amount"` AssetSummary map[string]any `json:"asset_summary,omitempty"` ScreenshotURLS []string `json:"screenshot_urls"` CoverURL string `json:"cover_url"` PriceCent int64 `json:"price_cent"` DepositAmountCent int64 `json:"deposit_amount_cent"` IsAccelerated bool `json:"is_accelerated_sale"` InTransaction bool `json:"in_transaction"` Status string `json:"status"` ReviewStatus string `json:"review_status"` HandoffMode string `json:"handoff_mode"` SettlementMode string `json:"settlement_mode"` ManagedAdminID *uint64 `json:"managed_admin_id,omitempty"` ReviewReason string `json:"review_reason"` PublishedAt *time.Time `json:"published_at"` ListingGroupConversationID uint64 `json:"listing_group_conversation_id,omitempty"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } // PublicListingListItemDTO 是首页商品卡片的最小公开数据。 // 号主身份、账号内部 ID、审核和结算字段仅限号主或后台接口返回。 type PublicListingListItemDTO struct { ID uint64 `json:"id"` ListingNo string `json:"listing_no"` Title string `json:"title"` GameName string `json:"game_name"` ServerRegion string `json:"server_region"` LoginPlatform string `json:"login_platform"` RankLevel string `json:"rank_level"` HafCoinAmount int64 `json:"haf_coin_amount"` AssetSummary map[string]any `json:"asset_summary,omitempty"` CoverURL string `json:"cover_url"` PriceCent int64 `json:"price_cent"` DepositAmountCent int64 `json:"deposit_amount_cent"` IsAccelerated bool `json:"is_accelerated_sale"` PublishedAt *time.Time `json:"published_at,omitempty"` CreatedAt time.Time `json:"created_at"` } // PublicListingDetailDTO 是公开商品详情数据,不包含号主身份或运营内部状态。 type PublicListingDetailDTO struct { PublicListingListItemDTO Description string `json:"description"` ScreenshotURLS []string `json:"screenshot_urls"` } type CreateRequest struct { Title string `json:"title" binding:"required"` Description string `json:"description"` ServerRegion string `json:"server_region" binding:"required"` LoginPlatform string `json:"login_platform"` RankLevel string `json:"rank_level"` HafCoinAmount int64 `json:"haf_coin_amount"` AssetSummary map[string]any `json:"asset_summary"` ScreenshotURLS []string `json:"screenshot_urls"` PriceCent int64 `json:"price_cent"` DepositAmountCent int64 `json:"deposit_amount_cent"` AgreedVirtualAssetSale bool `json:"agreed_virtual_asset_sale"` AgreedSellerAgreement bool `json:"agreed_seller_agreement"` } type UpdateRequest = CreateRequest type ReviewRequest struct { Reason string `json:"reason"` } type AdminPriceAdjustRequest struct { BuyerRatio float64 `json:"buyer_ratio"` BuyerTotalPriceCent int64 `json:"buyer_total_price_cent"` Reason string `json:"reason"` } const ( ExternalAdjustModeDiscountAmount = "discount_amount" ExternalAdjustModeSaleRatio = "sale_ratio" ) type AdminExternalListingAdjustRequest struct { HafCoinAmount int64 `json:"haf_coin_amount" binding:"required,min=1"` AWMBullets int `json:"awm_bullets" binding:"min=0,max=1000000"` Level6Helmets int `json:"level6_helmets" binding:"min=0,max=1000000"` Level6Armor int `json:"level6_armor" binding:"min=0,max=1000000"` DepositAmountCent int64 `json:"deposit_amount_cent" binding:"min=0"` AdjustMode string `json:"adjust_mode" binding:"required,oneof=discount_amount sale_ratio"` DiscountAmountCent int64 `json:"discount_amount_cent" binding:"min=0"` SaleRatio float64 `json:"sale_ratio" binding:"min=0"` Reason string `json:"reason" binding:"required,max=255"` } type TransferOwnerRequest struct { TargetUserID uint64 `json:"target_user_id" binding:"required"` Reason string `json:"reason"` } type AdminListQuery struct { OwnerID uint64 Keyword string Status string ReviewStatus string Insurance []string Stamina []string Load []string SkinGroup []string SkinName []string MinCoin *float64 MaxCoin *float64 MinDeposit *float64 MaxDeposit *float64 Limit int Page int PageSize int } type AdminListResult struct { Items []ListingDTO `json:"items"` Total int64 `json:"total"` Page int `json:"page"` PageSize int `json:"page_size"` } type PublicListQuery struct { Page int PageSize int Keyword string Sort string Zone string Server []string Region []string LoginMethod []string Rank []string Insurance []string Stamina []string Load []string SkinGroup []string SkinName []string MinCoin *float64 MaxCoin *float64 MinRatio *float64 MaxRatio *float64 MinPrice *float64 MaxPrice *float64 MinDeposit *float64 MaxDeposit *float64 MinTotal *float64 MaxTotal *float64 MinFireLevel *float64 MaxFireLevel *float64 MinDailyLoss *float64 MaxDailyLoss *float64 MinSecretKD *float64 MaxSecretKD *float64 ResourceRanges map[string]NumberRange } type NumberRange struct { Min *float64 Max *float64 } type PublicListResult struct { Items []PublicListingListItemDTO `json:"items"` Total int64 `json:"total"` Page int `json:"page"` PageSize int `json:"page_size"` ZoneCounts map[string]int64 `json:"zone_counts"` } type AdminActionRequest struct { Reason string `json:"reason" binding:"required"` } type AuditMeta = auditlog.Meta type ExternalUploadRequest struct { UploadTime int64 `json:"uploadTime"` UploaderName string `json:"uploaderName"` Uploaderame string `json:"uploaderame"` SourceChannel string `json:"sourceChannel"` SourceChannelSnake string `json:"source_channel"` Data json.RawMessage `json:"data"` } func (r ExternalUploadRequest) normalizedUploaderName() string { if name := strings.TrimSpace(r.UploaderName); name != "" { return name } return strings.TrimSpace(r.Uploaderame) } func (r ExternalUploadRequest) normalizedSourceChannel() string { if channel := normalizeExternalSourceChannel(r.SourceChannel); channel != "" { return channel } return normalizeExternalSourceChannel(r.SourceChannelSnake) } type ExternalAccountData struct { LoginMethod string `json:"loginMethod"` Rank string `json:"rank"` Level int `json:"level"` SafeSlots int `json:"safeSlots"` SecretKD float64 `json:"secretKD"` DailyLossM float64 `json:"dailyLossM"` Deposit float64 `json:"deposit"` BanRecord string `json:"banRecord"` CommonRegion string `json:"commonRegion"` ContactPhone string `json:"contactPhone"` OwnerOnlineTime string `json:"ownerOnlineTime"` Remark string `json:"remark"` Currency ExternalUploadCurrency `json:"currency"` DailyConsumption ExternalDailyConsumption `json:"dailyConsumption"` Inventory ExternalUploadInventory `json:"inventory"` } type ExternalUploadCurrency struct { HafuCoin float64 `json:"hafuCoin"` RecycleRatio float64 `json:"recycleRatio"` RecycleRent float64 `json:"recycleRent"` } type ExternalDailyConsumption struct { Stamina int `json:"stamina"` Weight int `json:"weight"` } type ExternalUploadInventory struct { AWMBullets int `json:"awmBullets"` Level6Helmets int `json:"level6Helmets"` Level6Armor int `json:"level6Armor"` Skins []string `json:"skins"` } type ExternalUploadMeta struct { IP string UserAgent string RawPayload []byte } type ExternalUploadResult struct { Index int `json:"index"` ListingID uint64 `json:"listing_id,omitempty"` ListingNo string `json:"listing_no,omitempty"` AccountID uint64 `json:"account_id,omitempty"` ListingGroupConversationID uint64 `json:"listing_group_conversation_id,omitempty"` Status string `json:"status,omitempty"` ReviewStatus string `json:"review_status,omitempty"` Error string `json:"error,omitempty"` } type ExternalUploadResponse struct { ListingID uint64 `json:"listing_id,omitempty"` ListingNo string `json:"listing_no,omitempty"` AccountID uint64 `json:"account_id,omitempty"` ListingGroupConversationID uint64 `json:"listing_group_conversation_id,omitempty"` Status string `json:"status,omitempty"` ReviewStatus string `json:"review_status,omitempty"` Total int `json:"total"` Success int `json:"success"` Failed int `json:"failed"` Items []ExternalUploadResult `json:"items,omitempty"` }