package weaver.interfaces.htsc.cus;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cloudstore.dev.api.util.MD5;
import com.engine.htsc.payment.enums.UnNumber;
import com.engine.htsc.payment.log.PaymentLogger;
import com.engine.htsc.payment.log.PaymentLoggerFactory;
import com.engine.htsc.payment.service.impl.SettlePaymentFlowServiceImpl;
import com.engine.htsc.payment.util.InterfaceLogUtil;
import com.engine.htsc.payment.util.PayUtil;
import com.engine.htsc.trip.util.WeaverUtil;
import com.google.common.collect.Lists;
import javafx.util.Pair;
import org.apache.axis.Constants;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;
import org.apache.axis.encoding.ser.BeanDeserializerFactory;
import org.apache.axis.encoding.ser.BeanSerializerFactory;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.json.XML;
import org.springframework.beans.BeanUtils;
import sun.misc.BASE64Encoder;
import weaver.conn.RecordSet;
import weaver.conn.RecordSetDataSource;
import weaver.file.ImageFileManager;
import weaver.general.BaseBean;
import weaver.general.Util;
import weaver.hrm.company.DepartmentComInfo;
import weaver.hrm.resource.ResourceComInfo;
import weaver.interfaces.htsc.GlobatTools.JAVATools;
import weaver.interfaces.htsc.comInfo.PropBean;
import weaver.interfaces.htsc.cus.webservices.FileInfoEntity;
import weaver.interfaces.htsc.cus.webservices.ImageServiceSoapStub;
import weaver.interfaces.htsc.cus.webservices.UploadfileEntity;
import weaver.interfaces.htsc.cus.webservices.jtgl.*;
import weaver.interfaces.htsc.cus.webservices.lhzp.InputBudgetData;
import weaver.interfaces.htsc.cus.webservices.lhzp.PageData;
import weaver.interfaces.htsc.cus.webservices.lhzp.ProjectInfoSafety;
import weaver.interfaces.htsc.util.XmlUtils;

import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;
import java.io.*;
import java.net.URL;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Author:DTY-PC Date:2020/10/20 13:48 Description: 华泰证券自定义工具类 Copyright:上海泛微网络科技股份有限公司
 */
public class HTUtil extends BaseBean {

  private Log log = LogFactory.getLog(HTUtil.class);
  private static final PaymentLogger logger = PaymentLoggerFactory.getLogger(HTUtil.class);

  /**
   * 流程结束提交审批数据至携程
   *
   * @param params 参数集合
   * @return 结果
   */
  public boolean SubData2Trip(Map<String, Object> params) {
    try {
      if (params.isEmpty()) {
        return false;
      }

      String token = getAppToken();
      if ("".equals(token)) {
        return false;
      }
      Map<String, String> headers = new HashMap<>();
      headers.put("JTXT-AUTH-TOKEN", token);
      headers.put("JTXT-AUTH-TYPE", "APP");

      String data2tripUrl = Util.null2String(new PropBean().getPropName("data2tripUrl"));
      String reqStr = JSON.toJSONString(params);
      log.info("=======HTUtil>>>方法======SubData2Trip=======");
      log.info("=======提交审批数据至携程=======");
      log.info("=======预审批数据请求：" + reqStr + "=======");
      String res = Util.null2String(httpPostRaw(data2tripUrl, reqStr, headers, null));
      log.info("=======预审批数据响应：" + res + "=======");
      if ("上传预审批单成功".equals(res)) {
        return true;
      } else {
        log.info("HTUtil.SubData2Trip,上传预审批单失败--->" + res);
        return false;
      }
    } catch (Exception e) {
      StackTraceElement stackTraceElement = e.getStackTrace()[0];
      log.info("File=" + stackTraceElement.getFileName());
      log.info("Line=" + stackTraceElement.getLineNumber());
      log.info("Method=" + stackTraceElement.getMethodName());
      log.info("提交数据至携程捕获异常:" + params);
      writeLog("subdata to trip error!", e);
      return false;
    }
  }

  /**
   * 保存行程数据接口
   *
   * @param jsonStr 请求数据字符串
   * @return 结果
   */
  public boolean saveTrip(String jsonStr) {
    try {
      if ("".equals(jsonStr)) {
        return false;
      }
      String token = getAppToken();
      if ("".equals(token)) {
        return false;
      }
      Map<String, String> headers = new HashMap<>();
      headers.put("JTXT-AUTH-TOKEN", token);
      headers.put("JTXT-AUTH-TYPE", "APP");
      log.info("=======HTUtil>>>方法======saveTrip=======");
      String savetripUrl = Util.null2String(new PropBean().getPropName("savetripUrl"));
      log.info("=====InterfaceInfo.savetripUrl值: " + savetripUrl + "======");
      log.info("=====保存行程接口请求: " + jsonStr + "======");
      String res = Util.null2String(httpPostRaw(savetripUrl, jsonStr, headers, null));
      log.info("=====保存行程接口响应：" + res + "======");
      if ("success".equalsIgnoreCase(res)) {
        log.info("保存行程成功！");
        return true;
      } else {
        log.info("保存行程数据请求失败：" + res);
        return false;
      }
    } catch (Exception e) {
      StackTraceElement stackTraceElement = e.getStackTrace()[0];
      log.info("File=" + stackTraceElement.getFileName());
      log.info("Line=" + stackTraceElement.getLineNumber());
      log.info("Method=" + stackTraceElement.getMethodName());
      log.info("保存行程数据捕获异常:" + jsonStr);
      writeLog("save trip error!", e);
      return false;
    }
  }

  /**
   * 获取保存行程请求数据
   *
   * @param params 参数集合
   * @return res
   */
  public String getSaveTripReqString(Map<String, Object> params) {
    String res = "";
    try {
      PropBean pb = new PropBean();
      String requestid = Util.null2String(params.get("requestid"));//流程请求ID
      String status = Util.null2String(params.get("status"));//流程状态
      RecordSet rsQuery = new RecordSet();
      rsQuery.executeQuery("select requestname from workflow_requestbase where requestid =?",
          new Object[]{requestid});
      rsQuery.next();
      String requestname = Util.null2String(rsQuery.getString(1));
      String pcHost = Util.null2String(pb.getPropName("pcHost"));
      String mobileHost = Util.null2String(pb.getPropName("mobileHost"));
      String tableName = Util.null2String(getTableNameByRequestid(requestid, "0"));//主表名
      String tableDt2Name = tableName + "_dt2";//明细2表名
      String tableDt3Name = tableName + "_dt3";//明细3表名
      String tableDt4Name = tableName + "_dt4";//明细3表名
      //添加有无自费费用待报销
      String sql = "select id,lcbh,sfhwcc,ngr,szbm,ngrq,cclxzxx,cclx,qttzyddx,ccyy,yctjsqyy,YWZFFYDBX from " +
          tableName + " where requestid = " + requestid;
      RecordSet rs = new RecordSet();
      //获取后台部门
      PropBean pp = new PropBean();
      String backdept = pp.getPropName("backdept");
      List<String> backDept = Arrays.asList(backdept.split(","));
      if (rs.execute(sql) && rs.next()) {
        int mainid = Util.getIntValue(rs.getInt("id"));//主表ID
        String lcbh = Util.null2String(rs.getString("lcbh"));//流程编号
        String sfhwcc = Util.null2String(rs.getString("sfhwcc"));//是否海外出差，海外出差不调用接口
        String ngr = Util.null2String(rs.getString("ngr"));//拟稿人
        String ngrq = Util.null2String(rs.getString("ngrq"));//拟稿日期
        // 投行项目出差  客户拜访出差  其他商旅出差  外部培训/会议  内部培训/会议
        String cclxzxx = Util.null2String(rs.getString("cclxzxx"));//出差类型二级
        //出差情况 1=出差完成
        String travelSituation = Util.null2String(rs.getString("ccqk"));
        switch (cclxzxx) {
          case "0":
            cclxzxx = "投行项目出差";
            break;
          case "1":
            cclxzxx = "客户拜访出差";
            break;
          case "2":
            cclxzxx = "其他商旅出差";
            break;
          case "3":
            cclxzxx = "外部培训/会议";
            break;
          case "4":
            cclxzxx = "内部培训/会议";
            break;
          default:
            cclxzxx = "";
            break;
        }
        // 商旅出差  培训/会议
        String cclx = Util.null2String(rs.getString("cclx"));//出差类型一级
        if (cclx.equals("0")) {
          cclx = "商旅出差";
        } else {
          cclx = "培训/会议";
        }
        String tzyddxhz = Util.null2String(rs.getString("qttzyddx"));//通知阅读人
        String yctjsqyy = Util.null2String(rs.getString("yctjsqyy"));//延迟提交原因
        String ccyy = Util.null2String(rs.getString("ccyy"));//出差原因
        ResourceComInfo rc = new ResourceComInfo();
        DepartmentComInfo dc = new DepartmentComInfo();
        String departmentCode = dc.getDepartmentCode(rc.getDepartmentID(ngr));//拟稿人部门编码
        JSONObject req = new JSONObject();
        req.put("draftTime", ngrq + ":00");//拟稿时间
        req.put("drafterCode", rc.getWorkcode(ngr));//拟稿人工号
        req.put("drafterDeptCode", departmentCode);//拟稿人部门编码
        req.put("drafterName", rc.getLastname(ngr));//拟稿人姓名
        req.put("drafterPhone", rc.getMobile(ngr));//拟稿人手机
        req.put("travelApplicationBizNo", lcbh);//流程编号
        req.put("highestJobGrade", WeaverUtil.getJobGradeStandard(ngr, backDept));//最高职级对应的差标
        req.put("travelApplicationProcessId", requestid);//流程请求ID
        req.put("travelSubType", cclxzxx);//出差类型二级
        req.put("travelType", cclx);//出差类型一级
        Map<String, Object> projOrCrmInfoForSaveJourney = getProjOrCrmInfoForSaveJourney(requestid);
        req.putAll(projOrCrmInfoForSaveJourney);
        List<String> tzyddxhzList = Arrays.asList(tzyddxhz.split(","));//这是多人力资源
        JSONArray tzyddxhzArr = new JSONArray();//阅知人信息
        RecordSet recordSet = new RecordSet();
        if (!"".equals(tzyddxhz)) {
          for (String item : tzyddxhzList) {
            JSONObject ydr = new JSONObject();//阅知人
            ydr.put("deptCode", dc.getDepartmentCode(rc.getDepartmentID(item)));
            ydr.put("deptName", dc.getDepartmentName(rc.getDepartmentID(item)));
            ydr.put("userId", rc.getWorkcode(item));
            recordSet.executeQuery("select field9 from cus_fielddata where scopeid = 1 and id = ? ",
                new Object[]{item});
            recordSet.next();
            ydr.put("jobGrade", recordSet.getString(1));
            ydr.put("userName", rc.getLastname(item));
            tzyddxhzArr.add(ydr);
          }
        }

        req.put("notificationReaderList", tzyddxhzArr);//通知阅读人信息
        req.put("reason", ccyy);//出差原因
        req.put("delayReason", yctjsqyy);//延迟提交原因
        //添加有无自费费用待报销参数
        req.put("delayReimbursement", Util.null2String(rs.getString("YWZFFYDBX")));

        if ("1".equals(sfhwcc)) {//国内行程
          RecordSet rs_mx_2 = new RecordSet();
          sql = "select ccrgh,xm,bm,zj from " + tableDt2Name + " where mainid = " + mainid;
          JSONArray applicantList = new JSONArray();//出差人信息
          rs_mx_2.execute(sql);
          while (rs_mx_2.next()) {
            JSONObject ccr = new JSONObject();
            String xm = Util.null2String(rs_mx_2.getString("xm"));//姓名
            String ccrgh = Util.null2String(rs_mx_2.getString("ccrgh"));//工号
            String bm = Util.null2String(rs_mx_2.getString("bm"));//部门
            String zj = Util.null2String(rs_mx_2.getString("zj"));//职级
            ccr.put("deptCode", dc.getDepartmentCode(bm));
            ccr.put("deptName", dc.getDepartmentName(bm));
            ccr.put("userId", ccrgh);
            ccr.put("jobGrade", zj);
            ccr.put("userName", rc.getLastname(xm));
            applicantList.add(ccr);
          }
          req.put("applicantList", applicantList);
          RecordSet rs_mx_3 = new RecordSet();
          JSONArray subJourneyList = new JSONArray();//行程信息
          if ("1".equals(travelSituation)) {
            //出差情况为出差完成,取表4的数据更新行程
            sql = "select cfsj,fhsj,cfdgn,mddgn from " + tableDt4Name + " where mainid = " + mainid;
          } else {
            sql = "select cfsj,fhsj,cfdgn,mddgn from " + tableDt3Name + " where mainid = " + mainid;
          }
          rs_mx_3.execute(sql);
          List<String> cfsjList = new ArrayList<>();//出发时间集合
          List<String> fhsjList = new ArrayList<>();//返回时间集合
          RecordSetDataSource rsd = new RecordSetDataSource("Travel");//城市地址的外部数据源
          while (rs_mx_3.next()) {
            JSONObject jsonObject = new JSONObject();
            String cfsj = Util.null2String(rs_mx_3.getString("cfsj"));
            String cfdgn = getCityName(rsd, Util.null2String(rs_mx_3.getString("cfdgn")));
            jsonObject.put("beginPlace", cfdgn);
            jsonObject.put("beginTime", cfsj + " 09:00:00");
            cfsjList.add(cfsj);//出发时间
            String fhsj = Util.null2String(rs_mx_3.getString("fhsj"));
            String mddgn = getCityName(rsd, Util.null2String(rs_mx_3.getString("mddgn")));
            jsonObject.put("endPlace", mddgn);
            jsonObject.put("endTime", fhsj + " 17:00:00");
            fhsjList.add(fhsj);//返回时间
            subJourneyList.add(jsonObject);
          }
          //明细4没有数据,再取明细表3
          if (CollectionUtils.isEmpty(cfsjList)) {
            sql = "select cfsj,fhsj,cfdgn,mddgn from " + tableDt3Name + " where mainid = " + mainid;
            rs_mx_3.execute(sql);
            while (rs_mx_3.next()) {
              JSONObject jsonObject = new JSONObject();
              String cfsj = Util.null2String(rs_mx_3.getString("cfsj"));
              String cfdgn = getCityName(rsd, Util.null2String(rs_mx_3.getString("cfdgn")));
              jsonObject.put("beginPlace", cfdgn);
              jsonObject.put("beginTime", cfsj + " 09:00:00");
              cfsjList.add(cfsj);//出发时间
              String fhsj = Util.null2String(rs_mx_3.getString("fhsj"));
              String mddgn = getCityName(rsd, Util.null2String(rs_mx_3.getString("mddgn")));
              jsonObject.put("endPlace", mddgn);
              jsonObject.put("endTime", fhsj + " 17:00:00");
              fhsjList.add(fhsj);//返回时间
              subJourneyList.add(jsonObject);
            }
          }

          req.put("subJourneyList", subJourneyList);
          String minCFSJ = sortDateList(cfsjList, false);
          String maxFHSJ = sortDateList(fhsjList, true);
          req.put("beginTime", minCFSJ + " 09:00:00");
          req.put("endTime", maxFHSJ + " 17:00:00");
          req.put("isAbroad", false);//是否海外
          req.put("organization", 1);//是否联合
          req.put("title", requestname);
          req.put("travelApplicationStatus", status);
          //企业微信集成链接地址的key
          String wechatlinkkey = Util.null2String(new PropBean().getPropName("wechatlinkkey"));
          req.put("weaverTravelApplyMobileUrl",
              mobileHost + "/htmoa/wxapi/wxclientmenu/" + wechatlinkkey + "?requestid=" +
                  requestid + "");
          req.put("weaverTravelApplyPcUrl",
              pcHost + "/workflow/request/ViewRequestForwardSPA.jsp?requestid=" + requestid);
          res = req.toJSONString();
        } else {
          res = "-1";
        }
      }
    } catch (Exception e) {
      log.error("getSaveTripReqString error", e);
      return "";
    }
    return res;
  }

  /**
   * 转换外部数据源的城市名称
   *
   * @param id
   * @return
   */
  private String getCityName(RecordSetDataSource rsd, String id) {

    if (id.equals("")) {
      return id;
    }
    String name = "";
    String sql = "select name from travel_area where code in (" + id + ")";
    rsd.execute(sql);
    while (rsd.next()) {
      if (name.equals("")) {
        name = Util.null2String(rsd.getString(1));
      } else {
        name += "-" + Util.null2String(rsd.getString(1));
      }
    }
    return name;
  }

