var System = require("../../system");
const querystring = require('querystring');
var settings = require("../../../config/settings");
const logCtl = System.getObject("web.oplogCtl");
const crypto = require('crypto');
const uuidv4 = require('uuid/v4');
const fs = require("fs");
const axios = require("axios");
//工商查询操作
class UtilESignBaoService {
  constructor() {
    this.eSignBaoUrl = settings.apiconfig.eSignBaoUrl();
    this.eSignBaoBankVerifyUrl = settings.apiconfig.eSignBaoBankVerifyUrl();
    this.restClient = System.getObject("util.restClient");
    this.ossClient = System.getObject("util.ossClient");
  }

  //-------------------------------------------------------------------------e签宝银行四要素、三要素验证---开始----------------
  async bankthree(params, opName) { //三要素验证
    var result = {
      code: 1,
      message: "success",
      data: {}
    };
    var reqUrl = this.eSignBaoBankVerifyUrl + "/infoauth/psn/bankthree";
    var tResult = await this.returnResult(params, reqUrl, opName, "createAccountId", result);
    if (tResult.errCode != 0) {
      result.code = -110;
      if (tResult.message && tResult.message.indexOf(":") > 0) {
        var tmpListStr = tResult.message.split(':');
        result.message = tmpListStr[1] ? tmpListStr[1] : tmpListStr[0];
      } else {
        result.message = "接口请求错误";
      }
      return result;
    }
    if (tResult.errCode == 0 && tResult.data && !tResult.data.pass) {
      result.code = -120;
      result.message = "亲，提供的信息不正确，请验证后再试！";
      return result;
    }
    result.data = tResult.data;
    return result;
  }
  async bankfour(params, opName) { //四要素验证
    var result = {
      code: 1,
      message: "success",
      data: {}
    };
    var reqUrl = this.eSignBaoBankVerifyUrl + "/infoauth/psn/bankfour";
    var tResult = await this.returnResult(params, reqUrl, opName, "createAccountId", result);
    if (tResult.errCode != 0) {
      result.code = -110;
      if (tResult.message && tResult.message.indexOf(":") > 0) {
        var tmpListStr = tResult.message.split(':');
        result.message = tmpListStr[1] ? tmpListStr[1] : tmpListStr[0];
      } else {
        result.message = "接口请求错误";
      }
      return result;
    }
    if (tResult.errCode == 0 && tResult.data && !tResult.data.pass) {
      result.code = -120;
      result.message = "亲，提供的信息不正确，请验证后再试！";
      return result;
    }
    result.data = tResult.data;
    return result;
  }
  //-------------------------------------------------------------------------e签宝银行四要素、三要素验证---结束----------------


  //-------------------------------------------------------------------------下载e签宝合同文件---开始----------------

  async downloadUserContractFile(flowId, opName) { //下载e签宝合同文件，并包含已经上传自己oss服务器的文件地址
    var result = {
      code: 1,
      message: "success",
      data: {}
    };
    var downFileInfo = await this.getUserContractFile(flowId, opName, result);
    if (downFileInfo.code != 1) {
      return downFileInfo;
    }
    if (downFileInfo.data.lenght == 0) {
      result.code = -111;
      result.message = "没有合同数据";
      return result;
    }
    //e签宝返回的操作属性
    var tData = downFileInfo.data[0];
    var docId = tData.docId;
    var thirdDocId = tData.thirdDocId;
    var docUrl = tData.docUrl;
    if (docUrl == null || docUrl == "" || docUrl == "undefined") {
      result.code = -112;
      result.message = "文档链接为空";
      return result;
    }
    var opDownFileResult = await this.opDownFileInfo(docUrl, flowId, result);
    // console.log(opDownFileResult,"==========opDownFile????====================================");
    if (opDownFileResult.code != 1) {
      return opDownFileResult;
    }
    result.data = {
      docId: docId,
      thirdDocId: thirdDocId,
      docUrl: docUrl,
      selfossUrl: opDownFileResult.data.url
    };
    return result;
  }
  async getUserContractFile(flowId, opName, result) { //获取用户的签署合同文件
    var param = {
      flowId: flowId
    }
    var reqUrl = this.eSignBaoUrl + "/sign/download";
    var tResult = await this.returnResult(param, reqUrl, opName, "getUserContractFile", result);
    if (tResult.errCode != 0) {
      //日志记录
      logCtl.info({
        optitle: "e签宝===>获取用户合同信息info",
        op: "app/base/service/impl/utilesignbaoSve/getUserContractFile",
        content: "参数：flowId=" + flowId + "，请求返回的参数：" + JSON.stringify(tResult),
        clientIp: ""
      });
      
      result.code = -110;
      result.errCode = tResult.errCode;
      result.message = "获取文件接口请求错误";
      return result;
    }
    result.data = tResult.data;
    return result;
  }
  async opDownFileInfo(docUrl, flowId, result) { //从oss下载到本地并上传到自己oss，之后删除本地文件
    /*docUrl下载链接，全路径，如：https://XXXXXX.pdf?XXXXX */
    try {
      var tmpFileName = docUrl.substring(0, docUrl.lastIndexOf("?"));
      var fileName = tmpFileName.substr(tmpFileName.lastIndexOf("/") + 1, tmpFileName.lenght);
      //解码后的文件全名:xxx.pdf
      var fileAllName = decodeURIComponent(fileName); //为xxx.pdf
      var saveFilePath = '/tmp/' + flowId + ".pdf";
      // 下载文件到指定的路径
      var tmpp = await this.restClient.execDownload("'" + docUrl + "'", saveFilePath);
      //上传 saveFilePath的文件 到ossClient
      var uuid = uuidv4();
      var u = uuid.replace(/\-/g, "");
      var upFileName = "zc_zxy_" + u + ".pdf";
      var rtn = await this.ossClient.upfile(upFileName, saveFilePath);
      result.data = rtn;
      //删除本地文件
      fs.unlink(saveFilePath, function (err) {});
    } catch (e) {
      result.code = -200;
      result.message = "通过flowId获取到的文件url下载操作异常异常error";
      console.log(e.stack);
      //日志记录
      logCtl.error({
        optitle: "e签宝通过flowId获取到的文件url下载操作异常异常error",
        op: "base/service/impl/utilesignbaoSve/opDownFileInfo",
        content: "请求参数：docUrl=" + docUrl + "，异常信息error：" + e.stack,
        clientIp: ""
      });
    }
    return result;
  }

