const system = require("../../system");
var settings = require("../../../config/settings");
const ServiceBase = require("../sve.base");
const logCtl = system.getObject("web.oplogCtl");

const moment = require('moment');
const crypto = require('crypto');
const cryptoJS = require("crypto-js");
const md5 = require("MD5");

class EcontractService extends ServiceBase {
  constructor() {
    super(ServiceBase.getDaoName(EcontractService));
    this.etemplateSve = system.getObject("service.etemplateSve");
    this.ecompanyDao = system.getObject("db.ecompanyDao");
    this.etemplateDao = system.getObject("db.etemplateDao");

    this.usereaccountDao = system.getObject("db.usereaccountDao")
    this.utilesignbaoSve = system.getObject("service.utilesignbaoSve");
    this.ejobapplyDao = system.getObject("db.ejobapplyDao");
    this.emessageDao = system.getObject("db.emessageDao");
    this.ecompanybusiDao = system.getObject("db.ecompanybusiDao");
    this.userDao = system.getObject("db.userDao");
    this.esealSve = system.getObject("service.esealSve");

    this.ejobapplySve = system.getObject("service.ejobapplySve");

    this.restClient = system.getObject("util.restClient");
    this.maindict = system.getObject("util.maindict");

    this.eSignBaoRedirectBossUrl = settings.apiconfig.eSignBaoRedirectBossUrl();
  }

  async saveOffline(obj) {
    var ecompanyName = obj.ecompanyName;
    var ecompany_id = obj.ecompany_id;
    var userName = obj.userName;
    var mobile = obj.mobile;
    var personsSign = obj.personsSign;
    var bankno = obj.bankno;
    var fileurl = obj.fileurl;

    // 创建account
    var account = await this.usereaccountDao.findOne({
      personsSign: personsSign
    }) || {};
    account.userName = userName;
    account.mobile = mobile;
    account.bankno = bankno;
    account.personsSign = personsSign;
    if (account.id) {
      await account.save();
    } else {
      account.user_id = 0;
      account = await this.usereaccountDao.create(account);
    }

    var now = moment();
    var end = moment().add(1, "years");


    // 创建合同
    var contract = {
      name: ecompanyName,
      fileurl: fileurl,
      eflowstatusname: "已完成",
      eflowstatus: "2",
      begin_at: now,
      completed_at: now,
      user_id: account.user_id,
      usereaccount_id: account.id,
      etemplate_id: 0,
      ecompany_id: ecompany_id,
      end_at: end,
    }

    contract = await this.create(contract);
    this.syncContract(contract.id);
    return contract.id;
  }

