PayrollManagementSystem/backend/app/core/redis_client.py
liuwenxin 273ebf4657 chore: 初始化项目结构与登录鉴权模块
后端 FastAPI 六层结构(api/services/repositories/models/schemas/core),
统一响应信封、全局异常、日志脱敏;6 张表经 Alembic 迁移建库,SQL 留存
db/migration;登录鉴权含图形验证码(Redis GETDEL 防重放)、JWT、登录限流、
登出黑名单(TTL=令牌剩余有效期)、登录日志。

前端 Vue3 + TS + Element Plus 骨架,含登录页、路由守卫、请求封装与 Vite 代理。

工程配置:uv 锁定 Python 3.12、ruff 检查与格式化、editorconfig、gitattributes。

测试 184 项(单元 155 / 集成 29)全绿,浏览器端到端 8 项通过。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-09 18:46:36 +08:00

42 lines
1.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Redis 连接管理。
承担三类职责:图形验证码、登录失败限流、JWT 登出黑名单。
键名模板统一在 `app.core.constants` 中定义,禁止在业务代码里拼接字符串。
与其他基础设施一致采用**同步客户端**:路由写 `def` 由 FastAPI 放入线程池执行。
若 DB 同步而 Redis 异步,同一请求里就会出现"要么路由必须写 async(于是同步 DB
阻塞事件循环)、要么把 Redis 调用包进 run_in_threadpool"的两难,两头都别扭。
"""
from redis import Redis
from app.core.config import get_settings
_client: Redis | None = None
def get_redis() -> Redis:
"""获取 Redis 客户端单例(首次调用时创建)。
延迟创建:Redis 未启动时不影响应用启动。
返回的是**同步**客户端,直接调用即可,不要 await。
"""
global _client
if _client is None:
settings = get_settings()
_client = Redis.from_url(
settings.redis_url,
encoding="utf-8",
decode_responses=True,
socket_connect_timeout=3,
)
return _client
def close_redis() -> None:
"""关闭连接池。应用退出时调用。"""
global _client
if _client is not None:
_client.close()
_client = None