fix(distribution): 分站挂牌的号主收入记入对应分站钱包
结账和仲裁不再把分销站号主收入写入主站钱包,用户列表也只展示主站余额。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -58,7 +58,7 @@ func (r *Repository) List(ctx context.Context, page, pageSize int, query ListQue
|
|||||||
Joins("LEFT JOIN (SELECT owner_id AS user_id, COUNT(*) AS listing_count FROM rental_listings GROUP BY owner_id) AS l ON l.user_id = u.id").
|
Joins("LEFT JOIN (SELECT owner_id AS user_id, COUNT(*) AS listing_count FROM rental_listings GROUP BY owner_id) AS l ON l.user_id = u.id").
|
||||||
Joins("LEFT JOIN (SELECT user_id, COUNT(*) AS dispute_count FROM (SELECT initiator_id AS user_id FROM disputes UNION ALL SELECT target_user_id AS user_id FROM disputes) AS dispute_users GROUP BY user_id) AS d ON d.user_id = u.id").
|
Joins("LEFT JOIN (SELECT user_id, COUNT(*) AS dispute_count FROM (SELECT initiator_id AS user_id FROM disputes UNION ALL SELECT target_user_id AS user_id FROM disputes) AS dispute_users GROUP BY user_id) AS d ON d.user_id = u.id").
|
||||||
Joins("LEFT JOIN (SELECT renter_id AS user_id, SUM(deposit_waived_amount_cent) AS deposit_free_used_cent FROM rental_orders WHERE status NOT IN ('completed', 'cancelled', 'closed') GROUP BY renter_id) AS df ON df.user_id = u.id").
|
Joins("LEFT JOIN (SELECT renter_id AS user_id, SUM(deposit_waived_amount_cent) AS deposit_free_used_cent FROM rental_orders WHERE status NOT IN ('completed', 'cancelled', 'closed') GROUP BY renter_id) AS df ON df.user_id = u.id").
|
||||||
Joins("LEFT JOIN wallet_accounts AS w ON w.user_id = u.id")
|
Joins("LEFT JOIN wallet_accounts AS w ON w.user_id = u.id AND w.distribution_site_id = 0")
|
||||||
listTx = applyUserFilter(listTx, query, growthConfig)
|
listTx = applyUserFilter(listTx, query, growthConfig)
|
||||||
err = listTx.
|
err = listTx.
|
||||||
Order("u.id DESC").
|
Order("u.id DESC").
|
||||||
@@ -397,7 +397,7 @@ func (r *Repository) Find(ctx context.Context, userID uint64) (*UserDTO, error)
|
|||||||
Joins("LEFT JOIN (SELECT owner_id AS user_id, COUNT(*) AS listing_count FROM rental_listings GROUP BY owner_id) AS l ON l.user_id = u.id").
|
Joins("LEFT JOIN (SELECT owner_id AS user_id, COUNT(*) AS listing_count FROM rental_listings GROUP BY owner_id) AS l ON l.user_id = u.id").
|
||||||
Joins("LEFT JOIN (SELECT user_id, COUNT(*) AS dispute_count FROM (SELECT initiator_id AS user_id FROM disputes UNION ALL SELECT target_user_id AS user_id FROM disputes) AS dispute_users GROUP BY user_id) AS d ON d.user_id = u.id").
|
Joins("LEFT JOIN (SELECT user_id, COUNT(*) AS dispute_count FROM (SELECT initiator_id AS user_id FROM disputes UNION ALL SELECT target_user_id AS user_id FROM disputes) AS dispute_users GROUP BY user_id) AS d ON d.user_id = u.id").
|
||||||
Joins("LEFT JOIN (SELECT renter_id AS user_id, SUM(deposit_waived_amount_cent) AS deposit_free_used_cent FROM rental_orders WHERE status NOT IN ('completed', 'cancelled', 'closed') GROUP BY renter_id) AS df ON df.user_id = u.id").
|
Joins("LEFT JOIN (SELECT renter_id AS user_id, SUM(deposit_waived_amount_cent) AS deposit_free_used_cent FROM rental_orders WHERE status NOT IN ('completed', 'cancelled', 'closed') GROUP BY renter_id) AS df ON df.user_id = u.id").
|
||||||
Joins("LEFT JOIN wallet_accounts AS w ON w.user_id = u.id").
|
Joins("LEFT JOIN wallet_accounts AS w ON w.user_id = u.id AND w.distribution_site_id = 0").
|
||||||
Where("u.id = ?", userID).
|
Where("u.id = ?", userID).
|
||||||
First(&row).Error
|
First(&row).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -99,6 +99,7 @@ func (r *Repository) Arbitrate(ctx context.Context, adminID uint64, id uint64, r
|
|||||||
); err != nil {
|
); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
stampOwnerIncomeSite(&settlement, &listing)
|
||||||
if err := wallet.AppendEntries(tx, settlement.Entries...); err != nil {
|
if err := wallet.AppendEntries(tx, settlement.Entries...); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -442,6 +443,22 @@ func newArbitrationSettlement(order model.RentalOrder, renterFrozenBalanceCent i
|
|||||||
return settlement
|
return settlement
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func stampOwnerIncomeSite(settlement *arbitrationSettlement, listing *model.RentalListing) {
|
||||||
|
if settlement == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
siteID := uint64(0)
|
||||||
|
if listing != nil && listing.DistributionSiteID != nil {
|
||||||
|
siteID = *listing.DistributionSiteID
|
||||||
|
}
|
||||||
|
for i := range settlement.Entries {
|
||||||
|
entry := &settlement.Entries[i]
|
||||||
|
if entry.Direction == "in" && entry.BalanceType == "available" && entry.BizType == "arbitration_owner_income" {
|
||||||
|
entry.DistributionSiteID = siteID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (settlement *arbitrationSettlement) addOwnerIncome(order model.RentalOrder, amountCent int64, remark string) {
|
func (settlement *arbitrationSettlement) addOwnerIncome(order model.RentalOrder, amountCent int64, remark string) {
|
||||||
if settlement == nil || amountCent <= 0 {
|
if settlement == nil || amountCent <= 0 {
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
|
|
||||||
"hfb_sys/backend/internal/database"
|
"hfb_sys/backend/internal/database"
|
||||||
"hfb_sys/backend/internal/model"
|
"hfb_sys/backend/internal/model"
|
||||||
|
"hfb_sys/backend/internal/modules/wallet"
|
||||||
|
|
||||||
"gorm.io/datatypes"
|
"gorm.io/datatypes"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
@@ -753,3 +754,19 @@ func TestApplyAdminListFiltersSmartRouting(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestStampOwnerIncomeSiteUsesListingSite(t *testing.T) {
|
||||||
|
siteID := uint64(3)
|
||||||
|
orderID := uint64(9)
|
||||||
|
settlement := arbitrationSettlement{Entries: []wallet.Entry{
|
||||||
|
{UserID: 1, OrderID: &orderID, Direction: "in", AmountCent: 100, BalanceType: "available", BizType: "arbitration_owner_income"},
|
||||||
|
{UserID: 2, OrderID: &orderID, Direction: "out", AmountCent: 50, BalanceType: "frozen", BizType: "arbitration_release_frozen"},
|
||||||
|
}}
|
||||||
|
stampOwnerIncomeSite(&settlement, &model.RentalListing{DistributionSiteID: &siteID})
|
||||||
|
if settlement.Entries[0].DistributionSiteID != 3 {
|
||||||
|
t.Fatalf("号主入账站点 = %d, want 3", settlement.Entries[0].DistributionSiteID)
|
||||||
|
}
|
||||||
|
if settlement.Entries[1].DistributionSiteID != 0 {
|
||||||
|
t.Fatalf("租客解冻站点 = %d, want 0", settlement.Entries[1].DistributionSiteID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ func (r *Repository) finalizeCheckout(tx *gorm.DB, order *model.RentalOrder, che
|
|||||||
if settlement.ShortfallCent > 0 {
|
if settlement.ShortfallCent > 0 {
|
||||||
return nil, ErrCheckoutDepositShortfall
|
return nil, ErrCheckoutDepositShortfall
|
||||||
}
|
}
|
||||||
if err := appendCheckoutOwnerIncome(tx, order, settlement); err != nil {
|
if err := appendCheckoutOwnerIncome(tx, order, listing, settlement); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
refund, err := r.prepareCheckoutRefund(order, settlement)
|
refund, err := r.prepareCheckoutRefund(order, settlement)
|
||||||
@@ -65,7 +65,14 @@ func (r *Repository) finalizeCheckout(tx *gorm.DB, order *model.RentalOrder, che
|
|||||||
return refund, nil
|
return refund, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func appendCheckoutOwnerIncome(tx *gorm.DB, order *model.RentalOrder, settlement checkoutSettlement) error {
|
func ownerWalletSiteID(listing *model.RentalListing) uint64 {
|
||||||
|
if listing != nil && listing.DistributionSiteID != nil {
|
||||||
|
return *listing.DistributionSiteID
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func appendCheckoutOwnerIncome(tx *gorm.DB, order *model.RentalOrder, listing *model.RentalListing, settlement checkoutSettlement) error {
|
||||||
if isPlatformSettlementOrder(*order) {
|
if isPlatformSettlementOrder(*order) {
|
||||||
amountCent := settlement.OwnerRentIncomeCent + settlement.DepositCompensationCent
|
amountCent := settlement.OwnerRentIncomeCent + settlement.DepositCompensationCent
|
||||||
order.OfflineSettlementAmountCent = amountCent
|
order.OfflineSettlementAmountCent = amountCent
|
||||||
@@ -77,11 +84,12 @@ func appendCheckoutOwnerIncome(tx *gorm.DB, order *model.RentalOrder, settlement
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
orderID := order.ID
|
orderID := order.ID
|
||||||
|
siteID := ownerWalletSiteID(listing)
|
||||||
var ownerEntries []wallet.Entry
|
var ownerEntries []wallet.Entry
|
||||||
if settlement.OwnerRentIncomeCent > 0 {
|
if settlement.OwnerRentIncomeCent > 0 {
|
||||||
ownerEntries = append(ownerEntries, wallet.Entry{
|
ownerEntries = append(ownerEntries, wallet.Entry{
|
||||||
UserID: order.OwnerID,
|
UserID: order.OwnerID,
|
||||||
DistributionSiteID: 0,
|
DistributionSiteID: siteID,
|
||||||
OrderID: &orderID,
|
OrderID: &orderID,
|
||||||
Direction: "in",
|
Direction: "in",
|
||||||
AmountCent: settlement.OwnerRentIncomeCent,
|
AmountCent: settlement.OwnerRentIncomeCent,
|
||||||
@@ -94,7 +102,7 @@ func appendCheckoutOwnerIncome(tx *gorm.DB, order *model.RentalOrder, settlement
|
|||||||
if settlement.DepositCompensationCent > 0 {
|
if settlement.DepositCompensationCent > 0 {
|
||||||
ownerEntries = append(ownerEntries, wallet.Entry{
|
ownerEntries = append(ownerEntries, wallet.Entry{
|
||||||
UserID: order.OwnerID,
|
UserID: order.OwnerID,
|
||||||
DistributionSiteID: 0,
|
DistributionSiteID: siteID,
|
||||||
OrderID: &orderID,
|
OrderID: &orderID,
|
||||||
Direction: "in",
|
Direction: "in",
|
||||||
AmountCent: settlement.DepositCompensationCent,
|
AmountCent: settlement.DepositCompensationCent,
|
||||||
|
|||||||
@@ -694,3 +694,16 @@ func TestApplyCheckoutPriceView_RoleIsolationAndPlatformFeeHidden(t *testing.T)
|
|||||||
t.Fatalf("租客视角必须展示 RenterRefundAmountCent, 实际为: %v", renterDTO.RenterRefundAmountCent)
|
t.Fatalf("租客视角必须展示 RenterRefundAmountCent, 实际为: %v", renterDTO.RenterRefundAmountCent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestOwnerWalletSiteIDFollowsListingSite(t *testing.T) {
|
||||||
|
if got := ownerWalletSiteID(nil); got != 0 {
|
||||||
|
t.Fatalf("空挂牌站点 = %d, want 0", got)
|
||||||
|
}
|
||||||
|
if got := ownerWalletSiteID(&model.RentalListing{}); got != 0 {
|
||||||
|
t.Fatalf("主站挂牌站点 = %d, want 0", got)
|
||||||
|
}
|
||||||
|
siteID := uint64(3)
|
||||||
|
if got := ownerWalletSiteID(&model.RentalListing{DistributionSiteID: &siteID}); got != 3 {
|
||||||
|
t.Fatalf("分站挂牌站点 = %d, want 3", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user