router.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. from typing import Any, Union, Optional
  2. from fastapi import APIRouter, Depends, Query
  3. from pydantic import ValidationError
  4. from alien_lawyer.api.deps import get_contract_service, get_contract_center_service
  5. from alien_contract.schemas.request.contract import BundleCreateRequest
  6. from alien_contract.services.contract_server import ContractCenterService
  7. from alien_lawyer.schemas.request.contract_lawyer import LawyerTemplatesCreate
  8. from alien_lawyer.schemas.response.contract_lawyer import (
  9. ModuleStatusResponse,
  10. TemplatesCreateResponse,
  11. ErrorResponse,
  12. PaginatedResponse,
  13. SuccessResponse,
  14. )
  15. from alien_lawyer.services.contract_server import LawyerContractServer
  16. router = APIRouter()
  17. def _format_validation_errors(exc: ValidationError) -> list[dict[str, str]]:
  18. errors = []
  19. for err in exc.errors():
  20. loc = err.get("loc", ())
  21. field = ".".join(str(item) for item in loc if item != "body")
  22. errors.append(
  23. {
  24. "field": field or "body",
  25. "type": err.get("type", "validation_error"),
  26. "message": err.get("msg", "参数校验失败"),
  27. }
  28. )
  29. return errors
  30. @router.get("/", response_model=ModuleStatusResponse)
  31. async def index() -> ModuleStatusResponse:
  32. return ModuleStatusResponse(module="LawyerContract", status="Ok")
  33. @router.post("/get_esign_templates", response_model=Union[TemplatesCreateResponse, ErrorResponse])
  34. async def create_esign_templates(
  35. templates_data_raw: dict[str, Any],
  36. templates_server: ContractCenterService = Depends(get_contract_center_service),
  37. ) -> Union[TemplatesCreateResponse, ErrorResponse]:
  38. try:
  39. templates_data = LawyerTemplatesCreate.model_validate(templates_data_raw)
  40. except ValidationError as exc:
  41. return ErrorResponse(success=False, message="请求参数校验失败", raw={"errors": _format_validation_errors(exc)})
  42. request = BundleCreateRequest(
  43. subject_type="lawyer",
  44. subject_id=templates_data.lawyer_id,
  45. subject_name=templates_data.law_firm_name,
  46. business_segment=templates_data.business_segment,
  47. contact_name=templates_data.contact_name,
  48. contact_phone=templates_data.contact_phone,
  49. ord_id=templates_data.ord_id,
  50. )
  51. result = await templates_server.create_bundle(request)
  52. if not result.get("success"):
  53. return ErrorResponse(**result)
  54. return TemplatesCreateResponse(
  55. success=True,
  56. message=result["message"],
  57. sign_flow_id=result.get("primary_sign_flow_id"),
  58. file_id=result.get("created_contracts", [{}])[0].get("file_id") if result.get("created_contracts") else None,
  59. contract_url=result.get("created_contracts", [{}])[0].get("contract_url") if result.get("created_contracts") else None,
  60. created_contracts=result.get("created_contracts"),
  61. )
  62. @router.get("/contracts/{lawyer_id}", response_model=PaginatedResponse)
  63. async def list_contracts(
  64. lawyer_id: int,
  65. status: Optional[int] = Query(None, description="筛选合同状态:0 未签署,1 已签署"),
  66. page: int = Query(1, ge=1, description="页码,从1开始"),
  67. page_size: int = Query(10, ge=1, le=100, description="每页条数,默认10"),
  68. templates_server: LawyerContractServer = Depends(get_contract_service),
  69. ) -> PaginatedResponse:
  70. result = await templates_server.list_contracts(lawyer_id, status, page, page_size)
  71. return PaginatedResponse(**result)
  72. @router.get("/contracts/detail/{sign_flow_id}", response_model=Union[dict, ErrorResponse])
  73. async def get_contract_detail(
  74. sign_flow_id: str,
  75. templates_server: LawyerContractServer = Depends(get_contract_service),
  76. ) -> Union[dict, ErrorResponse]:
  77. result = await templates_server.get_contract_detail(sign_flow_id)
  78. if not result.get("success", True):
  79. return ErrorResponse(**result)
  80. return result
  81. @router.post("/esign/callback", response_model=Union[SuccessResponse, ErrorResponse])
  82. async def esign_callback(
  83. payload: dict,
  84. templates_server: LawyerContractServer = Depends(get_contract_service),
  85. ) -> Union[SuccessResponse, ErrorResponse]:
  86. result = await templates_server.process_esign_callback(payload)
  87. if not result.get("success"):
  88. return ErrorResponse(**result)
  89. return SuccessResponse(code=result["code"], msg=result["msg"])