  //-------------------------------------------------------------------------下载e签宝合同文件---结束----------------

  //-------------------------------------------------------------------------创建账号---开始----------------
  async creatCompanyAccountId(params, opName) { //创建企业账号
    var result = {
      code: 1,
      message: "success",
      data: {}
    };
    var reqUrl = this.eSignBaoUrl + "/account/create/organize/common";
    var tResult = await this.returnResult(params, reqUrl, opName, "creatCompanyAccountId", result);
    if (tResult.errCode != 0) {
      result.code = -110;
      result.message = "接口请求错误";
    }
    result.data = tResult.data;
    return result;
  }
  async grantAuthorization(params, opName) { //设置企业静默签署授权
    var result = {
      code: 1,
      message: "success"
    };
    var reqUrl = this.eSignBaoUrl + "/account/platform/silentsign";
    var tResult = await this.returnResult(params, reqUrl, opName, "grantAuthorization", result);
    console.log("--------------tResult--------------------");
    console.log(tResult);
    if (tResult.errCode != 0) {
      result.code = -110;
      result.message = "接口请求错误";
    }
    console.log("-------------result----------------------");
    console.log(result);
    return result;
  }

  async createAccountId(params, opName) { //创建个人账号
    var result = {
      code: 1,
      message: "success",
      data: {}
    };
    var reqUrl = this.eSignBaoUrl + "/account/create/person";
    var tResult = await this.returnResult(params, reqUrl, opName, "createAccountId", result);
    if (tResult.errCode != 0) {
      result.code = -110;
      result.message = "接口请求错误";
      return result;
    }
    result.data = tResult.data;
    return result;
  }

  async updateAccountId(params, opName) { //创建个人账号
    var result = {
      code: 1,
      message: "success",
      data: {}
    };
    var reqUrl = this.eSignBaoUrl + "/account/person/update";
    var tResult = await this.returnResult(params, reqUrl, opName, "updateAccountId", result);
    if (tResult.errCode != 0) {
      result.code = -110;
      result.message = "接口请求错误";
      return result;
    }
    result.data = {
      accountId: params.accountId
    };
    return result;
  }

  //-------------------------------------------------------------------------创建账号---结束----------------

  //-------------------------------------------------------------------------创建企业印章---开始----------------
  async createEntSeal(sealUrl, accountId, aliasName, opName) {
    //日志记录
    logCtl.info({
      optitle: "e签宝===>创建模板文件信息info",
      op: "app/base/service/impl/utilesignbaoSve/createEntSeal",
      content: "参数：sealUrl=" + sealUrl,
      clientIp: ""
    });
    var result = {
      code: 1,
      message: "success",
      data: {}
    }
    var templateFileResult = await this.downloadEntTemplateFile(sealUrl, result);
    if (templateFileResult.code != 1) {
      return result;
    }
    //操作的本地文件
    const opFileAllName = templateFileResult.data.file_all_name;
    //获取文件属性
    var stats = await this.statpromise(opFileAllName);
    var uploadFileResult = await this.uploadfileToeBao(opFileAllName, stats.size, result, opName);
    if (uploadFileResult.code != 1) {
      return result;
    }
    //e签宝返回的操作属性
    const opFileKey = uploadFileResult.data.fileKey;
    const opUploadFileUrl = uploadFileResult.data.uploadUrl;
    const opContentMd5 = uploadFileResult.data.content_md5;
    //日志记录
    logCtl.info({
      optitle: "e签宝===>curlUpResult模板到e签宝服务器请求参数信息info",
      op: "app/base/service/impl/utilesignbaoSve/curlPutFileToeBao",
      content: "请求参数：opFileKey=" + opFileKey + "，opUploadFileUrl=" + opUploadFileUrl + "，opFileAllName=" + opFileAllName + "，opContentMd5=" + opContentMd5,
      clientIp: ""
    });
    //curl文件到e签宝
    var curlUpResult = await this.curlPutFileToeBao(opFileAllName, opUploadFileUrl, opFileKey, opContentMd5, opName, result);
    if (uploadFileResult.code != 1) {
      return result;
    }

    var sealParams = {
      accountId: accountId,
      alias: aliasName,
      color: "RED",
      fileKey: opFileKey
    }
    var reqUrl = this.eSignBaoUrl + "/seal/create/image/organize";
    var tResult = await this.returnResult(sealParams, reqUrl, opName, "create organize", result);
    if (tResult.errCode != 0) {
      result.code = -110;
      result.message = "接口请求错误";
      return result;
    }

    // 创建印章id
    result.data = {
      fileKey: opFileKey,
      sealId: tResult.data.sealId,
    };
    return result
  }
  //-------------------------------------------------------------------------创建企业印章---结束----------------

