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

class EntcontractService extends ServiceBase {
    constructor() {
        super(ServiceBase.getDaoName(EntcontractService));
        this.enttemplateSve = system.getObject("service.enttemplateSve");
        this.entcompanyDao = system.getObject("db.entcompanyDao");
        this.usereaccountDao = system.getObject("db.usereaccountDao");
        this.ecompanybusiDao = system.getObject("db.ecompanybusiDao");
        this.utilesignbaoSve = system.getObject("service.utilesignbaoSve");
        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.yzmerchantsignedDao = system.getObject("db.yzmerchantsignedDao");

        this.etemplateDao = system.getObject("db.etemplateDao");
        this.ecompanyDao = system.getObject("db.ecompanyDao");
        this.econtractDao = system.getObject("db.econtractDao");

        this.etemplatebusiDao = system.getObject("db.etemplatebusiDao");

        this.bankthreelogDao = system.getObject("db.bankthreelogDao");


        this.URL = "http://39.106.185.66:8000/merchant/busi/reg";
        this.YZKEY = "4a112ce87c38464d8d454caf23b7b31f";

        this.YZHDURL = "http://bifrost-youzan-gateway.qa.s.qima-inc.com/api/auth_exempt/youzan.pay.finance.tax.sign.merchant.gsb.notify/1.0.0";

        this.redisClient = system.getObject("util.redisClient");
    }

    async getAppConfig() {
        return {
            appId: "1201869719607517185",
            key: "bee7870e008ab144bf518b70ef91f8ac",
        }
    }

