/*
 * @Descripttion: 安徽-马鞍山 接口
 * @Author: vian
 * @Date: 2020-08-17 15:40:08
 */

// INTERFACE_EXPORT =，必须这么写，这样才能在导出时动态加载脚本后，覆盖前端代码
INTERFACE_EXPORT = (() => {
  'use strict';

  /**
   * 
   * @param {String} areaKey - 地区标识，如：'安徽@马鞍山'，有些地区的接口只是取值上有不同，共有一个接口脚本， 需要通过地区标识确定一些特殊处理
   * @param {Number} exportKind - 导出类型，招标、投标、控制价
   * @param {Object} projectData - 项目表数据：{ 建设项目Data, children: [单位工程...] }
   * @param {Object} tenderDetailMap - 单位工程ID与getData接口数据(projectObj.project的结构)的映射。
   * @return {Promise<Array>} - 返回的数据结构必须按照规定：[{ data, exportKind, fileName }]，参考web\building_saas\standard_interface\index.js中的注释说明
   */
  async function entry(areaKey, exportKind, projectData, tenderDetailMap) {
    const {
      CONFIG: {
        TYPE,
        WHITE_SPACE
      },
      UTIL: {
        getValueByKey,
        getHan,
        getFee,
        getUnitFee,
        generateHardwareId,
      },
      Element,
    } = INTERFACE_EXPORT_BASE;

    const {
      EXPORT_KIND: { BID_INVITATION, BID_SUBMISSION, CONTROL },
      fixedFlag,
      RationType,
    } = window.commonConstants

    const GljType = gljUtil.gljType;

    const { isEmptyVal, isDef } = window.commonUtil;

    const isBidInvitation = exportKind === BID_INVITATION; // 是否是招标
    const isBidSubmission = exportKind === BID_SUBMISSION; // 是否是投标
    const isControl = exportKind === CONTROL; // 是否是控制价

    // 节点定义--------------------------------

    const subArea = areaKey.split('@')[1];
    
    // 建设项目基本信息
    function JingJiBiao(projectName, information) {
      const taxModeMap = {
        '一般计税': '1',
        '简易计税': '2',
      };
      const czzt = {
        [BID_INVITATION]: '招标',
        [BID_SUBMISSION]: '投标',
        [CONTROL]: '招标控制',
      };
      const attrs = [
        { name: 'Xmbh', value: getValueByKey(information, 'projNum'), minLen: 1, whiteSpace: WHITE_SPACE.COLLAPSE }, // 项目编号，招标xsd中有规定minLen whiteSpace，这里投标招标统一处理
        { name: 'Xmmc', value: projectName }, // 项目名称
        { name: 'Bzlx', value: '清单' }, // 项目编制类型
        { name: 'Jjyj', value: '【18清单】2018部颁清单计价依据' }, // 计价依据
        { name: 'Xmqzzh', value: getValueByKey(information, 'startEndChainages') }, // 项目起止桩号
        { name: 'Jsdw', value: getValueByKey(information, 'constructingUnits') }, // 建设单位
        { name: 'Czzt', value: czzt[exportKind] }, // 操作状态：招标、投标、招标控制，即导出接口时，所选的文件类型
        { name: 'Jsfs', value: taxModeMap[getValueByKey(information, 'taxMode')] || '1', type: TYPE.INT }, // 计税方式，默认1。1=一般计税 2=简易计税
        { name: 'Version', value: ['淮北', '铜陵', '亳州', '六安', '张掖', '安庆'].includes(subArea) ? '1.1' : '1.0' },
      ];
      Element.call(this, 'JingJiBiao', attrs);
    }


    // 招标信息
    function ZhaoBiaoXx(information) {
      const attrs = [
        { name: 'Zbr', value: getValueByKey(information, 'tendereeName') }, // 招标人
        { name: 'Zxr', value: getValueByKey(information, 'costConsultant') }, // 造价咨询人
        { name: 'ZbrDb', value: getValueByKey(information, 'tenderAuthorizer') }, // 招标人法定代表人或其授权人
        { name: 'ZxrDb', value: getValueByKey(information, 'consultantAuthorizer') }, // 造价咨询人法定代表人或其授权人
        { name: 'Bzr', value: getValueByKey(information, 'compileApprover') }, // 编制人
        { name: 'Fhr', value: getValueByKey(information, 'reviewApprover') }, // 复核人
        { name: 'BzTime', value: getValueByKey(information, 'compileDate'), type: TYPE.DATE }, // 编制时间
        { name: 'FhTime', value: getValueByKey(information, 'reviewDate'), type: TYPE.DATE }, // 复核时间
      ];
      // 额外字段
      const extraMap = {
        '淮北': [
          { name: 'ZbrNssbh', value: getValueByKey(information, 'tendereeTaxpayerIdentificationNo') }, // 招标人纳税识别号
          { name: 'ZxrNssbh', value: getValueByKey(information, 'costConsultantTaxpayerIdentificationNo') }, // 造价咨询人纳税识别号
          { name: 'ZbrDbSfzh', value: getValueByKey(information, 'tenderAuthorizerIDNo') }, // 招标人法定代表人或其授权人身份证号
          { name: 'ZxrDbSfzh', value: getValueByKey(information, 'consultantAuthorizerTaxpayerIdentificationNo') }, // 造价咨询人法定代表或其授权人纳税识别号
        ],
        '铜陵': [
          { name: 'ZbrNssbh', value: getValueByKey(information, 'tendereeTaxpayerIdentificationNo') }, // 招标人纳税识别号
          { name: 'ZxrNssbh', value: getValueByKey(information, 'costConsultantTaxpayerIdentificationNo') }, // 造价咨询人纳税识别号
          { name: 'ZbrDbSfzh', value: getValueByKey(information, 'tenderAuthorizerIDNo') }, // 招标人法定代表人或其授权人身份证号
          { name: 'ZxrDbSfzh', value: getValueByKey(information, 'consultantAuthorizerTaxpayerIdentificationNo') }, // 造价咨询人法定代表或其授权人纳税识别号
        ],
        '亳州': [
          { name: 'ZbrNssbh', value: getValueByKey(information, 'tendereeTaxpayerIdentificationNo') }, // 招标人纳税识别号
          { name: 'ZxrNssbh', value: getValueByKey(information, 'costConsultantTaxpayerIdentificationNo') }, // 造价咨询人纳税识别号
          { name: 'ZbrDbSfzh', value: getValueByKey(information, 'tenderAuthorizerIDNo') }, // 招标人法定代表人或其授权人身份证号
          { name: 'ZxrDbSfzh', value: getValueByKey(information, 'consultantAuthorizerTaxpayerIdentificationNo') }, // 造价咨询人法定代表或其授权人纳税识别号
        ],
        '六安': [
          { name: 'ZbrNssbh', value: getValueByKey(information, 'tendereeTaxpayerIdentificationNo') }, // 招标人纳税识别号
          { name: 'ZxrNssbh', value: getValueByKey(information, 'costConsultantTaxpayerIdentificationNo') }, // 造价咨询人纳税识别号
          { name: 'ZbrDbSfzh', value: getValueByKey(information, 'tenderAuthorizerIDNo') }, // 招标人法定代表人或其授权人身份证号
          { name: 'ZxrDbSfzh', value: getValueByKey(information, 'consultantAuthorizerTaxpayerIdentificationNo') }, // 造价咨询人法定代表或其授权人纳税识别号
        ],
        '张掖': [
          { name: 'ZbrNssbh', value: getValueByKey(information, 'tendereeTaxpayerIdentificationNo') }, // 招标人纳税识别号
          { name: 'ZxrNssbh', value: getValueByKey(information, 'costConsultantTaxpayerIdentificationNo') }, // 造价咨询人纳税识别号
          { name: 'ZbrDbSfzh', value: getValueByKey(information, 'tenderAuthorizerIDNo') }, // 招标人法定代表人或其授权人身份证号
          { name: 'ZxrDbSfzh', value: getValueByKey(information, 'consultantAuthorizerTaxpayerIdentificationNo') }, // 造价咨询人法定代表或其授权人纳税识别号
        ],
        '安庆': [
          { name: 'ZbrNssbh', value: '' }, // 招标人纳税识别号
          { name: 'ZxrNssbh', value: '' }, // 造价咨询人纳税识别号
          { name: 'ZbrDbSfzh', value: '' }, // 招标人法定代表人或其授权人身份证号
          { name: 'ZxrDbSfzh', value: '' }, // 造价咨询人法定代表或其授权人纳税识别号
        ],
      };
      if (extraMap[subArea]) {
        attrs.push(...extraMap[subArea]);
      }
      Element.call(this, 'ZhaoBiaoXx', attrs);
    }

    // 招标控制价信息
    function ZhaoBiaoKzXx(information, totalCost) {
      const attrs = [
        { name: 'Zbr', value: getValueByKey(information, 'tendereeName') }, // 招标人
        { name: 'Zxr', value: getValueByKey(information, 'costConsultant') }, // 造价咨询人
        { name: 'ZbrDb', value: getValueByKey(information, 'tenderAuthorizer') }, // 招标人法定代表人或其授权人
        { name: 'ZxrDb', value: getValueByKey(information, 'consultantAuthorizer') }, // 造价咨询人法定代表人或其授权人
        { name: 'Bzr', value: getValueByKey(information, 'compileApprover') }, // 编制人
        { name: 'Fhr', value: getValueByKey(information, 'reviewApprover') }, // 复核人
        { name: 'BzTime', value: getValueByKey(information, 'compileDate'), type: TYPE.DATE }, // 编制时间
        { name: 'FhTime', value: getValueByKey(information, 'reviewDate'), type: TYPE.DATE }, // 复核时间
        { name: 'Zbkzj', value: totalCost, type: TYPE.DECIMAL }, // 控制价总价（元），取“投标报价”的金额。
      ];
      // 额外字段
      const extraMap = {
        '淮北': [
          { name: 'ZbrNssbh', value: getValueByKey(information, 'tendereeTaxpayerIdentificationNo') }, // 招标人纳税识别号
          { name: 'ZxrNssbh', value: getValueByKey(information, 'costConsultantTaxpayerIdentificationNo') }, // 造价咨询人纳税识别号
          { name: 'ZbrDbSfzh', value: getValueByKey(information, 'tenderAuthorizerIDNo') }, // 招标人法定代表人或其授权人身份证号
          { name: 'ZxrDbSfzh', value: getValueByKey(information, 'consultantAuthorizerTaxpayerIdentificationNo') }, // 造价咨询人法定代表或其授权人纳税识别号
        ],
        '铜陵': [
          { name: 'ZbrNssbh', value: getValueByKey(information, 'tendereeTaxpayerIdentificationNo') }, // 招标人纳税识别号
          { name: 'ZxrNssbh', value: getValueByKey(information, 'costConsultantTaxpayerIdentificationNo') }, // 造价咨询人纳税识别号
          { name: 'ZbrDbSfzh', value: getValueByKey(information, 'tenderAuthorizerIDNo') }, // 招标人法定代表人或其授权人身份证号
          { name: 'ZxrDbSfzh', value: getValueByKey(information, 'consultantAuthorizerTaxpayerIdentificationNo') }, // 造价咨询人法定代表或其授权人纳税识别号
        ],
        '亳州': [
          { name: 'ZbrNssbh', value: getValueByKey(information, 'tendereeTaxpayerIdentificationNo') }, // 招标人纳税识别号
          { name: 'ZxrNssbh', value: getValueByKey(information, 'costConsultantTaxpayerIdentificationNo') }, // 造价咨询人纳税识别号
          { name: 'ZbrDbSfzh', value: getValueByKey(information, 'tenderAuthorizerIDNo') }, // 招标人法定代表人或其授权人身份证号
          { name: 'ZxrDbSfzh', value: getValueByKey(information, 'consultantAuthorizerTaxpayerIdentificationNo') }, // 造价咨询人法定代表或其授权人纳税识别号
        ],
        '六安': [
          { name: 'ZbrNssbh', value: getValueByKey(information, 'tendereeTaxpayerIdentificationNo') }, // 招标人纳税识别号
          { name: 'ZxrNssbh', value: getValueByKey(information, 'costConsultantTaxpayerIdentificationNo') }, // 造价咨询人纳税识别号
          { name: 'ZbrDbSfzh', value: getValueByKey(information, 'tenderAuthorizerIDNo') }, // 招标人法定代表人或其授权人身份证号
          { name: 'ZxrDbSfzh', value: getValueByKey(information, 'consultantAuthorizerTaxpayerIdentificationNo') }, // 造价咨询人法定代表或其授权人纳税识别号
        ],
        '张掖': [
          { name: 'ZbrNssbh', value: getValueByKey(information, 'tendereeTaxpayerIdentificationNo') }, // 招标人纳税识别号
          { name: 'ZxrNssbh', value: getValueByKey(information, 'costConsultantTaxpayerIdentificationNo') }, // 造价咨询人纳税识别号
          { name: 'ZbrDbSfzh', value: getValueByKey(information, 'tenderAuthorizerIDNo') }, // 招标人法定代表人或其授权人身份证号
          { name: 'ZxrDbSfzh', value: getValueByKey(information, 'consultantAuthorizerTaxpayerIdentificationNo') }, // 造价咨询人法定代表或其授权人纳税识别号
        ],
        '安庆': [
          { name: 'ZbrNssbh', value: '' }, // 招标人纳税识别号
          { name: 'ZxrNssbh', value: '' }, // 造价咨询人纳税识别号
          { name: 'ZbrDbSfzh', value: '' }, // 招标人法定代表人或其授权人身份证号
          { name: 'ZxrDbSfzh', value: '' }, // 造价咨询人法定代表或其授权人纳税识别号
        ],
      };
      if (extraMap[subArea]) {
        attrs.push(...extraMap[subArea]);
      }
      Element.call(this, 'ZhaoBiaoKzXx', attrs);
    }

    // 招标控制价信息
    function TouBiaoXx(information, totalCost) {
      const attrs = [
        { name: 'Zbr', value: getValueByKey(information, 'tendereeName') }, // 招标人
        { name: 'Tbr', value: getValueByKey(information, 'bidder') }, // 投标人
        { name: 'TbrDb', value: getValueByKey(information, 'bidderAuthorizer') }, // 投标人法定代表或其授权
        { name: 'Bzr', value: getValueByKey(information, 'compileApprover') }, // 编制人
        { name: 'BzTime', value: getValueByKey(information, 'compileDate'), type: TYPE.DATE }, // 编制时间
        { name: 'Tbzj', value: totalCost, type: TYPE.DECIMAL }, // 控制价总价（元），取“投标报价”的金额。
      ];
      // 额外字段
      const extraMap = {
        '淮北': [
          { name: 'ZbrNssbh', value: getValueByKey(information, 'tendereeTaxpayerIdentificationNo') }, // 招标人纳税识别号
          { name: 'TbrNssbh', value: getValueByKey(information, 'bidderTaxpayerIdentificationNo') }, // 投标人纳税识别号
          { name: 'TbrDbSfzh', value: getValueByKey(information, 'bidderAuthorizerTaxpayerIdentificationNo') }, // 投标人法定代表或其授权人身份证号
        ],
        '铜陵': [
          { name: 'ZbrNssbh', value: getValueByKey(information, 'tendereeTaxpayerIdentificationNo') }, // 招标人纳税识别号
          { name: 'TbrNssbh', value: getValueByKey(information, 'bidderTaxpayerIdentificationNo') }, // 投标人纳税识别号
          { name: 'TbrDbSfzh', value: getValueByKey(information, 'bidderAuthorizerTaxpayerIdentificationNo') }, // 投标人法定代表或其授权人身份证号
        ],
        '亳州': [
          { name: 'ZbrNssbh', value: getValueByKey(information, 'tendereeTaxpayerIdentificationNo') }, // 招标人纳税识别号
          { name: 'TbrNssbh', value: getValueByKey(information, 'bidderTaxpayerIdentificationNo') }, // 投标人纳税识别号
          { name: 'TbrDbSfzh', value: getValueByKey(information, 'bidderAuthorizerTaxpayerIdentificationNo') }, // 投标人法定代表或其授权人身份证号
        ],
        '六安': [
          { name: 'ZbrNssbh', value: getValueByKey(information, 'tendereeTaxpayerIdentificationNo') }, // 招标人纳税识别号
          { name: 'TbrNssbh', value: getValueByKey(information, 'bidderTaxpayerIdentificationNo') }, // 投标人纳税识别号
          { name: 'TbrDbSfzh', value: getValueByKey(information, 'bidderAuthorizerTaxpayerIdentificationNo') }, // 投标人法定代表或其授权人身份证号
        ],
        '张掖': [
          { name: 'ZbrNssbh', value: getValueByKey(information, 'tendereeTaxpayerIdentificationNo') }, // 招标人纳税识别号
          { name: 'TbrNssbh', value: getValueByKey(information, 'bidderTaxpayerIdentificationNo') }, // 投标人纳税识别号
          { name: 'TbrDbSfzh', value: getValueByKey(information, 'bidderAuthorizerTaxpayerIdentificationNo') }, // 投标人法定代表或其授权人身份证号
        ],
        '安庆': [
          { name: 'ZbrNssbh', value: '' }, // 招标人纳税识别号
          { name: 'TbrNssbh', value: '' }, // 投标人纳税识别号
          { name: 'TbrDbSfzh', value: '' }, // 投标人法定代表或其授权人身份证号
        ],
      };
      if (extraMap[subArea]) {
        attrs.push(...extraMap[subArea]);
      }
      Element.call(this, 'TouBiaoXx', attrs);
    }

    // 单项工程信息，因项目管理中无“单项工程”这一层，从单位工程的工程特征信息中拼凑出来
    function Dxgcxx(code, name) {
      const attrs = [
        { name: 'Dxgcbh', value: code, minLen: 1, whiteSpace: WHITE_SPACE.COLLAPSE }, // 单项工程编号
        { name: 'Dxgcmc', value: name }, // 单项工程名称
      ];
      Element.call(this, 'Dxgcxx', attrs);
    }

    // 单位工程信息
    function Dwgcxx(tenderName, feature) {
      const attrs = [
        { name: 'Dwgcbh', value: getValueByKey(feature, 'unitProjNo'), minLen: 1, whiteSpace: WHITE_SPACE.COLLAPSE }, // 单位工程编号
        { name: 'Dwgcmc', value: tenderName }, // 单位工程名称
      ];
      Element.call(this, 'Dwgcxx', attrs);
    }

    // 取费信息（费率信息）
    function Qfxx() {
      Element.call(this, 'Qfxx');
    }

    // 计价费率表
    function JjFlb() {
      Element.call(this, 'JjFlb');
    }

    // 费率明细名称-编码映射表
    const FeeRateCodeMap = {
      '冬季施工增加费': 'DJF',
      '雨季施工增加费': 'YJF',
      '夜间施工增加费': 'YEF',
      '工地转移费': 'ZYF',
      '高原地区施工增加费': 'GYF',
      '风沙地区施工增加费': 'FSF',
      '沿海地区施工增加费': 'YHF',
      '行车干扰施工增加费': 'XCF',
      '施工辅助费': 'SFF',
      '养老保险费': 'YLF',
      '失业保险费': 'SYF',
      '医疗保险费': 'YBF',
      '住房公积金': 'ZFF',
      '工伤保险费': 'GSF',
      '基本费用': 'JBF',
      '主副食运费补贴': 'YFF',
      '职工探亲路费': 'TQF',
      '职工取暖补贴': 'QNF',
      '财务费用': 'CWF',
      '利润': 'LR',
      '税金': 'SJ',
    };
    // 费率工程名称-取费类别映射表
    const FeeRateTypeMap = {
      '土方': 1,
      '路基': 1,
      '石方': 3,
      '运输': 2,
      '路面': 4,
      '隧道': 11,
      '构造物Ⅰ': 5,
      '构造物Ⅰ(不计冬)': 16,
      '构造物Ⅱ': 6,
      '构造物Ⅲ(桥梁)': 9,
      '桥梁': 9,
      '构造物Ⅲ(除桥以外不计雨夜)': 8,
      '技术复杂大桥': 10,
      '钢材及钢结构(桥梁)': 12,
      '钢材及钢结构': 12,
      '钢材及钢结构(除桥以外不计夜)': 13,
      '费率为0': 17,
      '路面(不计雨)': 18,
      '构造物Ⅰ(不计雨)': 19,
      '构造物Ⅲ(除桥以外)': 7,
      '钢材及钢结构(除桥以外)': 20,
      '设备': 15,
      '量价': 14,
    };

    // 计价费率表明细，造价书费率页面左侧最底层数据
    function JjFlbMx(rootItem, item) {
      const rate = isEmptyVal(item.rate) ? '100' : item.rate; // 为空时输出=100，为0时输出=0
      const attrs = [
        { name: 'Bm', value: FeeRateCodeMap[item.name] }, // 编码
        { name: 'Name', value: item.name }, // 名称
        { name: 'Fl', value: rate, type: TYPE.DECIMAL }, // 费率
        { name: 'Qflb', value: FeeRateTypeMap[rootItem.name], type: TYPE.INT }, // 取费类别
      ];
      Element.call(this, 'JjFlbMx', attrs);
    }

    // 计价费率项
    function JjFlx() {
      Element.call(this, 'JjFlx');
    }

    // 计价费率项明细，造价书费率页面右侧最顶层数据
    function JjFlxMx(item) {
      // 编码取名称拼音首字母
      const allHanName = getHan(item.name || '');
      const code = pinyinUtil.getFirstLetter(allHanName).toLowerCase();
      let value;
      if (isDef(item.value)) {
        value = item.value;
      } else {
        const selected = item.optionList.find(item => item.selected);
        value = selected && selected.name || '';
      }
      const attrs = [
        { name: 'Bm', value: code }, // 编码
        { name: 'Mc', value: item.name }, // 名称
        { name: 'ShuZhi', value: value }, // 数值
      ];
      Element.call(this, 'JjFlxMx', attrs);
    }

    // 清单项目
    function QdXm() {
      Element.call(this, 'QdXm');
    }
    // 标题类别：1=100~700清单合计，2=暂估价合计，3=清单不包含暂估价合计，4=计日工，5=暂列金额（不含计日工总额）），6=投标报价，0=其他
    const BillsTitleType = {
      [fixedFlag.ONE_SEVEN_BILLS]: '1',
      [fixedFlag.PROVISIONAL_TOTAL]: '2',
      [fixedFlag.BILLS_TOTAL_WT_PROV]: '3',
      [fixedFlag.DAYWORK_LABOR]: '4',
      [fixedFlag.PROVISIONAL]: '5',
      [fixedFlag.TOTAL_COST]: '6',
    };
    // 标题映射
    /*     写死:
    “第100章至700章清单”输出=1、
    “已包含在清单合计中的材料、工程设备、专业工程暂估价合计”输出=9、
    “清单合计减去材料、工程设备、专业工程暂估价合计”输出=10、
    “计日工合计”输出=11、
    “暂列金额(不含计日工总额)”输出=12、
    “投标报价”输出=13；
    如果有新增的同级的大项费用，则以14开始编号 */
    const BillsTitleValue = {
      [fixedFlag.ONE_SEVEN_BILLS]: '1',
      [fixedFlag.PROVISIONAL_TOTAL]: '9',
      [fixedFlag.BILLS_TOTAL_WT_PROV]: '10',
      [fixedFlag.DAYWORK_LABOR]: '11',
      [fixedFlag.PROVISIONAL]: '12',
      [fixedFlag.TOTAL_COST]: '13',
    };
    let curTitleValue;
    // 清单标题 造价书的第一层数据。
    function QdBt(node, allNodes) {
      const row = node.row();
      const orgFee = getFee(node.data.fees, 'common.tenderTotalFee');
      const fee = isBidInvitation ? '0' : orgFee;
      const flag = node.getFlag();
      // 编号：清单编码有值则直接取，无值则写死
      const bm = node.data.code || BillsTitleValue[flag] || curTitleValue++;
      const titleType = BillsTitleType[flag];
      const calcBase = titleType === '5'
        ? orgFee
        : node.data.calcBase
          ? cbParser.toFExpr(node.data.calcBase, allNodes)
          : '';
      const attrs = [
        { name: 'Xh', value: row, type: TYPE.INT }, // 序号
        { name: 'Bm', value: bm }, // 编码
        { name: 'Name', value: node.data.name }, // 名称
        { name: 'Je', value: fee, type: TYPE.DECIMAL }, // 金额
        { name: 'Code', value: `F${row}` }, // 行引用
        { name: 'Jsgs', value: calcBase }, // 计算基数
        { name: 'Lb', value: titleType, type: TYPE.INT }, // 类别
        { name: 'Bz', value: node.data.remark }, // 备注
      ];
      Element.call(this, 'QdBt', attrs);
    }

    // 清单明细 （只有100-700章清单标题输出）
    function QdMx(node, allNodes) {
      const row = node.row();
      const name = node.data.name || '';
      // 编码: 清单编码有值则取清单编码，无值则：清单非章级的，读取清单编码列。章级的清单，写死：“清单第100章总则”输出=100，“清单第200章”输出=200，依次类推。可以判断章级的，取清单名称中的数字。
      let code = node.data.code || '';
      if (!code) {
        const codeMatched = name.match(/第\s*(\d+)\s*章/);
        if (codeMatched && codeMatched[1]) {
          code = codeMatched[1];
        }
      }
      const iszg = node.data.specialProvisional === '专业工程';
      const calcBaseBeFee = iszg || node.getFlag() === fixedFlag.PROVISIONAL;
      const orgFee = getFee(node.data.fees, 'common.tenderTotalFee');
      const calcBase = calcBaseBeFee
        ? orgFee
        : node.data.calcBase
          ? cbParser.toFExpr(node.data.calcBase, allNodes)
          : '';
      const attrs = [
        { name: 'Xh', value: row, type: TYPE.INT }, // 序号
        { name: 'Qdbm', value: code, minLen: 1 }, // 编码
        { name: 'Name', value: node.data.name }, // 名称
        { name: 'Dw', value: node.data.unit }, // 单位
        { name: 'Sl', value: node.data.quantity, type: TYPE.DECIMAL }, // 工程量
        { name: 'Sl2', value: '0', type: TYPE.DECIMAL }, // 工程量2
        { name: 'Rgf', value: isBidInvitation ? '0' : getUnitFee(getFee(node.data.fees, 'marketLabour.tenderTotalFee'),node.data.quantity,2), type: TYPE.DECIMAL }, // 人工费
        { name: 'Clf', value: isBidInvitation ? '0' : getUnitFee(getFee(node.data.fees, 'marketMaterial.tenderTotalFee'),node.data.quantity,2), type: TYPE.DECIMAL }, // 材料费
        { name: 'Jxf', value: isBidInvitation ? '0' : getUnitFee(getFee(node.data.fees, 'marketMachine.tenderTotalFee'),node.data.quantity,2), type: TYPE.DECIMAL }, // 机械费
        { name: 'Sbf', value: isBidInvitation ? '0' : getUnitFee(getFee(node.data.fees, 'marketEquipment.tenderTotalFee'),node.data.quantity,2), type: TYPE.DECIMAL }, // 设备费
        { name: 'Csf', value: isBidInvitation ? '0' : getUnitFee(getFee(node.data.fees, 'measure.tenderTotalFee'),node.data.quantity,2), type: TYPE.DECIMAL }, // 措施费
        { name: 'Glf', value: isBidInvitation ? '0' : getUnitFee(getFee(node.data.fees, 'manage.tenderTotalFee'),node.data.quantity,2), type: TYPE.DECIMAL }, // 企业管理费
        { name: 'Gf', value: isBidInvitation ? '0' : getUnitFee(getFee(node.data.fees, 'force.tenderTotalFee'),node.data.quantity,2), type: TYPE.DECIMAL }, // 规费
        { name: 'Lr', value: isBidInvitation ? '0' : getUnitFee(getFee(node.data.fees, 'profit.tenderTotalFee'),node.data.quantity,2), type: TYPE.DECIMAL }, // 利润
        { name: 'Sj', value: isBidInvitation ? '0' : getUnitFee(getFee(node.data.fees, 'tax.tenderTotalFee'),node.data.quantity,2), type: TYPE.DECIMAL }, // 税金
        { name: 'Zhdj', value: isBidInvitation ? '0' : getFee(node.data.fees, 'common.tenderUnitFee'), type: TYPE.DECIMAL }, // 单价
        { name: 'Zhhj', value: isBidInvitation ? '0' : orgFee, type: TYPE.DECIMAL }, // 合价
        { name: 'Zgj', value: isBidInvitation ? '0' : getFee(node.data.fees, 'estimate.tenderTotalFee'), type: TYPE.DECIMAL }, // 暂估价
        { name: 'Iszg', value: iszg, type: TYPE.BOOL }, // 是否暂定 如果专项暂定列选择了“专业工程”，则输出true，否则是false。
        { name: 'Djfx', value: !!node.data.unitPriceAnalysis, type: TYPE.BOOL }, // 单价分析
        { name: 'Jsgs', value: calcBase }, // 计算基数
        { name: 'Bl', value: '' }, // 变量
        { name: 'Bz', value: node.data.remark }, // 备注
      ];
      Element.call(this, 'QdMx', attrs);
    }

    // 定额组价
    function Qdxdezj() {
      Element.call(this, 'Qdxdezj');
    }

    // 定额租价明细 招标文件不输出
    function QdxdezjMx(ration) {
      const typeMap = {
        [RationType.RATION]: '1',
        [RationType.VOLUME_PRICE + GljType.LABOUR]: '2',
        [RationType.VOLUME_PRICE + GljType.GENERAL_MATERIAL]: '3',
        [RationType.VOLUME_PRICE + GljType.GENERAL_MACHINE]: '4',
        [RationType.VOLUME_PRICE + GljType.EQUIPMENT]: '2',
      };
      const typeKey = (ration.type || '') + (ration.subType || '');
      const type = typeMap[typeKey];
      const attrs = [
        { name: 'Debm', value: ration.code }, // 编码
        { name: 'Mc', value: ration.name }, // 名称
        { name: 'Dw', value: ration.unit }, // 单位
        { name: 'Sl', value: ration.tenderQuantity, type: TYPE.DECIMAL }, // 工程量
        { name: 'Dj', value: getFee(ration.fees, 'common.tenderUnitFee'), type: TYPE.DECIMAL }, // 单价
        { name: 'Hj', value: getFee(ration.fees, 'common.tenderTotalFee'), type: TYPE.DECIMAL }, // 合价
        { name: 'Rgf', value: getUnitFee(getFee(ration.fees, 'marketLabour.tenderTotalFee'),ration.tenderQuantity,2), type: TYPE.DECIMAL }, // 人工费
        { name: 'Clf', value: getUnitFee(getFee(ration.fees, 'marketMaterial.tenderTotalFee'),ration.tenderQuantity,2), type: TYPE.DECIMAL }, // 材料费
        { name: 'Jxf', value: getUnitFee(getFee(ration.fees, 'marketMachine.tenderTotalFee'),ration.tenderQuantity,2), type: TYPE.DECIMAL }, // 机械费
        { name: 'Sbf', value: getUnitFee(getFee(ration.fees, 'marketEquipment.tenderTotalFee'),ration.tenderQuantity,2), type: TYPE.DECIMAL }, // 设备费
        { name: 'Csf', value: getUnitFee(getFee(ration.fees, 'measure.tenderTotalFee'),ration.tenderQuantity,2), type: TYPE.DECIMAL }, // 措施费
        { name: 'Glf', value: getUnitFee(getFee(ration.fees, 'manage.tenderTotalFee'),ration.tenderQuantity,2), type: TYPE.DECIMAL }, // 企业管理费
        { name: 'Gf', value: getUnitFee(getFee(ration.fees, 'force.tenderTotalFee'),ration.tenderQuantity,2), type: TYPE.DECIMAL }, // 规费
        { name: 'Lr', value: getUnitFee(getFee(ration.fees, 'profit.tenderTotalFee'),ration.tenderQuantity,2), type: TYPE.DECIMAL }, // 利润
        { name: 'Sj', value: getUnitFee(getFee(ration.fees, 'tax.tenderTotalFee'),ration.tenderQuantity,2), type: TYPE.DECIMAL }, // 税金
        { name: 'Delb', value: type, type: TYPE.INT }, // 取定额/量价/设备的类别。（1=普通定额，2=人工，3=材料，4=机械，5=设备）
        { name: 'Iszd', value: 'false', type: TYPE.BOOL }, // 暂时，全部取fals
      ];
      Element.call(this, 'QdxdezjMx', attrs);
    }

    // 定额人材机含量
    function Qdxdercjhl() {
      Element.call(this, 'Qdxdercjhl');
    }

    // 定额人材机含量明细
    function QdxdercjhlMx(rcjID, quantity) {
      const attrs = [
        { name: 'RcjId', value: rcjID }, // 人材机资源ID
        { name: 'Sl', value: quantity, type: TYPE.DECIMAL }, // 消耗量
      ]
      Element.call(this, 'QdxdercjhlMx', attrs);
    }

    // 清单人材机含量
    function Qdxrcjhl() {
      Element.call(this, 'Qdxrcjhl');
    }

    // 清单人材机含量明细
    function QdxrcjhlMx(item) {
      const attrs = [
        { name: 'RcjId', value: item.rcjID }, // 人材机资源ID
        { name: 'Rcjhl', value: item.contain, type: TYPE.DECIMAL }, // 含量：取叶子清单下所有的人材机的含量，=各定额下的人材机总消耗量之和，再除以清单工程量
        { name: 'Rcjhj', value: item.totalPrice, type: TYPE.DECIMAL }, // 合价：人材机含量*人材机预算价
        { name: 'Zgjbz', value: item.isEvaluate, type: TYPE.BOOL }, // 是否暂估,根据资源ID，读取工料机汇总界面对应的“是否暂估”
        { name: 'Zcbz', value: 'false', type: TYPE.BOOL }, // 主材标记，公路上无此概念，默认输出=fales
        { name: 'Zyclbz', value:  item.isMainMaterial, type: TYPE.BOOL }, // 根据资源ID，读取工料机汇总界面对应的“主要材料”
      ]
      Element.call(this, 'QdxrcjhlMx', attrs);
    }

    // 计日工
    function Jrg() {
      Element.call(this, 'Jrg');
    }

    // 计日工标题
    function JrgBt(node) {
      const typeMap = {
        [fixedFlag.LABOUR_SERVICE]: '1',
        [fixedFlag.MATERIAL]: '2',
        [fixedFlag.CONSTRUCTION_MACHINE]: '3',
      };
      const attrs = [
        { name: 'Name', value: node.data.name }, // 名称
        { name: 'Je', value: isBidInvitation ? '0' : getFee(node.data.fees, 'common.tenderTotalFee'), type: TYPE.DECIMAL }, // 金额
        { name: 'Lb', value: typeMap[node.getFlag()], type: TYPE.INT }, // 类别：1=劳务；2=材料；3=施工机械
        { name: 'Bz', value: node.data.remark }, // 备注
      ];
      Element.call(this, 'JrgBt', attrs);
    }

    // 计日工明细
    function JrgMx(node) {
      const attrs = [
        { name: 'Bh', value: node.data.code }, // 编码
        { name: 'Name', value: node.data.name }, // 名称
        { name: 'Dw', value: node.data.unit }, // 单位
        { name: 'Sl', value: node.data.quantity, type: TYPE.DECIMAL }, // 工程量
        { name: 'Dj', value: isBidInvitation ? '0' : getFee(node.data.fees, 'common.tenderTotalFee'), type: TYPE.DECIMAL }, // 单价
        { name: 'Hj', value: isBidInvitation ? '0' : getFee(node.data.fees, 'common.tenderUnitFee'), type: TYPE.DECIMAL }, // 合价
      ];
      Element.call(this, 'JrgMx', attrs);
    }

    // 暂估材料表、评标材料表
    function gljRefRoot(eleName) {
      Element.call(this, eleName);
    }

    // 暂估材料表、评标材料表明细
    function gljRefElement(eleName, glj) {
      const attrs = [
        { name: 'Xh', value: glj.seq }, // 序号
        { name: 'RcjId', value: projectGLJIDToRcjID[glj.projectGLJID] }, // 资源ID
        { name: 'Bm', value: glj.code }, // 编码
        { name: 'Mc', value: glj.name }, // 名称
        { name: 'Ggxh', value: glj.specs }, // 规格型号
        { name: 'Dw', value: glj.unit }, // 单位
        { name: 'Sl', value: BID_INVITATION ? '0' : glj.quantity, type: TYPE.DECIMAL }, // 工程量
        { name: 'Dj', value: glj.marketPrice, type: TYPE.DECIMAL }, // 暂定价、单价
        { name: 'Hj', value: BID_INVITATION ? '0' : glj.totalPrice, type: TYPE.DECIMAL }, // 合价
        { name: 'Bz', value: glj.remark }, // 备注
      ];
      Element.call(this, eleName, attrs);
    }

    // 人材机汇总
    function Rcjhz() {
      Element.call(this, 'Rcjhz');
    }

    // 人材机汇总明细
    function RcjhzMx(glj) {
      const rootTypeReg = /\d/;
      let rootType = rootTypeReg.exec(glj.type)[0];
      if (!['1', '2', '3'].includes(rootType)) {
        rootType = '2';
      }
      
      const attrs = [
        { name: 'RcjId', value: projectGLJIDToRcjID[glj.id] }, // 资源ID
        { name: 'RcjBm', value: glj.code }, // 编码
        { name: 'Name', value: glj.name }, // 名称
        { name: 'Ggxh', value: glj.specs }, // 规格型号
        { name: 'Dw', value: glj.unit }, // 单位
        { name: 'Dj', value: glj.priceInfo.tenderPrice, type: TYPE.DECIMAL }, // 预算价，调后
        { name: 'Sl', value: glj.tenderQuantity, type: TYPE.DECIMAL }, // 总消耗量
        { name: 'Hj', value: glj.priceInfo.totalPrice, type: TYPE.DECIMAL }, // 合价，人材料总消耗量*预算价
        { name: 'Cd', value: '' }, // 产地
        { name: 'Gycs', value: '' }, // 厂商
        { name: 'Rcjlb', value: rootType, type: TYPE.INT }, // 人材机类型 1=人工；2=材料；3=机械
        { name: 'Jgbz', value: 'false', type: TYPE.BOOL }, // 供材方
        { name: 'Zyclbz', value:  !!glj.is_main_material, type: TYPE.BOOL }, // 主要材料
        { name: 'Zgjbz', value: !!glj.is_evaluate, type: TYPE.BOOL }, // 是否暂估
        { name: 'Zcbz', value: 'false' , type: TYPE.BOOL }, // 主材标记
      ];
      console.log(!!glj.is_main_material);
      Element.call(this, 'RcjhzMx', attrs);
    }

    // 配比组成
    function PbZc() {
      Element.call(this, 'PbZc');
    }

    // 配比明细
    function PbZcMx(ratio) {
      const attrs = [
        { name: 'RcjId', value: projectGLJIDToRcjID[ratio.projectGLJID] }, // 组成物对应人材机汇总的资源ID
        { name: 'Sl', value: ratio.consumption, type: TYPE.DECIMAL }, // 组成物消耗量
      ];
      Element.call(this, 'PbZcMx', attrs);
    }

    // 校验信息
    function Jyxx(cpuID, diskID, macID, toMD5Value) {
      const attrs = [
        { name: 'SoftName', value: '珠海纵横创新软件有限公司' }, // 公司名
        { name: 'SoftNum', value: md5(toMD5Value) }, // 校验数据
        { name: 'MacAdress', value: macID }, // mac地址
        { name: 'DogNum', value: userID }, // 加密锁号，取用户ID
        { name: 'ComputerName', value: USER_NAME }, // 计算机名，取用户名称
        { name: 'HDDSerial', value: diskID }, // 硬盘序列号
        { name: 'CPUSerial', value: cpuID }, // CPU序列号
      ];
      Element.call(this, 'Jyxx', attrs);
    }

    // 组装数据 --------------------------------------

    // 组装建设项目数据
    function setupConstruction(constructionData) {
      const information = constructionData.property && constructionData.property.basicInformation || [];
      const summaryInfo = constructionData.summaryInfo[constructionData.ID];
      const jingJiBiao = new JingJiBiao(constructionData.name, information);
      if (isBidInvitation) {
        jingJiBiao.children.push(new ZhaoBiaoXx(information));
      } else if (isControl) {
        jingJiBiao.children.push(new ZhaoBiaoKzXx(information, summaryInfo.totalCost));
      } else {
        jingJiBiao.children.push(new TouBiaoXx(information, summaryInfo.totalCost));
      }
      // 将单位工程工程特征中，单项工程编号、名称相同的，插入到建设项目和分段（单位工程）的中间层。
      const midLayerMap = {}; // 单项工程key(code@name)与单项工程节点映射
      for (const tenderData of constructionData.children) {
        const feature = tenderData.property && tenderData.property.projectFeature || [];
        const midLayerCode = getValueByKey(feature, 'singleProjNo');
        const midLayerName = getValueByKey(feature, 'singleProjName');
        const midLayerKey = `${midLayerCode}@${midLayerName}`;
        if (!midLayerMap[midLayerKey]) {
          jingJiBiao.children.push(midLayerMap[midLayerKey] = new Dxgcxx(midLayerCode, midLayerName));
        }
        midLayerMap[midLayerKey].children.push(setupTender(tenderData, information, feature));
      }
      // 校验信息
      const [cpuID, diskID, macID] = generateHardwareId().split(';');
      const suffix = INTERFACE_CONFIG[areaKey]['fileSuffix'][exportKind];
      // 需要md5的值：MD5（“WHGLZTB”+项目名称+机器码+加密锁锁号）机器码取mac地址，加密锁锁号取用户账号id
      const toMD5Suffix = suffix.split('.')[1];
      const toMD5Value = `${toMD5Suffix}${constructionData.name}${macID}${userID}`;
      jingJiBiao.children.push(new Jyxx(cpuID, diskID, macID, suffix, toMD5Value));
      return [{
        data: jingJiBiao,
        exportKind,
        fileName: `${constructionData.name}${suffix}`
      }];
    }

    // getData接口数据
    let curDetail;

    // 需要先设置项目人材机的关联ID(从1开始)，因为定额人材机等一些节点需要用到这个关联ID
    const projectGLJIDToRcjID = {}; // 项目人材机ID与新生成的整形ID映射
    const projectGLJMap = {}; // 项目人材机与项目人材机数据映射

    // 组装单位工程数据
    function setupTender(tenderData, info, feature) {
      curDetail = tenderDetailMap[tenderData.ID];
      curDetail.projectGLJ.datas.gljList.forEach((glj, index) => {
        projectGLJIDToRcjID[glj.id] = index + 1;
        projectGLJMap[glj.id] = glj;
      });
      curTitleValue = 14;
      const dwgcxx = new Dwgcxx(tenderData.name, feature);
      dwgcxx.children.push(
        setupFeeRate(curDetail.FeeRate, info),
        setupBills(curDetail.mainTree),
        ...setupGLJList(curDetail)
      );
      return dwgcxx;
    }

    // 组装费率数据
    function setupFeeRate(feeRateDetail, info) {
      const qfxx = new Qfxx();
      const jjflb = new JjFlb();
      // 费率界面左侧底层数据
      let curRootItem;
      feeRateDetail.datas.rates.forEach(item => {
        if (!item.ParentID) {
          curRootItem = item;
        } else if (!item.sum) { // 最底层
          const curFeeRateType = FeeRateTypeMap[curRootItem.name];
          const exclude = [18, 19, 20];
          if (!exclude.includes(curFeeRateType)) {
            jjflb.children.push(new JjFlbMx(curRootItem, item));
          }
        }
      });
      // 费率界面右侧顶层数据
      // 除右侧数据外，还应拼凑工程所在地、费率标准的数据。
      const jjflx = new JjFlx();
      // 工程所在地取建设项目-基本信息中的“工程所在地”；
      const locationItem = { name: '工程所在地', value: getValueByKey(info, 'location') };
      jjflx.children.push(new JjFlxMx(locationItem));
      // 费率标准取，费率-重选标准中当前用的费率标准名称。
      const feeRateStandardItem = { name: '费率标准', value: feeRateDetail.datas.libName };
      jjflx.children.push(new JjFlxMx(feeRateStandardItem));
      const flxmxData = feeRateDetail
        .getAllSubRates()
        .filter(item => !item.isSub)
        .map(item => new JjFlxMx(item));
      jjflx.children.push(...flxmxData);

      qfxx.children.push(jjflb, jjflx);
      return qfxx;
    }

    // 组装清单数据
    function setupBills(mainTree) {
      const qdxm = new QdXm();
      mainTree.roots.forEach(node => {
        const flag = node.getFlag();
        const qdbt = new QdBt(node, mainTree.items);
        if (flag === fixedFlag.ONE_SEVEN_BILLS) { // 100章到700章清单需要输出详细数据
          qdbt.children.push(...setupSubBills(node.children, mainTree.items));
        } else if (flag === fixedFlag.DAYWORK_LABOR) {
          qdbt.children.push(setupDaywork(node.children));
        }
        qdxm.children.push(qdbt);
      });

      function setupSubBills(nodes, allNodes) {
        const rst = [];
        nodes.forEach(node => {
          const qdmx = new QdMx(node, allNodes);
          rst.push(qdmx);
          const subIsRations = node.children.length && !node.source.children.length;
          if (subIsRations) {
            qdmx.children.push(...setupRations(node.children));
            qdmx.children.push(...setupBillsContain(node.data,node.children));
          } else {
            qdmx.children.push(...setupSubBills(node.children, allNodes));
          }
        });
        return rst;
      }

      function setupDaywork(nodes) {
        const dayworkRoot = new Jrg();
        const dayworkBT = nodes.map(node => {
          const bt = new JrgBt(node);
          const dayworkMX = node.children.map(child => new JrgMx(child));
          bt.children.push(...dayworkMX);
          return bt;
        });
        dayworkRoot.children.push(...dayworkBT);
        return dayworkRoot;
      }

      return qdxm;
    }
    

    // 组装定额、定额人材机数据
    function setupRations(rationNodes) {
      // 招标文件不输出
      if (isBidInvitation) {
        return [];
      }
      const rationRoot = new Qdxdezj();
      const rationEles = rationNodes.map(node => {
        const rationEle = new QdxdezjMx(node.data);
        /* // 定额人材机
        let rationGLJList = curDetail.ration_glj.datas.filter(glj => glj.rationID === node.data.ID);
        rationGLJList = gljUtil.sortRationGLJ(rationGLJList); */
        const rationGLJRoot = new Qdxdercjhl();
        const rationGLJEles = node.data.rationGLJList.map(glj => new QdxdercjhlMx(projectGLJIDToRcjID[glj.projectGLJID], glj.tenderQuantity));
        rationGLJRoot.children.push(...rationGLJEles);
        rationEle.children.push(rationGLJRoot);
        return rationEle;
      });
      rationRoot.children.push(...rationEles);
      return [rationRoot];
    }

    // 组装清单人材机含量数据
    function setupBillsContain(bills,rationNodes) {
      if (isBidInvitation) {
        return [];
      }
      const rationIDMap = {};
      for(const node of rationNodes){
        rationIDMap[node.data.ID] = node.data;
      }
      // 读取清单下的人材机，先将各定额下的人材机汇总，相同的合并（相同的项目人材机ID）
      const gljList = curDetail.ration_glj.datas.filter(glj => glj.billsItemID === bills.ID);
      if (!gljList) {
        return [];
      }
      const map = {};
      gljList.forEach(glj => {
        if (!map[glj.projectGLJID]) {
          const projectGLJ = projectGLJMap[glj.projectGLJID];
          map[glj.projectGLJID] = {
            rcjID: projectGLJIDToRcjID[glj.projectGLJID],
            totalQuantity: !!rationIDMap[glj.rationID]?gljOprObj.getTotalQuantity(glj,rationIDMap[glj.rationID]):0 ,
            price: projectGLJ.priceInfo.tenderPrice,
            isEvaluate: !!projectGLJ.is_evaluate,
            isMainMaterial: !!projectGLJ.is_main_material
          };
        } else {
          const subQuantity = !!rationIDMap[glj.rationID]?gljOprObj.getTotalQuantity(glj,rationIDMap[glj.rationID]):0;
          map[glj.projectGLJID].totalQuantity = scMathUtil.roundTo(map[glj.projectGLJID].totalQuantity + subQuantity, -6);
        }
      });
      const containItems = Object
        .values(map)
        .map(glj => {
          const contain = glj.totalQuantity / (bills.quantity || 1);
          return {
            rcjID: glj.rcjID,
            contain: scMathUtil.roundTo(contain, -6), // 固定取6位
            totalPrice: scMathUtil.roundTo(contain * glj.price, -2), // 固定取2位
            isEvaluate: glj.isEvaluate,
            isMainMaterial: glj.isMainMaterial
          };
        });
      const root = new Qdxrcjhl();
      root.children.push(...containItems.map(item => new QdxrcjhlMx(item)));
      return [root]
    }

    // 组装人材机汇总相关表数据
    function setupGLJList(tenderDetail) {
      // 暂估材料
      const zgcl = new gljRefRoot('ZgCl');
      zgcl.children = tenderDetail.evaluateMaterialData.map(glj => new gljRefElement('ZgClMx', glj));

      // 评标材料
      const jpcl = new gljRefRoot('JpCl');
      jpcl.children = tenderDetail.bidMaterialData.map(glj => new gljRefElement('JpClMx', glj));
      if (isBidInvitation) {
        return [zgcl, jpcl];
      }
      // 人材机汇总 (招标不导出)
      const rcjhz = new Rcjhz();
      rcjhz.children = tenderDetail.projectGLJ.datas.gljList.map(pGLJ => {
        const gljElement = new RcjhzMx(pGLJ);
        // 组成物
        const connectKey = gljUtil.getIndex(pGLJ, gljKeyArray);
        const ratioData = tenderDetail.projectGLJ.datas.mixRatioMap[connectKey];
        if (ratioData && ratioData.length) {
          const pbzc = new PbZc();
          pbzc.children = ratioData.map(ratio => new PbZcMx(ratio));
          gljElement.children.push(pbzc);
        }
        return gljElement;
      });
      return [zgcl, jpcl, rcjhz];
    }

    return setupConstruction(projectData);


  }

  return {
    entry,
  };
})();