  /**
   * 获取该人员集合的职级集合
   *
   * @param hrmList 人员数据id集合
   * @return 职级集合
   */
  public List<String> getLevList(List<String> hrmList) {
    List<String> levList = new ArrayList<>();//职级数据集合
    RecordSet rs = new RecordSet();
    String sql = "";
    try {
      PropBean pb = new PropBean();
      ResourceComInfo rc = new ResourceComInfo();
      DepartmentComInfo dc = new DepartmentComInfo();
      //中后台部门 合规与风险管理部、质量控制部、战略运营部、人力资源部、财务管理部
      List<String> listDepMB = Arrays.asList(pb.getPropName("htlh.nonbusinessDept").split(","));
      //String depMB = "163001,ZZ323446,180,188,110,ZZ323493,ZZ323494";//--"163001,ZZ323446,180,188,110";
      //List<String> listDepMB = Util.splitString2List(depMB, ",");
      String workcode = "";
      String depCode = "";
      for (String hrmid : hrmList) {
        workcode = Util.null2String(rc.getWorkcode(hrmid));
        //特殊人员 张冠峰 009198
        //新增L3P特殊差标
        PropBean pp = new PropBean();
        Set<String> l3pTravelStandardSet = new HashSet<>(
            Arrays.asList(pp.getPropName("travel_standard_l3p").split(",")));
        if (l3pTravelStandardSet.contains(workcode)) {
          levList.add("L3P");
        } else {
          depCode = dc.getDepartmentCode(rc.getDepartmentID(hrmid));//部门编码
          if (depCode.equals("101") || depCode.equals("103")) {//董事会 和 执行委员会
            levList.add("L1");
          } else if (workcode.equals("014931") || workcode.equals("006781") ||
              workcode.equals("009240")) {//党委副书记，合规总监，宁敖
            levList.add("L1");
          } else if ("009198".equals(workcode)) {
            levList.add("L2");
          } else if (listDepMB.contains(depCode)) {//中后台部门
            levList.add(getlev("B", hrmid));
          } else {//前台部门
            levList.add(getlev("F", hrmid));
          }
        }
      }
    } catch (Exception e) {
      log.error("获取人员职级集合捕获异常", e);
      return levList;
    }
    return levList;
  }

  /**
   * 根据中后台还是前台部门类型判断人员职级
   *
   * @param type  F：前台   B：中后台
   * @param hrmid 人员ID
   * @return L2 L3
   */
  private String getlev(String type, String hrmid) {
    String res = "";
    RecordSet rs = new RecordSet();
    rs.executeQuery("select field9 from cus_fielddata where scopeid = 1 and id = ? ",
        new Object[]{hrmid});
    if (rs.next()) {
      String lev = Util.null2String(rs.getString(1));//职级
      if (type.equals("F")) {//前台
        if (lev.equals("MD") || lev.equals("ED")) {
          res = "L3";
        } else {
          res = "L4";
        }
      } else {//中后台
        if (lev.equals("SD") || lev.equals("D")) {
          res = "L3";
        } else {
          res = "L4";
        }
      }
    }
    rs.writeLog("判断人员" + hrmid + "职级" + type + "===getlev" + res);
    return res;
  }

