from fastapi import APIRouter, UploadFile, File, HTTPException from sse_starlette.sse import EventSourceResponse import uuid import os import json import asyncio from app.schemas.compliance import ( AnalyzeResponse, ComplianceChatRequest, ) from app.services.mock_data import ( generate_task_id, get_mock_compliance_result, get_mock_compliance_chat_response, ) router = APIRouter(prefix="/compliance", tags=["合规分析"]) # 临时存储分析任务 tasks_store: dict[str, dict] = {} @router.post("/analyze", response_model=AnalyzeResponse) async def analyze_document(file: UploadFile = File(...)): """上传设计方案进行分析""" # 生成任务ID task_id = generate_task_id() # 保存文件 raw_dir = "/airegulation/demo-mao/backend/data/raw" os.makedirs(raw_dir, exist_ok=True) file_path = os.path.join(raw_dir, f"compliance_{task_id}_{file.filename}") content = await file.read() with open(file_path, "wb") as f: f.write(content) # 记录任务 tasks_store[task_id] = { "task_id": task_id, "file_path": file_path, "status": "processing", "result": None, } # 模拟异步处理完成(立即返回结果) # 实际应用中这应该是后台任务 tasks_store[task_id]["status"] = "completed" tasks_store[task_id]["result"] = get_mock_compliance_result(task_id) return AnalyzeResponse(task_id=task_id) @router.get("/result/{task_id}") async def get_result(task_id: str): """获取分析结果""" if task_id not in tasks_store: # 如果任务ID不存在,返回默认mock结果 return get_mock_compliance_result(task_id) task = tasks_store[task_id] if task["status"] == "processing": return {"status": "processing", "message": "分析进行中"} return task["result"] @router.post("/chat/{segment_id}") async def compliance_chat(segment_id: int, request: ComplianceChatRequest): """针对段落进行合规对话""" # 根据segment_id获取对应的intent intent_map = { 1: "车身结构设计", 2: "动力系统配置", 3: "安全配置设计", } intent = intent_map.get(segment_id, "车身结构设计") async def generate(): # 获取预设响应 response = get_mock_compliance_chat_response(intent, request.query) # 流式输出响应 sentences = response.split("\n\n") for sentence in sentences: if sentence.strip(): chunks = sentence.split("\n") for chunk in chunks: if chunk.strip(): await asyncio.sleep(0.05) yield {"event": "message", "data": json.dumps({"type": "chunk", "text": chunk + "\n"})} yield {"event": "message", "data": json.dumps({"type": "done"})} return EventSourceResponse(generate())