  async autoSaveOffline(obj) {
    var ecompany = {};
    //获取模板相关的信息
    var etemplate = await this.etemplateSve.getInfo(obj.etemplate_id);
    var ecompany = await this.ecompanyDao.findById(etemplate.ecompany_id);
    var ecompanyName = ecompany.name || "";
    var ecompany_id = ecompany.id || 0;

    var now = moment();
    var end = moment().add(1, "years");

    var errorItems = [];
    // 循环上传的excle4要素集合
    for (var item in obj.autoExcel) {
      try {
        var userName = obj.autoExcel[item]['name'];
        var mobile = obj.autoExcel[item]['phone'];
        var personsSign = obj.autoExcel[item]['id_card'];
        var bankno = obj.autoExcel[item]['bank_no'];

        // 根据身份证号，获取相应的account
        var account = await this.usereaccountDao.findOne({
          personsSign: personsSign
        }) || {};

        //是否需要电子签约
        var isNeedCreate = true;
        if (account) {
          isNeedCreate = !account.eaccountid || userName != account.userName || account.mobile != mobile || account.bankno != bankno;
        }

        account.userName = userName;
        account.mobile = mobile;
        account.bankno = bankno;
        account.personsSign = personsSign;
        if (account.id) {
          // 验证是否已经签约过
          var signdContract = await this.dao.findOne({
            usereaccount_id: account.id,
            etemplate_id: etemplate.id,
            eflowstatus: '2'
          });
          if (signdContract) {
            errorItems.push(userName + "-已签约");
            continue;
          }
        } else {
          // TODO 创建p_user
          account.user_id = 0;
          account = await this.usereaccountDao.create(account);
        }
        // isNeedCreate = false;
        if (isNeedCreate) {
          // 1.三要素验证,验证失败的话 continue, 记录当前用户失败原因
          var bankthreeParams = {
            name: userName,
            idno: personsSign,
            cardno: bankno
          };
          var threeResult = await this.utilesignbaoSve.bankthree(bankthreeParams, "bankinfoAuth");
          // {"code":-110,"message":"手机号格式错误","data":{}}
          //1成功,-110提示验证信息有误，-120亲，提供的信息不正确，请验证后再试！
          console.log("threeResult-----------------------------", threeResult);
          if (!threeResult || threeResult.code == -120) {
            errorItems.push(userName + "-银行三要素（姓名、身份证、银行卡号）验证失败");
            continue;
          }
          if (threeResult.code == -110) {
            errorItems.push(userName + "-" + threeResult.message || "银行三要素验证失败");
            continue;
          }

          var uidStr = await this.getUidStr(8, 36);
          var thirdId = etemplate.id + "_" + account.id + uidStr;

          //2.创建e签宝account 5.2.1 , 创建后save()
          var params = {
            thirdId: thirdId,
            name: userName,
            idNo: personsSign,
            idType: 19,
            mobile: mobile
          };
          var getAccount = await this.utilesignbaoSve.createAccountId(params, "econtractSve");
          if (getAccount && getAccount.code == 1 && getAccount.data) {
            account.eaccountid = getAccount.data.accountId;
            await account.save();
          } else {
            errorItems.push(userName + "-e签宝账户创建失败");
            continue;
          }
        }

        //3.设置静默签署授权 5.2.5 
        if (!account.isGrantAuto) {
          var paramsGrant = {
            grantAccountId: account.eaccountid
          };
          var grantAuto = await this.utilesignbaoSve.grantAuthorization(paramsGrant, "econtractSve");
          if (grantAuto.code != 1) {
            errorItems.push(userName + "-静默签署设置失败");
            continue;
          }
          account.isGrantAuto = true;
          await account.save();
        }

        //------------------------------------------------
        var resultAll = {
          code: 1,
          message: "success",
          data: {}
        };

        // 创建合同   fileurl、esignUrl 怎么赋值????????????  
        var contract = {
          name: ecompanyName,
          eflowstatusname: "签约中",
          eflowstatus: "1",
          // begin_at: now,
          // completed_at: now,
          user_id: account.user_id,
          usereaccount_id: account.id,
          etemplate_id: obj.etemplate_id,
          ecompany_id: ecompany_id,
          // end_at: end,
        }
        contract = await this.create(contract);

        // 创建印章id
        var sealId = "";
        var eseal = await this.esealSve.findOne({
          nameA: etemplate.nameA
        });
        // TODO 生产环境需要打开
        if (!eseal) {
          // var rs = await this.utilesignbaoSve.creatEntSignet("f50d8f8cdd8d4bcda6b1aaad1d4b14bf", etemplate.nameA + "alias", etemplate.nameA, "", "", "econtractSve");
          var rs = await this.utilesignbaoSve.creatEntSignet(settings.apiconfig.companyAccountId(), etemplate.nameA + "alias", etemplate.nameA, "", "", "econtractSve");
          if (rs && rs.code == 1) {
            sealId = rs.data.sealId;
            await this.esealSve.create({
              nameA: etemplate.nameA,
              sealId: sealId,
            });
          } else {
            errorItems.push(userName + "-生成印章错误");
            continue;
          }
        } else {
          sealId = eseal.sealId;
        }

        let today = new Date().Format("yyyy-MM-dd");
        var signParams = {
          templateId: etemplate.templateid, //模板id，由创建模板接口调用返回的templateId 必填
          name: ecompany.name, //合同模板名称 必填
          simpleFormFields: {
            nameA: etemplate.nameA, //甲方 必填
            nameB: account.userName, //乙方 必填
            unit: ecompany.name, //合作单位（国美） 必填---------------------------超出长度风险---目前不知多少长度
            signDateA: today, //甲方签约日期 必填
            signDateB: today //乙方签约日期 必填
          }
        }
        var ebaoAccountId = account.eaccountid; //签署人账户id-- 必填
        var thirdOrderNo = contract.id; //第三方流水号，通知回调使用---选填
        var eBaoRedirectBossUrl = "";

        var tt = await this.utilesignbaoSve.userAutoSignContractNoTemplate(signParams, ebaoAccountId, thirdOrderNo, eBaoRedirectBossUrl, "econtractSve", sealId);
        if (tt && tt.data && tt.code == 1) {
          contract.eflowid = tt.data.flowId;
          contract.edocid = tt.data.docId;
          contract.eflowstatus = '2';
          contract.eflowstatusname = "已完成";

          var signTime = new Date();
          contract.completed_at = signTime;
          contract.begin_at = signTime;
          var end_at = new Date();
          end_at.setFullYear(end_at.getFullYear() + 1);
          contract.end_at = end_at;

          contract.save();
        }

      } catch (error) {
        console.log(error.message);
        continue;
      }
    }

    if (errorItems.length > 0) {
      var errors = "";
      for (var item of errorItems) {
        errors += item + "、";
      }
      return system.getErrResult2(errors.substr(0, errors.length - 1));
    }

    return resultAll;
  }

