docs(uiux): UIUX 设计方案大改 + 5 份作业指导书对齐 + 开发任务文档
- UIUX 文档:填充 19 个缺口(多主体画像/健康度/AI+看板/增长域/洞察域/创始人端/OODA/助推/商密) - UIUX 文档:插入 6 个新章节(十四~十九),旧章节重编号为二十~三十一,更新目录和交叉引用 - 作业指导书 x5:导航改为 6 域分组,新增 Context Bar/工作模式/Insight Rail/决策线程/多工作区等 UI 概念 - 新建 docs/2-task-uiux.md:50 个代码落地开发任务,按 P0-P6 分优先级 + 8 Sprint 规划 - 后端/前端:大量新增模型、路由、组件(来自之前 Phase 开发)
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
"""限流中间件 — 登录 5 次/min + 写接口按用户限流。"""
|
||||
|
||||
import time
|
||||
from collections import defaultdict
|
||||
|
||||
from fastapi import HTTPException, Request, status
|
||||
|
||||
|
||||
class RateLimiter:
|
||||
"""简单的内存限流器。"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
self._requests: dict[str, list[float]] = defaultdict(list)
|
||||
|
||||
def check(self, key: str, max_requests: int, window_seconds: int) -> bool:
|
||||
"""检查是否超过限流阈值。"""
|
||||
now = time.time()
|
||||
window_start = now - window_seconds
|
||||
|
||||
# 清理过期记录
|
||||
self._requests[key] = [t for t in self._requests[key] if t > window_start]
|
||||
|
||||
if len(self._requests[key]) >= max_requests:
|
||||
return False
|
||||
|
||||
self._requests[key].append(now)
|
||||
return True
|
||||
|
||||
|
||||
rate_limiter = RateLimiter()
|
||||
|
||||
|
||||
async def login_rate_limit(request: Request) -> None:
|
||||
"""登录接口限流 — 5 次/min/IP。"""
|
||||
client_ip = request.client.host if request.client else "unknown"
|
||||
if not rate_limiter.check(f"login:{client_ip}", max_requests=5, window_seconds=60):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_429_TOO_MANY_REQUESTS,
|
||||
detail="登录尝试过于频繁,请稍后再试",
|
||||
headers={"Retry-After": "60"},
|
||||
)
|
||||
Reference in New Issue
Block a user