welcome to xlongwei.com

欢迎大家一起学习、交流、分享


QQ:9167702333 邮箱:admin@xlongwei.com

SignUtil e签宝电子签名快捷签接入


分类 Java   关键字 分享   标签 java   web   发布 hongwei  1461288437645
注意 转载须保留原文链接,译文链接,作者译者等信息。  
随着互联网金融的普及,在线签订电子合同越来越得到借款方和出借方的认可。借款人与出借方之间采用电子合同电子签名的方式,可以很好的解决法律效力的问题,电子签名与纸质签名具备同等的法律效力。e签宝快捷签是专为互联网金融平台提供的电子签名方案。

依赖,http://nexus.xlongwei.com/content/groups/public/timevale/tech-sdk/1.0.0/tech-sdk-1.0.0.jar
<dependency>
<groupId>timevale</groupId>
<artifactId>tech-sdk</artifactId>
<version>1.0.0</version>
</dependency>

配置,tech-sdk-1.0.0-SNAPSHOT.jar包含测试的systemconfig.properties,可以删除后上传到maven仓库
# systemconfig.properties
getAPIInfoUrl=http://121.43.159.210:8080/tgmonitor/rest/app!getAPIInfo2
http_config_retry=5
sign.project_id=
sign.project_secret=

sign.investor=true
sign.borrower=true
sign.platform=true
sign.save=false #合同保全
sign.upload=false

sign.organize.hText=合同专用章

#再配置borrower和platform的签署位置
sign.pos.x.investor=420
sign.pos.y.investor=350
sign.pos.page.investor=1


