Browse Source

Merge branch '1.0.0_online' of http://smartcost.f3322.net:3000/SmartCost/ConstructionCost into 1.0.0_online

zhongzewei 7 years ago
parent
commit
baf81be91b

+ 0 - 1
modules/ration_glj/controllers/ration_glj_controller.js

@@ -85,7 +85,6 @@ async function replaceGLJ(req, res){
     try {
         let data = req.body.data;
         data = JSON.parse(data);
-        console.log(data);
         let rdata= await ration_glj_facade.replaceGLJ(data);
         result.data=rdata;
     }catch (err){

+ 31 - 6
modules/ration_glj/facade/glj_calculate_facade.js

@@ -30,14 +30,14 @@ let stateSeq ={
 };
 
 
-async function calculateQuantity(query,noNeedCal){
+async function calculateQuantity(query,noNeedCal,refreshRationName = false){
     try {
          let  result ={
              glj_result:[],
              rationID:query.rationID
          };
          let impactRation = await ration.findOne({projectID:query.projectID,ID:query.rationID,deleteInfo:null});
-         let gljList = await ration_glj.find(query)//{projectID:query.projectID,rationID:query.rationID}
+         let gljList = await ration_glj.find(query);//{projectID:query.projectID,rationID:query.rationID}
          let coeList = await ration_coe.find({projectID:query.projectID,rationID:query.rationID}).sort('seq').exec();
          let assList=[];
          let assRation = null;
@@ -55,19 +55,25 @@ async function calculateQuantity(query,noNeedCal){
                  }
              }
          }
-        gljList = sortRationGLJ(gljList);
+         gljList = sortRationGLJ(gljList);
          for(let i =0;i<gljList.length;i++ ){
              let r = await calculateQuantityPerGLJ(gljList[i],i,coeList,assList,adjustState,noNeedCal);
              result.glj_result.push(r);
          }
 
-        if(noNeedCal==null){
+         if(noNeedCal==null){
             await ration_glj.bulkWrite(generateUpdateTasks(result.glj_result));
-        }
+         }
          adjustState= _.sortByOrder(adjustState, ['index'], ['asc']);
          adjustState=_.map(adjustState, _.property('content'));
          let adjustStateString = adjustState.join(';');
-         await ration.update({projectID:query.projectID,ID:query.rationID,deleteInfo: null},{adjustState:adjustStateString});
+         let setData = {adjustState:adjustStateString};
+         if(refreshRationName == true){//需要更新定额名称
+             let newName = generateRationName(impactRation,gljList);
+             setData.name = newName;
+             result.rationName = newName;
+         }
+         await ration.update({projectID:query.projectID,ID:query.rationID,deleteInfo: null},setData);
          result.adjustState=adjustStateString;
          return result;
     }catch (err){
@@ -76,6 +82,25 @@ async function calculateQuantity(query,noNeedCal){
     }
 }
 
+function generateRationName(ration,gljList) {
+    let caption = ration.caption ? ration.caption:ration.name;
+    if(ration.rationAssList && ration.rationAssList.length > 0){
+        let ass = ration.rationAssList[0];
+        if(ass.actualValue != null && ass.actualValue != undefined ){
+            caption =  caption.replace('%s',ass.actualValue);
+        }
+    }
+
+    for(let g of gljList){
+        //glj._doc.createType=='replace'&&glj.rcode!=glj.code
+        if(g.createType=='replace'&&g.rcode!=g.code){ //是替换工料机
+            caption = caption + ' '+g.name;
+            if(!_.isEmpty(g.specs)) caption = caption + ' '+g.specs
+        }
+    }
+    return caption;
+}
+
 function generateUpdateTasks(result) {
     let tasks = [];
     for(let i =0;i<result.length;i++){

+ 3 - 3
modules/ration_glj/facade/ration_ass_facade.js

@@ -58,7 +58,7 @@ function update_ration_ass(user_id,datas) {
                         stateRefresh:true,
                         rationID:result.cal_result.rationID,
                         adjustState:result.cal_result.adjustState,
-                        name:datas.doc.name
+                        name:result.cal_result.rationName
                     }
                 };
                 callback(null,[newObject,ration_glj_data,ration_data]);
@@ -73,10 +73,10 @@ async function doRationAssAdjust(ration,doc) {
     let result ={
         err:null,
         cal_result:[]
-    }
+    };
     try{
         await rationModel.update({projectID:ration.projectID,ID:ration.ID,deleteInfo: null},doc);
-        let cal_result = await glj_calculate_facade.calculateQuantity({projectID:ration.projectID,rationID:ration.ID});
+        let cal_result = await glj_calculate_facade.calculateQuantity({projectID:ration.projectID,rationID:ration.ID},null,true);
         result.cal_result=cal_result;
         return result;
     }catch (err){

+ 6 - 4
modules/ration_glj/facade/ration_glj_facade.js

@@ -644,9 +644,10 @@ async function replaceGLJ(data) {
     let stateResult = await glj_calculate_facade.calculateQuantity({
         projectID: data.projectID,
         rationID: data.rationID
-    }, true);
+    }, true,true);
     rdata.data = data;
     rdata.adjustState = stateResult.adjustState;
+    rdata.name = stateResult.rationName;
     return rdata;
 }
 async function mReplaceGLJ(data) {
@@ -724,8 +725,9 @@ async function doRationGLJUpdate(data) {
     let stateResult = await glj_calculate_facade.calculateQuantity({
         projectID: data.query.projectID,
         rationID: data.query.rationID
-    });
+    },null,true);
     resutl.adjustState = stateResult.adjustState;
+    resutl.name = stateResult.rationName;
     return resutl;
 }
 
@@ -800,9 +802,9 @@ async function changAdjustState(data, rationList) {
         let stateResult = await glj_calculate_facade.calculateQuantity({
             projectID: data.query.projectID,
             rationID: r
-        }, true);
+        }, true,true);
         if(stateResult){
-            stateList.push({rationID: r, adjustState: stateResult.adjustState});
+            stateList.push({rationID: r, adjustState: stateResult.adjustState,name:stateResult.rationName});
         }
     }
     return stateList;

