api.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. import os
  2. import shutil
  3. from uuid import uuid4
  4. from typing import Dict, Any, List
  5. from fastapi import FastAPI, UploadFile, File, Form
  6. from fastapi.middleware.cors import CORSMiddleware
  7. from fastapi.responses import HTMLResponse
  8. from fastapi.staticfiles import StaticFiles
  9. from backend.db import (
  10. init_case_db,
  11. upsert_case_management,
  12. list_case_management,
  13. delete_case_management,
  14. store_case_record,
  15. update_case_materials,
  16. fetch_case_management,
  17. fetch_case_record,
  18. parse_case_description
  19. )
  20. from backend.text_utils import save_uploads, list_files_by_ext
  21. from backend.services import (
  22. extract_application_text,
  23. extract_transcript_text,
  24. process_case_text_with_evidence,
  25. build_case_summary_text
  26. )
  27. from tools.documents_extractor import DocumentReader
  28. from application_extractor.rectify_OCR_result import RectifyClient_application
  29. from transcript_extractor.rectify_transcript import RectifyClient_transcript
  30. from law_rag.run import law_rag_run
  31. CASE_CACHE: Dict[str, Dict[str, Any]] = {}
  32. def build_file_items(file_paths: List[str], uploads_dir: str) -> List[Dict[str, str]]:
  33. items = []
  34. for path in file_paths:
  35. rel_path = os.path.relpath(path, uploads_dir).replace("\\", "/")
  36. items.append({"name": os.path.basename(path), "url": f"/uploads/{rel_path}"})
  37. return items
  38. def create_app() -> FastAPI:
  39. app = FastAPI()
  40. app.add_middleware(
  41. CORSMiddleware,
  42. allow_origins=["*"],
  43. allow_credentials=True,
  44. allow_methods=["*"],
  45. allow_headers=["*"]
  46. )
  47. root_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
  48. frontend_dir = os.path.join(root_dir, "frontend")
  49. uploads_dir = os.path.join(root_dir, "uploads")
  50. os.makedirs(uploads_dir, exist_ok=True)
  51. if os.path.exists(frontend_dir):
  52. app.mount("/assets", StaticFiles(directory=frontend_dir), name="assets")
  53. @app.get("/", response_class=HTMLResponse)
  54. def serve_index():
  55. with open(os.path.join(frontend_dir, "index.html"), "r", encoding="utf-8") as f:
  56. return f.read()
  57. app.mount("/uploads", StaticFiles(directory=uploads_dir), name="uploads")
  58. @app.post("/api/arbitration/submit")
  59. async def arbitration_submit(
  60. case_id: str = Form(...),
  61. case_title: str = Form(""),
  62. applicationFile: List[UploadFile] = File(default_factory=list),
  63. transcriptFile: List[UploadFile] = File(default_factory=list),
  64. evidenceWage: List[UploadFile] = File(default_factory=list),
  65. evidenceTerminate: List[UploadFile] = File(default_factory=list),
  66. evidenceAttendance: List[UploadFile] = File(default_factory=list),
  67. evidenceLabor: List[UploadFile] = File(default_factory=list),
  68. evidenceBank: List[UploadFile] = File(default_factory=list),
  69. evidenceList: List[UploadFile] = File(default_factory=list),
  70. evidenceWitness: List[UploadFile] = File(default_factory=list),
  71. evidenceOther: List[UploadFile] = File(default_factory=list)
  72. ):
  73. init_case_db()
  74. case_dir = os.path.join(uploads_dir, case_id)
  75. application_dir = os.path.join(case_dir, "申请书")
  76. transcript_dir = os.path.join(case_dir, "庭审笔录")
  77. evidence_dir = os.path.join(case_dir, "证据")
  78. application_paths = await save_uploads(applicationFile, application_dir)
  79. transcript_paths = await save_uploads(transcriptFile, transcript_dir)
  80. evidence_map = {
  81. "工资单": evidenceWage,
  82. "解除劳动关系相关材料": evidenceTerminate,
  83. "考勤表": evidenceAttendance,
  84. "劳动关系证明材料": evidenceLabor,
  85. "银行流水": evidenceBank,
  86. "证据清单": evidenceList,
  87. "证人证言": evidenceWitness,
  88. "其他文字材料": evidenceOther
  89. }
  90. evidence_files = {}
  91. for category, files in evidence_map.items():
  92. file_paths = await save_uploads(files, os.path.join(evidence_dir, category))
  93. evidence_files[category] = build_file_items(file_paths, uploads_dir)
  94. application_text = extract_application_text(application_dir)
  95. transcript_text = extract_transcript_text(transcript_dir)
  96. CASE_CACHE[case_id] = {
  97. "case_title": case_title,
  98. "application_text": application_text,
  99. "transcript_text": transcript_text,
  100. "application_result": application_text,
  101. "transcript_result": transcript_text,
  102. "application_files": build_file_items(application_paths, uploads_dir),
  103. "transcript_files": build_file_items(transcript_paths, uploads_dir),
  104. "evidence_files": evidence_files,
  105. "evidence_dir": evidence_dir,
  106. "uploads_dir": uploads_dir
  107. }
  108. upsert_case_management(case_id, case_title or case_id, "", "草稿", "材料提交")
  109. update_case_materials(
  110. case_id,
  111. {
  112. "application_result": application_text,
  113. "transcript_result": transcript_text,
  114. "application_files": build_file_items(application_paths, uploads_dir),
  115. "transcript_files": build_file_items(transcript_paths, uploads_dir),
  116. "evidence_files": evidence_files
  117. }
  118. )
  119. return {
  120. "case_id": case_id,
  121. "application_result": application_text,
  122. "transcript_result": transcript_text,
  123. "application_files": build_file_items(application_paths, uploads_dir),
  124. "transcript_files": build_file_items(transcript_paths, uploads_dir),
  125. "evidence_files": evidence_files
  126. }
  127. @app.post("/api/arbitration/judgement")
  128. def arbitration_judgement(payload: Dict[str, Any]):
  129. case_id = payload.get("case_id", "")
  130. application_result = payload.get("application_result", "")
  131. transcript_result = payload.get("transcript_result", "")
  132. cache = CASE_CACHE.get(case_id, {})
  133. evidence_dir = cache.get("evidence_dir", "")
  134. result = process_case_text_with_evidence(case_id, application_result, transcript_result, evidence_dir)
  135. cache.update(result)
  136. CASE_CACHE[case_id] = cache
  137. upsert_case_management(case_id, cache.get("case_title", case_id), "", "草稿", "裁决中")
  138. return {
  139. "case_id": case_id,
  140. "final_decision": result["final_judgement"].get("final_decision", ""),
  141. "final_judgement": result["final_judgement"],
  142. "similar_cases": result["similar_cases"],
  143. "law_results": result["law_results"]
  144. }
  145. @app.get("/api/arbitration/case")
  146. def arbitration_case(case_id: str = ""):
  147. init_case_db()
  148. management = fetch_case_management(case_id)
  149. materials = parse_case_description(management.get("description", "")).get("materials", {})
  150. record = fetch_case_record(case_id)
  151. case_dir = os.path.join(uploads_dir, case_id)
  152. application_dir = os.path.join(case_dir, "申请书")
  153. transcript_dir = os.path.join(case_dir, "庭审笔录")
  154. evidence_dir = os.path.join(case_dir, "证据")
  155. application_files = list_files_by_ext(application_dir, [".pdf", ".doc", ".docx", ".png", ".jpg", ".jpeg", ".bmp", ".gif"])
  156. transcript_files = list_files_by_ext(transcript_dir, [".pdf", ".doc", ".docx", ".png", ".jpg", ".jpeg", ".bmp", ".gif"])
  157. evidence_files = {}
  158. if os.path.exists(evidence_dir):
  159. for name in os.listdir(evidence_dir):
  160. full_path = os.path.join(evidence_dir, name)
  161. if os.path.isdir(full_path):
  162. files = list_files_by_ext(full_path, [".pdf", ".doc", ".docx", ".png", ".jpg", ".jpeg", ".bmp", ".gif"])
  163. evidence_files[name] = build_file_items(files, uploads_dir)
  164. data = {
  165. "case_id": case_id,
  166. "title": management.get("title", ""),
  167. "description": management.get("description", ""),
  168. "status": management.get("status", ""),
  169. "stage": management.get("stage", ""),
  170. "application_result": materials.get("application_result", ""),
  171. "transcript_result": materials.get("transcript_result", ""),
  172. "application_files": materials.get("application_files") or build_file_items(application_files, uploads_dir),
  173. "transcript_files": materials.get("transcript_files") or build_file_items(transcript_files, uploads_dir),
  174. "evidence_files": materials.get("evidence_files") or evidence_files,
  175. "law_results": record.get("law_results", {}),
  176. "final_judgement": record.get("final_judgement", {}),
  177. "final_decision": record.get("final_judgement", {}).get("final_decision", "")
  178. }
  179. return {"case_id": case_id, "case": data}
  180. @app.post("/api/arbitration/confirm")
  181. def arbitration_confirm(payload: Dict[str, Any]):
  182. case_id = payload.get("case_id", "")
  183. final_decision = payload.get("final_decision", "")
  184. cache = CASE_CACHE.get(case_id, {})
  185. final_judgement = cache.get("final_judgement", {})
  186. if isinstance(final_judgement, dict):
  187. final_judgement["final_decision"] = final_decision
  188. init_case_db()
  189. store_case_record(
  190. case_id,
  191. build_case_summary_text(cache.get("case_profile", {}), cache.get("dispute_points", [])),
  192. cache.get("case_profile", {}),
  193. cache.get("dispute_points", []),
  194. cache.get("law_results", {}),
  195. cache.get("evidence_results", {}),
  196. final_judgement,
  197. cache.get("embedding", [])
  198. )
  199. upsert_case_management(case_id, cache.get("case_title", case_id), "", "已完成", "裁决完成")
  200. return {"case_id": case_id, "status": "stored"}
  201. @app.get("/api/cases")
  202. def list_cases():
  203. init_case_db()
  204. return {"cases": list_case_management()}
  205. @app.post("/api/cases")
  206. def create_case(payload: Dict[str, Any]):
  207. init_case_db()
  208. case_id = payload.get("case_id", "")
  209. title = payload.get("title", "")
  210. description = payload.get("description", "")
  211. status = payload.get("status", "草稿")
  212. stage = payload.get("stage", "案件管理")
  213. return {"case": upsert_case_management(case_id, title, description, status, stage)}
  214. @app.put("/api/cases")
  215. def update_case(payload: Dict[str, Any]):
  216. init_case_db()
  217. case_id = payload.get("case_id", "")
  218. title = payload.get("title", "")
  219. description = payload.get("description", "")
  220. status = payload.get("status", "草稿")
  221. stage = payload.get("stage", "案件管理")
  222. return {"case": upsert_case_management(case_id, title, description, status, stage)}
  223. @app.delete("/api/cases")
  224. def delete_case(payload: Dict[str, Any]):
  225. init_case_db()
  226. case_id = payload.get("case_id", "")
  227. delete_case_management(case_id)
  228. if case_id in CASE_CACHE:
  229. CASE_CACHE.pop(case_id, None)
  230. case_dir = os.path.join(uploads_dir, case_id)
  231. if os.path.exists(case_dir):
  232. shutil.rmtree(case_dir, ignore_errors=True)
  233. return {"status": "deleted", "case_id": case_id}
  234. @app.post("/api/tools/application")
  235. async def tool_application(files: List[UploadFile] = File(default_factory=list)):
  236. tool_id = uuid4().hex
  237. tool_dir = os.path.join(uploads_dir, "tools", "application", tool_id)
  238. file_paths = await save_uploads(files, tool_dir)
  239. reader = DocumentReader()
  240. contents = [reader.process_input(path) for path in file_paths]
  241. content = "\n\n".join(contents)
  242. client = RectifyClient_application()
  243. result = client.extract_legal_document(content)
  244. return {"result": result, "files": build_file_items(file_paths, uploads_dir)}
  245. @app.post("/api/tools/transcript")
  246. async def tool_transcript(files: List[UploadFile] = File(default_factory=list)):
  247. tool_id = uuid4().hex
  248. tool_dir = os.path.join(uploads_dir, "tools", "transcript", tool_id)
  249. file_paths = await save_uploads(files, tool_dir)
  250. reader = DocumentReader()
  251. contents = [reader.process_input(path) for path in file_paths]
  252. content = "\n\n".join(contents)
  253. client = RectifyClient_transcript()
  254. result = client.clean_text(content)
  255. return {"result": result or "", "files": build_file_items(file_paths, uploads_dir)}
  256. @app.post("/api/tools/law")
  257. def tool_law(payload: Dict[str, Any]):
  258. query = (payload.get("query") or "").strip()
  259. result = law_rag_run(query, with_score=True) if query else []
  260. return {"result": result}
  261. return app
  262. app = create_app()