Zn%&P4d`OIRFtbP6B0**@$YMO#!9+q}F658&
zGIPBy922gGzb=;~{5KUPVzn#5ja
mD2n
literal 0
HcmV?d00001
diff --git a/middleware/__pycache__/exceptions.cpython-312.pyc b/middleware/__pycache__/exceptions.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..279b97a65fdcdab7326abde88ba7073df0f31306
GIT binary patch
literal 3207
zcmbtWZ){W76~FgA|BanEfK!sNC0@x8hQ=flemG=8gR@2H|Xi%_Yyz%*$($T
zH-rU*fL3H80*P*cHWleKwy0KBsG>kzBD}!
z2dh^^^0pKeI}(y0$YKvq#17H$lj7^{)odImB_);PPE`~h#b+$rsk(CL&Z6nHH5W~n
zocb`}T!1x1N}&Tc07{Zih#aSta9koKq-9DwIqpQ7m-8G}Q3+WM^0yFKL-($t9lc(9
z2e%6;Wzbzfe`OeR?J&EDV91G5Da}f9pF2t&YBXx!dH65<3VgB;VQ{b=sY?!x7s}@M
z2=D>oCIeu3`~WU1a4gF!2K52@&@`II#0X@lu`3$c{3Tjhm3~#d6-O{MfHuaUX?V~J
zW6aM(NPQbl`aO1#eb;P8rjad8w?Dv`p}nJT~mV
z#QQVf`Do@B=Vm4*V2OsBr`|I+{=?bx?=*P`#qlzlBUc%?Xi5+@Yc!Qq#iW|1i3qS~
z2Yx#9@l^vN47I@qxf0T2XDVG$C^CC>;OQ@iW`1yI?q@f177qRRFE?%)JEcWxp}u2i
zfEsmuWaiy>o}C|g_TKfm@o}2Yss813?sXG-Zp}nhX_kbj#!`aDrirXMp}>(|uA3)(
zLeWfu6jccg0nG}zJSio+^xUbLMOw|45eZFVgcfMcO=}~!wV{D)_P27Oz`;X-_As$h
zmMuyoRf_U5Sxcuiy5u&H+#3uBLP7uQTzeq&tw4wighKm6ntiFzc};}Ire=q|GM5xj
zs+x`DtE`4ag(g=hPaZwRYn5Gc>NqcRONEDv@kyvgg!n*CuVA)tC46@4Mz3
zbB}aQ`I@u7=EvTa%*NJCWnj|z+MlYPAKw1BYV*{Z%@=L+7UXopwydLe_@z%B8|dC(
zfAHFo;n>uMrtF5M%-45j*1bCE-1SG-+KaCFQsjQ&pNr+lS@}0)GKX}toc+!#XNLJ7
zNgqkWZ{BuH_&?eE^Su*0GZk%&7fo8(Xp)Tc#Tt@7nL!f6YIV?n&9Y1B)y!
z58=NfY!Bhj7r~Hq6!Vyl>FRf7syC0d+{UA?jl7bn+&ZCtW^2uZy^-Dc#&kp5WcYCA
z$kE5)NVe`xigirKI+nw#pjbJ#0T%dT&B(#g=SFOq%EpP-&usoesQQM?uJ9x;WW>(L
zd{?$EM$zIrS{#2qZ>2#0R!+f}IfvW6iZA#Zo425Q+i-Ke>E6pP1AYGmx_-YNQ+kWN
zt(v|6ir>>(!#=3QFnLgA2KIv*C#5&}?SUQa!M{Rj`j-l<}yX
zG9Fc!DP7G1tyzeurb#jiRxCAorJ?enh278%7Swoksm2$p>H-$v!6xA`lkvE0hZjrm
zR831NEeoDxO7*Xs5r|Xx!=+t~`+K
z)!gH6H)#S9`eIUcLO0K1jQ@aM%%T^6k2dMQuPxeGTzh55B7$MQtQN=dNZSIU<9sVN
OW6SWaMFfL>uKxf?q3YcL
literal 0
HcmV?d00001
diff --git a/middleware/blog_visit_middleware.py b/middleware/blog_visit_middleware.py
new file mode 100644
index 0000000..64a671e
--- /dev/null
+++ b/middleware/blog_visit_middleware.py
@@ -0,0 +1,41 @@
+import re
+from fastapi import Request
+
+from models.blog import BlogVisit
+from service import blog_service
+from utils.blog_utils import get_user_agent_info, get_client_ip
+from config.database import SessionLocal
+from middleware.exceptions import AppException
+
+
+async def blog_visit_middleware(request: Request, call_next):
+ # 检查路径是否匹配 /blog/content/{blog_id}
+ if match := re.match(r"^/blog/content/(\d+)$", request.url.path):
+ # 获取客户端信息
+ ip = get_client_ip(request)
+ user_agent = request.headers.get("User-Agent", "")
+ os, browser = get_user_agent_info(user_agent)
+ blog_id = int(match.group(1))
+
+ # 创建访问记录
+ blog_visit = BlogVisit(
+ ip=ip,
+ os=os,
+ browser=browser,
+ uri=request.url.path,
+ blog_id=blog_id
+ )
+
+ db = SessionLocal()
+ try:
+ blog_service.add_blog_visit(db, blog_visit)
+ db.commit()
+ except Exception as e:
+ db.rollback()
+ raise AppException(f"新增博客{blog_id}访问记录失败: {e}")
+ finally:
+ db.close()
+
+ # 继续处理请求
+ response = await call_next(request)
+ return response
diff --git a/middleware/exceptions.py b/middleware/exceptions.py
new file mode 100644
index 0000000..8013846
--- /dev/null
+++ b/middleware/exceptions.py
@@ -0,0 +1,54 @@
+from fastapi import Request, HTTPException, status
+from fastapi.responses import JSONResponse
+from sqlalchemy.exc import SQLAlchemyError
+from config.logging import logger
+
+
+# 自定义异常类
+class AppException(Exception):
+ def __init__(self, message: str, details=None):
+ self.message = message
+ self.details = details
+
+
+# 全局异常处理中间件
+async def global_exception_handler(request: Request, call_next):
+ try:
+ # 记录请求信息(可选)
+ logger.info(f"请求: {request.method} {request.url}")
+ if request.query_params:
+ logger.info(f"查询参数: {dict(request.query_params)}")
+
+ response = await call_next(request)
+
+ # 记录响应信息(可选)
+ if response.status_code >= 400:
+ logger.warning(f"响应: {response.status_code}")
+
+ return response
+
+ except AppException as e:
+ # 记录业务异常
+ logger.error(f"业务异常: {e.message} - 详情: {e.details}")
+ return JSONResponse(status_code=status.HTTP_400_BAD_REQUEST,
+ content={"message": e.message, "details": e.details})
+
+ except SQLAlchemyError as e:
+ # 记录数据库异常
+ logger.critical(f"数据库异常: {str(e)}", exc_info=True)
+ return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
+ content={"message": "数据库操作失败", "details": str(e)})
+
+ except Exception as e:
+ # 记录未知异常(带堆栈信息)
+ logger.critical(f"未知异常: {str(e)}", exc_info=True)
+ return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
+ content={"code": 500, "message": "服务器内部错误", "details": str(e)})
+
+
+def get_credentials_exception() -> HTTPException:
+ return HTTPException(
+ status_code=status.HTTP_401_UNAUTHORIZED,
+ detail="Could not validate credentials",
+ headers={"WWW-Authenticate": "Bearer"},
+ )
diff --git a/models/__pycache__/base.cpython-312.pyc b/models/__pycache__/base.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..d86d7a79467c5c163af7332b4568a350f38d0198
GIT binary patch
literal 2771
zcmcgu&2Q9J5P!DUUhh}3*@PttP=W{_tE4$lN(+rZP1B|kB|#!5E0X11KN2tYIy`#=
z+osYYAvHZz4dRgW)C-58aNr0h{(!0y5la)SBB)vp+!iILUfLNu-fR%iTP=Csyf^d4
z^XC0##=oReaRN{F>aWvcl#oAh5OZwZQEMU;poDk6t6
z-juAU67_k(l&zQ&^ZAGww-QRi=S4GVC6%PlOJ>SyQCfUHYPMQwC2h4SZ5-hVO&5DZ
zC$>jjz7tykPw-LFpw(799L$>O%GN~bpdH1&W=X))bZ7&=G(zMzf)Y()CtbU9Z{7G}-EY$FBAr9&|MA+Edw;
z%f3XnbD}4GW}9WJ4rzrEJ3obKCQ=UAmxpcy?s3+1{T5@xom(pp$)EL!O
z&2W~Ey(!a#Y@I_qu>9a+mOwXBJXSLAR$yP
zklWl?j%P`bda|mP;OMFf=MoC0Fu9Nll-PN!Dh_x=nmm_zFYq68nq32@e70-+P8v>EqeJ-$pyS!AMUbGoi
zjS?K+oj@qeFndOu0w5L8iSWVb`!{nQm_;(j7eh(YSnYNjw^R(l(p(1>Tr0gqVfIiL7izONoc+^cG8EBgGQ`VJTUWa#1h#X<0Yi
zFze(}*)$QuUR0+SwX*5H{0F?uaSYQ8@&*S_woBz1EFfdKln++67na#RBp9~FjA<@S1U=d!7pg=uP4wkw3Uh
zQqUlhhORa`AWNYtX0MkS)kng{IKI^?Gs8i`G>KR*DyJQa)v3vlUr!T3&2dzys(#t=
zfgN12ADABeTm$=_JQ%ct)9ecnV5f3^15y__j(bLi9+RP`z|+4
zBrw!F3Ey7bwZ>&uxy-_er89T+8utnG1+Eu51V30uZZj!yA1p|l1crL1dBe#i`(8(l
YJN=3mxC6N1OdYv;^4&_lx_|C}0Ua4%!~g&Q
literal 0
HcmV?d00001
diff --git a/models/__pycache__/blog.cpython-312.pyc b/models/__pycache__/blog.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..95125572e4684bfc000460b801b92decac23ce97
GIT binary patch
literal 3913
zcmb7HU2Gf25kCIik$2?rN3^8KP9mdC9Xbx1rm0;ymfA?NW%)-)YSnESqXeb9%9oHl
zdXHz9dMK#EX`BK^r3!)RI6>v0uxUt@)D&@DySDRQ6wt#JknYW>DT!|_EF(Z)+L=9(
zI$Cmo61chDZ+B;JXJ@_{{w)yT8Td8-{O_ml`5ES)*s1+I>y1aBLE{o5F_I(AWE=@c
z#+h(tTnSgkop5J72~UPiuo*7FWxNTm1Lrx@z6_t>Y1@?+GX8|$!8n;dMslBLB#-Q$
zc3HX;0gAGKayC??s25P54GmJ12UM`3A&U9|4cO3dL5u~fxJk@w^4-cve>N|V$i(Ej
zRW&WAvL@T3ru9tL-}pX8KW
zGw!-gJUByU0rl8Wj-p;bSsUu3C=V!SLj^?PY23qWo8hmo^Vv|ijrE;*8w$5UwFMbfm@Knk|+hG&`h{~k_bg3Qj-+5p-mLs257SljZ(A)&{i9|t?*2&&2)FC
z)sgCdVdp^|yp*Y2{HQYf>GIV3)lW+|oTfLcr_-sSv}|(2Y9=FR^ZGL|Yvt~2_3F(^
z@vrTxH-BCE{dJJlPo^p#T+~}(bh$KF8NUW{<+FR0$+7lVp!Y54+BR7EEMpCW(ql?WWYt=QI)JI(D^F3eKv2paf8v_jry&z2K5#M+D#uWKdER+e)I)w0)`)9
z*FZ<(s2O$CHl+3+-Sw0;J=XoyR}I9PO>Z)pO=aX{(&UrLj4J7AZ2ObRGkPj*jS%D_
z;sarN@=87}6AUiXmsfMiv#GQ$6F2s~ik2K9aw<=dUrfPfLX*?<3>wGehwBG7`Ex3f
zlEbQ=%@Yon1Yot4lypMln+Q~EO%1x2Wl#1jT1GRy>;9(QU>?C#=0AIT_n&%`sPD+b
zdF@o6l0U5v)w^h^mo=H3RfgqLa85a`okA?0D-aPDQxSrO_74!}nI(T@VsGhdldqSf
z^S?0shl&T6Le1mn%F%^=KQKZkiv3H$ZQ~Q?imrVuAgEw5(HlaMAbAYLyySUQ(vD&$iVY8Sqt8;;AuTu(
zM?nw%3bydWsQ5NCv|S+Js)g{xH%gJo-BbDbpBh4MvG;+$bw(PWQA7IB0S~_s~
z*2dclBaOzx1Tf>QQFa0o3oE%KHzXF;W-bm+vmF+bCJ;9q1PRYF&r8r6-A&C?r-mnK
zAifb#v9B}^(jh^OmTh)m>j~S?uRzfWkA`*y+lbNex65%u>?rm<5L&2J+AZhvvtzxM
zRdCJLR`~)(8m$6WXiSWolJBM&_C(CW=;q{VPs%h^Z_;5;&|cIb`yg%GlQIveAo(O-
z5@t3^B!3|g6Uno13=#w}sCz*wxyr}$l~0P)m1%lep1k<*?#C;Cx&z5aN2Xl<{5PxD
zFH|mzy`KhIU}oqvpLt?a2t))nsoWb}on^Lj1yKwPZfZs6&z?^JT8Q`Jmvh^Xg)
z>P(kT6pM^Gq&i3xPrrP6L==7SXzzl6%l8E**l}%An3Cp?7{2cnyY0w;;p+ipgXwN<
zH^hTLbbM%{x#XJM4&n4;gYPQ#pc5s4?07@$*>I!h7o$j58*YTVZ|z3zO*PyW!Q}$X
zWed2Pt8kLLUh8>mT4jz)HN0?a*n^9UFBBwi&f*kb~;2R&fSw
zUt!gP0ZFuBSn~z3nv=pakvdg`3Qe&nc@B(3_M!L=2px0e%7vS&bLUrQZ^Qkflj4mAexw)0ZtOezm5jzC_8l0;-pGkG22AekD0*%tX>2$}*^DydwKsAuJ`hzM$F6hDMV`z;8I4in`zLwpVV
z9O{A5a;FjMfMS5AkfzC(7IuBt5ITyzwy;>}IAVxLX#sGVEs-l&1aunVep&u%~sI
zl^cjXA{h92o;0WI#MZ@i@vjUaT-X*VuLkd!b{Ef!Eq02j^hNp#!hA
ZD7ItkZ2{W8H3nX5J4D1EGw`Ab=zmMK9)th@
literal 0
HcmV?d00001
diff --git a/models/base.py b/models/base.py
new file mode 100644
index 0000000..af5136a
--- /dev/null
+++ b/models/base.py
@@ -0,0 +1,57 @@
+from sqlalchemy import Column, BigInteger, String, DateTime, event
+from sqlalchemy.ext.declarative import declared_attr
+
+from config.auth import context_sub
+from config.database import Base
+from datetime import datetime
+
+from utils.common import camel_to_snake
+from id_generator import options, generator
+
+# https://github.com/yitter/IdGenerator/tree/master/Python
+options = options.IdGeneratorOptions(worker_id=23)
+idgen = generator.DefaultIdGenerator()
+idgen.set_id_generator(options)
+
+
+# 第二层基类:包含ID
+class IdBase(Base):
+ __abstract__ = True
+
+ id = Column(BigInteger, primary_key=True, index=True)
+
+ @declared_attr
+ def __tablename__(cls):
+ # 自动把数据库实体类名驼峰转为数据库表名下划线
+ return camel_to_snake(cls.__name__)
+
+
+# 自动填充id
+@event.listens_for(IdBase, 'before_insert', propagate=True)
+def before_insert_listener(mapper, connection, target):
+ if target.id is None:
+ target.id = idgen.next_id()
+
+
+# 第二层基类:包含ID和审计字段
+class AuditBase(IdBase):
+ __abstract__ = True
+
+ create_time = Column(DateTime, nullable=True, default=datetime.now)
+ create_by = Column(String(255), nullable=True)
+ update_time = Column(DateTime, nullable=True, onupdate=datetime.now)
+ update_by = Column(String(255), nullable=True)
+
+
+@event.listens_for(AuditBase, 'before_insert', propagate=True)
+def before_insert(mapper, connection, target):
+ value = context_sub.get(None)
+ if value is not None:
+ target.create_by = value
+
+
+@event.listens_for(AuditBase, 'before_update', propagate=True)
+def before_update(mapper, connection, target):
+ value = context_sub.get(None)
+ if value is not None:
+ target.update_by = value
diff --git a/models/blog.py b/models/blog.py
new file mode 100644
index 0000000..bcd2957
--- /dev/null
+++ b/models/blog.py
@@ -0,0 +1,99 @@
+from sqlalchemy import (
+ BigInteger,
+ Boolean,
+ Column,
+ Integer,
+ DECIMAL,
+ SMALLINT,
+ String,
+ LargeBinary
+)
+from sqlalchemy.orm import relationship
+
+from models.base import AuditBase
+
+
+class Blog(AuditBase):
+ title = Column(String(255), nullable=True, comment="博客标题")
+ top_value = Column(Integer, nullable=True, comment="置顶值 越大越靠前")
+ is_great = Column(Boolean, nullable=True, comment="是否是精品 0否1是")
+ category_id = Column(BigInteger, nullable=True, comment="博客类别")
+ summary = Column(String(255), nullable=True, comment="博客内容概要")
+ content_id = Column(BigInteger, nullable=True, comment="博客内容")
+ word_count = Column(Integer, nullable=True, comment="字数统计")
+ read_duration = Column(DECIMAL(10, 2), nullable=True, comment="阅读时长")
+
+ category = relationship(
+ "BlogCategory",
+ back_populates="blogs",
+ primaryjoin="foreign(Blog.category_id) == BlogCategory.id"
+ )
+
+ content = relationship(
+ "BlogContent",
+ back_populates="blog",
+ primaryjoin="foreign(Blog.content_id) == BlogContent.id"
+ )
+
+ visits = relationship(
+ "BlogVisit",
+ back_populates="blog",
+ primaryjoin="Blog.id == foreign(BlogVisit.blog_id)"
+ )
+
+ comments = relationship(
+ "BlogComment",
+ back_populates="blog",
+ primaryjoin="Blog.id == foreign(BlogComment.blog_id)"
+ )
+
+
+class BlogCategory(AuditBase):
+ name = Column(String(45), nullable=True, comment="类别名称")
+
+ blogs = relationship(
+ "Blog",
+ back_populates="category",
+ primaryjoin="BlogCategory.id == foreign(Blog.category_id)"
+ )
+
+
+class BlogContent(AuditBase):
+ content = Column(LargeBinary, comment="博客内容")
+
+ blog = relationship(
+ "Blog",
+ back_populates="content",
+ primaryjoin="BlogContent.id == foreign(Blog.content_id)"
+ )
+
+
+class BlogVisit(AuditBase):
+ ip = Column(String(255), nullable=True, comment="ip地址")
+ os = Column(String(255), nullable=True, comment="操作系统")
+ browser = Column(String(255), nullable=True, comment="浏览器")
+ uri = Column(String(255), nullable=True, comment="路径")
+ blog_id = Column(BigInteger, nullable=True, comment="博客id")
+
+ blog = relationship(
+ "Blog",
+ back_populates="visits",
+ primaryjoin="foreign(BlogVisit.blog_id) == Blog.id"
+ )
+
+
+class BlogComment(AuditBase):
+ blog_id = Column(BigInteger, comment="博客id")
+ parent_id = Column(BigInteger, comment="父评论id")
+ name = Column(String(255), comment="评论人昵称")
+ website = Column(String(255), nullable=True, comment="评论人网站")
+ ip_address = Column(String(45), nullable=True, comment="评论人ip")
+ user_agent = Column(String(255), nullable=True, comment="评论人浏览器信息")
+ content = Column(String(512), comment="评论内容")
+ is_approved = Column(SMALLINT, comment="是否通过")
+
+ blog = relationship(
+ "Blog",
+ back_populates="comments",
+ primaryjoin="foreign(BlogComment.blog_id) == Blog.id"
+ )
diff --git a/packages/PyJWT-2.10.1-py3-none-any.whl b/packages/PyJWT-2.10.1-py3-none-any.whl
new file mode 100644
index 0000000000000000000000000000000000000000..6195c57682405cded6020754dbf8111489923b9a
GIT binary patch
literal 22997
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 {H|6bO-iLuvIGgk4h!GQSi9AC{
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