  async pageByCondition(params) {
    var currentPage = Number(params.currentPage || 0);
    var pageSize = Number(params.pageSize || 10);

    var where = {};

    if (params.ecompanyIds) {
      where.ecompany_id = {
        [this.db.Op.in]: params.ecompanyIds
      };
    }

    if (params.ecompany_id) {
      where.ecompany_id = params.ecompany_id;
    }

    if (params.eflowstatusList) {
      where.eflowstatus = {
        [this.db.Op.in]: params.eflowstatusList
      };;
    }

    if (params.accountName || params.accountMobile || params.accountIdno) {
      var accountIds = await this.usereaccountDao.idsByCondition({
        userName: params.accountName || "",
        mobile: params.accountMobile || "",
        personsSign: params.accountIdno || "",
      });

      if (!accountIds || accountIds.length == 0) {
        return {
          total: 0,
          rows: []
        };
      }

      where.usereaccount_id = {
        [this.db.Op.in]: accountIds
      };
    }
    this.addWhereTime(where, 'completed_at', params.signBegin, params.signEnd, true);

    var orderby = [
      ["id", 'desc']
    ];

    var attributes = [`id`, `fileurl`, `eflowstatus`, `eflowstatusname`, `completed_at`, `end_at`, `user_id`, `usereaccount_id`, `ecompany_id`, `etemplate_id`];

    var page = await this.getPageList(currentPage, pageSize, where, orderby, attributes);
    if (page && page.rows) {
      for (var row of page.rows) {
        this.handleDate(row, ["completed_at", "end_at"], null);
      }
      await this.setEaccount(page.rows);
      await this.setCompany(page.rows);
      await this.setEtemplate(page.rows);
    }
    return page;
  }

  async setEaccount(list) {
    if (!list || list.length == 0) {
      return;
    }

    var ids = [];
    for (var item of list) {
      ids.push(item.usereaccount_id);
    }
    var attrs = " `id`, `mobile`, `userName`, `personsSign`, `bankno` ";
    var accountMap = await this.usereaccountDao.findMapByIds(ids, attrs);

    for (var item of list) {
      item.eaccount = accountMap["id_" + item.usereaccount_id];
    }
  }

  async setCompany(list) {
    if (!list || list.length == 0) {
      return;
    }

    var companyIds = [];
    for (var item of list) {
      companyIds.push(item.ecompany_id || 0);
    }
    var companyMap = await this.ecompanyDao.findMapByIds(companyIds, " id, name, contractMobile ");
    for (var item of list) {
      item.ecompany = companyMap["id_" + (item.ecompany_id || 0)];
    }
  }

  async setEtemplate(list) {
    if (!list || list.length == 0) {
      return;
    }

    var ids = [];
    for (var item of list) {
      ids.push(item.etemplate_id || 0);
    }
    var map = await this.etemplateDao.findMapByIds(ids, " id, nameA ");
    for (var item of list) {
      item.template = map[(item.etemplate_id || 0)];
    }
  }

  async findInfo(obj) {
    obj = obj || {};
    let v = [{
        model: this.db.models.ecompany,
        attributes: ["id", "name"]
      },
      {
        model: this.db.models.user,
        attributes: ["id", "userName", "mobile"]
      },
      {
        model: this.db.models.usereaccount,
        attributes: ["id", "userName", "mobile", "personsSign"]
      },
      {
        model: this.db.models.etemplate,
        attributes: ["id", "name"]
      }
    ];
    var result = await this.dao.model.findOne({
      where: obj,
      include: v
    });
    return result;
  }

  async findContracts(obj) {
    obj = obj || {};
    let v = [{
        model: this.db.models.ecompany,
        attributes: ["id", "name"]
      },
      {
        model: this.db.models.user,
        attributes: ["id", "userName", "mobile"]
      },
      {
        model: this.db.models.usereaccount,
        attributes: ["id", "userName", "mobile", "personsSign"]
      },
      {
        model: this.db.models.etemplate,
        attributes: ["id", "name"]
      }
    ];
    var result = await this.dao.model.findAll({
      where: obj,
      include: v
    });
    return result;
  }

  async findUserSinedCompanyIds(usereaccount_id) {
    return this.dao.findUserSinedCompanyIds(usereaccount_id);
  }

  async updateCallbackStatus(obj) {
    obj = obj || {};

    logCtl.info({
      optitle: "e签宝回调修改合同信息info",
      op: "app/base/service/impl/econtractSve/updateCallbackStatus",
      content: "请求参数：" + JSON.stringify(obj),
      clientIp: ""
    });

    let contract;
    try {
      let signTime = obj.signTime;
      let signResult = obj.signResult || "1";
      let thirdOrderNo = Number(obj.thirdOrderNo || 0);

      contract = await super.findById(Number(thirdOrderNo));
      if (!contract) {
        return;
      }

      contract.eflowstatus = signResult.toString();
      contract.completed_at = signTime;
      contract.begin_at = signTime;
      contract.resultDescription = obj.resultDescription || "";
      var end_at = new Date(signTime);
      end_at.setFullYear(end_at.getFullYear() + 1);
      contract.end_at = end_at;

      await contract.save();

      if (contract.isInsure) {
        try {
          // await this.sendInsure(contract.id);
        } catch (error) {
          logCtl.error({
            optitle: "调用团险失败，id = " + contract.id,
            op: "app/base/service/impl/econtractSve/updateCallbackStatus",
            content: "错误信息：" + e.stack,
            clientIp: ""
          });

        }
      }

      if (signResult == "2") {
        // TODO WANGKUN 改定时任务获取
        // let fileRs = await this.utilesignbaoSve.downloadUserContractFile(contract.eflowid, "econtractSve");
        // console.log(fileRs, "---------------------------------------------------");
        // if(fileRs.code == 1 && fileRs.data.selfossUrl) {
        //   contract.fileurl = fileRs.data.selfossUrl;
        //   contract.save();
        // }
        try {
          this.updateApply(contract.id);
        } catch (error) {}

        try {
          this.syncContract(contract.id);
        } catch (error) {}

        try {
          // 推送签约信息给客户
          this.syncSign(contract.id);
        } catch (error) {}
      }
    } catch (e) {
      logCtl.error({
        optitle: "e签宝回调修改合同信息error",
        op: "app/base/service/impl/econtractSve/updateCallbackStatus",
        content: "错误信息：" + e.stack,
        clientIp: ""
      });
    }
    return contract;
  }