  //-------------------------------------------------------------------------创建模板---开始----------------
  //创建模板文件
  async createEntTemplate(selfTemplateUrl, templateName, opName) {
    //日志记录
    logCtl.info({
      optitle: "e签宝===>创建模板文件信息info",
      op: "app/base/service/impl/utilesignbaoSve/createEntTemplate",
      content: "参数：selfTemplateUrl=" + selfTemplateUrl + "，templateName=" + templateName,
      clientIp: ""
    });
    var result = {
      code: 1,
      message: "success",
      data: {}
    }
    var templateFileResult = await this.downloadEntTemplateFile(selfTemplateUrl, result);
    if (templateFileResult.code != 1) {
      return result;
    }
    //操作的本地文件
    const opFileAllName = templateFileResult.data.file_all_name;
    //获取文件属性
    var stats = await this.statpromise(opFileAllName);
    var uploadFileResult = await this.uploadfileToeBao(opFileAllName, stats.size, result, opName);
    if (uploadFileResult.code != 1) {
      return result;
    }
    //e签宝返回的操作属性
    const opFileKey = uploadFileResult.data.fileKey;
    const opUploadFileUrl = uploadFileResult.data.uploadUrl;
    const opContentMd5 = uploadFileResult.data.content_md5;
    //日志记录
    logCtl.info({
      optitle: "e签宝===>curlUpResult模板到e签宝服务器请求参数信息info",
      op: "app/base/service/impl/utilesignbaoSve/curlPutFileToeBao",
      content: "请求参数：opFileKey=" + opFileKey + "，opUploadFileUrl=" + opUploadFileUrl + "，opFileAllName=" + opFileAllName + "，opContentMd5=" + opContentMd5,
      clientIp: ""
    });
    //curl文件到e签宝
    var curlUpResult = await this.curlPutFileToeBao(opFileAllName, opUploadFileUrl, opFileKey, opContentMd5, opName, result);
    if (uploadFileResult.code != 1) {
      return result;
    }
    //创建合同模板
    var upParams = {
      fileKey: opFileKey,
      templateName: templateName
    };
    var reqTemplateUrl = this.eSignBaoUrl + "/template/createbyfilekey";
    var templateResult = await this.returnResult(upParams, reqTemplateUrl, opName, "createEntTemplate", result);
    //日志记录
    logCtl.info({
      optitle: "e签宝===>template/createbyfilekey返回结果信息info",
      op: "app/base/service/impl/utilesignbaoSve/templateResult",
      content: "返回参数：" + JSON.stringify(templateResult),
      clientIp: ""
    });
    if (templateResult.errCode != 0 || templateResult.data == null) {
      result.code = -116;
      result.message = "文件上传接口请求错误";
    }
    uploadFileResult.data = {
      fileKey: opFileKey,
      templateId: templateResult.data.templateId
    };
    return uploadFileResult
  }
  //curl文件到e签宝(参数：opFileAllName本地文件xxx.pdf、opUploadFileUrl运程上传文件、opFileKey上传文件的filekey、opContentMd5上传文件的md5、opName)
  async curlPutFileToeBao(opFileAllName, opUploadFileUrl, opFileKey, opContentMd5, opName, result) {
    var cmd = "curl -X PUT '" + opUploadFileUrl + "' -T " + opFileAllName + " -H 'Charset: utf-8' -H 'cache-control: no-cache' -H 'Content-Type: application/pdf'" +
      " -H 'Content-MD5:" + opContentMd5 + "'";
    //日志记录
    logCtl.info({
      optitle: "e签宝===>curlUpResult模板到e签宝服务器请求参数==cmd==信息info",
      op: "app/base/service/impl/utilesignbaoSve/curlPutFileToeBao",
      content: "请求参数：cmd=" + cmd,
      clientIp: ""
    });
    var rtn = null;
    try {
      rtn = await this.restClient.execCustomPostESignBao(cmd);
      //日志记录
      logCtl.info({
        optitle: "e签宝===>curl文件到e签宝服务器信息info",
        op: "app/base/service/impl/utilesignbaoSve/curlPutFileToeBao",
        content: "cmd=" + cmd + "，返回信息=" + JSON.stringify(rtn),
        clientIp: ""
      });
      if (rtn.stdout == null || rtn.stdout == "" || rtn.stdout == "undefined") {
        result.code = -113;
        result.message = "请求结果返回为空";
        return result;
      }
      var upResult = JSON.parse(rtn.stdout);
      if (upResult.errCode == 0) {
        // console.log("del................................................");
        //删除本地文件
        fs.unlink(opFileAllName, function (err) {});
      }
      return result;
    } catch (e) {
      console.log("curl put e签宝对url文件上传操作异常error");
      console.log(e.stack);
      //日志记录
      logCtl.error({
        optitle: "curl put 上传e签宝远程文件操作opClassName=" + opName + "，opMethod=curlPutFileToeBao操作异常异常error",
        op: "base/service/impl/utilesignbaoSve/createEntTemplate",
        content: e.stack,
        clientIp: ""
      });
      result.code = -200;
      result.message = "操作异常"
      return result;
    }
  }
  //上传模板到e签宝
  async uploadfileToeBao(fileAllName, filesize, result, opName) {
    try {
      //读取一个Buffer
      var buffer = fs.readFileSync(fileAllName);
      var fsHash = crypto.createHash('md5');
      fsHash.update(buffer);
      var md5 = fsHash.digest();
      // console.log("文件的MD5是：%s", md5);
      var b = new Buffer(md5);
      var s = b.toString('base64');
      var uploadParams = {
        contentMd5: s,
        fileName: fileAllName,
        fileSize: filesize,
        contentType: "application/pdf"
      };
      //上传模板到e签宝
      var reqUrl = this.eSignBaoUrl + "/file/uploadurl";
      var tResult = await this.returnResult(uploadParams, reqUrl, opName, "uploadfileToeBao", result);
      // console.log(tResult,"上传模板到e签宝.....................tResult");
      //日志记录
      logCtl.info({
        optitle: "e签宝===>创建模板文件上传到e签宝服务器信息info",
        op: "app/base/service/impl/utilesignbaoSve/uploadfileToeBao",
        content: "参数：uploadParams=" + JSON.stringify(uploadParams) + "，返回信息=" + JSON.stringify(tResult),
        clientIp: ""
      });
      if (tResult.errCode != 0 || tResult.data == null) {
        result.code = -112;
        result.message = "文件上传接口请求错误";
      }
      result.data = {
        fileKey: tResult.data.fileKey,
        uploadUrl: tResult.data.uploadUrl,
        content_md5: s
      };
      return result;
    } catch (e) {
      console.log(e.stack);
      //日志记录
      logCtl.error({
        optitle: "e签宝文件上传opClassName=" + opName + "，opMethod=uploadfileToeBao操作异常异常error",
        op: "base/service/impl/utilesignbaoSve/uploadfileToeBao",
        content: e.stack,
        clientIp: ""
      });
      result.code = -200;
      result.message = "文件上传操作异常"
      return result;
    }
    return result;
  }
  //从自己阿里云下载公司模板文件(selfTemplateUrl:公司合同模板链接文件)
  async downloadEntTemplateFile(selfTemplateUrl, result) {
    var fileName = selfTemplateUrl.substr(selfTemplateUrl.lastIndexOf("/") + 1, selfTemplateUrl.lenght);
    var fileExpanded = selfTemplateUrl.substr(selfTemplateUrl.lastIndexOf(".") + 1, selfTemplateUrl.lenght); //pdf
    if (fileExpanded == null || fileExpanded == "") {
      result.code = -110;
      result.message = "文件格式不正确";
      return result;
    }
    //解码后的文件全名:xxx.pdf
    var fileAllName = decodeURIComponent(fileName); //为xxx.pdf
    var downfileInfo = await this.ossClient.downfile(fileAllName);
    if (downfileInfo == null || downfileInfo.res == null || downfileInfo.res.status != 200) {
      result.code = -111;
      result.message = "下载失败";
      return result;
    }
    result.data = {
      file_all_name: "/tmp/" + fileAllName
    };
    return result;
  }
  //获取文件信息
  async statpromise(filePath) {
    var promise = new Promise((resv, rej) => {
      fs.stat(filePath, function (err, stats) {
        if (err) {
          rej(err);
        } else {
          resv(stats);
        }
      });
    });
    return promise;
  }
  //-------------------------------------------------------------------------创建模板-----结束--------------

