Files
hfb_sys/backend/internal/modules/distribution/dto.go
T
yml2213 2a76d59a30 feat(distribution): 公告中心支持分站自定义
公告中心(前台公告列表/详情)此前完全没有站点概念,分站访客只能看到主站公告。
本次按「默认继承主站、站长可切仅本站」的口径支持分站自定义。

数据与口径:
- 新增 announcements.distribution_site_id(0=主站),前台按站点隔离
- 新增 distribution_sites.announcement_mode:inherit(默认,主站+本站)/ own_only(仅本站)

后端:
- 公告模块新增 ResolvePublicSiteScope:主站 [0]、inherit [0, siteID]、own_only [siteID],
  站点编码无效/已停用回落主站;列表与详情都按该范围过滤,详情不再允许跨站按 ID 读取
- 管理端公告列表支持按站点筛选(site_id:不传=全部,0=主站,>0=分站)并带出站点名
- 分销模块新增本站公告 CRUD(distribution/announcement.go):强制 distribution_site_id=本站,
  先过 ensureSiteAccess,跨站更新/删除/上下架一律 ErrAnnouncementNotFound
- UpdateSiteBranding 支持 announcement_mode 切换(非法值报错,读侧非法历史值回落 inherit)
- 新增权限 distribution:announcement_view|manage 并授予 super_admin/ops/finance,
  站长开通时继承 ops 角色即自动获得
- 路由:站长侧 /api/distribution/announcements*,平台侧 /api/admin/distribution/announcements*

前端:
- 分销后台新增「公告中心」页:来源开关(继承主站+本站 / 仅本站)、本站公告列表与
  新建/编辑/发布/下架/归档/恢复/删除,空态按来源模式给出引导
- 平台后台公告页新增「站点」列与筛选,新建公告可选择归属站点(主站或指定分站代发)
- 前台 PC/移动无需改动:请求已带 X-Distribution-Site-Code,后端按站点隔离,页面已有空态

测试:
- 公告模块:主站/继承/仅本站三种可见范围、跨站详情拦截、无效站点回落、管理端站点筛选
- 分销模块:本站公告 CRUD 与跨站防护、公告来源开关校验与非法值容错
2026-10-01 10:02:31 +08:00

621 lines
26 KiB
Go

