"""角色卡导入 / 导出 API。 rewrite/1.0 M2b:导入产出**可审阅灵胚**(含 character_book 暂存),不再直接建人物; 经照心编辑与启镜(POST /embryo-drafts/{id}/activate)后才物化人物与世谱。 """ import json from fastapi import APIRouter, Depends, File, Response, UploadFile from app.api.v1.deps import get_current_user from app.domains import jingsheng from app.schemas.auth import CurrentUser from app.services.card_import import card_to_embryo_payload, export_character_card router = APIRouter(prefix="/characters", tags=["characters"]) @router.post("/import-card", status_code=201) async def import_character_card_api( file: UploadFile = File(..., description="角色卡文件,支持 .png / .json / .charx。"), current_user: CurrentUser = Depends(get_current_user), ) -> dict: """导入酒馆角色卡(V1/V2/V3)→ 生成可审阅灵胚。 卡内容整体进入灵胚道体草稿(identity_baseline.import_card), ``character_book`` 在启镜时物化为该人物的世谱书与条目。 """ raw = await file.read() payload = card_to_embryo_payload(raw) book_entry_count = payload.pop("book_entry_count") embryo = await jingsheng.create_embryo( owner_scope=current_user.owner_scope, source="imported", name=payload["name"], description=payload["description"], identity_baseline=payload["identity_baseline"], ) return { "embryo_id": embryo.id, "status": embryo.status, "name": embryo.name, "source": embryo.source, "book_entry_count": book_entry_count, "next": "照心编辑 PATCH /embryo-drafts/{id},启镜 POST /embryo-drafts/{id}/activate", } @router.get("/{character_id}/export-card") async def export_character_card_api( character_id: str, current_user: CurrentUser = Depends(get_current_user), ) -> Response: """导出人物为 ST V3 卡静态快照(.json,丢弃演化维度)。""" card = await export_character_card(character_id, owner_scope=current_user.owner_scope) return Response( content=json.dumps(card, ensure_ascii=False, indent=2), media_type="application/json", headers={"Content-Disposition": 'attachment; filename="character_card.json"'}, )