初始化技术博客项目
功能特性: - 前端文章展示 (Markdown渲染、代码高亮) - 后台管理系统 (文章、分类、标签、作者管理) - 图片上传 (点击、拖拽、粘贴) - 网站设置 (Logo、底部宣传图片上传) - 访问统计 (IP记录、趋势图表) - 参考来源、附件支持 - 单端口部署 (16012) 技术栈: - Flask 3.0 + SQLAlchemy - SQLite数据库 - marked.js + highlight.js (Markdown渲染) - Chart.js (统计图表)
This commit is contained in:
83
app/models/visit_log.py
Normal file
83
app/models/visit_log.py
Normal file
@@ -0,0 +1,83 @@
|
||||
"""访问统计模型"""
|
||||
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()
|
||||
Reference in New Issue
Block a user