Browse Source

Merge branch 'master' of http://smartcost.f3322.net:3000/SmartCost/ConstructionCost

zhongzewei 7 năm trước cách đây
mục cha
commit
1fd6369d10

+ 4 - 1
modules/main/facade/bill_facade.js

@@ -131,7 +131,10 @@ async function pasteRationsAndRationGLJ (rations,ration_gljs) {
 
     for(let rg of ration_gljs){
         await getProjectGLJ(rg,gljKeyArray,gljMap);
-        new_ration_gljs.push(ration_glj_facade.createNewRecord(rg));
+        let temRecord = ration_glj_facade.createNewRecord(rg);
+        rg.rcode?temRecord.rcode = rg.rcode:'';
+        rg.hasOwnProperty("customQuantity")?temRecord.customQuantity = rg.customQuantity:'';
+        new_ration_gljs.push(temRecord);
     }
 
     rations.length>0?await insertMany(rations,ration_Model):'';

+ 20 - 2
modules/ration_glj/facade/glj_calculate_facade.js

@@ -157,7 +157,8 @@ function generateAdjustState(glj,coeList,adjustState,index,quantity) {
     if(glj._doc.createType=='replace'&&glj.rcode!=glj.code){
         adjustState.push({index:stateSeq.replace,content:glj.rcode+'换'+glj.code});
     }else if(glj._doc.createType=='add'){
-        adjustState.push({index:stateSeq.add,content:'添'+glj.code+'量'+parseFloat(quantity)});
+        let displayQuantity = glj._doc.hasOwnProperty('customQuantity')?parseFloat(glj.customQuantity):parseFloat(quantity);
+        adjustState.push({index:stateSeq.add,content:'添'+glj.code+'量'+ displayQuantity});
     }
     // to do
 
@@ -191,13 +192,30 @@ function generateAdjustState(glj,coeList,adjustState,index,quantity) {
 
 function getContent(coes) {
     let stringList=[];
+    let  temAmount = null;
+    let theSame = true;
+    for(let t of coes){
+        if(temAmount == null){
+            temAmount = t.amount;
+        }else if(temAmount != t.amount){
+            theSame = false;
+            break;
+        }
+    }
     for(let c of coes){
         if( c.amount&&c.amount!=1){
             let operator = c.operator;
             if(c.operator =="*"){
                 operator = "X";
             }
-            stringList.push(c.coeType+operator+c.amount);
+            if(theSame == true && c.coeType == "定额"){
+                stringList.push(c.coeType+operator+c.amount);
+                break;
+            }else
+            if(theSame == false && c.coeType != "定额"){
+                stringList.push(c.coeType+operator+c.amount);
+            }
+
         }
     }
     return stringList.join(",");

+ 21 - 4
modules/reports/util/rpt_construct_data_util.js

@@ -416,12 +416,12 @@ function filterData(sourceData, handleCfg, prjData) {
         }
         return rst;
     };
-    let compareObj = {};
-    for (let item of tempRstArr) {
+    let private_filter_compare = function (item, filterCfg) {
+        let compareObj = {};
         let compRst = true;
         let curComparePrjData = null;
         let startIdx = 0;
-        for (let cfg of handleCfg[JV.PROP_FILTER_KEYS]) {
+        for (let cfg of filterCfg[JV.PROP_FILTER_KEYS]) {
             if (cfg[JV.PROP_FILTER_COMPARE_VAL]) {
                 //比较key值
                 let keys = cfg.key.split(".");
@@ -472,10 +472,27 @@ function filterData(sourceData, handleCfg, prjData) {
             }
             startIdx++;
         }
-        if (compRst) {
+        return compRst;
+    };
+    for (let item of tempRstArr) {
+        if (private_filter_compare(item, handleCfg)) {
             rstArr.push(item);
         }
     }
+    if (handleCfg[JV.PROP_OTHER_SUB_FILTER] && handleCfg[JV.PROP_OTHER_SUB_FILTER].length > 0) {
+        let newRstArr = [];
+        for (let dtlItem of rstArr) {
+            let cmpRst = false;
+            for (let dtlCfg of handleCfg[JV.PROP_OTHER_SUB_FILTER]) {
+                cmpRst = private_filter_compare(dtlItem, dtlCfg);
+                if (cmpRst) {
+                    newRstArr.push(dtlItem);
+                    break;
+                }
+            }
+        }
+        rstArr = newRstArr;
+    }
     delete sourceData.data;
     sourceData.data = rstArr;
     // fsUtil.writeObjToFile(sourceData.data, "D:/GitHome/ConstructionCost/tmp/filteredRst.js");

+ 26 - 0
public/web/common_ajax.js

@@ -118,3 +118,29 @@ var CommonAjax = {
         });
     }
 };
+
+/**
+ * 设置全局的AJAX请求默认选项
+ * 主要设置了AJAX请求遇到Session过期的情况
+ */
+$.ajaxSetup({
+    complete: function (data) {
+        if (data.responseJSON&&data.responseJSON.ret_code && data.responseJSON.ret_code == 99) {
+            alert(data.responseJSON.ret_msg);
+            var top = getTopWindow();
+            setTimeout('top.location.href = "/login";', 300);
+        }
+    }
+});
+
+/**
+ * 在页面中任何嵌套层次的窗口中获取顶层窗口
+ * @return 当前页面的顶层窗口对象
+ */
+function getTopWindow() {
+    var p = window;
+    while (p != p.parent) {
+        p = p.parent;
+    }
+    return p;
+}

+ 1 - 0
public/web/rpt_value_define.js

@@ -52,6 +52,7 @@ const JV = {
     PROP_PARENT_SORT_KEYS: "父排序键值集",
     PROP_CHILD_SORT_KEYS: "子排序键值集",
     PROP_OTHER_SUB_SORT: "其他子排序",
+    PROP_OTHER_SUB_FILTER: "其他子过滤",
     PROP_HANDLE_TYPE: "预处理类型",
     PROP_FILTER_KEYS: "过滤键值集",
     PROP_FILTER_TOP_BILLS_NODES: "清单顶节点集",

+ 3 - 0
public/web/tree_sheet/tree_sheet_helper.js

@@ -427,6 +427,9 @@ var TREE_SHEET_HELPER = {
                 if (colSetting.showHint) {
                     sheet.getRange(-1, iCol, -1, 1).cellType(new TipCellType());
                 }
+                if(colSetting.formatter){
+                    sheet.setFormatter(-1, iCol, colSetting.formatter, GC.Spread.Sheets.SheetArea.viewport);
+                }
             });
             sheet.getRange(-1, setting.treeCol, -1, 1).cellType(new TreeNodeCellType());
             TREE_SHEET_HELPER.refreshTreeNodeData(setting, sheet, tree.roots, true);

+ 8 - 1
server.js

@@ -63,7 +63,14 @@ app.use(function (req, res, next) {
             // 判断session
             let sessionUser = req.session.sessionUser;
             if (!sessionUser) {
-                throw 'session error';
+                //处理 ajax 请求 session 过期问题
+                if (req.headers["x-requested-with"] != null
+                    && req.headers["x-requested-with"] == "XMLHttpRequest"
+                    && req.url != "/login") {
+                    return res.json({ret_code: 99, ret_msg: '登录信息失效,请您重新登录'});
+                }else {
+                    throw 'session error';
+                }
             }
             res.locals.sessionUser = sessionUser;
         } catch (error) {

+ 11 - 0
web/building_saas/js/global.js

@@ -95,3 +95,14 @@ function removeLocalCache(key) {
     }
     return storage.removeItem(key);
 }
+
+function getFormatter(decimal) {
+    var pre = "0.";
+    if (decimal <= 0) {
+        return "0";
+    }
+    for (let i = 0; i < decimal; i++) {
+        pre += "0"
+    }
+    return pre;
+}

+ 86 - 84
web/building_saas/main/js/models/calc_program.js

@@ -102,8 +102,13 @@ let calcTools = {
     isBill: function(treeNode){
         return treeNode.sourceType === ModuleNames.bills;
     },
+    isParentBill: function (treeNode) {
+        return this.isBill(treeNode) &&
+            treeNode.source.children &&
+            treeNode.source.children.length > 0;
+    },
     isLeafBill: function(treeNode){
-        return treeNode.sourceType === ModuleNames.bills &&
+        return this.isBill(treeNode) &&
             treeNode.source.children &&
             treeNode.source.children.length === 0;
     },
@@ -126,6 +131,21 @@ let calcTools = {
     isGljRation: function (treeNode) {
         return this.isRationCategory(treeNode) && treeNode.data.type === rationType.gljRation;
     },
+    getGLJList: function (treeNode) {
+        delete treeNode.data.gljList;
+        if (this.isRationCategory(treeNode)) {
+            if (treeNode.data.type != rationType.volumePrice) {
+                treeNode.data.gljList = projectObj.project.ration_glj.getGljArrByRation(treeNode.data);
+            };
+        }
+        else if (this.isBill(treeNode)){
+            let nodeQ = this.uiNodeQty(treeNode);
+            let q = nodeQ ? nodeQ : 1;
+            let rNodes = projectObj.project.Ration.getRationNodes(treeNode);
+            let rations = rNodes.map(function (node) {return node.data});
+            treeNode.data.gljList = projectObj.project.ration_glj.getGatherGljArrByRations(rations, q);
+        };
+    },
 
     initFees: function (treeNode){
         if (!treeNode.data.fees) {
@@ -261,12 +281,15 @@ let calcTools = {
         }
         return result;
     },
-    // 父清单暂估费是汇总子清单的暂估费,走计算程序逻辑,不在这里。
+    // 总造价清单、叶子清单、定额的暂估费。父清单是汇总子清单的暂估费,走计算程序逻辑,不在这里。
     estimateFee: function (treeNode, isBase = false){
         let me = this, sumU = 0, sumT = 0;
         let nodeQ = me.uiNodeQty(treeNode);
+        let isGather = (projectObj.project.property.zanguCalcMode == zanguCalcType.gatherMaterial);
+
         // 先汇总数量,再乘市场价
-        function estimateTotalFee(){
+        function eTFee(){
+            if (!treeNode.data.gljList) return 0;
             let GLJObjs = [];
             for (let glj of treeNode.data.gljList) {
                 if (!allMaterialTypes.includes(glj.type)) continue;
@@ -307,8 +330,20 @@ let calcTools = {
             };
             return rst;
         };
+        // 汇总子结点的暂估合价
+        function eTFeeByChildren(){
+            let rst = 0;
+            for (let node of treeNode.children){
+                if (node.data.feesIndex && node.data.feesIndex['estimate']) {
+                    rst = (rst + parseFloatPlus(node.data.feesIndex['estimate'].totalFee)).toDecimal(decimalObj.process);
+                };
+            };
+            rst = (rst).toDecimal(decimalObj.bills.totalPrice);
+            return rst;
+        };
         // 先数量乘市场价,再汇总
-        function estimateUnitFee(){
+        function eUFee(){
+            if (!treeNode.data.gljList) return 0;
             let rst = 0;
             for (let glj of treeNode.data.gljList) {
                 if (!allMaterialTypes.includes(glj.type)) continue;
@@ -351,29 +386,27 @@ let calcTools = {
             sumU = (sumU).toDecimal(decimalObj.bills.unitPrice);
             sumT = (sumT).toDecimal(decimalObj.bills.totalPrice);
         }
-        // 叶子清单、定额的暂估费
-        else{
-            if (!treeNode.data.gljList) return;
-            let isGather = (projectObj.project.property.zanguCalcMode == zanguCalcType.gatherMaterial);
-
-            if (calcTools.isRationCategory(treeNode)){
-                sumU = estimateUnitFee();
-                if (isBase) return sumU;
+        else if (me.isParentBill(treeNode)){  // 父清单不要汇总单价。
+            sumT = eTFeeByChildren();
+            sumU = undefined;
+        }
+        else if (me.isLeafBill(treeNode)){
+            if (isGather)
+                sumT = eTFee()
+            else
+                sumT = eTFeeByChildren();
 
-                if (isGather)
-                    sumT = estimateTotalFee()
-                else
-                    sumT = (nodeQ * sumU).toDecimal(decimalObj.ration.totalPrice);
-            }
-            else if (calcTools.isBill(treeNode)){
-                if (isGather)
-                    sumT = estimateTotalFee()
-                else
-                    sumT = 0;
+            let q = nodeQ ? nodeQ : 1;
+            sumU = (sumT / q).toDecimal(decimalObj.bills.totalPrice);
+        }
+        else if (me.isRationCategory(treeNode)){
+            sumU = eUFee();
+            if (isBase) return sumU;
 
-                let q = nodeQ ? nodeQ : 1;
-                sumU = (sumT / q).toDecimal(decimalObj.bills.totalPrice);
-            };
+            if (isGather)
+                sumT = eTFee()
+            else
+                sumT = (nodeQ * sumU).toDecimal(decimalObj.ration.totalPrice);
         };
 
         me.checkFeeField(treeNode, {'fieldName': 'estimate', 'unitFee': sumU, 'totalFee': sumT});
@@ -1367,10 +1400,16 @@ class CalcProgram {
         if (treeNode.calcType == treeNodeCalcType.ctGatherBillsFees || treeNode.calcType == treeNodeCalcType.ctGatherRationsFees){
             treeNode.data.programID = null;
             calcTools.initFees(treeNode);
-            let nodes = (treeNode.calcType == treeNodeCalcType.ctGatherBillsFees) ? treeNode.children : me.project.Ration.getRationNodes(treeNode);
+
+            let nodes = [];
+            if (treeNode.calcType == treeNodeCalcType.ctGatherRationsFees){
+                calcTools.getGLJList(treeNode);
+                nodes = me.project.Ration.getRationNodes(treeNode);
+            }
+            else nodes = treeNode.children;
+
             let rst = [];
             for (let ft of cpFeeTypes) {
-                let isEstimate = ft.type == 'estimate';
                 let ftObj = {};
                 ftObj.fieldName = ft.type;
                 ftObj.name = ft.name;
@@ -1379,11 +1418,8 @@ class CalcProgram {
 
                 if (treeNode.calcType == treeNodeCalcType.ctGatherBillsFees){
                     for (let node of nodes) {
-                        if (node.data.feesIndex && node.data.feesIndex[ft.type]) {
-                            // 父清单不要汇总综合单价。
-                            // buf = (buf + parseFloatPlus(node.data.feesIndex[ft.type].unitFee)).toDecimal(decimalObj.process);
+                        if (node.data.feesIndex && node.data.feesIndex[ft.type]) { // 父清单不要汇总综合单价。
                             btf = (btf + parseFloatPlus(node.data.feesIndex[ft.type].totalFee)).toDecimal(decimalObj.process);
-                            // btuf = (btuf + parseFloatPlus(node.data.feesIndex[ft.type].tenderUnitFee)).toDecimal(decimalObj.process);
                             bttf = (bttf + parseFloatPlus(node.data.feesIndex[ft.type].tenderTotalFee)).toDecimal(decimalObj.process);
                         };
                     };
@@ -1391,7 +1427,6 @@ class CalcProgram {
                 else if (treeNode.calcType == treeNodeCalcType.ctGatherRationsFees){     // 这里的算法要配合冷姐姐的神图才能看懂^_^
                     let sum_rtf = 0, sum_rttf = 0;
                     for (let node of nodes) {
-                        let rq = calcTools.uiNodeQty(node) ? calcTools.uiNodeQty(node) : 0;
                         let ruf = 0, rtuf = 0, rtf = 0, rttf = 0;
                         if (node.data.feesIndex && node.data.feesIndex[ft.type]) {
                             ruf = parseFloatPlus(node.data.feesIndex[ft.type].unitFee).toDecimal(decimalObj.bills.unitPrice);
@@ -1406,39 +1441,27 @@ class CalcProgram {
                         sum_rtf = (sum_rtf + rtf).toDecimal(decimalObj.process);
                         sum_rttf = (sum_rttf + rttf).toDecimal(decimalObj.process);
                     };
-                    if (isEstimate){
+
+                    if (me.project.property.billsCalcMode == leafBillGetFeeType.rationPriceConverse ||
+                        me.project.property.billsCalcMode == leafBillGetFeeType.rationPrice) {
+                        buf = (sum_rtf / bq).toDecimal(decimalObj.process);
+                        btuf = (sum_rttf / bq).toDecimal(decimalObj.process);
+                    };
+                    if (isBaseFeeType(ft.type) ||
+                        (me.project.property.billsCalcMode === leafBillGetFeeType.rationPrice && ft.type == "common")){
                         btf = sum_rtf;
                         bttf = sum_rttf;
-                    }else{
-                        if (me.project.property.billsCalcMode == leafBillGetFeeType.rationPriceConverse ||
-                            me.project.property.billsCalcMode == leafBillGetFeeType.rationPrice) {
-                            buf = (sum_rtf / bq).toDecimal(decimalObj.process);
-                            btuf = (sum_rttf / bq).toDecimal(decimalObj.process);
-                        };
-                        if (isBaseFeeType(ft.type) ||
-                            (me.project.property.billsCalcMode === leafBillGetFeeType.rationPrice && ft.type == "common")){
-                            btf = sum_rtf;
-                            bttf = sum_rttf;
-                        }
-                        else{
-                            btf = (buf.toDecimal(decimalObj.bills.unitPrice) * bq).toDecimal(decimalObj.process);
-                            bttf = (btuf.toDecimal(decimalObj.bills.unitPrice) * bq).toDecimal(decimalObj.process);
-                        };
+                    }
+                    else{
+                        btf = (buf.toDecimal(decimalObj.bills.unitPrice) * bq).toDecimal(decimalObj.process);
+                        bttf = (btuf.toDecimal(decimalObj.bills.unitPrice) * bq).toDecimal(decimalObj.process);
                     };
                 };
 
                 ftObj.totalFee = btf.toDecimal(decimalObj.bills.totalPrice);
                 ftObj.tenderTotalFee = bttf.toDecimal(decimalObj.bills.totalPrice);
-                if (isEstimate){
-                    if (treeNode.calcType == treeNodeCalcType.ctGatherRationsFees){
-                        ftObj.unitFee = (ftObj.totalFee / bq).toDecimal(decimalObj.bills.unitPrice);
-                        ftObj.tenderUnitFee = (ftObj.tenderTotalFee / bq).toDecimal(decimalObj.bills.unitPrice);
-                    }
-                }
-                else{
-                    ftObj.unitFee = buf.toDecimal(decimalObj.bills.unitPrice);
-                    ftObj.tenderUnitFee = btuf.toDecimal(decimalObj.bills.unitPrice);
-                }
+                ftObj.unitFee = buf.toDecimal(decimalObj.bills.unitPrice);
+                ftObj.tenderUnitFee = btuf.toDecimal(decimalObj.bills.unitPrice);
 
                 calcTools.checkFeeField(treeNode, ftObj);
 
@@ -1509,10 +1532,11 @@ class CalcProgram {
         // 定额或叶子清单自己的计算程序计算
         else{
             let fnArr = [];
+            calcTools.getGLJList(treeNode);
+
             if (treeNode.calcType == treeNodeCalcType.ctRationCalcProgram) {
                 // 量价、工料机类型的定额要求市场合价
                 if (treeNode.data.type == rationType.volumePrice || treeNode.data.type == rationType.gljRation){
-                    delete treeNode.data.gljList;
                     let muf = treeNode.data.marketUnitFee ? treeNode.data.marketUnitFee : 0;
                     let q = calcTools.uiNodeQty(treeNode) ? calcTools.uiNodeQty(treeNode) : 0;
                     let mtf = (muf * q).toDecimal(decimalObj.ration.totalPrice);
@@ -1521,33 +1545,9 @@ class CalcProgram {
                         treeNode.changed = true;
                     } ;
                 };
-
-                // 工料机类型的定额、定额要算暂估费
-                if (treeNode.data.type != rationType.volumePrice){
-                     treeNode.data.gljList = me.project.ration_glj.getGljArrByRation(treeNode.data);
-                    // 计算程序里没有暂估费的计算规则,会漏掉,所以这里要专门算。
-                    calcTools.estimateFee(treeNode);
-                    fnArr.push('estimate');
-                };
-
-                if (treeNode.data.programID == undefined){
-                    treeNode.data.programID = projectInfoObj.projectInfo.property.engineering;
-                };
-            }
-            else if (treeNode.calcType == treeNodeCalcType.ctBillCalcProgram) {
-                let rations = me.project.Ration.getBillsSortRation(treeNode.source.getID());
-                let q = calcTools.uiNodeQty(treeNode) ? calcTools.uiNodeQty(treeNode) : 1;
-                treeNode.data.gljList = me.project.ration_glj.getGatherGljArrByRations(rations, q);
-
-                if (treeNode.data.programID == undefined){
-                    treeNode.data.programID = projectInfoObj.projectInfo.property.engineering;
-                }
-
-                // 叶子清单自己的计算程序计算,其暂估费也要汇总算。
-                calcTools.estimateFee(treeNode);
-                fnArr.push('estimate');
             };
 
+            if (treeNode.data.programID == undefined) treeNode.data.programID = projectInfoObj.projectInfo.property.engineering;
             let template = me.compiledTemplates[treeNode.data.programID];
             treeNode.data.calcTemplate = template;
 
@@ -1579,6 +1579,8 @@ class CalcProgram {
             };
         };
 
+        if (!calcTools.isTotalCostBill(treeNode))  // 已在上面的分支中计算过
+            calcTools.estimateFee(treeNode);
         if (treeNode.changed && !changedArr.includes(treeNode)) changedArr.push(treeNode);
     };
 

+ 0 - 2
web/building_saas/main/js/models/composition.js

@@ -140,7 +140,6 @@ Composition.prototype.updateConsumptionInCache = function (pid,recode,updateData
 
 
 Composition.prototype.updateConsumption = function (updateData,recode,pid,callback){
-    console.log(updateData);
     let me = this;
     $.bootstrapLoading.start();
     CommonAjax.specialPost( '/glj/update',updateData,function (result) {
@@ -151,5 +150,4 @@ Composition.prototype.updateConsumption = function (updateData,recode,pid,callba
         }
         $.bootstrapLoading.end();
     })
-
 };

+ 1 - 1
web/building_saas/main/js/models/main_consts.js

@@ -299,7 +299,7 @@ const cpFeeTypes = [
     {type: 'machineDiff', name: '机械价差'},
     {type: 'adjustLabour', name: '调整人工费'},
     {type: 'adjustMachineLabour', name: '调整机上人工费'},
-    {type: 'estimate', name: '暂估费'},
+    // {type: 'estimate', name: '暂估费'},
     {type: 'common', name: '工程造价'},
     {type: 'fee1', name: '费用1'}//,
     // {type: 'fee2', name: '费用2'},

+ 2 - 3
web/building_saas/main/js/models/project_glj.js

@@ -186,11 +186,11 @@ ProjectGLJ.prototype.updatePriceFromRG = function (recode, updateField, newval)
     }
 };
 
-ProjectGLJ.prototype.updatePropertyFromMainSpread = function (node, updateField, newval) {
+ProjectGLJ.prototype.updatePropertyFromMainSpread = function (node, updateField, newval,editingText) {
     if (updateField == "contain") {//更新含量和工程量时,要走定额更新的逻辑
         projectObj.project.Ration.updateContain(newval,node);
     }if(updateField == "quantity"){
-        projectObj.project.quantity_detail.editMainTreeNodeQuantity(newval,node,updateField);
+        projectObj.project.quantity_detail.editMainTreeNodeQuantity(newval,node,updateField,editingText);
     } else {
         this.updateGLJProperty(node, updateField, newval);
     }
@@ -702,7 +702,6 @@ ProjectGLJ.prototype.calcQuantity  = function (init=false){
     let quantityMap={},changeArray=[];
     let rationGljGroup = _.groupBy(projectObj.project.ration_glj.datas,'projectGLJID')
     let q_decimal = getDecimal("glj.quantity");
-    console.log(init);
     for(let pglj of project_gljs ){
         let pg_index = gljOprObj.getIndex(pglj,gljKeyArray);
         pglj.subdivisionQuantity = 0;

+ 1 - 0
web/building_saas/main/js/models/quantity_detail.js

@@ -596,6 +596,7 @@ var quantity_detail = {
                         }else {
                             me.updateRationQuantity(value,node,null,editingText);
                         }
+                        gljOprObj.refreshView();
                     }else {
                         projectObj.mainController.refreshTreeNode([node]);
                     }

+ 9 - 0
web/building_saas/main/js/models/ration.js

@@ -653,3 +653,12 @@ var Ration = {
         return new ration(project);
     }
 };
+
+function FilterNumberFromUnit (unit) {
+    let reg = new RegExp('^[0-9]+');
+    if (reg.test(unit)) {
+        return parseInt(unit.match(reg)[0]);
+    } else {
+        return 1;
+    }
+};

+ 11 - 6
web/building_saas/main/js/models/ration_glj.js

@@ -489,22 +489,20 @@ var ration_glj = {
         ration_glj.prototype.insertGLJAsRation = function (GLJSelection, selected, callback) {
             let gljList = [];
             let allGLJ = gljOprObj.AllRecode;
-            let billsItemID = null;
-            let serialNo = 0;
-            let selectedSerialNo = null;
-            let nextNodeID = null;
-            let parentNodeID = null;
+            let billsItemID = null, serialNo = 0,selectedSerialNo = null,nextNodeID = null, parentNodeID = null, billNode = null;
             let children = [];
             if (selected.sourceType === project.Bills.getSourceType()) {
                 billsItemID = selected.data.ID;
                 parentNodeID = selected.getID();
                 nextNodeID = selected.tree.rootID();
+                billNode = selected;
             } else {
                 billsItemID = selected.data.billsItemID;
                 serialNo = selected.data.serialNo;
                 selectedSerialNo = selected.data.serialNo;
                 nextNodeID = selected.getNextSiblingID();
                 parentNodeID = selected.getParentID();
+                billNode = selected.parent;
             }
             children = project.Ration.getBillsSortRation(billsItemID);
             serialNo == 0 ? serialNo = children.length : "";
@@ -535,13 +533,20 @@ var ration_glj = {
                         materialType:glj.materialType,
                         materialCoe:glj.materialCoe,
                         repositoryId: glj.repositoryId
-                    }
+                    };
                     if (glj.hasOwnProperty("compilationId")) {
                         new_glj.from = "cpt";
                         if (glj.code.indexOf('-') != -1) {//这条工料机是用户通过修改名称、规格、型号等保存到补充工料机库的
                             new_glj.original_code = glj.code.split('-')[0];//取-前的编号作为原始编号
                         }
                     }
+                    if(optionsOprObj.getOption(optionsOprObj.optionsTypes.GENERALOPTS, 'rationQuanACToBillsQuan')){//需要根据清单转换工程量
+                        new_glj.quantityEXP="QDL";
+                        if(billNode.data.quantity){
+                            new_glj.quantity = scMathUtil.roundForObj(billNode.data.quantity/FilterNumberFromUnit(glj.unit),getDecimal("glj.quantity"));
+                            new_glj.contain =  scMathUtil.roundForObj(new_glj.quantity/billNode.data.quantity,6);
+                        }
+                    }
                     gljList.push(new_glj);
                 }
             }

+ 1 - 1
web/building_saas/main/js/views/calc_program_manage.js

@@ -51,7 +51,7 @@ let calcProgramManage = {
         me.mainSpread = sheetCommonObj.buildSheet($('#mainSpread')[0], me.mainSetting, me.datas.length);
         me.detailSpread = sheetCommonObj.buildSheet($('#detailSpread')[0], me.detailSetting, me.datas[0].calcItems.length);
         let arr = projectObj.project.calcProgram.compiledFeeTypeNames.slice();
-        arr.splice(arr.findIndex(function (e){return e == '暂估费'}), 1);
+        // arr.splice(arr.findIndex(function (e){return e == '暂估费'}), 1);
         let fieldName = new GC.Spread.Sheets.CellTypes.ComboBox();
         fieldName.items(arr);
         me.detailSpread.getSheet(0).getRange(-1, 4, -1, 1).cellType(fieldName);

+ 2 - 12
web/building_saas/main/js/views/glj_view.js

@@ -1186,7 +1186,7 @@ var gljOprObj = {
             projectObj.project.ration_glj.updateRationGLJByEdit(recode, updateField, newval);
         }
     },
-    updateRationTypeGLJ: function (value, node, fieldName) {
+    updateRationTypeGLJ: function (value, node, fieldName,editingText) {
         let newval;
         let updatePrice = false;
         if (fieldName == "marketUnitFee") {
@@ -1199,7 +1199,7 @@ var gljOprObj = {
             }
         } else {
             if (value != null) {
-                projectObj.project.projectGLJ.updatePropertyFromMainSpread(node, fieldName, value)
+                projectObj.project.projectGLJ.updatePropertyFromMainSpread(node, fieldName, value,editingText);
                 return;
                 //update
             }
@@ -1877,16 +1877,6 @@ function getDecimal(fieldID, node) {
     }
 }
 
-function getFormatter(decimal) {
-    var pre = "0.";
-    if (decimal <= 0) {
-        return "0";
-    }
-    for (i = 0; i < decimal; i++) {
-        pre += "0"
-    }
-    return pre;
-}
 
 function sortRationGLJ(list) {
     list = _.sortByAll(list, [function (item) {

+ 0 - 2
web/building_saas/main/js/views/glj_view_contextMenu.js

@@ -330,7 +330,6 @@ var gljContextMenu = {
 function getGLJData(actionType) {
     $('#actionType').val(actionType);
     $.bootstrapLoading.start();
-    console.log(+new Date());
     projectObj.project.ration_glj.getGLJData(function (result) {
         console.log(+new Date());
         zTreeHelper.createTree(result.datas.treeData, gljOprObj.gljTreeSetting, "gljTree", gljOprObj);
@@ -345,7 +344,6 @@ function getGLJData(actionType) {
         $('#modalCon').width($(window).width()*0.5);
         $("input[name='glj']").get(0).checked=true;
         $.bootstrapLoading.end();
-        console.log(+new Date());
         $("#glj_tree_div").modal({show:true});
         setTimeout(function(){
             gljOprObj.gljLibSpresd?gljOprObj.gljLibSpresd.refresh():'';

+ 86 - 60
web/building_saas/main/js/views/project_glj_view.js

@@ -85,6 +85,7 @@ projectGljObject={
         if(!this.projectGljSpread){
             this.projectGljSpread = SheetDataHelper.createNewSpread($("#project_glj_sheet")[0],2);
         }
+        this.projectGljSpread.bind(GC.Spread.Sheets.Events.RangeChanged, this.onProjectGljRangeChange);
         this.initProjectGljSheet();
         this.initMaterialTreeSheet();
     },
@@ -93,7 +94,6 @@ projectGljObject={
         this.initSheet(this.projectGljSheet,this.projectGljSetting);
         this.projectGljSheet.bind(GC.Spread.Sheets.Events.SelectionChanged,this.onProjectGljSelectionChange);
         this.projectGljSheet.bind(GC.Spread.Sheets.Events.EditStarting,this.onProjectGljEditStarting);
-        this.projectGljSpread.bind(GC.Spread.Sheets.Events.RangeChanged, this.onProjectGljRangeChange);
         this.projectGljSheet.name('projectGljSheet');
     },
     initMixRatio:function () {
@@ -102,7 +102,6 @@ projectGljObject={
             me.initMixRatioSpread();
             me.initRightClick();
         }
-        me.showMixRatioData();
     },
     initMixRatioSpread:function () {
         this.mixRatioSpread = SheetDataHelper.createNewSpread($("#mix_ratio_sheet")[0]);
@@ -116,7 +115,8 @@ projectGljObject={
         this.materialTree = cacheTree.createNew(this);
         this.materialTreeController = TREE_SHEET_CONTROLLER.createNew(this.materialTree, this.materialTreeSheet, this.materialTreeSetting);
         this.materialTreeController.bind(TREE_SHEET_CONTROLLER.eventName.treeSelectedChanged, this.onSelectionChange);
-        this.materialTreeSheet.bind(GC.Spread.Sheets.Events.EditStarting,this.onMaterialTreeEditStarting);
+        this.materialTreeSheet.bind(GC.Spread.Sheets.Events.EditStarting,this.onProjectGljEditStarting);
+        this.materialTreeSheet.bind(GC.Spread.Sheets.Events.ValueChanged, this.onProjectGLJValueChange);
         this.materialTreeSheet.name('materialTreeSheet');
     },
     createMaterialTreeSheetSetting:function () {
@@ -127,7 +127,6 @@ projectGljObject={
             this.materialTreeSetting.cols[l].readOnly = true;
         }
         return this.materialTreeSetting;
-
         function getSettingCol(header) {
             let aMap ={left:0,center:1,right:2};
             let hAlign = header.hAlign?aMap[header.hAlign]:0;
@@ -151,10 +150,18 @@ projectGljObject={
             if(header.cellType){
                 col.data.cellType = getCellType(header);
             }
+            if(header.decimalField){//设置formatter
+                let decimal = getDecimal(header.decimalField);
+                col.formatter = getFormatter(decimal);
+            }
+            col.readOnly = function (node) {
+                if(node.data.ParentID == -1 || node.data.id == 'GJ'){//三材类别项不能编辑)
+                    return true;
+                }
+                return false;
+            };
             return col;
         }
-
-        
         function getCellType(header) {
             return function () {
                 if(header.cellType === "checkBox"){
@@ -190,6 +197,7 @@ projectGljObject={
     showMixRatioData:function () {
         let me = this,gljId = null,gljType = null;
         let sheet = me.projectGljSpread.getActiveSheet();
+        let oldSel = me.mixRatioSheet.getSelections()[0];
         if(sheet.name() == 'projectGljSheet'){//projectGljSheet/materialSheet 工料机汇总和三材汇总表
             let sel = me.projectGljSheet.getSelections()[0];
             let srow = sel.row == -1?0:sel.row;
@@ -218,6 +226,7 @@ projectGljObject={
             me.mixRatioSheet.setRowCount(0);
             sheetCommonObj.showData(me.mixRatioSheet, me.mixRatioSetting,me.mixRatioData);
             me.mixRatioSheet.setRowCount(me.mixRatioData.length);
+            me.mixRatioSheet.setSelection(oldSel.row==-1?0:oldSel.row,oldSel.col,oldSel.rowCount,oldSel.colCount);
         })
     },
     getMixRatioSheetData:function (glj) {
@@ -246,9 +255,17 @@ projectGljObject={
     },
     projectGljEditChecking:function (row,col) {//return false表示不能编辑
         let me = projectGljObject;
-        let data = me.projectGljSheetData[row];
-        let dataCode = me.projectGljSetting.header[col].dataCode;
-        let lockColumns = me.projectGljSetting.view.lockColumns;
+        let data = null, setting=null;
+        let sheet = me.projectGljSpread.getActiveSheet();
+        if(sheet.name() ==  'projectGljSheet'){
+            data = me.projectGljSheetData[row];
+            setting = me.projectGljSetting;
+        }else if(sheet.name() ==  'materialTreeSheet'){
+            data = me.materialTree.selected.data;
+            setting = me.materialSetting;
+        }
+        let dataCode = setting.header[col].dataCode;
+        let lockColumns = setting.view.lockColumns;
 
         if(lockColumns.indexOf(col)!= -1){
             return false;
@@ -270,6 +287,12 @@ projectGljObject={
                return false;
             }
         }
+        if(dataCode == 'materialCoe'){//三材类别为空时,三材系数应只读,不允许输入。
+            if(data.materialType == undefined || data.materialType == null){
+                return false;
+            }
+        }
+
         return true;
     },
     onSelectionChange:function (){
@@ -277,19 +300,12 @@ projectGljObject={
         me.showMixRatioData();
         me.materialTreeSheet.repaint();
     },
-    onMaterialTreeEditStarting:function (sender, args) {
-        let me = projectGljObject;
-        let selected = me.materialTree.selected;
-        if(selected && (selected.data.ParentID == -1 || selected.data.id == 'GJ')){//三材类别项不能编辑
-            args.cancel = true;
-        }
-
-    },
     onProjectGljSelectionChange:function (sender, args) {
         let me = projectGljObject;
         let newSel = args.newSelections[0];
         let oldSel = args.oldSelections?args.oldSelections[0]:{};
         if(newSel.row != oldSel.row){
+            me.mixRatioSheet.getSelections()[0].row = -1;
             me.showMixRatioData();
         }
         me.projectGljSheet.repaint();
@@ -318,8 +334,8 @@ projectGljObject={
             }
         }
         if(canChange == false){//恢复原来的值
-            me.showProjectGljData();
-        }else {
+            info.sheetName =="materialTreeSheet"?me.showMaterialTreeData():me.showProjectGljData();
+        }else if(info.sheetName =="projectGljSheet"){
              me.batchUpdatePrice(changeInfo);
         }
     },
@@ -351,18 +367,27 @@ projectGljObject={
     showMaterialTreeData:function () {
         this.projectGljSpread.setActiveSheetIndex(1);
         let sel = this.materialTreeSheet.getSelections()[0];
-        let selNode = this.materialTree.selected;
         let gljList = projectObj.project.projectGLJ.datas.gljList;
         gljList = _.sortByAll(gljList, [ 'code']);
         this.createMaterialTree(gljList);
         this.materialTreeController.showTreeData();
         this.materialTreeSheet.setSelection(sel.row==-1?0:sel.row,sel.col,sel.rowCount,sel.colCount);
-        this.materialTreeController.setTreeSelected(selNode);
+        this.materialTreeController.setTreeSelected(this.materialTree.items[sel.row==-1?0:sel.row]);
     },
+    refreshDataSheet:function () {
+        let me = projectGljObject;
+        if(me.displayType == filterType.SCHZ){//三材汇总树节点
+            me.showMaterialTreeData();
+        }else {
+            me.showProjectGljData();
+            me.showMixRatioData();
+        }
+    },
+
     createMaterialTree:function (gljList) {
         let me = projectGljObject;
         let q_decimal = getDecimal("glj.quantity");
-        let GC = {id:'GC',name:materialType[materialTypeMap.GC],code:'GC',unit:'t',ParentID:-1,NextSiblingID:'MC'};//000001
+        let GC = {id:'GC',name:materialType[materialTypeMap.GC],code:'GC',unit:'t',ParentID:-1,NextSiblingID:'MC'};
         let GJ = {id:'GJ',name:materialType[materialTypeMap.GJ],code:'GJ',unit:'t',ParentID:'GC',NextSiblingID:-1};
         let MC = {id:'MC',name:materialType[materialTypeMap.MC],code:'MC',unit:'t',ParentID:-1,NextSiblingID:'SN'};
         let SN = {id:'SN',name:materialType[materialTypeMap.SN],code:'SN',unit:'m3',ParentID:-1,NextSiblingID:'SZ'};
@@ -503,11 +528,7 @@ projectGljObject={
             bgColour:'white'
         };
         gljOprObj.setGLJPrice(data,glj);
-
-
         data.is_main_material = glj.is_main_material == 1?1:0;
-
-
         //供货方式为完全甲供时设置甲供数量为总消耗量
         if (data.supply == 2) {
             data.supply_quantity = glj.quantity;
@@ -545,8 +566,6 @@ projectGljObject={
             me.showMixRatioData();
         }
         //me.projectGljSheetData[row] = me.getSheetDataByGLJ(glj);
-
-
     },
     initSheet: function (sheet,setting) {
         var me = this;
@@ -567,6 +586,7 @@ projectGljObject={
         let dataCode = me.mixRatioSetting.header[col].dataCode;
         let recode = me.mixRatioData[row];
         let value = info.newValue;
+        let parentSheet =  me.projectGljSpread.getActiveSheet();//三材汇总表和工料机汇总表
         if (!me.checkData(col,me.mixRatioSetting,value)) {
             alert('输入的数据类型不对,请重新输入!');
             me.mixRatioSheet.setValue(row, col, info.oldValue);
@@ -575,16 +595,27 @@ projectGljObject={
         value = scMathUtil.roundToString(value,getDecimal("glj.quantity"));
         let [parentMarketPrice, parentBasePrice] = me.getCompositionSumPrice('modify', row, value);
         let updateData ={id: recode.mix_ratio_id, field: 'mix_ratio.' + dataCode, value: value, market_price: parentMarketPrice, base_price: parentBasePrice};
-        let prow= projectGljObject.projectGljSheet.getActiveRowIndex();//取父机械或组成物的下标
-        let prowData = projectGljObject.projectGljSheetData[prow];
+        let prow = parentSheet.getActiveRowIndex();//取父机械或组成物的下标
+        let prowData = parentSheet.name() == 'projectGljSheet'?me.projectGljSheetData[prow]:me.materialTree.items[prow].data;
         composition.updateConsumption(updateData,recode,prowData.id,function (sid) {
-            me.refreshProjectGljRowByID(sid);
+           /* if(parentSheet.name() == 'projectGljSheet'){ 之前是单行刷新,父工料机与组成物对应的工料机分开刷,发现这样比整个刷新慢所以先整个刷新,当以后数据量大的时候再测试
+                me.refreshProjectGljRowByID(sid);
+            }*/
             me.refreshParentData(prow,prowData.id,sid);
         });
     },
     refreshParentData:function (row,pid,sid) {
         let me = this;
-        me.refreshProjectGljRow(row);
+        let sheet = me.projectGljSpread.getActiveSheet();
+        let parantData = null;
+        if(sheet.name() == 'projectGljSheet'){
+            me.showProjectGljData();// me.refreshProjectGljRow(row)  这里原来是分开刷新的,现在整个统一刷新,先留着
+            parantData = me.projectGljSheetData[row];
+        }else {
+            me.showMaterialTreeData();
+            parantData = me.materialTree.items[row].data;
+        }
+
         // 更新组成物缓存
         projectObj.project.composition.loadData();
         //先查找使用了父项目工料机的定额工料机
@@ -601,7 +632,7 @@ projectGljObject={
         for(let r of rations){
             let r_node = projectObj.project.mainTree.getNodeByID(r.ID);
             if(r_node){
-                r_node.data.marketUnitFee =  projectGljObject.projectGljSheetData[row].marketPrice;//parentMarketPrice;//这里用显示的价格
+                r_node.data.marketUnitFee =  parantData.marketPrice;//parentMarketPrice;//这里用显示的价格
                 updateNodes.push(r_node);
             }
         }
@@ -620,8 +651,9 @@ projectGljObject={
         let me = this, deleteRecode = me.mixRatioData[row];
         let consumption = deleteRecode.consumption;
         let [parentMarketPrice, parentBasePrice] = me.getCompositionSumPrice('delete', row);
-        let prow= projectGljObject.projectGljSheet.getActiveRowIndex();//取父机械或组成物的下标
-        let prowData = projectGljObject.projectGljSheetData[prow];
+        let parentSheet =  me.projectGljSpread.getActiveSheet();//三材汇总表和工料机汇总表
+        let prow= parentSheet.getActiveRowIndex();//取父机械或组成物的下标
+        let prowData = parentSheet.name() == 'projectGljSheet'?me.projectGljSheetData[prow]:me.materialTree.items[prow].data;
         let updateData = {id: deleteRecode.mix_ratio_id, field: 'mix_ratio.consumption' , value: 0, market_price: parentMarketPrice, base_price: parentBasePrice};
         projectObj.project.composition.deleteComposition(updateData,deleteRecode,prowData.id,function () {
             me.refreshParentData(prow,prowData.id);
@@ -651,25 +683,30 @@ projectGljObject={
     onProjectGLJValueChange:function (e,info) {//me.projectGljSetting
         let projectGLJ = projectObj.project.projectGLJ;
         let me = projectGljObject,row = info.row, col = info.col;
-        let dataCode = me.projectGljSetting.header[col].dataCode;
-        let recode = me.projectGljSheetData[row];
+        let setting = info.sheetName =="materialTreeSheet"?me.materialSetting:me.projectGljSetting;
+        let dataCode = setting.header[col].dataCode;
+        let recode = info.sheetName =="materialTreeSheet"?me.materialTree.selected.data:me.projectGljSheetData[row];
         let value = info.newValue;
-        if(info.newValue == undefined ){
+        if(info.newValue === undefined ){
             return;
         }
-        if (!me.checkData(col,me.projectGljSetting,value)) {
+        if (value&&!me.checkData(col,setting,value)) {
             setTimeout(function () {//为了不与click事件冲突
                 alert('输入的数据类型不对,请重新输入!');
             },200);
-            me.refreshProjectGljRow(row);
+            info.sheetName =="materialTreeSheet"?me.materialTreeController.refreshTreeNode([me.materialTree.selected]):me.refreshProjectGljRow(row);
             return ;
         }
         let callback=function (impactList) {
             info.sheet.suspendPaint();
             info.sheet.suspendEvent();
-            me.refreshProjectGljRow(row);
-            for(let g of impactList){
-                me.refreshProjectGljRowByID(g.id,row);
+            if(info.sheetName =="materialTreeSheet"){
+                me.showMaterialTreeData();
+            }else {
+                me.refreshProjectGljRow(row);
+                for(let g of impactList){
+                    me.refreshProjectGljRowByID(g.id,row);
+                }
             }
             info.sheet.resumeEvent();
             info.sheet.resumePaint();
@@ -679,6 +716,7 @@ projectGljObject={
                     projectObj.mainController.refreshTreeNode(projectObj.project.mainTree.roots);
                 });
             }
+            gljOprObj.refreshView();
         };
         if(dataCode=='basePrice'||dataCode=='marketPrice'){
             value= scMathUtil.roundForObj(value,getDecimal('glj.unitPrice'));//修改市场价和修改定额价时需要重新记算很多受影响的树节点,现在改成与定字额工料机那里调相同的方法。
@@ -764,7 +802,7 @@ projectGljObject={
     },
     changeFileCallback:function(){
         projectGljObject.unitPriceFileInit();
-        projectGljObject.showProjectGljData();
+        projectGljObject.refreshDataSheet();
         gljOprObj.refreshView();
         projectObj.project.calcProgram.calcAllNodesAndSave();
         if(socketObject.roomInfo){
@@ -790,7 +828,6 @@ projectGljObject={
     }
 };
 
-
 $(function () {
     let pojGljResizeEles = {};
     pojGljResizeEles.id = '#project-glj-main';
@@ -812,13 +849,10 @@ $(function () {
             me.initProjectGljSpread();
         }
         me.unitPriceFileInit();
-        //projectObj.project.projectGLJ.calcQuantity(); 在工程量有更新的地方调用
-        if(me.displayType == filterType.SCHZ){//三材汇总树节点
-            me.showMaterialTreeData();
-        }else {
-            me.showProjectGljData();
-        }
         me.initMixRatio();
+        //projectObj.project.projectGLJ.calcQuantity(); 在工程量有更新的地方调用
+        me.refreshDataSheet();
+
         loadSize(pojGljResizeEles, 'height', function () {
             me.projectGljSpread.refresh();
             me.mixRatioSpread?me.mixRatioSpread.refresh():'';
@@ -923,8 +957,6 @@ $(function () {
             $(".option.copy").show();
         }
     });
-
-
     $("#unitFile-save-as").on('shown.bs.modal', function () {
         // 获取当前建设项数据
         $("#save-as-name").val(projectGljObject.usedUnitPriceInfo.name + '副本');
@@ -960,14 +992,8 @@ $(function () {
     $("#filterType").on("click","ul li a",function(){
         let me = projectGljObject;
         me.displayType = filterType[this.id];
-        if(me.displayType == filterType.SCHZ){//三材汇总树节点
-            me.showMaterialTreeData();
-        }else {
-            me.showProjectGljData();
-            me.showMixRatioData();
-        }
+        me.refreshDataSheet();
     });
-
 });
 
 

+ 1 - 1
web/building_saas/main/js/views/project_property_decimal_view.js

@@ -43,7 +43,7 @@ decimalObj.decimal = function (field, node) {
             }
         }
     }
-    return this.process;
+    return  this[field]?this[field]:this.process;
 };
 
 function returnV(v, r){

+ 12 - 8
web/building_saas/main/js/views/project_view.js

@@ -404,7 +404,7 @@ var projectObj = {
         }else if(fieldName === 'remark'){
             projectObj.updateNodeField(node,value,'remark');
         }  else if(calcTools.isGljRation(node)){
-            gljOprObj.updateRationTypeGLJ(value,node,fieldName);
+            gljOprObj.updateRationTypeGLJ(value,node,fieldName,editingText);
         } else if (value !== calcFees.getFee(node.data, fieldName)||fieldName == 'quantity') {//工程量需要进行转换,所以做特殊处理
             if (fieldName === 'code' && !calcTools.isVolumePrice(node)) {
                 projectObj.updateCode(node, value);
@@ -659,17 +659,22 @@ var projectObj = {
                 that.mainController.bind(TREE_SHEET_CONTROLLER.eventName.beforeTreeSelectedChange, that.beforeMainTreeSelectedChange);
                 that.mainController.bind(TREE_SHEET_CONTROLLER.eventName.treeSelectedChanged, that.treeSelectedChanged);
 
-                that.mainSpread.getActiveSheet().startEdit();
-                that.mainSpread.getActiveSheet().endEdit();
+                setTimeout(function () {
+                    that.mainSpread.getActiveSheet().startEdit();//这两句需要挺多时间,而又需要在editend 事件前触发,而这些又不影响计算,所以这里用异步的方法
+                    that.mainSpread.getActiveSheet().endEdit();
+
+                    that.mainSpread.bind(GC.Spread.Sheets.Events.EditEnded, that.mainSpreadEditEnded);
+                },100);
                 that.mainSpread.bind(GC.Spread.Sheets.Events.SelectionChanged, that.amountAreaNumber);
                 that.mainSpread.bind(GC.Spread.Sheets.Events.LeaveCell, that.mainSpreadLeaveCell);
                 that.mainSpread.bind(GC.Spread.Sheets.Events.EnterCell, that.mainSpreadEnterCell);
                 that.mainSpread.bind(GC.Spread.Sheets.Events.EditStarting, that.mainSpreadEditStarting);
-                that.mainSpread.bind(GC.Spread.Sheets.Events.EditEnded, that.mainSpreadEditEnded);
+
                 that.mainSpread.bind(GC.Spread.Sheets.Events.RangeChanged, that.mainSpreadRangeChanged);
                 that.mainSpread.bind(GC.Spread.Sheets.Events.ClipboardChanged, that.msClipboardChanged);
                 that.mainSpread.bind(GC.Spread.Sheets.Events.ButtonClicked, that.onButtonClick);
                 that.mainSpread.bind(GC.Spread.Sheets.Events.CellDoubleClick, that.onCellDoubleClick);
+
                 //let loadOtherStartTime = +new Date();
                 that.loadMainSpreadContextMenu();
                 that.loadFocusLocation();
@@ -728,7 +733,7 @@ var projectObj = {
                             }
                             if(isFlag(selected.data)&&selected.data.flagsIndex.fixed.flag==fixedFlag.SUB_ENGINERRING){//焦点行是分部分项工程
                                 if(selected.children.length>0){
-                                   return selected.children[0].data.type==billType.FX;//焦点行是分部分项工程,且子项是分项
+                                   return selected.children[0].data.type==billType.FX ||selected.children[0].data.type==billType.BX;//焦点行是分部分项工程,且子项是分项或补项
                                 }else {
                                     return false
                                 }
@@ -1666,16 +1671,15 @@ $('#delete_row').on('shown.bs.modal', function (e) {
 
     function selectionChecking() {
         let selection = projectObj.mainSpread.getActiveSheet().getSelections()[0];
-        let mainTreeMap = {};
+        let mainTreeMap = {}, nodes = [];
         for(let i =0;i<selection.rowCount;i++){
             let tem_node = controller.tree.items[selection.row+i];
             if(i==0){//第一个直接添加;
                 mainTreeMap[tem_node.getID()] = tem_node;
             }else {
-                project.Bills.setNodeToMap(tem_node,mainTreeMap);
+                project.Bills.setNodeToMapAndArray(tem_node,mainTreeMap,nodes);
             }
         }
-        let nodes = changeMapToArray(mainTreeMap);
         if(nodes.length==1){
             return true
         }

+ 8 - 3
web/building_saas/pm/js/pm_newMain.js

@@ -648,12 +648,12 @@ const projTreeObj = {
     },
     showTreeData: function (nodes, headers,sheet) {
         let me = this;
-       // let sheet = me.workBook.getActiveSheet(); 为了共用
+        let tree = sheet.name() == "copyToSheet"?me.copyTree:me.tree;
         let fuc = function(){
             sheet.setRowCount(0);
             sheet.setRowCount(nodes.length);
             for(let i = 0; i < nodes.length; i++){
-                let treeNodeCell = me.getTreeNodeCell(me.tree);
+                let treeNodeCell = me.getTreeNodeCell(tree);
                 sheet.getCell(i, 0).cellType(treeNodeCell);
                 for(let j = 0; j < headers.length; j++){
                     sheet.getRange(-1, j, -1, 1).hAlign(GC.Spread.Sheets.HorizontalAlign[headers[j]['hAlign']]);
@@ -738,7 +738,12 @@ const projTreeObj = {
         let sheet = me.copyToWorkBook.getActiveSheet();
         sheet.options.isProtected = true;
         sheet.name('copyToSheet');
-        me.showTreeData(me.tree.items, me.copyToSetting.header, sheet);
+        let datas = [];
+        for(let i of me.tree.items){
+            datas.push(i.data);
+        }
+        me.copyTree  = pmTree.createNew(projTreeObj.setting, datas);
+        me.showTreeData(me.copyTree.items, me.copyToSetting.header, sheet);
         me.copySelected = null;
         let initSel = sheet.getSelections()[0] ? sheet.getSelections()[0] : {row: 0, rowCount: 1};
         projTreeObj.initSelection(initSel,null,sheet);