@@ -48,12 +48,3 @@ class GlobalDocument(Document):
|
|||||||
|
|
||||||
class Django:
|
class Django:
|
||||||
model = ElasticNews
|
model = ElasticNews
|
||||||
|
|
||||||
|
|
||||||
@GLOBAL_INDEX.doc_type
|
|
||||||
class AnalyticsDocument(Document):
|
|
||||||
overview = fields.TextField()
|
|
||||||
updated_at = fields.DateField()
|
|
||||||
|
|
||||||
class Django:
|
|
||||||
model = ElasticNews
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ Django版本的ES连接和操作模块
|
|||||||
from elasticsearch import Elasticsearch
|
from elasticsearch import Elasticsearch
|
||||||
from elasticsearch_dsl import connections
|
from elasticsearch_dsl import connections
|
||||||
import os
|
import os
|
||||||
from .documents import AchievementDocument, UserDocument, GlobalDocument, AnalyticsDocument
|
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
|
||||||
import time
|
import time
|
||||||
@@ -46,18 +46,10 @@ def create_index_with_mapping():
|
|||||||
# --- 3. 处理全局类型索引 ---
|
# --- 3. 处理全局类型索引 ---
|
||||||
if not es.indices.exists(index=GLOBAL_TYPES_INDEX_NAME):
|
if not es.indices.exists(index=GLOBAL_TYPES_INDEX_NAME):
|
||||||
GlobalDocument.init()
|
GlobalDocument.init()
|
||||||
AnalyticsDocument.init()
|
|
||||||
default_types = ['软著', '专利', '奖状']
|
default_types = ['软著', '专利', '奖状']
|
||||||
doc = GlobalDocument(type_list=default_types)
|
doc = GlobalDocument(type_list=default_types)
|
||||||
doc.meta.id = 'types'
|
doc.meta.id = 'types'
|
||||||
doc.save()
|
doc.save()
|
||||||
try:
|
|
||||||
a = AnalyticsDocument()
|
|
||||||
a.meta.id = 'overview'
|
|
||||||
a.overview = json.dumps({})
|
|
||||||
a.save()
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
print(f"✅ 创建索引 {GLOBAL_TYPES_INDEX_NAME} 并写入默认类型")
|
print(f"✅ 创建索引 {GLOBAL_TYPES_INDEX_NAME} 并写入默认类型")
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
@@ -68,16 +60,6 @@ def create_index_with_mapping():
|
|||||||
doc.meta.id = 'types'
|
doc.meta.id = 'types'
|
||||||
doc.save()
|
doc.save()
|
||||||
print("ℹ️ 全局类型文档缺失,已补充默认类型")
|
print("ℹ️ 全局类型文档缺失,已补充默认类型")
|
||||||
try:
|
|
||||||
AnalyticsDocument.get(id='overview')
|
|
||||||
except Exception:
|
|
||||||
try:
|
|
||||||
a = AnalyticsDocument()
|
|
||||||
a.meta.id = 'overview'
|
|
||||||
a.overview = json.dumps({})
|
|
||||||
a.save()
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# --- 4. 创建默认管理员用户(可选:也可检查用户是否已存在)---
|
# --- 4. 创建默认管理员用户(可选:也可检查用户是否已存在)---
|
||||||
# 这里简单处理:每次初始化都写入(可能重复),建议加唯一性判断
|
# 这里简单处理:每次初始化都写入(可能重复),建议加唯一性判断
|
||||||
@@ -327,29 +309,7 @@ def search_by_any_field(keyword):
|
|||||||
print(f"模糊搜索失败: {str(e)}")
|
print(f"模糊搜索失败: {str(e)}")
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def _read_analytics_overview():
|
ANALYTICS_CACHE = {"data": None, "ts": 0}
|
||||||
try:
|
|
||||||
doc = AnalyticsDocument.get(id='overview')
|
|
||||||
payload = getattr(doc, 'overview', '') or ''
|
|
||||||
try:
|
|
||||||
return json.loads(payload) if payload else {}
|
|
||||||
except Exception:
|
|
||||||
return {}
|
|
||||||
except Exception:
|
|
||||||
return {}
|
|
||||||
|
|
||||||
def _write_analytics_overview(data: dict):
|
|
||||||
try:
|
|
||||||
try:
|
|
||||||
doc = AnalyticsDocument.get(id='overview')
|
|
||||||
except Exception:
|
|
||||||
doc = AnalyticsDocument()
|
|
||||||
doc.meta.id = 'overview'
|
|
||||||
doc.overview = json.dumps(data, ensure_ascii=False)
|
|
||||||
doc.save()
|
|
||||||
return True
|
|
||||||
except Exception:
|
|
||||||
return False
|
|
||||||
|
|
||||||
def _compute_hist(range_gte: str, interval: str, fmt: str):
|
def _compute_hist(range_gte: str, interval: str, fmt: str):
|
||||||
from elasticsearch_dsl import Search
|
from elasticsearch_dsl import Search
|
||||||
@@ -387,16 +347,11 @@ def compute_analytics():
|
|||||||
}
|
}
|
||||||
|
|
||||||
def get_analytics_overview(force: bool = False):
|
def get_analytics_overview(force: bool = False):
|
||||||
if force:
|
now_ts = time.time()
|
||||||
data = compute_analytics()
|
if force or ANALYTICS_CACHE["data"] is None or (now_ts - ANALYTICS_CACHE["ts"]) > 3600:
|
||||||
_write_analytics_overview(data)
|
ANALYTICS_CACHE["data"] = compute_analytics()
|
||||||
return data
|
ANALYTICS_CACHE["ts"] = now_ts
|
||||||
data = _read_analytics_overview()
|
return ANALYTICS_CACHE["data"]
|
||||||
if data:
|
|
||||||
return data
|
|
||||||
data = compute_analytics()
|
|
||||||
_write_analytics_overview(data)
|
|
||||||
return data
|
|
||||||
|
|
||||||
def _seconds_until_hour(h: int):
|
def _seconds_until_hour(h: int):
|
||||||
now = datetime.now()
|
now = datetime.now()
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
from django.core.management.base import BaseCommand
|
|
||||||
from elastic.es_connect import create_index_with_mapping, get_analytics_overview
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
|
||||||
def handle(self, *args, **options):
|
|
||||||
create_index_with_mapping()
|
|
||||||
get_analytics_overview(force=True)
|
|
||||||
self.stdout.write("analytics updated")
|
|
||||||
Reference in New Issue
Block a user