功能特性: - 前端文章展示 (Markdown渲染、代码高亮) - 后台管理系统 (文章、分类、标签、作者管理) - 图片上传 (点击、拖拽、粘贴) - 网站设置 (Logo、底部宣传图片上传) - 访问统计 (IP记录、趋势图表) - 参考来源、附件支持 - 单端口部署 (16012) 技术栈: - Flask 3.0 + SQLAlchemy - SQLite数据库 - marked.js + highlight.js (Markdown渲染) - Chart.js (统计图表)
83 lines
2.6 KiB
Python
83 lines
2.6 KiB
Python
"""访问统计模型"""
|
||
from datetime import datetime
|
||
from app import db
|
||
|
||
|
||
class VisitLog(db.Model):
|
||
"""访问日志表"""
|
||
__tablename__ = 'visit_logs'
|
||
|
||
id = db.Column(db.Integer, primary_key=True)
|
||
|
||
# 访问信息
|
||
ip_address = db.Column(db.String(50), nullable=False)
|
||
user_agent = db.Column(db.String(500))
|
||
referer = db.Column(db.String(500))
|
||
|
||
# 访问路径
|
||
path = db.Column(db.String(500), nullable=False)
|
||
method = db.Column(db.String(10), default='GET')
|
||
|
||
# 访问者信息(可从IP解析)
|
||
country = db.Column(db.String(50))
|
||
city = db.Column(db.String(50))
|
||
|
||
# 文章关联(如果访问的是文章详情页)
|
||
article_id = db.Column(db.Integer, db.ForeignKey('articles.id'))
|
||
article = db.relationship('Article', backref='visit_logs')
|
||
|
||
# 时间戳
|
||
visited_at = db.Column(db.DateTime, default=datetime.utcnow, index=True)
|
||
|
||
def __repr__(self):
|
||
return f'<VisitLog {self.ip_address} - {self.path}>'
|
||
|
||
@staticmethod
|
||
def get_today_count():
|
||
"""获取今日访问量"""
|
||
from datetime import date
|
||
today = date.today()
|
||
return VisitLog.query.filter(
|
||
VisitLog.visited_at >= datetime.combine(today, datetime.min.time())
|
||
).count()
|
||
|
||
@staticmethod
|
||
def get_total_count():
|
||
"""获取总访问量"""
|
||
return VisitLog.query.count()
|
||
|
||
@staticmethod
|
||
def get_unique_ip_count():
|
||
"""获取独立IP数量"""
|
||
return db.session.query(db.func.count(db.func.distinct(VisitLog.ip_address))).scalar()
|
||
|
||
|
||
class DailyStats(db.Model):
|
||
"""每日统计汇总表"""
|
||
__tablename__ = 'daily_stats'
|
||
|
||
id = db.Column(db.Integer, primary_key=True)
|
||
date = db.Column(db.Date, unique=True, nullable=False, index=True)
|
||
|
||
# 统计数据
|
||
total_visits = db.Column(db.Integer, default=0)
|
||
unique_ips = db.Column(db.Integer, default=0)
|
||
article_views = db.Column(db.Integer, default=0)
|
||
|
||
# 热门文章
|
||
top_article_id = db.Column(db.Integer, db.ForeignKey('articles.id'))
|
||
top_article_views = db.Column(db.Integer, default=0)
|
||
|
||
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||
|
||
def __repr__(self):
|
||
return f'<DailyStats {self.date}>'
|
||
|
||
@staticmethod
|
||
def get_stats_list(days=30):
|
||
"""获取最近N天的统计数据"""
|
||
from datetime import date, timedelta
|
||
start_date = date.today() - timedelta(days=days)
|
||
return DailyStats.query.filter(
|
||
DailyStats.date >= start_date
|
||
).order_by(DailyStats.date.desc()).all() |