本篇主要详细说明如何通过明道云搭建的应用实现对法大大电子签的调用,实现效果参照这篇博博客(https://blog.mingdao.com/24959.html)
第一步 集成中心 API 配置
1.在 API 库中搜索“法大大”,并进行安装(路径:集成中心 ➡️API 库)
2.连接信息完善
参照 API 使用说明,完成法大大注册和自建应用配置,获取授权密钥信息
3.API 管理
开启对应的 API,下图是对应于法大大的接口调用流程
范例中用到了以下 5 个 API
- 获取服务访问凭证(说明:获取访问 token)
- 通过网络文件地址上传文件(说明:将合同信息从明道云传给法大大)
- 处理文件(说明:签署方和签署位置信息处理)
- 创建签署任务(说明:发送签署链接给相关方)
- 获取签署任务文档下载地址(说明:获取签署完成的合同附件)
4.授权到应用
授权给需要调用 API 的明道云应用
第二步 明道云工作表单配置
- 配置好签署的应用场景,主要是明道云工作表单的搭建配置
- 合同(劳动合同/销售合同/采购合同)
- 合同发起方(本公司抬头信息)
- 合同接收方(员工档案/客户信息/供应商信息)
案例以供应商场景为例,配置了采购合同的必要信息,以及合同签署需要的参数信息
下图为电子签接口调用相关的参数信息
合同签署参数子表字段配置
2.打印模板配置
依据公司实际的合同配置打印模板,会作为附件传递给法大大;
第三步 工作流配置
1.获取合同的打印模板,主要是为了确认用户发起签署的合同细节信息无误;
2.点击按钮发起签署,这一步的效果是将打印模板和合同签署信息传递给法大大,最终发送签署链接给合同双方;(案例中用的是手动签署,双方需操作;也可配置为发起方自动盖章)
2.1 获取授权 token
通过网络文件上传签署附件,并将返回信息跟新到主记录中;
- 调用其他 API 之前,需要先调用 API 获取服务访问凭证
- 处理附件链接,直接获取的附件链接是数组格式的,需要用代码块处理下(代码块见文末代码块 2)
- 将合同附件地址上传给法大大
2.2 处理文件
接口说明:应用上传文件成功后,在签署任务中使用上传的文件,这一步通过接口对文件进行后处理生成文件 fileId,在后续发起签署创建签署任务相关接口中会需要使用 fileId。
https://dev.fadada.com/api-doc/TV9HPJF4NB/FMPVRJBZHRKTM2J2/5-1
- 调用接口处理文件
2.3 创建签署任务
接口说明:https://dev.fadada.com/api-doc/XZA5UN1MIS/NDNV8ES5LCEWUFAW/5-1
通过接口,向法大大发起签署参数完备的签署任务(签署方信息、签署位置信息等)
- 处理生成签署位置信息,新增合同签署参数,包括关键字和骑缝章
- 用代码块对签署方信息、签署参数子表信息进行格式化处理(代码块见文末代码块 2)
- 调用创建签署任务接口
签署任务创建成功后,合同双方会收到签署的短信提醒,点击链接进行签署即可
3.配置回调工作流,将双方签署完成的合同 pdf 回写到明道云
说明:使用了明道云的封装业务流程来接收回调信息,需要在法大大配置回调链接信息
- 开启封装业流程的 API 能力
- 格式出处理回传的参数(代码块见文末代码块 3)
- 调用获取签署文档下载地址 API
使用到的 js 代码块
代码块 1:附件链接格式化处理
var list= JSON.parse(input.imgs?input.imgs:"[]");
output = {imgurl:(list.length>0?list[0]:"")};
代码块 2:对签署方信息、签署参数子表格式化处理
var uuid=require('uuid')
var sends=[];
var revicer=[];
var sendsign=[];
var revicersign=[]
var ctype=JSON.parse(input.ctype)
var page=JSON.parse(input.page)
var x=JSON.parse(input.x)
var y=JSON.parse(input.y)
for(var i=0;i<ctype.length;i++){
var obj={
"fieldId":"",
"fieldName":"",
"position":{"positionMode":"pixel"},
"fieldType": "corp_seal_cross_page"
}
var robj={
"fieldId":"",
"fieldName":"",
"position":{"positionMode":"pixel"},
"fieldType": "corp_seal_cross_page"
}
var suid=uuid.v4().replace(/-/g,'').substring(0,16);
var ruid=uuid.v4().replace(/-/g,'').substring(0,16);
if(page[i]!=""){
obj.position.positionPageNo=Number(page[i])
robj.position.positionPageNo=Number(page[i])
}
if(ctype[i]=="骑缝章"){
obj.position.positionX=Number(x[i])
obj.position.positionY=Number(y[i])
obj.fieldType= "corp_seal_cross_page"
robj.position.positionX=Number(x[i])
robj.position.positionY=200
robj.fieldType= "corp_seal_cross_page"
if(input.发起方=="corp"){
obj.fieldName='发起方骑缝章'
obj.fieldId=suid
sends.push(obj)
sendsign.push({"fieldDocId":"1","fieldId":suid})
}
if(input.接收方=="corp"){
robj.fieldName='接收方骑缝章'
robj.fieldId=ruid
revicer.push(robj)
revicersign.push({"fieldDocId":"1","fieldId":ruid})
}
}else{
obj.position.keywordOffsetX=Number(x[i])
obj.position.keywordOffsetY=Number(y[i])
obj.position.positionMode= "keyword"
obj.fieldName= "关键字签章"
obj.fieldType= "corp_seal"
robj.position.keywordOffsetX=Number(x[i])
robj.position.keywordOffsetY=Number(y[i])
robj.position.positionMode= "keyword"
robj.fieldName= "关键字签章"
robj.fieldType= "corp_seal"
if(input.发起方。toLowerCase()=="person"){
obj.fieldType= "person_sign"
}
obj.position.positionKeyword=input.发起方关键字
obj.fieldId=suid
sends.push(obj)
sendsign.push({"fieldDocId":"1","fieldId":suid})
if(input.接收方。toLowerCase()=="person"){
robj.fieldType= "person_sign"
}
robj.position.positionKeyword=input.接收方关键字
robj.fieldId=ruid
revicer.push(robj)
revicersign.push({"fieldDocId":"1","fieldId":ruid})
}
}
var alllist=sends.concat(revicer)
output = {alllist:alllist,
sends:sends,
revicer:revicer,
sendsign:sendsign,
revicersign:revicersign}
代码块 3:格式出处理回传的参数
/*
task_created: 任务创建中 (签署任务创建中,未提交)
fill_progress: 填写进行中 (签署任务正在进行协同填写流程阶段,必填控件尚未填完)
fill_completed: 填写已完成 (签署任务文档中所有的必填控件均已填写,但文档尚未定稿)
sign_progress: 签署进行中 (签署任务正在进行签署流程阶段)
sign_completed: 签署已完成 (签署任务所有参与方均已签署完成)
task_finished: 任务已结束 (签署任务已成功结束)
task_terminated: 任务异常停止 (签署任务已经因为某种原因而停止运行,如因为某方拒填或拒签、撤销、超期)
{'eventTime':'2022-12-13 00:00:00','signTaskId':'1234','signTaskStatus':'sign_completed'}
*/
var bizContent=JSON.parse(input.bizContent?input.bizContent:'{}')
output = {bizContent:bizContent };