From e3e980f114da2dc82ae65d6ecacd90f94402c88d Mon Sep 17 00:00:00 2001 From: yml2213 Date: Mon, 10 Aug 2026 14:12:55 +0800 Subject: [PATCH] feat(finance): count created pickups as paid --- .../modules/adminfinance/dashboard.go | 21 ++++++++++++------ .../modules/adminfinance/dashboard_test.go | 22 ++++++++++++++++--- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/backend/internal/modules/adminfinance/dashboard.go b/backend/internal/modules/adminfinance/dashboard.go index 2a46026..3dcad53 100644 --- a/backend/internal/modules/adminfinance/dashboard.go +++ b/backend/internal/modules/adminfinance/dashboard.go @@ -372,15 +372,22 @@ func (r *Repository) dailyItems(ctx context.Context, query DashboardQuery) ([]Fi return items, nil } -// dailyPaidOrders 仅统计普通租赁订单的成功支付,按实际支付完成时间归集。 +// dailyPaidOrders 按实际付款日统计普通租赁订单,并将创建的线下提号视为已付款成交。 func (r *Repository) dailyPaidOrders(ctx context.Context, query DashboardQuery) ([]dailyPaidOrderRow, error) { items := make([]dailyPaidOrderRow, 0) - err := r.db.WithContext(ctx).Table("payment_orders AS po"). - Select(`DATE(po.paid_at) AS date, - COUNT(DISTINCT po.order_id) AS paid_order_count`). - Where("po.biz_type = ? AND po.status = ?", "order_pay", "paid"). - Where("po.paid_at >= ? AND po.paid_at <= ?", query.StartDate, query.EndDate). - Group("DATE(po.paid_at)"). + err := r.db.WithContext(ctx).Table(`( + SELECT DATE(paid_at) AS date, COUNT(DISTINCT order_id) AS paid_order_count + FROM payment_orders + WHERE biz_type = 'order_pay' AND status = 'paid' AND paid_at >= ? AND paid_at <= ? + GROUP BY DATE(paid_at) + UNION ALL + SELECT DATE(created_at) AS date, COUNT(id) AS paid_order_count + FROM admin_pickups + WHERE created_at >= ? AND created_at <= ? + GROUP BY DATE(created_at) + ) AS daily_paid_orders`, query.StartDate, query.EndDate, query.StartDate, query.EndDate). + Select("date, SUM(paid_order_count) AS paid_order_count"). + Group("date"). Scan(&items).Error return items, err } diff --git a/backend/internal/modules/adminfinance/dashboard_test.go b/backend/internal/modules/adminfinance/dashboard_test.go index a965334..86f1d74 100644 --- a/backend/internal/modules/adminfinance/dashboard_test.go +++ b/backend/internal/modules/adminfinance/dashboard_test.go @@ -11,7 +11,7 @@ import ( "gorm.io/gorm/logger" ) -func TestDailyPaidOrdersUsePaidAtAndExcludeMohong(t *testing.T) { +func TestDailyPaidOrdersUsePaidAtAndIncludeCreatedPickups(t *testing.T) { db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{Logger: logger.Default.LogMode(logger.Silent)}) if err != nil { t.Fatalf("打开测试数据库失败: %v", err) @@ -25,6 +25,12 @@ func TestDailyPaidOrdersUsePaidAtAndExcludeMohong(t *testing.T) { )`).Error; err != nil { t.Fatalf("创建支付单表失败: %v", err) } + if err := db.Exec(`CREATE TABLE admin_pickups ( + id INTEGER PRIMARY KEY, + created_at DATETIME NOT NULL + )`).Error; err != nil { + t.Fatalf("创建提号表失败: %v", err) + } loc := timeutil.ShanghaiLocation() day := func(value int) time.Time { return time.Date(2026, 8, value, 10, 0, 0, 0, loc) } @@ -42,6 +48,16 @@ func TestDailyPaidOrdersUsePaidAtAndExcludeMohong(t *testing.T) { t.Fatalf("写入支付单失败: %v", err) } } + for _, row := range [][]any{ + {1, day(2)}, + {2, day(2)}, + {3, day(3)}, + {4, day(1)}, + } { + if err := db.Exec(`INSERT INTO admin_pickups (id, created_at) VALUES (?, ?)`, row...).Error; err != nil { + t.Fatalf("写入提号记录失败: %v", err) + } + } repo := NewRepository(db) query := DashboardQuery{ @@ -59,7 +75,7 @@ func TestDailyPaidOrdersUsePaidAtAndExcludeMohong(t *testing.T) { for _, row := range result { counts[row.Date] = row.PaidOrderCount } - if counts["2026-08-02"] != 1 || counts["2026-08-03"] != 1 { - t.Fatalf("每日已付款订单 = %#v, want 8月2日和8月3日均为1", counts) + if counts["2026-08-02"] != 3 || counts["2026-08-03"] != 2 { + t.Fatalf("每日已付款订单 = %#v, want 8月2日为3、8月3日为2", counts) } }