refactor(distribution): 重写分销迁移并落地利润百分比分成与货架比例

将 000064-000078 合并为 064/065/066,默认规则改为收号 35%、卖出 40%、服务费 25%。
货架调价改为增加分站 1 元兑换哈夫币比例。sql-guard 仅保护 main 已发布迁移。
This commit is contained in:
yml2213
2026-09-08 19:02:58 +08:00
parent 48a2961245
commit d762b33f54
48 changed files with 745 additions and 1073 deletions
@@ -259,10 +259,10 @@ func TestSnapshotPaidOrderTxAndApplyRefundTx(t *testing.T) {
Mode: ModeTwoPartyDistributorReceive,
Version: 1,
Status: "active",
DistributorReceiveRatio: 3.5,
PlatformSellRatio: 4.0,
ServiceFeeValue: 2.5,
ServiceFeeUnit: ServiceFeeUnitFixedAmount,
DistributorReceiveRatio: 35,
PlatformSellRatio: 40,
ServiceFeeValue: 25,
ServiceFeeUnit: ServiceFeeUnitPercent,
PaymentFeeBPS: 50,
TaxEnabled: true,
TaxRateBPS: 100,
@@ -279,8 +279,9 @@ func TestSnapshotPaidOrderTxAndApplyRefundTx(t *testing.T) {
OwnerID: 1,
RenterID: 2,
Status: "renting",
PlatformFeeCent: 999,
ShelfMarkupCent: 300,
RentAmountCent: 10000,
OwnerRentAmountCent: 6000,
PlatformFeeCent: 4000,
DistributionSiteID: &site.ID,
DistributionRuleVersionID: &rule.ID,
}
@@ -301,18 +302,18 @@ func TestSnapshotPaidOrderTxAndApplyRefundTx(t *testing.T) {
if financial.GrossPaidAmountCent != grossPaid || financial.SiteID != site.ID {
t.Fatalf("unexpected financial snapshot: %+v", financial)
}
if financial.MarkupAmountCent != 300 {
t.Fatalf("markup must come from shelf snapshot, got %d", financial.MarkupAmountCent)
if financial.SplitBaseAmountCent != 3950 || financial.ServiceFeeCent != 988 {
t.Fatalf("profit snapshot = %+v", financial)
}
var parties []model.DistributionOrderParty
if err := db.Where("order_id = ?", order.ID).Order("id ASC").Find(&parties).Error; err != nil || len(parties) != 2 {
t.Fatalf("unexpected parties count: len=%d, err=%v", len(parties), err)
}
if parties[0].PartyRole != "distributor_receive" || parties[0].PartyType != PartyTypeSite || parties[0].PartyID != site.ID || parties[0].IncomeAmountCent != 340 {
if parties[0].PartyRole != "distributor_receive" || parties[0].PartyType != PartyTypeSite || parties[0].PartyID != site.ID || parties[0].IncomeAmountCent != 1383 {
t.Fatalf("distributor party = %+v", parties[0])
}
if parties[1].PartyRole != "platform_sell" || parties[1].PartyType != PartyTypePlatform || parties[1].PartyID != 0 || parties[1].IncomeAmountCent != 688 {
if parties[1].PartyRole != "platform_sell" || parties[1].PartyType != PartyTypePlatform || parties[1].PartyID != 0 || parties[1].IncomeAmountCent != 1580 {
t.Fatalf("platform party = %+v", parties[1])
}
@@ -330,10 +331,6 @@ func TestSnapshotPaidOrderTxAndApplyRefundTx(t *testing.T) {
if err := ApplyRefundTx(db, order.ID, -10); err != ErrInvalidAmount {
t.Fatalf("expected ErrInvalidAmount for negative refund, got %v", err)
}
if err := ApplyRefundTx(db, order.ID, grossPaid+100); err != ErrInvalidAmount {
t.Fatalf("expected ErrInvalidAmount for excessive refund, got %v", err)
}
// 合法退款
refundAmount := int64(2000)
if err := ApplyRefundTx(db, order.ID, refundAmount); err != nil {
@@ -352,7 +349,7 @@ func TestSnapshotPaidOrderTxAndApplyRefundTx(t *testing.T) {
}
}
func TestSnapshotPaidOrderTxAddsShelfMarkupToSeller(t *testing.T) {
func TestSnapshotPaidOrderTxSplitsPercentOfProfit(t *testing.T) {
db := distributionTestDB(t)
now := time.Now()
site := model.DistributionSite{SiteCode: "sell_markup", SiteName: "卖出加价站", Domain: "sell-markup.dist.com", Status: "active", DisplayAccountEnabled: true}
@@ -361,8 +358,8 @@ func TestSnapshotPaidOrderTxAddsShelfMarkupToSeller(t *testing.T) {
}
rule := model.DistributionRuleVersion{
SiteID: &site.ID, Mode: ModeTwoPartyPlatformReceive, Version: 1, Status: "active",
PlatformReceiveRatio: 3.5, DistributorSellRatio: 4,
ServiceFeeValue: 0, ServiceFeeUnit: ServiceFeeUnitFixedAmount, PaymentFeeBPS: 50,
PlatformReceiveRatio: 35, DistributorSellRatio: 40,
ServiceFeeValue: 25, ServiceFeeUnit: ServiceFeeUnitPercent, PaymentFeeBPS: 50,
EffectiveFrom: now.Add(-time.Hour),
}
if err := db.Create(&rule).Error; err != nil {
@@ -370,7 +367,7 @@ func TestSnapshotPaidOrderTxAddsShelfMarkupToSeller(t *testing.T) {
}
order := model.RentalOrder{
OrderNo: "ORD-MARKUP-SELL", ListingID: 1, AccountID: 2, OwnerID: 3, RenterID: 4, Status: "renting",
PlatformFeeCent: 2000, ShelfMarkupCent: 10000,
RentAmountCent: 10000, OwnerRentAmountCent: 6000, PlatformFeeCent: 4000,
DistributionSiteID: &site.ID, DistributionRuleVersionID: &rule.ID, DistributionMode: ModeTwoPartyPlatformReceive,
}
if err := db.Create(&order).Error; err != nil {
@@ -395,20 +392,10 @@ func TestSnapshotPaidOrderTxAddsShelfMarkupToSeller(t *testing.T) {
if seller == nil || platform == nil {
t.Fatalf("missing parties: %+v", parties)
}
if seller.IncomeAmountCent < 10000 {
t.Fatalf("seller split must include 10000 markup, got %d", seller.IncomeAmountCent)
if seller.IncomeAmountCent != 1580 {
t.Fatalf("seller 40%% of profit = %d, want 1580", seller.IncomeAmountCent)
}
if platform.PartyID != 0 {
t.Fatalf("platform party_id = %d, want 0", platform.PartyID)
}
if err := db.Model(&order).Update("shelf_markup_cent", 0).Error; err != nil {
t.Fatal(err)
}
var financial model.DistributionOrderFinancial
if err := db.Where("order_id = ?", order.ID).First(&financial).Error; err != nil {
t.Fatal(err)
}
if financial.MarkupAmountCent != 10000 {
t.Fatalf("historical snapshot must keep markup, got %d", financial.MarkupAmountCent)
if platform.IncomeAmountCent != 1383 || platform.PartyID != 0 {
t.Fatalf("platform receive = %+v", platform)
}
}