唐山港网厅电子签章
前言
- 所有的服务与说明都是基于 v3 版本的e签宝进行的, 一些方法的细节我都在方法中用注释表述的比较明白了, 自己走一遍完整的逻辑即可明白代码, 所以下面只对本次升级的大体步骤进行说明
与网厅整合的整体流程
- 客户缴费节点: 客户缴费节点需要点击手动签章,签章成功后,e签宝通过回调接口通知网厅更新签署日志的状态, 才能通过合同
- 财务审核节点: 财务审核节点通过追加签署区的方式自动落章, 落章成功后, e签宝通过回调接口通知网厅下载附件以及绑定记录
具体实现
e签宝v3版本时序图如下
- 按照时序图提供的步骤, 需要用户签署之前先授权, 授权过程中需要发送短信, 所以每次签署都需要授权的操作过于繁琐, 已经联系e签宝工作人员解除授权的权限, 并且整合过程中弃用授权的操作
- 合同文件生成过程中可能存在内容错误的情况, 解决方案请看 "需要注意的地方第1条"
- 准备文件之后, 就是发起签署流程了, 2024.08.01新增逻辑 因为同步e签宝认证信息到网厅的操作(定时器+手动按钮)仍存在很差的时效性, 客户可能认证完毕以后立马开始办理合同, 所以在用户发起签署的时候, 需要同时校验e签宝和网厅是否都有认证信息, 如果连e签宝都没有, 那就证明该用户的公司尚未实名, 才会抛出异常, 否则拉下记录更新到网厅
表结构
sql-- 授权日志(已弃用签署前授权操作) CREATE TABLE "JT_YWDT_N"."ESIGN_AUTH_LOG" ( "ID" VARCHAR2 ( 36 ) NOT NULL ENABLE, "BUSINESS_ID" VARCHAR2 ( 36 ), -- 业务主表ID "AUTH_FLOW_ID" VARCHAR2 ( 50 ), -- 认证流程ID "AUTH_URL" VARCHAR2 ( 2000 ), -- 认证链接 "AUTH_SHORT_URL" VARCHAR2 ( 2000 ), -- 认证短链接 "STATUS" VARCHAR2 ( 50 ), -- 此次是否认证 "RECORD_NAM" VARCHAR2 ( 255 ), "RECORD_TIM" DATE, "UPDATE_NAM" VARCHAR2 ( 255 ), "UPDATE_TIM" DATE, "TASK_DEF_KEY" VARCHAR2 ( 50 ), -- 当前节点 CONSTRAINT "SYS_C0067639" PRIMARY KEY ( "ID" ) USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS STORAGE ( INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT ) TABLESPACE "TSG_PORTAL" ENABLE ) SEGMENT CREATION IMMEDIATE PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING STORAGE ( INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT ) TABLESPACE "TSG_PORTAL" -- 认证的用户和公司信息表 CREATE TABLE "JT_YWDT_N"."ESIGN_AUTH_INFO" ( "ID" VARCHAR2 ( 36 ) NOT NULL ENABLE, "SHIPPER_COD" VARCHAR2 ( 50 ), "SHIPPER_DOC" VARCHAR2 ( 500 ), "ESIGN_ID" VARCHAR2 ( 500 ), -- 用户/公司在e签宝的唯一标识 "USERID" VARCHAR2 ( 500 ), -- 如果TYPE是用户,则是用户名,用于签署过程中根据用户名查找该用户的e签宝信息,否则为空 "TYPE" VARCHAR2 ( 20 ), -- ORG公司, PSN个人 CONSTRAINT "SYS_C0067641" PRIMARY KEY ( "ID" ) USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS STORAGE ( INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT ) TABLESPACE "TSG_PORTAL" ENABLE ) SEGMENT CREATION IMMEDIATE PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING STORAGE ( INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT ) TABLESPACE "TSG_PORTAL" -- 签署流程信息 CREATE TABLE "JT_YWDT_N"."ESIGN_SIGN_INFO" ( "ID" VARCHAR2 ( 36 ) NOT NULL ENABLE, "BUSINESS_ID" VARCHAR2 ( 36 ) NOT NULL ENABLE, -- 业务主表ID "FILE_ID" VARCHAR2 ( 500 ) NOT NULL ENABLE, -- 上传e签宝后返回的文件ID "FILE_NAME" VARCHAR2 ( 500 ), -- 文件名 "FILE_UPLOAD_URL" VARCHAR2 ( 2000 ), -- 文件上传地址 "SIGN_FLOW_ID" VARCHAR2 ( 500 ), -- 签署流程ID "SHORT_URL" VARCHAR2 ( 2000 ), -- 签署链接 "URL" VARCHAR2 ( 2000 ), -- 签署短链接 "RECORD_NAM" VARCHAR2 ( 255 ), "RECORD_TIM" DATE, "UPDATE_NAM" VARCHAR2 ( 255 ), "UPDATE_TIM" DATE, CONSTRAINT "SYS_C0067634" PRIMARY KEY ( "ID" ) USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS STORAGE ( INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT ) TABLESPACE "TSG_PORTAL" ENABLE, CONSTRAINT "SYS_C0067635" CHECK ( "BUSINESS_ID" IS NOT NULL ) ENABLE, CONSTRAINT "SYS_C0067636" CHECK ( "FILE_ID" IS NOT NULL ) ENABLE ) SEGMENT CREATION IMMEDIATE PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING STORAGE ( INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT ) TABLESPACE "TSG_PORTAL" -- 签署日志 CREATE TABLE "JT_YWDT_N"."ESIGN_SIGN_LOG" ( "ID" VARCHAR2 ( 36 ) NOT NULL ENABLE, "BUSSINESS_ID" VARCHAR2 ( 50 ) NOT NULL ENABLE, -- 业务主表ID "ESIGN_ID" VARCHAR2 ( 500 ) NOT NULL ENABLE, -- 签署方在e签宝的唯一标识 "SIGN_STATUS" VARCHAR2 ( 1 ) DEFAULT '0' NOT NULL ENABLE, -- 签署状态 "RECORD_NAM" VARCHAR2 ( 50 ), "RECORD_TIM" DATE, "UPDATE_NAM" VARCHAR2 ( 50 ), "UPDATE_TIM" DATE, CONSTRAINT "SYS_C0067667" PRIMARY KEY ( "ID" ) USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS STORAGE ( INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT ) TABLESPACE "TSG_PORTAL" ENABLE, CONSTRAINT "SYS_C0067664" CHECK ( "BUSSINESS_ID" IS NOT NULL ) ENABLE, CONSTRAINT "SYS_C0067665" CHECK ( "ESIGN_ID" IS NOT NULL ) ENABLE, CONSTRAINT "SYS_C0067666" CHECK ( "SIGN_STATUS" IS NOT NULL ) ENABLE ) SEGMENT CREATION IMMEDIATE PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING STORAGE ( INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT ) TABLESPACE "TSG_PORTAL"文件树
tex热加载的服务类 esignnew ┣ annotation ┃ ┗ EsignExceptionHandle.java 自定义注解 ┣ aspect ┃ ┗ EsignExceptionHandler.java 自定义切面,被EsignExceptionHandle标注的方法返回值的状态码非0时抛出异常 ┣ config ┃ ┗ EsignConfig.java e签宝配置类,包括应用ID和秘钥以及各种回调接口 ┣ domain ┃ ┗ ElectronicStampNew.java v3版e签宝服务类 ┣ enums e签宝java示例自带的必要的常量包 ┃ ┣ EsignHeaderConstant.java ┃ ┗ EsignRequestType.java ┣ exception 自定义e签宝异常 ┃ ┗ EsignDemoException.java ┣ service ┃ ┣ AuthService.java 授权服务类 ┃ ┣ FileService.java 文件服务类 ┃ ┣ SealService.java 印章服务类 ┃ ┗ SignService.java 签署服务类 ┗ util e签宝java示例自带的必要的类包 ┃ ┣ AESUtils.java ┃ ┣ EsignCoreSdkInfo.java ┃ ┣ EsignEncryption.java ┃ ┣ EsignFileBean.java ┃ ┣ EsignHttpCfgHelper.java ┃ ┣ EsignHttpHelper.java ┃ ┣ EsignHttpResponse.java ┃ ┗ FileTransformation.java 回调接口定义在主工程,EsignController.java类方法说明

