Files

78 lines
2.8 KiB
Python
Raw Permalink Normal View History

2026-06-30 14:29:02 +08:00
from __future__ import annotations
from pathlib import Path
from fastapi import FastAPI, File, HTTPException, Request, UploadFile
from fastapi.responses import FileResponse, HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from pydantic import BaseModel, Field
from .config import ROOT_DIR
from .job_service import analyze_attachment_urls, job_store, process_uploads
app = FastAPI(title="PCF 焊接数据导入生成工具")
templates = Jinja2Templates(directory=str(ROOT_DIR / "templates"))
app.mount("/static", StaticFiles(directory=str(ROOT_DIR / "static")), name="static")
class ParseUrlRequest(BaseModel):
attachment_url: str | None = Field(default=None, description="单个附件 URL,支持 .pcf 或 .zip")
attachment_urls: list[str] | None = Field(default=None, description="多个附件 URL,支持 .pcf 或 .zip")
def urls(self) -> list[str]:
urls: list[str] = []
if self.attachment_url:
urls.append(self.attachment_url)
if self.attachment_urls:
urls.extend(self.attachment_urls)
return [url for url in urls if url]
@app.get("/", response_class=HTMLResponse)
async def index(request: Request):
return templates.TemplateResponse("index.html", {"request": request})
@app.post("/api/jobs")
async def create_job(files: list[UploadFile] = File(...)):
if not files:
raise HTTPException(status_code=400, detail="请至少上传一个 PCF 文件")
result = await process_uploads(files)
return result.to_public_dict()
@app.post("/api/AnalysisPcf")
async def analysis_pcf(request: ParseUrlRequest):
urls = request.urls()
if not urls:
raise HTTPException(status_code=400, detail="请提供 attachment_url 或 attachment_urls")
return await analyze_attachment_urls(urls)
@app.get("/api/jobs/{job_id}")
async def get_job(job_id: str):
result = job_store.get(job_id)
if not result:
raise HTTPException(status_code=404, detail="任务不存在或服务已重启")
return result.to_public_dict()
@app.get("/api/jobs/{job_id}/download/{kind}")
async def download(job_id: str, kind: str):
result = job_store.get(job_id)
if not result:
raise HTTPException(status_code=404, detail="任务不存在或服务已重启")
files = {
"xls": (result.output_xls, "application/vnd.ms-excel"),
"issues": (result.issues_csv, "text/csv; charset=utf-8"),
"report": (result.report_json, "application/json"),
}
if kind not in files:
raise HTTPException(status_code=404, detail="下载类型不存在")
path, media_type = files[kind]
if not Path(path).exists():
raise HTTPException(status_code=404, detail="文件不存在")
return FileResponse(path, media_type=media_type, filename=Path(path).name)