import logging from uuid import UUID from fastapi import APIRouter, Depends, HTTPException, Query from psycopg import AsyncConnection from app.auth.project_dependencies import get_project_pg_connection from app.domain.schemas.gis_attributes import ( ElementGisProperties, GisElementType, SourceGisFeatureProperties, ) from app.infra.db.postgresql.analysis import AnalysisRepository from app.infra.db.postgresql.gis_attributes import GisAttributeRepository router = APIRouter() logger = logging.getLogger(__name__) @router.get( "/source-gis/layers/{layer_key}/features/{source_fid}/properties", response_model=SourceGisFeatureProperties, summary="获取源 GIS 要素台账属性", ) async def get_source_gis_feature_properties( layer_key: str, source_fid: int, conn: AsyncConnection = Depends(get_project_pg_connection), ): normalized_layer_key = layer_key.strip() if ( not normalized_layer_key or len(normalized_layer_key) > 80 or source_fid < 0 ): raise HTTPException(status_code=422, detail="无效的源 GIS 要素编号") try: group = await GisAttributeRepository.get_source_feature_group( conn, normalized_layer_key, source_fid, ) if group is None: raise HTTPException(status_code=404, detail="源 GIS 要素不存在") return SourceGisFeatureProperties( layer_key=normalized_layer_key, source_fid=source_fid, group=group, ) except HTTPException: raise except Exception as exc: logger.warning("Source GIS feature properties are unavailable", exc_info=True) raise HTTPException(status_code=500, detail="查询源 GIS 要素属性失败") from exc @router.get( "/elements/{element_type}/{element_id}/gis-properties", response_model=ElementGisProperties, summary="获取元素 GIS 台账属性", ) async def get_element_gis_properties( element_type: GisElementType, element_id: str, conn: AsyncConnection = Depends(get_project_pg_connection), ): """Return source GIS records linked to one current-project map element.""" normalized_id = element_id.strip() if not normalized_id or len(normalized_id) > 160: raise HTTPException(status_code=422, detail="无效的元素编号") try: groups = await GisAttributeRepository.list_element_groups( conn, element_type, normalized_id, ) return ElementGisProperties( element_type=element_type, element_id=normalized_id, groups=groups, ) except Exception as exc: logger.warning("Element GIS properties are unavailable", exc_info=True) raise HTTPException(status_code=500, detail="查询 GIS 台账属性失败") from exc @router.get("/analysis/runs", summary="获取分析运行列表") async def get_analysis_runs( limit: int = Query(default=100, ge=1, le=100), offset: int = Query(default=0, ge=0), conn: AsyncConnection = Depends(get_project_pg_connection), ): """分页返回当前项目的持久分析运行。""" try: runs = await AnalysisRepository.list_runs(conn, limit=limit, offset=offset) return { "success": True, "data": runs, "count": len(runs), "limit": limit, "offset": offset, } except Exception as exc: logger.warning("Analysis run page is unavailable", exc_info=True) raise HTTPException(status_code=500, detail="查询分析运行失败") from exc @router.get("/analysis/runs/{run_id}", summary="获取分析运行") async def get_analysis_run( run_id: UUID, conn: AsyncConnection = Depends(get_project_pg_connection), ): """返回当前项目的一条持久分析运行。""" try: run = await AnalysisRepository.get_run(conn, run_id) if run is None: raise HTTPException(status_code=404, detail="分析运行不存在") return run except HTTPException: raise except Exception as exc: logger.warning("Analysis run is unavailable", exc_info=True) raise HTTPException(status_code=500, detail="查询分析运行失败") from exc @router.get("/analysis/runs/{run_id}/results", summary="获取分析结果") async def get_analysis_results( run_id: UUID, result_type: str | None = Query(default=None, description="结果类型"), limit: int = Query(default=100, ge=1, le=500), offset: int = Query(default=0, ge=0), conn: AsyncConnection = Depends(get_project_pg_connection), ): """分页返回一条分析运行的持久结果。""" try: return await AnalysisRepository.list_results( conn, run_id, result_type, limit=limit, offset=offset, ) except Exception as exc: logger.warning("Analysis result page is unavailable", exc_info=True) raise HTTPException( status_code=500, detail="查询分析结果失败", ) from exc