Bläddra i källkod

Merge branch 'master' of http://192.168.1.12:3000/SmartCost/ConstructionCost

TonyKang 7 år sedan
förälder
incheckning
d866590a3c

+ 3 - 3
modules/all_models/installation_fee.js

@@ -18,7 +18,7 @@ let feeRuleSchema = new Schema({
     machine: Number,
     position: String,//记取位置
     billID:String//记取位置对应的清单ID
-});
+},{versionKey:false,_id: false});
 
 //安装增加费-分册章节
 let installSectionSchema = new Schema({
@@ -26,7 +26,7 @@ let installSectionSchema = new Schema({
     feeItemId: String,
     feeRuleId: String,
     name: String
-});
+},{versionKey:false,_id: false});
 
 //安装增加费-费用项
 let installFeeItemSchema = new Schema({
@@ -36,7 +36,7 @@ let installFeeItemSchema = new Schema({
     position: String,//记取位置
     billID:String,//记取位置对应的清单ID
     isCal: {type: Number,default:0}//是否记取0:false 1:true
-});
+},{versionKey:false,_id: false});
 
 let installationFeeSchema = new Schema({
     ID:String,

+ 2 - 2
modules/fee_rates/facade/fee_rates_facade.js

@@ -409,7 +409,7 @@ async function getGCFeeRateFiles(userID){
 }
 
 async function getFeeRateByID(ID) {
-    let feeRateFile = await feeRateFileModel.findOne({'ID':ID});
-    let feeRate = await feeRateModel.findOne({ID:feeRateFile.feeRateID});
+    let feeRateFile = await feeRateFileModel.findOne({'ID':ID}, '-_id');
+    let feeRate = await feeRateModel.findOne({ID:feeRateFile.feeRateID}, '-_id');
     return [feeRateFile,feeRate]
 }

+ 20 - 17
modules/glj/models/glj_list_model.js

@@ -559,6 +559,7 @@ class GLJListModel extends BaseModel {
     async compositionInit(data, unitPriceFileId) {
         let gljId = data.glj_id === undefined ? 0 : data.glj_id;
         let projectId = data.project_id === undefined ? 0 : data.project_id;
+        let mixRatioModel = new MixRatioModel();
         if (gljId === 0 || projectId === 0) {
             throw '参数错误';
         }
@@ -568,27 +569,29 @@ class GLJListModel extends BaseModel {
         let [projectGljList, compositionGljList] = await this.getCompositionGLJList(gljId, projectId, indexs, fromTable);
         // 整理配合比待插入数据
         let mixRatioInsertData = [];
-        for (let tmp of compositionGljList) {
-            // 配合比数据插入
-            var connect_key =this.getIndex(data,['code','name','specs','unit','type']);
-            let mixRatioData = {
-                consumption: tmp.consumption,
-                glj_id: tmp.ID,
-                unit_price_file_id: unitPriceFileId,
-                connect_key: connect_key,
-                type: tmp.gljType,
-                code: tmp.code,
-                specs:tmp.specs,
-                name:tmp.name,
-                unit:tmp.unit
-            };
-            mixRatioInsertData.push(mixRatioData);
+        var connect_key =this.getIndex(data,['code','name','specs','unit','type']);
+        //先查找是否已存在配合比数据,在共用单价文件的情况下,有可能配合比数据存在,项目工料机数据不存在
+        let e_mList = await mixRatioModel.findDataByCondition({unit_price_file_id: unitPriceFileId,connect_key: connect_key},null,false);
+        if(e_mList.length <= 0){
+            for (let tmp of compositionGljList) {
+                // 配合比数据插入
+                let mixRatioData = {
+                    consumption: tmp.consumption,
+                    glj_id: tmp.ID,
+                    unit_price_file_id: unitPriceFileId,
+                    connect_key: connect_key,
+                    type: tmp.gljType,
+                    code: tmp.code,
+                    specs:tmp.specs,
+                    name:tmp.name,
+                    unit:tmp.unit
+                };
+                mixRatioInsertData.push(mixRatioData);
+            }
         }
-
         // 插入配合比表
         // 因为有可能项目工料机与单价数据已存在,但配合比数据不存在,所以先插入配合比,后续判断如果存在项目工料机则可以省下数据库操作
         if(mixRatioInsertData.length>0){
-            let mixRatioModel = new MixRatioModel();
             let addMixRatioResult = await mixRatioModel.add(mixRatioInsertData);
             if (!addMixRatioResult) {
                 throw '组成物插入单价数据失败!';

+ 3 - 3
modules/pm/controllers/new_proj_controller.js

@@ -33,9 +33,9 @@ module.exports = {
                 });
                 billsData.insertData(billsDatas, callback);
             },
-            function (cb) {
-                projCounter.insertData({"projectID": newProjID}, cb);
-            },
+           /* function (cb) {//这个计数器换了
+                projCounter.insertData({"projectID": newProjID}, cb);//这个计数器没什么用了
+            },*/
             async function (cb) {
                 let engineeringModel = new EngineeringLibModel();
                 let engineering = await engineeringModel.getEngineering(property.engineering_id);

+ 237 - 12
modules/pm/facade/pm_facade.js

@@ -4,13 +4,25 @@
 let mongoose = require('mongoose');
 let _ = require("lodash");
 let feeRate_facade = require('../../fee_rates/facade/fee_rates_facade');
+let logger = require("../../../logs/log_helper").logger;
 const uuidV1 = require('uuid/v1');
 let projectModel = mongoose.model('projects');
+let projectSettingModel =  mongoose.model('proj_setting');
+let billsModel = mongoose.model('bills');
+let rationModel = mongoose.model('ration');
+let gljListModel = mongoose.model("glj_list");
+let calcProgramsModel = mongoose.model('calc_programs');
+let labourCoesModel = mongoose.model('labour_coes');
 let feeRateModel = mongoose.model('fee_rates');
 let feeRateFileModel = mongoose.model('fee_rate_file');
 let unitPriceFileModel = mongoose.model("unit_price_file");
 let mixRatioModel = mongoose.model("mix_ratio");
 let unitPriceModel = mongoose.model("unit_price");
+let installationFeeModel = mongoose.model("installation_fee");
+let rationGLJModel = mongoose.model('ration_glj');
+let rationCoeModel = mongoose.model('ration_coe');
+let rationInstallationModel = mongoose.model('ration_installation');
+let quantityDetailModel = mongoose.model('quantity_detail');
 import CounterModel from "../../glj/models/counter_model";
 
 
@@ -19,24 +31,237 @@ module.exports={
     copyProject:copyProject
 };
 
-async function copyProject(userID, compilationID,data) {;
-    console.log(userID);
-    console.log(compilationID);
-    console.log(data);
+async function copyProject(userID, compilationID,data) {
+    let projectMap = data.projectMap;
+    let originalID = projectMap['copy'].document.ID;
+    let originalProperty = _.cloneDeep(projectMap['copy'].document.property);
+    let newProjectID = await getCounterID("projects");
+    let newFeeName = null,newUnitName = null;
+    let calcProgramFileID = uuidV1();//新的计算程序文件ID
+    let labourCoeFileID = uuidV1();//新的人工调整系数文件ID
+    let feeRateFileID = uuidV1();//新的费率文件ID
+    let unitPriceFileID = await getCounterID("unit_price_file");//新的单价文件ID
+    logger.info("复制项目: 旧项目ID: "+originalID+ " ------- 新项目ID: "+newProjectID);
+    //费率文件、单价文件重名检查
+    let feeRate =  await feeRateFileModel.findOne({rootProjectID:originalProperty.rootProjectID,name:originalProperty.feeFile.name,deleteInfo:null});
+    if(feeRate){//存在重名的文件
+        newFeeName = originalProperty.feeFile.name + '(' + new Date().Format('MM-dd hh:mm:ss') + '复制)';
+        projectMap['copy'].document.property.feeFile.name = newFeeName;
+    }
+
+    let unitPriceFile =  await unitPriceFileModel.findOne({root_project_id: originalProperty.rootProjectID,name:originalProperty.unitPriceFile.name,deleteInfo: null});
+    if(unitPriceFile){//存在重名的文件
+        newUnitName = originalProperty.unitPriceFile.name + '(' + new Date().Format('MM-dd hh:mm:ss') + '复制)';
+        projectMap['copy'].document.property.unitPriceFile.name = newUnitName;
+    }
 
-    let p = Promise.all([getFeeRate(),getUnitfile()]);
+    //更新项目的属性;
+    projectMap['copy'].document.ID = newProjectID;
+    projectMap['copy'].document.property.calcProgramFile.ID = calcProgramFileID;
+    projectMap['copy'].document.property.labourCoeFile.ID = labourCoeFileID;
+    projectMap['copy'].document.property.feeFile.id = feeRateFileID;
+    projectMap['copy'].document.property.unitPriceFile.id = unitPriceFileID;
+    projectMap['copy'].document.userID = userID;
+    projectMap['copy'].document.compilation = compilationID;
+    projectMap['copy'].document.createDateTime = new Date();
+
+    //清单、定额ID生成任务
+    let IDtasks = [
+        createIDsAndReturn(originalID,billsModel),
+        createIDsAndReturn(originalID,rationModel),
+        getProjectGLJIDAndReturn(originalID,newProjectID)
+    ];
+    let [billMap,rationMap,projectGLJMap] = await Promise.all(IDtasks);
+
+    //所有复制任务异步处理,提升效率  复制清单,定额,4个文件,项目工料机, 定额工料机,人工系数,工程量明细,定额安装增加费,安装增加费
+    let copyTasks = [
+        createProject(projectMap),
+        copyProjectSetting(originalID,newProjectID),
+        copyBills(newProjectID,billMap),
+        copyRations(newProjectID,billMap.uuidMaping,rationMap),
+        copyProjectGLJ(projectGLJMap.datas),
+        commonCopy(newProjectID,originalProperty.calcProgramFile.ID,calcProgramFileID,calcProgramsModel),
+        commonCopy(newProjectID,originalProperty.labourCoeFile.ID,labourCoeFileID,labourCoesModel),
+        copyFeeRate(originalProperty.rootProjectID,userID,originalProperty.feeFile.id,feeRateFileID,newFeeName),
+        copyUnitPriceFile(newProjectID,originalProperty.rootProjectID,userID,originalProperty.unitPriceFile.id,unitPriceFileID,newUnitName),
+        copyInstallFee(originalID,newProjectID),
+        copyRationSubList(originalID,newProjectID,billMap.uuidMaping,rationMap.uuidMaping,projectGLJMap.IDMap,rationGLJModel),
+        copyRationSubList(originalID,newProjectID,billMap.uuidMaping,rationMap.uuidMaping,projectGLJMap.IDMap,rationCoeModel),
+        copyRationSubList(originalID,newProjectID,billMap.uuidMaping,rationMap.uuidMaping,projectGLJMap.IDMap,quantityDetailModel),
+        copyRationSubList(originalID,newProjectID,billMap.uuidMaping,rationMap.uuidMaping,projectGLJMap.IDMap,rationInstallationModel)
+    ];
+    let p = await Promise.all(copyTasks);
+    return p[0];
+}
 
-    return await p;
+async function createIDsAndReturn(originalID,model) {
+    let uuidMaping = {};//做ID映射
+    let datas = [];
+    let result = await model.find({"projectID": originalID}, '-_id');
+    uuidMaping['-1'] = -1;
+    //建立uuid-ID映射
+    for(let d of result){
+        uuidMaping[d.ID] = uuidV1();
+        datas.push(d._doc);
+    }
+    return{uuidMaping:uuidMaping,datas:datas};
+}
 
+async function getProjectGLJIDAndReturn(originalID,newProjectID) {
+    let IDMap = {};
+    let datas = [];
+    let result = await gljListModel.find({project_id:originalID}, '-_id');
+    for(let d of result){
+        let newID = await getCounterID("glj_list");
+        IDMap[d.id] = newID;
+        d._doc.project_id = newProjectID;
+        d._doc.id = newID;
+        datas.push(d._doc);
+    }
+    return{IDMap:IDMap,datas:datas};
 }
 
+async function createProject(projectMap) {//复制项目
+    let tasks = [];
+    if(projectMap['update']){//如果复制后存在前一个节点,则更新其NextSiblingID
+        tasks.push({updateOne:{filter : projectMap['update'].query, update : {NextSiblingID:projectMap['copy'].document.ID}}});
+    }
+    tasks.push({insertOne: {document: projectMap['copy'].document}});//复制任务
+    await projectModel.bulkWrite(tasks);
+    return projectMap;
+}
+
+async function copyProjectSetting(originalID,newProjectID) {
+    let result = null;
+    let setting = await projectSettingModel.findOne({"projectID": originalID}, '-_id');
+    if(setting){
+        setting._doc.projectID =newProjectID;
+        result = await projectSettingModel.create(setting._doc);
+    }
+    return result;
+}
+
+async function copyBills(newProjectID,billMap) {
+     let uuidMaping = billMap.uuidMaping;//做ID映射
+    for(let doc of billMap.datas){
+         doc.projectID = newProjectID;
+         doc.ID = uuidMaping[doc.ID] ? uuidMaping[doc.ID] : -1;
+         doc.ParentID = uuidMaping[doc.ParentID] ? uuidMaping[doc.ParentID] : -1;
+         doc.NextSiblingID = uuidMaping[doc.NextSiblingID] ? uuidMaping[doc.NextSiblingID] : -1;
+    }
+    await insertMany(billMap.datas,billsModel);
+    return billMap.datas;
+}
+
+async function copyRations(newProjectID,billsIDMap,rationMap) {
+    let uuidMaping = rationMap.uuidMaping;
+    for(let doc of rationMap.datas){
+        doc.projectID = newProjectID;
+        doc.ID = uuidMaping[doc.ID] ? uuidMaping[doc.ID] : -1;
+        if(doc.billsItemID){
+            doc.billsItemID = billsIDMap[doc.billsItemID]?billsIDMap[doc.billsItemID]:-1;
+        }
+    }
+    if(rationMap.datas.length > 0){
+        await insertMany(rationMap.datas,rationModel);
+    }
+    return rationMap.datas;
+}
 
-async function getFeeRate() {
-    return await feeRateFileModel.findOne({ID:"e7527fa0-3bd0-11e8-bced-7f72a1e036f0"});
+async function copyProjectGLJ(gljList) {
+    await insertMany(gljList,gljListModel);
 }
 
-async function getUnitfile() {
-    return await unitPriceFileModel.findOne({id:958});
+async  function commonCopy(newProjectID,oldID,newID,model) { //对于只需更新ID和projectID的文件的复制
+    let result = null;
+    let file = await model.findOne({"ID": oldID}, '-_id');
+    if(file){
+        file._doc.ID = newID;
+        file._doc.projectID =newProjectID;
+        result = await model.create(file._doc);
+    }
+    return result;
+}
+
+async function copyFeeRate(rootProjectID,userID,originalFeeRateFileID,feeRateFileID,newName) {//复制费率和费率文件
+    let [feeRateFile,feeRate] =await feeRate_facade.getFeeRateByID(originalFeeRateFileID);
+    let newFeeRateID = uuidV1();
+    if(feeRate){
+        feeRate._doc.ID = newFeeRateID;
+        await feeRateModel.create(feeRate._doc);
+    }
+    if(feeRateFile){
+        feeRateFile._doc.ID = feeRateFileID;
+        newName?feeRateFile._doc.name = newName:'';
+        feeRateFile._doc.userID = userID;
+        feeRateFile._doc.rootProjectID = rootProjectID;
+        feeRateFile._doc.feeRateID = newFeeRateID;
+        await feeRateFileModel.create(feeRateFile._doc);
+    }
+}
+
+async function copyUnitPriceFile(newProjectID,rootProjectID,userID,originaluUnitPriceFileID,unitPriceFileID,newName) {//复制单价文件、组成物
+
+    let taskList = [
+        copyFile(newProjectID,rootProjectID,userID,originaluUnitPriceFileID,unitPriceFileID,newName),
+        copySubList(originaluUnitPriceFileID,unitPriceFileID,mixRatioModel),
+        copySubList(originaluUnitPriceFileID,unitPriceFileID,unitPriceModel)
+    ];
+
+    return await Promise.all(taskList);
+
+    async function copyFile(newProjectID,rootProjectID,userID,originaluUnitPriceFileID,unitPriceFileID,newName){
+        let unitPriceFile = await unitPriceFileModel.findOne({id:originaluUnitPriceFileID}, '-_id');
+        if(unitPriceFile){
+            unitPriceFile._doc.id = unitPriceFileID;
+            newName?unitPriceFile._doc.name = newName:'';
+            unitPriceFile._doc.project_id = newProjectID;
+            unitPriceFile._doc.user_id = userID;
+            unitPriceFile._doc.root_project_id = rootProjectID
+        }
+        await unitPriceFileModel.create(unitPriceFile._doc);
+    }
+
+    async function copySubList(srcFID,newFID,model) {
+        let mList = await model.find({unit_price_file_id: srcFID}, '-_id');
+        let rList = [];
+        for(let m of mList){
+            m._doc.unit_price_file_id = newFID;
+            m._doc.id = await getCounterID('mix_ratio');
+            rList.push(m._doc);
+        }
+        await insertMany(rList,model)
+    }
+}
+
+async function copyInstallFee(originalPID,newProjectID) {
+    let result = null;
+    let installationFee = await installationFeeModel.find({projectID:originalPID}, '-_id');
+    let newList = [];
+    for(let i of installationFee ){
+        i._doc.ID = uuidV1();
+        i._doc.projectID = newProjectID;
+        newList.push(i._doc);
+    }
+    if(newList.length >0){
+        result =  await installationFeeModel.insertMany(newList);
+    }
+    return result;
+}
+
+async function copyRationSubList(originalPID,newProjectID,billIDMap,rationIDMap,projectGLJIDMap,model) {// 定额工料机,附注条件,工程量明细,定额安装增加费
+    let subList = await model.find({projectID:originalPID}, '-_id');
+    let newList =[];
+    for(let s of subList){
+        s._doc.ID = uuidV1();
+        s._doc.projectID = newProjectID;
+        s._doc.rationID&&rationIDMap[s._doc.rationID]?s._doc.rationID = rationIDMap[s._doc.rationID]:'';
+        s._doc.billID&&billIDMap[s._doc.billID]?s._doc.billID = billIDMap[s._doc.billID]:'';
+        s._doc.billsItemID&&billIDMap[s._doc.billsItemID]?s._doc.billsItemID = billIDMap[s._doc.billsItemID]:'';
+        s._doc.projectGLJID&&projectGLJIDMap[s._doc.projectGLJID]?s._doc.projectGLJID = projectGLJIDMap[s._doc.projectGLJID]:'';
+        newList.push(s._doc);
+    }
+    await insertMany(newList,model);
 }
 
 async function moveProject(data) {
@@ -194,8 +419,8 @@ async function getCounterID(collectionName){
 async function insertMany(datas,model) {
     while (datas.length>1000){//因为mongoose限制了批量插入的条数为1000.所以超出限制后需要分批插入
         let newList = datas.splice(0,1000);//一次插入1000条
-        model.insertMany(newList);
+        await model.insertMany(newList);
     }
-    model.insertMany(datas);
+    await model.insertMany(datas);
 
 }

+ 6 - 1
web/building_saas/main/js/models/bills.js

@@ -612,6 +612,11 @@ var Bills = {
                         }
                     });
                 }else {
+                    if(parent){
+                        projectObj.converseCalculateBills(parent);
+                    }else { //删除的是大项费用要重新计算工程造价节点
+                        project.Bills.calcEngineeringCostNode(controller);
+                    }
                     project.projectGLJ.loadData();
                 }
             }
@@ -764,7 +769,7 @@ var Bills = {
                 }
                 controller.sheet.deleteRows(1, rowCount);
                 let index = sels[0]?sels[0].row:1;
-                controller.setTreeSelected(controller.tree.items[1]);
+                //controller.setTreeSelected(controller.tree.items[1]);
             });
             cbTools.refreshFormulaNodes();
         };

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

@@ -399,6 +399,7 @@ var cacheTree = {
             var success = false;
             success=this.cascadeRemove(node);
             this.sortTreeItems();
+            this.preSelected = null;
             return success;
         };
         Tree.prototype.cascadeRemove = function (node) {

+ 3 - 3
web/building_saas/main/js/views/project_view.js

@@ -459,8 +459,8 @@ var projectObj = {
     //repaint 动态下拉框
     mainSpreadEnterCell: function (sender, info) {
         let colSetting = projectObj.mainController.setting.cols[info.col];
-        if(colSetting.data.field === 'unit' || projectObj.lastCol.data.field === 'unit'||colSetting.data.field ==='subType'
-            || projectObj.lastCol.data.field === 'subType' || colSetting.data.field === 'programID' ||projectObj.lastCol.data.field === 'programID'){
+        if(colSetting.data.field === 'unit' || (projectObj.lastCol&&projectObj.lastCol.data.field === 'unit')||colSetting.data.field ==='subType'
+            || (projectObj.lastCol&&projectObj.lastCol.data.field === 'subType') || colSetting.data.field === 'programID' ||(projectObj.lastCol&&projectObj.lastCol.data.field === 'programID')){
             info.sheet.repaint();
         }
     },
@@ -1155,7 +1155,7 @@ var projectObj = {
         let me = this;
         TREE_SHEET_HELPER.massOperationSheet(sheet, function () {
             for(let node of nodes){
-                if(node){
+                if(node && node.serialNo()!= -1){
                     sheet.setStyle(node.serialNo(), -1, me.getNodeColorStyle(sheet, node));
                 }
             }

+ 9 - 0
web/building_saas/main/js/views/zlfb_view.js

@@ -276,6 +276,15 @@ let zlfb_object={
                     controller.sheet.showRow(1, GC.Spread.Sheets.VerticalPosition.center);
                 });
             }
+            mainTree.preSelected = null;
+            let selected = mainTree.findNode(mainTree.selected.getID());
+            if(!selected){
+                selected = controller.tree.items[0];
+            }
+            let sel = controller.sheet.getSelections()[0];
+            sel.row = selected.serialNo();
+            controller.sheet.setSelection(sel.row,sel.col,sel.rowCount,sel.colCount);
+            controller.setTreeSelected(selected);
             cbTools.refreshFormulaNodes();
             projectObj.project.installation_fee.calcInstallationFee(function () {
                 //重新计算

+ 31 - 96
web/building_saas/pm/js/pm_newMain.js

@@ -170,8 +170,6 @@ const projTreeObj = {
         }
         me.tree.selected = node;
         me.preSelection = newSel;
-        console.log("set main tree selected");
-        console.log(me.tree.selected);
         $(".tools-btn > a").not(".disabled").addClass("disabled");
         $("#add-engineering-btn").addClass("disabled");
         $('#add-tender-btn').removeClass('disabled');
@@ -293,7 +291,6 @@ const projTreeObj = {
                 tem_next = target.nextSibling;
                 //移动到target的后面
                 projectMap[target.id()] = {query:{'ID':target.id()},update:{'NextSiblingID':sel.id()}};
-                console.log(target.id()+'----'+target.data.name);
             }else {//移动后变成子项
                 tem_parent = target;
                 tem_next = target.firstChild();
@@ -301,11 +298,9 @@ const projTreeObj = {
             let nextID = tem_next?tem_next.id():-1;
             if(sel.preSibling() != null){//如果原来有前项,更新下一节点
                 projectMap[sel.preSibling().id()] = {query:{'ID':sel.preSibling().id()},update:{'NextSiblingID':sel.data.NextSiblingID}};
-                console.log(sel.preSibling().id()+'----'+sel.preSibling().data.name);
             }
             if(sel.parent.id() == tem_parent.id()){//移动前移动后的父项相同,只改变next
                 projectMap[selected.id()] = {query:{'ID':selected.id()},update:{'NextSiblingID':nextID}};
-                console.log(selected.id()+'----'+selected.data.name);
             }else {//
                 let temData = {query:{'ID':selected.id()},update:{'ParentID':tem_parent.id(),'NextSiblingID':nextID}};
                 let reName = projTreeObj.projectNameChecking(tem_parent,selected);//重名检查
@@ -313,7 +308,6 @@ const projTreeObj = {
                     temData.update['name'] = reName
                 }
                 projectMap[selected.id()] = temData;
-                console.log(selected.id()+'----'+selected.data.name);
             }
             return [tem_parent,tem_next]
         }
@@ -366,11 +360,12 @@ const projTreeObj = {
 
 
     },
-    projectNameChecking:function (parent,node) {
+    projectNameChecking:function (parent,node,type) {
         //decDate = '(' + new Date().Format('MM-dd hh:mm:ss') + '恢复)';
+        type=type?type:'移动';
         for(let c of parent.children){
            if(c.data.name == node.data.name){//如果存在同名的项目
-               return  node.data.name + '(' + new Date().Format('MM-dd hh:mm:ss') + '移动)';
+               return  node.data.name + '(' + new Date().Format('MM-dd hh:mm:ss') + type+')';
            }
         }
         return null;
@@ -626,6 +621,7 @@ const projTreeObj = {
         if(dataCode === 'engineeringCost'){
             if(node.data.projType !== projectType.folder){//显示除了文件夹节点的工程造价结果 -- vincent
                 value =  node.data.engineeringCost ? node.data.engineeringCost : '0.00';
+                value = scMathUtil.roundToString(value,2);
             }
         }
         else if(dataCode === 'unitPriceFile'){
@@ -700,6 +696,9 @@ const projTreeObj = {
     calEngineeringCost:function (node) {
         let projectNode = null;//建设项目节点
         let refreshNodes = [];
+        if(node.data.projType == projectType.folder){//如果是文件夹时不用计算
+            return;
+        }
         if(node.data.projType == projectType.project){
             projectNode = node;
         }
@@ -741,10 +740,11 @@ const projTreeObj = {
         projTreeObj.initSelection(initSel,null,sheet);
     },
     insert: function (data, parent, next) {
+        let preNode = this.tree.items[this.preSelection.row];
         let node = this.tree.addNodeData(data, parent, next);
         this.addRow(node);
         let newSel = this.workBook.getSheet(0).getSelections()[0];
-        this.initSelection(newSel, this.preSelection,this.workBook.getActiveSheet());
+        this.initSelection(newSel, {row:preNode.serialNo(),rowCount:1},this.workBook.getActiveSheet());//这里不能直接用this.preSelection,因为如果插入的记录在preSelection的前面时,之前old选中行已经变了,改不了old行的颜色
         return node;
     },
     addRow: function (node) {
@@ -1148,98 +1148,33 @@ $(document).ready(function() {
     $("#copy-to-confirm").click(function() {
         let originalNode = projTreeObj.tree.selected;
         let toNode = projTreeObj.copySelected;
-        let parent = null,next = null;
+        let parent = null,next = null,projectMap={};
         if(toNode.data.projType == projectType.engineering){//复制为目标的子节点
             parent = toNode;
-            next = toNode.nextSibling;
+            next = toNode.firstChild();
         }else if(toNode.data.projType == projectType.tender){//复制为目标的后兄弟
-            
-        }
-
-/*        tem_parent = target;
-        tem_next = target.firstChild();
-        tem_parent = target.parent;
-        tem_next = target.nextSibling;*/
-
+            parent = toNode.parent;
+            next = toNode.nextSibling;
+            projectMap['update'] = {query:{ID:toNode.id()}};//前一节点的下一个节点更新;
+        }
+        let nextID = next?next.id():-1;
+        let projectData = _.cloneDeep(originalNode.data);
+        projectData['ParentID'] = parent.id();
+        projectData['NextSiblingID'] = nextID;
+        projectData['property']['rootProjectID'] = parent.pid();
+        let rename = projTreeObj.projectNameChecking(parent,originalNode,"复制");//重名检查
+        rename? projectData['name'] = rename:'';
+        projectMap['copy'] = {document:projectData};
+        $("#copy-to-dialog").modal('hide');
 
-        console.log(originalNode);
-        console.log(toNode);
-        CommonAjax.post('/pm/api/copyProjects',{ID:'test',user_id: userID},function () {
-            
+        $.bootstrapLoading.start();
+        CommonAjax.post('/pm/api/copyProjects',{projectMap:projectMap,user_id: userID},function (result) {
+            console.log(result);
+            let newNode = projTreeObj.insert(result['copy'].document,parent,next);
+            let refreshNodes = projTreeObj.calEngineeringCost(newNode);
+            projTreeObj.refreshNodeData(refreshNodes);
+            $.bootstrapLoading.end();
         })
-        
-     /*   let dialog = $('#copy-to-dialog');
-         let target = GetTargetTreeNode($.fn.zTree.getZTreeObj('treeDemo2'));
-         let parent = null;
-         let next = null;
-         let pre = null;
-         let cur = projTreeObj.tree.selected;
-         if (!target) {
-         return false;
-         }
-         if (target.data.projType !== projectType.engineering) {
-         alert("请移动到单项工程中!");
-         return false;
-         }
-         if (target.data.projType !== projectType.tender && target.children.length !== 0 &&
-         target.firstChild().data.projType !== projectType.tender) {
-         dialog.modal('hide');
-         }
-
-         // 判断同级是否有同名
-         if (target.children.length > 0) {
-         for (let tmp in target.children) {
-         if (tmp === 0) {
-         continue;
-         }
-         if (target.children[tmp].data.name === cur.data.name) {
-         alert("对应单项工程中存在同名数据!");
-         return false;
-         }
-         }
-         }
-
-         if (target.data.projType === projectType.tender) {
-         parent = target.parent;
-         next = target.nextSibling;
-         } else {
-         parent = target;
-         next = target.firstChild();
-         }
-
-         if (parent !== cur.parent || (next !== cur && next !== cur.nextSibling)){
-         CommonAjax.post('/pm/api/getNewProjectID', {count: 1, user_id: userID}, function (IDs) {
-         let typeInfo = {
-         updateType: 'copy',
-         projType: cur.data.projectType
-         };
-         let updateData = GetUpdateData(null, parent, next, cur.data.name, cur.data.property, IDs.lowID, typeInfo);
-         updateData.forEach(function (data) {
-         if (data.updateType === 'copy') {
-         data['srcProjectId'] = cur.id();
-         }
-         });
-         pre = GetNeedUpdatePreNode(parent, next);
-         if (pre) {
-         updateData = {};
-         updateData['updateType'] = 'update';
-         updateData['updateData'] = {};
-         updateData['updateData'][projTreeObj.tree.setting.tree.id] = pre.id();
-         updateData['updateData'][projTreeObj.tree.setting.tree.nid] = projTreeObj.tree.maxNodeId() + 1;
-         }
-         projTreeObj.tree.maxNodeId(IDs.lowID - 1);
-         CommonAjax.post('/pm/api/copyProjects', {updateData: updateData, user_id: userID}, function (data) {
-         dialog.modal('hide');
-         data.forEach(function (nodeData) {
-         if (nodeData.updateType === 'copy') {
-         projTreeObj.insert(nodeData.updateData, parent, next);
-         }
-         });
-         }, function () {
-         dialog.modal('hide');
-         });
-         });
-         }*/
 
     });