  async sendInsure(id) {
    var contract = await this.dao.findById(id);
    var account = await this.usereaccountDao.findById(contract.usereaccount_id);
    if (!account || !account.userName || !account.personsSign || !account.mobile) {
      return;
    }

    var url = "https://api.baoxianxia.com.cn/api/yxyy/service/insure";

    var params = {
      "type": "B",
      "name": account.userName,
      "cid": account.personsSign.toUpperCase(),
      "mobile": account.mobile,
      "email": account.mobile + "@yxinsur.com",
      "underwrite": "B",
      "period": "7",
      "channel": "gsb",
      "job": "OE"
    }
    console.log(JSON.stringify(params));
    var rs = await this.restClient.execPost(params, url);
    console.log(rs);

    contract.insurecb = rs.stdout;
    await contract.save();
  }

  async syncSign(contractId) {
    var contract = await this.dao.findById(contractId);
    if (!contract) {
      return null;
    }
    var account = await this.usereaccountDao.findById(contract.usereaccount_id);
    if (!account) {
      return null;
    }
    var user = await this.userDao.findById(account.user_id);

    var busi = await this.ecompanybusiDao.findOne({
      etemplate_id: contract.etemplate_id
    });
    if (!account.isPush && busi && busi.postsignurl) {
      var param = {
        "appId": busi.appId,
        "idNo": account.personsSign,
        "idName": account.userName,
        "bankNo": account.bankno,
        "mobile": account.mobile,
        "appId3rd": user.appId3rd || "",
        "userCode3rd": user.userCode3rd || "",
        "userId3rd": user.userId3rd || "",
        "branchCode3rd": user.branchCode3rd || "",
        "nonceStr": await this.getUidStr(16),
        "beginDate": await this.formateTime(contract.begin_at),
        "endDate": await this.formateTime(contract.end_at),
      }
      if (!user.userCode3rd && !user.userId3rd) {
        param.openId = user.openId;
      }
      if (contract.ecompany_id == 10173 || contract.ecompany_id == 10174 || contract.ecompany_id == 10175 || contract.ecompany_id == 10207) {
        param.pbType = "eSign";
      }

      var signArr = [];
      signArr.push("appId=" + param.appId);
      signArr.push("appId3rd=" + param.appId3rd);
      signArr.push("bankNo=" + param.bankNo);
      signArr.push("beginDate=" + param.beginDate);
      signArr.push("branchCode3rd=" + param.branchCode3rd);
      signArr.push("endDate=" + param.endDate);
      signArr.push("idName=" + param.idName);
      signArr.push("idNo=" + param.idNo);
      signArr.push("mobile=" + param.mobile);
      signArr.push("nonceStr=" + param.nonceStr);
      if (!user.userCode3rd && !user.userId3rd) {
        signArr.push("openId=" + param.openId);
      }
      if (contract.ecompany_id == 10173 || contract.ecompany_id == 10174 || contract.ecompany_id == 10175 || contract.ecompany_id == 10207) {
        signArr.push("pbType=eSign");
      }
      signArr.push("userCode3rd=" + param.userCode3rd);
      signArr.push("userId3rd=" + param.userId3rd);
      signArr.push("key=" + busi.key);

      param.sign = md5(signArr.join("&")).toUpperCase();
      console.log(JSON.stringify(param));

      try {
        var rs = await this.restClient.execPost(param, busi.postsignurl);
        if (rs.stdout) {
          let rsData = JSON.parse(rs.stdout);
          if (rsData.code == "0" || rsData.code == "0000") {
            account.isPush = true;
            account.save();
          }
        }
        return rs.stdout;
      } catch (error) {
        console.log(error);
        return "error";
      }
    }
  }

