# -*- 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 server.core.response import api_success 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 api_success({ "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 api_success(daily_data)