| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- import json
- import logging
- import requests
- from common.esigntool.esign_config import Config
- from common.esigntool.esign_algorithm import buildSignJsonHeader
- from datetime import datetime
- logger = logging.getLogger(__name__)
- config = Config()
- def _request(method: str, api_path: str, body: dict = None) -> str:
- """统一的e签宝API请求方法
- Args:
- method: HTTP方法 (GET/POST)
- api_path: API路径
- body: 请求体字典
- Returns:
- 响应文本
- """
- headers = buildSignJsonHeader(config.appId, config.scert, method, api_path, body=body)
- url = config.host + api_path
- if body is not None:
- data = json.dumps(body, separators=(",", ":"), ensure_ascii=False)
- resp = requests.request(method, url, data=data, headers=headers)
- else:
- resp = requests.request(method, url, headers=headers)
- logger.debug("请求 %s %s, 响应: %s", method, api_path, resp.text)
- return resp.text
- # ==================== 签署流程标题映射 ====================
- SIGN_FLOW_TITLES = {
- "store_agreement": "商家入驻U店平台协议签署",
- "alipay_auth": "支付宝授权函签署",
- "wechat_pay_commitment": "微信支付承诺函签署",
- "lawyer_agreement": "律所入驻U店平台协议签署",
- }
- # ==================== 签署位置配置 ====================
- SIGN_POSITIONS = {
- "store_agreement": {
- "alien": {"page": 7, "x": 294, "y": 668},
- "signer": {"page": 7, "x": 114, "y": 666},
- },
- "alipay_auth": {
- "alien": {"page": 1, "x": 535, "y": 555},
- "signer": {"page": 1, "x": 535, "y": 431},
- },
- "wechat_pay_commitment": {
- "signer": {"page": 1, "x": 535, "y": 515},
- },
- "lawyer_agreement": {
- "alien": {"page": 6, "x": 336, "y": 418},
- "signer": {"page": 6, "x": 145, "y": 418},
- },
- }
- # ==================== 模板填充配置 ====================
- TEMPLATE_COMPONENT_VALUES = {
- "store_agreement": {
- "alien_name": "爱丽恩严(大连)商务科技有限公司",
- "date": None, # 运行时填充
- "one_name": None, # 运行时填充
- "store_name": None, # 运行时填充
- },
- "lawyer_agreement": {
- "alien_name": "爱丽恩严(大连)商务科技有限公司",
- "alien_name_2": "爱丽恩严(大连)商务科技有限公司",
- "law_firm_name": None, # 运行时填充
- "law_firm_name_2": None, # 运行时填充
- "signing_date": None, # 运行时填充
- },
- "alipay_auth": {},
- "wechat_pay_commitment": {},
- }
- def get_auth_flow_id(org_name, org_id, legal_rep_name, legal_rep_id):
- """获取机构认证&授权页面链接"""
- body = {
- "clientType": "ALL",
- "redirectConfig": {
- "redirectUrl": "https://www.baidu.com"
- },
- "orgAuthConfig": {
- "orgName": org_name,
- "orgInfo": {
- "orgIDCardNum": org_id,
- "orgIDCardType": "CRED_ORG_USCC",
- "legalRepName": legal_rep_name,
- "legalRepIDCardNum": legal_rep_id,
- "legalRepIDCardType": "CRED_PSN_CH_IDCARD"
- },
- "transactorInfo": {
- "psnAccount": "17337039317",
- "psnInfo": {
- "psnName": "孟骞康",
- "psnIDCardNum": "411426200308121212",
- "psnIDCardType": "CRED_PSN_CH_IDCARD",
- "psnMobile": "17337039317"
- }
- }
- },
- "notifyUrl": "http://120.26.186.130:33333/api/store/esign/callback_auth",
- "transactorUseSeal": True
- }
- return _request("POST", "/v3/org-auth-url", body)
- def get_template_detail():
- """查询合同模板中控件详情"""
- return _request("GET", f"/v3/doc-templates/{config.templates_id}")
- def fill_in_template(name, contract_type="store_agreement"):
- """填写模板生成文件
- Args:
- name: 商家/律所名称
- contract_type: 合同类型 (store_agreement/lawyer_agreement/alipay_auth/wechat_pay_commitment)
- """
- today = datetime.now().strftime("%Y年%m月%d日")
- base_values = TEMPLATE_COMPONENT_VALUES.get(contract_type, {})
- # 根据合同类型填充动态字段
- dynamic_values = {
- "store_agreement": {"store_name": name, "one_name": name, "date": today},
- "lawyer_agreement": {"law_firm_name": name, "law_firm_name_2": name, "signing_date": today},
- }.get(contract_type, {})
- components = [
- {"componentKey": key, "componentValue": value}
- for key, value in {**base_values, **dynamic_values}.items()
- ]
- body = {
- "docTemplateId": config.templates_map.get(contract_type, ""),
- "fileName": config.template_file_names.get(contract_type, ""),
- "components": components
- }
- return _request("POST", "/v3/files/create-by-doc-template", body)
- def get_contract_detail(file_id):
- """查询PDF模板填写后文件"""
- return _request("GET", f"/v3/files/{file_id}")
- def _build_alien_signer(file_id, position):
- """构建平台方(爱丽恩严)签署人配置"""
- return {
- "signConfig": {"signOrder": 1},
- "signerType": 1,
- "signFields": [{
- "customBizNum": "9527",
- "fileId": file_id,
- "normalSignFieldConfig": {
- "autoSign": True,
- "signFieldStyle": 1,
- "signFieldPosition": {
- "positionPage": str(position["page"]),
- "positionX": position["x"],
- "positionY": position["y"]
- }
- }
- }]
- }
- def _build_org_signer(file_id, position, signer_name, signer_id_num, psn_account, psn_name):
- """构建签署方(商家/律所)签署人配置"""
- return {
- "signConfig": {"forcedReadingTime": 10, "signOrder": 2},
- "signerType": 1,
- "orgSignerInfo": {
- "orgName": signer_name,
- "orgInfo": {
- "orgIDCardNum": signer_id_num,
- "orgIDCardType": "CRED_ORG_USCC"
- },
- "transactorInfo": {
- "psnAccount": psn_account,
- "psnInfo": {"psnName": psn_name}
- }
- },
- "signFields": [{
- "customBizNum": "自定义编码001",
- "fileId": file_id,
- "normalSignFieldConfig": {
- "signFieldStyle": 1,
- "signFieldPosition": {
- "positionPage": str(position["page"]),
- "positionX": position["x"],
- "positionY": position["y"]
- }
- }
- }]
- }
- def create_by_file(file_id, file_name, signer_name, signer_id_num, psn_account, psn_name, contract_type="store_agreement"):
- """基于文件发起签署
- Args:
- file_id: 文件ID
- file_name: 文件名
- signer_name: 签署方名称
- signer_id_num: 签署方证件号
- psn_account: 经办人账号标识(手机号/邮箱)
- psn_name: 经办人姓名
- contract_type: 合同类型 (store_agreement/alipay_auth/wechat_pay_commitment/lawyer_agreement)
- """
- positions = SIGN_POSITIONS.get(contract_type, SIGN_POSITIONS["store_agreement"])
- signers = []
- if positions.get("alien"):
- signers.append(_build_alien_signer(file_id, positions["alien"]))
- if positions.get("signer"):
- signers.append(_build_org_signer(file_id, positions["signer"], signer_name, signer_id_num, psn_account, psn_name))
- body = {
- "docs": [{"fileId": file_id, "fileName": f"{file_name}.pdf"}],
- "signFlowConfig": {
- "signFlowTitle": SIGN_FLOW_TITLES.get(contract_type, "合同签署"),
- "autoFinish": True,
- "noticeConfig": {"noticeTypes": "1,2"},
- "notifyUrl": "http://120.26.186.130:33333:/api/store/esign/callback",
- "redirectConfig": {"redirectUrl": "https://www.esign.cn/"},
- },
- "signers": signers
- }
- return _request("POST", "/v3/sign-flow/create-by-file", body)
- def sign_url(sign_flow_id, psn_account):
- """获取签署页面链接"""
- body = {
- "signFlowId": sign_flow_id,
- "clientType": "ALL",
- "needLogin": False,
- "operator": {"psnAccount": psn_account},
- "urlType": 2
- }
- return _request("POST", f"/v3/sign-flow/{sign_flow_id}/sign-url", body)
- def file_download_url(sign_flow_id):
- """下载已签署文件及附属材料"""
- body = {"urlAvailableDate": "3600"}
- return _request("POST", f"/v3/sign-flow/{sign_flow_id}/file-download-url", body)
|