init the project

This commit is contained in:
evyzacq
2026-05-25 15:09:42 +08:00
commit 7fc0e7852e
122 changed files with 14557 additions and 0 deletions
+81
View File
@@ -0,0 +1,81 @@
# PRD 上传与解析接口
import logging
from concurrent.futures import ThreadPoolExecutor
from fastapi import APIRouter, UploadFile, File, HTTPException
from server.services.prd_manager.service import prd_service
logger = logging.getLogger(__name__)
router = APIRouter()
ALLOWED_EXTENSIONS = {".md", ".txt", ".docx", ".pdf"}
_parse_executor = ThreadPoolExecutor(max_workers=2)
@router.post("/upload")
async def upload_prd(file: UploadFile = File(...)):
"""上传 PRD 文件,立即返回 PRD ID,后台异步解析"""
ext = "." + file.filename.rsplit(".", 1)[-1].lower() if "." in file.filename else ""
if ext not in ALLOWED_EXTENSIONS:
raise HTTPException(400, f"不支持的文件格式: {ext},支持: {', '.join(ALLOWED_EXTENSIONS)}")
content = await file.read()
if len(content) == 0:
raise HTTPException(400, "文件为空")
try:
# Quick: save and return immediately
prd_version = await prd_service.upload_quick(file.filename, content)
# Background: parse async (image analysis may take 60s+)
_parse_executor.submit(_parse_in_background, prd_version["prd_id"], file.filename, content)
return {
"prd_id": prd_version["prd_id"],
"filename": prd_version["filename"],
"status": "parsing",
"uploaded_at": prd_version["uploaded_at"],
}
except Exception as e:
logger.error("PRD upload failed: %s", e)
raise HTTPException(500, f"上传失败: {e}")
def _parse_in_background(prd_id: str, filename: str, content: bytes):
"""Run full parsing (text + images + vision analysis) in background thread."""
import asyncio
try:
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(prd_service.parse_async(prd_id, filename, content))
except Exception as e:
logger.error("Background parse failed for %s: %s", prd_id, e)
prd_service.set_status(prd_id, "error", str(e))
@router.get("/{prd_id}/status")
async def get_prd_status(prd_id: str):
"""获取 PRD 解析状态"""
status = await prd_service.get_status(prd_id)
if not status:
raise HTTPException(404, "PRD not found")
return status
@router.get("/{prd_id}")
async def get_prd(prd_id: str):
"""获取 PRD 详情与版本"""
prd = await prd_service.get_prd(prd_id)
if not prd:
raise HTTPException(404, "PRD not found")
return {
"prd_id": prd["prd_id"],
"filename": prd["filename"],
"status": prd.get("status", "ready"),
"full_text": prd.get("full_text", ""),
"sections": prd.get("sections", []),
"images": prd.get("images", []),
"uploaded_at": prd["uploaded_at"],
}