1、修复后台首页数据概览的团队积分消耗排行情况

2、修复前台团队的退款统计问题
This commit is contained in:
2026-08-05 10:17:12 +08:00
parent 5de637ab6b
commit ceb930bd5a
2 changed files with 21 additions and 21 deletions
+15 -20
View File
@@ -2,7 +2,7 @@ from datetime import datetime, timezone, timedelta
import json
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy import case, delete, func, or_, select, update
from sqlalchemy import and_, case, delete, func, or_, select, update
from sqlalchemy.ext.asyncio import AsyncSession
from app.dependencies import get_db, get_admin_user
@@ -1963,36 +1963,31 @@ async def get_stats(
]
# ── 各团队积分消耗(有团队 vs 无团队,使用流水中的团队快照)
# 消耗 = 扣除金额 - 退回金额(净消耗
# 消耗 = 实际消费(charge_action IS NULL 或 charge - 退款(charge_action=refund 不限制
# 注意:real_credit_charge_filter 仅应限制 consume 类型(预扣 hold 释放不算真实消费);
# refund 类型的 charge_action = 'refund',不能套用同一个 filter
# 所以把该 filter 下移到 CASE WHEN 内而不是写在 WHERE 中,避免退款被误过滤。
_consume_filter = and_(
CreditRecord.type == "consume",
real_credit_charge_filter,
)
_consume_expr = case((_consume_filter, func.abs(CreditRecord.amount)), else_=0)
_refund_expr = case((CreditRecord.type == "refund", func.abs(CreditRecord.amount)), else_=0)
team_credit_rows = (await db.execute(
select(
func.coalesce(CreditRecord.team_name_snapshot, '未分配团队').label('team_name'),
CreditRecord.team_id_snapshot.label('team_id'),
func.coalesce(
func.sum(
case(
(CreditRecord.type == "consume", func.abs(CreditRecord.amount)),
else_=0,
)
), 0
).label("total_consume"),
func.coalesce(
func.sum(
case(
(CreditRecord.type == "refund", func.abs(CreditRecord.amount)),
else_=0,
)
), 0
).label("total_refund"),
func.coalesce(func.sum(_consume_expr), 0).label("total_consume"),
func.coalesce(func.sum(_refund_expr), 0).label("total_refund"),
)
.where(
CreditRecord.type.in_(["consume", "refund"]),
real_credit_charge_filter,
CreditRecord.created_at >= date_start,
CreditRecord.created_at <= date_end,
)
.group_by(CreditRecord.team_id_snapshot, CreditRecord.team_name_snapshot)
.order_by(func.coalesce(func.sum(case((CreditRecord.type == "consume", func.abs(CreditRecord.amount)), else_=0)), 0).desc())
# 按"净消耗 = 总消费 - 总退款"倒序排序(排行榜)
.order_by((func.coalesce(func.sum(_consume_expr), 0) - func.coalesce(func.sum(_refund_expr), 0)).desc())
)).all()
credits_by_team = [
TeamCreditOut(