mirror of
https://github.com/LifeArchiveProject/WeChatDataAnalysis.git
synced 2026-02-20 06:40:49 +08:00
feat(wrapped): 年度总结支持目录/单卡片接口,新增卡片#0/#2
- 新增 /api/wrapped/annual/meta 与 /api/wrapped/annual/cards/{card_id},用于前端懒加载单页卡片
- 增加卡片 manifest / 缓存版本控制 / 并发锁,避免重复计算与旧缓存串数据
- 新增 Card#0「年度全局概览」:活跃天数、top 联系人/群、常用表达/金句/表情等汇总
- 新增 Card#2「年度消息字数」:收发字数统计 + 类比呈现 + 键盘敲击统计
- 完善 Card#1 赛博作息表:支持更快的索引计算与更丰富的叙事文案
This commit is contained in:
@@ -3,10 +3,10 @@ from __future__ import annotations
|
||||
import asyncio
|
||||
from typing import Optional
|
||||
|
||||
from fastapi import APIRouter, Query
|
||||
from fastapi import APIRouter, HTTPException, Path, Query
|
||||
|
||||
from ..path_fix import PathFixRoute
|
||||
from ..wrapped.service import build_wrapped_annual_response
|
||||
from ..wrapped.service import build_wrapped_annual_card, build_wrapped_annual_meta, build_wrapped_annual_response
|
||||
|
||||
router = APIRouter(route_class=PathFixRoute)
|
||||
|
||||
@@ -17,7 +17,39 @@ async def wrapped_annual(
|
||||
account: Optional[str] = Query(None, description="解密后的账号目录名。默认取第一个可用账号。"),
|
||||
refresh: bool = Query(False, description="是否强制重新计算(忽略缓存)。"),
|
||||
):
|
||||
"""返回年度总结数据(目前仅实现第 1 个点子:年度赛博作息表)。"""
|
||||
"""返回年度总结完整数据(一次性包含全部卡片,可能较慢)。"""
|
||||
|
||||
# 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
|
||||
|
||||
Reference in New Issue
Block a user