  //-------------------------------------------------------------------------根据模板创建用户签署合同及签署过程-----开始--------------
  /*参数说明:
      var params = {
      templateId: "2c98d5446734acf5016827d168a6013b",  //模板id，由创建模板接口调用返回的templateId 必填
      name: "汉唐信通（北京）咨询股份有限公司",  //合同模板名称 必填
      simpleFormFields: {
        nameA: "汉唐信通（北京）咨询股份有限公司",    //甲方 必填
        nameB: "高宇强",    //乙方 必填
        unit: "吉林省华生商贸有限公司公主岭华生百货商场-公主岭百货",     //合作单位（国美） 必填---------------------------超出长度风险---目前不知多少长度
        signDateA: "2018-12-09",  //甲方签约日期 必填
        signDateB: "2018-12-09"   //乙方签约日期 必填
      }
    };
    var ebaoAccountId = "9238f57f559b411eb9b4685bc1b903f7";//签署人账户id-- 必填
    var thirdOrderNo = "";//第三方流水号，通知回调使用---选填
    var eSignBaoRedirectBossUrl = "https://boss.gongsibao.com/";// //页面签署完成后跳转地址
    opName:操作类名
    sealId:印章id，不传时使用账户默认印章
  */
  async userSignContractNoTemplate(params, ebaoAccountId, thirdOrderNo, eSignBaoRedirectBossUrl, opName, sealId) { //用户签署合同-------调用此方法
    //日志记录
    logCtl.info({
      optitle: "e签宝===>创建用户签署合同信息info",
      op: "app/base/service/impl/utilesignbaoSve/userSignContractNoTemplate",
      content: "参数：ebaoAccountId=" + ebaoAccountId + "，thirdOrderNo=" + thirdOrderNo + "，eSignBaoRedirectBossUrl=" + eSignBaoRedirectBossUrl + "，请求params参数：" + JSON.stringify(params),
      clientIp: ""
    });
    /*
    1.合同模板创建合同 5.4.2
    2.创建合同签署流程 5.5.1
    3.发起对接平台自动签署 5.5.2
    4.发起个人手动签署 5.5.4
    */
    var result = {
      code: 1,
      message: "success",
      data: {}
    };
    if (ebaoAccountId == null || ebaoAccountId == "" || ebaoAccountId == "undefined") {
      result.code = -100;
      result.message = "ebaoAccountId参数有误";
      return result;
    }
    var tThirdOrderNo = thirdOrderNo == null || thirdOrderNo == "" || thirdOrderNo == "undefined" ? "" : thirdOrderNo
    var self = this;
    //1.合同模板创建合同 5.4.2
    var createTemplate = await self.createByTemplate(params, opName, result);
    if (createTemplate.code != 1) {
      return result;
    }
    var tDocId = createTemplate.data.docId;
    var addProcessParams = {
      businessScene: params.name, //业务场景名称-- 必填
      initiatorAccountId: "", //发起方账户id，默认对接平台,--使用默认的，不用填写
      signValidity: "", //签署截止时间戳毫秒值-- 选填
      payer: "", //签署付费方，默认对接平台-- 选填
      signPlatform: "1", //指定用户签署的平台,空值表示不限平台(1:H5签2:支付宝生活号签3:微信小程序签(后续版本支持))-- 选填
      noticeType: "", //用户接收签署任务通知的方式,空值不通知,1短信，2邮箱，格式"1,2"
      redirectUrl: eSignBaoRedirectBossUrl, //页面签署完成后跳转地址
      docId: tDocId, //合同id
      docName: "" //合同名称，默认使用创建合同时的名称-- 选填
    };
    //2.创建合同签署流程 5.5.1
    var createAddProcess = await self.addProcess(addProcessParams, opName, result);
    if (createAddProcess.code != 1) {
      return result;
    }
    var tFlowId = createAddProcess.data.flowId;
    var platformSignTaskParams = {
      flowId: tFlowId, //流程id-- 必填
      thirdOrderNo: tThirdOrderNo, //第三方流水号，通知回调使用
      posList: [{
        signType: 1, //盖章位置定位方式,1关键字定位-- 必填
        key: "sealA" //-- 必填
      }]
    };

    if (sealId) {//印章id，不传时使用账户默认印章
      platformSignTaskParams.sealId = sealId;
    }
    //3.发起对接平台自动签署 5.5.2
    var platformSignTaskResult = await self.platformSignTask(platformSignTaskParams, opName, result);
    if (platformSignTaskResult.code != 1) {
      return result;
    }
    var handPersonSignTaskParams = {
      flowId: tFlowId, //流程id-- 必填
      accountId: ebaoAccountId, //签署人账户id-- 必填
      thirdOrderNo: tThirdOrderNo, //第三方流水号，通知回调使用
      sealType: "0", //印章类型, 指定签署印章类型,0:手绘印章;1:模板印章-- 必填
      posList: [{
        signType: 1, //盖章位置定位方式,1关键字定位-- 必填
        key: "sealB" //-- 必填
      }]
    };
    //4.发起个人手动签署 5.5.4
    var handPersonSignTaskResult = await self.handPersonSignTask(handPersonSignTaskParams, opName, result);
    if (handPersonSignTaskResult.code != 1) {
      return result;
    }
    result.data = {
      flowId: tFlowId, //流程id
      docId: tDocId, //合同id
      signUrl: handPersonSignTaskResult.data.signUrl, //签署地址，用户可通过本地址跳转至 e 签宝签署页面进行签署，链接永久有效
      signShortUrl: handPersonSignTaskResult.data.signShortUrl, //接口调用时传入的对接方业务流水号，用于支持对接方进行上下文关联
      templateId: params.templateId //模板id，由创建模板接口调用返回的templateId
    };
    return result;
  }
 /*参数说明:
        var params = {
        templateId: "2c98d5446734acf5016827d168a6013b",  //模板id，由创建模板接口调用返回的templateId 必填
        name: "汉唐信通（北京）咨询股份有限公司",  //合同模板名称 必填
        simpleFormFields: {
          nameA: "汉唐信通（北京）咨询股份有限公司",    //甲方 必填
          nameB: "高宇强",    //乙方 必填
          unit: "吉林省华生商贸有限公司公主岭华生百货商场-公主岭百货",     //合作单位（国美） 必填---------------------------超出长度风险---目前不知多少长度
          signDateA: "2018-12-09",  //甲方签约日期 必填
          signDateB: "2018-12-09"   //乙方签约日期 必填
        }
      };
      var ebaoAccountId = "9238f57f559b411eb9b4685bc1b903f7";//签署人账户id-- 必填
      var thirdOrderNo = "";//第三方流水号，通知回调使用---选填
      var eSignBaoRedirectBossUrl = "https://boss.gongsibao.com/";// //页面签署完成后跳转地址
      opName:操作类名
      sealId:印章id，不传时使用账户默认印章
    */
  async userAutoSignContractNoTemplate(params, ebaoAccountId, thirdOrderNo, eSignBaoRedirectBossUrl, opName, sealId) { //用户签署合同-------调用此方法
    //日志记录
    logCtl.info({
      optitle: "e签宝===>创建用户签署合同信息info",
      op: "app/base/service/impl/utilesignbaoSve/userSignContractNoTemplate",
      content: "参数：ebaoAccountId=" + ebaoAccountId + "，thirdOrderNo=" + thirdOrderNo + "，eSignBaoRedirectBossUrl=" + eSignBaoRedirectBossUrl + "，请求params参数：" + JSON.stringify(params),
      clientIp: ""
    });
    /*
    1.合同模板创建合同 5.4.2
    2.创建合同签署流程 5.5.1
    3.发起对接平台自动签署 5.5.2
    4.发起用户自动签署 5.5.3
    */
    var result = {
      code: 1,
      message: "success",
      data: {}
    };
    if (ebaoAccountId == null || ebaoAccountId == "" || ebaoAccountId == "undefined") {
      result.code = -100;
      result.message = "ebaoAccountId参数有误";
      return result;
    }
    var tThirdOrderNo = thirdOrderNo == null || thirdOrderNo == "" || thirdOrderNo == "undefined" ? "" : thirdOrderNo
    var self = this;
    //1.合同模板创建合同 5.4.2
    var createTemplate = await self.createByTemplate(params, opName, result);
    if (createTemplate.code != 1) {
      return result;
    }
    var tDocId = createTemplate.data.docId;
    var addProcessParams = {
      businessScene: params.name, //业务场景名称-- 必填
      initiatorAccountId: "", //发起方账户id，默认对接平台,--使用默认的，不用填写
      signValidity: "", //签署截止时间戳毫秒值-- 选填
      payer: "", //签署付费方，默认对接平台-- 选填
      signPlatform: "1", //指定用户签署的平台,空值表示不限平台(1:H5签2:支付宝生活号签3:微信小程序签(后续版本支持))-- 选填
      noticeType: "", //用户接收签署任务通知的方式,空值不通知,1短信，2邮箱，格式"1,2"
      redirectUrl: eSignBaoRedirectBossUrl, //页面签署完成后跳转地址
      docId: tDocId, //合同id
      docName: "" //合同名称，默认使用创建合同时的名称-- 选填
    };
    //2.创建合同签署流程 5.5.1
    var createAddProcess = await self.addProcess(addProcessParams, opName, result);
    if (createAddProcess.code != 1) {
      return result;
    }
    var tFlowId = createAddProcess.data.flowId;
    var platformSignTaskParams = {
      flowId: tFlowId, //流程id-- 必填
      thirdOrderNo: tThirdOrderNo, //第三方流水号，通知回调使用
      posList: [{
        signType: 1, //盖章位置定位方式,1关键字定位-- 必填
        key: "sealA" //-- 必填
      }]
    };

    if (sealId) {//印章id，不传时使用账户默认印章
      platformSignTaskParams.sealId = sealId;
    }
    //3.发起对接平台自动签署 5.5.2
    var platformSignTaskResult = await self.platformSignTask(platformSignTaskParams, opName, result);
    if (platformSignTaskResult.code != 1) {
      return result;
    }

    var autoUserSignTaskParams = {
      flowId: tFlowId, //流程id-- 必填
      accountId: ebaoAccountId, //签署人账户id-- 必填
      thirdOrderNo: tThirdOrderNo, //第三方流水号，通知回调使用
      sealType: "0", //印章类型, 指定签署印章类型,0:手绘印章;1:模板印章-- 必填 ?????????????????????????????
      posList: [{
        signType: 1, //盖章位置定位方式,1关键字定位-- 必填
        key: "sealB" //-- 必填
      }]
    };

    //4.发起用户自动签署 5.5.3
    var autoUserSignTaskResult = await self.autoUserSignTask(autoUserSignTaskParams, opName, result);
    if (autoUserSignTaskResult.code != 1) {
      return result;
    }
    // 测试归档时，打开这行注释
    await this.archiveProcess({flowId: tFlowId}, opName);
    result.data = {
      flowId: tFlowId, //流程id
      docId: tDocId, //合同id
      templateId: params.templateId //模板id，由创建模板接口调用返回的templateId
    };
    return result;
  }

