Browse Source

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

TonyKang 7 years ago
parent
commit
be26d95ed7
39 changed files with 697 additions and 297 deletions
  1. 4 2
      config/gulpConfig.js
  2. 19 2
      modules/fee_rates/controllers/fee_rates_controller.js
  3. 7 9
      modules/fee_rates/facade/fee_rates_facade.js
  4. 1 1
      modules/fee_rates/routes/fee_rates_route.js
  5. 60 0
      modules/glj/controllers/glj_controller.js
  6. 3 1
      modules/glj/models/glj_list_model.js
  7. 3 0
      modules/glj/models/schemas/mix_ratio.js
  8. 2 0
      modules/glj/models/schemas/unit_price.js
  9. 2 2
      modules/glj/models/unit_price_model.js
  10. 1 0
      modules/glj/routes/glj_router.js
  11. 18 2
      modules/main/controllers/labour_coe_controller.js
  12. 4 0
      modules/main/controllers/project_controller.js
  13. 1 0
      modules/main/facade/calc_program_facade.js
  14. 16 2
      modules/main/facade/labour_coe_facade.js
  15. 28 5
      modules/main/models/project.js
  16. 1 0
      modules/main/routes/labour_coe_route.js
  17. 40 13
      public/calc_util.js
  18. 0 23
      public/web/calculation/calc_util.js
  19. 12 3
      public/web/number_util.js
  20. 17 1
      public/web/scMathUtil.js
  21. 3 11
      web/building_saas/fee_rates/fee_rate.html
  22. 1 1
      web/building_saas/glj/js/common_spread.js
  23. 3 0
      web/building_saas/glj/js/composition.js
  24. 1 1
      web/building_saas/glj/js/composition_spread.js
  25. 1 0
      web/building_saas/glj/js/project_glj.js
  26. 1 1
      web/building_saas/main/html/calc_program_manage.html
  27. 5 4
      web/building_saas/main/html/main.html
  28. 11 0
      web/building_saas/main/js/main.js
  29. 77 0
      web/building_saas/main/js/models/composition.js
  30. 80 31
      web/building_saas/main/js/models/fee_rate.js
  31. 17 0
      web/building_saas/main/js/models/labour_coe.js
  32. 2 0
      web/building_saas/main/js/models/project.js
  33. 34 21
      web/building_saas/main/js/views/calc_program_manage.js
  34. 162 138
      web/building_saas/main/js/views/fee_rate_view.js
  35. 1 1
      web/building_saas/main/js/views/glj_view.js
  36. 53 22
      web/building_saas/main/js/views/project_property_labour_coe_view.js
  37. 4 0
      web/building_saas/main/js/views/project_view.js
  38. 1 0
      web/common/html/header.html
  39. 1 0
      web/users/html/login.html

+ 4 - 2
config/gulpConfig.js

