Преглед на файлове

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

TonyKang преди 7 години
родител
ревизия
128c5c10a6
променени са 29 файла, в които са добавени 627 реда и са изтрити 156 реда
  1. 13 3
      modules/complementary_ration_lib/models/searchModel.js
  2. 1 1
      modules/fee_rates/controllers/fee_rates_controller.js
  3. 2 2
      modules/fee_rates/facade/fee_rates_facade.js
  4. 27 1
      modules/glj/controllers/glj_controller.js
  5. 1 0
      modules/glj/routes/glj_router.js
  6. 23 1
      modules/main/controllers/ration_controller.js
  7. 15 4
      modules/main/facade/ration_facade.js
  8. 1 0
      modules/main/routes/ration_route.js
  9. 3 3
      modules/pm/models/project_model.js
  10. 14 8
      modules/ration_glj/facade/ration_glj_facade.js
  11. 1 1
      modules/std_billsGuidance_lib/facade/facades.js
  12. 3 0
      public/web/tree_sheet/tree_sheet_helper.js
  13. 1 1
      web/building_saas/fee_rates/fee_rate.html
  14. 1 1
      web/building_saas/glj/html/glj_index.html
  15. 29 2
      web/building_saas/glj/html/project_glj.html
  16. 4 6
      web/building_saas/main/html/main.html
  17. 12 6
      web/building_saas/main/js/models/installation_fee.js
  18. 11 0
      web/building_saas/main/js/models/project_glj.js
  19. 96 0
      web/building_saas/main/js/models/ration.js
  20. 34 14
      web/building_saas/main/js/models/ration_glj.js
  21. 4 0
      web/building_saas/main/js/views/character_content_view.js
  22. 15 11
      web/building_saas/main/js/views/glj_view.js
  23. 6 1
      web/building_saas/main/js/views/installation_fee_view.js
  24. 2 2
      web/building_saas/main/js/views/main_tree_col.js
  25. 94 8
      web/building_saas/main/js/views/project_glj_view.js
  26. 1 0
      web/building_saas/main/js/views/project_info.js
  27. 6 6
      web/building_saas/main/js/views/project_view.js
  28. 136 7
      web/building_saas/main/js/views/std_billsGuidance_lib.js
  29. 71 67
      web/building_saas/main/js/views/std_bills_lib.js

+ 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';

+ 1 - 1
modules/fee_rates/controllers/fee_rates_controller.js