  /*
        seal 位置反转
     */
  async userSignContractNoTemplaterEversalSeal(params, ebaoAccountId, thirdOrderNo, eSignBaoRedirectBossUrl, opName, sealId) { //用户签署合同-------调用此方法
    //日志记录
    logCtl.info({
      optitle: "e签宝===>创建用户签署合同信息info",
      op: "app/base/service/impl/utilesignbaoSve/userSignContractNoTemplate",
      content: "参数：ebaoAccountId=" + ebaoAccountId + "，thirdOrderNo=" + thirdOrderNo + "，eSignBaoRedirectBossUrl=" + eSignBaoRedirectBossUrl + "，请求params参数：" + JSON.stringify(params),
      clientIp: ""
    });
    /*
     1.合同模板创建合同 5.4.2
     2.创建合同签署流程 5.5.1
     3.发起对接平台自动签署 5.5.2
     4.发起个人手动签署 5.5.4
     */
    var result = {
      code: 1,
      message: "success",
      data: {}
    };
    if (ebaoAccountId == null || ebaoAccountId == "" || ebaoAccountId == "undefined") {
      result.code = -100;
      result.message = "ebaoAccountId参数有误";
      return result;
    }
    var tThirdOrderNo = thirdOrderNo == null || thirdOrderNo == "" || thirdOrderNo == "undefined" ? "" : thirdOrderNo
    var self = this;
    //1.合同模板创建合同 5.4.2
    var createTemplate = await self.createByTemplate(params, opName, result);
    if (createTemplate.code != 1) {
      return result;
    }
    var tDocId = createTemplate.data.docId;
    var addProcessParams = {
      businessScene: params.name, //业务场景名称-- 必填
      initiatorAccountId: "", //发起方账户id，默认对接平台,--使用默认的，不用填写
      signValidity: "", //签署截止时间戳毫秒值-- 选填
      payer: "", //签署付费方，默认对接平台-- 选填
      signPlatform: "1", //指定用户签署的平台,空值表示不限平台(1:H5签2:支付宝生活号签3:微信小程序签(后续版本支持))-- 选填
      noticeType: "", //用户接收签署任务通知的方式,空值不通知,1短信，2邮箱，格式"1,2"
      redirectUrl: eSignBaoRedirectBossUrl, //页面签署完成后跳转地址
      docId: tDocId, //合同id
      docName: "" //合同名称，默认使用创建合同时的名称-- 选填
    };
    //2.创建合同签署流程 5.5.1
    var createAddProcess = await self.addProcess(addProcessParams, opName, result);
    if (createAddProcess.code != 1) {
      return result;
    }
    var tFlowId = createAddProcess.data.flowId;
    var platformSignTaskParams = {
      flowId: tFlowId, //流程id-- 必填
      thirdOrderNo: tThirdOrderNo, //第三方流水号，通知回调使用
      posList: [{
        signType: 1, //盖章位置定位方式,1关键字定位-- 必填
        key: "sealB" //-- 必填
      }]
    };

    if (sealId) {//印章id，不传时使用账户默认印章
      platformSignTaskParams.sealId = sealId;
    }
    //3.发起对接平台自动签署 5.5.2
    var platformSignTaskResult = await self.platformSignTask(platformSignTaskParams, opName, result);
    if (platformSignTaskResult.code != 1) {
      return result;
    }

    var handPersonSignTaskParams = {
      flowId: tFlowId, //流程id-- 必填
      accountId: ebaoAccountId, //签署人账户id-- 必填
      thirdOrderNo: tThirdOrderNo, //第三方流水号，通知回调使用
      sealType: "0", //印章类型, 指定签署印章类型,0:手绘印章;1:模板印章-- 必填 ?????????????????????????????
      posList: [{
        signType: 1, //盖章位置定位方式,1关键字定位-- 必填
        key: "sealA" //-- 必填
      }]
    };

    //4.发起个人手动签署 5.5.4
    var handPersonSignTaskResult = await self.handPersonSignTask(handPersonSignTaskParams, opName, result);
    if (handPersonSignTaskResult.code != 1) {
      return result;
    }

    result.data = {
      flowId: tFlowId, //流程id
      docId: tDocId, //合同id
      signUrl: handPersonSignTaskResult.data.signUrl, //签署地址，用户可通过本地址跳转至 e 签宝签署页面进行签署，链接永久有效
      signShortUrl: handPersonSignTaskResult.data.signShortUrl, //接口调用时传入的对接方业务流水号，用于支持对接方进行上下文关联
      templateId: params.templateId //模板id，由创建模板接口调用返回的templateId
    };
    return result;
  }