电子签名工具类
public class SignUtil {
private static final EsignsdkService esignsdkService = EsignsdkServiceFactory.instance();
private static final AccountService accountService = AccountServiceFactory.instance();
private static final SignService signService = SignServiceFactory.instance();
private static final SealService sealService = SealServiceFactory.instance();
private static final Logger logger = LoggerFactory.getLogger(SignUtil.class);
private static final String resource = "systemconfig.properties";//配置文件只能命名为systemconfig.properties
private static final Properties props = PropertiesUtil.get(resource);
private static String devId = null;

/** 签署单个投资 */
public static boolean sign(Long investmentId) {
if(devId == null) return false;
boolean i = NumberUtil.parseBoolean(props.getProperty("sign.investor"), false), b = NumberUtil.parseBoolean(props.getProperty("sign.borrower"), false), p = NumberUtil.parseBoolean(props.getProperty("sign.platform"), false);

//获取投资和项目信息
String dir = GinkgoConfig.getProperty("uploads_file")+"contracts/";
String contracts = GinkgoConfig.getProperty("uploads")+"contract/";
String contract = invest.getProjectId()+"-CONTRACT";
String dstPdf = dstPdf(dir, contracts, invest.getProjectId(), invest.getId());
if(dstPdf==null) {//投资已签署过,直接返回成功
logger.info("sign investment: "+invest.getId()+", already done.");
return true;
}
String srcPdf = srcPdf(dir, contracts, contract);
if(srcPdf == null) {//需要签署的文档不存在,返回失败
logger.info("sign investment skipped, srcPdf not ready: "+contracts+contract+".pdf");
return false;
}

SignInfo investorSignInfo = i ? signInfo(invest.getInverstorId()) : null;
SignInfo borrowerSignInfo = b ? signInfo(invest.getLoaneeId()) : null;
if((i && investorSignInfo==null) || (b && borrowerSignInfo==null)) {//签署人的签名信息不存在,返回失败
logger.info("sign investment skipped, signInfo not ready: investorSignInfo="+investorSignInfo+",borrowerSignInfo="+borrowerSignInfo);
return false;
}
//投资人、借款人、平台三方签署
boolean s = i==false ? true : sign(srcPdf, dstPdf+".i", signPos("investor"), investorSignInfo);
if(s) s = b==false ? true : sign(i==true ? dstPdf+".i" : srcPdf, dstPdf+"."+(i?"i":"")+"b", signPos("borrower"), borrowerSignInfo);
if(s) s= p==false ? true : sign(b==true ? dstPdf+"."+(i?"i":"")+"b" : (i==true?dstPdf+".i":srcPdf), dstPdf+"."+(i?"i":"")+(b?"b":"")+"p", signPos("platform"), null);
logger.info("sign investment: "+invest.getId()+", result: "+s);

if(s == false) return false;//签署失败返回
boolean c = CodeUtil.copy(dstPdf+"."+(i?"i":"")+(b?"b":"")+(p?"p":""), dstPdf);
if(c) {
if(NumberUtil.parseBoolean(props.getProperty("sign.upload"), false)) UploadUtil.contract("contract", dstPdf);
if(i) new File(dstPdf+".i").delete();//上传签署文档,删除临时文件
if(b) new File(dstPdf+"."+(i?"i":"")+"b").delete();
if(p) new File(dstPdf+"."+(i?"i":"")+(b?"b":"")+"p").delete();
}

int docId = NumberUtil.parseBoolean(props.getProperty("sign.save"), false) ? docSave(dstPdf, signInfo(invest.getInverstorId()).getAccountId()) : -1;//文档保全
if(docId != -1) {
//保存文档保全信息
service.mergeSignPdf(signPdf);
}
logger.info("sign.save="+NumberUtil.parseBoolean(props.getProperty("sign.save"), false)+", docId="+docId);
return true;
}

/** 在某个位置签署某个印章 */
public static boolean sign(String src, String dst, PosBean pos, SignInfo signInfo) {
if(devId == null) return false;
Result r = signInfo!=null ? signService.localSignPDF(devId, signInfo.getAccountId(), signInfo.getSealData(), src, dst, pos, SignType.Single, null) : signService.localSignPDF(devId, src, dst, pos, 0, SignType.Single, null);
logger.info(show(r));
return success(r);
}

/** 保全文档,返回docId */
public static int docSave(String dstPdf, String accountId) {
if(devId == null) return -1;
SignedFileResult r = signService.saveSignedFile(devId, dstPdf, FilenameUtils.getBaseName(dstPdf)+".pdf", new String[] { accountId });
logger.info("save signed file: "+dstPdf+", result: "+show(r));
return success(r) ? r.getDocId() : -1;
}

/** 获取文档链接 */
public static String docGet(int docId) {
if(devId == null) return null;
GetSignedFileResult r = signService.getSignedFile(devId, docId);
logger.info("get saved file, docId: "+docId+", result: "+show(r));
return success(r) ? r.getUrl() : null;
}

/** 创建个人账户,返回accountId */
public static String addAccount(String name, String idNo, String mobile) {
if(devId == null) return null;
AddAccountResult r = accountService.addAccount(devId, new PersonBean().setName(name).setMobile(mobile).setIdNo(idNo));
logger.info("addAccount: "+name+","+idNo+","+mobile+" result: "+show(r));
return success(r) ? r.getAccountId() : null;
}
/** 创建机构账户,返回accountId */
public static String addOrganize(String name, String organCode, String mobile, String legalName, String legalIdNo) {
if(devId == null) return null;
AddAccountResult r = accountService.addAccount(devId, new OrganizeBean().setName(name).setMobile(mobile).setOrganCode(organCode).setUserType(2).setLegalName(legalName).setLegalIdNo(legalIdNo));
logger.info("addAccount: "+name+","+organCode+","+mobile+" result: "+show(r));
return success(r) ? r.getAccountId() : null;
}

/** 创建个人印章,返回印章数据 */
public static String addSeal(String accountId) {
if(devId == null) return null;
AddSealResult r = sealService.addTemplateSeal(devId, accountId, PersonTemplateType.RECTANGLE, SealColor.RED);
logger.info("addSeal: "+accountId+", result: "+show(r));
return success(r) ? r.getSealData() : null;
}
/** 创建机构印章,返回印章数据 */
public static String addSeal(String accountId, String regCode) {
if(devId == null) return null;
AddSealResult r = sealService.addTemplateSeal(devId, accountId, OrganizeTemplateType.STAR, SealColor.RED, props.getProperty("sign.organize.hText", ""), regCode);
logger.info("addSeal: "+accountId+", regCode: "+regCode+" result: "+show(r));
return success(r) ? r.getSealData() : null;
}

public static PosBean signPos(String type) {
PosBean pos = new PosBean();
pos.setPosX(NumberUtil.parseInt(props.getProperty("sign.pos.x."+type), 400));
pos.setPosY(NumberUtil.parseInt(props.getProperty("sign.pos.y."+type), 400));
pos.setPosPage(props.getProperty("sign.pos.page."+type, "1"));
return pos;
}

/** 创建账户和印章信息 */
public static SignInfo signInfo(Long userId) {
com.qingbo.ginkgo.project.service.SignService service = applicationContext.getBean(com.qingbo.ginkgo.project.service.SignService.class);
SignInfo signInfo = service.getSignInfo(userId).getObject();
if(signInfo!=null) return signInfo;
CustomerService customerService = applicationContext.getBean(CustomerService.class);
User user = customerService.getUserByUserId(userId).getObject();//获取用户信息
if(user.getRegisterType().equals(UserRegisterType.ENTERPRISE.getCode())) {
UserEnterpriseProfile enterpriseProfile = user.getEnterpriseProfile();
String accountId = addOrganize(enterpriseProfile.getEnterpriseName(), enterpriseProfile.getOrganizationCode(), enterpriseProfile.getContactPhone(), enterpriseProfile.getLegalPersonName(), enterpriseProfile.getLegalPersonIdNum());
if(accountId != null) {//机构开户和创建印章
String sealData = addSeal(accountId, enterpriseProfile.getLicenseNum());
if(sealData != null) {
signInfo = service.getSignInfo(userId).getObject();
return signInfo;//保存签名信息
}
}
}else {
UserProfile userProfile = user.getUserProfile();
String accountId = addAccount(userProfile.getRealName(), userProfile.getIdNum(), userProfile.getMobile());
if(accountId != null) {
String sealData = addSeal(accountId);//个人开户和创建印章
if(sealData != null) {
signInfo = service.getSignInfo(userId).getObject();
if(signInfo == null) signInfo = new SignInfo();
signInfo.setUserId(userId);
signInfo.setAccountId(accountId);
signInfo.setSealData(sealData);
service.mergeSignInfo(signInfo);
return signInfo;
}
}
}
return null;
}

private static String srcPdf(String dir, String contracts, String contract) {
String pdfPath = contract+".pdf";
File pdfFile = new File(dir, pdfPath);
if(!pdfFile.exists()) {
logger.info("srcPdf not exist: "+pdfFile.getAbsolutePath());
String pdfUrl = contracts+pdfPath;
if(CodeUtil.exist(pdfUrl)) CodeUtil.down(pdfUrl, pdfFile.getAbsolutePath());
logger.info("try download from: "+pdfUrl+", result: "+pdfFile.exists());
}
return pdfFile.exists() ? pdfFile.getAbsolutePath() : null;
}

private static String dstPdf(String dir, String contracts, Long projectId, Long investId) {
String pdfPath = projectId+"-"+investId+".signed.pdf";
File pdfFile = new File(dir, pdfPath);
String pdfUrl = contracts+pdfPath;
if(CodeUtil.exist(pdfUrl)) return null;
else if(pdfFile.exists()) {
logger.info("dstPdf exist and re-uploaded: "+pdfFile.getAbsolutePath());
if(NumberUtil.parseBoolean(props.getProperty("sign.upload"), false)) UploadUtil.contract("contract", pdfFile.getAbsolutePath());
return null;
}else return pdfFile.getAbsolutePath();
}

private static boolean success(Result r) { return r!=null && r.getErrCode()==0; }
private static String show(Result r) { return r==null ? "null" : JSON.toJSONString(r); }

static {//初始化和登录
String projectId = props.getProperty("sign.project_id");
String projectSecret = props.getProperty("sign.project_secret");
if(StringUtils.isNotBlank(projectId) && StringUtils.isNotBlank(projectSecret)) {
ConfigProperties cfg = new ConfigProperties(resource);
Result init = esignsdkService.init(projectId, projectSecret);
if(success(init)) {
logger.info("SignUtil init success");
LoginResult login = esignsdkService.login();
if(success(login)) {
devId = login.getAccountId();
logger.info("SignUtil login success, accountId: "+devId);
}
}
}
}
}