  /**
   * 获取某个日期的前几天或后几天
   *
   * @param dateStr 传入某个日期
   * @param num     前几天传 负数  ，后几天传 正数
   * @return 前后的天数的日期
   */
  public String getPreOrLaterDay(String dateStr, int num) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    try {
      Date date = sdf.parse(dateStr);
      Calendar cal = Calendar.getInstance();
      cal.setTime(date);
      int day = cal.get(Calendar.DATE);
      int real = day + num;
      cal.add(Calendar.DATE, num);
      return sdf.format(cal.getTime());
    } catch (ParseException e) {
      log.error("getPreOrLaterDay", e);
      return "";
    }
  }

  /**
   * 发送http请求
   *
   * @param url        接口地址
   * @param stringJson 请求的 json 字符串
   * @param headers    头部参数
   * @param encode     编码
   * @return 响应结果
   */
  public String httpPostRaw(String url, String stringJson, Map<String, String> headers,
                            String encode) {
    if (encode == null) {
      encode = "utf-8";
    }
    String content = null;
    CloseableHttpResponse httpResponse = null;
    CloseableHttpClient closeableHttpClient = null;
    try {
      //HttpClients.createDefault()等价于 HttpClientBuilder.create().build();
      closeableHttpClient = HttpClients.createDefault();
      HttpPost httpost = new HttpPost(url);
      //设置header
      httpost.setHeader("Content-type", "application/json");
      if (headers != null && headers.size() > 0) {
        for (Map.Entry<String, String> entry : headers.entrySet()) {
          httpost.setHeader(entry.getKey(), entry.getValue());
        }
      }
      //组织请求参数
      StringEntity stringEntity = new StringEntity(stringJson, encode);
      httpost.setEntity(stringEntity);
      //响应信息
      httpResponse = closeableHttpClient.execute(httpost);
      HttpEntity entity = httpResponse.getEntity();
      content = EntityUtils.toString(entity, encode);

    } catch (Exception e) {
      log.error("http post error", e);
    } finally {
      try {
        httpResponse.close();
      } catch (IOException e) {
        log.error("http response close error", e);
      }
    }
    try {  //关闭连接、释放资源
      closeableHttpClient.close();
    } catch (IOException e) {
      log.error("http connection close error", e);
    }
    return content;
  }

  /**
   * 根据 requestid 获取表单名
   *
   * @param requestid 请求ID
   * @param num       主表：0 明细：1,2,3
   * @return 表名
   */
  public String getTableNameByRequestid(String requestid, String num) {
    String tableName = "";
    String table = "";
    RecordSet rs = new RecordSet();
    rs.execute(
        "select t1.tablename from workflow_bill t1,workflow_base t2,workflow_requestbase t3 \n where t1.id =t2.formid and t2.id = t3.workflowid and t3.requestid = "
            +
            requestid);
    if (rs.next()) {
      table = Util.null2String(rs.getString("tablename"));
      if (num.equals("0")) {
        tableName = table;
      } else {
        tableName = table + "_dt" + num;
      }
    }
    return tableName;
  }

  /**
   * get请求
   *
   * @param url
   * @param headers
   * @param encode
   * @return
   */
  public String httpGetRaw(String url, Map<String, String> headers, String encode) {
    if (encode == null) {
      encode = "utf-8";
    }
    String content = null;
    CloseableHttpResponse httpResponse = null;
    CloseableHttpClient closeableHttpClient = null;
    try {

      //HttpClients.createDefault()等价于 HttpClientBuilder.create().build();
      closeableHttpClient = HttpClients.createDefault();
      HttpGet httpGet = new HttpGet(url);

      //设置header
      httpGet.setHeader("Content-type", "application/json");
      if (headers != null && headers.size() > 0) {
        for (Map.Entry<String, String> entry : headers.entrySet()) {
          httpGet.setHeader(entry.getKey(), entry.getValue());
        }
      }
      //响应信息
      httpResponse = closeableHttpClient.execute(httpGet);
      HttpEntity entity = httpResponse.getEntity();
      content = EntityUtils.toString(entity, encode);
    } catch (Exception e) {
      log.error("http get error", e);
    } finally {
      try {
        httpResponse.close();
      } catch (IOException e) {
        log.error("http response close error", e);
      }
    }
    try {  //关闭连接、释放资源
      closeableHttpClient.close();
    } catch (IOException e) {
      log.error("http connection close error", e);
    }
    return content;
  }

  /**
   * 上传发票验真
   *
   * @param paras 参数集合
   * @return
   */
  public String SendImage(Map<String, Object> paras) {
    String resJSON = "";
    try {
      log.info("send image start");
      String billid = Util.null2String(paras.get("billid"));//流程编号
      String workcode = Util.null2String(paras.get("workcode"));//工号
      String filetype = Util.null2String(paras.get("filetype"));//文件类型 0：非票据  1：票据
      String fileids = Util.null2String(paras.get("fileids"));//附件ID
      List<String> fileidsList = Util.splitString2List(fileids, ",");
      String sql = "select imagefileid,imagefilename from docimagefile where docid = ?";
      RecordSet rsQuery = new RecordSet();
      String sendImageUrl = Util.null2String(new PropBean().getPropName("sendImageUrl"));
      log.info("send image url: " + sendImageUrl);
      URL url = new URL(sendImageUrl);
      ImageServiceSoapStub stub = new ImageServiceSoapStub(url, null);
      UploadfileEntity uploadfileEntity = new UploadfileEntity();
      uploadfileEntity.setBillID(billid);
      uploadfileEntity.setFileType(filetype);
      uploadfileEntity.setUserCode(workcode);
      log.info("send image request: " + JSON.toJSONString(uploadfileEntity));
      FileInfoEntity[] fileInfoEntities = new FileInfoEntity[fileidsList.size()];
      String fileTypeID = Util.null2String(new PropBean().getPropName("cft.image.type.invoice"));
      int i = 0;
      for (String ids : fileidsList) {
        rsQuery.executeQuery(sql, new Object[]{ids});
        rsQuery.next();
        String imagefileid = Util.null2String(rsQuery.getString("imagefileid"));
        String imagefilename = Util.null2String(rsQuery.getString("imagefilename"));
        InputStream inputstream = ImageFileManager
            .getInputStreamById(Util.getIntValue(imagefileid));
        FileInfoEntity fileInfoEntity = new FileInfoEntity();
        fileInfoEntity.setFileName(imagefilename);
        fileInfoEntity.setContent(InputStream2Byte(inputstream));
        fileInfoEntity.setFileTypeID(fileTypeID);
        fileInfoEntities[i] = fileInfoEntity;
        uploadfileEntity.setFileInfoEntityArr(fileInfoEntities);
        i++;
      }
//      log.info("send image request: " + JSON.toJSONString(uploadfileEntity));
      resJSON = stub.sendImageOnPC(uploadfileEntity);
      writeLog("send image response: " + resJSON);
    } catch (Exception e) {
      writeLog("send image error!", e);
      return "";
    }
    return resJSON;
  }

  /**
   * 上传附件 ocr
   *
   * @param paras 参数集合
   * @return
   */
  public String SendImageWithAffix(Map<String, Object> paras) {
    String resJSON = "";
    try {
      logger.info("send image start");
      String billid = Util.null2String(paras.get("billid"));//流程编号
      String workcode = Util.null2String(paras.get("workcode"));//工号
      String filetype = "0";//文件类型 0：非票据  1：票据
      String fileids = Util.null2String(paras.get("fileids"));//附件ID
      List<String> fileidsList = Util.splitString2List(fileids, ",");
      String sql = "select imagefileid,imagefilename from docimagefile where docid = ?";
      RecordSet rsQuery = new RecordSet();
      String sendImageUrl = Util.null2String(new PropBean().getPropName("sendImageUrl"));
      logger.info("send image url: " + sendImageUrl);
      URL url = new URL(sendImageUrl);
      ImageServiceSoapStub stub = new ImageServiceSoapStub(url, null);
      UploadfileEntity uploadfileEntity = new UploadfileEntity();
      uploadfileEntity.setBillID(billid);
      uploadfileEntity.setFileType(filetype);
      uploadfileEntity.setUserCode(workcode);
      logger.info("send image request: " + JSON.toJSONString(uploadfileEntity));
      FileInfoEntity[] fileInfoEntities = new FileInfoEntity[fileidsList.size()];
      String fileTypeID = Util.null2String(new PropBean().getPropName("cft.image.type.other"));
      int i = 0;
      for (String ids : fileidsList) {
        rsQuery.executeQuery(sql, new Object[]{ids});
        rsQuery.next();
        String imagefileid = Util.null2String(rsQuery.getString("imagefileid"));
        String imagefilename = Util.null2String(rsQuery.getString("imagefilename"));
        InputStream inputstream = ImageFileManager
            .getInputStreamById(Util.getIntValue(imagefileid));
        FileInfoEntity fileInfoEntity = new FileInfoEntity();
        fileInfoEntity.setFileName(imagefilename);
        fileInfoEntity.setContent(InputStream2Byte(inputstream));
        fileInfoEntity.setFileTypeID(fileTypeID);
        fileInfoEntities[i] = fileInfoEntity;
        uploadfileEntity.setFileInfoEntityArr(fileInfoEntities);
        i++;
      }
//      log.info("send image request: " + JSON.toJSONString(uploadfileEntity));
      resJSON = stub.sendImageOnPC(uploadfileEntity);
      logger.info("send image response: " + resJSON);
    } catch (Exception e) {
      logger.info("send image error!", e);
      return "";
    }
    return resJSON;
  }

  /**
   * 上传浪潮ocr
   *
   * @param paras 参数集合
   *              billid
   *              workcode
   *              filePath
   * @return
   */
  public String SendImageWithInputStream(Map<String, Object> paras) {
    String resJSON = "";
    try {
      logger.info("send image start");
      String billid = Util.null2String(paras.get("billid"));//流程编号
      String workcode = Util.null2String(paras.get("workcode"));//工号
      String filetype = "0";//文件类型 0：非票据  1：票据
      String filePath = Util.null2String(paras.get("filePath"));//文件路径
      String sendImageUrl = Util.null2String(new PropBean().getPropName("sendImageUrl"));
      logger.info("send image url: " + sendImageUrl);
      URL url = new URL(sendImageUrl);
      ImageServiceSoapStub stub = new ImageServiceSoapStub(url, null);
      UploadfileEntity uploadfileEntity = new UploadfileEntity();
      uploadfileEntity.setBillID(billid);
      uploadfileEntity.setFileType(filetype);
      uploadfileEntity.setUserCode(workcode);
      logger.info("send image request: " + JSON.toJSONString(uploadfileEntity));
      FileInfoEntity[] fileInfoEntities = new FileInfoEntity[1];
      String fileTypeID = Util.null2String(new PropBean().getPropName("cft.image.type.png"));
      int i = 0;
      InputStream inputstream = getInputStreamFromPath(filePath);
      FileInfoEntity fileInfoEntity = new FileInfoEntity();
      fileInfoEntity.setFileName(billid + ".pdf"); //文件名称=流程编号.pdf
      fileInfoEntity.setContent(InputStream2Byte(inputstream));
      fileInfoEntity.setFileTypeID(fileTypeID);
      fileInfoEntities[i] = fileInfoEntity;
      uploadfileEntity.setFileInfoEntityArr(fileInfoEntities);
      resJSON = stub.sendImageOnPC(uploadfileEntity);
      logger.info("send image response: " + resJSON);
    } catch (Exception e) {
      logger.error("send image error!", e);
      return "";
    }
    return resJSON;
  }

  /**
   * 获取文件流, by path
   *
   * @param filePath
   * @return
   * @throws FileNotFoundException
   */
  private InputStream getInputStreamFromPath(String filePath) throws FileNotFoundException {
    try {
      File thefile = new File(filePath);
      return new BufferedInputStream(new FileInputStream(thefile));
    } catch (FileNotFoundException e) {
      logger.info(String.format("filePath:%s, file not  found", filePath));
      throw new FileNotFoundException(String.format("filePath:%s, file not  found", filePath));
    }
  }

  /**
   * 转换成 byte []
   *
   * @param inputStream 附件转的流
   * @return byte
   */
  public byte[] InputStream2Byte(InputStream inputStream) {
    byte[] result;
    try {
      ByteArrayOutputStream bos = new ByteArrayOutputStream();
      byte[] buffer = new byte[1024];
      int len = 0;
      while ((len = inputStream.read(buffer)) != -1) {
        bos.write(buffer, 0, len);
      }
      inputStream.close();
      bos.flush();
      result = bos.toByteArray();
    } catch (Exception e) {
      log.error("字节流转换出错！");
      return null;
    }
    return result;
  }

  /**
   * form表单提交
   *
   * @param url
   * @param params
   * @param headers
   * @param encode
   * @return
   */
  public static String httpPostForm(String url, Map<String, String> params,
                                    Map<String, String> headers, String encode) {
    if (encode == null) {
      encode = "utf-8";
    }
    String content = null;
    CloseableHttpResponse httpResponse = null;
    CloseableHttpClient closeableHttpClient = null;
    try {
      closeableHttpClient = HttpClients.createDefault();
      HttpPost httpost = new HttpPost(url);
      //设置header
      if (headers != null && headers.size() > 0) {
        for (Map.Entry<String, String> entry : headers.entrySet()) {
          httpost.setHeader(entry.getKey(), entry.getValue());
        }
      }
      //组织请求参数
      List<NameValuePair> paramList = new ArrayList<NameValuePair>();
      if (params != null && params.size() > 0) {
        Set<String> keySet = params.keySet();
        for (String key : keySet) {
          paramList.add(new BasicNameValuePair(key, params.get(key)));
        }
      }
      httpost.setEntity(new UrlEncodedFormEntity(paramList, encode));
      httpResponse = closeableHttpClient.execute(httpost);
      HttpEntity entity = httpResponse.getEntity();
      content = EntityUtils.toString(entity, encode);
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      try {
        httpResponse.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    try {  //关闭连接、释放资源
      closeableHttpClient.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
    return content;
  }

  /**
   * 获取影像信息
   *
   * @param paras
   * @return
   */
  public String getImage(Map<String, Object> paras) {
    String response = "";
    try {
      String userCode = Util.null2String(paras.get("userCode"));
      String billId = Util.null2String(paras.get("billIDs"));
      String langChaoIp = Util.null2String(new PropBean().getPropName("langChaoIp"));
      String url = String
          .format("%s/cwbase/sg/v1/ERP/JTCW/HTZQ/API_JTCW_IMAGESYS/GetImage?userCode=%s&billIDs=%s",
              langChaoIp, userCode + billId);
      writeLog("get image request:" + url);
      Map<String, String> headers = getLangChaoHeaders();
      writeLog("get image headers:" + JSONObject.toJSONString(headers));
      // invoke interface
      response = Util.null2String(httpGetRaw(url, headers, null));
      writeLog("get image response:" + response);
    } catch (Exception e) {
      writeLog("get image error", e);
    }
    return response;
  }

  /**
   * 获取浪潮header
   *
   * @return
   */
  private Map<String, String> getLangChaoHeaders() {
    Map<String, String> headers = new HashMap<>();
    headers.put("Content-Type", "application/json");
    headers.put("GSAPPID", "02");
    headers.put("AUTHTYPE", "Anonymous");
    return headers;
  }

  /**
   * 查询云票夹
   *
   * @param paras
   * @return
   */
  public String queryInvoice(Map<String, Object> paras) {
    String response = "";
    try {
      String langChaoIp = Util.null2String(new PropBean().getPropName("langChaoIp"));
      String url = String
          .format("%s/cwbase/sg/v1/ERP/JTCW/HTZQ/API_JTCW_IMAGESYS/QueryInvoiceInfo", langChaoIp);
      writeLog("query invoice url:" + url);
      Map<String, String> headers = getLangChaoHeaders();
      writeLog("query invoice headers:" + JSONObject.toJSONString(headers));
      String request = String.format(
          "{\"UserCode\":\"%s\",\"Filter\":{\"InvoiceType\":\"%s\",\"InvoiceDate\":\"%s\",\"InvoiceCode\":\"%s\",\"InvoiceNum\":\"%s\",\"PriceAndTax\":\"%s\",\"NotTaxPrice\":\"%s\",\"Note\":\"%s\",\"Page\":\"%s\",\"PageSize\":\"%s\"}}",
          Util.null2String(paras.get("UserCode")), Util.null2String(paras.get("InvoiceType")),
          Util.null2String(paras.get("InvoiceDate")), Util.null2String(paras.get("InvoiceCode")),
          Util.null2String(paras.get("InvoiceNum")), Util.null2String(paras.get("PriceAndTax")),
          Util.null2String(paras.get("NotTaxPrice")), Util.null2String(paras.get("Note")),
          Util.null2String(paras.get("Page")), Util.null2String(paras.get("PageSize")));
      writeLog("query invoice request:" + request);
      Map<String, String> map = new HashMap<>();
      BASE64Encoder encoder = new BASE64Encoder();
      map.put("jsonStr", encoder.encode(request.getBytes()));
      request = JSONObject.toJSONString(map);
      writeLog("query invoice base64:" + request);
      // invoke interface
      response = Util.null2String(httpPostRaw(url, request, getLangChaoHeaders(), null));
      writeLog("query invoice response:" + response);
    } catch (Exception e) {
      writeLog("query invoice error", e);
    }
    return response;
  }

  /**
   * 影像单据信息关联
   *
   * @param paras
   * @return
   */
  public String connectInvAndBill(Map<String, Object> paras) {
    log.info("connect inv and bill param: " + JSON.toJSONString(paras));
    String langChaoIp = Util.null2String(new PropBean().getPropName("langChaoIp"));
    String requestUrl =
        langChaoIp + "/cwbase/sg/v1/ERP/JTCW/HTZQ/API_JTCW_IMAGESYS/ConnectInvAndBill";
    Map<String, Object> requestData = new HashMap<>(4);
    requestData.put("UserCode", Util.null2String(paras.get("UserCode")));
    requestData.put("BillID", Util.null2String(paras.get("BillID")));
    requestData.put("InvoiceInfo", paras.get("InvoiceInfo"));
    Map<String, String> map = new HashMap<>();
    String jsonStr = JSON.toJSONString(requestData);
    try {
      log.info("connect inv and bill request: " + jsonStr);
      // 用iso转一道 防止出现中文字数奇数乱码问题
      String iso = new String(jsonStr.getBytes("UTF-8"), "ISO-8859-1");
      jsonStr = new String(iso.getBytes("ISO-8859-1"), "UTF-8");
      BASE64Encoder encoder = new BASE64Encoder();
      map.put("jsonStr", encoder.encode(jsonStr.getBytes("UTF-8")));
      String response = httpPostRaw(requestUrl, JSON.toJSONString(map), getLangChaoHeaders(), null);
      log.info("connect inv and bill response: " + response);

      //日志
      InterfaceLogUtil.saveLogWithMapParams(paras, response, "connectInvAndBill");

      return response;
    } catch (Exception e) {
      log.error("connect inv and bill error", e);
      return "";
    }
  }

  /**
   * 重置影像和单据关系
   *
   * @param paras
   * @return
   */
  public String resetImageAndBill(Map<String, Object> paras) {
    String response = "";
    try {
      String langChaoIp = Util.null2String(new PropBean().getPropName("langChaoIp"))
          .replace("\"", "");
      String url = String
          .format("%s/cwbase/sg/v1/ERP/JTCW/HTZQ/API_JTCW_IMAGESYS/ResetImageAndBill", langChaoIp);
      Map<String, String> paramsMap = new HashMap<>();
      String reqStr = String.format(
          "{\"UserCode\":\"%s\",\"BillID\":\"%s\",\"FileID\":\"%s\",\"InvoiceCode\":\"%s\",\"InvoiceNum\":\"%s\"}",
          Util.null2String(paras.get("UserCode")), Util.null2String(paras.get("BillID")),
          Util.null2String(paras.get("FileID")),
          Util.null2String(paras.get("InvoiceCode")), Util.null2String(paras.get("InvoiceNum")));
      log.info("reset image and bill gbk reqStr:" + reqStr);
      // 用iso转一道 防止出现中文字数奇数乱码问题
      String iso = new String(reqStr.getBytes("UTF-8"), "ISO-8859-1");
      reqStr = new String(iso.getBytes("ISO-8859-1"), "UTF-8");
      log.info("reset image and bill utf-8 reqStr:" + reqStr);
      log.info("reset image and bill request:" + url);
      log.info("reset image and bill params:" + reqStr);
      BASE64Encoder encoder = new BASE64Encoder();
      paramsMap.put("jsonStr", encoder.encode(reqStr.getBytes("UTF-8")));
      response = Util
          .null2String(httpPostRaw(url, JSON.toJSONString(paramsMap), getLangChaoHeaders(), null));
      log.info("reset image and bill response:" + response);

      //日志
      InterfaceLogUtil.saveLogWithMapParams(paras, response, "resetImageAndBill");

      return response;
    } catch (Exception e) {
      writeLog("reset image and bill error", e);
      return "";
    }

  }

  /**
   * 获取预算
   *
   * @param paras
   * @return
   */
  public String getBudget(Map<String, Object> paras) {
    String response = "";
    try {
      String endpoint = String.format("%s/cwbase/JTGL/BudgetProcess.asmx?wsdl",
          Util.null2String(new PropBean().getPropName("budgetIp")));
      String soapAction = "http://tempuri.org/";
      String bgElement = Util.null2String(paras.get("BgElement"));
      if (StringUtils.isBlank(bgElement)) {
        bgElement = "0101";
      }
      String bgPeriod = Util.null2String(paras.get("BgPeriod"));
      if (StringUtils.isBlank(bgPeriod)) {
        bgPeriod = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
      }
      Service service = new Service();
      Call call = (Call) service.createCall();
      call.setTargetEndpointAddress(endpoint);
      call.setOperationName(new QName(soapAction, "GetBudget"));
      call.addParameter(new QName(soapAction, "deptNum"), Constants.XSD_STRING, ParameterMode.IN);
      call.addParameter(new QName(soapAction, "deptType"), Constants.XSD_STRING, ParameterMode.IN);
      call.addParameter(new QName(soapAction, "Bgitem"), Constants.XSD_STRING, ParameterMode.IN);
      call.addParameter(new QName(soapAction, "BgElement"), Constants.XSD_STRING, ParameterMode.IN);
      call.addParameter(new QName(soapAction, "BgPeriod"), Constants.XSD_STRING, ParameterMode.IN);
      call.setReturnType(XMLType.XSD_STRING);//（标准的类型）
      call.setUseSOAPAction(true);
      call.setSOAPActionURI(soapAction + "GetBudget");

      writeLog("get budget request:" + String
          .format("deptNum=%s, deptType=%s, Bgitem=%s, BgElement=%s, BgPeriod=%s",
              Util.null2String(paras.get("deptNum")), Util.null2String(paras.get("deptType")),
              Util.null2String(paras.get("Bgitem")), bgElement, bgPeriod));

      response = (String) call.invoke(new Object[]{Util.null2String(paras.get("deptNum")),
          Util.null2String(paras.get("deptType")), Util.null2String(paras.get("Bgitem")), bgElement,
          bgPeriod});
      response = XML.toJSONObject(response).toString();
      if ("1".equals(Util.null2String(new PropBean().getPropName("show.debug.log")))) {
        writeLog("get budget response:" + response);
      }
    } catch (Exception e) {
      writeLog("get budget error", e);
    }
    return response;
  }

  /**
   * 提交预算
   *
   * @param paras
   * @return
   */
  public String budgetCommit(Map<String, Object> paras) {
    String response = "";
    try {
      String endpoint = String.format("%s/cwbase/JTGL/BudgetProcess.asmx?wsdl",
          Util.null2String(new PropBean().getPropName("budgetIp")));
      String soapAction = "http://tempuri.org/";
      String text = Util.null2String(paras.get("data"));
      if (StringUtils.isNotBlank(text)) {
        InputBudgetData data = JSON.parseObject(text, InputBudgetData.class);
        if (data != null) {
          String xmlString = XmlUtils.toXml(data, InputBudgetData.class, true);
          Service service = new Service();
          Call call = (Call) service.createCall();
          call.setTargetEndpointAddress(endpoint);
          call.setOperationName(new QName(soapAction, "BudgetCommit"));
          call.addParameter(new QName(soapAction, "xmlString"), Constants.XSD_STRING,
              ParameterMode.IN);
          //（标准的类型）
          call.setReturnType(XMLType.XSD_STRING);
          call.setUseSOAPAction(true);
          call.setSOAPActionURI(soapAction + "BudgetCommit");

          writeLog("budget commit request:" + String.format("xmlString=%s", xmlString));
          response = (String) call.invoke(new Object[]{xmlString});
          //response = XML.toJSONObject(response).toString();

          //日志
          InterfaceLogUtil.saveLogWithMapParams(paras, response, "budgetCommit");


          if ("1".equals(Util.null2String(new PropBean().getPropName("show.debug.log")))) {
            writeLog("budget commit response:" + response);
          }
        }
      }

    } catch (Exception e) {
      writeLog("budget commit error", e);
    }
    return response;
  }

  /**
   * 获取投行项目
   *
   * @param paras
   * @return
   */
  public String getProject(Map<String, Object> paras) {
    String response = "";
    try {
      String projectUrl = Util.null2String(new PropBean().getPropName("projectUrl"));
      String projectIp = Util.null2String(new PropBean().getPropName("projectIp"));
      String projectService = Util.null2String(new PropBean().getPropName("projectService"));
      String projectKey = Util.null2String(new PropBean().getPropName("projectKey"));
      String projectName = Util.null2String(new PropBean().getPropName("projectName"));
      String userId = Util.null2String(paras.get("userId"));
      String secretKey = MD5.md5(projectKey).toUpperCase();
      String endpoint = projectIp + projectUrl;

      Service service = new Service();
      Call call = (Call) service.createCall();
      call.registerTypeMapping(ProjectInfoSafety.class,
          new QName(projectService, "ProjectInfoSafety"),
          new BeanSerializerFactory(ProjectInfoSafety.class,
              new QName(projectService, "ProjectInfoSafety")),
          new BeanDeserializerFactory(ProjectInfoSafety.class,
              new QName(projectService, "ProjectInfoSafety")));
      call.setTargetEndpointAddress(endpoint);
      call.setOperationName(new QName(projectService, "findProjectsByUserIdSafety"));
      call.addParameter("userId", Constants.XSD_STRING, ParameterMode.IN);
      call.addParameter("md5key", Constants.XSD_STRING, ParameterMode.IN);
      call.addParameter("platformName", Constants.XSD_STRING, ParameterMode.IN);
      call.setReturnType(new QName(projectService, "ProjectInfoSafety[]"));
      // 部分账号返回项目过多 设置socket_time_out 5min
      call.setTimeout(5 * 60 * 1000);
      writeLog("get project request:" + String
          .format("userId=%s, md5key=%s, platformName=%s", userId, secretKey, projectName));
      ProjectInfoSafety[] bean = (ProjectInfoSafety[]) call
          .invoke(new Object[]{userId, secretKey, projectName});
      response = JSONArray.toJSONString(bean);
      if ("1".equals(Util.null2String(new PropBean().getPropName("show.debug.log")))) {
        writeLog("get project response:" + response);
      }
      return response;
    } catch (Exception e) {
      writeLog("get project error", e);
    }
    return response;
  }

  /**
   * 按照项目ID获取项目详情
   *
   * @param paras
   * @return
   */
  public String getProjectById(Map<String, Object> paras) {
    String response = "";
    String projectIdStr = Util.null2String(paras.get("projectId"));
    if (StringUtils.isBlank(projectIdStr)) {
      writeLog("project id is empty!");
      return response;
    }
    int projectId = Integer.parseInt(projectIdStr);
    String projectUrl = Util.null2String(new PropBean().getPropName("projectUrl"));
    String projectIp = Util.null2String(new PropBean().getPropName("projectIp"));
    String projectService = Util.null2String(new PropBean().getPropName("projectService"));
    String projectKey = Util.null2String(new PropBean().getPropName("projectKey"));
    String projectName = Util.null2String(new PropBean().getPropName("projectName"));
    String md5key = MD5.md5(projectKey).toUpperCase();
    String endpoint = projectIp + projectUrl;
    ProjectInfoSafety bean = null;
    try {
      QName qName = new QName(projectService, "ProjectInfoSafety");
      Service service = new Service();
      Call call = (Call) service.createCall();
      call.registerTypeMapping(ProjectInfoSafety.class, qName,
          new BeanSerializerFactory(ProjectInfoSafety.class, qName),
          new BeanDeserializerFactory(ProjectInfoSafety.class, qName));
      call.setTargetEndpointAddress(endpoint);
      call.setOperationName(new QName(projectService, "findProjectByIdSafety"));
      call.addParameter("projectId", Constants.XSD_INT, ParameterMode.IN);
      call.addParameter("md5key", Constants.XSD_STRING, ParameterMode.IN);
      call.addParameter("platformName", Constants.XSD_STRING, ParameterMode.IN);
      call.setReturnType(qName);
      writeLog("get project by id request:" + String
          .format("projectId=%s, md5key=%s, platformName=%s", projectId, md5key, projectName));
      bean = (ProjectInfoSafety) call.invoke(new Object[]{projectId, md5key, projectName});
      if (bean != null) {
        response = JSON.toJSONString(bean);
      }
      if ("1".equals(Util.null2String(new PropBean().getPropName("show.debug.log")))) {
        writeLog("get project by id response:" + response);
      }
    } catch (Exception e) {
      writeLog("get project by id error!", e);
    }
    return response;
  }

  /**
   * 获取客户信息
   *
   * @param paras
   * @return
   */
  public String getCust(Map<String, Object> paras) {
    return null;
  }

  /**
   * 根据部门ID获取部门类型的编码
   *
   * @param rs  数据库连接
   * @param ids 部门id
   * @return 类型编码
   */
  public static String getDeptTypeByDeptid(RecordSet rs, String ids) {
    String sql = "select depttypecode from hrmdepartmentdefined where deptid = ?";
    if (rs.executeQuery(sql, new Object[]{ids}) && rs.next()) {
      return Util.null2String(rs.getString(1));
    }
    return "";
  }

  /**
   * 查找出差行程信息
   *
   * @param params 入参
   * @return
   */
  public String queryByJourneyId(Map<String, Object> params) {
    try {
      Map<String, String> headers = new HashMap<>();
      String token = getToken(Util.null2String(new PropBean().getPropName("journey.token.empcode")));
      if ("".equals(token)) {
        return "";
      }
      headers.put("JTXT-AUTH-TOKEN", token);
      headers.put("JTXT-AUTH-TYPE", "USER");
      String url = Util.null2String(new PropBean().getPropName("queryjourneyUrl"));//查询行程信息接口
      log.info("=======HTUtil>>>方法======queryByJourneyId=======");
      log.info("=======url>>> " + url);
      log.info("=======查找出差行程信息,请求参数==== " + params);
      String res = httpPostRaw(url, JSONObject.toJSONString(params), headers, null);
      log.info("=======查找出差行程信息,响应==== " + res);
      return res;
    } catch (Exception e) {
      log.error("查找出差行程信息 exception", e);
      return "";
    }
  }

  /**
   * 获取token
   *
   * @param workcode 工号
   * @return 认证信息
   */
  public String getToken(String workcode) {
    try {
      if (!"".equals(workcode)) {
        String url = Util.null2String(new PropBean().getPropName("tokenUrl"));
        log.info("=======HTUtil>>>方法======getToken=======");
        log.info("=======处理: 获取token=======");
        log.info("=======InterfaceInfo.tokenUrl: " + url);
        Map<String, String> headers = new HashMap<>();
        headers.put("iv-user", workcode);
        log.info("=======请求参数: " + workcode);
        String res = httpPostRaw(url, new JSONObject().toJSONString(), headers, null);
        log.info("=======响应参数: " + res);
        if (!"".equals(res)) {
          JSONObject resObj = JSONObject.parseObject(res);
          return resObj.get("accessToken").toString();
        } else {
          return "";
        }
      } else {
        return "";
      }
    } catch (Exception e) {
      log.error("getToken exception", e);
      return "";
    }
  }

  /**
   * 根据 流程ID获取主表名
   *
   * @param wfid 流程id
   * @return 表名
   */
  public String getTableNameByWfid(int wfid) {
    String tableName = "";
    try {
      if (!"".equals(wfid)) {
        String sql =
            "select t1.tablename from workflow_bill t1,workflow_base t2 where t1.id = t2.formid and t2.id = "
                +
                wfid;
        RecordSet rs = new RecordSet();
        rs.execute(sql);
        if (rs.next()) {
          tableName = Util.null2String(rs.getString("tablename"));
        }
      }
    } catch (Exception e) {
      log.error("getTableNameByWfid exception", e);
    }
    return tableName;
  }

  /**
   * 获取应用的token
   *
   * @return token
   */
  public String getAppToken() {
    String url = Util.null2String(new PropBean().getPropName("appToken"));
//    String url = "http://168.61.69.225:8080/jtxt/auth/applogin/WEAVER/Admin@123";
    JSONObject res = JSONObject.parseObject(httpPostRaw(url, "", null, null));
    return Util.null2String(res.get("accessToken"));
  }


  /**
   * 获取应用授权header
   *
   * @return
   */
  public Map<String, String> getAppHeader() {
    Map<String, String> headers = new HashMap<>();
    String token = getAppToken();
    if (StringUtils.isBlank(token)) {
      writeLog("get app token failed!");
      return headers;
    }
    headers.put("JTXT-AUTH-TOKEN", token);
    headers.put("JTXT-AUTH-TYPE", "APP");
    return headers;
  }


  /**
   * 获取用户授权header
   *
   * @param empCode 华泰用户工号
   * @return
   */
  public Map<String, String> getUserHeader(String empCode) {
    Map<String, String> headers = new HashMap<>();
    String token = getToken(empCode);
    if (StringUtils.isBlank(token)) {
      writeLog("get user token failed!");
      return headers;
    }
    headers.put("JTXT-AUTH-TOKEN", token);
    headers.put("JTXT-AUTH-TYPE", "USER");
    return headers;
  }

  /**
   * 更新差旅报销信息接口
   *
   * @param params 入参
   * @return 结果
   */
  public String updateReimbursement(Map<String, Object> params) {
    try {
      String token = getAppToken();
      if ("".equals(token)) {
        return "";
      }
      Map<String, String> headers = new HashMap<>();
      headers.put("JTXT-AUTH-TOKEN", token);
      headers.put("JTXT-AUTH-TYPE", "APP");
      log.info("=======HTUtil>>>方法======updateReimbursement=======");
      log.info("=======更新差旅报销信息接口=======");
      log.info("=======更新差旅报销信息接口请求参数: " + params);
      String url = Util.null2String(new PropBean().getPropName("updateReUrl"));
      log.info("=======更新差旅报销信息接口请求url: " + url);
      String res = httpPostRaw(url, JSONObject.toJSONString(params), headers, null);
      log.info("=======更新差旅报销信息接口请求响应: " + res);
      return res;
    } catch (Exception e) {
      log.error("=======更新差旅报销信息接口异常", e);
      return "";
    }
  }


  /**
   * 自动签章
   *
   * @param reqString 请求字符串
   * @return 响应结果
   */
  public String doAutoSign(String reqString) {
    String response = "";
    log.info("doAutoSign----->Start");
    log.info("自动签章请求：" + reqString);
    try {
      PropBean pb = new PropBean();
      //自动签章接口地址
      String AutoSignUrl = Util.null2String(pb.getPropName("AutoSign.url"));
      log.info("AutoSignUrl----->" + AutoSignUrl);
      Map<String, String> handermap = getAppHeader();
      JAVATools.SetCmdwritelog("handermap:" + handermap.size());
      if (handermap != null && handermap.size() > 0) {
        for (Map.Entry<String, String> entry : handermap.entrySet()) {
          System.out.println(entry.getKey() + ":" + entry.getValue());
        }
      }
      response = httpPostRaw(AutoSignUrl, reqString, handermap, null);
    } catch (Exception e) {
      log.error("doAutoSign捕获异常：", e);
      e.printStackTrace();
    }
    log.info("自动签章响应：" + response);
    log.info("doAutoSign----->End");
    return response;
  }

  /**
   * 手动签章
   *
   * @param reqString 请求字符串
   * @return 响应结果
   */
  public String ManualSignPost(String reqString) {
    String response = "";
    log.info("doAutoSign----->Start");
    log.info("手动签章请求：" + reqString);
    try {
      PropBean pb = new PropBean();
      //自动签章接口地址
      String AutoSignUrl = Util.null2String(pb.getPropName("ManualSign.url"));
      log.info("ManualSignPost----->" + AutoSignUrl);
      Map<String, String> handermap = getAppHeader();
      JAVATools.SetCmdwritelog("handermap:" + handermap.size());
      if (handermap != null && handermap.size() > 0) {
        for (Map.Entry<String, String> entry : handermap.entrySet()) {
          System.out.println(entry.getKey() + ":" + entry.getValue());
        }
      }
      response = httpPostRaw(AutoSignUrl, reqString, handermap, null);
    } catch (Exception e) {
      log.error("ManualSignPost捕获异常：", e);
    }
    log.info("手动签章响应：" + response);
    log.info("doAutoSign----->End");
    return response;
  }

  /**
   * 手动签章(对手方电子用印)
   *
   * @param reqString 请求字符串
   * @return 响应结果
   */
  public String ManualSignPostNew(String reqString) {
    String response = "";
    log.info("ManualSignPostNew----->Start");
    log.info("手动签章请求：" + reqString);
    try {
      PropBean pb = new PropBean();
      //接口地址
      String signUrl = Util.null2String(pb.getPropName("jtxt.base.url")) + "/weaver/seal/sendEseal";
      log.info("ManualSignPostNew----->" + signUrl);
      Map<String, String> handermap = getAppHeader();
      JAVATools.SetCmdwritelog("handermap:" + handermap.size());
      if (handermap != null && handermap.size() > 0) {
        for (Map.Entry<String, String> entry : handermap.entrySet()) {
          System.out.println(entry.getKey() + ":" + entry.getValue());
        }
      }
      response = httpPostRaw(signUrl, reqString, handermap, null);
    } catch (Exception e) {
      log.error("ManualSignPostNew捕获异常：", e);
    }
    log.info("手动签章响应：" + response);
    log.info("ManualSignPostNew----->End");
    return response;
  }

  /**
   * 触发用印信息变更
   *
   * @param reqString 请求字符串
   * @return 响应结果
   */
  public String ApplyPrintPost(String reqString) {
    String response = "";
    log.info("doApplyPrint----->Start");
    log.info("触发用印信息变更请求：" + reqString);
    try {
      PropBean pb = new PropBean();
      //触发用印信息变更接口地址
      String AutoSignUrl = Util.null2String(pb.getPropName("ApplyPrint.url"));
      log.info("ApplyPrintPost----->" + AutoSignUrl);
      Map<String, String> handermap = getAppHeader();
      JAVATools.SetCmdwritelog("handermap:" + handermap.size());
      if (handermap != null && handermap.size() > 0) {
        for (Map.Entry<String, String> entry : handermap.entrySet()) {
          System.out.println(entry.getKey() + ":" + entry.getValue());
        }
      }
      response = httpPostRaw(AutoSignUrl, reqString, handermap, null);
    } catch (Exception e) {
      log.error("ApplyPrintPost捕获异常：", e);
    }
    log.info("触发用印信息变更响应：" + response);
    log.info("doApplyPrint----->End");
    return response;
  }

  /**
   * 查询用印信息
   *
   * @param reqString 请求字符串
   * @return 响应结果
   */
  public String getPrintInfo(String reqString) {
    String response = "";
    log.info("PrintInfo----->Start");
    log.info("查询用印信息请求：" + reqString);
    try {
      PropBean pb = new PropBean();
      //触发用印信息变更接口地址
      String AutoSignUrl = Util.null2String(pb.getPropName("PrintInfo.url"));
      log.info("ApplyPrintPost----->" + AutoSignUrl);
      Map<String, String> handermap = getAppHeader();
      JAVATools.SetCmdwritelog("handermap:" + handermap.size());
      if (handermap != null && handermap.size() > 0) {
        for (Map.Entry<String, String> entry : handermap.entrySet()) {
          System.out.println(entry.getKey() + ":" + entry.getValue());
        }
      }
      response = httpPostRaw(AutoSignUrl, reqString, handermap, null);
    } catch (Exception e) {
      log.error("PrintInfo捕获异常：", e);
    }
    log.info("查询用印信息请求：" + response);
    log.info("PrintInfo----->End");
    return response;
  }

  /**
   * rpa防伪打印
   *
   * @param reqString 请求字符串
   * @return 响应结果
   */
  public String doRpaPrint(String reqString) {
    String response = "";
    log.info("doRpaPrint----->Start");
    log.info("调用rpa防伪打印请求：" + reqString);
    try {
      PropBean pb = new PropBean();
      //触发用印信息变更接口地址
      String RpaPrintUrl = Util.null2String(pb.getPropName("jtxt.base.url")) + "/weaver/seal/print";
      log.info("doRpaPrint----->" + RpaPrintUrl);
      Map<String, String> handermap = getAppHeader();
      JAVATools.SetCmdwritelog("handermap:" + handermap.size());
      if (handermap != null && handermap.size() > 0) {
        for (Map.Entry<String, String> entry : handermap.entrySet()) {
          System.out.println(entry.getKey() + ":" + entry.getValue());
        }
      }
      response = httpPostRaw(RpaPrintUrl, reqString, handermap, null);
    } catch (Exception e) {
      log.error("doRpaPrint捕获异常：", e);
    }
    log.info("调用rpa防伪打印请求：" + response);
    log.info("doRpaPrint----->End");
    return response;
  }

  /**
   * 核算接口
   *
   * @param paras
   * @return
   */
  public String saveFydj(Map<String, Object> paras) {
    String response = "";
    RootData rootData = new RootData();
    //类别
    String lb = Util.null2String(paras.get("lb"));

    switch (lb.toLowerCase()) {
      //联合差旅费用报销
      case "lhcl":
        rootData = getLhclFydjRoot(paras);
        break;
      //联合普通费用报销
      case "lhpt":
        rootData = getLhptFydjRoot(paras);
        break;
      //联合付款
      case "lhfk":
        rootData = getLhfkFydjRoot(paras);
        break;
      //总部差旅费用报销
      case "htcl":
        rootData = getHtclFydjRoot(paras);
        break;
      //总部普通费用报销
      case "htpt":
        rootData = getHtptFydjRoot(paras);
        break;
      //采购商城付款
      case "cgsc":
        rootData = getHtptFydjRoot(paras);
        break;
      //总部付款
      case "htfk":
        rootData = getHtfkFydjRoot(paras);
        break;
      //财务调整
      case "fnaj":
        rootData = getFnAjFydjRoot(paras);
        break;
      default:
        throw new IllegalArgumentException("费用核算类别参数有误");
    }

    List<InputData> list = rootData.getList();
    if (CollectionUtils.isEmpty(list)) {
      log.info("input data list is empty!");
      return response;
    }
    String dq = Util.null2String(paras.get("dq"));
    // 联合的单号要变下
    if (StringUtils.isNotBlank(dq)) {
      // 付款单号
      String fkdh = Util.null2String(paras.get("fkdh"));
      for (int i = 0; i < rootData.getList().size(); i++) {
        InputData inputData = rootData.getList().get(i);
        String[] arr = inputData.getDJID().split("#");
        if (StringUtils.isBlank(fkdh)) {
          throw new NullPointerException("请先点击付款生成单号");
        }
        if (StringUtils.isNotBlank(dq) && arr.length > 1) {
          inputData.setDJID(fkdh + "#" + arr[1]);
        }
      }
    }
    LangChaoClient client = new LangChaoClient();
    response = client.saveHtFydj(list);

    if ("cgsc".equals(lb.toLowerCase())&&("success".equals(response))){
      SettlePaymentFlowServiceImpl settlePaymentFlowService = new SettlePaymentFlowServiceImpl();
      String requestid = JAVATools.getRequestidByRequestMark(paras.get("fkdh").toString());
      settlePaymentFlowService.updatepayStatus("",requestid,"4");
    }
    //修改主表付款状态
    if("success".equals(response) && !"fnaj".equals(lb.toLowerCase())){
      String bxbh = Util.null2String(paras.get("bxbh"));
      if(StringUtils.isNotEmpty(bxbh)){
        String mainTable = "formtable_main_";
        RecordSet rst = new RecordSet();
        String sql = "select abs(e.formid) as formid from workflow_requestbase s left join workflow_base e on s.workflowid=e.id where s.requestmark = '"+bxbh+"'";
        rst.executeQuery(sql);
        if (rst.next()) {
          mainTable = mainTable + Util.null2String(rst.getString("formid"));
          String sqlUpdate = "update "+ mainTable +" t set t.fkzt=0 where t.lcbh='"+ bxbh + "'";
          rst.execute(sqlUpdate);
        }
      }
    }
    //日志
    InterfaceLogUtil.saveLogWithMapParams(paras, response, "saveFydj");

    return response;
  }

  private RootData getFnAjFydjRoot(Map<String, Object> paras) {
    RootData rootData = new RootData();
    try {
      InputData data = new InputData();
      String bxbmbh = Util.null2String(paras.get("bxbmbh"));
      if (StringUtils.isBlank(bxbmbh)) {
        writeLog("bxbmbh is empty! bxbm:" + bxbmbh);
        return null;
      }
      int deptId = getDeptId(bxbmbh);
      if (deptId <= 0) {
        writeLog("deptId is empty! bxbmbh:" + bxbmbh);
        return null;
      }
      String deptTypeCode = getDeptTypeCode(String.valueOf(deptId));
      if (StringUtils.isBlank(deptTypeCode)) {
        writeLog("deptTypeCode is empty! bxbmbh:" + bxbmbh);
        return null;
      }
      data.setBXBM(Util.null2String(paras.get("bxbm")));
      data.setBXR(Util.null2String(paras.get("bxr")));
      data.setDJBH(Util.null2String(paras.get("bxbh")));
      // data.setDJID(Util.null2String(paras.get("djid")));
      String djid = Util.null2String(paras.get("djid"));
      //财务调整单据
      data.setDJLX(ReimburseType.CWTZDJ);
      data.setDJRQ(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")));
      //华泰资管虚拟部门，用于人力资源部发起资管付款
      //org.HRinZG=HRinZG001
      String zgxnbm = Util.null2String(new PropBean().getPropName("htfkfydj_zgxnbm"));
      if (bxbmbh.equals(zgxnbm)) {
        //资产管理总部
        //org.zgdeptcode=ZZ001013
        String zcglzb = Util.null2String(new PropBean().getPropName("htfkfydj_zcglzb"));
        data.setDWBH(zcglzb);
      } else {
        data.setDWBH(bxbmbh);
      }
      data.setFJZS(Util.null2String(paras.get("fjzs")));
      data.setKHYH("-");
      data.setYHZH("-");
      data.setSFDW("-");
      String dq = Util.null2String(paras.get("dq"));
      data.setDQ(dq);
      // 摘要
      data.setZY(Util.null2String(paras.get("zy")));
      // 报销方式
      String bxfs = Util.null2String(paras.get("bxfs"));
      // 付款单号
      String fkdh = Util.null2String(paras.get("fkdh"));
      // 币种
      String bz = Util.null2String(paras.get("bz"));
      // 拟稿日期
      String ngrq = Util.null2String(paras.get("ngrq"));
      // BH1
      data.setBH1(Util.null2String(paras.get("bh1")));
      // BZ1
      data.setBZ1(Util.null2String(paras.get("bz1")));
      // BZ2
      data.setBZ2(Util.null2String(paras.get("bz2")));
      //是否全电子发票
      data.setSFQDZ(Util.null2String(paras.get("sfqdz")));
      //会计明细
      //借方(财务调整流程只涉及kjmx,reason作为借贷方判断)
      String kjmx = Util.null2String(paras.get("kjmx"));
      int i = 0;
      if (StringUtils.isNotBlank(kjmx)) {
        @SuppressWarnings("unchecked") List<AccountingDetail> accountingDetailList = JSON
            .parseArray(kjmx, AccountingDetail.class);
        if (CollectionUtils.isNotEmpty(accountingDetailList)) {
          for (AccountingDetail costShare : accountingDetailList) {
            InputData inputData = new InputData();
            BeanUtils.copyProperties(data, inputData);
            //重设单据编号
            inputData.setDJID(String.format("%s#%s", djid, i++));
            //分摊部门（编号）
            inputData.setFTBM(costShare.getExpenseDeptCode());
            //分摊部门（名称）
            inputData.setFTBMMC(costShare.getExpenseDept());
            //分摊人(名称)
            inputData.setFTR("-");
            //分摊人(名称)
            inputData.setFTRYMC("-");
            //部门类型编码 为 JGLX10或JGLX11 (等同于company==10)
            if ("JGLX10".equals(deptTypeCode) || "JGLX11".equals(deptTypeCode)) {
              inputData.setJZFX("D");
              inputData.setVoucherdate(ngrq);
              inputData.setAccountperiod(
                  LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
              inputData.setCurrencycode(bz);
            } else {
              //0:借 1:贷
              String jd = costShare.getReason();
              if ("0".equals(jd)) {
                inputData.setJZFX("1");
              } else if ("1".equals(jd)) {
                inputData.setJZFX("2");
              }
            }
            inputData.setZFFS("-");
            //华泰会计科目编号
            if (null != costShare.getSubjectData()) {
              //会计科目编号
              inputData.setKJKM(costShare.getSubjectData().getItemCode());
            } else {
              if (null != costShare.getYssuanData()) {
                inputData.setKJKM(costShare.getYssuanData().getRelationCode());
              }
            }
            if (null != costShare.getYssuanData()) {
              //预算科目
              if (StringUtils.isNotBlank(costShare.getYssuanData().getItemCode())) {
                inputData.setYSXMBH(costShare.getYssuanData().getItemCode());
                inputData.setYSXMMC(costShare.getYssuanData().getItemName());
              }
            }
            if (StringUtils.isNotBlank(costShare.getPriceRMB())) {
              inputData.setJE(costShare.getPriceRMB());
            } else {
              //分摊金额
              inputData.setJE(costShare.getMoney());
            }
            inputData.setSY("");
            rootData.getList().add(inputData);
          }
        }
      }
      return rootData;
    } catch (Exception e) {
      log.error("财务调整核算生成数据错误：", e);
    }
    return rootData;
  }

  /**
   * 联合差旅报销费用合计
   *
   * @param paras
   * @return
   */
  public RootData getLhclFydjRoot(Map<String, Object> paras) {
    RootData rootData = new RootData();
    try {
      InputData data = new InputData();
      data.setBXBM(Util.null2String(paras.get("bxbm")));
      data.setBXR(Util.null2String(paras.get("bxr")));
      data.setDJBH(Util.null2String(paras.get("bxbh")));
      data.setDJID(Util.null2String(paras.get("djid")));
      data.setDJLX(ReimburseType.CLFYBX);
      data.setDJRQ(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")));
      data.setDWBH("华泰联合");
      data.setFJZS(Util.null2String(paras.get("fjzs")));
      data.setKHYH("-");
      data.setYHZH("-");
      data.setSFDW("-");
      String dq = Util.null2String(paras.get("dq"));
      data.setDQ(dq);
      // 摘要
      data.setZY(Util.null2String(paras.get("zy")));
      // 报销方式
      String bxfs = Util.null2String(paras.get("bxfs"));
      // 付款单号
      String fkdh = Util.null2String(paras.get("fkdh"));
      //是否全电子发票
      data.setSFQDZ(Util.null2String(paras.get("sfqdz")));
      //会计明细
      String kjmx = Util.null2String(paras.get("kjmx"));
      if (StringUtils.isNotBlank(kjmx)) {
        @SuppressWarnings("unchecked") List<AccountingDetail> accountingDetailList = JSON
            .parseArray(kjmx, AccountingDetail.class);
        if (CollectionUtils.isNotEmpty(accountingDetailList)) {
          for (AccountingDetail costShare : accountingDetailList) {
            InputData inputData = new InputData();
            BeanUtils.copyProperties(data, inputData);
            inputData.setFTBM(costShare.getExpenseDeptCode());// 分摊部门（名称）
            inputData.setFTBMMC(costShare.getExpenseDept());// 分摊部门（名称）
            inputData.setFTR(costShare.getExpenseBadge());// 分摊人(名称)
            inputData.setFTRYMC(costShare.getExpensePerson());// 分摊人(名称)
            inputData.setJZFX("1");
            inputData.setZFFS("-");
            // 华泰会计科目编号
            if (null != costShare.getSubjectData()) {
              inputData.setKJKM(costShare.getSubjectData().getItemCode());// 会计科目编号
              inputData.setZY(
                  costShare.getExpensePerson() + "报销" + costShare.getSubjectData().getItemName());
            } else {
              if (null != costShare.getYssuanData()) {
                inputData.setKJKM(costShare.getYssuanData().getRelationCode());
              }
            }
            if (null != costShare.getYssuanData()) {
              // 预算科目
              if (org.apache.commons.lang.StringUtils
                  .isNotEmpty(costShare.getYssuanData().getItemCode())) {
                inputData.setYSXMBH(costShare.getYssuanData().getItemCode());
                inputData.setYSXMMC(costShare.getYssuanData().getItemName());
              }
              inputData.setZY(
                  costShare.getExpensePerson() + "报销" + costShare.getYssuanData().getItemName());
            }
            if (org.apache.commons.lang.StringUtils.isNotEmpty(costShare.getPriceRMB())) {
              inputData.setJE(costShare.getPriceRMB());
            } else {
              inputData.setJE(costShare.getMoney());// 分摊金额
            }
            if (org.apache.commons.lang.StringUtils.isNotEmpty(costShare.getProjectCode())) {
              inputData.setFYXM(costShare.getProjectCode());
            } else {
              inputData.setFYXM("-");
            }
            if (org.apache.commons.lang.StringUtils.isNotEmpty(costShare.getProject())) {
              inputData.setFYXMMC(costShare.getProject());
            } else {
              inputData.setFYXMMC("-");
            }
            inputData.setSY(costShare.getReason() == null ? ""
                : costShare.getReason().replaceAll(" ", "").replaceAll("'", ""));
            rootData.getList().add(inputData);
          }
        }
      }
      //支付明细
      String zfmx = Util.null2String(paras.get("zfmx"));
      if (StringUtils.isNotBlank(zfmx)) {
        @SuppressWarnings("unchecked") List<PayDetail> payDetailList = JSON
            .parseArray(zfmx, PayDetail.class);
        if (CollectionUtils.isNotEmpty(payDetailList)) {
          for (PayDetail costShare : payDetailList) {
            // 银行支付
            if (StringUtils.isNotBlank(costShare.getPayByBank())) {
              double bankPay = Double.parseDouble(costShare.getPayByBank());
              if (bankPay > 0) {
                InputData inputData = new InputData();
                BeanUtils.copyProperties(data, inputData);
                // 分摊部门（名称）
                inputData.setFTBM("-");
                // 分摊人(名称)
                inputData.setFTR("-");
                inputData.setJZFX("2");
                inputData.setZFFS("1");
                inputData.setJE(costShare.getPayByBank());
                if (StringUtils.isNotBlank(costShare.getBankName())) {
                  inputData.setKHYH(costShare.getBankName() == null ? ""
                      : costShare.getBankName().replaceAll(" ", "").replaceAll("'", ""));
                }
                if (StringUtils.isNotBlank(costShare.getBankAccount())) {
                  inputData.setYHZH(costShare.getBankAccount() == null ? ""
                      : costShare.getBankAccount().replaceAll(" ", "").replaceAll("'", ""));
                }
                if (StringUtils.isNotBlank(bxfs) && "月结对公".equals(bxfs)) {
                  inputData.setZY("支付" + costShare.getEmployeeDept() + "报销费用");
                } else {
                  inputData.setZY("支付" + costShare.getEmployeeName() + "报销费用");
                }

                rootData.getList().add(inputData);
              }
            }
            // 现金支付
            if (StringUtils.isNotBlank(costShare.getPayByCash())) {
              double cashPay = Double.parseDouble(costShare.getPayByCash());
              if (cashPay > 0) {
                InputData inputData = new InputData();
                BeanUtils.copyProperties(data, inputData);
                inputData.setFTBM("-");// 分摊部门（名称）
                inputData.setFTR("-");// 分摊人(名称)
                inputData.setFYXM("-");
                inputData.setJZFX("2");
                inputData.setZFFS("2");
                inputData.setJE(costShare.getPayByCash());
                if (StringUtils.isNotBlank(costShare.getBankName())) {
                  inputData.setKHYH(costShare.getBankName());
                }
                if (StringUtils.isNotBlank(costShare.getBankAccount())) {
                  inputData.setYHZH(costShare.getBankAccount());
                }
                if (StringUtils.isNotBlank(bxfs) && "月结对公".equals(bxfs)) {
                  inputData.setZY("支付" + costShare.getEmployeeDept() + "报销费用");
                } else {
                  inputData.setZY("支付" + costShare.getEmployeeName() + "报销费用");
                }
                rootData.getList().add(inputData);
              }
            }
          }
        }
      }

      if (null != rootData.getList()) {
        for (int i = 0; i < rootData.getList().size(); i++) {
          InputData inputData = rootData.getList().get(i);
          inputData.setDJID(inputData.getDJID() + "#" + (i + 1));
        }
        return rootData;
      }
    } catch (Exception e) {
      log.error("联合差旅报销费用核算生成数据错误", e);
    }
    return rootData;


  }

  /**
   * 联合通用报销费用合计
   *
   * @param paras
   * @return
   */
  public RootData getLhptFydjRoot(Map<String, Object> paras) {
    RootData rootData = new RootData();
    try {
      InputData data = new InputData();
      data.setBXBM(Util.null2String(paras.get("bxbm")));
      data.setBXR(Util.null2String(paras.get("bxr")));
      data.setDJBH(Util.null2String(paras.get("bxbh")));
      data.setDJID(Util.null2String(paras.get("djid")));
      data.setDJLX(ReimburseType.PTFYBX);
      data.setDJRQ(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")));
      data.setDWBH("华泰联合");
      data.setFJZS(Util.null2String(paras.get("fjzs")));
      data.setKHYH("-");
      data.setYHZH("-");
      data.setSFDW("-");
      String dq = Util.null2String(paras.get("dq"));
      data.setDQ(dq);
      // 摘要
      data.setZY(Util.null2String(paras.get("zy")));
      // 报销方式
      String bxfs = Util.null2String(paras.get("bxfs"));
      // 付款单号
      String fkdh = Util.null2String(paras.get("fkdh"));
      //是否全电子发票
      data.setSFQDZ(Util.null2String(paras.get("sfqdz")));
      //会计明细
      String kjmx = Util.null2String(paras.get("kjmx"));
      if (StringUtils.isNotBlank(kjmx)) {
        @SuppressWarnings("unchecked") List<AccountingDetail> accountingDetailList = JSON
            .parseArray(kjmx, AccountingDetail.class);
        if (CollectionUtils.isNotEmpty(accountingDetailList)) {
          for (AccountingDetail costShare : accountingDetailList) {
            InputData inputData = new InputData();
            BeanUtils.copyProperties(data, inputData);
            inputData.setFTBM(costShare.getExpenseDeptCode());// 分摊部门（名称）
            inputData.setFTBMMC(costShare.getExpenseDept());// 分摊部门（名称）
            inputData.setFTR(costShare.getExpenseBadge());// 分摊人(名称)
            inputData.setFTRYMC(costShare.getExpensePerson());// 分摊人(名称)
            inputData.setJZFX("1");
            inputData.setZFFS("-");
            // 华泰会计科目编号
            if (null != costShare.getSubjectData()) {
              inputData.setKJKM(costShare.getSubjectData().getItemCode());// 会计科目编号
            } else {
              if (null != costShare.getYssuanData()) {
                inputData.setKJKM(costShare.getYssuanData().getRelationCode());
              }
            }
            String yskmmc="";
            if (null != costShare.getYssuanData()) {
              // 预算科目
              if (org.apache.commons.lang.StringUtils
                  .isNotEmpty(costShare.getYssuanData().getItemCode())) {
                inputData.setYSXMBH(costShare.getYssuanData().getItemCode());
                yskmmc=getLHYSKMMC(costShare.getYssuanData().getItemCode());
                inputData.setYSXMMC(yskmmc);
              }
            }
            if (org.apache.commons.lang.StringUtils.isNotEmpty(costShare.getPriceRMB())) {
              inputData.setJE(costShare.getPriceRMB());
            } else {
              inputData.setJE(costShare.getMoney());// 分摊金额
            }
            if (org.apache.commons.lang.StringUtils.isNotEmpty(costShare.getProjectCode())) {
              inputData.setFYXM(costShare.getProjectCode());
            } else {
              inputData.setFYXM("-");
            }
            if (org.apache.commons.lang.StringUtils.isNotEmpty(costShare.getProject())) {
              inputData.setFYXMMC(costShare.getProject());
            } else {
              inputData.setFYXMMC("-");
            }
            inputData.setSY(costShare.getReason() == null ? ""
                : costShare.getReason().replaceAll(" ", "").replaceAll("'", ""));
            inputData.setZY(
                costShare.getExpensePerson() + "报销" + yskmmc);
            rootData.getList().add(inputData);
          }
        }
      }
      //支付明细
      String zfmx = Util.null2String(paras.get("zfmx"));
      if (StringUtils.isNotBlank(zfmx)) {
        @SuppressWarnings("unchecked") List<PayDetail> payDetailList = JSON
            .parseArray(zfmx, PayDetail.class);
        if (CollectionUtils.isNotEmpty(payDetailList)) {
          for (PayDetail costShare : payDetailList) {
            // 银行支付
            if (StringUtils.isNotBlank(costShare.getPayByBank())) {
              double bankPay = Double.parseDouble(costShare.getPayByBank());
              if (bankPay > 0) {
                InputData inputData = new InputData();
                BeanUtils.copyProperties(data, inputData);
                // 分摊部门（名称）
                inputData.setFTBM("-");
                // 分摊人(名称)
                inputData.setFTR("-");
                inputData.setJZFX("2");
                inputData.setZFFS("1");
                inputData.setJE(costShare.getPayByBank());
                if (StringUtils.isNotBlank(costShare.getBankName())) {
                  inputData.setKHYH(costShare.getBankName() == null ? ""
                      : costShare.getBankName().replaceAll(" ", "").replaceAll("'", ""));
                }
                if (StringUtils.isNotBlank(costShare.getBankAccount())) {
                  inputData.setYHZH(costShare.getBankAccount() == null ? ""
                      : costShare.getBankAccount().replaceAll(" ", "").replaceAll("'", ""));
                }
                inputData.setZY("支付" + costShare.getEmployeeName() + "报销费用");
                rootData.getList().add(inputData);
              }
            }
            // 现金支付
            if (StringUtils.isNotBlank(costShare.getPayByCash())) {
              double cashPay = Double.parseDouble(costShare.getPayByCash());
              if (cashPay > 0) {
                InputData inputData = new InputData();
                BeanUtils.copyProperties(data, inputData);
                inputData.setFTBM("-");// 分摊部门（名称）
                inputData.setFTR("-");// 分摊人(名称)
                inputData.setFYXM("-");
                inputData.setJZFX("2");
                inputData.setZFFS("2");
                inputData.setJE(costShare.getPayByCash());
                if (StringUtils.isNotBlank(costShare.getBankName())) {
                  inputData.setKHYH(costShare.getBankName());
                }
                if (StringUtils.isNotBlank(costShare.getBankAccount())) {
                  inputData.setYHZH(costShare.getBankAccount());
                }
                inputData.setZY("支付" + costShare.getEmployeeName() + "报销费用");
                rootData.getList().add(inputData);
              }
            }
          }
        }
      }

      if (null != rootData.getList()) {
        for (int i = 0; i < rootData.getList().size(); i++) {
          InputData inputData = rootData.getList().get(i);
          inputData.setDJID(inputData.getDJID() + "#" + (i + 1));
        }
        return rootData;
      }
    } catch (Exception e) {
      log.error("联合通用报销费用核算生成数据错误", e);
    }
    return rootData;


  }

  public String getLHYSKMMC(String yskmbm) {
    List<String> list = new ArrayList<>();
    do {
      Pair<String, String> pair = getLHYSKM(yskmbm);
      if (Objects.isNull(pair) || "".equals(pair.getValue())) {
        break;
      }
      list.add(pair.getKey());
      yskmbm = pair.getValue();
    } while (true);
    //倒序 剔除第一个元素
    list = list.stream().skip(0).collect(Collectors.toList());
    Collections.reverse(list);
    return String.join("-", list);
  }

  public Pair<String,String> getLHYSKM(String yskmbm){
    RecordSet rs = new RecordSet();
    rs.executeQuery(
        "select yskmmc,sjyskm from uf_lhkmpz where yskmbm= ?",yskmbm);
    if (rs.next()) {
      String mc = Util.null2String(rs.getString("yskmmc"));
      String sjkm=Util.null2String(rs.getString("sjyskm"));
      return new Pair<>(mc,sjkm);
    }
    return null;
  }

  /**
   * 联合通用付款费用合计
   *
   * @param paras
   * @return
   */
  public RootData getLhfkFydjRoot(Map<String, Object> paras) {
    RootData rootData = new RootData();
    try {
      InputData data = new InputData();
      data.setBXBM(Util.null2String(paras.get("bxbm")));
      data.setBXR(Util.null2String(paras.get("bxr")));
      data.setDJBH(Util.null2String(paras.get("bxbh")));
      data.setDJID(Util.null2String(paras.get("djid")));
      data.setDJLX(ReimburseType.WSFKSP);
      data.setDJRQ(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")));
      data.setDWBH("华泰联合");
      data.setFJZS(Util.null2String(paras.get("fjzs")));
      data.setKHYH("-");
      data.setYHZH("-");
      data.setSFDW("-");
      String dq = Util.null2String(paras.get("dq"));
      data.setDQ(dq);
      // 摘要
      data.setZY(Util.null2String(paras.get("zy")));
      // 报销方式
      String bxfs = Util.null2String(paras.get("bxfs"));
      // 付款单号
      String fkdh = Util.null2String(paras.get("fkdh"));
      //是否全电子发票
      data.setSFQDZ(Util.null2String(paras.get("sfqdz")));
      //会计明细
      String kjmx = Util.null2String(paras.get("kjmx"));
      if (StringUtils.isNotBlank(kjmx)) {
        @SuppressWarnings("unchecked") List<AccountingDetail> accountingDetailList = JSON
            .parseArray(kjmx, AccountingDetail.class);
        if (CollectionUtils.isNotEmpty(accountingDetailList)) {
          for (AccountingDetail costShare : accountingDetailList) {
            InputData inputData = new InputData();
            BeanUtils.copyProperties(data, inputData);
            inputData.setFTBM(costShare.getExpenseDeptCode());// 分摊部门（名称）
            inputData.setFTBMMC(costShare.getExpenseDept());// 分摊部门（名称）
            inputData.setFTR("-");// 分摊人(名称)
            inputData.setFTRYMC("-");// 分摊人(名称)
            inputData.setJZFX("1");
            // 华泰会计科目编号
            if (null != costShare.getSubjectData()) {
              inputData.setKJKM(costShare.getSubjectData().getItemCode());// 会计科目编号
            } else {
              if (null != costShare.getYssuanData()) {
                inputData.setKJKM(costShare.getYssuanData().getRelationCode());
              }
            }
            if (null != costShare.getYssuanData()) {
              // 预算科目
              if (org.apache.commons.lang.StringUtils
                  .isNotEmpty(costShare.getYssuanData().getItemCode())) {
                inputData.setYSXMBH(costShare.getYssuanData().getItemCode());
                inputData.setYSXMMC(costShare.getYssuanData().getItemName());
              }
            }
            if (org.apache.commons.lang.StringUtils.isNotEmpty(costShare.getPriceRMB())) {
              inputData.setJE(costShare.getPriceRMB());
            } else {
              inputData.setJE(costShare.getMoney());// 分摊金额
            }
            if (org.apache.commons.lang.StringUtils.isNotEmpty(costShare.getProjectCode())) {
              inputData.setFYXM(costShare.getProjectCode());
            } else {
              inputData.setFYXM("-");
            }
            if (org.apache.commons.lang.StringUtils.isNotEmpty(costShare.getProject())) {
              inputData.setFYXMMC(costShare.getProject());
            } else {
              inputData.setFYXMMC("-");
            }
            inputData.setSY("-");
            rootData.getList().add(inputData);
          }
        }
      }
      //支付明细
      String zfmx = Util.null2String(paras.get("zfmx"));
      if (StringUtils.isNotBlank(zfmx)) {
        @SuppressWarnings("unchecked") List<PayDetail> payDetailList = JSON
            .parseArray(zfmx, PayDetail.class);
        if (CollectionUtils.isNotEmpty(payDetailList)) {
          for (PayDetail costShare : payDetailList) {
            // 银行支付
            if (StringUtils.isNotBlank(costShare.getPayByBank())) {
              double bankPay = Double.parseDouble(costShare.getPayByBank());
              if (bankPay > 0) {
                InputData inputData = new InputData();
                BeanUtils.copyProperties(data, inputData);
                // 分摊部门（名称）
                inputData.setFTBM("-");
                // 分摊人(名称)
                inputData.setFTR("-");
                inputData.setJZFX("2");
                inputData.setZFFS("1");
                inputData.setSFDW(costShare.getPayee());
                inputData.setJE(costShare.getPayByBank());
                if (StringUtils.isNotBlank(costShare.getBankName())) {
                  inputData.setKHYH(costShare.getBankName() == null ? ""
                      : costShare.getBankName().replaceAll(" ", "").replaceAll("'", ""));
                }
                if (StringUtils.isNotBlank(costShare.getBankAccount())) {
                  inputData.setYHZH(costShare.getBankAccount() == null ? ""
                      : costShare.getBankAccount().replaceAll(" ", "").replaceAll("'", ""));
                }
                rootData.getList().add(inputData);
              }
            }
            // 现金支付
            if (StringUtils.isNotBlank(costShare.getPayByCash())) {
              double cashPay = Double.parseDouble(costShare.getPayByCash());
              if (cashPay > 0) {
                InputData inputData = new InputData();
                BeanUtils.copyProperties(data, inputData);
                inputData.setFTBM("-");// 分摊部门（名称）
                inputData.setFTR("-");// 分摊人(名称)
                inputData.setFYXM("-");
                inputData.setJZFX("2");
                inputData.setZFFS("2");
                inputData.setSFDW(costShare.getPayee());
                inputData.setJE(costShare.getPayByCash());
                if (StringUtils.isNotBlank(costShare.getBankName())) {
                  inputData.setKHYH(costShare.getBankName());
                }
                if (StringUtils.isNotBlank(costShare.getBankAccount())) {
                  inputData.setYHZH(costShare.getBankAccount());
                }
                rootData.getList().add(inputData);
              }
            }
            // 支票支付
            if (StringUtils.isNotBlank(costShare.getPayByZhiPiao())) {
              double chequePay = Double.parseDouble(costShare.getPayByZhiPiao());
              if (chequePay > 0) {
                InputData inputData = new InputData();
                BeanUtils.copyProperties(data, inputData);
                inputData.setFTBM("-");// 分摊部门（名称）
                inputData.setFTR("-");// 分摊人(名称)
                inputData.setFYXM("-");
                inputData.setJZFX("2");
                inputData.setZFFS("3");
                inputData.setSFDW(costShare.getPayee());
                inputData.setJE(costShare.getPayByCash());
                if (StringUtils.isNotBlank(costShare.getBankName())) {
                  inputData.setKHYH(costShare.getBankName());
                }
                if (StringUtils.isNotBlank(costShare.getBankAccount())) {
                  inputData.setYHZH(costShare.getBankAccount());
                }
                rootData.getList().add(inputData);
              }
            }
          }
        }
      }

      if (null != rootData.getList()) {
        for (int i = 0; i < rootData.getList().size(); i++) {
          InputData inputData = rootData.getList().get(i);
          inputData.setDJID(inputData.getDJID() + "#" + (i + 1));
        }
        return rootData;
      }
    } catch (Exception e) {
      log.error("联合通用付款费用核算生成数据错误", e);
    }
    return rootData;


  }

  /**
   * 总部差旅报销费用合计
   *
   * @param paras
   * @return
   */
  public RootData getHtclFydjRoot(Map<String, Object> paras) {
    RootData rootData = new RootData();
    try {
      InputData data = new InputData();
      String bxbmbh = Util.null2String(paras.get("bxbmbh"));
      if (StringUtils.isBlank(bxbmbh)) {
        writeLog("bxbmbh is empty! bxbm:" + bxbmbh);
        return null;
      }
      int deptId = getDeptId(bxbmbh);
      if (deptId <= 0) {
        writeLog("deptId is empty! bxbmbh:" + bxbmbh);
        return null;
      }
      String deptTypeCode = getDeptTypeCode(String.valueOf(deptId));
      if (StringUtils.isBlank(deptTypeCode)) {
        writeLog("deptTypeCode is empty! bxbmbh:" + bxbmbh);
        return null;
      }
      data.setBXBM(Util.null2String(paras.get("bxbm")));
      data.setBXR(Util.null2String(paras.get("bxr")));
      data.setDJBH(Util.null2String(paras.get("bxbh")));
      // data.setDJID(Util.null2String(paras.get("djid")));
      String djid = Util.null2String(paras.get("djid"));
      data.setDJLX(ReimburseType.CLFYBX);
      data.setDJRQ(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")));
      data.setDWBH(bxbmbh);
      data.setFJZS(Util.null2String(paras.get("fjzs")));
      data.setKHYH("-");
      data.setYHZH("-");
      data.setSFDW("-");
      // 摘要
      data.setZY(Util.null2String(paras.get("zy")));
      // 币种
      String bz = Util.null2String(paras.get("bz"));
      // 拟稿日期
      String ngrq = Util.null2String(paras.get("ngrq"));
      //是否全电子发票
      data.setSFQDZ(Util.null2String(paras.get("sfqdz")));
      //会计明细
      String kjmx = Util.null2String(paras.get("kjmx"));
      data.setDJSL(Util.null2String(paras.get("djsl")));//单据数量
      data.setZZDJSL(Util.null2String(paras.get("zzdjsl")));//纸质单据数量
      int i = 0;
      if (StringUtils.isNotBlank(kjmx)) {
        @SuppressWarnings("unchecked") List<AccountingDetail> accountingDetailList = JSON
            .parseArray(kjmx, AccountingDetail.class);
        if (CollectionUtils.isNotEmpty(accountingDetailList)) {
          for (AccountingDetail costShare : accountingDetailList) {
            InputData inputData = new InputData();
            BeanUtils.copyProperties(data, inputData);
            //重设单据编号
            inputData.setDJID(String.format("%s#%s", djid, i++));
            inputData.setFTBM(costShare.getExpenseDeptCode());// 分摊部门（名称）
            inputData.setFTBMMC(costShare.getExpenseDept());// 分摊部门（名称）
            inputData.setFTR(costShare.getExpenseBadge());// 分摊人(名称)
            inputData.setFTRYMC(costShare.getExpensePerson());// 分摊人(名称)
            if ("JGLX10".equals(deptTypeCode) || "JGLX11".equals(deptTypeCode)) {
              inputData.setJZFX("D");
            } else {
              inputData.setJZFX("1");
            }
            inputData.setZFFS("-");
            // 华泰会计科目编号
            if (null != costShare.getSubjectData()) {
              inputData.setKJKM(costShare.getSubjectData().getItemCode());// 会计科目编号
            } else {
              if (null != costShare.getYssuanData()) {
                inputData.setKJKM(costShare.getYssuanData().getRelationCode());
              }
            }
            if (null != costShare.getYssuanData()) {
              // 预算科目
              if (StringUtils
                  .isNotEmpty(costShare.getYssuanData().getItemCode())) {
                inputData.setYSXMBH(costShare.getYssuanData().getItemCode());
                inputData.setYSXMMC(costShare.getYssuanData().getItemName());
              }
            }
            if (StringUtils.isNotEmpty(costShare.getPriceRMB())) {
              inputData.setJE(costShare.getPriceRMB());
            } else {
              inputData.setJE(costShare.getMoney());// 分摊金额
            }
            inputData.setSY(costShare.getReason());
            String rylx = getRylx(costShare.getExpenseBadge());
            inputData.setRYLX(rylx);
            rootData.getList().add(inputData);
          }
        }
      }
      //支付明细
      String zfmx = Util.null2String(paras.get("zfmx"));
      if (StringUtils.isNotBlank(zfmx)) {
        @SuppressWarnings("unchecked") List<PayDetail> payDetailList = JSON
            .parseArray(zfmx, PayDetail.class);
        if (CollectionUtils.isNotEmpty(payDetailList)) {
          for (PayDetail costShare : payDetailList) {
            // 银行支付
            if (StringUtils.isNotBlank(costShare.getPayByBank())) {
              double bankPay = Double.parseDouble(costShare.getPayByBank());
              if (bankPay > 0) {
                InputData inputData = new InputData();
                BeanUtils.copyProperties(data, inputData);
                //重设单据编号
                inputData.setDJID(String.format("%s#%s", djid, i++));
                // 分摊部门（名称）
                inputData.setFTBM("-");
                // 分摊人(名称)
                inputData.setFTR("-");
                if ("JGLX10".equals(deptTypeCode) || "JGLX11".equals(deptTypeCode)) {
                  inputData.setJZFX("C");
                } else {
                  inputData.setJZFX("2");
                }
                inputData.setZFFS("1");
                inputData.setJE(costShare.getPayByBank());
                if (StringUtils.isNotBlank(costShare.getBankName())) {
                  inputData.setKHYH(costShare.getBankName());
                }
                if (StringUtils.isNotBlank(costShare.getBankAccount())) {
                  inputData.setYHZH(costShare.getBankAccount());
                }
                String rylx = getRylx(costShare.getEmployeeBadge());
                inputData.setRYLX(rylx);
                rootData.getList().add(inputData);
              }
            }
            // 现金支付
            if (StringUtils.isNotBlank(costShare.getPayByCash())) {
              double cashPay = Double.parseDouble(costShare.getPayByCash());
              if (cashPay > 0) {
                InputData inputData = new InputData();
                BeanUtils.copyProperties(data, inputData);
                //重设单据编号
                inputData.setDJID(String.format("%s#%s", djid, i++));
                inputData.setFTBM("-");// 分摊部门（名称）
                inputData.setFTR("-");// 分摊人(名称)
                inputData.setFYXM("-");
                if ("JGLX10".equals(deptTypeCode) || "JGLX11".equals(deptTypeCode)) {
                  inputData.setJZFX("C");
                } else {
                  inputData.setJZFX("2");
                }
                inputData.setZFFS("2");
                inputData.setJE(costShare.getPayByCash());
                if (StringUtils.isNotBlank(costShare.getBankName())) {
                  inputData.setKHYH(costShare.getBankName());
                }
                if (StringUtils.isNotBlank(costShare.getBankAccount())) {
                  inputData.setYHZH(costShare.getBankAccount());
                }
                String rylx = getRylx(costShare.getEmployeeBadge());
                inputData.setRYLX(rylx);
                rootData.getList().add(inputData);
              }
            }
          }
        }
      }
    } catch (Exception e) {
      writeLog("总部差旅报销费用核算生成数据错误", e);
    }
    return rootData;
  }

  /**
   * 人员类型
   *
   * @param empCode
   * @return
   */
  private String getRylx(String empCode) {
    String rylx = "-";
    if (StringUtils.isEmpty(empCode)) {
      return rylx;
    }
    try {
      //获取当前员工的工作城市
      String workCity = getWorkCity(empCode);
      String deptCode = getDeptCodeByEmpCode(empCode);
      int deptId = DepartmentUtils.getDeptId(deptCode);
      String deptTypeCode = DepartmentUtils.getDeptTypeCode(deptId);
      String pzCityConfig = Util
          .null2String(new PropBean().getPropName(String.format("htclfydj_pz_%s", deptCode)));
      // 派驻城市
      List<String> pzCity = StringUtils.isBlank(pzCityConfig) ? null
          : Arrays.stream(pzCityConfig.split(",")).collect(Collectors.toList());

      boolean isSub = DepartmentUtils.isSub(deptCode);
      if (isSub) {
        rylx = "05";
      } else {
        if ("JGLX01".equals(deptTypeCode)) {
          if (!hasEmployee(empCode)) {
            rylx = "01";
          } else {
            // 2015-08-11 wh 新增 对非计划财务部之外的部门派驻
            if (null == pzCity) {
              String pzCityOtherConfig = Util
                  .null2String(new PropBean().getPropName("htclfydj_pz_other"));
              pzCity = StringUtils.isBlank(pzCityOtherConfig) ? null
                  : Arrays.stream(pzCityOtherConfig.split(",")).collect(Collectors.toList());
            }
            if (pzCity != null && pzCity.contains(workCity)
                && getPZDept().contains(deptCode)) {
              if ("上海市".equals(workCity)) {
                rylx = "02";
              } else if ("北京市".equals(workCity)) {
                rylx = "03";
              }
            } else {
              rylx = "01";
            }
          }
        } else if (deptTypeCode.equals("JGLX04") || deptTypeCode.equals("JGLX03") || deptTypeCode
            .equals("JGLX09")) {
          rylx = "04";
        }
      }
    } catch (Exception e) {
      log.error(e.getMessage(), e);
    }
    return rylx;
  }

  private String getDeptCodeByEmpCode(String empCode) {
    String deptCode = "";
    int deptId = 0;
    RecordSet rs = new RecordSet();
    rs.executeQuery(
        "select departmentid from hrmresource where workcode = ? and accounttype=0",
        empCode);
    while (rs.next()) {
      deptId = rs.getInt("departmentid");
    }
    if (deptId > 0) {
      deptCode = DepartmentUtils.getDeptCode(deptId);
    }
    return deptCode;
  }

  private boolean hasEmployee(String empCode) {
    RecordSet rs = new RecordSet();
    rs.executeQuery("select id from hrmresource where workcode = ?", empCode);
    return rs.next();
  }

  private String getWorkCity(String empCode) {
    String workCity = "";
    RecordSet rs = new RecordSet();
    rs.executeQuery(
        "select cfd.field0 from hrmresource hrm join cus_fielddata cfd on hrm.id=cfd.id where hrm.workcode = ?",
        empCode);
    while (rs.next()) {
      workCity = Util.null2String(rs.getString("field0"));
    }
    return workCity;
  }

  private List<String> getPZDept() {
    String emial = Util.null2String(new PropBean().getPropName("htclfydj_htpzdept"));
    if (StringUtils.isNotBlank(emial)) {
      return Arrays.stream(emial.split(",")).collect(Collectors.toList());
    }
    return Lists.newArrayList();
  }


  /**
   * 总部通用报销费用合计
   *
   * @param paras
   * @return
   */
  public RootData getHtptFydjRoot(Map<String, Object> paras) {
    RootData rootData = new RootData();
    try {
      InputData data = new InputData();
      String bxbmbh = Util.null2String(paras.get("bxbmbh"));
      if (StringUtils.isBlank(bxbmbh)) {
        writeLog("bxbmbh is empty! bxbm:" + bxbmbh);
        return null;
      }
      int deptId = getDeptId(bxbmbh);
      if (deptId <= 0) {
        writeLog("deptId is empty! bxbmbh:" + bxbmbh);
        return null;
      }
      String deptTypeCode = getDeptTypeCode(String.valueOf(deptId));
      if (StringUtils.isBlank(deptTypeCode)) {
        writeLog("deptTypeCode is empty! bxbmbh:" + bxbmbh);
        return null;
      }
      data.setBXBM(Util.null2String(paras.get("bxbm")));
      data.setBXR(Util.null2String(paras.get("bxr")));
      data.setDJBH(Util.null2String(paras.get("bxbh")));
      // data.setDJID(Util.null2String(paras.get("djid")));
      String djid = Util.null2String(paras.get("djid"));
      data.setDJLX(ReimburseType.PTFYBX);
      data.setDJRQ(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")));
      data.setDWBH(bxbmbh);
      data.setFJZS(Util.null2String(paras.get("fjzs")));
      data.setKHYH("-");
      data.setYHZH("-");
      data.setSFDW("-");
      // 摘要
      data.setZY(Util.null2String(paras.get("zy")));
      // 币种
      String bz = Util.null2String(paras.get("bz"));
      // 拟稿日期
      String ngrq = Util.null2String(paras.get("ngrq"));
      //是否全电子发票
      data.setSFQDZ(Util.null2String(paras.get("sfqdz")));
      //会计明细
      String kjmx = Util.null2String(paras.get("kjmx"));
      data.setDJSL(Util.null2String(paras.get("djsl")));//单据数量
      data.setZZDJSL(Util.null2String(paras.get("zzdjsl")));//纸质单据数量
      int i = 0;
      if (StringUtils.isNotBlank(kjmx)) {
        @SuppressWarnings("unchecked") List<AccountingDetail> accountingDetailList = JSON
            .parseArray(kjmx, AccountingDetail.class);
        if (CollectionUtils.isNotEmpty(accountingDetailList)) {
          for (AccountingDetail costShare : accountingDetailList) {
            InputData inputData = new InputData();
            BeanUtils.copyProperties(data, inputData);
            //重设单据编号
            inputData.setDJID(String.format("%s#%s", djid, i++));
            inputData.setFTBM(costShare.getExpenseDeptCode());// 分摊部门（名称）
            inputData.setFTBMMC(costShare.getExpenseDept());// 分摊部门（名称）
            inputData.setFTR(costShare.getExpenseBadge());// 分摊人(名称)
            inputData.setFTRYMC(costShare.getExpensePerson());// 分摊人(名称)
            if ("JGLX10".equals(deptTypeCode) || "JGLX11".equals(deptTypeCode)) {
              inputData.setJZFX("D");
              inputData.setVoucherdate(ngrq);
              inputData.setAccountperiod(
                  LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
              inputData.setCurrencycode(bz);
            } else {
              inputData.setJZFX("1");
            }
            inputData.setZFFS("-");
            // 华泰会计科目编号
            if (null != costShare.getSubjectData()) {
              inputData.setKJKM(costShare.getSubjectData().getItemCode());// 会计科目编号
            } else {
              if (null != costShare.getYssuanData()) {
                inputData.setKJKM(costShare.getYssuanData().getRelationCode());
              }
            }
            if (null != costShare.getYssuanData()) {
              // 预算科目
              if (StringUtils
                  .isNotEmpty(costShare.getYssuanData().getItemCode())) {
                inputData.setYSXMBH(costShare.getYssuanData().getItemCode());
                inputData.setYSXMMC(costShare.getYssuanData().getItemName());
              }
            }
            if (StringUtils.isNotEmpty(costShare.getPriceRMB())) {
              inputData.setJE(costShare.getPriceRMB());
            } else {
              inputData.setJE(costShare.getMoney());// 分摊金额
            }
            inputData.setSY(costShare.getReason());
            String rylx = getRylx(costShare.getExpenseBadge());
            inputData.setRYLX(rylx);
            rootData.getList().add(inputData);
          }
        }
      }
      //支付明细
      String zfmx = Util.null2String(paras.get("zfmx"));
      if (StringUtils.isNotBlank(zfmx)) {
        @SuppressWarnings("unchecked") List<PayDetail> payDetailList = JSON
            .parseArray(zfmx, PayDetail.class);
        if (CollectionUtils.isNotEmpty(payDetailList)) {
          for (PayDetail costShare : payDetailList) {
            // 银行支付
            if (StringUtils.isNotBlank(costShare.getPayByBank())) {
              double bankPay = Double.parseDouble(costShare.getPayByBank());
              if (bankPay > 0) {
                InputData inputData = new InputData();
                BeanUtils.copyProperties(data, inputData);
                //重设单据编号
                inputData.setDJID(String.format("%s#%s", djid, i++));
                // 分摊部门（名称）
                inputData.setFTBM("-");
                // 分摊人(名称)
                inputData.setFTR("-");
                if ("JGLX10".equals(deptTypeCode) || "JGLX11".equals(deptTypeCode)) {
                  inputData.setJZFX("C");
                  inputData.setVoucherdate(ngrq);
                  inputData.setAccountperiod(
                      LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
                  inputData.setCurrencycode(bz);
                } else {
                  inputData.setJZFX("2");
                }
                inputData.setZFFS("1");
                DecimalFormat df = new DecimalFormat("#.00");
                inputData.setJE(df.format(bankPay));
                if (StringUtils.isNotBlank(costShare.getBankName())) {
                  inputData.setKHYH(costShare.getBankName());
                }
                if (StringUtils.isNotBlank(costShare.getBankAccount())) {
                  inputData.setYHZH(costShare.getBankAccount());
                }
                String rylx = getRylx(costShare.getEmployeeBadge());
                inputData.setRYLX(rylx);
                rootData.getList().add(inputData);
              }
            }
            // 现金支付
            if (StringUtils.isNotBlank(costShare.getPayByCash())) {
              double cashPay = Double.parseDouble(costShare.getPayByCash());
              if (cashPay > 0) {
                InputData inputData = new InputData();
                BeanUtils.copyProperties(data, inputData);
                //重设单据编号
                inputData.setDJID(String.format("%s#%s", djid, i++));
                inputData.setFTBM("-");// 分摊部门（名称）
                inputData.setFTR("-");// 分摊人(名称)
                inputData.setFYXM("-");
                if ("JGLX10".equals(deptTypeCode) || "JGLX11".equals(deptTypeCode)) {
                  inputData.setJZFX("C");
                  inputData.setVoucherdate(ngrq);
                  inputData.setAccountperiod(
                      LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
                  inputData.setCurrencycode(bz);
                } else {
                  inputData.setJZFX("2");
                }
                inputData.setZFFS("2");
                DecimalFormat df = new DecimalFormat("#.00");
                inputData.setJE(df.format(cashPay));
                if (StringUtils.isNotBlank(costShare.getBankName())) {
                  inputData.setKHYH(costShare.getBankName());
                }
                if (StringUtils.isNotBlank(costShare.getBankAccount())) {
                  inputData.setYHZH(costShare.getBankAccount());
                }
                String rylx = getRylx(costShare.getEmployeeBadge());
                inputData.setRYLX(rylx);
                rootData.getList().add(inputData);
              }
            }
          }
        }
      }
    } catch (Exception e) {
      writeLog("总部通用报销费用核算生成数据错误", e);
    }
    return rootData;
  }

  /**
   * 总部付款费用合计
   *
   * @param paras
   * @return
   */
  public RootData getHtfkFydjRoot(Map<String, Object> paras) {
    RootData rootData = new RootData();
    try {
      InputData data = new InputData();
      String bxbmbh = Util.null2String(paras.get("bxbmbh"));
      if (StringUtils.isBlank(bxbmbh)) {
        writeLog("bxbmbh is empty! bxbm:" + bxbmbh);
        return null;
      }
      int deptId = getDeptId(bxbmbh);
      if (deptId <= 0) {
        writeLog("deptId is empty! bxbmbh:" + bxbmbh);
        return null;
      }
      String deptTypeCode = getDeptTypeCode(String.valueOf(deptId));
      if (StringUtils.isBlank(deptTypeCode)) {
        writeLog("deptTypeCode is empty! bxbmbh:" + bxbmbh);
        return null;
      }
      data.setBXBM(Util.null2String(paras.get("bxbm")));
      data.setBXR(Util.null2String(paras.get("bxr")));
      data.setDJBH(Util.null2String(paras.get("bxbh")));
      // data.setDJID(Util.null2String(paras.get("djid")));
      String djid = Util.null2String(paras.get("djid"));
      data.setDJLX(ReimburseType.WSFKSP);
      data.setDJRQ(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")));
      //华泰资管虚拟部门，用于人力资源部发起资管付款
      //org.HRinZG=HRinZG001
      String zgxnbm = Util.null2String(new PropBean().getPropName("htfkfydj_zgxnbm"));
      if (bxbmbh.equals(zgxnbm)) {
        //资产管理总部
        //org.zgdeptcode=ZZ001013
        String zcglzb = Util.null2String(new PropBean().getPropName("htfkfydj_zcglzb"));
        data.setDWBH(zcglzb);
      } else {
        data.setDWBH(bxbmbh);
      }
      data.setFJZS(Util.null2String(paras.get("fjzs")));
      data.setKHYH("-");
      data.setYHZH("-");
      data.setSFDW("-");
      String dq = Util.null2String(paras.get("dq"));
      data.setDQ(dq);
      // 摘要
      data.setZY(Util.null2String(paras.get("zy")));
      // 报销方式
      String bxfs = Util.null2String(paras.get("bxfs"));
      // 付款单号
      String fkdh = Util.null2String(paras.get("fkdh"));
      // 币种
      String bz = Util.null2String(paras.get("bz"));
      // 拟稿日期
      String ngrq = Util.null2String(paras.get("ngrq"));
      // BH1
      data.setBH1(Util.null2String(paras.get("bh1")));
      // BZ1
      data.setBZ1(Util.null2String(paras.get("bz1")));
      // BZ2
      data.setBZ2(Util.null2String(paras.get("bz2")));
      //是否全电子发票
      data.setSFQDZ(Util.null2String(paras.get("sfqdz")));
      //是否先付款后发票
      data.setDJSL(Util.null2String(paras.get("djsl")));//单据数量
      data.setZZDJSL(Util.null2String(paras.get("zzdjsl")));//纸质单据数量
      data.setSFYFP(Util.null2String(paras.get("sFYFP")));
      //会计明细
      String kjmx = Util.null2String(paras.get("kjmx"));
      int i = 0;
      if (StringUtils.isNotBlank(kjmx)) {
        @SuppressWarnings("unchecked") List<AccountingDetail> accountingDetailList = JSON
            .parseArray(kjmx, AccountingDetail.class);
        if (CollectionUtils.isNotEmpty(accountingDetailList)) {
          for (AccountingDetail costShare : accountingDetailList) {
            InputData inputData = new InputData();
            BeanUtils.copyProperties(data, inputData);
            //重设单据编号
            inputData.setDJID(String.format("%s#%s", djid, i++));
            //分摊部门（编号）
            inputData.setFTBM(costShare.getExpenseDeptCode());
            //分摊部门（名称）
            inputData.setFTBMMC(costShare.getExpenseDept());
            //分摊人(名称)
            inputData.setFTR("-");
            //分摊人(名称)
            inputData.setFTRYMC("-");
            //部门类型编码 为 JGLX10或JGLX11 (等同于company==10)
            if ("JGLX10".equals(deptTypeCode) || "JGLX11".equals(deptTypeCode)) {
              inputData.setJZFX("D");
              inputData.setVoucherdate(ngrq);
              inputData.setAccountperiod(
                  LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
              inputData.setCurrencycode(bz);
            } else {
              inputData.setJZFX("1");
            }
            inputData.setZFFS("-");
            //华泰会计科目编号
            if (null != costShare.getSubjectData()) {
              //会计科目编号
              inputData.setKJKM(costShare.getSubjectData().getItemCode());
            } else {
              if (null != costShare.getYssuanData()) {
                inputData.setKJKM(costShare.getYssuanData().getRelationCode());
              }
            }
            if (null != costShare.getYssuanData()) {
              //预算科目
              if (StringUtils.isNotBlank(costShare.getYssuanData().getItemCode())) {
                inputData.setYSXMBH(costShare.getYssuanData().getItemCode());
                inputData.setYSXMMC(costShare.getYssuanData().getItemName());
              }
            }
            if (StringUtils.isNotBlank(costShare.getPriceRMB())) {
              inputData.setJE(costShare.getPriceRMB());
            } else {
              //分摊金额
              inputData.setJE(costShare.getMoney());
            }
            inputData.setSY(costShare.getReason());
            rootData.getList().add(inputData);
          }
        }
      }
      //支付明细
      String zfmx = Util.null2String(paras.get("zfmx"));
      if (StringUtils.isNotBlank(zfmx)) {
        @SuppressWarnings("unchecked") List<PayDetail> payDetailList = JSON
            .parseArray(zfmx, PayDetail.class);
        if (CollectionUtils.isNotEmpty(payDetailList)) {
          for (PayDetail costShare : payDetailList) {
            // 银行支付
            if (StringUtils.isNotBlank(costShare.getPayByBank())) {
              double bankPay = Double.parseDouble(costShare.getPayByBank());
              if (bankPay > 0) {
                InputData inputData = new InputData();
                BeanUtils.copyProperties(data, inputData);
                //重设单据编号
                inputData.setDJID(String.format("%s#%s", djid, i++));
                // 分摊部门（名称）
                inputData.setFTBM("-");
                // 分摊人(名称)
                inputData.setFTR("-");
                if ("JGLX10".equals(deptTypeCode) || "JGLX11".equals(deptTypeCode)) {
                  inputData.setJZFX("C");
                  inputData.setVoucherdate(ngrq);
                  inputData.setAccountperiod(
                      LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
                  inputData.setCurrencycode(bz);
                } else {
                  inputData.setJZFX("2");
                }
                inputData.setZFFS("1");
                inputData.setSFDW(costShare.getPayee());
                inputData.setJE(costShare.getPayByBank());
                if (StringUtils.isNotBlank(costShare.getBankName())) {
                  inputData.setKHYH(costShare.getBankName());
                }
                if (StringUtils.isNotBlank(costShare.getBankAccount())) {
                  inputData.setYHZH(costShare.getBankAccount());
                }
                rootData.getList().add(inputData);
              }
            }
            //现金支付
            if (StringUtils.isNotBlank(costShare.getPayByCash())) {
              double cashPay = Double.parseDouble(costShare.getPayByCash());
              if (cashPay > 0) {
                InputData inputData = new InputData();
                BeanUtils.copyProperties(data, inputData);
                //重设单据编号
                inputData.setDJID(String.format("%s#%s", djid, i++));
                // 分摊部门（名称）
                inputData.setFTBM("-");
                // 分摊人(名称)
                inputData.setFTR("-");
                inputData.setFYXM("-");
                if ("JGLX10".equals(deptTypeCode) || "JGLX11".equals(deptTypeCode)) {
                  inputData.setJZFX("C");
                  inputData.setVoucherdate(ngrq);
                  inputData.setAccountperiod(
                      LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
                  inputData.setCurrencycode(bz);
                } else {
                  inputData.setJZFX("2");
                }
                inputData.setZFFS("2");
                inputData.setSFDW(costShare.getPayee());
                inputData.setJE(costShare.getPayByCash());
                if (StringUtils.isNotBlank(costShare.getBankName())) {
                  inputData.setKHYH(costShare.getBankName());
                }
                if (StringUtils.isNotBlank(costShare.getBankAccount())) {
                  inputData.setYHZH(costShare.getBankAccount());
                }
                rootData.getList().add(inputData);
              }
            }
            //支票支付
            if (StringUtils.isNotBlank(costShare.getPayByZhiPiao())) {
              double zhiPiao = Double.parseDouble(costShare.getPayByZhiPiao());
              if (zhiPiao > 0) {
                InputData inputData = new InputData();
                BeanUtils.copyProperties(data, inputData);
                //重设单据编号
                inputData.setDJID(String.format("%s#%s", djid, i++));
                // 分摊部门（名称）
                inputData.setFTBM("-");
                // 分摊人(名称)
                inputData.setFTR("-");
                inputData.setFYXM("-");
                if ("JGLX10".equals(deptTypeCode) || "JGLX11".equals(deptTypeCode)) {
                  inputData.setJZFX("C");
                  inputData.setVoucherdate(ngrq);
                  inputData.setAccountperiod(
                      LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
                  inputData.setCurrencycode(bz);
                } else {
                  inputData.setJZFX("2");
                }
                inputData.setZFFS("3");
                inputData.setSFDW(costShare.getPayee());
                inputData.setJE(costShare.getPayByZhiPiao());
                if (StringUtils.isNotBlank(costShare.getBankName())) {
                  inputData.setKHYH(costShare.getBankName());
                }
                if (StringUtils.isNotBlank(costShare.getBankAccount())) {
                  inputData.setYHZH(costShare.getBankAccount());
                }
                rootData.getList().add(inputData);
              }
            }
          }
        }
      }
      return rootData;
    } catch (Exception e) {
      log.error("总部付款费用核算生成数据错误：", e);
    }
    return rootData;


  }

  /**
   * 根据部门编号获取泛微部门ID
   *
   * @param deptCode
   * @return
   */
  private int getDeptId(String deptCode) {
    int id = 0;
    String sql = String.format("select id from %s where departmentcode=?", "hrmdepartment");
    RecordSet rs = new RecordSet();
    rs.executeQuery(sql, deptCode);
    while (rs.next()) {
      id = rs.getInt("id");
      break;
    }
    return id;
  }

  private String getDeptTypeCode(String deptId) {
    String code = "";
    String sql = String
        .format("select depttypecode from %s where deptid=?", "hrmdepartmentdefined");
    RecordSet rs = new RecordSet();
    rs.executeQuery(sql, deptId);
    while (rs.next()) {
      code = rs.getString("depttypecode");
      break;
    }
    return code;
  }

  /**
   * 日期list排序
   *
   * @param dateList 日期list
   * @param order    true 为 正序 ，false 为 倒序
   * @return true正序取日期最大值，false倒序取日期最小值
   */
  public String sortDateList(List<String> dateList, boolean order) {
    List<String> collect = dateList.stream().filter(StringUtils::isNotBlank).sorted()
        .collect(Collectors.toList());
    System.out.println("collect = " + collect);
    if (!order) {
      return collect.get(0);
    } else {
      return collect.get(collect.size() - 1);
    }
  }

  /**
   * 添加投行项目/crm客户code或名称
   *
   * @return
   */
  public Map<String, Object> getProjOrCrmInfoForSaveJourney(String reqId) {
    Map<String, Object> req = new HashMap<>();
    try {
      String ccsq = UnNumber.CCSQ.getUnNumber();
      String main = PayUtil.getTableNameByUnNumber(ccsq);
      String sql =
          "select NGRGH,CUSTNAME,XMJC,TXXMBM,TXXMJC,KHMC,KHBM from " + main + " where REQUESTID=" +
              reqId;
      RecordSet rs = new RecordSet();
      rs.executeQuery(sql);
      if (rs.next()) {
        req.put("projectCode", Util.null2String(rs.getString("TXXMBM")));//投行项目code
        req.put("projectName", Util.null2String(rs.getString("TXXMJC")));//投行项目名称
        req.put("crmCode", Util.null2String(rs.getString("KHBM")));//crm code
        req.put("crmName", Util.null2String(rs.getString("KHMC")));//crm名称
      }
    } catch (Exception e) {
      req.put("projectCode", "");//投行项目code
      req.put("projectName", "");//投行项目名称
      req.put("crmCode", "");//crm code
      req.put("crmName", "");//crm名称
    }
    return req;

  }

  //差补详情queryAllowanceDetail
  public String getAllowanceCollectDetail(Map<String, Object> params) {
    String result = "";
    try {
      if (params == null) {
        log.warn("input parmas null!");
        return result;
      }

      String token = getToken((String) params.get("ngr"));
      if ("".equals(token)) {
        log.warn("get access token failed!");
        return result;
      }
      Map<String, String> headers = new HashMap<>();
      headers.put("JTXT-AUTH-TOKEN", token);
      headers.put("JTXT-AUTH-TYPE", "USER");
      //http://168.61.69.225:8080/jtxt/ctrip/allowance/search/queryAllowanceDetail
      String getAllowanceCollectDetailUrl = Util
          .null2String(new PropBean().getPropName("rest.payment_chaibuxiangqing"));
      String reqStr = JSON.toJSONString(params);
      log.info("=======HTUtil>>>方法======getAllowanceCollectDetail=======");
      log.info("=======查询差补详情=======");
      log.info("=======查询差补详情请求：" + reqStr + "=======");
      String res = Util
          .null2String(httpPostRaw(getAllowanceCollectDetailUrl, reqStr, headers, null));
      if ("1".equals(Util.null2String(new PropBean().getPropName("show.debug.log")))) {
        log.info("=======查询差补详情返回：" + res + "=======");
        ;
      }
      if (StringUtils.isNotBlank(res)) {
        result = res;
      } else {
        log.info("HTUtil.getAllowanceCollectDetail,查询返回结果为空--->" + res);
      }
    } catch (Exception e) {
      log.warn("HTUtil.getAllowanceCollectDetail failed! errorMessage:", e);
    }
    return result;
  }

  //对比queryResult
  public String getCompareResults(Map<String, Object> params) {
    String result = "";
    try {
      if (params == null) {
        log.warn("input parmas null!");
        return result;
      }

      String token = getToken((String) params.get("ngr"));
      if ("".equals(token)) {
        log.warn("get access token failed!");
        return result;
      }
      Map<String, String> headers = new HashMap<>();
      headers.put("JTXT-AUTH-TOKEN", token);
      headers.put("JTXT-AUTH-TYPE", "USER");

      String getAllowanceCollectDetailUrl = Util.null2String(new PropBean().getPropName("rest.payment_duibi"));
      String reqStr = JSON.toJSONString(params);
      log.info("=======HTUtil>>>方法======getCompareResults=======");
      log.info("=======查询对比详情=======");
      log.info("=======查询对比详情请求：" + reqStr + "=======");
      String res = Util
          .null2String(httpPostRaw(getAllowanceCollectDetailUrl, reqStr, headers, null));
      if ("1".equals(Util.null2String(new PropBean().getPropName("show.debug.log")))) {
        log.info("=======查询差补详情返回：" + res + "=======");
        ;
      }
      if (StringUtils.isNotBlank(res)) {
        result = res;
      } else {
        log.info("HTUtil.getCompareResults,查询返回结果为空--->" + res);
      }
    } catch (Exception e) {
      log.warn("HTUtil.getCompareResults failed! errorMessage:", e);
    }
    return result;
  }

  //快照汇总querySnapshotInfo
  public String getOrderSnapshotInfo(Map<String, Object> params) {
    String result = "";
    try {
      if (params == null) {
        log.warn("input parmas null!");
        return result;
      }

      String token = getToken((String) params.get("ngr"));
      if ("".equals(token)) {
        log.warn("get access token failed!");
        return result;
      }
      Map<String, String> headers = new HashMap<>();
      headers.put("JTXT-AUTH-TOKEN", token);
      headers.put("JTXT-AUTH-TYPE", "USER");

      String getAllowanceCollectDetailUrl = Util.null2String(new PropBean().getPropName("rest.payment_huizong"));
      String reqStr = JSON.toJSONString(params);
      log.info("=======HTUtil>>>方法======getOrderSnapshotInfo=======");
      log.info("=======查询订单快照汇总=======");
      log.info("=======查询订单快照请求：" + reqStr + "=======");
      String res = Util
          .null2String(httpPostRaw(getAllowanceCollectDetailUrl, reqStr, headers, null));
      if ("1".equals(Util.null2String(new PropBean().getPropName("show.debug.log")))) {
        log.info("=======查询订单快照返回：" + res + "=======");
        ;
      }
      if (StringUtils.isNotBlank(res)) {
        result = res;
      } else {
        log.info("HTUtil.getOrderSnapshotInfo,查询返回结果为空--->" + res);
      }
    } catch (Exception e) {
      log.warn("HTUtil.getOrderSnapshotInfo failed! errorMessage:", e);
    }
    return result;
  }

  //快照详情query
  public String queryOrderSnapshotDetails(Map<String, Object> params) {
    String result = "";
    try {
      if (params == null) {
        log.warn("input parmas null!");
        return result;
      }

      String token = getToken((String) params.get("ngr"));
      if ("".equals(token)) {
        log.warn("get access token failed!");
        return result;
      }
      Map<String, String> headers = new HashMap<>();
      headers.put("JTXT-AUTH-TOKEN", token);
      headers.put("JTXT-AUTH-TYPE", "USER");

      String getAllowanceCollectDetailUrl = Util.null2String(new PropBean().getPropName("rest.payment_xiangqing"));
      String reqStr = JSON.toJSONString(params);
      log.info("=======HTUtil>>>方法======queryOrderSnapshotDetails=======");
      log.info("=======查询订单明细快照=======");
      log.info("=======查询订单明细快照请求：" + reqStr + "=======");
      String res = Util
          .null2String(httpPostRaw(getAllowanceCollectDetailUrl, reqStr, headers, null));
      if ("1".equals(Util.null2String(new PropBean().getPropName("show.debug.log")))) {
        log.info("=======查询订单明细快照返回：" + res + "=======");
        ;
      }
      if (StringUtils.isNotBlank(res)) {
        result = res;
      } else {
        log.info("HTUtil.queryOrderSnapshotDetails,查询返回结果为空--->" + res);
      }
    } catch (Exception e) {
      log.warn("HTUtil.queryOrderSnapshotDetails failed! errorMessage:", e);
    }
    return result;
  }

  //差补queryAllowanceInfo
  public String getTravelAllowanceCollectInformation(Map<String, Object> params) {
    String result = "";
    try {
      if (params == null) {
        log.warn("input parmas null!");
        return result;
      }

      String token = getToken((String) params.get("ngr"));
      if ("".equals(token)) {
        log.warn("get access token failed!");
        return result;
      }
      Map<String, String> headers = new HashMap<>();
      headers.put("JTXT-AUTH-TOKEN", token);
      headers.put("JTXT-AUTH-TYPE", "USER");

      String getAllowanceCollectDetailUrl = Util.null2String(new PropBean().getPropName("rest.payment_chaibu"));
      String reqStr = JSON.toJSONString(params);
      log.info("=======HTUtil>>>方法======getTravelAllowanceCollectInformation=======");
      log.info("=======查询差补汇总=======");
      log.info("=======查询差补汇总请求：" + reqStr + "=======");
      String res = Util
          .null2String(httpPostRaw(getAllowanceCollectDetailUrl, reqStr, headers, null));
      if ("1".equals(Util.null2String(new PropBean().getPropName("show.debug.log")))) {
        log.info("=======查询差补汇总返回：" + res + "=======");
      }
      if (StringUtils.isNotBlank(res)) {
        result = res;
      } else {
        log.info("HTUtil.getTravelAllowanceCollectInformation,查询返回结果为空--->" + res);
      }
    } catch (Exception e) {
      log.warn("HTUtil.getTravelAllowanceCollectInformation failed! errorMessage:", e);
    }
    return result;
  }

  //对接投行云平台获取投行项目新接口，新接口支持模糊搜索+分页
  public String getProjectByPage(Map<String, Object> paras) {
    String response = "";
    try {
      String projectUrl = Util.null2String(new PropBean().getPropName("projectUrl"));
      String projectIp = Util.null2String(new PropBean().getPropName("projectIp"));
      String projectService = Util.null2String(new PropBean().getPropName("projectService"));
      String projectKey = Util.null2String(new PropBean().getPropName("projectKey"));
      String projectName = Util.null2String(new PropBean().getPropName("projectName"));
      String userId = Util.null2String(paras.get("userId"));
      String shortName = Util.null2String(paras.get("shortName"));
      int pageSize = Integer.parseInt(Util.null2String(paras.get("pageSize")));
      int pageNum = Integer.parseInt(Util.null2String(paras.get("pageNum")));
      String platformName = projectName;
      String secretKey = MD5.md5(projectKey).toUpperCase();
      String endpoint = projectIp + projectUrl;
      Service service = new Service();
      Call call = (Call) service.createCall();
      //返回结构及其子目录都需要配置序列化 反序列化 声明
      call.registerTypeMapping(PageData.class, new QName(projectService, "PageData"),
          new BeanSerializerFactory(PageData.class, new QName(projectService, "PageData")),
          new BeanDeserializerFactory(PageData.class, new QName(projectService, "PageData")));
      call.registerTypeMapping(ProjectInfoSafety.class,
          new QName(projectService, "ProjectInfoSafety"),
          new BeanSerializerFactory(ProjectInfoSafety.class,
              new QName(projectService, "ProjectInfoSafety")),
          new BeanDeserializerFactory(ProjectInfoSafety.class,
              new QName(projectService, "ProjectInfoSafety")));
      call.setTargetEndpointAddress(endpoint);
      call.setOperationName(new QName(projectService, "findProjectByIdAndShortNameSafety"));
      call.addParameter("userId", Constants.XSD_STRING, ParameterMode.IN);
      call.addParameter("shortName", Constants.XSD_STRING, ParameterMode.IN);
      call.addParameter("pageSize", Constants.XSD_INT, ParameterMode.IN);
      call.addParameter("pageNum", Constants.XSD_INT, ParameterMode.IN);
      call.addParameter("md5key", Constants.XSD_STRING, ParameterMode.IN);
      call.addParameter("platformName", Constants.XSD_STRING, ParameterMode.IN);
      call.setReturnType(new QName(projectService, "pageData"));
      writeLog("get project by page request:" + String.format(
          "userId=%s, md5key=%s, platformName=%s ,shortName = %s ,pageSize = %s , pageNum = %s",
          userId, secretKey, platformName, shortName, pageSize, pageNum));
      PageData bean = (PageData) call
          .invoke(new Object[]{userId, shortName, pageSize, pageNum, secretKey, platformName});
      response = JSONArray.toJSONString(bean);
      if ("1".equals(Util.null2String(new PropBean().getPropName("show.debug.log")))) {
        writeLog("get project by page response:" + response);
      }
      return response;
    } catch (Exception e) {
      writeLog("get project by page error", e);
    }
    return response;
  }

  public Map<String, Object> getProjectInfoByCode(String userCode, String projectCode) {
    Map<String, Object> result = new HashMap<>();
    Map<String, Object> params = new HashMap<>();
    params.put("userId", userCode);
    int pageSize = 10;
    params.put("pageSize", pageSize + "");
    params.put("pageNum", "1");
    boolean flag = true;
    do {
      String projectByPage = getProjectByPage(params);
      if (StringUtils.isNotBlank(projectByPage)) {
        JSONObject jsonObject = JSONObject.parseObject(projectByPage);
        if (Objects.nonNull(jsonObject)) {
          JSONArray dataArray = jsonObject.getJSONArray("data");
          if (Objects.nonNull(dataArray) && dataArray.size() > 0) {
            //处理数据
            for (int i = 0; i < dataArray.size(); i++) {
              JSONObject dataObject = dataArray.getJSONObject(i);
              String code = dataObject.getString("code");
              if (projectCode.equals(code)) {
                result.put("code", code);
                result.put("id", dataObject.getString("id"));
                result.put("name", dataObject.getString("shortName"));
                result.put("deptCode", dataObject.getString("promiseDeptId"));
                result.put("deptName", dataObject.getString("promiseDeptName"));
                flag = false;
                break;
              }
            }
            if (dataArray.size() < pageSize) {
              flag = false;
            }
          } else {
            flag = false;
          }
        } else {
          flag = false;
        }
      } else {
        flag = false;
      }
      params.put("pageNum", String.valueOf(Integer.parseInt(Util.null2String(params.get("pageNum"))) + 1));
    } while (flag);

    return result;
  }

  public Map<String, Object> getProjectInfoById(String userCode, String projectId) {
    Map<String, Object> result = new HashMap<>();
    Map<String, Object> params = new HashMap<>();
    params.put("projectId", projectId);
//    int pageSize = 10;
//    params.put("pageSize", pageSize + "");
//    params.put("pageNum", "1");
    boolean flag = true;
//    try {
//      String projectByPage = getProjectByPage(params);
      String projectByPage = getProjectById(params);
      if (StringUtils.isNotBlank(projectByPage)) {
        JSONObject jsonObject = JSONObject.parseObject(projectByPage);
        if (Objects.nonNull(jsonObject)) {
//          JSONArray dataArray = jsonObject.getJSONArray("data");
//          if (Objects.nonNull(dataArray) && dataArray.size() > 0) {
//            处理数据
//            for (int i = 0; i < dataArray.size(); i++) {
//              JSONObject dataObject = dataArray.getJSONObject(i);
              String id = jsonObject.getString("id");
              if (projectId.equals(id)) {
                result.put("code", jsonObject.getString("code"));
                result.put("id", id);
                result.put("name", jsonObject.getString("shortName"));
                result.put("deptCode", jsonObject.getString("promiseDeptId"));
                result.put("deptName", jsonObject.getString("promiseDeptName"));
//                flag = false;
//                break;
              }
//            }
//            if (dataArray.size() < pageSize) {
//              flag = false;
            }
//          } else {
//            flag = false;
          }
//        } else {
//          flag = false;
//        }
//      } else {
//        flag = false;
//      }
//      params.put("pageNum", String.valueOf(Integer.parseInt(Util.null2String(params.get("pageNum"))) + 1));
//    } while (flag);

    return result;
  }

  public String sendLinkMsg(String content, List<String> userCodeList){
    Map<String, Object> request = new HashMap<>();
    String baseUrl = Util.null2String(new PropBean().getPropName("jtxt.base.url"));
    String msgUrl = "/app/Msg/sendText";
    String token = getAppToken();
    if ("".equals(token)) {
      return "fail";
    }
    Map<String, String> headers = new HashMap<>();
    headers.put("JTXT-AUTH-TOKEN", token);
    headers.put("JTXT-AUTH-TYPE", "APP");
    request.put("content", content);
    request.put("userCodeList", userCodeList);
    try {
      String res = Util.null2String(httpPostRaw(baseUrl + msgUrl, JSONObject.toJSONString(request), headers, null));
      if (StringUtils.isNotBlank(res)) {
        return res;
      } else {
        log.info("HTUtil.sendLinkMsg,返回结果为空--->" + res);
        return "fail";
      }
    }catch (Exception e){
      log.info("HTUtil.sendLinkMsg,执行失败--->" + e);
      return "fail";
    }
  }

}
