Files
WeChatDataAnalysis/src/wechat_decrypt_tool/routers/wrapped.py
2977094657 77a60bde70 feat(wrapped): 年度总结支持目录/单卡片接口,新增卡片#0/#2
- 新增 /api/wrapped/annual/meta 与 /api/wrapped/annual/cards/{card_id},用于前端懒加载单页卡片
- 增加卡片 manifest / 缓存版本控制 / 并发锁,避免重复计算与旧缓存串数据
- 新增 Card#0「年度全局概览」:活跃天数、top 联系人/群、常用表达/金句/表情等汇总
- 新增 Card#2「年度消息字数」:收发字数统计 + 类比呈现 + 键盘敲击统计
- 完善 Card#1 赛博作息表:支持更快的索引计算与更丰富的叙事文案
2026-01-31 14:54:11 +08:00

56 lines
2.7 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.
from __future__ import annotations
import asyncio
from typing import Optional
from fastapi import APIRouter, HTTPException, Path, Query
from ..path_fix import PathFixRoute
from ..wrapped.service import build_wrapped_annual_card, build_wrapped_annual_meta, build_wrapped_annual_response
router = APIRouter(route_class=PathFixRoute)
@router.get("/api/wrapped/annual", summary="微信聊天年度总结WeChat Wrapped- 后端数据")
async def wrapped_annual(
year: Optional[int] = Query(None, description="年份(例如 2026。默认当前年份。"),
account: Optional[str] = Query(None, description="解密后的账号目录名。默认取第一个可用账号。"),
refresh: bool = Query(False, description="是否强制重新计算(忽略缓存)。"),
):
"""返回年度总结完整数据(一次性包含全部卡片,可能较慢)。"""
# This endpoint performs blocking sqlite/file IO, so run it in a worker thread.
return await asyncio.to_thread(build_wrapped_annual_response, account=account, year=year, refresh=refresh)
@router.get("/api/wrapped/annual/meta", summary="微信聊天年度总结WeChat Wrapped- 目录(轻量)")
async def wrapped_annual_meta(
year: Optional[int] = Query(None, description="年份(例如 2026。默认当前年份。"),
account: Optional[str] = Query(None, description="解密后的账号目录名。默认取第一个可用账号。"),
refresh: bool = Query(False, description="是否强制重新计算(忽略缓存)。"),
):
"""返回年度总结的目录/元信息,用于前端懒加载每一页。"""
return await asyncio.to_thread(build_wrapped_annual_meta, account=account, year=year, refresh=refresh)
@router.get("/api/wrapped/annual/cards/{card_id}", summary="微信聊天年度总结WeChat Wrapped- 单张卡片(按页加载)")
async def wrapped_annual_card(
card_id: int = Path(..., description="卡片ID与前端页面一一对应", ge=0),
year: Optional[int] = Query(None, description="年份(例如 2026。默认当前年份。"),
account: Optional[str] = Query(None, description="解密后的账号目录名。默认取第一个可用账号。"),
refresh: bool = Query(False, description="是否强制重新计算(忽略缓存)。"),
):
"""按卡片 ID 返回单页数据(避免首屏一次性计算全部卡片)。"""
try:
return await asyncio.to_thread(
build_wrapped_annual_card,
account=account,
year=year,
card_id=card_id,
refresh=refresh,
)
except ValueError as e:
raise HTTPException(status_code=404, detail=str(e)) from e