Files
boss_dp/server/api/stats.py
Your Name 87f915819f 哈哈
2026-02-14 17:58:29 +08:00

109 lines
3.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-
"""
统计分析 API需要登录
- GET /api/stats -> 总览统计
- GET /api/stats/daily -> 按日统计
"""
from datetime import timedelta
from django.db.models import Count, Q
from django.utils import timezone
from rest_framework.decorators import api_view
from rest_framework.response import Response
from server.models import ContactRecord, BossAccount, TaskLog
from server.core.worker_manager import worker_manager
@api_view(["GET"])
def stats_overview(request):
"""总览统计数据。"""
period = request.query_params.get("period", "all")
now = timezone.now()
# 根据时间段过滤
date_filter = Q()
if period == "today":
date_filter = Q(contacted_at__date=now.date())
elif period == "week":
date_filter = Q(contacted_at__gte=now - timedelta(days=7))
elif period == "month":
date_filter = Q(contacted_at__gte=now - timedelta(days=30))
contacts_qs = ContactRecord.objects.filter(date_filter)
total_contacts = contacts_qs.count()
total_replied = contacts_qs.filter(reply_status="已回复").count()
total_wechat = contacts_qs.filter(wechat_exchanged=True).count()
# 今日数据
today_filter = Q(contacted_at__date=now.date())
today_contacts = ContactRecord.objects.filter(today_filter).count()
today_replied = ContactRecord.objects.filter(today_filter, reply_status="已回复").count()
today_wechat = ContactRecord.objects.filter(today_filter, wechat_exchanged=True).count()
# 账号统计
total_accounts = BossAccount.objects.count()
logged_in_accounts = BossAccount.objects.filter(is_logged_in=True).count()
# Worker 统计
all_workers = worker_manager.get_all_workers()
online_workers = [w for w in all_workers if w.online]
# 任务统计
total_task_logs = TaskLog.objects.count()
reply_rate = round(total_replied / max(total_contacts, 1) * 100, 1)
wechat_rate = round(total_wechat / max(total_replied, 1) * 100, 1)
return Response({
"period": period,
"contacts": {
"total": total_contacts,
"today": today_contacts,
"replied": total_replied,
"today_replied": today_replied,
"reply_rate": reply_rate,
},
"wechat": {
"total": total_wechat,
"today": today_wechat,
"success_rate": wechat_rate,
},
"accounts": {
"total": total_accounts,
"logged_in": logged_in_accounts,
},
"workers": {
"total": len(all_workers),
"online": len(online_workers),
},
"tasks": {
"total_logs": total_task_logs,
},
})
@api_view(["GET"])
def stats_daily(request):
"""按日统计最近 N 天数据。"""
days = int(request.query_params.get("days", 7))
now = timezone.now()
daily_data = []
for i in range(days - 1, -1, -1):
day = (now - timedelta(days=i)).date()
day_filter = Q(contacted_at__date=day)
qs = ContactRecord.objects.filter(day_filter)
total = qs.count()
replied = qs.filter(reply_status="已回复").count()
wechat = qs.filter(wechat_exchanged=True).count()
daily_data.append({
"date": day.isoformat(),
"contacts": total,
"replied": replied,
"wechat": wechat,
"reply_rate": round(replied / max(total, 1) * 100, 1),
})
return Response(daily_data)