Jelajahi Sumber

Merge branch 'master' into olym

olym 7 tahun lalu
induk
melakukan
962e88f01b

+ 18 - 2
modules/main/controllers/labour_coe_controller.js

@@ -7,7 +7,8 @@ let labourCoeFacade = require('../facade/labour_coe_facade');
 
 module.exports = {
     getProjectLabourCoe: getProjectLabourCoe,
-    getStdLabourCoe: getStdLabourCoe
+    getStdLabourCoe: getStdLabourCoe,
+    save: save
 };
 
 async function getProjectLabourCoe(req, res) {
@@ -29,7 +30,7 @@ async function getStdLabourCoe(req, res) {
     let result = {error: 0, message: '', data: null};
 
     try {
-        let stdLC = await labourCoeFacade.getStdLabourCoe(req.body.ID);
+        let stdLC = await labourCoeFacade.getStdLabourCoe(JSON.parse(req.body.data).ID);
         result.data= stdLC;
     }catch (err){
         console.log(err);
@@ -39,3 +40,18 @@ async function getStdLabourCoe(req, res) {
 
     res.json(result);
 };
+
+function save(req, res) {
+    let result = {error: 0, message: '', data: null};
+
+    labourCoeFacade.save(req.body.data, function (err, message, data) {
+        if (err == 0){
+            result.data = data;
+        }else{
+            result.error = 1;
+            result.message = message;
+        }
+    });
+
+    res.json(result);
+};

+ 4 - 0
modules/main/controllers/project_controller.js

@@ -22,6 +22,10 @@ module.exports = {
     },
     getData: function (req, res) {
         var data = JSON.parse(req.body.data);
+        // 注释代码用于测试getFilterData
+        // Project.getFilterData(data.project_id, ['bills', 'projectGLJ'], function (err, result) {
+        //     console.log(result);
+        // });
         Project.getData(data.project_id, function (err, message, result) {
             if (!err) {
                 callback(req, res, err, message, result);

+ 16 - 2
modules/main/facade/labour_coe_facade.js

@@ -83,6 +83,20 @@ function getData(projectID, callback) {
 };
 
 // 统一的 save() 方法供project调用
-function save (user_id, datas, callback) {
-    projectLabourCoesModel.update({"projectID": 553}, {"libName":"goo"}, callback(null, {data: 'ok'}));
+function save (data, callback) {
+    let updateArr = [];
+    let datas = JSON.parse(data);
+    for (let Item of datas.updateData) {
+         let ItemObj = {
+             updateOne: {
+                 filter: {projectID: datas.projectID, 'coes.ID': Item.ID},
+                 update: { 'coes.$.coe': Item.value }
+             }
+         };
+         updateArr.push(ItemObj);
+    };
+    // console.log(JSON.stringify(updateArr));
+    projectLabourCoesModel.bulkWrite(updateArr)
+        .then(callback(0, '', null))
+        .catch(function (err) {callback(1, err, null)});
 }

+ 28 - 5
modules/main/models/project.js

@@ -14,9 +14,13 @@ let projSetting = require('./proj_setting_model');
 let volumePriceData = require('../../volume_price/models/volume_price_model');
 var labour_coe_facade = require('../facade/labour_coe_facade');
 var calc_program_facade = require('../facade/calc_program_facade');
+
+const ProjectModel = require('../../pm/models/project_model').project;
+import GLJListModel from "../../glj/models/glj_list_model";
+
 var consts = require('./project_consts');
 var projectConsts = consts.projectConst;
-var async = require("async");
+var asyncTool = require("async");
 
 var moduleMap = {};
 
@@ -73,7 +77,7 @@ Project.prototype.save = function(datas, callback){
         functions.push(saveModule(item));
     }
 
-    async.parallel(functions, function(err, results) {
+    asyncTool.parallel(functions, function(err, results) {
         if (!err){
             callback(null, '', results)
         }
@@ -98,7 +102,7 @@ Project.prototype.getData = function(projectID, callback){
         })(itemName))
     }
 
-    async.parallel(functions, function(err, results) {
+    asyncTool.parallel(functions, function(err, results) {
         if (!err){
             callback(null, '', results)
         }
@@ -111,11 +115,29 @@ Project.prototype.getData = function(projectID, callback){
 Project.prototype.getFilterData = function (projectID, filter, callback) {
     let functions = [];
     let getModuleData = function (moduleName) {
-        return function (cb) {
+        return async function (cb) {
             if (moduleMap[moduleName]) {
                 moduleMap[moduleName].getData(projectID, function (err, name, data) {
                     cb(err, {'moduleName': name, 'data': data})
                 });
+            } else if (moduleName === projectConsts.PROJECTGLJ) {
+                try {
+                    if (isNaN(projectID) || projectID <= 0) {
+                        throw '标段id有误';
+                    }
+                    // 获取标段对应的单价文件id
+                    let unitPriceFileId = await ProjectModel.getUnitPriceFileId(projectID);
+                    if (unitPriceFileId <= 0) {
+                        throw '没有对应的单价文件';
+                    }
+                    // 先获取对应标段的项目工料机数据
+                    let gljListModel = new GLJListModel();
+                    let [gljList, mixRatioConnectData] = await gljListModel.getListByProjectId(projectID, unitPriceFileId);
+
+                    cb(null, {'moduleName': moduleName, 'data': gljList});
+                } catch (error) {
+                    cb(error, null);
+                }
             } else {
                 throw '要查询的项目模块不存在';
             }
@@ -124,7 +146,8 @@ Project.prototype.getFilterData = function (projectID, filter, callback) {
     for (let itemName of filter) {
         functions.push(getModuleData(itemName));
     }
-    async.parallel(functions, function (err, results) {
+    asyncTool.parallel(functions, function (err, results) {
+        console.log(results);
         if (err) {
             throw '获取项目数据出错';
         } else {

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

@@ -11,6 +11,7 @@ module.exports = function (app) {
 
     lcRouter.post('/getProjectLabourCoe', lcController.getProjectLabourCoe);
     lcRouter.post('/getStdLabourCoe', lcController.getStdLabourCoe);
+    lcRouter.post('/save', lcController.save);
 
     app.use('/labourCoe',lcRouter);
 }

+ 41 - 35
modules/reports/controllers/rpt_controller.js

@@ -8,6 +8,9 @@ import async from "async";
 import JV from "../rpt_component/jpc_value_define";
 
 let Template = mongoose.model('rpt_templates');
+let rptTplDataFacade = require("../facade/rpt_tpl_data_facade");
+//let fsUtil = require("../../../public/fsUtil");
+
 import rptTplFacade from "../facade/rpt_template_facade";
 import demoTemplateFacade from "../facade/rpt_tpl_data_demo_facade";
 
@@ -17,6 +20,7 @@ import rpt_xl_util from "../util/rpt_excel_util";
 import rpt_pdf_util from "../util/rpt_pdf_util";
 import fs from "fs";
 import strUtil from "../../../public/stringUtil";
+import rptDataExtractor from "../util/rpt_construct_data_util";
 
 //统一回调函数
 let callback = function(req, res, err, data){
@@ -68,42 +72,36 @@ function getAllPagesCommonOrg(rpt_id, pageSize, option, cb) {
     );
 }
 
-function getAllPagesCommon(rpt_id, pageSize, cb) {
+function getAllPagesCommon(user_id, prj_id, rpt_id, pageSize, option, cb) {
     let rptTpl = null;
     rptTplFacade.getRptTemplate(rpt_id).then(function(rst) {
         rptTpl = rst;
         if (rptTpl) {
-            let tplData = {};
-            if (rptTpl[JV.NODE_FIELD_MAP]) {
-                //1. 离散数据
-                if (rptTpl[JV.NODE_FIELD_MAP][JV.NODE_DISCRETE_FIELDS] && rptTpl[JV.NODE_FIELD_MAP][JV.NODE_DISCRETE_FIELDS].length > 0) {
-                    tplData[JV.DATA_DISCRETE_DATA] = [];
-                }
-                //2. 主数据
-                if (rptTpl[JV.NODE_FIELD_MAP][JV.NODE_MASTER_FIELDS] && rptTpl[JV.NODE_FIELD_MAP][JV.NODE_MASTER_FIELDS].length > 0) {
-                    tplData[JV.DATA_MASTER_DATA] = [];
-                }
-                //3. 从数据
-                if (rptTpl[JV.NODE_FIELD_MAP][JV.NODE_DETAIL_FIELDS] && rptTpl[JV.NODE_FIELD_MAP][JV.NODE_DETAIL_FIELDS].length > 0) {
-                    tplData[JV.DATA_DETAIL_DATA] = [];
-                }
-                //2. Ex主数据
-                if (rptTpl[JV.NODE_FIELD_MAP][JV.NODE_MASTER_FIELDS_EX] && rptTpl[JV.NODE_FIELD_MAP][JV.NODE_MASTER_FIELDS_EX].length > 0) {
-                    tplData[JV.DATA_MASTER_DATA_EX] = [];
-                }
-                //3. Ex从数据
-                if (rptTpl[JV.NODE_FIELD_MAP][JV.NODE_DETAIL_FIELDS_EX] && rptTpl[JV.NODE_FIELD_MAP][JV.NODE_DETAIL_FIELDS_EX].length > 0) {
-                    tplData[JV.DATA_DETAIL_DATA_EX] = [];
-                }
-                //4. 重点: 开始组装$PROJECT对象
-                let $PROJECT = {};
-                //let $PROJECT.COMMON = {};
-                //return demoTemplateData.getPromise(rptTpl.ID_KEY);
-                //return demoTemplateData.findOne({"Data_Key": rptTpl.ID_KEY}).exec();
+            let rptDataUtil = new rptDataExtractor();
+            rptDataUtil.initialize((rptTpl._doc)?rptTpl._doc:rptTpl);
+            let filter = rptDataUtil.getDataRequestFilter();
+            rptTplDataFacade.prepareProjectData(user_id, prj_id, filter, function (err, msg, rawDataObj) {
+                if (!err) {
+                    let tplData = rptDataUtil.assembleData(rawDataObj);
+                    let printCom = JpcEx.createNew();
+                    rptTpl[JV.NODE_MAIN_INFO][JV.NODE_PAGE_INFO][JV.PROP_PAGE_SIZE] = pageSize;
+                    let defProperties = rptUtil.getReportDefaultCache();
+                    let dftOption = option||JV.PAGING_OPTION_NORMAL;
+                    printCom.initialize(rptTpl);
+                    printCom.analyzeData(rptTpl, tplData, defProperties, dftOption);
+                    let maxPages = printCom.totalPages;
+                    let pageRst = printCom.outputAsSimpleJSONPageArray(rptTpl, tplData, 1, maxPages, defProperties);
+                    if (pageRst) {
+                        //fsUtil.wirteObjToFile(pageRst, "D:/GitHome/ConstructionCost/tmp/testBuiltPageResult.js");
+                        cb(null, pageRst);
+                    } else {
+                        cb('Have errors while on going...', null);
+                    }
 
-            } else {
-                cb('No report template data were found!', null);
-            }
+                } else {
+                    cb('No report data were found!', null);
+                }
+            });
         } else {
             cb('No report template was found!', null);
         }
@@ -111,7 +109,15 @@ function getAllPagesCommon(rpt_id, pageSize, cb) {
 }
 
 module.exports = {
-    getReportAllPages: function(req, res){
+    getReportAllPages: function (req, res) {
+        let rpt_id = req.body.rpt_tpl_id, prj_id = req.body.prj_id,
+            user_id = req.body.user_id, pageSize = req.body.pageSize;
+        getAllPagesCommon(rpt_id, prj_id, user_id, pageSize, function (err, pageRst) {
+            callback(req, res, err, pageRst);
+        });
+    },
+
+    getTestReportAllPages: function(req, res){
         let rpt_id = req.body.ID;
         let pageSize = req.body.pageSize;
         getAllPagesCommonOrg(rpt_id, pageSize, JV.PAGING_OPTION_NORMAL, function(err, pageRst){
@@ -119,7 +125,7 @@ module.exports = {
             callback(req, res, err, pageRst);
         })
     },
-    getExcel: function(req, res) {
+    getTestExcel: function(req, res) {
         let rpt_id = req.params.id,
             pageSize = req.params.size,
             rptName = req.params.rptName,
@@ -145,7 +151,7 @@ module.exports = {
             }
         })
     },
-    getExcelInOneBook: function(req, res) {
+    getTestExcelInOneBook: function(req, res) {
         let rpt_ids = req.params.ids.split(','),
             pageSize = req.params.size,
             rptName = req.params.rptName,
@@ -185,7 +191,7 @@ module.exports = {
             }
         })
     },
-    getPDF:function (req, res) {
+    getTestPDF:function (req, res) {
         let rpt_id = req.params.id,
             pageSize = req.params.size,
             rptName = req.params.rptName;

+ 10 - 4
modules/reports/routes/report_router.js

@@ -17,11 +17,17 @@ module.exports =function (app) {
                     userID: req.session.managerData.userID});
         }
     });
-    rptRouter.post('/getReport', reportController.getReportAllPages);
 
-    rptRouter.get('/getExcel/:id/:size/:rptName/:isOneSheet/:option', reportController.getExcel);
-    rptRouter.get('/getExcelInOneBook/:ids/:size/:rptName/:option', reportController.getExcelInOneBook);
+    //test
+    rptRouter.post('/getTestReport', reportController.getTestReportAllPages);
+    rptRouter.get('/getTestExcel/:id/:size/:rptName/:isOneSheet/:option', reportController.getTestExcel);
+    rptRouter.get('/getTestExcelInOneBook/:ids/:size/:rptName/:option', reportController.getTestExcelInOneBook);
+    rptRouter.get('/getTestPDF/:id/:size/:rptName', reportController.getTestPDF);
+    //now is the real:
+    rptRouter.post('/getReport', reportController.getReportAllPages);
+    // rptRouter.get('/getExcel/:id/:size/:rptName/:isOneSheet/:option', reportController.getExcel);
+    // rptRouter.get('/getExcelInOneBook/:ids/:size/:rptName/:option', reportController.getExcelInOneBook);
+    // rptRouter.get('/getPDF/:id/:size/:rptName', reportController.getPDF);
 
-    rptRouter.get('/getPDF/:id/:size/:rptName', reportController.getPDF);//2/A4/07-1表
     app.use("/report_api", rptRouter);
 };

+ 26 - 5
modules/reports/util/rpt_construct_data_util.js

@@ -47,6 +47,12 @@ class Rpt_Data_Extractor {
                     if (field[JV.PROP_FIELD_EXP_MAP]) {
                         if (field[JV.PROP_FIELD_EXP_MAP].indexOf('.' + key + '.') >= 0) {
                             rst.push(key);
+                            if (key === projectConst.RATION_GLJ && (rst.indexOf(projectConst.PROJECTGLJ) < 0)) {
+                                //rst.push(projectConst.PROJECTGLJ);
+                            }
+                            if (key === projectConst.PROJECTGLJ && (rst.indexOf(projectConst.RATION_GLJ) < 0)) {
+                                rst.push(projectConst.RATION_GLJ);
+                            }
                         }
                     }
                 }
@@ -341,7 +347,7 @@ function ext_mainGetPropety(propKey) {
     return rst;
 }
 
-function ext_mainGetFee(feeKey) {
+function ext_mainGetFee(feeKey, dtlFeeKey) {
     let rst = [];
     let parentObj = this;
     let dtObj = parentObj["myOwnRawDataObj"];
@@ -349,7 +355,11 @@ function ext_mainGetFee(feeKey) {
         if (dtObj.hasOwnProperty("fees")) {
             for (let fee of dtObj["fees"]) {
                 if (fee["fieldName"] === feeKey) {
-                    rst.push(dtObj["fees"][feeKey]);
+                    if (dtlFeeKey) {
+                        rst.push(fee[dtlFeeKey]);
+                    } else {
+                        rst.push(fee["unitFee"]);
+                    }
                     break;
                 }
             }
@@ -380,22 +390,33 @@ function ext_getPropety(propKey) {
     return rst;
 }
 
-function ext_getFee(feeKey) {
+function ext_getFee(feeKey, dtlFeeKey) {
     let rst = [], parentObj = this;
     let dtObj = parentObj["myOwnRawDataObj"];
     if (feeKey && dtObj) {
         for (let dItem of dtObj.data) {
+            let hasValue = false;
             if (dItem.hasOwnProperty("fees")) {
                 for (let fee of dItem["fees"]) {
                     if (fee["fieldName"] === feeKey) {
-                        rst.push(dItem["fees"][feeKey]);
+                        if (dtlFeeKey) {
+                            rst.push(fee[dtlFeeKey]);
+                        } else {
+                            rst.push(fee["unitFee"]);
+                        }
+                        hasValue = true;
                         break;
                     }
                 }
             } else if (dItem.hasOwnProperty(feeKey)) {
+                hasValue = true;
                 rst.push(dItem[feeKey]);
             } else {
-                rst.push[0];
+                hasValue = true;
+                rst.push(0);
+            }
+            if (!hasValue) {
+                rst.push(0);
             }
         }
     }

+ 8 - 8
public/fsUtil.js

@@ -2,26 +2,26 @@
  * Created by Tony on 2017/4/10.
  */
 
-var fs = require('fs');
+let fs = require('fs');
 
 module.exports = {
     writeArrayToFile: function(arr, filePath) {
         if (arr && filePath && Array.isArray(arr)) {
-            var chunks = [], len = 0;
-            for (var i = 0; i < arr.length; i++) {
-                var buffer = new Buffer(arr[i]);
+            let chunks = [], len = 0;
+            for (let i = 0; i < arr.length; i++) {
+                let buffer = new Buffer(arr[i]);
                 chunks.push(buffer);
                 len += buffer.length;
                 //
             }
-            var resultBuffer = new Buffer(len);
-            for(var i=0,size=chunks.length,pos=0;i<size;i++){
+            let resultBuffer = new Buffer(len);
+            for(let i=0,size=chunks.length,pos=0;i<size;i++){
                 chunks[i].copy(resultBuffer,pos);
                 pos += chunks[i].length;
             }
             fs.writeFile(filePath, resultBuffer, function(err){
                 if(err) throw err;
-                console.log('Write file: ' + filePath + ' ok!');
+                //console.log('Write file: ' + filePath + ' ok!');
             });
         }
     },
@@ -32,4 +32,4 @@ module.exports = {
             this.writeArrayToFile(arr, filePath);
         }
     }
-}
+};

+ 12 - 3
public/web/number_util.js

@@ -2,9 +2,9 @@
  * Created by chen on 2017/7/5.
  */
 
-Number.prototype.toDecimal = function (ADigit) {
-    return parseFloat(this.toFixed(ADigit));
-};
+// Number.prototype.toDecimal = function (ADigit) {
+//     return parseFloat(this.toFixed(ADigit));
+// };
 
 var  number_util = {
     isNumber : function (obj) {
@@ -24,5 +24,14 @@ var  number_util = {
             value = editingText;
         }
         return value;
+    },
+    roundToString:function(obj,decimal){
+        let value;
+        if(this.isNumber(obj)){
+            value = scMathUtil.roundTo(obj,-decimal)
+        }else {
+            value = scMathUtil.roundTo(Number(obj),-decimal);
+        }
+        return value.toFixed(decimal);
     }
 }

+ 10 - 1
public/web/scMathUtil.js

@@ -66,7 +66,7 @@ let scMathUtil = {
             if (num === 0){
                 num = 1;
                 let bin1 = bin.substring(0, i);
-                let bin2 = zeroString(iLength - (i + 1));//bin.substring(i + 1, iLength);
+                let bin2 = this.zeroString(iLength - (i + 1));//bin.substring(i + 1, iLength);
                 result = bin1 + num.toString() + bin2;
                 break;
             }
@@ -78,4 +78,13 @@ let scMathUtil = {
         let me = this;
         return me.innerRoundTo(me.binToFloat(me.incMantissa(me.floatToBin(num))), digit);
     }
+};
+
+Number.prototype.toDecimal = function (ADigit) {
+    //return parseFloat(this.toFixed(ADigit));
+    digit = (ADigit && typeof(ADigit) === 'number' && Number.isInteger(ADigit) && ADigit >= 0) ? -ADigit : -2;
+    // var s = scMathUtil.roundTo(this, digit);
+    // console.log('Number: ' + this + '   Digit: ' + digit + '    Result: ' + s);
+    // return parseFloat(s);
+    return scMathUtil.roundTo(this, digit);
 };

+ 3 - 11
web/building_saas/fee_rates/fee_rate.html

@@ -1,14 +1,6 @@
-<!DOCTYPE html>
-<html lang="en">
 
-<head>
-    <meta charset="utf-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
-    <meta http-equiv="x-ua-compatible" content="ie=edge">
 
-</head>
-
-<body >
+<div >
 <div class="toolsbar 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>)
@@ -164,5 +156,5 @@
 </div>
 
 
-</body>
-</html>
+</div>
+

+ 1 - 0
web/building_saas/glj/js/project_glj.js

@@ -26,6 +26,7 @@ let currentTag = '';
 let isChanging = false;
 $(document).ready(function () {
     $('#tab_gongliaoji').on('show.bs.tab', function (e) {
+        $(e.relatedTarget.hash).removeClass('active');
         init();
     });
 

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

@@ -76,11 +76,11 @@
     <div class="main">
         <div class="main-nav">
             <ul class="nav nav-tabs flex-column" role="tablist">
-                <li class="nav-item"><a class="active" data-toggle="tab" href="#zaojiashu" role="tab">造价书</a></li>
+                <li class="nav-item"><a class="active" data-toggle="tab" href="#zaojiashu" id="tab_zaojiashu" role="tab">造价书</a></li>
                 <li class="nav-item"><a data-toggle="tab" href="#gongliaoji" id="tab_gongliaoji" role="tab">工料机</a></li>
                 <li class="nav-item"><a data-toggle="tab" href="#fee_rates" id="tab_fee_rate" role="tab" >费率</a></li>
                 <li class="nav-item"><a data-toggle="tab" href="#calc_program_manage" id="tab_calc_program_manage" role="tab">计算程序</a></li>
-                <li class="nav-item"><a data-toggle="tab" href="#baobiao" role="tab" onclick="">报表</a></li>
+                <li class="nav-item"><a data-toggle="tab" href="#baobiao" role="tab" id="tab_baobiao" onclick="">报表</a></li>
             </ul>
         </div>
         <div class="content">

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

@@ -6,4 +6,15 @@ $(function () {
     projectInfoObj.showProjectInfo();
     projectObj.checkMainSpread();
     projectObj.loadProjectData();
+
+    $('#tab_baobiao').on('shown.bs.tab', function (e) {
+        $(e.relatedTarget.hash).removeClass('active');
+        // do something
+    });
+
+    $('#tab_zaojiashu').on('shown.bs.tab', function (e) {
+        $(e.relatedTarget.hash).removeClass('active');
+        // do something
+    });
+
 });

+ 43 - 40
web/building_saas/main/js/models/fee_rate.js

@@ -15,15 +15,6 @@ var FeeRate = {
             this.datas = datas;
             socketObject.connect();
         };
-   /*     FeeRate.prototype.getViewDatas = function(){
-            var  rates=[];
-            _.forEach(this.datas,function (item) {
-                if(item.status == 'activate'){
-                    rates= item.rates;
-                }
-            })
-            return rates;
-        };*/
         FeeRate.prototype.getActivateFeeRate = function () {
             var feeRate={
                 rates:[]
@@ -126,7 +117,8 @@ var FeeRate = {
             doc.rate.rate =doc.rate.rate.toDecimal(feeRate_consts.decimal);
             this.updateFeeRate(query,doc);
             if(this.ifRateChange(params)){
-                this.synchronizeFeeRate();
+                //this.synchronizeFeeRate();
+                this.onFeeRateChange(params.dataItem.ID,params.dataItem.rate);
             }
         };
 
@@ -139,7 +131,6 @@ var FeeRate = {
         FeeRate.prototype.updateFeeRate=function (query,doc) {
           var updateData = this.getUpdateData('ut_update',query,doc,'update_rates');
             project.pushNow('updateFeeRate',[this.sourceType],updateData);
-            socket.emit('feeRateChangeNotify', this.getActivateFeeRateFileID());
         };
         FeeRate.prototype.updateStatusBySelected = function (updateTasks) {
             var updateData = [];
@@ -155,18 +146,53 @@ var FeeRate = {
             var node = project.mainTree.selected;
             if(node){
                 if (node.sourceType==='ration' && calcProgramObj.sheet) {
-                    project.calcProgram.compileAllTemps();
                     calcProgramObj.showData(node);
                 }
             }
         };
         FeeRate.prototype.ifRateChange=function (params) {
-            if(params.dataItem.rate!=params.oldDataItem.rate){
+            if(params.dataItem.memo==params.oldDataItem.memo){
                 return true;
             }else {
                 return false;
             }
         };
+        FeeRate.prototype.onFeeRateChange=function (rateID,value) {
+            var node = project.mainTree.selected;
+            this.refreshCalProgramByRateID(rateID,value);
+            this.refreshBillsByRateID(rateID,value);
+            if(node){
+                if (node.sourceType==='ration' && calcProgramObj.sheet) {
+                    calcProgramObj.showData(node);
+                }
+            }
+            socket.emit('feeRateChangeNotify', this.getActivateFeeRateFileID());
+        };
+        FeeRate.prototype.refreshCalProgramByRateID=function (rateID,value) {
+            var templates = project.calcProgram.datas.templates;
+            for(var i =0;i<templates.length;i++){
+                _.forEach(templates[i].calcItems,function (item) {
+                    if(item.feeRateID==rateID){
+                        item.feeRate = value;
+                    }
+                })
+            }
+            project.calcProgram.compileAllTemps();
+            rationPM.refreshDetailSheet();
+        };
+        FeeRate.prototype.refreshBillsByRateID=function(rateID,value){
+            var nodes = _.filter(projectObj.project.mainTree.items,function (n) {
+                if(n.sourceType==ModuleNames.bills&&n.data.feeRateID==rateID){
+                    n.data.feeRate=number_util.roundToString(value,feeRate_consts.decimal);
+                    return true;
+                }else {
+                    return false;
+                }
+            })
+            if(nodes.length>0){
+                projectObj.mainController.refreshTreeNode(nodes)
+            }
+        };
         FeeRate.prototype.changeFeeRateStandard=function(newVal,callback){
             var me =this;
             var feeRate = this.getActivateFeeRate();
@@ -235,8 +261,8 @@ var FeeRate = {
                     var data=me.getfbUpdateData(rate,bill,value);
                     this.setFeeRateToBill(data,function (result) {
                         if(data.hasOwnProperty('feeRate')){
-                            me.refreshBillsByRateID(rate,value);
-                            socket.emit('feeRateChangeNotify', me.getActivateFeeRateFileID());
+                            rate.rate=value;
+                            me.onFeeRateChange(rate.ID,value);
                         }else {
                             bill.feeRate=value;
                             projectObj.mainController.refreshTreeNode([node])
@@ -281,33 +307,10 @@ var FeeRate = {
                 }
             }
             CommonAjax.post('/feeRates/updateFeeRate', data, function (data) {
-                for(var i =0;i<rationPM.datas.length;i++){
-                    _.forEach(rationPM.datas[i].calcItems,function (item) {
-                        if(item.feeRateID==rate.ID){
-                            item.feeRate = value;
-                        }
-                    })
-                }
                 rate.rate=value;
-                project.calcProgram.compileAllTemps();
-                rationPM.refreshDetailSheet();
-                socket.emit('feeRateChangeNotify', me.getActivateFeeRateFileID());
+                me.onFeeRateChange(rate.ID,value);
             });
         }
-        FeeRate.prototype.refreshBillsByRateID=function(rate,value){
-            rate.rate=value;
-            var nodes = _.filter(projectObj.project.mainTree.items,function (n) {
-                if(n.sourceType==ModuleNames.bills&&n.data.feeRateID==rate.ID){
-                    n.data.feeRate=value;
-                    return true;
-                }else {
-                    return false;
-                }
-            })
-            if(nodes.length>0){
-                projectObj.mainController.refreshTreeNode(nodes)
-            }
-        };
 
         FeeRate.prototype.getfbUpdateData=function (rate,bill,value) {
             var data={};
@@ -383,7 +386,7 @@ var FeeRate = {
             if(node.data.feeRateID){
                 var feeRate = this.getFeeRateByID(node.data.feeRateID);
                 if(feeRate){
-                    node.data.feeRate=parseFloat(feeRate.rate).toFixed(feeRate_consts.decimal);
+                    node.data.feeRate=number_util.roundToString(feeRate.rate,feeRate_consts.decimal);// parseFloat(feeRate.rate).toFixed(feeRate_consts.decimal);
                 }
             }
         };

+ 17 - 0
web/building_saas/main/js/models/labour_coe.js

@@ -21,5 +21,22 @@ class LabourCoe {
             // do
         }
     };
+
+    refreshData (data){
+        let me = this;
+        if (data.libID && data.libID != me.datas.libID){
+            me.datas.libID = data.libID;
+            me.datas.libName = data.libName;
+        };
+
+        for (let newItem of data.newItemArr){
+              for (let oldItem of me.datas.coes){
+                   if (oldItem.ID == newItem.ID){
+                       oldItem.coe = newItem.value;
+                       break;
+                   }
+              };
+        };
+    }
 }
 

+ 5 - 2
web/building_saas/main/js/views/calc_program_manage.js

@@ -113,14 +113,17 @@ let rationPM = {
     },
     refreshDetailSheet:function () {
         var me=this;
-        var mainSheetIndex = me.mainSpread.getActiveSheet().getActiveRowIndex();
-        sheetCommonObj.showData(me.detailSpread.getSheet(0), me.detailSetting,me.datas[mainSheetIndex].calcItems);
+        if(me.mainSpread&&me.detailSpread){
+            var mainSheetIndex = me.mainSpread.getActiveSheet().getActiveRowIndex();
+            sheetCommonObj.showData(me.detailSpread.getSheet(0), me.detailSetting,me.datas[mainSheetIndex].calcItems);
+        }
     }
 
 };
 
 $(document).ready(function(){
     $('#tab_calc_program_manage').on('shown.bs.tab', function (e) {
+        $(e.relatedTarget.hash).removeClass('active');
         rationPM.buildSheet();
     });
 });

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

@@ -350,6 +350,10 @@ var feeRateObject={
             this.mainViews.destroy();
             this.mainViews = null;
         }
+        if(subRateObject.views){
+            subRateObject.views.destroy();
+            subRateObject.views = null;
+        }
         this.activateFeeRate = projectObj.project.FeeRate.getActivateFeeRate();
         this.datas = this.activateFeeRate.rates;
         this.mainViews = new GC.Spread.Views.DataView($('#divFee')[0],
@@ -648,7 +652,7 @@ var feeRateObject={
         var data={'projectID': projectObj.project.ID(),'templatesID': calInfo.template.ID,'calcItem': calInfo.calcItem};
         rationPM.saveCalcItem(data,function (result) {
             calInfo.calcItem.feeRate=rate.rate;
-            project.calcProgram.compileAllTemps();
+            projectObj.project.calcProgram.compileAllTemps();
             rationPM.refreshDetailSheet();
             $("#fee_rate_tree").modal('hide');
         });
@@ -691,6 +695,7 @@ $(function(){
     );
 
     $('#tab_fee_rate').on('shown.bs.tab', function (e) {
+        $(e.relatedTarget.hash).removeClass('active');
         feeRateObject.reFreshRateViews();
         feeRateObject.loadPageContent();
     });

+ 24 - 22
web/building_saas/main/js/views/project_property_labour_coe_view.js

@@ -18,7 +18,7 @@ let labourCoeView = {
             };
 
             for (let lib of stdLabourCoeLibs){
-                result += '<option value="'+ lib.id +'">'+ lib.name +'</option>';
+                result += '<option value='+ lib.id +'>'+ lib.name +'</option>';
             };
             return result;
         };
@@ -57,7 +57,6 @@ let labourCoeView = {
         var me = labourCoeView;
         if (args.propertyName !== "value"){return;};
         let cell = me.sheet.getCell(args.row, args.col);
-        // me.needUpdateDatas.push({ID: cell.coeID, value: cell.value()});
         me.addNeedUpdateData({ID: cell.tag(), value: cell.value()});
     },
 
@@ -76,6 +75,11 @@ let labourCoeView = {
         }
     },
 
+    needSave: function (){
+        let me = this;
+        return me.needUpdateDatas.length > 0;
+    },
+
     loadData(datas){          // 树结构转换二维表显示,行列转换
         let me = this;
         me.spread.suspendEvent();
@@ -110,7 +114,6 @@ let labourCoeView = {
                     if ((v.ParentID == libID) && (v.name == rowName)) {
                         let cell = me.sheet.getCell(r, c+ 1);
                         cell.value(v.coe);
-                        // cell.coeID = v.ID;
                         cell.tag(v.ID);
                         break;
                     };
@@ -126,6 +129,21 @@ let labourCoeView = {
         me.init();
         me.buildSheet();
         me.loadData(datas);
+    },
+
+    save(){
+        let me = this;
+        if (me.needUpdateDatas.length > 0){
+            let data = {projectID: projectInfoObj.projectInfo.ID, updateData: me.needUpdateDatas};
+            let libID = $("#std_labour_coe_files").children("option:selected").val();
+            let libName = $("#std_labour_coe_files").children("option:selected").text();
+            CommonAjax.post('/labourCoe/save', data, function (){
+                projectObj.project.labourCoe.refreshData({libID: libID, libName: libName, newItemArr: me.needUpdateDatas});
+                me.needUpdateDatas.splice(0, me.needUpdateDatas.length);
+                projectObj.project.calcProgram.compileAllTemps();
+                rationPM.buildSheet();
+            });
+        }
     }
 };
 
@@ -142,25 +160,9 @@ $(document).ready(function(){
             return false;
         };
 
-        $.ajax({
-            type:"POST",
-            url: '/labourCoe/getStdLabourCoe',
-            data: {"ID": libID},
-            dataType: 'json',
-            cache: false,
-            timeout: 50000,
-            success: function(result){
-                if (result.error === 0) {
-                    labourCoeView.buildSheet();
-                    labourCoeView.loadData(result.data.coes);
-
-                } else {
-                    alert('error: ' + result.message);
-                }
-            },
-            error: function(jqXHR, textStatus, errorThrown){
-                alert('error ' + textStatus + " " + errorThrown);
-            }
+        CommonAjax.post('/labourCoe/getStdLabourCoe', {"ID": libID}, function (data) {
+            labourCoeView.buildSheet();
+            labourCoeView.loadData(data.coes);
         });
     });
 });

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

@@ -575,6 +575,10 @@ $('#property_ok').click(function () {
         project.projSetting.zanguCalcMode = zanguMode;
         reCalc = true;
     }
+    if (labourCoeView.needSave()){
+        labourCoeView.save();
+        reCalc = true;
+    }
     if (reCalc) {
         projectObj.calculateAll();
         project.pushNow('editBillsCalcMode',