# -*- coding: UTF-8 -*- import time import esigntool import requests from esigntool import esign_run_print_outer from esigntool.esign_file import fileHelp """ * 本文件适用于平台方自动+企业用户自动签署场景 * 基本流程如下: * 1、企业用户将印章授权给平台方,可通过登录e签宝官网企业控制台完成,或者通过印章开放服务完成:https://open.esign.cn/doc/opendoc/seal3/qkxyha * 2、发起签署时,设置signFields入参规则:signers.orgSignerInfo对象中的orgId为平台方企业账号id,assignedSealId为授权企业的印章id,autoSign设置为true * 3、流程完结后,下载签署后文件 """ config = esigntool.Config() # 初始化配置类 @esign_run_print_outer def findOrgIdentityInfo(orgName): """ 查询机构认证信息 :return: """ api_path = "/v3/organizations/identity-info?orgName={}".format(orgName) method = esigntool.httpMethodEnum.GET if orgName == "": print("请设置实名企业名称") exit() # 签名并构造签名鉴权json请求头 json_headers = esigntool.buildSignJsonHeader(config.appId, config.scert, method, esigntool.apiPathSort(api_path)) # 发起请求 resp = requests.request(method, config.host + api_path, json=None, headers=json_headers) print(resp.text) orgId = resp.json()['data']['orgId'] return orgId @esign_run_print_outer def getFileUploadUrl(file): """ 获取文件上传地址 :return: """ contentType = "application/pdf" # 声明请求变量 body = { "contentMd5": file.contentMd5, "contentType": contentType, "convert2Pdf": False, "fileName": file.fileName, "fileSize": file.fileSize } # 构建请求参数body体 api_path = "/v3/files/file-upload-url" method = esigntool.httpMethodEnum.POST json_headers = esigntool.buildSignJsonHeader(config.appId, config.scert, method, api_path, body) # 签名并构造签名鉴权json请求头 resp = requests.request(method, config.host + api_path, json=body, headers=json_headers) # 发送请求 fileUploadUrl = resp.json()['data']['fileUploadUrl'] # 获取文件上传路径 fileId = resp.json()['data']['fileId'] print(resp.text) return fileUploadUrl, fileId @esign_run_print_outer def fileStreamUpload(binfile, fileUploadUrl): """ 文件流上传服务器 :return: """ contentMd5 = file.contentMd5 # 声明请求变量 contentType = "application/pdf" # 声明请求变量 method = esigntool.httpMethodEnum.PUT # 声明请求方法 json_headers = esigntool.buildFileUploadHeader(contentType, contentMd5) # 构建请求头 resp = requests.request(method, fileUploadUrl, data=binfile, headers=json_headers) # 发送请求 print(resp.text) return resp @esign_run_print_outer def signFlowCreateByFile(fileId, orgId, sealId): """ 基于文件发起签署 :return: """ body = { "docs": [ { "fileId": fileId, "fileName": "xx企业劳动合同.pdf" } ], "attachments": [ { "fileId": fileId, "fileName": "入职材料.pdf" } ], "signers": [ { "orgSignerInfo": { "orgId": orgId }, "signConfig": { "signOrder": 1 }, "signFields": [ { "customBizNum": "自定义编码", "fileId": fileId, "normalSignFieldConfig": { "autoSign": True, "signFieldPosition": { "positionPage": "1", "positionX": 300, "positionY": 300 }, "signFieldStyle": 1 } } ], "signerType": 1 }, { "orgSignerInfo": { "orgId": orgId }, "signConfig": { "signOrder": 1 }, "signFields": [ { "customBizNum": "自定义编码", "fileId": fileId, "normalSignFieldConfig": { "autoSign": True, "assignedSealId": sealId, # 传入授权后的印章ID "signFieldPosition": { "positionPage": "1", "positionX": 100, "positionY": 200 }, "signFieldStyle": 1 } } ], "signerType": 1 } ], "signFlowConfig": { "autoFinish": True, # 自动完结,为false的时候需要单独调用对应完结接口 "autoStart": True, # 自动开启,为false的时候需要单独调用对应开启接口 "noticeConfig": { "noticeTypes": "1" }, "notifyUrl": "http://xx.xx.86.172:8081/asyn/notify", "redirectConfig": { "redirectDelayTime": "3", "redirectUrl": "http://www.esign.cn" }, "signConfig": { "availableSignClientTypes": "1", "showBatchDropSealButton": True }, "signFlowTitle": "企业员工劳动合同签署" } } # 构建请求body体 api_path = "/v3/sign-flow/create-by-file" # 拼接请求路径 method = esigntool.httpMethodEnum.POST # 声明请求方法 json_headers = esigntool.buildSignJsonHeader(config.appId, config.scert, method, api_path, body) # 签名并构造签名鉴权json请求头 resp = requests.request(method, config.host + api_path, json=body, headers=json_headers) # 发送请求 print(resp.text) sign_flowId = resp.json()['data']['signFlowId'] return sign_flowId @esign_run_print_outer def fileDownloadUrl(sign_flowId): """ 下载已签署文件及附属材料 :return: """ api_path = "/v3/sign-flow/{}/file-download-url".format(sign_flowId) # 拼接请求路径 method = esigntool.httpMethodEnum.GET # 声明请求方法 json_headers = esigntool.buildSignJsonHeader(config.appId, config.scert, method, api_path) # 签名并构造签名鉴权json请求头 resp = requests.request(method, config.host + api_path, json=None, headers=json_headers) # 发送请求 print(resp.text) return resp if __name__ == '__main__': if config.appId == "" or config.scert == "": print("请设置应用Appid和应用Secret") exit() fileUrl = "D://**文件//1.pdf" # 本地文件路径 orgName = "**企业" # 平台自身企业名称,即appid所属的企业名称 sealId = "*******fef" # 通过印章开放服务来获取印章ID orgId = findOrgIdentityInfo(orgName) # 查询平台自身实名帐号ID file = fileHelp(fileUrl) # 初始化文件辅助类 fileUploadUrl, fileId = getFileUploadUrl(file) # 获取文件ID&文件上传路径 fileStreamUpload(file.getBinFile(), fileUploadUrl) # 上传文件流 sign_flowId = signFlowCreateByFile(fileId, orgId, sealId) # 发起一步签署:主动发送签署短信给签署用户 time.sleep(2) fileDownloadUrl(sign_flowId) # 合同结束后(个人用户签署完成后),下载签署后合同