from fastapi import APIRouter, Depends, HTTPException, Request from typing import Optional, List from pydantic import BaseModel from model.response import StandardResponse from db.session import get_db from sqlalchemy.orm import Session from service.kg_node_service import KGNodeService from service.kg_edge_service import KGEdgeService from service.kg_prop_service import KGPropService import logging from utils.ObjectToJsonArrayConverter import ObjectToJsonArrayConverter router = APIRouter(prefix="/v1/knowledge", tags=["SaaS Knowledge Base"]) logger = logging.getLogger(__name__) class PaginatedSearchRequest(BaseModel): name: str distance: float = 1.45 category: Optional[str] = None pageNo: int = 1 limit: int = 10 async def get_request_id(request: Request): return request.state.context["request_id"] @router.post("/nodes/paginated_search", response_model=StandardResponse) async def paginated_search( payload: PaginatedSearchRequest, db: Session = Depends(get_db), request_id: str = Depends(get_request_id) ): try: service = KGNodeService(db) search_params = { 'keyword': payload.name, 'category': payload.category, 'pageNo': payload.pageNo, 'limit': payload.limit, 'load_props': True, 'distance': 2.0-payload.distance, } result = service.paginated_search(search_params) #result[data]的distance属性去掉 for item in result['records']: item.pop('distance', None) #result[pagination]去掉 result.pop('pagination', None) #result[records]改为result[nodes] result['nodes'] = result['records'] result.pop('records', None) return StandardResponse( success=True, requestId=request_id, data=ObjectToJsonArrayConverter.convert(result) ) except Exception as e: logger.error(f"分页查询失败: {str(e)}") raise HTTPException( status_code=500, detail=StandardResponse( success=False, error_code=500, error_msg=str(e) ) ) @router.get("/nodes/{src_id}/relationships", response_model=StandardResponse) async def get_node_relationships( src_id: int, db: Session = Depends(get_db), request_id: str = Depends(get_request_id) ): try: edge_service = KGEdgeService(db) prop_service = KGPropService(db) edges = edge_service.get_edges_by_nodes(src_id=src_id, dest_id=None) relationships = [] #count = 0 for edge in edges: #if count >= 2: #break dest_node = edge['dest_node'] dest_props = [] edge_props = [] #count += 1 #dest_props = [{'prop_title': p['prop_title'], 'prop_value': p['prop_value']} # for p in prop_service.get_props_by_ref_id(dest_node['id'])] #edge_props = [{'prop_title': p['prop_title'], 'prop_value': p['prop_value']} # for p in prop_service.get_props_by_ref_id(edge['id'])] relationships.append({ "name": edge['name'], "props": edge_props, "destNode": { "category": dest_node['category'], "id": str(dest_node['id']), "name": dest_node['name'], "props": dest_props } }) return StandardResponse( success=True, requestId=request_id, data=ObjectToJsonArrayConverter.convert({"relationships": relationships}) ) except Exception as e: logger.error(f"获取节点关系失败: {str(e)}") raise HTTPException(500, detail=StandardResponse.error(str(e))) knowledge_nodes_api_router = router