需要注意的地方
- 合同文件的填充操作仍旧沿用旧版电子签章的stamp方法, 只不过新版接口上传签署文件只需要上传docx文件即可, e签宝会自动将其转成pdf格式, 生成合同docx文件以一公司卸船为例, 填充完模板以后, 服务器中的/stampOK/year_pact_unload1_ok.docx的内容就是本次合同的内容了, 然后将这个附件复制到/stampTemp文件夹下, 以合同主表命名, 但是仍旧存在一个问题, 两个线程同时调用生成的逻辑, 可能会造成内容混乱, 我的想法是往/stampOK/year_pact_unload1_ok.docx文件中填内容的方法上加锁, 但是建议没被采纳, 所以某天A公司的内容生成后是B公司的, 可以往这方面考虑
- e签宝 签署服务的回调通知都是异步的(包括追加签署区), 故用户签署成功的状态更新、财务自动落章后从e签宝下载附件到本地并绑定记录等操作都需要e签宝调用网厅的回调接口触发
- 代码中的自定义注解和切面可以保证e签宝返回 非0的状态码 后,向前台抛出异常,但是没有在授权服务中使用该注解,原因是 同步认证的e签宝用户和公司信息 的逻辑中,是for循环调用认证服务,如果某个元素调用后抛出了异常会停止剩余元素的认证查询
相关链接