contract_builder.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. import json
  2. import logging
  3. import re
  4. import urllib.parse
  5. from typing import Any
  6. from common.esigntool.main import fill_in_template, create_by_file
  7. logger = logging.getLogger(__name__)
  8. class ContractBuildError(Exception):
  9. def __init__(self, message: str, raw: Any):
  10. super().__init__(message)
  11. self.message = message
  12. self.raw = raw
  13. def build_contract_items(
  14. configs: list[tuple[str, str, int]],
  15. template_name: str,
  16. signer_name: str,
  17. signer_id_num: str,
  18. psn_account: str,
  19. psn_name: str,
  20. ) -> list[dict[str, Any]]:
  21. items: list[dict[str, Any]] = []
  22. for contract_type, contract_name, is_master in configs:
  23. res_text = fill_in_template(template_name, contract_type=contract_type)
  24. try:
  25. res_data = json.loads(res_text)
  26. except json.JSONDecodeError:
  27. logger.error("fill_in_template non-json resp contract_type=%s: %s", contract_type, res_text)
  28. raise ContractBuildError(
  29. message=f"{contract_name}生成失败:e签宝返回非 JSON",
  30. raw={"contract_type": contract_type, "resp": res_text},
  31. )
  32. try:
  33. contract_url = res_data["data"]["fileDownloadUrl"]
  34. file_id = res_data["data"]["fileId"]
  35. m = re.search(r"/([^/]+)\.pdf", contract_url)
  36. if m:
  37. encoded_name = m.group(1)
  38. file_name = urllib.parse.unquote(encoded_name)
  39. else:
  40. file_name = f"{contract_type}.pdf"
  41. except Exception:
  42. logger.error("fill_in_template missing fileDownloadUrl contract_type=%s: %s", contract_type, res_data)
  43. raise ContractBuildError(
  44. message=f"{contract_name}生成失败:e签宝返回缺少 fileDownloadUrl",
  45. raw={"contract_type": contract_type, "resp": res_data},
  46. )
  47. sign_data = create_by_file(
  48. file_id,
  49. file_name,
  50. signer_name,
  51. signer_id_num,
  52. psn_account,
  53. psn_name,
  54. contract_type=contract_type,
  55. )
  56. try:
  57. sign_json = json.loads(sign_data)
  58. except json.JSONDecodeError:
  59. logger.error("create_by_file non-json resp contract_type=%s: %s", contract_type, sign_data)
  60. raise ContractBuildError(
  61. message=f"{contract_name}发起签署失败:e签宝返回非 JSON",
  62. raw={"contract_type": contract_type, "resp": sign_data},
  63. )
  64. if not sign_json.get("data"):
  65. logger.error("create_by_file failed or missing data contract_type=%s: %s", contract_type, sign_json)
  66. raise ContractBuildError(
  67. message=f"{contract_name}发起签署失败",
  68. raw={"contract_type": contract_type, "resp": sign_json},
  69. )
  70. sign_id = sign_json["data"].get("signFlowId")
  71. if not sign_id:
  72. logger.error("create_by_file missing signFlowId contract_type=%s: %s", contract_type, sign_json)
  73. raise ContractBuildError(
  74. message=f"{contract_name}发起签署失败:e签宝返回缺少 signFlowId",
  75. raw={"contract_type": contract_type, "resp": sign_json},
  76. )
  77. items.append(
  78. {
  79. "contract_type": contract_type,
  80. "contract_name": contract_name,
  81. "contract_url": contract_url,
  82. "file_name": file_name,
  83. "file_id": file_id,
  84. "status": 0,
  85. "sign_flow_id": sign_id,
  86. "sign_url": "",
  87. "signing_time": "",
  88. "effective_time": "",
  89. "expiry_time": "",
  90. "contract_download_url": "",
  91. "is_master": is_master,
  92. }
  93. )
  94. return items