Merge remote-tracking branch 'origin/Django' into Django

# Conflicts:
#	elastic/views.py
This commit is contained in:
2025-11-15 20:22:57 +08:00

View File

@@ -5,6 +5,8 @@ Django版本的ES连接和操作模块
from elasticsearch import Elasticsearch from elasticsearch import Elasticsearch
from elasticsearch_dsl import connections from elasticsearch_dsl import connections
import os import os
import json
import re
from .documents import AchievementDocument, UserDocument, GlobalDocument from .documents import AchievementDocument, UserDocument, GlobalDocument
from .indexes import ACHIEVEMENT_INDEX_NAME, USER_INDEX_NAME, GLOBAL_INDEX_NAME from .indexes import ACHIEVEMENT_INDEX_NAME, USER_INDEX_NAME, GLOBAL_INDEX_NAME
import hashlib import hashlib
@@ -321,23 +323,45 @@ def _compute_hist(range_gte: str, interval: str, fmt: str):
buckets = getattr(resp.aggs, 'b').buckets buckets = getattr(resp.aggs, 'b').buckets
return [{"label": b.key_as_string, "count": b.doc_count} for b in buckets] return [{"label": b.key_as_string, "count": b.doc_count} for b in buckets]
def _compute_type_counts(range_gte: str, types: list): def _parse_type_from_data(data_str: str):
counts = [] try:
for t in types: obj = json.loads(data_str)
s = AchievementDocument.search() if isinstance(obj, dict):
s = s.filter('range', time={'gte': range_gte, 'lte': 'now'}) for k in ("数据类型", "类型", "type"):
s = s.query('match_phrase', data=str(t)) if k in obj and obj.get(k):
total = s.count() return str(obj.get(k)).strip().strip(';')
counts.append({"type": str(t), "count": int(total)}) except Exception:
return counts pass
try:
m = re.search(r'"数据类型"\s*:\s*"(.*?)"', data_str)
if m:
return str(m.group(1)).strip().strip(';')
except Exception:
pass
return None
def _compute_type_counts_dynamic(range_gte: str):
s = AchievementDocument.search()
s = s.filter('range', time={'gte': range_gte, 'lte': 'now'})
s = s.query('match_all')
counts_map = {}
for hit in s.scan():
t = _parse_type_from_data(getattr(hit, 'data', '') or '')
if not t:
continue
counts_map[t] = counts_map.get(t, 0) + 1
try:
ensure_type_in_list(t)
except Exception:
pass
return [{"type": k, "count": int(v)} for k, v in counts_map.items()]
def compute_analytics(): def compute_analytics():
types = get_type_list()
days = _compute_hist('now-10d/d', 'day', 'yyyy-MM-dd') days = _compute_hist('now-10d/d', 'day', 'yyyy-MM-dd')
weeks = _compute_hist('now-10w/w', 'week', 'yyyy-ww') weeks = _compute_hist('now-10w/w', 'week', 'yyyy-ww')
months = _compute_hist('now-10M/M', 'month', 'yyyy-MM') months = _compute_hist('now-10M/M', 'month', 'yyyy-MM')
pie_1m = _compute_type_counts('now-1M/M', types) pie_1m = _compute_type_counts_dynamic('now-1M/M')
pie_12m = _compute_type_counts('now-12M/M', types) pie_12m = _compute_type_counts_dynamic('now-12M/M')
return { return {
"last_10_days": days[-10:], "last_10_days": days[-10:],
"last_10_weeks": weeks[-10:], "last_10_weeks": weeks[-10:],