  /*参数说明:
      var params = {
      templateId: "2c98d5446734acf5016827d168a6013b",  //模板id，由创建模板接口调用返回的templateId 必填
      name: "汉唐信通（北京）咨询股份有限公司",  //合同模板名称 必填
      simpleFormFields: {
        nameA: "汉唐信通（北京）咨询股份有限公司",    //甲方 必填
        nameB: "高宇强",    //乙方 必填
        unit: "吉林省华生商贸有限公司公主岭华生百货商场-公主岭百货",     //合作单位（国美） 必填---------------------------超出长度风险---目前不知多少长度
        signDateA: "2018-12-09",  //甲方签约日期 必填
        signDateB: "2018-12-09"   //乙方签约日期 必填
      }
    };
    var ebaoAccountId = "9238f57f559b411eb9b4685bc1b903f7";//签署人账户id-- 必填
    var thirdOrderNo = "";//第三方流水号，通知回调使用---选填
    var eSignBaoRedirectBossUrl = "https://boss.gongsibao.com/";// //页面签署完成后跳转地址
    opName:操作类名
    sealId:印章id，不传时使用账户默认印章
  */
  async userSignContractNoTemplate2(params, ebaoAccountId, thirdOrderNo, eSignBaoRedirectBossUrl, opName, sealId) { //用户签署合同-------调用此方法
    //日志记录k
    logCtl.info({
      optitle: "e签宝===>创建用户签署合同信息info",
      op: "app/base/service/impl/utilesignbaoSve/userSignContractNoTemplate2",
      content: "参数：ebaoAccountId=" + ebaoAccountId + "，thirdOrderNo=" + thirdOrderNo + "，eSignBaoRedirectBossUrl=" + eSignBaoRedirectBossUrl + "，请求params参数：" + JSON.stringify(params),
      clientIp: ""
    });
    /*
    1.合同模板创建合同 5.4.2
    2.创建合同签署流程 5.5.1
    3.发起对接平台自动签署 5.5.2
    4.发起个人手动签署 5.5.4
    */
    var result = {
      code: 1,
      message: "success",
      data: {}
    };
    if (ebaoAccountId == null || ebaoAccountId == "" || ebaoAccountId == "undefined") {
      result.code = -100;
      result.message = "ebaoAccountId参数有误";
      return result;
    }
    var tThirdOrderNo = thirdOrderNo == null || thirdOrderNo == "" || thirdOrderNo == "undefined" ? "" : thirdOrderNo
    var self = this;
    //1.合同模板创建合同 5.4.2
    var createTemplate = await self.createByTemplate(params, opName, result);
    if (createTemplate.code != 1) {
      return result;
    }
    var tDocId = createTemplate.data.docId;
    var addProcessParams = {
      businessScene: params.name, //业务场景名称-- 必填
      initiatorAccountId: "", //发起方账户id，默认对接平台,--使用默认的，不用填写
      signValidity: "", //签署截止时间戳毫秒值-- 选填
      payer: "", //签署付费方，默认对接平台-- 选填
      signPlatform: "1", //指定用户签署的平台,空值表示不限平台(1:H5签2:支付宝生活号签3:微信小程序签(后续版本支持))-- 选填
      noticeType: "", //用户接收签署任务通知的方式,空值不通知,1短信，2邮箱，格式"1,2"
      redirectUrl: eSignBaoRedirectBossUrl, //页面签署完成后跳转地址
      docId: tDocId, //合同id
      docName: "" //合同名称，默认使用创建合同时的名称-- 选填
    };
    //2.创建合同签署流程 5.5.1
    var createAddProcess = await self.addProcess(addProcessParams, opName, result);
    if (createAddProcess.code != 1) {
      return result;
    }
    var tFlowId = createAddProcess.data.flowId;
    var platformSignTaskParams = {
      flowId: tFlowId, //流程id-- 必填
      thirdOrderNo: tThirdOrderNo, //第三方流水号，通知回调使用
      posList: [{
        signType: 1, // 盖章位置定位方式,1关键字定位-- 必填
        key: "sealA" // -- 必填
      }]
    };

    if (sealId) {//印章id，不传时使用账户默认印章
      platformSignTaskParams.sealId = sealId;
    }
    //3.发起对接平台自动签署 5.5.2
    var platformSignTaskResult = await self.platformSignTask(platformSignTaskParams, opName, result);
    if (platformSignTaskResult.code != 1) {
      return result;
    }
    var handPersonSignTaskParams = {
      flowId: tFlowId, //流程id-- 必填
      accountId: ebaoAccountId, //签署人账户id-- 必填
      thirdOrderNo: tThirdOrderNo, //第三方流水号，通知回调使用
      sealType: "0", //印章类型, 指定签署印章类型,0:手绘印章;1:模板印章-- 必填
      posList: [{
        signType: 1, //盖章位置定位方式,1关键字定位-- 必填
        key: "sealB" //-- 必填
      }]
    };
    //4.发起个人手动签署 5.5.4
    var handPersonSignTaskResult = await self.handPersonSignTask(handPersonSignTaskParams, opName, result);
    if (handPersonSignTaskResult.code != 1) {
      return result;
    }
    result.data = {
      flowId: tFlowId, //流程id
      docId: tDocId, //合同id
      signUrl: handPersonSignTaskResult.data.signUrl, //签署地址，用户可通过本地址跳转至 e 签宝签署页面进行签署，链接永久有效
      signShortUrl: handPersonSignTaskResult.data.signShortUrl, //接口调用时传入的对接方业务流水号，用于支持对接方进行上下文关联
      templateId: params.templateId //模板id，由创建模板接口调用返回的templateId
    };
    return result;
  }