  async pushArr(company, clist, keyHex, ivHex) {
    //data加密
    var cipherDataStr = JSON.stringify(clist);
    var _d = cryptoJS.TripleDES.encrypt(cipherDataStr, keyHex, {
      iv: ivHex
    }).toString();
    var cipherData = encodeURIComponent(_d);
    let postData = "md5=" + md5(_d) + "&data=" + cipherData
    try {
      // let rs = await this.restClient.execPost({md5:md5(cipherData), data : cipherData}, company.posturl);
      let rs = await this.restClient.execPostForm(postData, company.posturl);
      if (rs.stdout) {
        let rsData = JSON.parse(rs.stdout);
        if (Number(rsData.code || 0) == 0) {
          // 更新push状态
          for (let item of clist) {
            await this.dao.updateByWhere({
              isPush: true
            }, {
              where: {
                id: item.dataId
              }
            });
          }
        }
      } else {
        logCtl.error({
          optitle: "curl pos 推送（" + company.name + ", [" + JSON.stringify(errIds) + "]）合同签署人信息, 无返回信息异常error",
          op: "/app/base/service/impl/econtractSve.js",
          content: e.stack,
          clientIp: ""
        });
      }
    } catch (e) {
      console.error(e);
      let errIds = [];
      for (let c of clist) {
        errIds.push(c.dataId);
      }
      logCtl.error({
        optitle: "curl pos 推送（" + company.name + ", [" + JSON.stringify(errIds) + "]）合同签署人信息, 操作异常异常error",
        op: "/app/base/service/impl/econtractSve.js",
        content: e.stack,
        clientIp: ""
      });
    }
  }
  async pushContract() {
    var comsql = "SELECT id, `name`,`encryptkey`, `posturl` FROM `c_ecompany` WHERE posturl <> '' AND posturl IS NOT NULL AND encryptkey IS NOT NULL AND isEnabled = 1";
    var companyList = await this.customQuery(comsql);
    var rs = [];
    for (let company of companyList) {
      let deskey = company.encryptkey || ""
      let posturl = company.posturl;
      if (deskey.length <= 8 || !posturl) {
        continue;
      }
      // company.posturl = "http://192.168.18.102:8080/gongsibao-web/web/common/reviceData";
      var sql = "SELECT " +
        "t1.id, t1.etemplate_id, t1.`name`, t1.`eflowstatus`, t1.`eflowstatusname`, t2.`mobile`, t2.`userName`, t2.`personsSign`, t1.`created_at`, t1.`completed_at`, t1.`end_at` " +
        "FROM c_econtract t1 " +
        "INNER JOIN p_user_eaccount t2 ON t1.`usereaccount_id` = t2.`id` WHERE t1.isPush = 0 AND t1.`eflowstatus` = '2' AND t1.ecompany_id = " + company.id;

      var list = await this.dao.customQuery(sql);
      if (!list || list.length == 0) {
        continue;
      }

      let keyHex = cryptoJS.enc.Utf8.parse(deskey);
      let ivHex = cryptoJS.enc.Utf8.parse(deskey.substring(0, 8));

      var clist = [];
      for (let item of list) {
        let completeTime = item.completed_at || "";
        if (completeTime) {
          completeTime = completeTime.Format("yyyy-MM-dd hh:mm:ss")
        }
        let invalidTime = item.end_at || "";
        if (invalidTime) {
          invalidTime = invalidTime.Format("yyyy-MM-dd hh:mm:ss")
        }
        clist.push({
          "dataId": item.id,
          "agreementId": item.etemplate_id,
          "contractName": item.name,
          "companyName": company.name,
          "statusName": item.eflowstatusname,
          "mobile": item.mobile,
          "userName": item.userName,
          "idCard": item.personsSign.toUpperCase(),
          "beginTime": item.created_at.Format("yyyy-MM-dd hh:mm:ss"),
          "completeTime": completeTime,
          "invalidTime": invalidTime
        });
        if (clist.length >= 2) {
          await this.pushArr(company, clist, keyHex, ivHex);
          clist = [];
        }
      }

      if (clist.length > 0) {
        await this.pushArr(company, clist, keyHex, ivHex);
      }
    }
    return rs;
  }

  async downloadCompleteUrl(limit) {
    var sql = "SELECT id FROM `c_econtract` WHERE eflowstatus = '2' AND (fileurl IS NULL OR fileurl = '')  ORDER BY id DESC ";
    if (limit) {
      sql = sql + " LIMIT " + limit;
    }
    var list = await this.dao.customQuery(sql);

    if (!list || list.length == 0) {
      return;
    }

    for (var o of list) {
      var id = o.id;
      try {
        var contract = await this.dao.findById(id);
        if (!contract) {
          continue;
        }

        if (contract.eflowstatus != "2") {
          continue;
        }

        if (!contract.fileurl) {
          //  请求文件地址
          let fileRs = await this.utilesignbaoSve.downloadUserContractFile(contract.eflowid, "econtractSve");
          if (fileRs.code == 1 && fileRs.data.selfossUrl) {
            contract.fileurl = fileRs.data.selfossUrl;
            contract.save();
          }
        }
      } catch (e) {
        console.error(e);
        //日志记录
        logCtl.error({
          optitle: "定时下载合同任务异常, id=" + id,
          op: "app/base/service/impl/econtractSve.js",
          content: e.stack,
          clientIp: ""
        });
        return {
          code: -200,
          message: "error",
          data: {}
        };
      }
    }
  }