@@ -8,7 +8,8 @@ module.exports = {
         'lib/jquery/jquery-3.2.1.min.js',
         'lib/popper/popper.min.js',
         'lib/bootstrap/bootstrap.min.js',
-        'web/building_saas/js/*.js'
+        'web/building_saas/js/*.js',
+        'public/web/scMathUtil.js'
     ],
     common_css:[
         'lib/bootstrap/css/bootstrap.min.css',
@@ -38,6 +39,7 @@ module.exports = {
         '!lib/JSExpressionEval_src/JsHashMap.js',
         'lib/jquery-contextmenu/*.js',
         'lib/lodash/lodash.js',
+        'web/building_saas/main/js/models/main_consts.js',
         'web/building_saas/glj/js/project_glj.js',
         'web/building_saas/glj/js/composition.js',
         'web/building_saas/glj/js/common_spread.js',
@@ -58,12 +60,12 @@ module.exports = {
        // 'lib/spreadjs/views/gc.spread.views.dataview.10.0.0.min.js',
        // "lib/spreadjs/views/common/gc.spread.common.10.0.0.min.js",
       //  'lib/spreadjs/views/plugins/gc.spread.views.gridlayout.10.0.0.min.js',
-        'web/building_saas/main/js/models/main_consts.js',
         'web/building_saas/main/js/models/project.js',
         'web/building_saas/main/js/models/bills.js',
         'web/building_saas/main/js/models/ration.js',
         'web/building_saas/main/js/models/glj.js',
         'web/building_saas/main/js/models/project_glj.js',
+        'web/building_saas/main/js/models/composition.js',
         'web/building_saas/main/js/models/fee_rate.js',
         'web/building_saas/main/js/models/ration_glj.js',
         'web/building_saas/main/js/models/ration_coe.js',

+ 19 - 2
modules/fee_rates/controllers/fee_rates_controller.js

@@ -54,7 +54,8 @@ module.exports = {
     getChangeInfo:getChangeInfo,
     changeFeeRateFileFromCurrent:changeFeeRateFileFromCurrent,
     changeFeeRateFileFromOthers:changeFeeRateFileFromOthers,
-    setFeeRateToBill:setFeeRateToBill
+    setFeeRateToBill:setFeeRateToBill,
+    updateFeeRate:updateFeeRate
 }
 
 function libNames(req, res) {
@@ -193,4 +194,20 @@ async function setFeeRateToBill(req,res) {
         result.message = err.message;
     }
     res.json(result);
-}
+}
+
+async function updateFeeRate(req,res) {
+    let result={
+        error:0
+    }
+    try {
+        let data = req.body.data;
+        let uresult= await feeRateFacde.updateFeeRate(data);
+        result.data=uresult;
+    }catch (err){
+        console.log(err);
+        result.error=1;
+        result.message = err.message;
+    }
+    res.json(result);
+}

+ 7 - 9
modules/fee_rates/facade/fee_rates_facade.js

@@ -27,8 +27,9 @@ module.exports={
     changeFeeRateFileFromOthers:changeFeeRateFileFromOthers,
     newFeeRateFile:newFeeRateFile,
     getFeeRatesByProject:getFeeRatesByProject,
+    getGCFeeRateFiles: getGCFeeRateFiles ,
     setFeeRateToBill:setFeeRateToBill,
-    getGCFeeRateFiles: getGCFeeRateFiles
+    updateFeeRate:updateFeeRate
 };
 let operationMap={
     'ut_create':create_fee_rate,
@@ -43,14 +44,6 @@ let updateFunctionMap = {
     'feeRateFileSaveAs':feeRateFileSaveAs
 }
 
-//测试数据 key projectID, value feeRateFileID
-let project_feeRateF_map={
-    99:'da059df1-7c18-11e7-9e2f-1390b52643b4'
-}
-
-
-
-
 
 function create_fee_rate() {
 
@@ -359,6 +352,11 @@ async function setFeeRateToBill(data){
     return "ok";
 }
 
+async function updateFeeRate(data) {
+    data=JSON.parse(data);
+   return  await feeRateModel.findOneAndUpdate(data.query,data.doc);
+}
+
 async function changeFeeRateFileFromCurrent(jdata){
     let data = JSON.parse(jdata);
     let newFeeRateFile=data.newFeeRateFile;

+ 1 - 1
modules/fee_rates/routes/fee_rates_route.js

@@ -19,7 +19,7 @@ module.exports = function (app) {
     frRouter.post('/changeFeeRateFileFromCurrent', frController.changeFeeRateFileFromCurrent);
     frRouter.post('/changeFeeRateFileFromOthers', frController.changeFeeRateFileFromOthers);
     frRouter.post('/setFeeRateToBill', frController.setFeeRateToBill);
-
+    frRouter.post('/updateFeeRate', frController.updateFeeRate);
     app.use('/feeRates',frRouter);
 }
 

+ 60 - 0
modules/glj/controllers/glj_controller.js

@@ -428,6 +428,66 @@ class GLJController extends BaseController {
     }
 
     /**
+     * 获取项目中所有组成物数据(用户缓存到前端变量)
+     *
+     * @param {object} request
+     * @param {object} response
+     * @return {void}
+     */
+    async getComposition(request, response) {
+        let projectId = request.body.project_id;
+        projectId = parseInt(projectId);
+
+        let responseData = {
+            err: 0,
+            data: null
+        };
+        try {
+            // 当前单价文件id
+            let currentUnitPriceId = await ProjectModel.getUnitPriceFileId(projectId);
+            if (currentUnitPriceId <= 0) {
+                throw '没有找到对应的单价文件';
+            }
+
+            // 获取组成物数据
+            let mixRatioModel = new MixRatioModel();
+            let compositionData = await mixRatioModel.findDataByCondition({unit_price_file_id: currentUnitPriceId}, null, false);
+            if (compositionData === null) {
+                throw '没有找到组成物数据';
+            }
+            compositionData = JSON.parse(JSON.stringify(compositionData));
+            // 查找对应的单价数据
+            let unitPriceModel = new UnitPriceModel();
+            let unitPriceData = await unitPriceModel.findDataByCondition({unit_price_file_id: currentUnitPriceId}, null, false, 'glj_id');
+
+            // 整理数据
+            let result = {};
+            for(let composition of compositionData) {
+                let tmpId = composition.glj_id !== undefined ? composition.glj_id : -1;
+                let tmpData = {
+                    market_price: unitPriceData[tmpId] !== undefined ?
+                        unitPriceData[tmpId].market_price : 0,
+                    base_price: unitPriceData[tmpId] !== undefined ?
+                        unitPriceData[tmpId].base_price : 0,
+                    consumption: composition.consumption,
+                    glj_type: composition.glj_type,
+                    connect_code: composition.connect_code
+                };
+                if (result[tmpId] === undefined) {
+                    result[tmpId] = [];
+                }
+                result[tmpId].push(tmpData);
+            }
+            responseData.data = result;
+        } catch (error) {
+            responseData.err = 1;
+            responseData.data = null;
+        }
+
+        response.json(responseData);
+    }
+
+    /**
      * 模拟定额插入
      *
      * @param {object} request

+ 3 - 1
modules/glj/models/glj_list_model.js

@@ -439,7 +439,8 @@ class GLJListModel extends BaseModel {
                 glj_id: tmp.ID,
                 unit_price_file_id: unitPriceFileId,
                 connect_code: tmp.connectCode,
-                glj_type: tmp.gljType
+                glj_type: tmp.gljType,
+                code: tmp.code,
             };
             mixRatioInsertData.push(mixRatioData);
         }
@@ -484,6 +485,7 @@ class GLJListModel extends BaseModel {
                 unit_price_file_id: unitPriceFileId,
                 type: tmp.gljType,
                 short_name: tmp.shortName === undefined ? '' : tmp.shortName,
+                glj_id: tmp.ID,
             };
             unitPriceInsertData.push(unitPriceData);
         }

+ 3 - 0
modules/glj/models/schemas/mix_ratio.js

@@ -29,6 +29,9 @@ let modelSchema = {
         type: String,
         index: true
     },
+    // 对应工料机code
+    code: String,
+    // 工料机类型
     glj_type: Number
 };
 let model = mongoose.model(collectionName, new Schema(modelSchema, {versionKey: false, collection: collectionName}));

+ 2 - 0
modules/glj/models/schemas/unit_price.js

@@ -32,6 +32,8 @@ let modelSchema = {
     short_name: String,
     // 单价文件表id
     unit_price_file_id: Number,
+    // 对应标准库工料机id
+    glj_id: Number
 };
 let model = mongoose.model(collectionName, new Schema(modelSchema, {versionKey: false, collection: collectionName}));
 export {model as default, collectionName as collectionName};

+ 2 - 2
modules/glj/models/unit_price_model.js

@@ -107,7 +107,6 @@ class UnitPriceModel extends BaseModel {
             data.name = regular.test(data.name) ? data.name.replace(regular, changeString) :
                 data.name + changeString;
         }
-
         let insertData = {
             code: data.code,
             base_price: data.base_price,
@@ -115,7 +114,8 @@ class UnitPriceModel extends BaseModel {
             unit_price_file_id: unitPriceFileId,
             name: data.name,
             type: data.type,
-            short_name: data.shortName !== undefined ? data.shortName : ''
+            short_name: data.shortName !== undefined ? data.shortName : '',
+            glj_id: data.glj_id
         };
 
         let addPriceResult = await this.add(insertData);

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

@@ -20,6 +20,7 @@ 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('/save-as', gljController.init, gljController.unitPriceSaveAs);
+router.post('/get-composition', gljController.init, gljController.getComposition);
 
 router.get('/test', gljController.init, gljController.test);
 router.get('/testModify', gljController.init, gljController.testModify);

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

+ 1 - 0
modules/main/facade/calc_program_facade.js

@@ -88,6 +88,7 @@ function save (user_id, datas, callback) {
 }
 
 function saveCalcItem(dataObj, callback) {
+    dataObj=JSON.parse(dataObj);
     projectCalcProgramsModel.findOne({projectID: dataObj.projectID}, function (err, data) {
         if(!err){
             for (let i = 0; i < data.templates.length; i++){

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

+ 40 - 13
public/calc_util.js

@@ -23,20 +23,47 @@ let executeObj = {
 
         if (base != null) {
             let price = 0, aprice = 0, mprice = 0, tmpSum = 0;
-            for (let glj of me.treeNode.data.gljList) {
-                if (base.gljTypes.indexOf(glj.type) >= 0) {
-                    if (base.calcType == baseCalc){ price = glj["basePrice"];}
-                    else if (base.calcType == adjustCalc){price = glj["adjustPrice"];}
-                    else if (base.calcType == budgetCalc){price = glj["marketPrice"];}
-                    else if (base.calcType == diffCalc){
-                        aprice = glj["adjustPrice"];
-                        if (!aprice) aprice = 0;
-                        mprice = glj["marketPrice"];
-                        if (!mprice) mprice = 0;
-                        price = mprice - aprice;
+
+            function isSubset(sub, arr){
+                // if(!(sub instanceof Array) || !(arr instanceof Array)) return false;
+                // if(sub.length > arr.length) return false;
+                for(var i = 0, len = sub.length; i < len; i++){
+                    if(arr.indexOf(sub[i]) == -1) return false;
+                }
+                return true;
+            }
+
+            // 机上人工费:多一层
+            if (isSubset(base.gljTypes, [gljType.MACHINE_LABOUR])) {
+                for (let glj of me.treeNode.data.gljList) {
+                       if (glj.type == gljType.GENERAL_MACHINE) {
+                            // 获取机械组成物
+                           let mds = projectObj.project.composition.getCompositionByCode(glj.code);
+                           for (let md of mds){
+                               if (base.gljTypes.indexOf(md.glj_type) >= 0) {
+                                   price = md["base_price"];
+                                   if (!price) price = 0;
+                                   tmpSum = tmpSum + glj["quantity"] * md["consumption"] * price;
+                               }
+                           };
+                       }
+                };
+            }else{
+                for (let glj of me.treeNode.data.gljList) {
+                    if (base.gljTypes.indexOf(glj.type) >= 0) {
+                        if (base.calcType == baseCalc){ price = glj["basePrice"];}
+                        else if (base.calcType == adjustCalc){price = glj["adjustPrice"];}
+                        else if (base.calcType == budgetCalc){price = glj["marketPrice"];}
+                        else if (base.calcType == diffCalc){
+                            aprice = glj["adjustPrice"];
+                            if (!aprice) aprice = 0;
+                            mprice = glj["marketPrice"];
+                            if (!mprice) mprice = 0;
+                            price = mprice - aprice;
+                        };
+                        if (!price) price = 0;
+                        tmpSum = tmpSum + glj["quantity"] * price;
                     };
-                    if (!price) price = 0;
-                    tmpSum = tmpSum + glj["quantity"] * price;
                 };
             };
             rst = tmpSum;

+ 0 - 23
public/web/calculation/calc_util.js

@@ -1,23 +0,0 @@
-/**
- * Created by Tony on 2017/6/19.
- */
-
-class calculation {
-    init(calcTpl, calFee){
-        let me = this;
-        me.calcTpl = calcTpl;
-        me.calFee = calFee;
-        me.hasCompiled = false;
-    };
-
-    compile(){
-        let me = this;
-        me.hasCompiled = false;
-        if (me.calcTpl && me.calcTpl.calcItems && me.calcTpl.calcItems.length > 0) {
-            me.calcTpl.compiledSeq = [];
-        }
-    };
-    calculate(){
-        //
-    }
-}

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

+ 17 - 1
public/web/scMathUtil.js

@@ -49,6 +49,13 @@ let scMathUtil = {
         };
         return sign + result;
     },
+    zeroString: function(length){
+        let result = '';
+        for (let i = 0; i < length; i++){
+            result = result + '0';
+        };
+        return result;
+    },    
     incMantissa: function(bin){
         let result = bin;
         let iDot = bin.indexOf('.');
@@ -59,7 +66,7 @@ let scMathUtil = {
             if (num === 0){
                 num = 1;
                 let bin1 = bin.substring(0, i);
-                let bin2 = bin.substring(i + 1, iLength);
+                let bin2 = this.zeroString(iLength - (i + 1));//bin.substring(i + 1, iLength);
                 result = bin1 + num.toString() + bin2;
                 break;
             }
@@ -71,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 - 1
web/building_saas/glj/js/common_spread.js

@@ -194,7 +194,7 @@ CommonSpreadJs.prototype.filterData = function(field, filterList) {
     let fieldColumn = this.getFieldColumn(field);
     fieldColumn = parseInt(fieldColumn);
 
-    let filter = new GC.Spread.Sheets.Filter.HideRowFilter(new GC.Spread.Sheets.Range(-1, 5, -1, 1));
+    let filter = new GC.Spread.Sheets.Filter.HideRowFilter(new GC.Spread.Sheets.Range(-1, fieldColumn, -1, 1));
     this.sheet.rowFilter(filter);
 
     let rowFilter = this.sheet.rowFilter();

+ 3 - 0
web/building_saas/glj/js/composition.js

@@ -69,4 +69,7 @@ function compositionSuccess(info) {
     projectGLJSheet.setCellByField('unit_price.market_price', info.parentMarketPrice, false);
     projectGLJSheet.setCellByField('unit_price.base_price', info.parentBasePrice, false);
     projectGLJSheet.setCellByField('adjust_price', info.parentMarketPrice, false);
+
+    // 更新组成物缓存
+    projectObj.project.composition.loadData();
 }

+ 1 - 1
web/building_saas/glj/js/composition_spread.js

@@ -92,7 +92,7 @@ CompositionSpread.prototype.initRightClick = function(target) {
                     let row = self.rightClickTarget.row;
                     let idColumn = self.sheetObj.getFieldColumn('mix_ratio_id');
                     let deleteId = activeSheet.getValue(row, idColumn);
-                    self.deleteComposition(deleteId, row, mixRatioSuccess);
+                    self.deleteComposition(deleteId, row, self.successCallback);
                 }
             },
         }

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

+ 1 - 1
web/building_saas/main/html/calc_program_manage.html

@@ -9,7 +9,7 @@
 
 <body>
 <div style="">
-    <img id="f_btn" src="/web/dest/css/img/feeRate_btn.jpg" alt="" />
+    <img id="f_btn" src="/web/dest/css/img/feeRate_btn.jpg" alt="" style="display: none" />
 </div>
     <div class="toolsbar px-1">
     </div>

+ 5 - 4
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" onclick="">费率</a></li>
-                <li class="nav-item"><a data-toggle="tab" href="#calc_program_manage" id="tab_calc_program_manage" role="tab" onclick="">计算程序</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="#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" id="tab_baobiao" onclick="">报表</a></li>
             </ul>
         </div>
         <div class="content">
@@ -719,6 +719,7 @@
     <script type="text/javascript" src="/web/building_saas/main/js/models/ration.js"></script>
     <script type="text/javascript" src="/web/building_saas/main/js/models/glj.js"></script>
     <script type="text/javascript" src="/web/building_saas/main/js/models/project_glj.js"></script>
+    <script type="text/javascript" src="/web/building_saas/main/js/models/composition.js"></script>
     <script type="text/javascript" src="/web/building_saas/main/js/models/fee_rate.js"></script>
     <script type="text/javascript" src="/web/building_saas/main/js/models/ration_glj.js"></script>
     <script type="text/javascript" src="/web/building_saas/main/js/models/ration_coe.js"></script>

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

+ 77 - 0
web/building_saas/main/js/models/composition.js

@@ -0,0 +1,77 @@
+/**
+ * 组成物相关数据
+ *
+ * @author CaiAoLin
+ * @date 2017/10/27
+ * @version
+ */
+
+function Composition() {
+    this.datas = null;
+    this.isLoading = false;
+}
+/**
+ * 加载数据
+ *
+ * @param {function} callback
+ * @return {boolean}
+ */
+Composition.prototype.loadData = function (callback = null) {
+    let self = this;
+    if (self.isLoading) {
+        return false;
+    }
+    // 加载组成物数据
+    $.ajax({
+        url: '/glj/get-composition',
+        type: 'post',
+        dataType: 'json',
+        data: {project_id: scUrlUtil.GetQueryString('project')},
+        error: function() {
+            // alert('数据传输错误');
+        },
+        beforeSend: function() {
+            self.isLoading = true;
+        },
+        success: function(response) {
+            self.isLoading = false;
+            if (response.err === 1) {
+                let msg = response.msg !== undefined && response.msg !== '' ? response.msg : '读取组成物数据失败!';
+                alert(msg);
+                return false;
+            }
+            self.datas = response.data;
+            // 回调函数
+            if (callback !== null) {
+                callback(response.data);
+            }
+            // 存入缓存
+            projectObj.project.composition = self;
+        }
+    });
+};
+
+/**
+ * 获取对应code的组成物数据
+ *
+ * @param {String} code
+ * @param {Number} gljType
+ * @return {Array}
+ */
+Composition.prototype.getCompositionByCode = function(code, gljType = 0) {
+    let result = [];
+    if (code === '') {
+        return result;
+    }
+    if (gljType === 0) {
+        return this.datas[code];
+    }
+
+    for(let composition of this.datas[code]) {
+        if (composition.glj_type === gljType) {
+            result.push(composition);
+        }
+    }
+
+    return result;
+};

+ 80 - 31
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])
@@ -247,20 +273,44 @@ var FeeRate = {
                 }
             }
         };
-        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;
+
+        FeeRate.prototype.updateFeeRateFromCalc=function (value,editInfo) {
+            var value= number_util.checkNumberValue(value,feeRate_consts.decimal);
+            if(value){
+                if(editInfo.calcItem.feeRateID){
+                    var rate = projectObj.project.FeeRate.getFeeRateByID(editInfo.calcItem.feeRateID);
+                    if(rate!=undefined){
+                        this.updateFeeRateByCalc(rate,value);
+                        return;
+                    }
                 }
-            })
-            if(nodes.length>0){
-                projectObj.mainController.refreshTreeNode(nodes)
+                editInfo.calcItem.feeRate=value;
+                editInfo.calcItem.feeRateID=null;
+                var data={'projectID': projectObj.project.ID(),'templatesID': editInfo.template.ID,'calcItem': editInfo.calcItem};
+                rationPM.saveCalcItem(data,function (result) {
+                    project.calcProgram.compileAllTemps();
+                    rationPM.refreshDetailSheet();
+                })
+            }else {
+                rationPM.refreshDetailSheet();
             }
         };
