main.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. from pathlib import Path
  2. from fastapi import FastAPI, HTTPException
  3. from fastapi.responses import FileResponse
  4. from fastapi.staticfiles import StaticFiles
  5. from app.market import MarketService
  6. from app.market.models import InquiryRequest
  7. from app.mock_data import LocalMockDataService, MockBatchRequest
  8. from app.repository import RDFRepository
  9. app = FastAPI(title="格士立全球运输与AI市场接口")
  10. ROOT = Path(__file__).resolve().parents[1]
  11. QUERIES = ROOT / "queries"
  12. STATIC = ROOT / "app" / "static"
  13. repository = RDFRepository(ROOT)
  14. market_service = MarketService(ROOT, repository)
  15. mock_data_service = LocalMockDataService(ROOT, repository, market_service)
  16. app.mount("/static", StaticFiles(directory=STATIC), name="static")
  17. @app.get("/health")
  18. def health():
  19. return {
  20. "status": "ok",
  21. "data_backend": "local",
  22. "triple_count": repository.triple_count,
  23. "in_memory_triple_count": repository.in_memory_triple_count,
  24. "loaded_files": repository.loaded_file_names,
  25. }
  26. @app.get("/")
  27. def index():
  28. return FileResponse(STATIC / "index.html")
  29. @app.get("/api/orders")
  30. def orders():
  31. return query_file("order-status.rq")
  32. @app.get("/api/risks")
  33. def risks():
  34. return query_file("risk-orders.rq")
  35. @app.get("/api/flow")
  36. def flow():
  37. return query_file("operation-flow.rq")
  38. @app.get("/api/node-times")
  39. def node_times():
  40. return query_file("node-time-status.rq")
  41. @app.get("/api/order-cutoffs")
  42. def order_cutoffs():
  43. return query_file("order-cutoff-times.rq")
  44. @app.get("/api/exception-map")
  45. def exception_map():
  46. return query_file("exception-risk-map.rq")
  47. @app.get("/api/market/customers")
  48. def market_customers():
  49. return {"rows": market_service.customers()}
  50. @app.get("/api/market/form-options")
  51. def market_form_options():
  52. return market_service.form_options()
  53. @app.post("/api/market/recommend")
  54. def market_recommend(inquiry: InquiryRequest):
  55. try:
  56. return market_service.recommend(inquiry)
  57. except ValueError as exc:
  58. raise HTTPException(status_code=422, detail=str(exc)) from exc
  59. @app.get("/api/market/recommendations/{run_id}")
  60. def market_recommendation(run_id: str):
  61. result = market_service.get_run(run_id)
  62. if not result:
  63. raise HTTPException(status_code=404, detail="推荐任务不存在或服务已经重启")
  64. return result
  65. @app.get("/api/market/recommendations/{run_id}/audit")
  66. def market_recommendation_audit(run_id: str):
  67. result = market_service.get_audit(run_id)
  68. if not result:
  69. raise HTTPException(status_code=404, detail="推荐任务审计记录不存在")
  70. return result
  71. @app.get("/api/mock/catalog")
  72. def mock_catalog():
  73. return mock_data_service.catalog()
  74. @app.post("/api/mock/generate")
  75. def mock_generate(request: MockBatchRequest):
  76. try:
  77. return mock_data_service.generate(request)
  78. except ValueError as exc:
  79. raise HTTPException(status_code=422, detail=str(exc)) from exc
  80. @app.post("/api/mock/reset")
  81. def mock_reset():
  82. return mock_data_service.reset()
  83. def query_file(filename: str):
  84. path = QUERIES / filename
  85. if not path.exists():
  86. raise HTTPException(status_code=404, detail=f"Query file not found: {filename}")
  87. try:
  88. return repository.query_file(path)
  89. except Exception as exc:
  90. raise HTTPException(
  91. status_code=500,
  92. detail=f"本地RDF查询执行失败: {filename}",
  93. ) from exc