Ver código fonte

清单指引插入清单定额

zhongzewei 7 anos atrás
pai
commit
250cd461be

+ 13 - 3
modules/complementary_ration_lib/models/searchModel.js

@@ -10,16 +10,26 @@ let stdSectionTreeModel = require ('../../ration_repository/models/ration_sectio
 let stdRationModel = require ('../../ration_repository/models/ration_item').Model;
 
 class SearchDao{
-    async getRationItem(userId, rationRepIds, code, callback){
+    async getRationItem(userId, rationRepIds, code, ID, callback){
         let ration = null;
         try{
-            let stdRation = await stdRationModel.findOne({rationRepId: {$in: rationRepIds}, code: code, $or: [{isDeleted: null}, {isDeleted: false}]});
+            let stdQuery = {rationRepId: {$in: rationRepIds}, code: code, $or: [{isDeleted: null}, {isDeleted: false}]};
+            if(ID){
+                stdQuery = {ID: ID, $or: [{isDeleted: null}, {isDeleted: false}]};
+            }
+            //let stdRation = await stdRationModel.findOne({rationRepId: {$in: rationRepIds}, code: code, $or: [{isDeleted: null}, {isDeleted: false}]});
+            let stdRation = await stdRationModel.findOne(stdQuery);
             if(isDef(stdRation)){
                 ration = stdRation._doc;
                 ration.type = 'std';
             }
             else{
-                let compleRation = await compleRationModel.findOne({userId: userId, rationRepId: {$in: rationRepIds}, code: code, deleteInfo: null});
+                let compleQuery = {userId: userId, rationRepId: {$in: rationRepIds}, code: code, deleteInfo: null};
+                if(ID){
+                    compleQuery = {ID: ID, deleteInfo: null};
+                }
+                //let compleRation = await compleRationModel.findOne({userId: userId, rationRepId: {$in: rationRepIds}, code: code, deleteInfo: null});
+                let compleRation = await compleRationModel.findOne(compleQuery);
                 if(isDef(compleRation)){
                     ration = compleRation._doc;
                     ration.type = 'complementary';

+ 23 - 1
modules/main/controllers/ration_controller.js

@@ -45,7 +45,8 @@ module.exports = {
     },
     insertGLJAsRation:insertGLJAsRation,
     replaceRations:replaceRations,
-    addNewRation:addNewRation
+    addNewRation:addNewRation,
+    addMultiRation: addMultiRation
 };
 
 async function addNewRation(req,res) {
@@ -67,6 +68,27 @@ async function addNewRation(req,res) {
     res.json(result);
 }
 
+async function addMultiRation(req,res) {
+    let result={
+        error:0
+    }
+    try {
+        let data = req.body.data;
+        if(typeof data === 'object'){
+            data = JSON.stringify(data);
+        }
+        data = JSON.parse(data);
+        console.log(`data`);
+        console.log(data);
+        result.data = await ration_facade.addMultiRation(data.newDatas);
+    }catch (err){
+        logger.err(err);
+        result.error=1;
+        result.message = err.message;
+    }
+    res.json(result);
+}
+
 async function replaceRations(req,res) {
     let result={
         error:0

+ 15 - 4
modules/main/facade/ration_facade.js

@@ -23,7 +23,8 @@ let projectModel = mongoose.model('projects');
 
 module.exports = {
     replaceRations: replaceRations,
-    addNewRation:addNewRation
+    addNewRation:addNewRation,
+    addMultiRation: addMultiRation
 };
 async function addNewRation(data) {
     let query = data.itemQuery;
@@ -31,8 +32,8 @@ async function addNewRation(data) {
     let startTime = +new Date();
     if(query){
         let searchDao = new SearchDao();
-        stdRation = await searchDao.getRationItem(query.userID,[query.rationRepId],query.code);
-        data.newData.code = query.code;
+        stdRation = await searchDao.getRationItem(query.userID,[query.rationRepId],query.code, query.ID);
+        //data.newData.code = query.code;
     }
     let stdRationTime = +new Date();
     console.log("取std定额时间-------------------------------"+(stdRationTime - startTime));
@@ -49,6 +50,15 @@ async function addNewRation(data) {
     }
 }
 
+async function addMultiRation(datas) {
+    let rst = [];
+    for(let data of datas){
+        let r = await addNewRation(data);
+        rst.push(r);
+    }
+    return rst;
+}
+
 async function  updateSerialNo(serialNoUpdate){
     let tasks=[];
     for(let data of serialNoUpdate){
@@ -72,6 +82,7 @@ async function  updateSerialNo(serialNoUpdate){
 async function insertNewRation(newData,firstLibID,std,calQuantity) {//插入新的定额
     let startTime = +new Date();
     if(std){
+        newData.code = std.code;
         newData.name = std.name;
         newData.caption = std.caption;
         newData.unit = std.unit;
@@ -109,7 +120,7 @@ async function replaceRations(userID,data) {
     let searchDao = new SearchDao();
     let recodes = [];
     for(let recode of data.nodeInfo){
-        let stdRation = await searchDao.getRationItem(userID,data.libIDs,recode.newCode);
+        let stdRation = await searchDao.getRationItem(userID,data.libIDs,recode.newCode, null);
         let newRecode = await replaceRation(recode,stdRation,data.firstLibID,data.projectID,data.calQuantity);
         if(newRecode){
             recodes.push(newRecode);

+ 1 - 0
modules/main/routes/ration_route.js

@@ -12,6 +12,7 @@ module.exports = function (app) {
     rationRouter.post('/insertGLJAsRation', rationController.insertGLJAsRation);
     rationRouter.post('/replaceRations', rationController.replaceRations);
     rationRouter.post('/addNewRation', rationController.addNewRation);
+    rationRouter.post('/addMultiRation', rationController.addMultiRation);
 
     app.use('/ration', rationRouter);
 };

+ 1 - 1
modules/std_billsGuidance_lib/facade/facades.js

@@ -39,7 +39,7 @@ async function getLibWithBills(libID){
     if(!billsLib){
         throw '引用的清单规则库不存在!';
     }
-    let bills = await stdBillsModel.find({billsLibId: billsLib.billsLibId, deleted: false}, '-_id code name ID NextSiblingID ParentID');
+    let bills = await stdBillsModel.find({billsLibId: billsLib.billsLibId, deleted: false});
     return {guidanceLib: guidanceLib[0], bills};
 }
 

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

@@ -333,6 +333,9 @@ var TREE_SHEET_HELPER = {
                 else if(sheetName === 'stdRationLib_chapter'){
                     sessionStorage.setItem('stdRationLibExpState', rationLibObj.tree.getExpState(rationLibObj.tree.items));
                 }
+                else if(sheetName === 'stdBillsGuidance_bills'){
+                    sessionStorage.setItem('stdBillsGuidanceExpState', billsGuidance.bills.tree.getExpState(billsGuidance.bills.tree.items));
+                }
                 TREE_SHEET_HELPER.massOperationSheet(hitinfo.sheet, function () {
                     let iCount = node.posterityCount(), i, child;
                     for (i = 0; i < iCount; i++) {

+ 2 - 4
web/building_saas/main/html/main.html

@@ -265,9 +265,9 @@
                                       </div>
                                   </div>
                                   <div class="row" style="margin-left: 1px;">
-                                      <div id="billsGuidance_bills" class="main-data-side-zb" style="width: 49%; float: left; margin: 0; padding: 0;">
+                                      <div id="billsGuidance_bills" class="main-data-side-zb" style="width: 53%; float: left; margin: 0; padding: 0;">
                                       </div>
-                                      <div id="billsGuidance_items" class="main-data-side-zi" style="width: 50%; float: left; margin: 0; padding: 0;">
+                                      <div id="billsGuidance_items" class="main-data-side-zi" style="width: 46%; float: left; margin: 0; padding: 0;">
                                       </div>
                                   </div>
                               </div>
@@ -1346,8 +1346,6 @@
 
 
             $(document).ready(function(){
-                console.log(1 - 1);
-                console.log(1 - 1);
                 //createTree();
               /*  document.onkeydown=keydown;
                 function keydown(e){

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

@@ -434,6 +434,102 @@ var Ration = {
                 }
             })
         };
+        ration.prototype.addMultiRation = function (items, callback) {
+            let me = this;
+            let project = projectObj.project, sheetController = projectObj.mainController;
+            let engineering = projectInfoObj.projectInfo.property.engineering;
+            let selected = project.mainTree.selected, newSource = null, newNode = null,pre=null,br=null;
+            let billItemID = null,serialNo=1,nextID=null;
+            let needInstall = false;
+            let newDatas = [];
+            if (selected === null) { return; }
+            if (selected.sourceType === project.Bills.getSourceType() && selected.depth() > 0) {
+                if (selected.source.children.length > 0) {
+                    alert('当前清单已有清单子项,不能套用定额。');
+                } else if (selected.data.calcBase&&selected.data.calcBase!="") {
+                    alert('当前有基数计算不能插入定额/量价/工料机。');
+                } else {
+                    if(selected.data.type === billType.FB){
+                        return;
+                    }
+                    billItemID = selected.source.getID();
+                    nextID = selected.tree.rootID();
+                    br = this.getBillsSortRation(billItemID);
+                    serialNo = br.length > 0 ? br[br.length - 1].serialNo + 1 : 1
+                }
+            } else if (selected.sourceType === project.Ration.getSourceType()) {
+                billItemID = selected.getParentID();
+                br = this.getBillsSortRation(billItemID);
+                serialNo = selected.data.serialNo+1;
+                nextID = selected.getNextSiblingID();
+                pre = selected.source;
+            };
+            if(billItemID){
+                let calQuantity = optionsOprObj.getOption(optionsOprObj.optionsTypes.GENERALOPTS, 'rationQuanACToBillsQuan');
+                if(engineering==engineeringType.BUILD_IN) {//如果是安装工程,要看需不需要生成安装增加费
+                    let billsNode = project.mainTree.getNodeByID(billItemID);
+                    needInstall = project.Bills.isFBFX(billsNode);//在分部分项插入的定额才需要定额安装增加费
+                }
+                for(let i = 0; i < items.length; i++){
+                    let newData = me.getTempRationData(me.getNewRationID(), billItemID, serialNo, items[i].rationType);
+                    serialNo++;
+                    let brUpdate = [];
+                    //更新兄弟节点的序列号
+                    if (i ===0 && pre) {
+                        let preIndex = br.indexOf(pre), i;
+                        for (i = preIndex + 1; i < br.length; i++) {
+                            br[i].serialNo = i < br.length - 1 ? br [i + 1].serialNo + items.length - 1 : br[i].serialNo + items.length;
+                            brUpdate.push({projectID:newData.projectID,ID:br[i].ID,serialNo:br[i].serialNo});
+                        }
+                    }
+                    newDatas.push({itemQuery: items[i].itemQuery, newData: newData, firstLibID: rationLibObj.getFirstStdRationLibID(), calQuantity: calQuantity, brUpdate: brUpdate, needInstall: needInstall})
+                }
+
+                $.bootstrapLoading.start();
+                CommonAjax.post("/ration/addMultiRation",{newDatas: newDatas},function (rstData) {
+                    let newNodes = [];
+                    //更新缓存
+                    for(let data of rstData){
+                        me.datas.push(data.ration);
+                        project.ration_glj.addDatasToList(data.ration_gljs);
+                        project.ration_coe.addDatasToList(data.ration_coes);
+                        project.ration_installation.addDatasToList(data.ration_installs);
+
+                        //插入树节点
+                        newSource = data.ration;
+                        newNode = project.mainTree.insert(billItemID, nextID, newSource.ID);
+                        newNodes.push(newNode);
+                        nextID = project.mainTree.selected.getNextSiblingID();
+                        newNode.source = newSource;
+                        newNode.sourceType = project.Ration.getSourceType();
+                        newNode.data = newSource;
+                        ProjectController.syncDisplayNewNode(sheetController, newNode);
+                    }
+                    project.projectGLJ.loadData(function () {
+                        for(let data of rstData){
+                            project.ration_glj.addToMainTree(data.ration_gljs);
+                        }
+                        projectObj.mainController.refreshTreeNode(newNodes, false);
+                        if(project.Bills.isFBFX(newNodes[0])) { //判断是否属于分部分项工程 ,是的话才需要做计取安装费计算
+                            project.installation_fee.calcInstallationFee(function (isChange,rations) {
+                                if(isChange){
+                                    rations = rations.concat(newNodes);
+                                    project.calcProgram.calcRationsAndSave(rations);
+                                }else {
+                                    project.calcProgram.calcRationsAndSave(newNodes);
+                                }
+                            });
+                        }else {
+                            project.calcProgram.calcNodesAndSave(newNodes);
+                        }
+                        if(callback){
+                            callback();
+                        }
+                        $.bootstrapLoading.end();
+                    });
+                })
+            }
+        };
         ration.prototype.addNewRation = function (itemQuery,rationType) {
             let me = this;
             let project = projectObj.project, sheetController = projectObj.mainController;

+ 4 - 0
web/building_saas/main/js/views/character_content_view.js

@@ -877,6 +877,10 @@ let pageCCOprObj = {
 
     },
     setItemContentNode: function (node, jobs, items, name = '') {
+        console.log(`jobs`);
+        console.log(jobs);
+        console.log(`items`);
+        console.log(items);
         let theCont = contentOprObj, theCha = characterOprObj,
             jobContent, itemCharacter, contentTxt, characterTxt;
         jobContent = theCont.buildJobContent(jobs);

+ 136 - 7
web/building_saas/main/js/views/std_billsGuidance_lib.js

@@ -11,6 +11,10 @@
 const billsGuidance = (function () {
 
     const libSel = $('#stdBillsGuidanceLibSelect');
+    //工作内容
+    let stdBillsJobData = [];
+    //项目特征
+    let stdBillsFeatureData = [];
     const bills = {
         dom: $('#billsGuidance_bills'),
         workBook: null,
@@ -66,6 +70,35 @@ const billsGuidance = (function () {
         events: {
             SelectionChanging: function (sender, info) {
                 billsInitSel(info.newSelections[0].row);
+            },
+            CellDoubleClick: function (sender, args) {
+                let node = bills.tree.items[args.row];
+                if(!node){
+                    return;
+                }
+                if(node.children.length === 0){
+                    //插入清单
+                    let insert = billsLibObj.insertBills(stdBillsJobData, stdBillsFeatureData, node);
+                    if(insert){
+                        //插入选中的定额
+                        let addRationDatas = getInsertRationData(getCheckedRows());
+                        insertRations(addRationDatas);
+                    }
+                }
+                else {
+                    node.setExpanded(!node.expanded);
+                    //设置展开收起状态
+                    sessionStorage.setItem('stdBillsGuidanceExpState', bills.tree.getExpState(bills.tree.items));
+                    renderSheetFunc(args.sheet, function () {
+                        let iCount = node.posterityCount(), i, child;
+                        for (i = 0; i < iCount; i++) {
+                            child = bills.tree.items[args.row + i + 1];
+                            args.sheet.setRowVisible(args.row + i + 1, child.visible, args.sheetArea);
+                        }
+                        args.sheet.invalidateLayout();
+                    });
+                    args.sheet.repaint();
+                }
             }
         }
     };
@@ -138,6 +171,14 @@ const billsGuidance = (function () {
                     args.sheet.endEdit(true);
                 }
             },
+            CellDoubleClick: function (sender, args) {
+                if(guideItem.headers[args.col]['dataCode'] === 'name'){
+                    if(!bills.tree.selected){
+                        return;
+                    }
+                    insertRations(getInsertRationData([args.row]));
+                }
+            }
         }
     };
     const options = {
@@ -201,7 +242,6 @@ const billsGuidance = (function () {
             return;
         }
         const Events = GC.Spread.Sheets.Events;
-        let sheet = workBook.getActiveSheet();
         for(let event in events){
             workBook.bind(Events[event], events[event]);
         }
@@ -216,6 +256,7 @@ const billsGuidance = (function () {
                 //默认初始可控制焦点在清单表中
                 module.workBook.focus();
                 sheet.options.isProtected = true;
+                sheet.name('stdBillsGuidance_bills');
             }
             if(module === guideItem){
                 sheet.options.isProtected = true;
@@ -250,6 +291,9 @@ const billsGuidance = (function () {
         module.tree = idTree.createNew({id: 'ID', pid: 'ParentID', nid: 'NextSiblingID', rootId: -1, autoUpdate: true});
         module.controller = TREE_SHEET_CONTROLLER.createNew(module.tree, sheet, treeSetting);
         module.tree.loadDatas(datas);
+        if(module === bills){
+            initExpandStat();
+        }
         module.controller.showTreeData();
     }
     //项目指引表焦点控制
@@ -263,8 +307,6 @@ const billsGuidance = (function () {
                 billsNode.guidance.tree.selected = node;
             }
         }
-
-
     }
     //根据项目指引的类型设置单元格类型,定额类型的项目指引为复选框
     //@param {Array}nodes @return {void}
@@ -304,11 +346,36 @@ const billsGuidance = (function () {
             guideItemInitSel(guideSheet.getActiveRowIndex() ? guideSheet.getActiveRowIndex() : 0);
         }
     }
+    //初始化清单的工作内容和项目特征
+    //@param {Number}billsLibId @return {void}
+    function initJobAndCharacter(billsLibId){
+        CommonAjax.post('/stdBillsEditor/getJobContent', {userId: userID, billsLibId: billsLibId}, function (datas) {
+            stdBillsJobData = datas;
+        });
+        CommonAjax.post('/stdBillsEditor/getItemCharacter', {userId: userID, billsLibId: billsLibId}, function (datas) {
+            stdBillsFeatureData = datas;
+        });
+    }
+    //初始化清单展开收起状态
+    //@return {void}
+    function initExpandStat(){
+        //读取展开收起状态
+        let currentExpState = sessionStorage.getItem('stdBillsGuidanceExpState');
+        if(currentExpState){
+            bills.tree.setExpandedByState(bills.tree.items, currentExpState);
+        }
+        //非叶子节点默认收起
+        else{
+            bills.tree.setRootExpanded(bills.tree.roots, false);
+        }
+    }
     //初始选择清单指引库
     //@param {Number}libID @return {void}
     function libInitSel(libID){
         //获取清单
         CommonAjax.post('/billsGuidance/api/getLibWithBills', {libID: libID}, function(rstData){
+            //获取清单库中的工作内容和项目特征
+            initJobAndCharacter(rstData.guidanceLib.billsLibId);
             initTree(bills, bills.workBook.getActiveSheet(), bills.treeSetting, rstData.bills);
             //每一棵项目指引树挂在清单节点上
             for(let node of bills.tree.items){
@@ -322,8 +389,12 @@ const billsGuidance = (function () {
     //@param {Array}libDats @return {void}
     function initLibs(libDatas){
         libSel.empty();
+        let selectedLib = sessionStorage.getItem('stdBillsGuidance');
         for(let libData of libDatas){
-            let opt = `<option value="${libData.id}">${libData.name}</option>`;
+            let opt = $('<option>').val(libData.id).text(libData.name);
+            if(selectedLib && libData.id == selectedLib){
+                opt.attr('selected', 'selected');
+            }
             libSel.append(opt);
         }
         //初始默认选择
@@ -336,6 +407,48 @@ const billsGuidance = (function () {
         initWorkBooks(modules);
 
     }
+    //获取选中的行
+    //@return {Array}
+    function getCheckedRows(){
+        let rst = [];
+        let itemSheet = guideItem.workBook.getActiveSheet();
+        for(let row = 0; row < itemSheet.getRowCount(); row++){
+            let rowV = itemSheet.getValue(row, 1);
+            if(rowV){
+                rst.push(row);
+            }
+        }
+        return rst;
+    }
+    //获取选中的定额数据
+    //@param {Array}rows @return {Array}
+    function getInsertRationData(rows){
+        let rst = [];
+        for(let row of rows){
+            let node = bills.tree.selected.guidance.tree.items[row];
+            if(node && node.data.type === itemType.ration){
+                rst.push({itemQuery: {userID: userID, ID: node.data.rationID}, rationType: rationType.ration});
+            }
+        }
+        return rst;
+    }
+    //插入定额
+    //@return {void}
+    function insertRations(addRationDatas){
+        if(addRationDatas.length > 0){
+            projectObj.project.Ration.addMultiRation(addRationDatas, function () {
+                //恢复
+                let sheet = guideItem.workBook.getActiveSheet();
+                renderSheetFunc(sheet, function () {
+                    for(let row = 0; row < sheet.getRowCount(); row++){
+                        if(sheet.getValue(row, 1)){
+                            sheet.setValue(row, 1, false);
+                        }
+                    }
+                });
+            });
+        }
+    }
     //各按钮监听事件
     //@return {void}
     function bindBtn(){
@@ -348,14 +461,30 @@ const billsGuidance = (function () {
         //更改清单指引库
         $('#stdBillsGuidanceLibSelect').change(function () {
             libInitSel($(this).select().val());
+            //记住选项
+            sessionStorage.setItem('stdBillsGuidance', $(this).select().val());
+            //清除展开收起状态sessionStorage
+            sessionStorage.removeItem('stdBillsGuidanceExpState');
         });
         //插入定额
         $('#guidanceInsertRation').click(function () {
-
+            let addRationDatas = getInsertRationData(getCheckedRows());
+            insertRations(addRationDatas);
         });
         //插入清单
         $('#guidanceInsertBills').click(function () {
-
+            //插入清单
+            if(!bills.tree.selected){
+                return;
+            }
+            if(bills.tree.selected.children.length === 0){
+                let insert = billsLibObj.insertBills(stdBillsJobData, stdBillsFeatureData, bills.tree.selected);
+                if(insert){
+                    //插入选中的定额
+                    let addRationDatas = getInsertRationData(getCheckedRows());
+                    insertRations(addRationDatas);
+                }
+            }
         });
     }
     //刷新表
@@ -369,7 +498,7 @@ const billsGuidance = (function () {
         }
     }
 
-    return {initViews, bindBtn, refreshWorkBook};
+    return {initViews, bindBtn, refreshWorkBook, bills};
 })();
 
 $(document).ready(function(){

+ 71 - 67
web/building_saas/main/js/views/std_bills_lib.js

@@ -76,6 +76,73 @@ var billsLibObj = {
             billsLibObj.loadStdBills(select.val());
         }
     },
+     sortJobsAndFeatures: function (arr) {
+        arr.sort(function (a, b) {
+            let rst = 0;
+            if(a.serialNo > b.serialNo) rst = 1;
+            else if(a.serialNo < b.serialNo) rst = -1;
+            return rst;
+        });
+    },
+     findData: function (value, field, Array) {
+        var i = 0;
+        for (i = 0; i < Array.length; i++) {
+            if (value[field] == Array[i][field]) {
+                return Array[i];
+            }
+        }
+        return null;
+    },
+    getBillsJobs: function (stdBillsJobData, node) {
+        var jobs = [], i, jobData = null;
+        if (stdBillsJobData && node && node.data.jobs) {
+            for (i = 0; i < node.data.jobs.length; i++) {
+                jobData = this.findData(node.data.jobs[i], 'id', stdBillsJobData);
+                if (jobData) {
+                    jobData.serialNo = node.data.jobs[i].serialNo;
+                    jobs.push(jobData);
+                }
+            }
+        }
+        this.sortJobsAndFeatures(jobs);
+        return jobs;
+    },
+    getBillsFeatures: function (stdBillsFeatureData, node) {
+        var features = [], i, featureData = null;
+        if (stdBillsFeatureData && node && node.data.items) {
+            for (i = 0; i < node.data.items.length; i++) {
+                featureData = this.findData(node.data.items[i], 'id', stdBillsFeatureData);
+                if (featureData) {
+                    featureData.serialNo = node.data.items[i].serialNo;
+                    features.push(featureData);
+                }
+            }
+        }
+        this.sortJobsAndFeatures(features);
+        return features;
+    },
+    insertBills: function (stdBillsJobData, stdBillsFeatureData, node) {
+        if(projectInfoObj.projectInfo.property.lockBills == true){
+            return false;
+        }
+        //特征及内容转化
+        pageCCOprObj.setItemContentNode(node, this.getBillsJobs(stdBillsJobData, node), this.getBillsFeatures(stdBillsFeatureData, node), node.data.name);
+        if (/\//.test(node.data.unit)) {
+            let existB = projectObj.project.Bills.sameStdCodeBillsData(node.data.code);
+            if (existB) {
+                let std = JSON.parse(JSON.stringify(node.data));
+                std.unit = existB.unit;
+                ProjectController.addBills(projectObj.project, projectObj.mainController, std);
+            } else {
+                ConfirmModal.stdBillsUnit.check(node.data, function (std) {
+                    ProjectController.addBills(projectObj.project, projectObj.mainController, std);
+                });
+            }
+        } else {
+            ProjectController.addBills(projectObj.project, projectObj.mainController, node.data);
+        }
+        return true;
+    },
     loadStdBills: function (stdBillsLibID) {
         var that = this;
         var stdBillsJobData, stdBillsFeatureData, stdBills;
@@ -84,51 +151,6 @@ var billsLibObj = {
         }
         that.stdBillsTree  = idTree.createNew({id: 'ID', pid: 'ParentID', nid: 'NextSiblingID', rootId: -1, autoUpdate: true});
         var stdBillsTreeController = TREE_SHEET_CONTROLLER.createNew(that.stdBillsTree, billsLibObj.stdBillsSpread.getActiveSheet(), billsLibObj.stdBillsTreeSetting);
-        var findData = function (value, field, Array) {
-            var i = 0;
-            for (i = 0; i < Array.length; i++) {
-                if (value[field] == Array[i][field]) {
-                    return Array[i];
-                }
-            }
-            return null;
-        };
-        let sortJobsAndFeatures = function (arr) {
-            arr.sort(function (a, b) {
-                let rst = 0;
-                if(a.serialNo > b.serialNo) rst = 1;
-                else if(a.serialNo < b.serialNo) rst = -1;
-                return rst;
-            });
-        };
-        var getBillsJobs = function (node) {
-            var jobs = [], i, jobData = null;
-            if (stdBillsJobData && node && node.data.jobs) {
-                for (i = 0; i < node.data.jobs.length; i++) {
-                    jobData = findData(node.data.jobs[i], 'id', stdBillsJobData);
-                    if (jobData) {
-                        jobData.serialNo = node.data.jobs[i].serialNo;
-                        jobs.push(jobData);
-                    }
-                }
-            }
-            sortJobsAndFeatures(jobs);
-            return jobs;
-        };
-        var getBillsFeatures = function (node) {
-            var features = [], i, featureData = null;
-            if (stdBillsFeatureData && node && node.data.items) {
-                for (i = 0; i < node.data.items.length; i++) {
-                    featureData = findData(node.data.items[i], 'id', stdBillsFeatureData);
-                    if (featureData) {
-                        featureData.serialNo = node.data.items[i].serialNo;
-                        features.push(featureData);
-                    }
-                }
-            }
-            sortJobsAndFeatures(features);
-            return features;
-        };
         var showJobs = function (jobs) {
             SheetDataHelper.loadSheetHeader(billsLibObj.jobsSetting, billsLibObj.stdBillsJobSpread.getActiveSheet());
             SheetDataHelper.loadSheetData(billsLibObj.jobsSetting, billsLibObj.stdBillsJobSpread.getActiveSheet(), jobs);
@@ -142,9 +164,9 @@ var billsLibObj = {
             $('#stdBillsRemarkTab').hide();
             billsLibObj.refreshBillsRelaSpread();
             billsLibObj.checkBillsRelaSpread();
-            sortJobsAndFeatures(getBillsJobs(node));
-            showJobs(getBillsJobs(node));
-            showFeatures(getBillsFeatures(node));
+            billsLibObj.sortJobsAndFeatures(billsLibObj.getBillsJobs(node));
+            showJobs(billsLibObj.getBillsJobs(node));
+            showFeatures(billsLibObj.getBillsFeatures(node));
         };
         var showBillsRemark = function (node) {
             $('#stdBillsJobTab').hide();
@@ -190,25 +212,7 @@ var billsLibObj = {
                 let selectNode = that.stdBillsTree.items[args.row];
                 let name = selectNode.data.name;
                 if (that.stdBillsTree.items[args.row].children.length === 0) {
-                    if(projectInfoObj.projectInfo.property.lockBills == true){
-                        return;
-                    }
-                    //特征及内容转化
-                    pageCCOprObj.setItemContentNode(that.stdBillsTree.items[args.row], getBillsJobs(that.stdBillsTree.items[args.row]), getBillsFeatures(that.stdBillsTree.items[args.row]), name);
-                    if (/\//.test(selectNode.data.unit)) {
-                        let existB = projectObj.project.Bills.sameStdCodeBillsData(selectNode.data.code);
-                        if (existB) {
-                            let std = JSON.parse(JSON.stringify(selectNode.data));
-                            std.unit = existB.unit;
-                            ProjectController.addBills(projectObj.project, projectObj.mainController, std);
-                        } else {
-                            ConfirmModal.stdBillsUnit.check(selectNode.data, function (std) {
-                                ProjectController.addBills(projectObj.project, projectObj.mainController, std);
-                            });
-                        }
-                    } else {
-                        ProjectController.addBills(projectObj.project, projectObj.mainController, selectNode.data);
-                    }
+                    billsLibObj.insertBills(stdBillsJobData, stdBillsFeatureData, selectNode);
                 }
                 else{
                     let me = billsLibObj;