    async autoSign(params) {
        var ecid = params.ecid;
        var unionId = params.appId + "_" + params.userId;
        // enttemplate 模板查询
        var enttemplate = await this.enttemplateSve.findById(ecid);
        // entcompany
        var entcompany = await this.entcompanyDao.findById(enttemplate.entcompany_id);
        // p_user
        var user = await this.userDao.findOne({
            unionId: unionId,
        });

        if (!user) {
            user = await this.userDao.create({
                appkey: params.appId,
                unionId: unionId,
                userId3rd: params.userId,
                userName: params.idName,
                mobile: params.mobile,
                utype: 0,
            });
        }

        // p_user_eaccount
        var eaccount = await this.usereaccountDao.findOne({
            user_id: user.id,
            personsSign: params.idNo,
        }) || {};

        var isNeedCreate = !eaccount.eaccountid || eaccount.userName != params.idName || eaccount.mobile != params.mobile || eaccount.bankno != params.bankno;

        eaccount.user_id = user.id;
        eaccount.userName = params.idName;
        eaccount.mobile = params.mobile;
        eaccount.bankno = params.bankno;
        eaccount.personsSign = params.idNo;
        if (eaccount.id) {
            await eaccount.save();
        } else {
            eaccount = await this.usereaccountDao.create(eaccount);
        }

        // c_entcontract
        var entcontract = await this.dao.findOne({
            eflowstatus: '2',
            usereaccount_id: eaccount.id,
            enttemplate_id: ecid,
        });

        if (entcontract) {
            return this.returnjson(0, "用户已经签约，请不要重复签约");
        }

        let banklog = await this.bankthreelogDao.findOne({
            userName: eaccount.userName,
            userIdNo: eaccount.personsSign,
            userBankNo: eaccount.bankno,
            result: 1,
        });
        if (!banklog) {
            var bankthreeParams = {
                name: eaccount.userName,
                idno: eaccount.personsSign,
                cardno: eaccount.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) {
                return this.returnjson(-1, "银行三要素（姓名、身份证、银行卡号）验证失败");
            }
            if (threeResult.code == -110) {
                return this.returnjson(-1, "银行三要素验证失败");
            }
        }

        // e签宝流程
        if (isNeedCreate) {
            var uidStr = await this.getUidStr(8, 36);
            var thirdId = enttemplate.id + "_" + eaccount.id + uidStr;

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

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

        // 创建合同
        entcontract = {
            name: entcompany.name,
            eflowstatusname: "签约中",
            eflowstatus: "1",
            user_id: eaccount.user_id,
            usereaccount_id: eaccount.id,
            enttemplate_id: enttemplate.id,
            entcompany_id: entcompany.id,
        };
        entcontract = await this.create(entcontract);
        var sealId = entcompany.sealId;
        let today = new Date().Format("yyyy") + "年" + new Date().Format("MM") + "月" + new Date().Format("dd") + "日";
        var signParams = {
            templateId: enttemplate.templateid, //模板id，由创建模板接口调用返回的templateId 必填
            name: enttemplate.name, //合同模板名称 必填
            simpleFormFields: {
                nameA: params.name, //甲方 必填
                addressA: params.addr, //甲方地址
                representA: params.legal,//甲方法定代表人
                agentA: params.contactName,//甲方联系人
                agentMobileA: params.contactMobile,//甲方 联系电话

                nameB: eaccount.userName, //乙方 必填
                addressB: entcompany.addr, //乙方 地址
                representB: entcompany.legal,//乙方 法定代表人
                agentB: entcompany.contactName,//乙方 联系人
                agentMobileB: eaccount.mobile,//乙方 联系电话

                bankNameB: entcompany.bankAccount,//账户名称
                bank: entcompany.bankName,//开户行
                bankNumB: entcompany.bankNo,//账号

                signDate: today,//签约时间
                signDateA: today, //甲方签约日期 必填
                signDateB: today //乙方签约日期 必填
            }
        };
        var ebaoAccountId = eaccount.eaccountid; //签署人账户id-- 必填
        var thirdOrderNo = "ent_" + entcontract.id; //第三方流水号，通知回调使用---选填
        var eBaoRedirectBossUrl = "";
        var tt = await this.utilesignbaoSve.userAutoSignContractNoTemplate(signParams, ebaoAccountId, thirdOrderNo, eBaoRedirectBossUrl, "econtractSve", sealId);
        if (tt && tt.data && tt.code == 1) {
            entcontract.eflowid = tt.data.flowId;
            entcontract.edocid = tt.data.docId;
            entcontract.eflowstatus = '2';
            entcontract.eflowstatusname = "已完成";

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

            await entcontract.save();
            // 合同下载任务
            this.redisClient.rpushBCD({id: entcontract.id, sve: "ent"});

            // this.syncSign(entcontract.id);
            // return await this.createMerchant(params);  暂时先不用了
            // return this.returnjson(0, "success", {
            //     contractId: entcontract.id
            // });
        }
        return this.returnjson(-1, tt.message || "签约失败", tt.code);
    }


    async createYzMerchant(params) {
        var data = {
            // appId: "1202849621743763458",
            // mchtId: "1202848945651318786",
            appId: params.toAppId,
            mchtId: params.toMcthid,
            ageFlag: 0,
            type: "0",// 类型 0 一般纳税人 1 小规模纳税人
            companyName: params.merchantName,//商户名称
            mobile: params.mobile,//手机号
            mainId: "67731101",
            signedName: params.merchantName, //合同名称 使用商户名称
            beginTime: moment().format("YYYY-MM-DD"), //当前时间, //  签约开始时间
            invalidTime: moment().add(2, 'y').format("YYYY-MM-DD"), // 签约失效时间
            completeTime: moment().format("YYYY-MM-DD"), //  签约完成时间 取当前时间
            incomeCompany: "0", // 个税来源 0 个税向个人收 1 个税向企业收
            addedCollectType: "0", //  服务费PLUS收取类型, 0 个人收 1 企业收
            addedValueRate: "0.0", //    服务费PLUS费率(%)
            serviceCollectType: "0", //  服务费收取类型, 0 个人收 1 企业收
            serviceRate: "10.0",    //服务费率(%)
            operatingCost: '0.0', //  核定成本费用率(%)
            taxChargeMode: "0", //  个税计费模式 0 按月，1 按年
            signType: 'MD5',
            nonceStr: await this.getUidStr(16, 36)
        };
        console.log("有赞商户创建data：", data);

        var signArr = [];
        var keys = Object.keys(data).sort();
        for (var i = 0; i < keys.length; i++) {
            var k = keys[i];
            var v = data[k];
            signArr.push(k + "=" + v);
        }
        var signStr = signArr.join("&") + "&key=" + params.key;
        console.log("有赞商户创建signStr：", signStr);
        data.sign = md5(signStr).toUpperCase();
        console.log("有赞商户创建sign：", data.sign);

        data.bizContent = [
            {
                "quickDeductionFactor": 0,
                "minValue": 0,
                "rate": 0,
                "maxValue": 3000000
            },
            {
                "quickDeductionFactor": 0,
                "minValue": 3000001,
                "rate": 1.5,
                "maxValue": 10000000
            },
            {
                "quickDeductionFactor": 0,
                "minValue": 10000001,
                "rate": 4.86,
                "maxValue": 214748364700
            }
        ];
        var rtn = null;
        try {
            let url = settings.apiconfig.settleApiConfig().createMerchantApi;
            console.log("有赞商户创建url：", url);
            let rs = await axios({
                method: 'post',
                url: url,
                data: data,
            });

            console.log("段经理接口返回===============", rs);
            console.log("有赞商户创建result：", rs.data);
            var reso = rs.data;
            var erchants = await this.yzmerchantsignedDao.findOne({
                companyName: params.merchantName,
            });
            if (!erchants) {
                erchants = await this.yzmerchantsignedDao.create({
                    companyName: params.merchantName,
                    appId: reso.data.appId,
                    mchtId: reso.data.mchtId,
                    mainId: reso.data.mainId,
                    secret: reso.data.secret,
                    entcontract_id: params.entcontract_id,
                });
            }

            let ecompany = await this.ecompanyDao.findOne({
                "name": params.merchantName,
            })
            if (!ecompany) {
                // 创建ecompany
                ecompany = await this.ecompanyDao.create({
                    "name": params.merchantName,
                    "nameA": '',
                    "isEnabled": true,
                    "isQuiet": true,
                    "sealurl": "",
                    "encryptkey": "",
                    "posturl": ""
                });
            }


            let temp = await this.etemplateDao.findById(10222);
            let template = await this.etemplateDao.findOne({
                ecompany_id: ecompany.id,
            });
            if (!template) {
                template = await this.etemplateDao.create({
                    ecompany_id: ecompany.id,
                    name: ecompany.name,
                    templateid: temp.templateid,
                    ecompanyMainId: temp.ecompanyMainId,
                    nameA: temp.nameA,
                    filekey: temp.filekey,//e签宝返回文件key
                    filepath: temp.filepath,//需要在后台补充
                    placeholderkey: temp.placeholderkey,//模板占位信息
                    isEnabled: true,
                });
            }

            reso.data.ecid = template.id;
            if (!erchants.ecid) {
                erchants.ecid = template.id;
                await erchants.save();
            }

            var etemplatebusi = await this.etemplatebusiDao.findOne({
                template_id: erchants.ecid,
                busi_id: erchants.mchtId,
            });
            if (!etemplatebusi) {
                this.etemplatebusiDao.create({
                    template_type: 1,
                    template_id: erchants.ecid,
                    busi_id: erchants.mchtId,
                    busi_company_name: erchants.companyName,
                });
            }

            let busi = await this.ecompanybusiDao.findOne({
                ecompany_id: ecompany.id,
                etemplate_id: template.id,
            });
            if (!busi) {
                await this.ecompanybusiDao.create({
                    ecompany_id: ecompany.id,
                    etemplate_id: template.id,
                    postwxurl: "",
                    postsignurl: "",
                    appId: reso.data.appId,
                    mchtId: reso.data.mchtId,
                    mainId: reso.data.mainId,
                    key: reso.data.secret,
                });
            } else {
                busi.appId = reso.data.appId;
                busi.mchtId = reso.data.mchtId;
                busi.mainId = reso.data.mainId;
                busi.key = reso.data.secret;
                await busi.save();
            }
            return reso;
        } catch (e) {
            console.log(e.stack);
            let result = {};
            result.code = -1;
            result.message = "操作异常";
            return result;
        }
    }


    async yzMerchantAutoSigns(params, enttemplate) {
        //判断商户是否签约
        var ecid = params.ecid;
        var unionId = params.appId + "_" + params.merchantId + "_" + params.idNo;
        var user = await this.userDao.findOne({unionId: unionId});
        if (!user) {
            user = await this.userDao.create({
                appkey: params.appId,
                unionId: unionId,
                userId3rd: params.merchantId,
                userName: params.idName,
                mobile: params.mobile,
                utype: 0,
            });
        }
        // p_user_eaccount
        var eaccount = await this.usereaccountDao.findOne({user_id: user.id, personsSign: params.idNo,}) || {};

        eaccount.user_id = user.id;
        eaccount.userName = params.idName;
        eaccount.mobile = params.mobile;
        eaccount.bankno = "";
        eaccount.personsSign = params.idNo;
        if (eaccount.id) {
            await eaccount.save();
        } else {
            eaccount = await this.usereaccountDao.create(eaccount);
        }

        var entcontract = await this.dao.findOne({
            eflowstatus: '2',
            usereaccount_id: eaccount.id,
            enttemplate_id: ecid,
        });

        if (entcontract) {
            let merchantSign = await this.yzmerchantsignedDao.findOne({
                entcontract_id: entcontract.id,
            });
            if (!merchantSign) {
                return this.returnjson(-1, "数据错误");
            }
            let res = {
                code: 0,
                msg: "执行成功",
                data: {
                    ecid: merchantSign.ecid,
                    appId: merchantSign.appId,
                    mchtId: merchantSign.mchtId,
                    mainId: merchantSign.mainId,
                    secret: merchantSign.secret,
                },
            }
            return res;
        }

        var reso = await this.createYzMerchant_1(params, enttemplate);

        if (reso.code == -1) {
            return this.returnjson(-1, "签约失败");
        }
        this.toSignUp(params, eaccount, user, entcontract, reso.erchants);
        delete reso.erchants;
        return reso;
    }

    async createYzMerchant_1(params, enttemplate) {

        var data = {
            appId: enttemplate.appid,
            mchtId: enttemplate.mcthid,
            ageFlag: 0,
            type: "0",// 类型 0 一般纳税人 1 小规模纳税人
            companyName: params.merchantName,//商户名称
            mobile: params.mobile,//手机号
            mainId:enttemplate.mainId,//代征主体 67731101  测试 67731504
            signedName: params.merchantName, //合同名称 使用商户名称
            beginTime: moment().format("YYYY-MM-DD"), //当前时间, //  签约开始时间
            invalidTime: moment().add(2, 'y').format("YYYY-MM-DD"), // 签约失效时间
            completeTime: moment().format("YYYY-MM-DD"), //  签约完成时间 取当前时间
            incomeCompany: "0", // 个税来源 0 个税向个人收 1 个税向企业收
            addedCollectType: "0", //  服务费PLUS收取类型, 0 个人收 1 企业收
            addedValueRate: "0.0", //    服务费PLUS费率(%)
            serviceCollectType: "0", //  服务费收取类型, 0 个人收 1 企业收
            serviceRate: "10.0",    //服务费率(%)
            operatingCost: '0.0', //  核定成本费用率(%)
            taxChargeMode: "0", //  个税计费模式 0 按月，1 按年
            signType: 'MD5',
            nonceStr: await this.getUidStr(16, 36)
        };
        console.log("有赞商户创建data：", data);
        var signArr = [];
        var keys = Object.keys(data).sort();
        for (var i = 0; i < keys.length; i++) {
            var k = keys[i];
            var v = data[k];
            signArr.push(k + "=" + v);
        }
        var signStr = signArr.join("&") + "&key=" + enttemplate.key;
        data.sign = md5(signStr).toUpperCase();
        data.bizContent = [
            {
                "quickDeductionFactor": 0,
                "minValue": 0,
                "rate": 0,
                "maxValue": 3000000
            },
            {
                "quickDeductionFactor": 0,
                "minValue": 3000001,
                "rate": 1.5,
                "maxValue": 10000000
            },
            {
                "quickDeductionFactor": 0,
                "minValue": 10000001,
                "rate": 4.86,
                "maxValue": 214748364700
            }
        ];
        try {

            var erchants = await this.yzmerchantsignedDao.findOne({
                companyName: params.merchantName,
            });

            if (erchants) {
                return {
                    code: 0,
                    msg: "执行成功",
                    data: {
                        ecid: erchants.ecid,
                        appId: erchants.appId,
                        mchtId: erchants.mchtId,
                        mainId: erchants.mainId,
                        secret: erchants.secret,
                    },
                    erchants: erchants
                }
            }
            let url =enttemplate.merchantApi;
            console.log("有赞商户创建url：", url);
            let rs = await axios({
                method: 'post',
                url: url,
                data: data,
            });
            var reso = rs.data;
            if (reso.code == -1) {
                console.log("有赞创建商户错误===========", reso)
                return reso;
            }

            erchants = {
                companyName: params.merchantName,
                appId: reso.data.appId,
                mchtId: reso.data.mchtId,
                mainId: reso.data.mainId,
                secret: reso.data.secret,
                params: JSON.stringify(params),
                ecid: 10287
            };
            try {


                erchants = await this.yzmerchantsignedDao.create(erchants);
            } catch (e) {
                console.log("c_yzmerchant_signed插入失败", erchants);
                console.log(e.stack);
            }

            var etemplatebusi = await this.etemplatebusiDao.findOne({
                template_id: erchants.ecid,
                busi_id: erchants.mchtId,
            });
            if (!etemplatebusi) {
                this.etemplatebusiDao.create({
                    template_type: 1,
                    template_id: 10287,
                    busi_id: erchants.mchtId,
                    busi_company_name: erchants.companyName,
                });
            }
            reso.erchants = erchants;
            reso.data.ecid = 10287;

            //----------------

            // let ecompany = await this.ecompanyDao.findOne({
            //     "name": params.merchantName,
            // })
            // if (!ecompany) {
            //     // 创建ecompany
            //     ecompany = await this.ecompanyDao.create({
            //         "name": params.merchantName,
            //         "nameA": '',
            //         "isEnabled": true,
            //         "isQuiet": true,
            //         "sealurl": "",
            //         "encryptkey": "",
            //         "posturl": ""
            //     });
            // }
            //
            // let busi = await this.ecompanybusiDao.findOne({
            //     ecompany_id: ecompany.id,
            //     etemplate_id: 10287,
            // });
            // if (!busi) {
            //     await this.ecompanybusiDao.create({
            //         ecompany_id: ecompany.id,
            //         etemplate_id: 10287,
            //         postwxurl: "",
            //         postsignurl: "",
            //         appId: reso.data.appId,
            //         mchtId: reso.data.mchtId,
            //         mainId: reso.data.mainId,
            //         key: reso.data.secret,
            //     });
            // } else {
            //     busi.appId = reso.data.appId;
            //     busi.mchtId = reso.data.mchtId;
            //     busi.mainId = reso.data.mainId;
            //     busi.key = reso.data.secret;
            //     await busi.save();
            // }
            //----------------

            return reso;
        } catch (e) {
            console.log(e.stack);
            return {code: -1, message: "操作异常"};
        }

    }

    async toSignUp(params, eaccount, user, entcontract, erchants) {
        var ecid = params.ecid;
        var unionId = params.appId + "_" + params.merchantId + "_" + params.idNo;
        // enttemplate 模板查询
        var enttemplate = await this.enttemplateSve.findById(ecid);
        // entcompany
        var entcompany = await this.entcompanyDao.findById(enttemplate.entcompany_id);

        var isNeedCreate = !eaccount.eaccountid || eaccount.userName != params.idName || eaccount.mobile != params.mobile;

        eaccount.user_id = user.id;
        eaccount.userName = params.idName;
        eaccount.mobile = params.mobile;
        eaccount.bankno = "";
        eaccount.personsSign = params.idNo;
        if (eaccount.id) {
            await eaccount.save();
        } else {
            eaccount = await this.usereaccountDao.create(eaccount);
        }

        // e签宝流程
        if (isNeedCreate) {
            var uidStr = await this.getUidStr(8, 36);
            var thirdId = enttemplate.id + "_" + eaccount.id + uidStr;
            //2.创建e签宝account 5.2.1 , 创建后save()
            let createParams = {
                thirdId: thirdId,
                name: eaccount.userName,
                idNo: eaccount.personsSign,
                idType: params.idType,
                mobile: eaccount.mobile
            };
            var getAccount = await this.utilesignbaoSve.createAccountId(createParams, "econtractSve");
            if (getAccount && getAccount.code == 1 && getAccount.data) {
                eaccount.eaccountid = getAccount.data.accountId;
                await eaccount.save();
            } else {
                return this.returnjson(-1, "账户创建失败");
            }
        }

        // 3.设置静默签署授权 5.2.5
        if (!eaccount.isGrantAuto) {
            var paramsGrant = {
                grantAccountId: eaccount.eaccountid
            };
            var grantAuto = await this.utilesignbaoSve.grantAuthorization(paramsGrant, "econtractSve");
            if (grantAuto.code != 1) {
                return this.returnjson(-1, "静默签署设置失败");
            }
            eaccount.isGrantAuto = true;
            await eaccount.save();
        }
        // 创建合同
        entcontract = {
            name: entcompany.name,
            eflowstatusname: "签约中",
            eflowstatus: "1",
            user_id: eaccount.user_id,
            usereaccount_id: eaccount.id,
            enttemplate_id: enttemplate.id,
            entcompany_id: entcompany.id,
        };
        entcontract = await this.create(entcontract);
        erchants.entcontract_id = entcontract.id;
        erchants.save();
        var sealId = entcompany.sealId;
        let today = new Date().Format("yyyy") + "年" + new Date().Format("MM") + "月" + new Date().Format("dd") + "日";
        var signParams = {
            templateId: enttemplate.templateid, //模板id，由创建模板接口调用返回的templateId 必填
            name: enttemplate.name, //合同模板名称 必填
            simpleFormFields: {
                nameA: params.merchantName, //甲方 必填
                addressA: params.merchantAddr, //甲方地址
                representA: params.merchantLegal,//甲方法定代表人
                agentA: params.idName,//甲方联系人
                agentMobileA: params.mobile,//甲方 联系电话

                nameB: entcompany.name, //乙方 必填
                addressB: entcompany.addr, //乙方 地址
                representB: entcompany.legal,//乙方 法定代表人
                agentB: entcompany.contactName,//乙方 联系人
                agentMobileB: entcompany.contactMobile,//乙方 联系电话

                signDate: today,//签约时间
                signDateA: today, //甲方签约日期 必填
                signDateB: today //乙方签约日期 必填
            }
        };
        var ebaoAccountId = eaccount.eaccountid; //签署人账户id-- 必填
        var thirdOrderNo = entcontract.id; //第三方流水号，通知回调使用---选填
        var eBaoRedirectBossUrl = "";
        var tt = await this.utilesignbaoSve.userAutoSignContractNoTemplaterEversalSeal(signParams, ebaoAccountId, thirdOrderNo, eBaoRedirectBossUrl, "econtractSve", sealId);
        if (tt && tt.data && tt.code == 1) {
            entcontract.eflowid = tt.data.flowId;
            entcontract.edocid = tt.data.docId;
            entcontract.eflowstatus = '2';
            entcontract.eflowstatusname = "已完成";

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

            await entcontract.save();
            params.entcontract_id = entcontract.id;
            params.toAppId = enttemplate.appid;
            params.toMcthid = enttemplate.mcthid;
            params.key = enttemplate.key;
            // 合同下载任务
            this.redisClient.rpushBCD({id: entcontract.id, sve: "ent"});
            console.log("===============有赞商户签约异步签约成功===============", new Date())
        } else {
            console.log(new Date(), "===============有赞商户签约异步签约失败===============", tt)
        }
    }


    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.enttemplate_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 (this.ydCompanyIds.indexOf(contract.entcompany_id) > -1) {
                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) {
            if (this.ydCompanyIds.indexOf(contract.entcompany_id) > -1) {
                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));
            var rs = "";
            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(rs, "push sign url " + busi.postsignurl, "rs = " + rs);
                console.log(error);
                return "error";
            }
        }
    }

    async findSignedUses4Push(params) {
        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 AS merchantId, t1.fileurl AS fileUrl");
        sql.push("FROM c_entcontract 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.`entcompany_id` = :entcompanyId 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 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 yzMerchantAutoSign(params) {
        var ecid = params.ecid;
        var unionId = params.appId + "_" + params.merchantId + "_" + params.idNo;
        // enttemplate 模板查询
        var enttemplate = await this.enttemplateSve.findById(ecid);
        // entcompany
        var entcompany = await this.entcompanyDao.findById(enttemplate.entcompany_id);
        // p_user
        var user = await this.userDao.findOne({
            unionId: unionId,
        });

        if (!user) {
            user = await this.userDao.create({
                appkey: params.appId,
                unionId: unionId,
                userId3rd: params.merchantId,
                userName: params.idName,
                mobile: params.mobile,
                utype: 0,
            });
        }

        // p_user_eaccount
        var eaccount = await this.usereaccountDao.findOne({
            user_id: user.id,
            personsSign: params.idNo,
        }) || {};

        var isNeedCreate = !eaccount.eaccountid || eaccount.userName != params.idName || eaccount.mobile != params.mobile;

        eaccount.user_id = user.id;
        eaccount.userName = params.idName;
        eaccount.mobile = params.mobile;
        eaccount.bankno = "";
        eaccount.personsSign = params.idNo;
        if (eaccount.id) {
            await eaccount.save();
        } else {
            eaccount = await this.usereaccountDao.create(eaccount);
        }

        // c_entcontract
        var entcontract = await this.dao.findOne({
            eflowstatus: '2',
            usereaccount_id: eaccount.id,
            enttemplate_id: ecid,
        });

        if (entcontract) {
            // return this.returnjson(0, "该商户已签约");
            let merchantSign = await this.yzmerchantsignedDao.findOne({
                entcontract_id: entcontract.id,
            });
            if (!merchantSign) {
                return this.returnjson(-1, "数据错误");
            }

            let res = {
                code: 0,
                msg: "执行成功",
                data: {
                    ecid: merchantSign.ecid,
                    appId: merchantSign.appId,
                    mchtId: merchantSign.mchtId,
                    mainId: merchantSign.mainId,
                    secret: merchantSign.secret,
                },
            }
            return res;
        }

        // e签宝流程
        if (isNeedCreate) {
            //  任博说有赞商户不验证银行卡三要素
            // var bankthreeParams = {
            //     name: eaccount.userName,
            //     idno: eaccount.personsSign,
            //     cardno: eaccount.bankno
            // };
            // var threeResult = await this.utilesignbaoSve.bankthree(bankthreeParams, "bankinfoAuth");
            // console.log("threeResult-----------------------------", threeResult);
            // if (!threeResult || threeResult.code == -120) {
            //     return this.returnjson(-1, "银行三要素（姓名、身份证、银行卡号）验证失败");
            // }
            // if (threeResult.code == -110) {
            //     return this.returnjson(-1, "银行三要素验证失败");
            // }

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

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

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

        // 创建合同
        entcontract = {
            name: entcompany.name,
            eflowstatusname: "签约中",
            eflowstatus: "1",
            user_id: eaccount.user_id,
            usereaccount_id: eaccount.id,
            enttemplate_id: enttemplate.id,
            entcompany_id: entcompany.id,
        };
        entcontract = await this.create(entcontract);
        var sealId = entcompany.sealId;
        let today = new Date().Format("yyyy") + "年" + new Date().Format("MM") + "月" + new Date().Format("dd") + "日";
        var signParams = {
            templateId: enttemplate.templateid, //模板id，由创建模板接口调用返回的templateId 必填
            name: enttemplate.name, //合同模板名称 必填
            simpleFormFields: {
                nameA: params.merchantName, //甲方 必填
                addressA: params.merchantAddr, //甲方地址
                representA: params.merchantLegal,//甲方法定代表人
                agentA: params.idName,//甲方联系人
                agentMobileA: params.mobile,//甲方 联系电话

                nameB: entcompany.name, //乙方 必填
                addressB: entcompany.addr, //乙方 地址
                representB: entcompany.legal,//乙方 法定代表人
                agentB: entcompany.contactName,//乙方 联系人
                agentMobileB: entcompany.contactMobile,//乙方 联系电话

                // bankNameB: entcompany.bankAccount,//账户名称
                // bank: entcompany.bankName,//开户行
                // bankNumB: entcompany.bankNo,//账号

                signDate: today,//签约时间
                signDateA: today, //甲方签约日期 必填
                signDateB: today //乙方签约日期 必填
            }
        };
        var ebaoAccountId = eaccount.eaccountid; //签署人账户id-- 必填
        var thirdOrderNo = entcontract.id; //第三方流水号，通知回调使用---选填
        var eBaoRedirectBossUrl = "";
        var tt = await this.utilesignbaoSve.userAutoSignContractNoTemplaterEversalSeal(signParams, ebaoAccountId, thirdOrderNo, eBaoRedirectBossUrl, "econtractSve", sealId);
        if (tt && tt.data && tt.code == 1) {
            entcontract.eflowid = tt.data.flowId;
            entcontract.edocid = tt.data.docId;
            entcontract.eflowstatus = '2';
            entcontract.eflowstatusname = "已完成";

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

            await entcontract.save();
            params.entcontract_id = entcontract.id;
            // this.syncSign(entcontract.id);
            params.toAppId = enttemplate.appid;
            params.toMcthid = enttemplate.mcthid;
            params.key = enttemplate.key;

            // 合同下载任务
            this.redisClient.rpushBCD({id: entcontract.id, sve: "ent"});

            return await this.createYzMerchant(params);
            // return this.returnjson(0, "success", {
            //     contractId: entcontract.id
            // });
        }
        return this.returnjson(-1, tt.message || "签约失败", tt.code);
    }


    returnjson(code, msg, data) {
        return {
            code: code,
            msg: msg,
            data: data || null
        }
    }

    async downloadCompleteUrl(limit) {
        var sql = "SELECT id FROM `c_entcontract` 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) {
                    //await this.syncYzSign(2134);
                    //  请求文件地址
                    let fileRs = await this.utilesignbaoSve.downloadUserContractFile(contract.eflowid, "econtractSve");
                    if (fileRs.code == 1 && fileRs.data.selfossUrl) {
                        contract.fileurl = fileRs.data.selfossUrl;
                        await contract.save();
                        this.syncYzSign(contract.id);
                    } else {
                        await this.utilesignbaoSve.archiveProcess({flowId: contract.eflowid}, "econtractSve");
                        let fileRs = await this.utilesignbaoSve.downloadUserContractFile(contract.eflowid, "econtractSve");
                        if (fileRs.code == 1 && fileRs.data.selfossUrl) {
                            contract.fileurl = fileRs.data.selfossUrl;
                            await contract.save();
                            this.syncYzSign(contract.id);
                        }
                    }
                }
            } 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 downloadContract(id) {
        try {
            let contract = await this.dao.findById(id);
            if (!contract || contract.eflowstatus != "2" || contract.fileurl) {
                return;
            }

            //await this.syncYzSign(2134);
            //  请求文件地址
            let fileRs = await this.utilesignbaoSve.downloadUserContractFile(contract.eflowid, "econtractSve");
            if (fileRs.code == 1 && fileRs.data.selfossUrl) {
                contract.fileurl = fileRs.data.selfossUrl;
                await contract.save();
                this.syncYzSign(contract.id);
            } else {
                await this.utilesignbaoSve.archiveProcess({flowId: contract.eflowid}, "econtractSve");
                let fileRs = await this.utilesignbaoSve.downloadUserContractFile(contract.eflowid, "econtractSve");
                if (fileRs.code == 1 && fileRs.data.selfossUrl) {
                    contract.fileurl = fileRs.data.selfossUrl;
                    await contract.save();
                    this.syncYzSign(contract.id);
                }
            }
        } catch (e) {
            console.error(e);
            return {
                code: -200,
                message: "error",
                data: {}
            };
        }
    }

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

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

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

            contract = await this.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;

            // 合同下载任务
            this.redisClient.rpushBCD({id: contract.id, sve: "ent"});
            await contract.save();
        } catch (e) {
            logCtl.error({
                optitle: "e签宝回调修改合同信息error",
                op: "app/base/service/impl/dkcontractSve/updateCallbackStatus",
                content: "错误信息：" + e.stack,
                clientIp: ""
            });
        }
        return contract;
    }
    async syncYzSign(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);
        // 查商户签约返回值
        let signInfo = await this.yzmerchantsignedDao.findOne({entcontract_id: contractId});
        if (!signInfo) {
            return null;
        }

        // 获取yz配置
        //  let conf = await this.getAppConfig();
        let enttemplate = await this.enttemplateSve.findById(contract.enttemplate_id);

        // 推送数据
        var param = {
            "appId": enttemplate.appid,    // appId
            "merchantName": signInfo.companyName,   // 有赞商户名称
            "merchantId": user.userId3rd,           // 有赞商户id
            "fileUrl": contract.fileurl,            // 签约合同pdf文件
            "idName": account.userName,             // 代理人姓名
            "idNo": account.personsSign,            // 代理人身份证
            "mobile": account.mobile,              //代理人手机号
            "nonceStr": await this.getUidStr(16),   // 随机码
            "beginDate": await this.formateTime(contract.begin_at), // 合同开始时间
            "endDate": await this.formateTime(contract.end_at),     // 合同结束时间
        };

        // 签名
        var signArr = [];
        signArr.push("appId=" + param.appId);
        // ...补全签名信息
        signArr.push("nonceStr=" + param.nonceStr);
        signArr.push("key=" + enttemplate.key);
        param.sign = md5(signArr.join("&")).toUpperCase();
        console.log(JSON.stringify(param));
        var rs = "";
        try {
            rs = await axios({
                method: 'post',
                url: this.YZHDURL,
                data: param,
                headers: {'X-Service-Chain': {"name": "prj0015875"}},
            });

        } catch (error) {
            console.log(rs, "push sign url 有赞回调接口", "rs = " + rs);
            console.log(error);
            return "error";
        }
        // try {
        //     var rs = await this.restClient.execPost(param, "http://bifrost-youzan-gateway.qa.uth_exence.tax.sign.merchant.gsb.notify/1.0.");
        //     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(rs, "push sign url 有赞回调接口", "rs = " + rs);
        //     console.log(error);
        //     return "error";
        // }
    }

    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;
    }

}

module.exports = EntcontractService;