+        FeeRate.prototype.updateFeeRateByCalc=function (rate,value) {
+            var me=this;
+            var data={
+                query:{
+                    'ID':this.getActivateFeeRateID(),
+                    'rates.ID':rate.ID
+                },
+                doc:{
+                    'rates.$.rate':value
+                }
+            }
+            CommonAjax.post('/feeRates/updateFeeRate', data, function (data) {
+                rate.rate=value;
+                me.onFeeRateChange(rate.ID,value);
+            });
+        }
 
         FeeRate.prototype.getfbUpdateData=function (rate,bill,value) {
             var data={};
@@ -324,6 +374,9 @@ var FeeRate = {
                 }
             this.setFeeRateToBill(data,callback);
         };
+
+       
+
         FeeRate.prototype.setFeeRateToBill=function(data,callback){
             CommonAjax.post('/feeRates/setFeeRateToBill', data, function (data) {
                 callback(data);
@@ -333,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);
                 }
             }
         };
@@ -372,10 +425,6 @@ var FeeRate = {
 
         };
 
-        FeeRate.prototype.getRate = function (fileID, rateID){
-            return 1.25;
-        };
-
         var feeRate = new FeeRate(project);
         return feeRate;
     },

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

+ 2 - 0
web/building_saas/main/js/models/project.js

