|  | @@ -1174,7 +1174,7 @@ const XMLStandard = (function () {
 | 
	
		
			
				|  |  |              tender.children.push(loadCSXM(tenderDetail));
 | 
	
		
			
				|  |  |              //其他项目清单
 | 
	
		
			
				|  |  |              let other = loadOtherBills(tenderDetail);
 | 
	
		
			
				|  |  | -            if (other) {
 | 
	
		
			
				|  |  | +            if (other && other.children.length) {
 | 
	
		
			
				|  |  |                  tender.children.push(other);
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |              //规费和税金清单
 | 
	
	
		
			
				|  | @@ -1630,6 +1630,15 @@ const XMLStandard = (function () {
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 过滤其他项目子清单空行
 | 
	
		
			
				|  |  | +        // 空行判断条件:编码、名称、单位都是空,综合合价=0或空,则判断为空行。
 | 
	
		
			
				|  |  | +        function filterEmptyNodes(nodes) {
 | 
	
		
			
				|  |  | +            return nodes.filter(c => {
 | 
	
		
			
				|  |  | +                return c.data.code || c.data.name || c.data.unit || _util.getFee(c.data.fees, 'common.totalFee');
 | 
	
		
			
				|  |  | +            });
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          /*
 | 
	
		
			
				|  |  |           * 加载其他项目清单,要出现此节点,需要遵循标准条件(至少含有一条相关明细)
 | 
	
		
			
				|  |  |           * @param {Object}detail
 | 
	
	
		
			
				|  | @@ -1644,18 +1653,18 @@ const XMLStandard = (function () {
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |              //添加暂列金额元素
 | 
	
		
			
				|  |  |              let provisionalNode = detail.Bills.tree.items.find(node => node.getFlag() === fixedFlag.PROVISIONAL);
 | 
	
		
			
				|  |  | -            if (provisionalNode && provisionalNode.children.length > 0) {
 | 
	
		
			
				|  |  | +            if (provisionalNode && _util.getFee(provisionalNode.data.fees, 'common.totalFee') && filterEmptyNodes(provisionalNode.children).length > 0) {
 | 
	
		
			
				|  |  |                  otherEle.children.push(loadProvisional(provisionalNode));
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |              //添加专业工程暂估价元素
 | 
	
		
			
				|  |  |              let engEstimateNode = detail.Bills.tree.items.find(node => node.getFlag() === fixedFlag.ENGINEERING_ESITIMATE);
 | 
	
		
			
				|  |  | -            if (engEstimateNode && engEstimateNode.children.length > 0) {
 | 
	
		
			
				|  |  | +            if (engEstimateNode && _util.getFee(engEstimateNode.data.fees, 'common.totalFee') && filterEmptyNodes(engEstimateNode.children).length > 0) {
 | 
	
		
			
				|  |  |                  otherEle.children.push(loadEngEstimate(engEstimateNode));
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |              //添加计日工元素
 | 
	
		
			
				|  |  |              let dayWorkNode = detail.Bills.tree.items.find(node => node.getFlag() === fixedFlag.DAYWORK);
 | 
	
		
			
				|  |  |              let dayWorkEle = new DayWork({fees: dayWorkNode.data.fees});
 | 
	
		
			
				|  |  | -            if (dayWorkNode && dayWorkNode.children.length > 0) {
 | 
	
		
			
				|  |  | +            if (dayWorkNode && _util.getFee(dayWorkNode.data.fees, 'common.totalFee') && dayWorkNode.children.length > 0) {
 | 
	
		
			
				|  |  |                  //要显示计日工元素,人工、材料、施工机械,最少有一条含有子项(计日工项目)
 | 
	
		
			
				|  |  |                  let filterNodes = dayWorkNode.children.filter(node => [fixedFlag.LABOUR, fixedFlag.MATERIAL, fixedFlag.MACHINE].includes(node.getFlag()));
 | 
	
		
			
				|  |  |                  for (let fNode of filterNodes) {
 | 
	
	
		
			
				|  | @@ -1672,12 +1681,13 @@ const XMLStandard = (function () {
 | 
	
		
			
				|  |  |                          ele = new Machine();
 | 
	
		
			
				|  |  |                          constraints = curTenderEle.constraints.machineDayWorkCode;
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  | -                    if (fNode.children.length > 0) {
 | 
	
		
			
				|  |  | +                    const fNodeChildren = filterEmptyNodes(fNode.children);
 | 
	
		
			
				|  |  | +                    if (_util.getFee(fNode.data.fees, 'common.totalFee') && fNodeChildren.length > 0) {
 | 
	
		
			
				|  |  |                          let isValidDepth = _util.validDepth(1, fNode);
 | 
	
		
			
				|  |  |                          if (!isValidDepth) {
 | 
	
		
			
				|  |  |                              _failList.push(`计日工${ele.name}子项超过一层`);
 | 
	
		
			
				|  |  |                          } else {
 | 
	
		
			
				|  |  | -                            for (let itemNode of fNode.children) {
 | 
	
		
			
				|  |  | +                            for (let itemNode of fNodeChildren) {
 | 
	
		
			
				|  |  |                                  ele.children.push(loadDayWorkItem(itemNode, constraints, `${ele.name}计日工项目编号`));
 | 
	
		
			
				|  |  |                              }
 | 
	
		
			
				|  |  |                              dayWorkEle.children.push(ele);
 | 
	
	
		
			
				|  | @@ -1691,33 +1701,36 @@ const XMLStandard = (function () {
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |              //添加总承包服务费元素
 | 
	
		
			
				|  |  |              let tkcNode = detail.Bills.tree.items.find(node => node.getFlag() === fixedFlag.TURN_KEY_CONTRACT);
 | 
	
		
			
				|  |  | -            if (tkcNode && tkcNode.children.length > 0) {  //必须要有子项才显示总承包服务费元素
 | 
	
		
			
				|  |  | +            const tkcChildren = filterEmptyNodes(tkcNode.children);
 | 
	
		
			
				|  |  | +            if (tkcNode && _util.getFee(tkcNode.data.fees, 'common.totalFee') && tkcChildren.length > 0) {  //必须要有子项才显示总承包服务费元素
 | 
	
		
			
				|  |  |                  let isValidDepth = _util.validDepth(2, tkcNode);  //最多2层子项:总承包服务费分类-总承包服务费费用项
 | 
	
		
			
				|  |  |                  if (!isValidDepth) {
 | 
	
		
			
				|  |  |                      _failList.push('总承包服务费子项超过两层');
 | 
	
		
			
				|  |  |                  } else {
 | 
	
		
			
				|  |  |                      let tkcEle = new TurnKeyContract({fees: tkcNode.data.fees});
 | 
	
		
			
				|  |  |                      otherEle.children.push(tkcEle);
 | 
	
		
			
				|  |  | -                    loadService(tkcEle, tkcNode.children);
 | 
	
		
			
				|  |  | +                    loadService(tkcEle, tkcChildren);
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |              //添加索赔计价汇总元素
 | 
	
		
			
				|  |  |              let claimNode = detail.Bills.tree.items.find(node => node.getFlag() === fixedFlag.CLAIM);
 | 
	
		
			
				|  |  | -            if (claimNode && claimNode.children.length > 0) {   //必须要有子项才能显示索赔计价汇总元素
 | 
	
		
			
				|  |  | +            const claimChildren = filterEmptyNodes(claimNode.children);
 | 
	
		
			
				|  |  | +            if (claimNode && _util.getFee(claimNode.data.fees, 'common.totalFee') && claimChildren.length > 0) {   //必须要有子项才能显示索赔计价汇总元素
 | 
	
		
			
				|  |  |                  let claimEle = new XML_EXPORT_BASE.Element('索赔计价汇总', [
 | 
	
		
			
				|  |  |                      {name: '金额', value: _util.getFee(claimNode.data.fees, 'common.totalFee')}]);
 | 
	
		
			
				|  |  | -                for (let n of claimNode.children) {
 | 
	
		
			
				|  |  | +                for (let n of claimChildren) {
 | 
	
		
			
				|  |  |                      claimEle.children.push(new ClaimVisaFeeItem(n.data));
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |                  otherEle.children.push(claimEle);
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |              //添加现场签证计价汇总元素
 | 
	
		
			
				|  |  |              let visaNode = detail.Bills.tree.items.find(node => node.getFlag() === fixedFlag.VISA);
 | 
	
		
			
				|  |  | -            if (visaNode && visaNode.children.length > 0) {     //必须要有子项才能显示现场签证计价汇总元素
 | 
	
		
			
				|  |  | +            const visaChildren = filterEmptyNodes(visaNode.children);
 | 
	
		
			
				|  |  | +            if (visaNode && _util.getFee(visaNode.data.fees, 'common.totalFee') && visaChildren.length > 0) {     //必须要有子项才能显示现场签证计价汇总元素
 | 
	
		
			
				|  |  |                  let visaEle = new XML_EXPORT_BASE.Element('现场签证计价汇总', [
 | 
	
		
			
				|  |  |                      {name: '金额', value: _util.getFee(visaNode.data.fees, 'common.totalFee')}
 | 
	
		
			
				|  |  |                  ]);
 | 
	
		
			
				|  |  | -                for (let n of visaNode.children) {
 | 
	
		
			
				|  |  | +                for (let n of visaChildren) {
 | 
	
		
			
				|  |  |                      visaEle.children.push(new ClaimVisaFeeItem(n.data));
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |                  otherEle.children.push(visaEle);
 | 
	
	
		
			
				|  | @@ -1739,7 +1752,8 @@ const XMLStandard = (function () {
 | 
	
		
			
				|  |  |                  if (!isValidDepth) {
 | 
	
		
			
				|  |  |                      _failList.push('暂列金额子项超过一层');
 | 
	
		
			
				|  |  |                  } else {    //加载暂列金额明细
 | 
	
		
			
				|  |  | -                    for (let n of node.children) {
 | 
	
		
			
				|  |  | +                    const children = filterEmptyNodes(node.children);
 | 
	
		
			
				|  |  | +                    for (let n of children) {
 | 
	
		
			
				|  |  |                          let pDetailSource = {
 | 
	
		
			
				|  |  |                                  row: detail.mainTree.nodes[detail.mainTree.prefix + n.data.ID].serialNo() + 1,
 | 
	
		
			
				|  |  |                                  code: n.data.code,
 | 
	
	
		
			
				|  | @@ -1765,7 +1779,8 @@ const XMLStandard = (function () {
 | 
	
		
			
				|  |  |                  if (!isValidDepth) {
 | 
	
		
			
				|  |  |                      _failList.push('专业工程暂估价子项超过一层');
 | 
	
		
			
				|  |  |                  } else {    //加载专业工程暂估明细
 | 
	
		
			
				|  |  | -                    for (let n of node.children) {
 | 
	
		
			
				|  |  | +                    const children = filterEmptyNodes(node.children);
 | 
	
		
			
				|  |  | +                    for (let n of children) {
 | 
	
		
			
				|  |  |                          let eDetailSource = {
 | 
	
		
			
				|  |  |                                  row: detail.mainTree.nodes[detail.mainTree.prefix + n.data.ID].serialNo() + 1,
 | 
	
		
			
				|  |  |                                  code: n.data.code,
 |