Browse Source

四川养护2013、部颁2018计价标准,增加单价下浮功能

chenshilong 3 years atrás
parent
commit
50d39a89ff

+ 20 - 19
modules/all_models/bills.js

@@ -3,19 +3,19 @@
  */
 let mongoose = require("mongoose");
 let subSchema = require("../all_schemas/bills_sub_schemas");
-let deleteSchema = require('../all_schemas/delete_schema');
+let deleteSchema = require("../all_schemas/delete_schema");
 let Schema = mongoose.Schema;
 let billsSchema = new Schema({
   ID: {
     type: String,
-    index: true
+    index: true,
   },
-  "GUID": String, // 接口需要(导入导出不可变,因此不可用ID作为GUID)
+  GUID: String, // 接口需要(导入导出不可变,因此不可用ID作为GUID)
   ParentID: String,
   NextSiblingID: String,
   projectID: {
     type: Number,
-    index: true
+    index: true,
   },
   serialNo: Number,
   chapterID: Number,
@@ -25,11 +25,11 @@ let billsSchema = new Schema({
   fullCode: String,
   type: {
     type: Number,
-    default: 4
+    default: 4,
   }, //1 :大项费用 2:分部 3分项 4清单;5补项
   isAdd: {
     type: Number,
-    default: 0
+    default: 0,
   }, //1 true 0 false是否新增
   name: String,
   unit: String,
@@ -40,9 +40,10 @@ let billsSchema = new Schema({
   feeRate: String,
   isFromDetail: {
     type: Number,
-    default: 0
+    default: 0,
   }, //1 true 0 false
   programID: Number,
+  unitPriceCoe: String, // 单价浮动系数
   calcBase: String,
   calcBaseValue: String, // 计算基数表达式的值
   tenderCalcBaseValue: String, // 调价后计算基数表达式的值
@@ -81,37 +82,37 @@ let billsSchema = new Schema({
   // 不调价
   is_adjust_price: {
     type: Number,
-    default: 0
+    default: 0,
   },
   installationKey: String, //用来记录安装增加费的关联字段
   deleteInfo: deleteSchema,
   isEstimate: {
     type: Number,
-    default: 0
+    default: 0,
   }, // 1 true 0 false 是否暂估
   lockUnitPrice: {
     type: Schema.Types.Mixed,
-    default: false
+    default: false,
   }, //  true  false 锁定综合单价,true 为锁定
   unitPriceAnalysis: {
     type: Number,
-    default: 0
+    default: 0,
   }, // 1 true 0 false 单价分析
   specialProvisional: String,
-  outPutMaxPrice:{type:Schema.Types.Mixed,default:false},//输出最高限价 true 是,false否,null 不确定,三个状态
-  outPutLimitPrice:{type:Schema.Types.Mixed,default:false},//输出限价 true 是,false否,null 不确定,三个状态
-  appraisalBills:{type:Schema.Types.Mixed,default:false},//true 是,false否,null 不确定,三个状态
-  maxPrice:String,//最高限价
-  minPrice:String,//最低限价
+  outPutMaxPrice: { type: Schema.Types.Mixed, default: false }, //输出最高限价 true 是,false否,null 不确定,三个状态
+  outPutLimitPrice: { type: Schema.Types.Mixed, default: false }, //输出限价 true 是,false否,null 不确定,三个状态
+  appraisalBills: { type: Schema.Types.Mixed, default: false }, //true 是,false否,null 不确定,三个状态
+  maxPrice: String, //最高限价
+  minPrice: String, //最低限价
   remark: String,
   engineeringContent: String, //工程内容
   serviceContent: String, //服务内容
   claimVisa: String, //签证及索赔依据
   calcFlag: {
-    type: Number
+    type: Number,
   }, // 叶子清单的计算类型。末定义:按定额计算。1:用户输入金额。2:用户输入单价。3:用户输入设计单价。
   bookmarkBackground: String, //书签背景色
-  bookmarkAnnotation: String //批注
+  bookmarkAnnotation: String, //批注
 });
 
-mongoose.model("bills", billsSchema);
+mongoose.model("bills", billsSchema);

+ 18 - 11
web/building_saas/main/js/models/calc_program.js

@@ -1985,30 +1985,28 @@ class CalcProgram {
             sum_rtf = (sum_rtf + rtf).toDecimal(decimalObj.process);
             sum_rttf = (sum_rttf + rttf).toDecimal(decimalObj.process);
           }
-
-          buf = (sum_rtf / bq).toDecimal(decimalObj.process);
-          btuf = (sum_rttf / btq).toDecimal(decimalObj.process);
-          btf = sum_rtf;
-          bttf = sum_rttf;
+          btf = sum_rtf.toDecimal(decimalObj.bills.totalPrice);
+          bttf = sum_rttf.toDecimal(decimalObj.bills.totalPrice);
+          buf = (btf / bq).toDecimal(decimalObj.bills.unitPrice);
+          buf = billFloatUnitPrice(buf, treeNode);
+          btuf = (bttf / btq).toDecimal(decimalObj.bills.unitPrice);
         }
 
         // debugger;
         if (me.project.property.billsCalcMode == leafBillGetFeeType.rationPriceConverse && ["common", "rationCommon", "indexCommon"].includes(ft.type)) {
           // 招投标项目, 还要反算
           // 9-24 新需求 开放正算反算选项,按选项判断
-          buf = buf.toDecimal(decimalObj.bills.unitPrice);
-          btuf = btuf.toDecimal(decimalObj.bills.unitPrice);
           btf = (buf * nQ).toDecimal(decimalObj.bills.totalPrice);
           bttf = (btuf * nQ).toDecimal(decimalObj.bills.totalPrice);
         }
       }
 
-      ftObj.totalFee = btf.toDecimal(decimalObj.bills.totalPrice);
-      ftObj.tenderTotalFee = bttf.toDecimal(decimalObj.bills.totalPrice);
+      ftObj.totalFee = btf;
+      ftObj.tenderTotalFee = bttf;
       // 需求变更:BUG #2980 预算项目类型,造价书大项费用的经济指标,在有数量有金额的情况下要反算求值(等于金额/数量),工程量清单项目类型不处理。
       // if (treeNode.parent) { // 非大项费用才需要计算、显示单价
-      ftObj.unitFee = buf.toDecimal(decimalObj.bills.unitPrice);
-      ftObj.tenderUnitFee = btuf.toDecimal(decimalObj.bills.unitPrice);
+      ftObj.unitFee = buf;
+      ftObj.tenderUnitFee = btuf;
       // }
 
       calcTools.checkFeeField(treeNode, ftObj);
@@ -2020,6 +2018,13 @@ class CalcProgram {
     };
   }
 
+  billFloatUnitPrice(orgUnitPrice, treeNode) {
+    if (compilationName === "四川养护(2013)" || compilationName === "部颁2018计价标准") {
+      let coe = treeNode.data.unitPriceCoe || 1; // 单价浮动系数。只有叶子清单层的浮动系数生效
+      return (orgUnitPrice * coe).toDecimal(decimalObj.bills.unitPrice);
+    } else return orgUnitPrice;
+  }
+
   innerCalcBillExpr(treeNode) {
     delete treeNode.data.gljList;
     let me = this;
@@ -2033,6 +2038,7 @@ class CalcProgram {
     let q = nQ ? nQ : 1;
     let tq = nTQ ? nTQ : 1;
     let uf = (tf / q).toDecimal(decimalObj.bills.unitPrice);
+    uf = billFloatUnitPrice(uf, treeNode);
     let tuf = (ttf / tq).toDecimal(decimalObj.bills.unitPrice);
     if (calcTools.isBillProject()) {
       tf = (uf * q).toDecimal(decimalObj.bills.totalPrice);
@@ -2084,6 +2090,7 @@ class CalcProgram {
       if (treeNode.data.calcFlag == treeNodeCalcFlag.customUnitPrice) {
         // 修改了清单单价:以单价为准,算金额
         ftObj.unitFee = parseFloatPlus(treeNode.data.feesIndex.common.unitFee);
+        // uf = billFloatUnitPrice(uf, treeNode); 浮动单价要覆盖原单价。其它类型覆盖了没事,有基础在,还可以算回来。手工输入的不行,一覆盖就从地球上消失了。
         ftObj.totalFee = (ftObj.unitFee * nQ).toDecimal(decimalObj.bills.totalPrice);
         ftObj.tenderUnitFee = ftObj.unitFee;
         ftObj.tenderTotalFee = (ftObj.tenderUnitFee * nTQ).toDecimal(decimalObj.bills.totalPrice);

+ 212 - 154
web/building_saas/main/js/views/main_tree_col.js

@@ -9,18 +9,21 @@ let MainTreeCol = {
         return billText[node.data.type];
         // CSL, 2017-11-29
       } else if (node.sourceType === projectObj.project.Ration.getSourceType()) {
-        if (node.data.type == 1 || node.data.type == undefined)    // 兼容旧定额
-          return '定';
-        else if (node.data.type == 2) {    // 量价
+        if (node.data.type == 1 || node.data.type == undefined)
+          // 兼容旧定额
+          return "定";
+        else if (node.data.type == 2) {
+          // 量价
           return volumePriceMaps[node.data.subType];
-        }
-        else if (node.data.type == 3) {    // 工料机定额
-          return projectObj.project.projectGLJ.getShortNameByID(node.data.subType);//工料机名字缩写
-        } else if (node.data.type == 4) {//安装增加费生成的定额
-          return '安';
+        } else if (node.data.type == 3) {
+          // 工料机定额
+          return projectObj.project.projectGLJ.getShortNameByID(node.data.subType); //工料机名字缩写
+        } else if (node.data.type == 4) {
+          //安装增加费生成的定额
+          return "安";
         }
       } else if (node.sourceType === projectObj.project.ration_glj.getSourceType()) {
-        return projectObj.project.projectGLJ.getShortNameByID(node.data.subType);//工料机名字缩写
+        return projectObj.project.projectGLJ.getShortNameByID(node.data.subType); //工料机名字缩写
       }
     },
     quantity: function (node) {
@@ -35,8 +38,7 @@ let MainTreeCol = {
       let programID = node.data.programID;
       if (!programID) {
         return node.sourceType === projectObj.project.Bills.getSourceType() ? "" : "请选择…";
-      }
-      else return projectObj.project.calcProgram.compiledTemplateMaps[programID];
+      } else return projectObj.project.calcProgram.compiledTemplateMaps[programID];
     },
     calcBase: function (node) {
       if (node.data.calcBase && node.data.calcBase != "") {
@@ -45,23 +47,28 @@ let MainTreeCol = {
     },
     code: function (node) {
       if (!isDef(node)) {
-        return '';
+        return "";
       }
 
-      let rst = '';
-      if (node.sourceType === projectObj.project.Ration.getSourceType() && node.data.type === rationType.ration
-        && isDef(node.data.code) && isDef(node.data.prefix) && node.data.prefix !== '') {
-        rst = node.data.prefix + node.data.code.replace(new RegExp(node.data.prefix, 'g'), '');
-      }
-      else
-        rst = isDef(node.data.code) ? node.data.code : '';
+      let rst = "";
+      if (
+        node.sourceType === projectObj.project.Ration.getSourceType() &&
+        node.data.type === rationType.ration &&
+        isDef(node.data.code) &&
+        isDef(node.data.prefix) &&
+        node.data.prefix !== ""
+      ) {
+        rst = node.data.prefix + node.data.code.replace(new RegExp(node.data.prefix, "g"), "");
+      } else rst = isDef(node.data.code) ? node.data.code : "";
 
-      if (node.data.adjustState && rst != '')
-        rst = rst + rationPrefix.replace;
+      if (node.data.adjustState && rst != "") rst = rst + rationPrefix.replace;
       return rst;
     },
     marketPrice: function (node) {
-      if ((node.sourceType === projectObj.project.Ration.getSourceType() && node.data.type != rationType.ration) || node.sourceType == projectObj.project.ration_glj.getSourceType()) {
+      if (
+        (node.sourceType === projectObj.project.Ration.getSourceType() && node.data.type != rationType.ration) ||
+        node.sourceType == projectObj.project.ration_glj.getSourceType()
+      ) {
         if (node.data.marketUnitFee) return calcTools.uiGLJPrice(node.data.marketUnitFee);
       }
     },
@@ -75,15 +82,16 @@ let MainTreeCol = {
     maxPrice: function (node) {
       if (node.data.outPutMaxPrice == true || node.data.outPutLimitPrice == true) {
         if (node.data.maxPrice === null && node.data.feesIndex && node.data.feesIndex.common) {
-          return node.data.feesIndex.common.unitFee ? node.data.feesIndex.common.unitFee : ""
-        };
+          return node.data.feesIndex.common.unitFee ? node.data.feesIndex.common.unitFee : "";
+        }
         return node.data.maxPrice ? node.data.maxPrice : "";
       }
       return "";
     },
     minPrice: function (node) {
       if (node.data.outPutLimitPrice == true) {
-        if (node.data.minPrice === null && node.data.feesIndex && node.data.feesIndex.common) return node.data.feesIndex.common.unitFee ? node.data.feesIndex.common.unitFee : "";
+        if (node.data.minPrice === null && node.data.feesIndex && node.data.feesIndex.common)
+          return node.data.feesIndex.common.unitFee ? node.data.feesIndex.common.unitFee : "";
         return node.data.minPrice ? node.data.minPrice : "";
       }
       return "";
@@ -108,7 +116,8 @@ let MainTreeCol = {
       return false;
     },
     calcProgramName: function (node) {
-      if (node.sourceType === projectObj.project.Ration.getSourceType() ||
+      if (
+        node.sourceType === projectObj.project.Ration.getSourceType() ||
         (calcTools.isLeafBill(node) && projectObj.project.property.billsCalcMode === leafBillGetFeeType.billsPrice)
       ) {
         //当打勾估价项目选项后,该定额取费专业只读
@@ -120,18 +129,19 @@ let MainTreeCol = {
       return true;
     },
     non_editSubType: function (node) {
-      return node.data.subType != 201 && node.data.subType != 4 && node.data.subType != 5
+      return node.data.subType != 201 && node.data.subType != 4 && node.data.subType != 5;
     },
     commonUnitFee: function (node) {
       // 2018-11-15 zhang
       let Bills = projectObj.project.Bills;
-      if (node.sourceType == ModuleNames.bills) {//针对清单、分项部分
+      if (node.sourceType == ModuleNames.bills) {
+        //针对清单、分项部分
         // 当前属于分部分项、施工技术措施项目,综合单价只读。
         if (Bills.isFBFX(node) || Bills.isTechMeasure(node)) return true;
         // 不属于分部分项、施工技术措施项目的部分,如果不是叶子清单,或有基数计算/定额/量价/人材机 只读
         if (!calcTools.isLeafBill(node) || calcTools.isCalcBaseBill(node) || node.children.length > 0) return true;
       }
-      if(gljOprObj.marketPriceReadOnly(node)) return true;
+      if (gljOprObj.marketPriceReadOnly(node)) return true;
       //当前是定额,综合单价只读。 2018-11-15
       if (MainTreeCol.readOnly.ration(node)) return true;
       return false;
@@ -161,18 +171,17 @@ let MainTreeCol = {
 
       let calcBase = projectObj.project.calcBase;
       let parent = node.parent;
-      if (isFlag(node.data) && (node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.SUB_ENGINERRING
-        || node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.CONSTRUCTION_TECH)) {
+      if (
+        isFlag(node.data) &&
+        (node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.SUB_ENGINERRING || node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.CONSTRUCTION_TECH)
+      ) {
         return true;
-      }
-      else if (isFlag(node.data) && node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.CONSTRUCTION_ORGANIZATION) {
+      } else if (isFlag(node.data) && node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.CONSTRUCTION_ORGANIZATION) {
         return false;
-      }
-      else {
+      } else {
         if (!parent) {
           return false;
-        }
-        else {
+        } else {
           return this.calcBaseType(parent);
         }
       }
@@ -196,7 +205,7 @@ let MainTreeCol = {
       return !(node.sourceType == ModuleNames.bills && node.source.children.length == 0 && belongFlagList.includes(fixedFlag.ONE_SEVEN_BILLS));
     },
     volumePrice: function (node) {
-      return (node.data.type == rationType.volumePrice || node.data.type == rationType.gljRation);
+      return node.data.type == rationType.volumePrice || node.data.type == rationType.gljRation;
     },
     non_bills: function (node) {
       return node.sourceType !== projectObj.project.Bills.getSourceType();
@@ -211,17 +220,22 @@ let MainTreeCol = {
       return node.sourceType === projectObj.project.Bills.getSourceType() && node.source.children.length > 0;
     },
     leafBillsWithDetail: function (node) {
-      return (!MainTreeCol.readOnly.billsParent(node)) && (node.children.length > 0);
+      return !MainTreeCol.readOnly.billsParent(node) && node.children.length > 0;
     },
     forCalcBase: function (node) {
       // to do according to billsParentType
-      return MainTreeCol.readOnly.billsParent(node) || MainTreeCol.readOnly.non_bills(node) || MainTreeCol.readOnly.leafBillsWithDetail(node) || MainTreeCol.readOnly.calcBaseType(node);
+      return (
+        MainTreeCol.readOnly.billsParent(node) ||
+        MainTreeCol.readOnly.non_bills(node) ||
+        MainTreeCol.readOnly.leafBillsWithDetail(node) ||
+        MainTreeCol.readOnly.calcBaseType(node)
+      );
     },
     forUnitFee: function (node) {
       return MainTreeCol.readOnly.ration(node) || MainTreeCol.readOnly.billsParent(node) || MainTreeCol.readOnly.leafBillsWithDetail(node);
     },
     forTotalFee: function (node) {
-      return MainTreeCol.readOnly.non_bills(node) || MainTreeCol.readOnly.billsParent(node) || (MainTreeCol.readOnly.leafBillsWithDetail(node));
+      return MainTreeCol.readOnly.non_bills(node) || MainTreeCol.readOnly.billsParent(node) || MainTreeCol.readOnly.leafBillsWithDetail(node);
     },
     forQuantifyDetail: function (node) {
       return !(node.sourceType == ModuleNames.ration || !MainTreeCol.readOnly.billsParent(node));
@@ -231,7 +245,8 @@ let MainTreeCol = {
       let Bills = projectObj.project.Bills;
       //只有当选中节点是清单,并且不属于“分部分项工程”或“技术措施项目”,并且是叶子清单且没有定额/量价/工料机时,费率列才可编辑
       if (MainTreeCol.readOnly.bills(node)) {
-        if (!Bills.isFBFX(node) && !Bills.isTechMeasure(node) && node.children.length <= 0) {//不属于“分部分项工程”或“技术措施项目”,并且是叶子清单且没有定额/量价/工料机
+        if (!Bills.isFBFX(node) && !Bills.isTechMeasure(node) && node.children.length <= 0) {
+          //不属于“分部分项工程”或“技术措施项目”,并且是叶子清单且没有定额/量价/工料机
           readOnly = false;
         }
       }
@@ -239,7 +254,7 @@ let MainTreeCol = {
     },
     forQuantity: function (node) {
       if (node.sourceType === projectObj.project.Bills.getSourceType()) {
-        return false  //2020-11-13 开放清单所有输入限制
+        return false; //2020-11-13 开放清单所有输入限制
         //如果是预算项目的,所有清单的数量1、数量2不做输入限制。
         /*  if(projectObj.project.projectInfo.property && projectObj.project.projectInfo.property.valuationType == "bill")  return false;
          if(node.data.type==billType.DXFY||(node.data.type==billType.BILL&&MainTreeCol.readOnly.billsParent(node))){//大项费用、清单父项行,工程量只读。
@@ -251,32 +266,40 @@ let MainTreeCol = {
       return false;
     },
     forQuantity2: function (node) {
-      if (node.sourceType !== ModuleNames.bills) return true;//不是清单,只读
+      if (node.sourceType !== ModuleNames.bills) return true; //不是清单,只读
       //如果是预算项目的,所有清单的数量1、数量2不做输入限制。
       if (projectObj.project.projectInfo.property && projectObj.project.projectInfo.property.valuationType !== "ration") return false;
-      if (node.data.type == billType.DXFY || (node.data.type == billType.BILL && MainTreeCol.readOnly.billsParent(node))) return true;//大项费用、清单父项行,工程量只读。
-      return false
+      if (node.data.type == billType.DXFY || (node.data.type == billType.BILL && MainTreeCol.readOnly.billsParent(node))) return true; //大项费用、清单父项行,工程量只读。
+      return false;
     },
     forMarketPrice: function (node) {
-      return MainTreeCol.readOnly.bills(node) ||
+      return (
+        MainTreeCol.readOnly.bills(node) ||
         (node.sourceType === ModuleNames.ration && node.data.type == rationType.ration) ||
-        gljOprObj.marketPriceReadOnly(node);
+        gljOprObj.marketPriceReadOnly(node)
+      );
+    },
+    forUnitPriceCoe: function (node) {
+      return node.sourceType !== projectObj.project.Bills.getSourceType();
     },
     forContain: function (node) {
       return MainTreeCol.readOnly.non_ration(node) && !MainTreeCol.readOnly.glj(node);
     },
     forCode: function (node) {
       let Bills = projectObj.project.Bills;
-      if (MainTreeCol.readOnly.glj(node) || (node.sourceType === projectObj.project.Ration.getSourceType() && node.data.type === rationType.gljRation)) {//是主材或者设备、或者是工料机类型的定额
+      if (MainTreeCol.readOnly.glj(node) || (node.sourceType === projectObj.project.Ration.getSourceType() && node.data.type === rationType.gljRation)) {
+        //是主材或者设备、或者是工料机类型的定额
         return true;
       }
-      if (Bills.isTopThreeNode(node)) {//是大项1、2、3项的编号设置为只读
+      if (Bills.isTopThreeNode(node)) {
+        //是大项1、2、3项的编号设置为只读
         return true;
       }
       return false;
     },
     forName: function (node) {
-      if (projectObj.project.Bills.isTopThreeNode(node)) {//是大项1、2、3项的编号设置为只读
+      if (projectObj.project.Bills.isTopThreeNode(node)) {
+        //是大项1、2、3项的编号设置为只读
         return true;
       }
       return false;
@@ -296,29 +319,68 @@ let MainTreeCol = {
       return true;
     },
     maxPrice: function (node) {
-      const hasOutPutMaxPriceCol = !!projectObj.project.projSetting.main_tree_col.cols.find(item => item.data.field === 'outPutMaxPrice');
-      const hasOutPutLimitPriceCol = !!projectObj.project.projSetting.main_tree_col.cols.find(item => item.data.field === 'outPutLimitPrice');
-      return (hasOutPutMaxPriceCol && (node.data.outPutMaxPrice === undefined || node.data.outPutMaxPrice === false)) || (hasOutPutLimitPriceCol && (node.data.outPutLimitPrice === undefined || node.data.outPutLimitPrice === false));
+      const hasOutPutMaxPriceCol = !!projectObj.project.projSetting.main_tree_col.cols.find((item) => item.data.field === "outPutMaxPrice");
+      const hasOutPutLimitPriceCol = !!projectObj.project.projSetting.main_tree_col.cols.find((item) => item.data.field === "outPutLimitPrice");
+      return (
+        (hasOutPutMaxPriceCol && (node.data.outPutMaxPrice === undefined || node.data.outPutMaxPrice === false)) ||
+        (hasOutPutLimitPriceCol && (node.data.outPutLimitPrice === undefined || node.data.outPutLimitPrice === false))
+      );
     },
     minPrice: function (node) {
-      const hasOutPutLimitPriceCol = !!projectObj.project.projSetting.main_tree_col.cols.find(item => item.data.field === 'outPutLimitPrice');
-      return (hasOutPutLimitPriceCol && (node.data.outPutLimitPrice === undefined || node.data.outPutLimitPrice === false));
+      const hasOutPutLimitPriceCol = !!projectObj.project.projSetting.main_tree_col.cols.find((item) => item.data.field === "outPutLimitPrice");
+      return hasOutPutLimitPriceCol && (node.data.outPutLimitPrice === undefined || node.data.outPutLimitPrice === false);
     },
   },
   cellType: {
     unit: function (node, setting) {
       let tips = "";
       //在这里做要不要显示的判断
-      if (node.sourceType == ModuleNames.bills && projectObj.ifItemCharHiden(setting)) {//清单、并且项目特征列隐藏的时候悬浮提示
-        tips = node.data.itemCharacterText ? node.data.itemCharacterText : '';
+      if (node.sourceType == ModuleNames.bills && projectObj.ifItemCharHiden(setting)) {
+        //清单、并且项目特征列隐藏的时候悬浮提示
+        tips = node.data.itemCharacterText ? node.data.itemCharacterText : "";
       }
-      if (node.sourceType == ModuleNames.ration && node.data.type == rationType.ration) {//定额类型时,显示人材机,工作内容等
+      if (node.sourceType == ModuleNames.ration && node.data.type == rationType.ration) {
+        //定额类型时,显示人材机,工作内容等
         //这里的人材机需要进行过滤,在初始化时组装会影响性能,应实时显示
-        tips = MainTreeCol.getRationUnitTips
-      }
-      let dynamicCombo = sheetCommonObj.getTipsCombo(true, tips, setting, node);//sheetCommonObj.getDynamicCombo(true);
-      dynamicCombo.itemHeight(10).items(['m', 'm2', 'm3', 'km', 't', 'kg', '台班', '工日', '昼夜', '元', '项', '处', '个', '件',
-        '根', '组', '系统', '台', '套', '株', '丛', '缸', '支', '只', '块', '座', '对', '份', '樘', '攒', '榀']).editable(true);
+        tips = MainTreeCol.getRationUnitTips;
+      }
+      let dynamicCombo = sheetCommonObj.getTipsCombo(true, tips, setting, node); //sheetCommonObj.getDynamicCombo(true);
+      dynamicCombo
+        .itemHeight(10)
+        .items([
+          "m",
+          "m2",
+          "m3",
+          "km",
+          "t",
+          "kg",
+          "台班",
+          "工日",
+          "昼夜",
+          "元",
+          "项",
+          "处",
+          "个",
+          "件",
+          "根",
+          "组",
+          "系统",
+          "台",
+          "套",
+          "株",
+          "丛",
+          "缸",
+          "支",
+          "只",
+          "块",
+          "座",
+          "对",
+          "份",
+          "樘",
+          "攒",
+          "榀",
+        ])
+        .editable(true);
       return dynamicCombo;
     },
     units: function () {
@@ -334,8 +396,8 @@ let MainTreeCol = {
       }
     },
     calcBase: function (node) {
-      let readOnly = projectReadOnly || !calcBaseView.ifEdit('bills', projectObj.project.mainTree.items.indexOf(node));
-      return sheetCommonObj.getCusButtonCellType(calcBaseView.onCalcBaseButtonClick, readOnly)
+      let readOnly = projectReadOnly || !calcBaseView.ifEdit("bills", projectObj.project.mainTree.items.indexOf(node));
+      return sheetCommonObj.getCusButtonCellType(calcBaseView.onCalcBaseButtonClick, readOnly);
       //return calcBaseView.getCalcBaseCellType('bills');
     },
 
@@ -349,11 +411,11 @@ let MainTreeCol = {
         // names._maxDropDownItems = 10;
         // names.items(projectObj.project.calcProgram.compiledTemplateNames);
         // return names;
-        let tips = '';
-        if (node.data.programID != null){
+        let tips = "";
+        if (node.data.programID != null) {
           let tpl = projectObj.project.calcProgram.compiledTemplates[node.data.programID];
-          if(tpl) tips = tpl.ID + ' ' + tpl.name + ':' + (tpl.memo ? tpl.memo : '[无]');   // 加个判断保护,兼容旧项目此处空值 
-        };
+          if (tpl) tips = tpl.ID + " " + tpl.name + ":" + (tpl.memo ? tpl.memo : "[无]"); // 加个判断保护,兼容旧项目此处空值
+        }
         let dynamicCombo = sheetCommonObj.getTipsCombo(true, tips, setting, node);
         dynamicCombo.itemHeight(10).items(projectObj.project.calcProgram.compiledTemplateNames).editable(false);
         return dynamicCombo;
@@ -364,9 +426,10 @@ let MainTreeCol = {
     subType: function (node) {
       if (node.sourceType != projectObj.project.Bills.getSourceType()) {
         let VPType = sheetCommonObj.getDynamicCombo();
-        if (node.sourceType == projectObj.project.Ration.getSourceType()) {//是定额类型
+        if (node.sourceType == projectObj.project.Ration.getSourceType()) {
+          //是定额类型
           if (node.data.type == rationType.volumePrice) {
-            VPType.itemHeight(5).items(["人工", "材料", "机械", "设备"])
+            VPType.itemHeight(5).items(["人工", "材料", "机械", "设备"]);
             return VPType;
           } else if (node.data.type == rationType.gljRation) {
             if (!MainTreeCol.readOnly.non_editSubType(node) && gljOprObj.hasComposition(node.data, true) == false) {
@@ -374,7 +437,8 @@ let MainTreeCol = {
               return VPType;
             }
           }
-        } else if (node.sourceType === projectObj.project.ration_glj.getSourceType()) {//是工料机类型
+        } else if (node.sourceType === projectObj.project.ration_glj.getSourceType()) {
+          //是工料机类型
           if (!MainTreeCol.readOnly.non_editSubType(node) && gljOprObj.hasComposition(node.data) == false) {
             VPType.itemHeight(3).items(["材料", "设备"]);
             return VPType;
@@ -383,12 +447,15 @@ let MainTreeCol = {
       }
     },
     isSubcontract: function (node) {
-      if (calcTools.isRationCategory(node))
-        return new GC.Spread.Sheets.CellTypes.CheckBox();
+      if (calcTools.isRationCategory(node)) return new GC.Spread.Sheets.CellTypes.CheckBox();
     },
     isEstimate: function (node) {
       //只对分项、补项、材料(包括混凝土等)、主材、设备有效
-      if (MainTreeCol.readOnly.glj(node) || (calcTools.isGljRation(node) && projectObj.project.projectGLJ.isEstimateType(node.data.subType)) || (MainTreeCol.readOnly.bills(node) && (node.data.type == billType.BX || node.data.type == billType.FX))) {
+      if (
+        MainTreeCol.readOnly.glj(node) ||
+        (calcTools.isGljRation(node) && projectObj.project.projectGLJ.isEstimateType(node.data.subType)) ||
+        (MainTreeCol.readOnly.bills(node) && (node.data.type == billType.BX || node.data.type == billType.FX))
+      ) {
         return new GC.Spread.Sheets.CellTypes.CheckBox();
       }
     },
@@ -403,29 +470,24 @@ let MainTreeCol = {
       if (node.sourceType == ModuleNames.ration) return new GC.Spread.Sheets.CellTypes.CheckBox();
     },
     commonTotalFee: function (node) {
-      let readOnly = projectReadOnly || !calcBaseView.ifEdit('bills', projectObj.project.mainTree.items.indexOf(node));
-      return sheetCommonObj.getCusButtonCellType(projectObj.onCommonTotalFeeButtonClick, readOnly) //projectObj.getCommonTotalFeeCellType();
+      let readOnly = projectReadOnly || !calcBaseView.ifEdit("bills", projectObj.project.mainTree.items.indexOf(node));
+      return sheetCommonObj.getCusButtonCellType(projectObj.onCommonTotalFeeButtonClick, readOnly); //projectObj.getCommonTotalFeeCellType();
     },
     specialProvisional: function (node) {
       if (!MainTreeCol.readOnly.specialProvisional(node)) {
         let dynamicCombo = sheetCommonObj.getDynamicCombo();
-        dynamicCombo.items(["材料暂估","工程设备","专业工程", ""]);//工程量清单项目,专项暂定的下拉加上“材料暂估”、“工程设备”(原来隐藏了) 20210913
+        dynamicCombo.items(["材料暂估", "工程设备", "专业工程", ""]); //工程量清单项目,专项暂定的下拉加上“材料暂估”、“工程设备”(原来隐藏了) 20210913
         return dynamicCombo;
       }
-
     },
     outPutMaxPrice: function (node) {
       if (node.sourceType === projectObj.project.Bills.getSourceType()) {
-        return projectObj.project.projectInfo.property.lockBills
-          ? sheetCommonObj.getReadOnlyCheckBox()
-          : sheetCommonObj.getCheckBox();
+        return projectObj.project.projectInfo.property.lockBills ? sheetCommonObj.getReadOnlyCheckBox() : sheetCommonObj.getCheckBox();
       }
     },
     outPutLimitPrice: function (node) {
       if (node.sourceType === projectObj.project.Bills.getSourceType()) {
-        return projectObj.project.projectInfo.property.lockBills
-          ? sheetCommonObj.getReadOnlyCheckBox()
-          : sheetCommonObj.getCheckBox();
+        return projectObj.project.projectInfo.property.lockBills ? sheetCommonObj.getReadOnlyCheckBox() : sheetCommonObj.getCheckBox();
       }
     },
     /* maxPrice: function (node, setting) {
@@ -442,28 +504,28 @@ let MainTreeCol = {
       };
       return sheetCommonObj.getTipsText(tips, setting, node);
     } */
-    appraisalBills:function (node) {
-      if(MainTreeCol.appraisalBillsEnable(node)) {
-          return projectObj.project.projectInfo.property.lockBills 
-              ? sheetCommonObj.getReadOnlyCheckBox()
-              : sheetCommonObj.getCheckBox(true)
-      };
-},
+    appraisalBills: function (node) {
+      if (MainTreeCol.appraisalBillsEnable(node)) {
+        return projectObj.project.projectInfo.property.lockBills ? sheetCommonObj.getReadOnlyCheckBox() : sheetCommonObj.getCheckBox(true);
+      }
+    },
   },
-  appraisalBillsEnable:function (node) {
+  appraisalBillsEnable: function (node) {
     let Bills = projectObj.project.Bills;
     return Bills.isBelongOneToSeven(node) && node.sourceType === ModuleNames.bills && node.getFlag() !== fixedFlag.ONE_SEVEN_BILLS;
-},
+  },
   editChecking: function (node) {
     if (node.sourceType == projectObj.project.Bills.getSourceType() && projectObj.project.isBillsLocked() && projectObj.project.withinBillsLocked(node)) {
       return true;
     }
-    if (gljOprObj.isInstallationNode(node)) {//如果是通过安装增加费自动生成的,都是只读类型
+    if (gljOprObj.isInstallationNode(node)) {
+      //如果是通过安装增加费自动生成的,都是只读类型
       return true;
     }
     return false;
   },
-  setAutoHeight: function (cell, node) {//设置自动行高
+  setAutoHeight: function (cell, node) {
+    //设置自动行高
     cell.wordWrap(MainTreeCol.needAutoFit(node));
   },
   setAutoFitRow: function (sheet, node) {
@@ -484,7 +546,7 @@ let MainTreeCol = {
     return false;
   },
   getEvent: function (eventName) {
-    let names = eventName.split('.');
+    let names = eventName.split(".");
     let event = this;
     for (let name of names) {
       if (event[name]) {
@@ -499,44 +561,42 @@ let MainTreeCol = {
       return event;
     }
   },
-  getNumberFormatter: function (digit, align) {    // CSL, 2017-11-30 扩展:小数点是否对齐。
+  getNumberFormatter: function (digit, align) {
+    // CSL, 2017-11-30 扩展:小数点是否对齐。
     if (align) {
       switch (digit) {
         case 1:
-          return '0.0';
+          return "0.0";
         case 2:
-          return '0.00';
+          return "0.00";
         case 3:
-          return '0.000';
+          return "0.000";
         case 4:
-          return '0.0000';
+          return "0.0000";
         case 5:
-          return '0.00000';
+          return "0.00000";
         case 6:
-          return '0.000000';
+          return "0.000000";
         default:
-          return '0';
+          return "0";
       }
-      ;
-    }
-    else {
+    } else {
       switch (digit) {
         case 1:
-          return '0.#';
+          return "0.#";
         case 2:
-          return '0.##';
+          return "0.##";
         case 3:
-          return '0.###';
+          return "0.###";
         case 4:
-          return '0.####';
+          return "0.####";
         case 5:
-          return '0.#####';
+          return "0.#####";
         case 6:
-          return '0.######';
+          return "0.######";
         default:
-          return '0';
+          return "0";
       }
-      ;
     }
   },
   getRationUnitTips: function (node) {
@@ -544,28 +604,28 @@ let MainTreeCol = {
     let ration_glj = projectObj.project.ration_glj;
     let gljList = gljOprObj.filterGljByRation(node.data, ration_glj.datas);
     gljList = gljUtil.sortRationGLJ(gljList);
-    if (node.data.content && node.data.content.toString().trim() !== '') {
+    if (node.data.content && node.data.content.toString().trim() !== "") {
       tips += `工作内容:<br>`;
       tips += `${node.data.content.replace(/\n/g, "<br>")}<br><br>`;
     }
     for (let glj of gljList) {
-      tips += `${glj.code} ${glj.name}${glj.specs ? '&nbsp;&nbsp;&nbsp;' + glj.specs : ''}&nbsp;&nbsp&nbsp;${glj.unit}&nbsp;&nbsp;&nbsp;${glj.quantity}<br>`;
+      tips += `${glj.code} ${glj.name}${glj.specs ? "&nbsp;&nbsp;&nbsp;" + glj.specs : ""}&nbsp;&nbsp&nbsp;${glj.unit}&nbsp;&nbsp;&nbsp;${glj.quantity}<br>`;
     }
 
-    if (node.data.annotation && node.data.annotation.toString().trim() !== '') {
+    if (node.data.annotation && node.data.annotation.toString().trim() !== "") {
       tips += `附注:<br>`;
       tips += `${node.data.annotation.replace(/\n/g, "<br>")}<br>`;
     }
-    return tips
+    return tips;
   },
   // 字体颜色w
   foreColor: {
     // 清单综合单价>最高限价 清单综合单价<最低限价 时,标红显示
-    'feesIndex.common.unitFee': function (node) {
-      const color = 'red';
-      return calcTools.unitFeeGTMaxPrice(node, 'common.unitFee') || calcTools.unitFeeLTMinPrice(node, 'common.unitFee') ? color : null;
-    }
-  }
+    "feesIndex.common.unitFee": function (node) {
+      const color = "red";
+      return calcTools.unitFeeGTMaxPrice(node, "common.unitFee") || calcTools.unitFeeLTMinPrice(node, "common.unitFee") ? color : null;
+    },
+  },
 };
 
 let colSettingObj = {
@@ -578,12 +638,14 @@ let colSettingObj = {
     sheet.setColumnCount(setting.headRows, GC.Spread.Sheets.SheetArea.rowHeader);
     sheet.setColumnCount(1);
     sheet.getRange(-1, 0, -1, 1).cellType(this.checkBox).hAlign(GC.Spread.Sheets.HorizontalAlign.center);
-    sheet.getCell(0, 0, GC.Spread.Sheets.SheetArea.colHeader).value('显示');
+    sheet.getCell(0, 0, GC.Spread.Sheets.SheetArea.colHeader).value("显示");
     sheet.setColumnWidth(0, 100);
     sheet.setColumnWidth(0, 240, GC.Spread.Sheets.SheetArea.rowHeader);
 
     setting.cols.forEach(function (col, index) {
-      let i, iCol = 0, cell;
+      let i,
+        iCol = 0,
+        cell;
       for (i = 0; i < col.head.spanCols.length; i++) {
         if (col.head.spanCols[i] !== 0) {
           cell = sheet.getCell(index, iCol, GC.Spread.Sheets.SheetArea.rowHeader);
@@ -595,7 +657,6 @@ let colSettingObj = {
         }
         iCol += col.head.spanRows[i];
       }
-      ;
       let colWidth = sheet.getColumnWidth(index, GC.Spread.Sheets.SheetArea.rowHeader);
       colWidth = colWidth > col.width ? colWidth : col.width;
       //sheet.setColumnWidth(index, colWidth, GC.Spread.Sheets.SheetArea.rowHeader);
@@ -606,7 +667,7 @@ let colSettingObj = {
     sheet.resumePaint();
   },
   initSettingSpread: function () {
-    this.settingSpread = SheetDataHelper.createNewSpread($('#col_setting_spread')[0], {sheetCount: 1});
+    this.settingSpread = SheetDataHelper.createNewSpread($("#col_setting_spread")[0], { sheetCount: 1 });
     sheetCommonObj.spreadDefaultStyle(this.settingSpread);
     this.settingSpread.options.showScrollTip = GC.Spread.Sheets.ShowScrollTip.vertical;
     this.settingSpread.bind(GC.Spread.Sheets.Events.ButtonClicked, function (sender, args) {
@@ -627,7 +688,7 @@ let colSettingObj = {
     }
     return false;
   },
-  updateColSetting: function (skipSetValue = false,init=false) {
+  updateColSetting: function (skipSetValue = false, init = false) {
     let mainSheet = projectObj.mainSpread.getActiveSheet();
     if (!skipSetValue) {
       let sheet = this.settingSpread.getActiveSheet();
@@ -642,21 +703,21 @@ let colSettingObj = {
       mainSheet.showColumn(projectObj.project.projSetting.mainGridSetting.frozenCols, GC.Spread.Sheets.HorizontalPosition.left);
     });
     //refresh nodes to autoFitRow
-    if(init === false) projectObj.mainController.refreshTreeNode(projectObj.project.mainTree.roots, true);
+    if (init === false) projectObj.mainController.refreshTreeNode(projectObj.project.mainTree.roots, true);
     if (!skipSetValue) {
       //列设置将项目特征和工作内容都取消打钩后,更新快速列设置
-      if (!this.getVisible('itemCharacterText')) {
+      if (!this.getVisible("itemCharacterText")) {
         switchTznrHtml(true);
       }
-      if (this.getVisible('itemCharacterText')) {
+      if (this.getVisible("itemCharacterText")) {
         switchTznrHtml(false);
       }
     }
     //别人分享过来的项目,打开时,“显示特征”按钮应有效,不影响数据的修改
     if (!projectReadOnly) {
-      projectObj.project.pushNow('editColSetting', projectObj.project.projSetting.moduleName, {
+      projectObj.project.pushNow("editColSetting", projectObj.project.projSetting.moduleName, {
         projectID: projectObj.project.ID(),
-        main_tree_col: projectObj.project.projSetting.main_tree_col
+        main_tree_col: projectObj.project.projSetting.main_tree_col,
       });
     }
   },
@@ -699,44 +760,41 @@ let colSettingObj = {
     let cols = projectObj.project.projSetting.main_tree_col.cols;
     let colSetting = cols[col];
     return colSetting ? colSetting.data.field : null;
-  }
-
+  },
 };
 
 function switchTznrHtml(show) {
   if (show) {
-    $('#switchTznr').html('<i class="fa fa-eye" aria-hidden="true"></i> 显示特征');
-  }
-  else {
-    $('#switchTznr').html('<i class="fa fa-eye-slash" aria-hidden="true"></i> 隐藏特征');
+    $("#switchTznr").html('<i class="fa fa-eye" aria-hidden="true"></i> 显示特征');
+  } else {
+    $("#switchTznr").html('<i class="fa fa-eye-slash" aria-hidden="true"></i> 隐藏特征');
   }
 }
 
-$('#switchTznr').click(function () {
+$("#switchTznr").click(function () {
   let me = colSettingObj;
   let cur = $(this).text();
-  if (cur.includes('显示特征')) {
+  if (cur.includes("显示特征")) {
     switchTznrHtml(false);
-    me.setVisible('itemCharacterText', true);
+    me.setVisible("itemCharacterText", true);
     me.updateColSetting(true);
-  }
-  else {
+  } else {
     switchTznrHtml(true);
-    me.setVisible('itemCharacterText', false);
+    me.setVisible("itemCharacterText", false);
     me.updateColSetting(true);
   }
   let mainSheet = projectObj.mainSpread.getActiveSheet();
   mainSheet.showRow(mainSheet.getActiveRowIndex(), GC.Spread.Sheets.VerticalPosition.center);
 });
 
-$('#poj-set').on('shown.bs.modal', function (e) {
+$("#poj-set").on("shown.bs.modal", function (e) {
   if (!colSettingObj.settingSpread) {
     colSettingObj.initSettingSpread();
     if (projectReadOnly) {
       sheetCommonObj.disableSpread(colSettingObj.settingSpread);
     }
   }
-  if ($('#tab_display_setting').hasClass('active')) {
+  if ($("#tab_display_setting").hasClass("active")) {
     let sheet = colSettingObj.settingSpread.getActiveSheet();
     SheetDataHelper.massOperationSheet(sheet, function () {
       for (let row = 0; row < sheet.getRowCount(); row++) {
@@ -746,11 +804,11 @@ $('#poj-set').on('shown.bs.modal', function (e) {
     });
   }
   // 清单限价
-  $('#max-price-rate') && $('#max-price-rate').val(projectObj.project.property.maxPriceRate || 0);
-  $('#min-price-rate') && $('#min-price-rate').val(projectObj.project.property.minPriceRate || 0);
+  $("#max-price-rate") && $("#max-price-rate").val(projectObj.project.property.maxPriceRate || 0);
+  $("#min-price-rate") && $("#min-price-rate").val(projectObj.project.property.minPriceRate || 0);
 });
 
-$('#poj-set').on('hidden.bs.modal', function (e) {
+$("#poj-set").on("hidden.bs.modal", function (e) {
   if (colSettingObj.settingSpread) {
     //恢复
     let sheet = colSettingObj.settingSpread.getActiveSheet();
@@ -763,6 +821,6 @@ $('#poj-set').on('hidden.bs.modal', function (e) {
   }
 });
 
-$('#tab_display_setting').on('shown.bs.tab', function () {
+$("#tab_display_setting").on("shown.bs.tab", function () {
   sheetCommonObj.refreshWorkbookDelDefer(colSettingObj.settingSpread, 100);
 });