@@ -80,6 +80,8 @@ var PROJECT = {
             this.VolumePrice = VolumePrice.createNew(this);
             this.projectGLJ = new ProjectGLJ();
             this.projectGLJ.loadData();
+            this.composition = new Composition();
+            this.composition.loadData();
             this.Decimal = {
                 common: {
                     quantity: 3,

+ 34 - 21
web/building_saas/main/js/views/calc_program_manage.js

@@ -25,7 +25,7 @@ let rationPM = {
             {headerName:"费用名称",headerWidth:200,dataCode:"name", dataType: "String"},
             {headerName:"计算基数",headerWidth:180,dataCode:"dispExpr", dataType: "String"},
             {headerName:"基数说明",headerWidth:300,dataCode:"statement", dataType: "String"},
-            {headerName:"费率",headerWidth:80,dataCode:"feeRate", dataType: "Number",hAlign: "left"},
+            {headerName:"费率",headerWidth:80,dataCode:"feeRate", dataType: "Number",hAlign: "left",tofix:feeRate_consts.decimal},
             {headerName:"字段名称",headerWidth:140,dataCode:"displayFieldName", dataType: "String", hAlign: "center"},
             {headerName:"备注",headerWidth:100,dataCode:"memo", dataType: "String"}
         ],
@@ -56,12 +56,12 @@ let rationPM = {
 
         me.mainSpread.getSheet(0).bind(GC.Spread.Sheets.Events.EnterCell, me.onMainEnterCell);
         me.detailSpread.getSheet(0).bind(GC.Spread.Sheets.Events.CellChanged, me.onDetailCellChanged);
-        //me.detailSpread.getSheet(0).bind(GC.Spread.Sheets.Events.CellClick, me.onCellClick);
+        me.detailSpread.getSheet(0).bind(GC.Spread.Sheets.Events.EditEnded, me.onEditEnded);
         let mSheet = me.mainSpread.getSheet(0);
         sheetCommonObj.showData(mSheet, me.mainSetting, me.datas);
 
         let dSheet = me.detailSpread.getSheet(0);
-        feeRateObject.setFeeRateCellCol(dSheet,4);
+        feeRateObject.setFeeRateCellCol(dSheet,_.findIndex(me.detailSetting.header,{'dataCode':'feeRate'}));
         dSheet.name('calc_detail');
         sheetCommonObj.showData(dSheet, me.detailSetting, me.datas[0].calcItems);
 
@@ -76,30 +76,25 @@ let rationPM = {
         sheetCommonObj.showData(dSheet, me.detailSetting, dData);
         me.detailSpread.resumePaint();
     },
-
-    saveCalcItem: function (projectID, templatesID, calcItem) {
+    onEditEnded: function(sender, args) {
+        var me = rationPM;
+        if(me.detailSetting.header[args.col].dataCode=='feeRate'){
+            var editInfo= me.getSelectionInfo();
+            projectObj.project.FeeRate.updateFeeRateFromCalc(args.editingText,editInfo);
+        }
+    },
+    saveCalcItem: function (data,callback) {//data
         let me = this;
-/*        let projectID = projectInfoObj.projectInfo.ID,
-            templatesID = me.datas,
-            calcItem = {
-                "ID" : 99,
-                "code" : "test",
-                "name" : "testName",
-                "fieldName" : "direct",
-                "dispExpr" : "F2+F5+F6+F10",
-                "expression" : "@('2') + @('5') + @('6') + @('10')",
-                "compiledExpr" : "",
-                "statement" : "基价人工费+基价材料费+基价机械费+未计价材料费"
-            };*/
-
         $.ajax({
-            type: 'post',
+            type: 'POST',
             url: '/calcProgram/saveCalcItem',
-            data: {projectID: projectID, templatesID: templatesID, calcItem: calcItem},
+            data: {'data':JSON.stringify(data)},
             dataType: 'json',
             success: function (result) {
                 if(!result.error){
-                    alert('成功:' + result.message);
+                    if(callback){
+                        callback(result);
+                    }
                 }
                 else{
                     alert('失败:' + result.message);
@@ -107,10 +102,28 @@ let rationPM = {
             }
         })
     },
+    getSelectionInfo:function () {
+        var templateIndex = this.mainSpread.getActiveSheet().getActiveRowIndex();
+        var dIndex = this.detailSpread.getActiveSheet().getActiveRowIndex();
+        var info = {
+            template:this.datas[templateIndex],
+            calcItem:this.datas[templateIndex].calcItems[dIndex]
+        }
+        return info;
+    },
+    refreshDetailSheet:function () {
+        var me=this;
+        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();
     });
 });

+ 162 - 138
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],
@@ -640,11 +644,25 @@ var feeRateObject={
             $("#fee_rate_tree").modal('hide');
         });
     },
+    submitFeeRateFromCalc:function () {
+        var rate = feeRateObject.feeRateSelection;
+        var calInfo = rationPM.getSelectionInfo();
+        calInfo.calcItem.feeRateID=rate.ID;
+        calInfo.calcItem.feeRate=null;
+        var data={'projectID': projectObj.project.ID(),'templatesID': calInfo.template.ID,'calcItem': calInfo.calcItem};
+        rationPM.saveCalcItem(data,function (result) {
+            calInfo.calcItem.feeRate=rate.rate;
+            projectObj.project.calcProgram.compileAllTemps();
+            rationPM.refreshDetailSheet();
+            $("#fee_rate_tree").modal('hide');
+        });
+        console.log(calInfo);
+    },
     submitFeeRateBySelect:function () {
         var validate = this.checkSelectedFeeRate();
         if(validate){
             if($('#edit_from').val()=='calc_detail'){
-                //do calc_detail
+                this.submitFeeRateFromCalc();
             }else {
                 this.submitFeeRateFromBill();
             }
@@ -667,165 +685,171 @@ function getPopoverContent() {
     return popover_content;
 }
 
-$('#pop-lv').popover({
-        placement:"bottom",
-        html:true,
-        trigger:"hover | focus",
-        content:getPopoverContent
-    }
-);
-
-$('#tab_fee_rate').on('shown.bs.tab', function (e) {
-    feeRateObject.reFreshRateViews();
-    feeRateObject.loadPageContent();
-});
+$(function(){
+    $('#pop-lv').popover({
+            placement:"bottom",
+            html:true,
+            trigger:"hover | focus",
+            content:getPopoverContent
+        }
+    );
 
-$('#setNewFeeRate').bind('click', function () {
-    var feeRateFile = projectObj.project.FeeRate.getActivateFeeRate();
-    var usageProjects = feeRateFile.usageProjects;
-    var listString ='';
-    _.forEach(usageProjects,function (u) {
-        listString+="<li>"+u.name+"</li>"
-    })
-    $("#usageProjectList").html(listString);
-    $("#set-lv-feeRateName").text(feeRateFile.name);
-    $("#set-use-feeRateName").text(feeRateFile.name);
+    $('#tab_fee_rate').on('shown.bs.tab', function (e) {
+        $(e.relatedTarget.hash).removeClass('active');
+        feeRateObject.reFreshRateViews();
+        feeRateObject.loadPageContent();
+    });
 
-    feeRateObject.getFeeRateStandards(function (data) {
-        $('#standardSelect').empty();
-        _.forEach(data,function (s) {
-            var option =  $("<option>").val(s.ID).text(s.libName);
-            $('#standardSelect').append(option);
+    $('#setNewFeeRate').bind('click', function () {
+        var feeRateFile = projectObj.project.FeeRate.getActivateFeeRate();
+        var usageProjects = feeRateFile.usageProjects;
+        var listString ='';
+        _.forEach(usageProjects,function (u) {
+            listString+="<li>"+u.name+"</li>"
         })
-        $('#standardSelect').val(feeRateFile.libID);
+        $("#usageProjectList").html(listString);
+        $("#set-lv-feeRateName").text(feeRateFile.name);
+        $("#set-use-feeRateName").text(feeRateFile.name);
+
+        feeRateObject.getFeeRateStandards(function (data) {
+            $('#standardSelect').empty();
+            _.forEach(data,function (s) {
+                var option =  $("<option>").val(s.ID).text(s.libName);
+                $('#standardSelect').append(option);
+            })
+            $('#standardSelect').val(feeRateFile.libID);
+        });
+    });
+    $('#changeConfirm').bind('click', function (){
+        var newVal=$('#standardSelect').val();
+        var feeRateFile = projectObj.project.FeeRate.getActivateFeeRate();
+        if(newVal&&newVal!=feeRateFile.libID){
+            feeRateObject.changeFeeRateStandard(newVal);
+        }
     });
-});
-$('#changeConfirm').bind('click', function (){
-    var newVal=$('#standardSelect').val();
-    var feeRateFile = projectObj.project.FeeRate.getActivateFeeRate();
-    if(newVal&&newVal!=feeRateFile.libID){
-        feeRateObject.changeFeeRateStandard(newVal);
-    }
-});
 
-$('#saveAs').bind('click', function (){
-    var feeRateFile = projectObj.project.FeeRate.getActivateFeeRate();
-    $('#copyFeeRateName').val(feeRateFile.name+'副本');
-    $('#valid_name').val(feeRateFile.name+'副本');
-    $('#nameError').hide();
-});
+    $('#saveAs').bind('click', function (){
+        var feeRateFile = projectObj.project.FeeRate.getActivateFeeRate();
+        $('#copyFeeRateName').val(feeRateFile.name+'副本');
+        $('#valid_name').val(feeRateFile.name+'副本');
+        $('#nameError').hide();
+    });
 
-$('#saveAsConfirm').bind('click',function () {
-    feeRateObject.feeRateFileSaveAs($('#copyFeeRateName').val());
-})
+    $('#saveAsConfirm').bind('click',function () {
+        feeRateObject.feeRateFileSaveAs($('#copyFeeRateName').val());
+    })
 
 
-$('#copyFeeRateName').change(function () {
-    feeRateObject.checkFeeRateName(this.value);
-});
+    $('#copyFeeRateName').change(function () {
+        feeRateObject.checkFeeRateName(this.value);
+    });
 
-$('#newFeeRateName').change(function () {
-    var newName = $(this).val();
-    if(!newName||newName==""){
-        $('#renameConfirm').attr("disabled","disabled");
-        $('#renameError').text("请输入文件名称。").show();
-        return;
-    }
-    var callback=function (data) {
-        if(data){
+    $('#newFeeRateName').change(function () {
+        var newName = $(this).val();
+        if(!newName||newName==""){
             $('#renameConfirm').attr("disabled","disabled");
-            $('#renameError').text("本建设项目中已存在同名费率文件。").show();
-        }else {
-            $('#renameConfirm').removeAttr("disabled");
-            $('#renameError').hide();
+            $('#renameError').text("请输入文件名称。").show();
+            return;
         }
-    };
-    projectObj.project.FeeRate.checkFeeRateName(newName,callback);
-});
+        var callback=function (data) {
+            if(data){
+                $('#renameConfirm').attr("disabled","disabled");
+                $('#renameError').text("本建设项目中已存在同名费率文件。").show();
+            }else {
+                $('#renameConfirm').removeAttr("disabled");
+                $('#renameError').hide();
+            }
+        };
+        projectObj.project.FeeRate.checkFeeRateName(newName,callback);
+    });
 
 
-function changeFRadioClick() {
-    var radioV= $("input[name='chaneg-lv-Radio']:checked").val();
-    if(radioV==='0'){
+    function changeFRadioClick() {
+        var radioV= $("input[name='chaneg-lv-Radio']:checked").val();
+        if(radioV==='0'){
+            $("#fromProject").show();
+            $("#fromOther").hide();
+        }else {
+            $("#fromProject").hide();
+            $("#fromOther").show();
+        }
+    }
+    $('#changeFeeRateConfirm').bind('click',function (){
+        var radioV= $("input[name='chaneg-lv-Radio']:checked").val();
+        if(radioV==='0'){
+            feeRateObject.changeFeeRateFileFromCurrent();
+        }else {
+            feeRateObject.changeFeeRateFileFromOthers();
+        }
+    })
+
+    $('#changFeeRateFile').bind('click',function (){
+        $("input[name='chaneg-lv-Radio']")[0].checked=true;
         $("#fromProject").show();
         $("#fromOther").hide();
-    }else {
-        $("#fromProject").hide();
-        $("#fromOther").show();
-    }
-}
-$('#changeFeeRateConfirm').bind('click',function (){
-    var radioV= $("input[name='chaneg-lv-Radio']:checked").val();
-    if(radioV==='0'){
-        feeRateObject.changeFeeRateFileFromCurrent();
-    }else {
-        feeRateObject.changeFeeRateFileFromOthers();
-    }
-})
+        feeRateObject.getChangeInfo();
+    })
 
-$('#changFeeRateFile').bind('click',function (){
-    $("input[name='chaneg-lv-Radio']")[0].checked=true;
-    $("#fromProject").show();
-    $("#fromOther").hide();
-    feeRateObject.getChangeInfo();
-})
+    $('#otherProject').change(function(){
+        var newVal = $(this).val();
+        var projects = feeRateObject.changeInfo.others;
+        var selected = _.find(projects,{ID:parseInt(newVal)});
+        $('#otherFeeRateOption').empty();
+        _.forEach(selected.optionList,function (f) {
+            var option =  $("<option>").val(f.ID).text(f.name);
+            $('#otherFeeRateOption').append(option);
+        });
+    })
 
-$('#otherProject').change(function(){
-    var newVal = $(this).val();
-    var projects = feeRateObject.changeInfo.others;
-    var selected = _.find(projects,{ID:parseInt(newVal)});
-    $('#otherFeeRateOption').empty();
-    _.forEach(selected.optionList,function (f) {
-        var option =  $("<option>").val(f.ID).text(f.name);
-        $('#otherFeeRateOption').append(option);
-    });
-})
+    $('#renameConfirm').bind('click',function (){
+        var feeRateFileID= $("#newFeeRateID").val();
+        var name = $("#newFeeRateName").val();
+        feeRateObject.changeFeeRateFileConfirm(feeRateFileID,name);
+    })
 
-$('#renameConfirm').bind('click',function (){
-    var feeRateFileID= $("#newFeeRateID").val();
-    var name = $("#newFeeRateName").val();
-    feeRateObject.changeFeeRateFileConfirm(feeRateFileID,name);
-})
 
+    $('#inlineFormCustomSelect').change(function(){
+        var updateTask = [];
+        var selectID = $(this).val();
+        var oldValue=0;
+        _.forEach(projectObj.project.FeeRate.datas,function (feeRate) {
+            if(feeRate.status=='activate'){
+                oldValue=feeRate.ID;
+            }
+            if(feeRate.ID ==selectID){
+                feeRate.status='activate';
+            }else {
+                feeRate.status='disable';
+            }
+            updateTask.push({query:{ID:feeRate.feeRateID},doc:{status:feeRate.status}});
+        })
+        projectObj.project.FeeRate.updateStatusBySelected(updateTask);
+        feeRateObject.createSpreadView();
+        subRateObject.destorySpreadView();
+        socket.emit('changeActivateFeeRate',{oldRoom:oldValue,newRoom:selectID});
+    })
 
-$('#inlineFormCustomSelect').change(function(){
-    var updateTask = [];
-    var selectID = $(this).val();
-    var oldValue=0;
-    _.forEach(projectObj.project.FeeRate.datas,function (feeRate) {
-        if(feeRate.status=='activate'){
-            oldValue=feeRate.ID;
-        }
-        if(feeRate.ID ==selectID){
-            feeRate.status='activate';
-        }else {
-            feeRate.status='disable';
+    $('#fee_rate_tree').on('shown.bs.modal', function (e) {
+        if(feeRateObject.feeRateSpreads==null){
+            feeRateObject.createSheet();
         }
-        updateTask.push({query:{ID:feeRate.feeRateID},doc:{status:feeRate.status}});
-    })
-    projectObj.project.FeeRate.updateStatusBySelected(updateTask);
-    feeRateObject.createSpreadView();
-    subRateObject.destorySpreadView();
-    socket.emit('changeActivateFeeRate',{oldRoom:oldValue,newRoom:selectID});
-})
+        feeRateObject.feeRateSelection=null;
+        feeRateObject.showSelectTree();
+    });
 
-$('#fee_rate_tree').on('shown.bs.modal', function (e) {
-    if(feeRateObject.feeRateSpreads==null){
-        feeRateObject.createSheet();
-    }
-    feeRateObject.feeRateSelection=null;
-    feeRateObject.showSelectTree();
-});
+    $('#fee_rate_tree').on('hidden.bs.modal', function (e) {
+        if(feeRateObject.feeRateSpreads){
+            feeRateObject.feeRateSpreads.destroy();
+            feeRateObject.feeRateSpreads=null;
+            $('#edit_from').val('');
+            $('#edit_row').val('');
+        }
+    });
 
-$('#fee_rate_tree').on('hidden.bs.modal', function (e) {
-    if(feeRateObject.feeRateSpreads){
-        feeRateObject.feeRateSpreads.destroy();
-        feeRateObject.feeRateSpreads=null;
-        $('#edit_from').val('');
-        $('#edit_row').val('');
-    }
-});
+    $('#fee_selected_conf').bind('click',function (){
+        feeRateObject.submitFeeRateBySelect();
+    })
 
-$('#fee_selected_conf').bind('click',function (){
-    feeRateObject.submitFeeRateBySelect();
 })
+
+

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

@@ -301,7 +301,7 @@ var gljOprObj = {
         if(args.row>=me.sheetData.length){
             return;
         }
-        if(me.setting.header[args.col].dataCode=='marketPriceAdjust'){//市场单价调整
+        if(me.setting.header[args.col]&&me.setting.header[args.col].dataCode=='marketPriceAdjust'){//市场单价调整
             var type = me.sheetData[args.row].shortName;
             var index= _.indexOf(me.setting.notEditedType,type);
             if(index!=-1){

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

@@ -6,6 +6,7 @@ let labourCoeView = {
     datas: [],
     spread: null,
     sheet: null,
+    needUpdateDatas: [],
 
     init(){
         let me = this;
@@ -17,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;
         };
@@ -47,13 +48,41 @@ let labourCoeView = {
         sheet.setRowCount(1, sheetArea.colHeader);
         sheet.setRowCount(20, sheetArea.viewport);
         sheet.setRowHeight(0, 30, sheetArea.colHeader);
-
+        sheet.bind(GC.Spread.Sheets.Events.CellChanged, me.onCellChanged);
         sheet.resumeEvent();
         sheet.resumePaint();
     },
 
+    onCellChanged: function(sender, args){
+        var me = labourCoeView;
+        if (args.propertyName !== "value"){return;};
+        let cell = me.sheet.getCell(args.row, args.col);
+        me.addNeedUpdateData({ID: cell.tag(), value: cell.value()});
+    },
+
+    addNeedUpdateData: function (data) {
+        let me = this;
+        let isExist = false;
+        for (let el of me.needUpdateDatas){
+             if (el.ID == data.ID){
+                 isExist = true;
+                 el.value = data.value;
+                 return;
+             };
+        };
+        if (!isExist){
+            me.needUpdateDatas.push(data);
+        }
+    },
+
+    needSave: function (){
+        let me = this;
+        return me.needUpdateDatas.length > 0;
+    },
+
     loadData(datas){          // 树结构转换二维表显示,行列转换
         let me = this;
+        me.spread.suspendEvent();
         me.datas = datas;
         let libArr = [];
         for (let v of me.datas) {if (!v.ParentID) libArr.push(v);};
@@ -83,12 +112,15 @@ let labourCoeView = {
                 let rowName = me.sheet.getText(r, 0);
                 for (let v of me.datas) {
                     if ((v.ParentID == libID) && (v.name == rowName)) {
-                        me.sheet.setValue(r, c + 1, v.coe);
+                        let cell = me.sheet.getCell(r, c+ 1);
+                        cell.value(v.coe);
+                        cell.tag(v.ID);
                         break;
                     };
                 };
             };
         };
+        me.spread.resumeEvent();
     },
 
     showData(){
@@ -97,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();
+            });
+        }
     }
 };
 
@@ -113,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',

+ 1 - 0
web/common/html/header.html

@@ -61,4 +61,5 @@
 <script src="/lib/jquery/jquery-3.2.1.min.js"></script>
 <script type="text/javascript" src="/web/building_saas/js/moment.min.js"></script>
 <script type="text/javascript" src="/web/building_saas/js/message.js"></script>
+<script type="text/javascript" src="/public/web/scMathUtil.js"></script>
 <!-- endinject -->

+ 1 - 0
web/users/html/login.html

@@ -69,6 +69,7 @@
     </div>
     <!-- JS. -->
     <!-- inject:js -->
+    <script type="text/javascript" src="/public/web/scMathUtil.js"></script>
     <script src="/lib/jquery/jquery-3.2.1.min.js"></script>
     <script src="/public/web/url_util.js"></script>
     <script src="/lib/popper/popper.min.js"></script>