添加账户中心
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
from datetime import timedelta
|
||||
import calendar
|
||||
from datetime import date, timedelta
|
||||
from decimal import Decimal, InvalidOperation, ROUND_HALF_UP
|
||||
|
||||
from django.db import transaction
|
||||
@@ -34,6 +35,7 @@ _STAGE_BUCKET = {
|
||||
}
|
||||
|
||||
|
||||
|
||||
@api_view(["GET"])
|
||||
@permission_classes([IsAuthenticated])
|
||||
def summary(request):
|
||||
@@ -229,17 +231,41 @@ def trend(request):
|
||||
peak = max((Decimal(s["amount"]) for s in series), default=Decimal("0"))
|
||||
avg = (total_14d / len(series)).quantize(Decimal("0.0001")) if series else Decimal("0")
|
||||
|
||||
# 本月按阶段分布(task.task_type → 4 桶)
|
||||
month_start = today.replace(day=1)
|
||||
# 只用 task.task_type/project,defer 掉 task 的大 blob(单条可达 3MB+ base64 图),别把几十 MB 拉回
|
||||
month_charges = charges.filter(created_at__date__gte=month_start).select_related("task").defer("task__request_payload", "task__response_payload")
|
||||
# 按任务类型分布(与后台「任务监控」类型列同源);?month=YYYY-MM 指定月份,默认当月
|
||||
# 有扣费的类型全部返回,前端按金额降序全部展示,不截断
|
||||
month_param = (request.query_params.get("month") or "").strip()
|
||||
dist_year, dist_month = today.year, today.month
|
||||
if len(month_param) == 7 and month_param[4] == "-":
|
||||
try:
|
||||
dist_year = int(month_param[:4])
|
||||
dist_month = int(month_param[5:7])
|
||||
if not (1 <= dist_month <= 12):
|
||||
raise ValueError("bad month")
|
||||
except ValueError:
|
||||
dist_year, dist_month = today.year, today.month
|
||||
month_param = f"{dist_year:04d}-{dist_month:02d}"
|
||||
else:
|
||||
month_param = f"{dist_year:04d}-{dist_month:02d}"
|
||||
month_start = date(dist_year, dist_month, 1)
|
||||
last_day = calendar.monthrange(dist_year, dist_month)[1]
|
||||
month_end = date(dist_year, dist_month, last_day)
|
||||
month_charges = (
|
||||
charges.filter(created_at__date__gte=month_start, created_at__date__lte=month_end)
|
||||
.select_related("task")
|
||||
.defer("task__request_payload", "task__response_payload")
|
||||
)
|
||||
by_stage = {"script": Decimal("0"), "base": Decimal("0"), "storyboard": Decimal("0"), "video": Decimal("0")}
|
||||
by_task_type: dict[str, Decimal] = {}
|
||||
project_amounts: dict[str, Decimal] = {}
|
||||
month_charged = Decimal("0")
|
||||
for row in month_charges:
|
||||
month_charged += row.amount
|
||||
task = row.task
|
||||
bucket = _STAGE_BUCKET.get(task.task_type) if task else None
|
||||
if bucket:
|
||||
by_stage[bucket] += row.amount
|
||||
if task and task.task_type:
|
||||
by_task_type[task.task_type] = by_task_type.get(task.task_type, Decimal("0")) + row.amount
|
||||
pid = str(row.project_id) if row.project_id else None
|
||||
if pid:
|
||||
project_amounts[pid] = project_amounts.get(pid, Decimal("0")) + row.amount
|
||||
@@ -250,7 +276,10 @@ def trend(request):
|
||||
"total_14d": str(total_14d),
|
||||
"avg": str(avg),
|
||||
"peak": str(peak),
|
||||
"month": month_param,
|
||||
"month_charged": str(month_charged),
|
||||
"by_stage": {k: str(v) for k, v in by_stage.items()},
|
||||
"by_task_type": {k: str(v) for k, v in by_task_type.items()},
|
||||
"by_project": {k: str(v) for k, v in project_amounts.items()},
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1364,3 +1364,6 @@ class QuickCreateCoordinatorTests(TestCase):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user