  async fiterSignedCards(ecompanyId, cardList) {
    var sql = "SELECT t2.`personsSign` FROM c_econtract t1 " +
      "INNER JOIN p_user_eaccount t2 ON t1.`usereaccount_id` = t2.`id` " +
      "WHERE t2.`personsSign` IN (:cardList) AND t1.`ecompany_id` = :ecompanyId AND t1.`eflowstatus` = '2' AND t1.`end_at`>= NOW() " +
      "GROUP BY t2.`personsSign` ";

    var list = await this.dao.customQuery(sql, {
      ecompanyId: ecompanyId,
      cardList: cardList
    });
    var rs = [];
    if (list) {
      for (var item of list) {
        rs.push(item.personsSign);
      }
    }
    return rs;
  }

  async findSignedUsers(ecompanyId, minId, pageSize) {
    var sql = "SELECT t1.id, t2.userName, t2.mobile ,t2.`personsSign` AS idCard, t1.completed_at AS signTime, t1.end_at AS endTime FROM c_econtract t1 " +
      "INNER JOIN p_user_eaccount t2 ON t1.`usereaccount_id` = t2.`id` " +
      "WHERE t1.id > :minId AND t1.`ecompany_id` = :ecompanyId AND t1.`eflowstatus` = '2' AND t1.`end_at`>= NOW() " +
      "ORDER BY t1.id ASC LIMIT :pageSize ";

    var list = await this.dao.customQuery(sql, {
      ecompanyId: ecompanyId,
      minId: minId,
      pageSize: pageSize
    });
    for (var item of list) {
      item.endTime = await this.formateTime(item.endTime);
      item.signTime = await this.formateTime(item.signTime);
    }
    return list;
  }

  async findSignedUses4Push(params) {
    // var params = {
    //   ecompanyId: busi.ecompany_id,
    //   startId: startId,
    //   idNo: idNo,
    //   pageSize: pageSize,
    //   userId3rd: userId,
    //   userCode3rd: userCode,
    //   branchCode3rd: branchCode,
    // };


    var sql = [];
    sql.push("SELECT t1.id,t1.begin_at as beginDate,t1.end_at as endDate,");
    sql.push("t2.userName AS idName, t2.mobile ,t2.`personsSign` AS idNo, t1.completed_at AS signTime, t2.bankno AS bankNo,");
    sql.push("t3.userId3rd, t3.userCode3rd, t3.branchCode3rd");
    sql.push("FROM c_econtract t1");
    sql.push("INNER JOIN p_user_eaccount t2 ON t1.`usereaccount_id` = t2.`id`");
    sql.push("INNER JOIN p_user t3 ON t2.`user_id` = t3.`id`");
    sql.push("WHERE t1.id > :startId AND t1.`ecompany_id` = :ecompanyId AND t1.`eflowstatus` = '2' AND t1.`end_at`>= NOW()");
    if (params.idNo) {
      sql.push("AND t2.`personsSign` = :idNo");
    }
    if (params.userId3rd) {
      sql.push("AND t3.`userId3rd` = :userId3rd");
    }
    if (params.userCode3rd) {
      sql.push("AND t3.`userCode3rd` = :userCode3rd");
    }
    if (params.branchCode3rd) {
      sql.push("AND t3.`branchCode3rd` = :branchCode3rd");
    }

    sql.push("ORDER BY t1.id ASC LIMIT :pageSize ");
    var list = await this.dao.customQuery(sql.join(" "), params);
    for (var item of list) {
      item.signTime = await this.formateTime(item.signTime);
      item.beginDate = await this.formateTime(item.beginDate);
      item.endDate = await this.formateTime(item.endDate);
    }
    return list;
  }

  async setUser(list) {
    if (!list || list.length == 0) {
      return;
    }

    var ownerIds = [];
    for (var row of list) {
      if (row.owner_id) {
        ownerIds.push(row.owner_id);
      }
    }

    if (ownerIds.length == 0) {
      return;
    }

    var ownerMap = await this.userDao.findMapByIds(ownerIds);
    for (var row of rows) {
      if (row.owner_id) {
        row.owner = ownerMap["id_" + row.owner_id] || {};
      }
    }

    console.log(rows);
  }


  async syncAllSigners() {
    var sql = "SELECT t1.id FROM `c_econtract` t1 " +
      " INNER JOIN p_user_eaccount t2 ON t1.`usereaccount_id` = t2.`id` " +
      " WHERE t1.`eflowstatus` = '2' AND t1.syncCode <> '0' AND t1.syncCode <> '10010000' " +
      " GROUP BY t2.`personsSign` ORDER BY t1.`id` ASC ";
    var ids = await this.dao.customQuery(sql);

    for (var c of ids) {
      try {
        await this.syncContract(c.id);
      } catch (error) {
        console.error(error);
      }
    }
  }