  /*创建企业印章:
  accountId:企业账号id, 
  aliasName:印章别名, 
  templateType:
    模板类型：
      1.ROUND_STAR 圆形有五角星章
      2.ROUND_NONE 圆形无五角星章
      3.OVAL_STAR 椭圆有五角星印章
      4.OVAL_NONE 椭圆无五角星印章,
  color
    印章颜色：
      1.RED 红色
      2.BLUE 蓝色
      3.BLACK 黑色
  opName:操作类名
  */
  async creatEntSignet(accountId, aliasName, text, templateType, color, opName) {
    var tmpTemplateType = templateType || "ROUND_STAR";
    var tmpColor = templateType || "RED";
    var result = {
      code: 1,
      message: "success",
      data: {}
    };
    var params = {
      accountId: accountId,
      alias: aliasName,
      templateType: tmpTemplateType,
      text: text,
      color: tmpColor
    }
    var reqUrl = this.eSignBaoUrl + "/seal/create/organize";
    var tResult = await this.returnResult(params, reqUrl, opName, "creatEntSignet", result);
    if (tResult.errCode != 0) {
      result.code = -110;
      result.message = "接口请求错误";
      return result;
    }
    result.data = tResult.data;
    return result;
  }

  async createByTemplate(params, opName, result) { //合同模板创建合同
    var reqUrl = this.eSignBaoUrl + "/doc/createbytemplate";
    var tResult = await this.returnResult(params, reqUrl, opName, "createByTemplate", result);
    if (tResult.errCode != 0) {
      result.code = -110;
      result.message = "接口请求错误";
      return result;
    }
    result.data = tResult.data;
    return result; //获取用户合同id(docId)和合同e签宝url(docUrl)
  }
  async addProcess(params, opName, result) { //创建合同签署流程
    var reqUrl = this.eSignBaoUrl + "/sign/contract/addProcess";
    var tResult = await this.returnResult(params, reqUrl, opName, "addProcess", result);
    if (tResult.errCode != 0) {
      result.code = -210;
      result.message = "接口请求错误";
      return result;
    }
    result.data = tResult.data;
    return result;
  }
  async platformSignTask(params, opName, result) { //发起对接平台自动签署
    var result = {
      code: 1,
      message: "success",
      data: {}
    };
    var reqUrl = this.eSignBaoUrl + "/sign/contract/platformSignTask";
    var tResult = await this.returnResult(params, reqUrl, opName, "platformSignTask", result);
    if (tResult.errCode != 0) {
      result.code = -310;
      result.message = "接口请求错误";
      return result;
    }
    result.data = tResult.data;
    return result;
  }
  async handPersonSignTask(params, opName, result) { //发起个人手动签署
    var result = {
      code: 1,
      message: "success",
      data: {}
    };
    var reqUrl = this.eSignBaoUrl + "/sign/contract/handPersonSignTask";
    var tResult = await this.returnResult(params, reqUrl, opName, "handPersonSignTask", result);
    if (tResult.errCode != 0) {
      result.code = -410;
      result.message = "接口请求错误";
      return result;
    }
    result.data = tResult.data;
    return result;
  }

