Files
tech-blog/app/routes/admin/stats.py
hz4th_coder 503a9780b2 refactor: 拆分admin路由为模块化结构,端口改为16013
- 将 routes/admin.py (672行) 拆分为 routes/admin/ 包
- 按功能模块拆分:auth, dashboard, articles, categories, tags, settings, stats, upload, authors
- 端口从 16012 改为 16013
- 初始化数据库和管理员账户
2026-06-25 11:21:36 +08:00

66 lines
2.0 KiB
Python

"""访问统计路由"""
from flask import render_template, redirect, url_for, request, flash
from app.routes.admin import admin_bp, login_required
from app.services import VisitService
@admin_bp.route('/stats')
@login_required
def stats():
"""访问统计概览"""
stats_summary = VisitService.get_stats_summary()
top_ips = VisitService.get_top_ips(10)
top_articles = VisitService.get_top_articles(7, 10)
top_paths = VisitService.get_top_paths(20)
return render_template('admin/stats.html',
stats=stats_summary,
top_ips=top_ips,
top_articles=top_articles,
top_paths=top_paths)
@admin_bp.route('/stats/logs')
@login_required
def stats_logs():
"""访问日志列表"""
page = request.args.get('page', 1, type=int)
path_filter = request.args.get('path', '')
logs = VisitService.get_visit_list(page=page, per_page=50, path_filter=path_filter)
return render_template('admin/stats_logs.html',
logs=logs,
path_filter=path_filter)
@admin_bp.route('/stats/charts')
@login_required
def stats_charts():
"""访问统计图表"""
stats_summary = VisitService.get_stats_summary()
# 准备图表数据
daily_data = []
for stat in stats_summary['daily_stats']:
daily_data.append({
'date': stat.date.strftime('%Y-%m-%d'),
'visits': stat.total_visits,
'unique_ips': stat.unique_ips,
'article_views': stat.article_views
})
return render_template('admin/stats_charts.html',
daily_data=daily_data,
stats=stats_summary)
@admin_bp.route('/stats/clear', methods=['POST'])
@login_required
def stats_clear():
"""清理旧访问日志"""
days = request.form.get('days', 90, type=int)
deleted = VisitService.clear_old_logs(days)
flash(f'已清理 {deleted} 条旧日志记录', 'success')
return redirect(url_for('admin.stats_logs'))