feat: add pcf analysis web app and api
This commit is contained in:
+77
@@ -0,0 +1,77 @@
|
||||
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)
|
||||
Reference in New Issue
Block a user