  async updateApply(id) {
    var sql = "UPDATE `c_ejob_apply` SET sign_at = NOW() , `status` = '2' , statusName = '已签约' WHERE econtract_id = " + id;
    await this.dao.customExecAddOrPutSql(sql);
    var apply = await this.ejobapplyDao.findOne({
      econtract_id: id
    });
    if (!apply) {
      return;
    }
    var ecompany = await this.ecompanyDao.findById(apply.ecompany_id);

    var now = moment().format("YYYY年MM月DD日");
    // 发送消息
    var msg = "您于" + now + "与" + ecompany.name + "签约成功, 详情可登录薪必果小程序进行查看。";
    this.emessageDao.create({
      user_id: apply.user_id,
      title: '系统消息',
      type: '0',
      content: msg
    });
    this.ejobapplySve.addMessage(id, "零工签约", "成功签约");
  }

  async syncContract(id) {
    var contract = null;
    var account = null;
    var company = null;
    var signArr = null;
    try {
      contract = await this.dao.findById(id);
      if (!contract) {
        return null;
      }
      account = await this.usereaccountDao.findById(contract.usereaccount_id);
      if (!account) {
        return null;
      }
      company = await this.ecompanyDao.findById(contract.ecompany_id);
      var mainId = await this.maindict.getMainId(company.nameA) || "57731585";

      if (contract.syncCode == '0' || contract.syncCode == '10010000') {
        return null;
      }
      // 39.96.42.199 端口：80  appId:1086941347  mchtId:108694134791293777   mainId:57731585  secret:def87140063233abc
      var item = {
        "accNo": account.bankno || "",
        "appId": "1086941347",
        "beginTime": await this.formateTime2(contract.begin_at),
        "completeTime": await this.formateTime2(contract.completed_at),
        "idName": account.userName,
        "idNo": account.personsSign,
        "idType": "00",
        "invalidTime": await this.formateTime2(contract.end_at),
        "mainId": "57731585",
        "mchtId": "108694134791293777",
        "mobile": account.mobile,
        "nonceStr": await this.getUidStr(16),
        "signType": "MD5",
        "signedName": company.name
      }

      signArr = [];
      signArr.push("appId=" + (item.appId || ""));
      signArr.push("beginTime=" + (item.beginTime || ""));
      signArr.push("completeTime=" + (item.completeTime || ""));
      signArr.push("idName=" + (item.idName || ""));
      signArr.push("idNo=" + (item.idNo || ""));
      signArr.push("idType=" + (item.idType || ""));
      signArr.push("invalidTime=" + (item.invalidTime || ""));
      signArr.push("mainId=" + (item.mainId || ""));
      signArr.push("mchtId=" + (item.mchtId || ""));
      signArr.push("mobile=" + (item.mobile || ""));
      signArr.push("nonceStr=" + (item.nonceStr || ""));
      signArr.push("signType=" + (item.signType || ""));
      signArr.push("signedName=" + (item.signedName || ""));
      signArr.push("key=def87140063233abc");

      item.sign = md5(signArr.join("&")).toUpperCase();
      try {
        let rs = await this.restClient.execPost(item, "https://payadmin.gongsibao.com/merchant/userSigned/asyncNotify");

        if (rs && rs.stdout) {
          contract.syncCode = JSON.parse(rs.stdout).code;
        } else {
          contract.syncCode = '-10501';
        }
        await contract.save();
      } catch (error) {
        contract.syncCode = '-10500';
        await contract.save();
      }
    } catch (error) {
      console.error(error);
      if (contract) {
        contract.syncCode = '-500';
        await contract.save();
      }
    }
  }

  async getContractUrl(id) {
    var contract = await this.findById(id);
    if (contract.fileurl) {
      return contract.fileurl;
    }

    let fileRs = await this.utilesignbaoSve.downloadUserContractFile(contract.eflowid, "econtractSve");
    if (fileRs.code == 1 && fileRs.data.selfossUrl) {
      contract.fileurl = fileRs.data.selfossUrl;
      await contract.save();
      return contract.fileurl;
    }
    return "";
  }

  async testtransfer(result) {
    var date = new Date().Format("yyyy-MM-dd hh:mm:ss");
    var v = JSON.stringify(result) + "---" + date;
    var sql = "INSERT INTO `testtransfer` (`v`) VALUES ('" + v + "')  ";
    await this.dao.customExecAddOrPutSql(sql, {});
  }

  async addPayNotify(result) {
    var sql = [];
    sql.push("INSERT INTO c_pay_notify");
    sql.push("(fromid,username,flag,amount,created_at,orderItemId,income_tax, notifyTime)VALUE(");
    sql.push("'" + result.fromid + "',");
    sql.push("'" + result.username + "',");
    sql.push("'" + result.flag + "',");
    sql.push("'" + result.amount + "',");
    sql.push("NOW(),");
    sql.push("'" + result.orderItemId + "',");
    sql.push("'" + (result.income_tax || 0) + "', ");
    sql.push("'" + result.notifyTime + "')");
    await this.dao.customExecAddOrPutSql(sql.join(""), {});
  }

