feat(distribution): 补齐退款加价回退、本站自卖与开通默认规则

退款时压缩卖方加价,人工/自动批次仅完结单可入账,号主收入进主站钱包;仲裁后重算释放并支持作废未入账 DS。开通时四种模式按默认生效,对外口径合并为 35/40/25,不再单独展示通道费。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
yml2213
2026-09-10 18:13:46 +08:00
co-authored by Cursor
parent e621722218
commit 768902f2f7
28 changed files with 627 additions and 263 deletions
@@ -206,8 +206,8 @@ func SnapshotPaidOrderTx(tx *gorm.DB, orderID uint64, grossPaidCent int64) error
if err != nil {
return err
}
splits := SplitSettlement(ruleFromVersion(rule), result.SplitBaseAmountCent, markup)
financial := model.DistributionOrderFinancial{OrderID: order.ID, SiteID: *order.DistributionSiteID, RuleVersionID: rule.ID, GrossPaidAmountCent: grossRent, NetPaidAmountCent: result.NetPaidAmountCent, PaymentFeeBPS: rule.PaymentFeeBPS, PaymentFeeCent: result.PaymentFeeCent, ServiceFeeValue: rule.ServiceFeeValue, ServiceFeeUnit: rule.ServiceFeeUnit, ServiceFeeCent: result.ServiceFeeCent, MarkupAmountCent: markup, TaxEnabled: rule.TaxEnabled, TaxRateBPS: rule.TaxRateBPS, TaxAmountCent: result.TaxAmountCent, SplitBaseAmountCent: result.SplitBaseAmountCent, RoundingAdjustmentCent: SplitRoundingCent(result.SplitBaseAmountCent, result.ServiceFeeCent, markup, splits), SettlementStatus: "pending"}
splits := SplitSettlement(ruleFromVersion(rule), result.SplitBaseAmountCent, result.MarkupAmountCent)
financial := model.DistributionOrderFinancial{OrderID: order.ID, SiteID: *order.DistributionSiteID, RuleVersionID: rule.ID, GrossPaidAmountCent: grossRent, NetPaidAmountCent: result.NetPaidAmountCent, PaymentFeeBPS: rule.PaymentFeeBPS, PaymentFeeCent: result.PaymentFeeCent, ServiceFeeValue: rule.ServiceFeeValue, ServiceFeeUnit: rule.ServiceFeeUnit, ServiceFeeCent: result.ServiceFeeCent, MarkupAmountCent: markup, TaxEnabled: rule.TaxEnabled, TaxRateBPS: rule.TaxRateBPS, TaxAmountCent: result.TaxAmountCent, SplitBaseAmountCent: result.SplitBaseAmountCent, RoundingAdjustmentCent: SplitRoundingCent(result.SplitBaseAmountCent, result.ServiceFeeCent, result.MarkupAmountCent, splits), SettlementStatus: "pending"}
// 支付回调可能重复触发:保留已写入的释放与结算时间,避免把已释放的快照重置回待释放。
var existing model.DistributionOrderFinancial
if err := tx.Where("order_id = ?", order.ID).First(&existing).Error; err == nil {
@@ -336,7 +336,7 @@ func ApplyRefundTx(tx *gorm.DB, orderID uint64, refundAmountCent int64) error {
if err != nil {
return err
}
splits := SplitSettlement(ruleFromVersion(rule), result.SplitBaseAmountCent, financial.MarkupAmountCent)
splits := SplitSettlement(ruleFromVersion(rule), result.SplitBaseAmountCent, result.MarkupAmountCent)
// 已释放入账的订单保持 settled,避免自动释放任务重复入账;差额通过回冲流水追偿。
settlementStatus := "pending"
if financial.ReleasedAt != nil {
@@ -352,7 +352,7 @@ func ApplyRefundTx(tx *gorm.DB, orderID uint64, refundAmountCent int64) error {
"payment_fee_cent": result.PaymentFeeCent,
"service_fee_cent": result.ServiceFeeCent,
"split_base_amount_cent": result.SplitBaseAmountCent,
"rounding_adjustment_cent": SplitRoundingCent(result.SplitBaseAmountCent, result.ServiceFeeCent, financial.MarkupAmountCent, splits),
"rounding_adjustment_cent": SplitRoundingCent(result.SplitBaseAmountCent, result.ServiceFeeCent, result.MarkupAmountCent, splits),
"settlement_status": settlementStatus,
"release_at": releaseAt,
}).Error; err != nil {
@@ -433,7 +433,7 @@ func computeReleaseAt(tx *gorm.DB, order model.RentalOrder, financial model.Dist
if financial.ReleasedAt != nil {
return financial.ReleaseAt, nil
}
if order.Status != "completed" {
if !orderStatusAllowsRelease(order.Status) {
return financial.ReleaseAt, nil
}
completedAt := order.SettledAt
@@ -464,7 +464,7 @@ func rewritePendingReleaseAt(tx *gorm.DB, siteID uint64) error {
}
return err
}
if order.Status != "completed" {
if !orderStatusAllowsRelease(order.Status) {
continue
}
releaseAt, err := computeReleaseAt(tx, order, financial)
@@ -479,6 +479,10 @@ func rewritePendingReleaseAt(tx *gorm.DB, siteID uint64) error {
return nil
}
func orderStatusAllowsRelease(status string) bool {
return status == "completed" || status == "closed"
}
// partySettled 判断参与方份额是否已经通过结算批次入账。
func partySettled(tx *gorm.DB, partyID uint64) (bool, error) {
var count int64