Files
boss_dp/server/api/stats.py

109 lines
3.5 KiB
Python
Raw Normal View History

2026-02-14 17:58:29 +08:00
# -*- 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
2026-02-26 01:27:35 +08:00
from server.core.response import api_success
2026-02-14 17:58:29 +08:00
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)
2026-02-26 01:27:35 +08:00
return api_success({
2026-02-14 17:58:29 +08:00
"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({
2026-03-01 23:18:23 +08:00
"date": f"{day.isoformat()}T00:00:00",
2026-02-14 17:58:29 +08:00
"contacts": total,
"replied": replied,
"wechat": wechat,
"reply_rate": round(replied / max(total, 1) * 100, 1),
})
2026-02-26 01:27:35 +08:00
return api_success(daily_data)