+ 1 - 1
web/building_saas/main/js/controllers/block_controller.js

@@ -523,7 +523,7 @@ let BlockController = {
             temData.ID = newID; //新的清单ID
             if(temData.billsLibId && temData.billsLibId!="" && temData.code.length == 12){//是从清单库来的
                 let value = temData.code.substr(0,9);
-                if (value&&value.length === 9 && /^[\d]+$/.test(value)) {
+                if (value&&value.length === 9) {//&& /^[\d]+$/.test(value) 去掉全数字判断    07-31 zhang
                     temData.code = me.newFormatCode(value);
                 }
             }

+ 6 - 4
web/building_saas/main/js/controllers/project_controller.js

@@ -114,6 +114,7 @@ ProjectController = {
             newNode.data = newSource.data;
 
             this.syncDisplayNewNode(sheetController, newNode);
+            return newNode;
         }
         function getSubType(node){
             for(let sub of node.children){
@@ -135,10 +136,10 @@ ProjectController = {
         if (!project || !sheetController) { return null; }
         let selected = project.mainTree.selected;
         if(selected.parent==null&&isFlag(selected.data)&&selected.data.flagsIndex.fixed.flag==fixedFlag.SUB_ENGINERRING){//选中的是分部分项,则插入做为最后一个子项
-            this.addSpecialBill(project, sheetController,selected, null,true,billType.FB);
+            return this.addSpecialBill(project, sheetController,selected, null,true,billType.FB);
         }
         if(selected.parent){
-            this.addSpecialBill(project, sheetController,selected.parent, selected.nextSibling,true,billType.FB);
+            return this.addSpecialBill(project, sheetController,selected.parent, selected.nextSibling,true,billType.FB);
         }
 
     },
@@ -147,11 +148,11 @@ ProjectController = {
         let selected = project.mainTree.selected;
         console.log(selected);
         if(selected.data.type==billType.FB||(selected.parent==null&&isFlag(selected.data)&&selected.data.flagsIndex.fixed.flag==fixedFlag.SUB_ENGINERRING)){//选中的是分部或者是分部分项工程,则插入做为最后一个子项
-            this.addSpecialBill(project, sheetController,selected, null,true,billType.FX);
+            return this.addSpecialBill(project, sheetController,selected, null,true,billType.FX);
         }
         if(selected.parent){
             if(selected.data.type==billType.FX||selected.data.type==billType.BX){
-                this.addSpecialBill(project, sheetController,selected.parent, selected.nextSibling,true,billType.FX);
+                return this.addSpecialBill(project, sheetController,selected.parent, selected.nextSibling,true,billType.FX);
             }
         }
     },
@@ -169,6 +170,7 @@ ProjectController = {
             newNode.sourceType = project.Bills.getSourceType();
             newNode.data = newSource.data;
             this.syncDisplayNewNode(sheetController, newNode);
+            return newNode;
         }
     },
 

+ 28 - 8
web/building_saas/main/js/models/calc_program.js

@@ -112,8 +112,20 @@ let calcTools = {
             treeNode.source.children &&
             treeNode.source.children.length === 0;
     },
-    isbigBill: function(treeNode){
-        return this.isBill(treeNode) && treeNode.data.type == 1;
+    isBill_DXFY: function(treeNode){
+        return this.isBill(treeNode) && treeNode.data.type == billType.DXFY;
+    },
+    isBill_FB: function(treeNode){
+        return this.isBill(treeNode) && treeNode.data.type == billType.FB;
+    },
+    isBill_FX: function(treeNode){
+        return this.isBill(treeNode) && treeNode.data.type == billType.FX;
+    },
+    isBill_BILL: function(treeNode){
+        return this.isBill(treeNode) && treeNode.data.type == billType.BILL;
+    },
+    isBill_BX: function(treeNode){
+        return this.isBill(treeNode) && treeNode.data.type == billType.BX;
     },
     isNullBill: function (treeNode) {
         return this.isLeafBill(treeNode) && (treeNode.children.length === 0) && (!treeNode.data.calcBase);
@@ -137,6 +149,13 @@ let calcTools = {
     isGljRation: function (treeNode) {
         return this.isRationCategory(treeNode) && treeNode.data.type === rationType.gljRation;
     },
+    isSameTypeNode: function (node1, node2) {
+        if (node1.parent && node2.parent && (node1.parent === node2.parent) && (node1.sourceType === node1.sourceType)
+            && (node1.data && node2.data && node1.data.type === node2.data.type)){
+            return true;
+        }
+        return false;
+    },
     isInheritFrom: function (treeNode, flagsArr){
         let cur = treeNode;
         while (cur.parent) {
@@ -279,10 +298,10 @@ let calcTools = {
                 let aprice = calcTools.hasAdjustPrice() ? me.uiGLJPrice(glj["adjustPrice"], glj) : me.uiGLJPrice(glj["basePrice"], glj);
 
                 if (priceType == priceTypes.ptDiffPrice){
-                    if (aprice != mprice){
+                    // if (aprice != mprice){
                         temp = (temp + (qty * mprice).toDecimal(decimalObj.process)).toDecimal(decimalObj.process);
                         temp2 = (temp2 + (qty * aprice).toDecimal(decimalObj.process)).toDecimal(decimalObj.process);
-                    }
+                    // }
                 }
                 else {
                     if (priceType == priceTypes.ptBasePrice){ price = me.uiGLJPrice(glj["basePrice"], glj);}
@@ -324,12 +343,13 @@ let calcTools = {
                     if (md.type == gljType.MACHINE_LABOUR) {
                         let q = md["consumption"] ? md["consumption"] : 0;
                         let p = md["basePrice"] ? md["basePrice"] : 0;
-                        mdSum = mdSum + (q * p).toDecimal(decimalObj.ration.unitPrice);
-                        mdSum = (mdSum).toDecimal(decimalObj.ration.unitPrice);
+                        mdSum = mdSum + (q * p).toDecimal(decimalObj.glj.unitPriceHasMix);
+                        mdSum = (mdSum).toDecimal(decimalObj.glj.unitPriceHasMix);
                     }
                 }
-                result = result + (gljQ * mdSum).toDecimal(decimalObj.process);
-                result = (result).toDecimal(decimalObj.process);
+                // result = result + (gljQ * mdSum).toDecimal(decimalObj.process);
+                result = result + (gljQ * mdSum).toDecimal(decimalObj.ration.unitPrice);
+                result = (result).toDecimal(decimalObj.ration.unitPrice);
             }
         }
         result = (result).toDecimal(decimalObj.ration.unitPrice);

+ 14 - 7
web/building_saas/main/js/models/ration.js

@@ -553,10 +553,10 @@ var Ration = {
             let selected = project.mainTree.selected, newSource = null, newNode = null,pre=null,br=null;
             let billItemID = null,serialNo=1,nextID=null;
             let needInstall = false;
-            if (selected === null) { return; }
+            if (selected === null) { return null; }
             if (selected.sourceType === project.Bills.getSourceType() && selected.depth() > 0) {
                 if(selected.data.type === billType.FB){
-                    return;
+                    return null;
                 }
                 else if (selected.source.children.length > 0) {
                     alert('当前清单已有清单子项,不能套用定额。');
@@ -576,7 +576,8 @@ var Ration = {
                 pre = selected.source;
             };
             if(billItemID){
-                let newData =  me.getTempRationData(me.getNewRationID(), billItemID, serialNo, rationType);
+                let newID = me.getNewRationID();
+                let newData =  me.getTempRationData(newID, billItemID, serialNo, rationType);
                 let calQuantity =  isEmpty===true?false:optionsOprObj.getOption(optionsOprObj.optionsTypes.GENERALOPTS, 'rationQuanACToBillsQuan');
                 let brUpdate = [];
                 //更新兄弟节点的序列号
@@ -592,6 +593,9 @@ var Ration = {
                     needInstall = project.Bills.isFBFX(billsNode);//在分部分项插入的定额才需要定额安装增加费
                 }
                 $.bootstrapLoading.start();
+                newNode = project.mainTree.insert(billItemID, nextID, newID);
+                newNode.sourceType = project.Ration.getSourceType();
+                newNode.data = newData;
                 CommonAjax.post("/ration/addNewRation",{itemQuery:itemQuery,newData:newData,firstLibID: rationLibObj.getFirstStdRationLibID(),calQuantity:calQuantity,brUpdate:brUpdate,needInstall:needInstall},function (data) {
                     //更新缓存
                     me.datas.push(data.ration);
@@ -601,12 +605,12 @@ var Ration = {
 
                     //插入树节点
                     newSource = data.ration;
-                    newNode = project.mainTree.insert(billItemID, nextID, newSource.ID);
+                    // newNode = project.mainTree.insert(billItemID, nextID, newSource.ID);  上移到post方法外部。批量粘贴时,先插入空行,前端等不了,先生成树结点,效果同清单处理方式。
                     newNode.source = newSource;
-                    newNode.sourceType = project.Ration.getSourceType();
+                    // newNode.sourceType = project.Ration.getSourceType();
                     newNode.data = newSource;
                     project.projectGLJ.loadData(function () {
-                        ProjectController.syncDisplayNewNode(sheetController, newNode);
+                        // ProjectController.syncDisplayNewNode(sheetController, newNode);
                         project.ration_glj.addToMainTree(data.ration_gljs);
                         projectObj.mainController.refreshTreeNode([newNode], false);
                         project.calcProgram.calcAndSave(newNode,function () {
@@ -622,7 +626,10 @@ var Ration = {
                         $.bootstrapLoading.end();
                     });
                 })
+                ProjectController.syncDisplayNewNode(sheetController, newNode);
+                return newNode;
             }
+            else return null;
 
         };
         ration.prototype.deleteSubListOfRation = function(ration){
@@ -730,7 +737,7 @@ var Ration = {
                 if (calcTools.isLeafBill(node)
                     && (node.data.type != billType.DXFY)
                     && (node.data.type != billType.FB)
-                    && !project.Bills.isMeasure(node)) return true;  // 叶子清单项
+                    && project.Bills.isMeasure(node)) return true;  // 叶子清单项
             };
 
             return false;

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

@@ -430,9 +430,7 @@ var ration_glj = {
                     for (var key in doc) {
                         recode[key] = doc[key];
                     }
-                    if (data.hasOwnProperty('adjustState')) {//更新定额调整状态
-                        me.updateRationAdjustState(data.adjustState, recode.rationID, node);
-                    }
+                    me.refreshRationAfterEdit(data,recode.rationID, node);//更新名称和定额调整状态
                     if (recode.subList && recode.subList.length > 0) {
                         initShow = true;
                     }
@@ -481,16 +479,19 @@ var ration_glj = {
             var me = this;
             data.glj_result.forEach(function (item) {
                 me.refreshEachItme(item.doc, item.query);
-            })
-            me.updateRationAdjustState(data.adjustState, data.rationID, node);
+            });
+            me.refreshRationAfterEdit(data, data.rationID, node);
         };
-        ration_glj.prototype.updateRationAdjustState = function (adjustState, rationID, rnode) {
-            var nodes = [];
-            var node = _.find(projectObj.project.mainTree.items, function (n) {
-                return n.sourceType == ModuleNames.ration && n.data.ID == rationID;
-            })
+        ration_glj.prototype.refreshRationAfterEdit= function(data,rationID,rnode){
+            let nodes = [];
+            let node = projectObj.project.mainTree.findNode(rationID);
             if (node) {
-                node.data.adjustState = adjustState;
+                if(data.adjustState){
+                    node.data.adjustState = data.adjustState;
+                }
+                if(data.name){
+                    node.data.name = data.name;
+                }
                 nodes.push(node);
             }
             if (rnode) {
@@ -498,6 +499,7 @@ var ration_glj = {
             }
             projectObj.mainController.refreshTreeNode(nodes);
         };
+
         ration_glj.prototype.getGLJData = function (cb) {
             let engineerID = projectInfoObj.projectInfo.property.engineering_id;
             CommonAjax.get('/rationGlj/getGLJData/'+engineerID, function (data) {
@@ -684,6 +686,7 @@ var ration_glj = {
                             node ? nodes.push(node) : "";
                         }
                         rationNode.data.adjustState = result.adjustState;
+                        rationNode.data.name = result.name;
                         projectObj.mainController.refreshTreeNode(nodes);
                         project.calcProgram.calcAndSave(rationNode);
                         $.bootstrapLoading.end();

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

@@ -8,6 +8,7 @@ var gljOprObj = {
     ration: null,
     sheetData: [],
     checkb: null,
+    mainTreeSelectedChange:false,
     detailSheet: null,
     detailData: [],
     GLJSelection: [],
@@ -519,7 +520,10 @@ var gljOprObj = {
         this.addMixRatioToShow();//显示组成物信息
         this.initRationTree(init,this.getUnitPriceCodeMap());
         sheetCommonObj.showData(this.sheet, this.setting, this.sheetData);
-        if(selected){//定位光标到之前的位置
+        if(this.mainTreeSelectedChange == true){
+            this.sheet.setSelection(0,1,1,1);//默认选中第一行,第二列(名称列)
+            this.mainTreeSelectedChange = false;
+        }else if(selected){//定位光标到之前的位置
             this.sheet.setSelection(selected[0].row,selected[0].col,selected[0].rowCount,selected[0].colCount);
         }
     },
@@ -534,7 +538,7 @@ var gljOprObj = {
                    if(codeMap[preCode]) {
                        codeMap[preCode].push({text:code,value:connectKey});
                    }else {
-                       codeMap[preCode]=[{text:code,value:connectKey}];
+                       codeMap[preCode]=[{text:code ,value:connectKey}];
                    }
                 }
             }
@@ -1071,6 +1075,7 @@ var gljOprObj = {
                     }
                     //project.ration_glj.addToMainTree(data);
                     selected.data.adjustState = result.adjustState;
+                    selected.data.name = result.name;
                     projectObj.mainController.refreshTreeNode(nodes);
                     project.calcProgram.calcAndSave(selected);
                     $.bootstrapLoading.end();
@@ -1126,6 +1131,7 @@ var gljOprObj = {
             })
             if (node) {
                 node.data.adjustState = s.adjustState;
+                node.data.name = s.name;
                 nodes.push(node);
                 rationNodes.push(node);
             }

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

@@ -100,7 +100,7 @@ let MainTreeCol = {
             return node.data.subType != 201 && node.data.subType != 4 && node.data.subType != 5
         },
         commonUnitFee: function (node) {
-            return !(calcTools.isLeafBill(node) && !calcTools.isbigBill(node) && !calcTools.isCalcBaseBill(node) && !calcTools.isInheritFrom(node, [fixedFlag.SUB_ENGINERRING, fixedFlag.MEASURE]));
+            return !(calcTools.isLeafBill(node) && !calcTools.isBill_DXFY(node) && !calcTools.isCalcBaseBill(node) && !calcTools.isInheritFrom(node, [fixedFlag.SUB_ENGINERRING, fixedFlag.MEASURE]));
         },
         //根据节点、父节点类型判断是否可用计算基数
         calcBaseType: function (node) {

+ 127 - 4
web/building_saas/main/js/views/project_view.js

@@ -35,6 +35,7 @@ var projectObj = {
         if($('#linkComments').hasClass('active')){
             subViewObj.loadComments(node);
         }
+        gljOprObj.mainTreeSelectedChange = true;
         gljOprObj.showDataIfRationSelect(node);
         if (activeSubSheetIsCalcProgram())
             calcProgramObj.refreshCalcProgram(node, 3);
@@ -322,12 +323,12 @@ var projectObj = {
             withinValidFixed = true;
         }
         if(withinValidFixed && (node.data.type==billType.FX||node.data.type==billType.BX||(node.data.type==billType.BILL&&node.source.children.length==0))){//是分项、补项或者叶子清单的情况下才需要查找替换
-            if (value&&value.length === 9 && /^[\d]+$/.test(value)) {
+            if (value&&value.length === 9) {//&& /^[\d]+$/.test(value)  去掉全数字判断    07-31 zhang
                 stdMatchCode = value;
                 formatCode = project.Bills.newFormatCode(stdMatchCode);
                 searchStdBillsAndUpdate(stdMatchCode, formatCode);
                 return;
-            } else if (value&&value.length === 12 && /^[\d]+$/.test(value)) {
+            } else if (value&&value.length === 12 ) {//&& /^[\d]+$/.test(value) 去掉全数字判断    07-31 zhang
                 stdMatchCode = value.substr(0, 9);
                 matchs = project.Bills.sameStdCode(stdMatchCode, node.data.code);
                 if (matchs.indexOf(value) === -1) {
@@ -487,8 +488,7 @@ var projectObj = {
                 }
                 else if (node.sourceType === project.Ration.getSourceType()) {
                     project.Ration.updateField(node.source, fieldName, value);
-                };
-
+                }
                 if (colSetting.data.wordWrap) {
                     this.mainSpread.getActiveSheet().autoFitRow(node.serialNo());
                 }
@@ -583,6 +583,127 @@ var projectObj = {
             }
         }
     },
+    onClipboardPasting: function (sender, info){
+        info.cancel = true;
+
+        let rIdx = info.sheet.getActiveRowIndex();
+        let node = projectObj.project.mainTree.items[rIdx];
+        if (!node.parent){
+            hintBox.infoBox('系统提示','大项费用不允许粘贴!', 1);
+            return false;
+        };
+
+        let colName = projectObj.project.projSetting.main_tree_col.cols[info.cellRange.col].data.field;
+        if (colName == 'code'){
+            function getNodeType(node) {
+                let t = null;
+                if (calcTools.isRationItem(node))
+                    t = 1
+                else if (calcTools.isBill(node)){
+                    if (calcTools.isBill_FB(node))
+                        t = 2
+                    else if (calcTools.isBill_FX(node) || calcTools.isBill_BX(node))
+                        t = 3
+                    else if (calcTools.isBill_BILL(node))
+                        t = 4;
+                };
+                return t;
+            };
+            function getPasteTextArr(info) {
+                let copyText = info.pasteData.text.trim();
+                if (!copyText) return null;
+                let rows = copyText.split('\r\n');
+                let rstArr = [];
+                for (let row of rows) {
+                    row = row.trim();
+                    row = row.split('\t');
+                    rstArr.push(row);
+                }
+                return rstArr;
+            };
+            function getPasteNodes(count, nodeType) {
+                let nodesArr = [];
+                let curNode = null;
+                for (let i = rIdx; i < rIdx + count; i++) {
+                    curNode = projectObj.project.mainTree.items[i];
+                    if (curNode && calcTools.isSameTypeNode(curNode, node)){
+                        nodesArr.push(curNode);
+                    }
+                    else{
+                        curNode = projectObj.project.mainTree.items[i - 1];
+                        break;
+                    }
+                };
+
+                if (nodesArr.length < count){
+                    if (projectObj.project.mainTree.selected != curNode)
+                        projectObj.project.mainTree.selected = curNode;
+
+                    let add = count - nodesArr.length;
+                    for (let i = 0; i < add; i++) {
+                        switch (nodeType) {
+                            case 1:
+                                curNode = projectObj.project.Ration.addNewRation(null,rationType.ration,null,true);
+                                break;
+                            case 2:
+                                curNode = ProjectController.addFB(projectObj.project, projectObj.mainController);
+                                break;
+                            case 3:
+                                curNode = ProjectController.addFX(projectObj.project, projectObj.mainController);
+                                break;
+                            case 4:
+                                curNode = ProjectController.addBills(projectObj.project, projectObj.mainController);
+                                break;
+                        }
+
+                        if (!curNode){
+                            hintBox.infoBox('系统提示','插入新结点出错,粘贴失败!', 1);
+                            return nodesArr;
+                        }
+                        else{
+                            nodesArr.push(curNode);
+                            if (projectObj.project.mainTree.selected != curNode)
+                                projectObj.project.mainTree.selected = curNode;
+                        }
+                    }
+                };
+
+                return nodesArr;
+            };
+            function doPaste(datas, nodes, nodeType) {
+                if (nodeType == 1){  // 批量粘贴定额有严重的异步问题,这里要和清单分开处理
+                    let updateRationCodes = [];
+                    for (let i = 0; i < datas.length; i++) {
+                        let ptNode = nodes[i];
+                        let code = datas[i][0];
+                        updateRationCodes.push({'node':ptNode, value:code});
+                    }
+                    projectObj.project.Ration.updateRationCodes(updateRationCodes);
+                }
+                else {
+                    for (let i = 0; i < datas.length; i++) {
+                        let ptNode = nodes[i];
+                        let code = datas[i][0];
+                        if (!(ptNode.data && ptNode.data.code && ptNode.data.code.sameText(code))){
+                            projectObj.updateCode(ptNode, code);
+                        };
+                    }
+                }
+                projectObj.mainController.refreshTreeNode(nodes);
+            };
+
+            let tagType = getNodeType(node);
+            if (!tagType){
+                hintBox.infoBox('系统提示', '该树结点类型不支持从项目编码列粘贴!', 1);
+                return false;
+            };
+
+            let datas = getPasteTextArr(info);
+            if (!datas) return;
+            let pasteNodes = getPasteNodes(datas.length, tagType);
+            doPaste(datas, pasteNodes, tagType);
+        };
+    },
     mainSpreadEditEnded: function (sender, info) {
         console.log('enterEDEnd');
         let project = projectObj.project;
@@ -748,6 +869,8 @@ var projectObj = {
                 that.mainSpread.bind(GC.Spread.Sheets.Events.ButtonClicked, that.onButtonClick);
                 that.mainSpread.bind(GC.Spread.Sheets.Events.CellDoubleClick, that.onCellDoubleClick);
                 that.mainSpread.bind(GC.Spread.Sheets.Events.ColumnWidthChanged, that.onColumnWidthChanged);
+                that.mainSpread.bind(GC.Spread.Sheets.Events.ClipboardPasting, that.onClipboardPasting);
+
                 //let loadOtherStartTime = +new Date();
                 if(!projectReadOnly){
                     that.loadMainSpreadContextMenu();

+ 1 - 1
web/building_saas/report/html/rpt_main.html

@@ -26,8 +26,8 @@
                     <div class="panel">
                         <div class="panel-body">
                             <div class="btn-group" role="group" aria-label="Button group with nested dropdown" id="export_div">
-                                <button type="button" class="btn btn-outline-primary btn-sm" id="show_excel_output_cfg" data-toggle="modal" data-target="#export_excel" style="display:none"></button>
                                 <button type="button" class="btn btn-outline-primary btn-sm" onclick="rptControlObj.checkAndGetExcel()"><i class="fa fa-file-excel-o"></i> Excel <span class="badge badge-secondary">0</span></button>
+                                <button type="button" class="btn btn-outline-primary btn-sm" id="show_excel_output_cfg" data-toggle="modal" data-target="#export_excel" style="display:none"></button>
                                 <button type="button" class="btn btn-outline-primary btn-sm" onclick="rptControlObj.getPDF()"><i class="fa fa-file-pdf-o"></i> PDF <span class="badge badge-secondary">0</span></button>
                             </div>
                         </div>