fix(order): 修复分销收号商品在主站租用后报订单不存在的问题
This commit is contained in:
@@ -51,11 +51,11 @@ func (r *Repository) ListConversations(ctx context.Context, principal Principal,
|
||||
|
||||
if principal.Type == "user" {
|
||||
if site != nil {
|
||||
siteFilter := "(c.distribution_site_id = ? OR (c.order_id IS NOT NULL AND c.order_id IN (SELECT ro.id FROM rental_orders ro WHERE ro.distribution_site_id = ?)))"
|
||||
siteFilter := "(c.distribution_site_id = ? OR (c.order_id IS NOT NULL AND c.order_id IN (SELECT ro.id FROM rental_orders ro WHERE ro.distribution_site_id = ? AND ro.distribution_mode != 'two_party_distributor_receive')))"
|
||||
countDB = countDB.Where(siteFilter, site.ID, site.ID)
|
||||
dataQuery = dataQuery.Where(siteFilter, site.ID, site.ID)
|
||||
} else {
|
||||
mainFilter := "(c.distribution_site_id IS NULL OR c.distribution_site_id = 0) AND (c.order_id IS NULL OR c.order_id NOT IN (SELECT ro.id FROM rental_orders ro WHERE ro.distribution_site_id IS NOT NULL AND ro.distribution_site_id > 0))"
|
||||
mainFilter := "(c.distribution_site_id IS NULL OR c.distribution_site_id = 0) AND (c.order_id IS NULL OR c.order_id NOT IN (SELECT ro.id FROM rental_orders ro WHERE ro.distribution_site_id IS NOT NULL AND ro.distribution_site_id > 0 AND ro.distribution_mode != 'two_party_distributor_receive'))"
|
||||
countDB = countDB.Where(mainFilter)
|
||||
dataQuery = dataQuery.Where(mainFilter)
|
||||
}
|
||||
|
||||
@@ -76,10 +76,10 @@ func (r *Repository) CountUnreadMessages(ctx context.Context, principal Principa
|
||||
|
||||
if principal.Type == "user" {
|
||||
if site != nil {
|
||||
siteFilter := "(c.distribution_site_id = ? OR (c.order_id IS NOT NULL AND c.order_id IN (SELECT ro.id FROM rental_orders ro WHERE ro.distribution_site_id = ?)))"
|
||||
siteFilter := "(c.distribution_site_id = ? OR (c.order_id IS NOT NULL AND c.order_id IN (SELECT ro.id FROM rental_orders ro WHERE ro.distribution_site_id = ? AND ro.distribution_mode != 'two_party_distributor_receive')))"
|
||||
query = query.Where(siteFilter, site.ID, site.ID)
|
||||
} else {
|
||||
mainFilter := "(c.distribution_site_id IS NULL OR c.distribution_site_id = 0) AND (c.order_id IS NULL OR c.order_id NOT IN (SELECT ro.id FROM rental_orders ro WHERE ro.distribution_site_id IS NOT NULL AND ro.distribution_site_id > 0))"
|
||||
mainFilter := "(c.distribution_site_id IS NULL OR c.distribution_site_id = 0) AND (c.order_id IS NULL OR c.order_id NOT IN (SELECT ro.id FROM rental_orders ro WHERE ro.distribution_site_id IS NOT NULL AND ro.distribution_site_id > 0 AND ro.distribution_mode != 'two_party_distributor_receive'))"
|
||||
query = query.Where(mainFilter)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,10 +87,14 @@ func EnsureOrderConversation(tx *gorm.DB, order model.RentalOrder) (*model.ChatC
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var siteID *uint64
|
||||
if order.DistributionSiteID != nil && *order.DistributionSiteID > 0 && order.DistributionMode != "two_party_distributor_receive" {
|
||||
siteID = order.DistributionSiteID
|
||||
}
|
||||
now := time.Now()
|
||||
conversation := model.ChatConversation{
|
||||
OrderID: &order.ID,
|
||||
DistributionSiteID: order.DistributionSiteID,
|
||||
DistributionSiteID: siteID,
|
||||
Type: "order_group",
|
||||
Title: orderConversationTitle(order),
|
||||
Status: "active",
|
||||
|
||||
@@ -418,7 +418,7 @@ func (r *Repository) ListOrders(ctx context.Context, query DistributionOrderList
|
||||
size = 100
|
||||
}
|
||||
base := r.db.WithContext(ctx).Table("rental_orders ro").
|
||||
Joins("JOIN distribution_order_financials f ON f.order_id = ro.id").
|
||||
Joins("LEFT JOIN distribution_order_financials f ON f.order_id = ro.id").
|
||||
Joins("LEFT JOIN rental_listings rl ON rl.id = ro.listing_id").
|
||||
Joins("LEFT JOIN game_accounts ga ON ga.id = ro.account_id").
|
||||
Joins("LEFT JOIN users u ON u.id = ro.renter_id")
|
||||
@@ -450,8 +450,16 @@ func (r *Repository) ListOrders(ctx context.Context, query DistributionOrderList
|
||||
selectSQL := `
|
||||
ro.id AS order_id, ro.order_no, ro.distribution_site_id AS site_id, ro.listing_id, ro.account_id, ro.owner_id, ro.renter_id,
|
||||
ro.status, ro.handoff_status, ro.refund_status, ro.settlement_status, ro.distribution_mode,
|
||||
f.gross_paid_amount_cent, f.refund_amount_cent, f.net_paid_amount_cent, f.payment_fee_cent, f.service_fee_cent,
|
||||
f.markup_amount_cent, f.tax_amount_cent, f.split_base_amount_cent, f.rounding_adjustment_cent, ro.created_at,
|
||||
COALESCE(f.gross_paid_amount_cent, 0) AS gross_paid_amount_cent,
|
||||
COALESCE(f.refund_amount_cent, 0) AS refund_amount_cent,
|
||||
COALESCE(f.net_paid_amount_cent, 0) AS net_paid_amount_cent,
|
||||
COALESCE(f.payment_fee_cent, 0) AS payment_fee_cent,
|
||||
COALESCE(f.service_fee_cent, 0) AS service_fee_cent,
|
||||
COALESCE(f.markup_amount_cent, 0) AS markup_amount_cent,
|
||||
COALESCE(f.tax_amount_cent, 0) AS tax_amount_cent,
|
||||
COALESCE(f.split_base_amount_cent, 0) AS split_base_amount_cent,
|
||||
COALESCE(f.rounding_adjustment_cent, 0) AS rounding_adjustment_cent,
|
||||
ro.created_at,
|
||||
COALESCE(rl.listing_no, '') AS listing_no,
|
||||
COALESCE(ga.title, '') AS title,
|
||||
COALESCE(ga.game_name, '') AS game_name,
|
||||
@@ -518,8 +526,16 @@ func (r *Repository) FindOrder(ctx context.Context, adminID, id uint64) (*Distri
|
||||
selectSQL := `
|
||||
ro.id AS order_id, ro.order_no, ro.distribution_site_id AS site_id, ro.listing_id, ro.account_id, ro.owner_id, ro.renter_id,
|
||||
ro.status, ro.handoff_status, ro.refund_status, ro.settlement_status, ro.distribution_mode,
|
||||
f.gross_paid_amount_cent, f.refund_amount_cent, f.net_paid_amount_cent, f.payment_fee_cent, f.service_fee_cent,
|
||||
f.markup_amount_cent, f.tax_amount_cent, f.split_base_amount_cent, f.rounding_adjustment_cent, ro.created_at,
|
||||
COALESCE(f.gross_paid_amount_cent, 0) AS gross_paid_amount_cent,
|
||||
COALESCE(f.refund_amount_cent, 0) AS refund_amount_cent,
|
||||
COALESCE(f.net_paid_amount_cent, 0) AS net_paid_amount_cent,
|
||||
COALESCE(f.payment_fee_cent, 0) AS payment_fee_cent,
|
||||
COALESCE(f.service_fee_cent, 0) AS service_fee_cent,
|
||||
COALESCE(f.markup_amount_cent, 0) AS markup_amount_cent,
|
||||
COALESCE(f.tax_amount_cent, 0) AS tax_amount_cent,
|
||||
COALESCE(f.split_base_amount_cent, 0) AS split_base_amount_cent,
|
||||
COALESCE(f.rounding_adjustment_cent, 0) AS rounding_adjustment_cent,
|
||||
ro.created_at,
|
||||
COALESCE(rl.listing_no, '') AS listing_no,
|
||||
COALESCE(ga.title, '') AS title,
|
||||
COALESCE(ga.game_name, '') AS game_name,
|
||||
@@ -535,7 +551,7 @@ func (r *Repository) FindOrder(ctx context.Context, adminID, id uint64) (*Distri
|
||||
COALESCE(ro.deposit_amount_cent, 0) AS deposit_amount_cent
|
||||
`
|
||||
err := r.db.WithContext(ctx).Table("rental_orders ro").
|
||||
Joins("JOIN distribution_order_financials f ON f.order_id = ro.id").
|
||||
Joins("LEFT JOIN distribution_order_financials f ON f.order_id = ro.id").
|
||||
Joins("LEFT JOIN rental_listings rl ON rl.id = ro.listing_id").
|
||||
Joins("LEFT JOIN game_accounts ga ON ga.id = ro.account_id").
|
||||
Joins("LEFT JOIN users u ON u.id = ro.renter_id").
|
||||
|
||||
@@ -159,14 +159,16 @@ func Append(tx *gorm.DB, entries ...Entry) error {
|
||||
if siteID == nil {
|
||||
if (entry.BizType == "order" || entry.BizType == "order_handoff") && entry.BizID != nil && *entry.BizID > 0 {
|
||||
var orderSiteID *uint64
|
||||
row := tx.Table("rental_orders").Where("id = ?", *entry.BizID).Select("distribution_site_id").Row()
|
||||
if err := row.Scan(&orderSiteID); err == nil && orderSiteID != nil {
|
||||
var mode string
|
||||
row := tx.Table("rental_orders").Where("id = ?", *entry.BizID).Select("distribution_site_id, distribution_mode").Row()
|
||||
if err := row.Scan(&orderSiteID, &mode); err == nil && orderSiteID != nil && mode != "two_party_distributor_receive" {
|
||||
siteID = orderSiteID
|
||||
}
|
||||
} else if entry.BizType == "dispute" && entry.BizID != nil && *entry.BizID > 0 {
|
||||
var orderSiteID *uint64
|
||||
row := tx.Table("order_disputes d").Joins("JOIN rental_orders o ON o.id = d.order_id").Where("d.id = ?", *entry.BizID).Select("o.distribution_site_id").Row()
|
||||
if err := row.Scan(&orderSiteID); err == nil && orderSiteID != nil {
|
||||
var mode string
|
||||
row := tx.Table("order_disputes d").Joins("JOIN rental_orders o ON o.id = d.order_id").Where("d.id = ?", *entry.BizID).Select("o.distribution_site_id, o.distribution_mode").Row()
|
||||
if err := row.Scan(&orderSiteID, &mode); err == nil && orderSiteID != nil && mode != "two_party_distributor_receive" {
|
||||
siteID = orderSiteID
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"time"
|
||||
|
||||
"hfb_sys/backend/internal/model"
|
||||
"hfb_sys/backend/internal/modules/distribution"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
@@ -21,11 +22,13 @@ func (r *Repository) ListForUser(ctx context.Context, userID uint64, page, pageS
|
||||
code = strings.TrimSpace(siteCode[0])
|
||||
}
|
||||
if code != "" {
|
||||
base = base.Joins("INNER JOIN distribution_sites AS ds ON ds.id = o.distribution_site_id AND ds.site_code = ?", code)
|
||||
countBase = countBase.Joins("INNER JOIN distribution_sites AS ds ON ds.id = o.distribution_site_id AND ds.site_code = ?", code)
|
||||
base = base.Joins("INNER JOIN distribution_sites AS ds ON ds.id = o.distribution_site_id AND ds.site_code = ?", code).
|
||||
Where("o.distribution_mode != ?", distribution.ModeTwoPartyDistributorReceive)
|
||||
countBase = countBase.Joins("INNER JOIN distribution_sites AS ds ON ds.id = o.distribution_site_id AND ds.site_code = ?", code).
|
||||
Where("o.distribution_mode != ?", distribution.ModeTwoPartyDistributorReceive)
|
||||
} else {
|
||||
base = base.Where("o.distribution_site_id IS NULL OR o.distribution_site_id = 0")
|
||||
countBase = countBase.Where("o.distribution_site_id IS NULL OR o.distribution_site_id = 0")
|
||||
base = base.Where("o.distribution_site_id IS NULL OR o.distribution_site_id = 0 OR o.distribution_mode = ?", distribution.ModeTwoPartyDistributorReceive)
|
||||
countBase = countBase.Where("o.distribution_site_id IS NULL OR o.distribution_site_id = 0 OR o.distribution_mode = ?", distribution.ModeTwoPartyDistributorReceive)
|
||||
}
|
||||
|
||||
var total int64
|
||||
@@ -64,9 +67,10 @@ func (r *Repository) ListSellerHandoffs(ctx context.Context, userID uint64, quer
|
||||
base = base.Where("o.status = ?", query.Status)
|
||||
}
|
||||
if query.SiteCode != "" {
|
||||
base = base.Joins("INNER JOIN distribution_sites AS ds ON ds.id = o.distribution_site_id AND ds.site_code = ?", query.SiteCode)
|
||||
base = base.Joins("INNER JOIN distribution_sites AS ds ON ds.id = o.distribution_site_id AND ds.site_code = ?", query.SiteCode).
|
||||
Where("o.distribution_mode != ?", distribution.ModeTwoPartyDistributorReceive)
|
||||
} else {
|
||||
base = base.Where("o.distribution_site_id IS NULL OR o.distribution_site_id = 0")
|
||||
base = base.Where("o.distribution_site_id IS NULL OR o.distribution_site_id = 0 OR o.distribution_mode = ?", distribution.ModeTwoPartyDistributorReceive)
|
||||
}
|
||||
|
||||
var total int64
|
||||
@@ -98,9 +102,10 @@ func (r *Repository) ListSellerHandoffs(ctx context.Context, userID uint64, quer
|
||||
func (r *Repository) sellerHandoffMetrics(ctx context.Context, userID uint64, siteCode ...string) (SellerHandoffMetrics, error) {
|
||||
base := r.db.WithContext(ctx).Table("rental_orders AS o").Where("o.owner_id = ?", userID)
|
||||
if len(siteCode) > 0 && siteCode[0] != "" {
|
||||
base = base.Joins("INNER JOIN distribution_sites AS ds ON ds.id = o.distribution_site_id AND ds.site_code = ?", siteCode[0])
|
||||
base = base.Joins("INNER JOIN distribution_sites AS ds ON ds.id = o.distribution_site_id AND ds.site_code = ?", siteCode[0]).
|
||||
Where("o.distribution_mode != ?", distribution.ModeTwoPartyDistributorReceive)
|
||||
} else if len(siteCode) > 0 {
|
||||
base = base.Where("o.distribution_site_id IS NULL OR o.distribution_site_id = 0")
|
||||
base = base.Where("o.distribution_site_id IS NULL OR o.distribution_site_id = 0 OR o.distribution_mode = ?", distribution.ModeTwoPartyDistributorReceive)
|
||||
}
|
||||
var metrics SellerHandoffMetrics
|
||||
if err := base.Session(&gorm.Session{}).Where("o.status = ? AND o.handoff_status = ?", orderStatusPendingHandoff, handoffStatusPendingOwner).Count(&metrics.PendingHandoff).Error; err != nil {
|
||||
@@ -340,9 +345,10 @@ func (r *Repository) FindForUser(ctx context.Context, userID uint64, orderID uin
|
||||
code = strings.TrimSpace(siteCode[0])
|
||||
}
|
||||
if code != "" {
|
||||
query = query.Joins("INNER JOIN distribution_sites AS ds ON ds.id = o.distribution_site_id AND ds.site_code = ?", code)
|
||||
query = query.Joins("INNER JOIN distribution_sites AS ds ON ds.id = o.distribution_site_id AND ds.site_code = ?", code).
|
||||
Where("o.distribution_mode != ?", distribution.ModeTwoPartyDistributorReceive)
|
||||
} else if len(siteCode) > 0 {
|
||||
query = query.Where("o.distribution_site_id IS NULL OR o.distribution_site_id = 0")
|
||||
query = query.Where("o.distribution_site_id IS NULL OR o.distribution_site_id = 0 OR o.distribution_mode = ?", distribution.ModeTwoPartyDistributorReceive)
|
||||
}
|
||||
|
||||
if err := query.First(&row).Error; err != nil {
|
||||
|
||||
@@ -2018,7 +2018,7 @@ func TestListForUserAndFindForUserSiteIsolation(t *testing.T) {
|
||||
}
|
||||
db.Create(&mainOrder)
|
||||
|
||||
// Order 2: on distribution site (distribution_site_id = site.ID)
|
||||
// Order 2: on distribution site (distribution_site_id = site.ID, sold on site)
|
||||
distOrder := model.RentalOrder{
|
||||
OrderNo: "RO_DIST_001",
|
||||
ListingID: listing.ID,
|
||||
@@ -2027,9 +2027,23 @@ func TestListForUserAndFindForUserSiteIsolation(t *testing.T) {
|
||||
RenterID: renter.ID,
|
||||
Status: orderStatusCompleted,
|
||||
DistributionSiteID: &site.ID,
|
||||
DistributionMode: "two_party_platform_receive",
|
||||
}
|
||||
db.Create(&distOrder)
|
||||
|
||||
// Order 3: received by distribution site, but rented/sold on main site
|
||||
distRecvOrder := model.RentalOrder{
|
||||
OrderNo: "RO_DIST_RECV_001",
|
||||
ListingID: listing.ID,
|
||||
AccountID: account.ID,
|
||||
OwnerID: owner.ID,
|
||||
RenterID: renter.ID,
|
||||
Status: orderStatusCompleted,
|
||||
DistributionSiteID: &site.ID,
|
||||
DistributionMode: "two_party_distributor_receive",
|
||||
}
|
||||
db.Create(&distRecvOrder)
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
// 1. Query with site_code = "site_isolate_1": should return ONLY distOrder
|
||||
@@ -2041,13 +2055,13 @@ func TestListForUserAndFindForUserSiteIsolation(t *testing.T) {
|
||||
t.Fatalf("expected only RO_DIST_001, got %+v", distList.Items)
|
||||
}
|
||||
|
||||
// 2. Query without siteCode (main site mode): should return ONLY mainOrder
|
||||
// 2. Query without siteCode (main site mode): should return mainOrder AND distRecvOrder
|
||||
mainList, err := repo.ListForUser(ctx, renter.ID, 1, 20, "")
|
||||
if err != nil {
|
||||
t.Fatalf("ListForUser main err: %v", err)
|
||||
}
|
||||
if len(mainList.Items) != 1 || mainList.Items[0].OrderNo != "RO_MAIN_001" {
|
||||
t.Fatalf("expected only RO_MAIN_001, got %+v", mainList.Items)
|
||||
if len(mainList.Items) != 2 {
|
||||
t.Fatalf("expected 2 orders on main site, got %d: %+v", len(mainList.Items), mainList.Items)
|
||||
}
|
||||
|
||||
// 3. FindForUser: distOrder found under "site_isolate_1"
|
||||
@@ -2056,13 +2070,25 @@ func TestListForUserAndFindForUserSiteIsolation(t *testing.T) {
|
||||
t.Fatalf("FindForUser distOrder failed: %v", err)
|
||||
}
|
||||
|
||||
// 4. FindForUser: mainOrder CANNOT be accessed under "site_isolate_1"
|
||||
// 4. FindForUser: distRecvOrder found under main site mode ("")
|
||||
recvItem, err := repo.FindForUser(ctx, renter.ID, distRecvOrder.ID, "")
|
||||
if err != nil || recvItem.OrderNo != "RO_DIST_RECV_001" {
|
||||
t.Fatalf("FindForUser distRecvOrder failed on main site: %v", err)
|
||||
}
|
||||
|
||||
// 5. FindForUser: mainOrder CANNOT be accessed under "site_isolate_1"
|
||||
_, err = repo.FindForUser(ctx, renter.ID, mainOrder.ID, "site_isolate_1")
|
||||
if err == nil {
|
||||
t.Fatalf("expected error accessing mainOrder under distribution site, got nil")
|
||||
}
|
||||
|
||||
// 5. FindForUser: distOrder CANNOT be accessed under main site mode ("")
|
||||
// 6. FindForUser: distRecvOrder CANNOT be accessed under "site_isolate_1"
|
||||
_, err = repo.FindForUser(ctx, renter.ID, distRecvOrder.ID, "site_isolate_1")
|
||||
if err == nil {
|
||||
t.Fatalf("expected error accessing distRecvOrder under distribution site, got nil")
|
||||
}
|
||||
|
||||
// 7. FindForUser: distOrder CANNOT be accessed under main site mode ("")
|
||||
_, err = repo.FindForUser(ctx, renter.ID, distOrder.ID, "")
|
||||
if err == nil {
|
||||
t.Fatalf("expected error accessing distOrder under main site mode, got nil")
|
||||
|
||||
Reference in New Issue
Block a user