v1.0.0提交
This commit is contained in:
81
backend/routers/v1/stats.py
Normal file
81
backend/routers/v1/stats.py
Normal file
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
PerToolBox Server - 热度统计路由
|
||||
Copyright (C) 2024 Sea Network Technology Studio
|
||||
Author: Canglan <admin@sea-studio.top>
|
||||
License: AGPL v3
|
||||
"""
|
||||
|
||||
from datetime import datetime
|
||||
from fastapi import APIRouter
|
||||
from ...utils.redis_client import redis_client
|
||||
from ...models import ToolStatsTotal
|
||||
from ...dependencies import DbDependency
|
||||
from ...middleware.rate_limit import rate_limit
|
||||
|
||||
router = APIRouter(prefix="/api/v1", tags=["stats"])
|
||||
|
||||
# 预定义工具名称(对应前端页面)
|
||||
TOOL_NAMES = [
|
||||
"todos", "notes", "password", "qrcode",
|
||||
"crypto_hash", "crypto_base64", "crypto_url", "crypto_aes", "json"
|
||||
]
|
||||
|
||||
@router.post("/tool/usage")
|
||||
@rate_limit(requests=20, period=60)
|
||||
async def record_usage(tool_name: str, db: DbDependency):
|
||||
"""记录页面访问次数(热度)"""
|
||||
if tool_name not in TOOL_NAMES:
|
||||
raise HTTPException(status_code=400, detail="无效的工具名")
|
||||
|
||||
today = datetime.now().strftime("%Y-%m-%d")
|
||||
today_key = f"tool:stats:today:{tool_name}:{today}"
|
||||
total_key = f"tool:stats:total:{tool_name}"
|
||||
|
||||
# 增加今日计数(设置48小时过期)
|
||||
today_count = redis_client.incr(today_key)
|
||||
redis_client.expire(today_key, 48 * 3600)
|
||||
|
||||
# 增加总计数
|
||||
total_count = redis_client.incr(total_key)
|
||||
|
||||
# 异步更新 MySQL(可选,这里简单处理)
|
||||
# 实际可改为定时任务同步,此处为简化,直接更新
|
||||
stats = db.query(ToolStatsTotal).filter(ToolStatsTotal.tool_name == tool_name).first()
|
||||
if stats:
|
||||
stats.total_count = total_count
|
||||
else:
|
||||
stats = ToolStatsTotal(tool_name=tool_name, total_count=total_count)
|
||||
db.add(stats)
|
||||
db.commit()
|
||||
|
||||
return {"success": True}
|
||||
|
||||
@router.get("/tool/stats")
|
||||
@rate_limit(requests=100, period=60)
|
||||
async def get_stats(db: DbDependency):
|
||||
"""获取所有工具的今日/总访问次数"""
|
||||
today = datetime.now().strftime("%Y-%m-%d")
|
||||
result = {}
|
||||
|
||||
for tool_name in TOOL_NAMES:
|
||||
today_key = f"tool:stats:today:{tool_name}:{today}"
|
||||
total_key = f"tool:stats:total:{tool_name}"
|
||||
|
||||
today_count = redis_client.get(today_key)
|
||||
total_count = redis_client.get(total_key)
|
||||
|
||||
if total_count is None:
|
||||
# 从 MySQL 读取
|
||||
stats = db.query(ToolStatsTotal).filter(ToolStatsTotal.tool_name == tool_name).first()
|
||||
total_count = stats.total_count if stats else 0
|
||||
else:
|
||||
total_count = int(total_count)
|
||||
|
||||
result[tool_name] = {
|
||||
"today": int(today_count) if today_count else 0,
|
||||
"total": total_count
|
||||
}
|
||||
|
||||
return result
|
||||
Reference in New Issue
Block a user