  async getPayNotify(result) {
    var payNotify = {};
    var sql = "SELECT username,amount,income_tax,notifyTime from c_pay_notify where orderItemId =:orderItemId limit 1";
    var list = await this.dao.customQuery(sql, {
      orderItemId: result
    });

    if (list && list.length > 0) {
      payNotify = list[0] || [];
      payNotify.amount = system.f2y(payNotify.amount);
      payNotify.income_tax = system.f2y(payNotify.income_tax);
      // payNotify.created_at =  await this.formateTime3(payNotify.created_at);
      payNotify.notifyTime = moment(payNotify.notifyTime).add(-8, "hours").format("YYYY年MM月DD日 HH:mm");
    }

    return payNotify;
  }

  async formateTime(inputTime) {
    var date = new Date(inputTime);
    var y = date.getFullYear();
    var m = date.getMonth() + 1;
    m = m < 10 ? ('0' + m) : m;
    var d = date.getDate();
    d = d < 10 ? ('0' + d) : d;
    var h = date.getHours();
    h = h < 10 ? ('0' + h) : h;
    var minute = date.getMinutes();
    var second = date.getSeconds();
    minute = minute < 10 ? ('0' + minute) : minute;
    second = second < 10 ? ('0' + second) : second;
    return y + '-' + m + '-' + d + ' ' + h + ':' + minute + ':' + second;
  }

  async formateTime2(inputTime) {
    if (!inputTime) {
      return '';
    }
    var date = new Date(inputTime);
    var y = date.getFullYear();
    var m = date.getMonth() + 1;
    m = m < 10 ? ('0' + m) : m;
    var d = date.getDate();
    d = d < 10 ? ('0' + d) : d;
    var h = date.getHours();
    h = h < 10 ? ('0' + h) : h;
    var minute = date.getMinutes();
    var second = date.getSeconds();
    minute = minute < 10 ? ('0' + minute) : minute;
    second = second < 10 ? ('0' + second) : second;
    return y + '' + m + '' + d + '' + h + '' + minute + '' + second;
  }

  async formateTime3(inputTime) {
    if (!inputTime) {
      return '';
    }
    var date = new Date(inputTime);
    var y = date.getFullYear();
    var m = date.getMonth() + 1;
    m = m < 10 ? ('0' + m) : m;
    var d = date.getDate();
    d = d < 10 ? ('0' + d) : d;
    var h = date.getHours() - 8;
    h = h < 10 ? ('0' + h) : h;
    var minute = date.getMinutes();
    minute = minute < 10 ? ('0' + minute) : minute;
    return y + '年' + m + '月' + d + '日 ' + h + ':' + minute;
  }

  async getUidStr(len, radix) {
    var chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
    var uuid = [],
      i;
    radix = radix || chars.length;
    if (len) {
      for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
    } else {
      var r;
      uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
      uuid[14] = '4';
      for (i = 0; i < 36; i++) {
        if (!uuid[i]) {
          r = 0 | Math.random() * 16;
          uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
        }
      }
    }
    return uuid.join('');
  }

  // 银行三要素查询
  async findSinedByThree(userName, personsSign, bankno) {
    if (!userName || !personsSign || !bankno) {
      return [];
    }
    var sql = [];
    sql.push('SELECT t1.* FROM c_econtract t1 ');
    sql.push('INNER JOIN p_user_eaccount t2 ON t1.usereaccount_id = t2.id');
    sql.push('WHERE t2.personsSign = :personsSign AND t2.userName = :userName AND t2.bankno = :bankno');
    sql.push('GROUP BY t1.id ORDER BY t1.id DESC');

    var list = await this.dao.customQuery(sql.join(" "), {
      userName: userName,
      personsSign: personsSign,
      bankno: bankno
    });
    return list || [];
  }
  // 根据身份证Id,获取openId  status-2 签约成功
  async findOpenIdByNo(status, idNo) {
    if (!idNo) {
      return [];
    }
    var sql = [];
    sql.push('SELECT t2.`openId`, t1.`userName`, t1.`mobile` FROM p_user_eaccount t1');
    sql.push('INNER JOIN p_user t2 ON t1.`user_id` = t2.`id`');
    sql.push('INNER JOIN c_econtract t3 ON t1.`id` = t3.`usereaccount_id`');
    sql.push('WHERE t3.eflowstatus = :status AND t1.personsSign = :idNo');

    var list = await this.dao.customQuery(sql.join(" "), {
      status: status,
      idNo: idNo
    });
    return list || [];
  }

  async ydsignnumber() {
    var sql = "SELECT COUNT(1), etemplate_id FROM c_econtract WHERE eflowstatus = '2' AND etemplate_id IN (10066, 10074) GROUP BY etemplate_id";
    return await this.dao.customQuery(sql);
  }
}
module.exports = EcontractService;