公告中心(前台公告列表/详情)此前完全没有站点概念,分站访客只能看到主站公告。 本次按「默认继承主站、站长可切仅本站」的口径支持分站自定义。 数据与口径: - 新增 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 与跨站防护、公告来源开关校验与非法值容错
188 lines
12 KiB
Go
188 lines
12 KiB
Go
package model
|
|
|
|
import "time"
|
|
|
|
// DistributionSite 表示一个独立分销网站主体。
|
|
type DistributionSite struct {
|
|
ID uint64 `gorm:"primaryKey" json:"id"`
|
|
SiteCode string `gorm:"size:64;not null;uniqueIndex" json:"site_code"`
|
|
SiteName string `gorm:"size:128;not null" json:"site_name"`
|
|
Domain string `gorm:"size:255;not null;uniqueIndex" json:"domain"`
|
|
Status string `gorm:"size:16;not null;default:'active';index" json:"status"`
|
|
DisplayAccountEnabled bool `gorm:"not null;default:true" json:"display_account_enabled"`
|
|
LogoURL string `gorm:"size:512;not null;default:''" json:"logo_url"`
|
|
FaviconURL string `gorm:"size:512;not null;default:''" json:"favicon_url"`
|
|
BannersJSON string `gorm:"type:text" json:"banners_json"`
|
|
AnnouncementsJSON string `gorm:"type:text" json:"announcements_json"`
|
|
FooterInfoJSON string `gorm:"type:text" json:"footer_info_json"`
|
|
AWRecycleJSON string `gorm:"type:text" json:"aw_recycle_json"`
|
|
CooperationFeedbackJSON string `gorm:"type:text" json:"cooperation_feedback_json"`
|
|
// StorefrontTextJSON 首页文案(tagline/hero_badge/hero_desc/card_sub),空字段继承前台默认。
|
|
StorefrontTextJSON string `gorm:"type:text" json:"storefront_text_json"`
|
|
// AnnouncementMode 公告中心来源:inherit=主站公告+本站公告(默认),own_only=仅本站公告。
|
|
AnnouncementMode string `gorm:"size:16;not null;default:'inherit'" json:"announcement_mode"`
|
|
DefaultSupportGroupID *uint64 `gorm:"index" json:"default_support_group_id,omitempty"`
|
|
ListingQrcodeURL string `gorm:"size:512;not null;default:''" json:"listing_qrcode_url"`
|
|
SMSConfigJSON string `gorm:"type:text" json:"-"`
|
|
ReceiveRatioDelta float64 `gorm:"type:decimal(10,2);not null;default:0" json:"receive_ratio_delta"`
|
|
ReceiveCostDelta float64 `gorm:"type:decimal(10,2);not null;default:0" json:"receive_cost_delta"`
|
|
TaxEnabled bool `gorm:"not null;default:false" json:"tax_enabled"`
|
|
TaxRateBPS int64 `gorm:"not null;default:100" json:"tax_rate_bps"`
|
|
SettlementHoldDays int `gorm:"not null;default:7" json:"settlement_hold_days"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
}
|
|
|
|
func (DistributionSite) TableName() string { return "distribution_sites" }
|
|
|
|
// DistributionSiteMember 将现有后台管理员映射到分销网站。
|
|
type DistributionSiteMember struct {
|
|
ID uint64 `gorm:"primaryKey" json:"id"`
|
|
SiteID uint64 `gorm:"not null;uniqueIndex:uk_distribution_site_member;index" json:"site_id"`
|
|
AdminUserID uint64 `gorm:"not null;uniqueIndex:uk_distribution_site_member;index" json:"admin_user_id"`
|
|
MemberType string `gorm:"size:32;not null" json:"member_type"`
|
|
Status string `gorm:"size:16;not null;default:'active';index" json:"status"`
|
|
DataScope string `gorm:"size:32;not null;default:'site'" json:"data_scope"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
}
|
|
|
|
func (DistributionSiteMember) TableName() string { return "distribution_site_members" }
|
|
|
|
// DistributionSiteAccount 控制账号在分销网站的展示状态。
|
|
type DistributionSiteAccount struct {
|
|
ID uint64 `gorm:"primaryKey" json:"id"`
|
|
SiteID uint64 `gorm:"not null;uniqueIndex:uk_distribution_site_account;index" json:"site_id"`
|
|
AccountID uint64 `gorm:"not null;uniqueIndex:uk_distribution_site_account;index" json:"account_id"`
|
|
ListingID uint64 `gorm:"not null;index" json:"listing_id"`
|
|
DisplayStatus string `gorm:"size:16;not null;default:'enabled';index" json:"display_status"`
|
|
// DisplayDisabledBy 记录下架来源:operator=站长人工下架,system=系统自动下架,空=展示中或历史数据。
|
|
// 自动铺货只会恢复 system/空 来源的下架行,人工下架保持不动。
|
|
DisplayDisabledBy string `gorm:"size:16;not null;default:''" json:"display_disabled_by"`
|
|
MarkupAmountCent int64 `gorm:"not null;default:0" json:"markup_amount_cent"`
|
|
ShelfRatioDelta float64 `gorm:"type:decimal(10,2);not null;default:0" json:"shelf_ratio_delta"`
|
|
DisplayStartedAt *time.Time `json:"display_started_at,omitempty"`
|
|
DisplayEndedAt *time.Time `json:"display_ended_at,omitempty"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
}
|
|
|
|
func (DistributionSiteAccount) TableName() string { return "distribution_site_accounts" }
|
|
|
|
// DistributionRuleVersion 是新订单使用的分账规则快照来源。
|
|
type DistributionRuleVersion struct {
|
|
ID uint64 `gorm:"primaryKey" json:"id"`
|
|
SiteID *uint64 `gorm:"index" json:"site_id,omitempty"`
|
|
Mode string `gorm:"size:32;not null;index" json:"mode"`
|
|
Version int `gorm:"not null" json:"version"`
|
|
Status string `gorm:"size:16;not null;default:'draft';index" json:"status"`
|
|
PlatformReceiveRatio float64 `gorm:"type:decimal(10,2);not null;default:0" json:"platform_receive_ratio"`
|
|
PlatformSellRatio float64 `gorm:"type:decimal(10,2);not null;default:0" json:"platform_sell_ratio"`
|
|
DistributorReceiveRatio float64 `gorm:"type:decimal(10,2);not null;default:0" json:"distributor_receive_ratio"`
|
|
DistributorSellRatio float64 `gorm:"type:decimal(10,2);not null;default:0" json:"distributor_sell_ratio"`
|
|
DistributorARatio float64 `gorm:"type:decimal(10,2);not null;default:0" json:"distributor_a_ratio"`
|
|
DistributorBRatio float64 `gorm:"type:decimal(10,2);not null;default:0" json:"distributor_b_ratio"`
|
|
ServiceFeeValue float64 `gorm:"type:decimal(12,4);not null;default:0" json:"service_fee_value"`
|
|
ServiceFeeUnit string `gorm:"size:24;not null;default:'percent'" json:"service_fee_unit"`
|
|
PaymentFeeBPS int64 `gorm:"not null;default:50" json:"payment_fee_bps"`
|
|
TaxEnabled bool `gorm:"not null;default:false" json:"tax_enabled"`
|
|
TaxRateBPS int64 `gorm:"not null;default:100" json:"tax_rate_bps"`
|
|
EffectiveFrom time.Time `gorm:"index" json:"effective_from"`
|
|
EffectiveTo *time.Time `gorm:"index" json:"effective_to,omitempty"`
|
|
CreatedBy *uint64 `json:"created_by,omitempty"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
}
|
|
|
|
func (DistributionRuleVersion) TableName() string { return "distribution_rule_versions" }
|
|
|
|
// DistributionOrderFinancial 保存正常订单的分销财务快照。
|
|
type DistributionOrderFinancial struct {
|
|
ID uint64 `gorm:"primaryKey" json:"id"`
|
|
OrderID uint64 `gorm:"not null;uniqueIndex" json:"order_id"`
|
|
SiteID uint64 `gorm:"not null;index" json:"site_id"`
|
|
RuleVersionID uint64 `gorm:"not null" json:"rule_version_id"`
|
|
GrossPaidAmountCent int64 `gorm:"not null;default:0" json:"gross_paid_amount_cent"`
|
|
RefundAmountCent int64 `gorm:"not null;default:0" json:"refund_amount_cent"`
|
|
NetPaidAmountCent int64 `gorm:"not null;default:0" json:"net_paid_amount_cent"`
|
|
PaymentFeeBPS int64 `gorm:"not null;default:50" json:"payment_fee_bps"`
|
|
PaymentFeeCent int64 `gorm:"not null;default:0" json:"payment_fee_cent"`
|
|
ServiceFeeValue float64 `gorm:"type:decimal(12,4);not null;default:0" json:"service_fee_value"`
|
|
ServiceFeeUnit string `gorm:"size:24;not null;default:'percent'" json:"service_fee_unit"`
|
|
ServiceFeeCent int64 `gorm:"not null;default:0" json:"service_fee_cent"`
|
|
MarkupAmountCent int64 `gorm:"not null;default:0" json:"markup_amount_cent"`
|
|
TaxEnabled bool `gorm:"not null;default:false" json:"tax_enabled"`
|
|
TaxRateBPS int64 `gorm:"not null;default:100" json:"tax_rate_bps"`
|
|
TaxAmountCent int64 `gorm:"not null;default:0" json:"tax_amount_cent"`
|
|
SplitBaseAmountCent int64 `gorm:"not null;default:0" json:"split_base_amount_cent"`
|
|
RoundingAdjustmentCent int64 `gorm:"not null;default:0" json:"rounding_adjustment_cent"`
|
|
SettlementStatus string `gorm:"size:24;not null;default:'pending';index" json:"settlement_status"`
|
|
ReleaseAt *time.Time `gorm:"index:idx_distribution_financial_release,priority:2" json:"release_at,omitempty"`
|
|
ReleasedAt *time.Time `json:"released_at,omitempty"`
|
|
SettledAt *time.Time `json:"settled_at,omitempty"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
}
|
|
|
|
func (DistributionOrderFinancial) TableName() string { return "distribution_order_financials" }
|
|
|
|
// DistributionOrderParty 保存订单创建时的参与方和金额快照,避免规则或站点变更影响历史订单。
|
|
type DistributionOrderParty struct {
|
|
ID uint64 `gorm:"primaryKey" json:"id"`
|
|
OrderID uint64 `gorm:"not null;index" json:"order_id"`
|
|
SiteID uint64 `gorm:"not null;index" json:"site_id"`
|
|
PartyRole string `gorm:"size:32;not null;index" json:"party_role"`
|
|
PartyType string `gorm:"size:16;not null" json:"party_type"`
|
|
PartyID uint64 `gorm:"not null" json:"party_id"`
|
|
Ratio float64 `gorm:"type:decimal(10,2);not null;default:0" json:"ratio"`
|
|
IncomeAmountCent int64 `gorm:"not null;default:0" json:"income_amount_cent"`
|
|
CostAmountCent int64 `gorm:"not null;default:0" json:"cost_amount_cent"`
|
|
ProfitAmountCent int64 `gorm:"not null;default:0" json:"profit_amount_cent"`
|
|
TaxAmountCent int64 `gorm:"not null;default:0" json:"tax_amount_cent"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
}
|
|
|
|
func (DistributionOrderParty) TableName() string { return "distribution_order_parties" }
|
|
|
|
// DistributionSettlementBatch 是按站点生成的结算批次。
|
|
type DistributionSettlementBatch struct {
|
|
ID uint64 `gorm:"primaryKey" json:"id"`
|
|
SiteID uint64 `gorm:"not null;index" json:"site_id"`
|
|
BatchNo string `gorm:"size:64;not null;uniqueIndex" json:"batch_no"`
|
|
PeriodStart time.Time `gorm:"not null" json:"period_start"`
|
|
PeriodEnd time.Time `gorm:"not null" json:"period_end"`
|
|
TotalAmountCent int64 `gorm:"not null;default:0" json:"total_amount_cent"`
|
|
Status string `gorm:"size:16;not null;default:'draft';index" json:"status"`
|
|
CreatedBy *uint64 `json:"created_by,omitempty"`
|
|
SettledAt *time.Time `json:"settled_at,omitempty"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
}
|
|
|
|
func (DistributionSettlementBatch) TableName() string { return "distribution_settlement_batches" }
|
|
|
|
type DistributionSettlementItem struct {
|
|
ID uint64 `gorm:"primaryKey" json:"id"`
|
|
BatchID uint64 `gorm:"not null;index" json:"batch_id"`
|
|
OrderID uint64 `gorm:"not null;index" json:"order_id"`
|
|
PartyID uint64 `gorm:"not null;index" json:"party_id"`
|
|
AmountCent int64 `gorm:"not null;default:0" json:"amount_cent"`
|
|
Status string `gorm:"size:16;not null;default:'pending'" json:"status"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
}
|
|
|
|
func (DistributionSettlementItem) TableName() string { return "distribution_settlement_items" }
|
|
|
|
// DistributionSitePaymentChannel 将一个或多个现有支付商户配置绑定到分销站点。
|
|
type DistributionSitePaymentChannel struct {
|
|
ID uint64 `gorm:"primaryKey" json:"id"`
|
|
SiteID uint64 `gorm:"not null;uniqueIndex:uk_distribution_site_payment;index" json:"site_id"`
|
|
ConfigID uint64 `gorm:"not null;uniqueIndex:uk_distribution_site_payment;index" json:"config_id"`
|
|
Priority int `gorm:"not null;default:0" json:"priority"`
|
|
Status string `gorm:"size:16;not null;default:'active';index" json:"status"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
}
|
|
|
|
func (DistributionSitePaymentChannel) TableName() string { return "distribution_site_payment_channels" }
|