package distribution
import "time"
type SiteDTO struct {
ID uint64 `json:"id"`
SiteCode string `json:"site_code"`
SiteName string `json:"site_name"`
Domain string `json:"domain"`
Status string `json:"status"`
DisplayAccountEnabled bool `json:"display_account_enabled"`
LogoURL string `json:"logo_url"`
FaviconURL string `json:"favicon_url"`
BannersJSON string `json:"banners_json"`
AnnouncementsJSON string `json:"announcements_json"`
FooterInfoJSON string `json:"footer_info_json"`
AWRecycleJSON string `json:"aw_recycle_json"`
CooperationFeedbackJSON string `json:"cooperation_feedback_json"`
StorefrontTextJSON string `json:"storefront_text_json"`
AnnouncementMode string `json:"announcement_mode"`
DefaultSupportGroupID *uint64 `json:"default_support_group_id,omitempty"`
ListingQrcodeURL string `json:"listing_qrcode_url"`
ReceiveRatioDelta float64 `json:"receive_ratio_delta"`
ReceiveCostDelta float64 `json:"receive_cost_delta"`
TaxEnabled bool `json:"tax_enabled"`
TaxRateBPS int64 `json:"tax_rate_bps"`
SettlementHoldDays int `json:"settlement_hold_days"`
AdminUserID *uint64 `json:"admin_user_id,omitempty"`
AdminUsername string `json:"admin_username,omitempty"`
AdminNickname string `json:"admin_nickname,omitempty"`
MemberType string `json:"member_type,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type ResetSiteAdminPasswordRequest struct {
NewPassword string `json:"new_password" binding:"required,min=6"`
}
type CreateSiteRequest struct {
SiteCode string `json:"site_code" binding:"required,max=64"`
SiteName string `json:"site_name" binding:"required,max=128"`
Domain string `json:"domain" binding:"required,max=255"`
DisplayAccountEnabled *bool `json:"display_account_enabled"`
DefaultSupportGroupID *uint64 `json:"default_support_group_id"`
ListingQrcodeURL *string `json:"listing_qrcode_url"`
ReceiveRatioDelta *float64 `json:"receive_ratio_delta"`
ReceiveCostDelta *float64 `json:"receive_cost_delta"`
TaxEnabled *bool `json:"tax_enabled"`
TaxRateBPS *int64 `json:"tax_rate_bps"`
SettlementHoldDays *int `json:"settlement_hold_days"`
}
type UpdateSiteRequest struct {
SiteName *string `json:"site_name"`
Domain *string `json:"domain"`
Status *string `json:"status"`
DisplayAccountEnabled *bool `json:"display_account_enabled"`
DefaultSupportGroupID *uint64 `json:"default_support_group_id"`
ListingQrcodeURL *string `json:"listing_qrcode_url"`
ReceiveRatioDelta *float64 `json:"receive_ratio_delta"`
ReceiveCostDelta *float64 `json:"receive_cost_delta"`
TaxEnabled *bool `json:"tax_enabled"`
TaxRateBPS *int64 `json:"tax_rate_bps"`
SettlementHoldDays *int `json:"settlement_hold_days"`
LogoURL *string `json:"logo_url"`
FaviconURL *string `json:"favicon_url"`
BannersJSON *string `json:"banners_json"`
AnnouncementsJSON *string `json:"announcements_json"`
FooterInfoJSON *string `json:"footer_info_json"`
}
type RuleDTO struct {
ID uint64 `json:"id"`
SiteID *uint64 `json:"site_id,omitempty"`
Mode string `json:"mode"`
Version int `json:"version"`
Status string `json:"status"`
PlatformReceiveRatio float64 `json:"platform_receive_ratio"`
PlatformSellRatio float64 `json:"platform_sell_ratio"`
DistributorReceiveRatio float64 `json:"distributor_receive_ratio"`
DistributorSellRatio float64 `json:"distributor_sell_ratio"`
DistributorARatio float64 `json:"distributor_a_ratio"`
DistributorBRatio float64 `json:"distributor_b_ratio"`
ServiceFeeValue float64 `json:"service_fee_value"`
ServiceFeeUnit string `json:"service_fee_unit"`
PaymentFeeBPS int64 `json:"payment_fee_bps"`
TaxEnabled bool `json:"tax_enabled"`
TaxRateBPS int64 `json:"tax_rate_bps"`
EffectiveFrom time.Time `json:"effective_from"`
EffectiveTo *time.Time `json:"effective_to,omitempty"`
CreatedBy *uint64 `json:"created_by,omitempty"`
CreatedAt time.Time `json:"created_at"`
}
type CreateRuleRequest struct {
SiteID *uint64 `json:"site_id"`
Mode string `json:"mode" binding:"required"`
PlatformReceiveRatio float64 `json:"platform_receive_ratio"`
PlatformSellRatio float64 `json:"platform_sell_ratio"`
DistributorReceiveRatio float64 `json:"distributor_receive_ratio"`
DistributorSellRatio float64 `json:"distributor_sell_ratio"`
DistributorARatio float64 `json:"distributor_a_ratio"`
DistributorBRatio float64 `json:"distributor_b_ratio"`
ServiceFeeValue float64 `json:"service_fee_value"`
ServiceFeeUnit string `json:"service_fee_unit" binding:"required"`
PaymentFeeBPS int64 `json:"payment_fee_bps"`
TaxEnabled bool `json:"tax_enabled"`
TaxRateBPS int64 `json:"tax_rate_bps"`
EffectiveFrom time.Time `json:"effective_from"`
}
type UpdateRuleStatusRequest struct {
Status string `json:"status" binding:"required,oneof=draft active disabled"`
}
type DistributionOrderDTO struct {
OrderID uint64 `json:"order_id"`
OrderNo string `json:"order_no"`
SiteID uint64 `json:"site_id"`
ListingID uint64 `json:"listing_id"`
AccountID uint64 `json:"account_id"`
OwnerID uint64 `json:"owner_id"`
RenterID uint64 `json:"renter_id"`
Status string `json:"status"`
HandoffStatus string `json:"handoff_status"`
RefundStatus string `json:"refund_status"`
SettlementStatus string `json:"settlement_status"`
// 分销快照释放状态:pending=待释放,settled=已释放入账;release_at 为预计释放时间。
DistributorSettlementStatus string `json:"distributor_settlement_status"`
ReleaseAt *time.Time `json:"release_at,omitempty"`
DistributionMode string `json:"distribution_mode"`
GrossPaidAmountCent int64 `json:"gross_paid_amount_cent"`
RefundAmountCent int64 `json:"refund_amount_cent"`
NetPaidAmountCent int64 `json:"net_paid_amount_cent"`
PaymentFeeCent int64 `json:"payment_fee_cent"`
ServiceFeeCent int64 `json:"service_fee_cent"`
MarkupAmountCent int64 `json:"markup_amount_cent"`
TaxAmountCent int64 `json:"tax_amount_cent"`
SplitBaseAmountCent int64 `json:"split_base_amount_cent"`
RoundingAdjustmentCent int64 `json:"rounding_adjustment_cent"`
CreatedAt time.Time `json:"created_at"`
// 关联业务与分销商收益透传字段
ListingNo string `json:"listing_no,omitempty"`
Title string `json:"title,omitempty"`
GameName string `json:"game_name,omitempty"`
ServerRegion string `json:"server_region,omitempty"`
LoginPlatform string `json:"login_platform,omitempty"`
RentDurationHours int `json:"rent_duration_hours,omitempty"`
RentedAt *time.Time `json:"rented_at,omitempty"`
RenterPhone string `json:"renter_phone,omitempty"`
RenterNickname string `json:"renter_nickname,omitempty"`
OwnerRentAmountCent int64 `json:"owner_rent_amount_cent,omitempty"`
BasePriceCent int64 `json:"base_price_cent,omitempty"`
ShelfMarkupCent int64 `json:"shelf_markup_cent,omitempty"`
DepositAmountCent int64 `json:"deposit_amount_cent,omitempty"`
// 当前分销商在该订单中的收益拆解
DistributorEarningCent int64 `json:"distributor_earning_cent"`
DistributorRole string `json:"distributor_role,omitempty"`
DistributorMarkupCent int64 `json:"distributor_markup_cent"`
DistributorSplitCent int64 `json:"distributor_split_cent"`
}
type DistributionOrderListQuery struct {
SiteID uint64
Kind string
Role string
Status string
Mode string
FinancialStatus string
Keyword string
Page int
Size int
}
type DistributionOrderPage struct {
Items []DistributionOrderDTO `json:"items"`
Total int64 `json:"total"`
Page int `json:"page"`
PageSize int `json:"page_size"`
}
type AccountDisplayDTO struct {
ID uint64 `json:"id"`
SiteID uint64 `json:"site_id"`
AccountID uint64 `json:"account_id"`
ListingID uint64 `json:"listing_id"`
DisplayStatus string `json:"display_status"`
MarkupAmountCent int64 `json:"markup_amount_cent"`
ShelfRatioDelta float64 `json:"shelf_ratio_delta"`
BaseRatio float64 `json:"base_ratio,omitempty"`
SiteRatio float64 `json:"site_ratio,omitempty"`
ListingNo string `json:"listing_no,omitempty"`
Title string `json:"title,omitempty"`
GameName string `json:"game_name,omitempty"`
ServerRegion string `json:"server_region,omitempty"`
LoginPlatform string `json:"login_platform,omitempty"`
RankLevel string `json:"rank_level,omitempty"`
HafCoinAmount int64 `json:"haf_coin_amount,omitempty"`
PriceCent int64 `json:"price_cent,omitempty"`
SitePriceCent int64 `json:"site_price_cent,omitempty"`
DepositAmountCent int64 `json:"deposit_amount_cent,omitempty"`
ListingStatus string `json:"listing_status,omitempty"`
InTransaction bool `json:"in_transaction,omitempty"`
ListingSiteID *uint64 `json:"listing_site_id,omitempty"`
SourceChannel string `json:"source_channel,omitempty"`
}
type SyncSiteAccountsRequest struct {
ListingIDs []uint64 `json:"listing_ids"`
CleanStaleListings bool `json:"clean_stale_listings"`
DefaultShelfRatioDelta float64 `json:"default_shelf_ratio_delta"`
}
type SyncSiteAccountsResult struct {
SyncedCount int64 `json:"synced_count"`
SkippedCount int64 `json:"skipped_count"`
UpdatedCount int64 `json:"updated_count"`
ReenabledCount int64 `json:"reenabled_count"`
DisabledStaleCount int64 `json:"disabled_stale_count"`
TotalActive int64 `json:"total_active"`
}
type PublicDistributionListingDTO struct {
ListingID uint64 `json:"listing_id"`
ListingNo string `json:"listing_no"`
AccountID uint64 `json:"account_id"`
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"`
PriceCent int64 `json:"price_cent"`
DepositAmountCent int64 `json:"deposit_amount_cent"`
MarkupAmountCent int64 `json:"markup_amount_cent"`
ShelfRatioDelta float64 `json:"shelf_ratio_delta"`
InTransaction bool `json:"in_transaction"`
SiteCode string `json:"site_code"`
SiteName string `json:"site_name"`
}
type PublicDistributionListingsResult struct {
Items []PublicDistributionListingDTO `json:"items"`
Total int64 `json:"total"`
Page int `json:"page"`
PageSize int `json:"page_size"`
}
type PublicSiteInfoDTO struct {
SiteCode string `json:"site_code"`
SiteName string `json:"site_name"`
Domain string `json:"domain"`
Status string `json:"status"`
DisplayAccountEnabled bool `json:"display_account_enabled"`
LogoURL string `json:"logo_url"`
FaviconURL string `json:"favicon_url"`
BannersJSON string `json:"banners_json"`
AnnouncementsJSON string `json:"announcements_json"`
FooterInfoJSON string `json:"footer_info_json"`
StorefrontTextJSON string `json:"storefront_text_json"`
DefaultSupportGroupID *uint64 `json:"default_support_group_id,omitempty"`
ReceiveRatioDelta float64 `json:"receive_ratio_delta"`
ReceiveCostDelta float64 `json:"receive_cost_delta"`
}
type UpdateAccountDisplayRequest struct {
DisplayStatus string `json:"display_status" binding:"required,oneof=enabled disabled sold offline"`
}
type PaymentChannelDTO struct {
ID uint64 `json:"id"`
SiteID uint64 `json:"site_id"`
ConfigID uint64 `json:"config_id"`
Priority int `json:"priority"`
Status string `json:"status"`
}
type BindPaymentChannelRequest struct {
ConfigID uint64 `json:"config_id" binding:"required"`
Priority int `json:"priority"`
}
type SettlementBatchDTO struct {
ID uint64 `json:"id"`
SiteID uint64 `json:"site_id"`
BatchNo string `json:"batch_no"`
PeriodStart time.Time `json:"period_start"`
PeriodEnd time.Time `json:"period_end"`
TotalAmountCent int64 `json:"total_amount_cent"`
Status string `json:"status"`
}
type CreateSettlementBatchRequest struct {
SiteID uint64 `json:"site_id" binding:"required"`
PeriodStart time.Time `json:"period_start" binding:"required"`
PeriodEnd time.Time `json:"period_end" binding:"required"`
}
type SnapshotPartyRequest struct {
PartyRole string `json:"party_role" binding:"required"`
PartyType string `json:"party_type" binding:"required"`
PartyID uint64 `json:"party_id"`
Ratio float64 `json:"ratio"`
IncomeAmountCent int64 `json:"income_amount_cent"`
CostAmountCent int64 `json:"cost_amount_cent"`
}
type CreateFinancialSnapshotRequest struct {
SiteID uint64 `json:"site_id" binding:"required"`
RuleVersionID uint64 `json:"rule_version_id" binding:"required"`
GrossPaidAmountCent int64 `json:"gross_paid_amount_cent"`
RefundAmountCent int64 `json:"refund_amount_cent"`
MarkupAmountCent int64 `json:"markup_amount_cent"`
Parties []SnapshotPartyRequest `json:"parties"`
}
type SettlementItemDTO struct {
ID uint64 `json:"id"`
OrderID uint64 `json:"order_id"`
PartyRole string `json:"party_role"`
AmountCent int64 `json:"amount_cent"`
Status string `json:"status"`
}
type DistributionLoginRequest struct {
Username string `json:"username" binding:"required"`
Password string `json:"password" binding:"required"`
}
type DistributionLoginResponse struct {
Token string `json:"token"`
RefreshToken string `json:"refresh_token"`
Member DistributionCurrentMemberDTO `json:"member"`
}
type DistributionCurrentMemberDTO struct {
AdminID uint64 `json:"admin_id"`
Username string `json:"username"`
Nickname string `json:"nickname"`
IsSuperadmin bool `json:"is_superadmin"`
SiteID *uint64 `json:"site_id,omitempty"`
SiteCode string `json:"site_code,omitempty"`
SiteName string `json:"site_name,omitempty"`
Domain string `json:"domain,omitempty"`
MemberType string `json:"member_type,omitempty"`
}
type OnboardSiteRequest struct {
SiteCode string `json:"site_code" binding:"required,max=64"`
SiteName string `json:"site_name" binding:"required,max=128"`
Domain string `json:"domain" binding:"required,max=255"`
DisplayAccountEnabled *bool `json:"display_account_enabled"`
TaxEnabled *bool `json:"tax_enabled"`
TaxRateBPS *int64 `json:"tax_rate_bps"`
SettlementHoldDays *int `json:"settlement_hold_days"`
AdminUsername string `json:"admin_username" binding:"required,min=3,max=64"`
AdminPassword string `json:"admin_password" binding:"required,min=6,max=64"`
AdminNickname string `json:"admin_nickname"`
MemberType string `json:"member_type" binding:"omitempty,oneof=operator finance customer_service"`
DistributorReceiveRatio float64 `json:"distributor_receive_ratio"` // 兼容旧入参,开通时忽略,四种模式一律走默认分成
PlatformSellRatio float64 `json:"platform_sell_ratio"`
ServiceFeeValue float64 `json:"service_fee_value"`
}
type OnboardSiteResponse struct {
Site SiteDTO `json:"site"`
Rule RuleDTO `json:"rule"`
Member DistributionCurrentMemberDTO `json:"member"`
}
// ReceivedListingDTO 是分销站点收到的账号资产信息
type ReceivedListingDTO struct {
ListingID uint64 `json:"listing_id"`
ListingNo string `json:"listing_no"`
SiteID uint64 `json:"site_id"`
AccountID uint64 `json:"account_id"`
OwnerID uint64 `json:"owner_id"`
OwnerPhone string `json:"owner_phone"`
OwnerNickname string `json:"owner_nickname"`
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"`
SellerRatio float64 `json:"seller_ratio"`
SellerTotalPriceCent int64 `json:"seller_total_price_cent"`
BuyerRatio float64 `json:"buyer_ratio"`
PriceCent int64 `json:"price_cent"`
DepositAmountCent int64 `json:"deposit_amount_cent"`
Status string `json:"status"`
ReviewStatus string `json:"review_status"`
ReviewReason string `json:"review_reason"`
PublishedAt *time.Time `json:"published_at,omitempty"`
CreatedAt time.Time `json:"created_at"`
}
type ReceivedListingQuery struct {
SiteID uint64
Status string
ReviewStatus string
GameName string
Keyword string
Page int
PageSize int
Size int
}
type ReceivedListingPage struct {
Items []ReceivedListingDTO `json:"items"`
Total int64 `json:"total"`
Page int `json:"page"`
PageSize int `json:"page_size"`
}
type UpdateReceivedListingStatusRequest struct {
Status string `json:"status" binding:"required,oneof=published offline"`
}
// 站点品牌与装修 DTO。指针字段未传则保持原值,避免空字符串把装修清掉。
type UpdateSiteBrandingRequest struct {
LogoURL *string `json:"logo_url"`
FaviconURL *string `json:"favicon_url"`
BannersJSON *string `json:"banners_json"`
AnnouncementsJSON *string `json:"announcements_json"`
FooterInfoJSON *string `json:"footer_info_json"`
AWRecycleJSON *string `json:"aw_recycle_json"`
CooperationFeedbackJSON *string `json:"cooperation_feedback_json"`
StorefrontTextJSON *string `json:"storefront_text_json"`
// AnnouncementMode 公告中心来源:inherit(主站+本站)/ own_only(仅本站)。
AnnouncementMode *string `json:"announcement_mode"`
ListingQrcodeURL *string `json:"listing_qrcode_url"`
}
// SiteAnnouncementDTO 分站公告(站长自助维护)。
type SiteAnnouncementDTO struct {
ID uint64 `json:"id"`
DistributionSiteID uint64 `json:"distribution_site_id"`
Title string `json:"title"`
Content string `json:"content"`
Category string `json:"category"`
Priority int `json:"priority"`
IsPinned bool `json:"is_pinned"`
IsImportant bool `json:"is_important"`
ViewCount int `json:"view_count"`
Status string `json:"status"`
PublishedAt *time.Time `json:"published_at"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type SiteAnnouncementPage struct {
Items []SiteAnnouncementDTO `json:"items"`
Total int64 `json:"total"`
Page int `json:"page"`
PageSize int `json:"page_size"`
}
type CreateSiteAnnouncementRequest struct {
Title string `json:"title" binding:"required,max=255"`
Content string `json:"content" binding:"required"`
Category string `json:"category" binding:"omitempty,oneof=notice tutorial rule faq"`
Priority int `json:"priority"`
IsPinned bool `json:"is_pinned"`
IsImportant bool `json:"is_important"`
}
type UpdateSiteAnnouncementRequest struct {
Title string `json:"title" binding:"max=255"`
Content string `json:"content"`
Category string `json:"category" binding:"omitempty,oneof=notice tutorial rule faq"`
Priority int `json:"priority"`
IsPinned bool `json:"is_pinned"`
IsImportant bool `json:"is_important"`
}
// 自主加价 DTO:增加该站「1 元兑换哈夫币」比例,不是人民币。
type UpdateAccountMarkupRequest struct {
ShelfRatioDelta float64 `json:"shelf_ratio_delta"`
}
type AccountMarkupItem struct {
ID uint64 `json:"id,omitempty"`
ListingID uint64 `json:"listing_id,omitempty"`
ShelfRatioDelta float64 `json:"shelf_ratio_delta"`
}
type BatchUpdateAccountMarkupRequest struct {
ListingIDs []uint64 `json:"listing_ids"`
DisplayIDs []uint64 `json:"display_ids"`
ShelfRatioDelta float64 `json:"shelf_ratio_delta"`
Items []AccountMarkupItem `json:"items"`
}
type BatchUpdateAccountDisplayRequest struct {
DisplayIDs []uint64 `json:"display_ids"`
ListingIDs []uint64 `json:"listing_ids"`
TargetStatus string `json:"target_status" binding:"required,oneof=enabled disabled"`
}
type AccountDisplayQuery struct {
Page int `form:"page" json:"page"`
PageSize int `form:"page_size" json:"page_size"`
Status string `form:"status" json:"status"`
Keyword string `form:"keyword" json:"keyword"`
}
type AccountDisplayPageDTO struct {
Items []AccountDisplayDTO `json:"items"`
Total int64 `json:"total"`
Page int `json:"page"`
PageSize int `json:"page_size"`
}
// 商户钱包与提现 DTO
type SiteWalletDTO struct {
SiteID uint64 `json:"site_id"`
AvailableBalanceCent int64 `json:"available_balance_cent"`
FrozenBalanceCent int64 `json:"frozen_balance_cent"`
PendingReleaseCent int64 `json:"pending_release_cent"`
TotalSettledCent int64 `json:"total_settled_cent"`
TotalWithdrawnCent int64 `json:"total_withdrawn_cent"`
SettlementHoldDays int `json:"settlement_hold_days"`
}
type ApplySiteWithdrawalRequest struct {
SiteID uint64 `json:"site_id"`
AmountCent int64 `json:"amount_cent" binding:"required,gt=0"`
AccountType string `json:"account_type" binding:"required,oneof=alipay bank"`
AccountName string `json:"account_name" binding:"required"`
AccountNo string `json:"account_no" binding:"required"`
BankName string `json:"bank_name"`
BankBranch string `json:"bank_branch"`
}
type SiteWithdrawalDTO struct {
ID uint64 `json:"id"`
WithdrawNo string `json:"withdraw_no"`
SiteID uint64 `json:"site_id"`
AmountCent int64 `json:"amount_cent"`
FeeCent int64 `json:"fee_cent"`
ActualAmountCent int64 `json:"actual_amount_cent"`
AccountType string `json:"account_type"`
AccountName string `json:"account_name"`
AccountNo string `json:"account_no"`
BankName string `json:"bank_name"`
BankBranch string `json:"bank_branch"`
Status string `json:"status"`
ReviewRemark string `json:"review_remark"`
PaymentProofURL string `json:"payment_proof_url"`
PaymentRemark string `json:"payment_remark"`
PaidAt *time.Time `json:"paid_at,omitempty"`
CreatedAt time.Time `json:"created_at"`
}
type SiteWithdrawalPage struct {
Items []SiteWithdrawalDTO `json:"items"`
Total int64 `json:"total"`
Page int `json:"page"`
PageSize int `json:"page_size"`
}
// 运营大盘统计 DTO
type DistributionAnalyticsDTO struct {
TodayReceivedCount int64 `json:"today_received_count"`
TotalReceivedCount int64 `json:"total_received_count"`
ActiveListingCount int64 `json:"active_listing_count"`
TodayOrderCount int64 `json:"today_order_count"`
TodayGMVCent int64 `json:"today_gmv_cent"`
TodayProfitCent int64 `json:"today_profit_cent"`
MonthProfitCent int64 `json:"month_profit_cent"`
AvailableBalanceCent int64 `json:"available_balance_cent"`
TrendDays []DistributionTrendPoint `json:"trend_days"`
}
type DistributionTrendPoint struct {
Date string `json:"date"`
ReceivedCount int64 `json:"received_count"`
OrderCount int64 `json:"order_count"`
GMVCent int64 `json:"gmv_cent"`
ProfitCent int64 `json:"profit_cent"`
}
// 分销站点独立短信配置结构体
type SiteSMSConfigDTO struct {
Enabled bool `json:"enabled"`
Provider string `json:"provider"`
AccessKeyID string `json:"access_key_id"`
MaskedSecret string `json:"masked_secret"`
HasSecret bool `json:"has_secret"`
Endpoint string `json:"endpoint"`
SignName string `json:"sign_name"`
LoginTemplateCode string `json:"login_template_code"`
}
type UpdateSiteSMSConfigRequest struct {
Enabled *bool `json:"enabled"`
Provider *string `json:"provider"`
AccessKeyID *string `json:"access_key_id"`
AccessKeySecret *string `json:"access_key_secret"`
Endpoint *string `json:"endpoint"`
SignName *string `json:"sign_name"`
LoginTemplateCode *string `json:"login_template_code"`
}
type TestSiteSMSConfigRequest struct {
Phone string `json:"phone" binding:"required"`
Enabled *bool `json:"enabled"`
Provider *string `json:"provider"`
AccessKeyID *string `json:"access_key_id"`
AccessKeySecret *string `json:"access_key_secret"`
Endpoint *string `json:"endpoint"`
SignName *string `json:"sign_name"`
LoginTemplateCode *string `json:"login_template_code"`
}