diff --git a/backend/internal/modules/adminfinance/dashboard.go b/backend/internal/modules/adminfinance/dashboard.go
index 5794eec..2a46026 100644
--- a/backend/internal/modules/adminfinance/dashboard.go
+++ b/backend/internal/modules/adminfinance/dashboard.go
@@ -222,6 +222,10 @@ func (r *Repository) dailyItems(ctx context.Context, query DashboardQuery) ([]Fi
Scan(&payments).Error; err != nil {
return nil, err
}
+ paidOrders, err := r.dailyPaidOrders(ctx, query)
+ if err != nil {
+ return nil, err
+ }
settlements := make([]dailySettlementRow, 0)
if err := db.Table("rental_orders AS ro").
@@ -307,6 +311,13 @@ func (r *Repository) dailyItems(ctx context.Context, query DashboardQuery) ([]Fi
item.PendingRefundCount = row.PendingRefundCount
itemsByDate[date] = item
}
+ for _, row := range paidOrders {
+ date := dailyDateKey(row.Date)
+ item := itemsByDate[date]
+ item.Date = date
+ item.PaidOrderCount = row.PaidOrderCount
+ itemsByDate[date] = item
+ }
for _, row := range settlements {
date := dailyDateKey(row.Date)
item := itemsByDate[date]
@@ -361,6 +372,19 @@ func (r *Repository) dailyItems(ctx context.Context, query DashboardQuery) ([]Fi
return items, nil
}
+// 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)").
+ Scan(&items).Error
+ return items, err
+}
+
type paymentSummaryRow struct {
TotalFlowAmountCent int64
TotalRefundAmountCent int64
@@ -398,6 +422,11 @@ type dailyPaymentRow struct {
PendingRefundCount int64
}
+type dailyPaidOrderRow struct {
+ Date string
+ PaidOrderCount int64
+}
+
type dailySettlementRow struct {
Date string
PlatformIncomeAmountCent int64
diff --git a/backend/internal/modules/adminfinance/dashboard_test.go b/backend/internal/modules/adminfinance/dashboard_test.go
new file mode 100644
index 0000000..a965334
--- /dev/null
+++ b/backend/internal/modules/adminfinance/dashboard_test.go
@@ -0,0 +1,65 @@
+package adminfinance
+
+import (
+ "testing"
+ "time"
+
+ "hfb_sys/backend/internal/timeutil"
+
+ "gorm.io/driver/sqlite"
+ "gorm.io/gorm"
+ "gorm.io/gorm/logger"
+)
+
+func TestDailyPaidOrdersUsePaidAtAndExcludeMohong(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)
+ }
+ if err := db.Exec(`CREATE TABLE payment_orders (
+ id INTEGER PRIMARY KEY,
+ order_id INTEGER NOT NULL,
+ biz_type TEXT NOT NULL,
+ status TEXT NOT NULL,
+ paid_at DATETIME 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) }
+ rows := [][]any{
+ {1, 101, "order_pay", "paid", day(2)},
+ {2, 101, "order_pay", "paid", day(2)},
+ {3, 102, "order_pay", "paid", day(3)},
+ {4, 201, "mohong_pay", "paid", day(2)},
+ {5, 103, "order_pay", "created", nil},
+ {6, 104, "order_pay", "paid", day(1)},
+ }
+ for _, row := range rows {
+ if err := db.Exec(`INSERT INTO payment_orders (id, order_id, biz_type, status, paid_at)
+ VALUES (?, ?, ?, ?, ?)`, row...).Error; err != nil {
+ t.Fatalf("写入支付单失败: %v", err)
+ }
+ }
+
+ repo := NewRepository(db)
+ query := DashboardQuery{
+ StartDate: time.Date(2026, 8, 2, 0, 0, 0, 0, loc),
+ EndDate: time.Date(2026, 8, 3, 23, 59, 59, 0, loc),
+ }
+ result, err := repo.dailyPaidOrders(t.Context(), query)
+ if err != nil {
+ t.Fatalf("读取每日已付款订单失败: %v", err)
+ }
+ if len(result) != 2 {
+ t.Fatalf("每日已付款记录数 = %d, want 2", len(result))
+ }
+ counts := make(map[string]int64, len(result))
+ 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)
+ }
+}
diff --git a/backend/internal/modules/adminfinance/dto.go b/backend/internal/modules/adminfinance/dto.go
index ce74291..ade46f5 100644
--- a/backend/internal/modules/adminfinance/dto.go
+++ b/backend/internal/modules/adminfinance/dto.go
@@ -216,6 +216,7 @@ type FinanceDailyDTO struct {
SettledOrderCount int64 `json:"settled_order_count"`
PickupCompletedCount int64 `json:"pickup_completed_count"`
SalesCount int64 `json:"sales_count"`
+ PaidOrderCount int64 `json:"paid_order_count"`
OfflineSettlementPendingCount int64 `json:"offline_settlement_pending_count"`
OfflineSettlementPaidAmountCent int64 `json:"offline_settlement_paid_amount_cent"`
OfflineSettlementPaidCount int64 `json:"offline_settlement_paid_count"`
diff --git a/backend/migrations/000047_finance_daily_paid_order_stats.sql b/backend/migrations/000047_finance_daily_paid_order_stats.sql
new file mode 100644
index 0000000..1b38e1f
--- /dev/null
+++ b/backend/migrations/000047_finance_daily_paid_order_stats.sql
@@ -0,0 +1,9 @@
+-- +goose Up
+
+ALTER TABLE payment_orders
+ ADD KEY idx_payment_orders_biz_status_paid_at_order (biz_type, status, paid_at, order_id);
+
+-- +goose Down
+
+ALTER TABLE payment_orders
+ DROP KEY idx_payment_orders_biz_status_paid_at_order;
diff --git a/frontend/src/features/admin/api/adminFinance.ts b/frontend/src/features/admin/api/adminFinance.ts
index d23f0e7..4a8581f 100644
--- a/frontend/src/features/admin/api/adminFinance.ts
+++ b/frontend/src/features/admin/api/adminFinance.ts
@@ -53,6 +53,7 @@ export interface FinanceDailyItem {
settled_order_count: number
pickup_completed_count: number
sales_count: number
+ paid_order_count: number
offline_settlement_pending_count: number
offline_settlement_paid_amount_cent: number
offline_settlement_paid_count: number
diff --git a/frontend/src/features/admin/views/AdminFinanceDashboardView.vue b/frontend/src/features/admin/views/AdminFinanceDashboardView.vue
index 8b1fbd3..ddc5385 100644
--- a/frontend/src/features/admin/views/AdminFinanceDashboardView.vue
+++ b/frontend/src/features/admin/views/AdminFinanceDashboardView.vue
@@ -255,9 +255,12 @@ function diffType(value: number) {
{{ row.pickup_completed_count }}
-
+
{{ row.sales_count }}
+
+ {{ row.paid_order_count }}
+
{{ moneyCent(row.platform_income_amount_cent) }}