@@ -140,7 +140,7 @@ async function getChangeInfo(req, res) {
     }
     try {
         let data = req.body.data;
-        let info= await feeRateFacde.getChangeInfo(data);
+        let info= await feeRateFacde.getChangeInfo(data,req.session.sessionCompilation._id);
         result.data= info;
     }catch (err){
         console.log(err);

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

@@ -322,7 +322,7 @@ async function checkFeeRateName(jdata) {
     return false;
 }
 
-async function getChangeInfo(jdata){
+async function getChangeInfo(jdata,compilation){
     let data = JSON.parse(jdata);
     //{ rootProjectID: 99, user_id: '76075' }
     let result={};
@@ -332,7 +332,7 @@ async function getChangeInfo(jdata){
     }
     //根据用户ID 找除了当前项目的其它建设项目;
     let others =await projectsModel.find({'$and': [
-            {'$or':[{'userID': data.user_id,'projType':'Project', 'deleteInfo': null}, {'userID': data.user_id,'projType':'Project', 'deleteInfo.deleted': {'$in': [null, false]}}]},
+            {'$or':[{'userID': data.user_id,'compilation': compilation,'projType':'Project', 'deleteInfo': null}, {'userID': data.user_id,'compilation': compilation,'projType':'Project', 'deleteInfo.deleted': {'$in': [null, false]}}]},
             { 'ID':{'$nin':[data.rootProjectID]}}
         ]},['ID','name']);
     for(let o of others){

+ 27 - 1
modules/glj/controllers/glj_controller.js

@@ -249,7 +249,7 @@ class GLJController extends BaseController {
         try {
             let sessionUserData = request.session.sessionUser;
             // 获取对应用户所有的建设项目数据
-            let projectList = await ProjectModel.getUserProjectData(sessionUserData.id);
+            let projectList = await ProjectModel.getUserProjectData(sessionUserData.id,request.session.sessionCompilation._id);
             if (projectList === null) {
                 throw '没有找到对应的项目数据';
             }
@@ -295,6 +295,7 @@ class GLJController extends BaseController {
     async changeUnitPriceFile(request, response) {
         let projectId = request.body.project_id;
         let changeUnitPriceId = request.body.change_id;
+        let newName = request.body.newName;
         let type = request.body.type;
         type = parseInt(type);
         let responseData = {
@@ -317,6 +318,7 @@ class GLJController extends BaseController {
 
                 insertData = JSON.parse(JSON.stringify(currentUnitPrice));
                 insertData.root_project_id = rootProjectId;
+                newName?insertData.name = newName:'';
                 insertData.user_id = insertData.user_id === undefined ? request.session.sessionUser.id : insertData.user_id;
                 delete insertData._id;
                 delete insertData.ID;
@@ -372,6 +374,30 @@ class GLJController extends BaseController {
         response.json(responseData);
     }
 
+    async checkUnitFileName(request, response){
+        let result={
+            error:0
+        }
+        try {
+            let data = request.body.data;
+            let nameExist = false;
+            data = JSON.parse(data);
+            let unitPriceFileModel = new UnitPriceFileModel();
+            let count = await unitPriceFileModel.model.count({root_project_id:data.rootProjectID,name:data.name,deleteInfo:null});
+            if(count>0){
+                nameExist = true;
+            }else {
+                nameExist = false;
+            }
+            result.data= nameExist;
+        }catch (err){
+            console.log(err);
+            result.error=1;
+            result.message = err.message;
+        }
+        response.json(result);
+    }
+
     /**
      * 单价文件另存为
      *

+ 1 - 0
modules/glj/routes/glj_router.js

@@ -19,6 +19,7 @@ router.post('/get-ratio', gljController.init, gljController.getRatio);
 router.post('/delete-ratio', gljController.init, gljController.deleteMixRatio);
 router.post('/get-project-info', gljController.init, gljController.getProjectInfo);
 router.post('/change-file', gljController.init, gljController.changeUnitPriceFile);
+router.post('/checkUnitFileName', gljController.init, gljController.checkUnitFileName);
 router.post('/save-as', gljController.init, gljController.unitPriceSaveAs);
 router.post('/get-composition', gljController.init, gljController.getComposition);
 router.post('/updatePrice', gljController.init, gljController.updateUnitPrice);

+ 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);
 };

+ 3 - 3
modules/pm/models/project_model.js

@@ -638,11 +638,11 @@ ProjectsDAO.prototype.getUnitPriceFileId = async function (projectId) {
  * @paraconsolem {Number} userId
  * @return {Promise}
  */
-ProjectsDAO.prototype.getUserProjectData = async function (userId) {
+ProjectsDAO.prototype.getUserProjectData = async function (userId,compilation) {
     let projectList = await Projects.find({
         '$or': [
-            {'userID': userId, 'deleteInfo': null, projType: 'Project'},
-            {'userID': userId, 'deleteInfo.deleted': {'$in': [null, false]}, projType: 'Project'}
+            {'userID': userId, 'compilation': compilation, 'deleteInfo': null, projType: 'Project'},
+            {'userID': userId, 'compilation': compilation,'deleteInfo.deleted': {'$in': [null, false]}, projType: 'Project'}
         ]
     }, {_id: 0, name: 1, ID: 1});
 

+ 14 - 8
modules/ration_glj/facade/ration_glj_facade.js

@@ -658,21 +658,27 @@ async function mReplaceGLJ(data) {
     let projectGljModel = new GLJListModel();
     let result = await projectGljModel.addList(getGLJSearchInfo(data.doc));
     let typeString = result.type+'';
-    data.doc.projectGLJID = result.id;
+    let newDoc = {};
+    newDoc.projectGLJID = result.id;
     let rationList = await ration_glj.distinct('rationID', data.query);
-    let updateResult = await ration_glj.update(data.query, data.doc, {multi: true});
+    for(let t of data.tasks){
+        t.updateOne.update.projectGLJID = result.id;//更新项目工料机ID
+    }
+    await ration_glj.bulkWrite(data.tasks);
+    //let updateResult = await ration_glj.update(data.query, data.doc, {multi: true});
 
-    data.doc.marketPrice = result.unit_price.market_price;
-    data.doc.adjustPrice = result.unit_price.base_price;
-    data.doc.basePrice = result.unit_price.base_price;
-    data.doc.isAdd = result.unit_price.is_add;
+    newDoc.marketPrice = result.unit_price.market_price;
+    newDoc.adjustPrice = result.unit_price.base_price;
+    newDoc.basePrice = result.unit_price.base_price;
+    newDoc.isAdd = result.unit_price.is_add;
     if (typeString.startsWith("2")||typeString=='4'||typeString=='5') {//只有材料类型才显示是否暂估
-        data.doc.isEstimate = result.is_evaluate;
+        newDoc.isEstimate = result.is_evaluate;
     }
     if (result.hasOwnProperty('subList') && result.subList.length > 0) {
-        data.doc.subList = getMixRatioShowDatas(result.subList);
+        newDoc.subList = getMixRatioShowDatas(result.subList);
     }
     let stateList = await changAdjustState(data, rationList);
+    data.doc = newDoc;
     mresult.data = data;
     mresult.stateList = stateList;
     return mresult

+ 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++) {

+ 1 - 1
web/building_saas/fee_rates/fee_rate.html

@@ -3,7 +3,7 @@
 <div >
 <div class="toolsbar_feeRate px-1 ">
     <div class="form-inline py-1">
-        <label class="mx-2" >当前使用:<span id="feeRateFileName">费率1</span>(<a href="#" id="pop-lv"><span id="projectCount">3</span> 单位工程使用</a>)
+        <label class="mx-2" >当前使用:<span id="feeRateFileName">费率1</span>(<a href="#" id="pop-lv"><span id="projectCount">3</span> 单位工程使用</a>)
             <a class="btn btn-sm ml-1" href="#" data-toggle="modal" data-target="#change-lv" id="changFeeRateFile"><i class="fa fa-exchange"></i> 选择其他</a>
             <a class="btn btn-sm ml-1" href="#" data-toggle="modal" id="saveAs" data-target="#copy-lv"><i class="fa fa-files-o"></i> 另存单独用</a></label>
     </div>

+ 1 - 1
web/building_saas/glj/html/glj_index.html

@@ -5,7 +5,7 @@
 </style>
 <div class="toolsbar px-1">
     <div class="form-inline py-1">
-        <label class="mx-2">当前使用:<span id="used-name"></span>(<a href="#" id="pop-dj" data-original-title="" title=""><span id="used-count">0</span> 单位工程使用</a>)
+        <label class="mx-2">当前使用:<span id="used-name"></span>(<a href="#" id="pop-dj" data-original-title="" title=""><span id="used-count">0</span> 单位工程使用</a>)
             <a class="btn btn-sm ml-1" href="#" data-toggle="modal" data-target="#change-dj"><i class="fa fa-exchange"></i> 选择其他</a>
             <a class="btn btn-sm ml-1" href="#" data-toggle="modal" data-target="#file-save-as-dialog"><i class="fa fa-files-o"></i> 另存单独用</a></label>
     </div>

+ 29 - 2
web/building_saas/glj/html/project_glj.html

@@ -5,7 +5,7 @@
 </style>
 <div class="toolsbar px-1">
     <div class="form-inline py-1">
-        <label class="mx-2">当前使用:<span id="current-name"></span>(<a href="#" id="pop-used-list" data-original-title="" title=""><span id="used-project-count">0</span> 单位工程使用</a>)
+        <label class="mx-2">当前使用:<span id="current-name"></span>(<a href="#" id="pop-used-list" data-original-title="" title=""><span id="used-project-count">0</span> 单位工程使用</a>)
             <a class="btn btn-sm ml-1" href="#" data-toggle="modal" data-target="#change-unitFile"><i class="fa fa-exchange"></i> 选择其他</a>
             <a class="btn btn-sm ml-1" href="#" data-toggle="modal" data-target="#unitFile-save-as"><i class="fa fa-files-o"></i> 另存单独用</a></label>
     </div>
@@ -130,7 +130,34 @@
             </div>
             <div class="modal-footer">
                 <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
-                <a href="javascript:void(0);" class="btn btn-primary" id="save-as-confirm">确定</a>
+                <button type="button" class="btn btn-primary" id="save-as-confirm">确定</button>
+            </div>
+        </div>
+    </div>
+</div>
+
+
+<!--弹出 重命名窗口-->
+<div class="modal fade" id="rename-unitFile" data-backdrop="static">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">重命名</h5>
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">&times;</span>
+                </button>
+            </div>
+            <div class="modal-body">
+                <div class="form-group">
+                    <label>单价文件名称</label>
+                    <input class="form-control" id="newUnitFileID" value="" style="display: none">
+                    <input class="form-control" id="newUnitFileName" value="">
+                    <small class="form-text text-danger" id="renameError_unitFile">本建设项目中已存在同名单价文件。</small>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                <button type="button" class="btn btn-primary" data-dismiss="modal" id="renameUnitFileConfirm" disabled>确定</button>
             </div>
         </div>
     </div>

+ 4 - 6
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>
@@ -886,8 +886,8 @@
                 </div>
                 <div class="modal-footer" style="justify-content: center">
                     <button type="button" class="btn btn-primary"  data-dismiss="modal" id="deleteY" >是</button>
-                    <button type="button" class="btn btn-primary"  data-dismiss="modal" id="deleteN" >否</button>
-                    <button type="button" class="btn btn-secondary" data-dismiss="modal" id="deleteCancel">取消</button>
+                    <button type="button" class="btn btn-primary"  data-dismiss="modal" id="deleteN" style="display: none" >否</button>
+                    <button type="button" class="btn btn-secondary" data-dismiss="modal" id="deleteCancel">否</button><!--实际是取消-->
                 </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){

+ 12 - 6
web/building_saas/main/js/models/installation_fee.js

@@ -592,12 +592,18 @@ var installation_fee = {
                     labourQuantity = scMathUtil.roundForObj(parseFloat(project.Ration.getLabourTotalFee(ration))*parseFloat(labour),gljDecimal);
                     materialQuantity = scMathUtil.roundForObj(parseFloat(project.Ration.getMaterialTotalFee(ration))*parseFloat(material),gljDecimal);
                     machineQuantity = scMathUtil.roundForObj(parseFloat(project.Ration.getMachineTotalFee(ration))*parseFloat(machine),gljDecimal);
-                }else if(rule.base=='人工'){
-                    labourQuantity = scMathUtil.roundForObj(parseFloat(project.Ration.getLabourTotalFee(ration))*parseFloat(feeRate)*parseFloat(labour),gljDecimal);
-                }else if(rule.base=='材料'){
-                    materialQuantity = scMathUtil.roundForObj(parseFloat(project.Ration.getMaterialTotalFee(ration))*parseFloat(feeRate)*parseFloat(material),gljDecimal);
-                }else if(rule.base=='机械'){
-                    machineQuantity = scMathUtil.roundForObj(parseFloat(project.Ration.getMachineTotalFee(ration))*parseFloat(feeRate)*parseFloat(machine),gljDecimal);
+                }else {
+                    let base = 0;
+                    if(rule.base=='人工'){
+                        base = parseFloat(project.Ration.getLabourTotalFee(ration))*parseFloat(feeRate);
+                    }else if(rule.base=='材料'){
+                        base = parseFloat(project.Ration.getMaterialTotalFee(ration))*parseFloat(feeRate);
+                    }else if(rule.base=='机械'){
+                        base = parseFloat(project.Ration.getMachineTotalFee(ration))*parseFloat(feeRate);
+                    }
+                    labourQuantity = scMathUtil.roundForObj(base*parseFloat(labour),gljDecimal);
+                    materialQuantity = scMathUtil.roundForObj(base*parseFloat(material),gljDecimal);
+                    machineQuantity = scMathUtil.roundForObj(base*parseFloat(machine),gljDecimal);
                 }
                 return [labourQuantity,materialQuantity,machineQuantity];
             }

+ 11 - 0
web/building_saas/main/js/models/project_glj.js

@@ -412,6 +412,17 @@ ProjectGLJ.prototype.changeFile = function (changeData,callback) {
     });
 };
 
+ProjectGLJ.prototype.checkUnitFileName = function(newVal,callback){
+    let property = projectInfoObj.projectInfo.property;
+    let data = {
+        name:newVal,
+        rootProjectID:property.rootProjectID
+    }
+    CommonAjax.post('/glj/checkUnitFileName', data, function (data) {
+        callback(data);
+    });
+};
+
 ProjectGLJ.prototype.saveAs = function (saveData,callback) {
     $.bootstrapLoading.start();
     CommonAjax.specialPost('/glj/save-as',saveData,function () {

+ 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;

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

@@ -640,7 +640,7 @@ var ration_glj = {
             if (selectCode == gljOprObj.getIndex(oldData, gljKeyArray)) {
                 return callback(null);
             }
-            if (oldData.createType != 'replace') {
+            if (oldData.createType == 'normal') {//只有是定额下带的工料机才需把类型改成替换,其它的保持不变
                 oldData.rcode = oldData.code;
                 oldData.createType = 'replace';
             }
@@ -669,15 +669,16 @@ var ration_glj = {
         };
 
         ration_glj.prototype.mReplaceGLJ = function (selectCode, oldData, callback) {
-            var allGLJ = gljOprObj.AllRecode;
-            var glj = _.find(allGLJ, function (item) {
-                var i_key = gljOprObj.getIndex(item, gljLibKeyArray);
+            let allGLJ = gljOprObj.AllRecode,tasks = [],updateMap={};
+            let oldIndex = gljOprObj.getIndex(oldData, gljKeyArray);
+            let glj = _.find(allGLJ, function (item) {
+                let i_key = gljOprObj.getIndex(item, gljLibKeyArray);
                 return i_key == selectCode;
             });
-            if (selectCode == gljOprObj.getIndex(oldData, gljKeyArray)) {
+            if (selectCode == oldIndex) {
                 return callback(null);
             }
-            var query = {
+            let query = {
                 projectID: oldData.projectID,
                 code: oldData.code,
                 name: oldData.name,
@@ -687,7 +688,7 @@ var ration_glj = {
             if (oldData.specs && oldData.specs != '') {
                 query.specs = oldData.specs;
             }
-            var doc = {
+            let doc = {
                 GLJID: glj.ID,
                 createType: 'replace',
                 rationItemQuantity: 0,
@@ -702,12 +703,7 @@ var ration_glj = {
                 materialType: glj.materialType,   //三材类别
                 materialCoe: glj.materialCoe,
                 projectID: oldData.projectID
-            }
-            if (oldData.createType == 'replace') {
-                doc.rcode = oldData.rcode;
-            } else {
-                doc.rcode = oldData.code;
-            }
+            };
             if (glj.hasOwnProperty("compilationId")) {
                 doc.from = "cpt";
                 if (glj.code.indexOf('-') != -1) {//这条工料机是用户通过修改包称、规格、型号等保存到补充工料机库的
@@ -716,8 +712,32 @@ var ration_glj = {
             } else {
                 doc.from = "std";
             }
+            for(let d of this.datas){//查询出所有需替换的工料机
+                let tem_index = gljOprObj.getIndex(d, gljKeyArray);
+                if(tem_index == oldIndex){
+                    let tem_doc = _.cloneDeep(doc);
+                    if(d.createType == 'replace'){
+                        tem_doc.rcode = d.rcode;
+                    }else if(d.createType == 'add'){//对于添加的类型,替换后还是添加类型
+                        tem_doc.createType = 'add';
+                    }else {
+                        tem_doc.rcode = d.code
+                    }
+                    let task = {
+                        updateOne:{
+                            filter : {ID:d.ID},
+                            update : tem_doc
+                        }
+                    };
+                    tasks.push(task);
+                    updateMap[d.ID] = tem_doc;
+                }
+            }
+
             $.bootstrapLoading.start();
-            CommonAjax.post("/rationGlj/mReplaceGLJ", {query: query, doc: doc}, callback, function () {
+            CommonAjax.post("/rationGlj/mReplaceGLJ", {query: query, doc: doc,tasks:tasks}, function (result) {
+                callback(result,updateMap);
+            }, function () {
                 $.bootstrapLoading.end();
             });
         };

+ 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);

+ 15 - 11
web/building_saas/main/js/views/glj_view.js

@@ -1149,20 +1149,24 @@ var gljOprObj = {
         })
     },
     doMReplaceGLJ: function () {
-        var me = this;
-        var oldData = me.sheetData[gljContextMenu.selectedRow];
-        var project = projectObj.project;
-        var selectCode = me.GLJSelection[0];
+        let me = this;
+        let oldData = me.sheetData[gljContextMenu.selectedRow];
+        let project = projectObj.project;
+        let selectCode = me.GLJSelection[0];
         $("#glj_tree_div").modal('hide');
-        project.ration_glj.mReplaceGLJ(selectCode, oldData, function (result) {
-            var data = result.data;
-            var stateList = result.stateList;
-            var n_index = me.getIndex(data.query, gljKeyArray);
-            var nodes = [];
+        project.ration_glj.mReplaceGLJ(selectCode, oldData, function (result,updateMap) {
+            if(result == null){
+                return;
+            }
+            let data = result.data;
+            let stateList = result.stateList;
+            //let n_index = me.getIndex(data.query, gljKeyArray);
+            let nodes = [];
             _.forEach(project.ration_glj.datas, function (t) {
-                var t_index = me.getIndex(t, gljKeyArray);
-                if (n_index == t_index) {
+           //     let t_index = me.getIndex(t, gljKeyArray);
+                if (updateMap[t.ID]) {
                     me.updateProperty(t, data.doc);
+                    me.updateProperty(t, updateMap[t.ID]);
                     if (project.ration_glj.needShowToTree(t)) {//如果是造价书中的树节点,则也须刷新
                         project.ration_glj.transferToNodeData(t);
                         var node = project.ration_glj.findGLJNodeByID(t.ID);

+ 6 - 1
web/building_saas/main/js/views/installation_fee_view.js

@@ -1247,6 +1247,9 @@ let installationFeeObj={
                 projectObj.project.calcProgram.calcRationsAndSave(rations);
             }
             installationFeeObj.showRationInstallationData(projectObj.project.mainTree.selected);
+            if(callback){
+                callback();
+            }
         });
     },
     initSettingRadio:function () {
@@ -1366,7 +1369,9 @@ $(function () {
         if(canChange==false){
             return;
         }
-        me.calcInstallationFee();
+        me.calcInstallationFee(function () {
+
+        });
     });
     $('#btn_reset_to_default').click(function (){
         let ifModel =  projectObj.project.installation_fee;

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

@@ -335,7 +335,7 @@ let MainTreeCol = {
                 case 6:
                     return '0.000000';
                 default:
-                    return '0.00';
+                    return '0';
             }
             ;
         }
@@ -354,7 +354,7 @@ let MainTreeCol = {
                 case 6:
                     return '0.######';
                 default:
-                    return '0.##';
+                    return '0';
             }
             ;
         }

+ 94 - 8
web/building_saas/main/js/views/project_glj_view.js

@@ -40,6 +40,7 @@ projectGljObject={
         header:[
             {headerName: "编码", headerWidth: 120, dataCode: "code", dataType: "String"},
             {headerName: "名称", headerWidth: 120, dataCode: "name", dataType: "String"},
+            {headerName: "规格型号", headerWidth: 120, dataCode: "specs", dataType: "String"},
             {headerName: "单位", headerWidth: 120, dataCode: "unit", hAlign: "center", dataType: "String"},
             {headerName: "类型", headerWidth: 120, dataCode: "short_name", hAlign: "center", dataType: "String"},
             {headerName: "定额价", headerWidth: 120, dataCode: "basePrice", hAlign: "right", dataType: "Number",decimalField:'glj.unitPrice',validator:"number"},
@@ -48,7 +49,7 @@ projectGljObject={
             {headerName: "消耗量", headerWidth: 120, dataCode: "consumption", hAlign: "right", dataType: "Number",decimalField:"glj.quantity",validator:"number"}
         ],
         view: {
-            lockColumns: [0,1,2,3,4,5,6]
+            lockColumns: [0,1,2,3,4,5,6,7]
         }
     },
     materialTreeSetting:{
@@ -293,6 +294,7 @@ projectGljObject={
     showProjectGljData:function () {
         this.projectGljSpread.setActiveSheetIndex(0);
         let sel = this.projectGljSheet.getSelections()[0];
+        let oldData = sel.row<this.projectGljSheetData.length?this.projectGljSheetData[sel.row]:'';
         let projectGljSheetData = [];
         let gljList = projectObj.project.projectGLJ.datas.gljList;
         gljList = this.filterProjectGLJ(gljList);
@@ -304,15 +306,19 @@ projectGljObject={
         this.projectGljSheet.setRowCount(0);
         sheetCommonObj.showData(this.projectGljSheet, this.projectGljSetting,this.projectGljSheetData);
         this.projectGljSheet.setRowCount(this.projectGljSheetData.length);
+        sel.row = _.findIndex(this.projectGljSheetData,{'id':oldData.id});
         this.projectGljSheet.setSelection(sel.row==-1?0:sel.row,sel.col,sel.rowCount,sel.colCount);
     },
     showMaterialTreeData:function () {
         this.projectGljSpread.setActiveSheetIndex(1);
         let sel = this.materialTreeSheet.getSelections()[0];
+        let oldNodeID = this.materialTree.selected?this.materialTree.selected.data.id:"";
         let gljList = projectObj.project.projectGLJ.datas.gljList;
         gljList = _.sortByAll(gljList, [ 'code']);
         this.createMaterialTree(gljList);
         this.materialTreeController.showTreeData();
+        let newNode = this.materialTree.getNodeByID(oldNodeID);
+        sel.row = newNode?newNode.serialNo():-1;
         this.materialTreeSheet.setSelection(sel.row==-1?0:sel.row,sel.col,sel.rowCount,sel.colCount);
         this.materialTreeController.setTreeSelected(this.materialTree.items[sel.row==-1?0:sel.row]);
     },
@@ -571,11 +577,14 @@ projectGljObject={
         let parantData = null;
         if(sheet.name() == 'projectGljSheet'){
             me.showProjectGljData();// me.refreshProjectGljRow(row)  这里原来是分开刷新的,现在整个统一刷新,先留着
-            parantData = me.projectGljSheetData[row];
+            //parantData = _.find();  //me.projectGljSheetData[row];
         }else {
             me.showMaterialTreeData();
-            parantData = me.materialTree.items[row].data;
+            //parantData = me.materialTree.items[row].data;
         }
+        let pglj =  _.find(projectObj.project.projectGLJ.datas.gljList,{'id':pid});
+        parantData = pglj?me.getSheetDataByGLJ(pglj):null;
+        //projectObj.project.projectGLJ.datas.gljList
 
         // 更新组成物缓存
         projectObj.project.composition.loadData();
@@ -593,7 +602,7 @@ projectGljObject={
         for(let r of rations){
             let r_node = projectObj.project.mainTree.getNodeByID(r.ID);
             if(r_node){
-                r_node.data.marketUnitFee =  parantData.marketPrice;//parentMarketPrice;//这里用显示的价格
+                r_node.data.marketUnitFee = parantData?parantData.marketPrice:'';//parentMarketPrice;//这里用显示的价格
                 updateNodes.push(r_node);
             }
         }
@@ -767,6 +776,17 @@ projectGljObject={
                         me.deleteMixRatio(row);
                     }
                 },
+                "addMixRatio":{
+                    name: '添加',
+                    icon: 'fa-sign-in',
+                    disabled: function () {
+                        return me.rightClickTarget.row === undefined;
+                    },
+                    callback: function (key, opt) {
+                        let row = me.rightClickTarget.row;
+                        console.log(row);
+                    }
+                }
             }
         });
     },
@@ -795,6 +815,21 @@ projectGljObject={
                   });
               }
         }
+    },
+    checkUnitFileName:function (name,callback) {
+        let projectGLJ = projectObj.project.projectGLJ;
+        projectGLJ.checkUnitFileName(name,function (data) {
+            if(data){
+                $("#save-as-tips").text('已存在同名单价文件').show();
+                $('#save-as-confirm').attr("disabled","disabled");
+            }else {
+                $("#save-as-tips").hide();
+                $('#save-as-confirm').removeAttr("disabled");
+                if(callback){
+                    callback();
+                }
+            }
+        });
     }
 };
 
@@ -879,6 +914,7 @@ $(function () {
                     return false;
                 }
                 let data = response.data;
+                projectGljObject.changeInfo = data;
                 $("#current-project-name").text(data.currentProjectName);
                 // 本项目中的单价文件
                 if (data.self.length > 0) {
@@ -915,14 +951,24 @@ $(function () {
         let type = $("input[name='change-type']:checked").val();
         type = parseInt(type);
         let changeUnitPriceId = 0;
+        $('#change-unitFile').modal("hide");
         if (type === 0) {
             // 从本项目中选择
             changeUnitPriceId = $("#self-file").val();
         } else {
             // 从其他项目中复制
             changeUnitPriceId = $("#other-file").val();
+            let newName = $("#other-file").children("option:selected").text();
+            let currentOption = _.find(projectGljObject.changeInfo.self,{name:newName});
+            if(currentOption){ //存在则说明有重名的文件
+                //rename-unitFile
+                $("#rename-unitFile").modal({show:true});
+                $("#newUnitFileID").val(changeUnitPriceId);
+                $("#newUnitFileName").val(newName);
+                return;
+            }
+
         }
-        $('#change-unitFile').modal("hide");
         let data = {project_id: scUrlUtil.GetQueryString('project'), change_id: changeUnitPriceId, type: type};
         projectObj.project.projectGLJ.changeFile(data,function () {
             projectGljObject.changeFileCallback();
@@ -942,6 +988,7 @@ $(function () {
     $("#unitFile-save-as").on('shown.bs.modal', function () {
         // 获取当前建设项数据
         $("#save-as-name").val(projectGljObject.usedUnitPriceInfo.name + '副本');
+        projectGljObject.checkUnitFileName(projectGljObject.usedUnitPriceInfo.name + '副本');
     });
 
     // 从其他建设项目中复制 选择建设项目
@@ -957,17 +1004,56 @@ $(function () {
         $("#other-file").html(otherFileHtml);
     });
 
+    $('#save-as-name').change(function () {
+        projectGljObject.checkUnitFileName(this.value);
+    });
+
+    $('#newUnitFileName').change(function () {
+        let projectGLJ = projectObj.project.projectGLJ;
+        projectGLJ.checkUnitFileName(this.value,function (data) {
+            if(data){
+                $("#renameError_unitFile").text('已存在同名单价文件').show();
+                $('#renameUnitFileConfirm').attr("disabled","disabled");
+            }else {
+                $("#renameError_unitFile").hide();
+                $('#renameUnitFileConfirm').removeAttr("disabled");
+            }
+        });
+
+    });
+    $("#renameUnitFileConfirm").click(function () {
+        let projectGLJ = projectObj.project.projectGLJ;
+        let newName = $('#newUnitFileName').val();
+        let changeUnitPriceId = $('#newUnitFileID').val();
+        projectGLJ.checkUnitFileName(newName,function (data) {
+            if(data){
+                $("#renameError_unitFile").text('已存在同名单价文件').show();
+                $('#renameUnitFileConfirm').attr("disabled","disabled");
+            }else {
+                $("#renameError_unitFile").hide();
+                $('#renameUnitFileConfirm').removeAttr("disabled");
+                let data = {project_id: scUrlUtil.GetQueryString('project'), change_id: changeUnitPriceId, type: 1,newName:newName};
+                projectObj.project.projectGLJ.changeFile(data,function () {
+                    projectGljObject.changeFileCallback();
+                })
+            }
+        });
+    });
+
     // 单价文件另存为操作
     $("#save-as-confirm").click(function () {
+        let projectGLJ = projectObj.project.projectGLJ;
         let name = $("#save-as-name").val();
         if (name === '') {
             $("#save-as-tips").text('请填写单价文件名称').show();
             return false;
         }
         let saveData = {name: name, project_id: scUrlUtil.GetQueryString('project')};
-        projectObj.project.projectGLJ.saveAs(saveData,function () {
-             projectGljObject.changeFileCallback();
-            $("#unitFile-save-as").modal("hide");
+        projectGljObject.checkUnitFileName(name,function () {
+            projectGLJ.saveAs(saveData,function () {
+                projectGljObject.changeFileCallback();
+                $("#unitFile-save-as").modal("hide");
+            });
         });
     });
 

+ 1 - 0
web/building_saas/main/js/views/project_info.js

@@ -38,6 +38,7 @@ var projectInfoObj = {
                 basicInfoView.orgDatas = data.property.basicInformation ? basicInfoView.toViewDatas(data.property.basicInformation) : [];
                 projFeatureView.orgDatas = data.property.projectFeature ? projFeatureView.toViewDatas(data.property.projectFeature) : [];
                 $('#fullpath').html(that.getFullPathHtml(that.projectInfo));
+
             }
         });
     }

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

@@ -75,11 +75,11 @@ var projectObj = {
             if(node.sourceType !== that.project.Bills.getSourceType()){//焦点行是定额/量价/工料机,灰显。
                 return false;
             }else {
-                if(node.data.type == billType.FX){//是分项,灰显。
+                if(node.data.type == billType.FX || node.data.type == billType.BX){//是分项,或者补项灰显。
                     return false;
                 }
                 if(node.data.type == billType.FB&&node.nextSibling&&node.children.length>0){//焦点行是分部有后兄弟,有子项.
-                     if(node.children[0].data.type==billType.FX){ //焦点行子项是分项
+                     if(node.children[0].data.type==billType.FX || node.children[0].data.type==billType.BX){ //焦点行子项是分项
                          return false;
                      }
                 }
@@ -107,7 +107,7 @@ var projectObj = {
             if(node.sourceType !== that.project.Bills.getSourceType()) {//焦点行是定额/量价/工料机,灰显。
                 return false;
             }else {
-                if(node.data.type == billType.FX){//是分项,灰显。
+                if(node.data.type == billType.FX || node.data.type == billType.BX){//是分项,灰显。
                     return false;
                 }
                 if(!node.preSibling){//无前兄弟,灰显
@@ -116,7 +116,7 @@ var projectObj = {
                     return false
                 }
                 if(node.preSibling.children.length>0){//前兄弟有子项,子项是分项,灰显。
-                    if(node.data.type==billType.FB&&node.preSibling.children[0].data.type==billType.FX){//焦点行是分部前兄弟有子项,子项是分项,灰显。
+                    if(node.data.type==billType.FB&&(node.preSibling.children[0].data.type==billType.FX||node.preSibling.children[0].data.type==billType.BX)){//焦点行是分部前兄弟有子项,子项是分项,灰显。
                         return false;
                     }
                     if(node.data.type==billType.BILL&&node.preSibling.children[0].sourceType !== that.project.Bills.getSourceType()){//焦点行是清单,子项不是清单
@@ -638,9 +638,9 @@ var projectObj = {
                     // 综合单价、综合合价,小数部分应补0对齐。  CSLAAAAA
                     // if (col.data.field.hasSubStr("common")){
                         if (col.data.field.hasSubStr(".totalFee"))
-                            col.data.formatter = MainTreeCol.getNumberFormatter(decimalObj.ration.totalPrice, true)
+                            col.data.formatter = MainTreeCol.getNumberFormatter(decimalObj.ration.totalPrice, true);
                         else if (col.data.field.hasSubStr(".unitFee"))
-                            col.data.formatter = MainTreeCol.getNumberFormatter(decimalObj.ration.unitPrice, true)
+                            col.data.formatter = MainTreeCol.getNumberFormatter(decimalObj.ration.unitPrice, true);
                     // }
 
                 });

+ 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;