  async autoUserSignTask(params, opName, result) { //发起用户自动签署
    var result = {
      code: 1,
      message: "success",
      data: {}
    };
    var reqUrl = this.eSignBaoUrl + "/sign/contract/userSignTask";
    var tResult = await this.returnResult(params, reqUrl, opName, "autoUserSignTask", result);
    if (tResult.errCode != 0) {
      result.code = -410;
      result.message = "接口请求错误";
      return result;
    }
    result.data = tResult.data;
    return result;
  }


  //-------------------------------------------------------------------------根据模板创建用户签署合同及签署过程-----结束--------------

  //-------------------------------------------------------------------------签署成功后归档-----开始---------------
  async getContractDetails(params, opName) { //查询合同签署详情
    var result = {
      code: 1,
      message: "success",
      data: {}
    };
    var reqUrl = this.eSignBaoUrl + "/sign/contract/detail";
    var tResult = await this.returnResult(params, reqUrl, opName, "getContractDetails", result);
    if (tResult.errCode != 0) {
      result.code = -110;
      result.message = "接口请求错误";
    }
    result.data = tResult.data;
    console.log("-------------result----------------------");
    console.log(result);
    return result;
  }
  async archiveProcess(params, opName) { //归档流程
    var result = {
      code: 1,
      message: "success"
    };
    var reqUrl = this.eSignBaoUrl + "/sign/contract/archiveProcess";
    var tResult = await this.returnResult(params, reqUrl, opName, "archiveProcess", result);
    //日志记录
    logCtl.info({
      optitle: "e签宝签署回调归档流程返回的信息info",
      op: "base/service/impl/utilesignbaoSve/archiveProcess",
      content: "请求参数：" + JSON.stringify(tResult) + "，返回参数：" + JSON.stringify(tResult),
      clientIp: ""
    });
    if (tResult.errCode != 0) {
      result.code = -110;
      result.message = "接口请求错误";
    }
    return result;
  }
  //-------------------------------------------------------------------------签署成功后归档-----结束--------------
  // async returnResult(params, reqUrl, opClassName, opMethod, result) {
  //   var data = JSON.stringify(params);
  //   var rtn = null;
  //   try {
  //     rtn = await this.restClient.execPostESignBao(data, reqUrl);
  //     console.log(rtn, "rtn---------------------------------e签宝--------execPostESignBao---------------->>>>>>>>>>>>>>>>");
  //     if (rtn.stdout == null || rtn.stdout == "" || rtn.stdout == "undefined") {
  //       result.errCode = -100;
  //       result.code = -100;
  //       result.message = "请求结果返回为空";
  //       return result;
  //     }
  //     return JSON.parse(rtn.stdout);
  //   } catch (e) {
  //     console.log(e.stack);
  //     //日志记录
  //     logCtl.error({
  //       optitle: "e签宝opClassName=" + opClassName + "，opMethod=" + opMethod + "操作异常异常error",
  //       op: "base/service/impl/utilesignbaoSve/returnResult，请求url：" + reqUrl,
  //       content: "请求参数：" + data + "，返回结果参数rtn.stdout：" + rtn.stdout + "，异常信息error：" + e.stack,
  //       clientIp: ""
  //     });
  //     result.errCode = -200;
  //     result.code = -200;
  //     result.message = "操作异常"
  //     return result;
  //   }
  // }

  async returnResult(params, reqUrl, opClassName, opMethod, result) {
    var data = JSON.stringify(params);
    var rtn = null;
    try {
      if (settings.env == 'dev') {
        let rs = await axios({
          method: 'post',
          url: reqUrl,
          data: params,
          headers: {
            'X-Tsign-Open-App-Id': '5111588557',
            'X-Tsign-Open-App-Secret': '1595787e8d5b7d19f7b6798f16f41fc2'
          },
        });
        console.log(rs);
        if (rs.data.errCode != 0) {
          result.code = -110;
          result.message = "接口请求错误";
          return result;
        }
        result.errCode = 0;
        result.data = rs.data.data;
        return result;
      }
      rtn = await this.restClient.execPostESignBao(data, reqUrl);
      console.log(rtn, "rtn---------------------------------e签宝--------execPostESignBao---------------->>>>>>>>>>>>>>>>");
      if (rtn.stdout == null || rtn.stdout == "" || rtn.stdout == "undefined") {
        result.errCode = -100;
        result.code = -100;
        result.message = "请求结果返回为空";
        return result;
      }
      return JSON.parse(rtn.stdout);
    } catch (e) {
      console.log(e.stack);
      //日志记录
      logCtl.error({
        optitle: "e签宝opClassName=" + opClassName + "，opMethod=" + opMethod + "操作异常异常error",
        op: "base/service/impl/utilesignbaoSve/returnResult，请求url：" + reqUrl,
        content: "请求参数：" + data + "，返回结果参数rtn.stdout：" + rtn.stdout + "，异常信息error：" + e.stack,
        clientIp: ""
      });
      result.errCode = -200;
      result.code = -200;
      result.message = "操作异常"
      return result;
    }
  }
}
module.exports = UtilESignBaoService;