package com.engine.htsc.payment.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.api.htsc.businessMethod.SubUnionBizUtil;
import com.engine.core.impl.Service;
import com.engine.htsc.payment.dao.BudgetDao;
import com.engine.htsc.payment.dao.PaymentDao;
import com.engine.htsc.payment.enums.DataSourceName;
import com.engine.htsc.payment.enums.Sequences;
import com.engine.htsc.payment.pojo.*;
import com.engine.htsc.payment.service.BudgetCommand;
import com.engine.htsc.payment.service.BudgetService;
import com.engine.htsc.payment.service.PaymentService;
import com.engine.htsc.payment.util.*;
import com.engine.htsc.trip.util.WeaverUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import weaver.conn.RecordSet;
import weaver.conn.RecordSetTrans;
import weaver.formmode.setup.ModeRightInfo;
import weaver.formmode.virtualform.VirtualFormHandler;
import weaver.general.BaseBean;
import weaver.general.Util;
import weaver.hrm.company.DepartmentComInfo;
import weaver.hrm.resource.ResourceComInfo;
import weaver.interfaces.htsc.comInfo.PropBean;
import weaver.interfaces.htsc.cus.HTUtil;
import weaver.workflow.workflow.WorkflowBillComInfo;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class PaymentServiceImpl extends Service implements PaymentService {

  private final Log log = LogFactory.getLog(PaymentServiceImpl.class);

  private final PaymentDao pd = new PaymentDao();

  @Override
  public String checkRequestMark(String lcbh,
                              String type, String unNumber) throws Exception {
    int count = 1;
    RecordSet rs = new RecordSet();
    String tableName = PayUtil.getTableNameByUnNumber(unNumber);

    rs.writeLog(String.format("checkRequestMark, unNumber:%s; lcbh:%s", unNumber, lcbh));
    rs.executeQuery("SELECT COUNT(*) as n FROM "+tableName+" fm WHERE fm.lcbh = ?", lcbh);
    if (rs.next()) {
      count = rs.getInt("n");
    }
    if (count > 1) {
      Sequences sequences = null;
      if ("0".equals(type)) {
        sequences = Sequences.NET_REI_WORKFLOW_SEQ_ZB;
      } else if ("1".equals(type)) {
        sequences = Sequences.NET_REI_WORKFLOW_SEQ_FZ;
      } else if ("2".equals(type)) {
        sequences = Sequences.NET_REI_WORKFLOW_SEQ_ZGS;
      } else {
        throw new Exception("流程类型没有匹配");
      }
      return CoWfUtil.getRequestMarkByUnNumber(unNumber, sequences);

    }
    return "";
  }

  @Override
  public Map<String, String> controlBudget(BudgetReqDto bgRd) throws Exception {
    log.info("总部差旅报销超预算入参:" + bgRd.toString());
    Map<String, String> resp = new HashMap<>();
    String bgItem = bgRd.getBgItem();
    if (StringUtils.isBlank(bgItem)) {
      throw new Exception("超预算入参,bgItem不能为空");
    }
    HTUtil ht = new HTUtil();
    DepartmentComInfo dc = new DepartmentComInfo();
    String bmCode = dc.getDepartmentCode(bgRd.getDeptCode());
    Arrays.stream(bgItem.split(",")).forEach(item -> {
      Map<String, Object> reqs = new HashMap<>();
      reqs.put("deptNum", bmCode);
      reqs.put("deptType", PayUtil.getDeptTypeCode(bgRd.getDeptCode()));
      reqs.put("Bgitem", item);
      reqs.put("BgPeriod", bgRd.getBgPeriod());

      log.info("总部差旅报销超预算预算参数:" + reqs);
      String budget = ht.getBudget(reqs);

      resp.put(item, budget);
    });
    log.info("总部差旅报销超预算预算返回参数:" + JSONObject.toJSONString(resp));
    return resp;
  }

  @Override
  public Map<String, String> queryExchangeRate() throws Exception {
    RecordSet rs = new RecordSet();
    Map<String, String> resp = new HashMap<>();
    try {
      rs.executeQuery("select BZ,HL from UF_BZ_HL order by BZ");
      while (rs.next()) {
        resp.put(rs.getString("BZ"), rs.getString("HL"));
      }
      return resp;
    } catch (Exception e) {
      throw new Exception("获取汇率数据异常,error:" + e.getMessage());
    }
  }

  @Override
  public String queryContractPaidMoney(String contractCode, String processCode) throws Exception {
    try {
      String queryPaidMoneyUrl = new PropBean().getPropName("queryPaidMoneyUrl");
      Map<String, String> requestDTO = new HashMap<>();
      requestDTO.put("sysCode", "OA");
      requestDTO.put("moduleCode", "CTRCT");
      requestDTO.put("ctrctCode", contractCode);
      requestDTO.put("processCode", processCode);
      return HttpUtil.postApplicationJson(queryPaidMoneyUrl, requestDTO, new HTUtil().getAppHeader());
    } catch (Exception e) {
      throw new Exception("查询合同已付金额的接口调用异常");
    }
  }

  @Override
  public Map<String, String> doBudget(String ids, String isDiscard) {
    log.info("====PaymentServiceImpl.doBudget====预算接口调用@ \nids=" + ids + "@isDiscard=" + isDiscard);
    List<String> idList = Arrays.asList(ids.split(","));
    if (CollectionUtils.isEmpty(idList)) {
      log.info("====预算传入的id和type不能为空");
      Map<String, String> res = new HashMap<>();
      res.put("预算接口入参错误", "id为空");
      return res;
    }
    //匹配id对应的付款类型和流程id
    String idCondition = String.join("','", ids.split(","));
    String sql = "select tbdlcyszt, FKLX,REQUTID,LCBH,FKZT from UF_ZBFK where ID in('" + idCondition + "')";
    RecordSet rs = new RecordSet();
    rs.executeQuery(sql);
    List<String> typeList = new ArrayList<>();
    List<String> reqNoList = new ArrayList<>();
    List<String> reqMark = new ArrayList<>();
    List<String> fkztList = new ArrayList<>();
    List<String> tbdlcysztList = new ArrayList<>();
    while (rs.next()) {
      typeList.add(rs.getString("FKLX"));
      reqNoList.add(rs.getString("REQUTID"));
      reqMark.add(rs.getString("LCBH"));
      fkztList.add(rs.getString("FKZT"));
      tbdlcysztList.add(rs.getString("tbdlcyszt"));
    }
    log.info("====预算id对应的流程类型@" + typeList);
    log.info("====预算id对应的流程编号@" + reqNoList);
    //遍历list核算
    Map<String, String> results = new HashMap<>();
    try {
      for (int i = 0; i < idList.size(); i++) {
        if ("2".equals(fkztList.get(i))) { //已废弃
          results.put(reqMark.get(i), "流程已废弃,无法付款");
          continue;
        }
        if ("0".equals(tbdlcysztList.get(i))) { //已同步
          results.put(reqMark.get(i), "预算已经同步，禁止再次提交");
          continue;
        }
        String lb = typeList.get(i);
        String rn = reqNoList.get(i);
        String rm = reqMark.get(i);
        log.info("当前遍历的流程@" + rm);
        // 0 总部通用付款,1　总部IT付款,2　总部工会付款,9　总部通用报销,10　总部差旅报销
        BudgetCommand budgetCommand = BizUtils.getBudgetCommentByLb(lb);

        if ("1".equals(lb)) {
          //it 流程特殊处理
          boolean flag = BizUtils.whetherItOrTy(rn);
          log.info("当前it付款为:false为it付款 @" + flag);
          if (!flag) {
            //作it付款处理
            budgetCommand = new ITHeadPaymentBudgetCommand();
          }
        }

        //判断是否为废弃
        if ("0".equals(isDiscard)) {
          //废弃
          log.info("废弃");
          String result = budgetCommand.reject(rn);
          if ("F1001".equals(result)) {
            //更新预算状态
            results.put(rm, "废弃成功");
            rs.executeQuery("update UF_ZBFK set TBDLCZT=2,TBDLCYSZT=2,fkzt=2 where REQUTID=" + rn);
            //废弃后更新发票关联关系: uf_pjxxgl 浪潮
            BizUtils bizUtils = new BizUtils();
            bizUtils.cancelInvLink(rn);
          } else {
            results.put(rm, "废弃失败,返回值:" + result);
          }
        } else {
          String result = budgetCommand.finish(rn);
          if ("F1001".equals(result)) {
            //更新预算状态
            results.put(rm, "预算成功");
            rs.executeQuery("update UF_ZBFK set TBDLCYSZT=0 where REQUTID=" + rn);
            //预算成功时,当核算为成功状态,更新付款状态为已付款
            rs.executeQuery("update UF_ZBFK set FKZT=0 where TBDLCZT=0 and REQUTID=" + rn);
          } else {
            results.put(rm, "预算失败,返回值:" + result);
          }
        }

      }
    } catch (Exception e) {
      e.printStackTrace();
      results.put("预算失败", e.getMessage());
    }

    return results;
  }

  @Override
  public String doExport(String id, String type) {
    String sqlCondition = String.join("','", id.split(","));
    String sql = "";
    if ("0".equals(type) || StringUtils.isEmpty(type)) {
      log.info("====更新导出状态 总部@" + id);
      sql = "update UF_ZBFK set SFDC=0 where id in('" + sqlCondition + "')";
    } else if ("1".equals(type)) {
      log.info("====更新导出状态 联合@" + id);
      sql = "update uf_zfmx set dc=0 where id in('" + sqlCondition + "')";
    }
    RecordSetTrans rst = new RecordSetTrans();
    try {
      rst.setAutoCommit(false);
      log.info("====更新导出状态@" + id);
      rst.executeUpdate(sql);
      rst.commit();
      return String.format("%s 导出状态更新成功.", id);
    } catch (Exception e) {
      rst.rollback();
      e.printStackTrace();
      return "更新导出状态失败: " + e.getMessage();
    }
  }

  @Override
  public String updateManualPaymentStatus(String id) {
    log.info("====更新手动付款状态@" + id);
    if ("".equals(id)) {
      return "请勾选相关流程进行状态更改";
    }
    RecordSetTrans rst = new RecordSetTrans();
    rst.setAutoCommit(false);
    try {
      String sqlCondition = String.join("','", id.split(","));
      String sql = "SELECT ID,FKZT,LCBH FROM uf_zbfk WHERE id IN ('"+sqlCondition+"')";
      rst.executeQuery(sql);
      List<String> notUpdateIds = new ArrayList<>();
      List<String> updateIds = new ArrayList<>();
      while (rst.next()) {
        String id1 = Util.null2String(rst.getString("ID"));
        String lcbh = Util.null2String(rst.getString("LCBH"));
        if ("2".equals(Util.null2String(rst.getString("FKZT")))) { //已废弃
          notUpdateIds.add(lcbh);
        } else {
          updateIds.add(id1);
        }
      }
      rst.executeUpdate("update UF_ZBFK set FKFS=1,FKZT=0 where id in('" + String.join("','", updateIds) + "')");
      rst.commit();
      return "更新手动付款状态成功(注:id为 "+String.join(",", notUpdateIds)+" 已废弃,无法手动付款)";
    } catch (Exception e) {
      rst.rollback();
      log.error("====更新手动付款状态失败,出现异常@" + e.getMessage());
      e.printStackTrace();
      return "更新手动付款状态出现异常";
    }
  }

  @Override
  public String queryVirtualDepartment(String deptId) {
    log.info("====查询虚拟部门个数@" + deptId);
    List<String> deptIds = Arrays.asList(deptId.split(","));
    DepartmentComInfo dc = new DepartmentComInfo();
    String sqlValue = deptIds.stream().distinct().map(dc::getDepartmentCode).collect(Collectors.joining("','"));
    log.info("====sql value@" + sqlValue);
    RecordSet rs = new RecordSet();
    rs.executeQuery("select count(*) n from uf_fkxnbmpzb where DEPT_CODE in('" + sqlValue + "') and bs = '1'");
    if (rs.next()) {
      return Util.null2String(rs.getString("n"));
    }
    return "";
  }

  @Override
  public ContractInfoVo queryContractPagination(ContractRequestParam params) {
    ContractInfoVo o = new ContractInfoVo();
    try {
      log.info("合同esb接口请求参数，START> " + params + " <END");
      Integer currentPage = params.getCurrentPage();
      Integer pageSize = params.getPageSize();
      String userCode = params.getUserCode();
      String contractCode = params.getCode();
      String contractName = params.getName();
      ContractRequestJson contractRequestJson = new ContractRequestJson();
      contractRequestJson.setModuleCode("CTRCT");
      contractRequestJson.setSysCode("OA");
      contractRequestJson.setCurPage(currentPage);
      contractRequestJson.setMaxResult(pageSize);
      contractRequestJson.setUserId(userCode);
      contractRequestJson.setCtrctCode(contractCode);
      contractRequestJson.setCtrctName(contractName);
      contractRequestJson.setPaymentDate(LocalDateTime.now().toString());
      PropBean propBean = new PropBean();
      String queryContractUrl = propBean.getPropName("queryContract");
      log.info("合同接口url：START> " + queryContractUrl + " <END");
      HTUtil htUtil = new HTUtil();
      Map<String, String> appHeader = htUtil.getAppHeader();
      log.info("getAppHeader@" + appHeader + "@");
      String res = HttpUtil.postApplicationJson(queryContractUrl, JSON.toJSONString(contractRequestJson), appHeader);
      log.info("合同接口返回：START> " + res + " <END");
      o = JSON.parseObject(res, ContractInfoVo.class);
      return o;
    } catch (Exception e) {
      log.info("合同接口返回异常：" + e);
      e.printStackTrace();
      return o;
    }
  }

  @Override
  public ItProjectVo queryItProject(ItProjectQueryCondition condition) throws Exception {
    ItProjectVo itProjectVo = new ItProjectVo();
    PropBean propBean = new PropBean();
    String itProjectsUrl = propBean.getPropName("queryItProject");
    log.info("it项目esb接口请求参数，START> @" + condition + "@");
    log.info("it项目接口url：START> @" + itProjectsUrl + "@");
    HTUtil htUtil = new HTUtil();
    Map<String, String> appHeader = htUtil.getAppHeader();
    log.info("getAppHeader@" + appHeader + "@");
    String res = HttpUtil.postApplicationJson(itProjectsUrl, JSON.toJSONString(new JSONArray()), appHeader);
    log.info("it项目esb接口请求返回参数成功");
    //log.info("it项目esb接口请求返回参数@" + res);
    @SuppressWarnings("unchecked")
    List<TreeNode> list = JSON.parseArray(res, TreeNode.class);
//    itProjectVo.setTotal(list.size());
    //扁平化处理
    List<TreeNode> treeNodes = TreeUtil.tree2list(list, null);
    itProjectVo.setTotal(treeNodes.size());
    //数据清洗
//    treeNodes = treeNodes.stream().filter(TreeNode::qualify).collect(Collectors.toList());
    //回显
    if (StringUtils.isNotBlank(condition.getKey())) {
      Pattern key = Pattern.compile(condition.getKey());
      treeNodes = treeNodes.stream()
              .filter(node -> key.matcher(node.getKey()).matches())
              .collect(Collectors.toList());
      itProjectVo.setData(treeNodes);
      itProjectVo.setOk(true);
      return itProjectVo;
    }

    if (StringUtils.isNotBlank(condition.getCode()) || StringUtils.isNotBlank(condition.getName())) {
      Pattern name = Pattern.compile(condition.getName());
      Pattern code = Pattern.compile(condition.getCode());
      if (StringUtils.isBlank(condition.getCode())) {
        treeNodes = treeNodes.stream()
                .filter(node -> name.matcher(node.getName()).find())
                .collect(Collectors.toList());
      } else if (StringUtils.isBlank(condition.getName())) {
        treeNodes = treeNodes.stream()
                .filter(node -> code.matcher(node.getProjectCode()).find())
                .collect(Collectors.toList());
      } else {
        treeNodes = treeNodes.stream().filter(node ->
                name.matcher(node.getName()).find() && code.matcher(node.getProjectCode()).find())
                .collect(Collectors.toList());
      }
    } else {
      treeNodes = treeNodes.stream()
              .skip((condition.getPageNo() - 1) * condition.getPageSize())
              .limit(condition.getPageSize()).collect(Collectors.toList());
    }
    itProjectVo.setData(treeNodes);
    itProjectVo.setOk(true);
    return itProjectVo;
  }

  @Override
  public String getAccountCode(String budgetCode) {
    PropBean pp = new PropBean();
    RecordSet rs = new RecordSet();
    String accountTreeId = pp.getPropName("accountTreeId");
    rs.writeLog("====accountTreeId@" + accountTreeId);
    String sql = "SELECT t1.HJKMBM,t1.HJKMMC\n" +
            "FROM UF_KJKMPZ t1\n" +
            "LEFT OUTER JOIN UF_KJKMPZ_DT1 t2 on t1.id=t2.mainid\n" +
            "WHERE (t2.yskm='" + budgetCode + "')";
    rs.writeLog("====sql@" + sql);
    rs.executeQuery(sql);
    String value = "";
    String name = "";
    if (rs.next()) {
      value = Util.null2String(rs.getString("HJKMBM"));
      name = Util.null2String(rs.getString("HJKMMC"));
    }
    rs.writeLog("====value@" + value);
    rs.writeLog("====name@" + name);
    if (StringUtils.isEmpty(value)) {
      return "";
    } else {
      return accountTreeId + "_" + value + "@" + name;
    }
  }

  @Override
  public String getAccountCode4Lh(String budgetCode) {
    PropBean pp = new PropBean();
    RecordSet rs = new RecordSet();
    String accountTreeId = pp.getPropName("accountTreeId4Lh");
    rs.writeLog("====accountTreeId@" + accountTreeId);
    String sql = "SELECT t1.HJKMBM,t1.HJKMMC\n" +
            "FROM UF_LHKJKMPZ t1\n" +
            "LEFT OUTER JOIN UF_LHKJKMPZ_DT1 t2 on t1.id=t2.mainid\n" +
            "WHERE (t2.yskm='" + budgetCode + "')";
    rs.writeLog("====sql@" + sql);
    rs.executeQuery(sql);
    String value = "";
    String name = "";
    if (rs.next()) {
      value = Util.null2String(rs.getString("HJKMBM"));
      name = Util.null2String(rs.getString("HJKMMC"));
    }
    rs.writeLog("====value@" + value);
    rs.writeLog("====name@" + name);
    if (StringUtils.isEmpty(value)) {
      return "";
    } else {
      return accountTreeId + "_" + value + "@" + name;
    }
  }


  @Override
  public String getAccountCode4HK(String budgetCode) {
    PropBean pp = new PropBean();
    RecordSet rs = new RecordSet();
    String accountTreeId = pp.getPropName("accountTreeIdHK");
    rs.writeLog("====accountTreeId@" + accountTreeId);
    String sql = "SELECT t1.HJKMBM,t1.HJKMMC\n" +
            "FROM UF_XGKJKM t1\n" +
            "LEFT OUTER JOIN UF_XGKJKM_DT1 t2 on t1.id=t2.mainid\n" +
            "WHERE (t2.yskm='" + budgetCode + "')";
    rs.writeLog("====sql@" + sql);
    rs.executeQuery(sql);
    String value = "";
    String name = "";
    if (rs.next()) {
      value = Util.null2String(rs.getString("HJKMBM"));
      name = Util.null2String(rs.getString("HJKMMC"));
    }
    rs.writeLog("====value@" + value);
    rs.writeLog("====name@" + name);
    if (StringUtils.isEmpty(value)) {
      return "";
    } else {
      return accountTreeId + "_" + value + "@" + name;
    }
  }

  @Override
  public String generateRequestMark(HttpServletRequest request) {
    String isCreate = Util.null2String(request.getParameter("iscreate"));
    int workFlowId = Util.getIntValue(request.getParameter("workflowid"));
    int formModeId = PayUtil.getFormModeIdByCubeName("uf_fklcbh");
    log.info("生产流程编号的参数：@isCreate=" + isCreate + ",workFlowId=" + workFlowId + ",formModeId=" + formModeId + "@");
    StringBuilder mark = new StringBuilder(); //流程编码
    if ("1".equals(isCreate)) {
      String unNumber = PayUtil.getUnNumberByWorkFlowId(workFlowId);
      String modeUuid = "";
      LocalDateTime now = LocalDateTime.now();
      String yM = now.format(DateTimeFormatter.ofPattern("yyyyMM"));
      RecordSet rs = new RecordSet();
      rs.executeQuery("select id,lsh,MODEUUID from uf_fklcbh where ny = '" + yM + "' and LCLX='" + unNumber + "'");
      if (rs.next()) {
        //更新
        int num = Util.getIntValue(rs.getString("lsh")) + 1;
        int id = Util.getIntValue(rs.getString("id"));
        modeUuid = Util.null2String(rs.getString("MODEUUID"));
        String updateSql = "update uf_fklcbh set lsh=? where id=?";
        rs.executeUpdate(updateSql, num, id);
        mark = new StringBuilder(num + "");
        while (mark.length() < 6) {
          mark.insert(0, "0");
        }
        mark = new StringBuilder("总部通用付款" + now.format(DateTimeFormatter.ofPattern("yyyyMM")) + mark);
      } else {
        String userId = Util.null2String(request.getParameter("f_weaver_belongto_userid"));
        String userType = Util.null2String(request.getParameter("f_weaver_belongto_usertype"));
        String createDate = now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        String createTime = now.format(DateTimeFormatter.ofPattern("HH:mm:ss"));
        //插入
        String insertSql = "insert into uf_fklcbh" +
                "(FORMMODEID,MODEDATACREATER,MODEDATACREATERTYPE,MODEDATACREATEDATE,MODEDATACREATETIME,MODEUUID,LSH,NY,LCLX) \n" +
                "values(?,?,?,?,?,?,?,?,?)";
        String uuid = UUID.randomUUID().toString();
        modeUuid = uuid;
        rs.executeUpdate(insertSql, formModeId, userId, userType, createDate, createTime, uuid, "1", yM, unNumber);
        mark = new StringBuilder("总部通用付款" + now.format(DateTimeFormatter.ofPattern("yyyyMM")) + "000001");
      }

      //权限重构
      int dataId = PayUtil.getDataIdByUUID(modeUuid);
      ModeRightInfo modeRightInfo = new ModeRightInfo();
      modeRightInfo.editModeDataShare(1, formModeId, dataId);

    }
    return mark.toString();

  }

  @Override
  public String doBudgetAccount(String requestId, String tableName, String billStatus) throws Exception {
    log.info("====通用付款流程预算开始");
    log.info("====通用付款预算流程id@" + requestId + "@");
    log.info("====待预算流程表名@" + tableName + "@");
    JSONObject params = new JSONObject();
    BudgetDao budgetDao = new BudgetDao();
    RecordSet rs = new RecordSet();
    ResourceComInfo rc = new ResourceComInfo();
    DepartmentComInfo dc = new DepartmentComInfo();
    HTUtil htUtil = new HTUtil();
    DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    try {
      String budgetInvokeParam = budgetDao.mainFieldParam(tableName, requestId);
      rs.executeQuery(budgetInvokeParam);
      String bz = "0"; //对应fkxx字段
      String lcbh = "";
      String requestname = "";
      String ngr = "";
      String mainId = "";
      if (rs.next()) {
        lcbh = Util.null2String(rs.getString("lcbh"));
        ngr = Util.null2String(rs.getString("ngr"));
        mainId = Util.null2String(rs.getString("id"));
        bz = Util.null2String(rs.getString("fkxx"));
        requestname = Util.null2String(rs.getString("requestname"));
      }
      String yskmTable = tableName + "_dt8"; //预算科目表，本币dt8，外币dt9，主表字段fkxx区分
      if ("1".equals(bz)) {
        yskmTable = tableName + "_dt9";
      }
      params.put("billnum", requestId);
      params.put("billname", lcbh);
      params.put("billstatus", billStatus);
      params.put("billtitle", requestname);
      params.put("pesonName", rc.getLastname(ngr));
      params.put("bizdate", df.format(LocalDateTime.now()));
      log.info(">>主表字段获取: @" + params + "@");
      rs.executeQuery(budgetDao.isItPay(tableName, lcbh));
      boolean isItFlag = false;
      if (rs.next()) {
        if ("1".equals(Util.null2String(rs.getString("FKLX")))) {
          isItFlag = true;
        }
      }
      JSONArray levelList = new JSONArray();

      boolean itFlag = lcbh.contains("总部IT付款");
      String yskmTableFieldParam;
      if (itFlag) {
        yskmTableFieldParam = budgetDao.ITyskmTableFieldParam(yskmTable, mainId);
      } else {
        yskmTableFieldParam = budgetDao.yskmTableFieldParam(yskmTable, mainId);
      }
      rs.executeQuery(yskmTableFieldParam);
      String uuid = UUID.randomUUID().toString();
      int i = 1;
      while (rs.next()) {
        JSONObject level = new JSONObject();
        //费用承担部门
        String fysjcdbm = Util.null2String(rs.getString("fysjcdbm"));
        //预算科目
        String yskm = Util.null2String(rs.getString("yskm"));
        level.put("deptNum", dc.getDepartmentCode(fysjcdbm));
        if (itFlag) {//IT项目付款传项目编码
          level.put("bgitem", Util.null2String(rs.getString("PROJECTCODE")));
        } else {
          level.put("bgitem", PayUtil.getSuperBudgetCode(yskm));
        }
        // 费用类型编码（默认传0101）
        level.put("bgElement", "0101");
        level.put("billEntryID", uuid + "#" + i);
        level.put("itemEntryNum", yskm);
        level.put("bgITElement", level.get("bgitem"));
        //科目对应金额
        level.putAll(PayUtil.getKjKmCharges(yskmTable, mainId, isItFlag));
        levelList.add(level);
        i++;
      }
      if (i == 1) {
        //没有明细
        log.info("预算科目明细为空");
        return "没有分摊的预算科目, 流程禁止提交";
      }
      params.put("list", levelList);
      Map<String, Object> dataMap = new HashMap<>();
      dataMap.put("data", params);
      log.info(">>预算接口调用参数 params : @" + params + "@");
      String resp = htUtil.budgetCommit(dataMap);
      log.info(">>预算接口调用返回 resp : @" + resp + "@");
      if (!"F1001".equals(resp)) {
        log.info("预算接口执行失败!返回值: " + resp);
        return "预算接口执行失败!返回值: " + resp;
      } else {
        BudgetService bds = new BudgetServiceImpl();
        boolean isUpdate = bds.doBudgetMiddleTable(lcbh, billStatus, null,yskmTable, tableName, isItFlag);
        if (isUpdate) {
          return "预算接口执行成功";
        } else {
          return "节点后附加操作更新预算中间表失败!";
        }
      }
    } catch (Exception e) {
      log.info("预算发生异常: " + e);
      throw new Exception(e);
    }
  }

  @Override
  public String doITBudgetAccount(String requestId, String tableName, String billStatus) throws Exception {
    log.info("====it预算开始执行");
    log.info("====it预算流程id@" + requestId + "@");
    log.info("====待预算流程表名@" + tableName + "@");
    try {
      DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
      JSONObject params = new JSONObject();
      ResourceComInfo rc = new ResourceComInfo();
      DepartmentComInfo dc = new DepartmentComInfo();
      RecordSet rs = new RecordSet();
      BudgetDao budgetDao = new BudgetDao();
      String budgetInvokeParam = budgetDao.mainFieldParamForIt(tableName, requestId);
      rs.executeQuery(budgetInvokeParam);
      String bz = "0"; //对应xzfklx字段
      String lcbh = "";
      String requestname = "";
      String ngr = "";
      String mainId = "";
      if (rs.next()) {
        lcbh = Util.null2String(rs.getString("lcbh"));
        ngr = Util.null2String(rs.getString("ngr"));
        mainId = Util.null2String(rs.getString("id"));
        bz = Util.null2String(rs.getString("xzfklx")); //=0是明细8,=1是明细9
        requestname = Util.null2String(rs.getString("requestname"));
      }
      String yskmTable = tableName + "_dt8"; //预算科目表，本币dt8，外币dt9，主表字段xzfklx区分
      if ("1".equals(bz)) {
        yskmTable = tableName + "_dt9";
      }
      params.put("billnum", requestId);
      params.put("billname", lcbh);
      params.put("billstatus", billStatus);
      params.put("billtitle", requestname);
      params.put("pesonName", rc.getLastname(ngr));
      params.put("bizdate", df.format(LocalDateTime.now()));
      log.info(">>主表字段获取: @" + params + "@");
      rs.executeQuery(budgetDao.isItPay(tableName, lcbh));
      boolean isItFlag = false;
      if (rs.next()) {
        if ("1".equals(Util.null2String(rs.getString("FKLX")))) {
          isItFlag = true;
        }
      }
      JSONArray levelList = new JSONArray();
      String yskmTableFieldParam = budgetDao.yskmTableFieldParam(yskmTable, mainId);
      rs.executeQuery(yskmTableFieldParam);
      int i = 1;
      String uuid = UUID.randomUUID().toString();
      while (rs.next()) {
        JSONObject level = new JSONObject();
        //费用承担部门
        String fysjcdbm = Util.null2String(rs.getString("fysjcdbm"));
        //预算科目
        String yskm = Util.null2String(rs.getString("yskm"));
        level.put("deptNum", dc.getDepartmentCode(fysjcdbm));
        level.put("bgitem", PayUtil.getSuperBudgetCode(yskm));
        // 费用类型编码（默认传0101）
        level.put("bgElement", "0101");
        level.put("billEntryID", uuid + "#" + i);
        level.put("itemEntryNum", yskm);
        level.put("bgITElement", level.get("bgitem"));
        //科目对应金额
        level.putAll(PayUtil.getKjKmCharges(yskmTable, mainId, isItFlag));
        levelList.add(level);
        i++;
      }
      if (i == 1) {
        //没有明细
        log.info("没有分摊的预算科目");
        return "it预算成功";
      }
      params.put("list", levelList);
      log.info("ITBudgetInterfaceInvoke>>预算接口调用参数 params : @" + params + "@");
      String requestUrl = new PropBean().getPropName("ITBudgetUpdateUrl");
      HTUtil htUtil1 = new HTUtil();
      Map<String, String> appHeader = htUtil1.getAppHeader();
      log.info("getAppHeader@" + appHeader + "@");
      //新增token校验
      String resp = HttpUtil.postApplicationJson(requestUrl, params.toJSONString(), appHeader);
      log.info("ITBudgetInterfaceInvoke>>预算接口调用返回 resp : @" + resp + "@");
      if ("F1001".equals(resp)) {
        return "IT预算成功";
      } else {
        return "IT预算失败";
      }
    } catch (Exception e) {
      return "it预算接口执行失败";
    }
  }

  @Override
  public List<Map<String, String>> doCostAccount(String ids) throws Exception {
    log.info("====通用付款流程核算开始");
    log.info("====待核算建模流程序号@" + ids + "@");
    List<Map<String, String>> resMessage = new ArrayList<>();
    try {
      RecordSet rs = new RecordSet();
      String modeTableName = "uf_zbfk"; //唯一建模表
      //建模勾选的id
      String[] ids_ = ids.split(",");
      for (String id : ids_) {
        Map<String, String> resp = new HashMap<>();
        String sql = pd.getFormTableByModeOrderId(modeTableName, id);
        rs.executeQuery(sql);
        rs.next();
        String formId = Util.null2String(rs.getString("FORMID"));
        WorkflowBillComInfo workflowBillComInfo = new WorkflowBillComInfo();
        String workFlowTableName = VirtualFormHandler.getRealFromName(Util.null2String(workflowBillComInfo.getTablename(formId)));
        if ("".equals(workFlowTableName)) {
          log.info("id:" + id + "对应流程表名未找到");
          resp.put(id, "对应流程表名未找到,核算失败");
          resMessage.add(resp);
          return resMessage;
        }
        ResourceComInfo rc = new ResourceComInfo();
        DepartmentComInfo dc = new DepartmentComInfo();

        boolean cl = BizUtils.isCl(id);
        String baseInfo = pd.getBaseInfo(modeTableName, workFlowTableName, id);
        if (cl) {
          baseInfo = pd.getBaseInfoForCl(modeTableName, workFlowTableName, id);
        }
        String typeSql = pd.getPaymentType(modeTableName, workFlowTableName, id);
        String type = "";
        rs.execute(typeSql);
        if (rs.next()){
          type = Util.null2String(rs.getString("fklx"));
          //判断是否为采购商城付款,4为采购商城特殊逻辑
          if ("4".equals(type)){
            baseInfo = pd.getBaseInfoSettlePayment(modeTableName, workFlowTableName, id);
          }
        }
        rs.executeQuery(baseInfo);
        rs.next();
        String fklx = rs.getString("fklx"); //付款类型
        String ngr = Util.null2String(rs.getString("NGR"));
        String bm = Util.null2String(rs.getString("SZBM")); //部门
        String requestMark = Util.null2String(rs.getString("LCBH"));
        String requestId = Util.null2String(rs.getString("REQUTID"));
        String fjzs = Util.null2String(rs.getString("DJZS")); //附件张数
        String ngrq = "";
        if ("4".equals(type)){
          ngrq = Util.null2String(rs.getString("NGRQ")); //拟稿日期
        }else {
          ngrq = Util.null2String(rs.getString("NGSJ")); //拟稿日期
        }
        String requestName = Util.null2String(rs.getString("REQUESTNAME"));
        String ywht = Util.null2String(rs.getString("ywht")); //有无合同
        String sfqdz = Util.null2String(rs.getString("SFQDZ")); //是否全电子
        String fkzt = Util.null2String(rs.getString("fkzt")); //付款状态
        if ("2".equals(fkzt)) {
          resp.put(requestMark, "流程已废弃,无法付款");
          resMessage.add(resp);
          continue;
        }
        CostAccountDto costAccountDto = new CostAccountDto(); //核算接口json 一级
        //总部通用付款0、总部通用报销9、总部差旅报销10、总部IT付款1
        if("0,9,10,1".contains(fklx)){
          String cxsql = "select t1.djsl,t1.zzdjsl from "+workFlowTableName+" t1 where t1.requestid = ?";
          rs.executeQuery(cxsql,requestId);
          if (rs.next()){
            String djsl = Util.null2String(rs.getString("djsl")); //单据数量
            String zzdjsl = Util.null2String(rs.getString("zzdjsl")); //纸质单据数量
            costAccountDto.setDjsl(djsl);
            costAccountDto.setZzdjsl(zzdjsl);
          }
        }
        if ("0,1,2,3".contains(fklx)) {
          //付款类型为总部通用付款,总部it或总部工会的,构建核算参数(添加商旅结算付款类型3)
          costAccountDto.setElectronicBill(sfqdz); //是否电子票
          costAccountDto.setType("htfk"); //总部付款费用核算
          costAccountDto.setNgrDept(dc.getDepartmentmark(bm));
          costAccountDto.setNgrDeptCode(dc.getDepartmentCode(bm));
          costAccountDto.setNgrName(rc.getWorkcode(ngr));
          costAccountDto.setRequestMark(requestMark);
          costAccountDto.setRequestId(requestMark); //djid传流程编码,流程id总部不需要
          costAccountDto.setAttachmentNum(fjzs);
          costAccountDto.setLocationName("");
          costAccountDto.setTitle(requestName);
          costAccountDto.setCurrency("RMB");
          costAccountDto.setCreateDate(ngrq);
          costAccountDto.setReimbursementWay("");
          costAccountDto.setPayOrderNo(requestMark); //总部付款付款单号直接传流程编码

          if ("".equals(requestId)) {
            log.info("建模requestId为空,无法执行核算");
            resp.put(id, "建模requestId为空,无法执行核算");
            resMessage.add(resp);
            continue;
          }

          if ("1".equals(fklx)) {
            //付款类型为it
            boolean isIt = BizUtils.whetherItOrTy(requestId);
            if (!isIt) {
              // it费用付款 是否it付款=1
              rs.executeQuery("select XMMC,PROJECTCODE,LXBH,LXMC from " + workFlowTableName + "_DT8 t1\n" +
                      " left join " + workFlowTableName + " t2 on t1.MAINID=t2.ID\n" +
                      " where t2.REQUESTID=" + requestId);
              rs.next();
              costAccountDto.setBh1(Util.null2String(rs.getString("LXBH")));//20210528 业务说传立项编号
              costAccountDto.setBz1(Util.null2String(rs.getString("LXMC")));
            }
          } else {
            //总部付款
            costAccountDto.setBz2("0");
          }
          //获取支付明细(dt11)
          String getPayInfoFromDt11 = pd.getPayInfoFromDt11(workFlowTableName, requestId);
          List<PayDetail> payDetailList = new ArrayList<>();
          rs.executeQuery(getPayInfoFromDt11);
          while (rs.next()) {
            PayDetail payDetail = new PayDetail();
            String payByBank = Util.null2String(rs.getString("YXZFJE"));
            String payByCash = Util.null2String(rs.getString("XJZFJE"));
            String bankName = Util.null2String(rs.getString("KHXMC"));
            String bankAccount = Util.null2String(rs.getString("YXZH"));
            String SKDW = Util.null2String(rs.getString("SKDW"));
            payDetail.setPayByBank(payByBank);
            payDetail.setPayByCash(payByCash);
            payDetail.setBankName(bankName);
            payDetail.setBankAccount(bankAccount);
            payDetail.setEmployeeDept("");
            payDetail.setEmployeeName("");
            payDetail.setPayee(SKDW);
            payDetailList.add(payDetail);
          }
          if ("2".equals(fklx)) {
            //流程为工会付款流程时,同时取出对私的支付信息
            String tableNameGh = WeaverUtil.getTableNameByRequestId(requestId, rs);
            String getPayInfoFromDt13 = "select t2.YXZFJE,t2.KHXMC,t2.YXZH,t2.ygxm,t2.bm\n" +
                    "from " + tableNameGh + " t1\n" +
                    "left join " + tableNameGh + "_dt13 t2 on t1.ID=t2.MAINID\n" +
                    "where t1.REQUESTID=" + requestId;
            rs.executeQuery(getPayInfoFromDt13);
            while (rs.next()) {
              log.info("====当前流程为工会,附加个人支付明细开始@" + getPayInfoFromDt13);
              PayDetail payDetail = new PayDetail();
              String payByBank = Util.null2String(rs.getString("YXZFJE"));
              String payByCash = "";
              String bankName = Util.null2String(rs.getString("KHXMC"));
              String bankAccount = Util.null2String(rs.getString("YXZH"));
              String SKDW = "";
              String empDept = Util.null2String(rs.getString("bm"));
              String empName = Util.null2String(rs.getString("ygxm"));
              payDetail.setPayByBank(payByBank);
              payDetail.setPayByCash(payByCash);
              payDetail.setBankName(bankName);
              payDetail.setBankAccount(bankAccount);
              payDetail.setEmployeeDept(dc.getDepartmentmark(empDept));
              payDetail.setEmployeeName(rc.getWorkcode(empName));
              payDetail.setPayee(SKDW);
              log.info("====@个人payDetail" + payDetail.toString());
              payDetailList.add(payDetail);
            }

          }
          log.info("流程:@" + requestMark + "@");
          log.info("支付明细(dt11):@payDetailList=" + payDetailList + "@");
          if (CollectionUtils.isEmpty(payDetailList)) {
            log.info(requestMark + "支付明细数据为空，请检查表单数据后核算");
            resp.put(requestMark, "核算失败,支付明细数据为空");
            resMessage.add(resp);
            continue;
          }
          costAccountDto.setPayDetails(payDetailList);
          //获取预算明细
          String subjectInfoFromDt8AndDt12 = pd.getSubjectInfoFromDt8AndDt12(workFlowTableName, requestId);
          if ("4".equals(type)){
            subjectInfoFromDt8AndDt12 = pd.getSettleSubjectInfoFromDt8AndDt12(workFlowTableName, requestId);
          }
          List<KjDetail> kjDetailList = new ArrayList<>();
          rs.executeQuery(subjectInfoFromDt8AndDt12);
          while (rs.next()) {
            KjDetail kjDetail = new KjDetail();
            BudgetData budgetData = new BudgetData(); //预算科目
            SubjectData subjectData = new SubjectData(); //会计科目
            String fysjcdbm = Util.null2String(rs.getString("FYSJCDBM")); //费用承担部门
            String je = Util.null2String(rs.getString("JE"));
            String zhrmb = Util.null2String(rs.getString("ZHRMB"));
            String sy = Util.null2String(rs.getString("SY"));
            String hjkmmc = Util.null2String("");
            String hjkmbm = Util.null2String(rs.getString("HJKM"));
            subjectData.setItemCode(hjkmbm);
            subjectData.setItemName(hjkmmc);
            String dyyskm = Util.null2String(rs.getString("YSKM"));
            budgetData.setRelationCode(hjkmbm);
            budgetData.setItemCode(dyyskm);
            //采购商城付款没有YSKMMC
            if (!"4".equals(type)){
              String dyysmc = Util.null2String(rs.getString("YSKMMC"));
              budgetData.setItemName(dyysmc);
              kjDetail.setPriceRMB(zhrmb);
              kjDetail.setMoney(zhrmb);
            } else {
              kjDetail.setPriceRMB(je);
              kjDetail.setMoney(je);
            }
            kjDetail.setExpenseDeptCode(dc.getDepartmentCode(fysjcdbm));
            kjDetail.setExpenseDept(dc.getDepartmentmark(fysjcdbm));
            kjDetail.setExpenseBadge("");
            kjDetail.setExpensePerson("");
            kjDetail.setSubjectData(subjectData);
            kjDetail.setBudgetData(budgetData);
            kjDetail.setProjectCode("");
            kjDetail.setProject("");
            kjDetail.setReason(sy);
            kjDetailList.add(kjDetail);
          }
          log.info("流程:@" + requestMark + "@");
          log.info("会计明细(dt8,dt12):@kjDetailList=" + kjDetailList + "@");
          if (CollectionUtils.isEmpty(kjDetailList)) {
            log.info(requestMark + "会计明细数据为空，请检查表单数据后核算");
            resp.put(requestMark, "核算失败,会计明细数据为空");
            resMessage.add(resp);
            continue;
          }
          costAccountDto.setKjDetails(kjDetailList);
        } else {
          log.info("非总部通用,it,或工会付款,走HsFactory对应的id");
          HsFactory hsFactory = new HsFactory();
          costAccountDto = hsFactory.getHsService(requestId, fklx);
          if (costAccountDto == null) {
            log.info("获取核算数据异常@requestId=" + requestId);
            resp.put(requestMark, "核算失败,获取核算数据异常");
            resMessage.add(resp);
            continue;
          }
        }
        //HTO-11638查询主表，当付款流程中字段“先付款后发票”选项为“是”时，接口字段“SFYFP”传值“Y”，
        // “先付款后发票”选项为“否”时，接口字段“SFYFP”传值“N”；
        //针对总部通用付款，总部it付款，总部工会付款
        if(SubUnionBizUtil.equalsTableName(requestId, "zbtyfk") ||SubUnionBizUtil.equalsTableName(requestId, "zbghfk")
                ||SubUnionBizUtil.equalsTableName(requestId, "zbitfk")){
          RecordSet sqlFindYfp = new RecordSet();
          String sqlNew = "select sfxfkhtgfp from "+workFlowTableName+" where requestid = "+requestId;
          sqlFindYfp.execute(sqlNew);
          if (sqlFindYfp.next()){
            String sfxfkhtgfp = Util.null2String(sqlFindYfp.getString("sfxfkhtgfp"));
            if ("0".equals(sfxfkhtgfp)){
              //当付款流程中字段“先付款后发票”选项为“是”时，接口字段“SFYFP”传值“Y”
              costAccountDto.setSFYFP("Y");
            }else{
              //“先付款后发票”选项为“否”时，接口字段“SFYFP”传值“N”；
              costAccountDto.setSFYFP("N");
            }
          }
        }
        String costAccountDtoJsonStr = JSON.toJSONString(costAccountDto);
        @SuppressWarnings("unchecked")
        Map<String, Object> stringObjectMap = JSONObject.parseObject(costAccountDtoJsonStr);
        HTUtil ht = new HTUtil();
        log.info("开始执行核算接口");
        log.info("接口参数@request=" + stringObjectMap + "@");
        String response = ht.saveFydj(stringObjectMap);
        log.info("接口返回@response=" + response + "@");
        if (!"".equals(response)) {
          if ("success".equals(response)) {
            log.info("流程id" + requestId + "核算接口响应成功");
            resp.put(requestMark, "核算成功");
            resMessage.add(resp);
            //核算算成功,更新出纳付款建模表 为 同步到浪潮状态=0,付款状态=0
            //更新预付款中间表 SFFKQR=1
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
            String rzsj = sdf.format(new Date());
            rs.executeUpdate("update UF_ZBFK set TBDLCZT=0 ,rzsj = '"+rzsj+"'  where id =" + id);
            //核算成功,预算也成功的情况下,更新付款状态为已付款
            rs.executeUpdate("update UF_ZBFK set FKZT=0 where TBDLCYSZT=0 and id =" + id);
            //更新主表和预算中间表
            rs.executeUpdate("update UF_YFKMIDDLE set SFFKQR=1 where REQID=" + requestId);
            rs.executeUpdate("update " + workFlowTableName + " set FKZT=1 where REQUESTID=" + requestId);
            if ("0".equals(ywht)) {
              //有无合同为是
              //更新合同信息
              boolean flag = PayUtil.updatePaymentInfoToHuaTai(requestId);
              if (flag) {
                log.info("合同信息更新成功");
//								resMessage.add("合同信息更新成功");
              } else {
                log.info("合同信息更新失败");
//								resMessage.add("合同信息更新失败");
              }
              //更新it合同信息
//							if ("1".equals(fklx)) { //1是付款类型
//								boolean isIt = BizUtils.whetherItOrTy(requestId);
//								if (!isIt) {
//									log.info("====当前流程是it付款,执行it合同更新");
//									boolean flagIT = PayUtil.updateItPaymentInfoToHT(requestId, workFlowTableName);
//									if (flagIT) {
//										log.info("====IT合同信息更新成功");
//										resMessage.add("IT合同信息更新成功");
//									} else {
//										log.info("====IT合同信息更新失败");
//										resMessage.add("IT合同信息更新失败");
//									}
//								}
//							}
            }else if ("4".equals(fklx)){
              boolean flag = PayUtil.updatePaymentInfoListToHuaTai(requestId);
              if (flag) {
                log.info("合同信息更新成功");
              } else {
                log.info("合同信息更新失败");
              }
            }
          } else {
            log.info("流程id" + requestId + "核算接口响应失败");
            resp.put(requestMark, "核算失败");
            resMessage.add(resp);
          }
        } else {
          log.info("流程id" + requestId + "核算接口响应为空");
          resp.put(requestMark, "核算失败");
          resMessage.add(resp);
        }

      }

      return resMessage;
    } catch (Exception e) {
      log.info("doCostAccount方法异常:@" + e.getMessage());
      e.printStackTrace();
      Map<String, String> resp = new HashMap<>();
      resp.put("核算异常", e.getMessage());
      resMessage.add(resp);
      return resMessage;
    }

  }

  @Override
  public List<Map<String, String>> doPayment(String ids) throws Exception {
    log.info("====通用付款流程doPayment开始执行,待处理建模id数据@" + ids);
    List<Map<String, String>> singleMessage = new ArrayList<>();
    try {
      List<String> idArray = Arrays.stream(ids.split(",")).collect(Collectors.toList());
      String sql = "select t1.REQUTID,t1.fklx,t2.REQUESTMARK,t4.TABLENAME,t1.fkzt from UF_ZBFK t1\n" +
              "left join WORKFLOW_REQUESTBASE t2\n" +
              "on t1.REQUTID=t2.REQUESTID\n" +
              "left join workflow_base t3\n" +
              "on t2.workflowid = t3.id\n" +
              "left join workflow_bill t4\n" +
              "on t3.formid = t4.id\n" +
              "where t1.id=?";
      RecordSet rs = new RecordSet();
      for (String id : idArray) {
        Map<String, String> resp = new HashMap<>();
        log.info("====开始处理uf_zbfk建模id@" + id);
        rs.executeQuery(sql, id);
        String requestId = "";
        String tableName = "";
        String requestMark = "";
        String fklx = "";
        String fkzt = "";
        if (rs.next()) {
          requestId = rs.getString("REQUTID");
          tableName = rs.getString("TABLENAME");
          requestMark = rs.getString("REQUESTMARK");
          fklx = rs.getString("fklx"); //流程类别
          fkzt = rs.getString("fkzt"); //付款状态
        }

        if ("2".equals(fkzt)) {
          resp.put(requestMark, "流程已废弃,无法付款");
          singleMessage.add(resp);
          continue;
        }

        //预算
        BudgetCommand budgetCommand = BizUtils.getBudgetCommentByLb(fklx);

        //it优化部分
        if ("1".equals(fklx)) {
          boolean flag = BizUtils.whetherItOrTy(requestId, tableName);
          if (!flag) {
            log.info("it付款,且it类型@" + id);
            budgetCommand = new ITHeadPaymentBudgetCommand();
          }
        }

        String finish = budgetCommand.finish(requestId); //实占

        log.info("预算数据@" + requestMark + "@" + tableName);
        log.info("预算结果@" + finish);
        resp.put(requestMark, "F1001".equalsIgnoreCase(finish) ? "预算同步成功" : "预算同步失败");
        singleMessage.add(resp); //普通预算接口封装到返回消息中

        if ("F1001".equals(finish)) {
          rs.executeQuery("update UF_ZBFK set TBDLCYSZT=0 where id=" + id); // 更新建模表单状态 TBDLCYSZT
          singleMessage.addAll(doCostAccount(id));//核算
        }

      }
      return singleMessage;
    } catch (Exception e) {
      log.info("付款接口提交报错@" + e.getMessage());
      e.printStackTrace();
      Map<String, String> resp = new HashMap<>();
      resp.put("核算异常", e.getMessage());
      singleMessage.add(resp);
      return singleMessage;
    }

  }

  @Override
  public Map<String, String> queryInvoiceOnce(String fphm, String fpdm) throws Exception {
    Map<String, String> res = new HashMap<>();
    log.info("====发票去重校验接口调用开始");
    log.info("====入参@fphm:" + fphm + ";fpdm:" + fpdm);
    try {
      RecordSet rs = new RecordSet();
      String sql = "select t1.REQUESTID,t1.LCBM,t1.FPDM,t1.FPHM\n" +
              "from uf_pjxxgl t1\n" +
              "where FPHM =? and FPDM=?";
      rs.executeQuery(sql, fphm, fpdm);
      if (rs.next()) {
        res.put("relReq", Util.null2String(rs.getString("LCBM")));
        res.put("flag", "1"); //1存在,0不存在
        log.info("====返回参数@" + JSONObject.toJSONString(res));
        return res;
      }
    } catch (Exception e) {
      log.info("====queryInvoiceOnce报错@" + e.getMessage());
      e.printStackTrace();
    }
    res.put("relReq", "");
    res.put("flag", "0"); //1存在,0不存在
    log.info("====返回参数@" + JSONObject.toJSONString(res));
    return res;
  }

  @Override
  public Map<String, String> queryHistoryPayRecord(String bankAccount, String payeeDept, String bankName, String city) throws Exception {
    //配置项控制校验支付记录 TurnOnBankCardVerification (开启银行卡校验)
    Map<String, String> res = new HashMap<>();
    PropBean pp = new PropBean();
    String openFlag = pp.getPropName("TurnOnBankCardVerification"); //0=关闭 1=开启
    if ("1".equals(openFlag)) {
      log.info("屏蔽银行卡校验");
      res.put("flag", "1"); //可以提交
      res.put("isTrueAccount", "1"); // 存在正确的账户
      res.put("addition", "");
      return res;
    }

    RecordSet rs = new RecordSet();
    log.info("付款流程校验资金系统信息");
    log.info(String.format("入参@bankAccount:%s;payeeDept:%s;bankName:%s;city:%s", bankAccount, payeeDept, bankName, city));
    PropBean propBean = new PropBean();
    String financeDTable = propBean.getPropName("FinanceDTable");
    String sql = "select ZJJSDJ_DFZH,ZJJSDJ_DFHM,ZJJSDJ_DFKHH,ZJJSDJ_DFS,ZJJSDJ_DFCS from " + financeDTable + " where ZJJSDJ_DFZH='" + bankAccount + "'";
    try {
      rs.executeQueryWithDatasource(sql, DataSourceName.FinanceD.getName());
      String _city = PayUtil.cityCodeToName(city);
      boolean hasTrueAccount = false;
      while (rs.next()) {
        //匹配到银行账户
        hasTrueAccount = true;
        //校验其他信息
        String skdw = Util.null2String(rs.getString("ZJJSDJ_DFHM")); //收款单位
        String yhmc = Util.null2String(rs.getString("ZJJSDJ_DFKHH")); //开户行
        String province = Util.null2String(rs.getString("ZJJSDJ_DFS")); //省
        String cit = Util.null2String(rs.getString("ZJJSDJ_DFCS")); //市
        String cityInDb = province + "," + cit; //中文,逗号分割  江苏,南京
        if (payeeDept.equals(skdw) && bankName.equals(yhmc) && cityInDb.equals(_city)) {
          //匹配到一个就允许提交
          res.put("flag", "1"); //可以提交
          res.put("isTrueAccount", "1"); // 存在正确的账户
          res.put("addition", "");
          return res;
        }
      }
      if (hasTrueAccount) {
        //匹配到银行账户,但付款单位和开户行等校验失败
        res.put("flag", "0"); //不允许提交
        res.put("isTrueAccount", "1"); //正确账户
        res.put("addition", "付款信息错误，请检查往来单位信息");
      } else {
        //没有匹配到银行账户,通过收款单位进行查询,展示历史记录
        List<String> yhzhInDB = new ArrayList<>(); //付款单位对应的历史银行账户
        String sqlWithout = "select ZJJSDJ_DFZH from " + financeDTable + " where ZJJSDJ_DFHM='" + payeeDept + "'";
        rs.executeQueryWithDatasource(sqlWithout, DataSourceName.FinanceD.getName());
        while (rs.next()) {
          yhzhInDB.add(Util.null2String(rs.getString("ZJJSDJ_DFZH")));
        }
        if (CollectionUtils.isNotEmpty(yhzhInDB)) {
          //提示
          res.put("flag", "0"); //允许提交
          res.put("isTrueAccount", "0");
          res.put("addition", String.join(",", yhzhInDB));
        } else {
          res.put("flag", "0"); //允许提交
          res.put("isTrueAccount", "0");
          res.put("addition", "");
        }
      }
      return res;
    } catch (Exception e) {
      log.error("====queryHistoryPayRecord抛出异常");
      throw new Exception(e);
    }
  }

  @Override
  public String queryHistoryPayRecordWithSubmit(Map<String, List<String>> dtData) throws Exception {
    PropBean pp = new PropBean();
    String openFlag = pp.getPropName("TurnOnBankCardVerification"); //0=关闭 1=开启
    log.info(String.format("屏蔽银行卡校验openFlag=%s", openFlag));

    RecordSet rs = new RecordSet();
    PropBean propBean = new PropBean();
    String financeDTable = propBean.getPropName("FinanceDTable"); //资金表库
    List<String> msg = new ArrayList<>();
    dtData.values()
            .forEach(data -> {
              if ("1".equals(openFlag)) {
                msg.add(String.valueOf(true));
              } else {
                boolean newValue = true;
                boolean flag = false; //是否允许提交
                String sql = "select ZJJSDJ_DFZH,ZJJSDJ_DFHM,ZJJSDJ_DFKHH,ZJJSDJ_DFS,ZJJSDJ_DFCS from " + financeDTable + " where ZJJSDJ_DFZH='" + data.get(0) + "'";
                rs.executeQueryWithDatasource(sql, DataSourceName.FinanceD.getName());
                String _city = PayUtil.cityCodeToName(data.get(3));
                while (rs.next()) {
                  newValue = false;
                  //校验其他信息
                  String skdw = Util.null2String(rs.getString("ZJJSDJ_DFHM")); //收款单位
                  String yhmc = Util.null2String(rs.getString("ZJJSDJ_DFKHH")); //开户行
                  String province = Util.null2String(rs.getString("ZJJSDJ_DFS")); //省
                  String cit = Util.null2String(rs.getString("ZJJSDJ_DFCS")); //市
                  String cityInDb = province + "," + cit; //中文,逗号分割  江苏,南京
                  if (data.get(1).equals(skdw) && data.get(2).equals(yhmc) && cityInDb.equals(_city)) {
                    //匹配到一个就允许提交
                    flag = true;
                  }
                }
                msg.add(String.valueOf(flag || newValue));
              }
            });
    return String.join(",", msg);
  }

  @Override
  public Map<String, Object> upMainFKZT(Map<String, Object> params) {
    String ids = Util.null2String(params.get("ids"));
    boolean updateResult = updateColumnByRequestid(ids);
    Map<String, Object> result = new HashMap<>();
    result.put("code", updateResult ? "200" : "500");
    return result;
  }

  /*
   * 根据requestid更新流程主表中的一个字段
   * */
  public boolean updateColumnByRequestid(String ids) {
    boolean result = true;
    BaseBean bb = new BaseBean();
    bb.writeLog("建模表更新成功，同步更新流程表中的付款状态字段");
    RecordSet rs = new RecordSet();
    String sql;
    List<String> needUpdate = new ArrayList<>();
    sql = "select t1.REQUTID,t1.fklx,t2.REQUESTMARK,t4.TABLENAME,t1.fkzt from UF_ZBFK t1\n" +
            "left join WORKFLOW_REQUESTBASE t2\n" +
            "on t1.REQUTID=t2.REQUESTID\n" +
            "left join workflow_base t3\n" +
            "on t2.workflowid = t3.id\n" +
            "left join workflow_bill t4\n" +
            "on t3.formid = t4.id\n" +
            "where t1.id in (" + ids + ")";
    rs.executeQuery(sql);
    while (rs.next()) {
//      if (rs.getString("REQUESTMARK").contains("IT")) {
      needUpdate.add(Util.null2String(rs.getString("REQUTID")));
//      }
    }
    String tablename = "";
    if (needUpdate.size() > 0) {
      sql = "select t2.tablename from workflow_requestbase t0,workflow_base t1,workflow_bill t2 where t0.workflowid = t1.id and t1.formid = t2.id and t0.requestid = '" + needUpdate.get(0) + "'";
      rs.executeQuery(sql);
      if (rs.next()) {
        tablename = rs.getString("tablename");
      }
    }
    bb.writeLog("获取的表名是：" + tablename);
    for (String requestid : needUpdate) {
      sql = "update " + tablename + " set fkzt = 0 where requestid = '" + requestid + "'";
      result = result && rs.executeUpdate(sql);
    }
    return result;
  }

}
