|
@@ -0,0 +1,115 @@
|
|
|
+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
|