Browse Source

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

TonyKang 7 years ago
parent
commit
b1c2d22746
55 changed files with 1756 additions and 507 deletions
  1. 4 0
      config/gulpConfig.js
  2. 6 5
      lib/bootstrap/bootstrap.min.js
  3. 2 2
      lib/bootstrap/css/bootstrap.min.css
  4. 71 49
      modules/glj/controllers/glj_controller.js
  5. 5 1
      modules/main/facade/calc_program_facade.js
  6. 8 1
      modules/main/models/bills.js
  7. 4 3
      modules/main/models/proj_setting_model.js
  8. 3 0
      modules/main/models/project.js
  9. 9 9
      modules/main/models/schemas/proj_setting.js
  10. 6 1
      modules/pm/models/project_model.js
  11. 5 1
      modules/pm/models/project_property_template.js
  12. 4 4
      modules/ration_glj/facade/ration_glj_facade.js
  13. 8 1
      modules/users/controllers/login_controller.js
  14. 1 0
      modules/users/models/user_model.js
  15. 0 12
      public/calc_util.js
  16. 0 20
      public/common_util.js
  17. 0 28
      public/debug.js
  18. 2 2
      public/web/PerfectLoad.js
  19. 20 0
      public/web/common_util.js
  20. 6 1
      public/web/sheet/sheet_common.js
  21. 4 5
      server.js
  22. 2 2
      test/tmp_data/bills_grid_setting.js
  23. 50 47
      web/building_saas/css/main.css
  24. 4 1
      web/building_saas/glj/html/glj_index.html
  25. 8 0
      web/building_saas/glj/js/project_glj.js
  26. 3 3
      web/building_saas/glj/js/project_glj_spread.js
  27. 46 13
      web/building_saas/js/global.js
  28. 78 57
      web/building_saas/main/html/main.html
  29. 2 2
      web/building_saas/main/js/calc/bills_calc.js
  30. 1 1
      web/building_saas/main/js/controllers/project_controller.js
  31. 105 1
      web/building_saas/main/js/main.js
  32. 2 15
      web/building_saas/main/js/models/bills.js
  33. 455 0
      web/building_saas/main/js/models/calc_base.js
  34. 121 55
      web/building_saas/main/js/models/calc_program.js
  35. 36 21
      web/building_saas/main/js/models/fee_rate.js
  36. 8 7
      web/building_saas/main/js/models/main_consts.js
  37. 12 13
      web/building_saas/main/js/models/project.js
  38. 6 0
      web/building_saas/main/js/models/project_glj.js
  39. 330 0
      web/building_saas/main/js/views/calc_base_view.js
  40. 1 1
      web/building_saas/main/js/views/calc_program_manage.js
  41. 15 10
      web/building_saas/main/js/views/fee_rate_view.js
  42. 51 16
      web/building_saas/main/js/views/glj_view.js
  43. 76 21
      web/building_saas/main/js/views/main_tree_col.js
  44. 4 2
      web/building_saas/main/js/views/project_info.js
  45. 2 8
      web/building_saas/main/js/views/project_property_basicInfo.js
  46. 2 2
      web/building_saas/main/js/views/project_property_bills_quantity_decimal.js
  47. 14 4
      web/building_saas/main/js/views/project_property_decimal_view.js
  48. 20 0
      web/building_saas/main/js/views/project_property_display_view.js
  49. 2 1
      web/building_saas/main/js/views/project_property_labour_coe_view.js
  50. 2 2
      web/building_saas/main/js/views/project_property_projFeature.js
  51. 116 45
      web/building_saas/main/js/views/project_view.js
  52. 1 1
      web/building_saas/pm/html/project-management.html
  53. 8 8
      web/common/html/header.html
  54. 1 1
      web/users/html/login.html
  55. 4 2
      web/users/js/login.js

+ 4 - 0
config/gulpConfig.js

@@ -45,6 +45,7 @@ module.exports = {
         'lib/lodash/lodash.js',
         'lib/lodash/lodash.js',
         // 'test/tmp_data/test_ration_calc/ration_calc_base.js',
         // 'test/tmp_data/test_ration_calc/ration_calc_base.js',
         'web/building_saas/main/js/models/main_consts.js',
         'web/building_saas/main/js/models/main_consts.js',
+        'public/web/common_util.js',
         'web/building_saas/glj/js/project_glj.js',
         'web/building_saas/glj/js/project_glj.js',
         'web/building_saas/glj/js/composition.js',
         'web/building_saas/glj/js/composition.js',
         'web/building_saas/glj/js/common_spread.js',
         'web/building_saas/glj/js/common_spread.js',
@@ -55,6 +56,7 @@ module.exports = {
         'public/web/uuid.js',
         'public/web/uuid.js',
         'public/web/sheet/sheet_common.js',
         'public/web/sheet/sheet_common.js',
         'web/building_saas/main/js/models/calc_program.js',
         'web/building_saas/main/js/models/calc_program.js',
+        'web/building_saas/main/js/models/calc_base.js',
         'web/building_saas/main/js/views/calc_program_manage.js',
         'web/building_saas/main/js/views/calc_program_manage.js',
         'public/web/common_ajax.js',
         'public/web/common_ajax.js',
         'public/web/url_util.js',
         'public/web/url_util.js',
@@ -94,6 +96,7 @@ module.exports = {
         'web/building_saas/main/js/views/project_property_decimal_view.js',
         'web/building_saas/main/js/views/project_property_decimal_view.js',
         'web/building_saas/main/js/views/project_property_basicInfo.js',
         'web/building_saas/main/js/views/project_property_basicInfo.js',
         'web/building_saas/main/js/views/project_property_projFeature.js',
         'web/building_saas/main/js/views/project_property_projFeature.js',
+        'web/building_saas/main/js/views/project_property_display_view.js',
         'web/building_saas/main/js/main_ajax.js',
         'web/building_saas/main/js/main_ajax.js',
         'web/building_saas/main/js/main.js',
         'web/building_saas/main/js/main.js',
         'web/building_saas/main/js/controllers/project_controller.js',
         'web/building_saas/main/js/controllers/project_controller.js',
@@ -116,6 +119,7 @@ module.exports = {
         'web/building_saas/main/js/views/sub_view.js',
         'web/building_saas/main/js/views/sub_view.js',
         'web/building_saas/main/js/views/fee_rate_view.js',
         'web/building_saas/main/js/views/fee_rate_view.js',
         'web/building_saas/main/js/views/sub_fee_rate_views.js',
         'web/building_saas/main/js/views/sub_fee_rate_views.js',
+        'web/building_saas/main/js/views/calc_base_view.js',
         'web/building_saas/main/js/views/project_property_labour_coe_view.js'
         'web/building_saas/main/js/views/project_property_labour_coe_view.js'
     ]
     ]
 }
 }

File diff suppressed because it is too large
+ 6 - 5
lib/bootstrap/bootstrap.min.js


File diff suppressed because it is too large
+ 2 - 2
lib/bootstrap/css/bootstrap.min.css


+ 71 - 49
modules/glj/controllers/glj_controller.js

@@ -12,6 +12,7 @@ import UnitPriceModel from "../models/unit_price_model";
 import MixRatioModel from "../models/mix_ratio_model";
 import MixRatioModel from "../models/mix_ratio_model";
 import UnitPriceFileModel from "../models/unit_price_file_model";
 import UnitPriceFileModel from "../models/unit_price_file_model";
 let logger = require("../../../logs/log_helper").logger;
 let logger = require("../../../logs/log_helper").logger;
+let consts = require('../../main/models/project_consts');
 
 
 const ProjectModel = require('../../pm/models/project_model').project;
 const ProjectModel = require('../../pm/models/project_model').project;
 class GLJController extends BaseController {
 class GLJController extends BaseController {
@@ -37,59 +38,23 @@ class GLJController extends BaseController {
         // 标段id
         // 标段id
         let projectId = request.body.project_id;
         let projectId = request.body.project_id;
         projectId = parseInt(projectId);
         projectId = parseInt(projectId);
-        let responseData = {
-            err: 0,
-            msg: '',
-            data: {}
-        };
-        try {
-            if (isNaN(projectId) || projectId <= 0) {
-                throw '标段id有误';
-            }
-
-            // 获取标段对应的单价文件id
-            let unitPriceFileId = await ProjectModel.getUnitPriceFileId(projectId);
-            if (unitPriceFileId <= 0) {
-                throw '没有对应的单价文件';
-            }
-
-            // 获取使用该单价文件的项目数据
-            let tenderData = await ProjectModel.getTenderByUnitPriceFileId(unitPriceFileId);
-            let usedTenderList = [];
-            let usedUnitPriceInfo = {};
-            if (tenderData !== null) {
-                for (let tmp of tenderData) {
-                    usedTenderList.push(tmp.name);
-                    usedUnitPriceInfo.name = tmp.property.unitPriceFile.name;
-                    usedUnitPriceInfo.id = tmp.property.unitPriceFile.id;
-                }
-            }
-
-            // 先获取对应标段的项目工料机数据
-            let gljListModel = new GLJListModel();
-            let [gljList, mixRatioConnectData,mixRationMap] = await gljListModel.getListByProjectId(projectId, unitPriceFileId);
-
-            responseData.data.gljList = gljList;
-            responseData.data.mixRatioConnectData = mixRatioConnectData;
-            responseData.data.mixRatioMap = mixRationMap;
-            responseData.data.usedTenderList = usedTenderList;
-            responseData.data.constData = {
-                materialIdList: gljListModel.materialIdList,
-                ownCompositionTypes: gljListModel.ownCompositionTypes,
-                hostname: request.hostname,
-                roomId: unitPriceFileId,
-                GLJTypeConst: JSON.stringify(GLJTypeConst),
-                usedUnitPriceInfo: usedUnitPriceInfo
-            };
-        } catch (error) {
-            responseData.err = 1;
-            responseData.msg = error;
-        }
-
+        let responseData = await getGLJListByProjectID(projectId);
+        responseData.hostname = request.hostname;
         response.json(responseData);
         response.json(responseData);
     }
     }
 
 
     /**
     /**
+     * project getData 接口
+     * @param projectID
+     * @param callback
+     */
+    getData(projectID, callback){
+        getGLJListByProjectID(projectID).then(function(result){
+            callback(result.err,consts.projectConst.PROJECTGLJ,result.data);
+        })
+    }
+
+    /**
      * 更新数据
      * 更新数据
      *
      *
      * @param {object} request
      * @param {object} request
@@ -588,4 +553,61 @@ class GLJController extends BaseController {
 
 
 }
 }
 
 
+/**
+ * 取项目工料机列表
+ * @param projectId
+ * @returns {Promise.<void>}
+ */
+async function getGLJListByProjectID(projectId){
+    let responseData = {
+        err: 0,
+        msg: '',
+        data: {}
+    };
+    try {
+        if (isNaN(projectId) || projectId <= 0) {
+            throw '标段id有误';
+        }
+
+        // 获取标段对应的单价文件id
+        let unitPriceFileId = await ProjectModel.getUnitPriceFileId(projectId);
+        if (unitPriceFileId <= 0) {
+            throw '没有对应的单价文件';
+        }
+
+        // 获取使用该单价文件的项目数据
+        let tenderData = await ProjectModel.getTenderByUnitPriceFileId(unitPriceFileId);
+        let usedTenderList = [];
+        let usedUnitPriceInfo = {};
+        if (tenderData !== null) {
+            for (let tmp of tenderData) {
+                usedTenderList.push(tmp.name);
+                usedUnitPriceInfo.name = tmp.property.unitPriceFile.name;
+                usedUnitPriceInfo.id = tmp.property.unitPriceFile.id;
+            }
+        }
+
+        // 先获取对应标段的项目工料机数据
+        let gljListModel = new GLJListModel();
+        let [gljList, mixRatioConnectData,mixRationMap] = await gljListModel.getListByProjectId(projectId, unitPriceFileId);
+
+        responseData.data.gljList = gljList;
+        responseData.data.mixRatioConnectData = mixRatioConnectData;
+        responseData.data.mixRatioMap = mixRationMap;
+        responseData.data.usedTenderList = usedTenderList;
+        responseData.data.constData = {
+            materialIdList: gljListModel.materialIdList,
+            ownCompositionTypes: gljListModel.ownCompositionTypes,
+            roomId: unitPriceFileId,
+            GLJTypeConst: JSON.stringify(GLJTypeConst),
+            usedUnitPriceInfo: usedUnitPriceInfo
+        };
+    } catch (error) {
+        console.log(error);
+        responseData.err = 1;
+        responseData.msg = error;
+    }
+    return responseData;
+}
+
 export default GLJController;
 export default GLJController;

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

@@ -85,7 +85,11 @@ function getData(projectID, callback) {
 
 
 // 统一的 save() 方法供project调用
 // 统一的 save() 方法供project调用
 function save (user_id, datas, callback) {
 function save (user_id, datas, callback) {
-    projectCalcProgramsModel.update({"projectID": 553}, {"libName":"goo—test"}, callback(null, {data: 'test'}));
+    let returnData ={
+        moduleName:'calc_program',
+        data:{}
+    };
+    projectCalcProgramsModel.update({"projectID": 553}, {"libName":"goo—test"}, callback(null, returnData));
 }
 }
 
 
 function saveCalcItem(dataObj, callback) {
 function saveCalcItem(dataObj, callback) {

+ 8 - 1
modules/main/models/bills.js

@@ -31,6 +31,7 @@ let billsSchema = new Schema({
     isFromDetail:{type: Number,default:0},//1 true 0 false
     isFromDetail:{type: Number,default:0},//1 true 0 false
     programID: Number,
     programID: Number,
     calcBase: String,
     calcBase: String,
+    calcBaseValue: String,     // 计算基数表达式的值
     // 工程量计算规则
     // 工程量计算规则
     ruleText: String,
     ruleText: String,
     // 说明
     // 说明
@@ -105,7 +106,13 @@ class billsModel extends baseModel {
             functions.push(saveOne(data));
             functions.push(saveOne(data));
             quantity_detial.quantityEditChecking(data,'bills',functions);
             quantity_detial.quantityEditChecking(data,'bills',functions);
         }
         }
-        async.parallel(functions, callback);
+        async.parallel(functions, function(err,result){
+            let returnData = {
+                moduleName:'bills',
+                data:{}
+            };
+            callback(err, returnData);
+        });
     };
     };
 
 
     getItemTemplate (callback) {
     getItemTemplate (callback) {

+ 4 - 3
modules/main/models/proj_setting_model.js

@@ -3,7 +3,8 @@
  */
  */
 
 
 let baseModel = require('./base_model');
 let baseModel = require('./base_model');
-import {default as projSettingSchema, collectionName as collectionName, settingConst as settingConst} from "./schemas/proj_setting";
+// import {default as projSettingSchema, collectionName as collectionName, settingConst as settingConst} from "./schemas/proj_setting";
+import {default as projSettingSchema, collectionName as collectionName} from "./schemas/proj_setting";
 
 
 class projSettingModel extends baseModel {
 class projSettingModel extends baseModel {
 
 
@@ -16,13 +17,13 @@ class projSettingModel extends baseModel {
         this.model.findOne({"projectID": projectID}, '-_id', function (err, result) {
         this.model.findOne({"projectID": projectID}, '-_id', function (err, result) {
             if (!err) {
             if (!err) {
                 let data = JSON.parse(JSON.stringify(result));
                 let data = JSON.parse(JSON.stringify(result));
-                if (!data.billsCalcMode) {
+/*                if (!data.billsCalcMode) {
                     data.billsCalcMode = settingConst.billsCalcMode.rationContent;
                     data.billsCalcMode = settingConst.billsCalcMode.rationContent;
                 }
                 }
                 if (!data.zanguCalcMode) {
                 if (!data.zanguCalcMode) {
                     data.zanguCalcMode = settingConst.zanguCalcMode.common;
                     data.zanguCalcMode = settingConst.zanguCalcMode.common;
                 }
                 }
-                data.settingConst = settingConst;
+                data.settingConst = settingConst;*/
                 callback(0, collectionName, data);
                 callback(0, collectionName, data);
             } else {
             } else {
                 callback(1, '查询数据失败。', null);
                 callback(1, '查询数据失败。', null);

+ 3 - 0
modules/main/models/project.js

@@ -14,6 +14,8 @@ let projSetting = require('./proj_setting_model');
 // let volumePriceData = require('../../volume_price/models/volume_price_model');
 // let volumePriceData = require('../../volume_price/models/volume_price_model');
 var labour_coe_facade = require('../facade/labour_coe_facade');
 var labour_coe_facade = require('../facade/labour_coe_facade');
 var calc_program_facade = require('../facade/calc_program_facade');
 var calc_program_facade = require('../facade/calc_program_facade');
+import GLJController from "../../glj/controllers/glj_controller";
+
 
 
 const ProjectModel = require('../../pm/models/project_model').project;
 const ProjectModel = require('../../pm/models/project_model').project;
 import GLJListModel from "../../glj/models/glj_list_model";
 import GLJListModel from "../../glj/models/glj_list_model";
@@ -37,6 +39,7 @@ moduleMap[projSetting.collectionName] = projSetting;
 moduleMap[projectConsts.FEERATE] = fee_rate_data;
 moduleMap[projectConsts.FEERATE] = fee_rate_data;
 moduleMap[projectConsts.LABOUR_COE] = labour_coe_facade;
 moduleMap[projectConsts.LABOUR_COE] = labour_coe_facade;
 moduleMap[projectConsts.CALC_PROGRAM] = calc_program_facade;
 moduleMap[projectConsts.CALC_PROGRAM] = calc_program_facade;
+moduleMap[projectConsts.PROJECTGLJ] = new GLJController();
 
 
 var Project = function (){};
 var Project = function (){};
 
 

+ 9 - 9
modules/main/models/schemas/proj_setting.js

@@ -5,33 +5,33 @@
 let mongoose = require("mongoose");
 let mongoose = require("mongoose");
 let Schema = mongoose.Schema;
 let Schema = mongoose.Schema;
 let collectionName = 'proj_setting';
 let collectionName = 'proj_setting';
-let settingConst = {
+/*let settingConst = {
     billsCalcMode: {
     billsCalcMode: {
-        rationContent: 0, rationPrice: 1, rationPriceConverse: 2, billsPrice: 3
+        rationContent: 0, rationPriceConverse: 1, rationPrice: 2, billsPrice: 3
     },
     },
     zanguCalcMode: {
     zanguCalcMode: {
         common: 0, gatherMaterial: 1
         common: 0, gatherMaterial: 1
     }
     }
-}
-let billsCalcModeConst = {
+}*/
+/*let billsCalcModeConst = {
     
     
-};
+};*/
 let projSettingSchema = {
 let projSettingSchema = {
     projectID: Number,
     projectID: Number,
     // 列设置
     // 列设置
     main_tree_col: {
     main_tree_col: {
         type: Schema.Types.Mixed,
         type: Schema.Types.Mixed,
         default: {}
         default: {}
-    },
+    }/*,
     billsCalcMode: {
     billsCalcMode: {
         type: Number,
         type: Number,
         default: settingConst.billsCalcMode.rationContent
         default: settingConst.billsCalcMode.rationContent
-        // rationContent = 0, rationPrice = 1, rationPriceConverse = 2, billsPrice = 3
     },
     },
     zanguCalcMode: {
     zanguCalcMode: {
         type: Number,
         type: Number,
         default: settingConst.zanguCalcMode.common
         default: settingConst.zanguCalcMode.common
-    }
+    }*/
 };
 };
 let model = mongoose.model(collectionName, new Schema(projSettingSchema, {versionKey: false, collection: collectionName}));
 let model = mongoose.model(collectionName, new Schema(projSettingSchema, {versionKey: false, collection: collectionName}));
-export {model as default, collectionName as collectionName, settingConst as settingConst};
+// export {model as default, collectionName as collectionName, settingConst as settingConst};
+export {model as default, collectionName as collectionName};

+ 6 - 1
modules/pm/models/project_model.js

@@ -5,7 +5,7 @@ import mongoose from 'mongoose';
 import async_c from 'async';
 import async_c from 'async';
 import UnitPriceFileModel from "../../glj/models/unit_price_file_model";
 import UnitPriceFileModel from "../../glj/models/unit_price_file_model";
 import UnitPriceFiles from '../../glj/models/schemas/unit_price_file';
 import UnitPriceFiles from '../../glj/models/schemas/unit_price_file';
-import {defaultDecimal, billsQuantityDecimal, basicInformation, projectFeature} from './project_property_template';
+import {defaultDecimal, billsQuantityDecimal, basicInformation, projectFeature,displaySetting} from './project_property_template';
 let FeeRateFiles = mongoose.model('fee_rate_file');
 let FeeRateFiles = mongoose.model('fee_rate_file');
 let counter = require("../../../public/counter/counter.js");
 let counter = require("../../../public/counter/counter.js");
 
 
@@ -104,6 +104,11 @@ ProjectsDAO.prototype.updateUserProjects = async function(userId, datas, callbac
                     data.updateData.property.basicInformation = basicInformation;
                     data.updateData.property.basicInformation = basicInformation;
                     //工程特征
                     //工程特征
                     data.updateData.property.projectFeature = projectFeature;
                     data.updateData.property.projectFeature = projectFeature;
+                    //呈现选项
+		    data.updateData.property.displaySetting = displaySetting;
+		    
+                    data.updateData.property.billsCalcMode = 0;
+		    data.updateData.property.zanguCalcMode = 0;
                 }
                 }
                 newProject = new Projects(data.updateData);
                 newProject = new Projects(data.updateData);
                 // 查找同级是否存在同名数据
                 // 查找同级是否存在同名数据

+ 5 - 1
modules/pm/models/project_property_template.js

@@ -11,6 +11,10 @@ const defaultDecimal = {
     quantity_detail: 4,
     quantity_detail: 4,
     process: 6
     process: 6
 };
 };
+const displaySetting = {
+    autoHeight:true,
+    disPlayMainMateria:true
+}
 
 
 /*
 /*
 * 单位工程清单工程量精度模板
 * 单位工程清单工程量精度模板
@@ -119,4 +123,4 @@ const projectFeature = [
     {dispName: '门窗材料及装饰', key: 'doorsWindowsMaterial', value: ''}
     {dispName: '门窗材料及装饰', key: 'doorsWindowsMaterial', value: ''}
 ];
 ];
 
 
-export {defaultDecimal, billsQuantityDecimal, basicInformation, projectFeature};
+export {defaultDecimal, billsQuantityDecimal, basicInformation, projectFeature,displaySetting};

+ 4 - 4
modules/ration_glj/facade/ration_glj_facade.js

@@ -92,10 +92,10 @@ function combineQuantity(results,rations) {
         }
         }
         resultList.push(tmp);
         resultList.push(tmp);
       /*  if(resultMap.hasOwnProperty(data.projectGLJID)){
       /*  if(resultMap.hasOwnProperty(data.projectGLJID)){
-            resultMap[data.projectGLJID] += data.quantity;
-        }else {
-            resultMap[data.projectGLJID] = data.quantity;
-        }*/
+         resultMap[data.projectGLJID] += data.quantity;
+         }else {
+         resultMap[data.projectGLJID] = data.quantity;
+         }*/
     });
     });
 
 
  /*   var resultList =[];
  /*   var resultList =[];

+ 8 - 1
modules/users/controllers/login_controller.js

@@ -88,7 +88,14 @@ class LoginController {
             console.log(error);
             console.log(error);
             return response.json({error: 1, msg: error});
             return response.json({error: 1, msg: error});
         }
         }
-        response.json({error: 0, msg: '', login_ask: preferenceSetting.login_ask, compilation_list: JSON.stringify(compilationList)});
+        console.log(request.session.lastPage);
+        response.json({
+            error: 0,
+            msg: '',
+            login_ask: preferenceSetting.login_ask,
+            compilation_list: JSON.stringify(compilationList),
+            last_page: request.session.lastPage
+        });
     }
     }
 
 
 }
 }

+ 1 - 0
modules/users/models/user_model.js

@@ -97,6 +97,7 @@ class UserModel extends BaseModel {
             result = await logModel.addLoginLog(userDataFromDb._id, request);
             result = await logModel.addLoginLog(userDataFromDb._id, request);
         }
         }
         request.session.sessionUser.id = userDataFromDb._id;
         request.session.sessionUser.id = userDataFromDb._id;
+        request.session.sessionUser.real_name = userDataFromDb.real_name;
 
 
         return result;
         return result;
     }
     }

+ 0 - 12
public/calc_util.js

@@ -1,12 +0,0 @@
-/**
- * Created by Tony on 2017/6/21.
- * Modified by CSL, 2017-08-01 引入多套计算程序、费率同步、人工系数同步、改进基数计算、费字段映射等。
- * added by CSL, 2017-09-01 增加公式解析对象analyzer,用于解析用户修改公式、自定义表达式。
- */
-
-class Calculation {
-
-};
-
-/*
-export default analyzer;*/

+ 0 - 20
public/common_util.js

@@ -1,20 +0,0 @@
-/**
- * Created by CSL on 2017-06-06.
- * public functions.
- */
-
-function deleteEmptyObject(arr) {
-    function isEmptyObject(e) {
-        var t;
-        for (t in e)
-            return !1;
-        return !0
-    };
-
-    for (var i = 0; i < arr.length; i++) {
-        if (isEmptyObject(arr[i])) {
-            arr.splice(i, 1);
-            i = i - 1;
-        };
-    };
-};

+ 0 - 28
public/debug.js

@@ -1,28 +0,0 @@
-/**
- * Created by CSL on 2017-05-19.
- * 用于展示未知对象的内容。如:debug.m(GC.Spread.Sheets.Events);
- */
-
-debug = {
-    m: function (flag, obj) {
-        alert(flag + this.objStr(obj));
-    },
-
-    d: function (flag, obj) {
-        alert(flag + JSON.stringify(obj));
-    },
-
-    objStr: function (obj) {
-        var str = "";
-        var spr = "";
-        for (var x in obj) {
-            if (obj.hasOwnProperty(x)) {
-                if (str == '') {
-                    spr = ''
-                } else { spr = ', ' } ;
-                str += spr + x + ':' + obj[x];
-            }
-        }
-        return str;
-    }
-}

File diff suppressed because it is too large
+ 2 - 2
public/web/PerfectLoad.js


+ 20 - 0
public/web/common_util.js

@@ -0,0 +1,20 @@
+/**
+ * Created by CSL on 2017-06-06.
+ * public functions for web.
+ */
+
+// 忽略大小写判断字符串是否和参数指定的字符串相同
+String.prototype.sameText = function (str) {
+    return this.toLowerCase() == str.toLowerCase();
+};
+
+// 忽略大小写判断字符串是否有参数指定的子串
+String.prototype.hasSubStr = function (str) {
+    return this.toLowerCase().indexOf(str.toLowerCase()) > -1;
+};
+
+// 树结点计算时,取费会出现值为NaN的情况,导致往父节点汇总(递归相加)会出现错误。
+function parseFloatPlus(value){
+    let rst = parseFloat(value);
+    return  isNaN(rst) ? 0 : rst;
+};

+ 6 - 1
public/web/sheet/sheet_common.js

@@ -98,7 +98,9 @@ var sheetCommonObj = {
 
 
         sheet.clear(0, 0, sheet.getRowCount(), sheet.getColumnCount(), GC.Spread.Sheets.SheetArea.viewport, GC.Spread.Sheets.StorageType.data);
         sheet.clear(0, 0, sheet.getRowCount(), sheet.getColumnCount(), GC.Spread.Sheets.SheetArea.viewport, GC.Spread.Sheets.StorageType.data);
         if(sheet.getRowCount()<data.length){
         if(sheet.getRowCount()<data.length){
-            sheet.setRowCount(data.length);
+            data.length<30? sheet.setRowCount(30):sheet.setRowCount(data.length);
+        }else if(sheet.getRowCount()==0){
+            sheet.setRowCount(30);
         }
         }
         for (var col = 0; col < setting.header.length; col++) {
         for (var col = 0; col < setting.header.length; col++) {
             var hAlign = "left", vAlign = "center";
             var hAlign = "left", vAlign = "center";
@@ -126,6 +128,9 @@ var sheetCommonObj = {
                 //var cell = sheet.getCell(row, col, GC.Spread.Sheets.SheetArea.viewport);
                 //var cell = sheet.getCell(row, col, GC.Spread.Sheets.SheetArea.viewport);
                 var val = data[row][setting.header[col].dataCode];
                 var val = data[row][setting.header[col].dataCode];
                 if(val&&setting.header[col].dataType === "Number"){
                 if(val&&setting.header[col].dataType === "Number"){
+                    if(setting.header[col].hasOwnProperty('tofix')){
+                        val =scMathUtil.roundToString(val,setting.header[col].tofix);
+                    }
                     if(setting.header[col].hasOwnProperty('decimalField')){
                     if(setting.header[col].hasOwnProperty('decimalField')){
                         var decimal = getDecimal(setting.header[col].decimalField);
                         var decimal = getDecimal(setting.header[col].decimalField);
                         val =scMathUtil.roundToString(val,decimal);
                         val =scMathUtil.roundToString(val,decimal);

+ 4 - 5
server.js

@@ -52,7 +52,7 @@ app.use(bodyParser.json({limit: '3mb'}));
 app.use(session({
 app.use(session({
     name: 'usersSession',
     name: 'usersSession',
     secret: 'session users secret',
     secret: 'session users secret',
-    cookie: {maxAge: 1000*60*30},
+    cookie: {maxAge: 1000*60*60},
     resave: false,
     resave: false,
     rolling: true,
     rolling: true,
     saveUninitialized: true
     saveUninitialized: true
@@ -66,9 +66,7 @@ app.use(session({
 // 登录状态全局判断
 // 登录状态全局判断
 app.use(function (req, res, next) {
 app.use(function (req, res, next) {
     let url = req.originalUrl;
     let url = req.originalUrl;
-    // @todo 上一个页面跳转
-    let referer = '';
-    if (/^\/login/.test(url)) {
+    if (/^\/login/.test(url) || /\.map|\.ico$/.test(url)) {
         // 如果是登录页面则忽略判断数据
         // 如果是登录页面则忽略判断数据
         next();
         next();
     } else {
     } else {
@@ -78,9 +76,10 @@ app.use(function (req, res, next) {
             if (!sessionUser) {
             if (!sessionUser) {
                 throw 'session error';
                 throw 'session error';
             }
             }
-
             res.locals.sessionUser = sessionUser;
             res.locals.sessionUser = sessionUser;
         } catch (error) {
         } catch (error) {
+            // 最后一个页面存入session
+            req.session.lastPage = url;
             return res.redirect('/login');
             return res.redirect('/login');
         }
         }
 
 

+ 2 - 2
test/tmp_data/bills_grid_setting.js

@@ -405,10 +405,10 @@ var BillsGridSetting ={
                 ]
                 ]
             },
             },
             "data":{
             "data":{
-                "field":"",
+                "field":"calcBase",
                 "vAlign":1,
                 "vAlign":1,
                 "hAlign":0,
                 "hAlign":0,
-                "font":"Arial"
+                "font":"Arial",
             }
             }
         },
         },
         {
         {

+ 50 - 47
web/building_saas/css/main.css

@@ -8,10 +8,10 @@ body {
     font-size: 0.9rem
     font-size: 0.9rem
 }
 }
 .btn.disabled, .btn:disabled {
 .btn.disabled, .btn:disabled {
-    color:#999
+  color:#999
 }
 }
 .btn-link:focus, .btn-link:hover{
 .btn-link:focus, .btn-link:hover{
-    text-decoration: none
+  text-decoration: none
 }
 }
 /*自定义css*/
 /*自定义css*/
 .header {
 .header {
@@ -28,10 +28,10 @@ body {
     line-height: inherit
     line-height: inherit
 }
 }
 .top-msg{
 .top-msg{
-    position: fixed;
-    top:0;
-    width:100%;
-    z-index: 999
+  position: fixed;
+  top:0;
+  width:100%;
+  z-index: 999
 }
 }
 .in-1{padding-left:0px!important}
 .in-1{padding-left:0px!important}
 .in-2{padding-left:21px!important}
 .in-2{padding-left:21px!important}
@@ -70,7 +70,7 @@ body {
     color: #333
     color: #333
 }
 }
 .main-nav .nav-tabs{
 .main-nav .nav-tabs{
-    border-bottom: none
+  border-bottom: none
 }
 }
 .content {
 .content {
     border-left: 1px solid #ccc;
     border-left: 1px solid #ccc;
@@ -78,7 +78,7 @@ body {
     background: #fff
     background: #fff
 }
 }
 .toolsbar,.toolsbar-f {
 .toolsbar,.toolsbar-f {
-    border-bottom: 1px solid #ccc
+  border-bottom: 1px solid #ccc
 }
 }
 .tools-btn {
 .tools-btn {
     height: 30px;
     height: 30px;
@@ -92,23 +92,23 @@ body {
     overflow-y: hidden;
     overflow-y: hidden;
 }
 }
 .main-data-top,.main-data-full{
 .main-data-top,.main-data-full{
-    overflow: hidden;
-    width:100%
+  overflow: hidden;
+  width:100%
 }
 }
 .main-content.col-lg-8{
 .main-content.col-lg-8{
-    width:66.666667%
+  width:66.666667%
 }
 }
 .main-content.col-lg-12{
 .main-content.col-lg-12{
-    width:100%
+  width:100%
 }
 }
 .main-side.col-lg-4{
 .main-side.col-lg-4{
-    width: 33.333333%;
+  width: 33.333333%;
 }
 }
 .main-side.col-lg-0{
 .main-side.col-lg-0{
-    width:0%;
+  width:0%;
 }
 }
 .sidebar-bottom,.sidebar-bottom .col-lg-6,.sidebar-bottom .col-lg-12 {
 .sidebar-bottom,.sidebar-bottom .col-lg-6,.sidebar-bottom .col-lg-12 {
-    height:300px
+  height:300px
 }
 }
 .top-content, .fluid-content {
 .top-content, .fluid-content {
     overflow: auto;
     overflow: auto;
@@ -124,7 +124,7 @@ body {
     padding: 0.2em 0.5em
     padding: 0.2em 0.5em
 }
 }
 .side-tabs .nav-tabs .nav-item {
 .side-tabs .nav-tabs .nav-item {
-    z-index: 999
+  z-index: 999
 }
 }
 .side-tabs .nav-tabs {
 .side-tabs .nav-tabs {
     border-bottom: none;
     border-bottom: none;
@@ -251,69 +251,72 @@ body {
     overflow: auto;
     overflow: auto;
 }
 }
 .poj-list span.poj-icon {
 .poj-list span.poj-icon {
-    padding-right:7px;
-    color:#ccc
+  padding-right:7px;
+  color:#ccc
 }
 }
 .poj-list a.tree-open,.poj-list a.tree-close{
 .poj-list a.tree-open,.poj-list a.tree-close{
-    width:15px;
-    display: inline-block;
+  width:15px;
+  display: inline-block;
 }
 }
 .print-toolsbar{
 .print-toolsbar{
-    padding:5px
+  padding:5px
 }
 }
 .print-toolsbar .panel {
 .print-toolsbar .panel {
-    display:inline-block;
-    vertical-align:top;
-    background:#f7f7f9
+  display:inline-block;
+  vertical-align:top;
+  background:#f7f7f9
 }
 }
 .print-toolsbar .panel .panel-foot{
 .print-toolsbar .panel .panel-foot{
-    text-align: center;
-    font-size: 12px
+  text-align: center;
+  font-size: 12px
 }
 }
 .print-list {
 .print-list {
-    border-right:1px solid #ccc
+  border-right:1px solid #ccc
 }
 }
 .print-list .form-list {
 .print-list .form-list {
-    overflow: auto
+  overflow: auto
 }
 }
 .print-list .list-tools{
 .print-list .list-tools{
-    height:50px;
-    padding:10px 0;
-    border-bottom:1px solid #f2f2f2
+  height:50px;
+  padding:10px 0;
+  border-bottom:1px solid #f2f2f2
 }
 }
 .pageContainer {
 .pageContainer {
-    background: #ededed;
-    text-align: center
+  background: #ededed;
+  text-align: center
 }
 }
 .pageContainer .page{
 .pageContainer .page{
-    border:9px solid transparent;
-    display: inline-block;
+  border:9px solid transparent;
+  display: inline-block;
 }
 }
 .pageContainer .page img{
 .pageContainer .page img{
-    width:inherit;
-    height: inherit;
+  width:inherit;
+  height: inherit;
 }
 }
 .modal-auto-height {
 .modal-auto-height {
-    height: 400px;
-    overflow-y: auto;
+  height: 400px;
+  overflow-y: auto;
 }
 }
 .modal-fixed-height {
 .modal-fixed-height {
-    height: 400px;
-    overflow-y: hidden;
+  height: 400px;
+  overflow-y: hidden;
 }
 }
 .sidebar-tools-bar {
 .sidebar-tools-bar {
-    background:#fff
+  background:#fff
 }
 }
 .side-search-box{
 .side-search-box{
-    background:#fff;
-    border-bottom:1px solid #ddd
+  background:#fff;
+  border-bottom:1px solid #ddd
 }
 }
 .navbar-crumb span{
 .navbar-crumb span{
-    max-width: 200px
+  max-width: 200px
 }
 }
 .dropdown-item{
 .dropdown-item{
-    color:#007bff
+  color:#007bff
 }
 }
 .dropdown-item.disabled, .dropdown-item:disabled{
 .dropdown-item.disabled, .dropdown-item:disabled{
-    pointer-events:none
+  pointer-events:none
 }
 }
+.text-green{
+    color:#00FF00
+}

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

@@ -12,7 +12,7 @@
 </div>
 </div>
 <div class="container-fluid">
 <div class="container-fluid">
     <div class="row">
     <div class="row">
-        <div class="col-lg-12 p-0">
+        <div class="col-lg-12 p-0" id="glj-main">
             <div class="top-content">
             <div class="top-content">
                 <div class="main-data-top" id="project-glj">
                 <div class="main-data-top" id="project-glj">
                     <p style="text-align: center; margin-top: 30px;">正在加载数据</p>
                     <p style="text-align: center; margin-top: 30px;">正在加载数据</p>
@@ -29,6 +29,9 @@
                     <li class="nav-item">
                     <li class="nav-item">
                         <a class="nav-link" data-toggle="tab" data-name="machine" href="#jx" role="tab">机械单价</a>
                         <a class="nav-link" data-toggle="tab" data-name="machine" href="#jx" role="tab">机械单价</a>
                     </li>
                     </li>
+                    <li class="nav-item ml-auto mr-4">
+                        <a class="nav-link text-muted position-absolute resize" data-toggle="tooltip" data-placement="bottom" title="按住,上下拖动调整高度"><i class="fa fa-arrows-v"></i></a>
+                    </li>
                 </ul>
                 </ul>
                 <!-- Tab panes -->
                 <!-- Tab panes -->
                 <div class="tab-content">
                 <div class="tab-content">

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

@@ -32,6 +32,10 @@ $(document).ready(function () {
         init();
         init();
     });
     });
 
 
+    slideResize($("#glj-main"), function() {
+        projectGLJSpread.sheetObj.spread.refresh();
+    });
+
     // 单价文件切换弹框
     // 单价文件切换弹框
     $('#change-dj').on('shown.bs.modal', function () {
     $('#change-dj').on('shown.bs.modal', function () {
         // 获取当前建设项数据
         // 获取当前建设项数据
@@ -285,6 +289,10 @@ function spreadInit() {
             projectGLJSheet.filterData('unit_price.type', []);
             projectGLJSheet.filterData('unit_price.type', []);
         }
         }
     });
     });
+
+    loadSize("glj-main", function() {
+        projectGLJSpread.sheetObj.spread.refresh();
+    });
 }
 }
 
 
 /**
 /**

+ 3 - 3
web/building_saas/glj/js/project_glj_spread.js

@@ -48,9 +48,9 @@ ProjectGLJSpread.prototype.init = function () {
         {name: 'ID', field: 'id', visible: false},
         {name: 'ID', field: 'id', visible: false},
         {name: '类型', field: 'unit_price.type', visible: false},
         {name: '类型', field: 'unit_price.type', visible: false},
         {name: '总消耗量', field: 'quantity', visible: true,width:100},
         {name: '总消耗量', field: 'quantity', visible: true,width:100},
-        {name: '基价单价', field: "unit_price.base_price", visible: true,width:70},
-        {name: '调整价', field: 'adjust_price', visible: true,width:70},
-        {name: '市场价', field: "unit_price.market_price", visible: true, validator: 'number',width:70},
+        {name: '定额价', field: "unit_price.base_price", visible: true,width:70},
+        {name: '调整价', field: 'adjust_price', visible: true,width:70},
+        {name: '市场价', field: "unit_price.market_price", visible: true, validator: 'number',width:70},
         {
         {
             name: '是否暂估',
             name: '是否暂估',
             field: 'is_evaluate',
             field: 'is_evaluate',

+ 46 - 13
web/building_saas/js/global.js

@@ -17,17 +17,18 @@ function autoFlashHeight(){
     $(".poj-list").height($(window).height()-headerHeight-toolsbarHeight);
     $(".poj-list").height($(window).height()-headerHeight-toolsbarHeight);
     $(".form-view").height($(window).height()-headerHeight-ftoolsbarHeight);
     $(".form-view").height($(window).height()-headerHeight-ftoolsbarHeight);
     $(".form-list").height($(window).height()-headerHeight-50 );
     $(".form-list").height($(window).height()-headerHeight-50 );
+
 };
 };
 $(window).resize(autoFlashHeight);
 $(window).resize(autoFlashHeight);
 /*全局自适应高度结束*/
 /*全局自适应高度结束*/
-$(function(){
-/*侧滑*/
-$(".open-sidebar").click(function(){
-    $(".slide-sidebar").animate({width:"800"}).addClass("open");
-});
-$("body").click(function(event){
+$(function () {
+    /*侧滑*/
+    $(".open-sidebar").click(function () {
+        $(".slide-sidebar").animate({width: "800"}).addClass("open");
+    });
+    $("body").click(function (event) {
         var e = event || window.event; //浏览器兼容性
         var e = event || window.event; //浏览器兼容性
-        if(!$(event.target).is('a')) {
+        if (!$(event.target).is('a')) {
             var elem = event.target || e.srcElement;
             var elem = event.target || e.srcElement;
             while (elem) { //循环判断至跟节点,防止点击的是div子元素
             while (elem) { //循环判断至跟节点,防止点击的是div子元素
                 if (elem.className == "open-sidebar" || elem.className == 'slide-sidebar open') {
                 if (elem.className == "open-sidebar" || elem.className == 'slide-sidebar open') {
@@ -35,13 +36,45 @@ $("body").click(function(event){
                 }
                 }
                 elem = elem.parentNode;
                 elem = elem.parentNode;
             }
             }
-            $(".slide-sidebar").animate({width:"0"}).removeClass("open")// 关闭处理
+            $(".slide-sidebar").animate({width: "0"}).removeClass("open")// 关闭处理
         }
         }
 
 
     });
     });
-/*侧滑*/
-/*工具提示*/
-$(function () {
-  $('[data-toggle="tooltip"]').tooltip()
-});
+    /*侧滑*/
+    /*工具提示*/
+    $(function () {
+        $('[data-toggle="tooltip"]').tooltip();
+    });
+
 });
 });
+
+/**
+ * 设置本地缓存
+ *
+ * @param {String} key
+ * @param {String|Number} value
+ * @return {void}
+ */
+function setLocalCache(key, value) {
+    const storage = window.localStorage;
+    if (!storage || key === '' || value === '') {
+        return;
+    }
+
+    storage.setItem(key, value);
+}
+
+/**
+ * 获取本地缓存
+ *
+ * @param {String} key
+ * @return {String}
+ */
+function getLocalCache(key) {
+    const storage = window.localStorage;
+    if (!storage || key === '') {
+        return null;
+    }
+
+    return storage.getItem(key);
+}

+ 78 - 57
web/building_saas/main/html/main.html

@@ -5,7 +5,7 @@
     <meta charset="utf-8">
     <meta charset="utf-8">
     <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
     <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
     <meta http-equiv="x-ua-compatible" content="ie=edge">
     <meta http-equiv="x-ua-compatible" content="ie=edge">
-    <title>造价书-Smartcost</title>
+    <title>造价书-纵横云造价</title>
     <!-- inject:css -->
     <!-- inject:css -->
     <link rel="stylesheet" href="/lib/bootstrap/css/bootstrap.min.css">
     <link rel="stylesheet" href="/lib/bootstrap/css/bootstrap.min.css">
     <link rel="stylesheet" href="/web/building_saas/css/main.css">
     <link rel="stylesheet" href="/web/building_saas/css/main.css">
@@ -37,42 +37,6 @@
             </div>
             </div>
         </div>
         </div>
         <%include ../../../common/html/header.html %>
         <%include ../../../common/html/header.html %>
-        <nav class="navbar navbar-expand-lg justify-content-between navbar-light p-0">
-            <ul class="nav navbar-nav px-1">
-                <li class="nav-item">
-                    <a class="nav-link" href="#" aria-expanded="false" data-toggle="modal" data-target="#poj-set"><i class="fa fa-cube"></i> 项目属性</a>
-                </li>
-                <li class="nav-item">
-                    <a class="nav-link" href="#" aria-expanded="false" data-toggle="modal" data-target="#opts-set"><i class="fa fa-sliders"></i> 选项</a>
-                    <!--<a class="nav-link" href="#" aria-haspopup="true" aria-expanded="false"><i class="fa fa-sliders"></i> 选项</a>-->
-                </li>
-                <li class="nav-item dropdown">
-                    <a class="nav-link dropdown-toggle" href="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fa fa-wrench"></i> 工具</a>
-                    <div class="dropdown-menu">
-                        <a class="dropdown-item" href="#">定额库编辑器</a>
-                        <a class="dropdown-item" href="/complementaryGlj">工料机库编辑器</a>
-                    </div>
-                </li>
-                <li class="nav-item dropdown">
-                    <a class="nav-link dropdown-toggle" href="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fa fa-question-circle-o"></i> 帮助</a>
-                    <div class="dropdown-menu">
-                        <a class="dropdown-item" href="#">帮助</a>
-                        <a class="dropdown-item" href="#">升级说明</a>
-                        <a class="dropdown-item" href="#">重庆市2008定额说明</a>
-                        <a class="dropdown-item" href="#">纵横官网</a>
-                        <a class="dropdown-item" href="#">动画教程</a>
-                        <a class="dropdown-item" href="#">联系客服</a>
-                        <a class="dropdown-item" href="#">关于</a>
-                    </div>
-                </li>
-                <li class="nav-item">
-                    <a class="nav-link" href="#" aria-haspopup="true" aria-expanded="false"><i class="fa fa-history"></i> 历史记录</a>
-                </li>
-            </ul>
-            <form class="form-inline">
-                <input class="form-control form-control-sm mr-1" type="text" placeholder="告诉我你想做什么">
-            </form>
-        </nav>
     </div>
     </div>
     <div class="main">
     <div class="main">
         <div class="main-nav">
         <div class="main-nav">
@@ -90,15 +54,15 @@
               <!--造价书-->
               <!--造价书-->
               <div class="toolsbar px-1 d-flex justify-content-between">
               <div class="toolsbar px-1 d-flex justify-content-between">
                   <div class="tools-btn btn-group align-top">
                   <div class="tools-btn btn-group align-top">
-                    <a href="" class="btn btn-sm"><i class="fa fa-files-o" aria-hidden="true"></i> 复制</a>
-                    <a href="" class="btn btn-sm"><i class="fa fa-scissors" aria-hidden="true"></i> 接切</a>
-                    <a href="" class="btn btn-sm"><i class="fa fa-clipboard" aria-hidden="true"></i> 粘贴</a>
-                    <a href="javascript:void(0)" class="btn btn-sm" id="insert"><i class="fa fa-sign-in" aria-hidden="true"></i> 插入</a>
-                    <a href="javascript:void(0)" class="btn btn-sm" id="delete"><i class="fa fa-remove" aria-hidden="true"></i> 删除</a>
-                    <a href="javascript:void(0)" class="btn btn-sm" id="upLevel"><i class="fa fa-arrow-left" aria-hidden="true"></i> 升级</a>
-                    <a href="javascript:void(0)" class="btn btn-sm" id="downLevel"><i class="fa fa-arrow-right" aria-hidden="true"></i> 降级</a>
-                    <a href="javascript:void(0)" class="btn btn-sm" id="downMove"><i class="fa fa-arrow-down" aria-hidden="true"></i> 下移</a>
-                    <a href="javascript:void(0)" class="btn btn-sm" id="upMove"><i class="fa fa-arrow-up" aria-hidden="true"></i> 上移</a>
+                    <a href="" class="btn btn-sm" title="复制"><i class="fa fa-files-o" aria-hidden="true"></i></a>
+                    <a href="" class="btn btn-sm" title="接切"><i class="fa fa-scissors" aria-hidden="true"></i></a>
+                    <a href="" class="btn btn-sm" title="粘贴"><i class="fa fa-clipboard" aria-hidden="true"></i></a>
+                    <a href="javascript:void(0)" class="btn btn-sm" id="insert" title="插入"><i class="fa fa-sign-in" aria-hidden="true"></i></a>
+                    <a href="javascript:void(0)" class="btn btn-sm" id="delete" title="删除"><i class="fa fa-remove" aria-hidden="true"></i></a>
+                    <a href="javascript:void(0)" class="btn btn-sm" id="upLevel" title="升级"><i class="fa fa-arrow-left" aria-hidden="true"></i></a>
+                    <a href="javascript:void(0)" class="btn btn-sm" id="downLevel" title="降级"><i class="fa fa-arrow-right" aria-hidden="true"></i></a>
+                    <a href="javascript:void(0)" class="btn btn-sm" id="downMove" title="下移"><i class="fa fa-arrow-down" aria-hidden="true"></i></a>
+                    <a href="javascript:void(0)" class="btn btn-sm" id="upMove" title="上移"><i class="fa fa-arrow-up" aria-hidden="true"></i></a>
                   </div>
                   </div>
                   <div class="tools-btn">
                   <div class="tools-btn">
                       <a href="javacript:void(0);" data-toggle="modal" data-target="#column" class="btn btn-sm"><i class="fa fa-table" aria-hidden="true"></i> 列设置</a>
                       <a href="javacript:void(0);" data-toggle="modal" data-target="#column" class="btn btn-sm"><i class="fa fa-table" aria-hidden="true"></i> 列设置</a>
@@ -116,7 +80,7 @@
               </div>
               </div>
               <div class="container-fluid">
               <div class="container-fluid">
                   <div class="row">
                   <div class="row">
-                      <div class="main-content col-lg-12 p-0">
+                      <div class="main-content col-lg-12 p-0" id="main">
                           <div class="top-content">
                           <div class="top-content">
                               <div class="main-data-top" id="billsSpread"></div>
                               <div class="main-data-top" id="billsSpread"></div>
                           </div>
                           </div>
@@ -143,6 +107,9 @@
                                   <li class="nav-item">
                                   <li class="nav-item">
                                       <a class="nav-link" id="linkTZJNR" data-toggle="tab" href="#subSpread" role="tab">特征及内容</a>
                                       <a class="nav-link" id="linkTZJNR" data-toggle="tab" href="#subSpread" role="tab">特征及内容</a>
                                   </li>
                                   </li>
+                                  <li class="nav-item ml-auto mr-4">
+                                      <a class="nav-link text-muted position-absolute resize" data-toggle="tooltip" data-placement="bottom" title="按住,上下拖动调整高度"><i class="fa fa-arrows-v"></i></a>
+                                  </li>
                               </ul>
                               </ul>
                               <!-- Tab panes -->
                               <!-- Tab panes -->
                               <div class="tab-content" id="tabCon">
                               <div class="tab-content" id="tabCon">
@@ -268,6 +235,7 @@
                                 <li class="nav-item"><a class="nav-link" data-toggle="pill" href="#poj-settings-billsQuanDecimal" id="tab_poj-settings-bqDecimal" role="tab">清单工程量精度</a></li>
                                 <li class="nav-item"><a class="nav-link" data-toggle="pill" href="#poj-settings-billsQuanDecimal" id="tab_poj-settings-bqDecimal" role="tab">清单工程量精度</a></li>
                                 <li class="nav-item"><a class="nav-link" data-toggle="pill" href="#poj-settings-decimal" role="tab" id="tab_poj-settings-decimal">小数位数</a></li>
                                 <li class="nav-item"><a class="nav-link" data-toggle="pill" href="#poj-settings-decimal" role="tab" id="tab_poj-settings-decimal">小数位数</a></li>
                                 <li class="nav-item"><a class="nav-link" data-toggle="pill" href="#poj-settings-6" role="tab" id="tab_poj-settings-6">人工单价调整</a></li>
                                 <li class="nav-item"><a class="nav-link" data-toggle="pill" href="#poj-settings-6" role="tab" id="tab_poj-settings-6">人工单价调整</a></li>
+                                <li class="nav-item"><a class="nav-link" data-toggle="pill" href="#display_setting" role="tab" id="tab_display_setting">呈现选项</a></li>
                             </ul>
                             </ul>
                         </div>
                         </div>
                         <div class="col-9">
                         <div class="col-9">
@@ -302,13 +270,13 @@
                                             </div>
                                             </div>
                                             <div class="form-check">
                                             <div class="form-check">
                                                 <label class="form-check-label">
                                                 <label class="form-check-label">
-                                                    <input class="form-check-input" name="calcFlag" id="rationPrice" value="1" type="radio">
+                                                    <input class="form-check-input" name="calcFlag" id="rationPriceConverse" value="1" type="radio">
                                                     子目单价取费(反算):清单综合合价=清单综合单价*清单工程量
                                                     子目单价取费(反算):清单综合合价=清单综合单价*清单工程量
                                                 </label>
                                                 </label>
                                             </div>
                                             </div>
                                             <div class="form-check">
                                             <div class="form-check">
                                                 <label class="form-check-label">
                                                 <label class="form-check-label">
-                                                    <input class="form-check-input" name="calcFlag" id="rationPriceConverse" value="2" type="radio">
+                                                    <input class="form-check-input" name="calcFlag" id="rationPrice" value="2" type="radio">
                                                     子目单价取费(正算):清单综合合价=∑子目综合合价
                                                     子目单价取费(正算):清单综合合价=∑子目综合合价
                                                 </label>
                                                 </label>
                                             </div>
                                             </div>
@@ -416,6 +384,24 @@
                                     <div style="height:8px;"></div>
                                     <div style="height:8px;"></div>
                                     <div class="modal-auto-height" id="labourCoeSpread"></div>
                                     <div class="modal-auto-height" id="labourCoeSpread"></div>
                                 </div>
                                 </div>
+                                <!--人工单价调整-->
+                                <div class="tab-pane fade" id="display_setting" role="tabpanel">
+                                    <fieldset class="form-group">
+                                        <div class="row px-3">
+                                            <div class="checkbox">
+                                                <label class="form-check-label">
+                                                    <input type="checkbox" id="autoHeight" class="form-check-input">造价书表格自动调整行高
+                                                </label>
+                                            </div>
+                                        </div>
+                                        <div style="height:8px;"></div>
+                                        <div class="checkbox">
+                                            <label class="form-check-label">
+                                                <input type="checkbox" id="disPlayMainMateria" class="form-check-input">定额下显示主村、设备
+                                            </label>
+                                        </div>
+                                    </fieldset>
+                                </div>
                             </div>
                             </div>
                         </div>
                         </div>
                     </div>
                     </div>
@@ -607,6 +593,38 @@
             </div>
             </div>
         </div>
         </div>
     </div>
     </div>
+    <!--弹出 清单 计算基数-->
+    <div class="modal fade" id="qd-jsjs" data-backdrop="static">
+        <div class="modal-dialog" role="document">
+            <div class="modal-content">
+                <div class="modal-header">
+                    <h5 class="modal-title">计算基础选择</h5>
+                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                        <span aria-hidden="true">&times;</span>
+                    </button>
+                </div>
+                <div class="modal-body">
+                    <div class="form-group">
+                        <input class="form-control" id="calcBaseExp" value="">
+                        <p class="form-text">
+                            <button class="btn btn-secondary btn-sm" id="addOpr">+</button>
+                            <button class="btn btn-secondary btn-sm" id="subOpr">-</button>
+                            <button class="btn btn-secondary btn-sm" id="mulOpr">*</button>
+                            <button class="btn btn-secondary btn-sm" id="divOpr">/</button>
+                            <button class="btn btn-secondary btn-sm" id="leftOpr">(</button>
+                            <button class="btn btn-secondary btn-sm" id="rightOpr">)</button>
+                        </p>
+                    </div>
+                    <div class=" modal-auto-height" style="overflow: hidden" id="billsBaseSpread">
+                    </div>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
+                    <a href="javascript:void(0);" class="btn btn-primary" id="calcBaseConf">确定</a>
+                </div>
+            </div>
+        </div>
+    </div>
         <!-- JS. -->
         <!-- JS. -->
         <script type="text/javascript" src="/lib/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js"></script>
         <script type="text/javascript" src="/lib/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js"></script>
 
 
@@ -623,6 +641,8 @@
         <!-- inject:js -->
         <!-- inject:js -->
         <!--<script type="text/javascript" src="/test/tmp_data/test_ration_calc/ration_calc_base.js"></script>-->
         <!--<script type="text/javascript" src="/test/tmp_data/test_ration_calc/ration_calc_base.js"></script>-->
         <script type="text/javascript" src="/web/building_saas/main/js/models/main_consts.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/models/main_consts.js"></script>
+        <script type="text/javascript" src="/public/web/common_util.js"></script>
+
         <script type="text/javascript" src="/web/building_saas/glj/js/project_glj.js"></script>
         <script type="text/javascript" src="/web/building_saas/glj/js/project_glj.js"></script>
         <script type="text/javascript" src="/web/building_saas/glj/js/composition.js"></script>
         <script type="text/javascript" src="/web/building_saas/glj/js/composition.js"></script>
         <script type="text/javascript" src="/web/building_saas/glj/js/common_spread.js"></script>
         <script type="text/javascript" src="/web/building_saas/glj/js/common_spread.js"></script>
@@ -635,12 +655,6 @@
 
 
         <script type="text/javascript" src="/public/web/sheet/sheet_common.js"></script>
         <script type="text/javascript" src="/public/web/sheet/sheet_common.js"></script>
 
 
-
-        <!-- JS. -->
-        <script src="/lib/popper/popper.min.js"></script>
-        <script src="/lib/bootstrap/bootstrap.min.js"></script>
-        <script src="/web/building_saas/js/global.js"></script>
-
         <!--expression calculate-->
         <!--expression calculate-->
         <script src="/lib/JSExpressionEval_src/Date.js"></script>
         <script src="/lib/JSExpressionEval_src/Date.js"></script>
         <script src="/lib/JSExpressionEval_src/Stack.js"></script>
         <script src="/lib/JSExpressionEval_src/Stack.js"></script>
@@ -657,6 +671,11 @@
         <script type="text/javascript" src="/public/web/url_util.js"></script>
         <script type="text/javascript" src="/public/web/url_util.js"></script>
         <script type="text/javascript" src="/public/web/number_util.js"></script>
         <script type="text/javascript" src="/public/web/number_util.js"></script>
         <script type="text/javascript" src="/public/web/sheet/sheet_common.js"></script>
         <script type="text/javascript" src="/public/web/sheet/sheet_common.js"></script>
+
+        <!-- JS. -->
+        <script src="/lib/popper/popper.min.js"></script>
+        <script src="/lib/bootstrap/bootstrap.min.js"></script>
+        <script src="/web/building_saas/js/global.js"></script>
         <!--报表 zTree -->
         <!--报表 zTree -->
 
 
         <!-- SpreadJs -->
         <!-- SpreadJs -->
@@ -677,8 +696,10 @@
         <!--<script type="text/javascript" src="/web/building_saas/main/js/models/volume_price.js"></script>-->
         <!--<script type="text/javascript" src="/web/building_saas/main/js/models/volume_price.js"></script>-->
         <script type="text/javascript" src="/web/building_saas/main/js/models/labour_coe.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/models/labour_coe.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/models/calc_program.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/models/calc_program.js"></script>
+        <script type="text/javascript" src="/web/building_saas/main/js/models/calc_base.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/views/calc_program_manage.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/views/calc_program_manage.js"></script>
 
 
+
         <script type="text/javascript" src="/public/web/id_tree.js"></script>
         <script type="text/javascript" src="/public/web/id_tree.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/models/cache_tree.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/models/cache_tree.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/calc/calc_fees.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/calc/calc_fees.js"></script>
@@ -699,6 +720,7 @@
         <script type="text/javascript" src="/web/building_saas/main/js/views/project_property_decimal_view.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/views/project_property_decimal_view.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/views/project_property_basicInfo.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/views/project_property_basicInfo.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/views/project_property_projFeature.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/views/project_property_projFeature.js"></script>
+        <script type="text/javascript" src="/web/building_saas/main/js/views/project_property_display_view.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/main_ajax.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/main_ajax.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/main.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/main.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/controllers/project_controller.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/controllers/project_controller.js"></script>
@@ -722,6 +744,7 @@
         <script type="text/javascript" src="/web/building_saas/main/js/views/sub_view.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/views/sub_view.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/views/fee_rate_view.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/views/fee_rate_view.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/views/sub_fee_rate_views.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/views/sub_fee_rate_views.js"></script>
+        <script type="text/javascript" src="/web/building_saas/main/js/views/calc_base_view.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/views/project_property_labour_coe_view.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/views/project_property_labour_coe_view.js"></script>
         <!-- endinject -->
         <!-- endinject -->
 
 
@@ -729,8 +752,6 @@
             autoFlashHeight();
             autoFlashHeight();
         </script>
         </script>
 
 
-        <script src="/public/debug.js"></script>
-
         <SCRIPT type="text/javascript">
         <SCRIPT type="text/javascript">
             <!--
             <!--
 //            var zNodes =[
 //            var zNodes =[

+ 2 - 2
web/building_saas/main/js/calc/bills_calc.js

@@ -268,8 +268,8 @@ class BillsCalcHelper {
         let nodeCalc = nodeCalcObj, virData= null, decimal = this.project.Decimal;
         let nodeCalc = nodeCalcObj, virData= null, decimal = this.project.Decimal;
 
 
         // 清单单价:套用定额计算程序
         // 清单单价:套用定额计算程序
-        // if (this.project.calcFlag === billsPrice) {
-        if (this.project.projSetting.billsCalcMode === billsPrice) {
+        // if (this.project.projSetting.billsCalcMode === billsPrice) {
+        if (this.project.property.billsCalcMode === leafBillGetFeeType.billsPrice) {
             rationCalcObj.calcGljs = this.getBillsGLjs(node);
             rationCalcObj.calcGljs = this.getBillsGLjs(node);
             console.log(rationCalcObj.calcGljs);
             console.log(rationCalcObj.calcGljs);
             rationCalcObj.calcFields = rationCalcFields;
             rationCalcObj.calcFields = rationCalcFields;

+ 1 - 1
web/building_saas/main/js/controllers/project_controller.js

@@ -63,7 +63,7 @@ ProjectController = {
                     newSource = project.Ration.insertStdRation(selected.source.getID(), null, std);
                     newSource = project.Ration.insertStdRation(selected.source.getID(), null, std);
                     project.ration_glj.addRationGLJ(newSource,std);
                     project.ration_glj.addRationGLJ(newSource,std);
                 } else {
                 } else {
-                    newSource = project.Ration.insertRation(selected.source.getID());
+                    newSource = project.Ration.insertRation(selected.source.getID(),null, rationType);
                 }
                 }
 
 
                 newNode = project.mainTree.insert(selected.getID(), selected.tree.rootID());
                 newNode = project.mainTree.insert(selected.getID(), selected.tree.rootID());

+ 105 - 1
web/building_saas/main/js/main.js

@@ -19,4 +19,108 @@ $(function () {
         // do something
         // do something
     });
     });
 
 
-});
+    // 读取本地存储的高度
+    loadSize("main", function() {
+        refreshSubSpread();
+    });
+
+    slideResize($("#main"), function() {
+        projectObj.mainSpread.refresh();
+        refreshSubSpread();
+    });
+
+    const projectId = scUrlUtil.GetQueryString('project');
+    // 绑定点击事件
+    projectObj.mainSpread.bind(GC.Spread.Sheets.Events.CellClick, function(sender, info) {
+        if (info.row !== undefined && projectId !== undefined) {
+            setLocalCache('lastRow:' + projectId, info.row);
+            setLocalCache('lastCol:' + projectId, info.col);
+        }
+    });
+
+});
+
+/**
+ * 拖动更改div大小
+ *
+ * @param {Object} rootElement - 最顶层div
+ * @param {function} callback - 成功后执行
+ * @return {void}
+ */
+function slideResize(rootElement, callback) {
+    let startY = 0;
+    let drag = false;
+    const element = rootElement.find('.resize');
+    const topContentEle = rootElement.find(".top-content");
+    const bottomContentEle = rootElement.find(".bottom-content");
+    let topContentHeight = 0;
+    let bottomContentHeight = 0;
+    let navHeight = 0;
+    let topChangeHeight = 0;
+    let bottomChangeHeight = 0;
+
+    // 鼠标点下时
+    element.mousedown(function(e) {
+        drag = true;
+        startY = e.clientY;
+        // 获取上部分的高度
+        topContentHeight = topContentEle.height();
+        // 获取下部分的高度
+        bottomContentHeight = bottomContentEle.height();
+        // nav高度部分
+        navHeight = bottomContentEle.children('ul.nav').height();
+        element.tooltip('hide');
+    });
+
+    // 鼠标移动
+    $("body").mousemove(function(e) {
+        if (drag) {
+            let moveHeight = e.clientY - startY;
+            // 判断拖动范围不能超出
+            topChangeHeight = topContentHeight + moveHeight;
+            topChangeHeight = topChangeHeight < 170 ? 170 : topChangeHeight;
+            topChangeHeight = topChangeHeight > 700 ? 700 : topChangeHeight;
+            topContentEle.children(".main-data-top").height(topChangeHeight);
+
+            bottomChangeHeight = bottomContentHeight - moveHeight;
+            bottomChangeHeight = bottomChangeHeight < 170 ? 170 : bottomChangeHeight;
+            bottomChangeHeight = bottomChangeHeight > 700 ? 700 : bottomChangeHeight;
+            bottomContentEle.children().find(".main-data-bottom").height(bottomChangeHeight - navHeight);
+        }
+    });
+
+    // 鼠标弹起
+    $("body").mouseup(function(e) {
+        if (drag) {
+            callback();
+            drag = false;
+            // 存入本地缓存
+            const id = rootElement.attr('id');
+            setLocalCache('topHeight:' + id, topChangeHeight);
+            setLocalCache('bottomHeight:' + id, bottomChangeHeight);
+        }
+    });
+}
+
+/**
+ * 读取设置的高度
+ *
+ * @param {String} tag - 顶层div的id
+ * @param {function} callback - 回调函数
+ * @return {void}
+ */
+function loadSize(tag, callback) {
+    if (tag === '') {
+        return;
+    }
+    const topHeight = getLocalCache('topHeight:' + tag);
+    const bottomHeight = getLocalCache('bottomHeight:' + tag);
+    if (topHeight === null || bottomHeight === null) {
+        return;
+    }
+    const navHeight = $("#"+ tag +" .bottom-content").children('ul.nav').height();
+    $("#"+ tag +" .main-data-top").height(topHeight);
+    $("#"+ tag +" .main-data-bottom").height(bottomHeight - navHeight);
+    $("#"+ tag +" .bottom-content").height(bottomHeight);
+    callback();
+}

+ 2 - 15
web/building_saas/main/js/models/bills.js

@@ -122,6 +122,7 @@ var Bills = {
             if(data.quantityRefresh){
             if(data.quantityRefresh){
                 this.refreshDatas(data,'quantity');
                 this.refreshDatas(data,'quantity');
             }
             }
+            $.bootstrapLoading.end();
         };
         };
 
 
         bills.prototype.refreshDatas = function(data,fieldName){
         bills.prototype.refreshDatas = function(data,fieldName){
@@ -244,21 +245,7 @@ var Bills = {
             calcFees.setFee(node.data, field, newValue);
             calcFees.setFee(node.data, field, newValue);
             let updateData = [];
             let updateData = [];
             let data = {'ID': node.getID(), 'projectID': this.project.ID()};
             let data = {'ID': node.getID(), 'projectID': this.project.ID()};
-            if (field === 'quantity') {
-                data[field] = newValue;
-                data.isFromDetail=0;
-                // to do Calculate
-                if (node.data.fees) {
-                    data.fees = node.data.fees;
-                }
-            } else if (field === 'feesIndex.common.unitFee') {
-                // to do Calculate
-                if (node.data.fees) {
-                    data.fees = node.data.fees;
-                }
-            } else {
-                data[field] = newValue;
-            }
+            data[field] = newValue;
             updateData.push({'updateType': 'ut_update', 'updateData': tools.formatBillsUpdateData(data)});
             updateData.push({'updateType': 'ut_update', 'updateData': tools.formatBillsUpdateData(data)});
             this.project.pushNow('updateBills', this.getSourceType(), updateData);
             this.project.pushNow('updateBills', this.getSourceType(), updateData);
         };
         };

+ 455 - 0
web/building_saas/main/js/models/calc_base.js

@@ -0,0 +1,455 @@
+/**
+ * Created by Zhong on 2017/11/28.
+ */
+//清单固定行
+const fixedFlag = {
+    // 分部分项工程
+    SUB_ENGINERRING: 1,
+    // 措施项目
+    MEASURE: 2,
+    // 施工技术措施项目
+    CONSTRUCTION_TECH: 3,
+    // 安全文明施工按实计算费用
+    SAFETY_CONSTRUCTION_ACTUAL: 4,
+    // 施工组织措施专项费用
+    CONSTRUCTION_ORGANIZATION: 5,
+    // 安全文明施工专项费用
+    SAFETY_CONSTRUCTION: 6,
+    // 其他项目
+    OTHER: 7,
+    // 暂列金额
+    PROVISIONAL: 8,
+    // 暂估价
+    ESTIMATE: 9,
+    // 材料(工程设备)暂估价
+    MATERIAL_PROVISIONAL: 10,
+    // 专业工程暂估价
+    ENGINEERING_ESITIMATE: 11,
+    // 计日工
+    DAYWORK: 12,
+    // 总承包服务费
+    TURN_KEY_CONTRACT: 13,
+    // 索赔与现场签证
+    CLAIM_VISA: 14,
+    // 规费
+    CHARGE: 15,
+    // 社会保险费及住房公积金 Social insurance fee and housing accumulation fund
+    SOCIAL_INSURANCE_HOUSING_FUND: 16,
+    // 工程排污费 charges for disposing pollutants
+    POLLUTANTS: 17,
+    // 税金
+    TAX: 18
+};
+
+let cbTools = {
+    isDef: function (v) {
+        return v !== undefined && v !== null;
+    },
+    isUnDef: function (v) {
+        return v === undefined || v === null;
+    },
+    isNum: function (v) {
+        return this.isDef(v) && !isNaN(v) && v !== Infinity;
+    },
+    returnV: function (v, r) {
+        if(this.isDef(v)){
+            return v;
+        }
+        return r;
+    },
+    findBill: function (fixedFlag) {
+        let bills = projectObj.project.Bills.datas;
+        for(let i = 0, len = bills.length; i < len; i++){
+            if(bills[i].flagsIndex.flag === fixedFlag){
+                return bills[i];
+            }
+        }
+    },
+    //需要用到计算基数的时候,先找出所有的固定清单,避免每个基数都要去遍历寻找清单
+    setFixedBills: function (project, billsObj, fixedFlag) {
+        let bills = project.Bills.datas;
+        for(let i = 0, len = bills.length; i < len; i++){
+            if(this.isDef(bills[i].flagsIndex.fixed)){
+                for(let flag in fixedFlag){
+                    if(fixedFlag[flag] === bills[i].flagsIndex.fixed.flag){
+                        billsObj[fixedFlag[flag]] = bills[i];
+                    }
+                }
+            }
+        }
+    },
+    //生成清单基数计算分类模板
+    setBaseFigureClass: function (baseFigures, mapObj) {
+        mapObj['CONSTRUCTION_ORGANIZATION'] = Object.create(null);
+        mapObj['OTHER'] = Object.create(null);
+        mapObj['CHARGE'] = Object.create(null);
+        mapObj['TAX'] = Object.create(null);
+        mapObj['OTHERS'] = Object.create(null);
+        let filter = ['CSXMF', 'ZZCSXMF', 'ZZCSXMDEJJZJGCF', 'ZZCSXMDEJJRGF', 'ZZCSXMDEJJCLF', 'ZZCSXMDEJJJXF', 'QTXMF', 'GF', 'SJ'];
+        for(let figure in baseFigures){
+            if(filter.indexOf(baseFigures[figure]) === -1){
+                mapObj['CONSTRUCTION_ORGANIZATION'][figure] = baseFigures[figure];
+            }
+            if(baseFigures[figure] !== 'QTXMF'){
+                mapObj['OTHER'][figure] = baseFigures[figure];
+            }
+            if(baseFigures[figure] !== 'GF'){
+                mapObj['CHARGE'][figure] = baseFigures[figure];
+            }
+            if(baseFigures[figure] !== 'SJ'){
+                mapObj['TAX'][figure] = baseFigures[figure];
+            }
+            mapObj['OTHERS'][figure] = baseFigures[figure];
+        }
+    }
+};
+
+let baseFigureTemplate = {
+    'FBFXGCF': function () {
+        let bill = calcBase.fixedBills[calcBase.fixedFlag.SUB_ENGINERRING];
+        if(cbTools.isUnDef(bill)) return 0;
+        if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
+        return bill.feesIndex.common.totalFee || 0;
+    },
+    'FBFXDEJJRGF': function () {
+        let bill = calcBase.fixedBills[calcBase.fixedFlag.SUB_ENGINERRING];
+        if(cbTools.isUnDef(bill)) return 0;
+        if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
+        return bill.feesIndex.labour.totalFee || 0;
+    },
+    'FBFXDEJJCLF': function () {
+        let bill = calcBase.fixedBills[calcBase.fixedFlag.SUB_ENGINERRING];
+        if(cbTools.isUnDef(bill)) return 0;
+        if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
+        return bill.feesIndex.material.totalFee || 0;
+    },
+    'FBFXDEJJJXF': function () {
+        let bill = calcBase.fixedBills[calcBase.fixedFlag.SUB_ENGINERRING];
+        if(cbTools.isUnDef(bill)) return 0;
+        if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
+        return bill.feesIndex.machine.totalFee || 0;
+    },
+    'FBFXTZRGF': function () {
+        let bill = calcBase.fixedBills[calcBase.fixedFlag.SUB_ENGINERRING];
+        if(cbTools.isUnDef(bill)) return 0;
+        if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
+        return bill.feesIndex.adjustLabour.totalFee || 0;
+    },
+    'FBFXTZJSRGF': function () {
+        let bill = calcBase.fixedBills[calcBase.fixedFlag.SUB_ENGINERRING];
+        if(cbTools.isUnDef(bill)) return 0;
+        if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
+        return bill.feesIndex.adjustMachineLabour.totalFee || 0;
+    },
+    'FBFXZCF': function () {
+        let bill = calcBase.fixedBills[calcBase.fixedFlag.SUB_ENGINERRING];
+        if(cbTools.isUnDef(bill)) return 0;
+        if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
+        return bill.feesIndex.mainMaterial.totalFee || 0;
+    },
+    'FBFXSBF': function () {
+        let bill = calcBase.fixedBills[calcBase.fixedFlag.SUB_ENGINERRING];
+        if(cbTools.isUnDef(bill)) return 0;
+        if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
+        return bill.feesIndex.mainMaterial.totalFee || 0;
+    },
+    'FBFXWJJCLF': function () {
+        return 0;
+    },
+    'FBFXRGGR': function () {
+        return 0;
+    },
+    'FBFXGCLQDJJZJGCF': function () {
+        return this['FBFXDEJJRGF']() + this['FBFXDEJJCLF']() + this['FBFXDEJJJXF']();
+    },
+    'CSXMF': function () {
+        let bill = calcBase.fixedBills[calcBase.fixedFlag.MEASURE];
+        if(cbTools.isUnDef(bill)) return 0;
+        if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
+        return bill.feesIndex.common.totalFee || 0;
+    },
+    'ZZCSXMF': function () {
+        let bill = calcBase.fixedBills[calcBase.fixedFlag.CONSTRUCTION_ORGANIZATION];
+        if(cbTools.isUnDef(bill)) return 0;
+        if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
+        return bill.feesIndex.common.totalFee || 0;
+    },
+    'ZZCSXMDEJJZJGCF': function () {
+        return this['ZZCSXMDEJJRGF']() + this['ZZCSXMDEJJCLF']() + this['ZZCSXMDEJJJXF']()
+    },
+    'ZZCSXMDEJJRGF': function () {
+        let bill = calcBase.fixedBills[calcBase.fixedFlag.CONSTRUCTION_ORGANIZATION];
+        if(cbTools.isUnDef(bill)) return 0;
+        if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
+        return bill.feesIndex.labour.totalFee || 0;
+    },
+    'ZZCSXMDEJJCLF': function () {
+        let bill = calcBase.fixedBills[calcBase.fixedFlag.CONSTRUCTION_ORGANIZATION];
+        if(cbTools.isUnDef(bill)) return 0;
+        if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
+        return bill.feesIndex.material.totalFee || 0;
+    },
+    'ZZCSXMDEJJJXF': function () {
+        let bill = calcBase.fixedBills[calcBase.fixedFlag.CONSTRUCTION_ORGANIZATION];
+        if(cbTools.isUnDef(bill)) return 0;
+        if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
+        return bill.feesIndex.machine.totalFee || 0;
+    },
+    'JSCSXMF': function () {
+        let bill = calcBase.fixedBills[calcBase.fixedFlag.CONSTRUCTION_TECH];
+        if(cbTools.isUnDef(bill)) return 0;
+        if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
+        return bill.feesIndex.common.totalFee || 0;
+    },
+    'JSCSXMDEJJRGF': function () {
+        let bill = calcBase.fixedBills[calcBase.fixedFlag.CONSTRUCTION_TECH];
+        if(cbTools.isUnDef(bill)) return 0;
+        if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
+        return bill.feesIndex.labour.totalFee || 0;
+    },
+    'JSCSXMDEJJCLF': function () {
+        let bill = calcBase.fixedBills[calcBase.fixedFlag.CONSTRUCTION_TECH];
+        if(cbTools.isUnDef(bill)) return 0;
+        if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
+        return bill.feesIndex.material.totalFee || 0;
+    },
+    'JSCSXMDEJJJXF': function () {
+        let bill = calcBase.fixedBills[calcBase.fixedFlag.CONSTRUCTION_TECH];
+        if(cbTools.isUnDef(bill)) return 0;
+        if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
+        return bill.feesIndex.machine.totalFee || 0;
+    },
+    'JSCSXMTZRGF': function () {
+        let bill = calcBase.fixedBills[calcBase.fixedFlag.CONSTRUCTION_TECH];
+        if(cbTools.isUnDef(bill)) return 0;
+        if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
+        return bill.feesIndex.adjustLabour.totalFee || 0;
+    },
+    'JSCSXMTZJSRGF': function () {
+        let bill = calcBase.fixedBills[calcBase.fixedFlag.CONSTRUCTION_TECH];
+        if(cbTools.isUnDef(bill)) return 0;
+        if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
+        return bill.feesIndex.adjustMachineLabour.totalFee || 0;
+    },
+    'JSCSXMZCF': function () {
+        let bill = calcBase.fixedBills[calcBase.fixedFlag.CONSTRUCTION_TECH];
+        if(cbTools.isUnDef(bill)) return 0;
+        if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
+        return bill.feesIndex.mainMaterial.totalFee || 0;
+    },
+    'JSCSXMSBF': function () {
+        return 0;
+    },
+    'JSCSXMWJJCLF': function () {
+        return 0;
+    },
+    'JSCSXMRGGR': function () {
+        return 0;
+    },
+    'JSCSXMQDDEJJZJGCF': function () {
+        return this['JSCSXMDEJJRGF']() + this['JSCSXMDEJJCLF']() + this['JSCSXMDEJJJXF']();
+    },
+    'QTXMF': function () {
+        let bill = calcBase.fixedBills[calcBase.fixedFlag.OTHER];
+        if(cbTools.isUnDef(bill)) return 0;
+        if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
+        return bill.feesIndex.common.totalFee || 0;
+    },
+    'GF': function () {
+        let bill = calcBase.fixedBills[calcBase.fixedFlag.CHARGE];
+        if(cbTools.isUnDef(bill)) return 0;
+        if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
+        return bill.feesIndex.common.totalFee || 0;
+    },
+    'SJ': function () {
+        let bill = calcBase.fixedBills[calcBase.fixedFlag.TAX];
+        if(cbTools.isUnDef(bill)) return 0;
+        if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
+        return bill.feesIndex.common.totalFee || 0;
+    }
+};
+
+let baseFigureMap = {
+    '分部分项工程费': 'FBFXGCF',
+    '分部分项定额基价人工费': 'FBFXDEJJRGF',
+    '分部分项定额基价材料费': 'FBFXDEJJCLF',
+    '分部分项定额基价机械费': 'FBFXDEJJJXF',
+    '分部分项调整人工费': 'FBFXTZRGF',
+    '分部分项调整机上人工费': 'FBFXTZJSRGF',
+    '分部分项主材费': 'FBFXZCF',
+    '分部分项设备费': 'FBFXSBF',
+    '分部分项未计价材料费': 'FBFXWJJCLF',
+    '分部分项人工工日': 'FBFXRGGR',
+    '分部分项工程量清单中的基价直接工程费': 'FBFXGCLQDJJZJGCF',
+    '措施项目费': 'CSXMF',
+    '组织措施项目费': 'ZZCSXMF',
+    '组织措施项目定额基价直接工程费': 'ZZCSXMDEJJZJGCF',
+    '组织措施项目定额基价人工费': 'ZZCSXMDEJJRGF',
+    '组织措施项目定额基价材料费': 'ZZCSXMDEJJCLF',
+    '组织措施项目定额基价机械费': 'ZZCSXMDEJJJXF',
+    '技术措施项目费': 'JSCSXMF',
+    '技术措施项目定额基价人工费': 'JSCSXMDEJJRGF',
+    '技术措施项目定额基价材料费': 'JSCSXMDEJJCLF',
+    '技术措施项目定额基价机械费': 'JSCSXMDEJJJXF',
+    '技术措施项目调整人工费': 'JSCSXMTZRGF',
+    '技术措施项目调整机上人工费': 'JSCSXMTZJSRGF',
+    '技术措施项目主材费': 'JSCSXMZCF',
+    '技术措施项目设备费': 'JSCSXMSBF',
+    '技术措施项目未计价材料费': 'JSCSXMWJJCLF',
+    '技术措施项目人工工日': 'JSCSXMRGGR',
+    '技术措施项目清单中的定额基价直接工程费': 'JSCSXMQDDEJJZJGCF',
+    '其他项目费': 'QTXMF',
+    '规费': 'GF',
+    '税金': 'SJ'
+};
+
+//输入式分析器
+let cbAnalyzer = {
+    standar: function (exp) {
+        //去空格
+        exp = exp.replace(/\s/g, '');
+        //( to (
+        exp = exp.replace(/(/g, '(');
+        //)to )
+        exp = exp.replace(/)/g, ')');
+        return exp;
+    },
+    //输入合法性
+    inputLegal: function (exp) {
+        let ilegalRex = /[^0-9,\u4e00-\u9fa5,\+,\-,\/,\*,\(,\),.]/g;
+        return !ilegalRex.test(exp);
+    },
+    //基数合法性、存在性
+    baseLegal: function (baseFigures, exp) {
+        let expFigures = cbParser.getFigure(exp);
+        for(let i = 0, len = expFigures.length; i < len; i++){
+            if(cbTools.isUnDef(baseFigures[expFigures[i]])){
+                return false;
+            }
+        }
+        return true;
+    },
+    //四则运算合法性,前端控制不允许重复出现运算符,这里主要判断()的使用问题,这里再判断一次
+    arithmeticLeagl: function (exp) {
+        let ilegalRex = /[\+,\-,\*,\/]{2}/g;
+        return !ilegalRex.test(exp);
+    },
+    //
+    legalExp: function (exp) {
+        exp = this.standar(exp);
+        if(this.inputLegal(exp)){
+            if(this.baseLegal(calcBase.baseFigures, exp)){
+                if(this.arithmeticLeagl(exp)){
+                    return exp;
+                }
+            }
+            return null;
+        }
+        return null;
+    },
+
+    isCN: function(v){
+        let regex = /[\u4e00-\u9fa5]/g;
+        return (regex.test(v));
+    }
+};
+
+//输入式转换器
+let cbParser = {
+    //获取表达式中的基数
+    getFigure: function(expr){
+        let rst = [];
+        let cnRex = /[^\u4e00-\u9fa5]/;
+        let temp = expr.split(cnRex);
+        for(let i = 0, len = temp.length; i < len; i++){
+            if(temp[i] !== '' && rst.indexOf(temp[i]) === -1){
+                rst.push(temp[i]);
+            }
+        }
+        return rst;
+    },
+
+    //将表达式转换为可编译的表达式
+    toCompileExpr: function(v){
+        let strs = this.getFigure(v);
+        let exps = [];
+        for(let i = 0, len = strs.length; i < len; i++){
+            let exp = Object.create(null);
+            exp.orgExp = strs[i];
+            exps.push(exp);
+        }
+        for(let i = 0, len = exps.length;i < len; i++){
+            exps[i].compileExp = '$CBC.base(\'' + exps[i].orgExp;
+            exps[i].compileExp = exps[i].compileExp + '\')';
+            v = v.replace(new RegExp(exps[i].orgExp,"g"), exps[i].compileExp);
+        }
+        return v;
+    }
+};
+
+let cbCalctor = {
+    //计算基数
+    base: function (figure) {
+        return baseFigureTemplate[calcBase.baseFigures[figure]]();
+    },
+    //计算
+    exec: function () {
+
+    }
+};
+
+let calcBase = {
+    success: false,
+    //清单固定行
+    fixedFlag: null,
+    fixedBills: Object.create(null),
+    //清单基数
+    baseFigures: Object.create(null),
+    //清单可选基数映射,分两类:组织措施项目:排除父项和计算的父项; 其他项目、规费、税金、工程造价,及新增部分:显示所有计算基数
+    baseFigureClass: Object.create(null),
+    //初始化
+    init: function (project) {
+        let me = this;
+        me.project = project;
+        me.fixedFlag = fixedFlag;
+        cbTools.setFixedBills(project, me.fixedBills, me.fixedFlag);
+        me.baseFigures = baseFigureMap;
+        //me.baseFigures.fixedBills = me.fixedBills;
+        cbTools.setBaseFigureClass(me.baseFigures, me.baseFigureClass);
+    },
+    getBase: function (figure) {
+       return  cbCalctor.base(figure);
+
+    },
+    calculate: function (node) {
+        let me = calcBase,
+            $CBA = cbAnalyzer,
+            $CBP = cbParser,
+            $CBC = cbCalctor;
+        try {
+            me.success = false;
+            //分析输入式合法性
+            let exp = $CBA.legalExp(node.data.userCalcBase);
+            if(!exp){
+                throw '表达式不正确';
+            }
+            //输入式转换表达式
+            let compileExp = $CBP.toCompileExpr(exp);
+
+            //计算
+            let calcBaseValue = eval(compileExp);
+            if(!cbTools.isNum(calcBaseValue)){
+                throw '表达式不正确';
+            }
+            //存储
+            me.success = true;
+            node.data.calcBase = exp;
+            node.data.calcBaseValue = parseFloat(calcBaseValue).toDecimal(decimalObj.decimal('totalPrice', node));
+            me.project.calcProgram.calculate(node);
+            me.project.calcProgram.saveNode(node);
+        }
+        catch (err){
+            alert('表达式不正确');
+        }
+    },
+};

+ 121 - 55
web/building_saas/main/js/models/calc_program.js

@@ -6,7 +6,7 @@
  *  用到费率的规则必须有feeRateID属性,当有该属性时,会自动显示费率值。
  *  用到费率的规则必须有feeRateID属性,当有该属性时,会自动显示费率值。
  */
  */
 
 
-let defaultBillTemplate = {
+/*let defaultBillTemplate = {
     ID: 15,
     ID: 15,
     name: "清单公式",
     name: "清单公式",
     calcItems: [
     calcItems: [
@@ -98,7 +98,7 @@ let defaultBillTemplate = {
             memo: ''
             memo: ''
         }
         }
     ]
     ]
-};
+};*/
 
 
 const baseCalcType = {baseCalc: 0, adjustCalc: 1, budgetCalc: 2, diffCalc: 3,  offerCalc: 4};
 const baseCalcType = {baseCalc: 0, adjustCalc: 1, budgetCalc: 2, diffCalc: 3,  offerCalc: 4};
 
 
@@ -327,12 +327,12 @@ let executeObj = {
                             if (base.gljTypes.indexOf(md.glj_type) >= 0) {
                             if (base.gljTypes.indexOf(md.glj_type) >= 0) {
                                 let q = md["consumption"] ? md["consumption"] : 0;
                                 let q = md["consumption"] ? md["consumption"] : 0;
                                 let p = md["base_price"] ? md["base_price"] : 0;
                                 let p = md["base_price"] ? md["base_price"] : 0;
-                                mdSum = mdSum + (q * p).toDecimal(me.digit);
-                                mdSum = (mdSum).toDecimal(me.digitDefault);
+                                mdSum = mdSum + (q * p).toDecimal(decimalObj.process);
+                                mdSum = (mdSum).toDecimal(decimalObj.process);
                             }
                             }
                         };
                         };
-                        result = result + (glj["quantity"] * mdSum).toDecimal(me.digitDefault);
-                        result = (result).toDecimal(me.digitDefault);
+                        result = result + (glj["quantity"] * mdSum).toDecimal(decimalObj.process);
+                        result = (result).toDecimal(decimalObj.process);
                     };
                     };
                 };
                 };
                 return result;
                 return result;
@@ -349,10 +349,10 @@ let executeObj = {
                         else if (base.calcType == baseCalcType.diffCalc){
                         else if (base.calcType == baseCalcType.diffCalc){
                             let aprice = glj["adjustPrice"] ? glj["adjustPrice"] : 0;
                             let aprice = glj["adjustPrice"] ? glj["adjustPrice"] : 0;
                             let mprice = glj["marketPrice"] ? glj["marketPrice"] : 0;
                             let mprice = glj["marketPrice"] ? glj["marketPrice"] : 0;
-                            price = (parseFloat(mprice) - parseFloat(aprice)).toDecimal(me.digitDefault);
+                            price = (parseFloat(mprice) - parseFloat(aprice)).toDecimal(decimalObj.process);
                         };
                         };
-                        result = result + (glj["quantity"] * price).toDecimal(me.digitDefault);
-                        result = (result).toDecimal(me.digitDefault);
+                        result = result + (glj["quantity"] * price).toDecimal(decimalObj.process);
+                        result = (result).toDecimal(decimalObj.process);
                     };
                     };
                 };
                 };
                 return result;
                 return result;
@@ -386,9 +386,9 @@ let executeObj = {
     },
     },
     HJ: function () {
     HJ: function () {
         let me = this;
         let me = this;
-        let p = me.treeNode.data.calcBase ? me.treeNode.data.calcBase : 0;
+        let p = me.treeNode.data.calcBaseValue ? me.treeNode.data.calcBaseValue : 0;
         let q = me.treeNode.data.quantity ? me.treeNode.data.quantity : 1;
         let q = me.treeNode.data.quantity ? me.treeNode.data.quantity : 1;
-        let u = (p / q).toDecimal(me.digit);
+        let u = (p / q).toDecimal(decimalObj.decimal('unitPrice', me.treeNode));
         return u;
         return u;
     }
     }
 };
 };
@@ -411,16 +411,13 @@ class CalcProgram {
 
 
     doAfterUpdate (err, data) {
     doAfterUpdate (err, data) {
         if(!err){
         if(!err){
-            // do
+            $.bootstrapLoading.end();
         }
         }
     };
     };
 
 
     // 经测试,全部编译一次耗时0.003~0.004秒。耗时基本忽略不计。
     // 经测试,全部编译一次耗时0.003~0.004秒。耗时基本忽略不计。
     compileAllTemps(){
     compileAllTemps(){
         let me = this;
         let me = this;
-        me.digit = 2;
-        me.digitDefault = 6;
-
         me.compiledFeeRates = {};
         me.compiledFeeRates = {};
         me.compiledLabourCoes = {};
         me.compiledLabourCoes = {};
         me.compiledTemplates = {};
         me.compiledTemplates = {};
@@ -437,7 +434,7 @@ class CalcProgram {
         me.calcBases = rationCalcBase;
         me.calcBases = rationCalcBase;
         me.templates = this.project.calcProgram.datas.templates;
         me.templates = this.project.calcProgram.datas.templates;
 
 
-        me.templates.push(defaultBillTemplate);
+        // me.templates.push(defaultBillTemplate);
         // 先编译公用的基础数据
         // 先编译公用的基础数据
         me.compilePublics();
         me.compilePublics();
         for (let t of me.templates){
         for (let t of me.templates){
@@ -598,7 +595,30 @@ class CalcProgram {
                treeNode.source.children.length === 0;
                treeNode.source.children.length === 0;
     };
     };
 
 
-    // 仅内部调用。注意:外部不能直接使用,因为这里传入的树节点必须有一定的初始化。
+    isNullBill(treeNode){
+        let me = this;
+        return me.isLeafBill(treeNode) && (treeNode.children.length ===0) && (!treeNode.data.calcBase);
+    };
+
+    initFeeField(treeNode, fieldName){
+        if (!treeNode.data.fees) {
+            treeNode.data.fees = [];
+            treeNode.data.feesIndex = {};
+        };
+        if (!treeNode.data.feesIndex[fieldName]) {
+            let fee = {
+                'fieldName': fieldName,
+                'unitFee': 0,
+                'totalFee': 0,
+                'tenderUnitFee': 0,
+                'tenderTotalFee': 0
+            };
+            treeNode.data.fees.push(fee);
+            treeNode.data.feesIndex[fieldName] = fee;
+        };
+    };
+
+  // 仅内部调用。注意:外部不能直接使用,因为这里传入的树节点必须有一定的初始化。
     InnerCalc(treeNode){
     InnerCalc(treeNode){
         let me = this;
         let me = this;
         let project = me.project;
         let project = me.project;
@@ -660,10 +680,10 @@ class CalcProgram {
                     for (let item of objsArr) {
                     for (let item of objsArr) {
                         let data = item.data;
                         let data = item.data;
                         if (data.feesIndex && data.feesIndex[ft.type]) {
                         if (data.feesIndex && data.feesIndex[ft.type]) {
-                            buf = (buf + parseFloat(data.feesIndex[ft.type].unitFee)).toDecimal(me.digitDefault);
-                            btf = (btf + parseFloat(data.feesIndex[ft.type].totalFee)).toDecimal(me.digitDefault);
-                            btuf = (btuf + parseFloat(data.feesIndex[ft.type].tenderUnitFee)).toDecimal(me.digitDefault);
-                            bttf = (bttf + parseFloat(data.feesIndex[ft.type].tenderTotalFee)).toDecimal(me.digitDefault);
+                            buf = (buf + parseFloatPlus(data.feesIndex[ft.type].unitFee)).toDecimal(decimalObj.process);
+                            btf = (btf + parseFloatPlus(data.feesIndex[ft.type].totalFee)).toDecimal(decimalObj.process);
+                            btuf = (btuf + parseFloatPlus(data.feesIndex[ft.type].tenderUnitFee)).toDecimal(decimalObj.process);
+                            bttf = (bttf + parseFloatPlus(data.feesIndex[ft.type].tenderTotalFee)).toDecimal(decimalObj.process);
                         };
                         };
                     };
                     };
                 }
                 }
@@ -682,54 +702,93 @@ class CalcProgram {
                             rttf = parseFloat(data.feesIndex[ft.type].tenderTotalFee);
                             rttf = parseFloat(data.feesIndex[ft.type].tenderTotalFee);
                         };
                         };
 
 
-                        if (me.project.projSetting.billsCalcMode === leafBillGetFeeType.rationContent) {
-                            buf = (buf + (ruf * rq / bq).toDecimal(2)).toDecimal(2);
-                            btuf = (btuf + (rtuf * rq / bq).toDecimal(2)).toDecimal(2);
+                        if (me.project.property.billsCalcMode === leafBillGetFeeType.rationContent) {
+                            buf = (buf + (ruf * rq / bq).toDecimal(decimalObj.process)).toDecimal(decimalObj.process);
+                            btuf = (btuf + (rtuf * rq / bq).toDecimal(decimalObj.process)).toDecimal(decimalObj.process);
                         };
                         };
 
 
-                        sum_rtf = (sum_rtf + rtf).toDecimal(2);
-                        sum_rttf = (sum_rttf + rttf).toDecimal(2);
+                        sum_rtf = (sum_rtf + rtf).toDecimal(decimalObj.process);
+                        sum_rttf = (sum_rttf + rttf).toDecimal(decimalObj.process);
                     };
                     };
 
 
-                    if (me.project.projSetting.billsCalcMode === leafBillGetFeeType.rationPrice || me.project.projSetting.billsCalcMode === leafBillGetFeeType.rationPriceConverse) {
-                        buf = (sum_rtf / bq).toDecimal(2);
-                        btuf = (sum_rttf / bq).toDecimal(2);
+                    if (me.project.property.billsCalcMode === leafBillGetFeeType.rationPriceConverse || me.project.property.billsCalcMode === leafBillGetFeeType.rationPrice) {
+                        buf = (sum_rtf / bq).toDecimal(decimalObj.process);
+                        btuf = (sum_rttf / bq).toDecimal(decimalObj.process);
                     };
                     };
-                    if (isBaseFeeType(ft.type) || (me.project.projSetting.billsCalcMode === leafBillGetFeeType.rationPriceConverse && ft.type == "common")){
+                    if (isBaseFeeType(ft.type) || (me.project.property.billsCalcMode === leafBillGetFeeType.rationPrice && ft.type == "common")){
                         btf = sum_rtf;
                         btf = sum_rtf;
                         bttf = sum_rttf;
                         bttf = sum_rttf;
                     }
                     }
                     else{
                     else{
-                        btf = (buf * bq).toDecimal(2);
-                        bttf = (btuf * bq).toDecimal(2);
+                        btf = (buf * bq).toDecimal(decimalObj.process);
+                        bttf = (btuf * bq).toDecimal(decimalObj.process);
                     };
                     };
                 };
                 };
 
 
-                ftObj.unitFee = buf;
-                ftObj.totalFee = btf;
-                ftObj.tenderUnitFee = btuf;
-                ftObj.tenderTotalFee = bttf;
+                ftObj.unitFee = buf.toDecimal(decimalObj.bills.unitPrice);
+                ftObj.totalFee = btf.toDecimal(decimalObj.bills.totalPrice);
+                ftObj.tenderUnitFee = btuf.toDecimal(decimalObj.bills.unitPrice);
+                ftObj.tenderTotalFee = bttf.toDecimal(decimalObj.bills.totalPrice);
                 checkFee(treeNode, ftObj);
                 checkFee(treeNode, ftObj);
 
 
                 rst.push(ftObj);
                 rst.push(ftObj);
             };
             };
             treeNode.data.calcTemplate = {"calcItems": rst};
             treeNode.data.calcTemplate = {"calcItems": rst};
         }
         }
+        // 叶子清单的手工综合单价计算
+        else if (treeNode.calcType == treeNodeCalcType.ctCommonUnitFee){
+            delete treeNode.data.gljList;
+            if (treeNode.data.calcBase) treeNode.data.calcBase = null;  // 不能直接删除该属性,否则无法冲掉库中已存储的值
+            if (treeNode.data.calcBaseValue) treeNode.data.calcBaseValue = null;  // 不能直接删除该属性,否则无法冲掉库中已存储的值
+            if (treeNode.data.programID) treeNode.data.programID = null;
+
+            let uf = (treeNode.data.feesIndex && treeNode.data.feesIndex.common && treeNode.data.feesIndex.common.unitFee) ? treeNode.data.feesIndex.common.unitFee : 0;
+            let tuf = (treeNode.data.feesIndex && treeNode.data.feesIndex.common && treeNode.data.feesIndex.common.tenderUnitFee) ? treeNode.data.feesIndex.common.tenderUnitFee : 0;
+            let q = treeNode.data.quantity ? treeNode.data.quantity : 0;
+            let tf = (uf * q).toDecimal(decimalObj.bills.totalPrice);
+            let ttf = (tuf * q).toDecimal(decimalObj.bills.totalPrice);
+
+            delete treeNode.data.fees;    // 直接删掉再新增,不用一个个费判断更新,效率更高。
+            delete treeNode.data.feesIndex;
+            me.initFeeField(treeNode, 'common');
+            treeNode.data.feesIndex.common.unitFee = uf.toDecimal(decimalObj.bills.unitPrice);
+            treeNode.data.feesIndex.common.totalFee = tf.toDecimal(decimalObj.bills.totalPrice);
+            treeNode.data.feesIndex.common.tenderUnitFee = tuf.toDecimal(decimalObj.bills.unitPrice);
+            treeNode.data.feesIndex.common.tenderTotalFee = ttf.toDecimal(decimalObj.bills.totalPrice);
+            treeNode.changed = true;
+            treeNode.data.calcTemplate = {"calcItems": []};
+        }
+        // 叶子清单的计算基数计算
+        else if (treeNode.calcType == treeNodeCalcType.ctCalcBaseValue){
+            delete treeNode.data.gljList;
+            if (treeNode.data.programID) treeNode.data.programID = null;
+
+            let f = treeNode.data.feeRate ? treeNode.data.feeRate : 100;
+            let q = treeNode.data.quantity ? treeNode.data.quantity : 0;
+            let b = treeNode.data.calcBaseValue ? treeNode.data.calcBaseValue : 0;
+            let uf = (b * f * q / 100).toDecimal(decimalObj.bills.unitPrice);
+            let tuf = uf;
+            let tf = (me.project.property.billsCalcMode === leafBillGetFeeType.rationPrice) ? (b * f / 100).toDecimal(decimalObj.bills.totalPrice) : (uf * q).toDecimal(decimalObj.bills.totalPrice);
+            let ttf = tf;
+
+            delete treeNode.data.fees;    // 直接删掉再新增,不用一个个费判断更新,效率更高。
+            delete treeNode.data.feesIndex;
+            me.initFeeField(treeNode, 'common');
+            treeNode.data.feesIndex.common.unitFee = uf;
+            treeNode.data.feesIndex.common.totalFee = tf;
+            treeNode.data.feesIndex.common.tenderUnitFee = tuf;
+            treeNode.data.feesIndex.common.tenderTotalFee = ttf;
+            treeNode.changed = true;
+            treeNode.data.calcTemplate = {"calcItems": []};
+        }
+        // 定额或清单自己的计算程序计算
         else{
         else{
-            // 叶子清单的公式计算:使用缺省清单计算程序。需要提供总金额作为计算基数(不需要工料机),然后每条按比例(费率)计算,不需要工料机明细。
-            if (treeNode.calcType == treeNodeCalcType.ctCalcBaseValue){
-                delete treeNode.data.gljList;
-
-                if (treeNode.data.programID == undefined){
-                    treeNode.data.programID = defaultBillTemplate.ID;
-                };
-            }
-            else if (treeNode.calcType == treeNodeCalcType.ctRationCalcProgram) {
+            if (treeNode.calcType == treeNodeCalcType.ctRationCalcProgram) {
                 if (treeNode.data.type == rationType.volumePrice){
                 if (treeNode.data.type == rationType.volumePrice){
                     delete treeNode.data.gljList;
                     delete treeNode.data.gljList;
                     let muf = treeNode.data.marketUnitFee ? treeNode.data.marketUnitFee : 0;
                     let muf = treeNode.data.marketUnitFee ? treeNode.data.marketUnitFee : 0;
                     let q = treeNode.data.quantity ? treeNode.data.quantity : 0;
                     let q = treeNode.data.quantity ? treeNode.data.quantity : 0;
-                    treeNode.data.marketTotalFee = (muf * q).toDecimal(me.digit);
+                    treeNode.data.marketTotalFee = (muf * q).toDecimal(decimalObj.ration.totalPrice);
                 }
                 }
                 else if (treeNode.data.type == rationType.gljRation){
                 else if (treeNode.data.type == rationType.gljRation){
 
 
@@ -746,7 +805,8 @@ class CalcProgram {
                 let rations = project.Ration.getBillsSortRation(treeNode.source.getID());
                 let rations = project.Ration.getBillsSortRation(treeNode.source.getID());
                 treeNode.data.gljList = project.ration_glj.getGatherGljArrByRations(rations);
                 treeNode.data.gljList = project.ration_glj.getGatherGljArrByRations(rations);
 
 
-                if (treeNode.data.programID == undefined || treeNode.data.programID == defaultBillTemplate.ID){
+                // if (treeNode.data.programID == undefined || treeNode.data.programID == defaultBillTemplate.ID){
+                if (treeNode.data.programID == undefined){
                     treeNode.data.programID = projectInfoObj.projectInfo.property.engineering;
                     treeNode.data.programID = projectInfoObj.projectInfo.property.engineering;
                 }
                 }
             };
             };
@@ -767,11 +827,11 @@ class CalcProgram {
 
 
                     let feeRate = calcItem.feeRate;
                     let feeRate = calcItem.feeRate;
                     if (!feeRate) feeRate = 100;    // 100%
                     if (!feeRate) feeRate = 100;    // 100%
-                    calcItem.unitFee = (eval(calcItem.compiledExpr) * feeRate * 0.01).toDecimal(me.digit);   // 如果eval()对清单树有影响,就换成小麦的Expression对象再试
+                    calcItem.unitFee = (eval(calcItem.compiledExpr) * feeRate * 0.01).toDecimal(decimalObj.decimal('unitPrice', treeNode));   // 如果eval()对清单树有影响,就换成小麦的Expression对象再试
 
 
                     let quantity = treeNode.data.quantity;
                     let quantity = treeNode.data.quantity;
                     if (!quantity) quantity = 0;
                     if (!quantity) quantity = 0;
-                    calcItem.totalFee = (calcItem.unitFee * quantity).toDecimal(me.digit);
+                    calcItem.totalFee = (calcItem.unitFee * quantity).toDecimal(decimalObj.decimal('totalPrice', treeNode));
 
 
                     checkFee(treeNode, calcItem);
                     checkFee(treeNode, calcItem);
                 };
                 };
@@ -782,20 +842,21 @@ class CalcProgram {
     // 计算本节点(默认同时递归计算所有父节点,可选)
     // 计算本节点(默认同时递归计算所有父节点,可选)
     calculate(treeNode, calcParents = true){
     calculate(treeNode, calcParents = true){
         let me = this;
         let me = this;
-
         let isRation = treeNode.sourceType === me.project.Ration.getSourceType();
         let isRation = treeNode.sourceType === me.project.Ration.getSourceType();
         let isBill = treeNode.sourceType === me.project.Bills.getSourceType();
         let isBill = treeNode.sourceType === me.project.Bills.getSourceType();
-        let isBillPriceCalc = me.project.projSetting.billsCalcMode === leafBillGetFeeType.billsPrice;
-        let isLeafBill = me.isLeafBill(treeNode);
 
 
         if (isRation){
         if (isRation){
             treeNode.calcType = treeNodeCalcType.ctRationCalcProgram;
             treeNode.calcType = treeNodeCalcType.ctRationCalcProgram;
         }
         }
-        else if (isLeafBill) {
+        else  if (me.isNullBill(treeNode)){
+            treeNode.calcType = treeNodeCalcType.ctCommonUnitFee;
+        }
+        else if (me.isLeafBill(treeNode)) {
             if (treeNode.children && treeNode.children.length > 0){
             if (treeNode.children && treeNode.children.length > 0){
                 // me.calcLeafBillChildren(treeNode);
                 // me.calcLeafBillChildren(treeNode);
 
 
-                if (isBillPriceCalc)                        // 清单单价计算模式下的叶子清单:取自己的计算程序ID,找到自己的计算程序计算。(汇总清单所有定额的工料机)
+                // 清单单价计算模式下的叶子清单:取自己的计算程序ID,找到自己的计算程序计算。(汇总清单所有定额的工料机)
+                if (me.project.property.billsCalcMode === leafBillGetFeeType.billsPrice)
                     treeNode.calcType = treeNodeCalcType.ctBillCalcProgram;
                     treeNode.calcType = treeNodeCalcType.ctBillCalcProgram;
                 else                                        // 前三种计算模式下的叶子清单:汇总定额的计算程序的费用类别
                 else                                        // 前三种计算模式下的叶子清单:汇总定额的计算程序的费用类别
                     treeNode.calcType = treeNodeCalcType.ctGatherRationsFees;
                     treeNode.calcType = treeNodeCalcType.ctGatherRationsFees;
@@ -841,14 +902,19 @@ class CalcProgram {
                 let data = {
                 let data = {
                     ID: node.data.ID,
                     ID: node.data.ID,
                     projectID: me.project.ID(),
                     projectID: me.project.ID(),
+                    /*  subType、quantity、calcBase、programID、marketUnitFee等等字段较为特殊,它们的改变一定会触发计算并导致计算
+                    结果的变化,从而引发保存动作。将这些字段放在该位置跟计算结果一起保存,可减少前端跟后端的通讯频率。              */
                     subType: node.data.subType,
                     subType: node.data.subType,
                     quantity: node.data.quantity,
                     quantity: node.data.quantity,
                     calcBase: node.data.calcBase,
                     calcBase: node.data.calcBase,
+                    calcBaseValue: node.data.calcBaseValue,
                     programID: node.data.programID,
                     programID: node.data.programID,
                     marketUnitFee: node.data.marketUnitFee,
                     marketUnitFee: node.data.marketUnitFee,
                     marketTotalFee: node.data.marketTotalFee,
                     marketTotalFee: node.data.marketTotalFee,
                     fees: node.data.fees,
                     fees: node.data.fees,
-                    isFromDetail:node.data.isFromDetail
+                    isFromDetail:node.data.isFromDetail,
+                    feeRate: node.data.feeRate,
+                    feeRateID: node.data.feeRateID
                 };
                 };
                 let newData = {'updateType': 'ut_update', 'updateData': data};
                 let newData = {'updateType': 'ut_update', 'updateData': data};
                 me.project.push(node.sourceType, [newData]);
                 me.project.push(node.sourceType, [newData]);

+ 36 - 21
web/building_saas/main/js/models/fee_rate.js

@@ -50,6 +50,7 @@ var FeeRate = {
             }
             }
         };
         };
         FeeRate.prototype.getFeeRateByID=function (ID) {
         FeeRate.prototype.getFeeRateByID=function (ID) {
+            ID=parseInt(ID);
             var rates = this.getActivateFeeRate().rates;
             var rates = this.getActivateFeeRate().rates;
             return _.find(rates,{'ID':ID})
             return _.find(rates,{'ID':ID})
         };
         };
@@ -123,12 +124,13 @@ var FeeRate = {
                 rateIndex:params.sourceIndex,
                 rateIndex:params.sourceIndex,
                 rate:params.dataItem
                 rate:params.dataItem
             }
             }
-            doc.rate.rate =doc.rate.rate.toDecimal(feeRate_consts.decimal);
+            doc.rate.rate =doc.rate.rate.toDecimal(getDecimal("feeRate"));
             this.updateFeeRate(query,doc);
             this.updateFeeRate(query,doc);
             if(this.ifRateChange(params)){
             if(this.ifRateChange(params)){
                 //this.synchronizeFeeRate();
                 //this.synchronizeFeeRate();
                 this.onFeeRateChange(params.dataItem.ID,params.dataItem.rate);
                 this.onFeeRateChange(params.dataItem.ID,params.dataItem.rate);
             }
             }
+            $.bootstrapLoading.end();
         };
         };
 
 
         FeeRate.prototype.batchUpdateFeeRate = function (items,feerate) {
         FeeRate.prototype.batchUpdateFeeRate = function (items,feerate) {
@@ -190,6 +192,7 @@ var FeeRate = {
                     calcProgramObj.showData(node);
                     calcProgramObj.showData(node);
                 }
                 }
             }
             }
+            project.calcProgram.calcAllNodes(calcAllType.catBills);
             socket.emit('feeRateChangeNotify', this.getActivateFeeRateFileID());
             socket.emit('feeRateChangeNotify', this.getActivateFeeRateFileID());
         };
         };
         FeeRate.prototype.onFeeRateFileChange=function () {
         FeeRate.prototype.onFeeRateFileChange=function () {
@@ -201,6 +204,7 @@ var FeeRate = {
                     calcProgramObj.showData(node);
                     calcProgramObj.showData(node);
                 }
                 }
             }
             }
+            project.calcProgram.calcAllNodes(calcAllType.catBills);
             socket.emit('feeRateChangeNotify', this.getActivateFeeRateFileID());
             socket.emit('feeRateChangeNotify', this.getActivateFeeRateFileID());
         };
         };
 
 
@@ -211,7 +215,7 @@ var FeeRate = {
                     if(n.data.hasOwnProperty("feeRateID")&&n.data.feeRateID){
                     if(n.data.hasOwnProperty("feeRateID")&&n.data.feeRateID){
                         var rate = me.getFeeRateByID(n.data.feeRateID);
                         var rate = me.getFeeRateByID(n.data.feeRateID);
                         if(rate){
                         if(rate){
-                            n.data.feeRate=number_util.roundToString(rate.rate,feeRate_consts.decimal);
+                            n.data.feeRate=number_util.roundToString(rate.rate,getDecimal("feeRate"));
                             return true;
                             return true;
                         }else {
                         }else {
                             n.data.feeRate=null;
                             n.data.feeRate=null;
@@ -256,7 +260,7 @@ var FeeRate = {
         FeeRate.prototype.refreshBillsByRateID=function(rateID,value){
         FeeRate.prototype.refreshBillsByRateID=function(rateID,value){
             var nodes = _.filter(projectObj.project.mainTree.items,function (n) {
             var nodes = _.filter(projectObj.project.mainTree.items,function (n) {
                 if(n.sourceType==ModuleNames.bills&&n.data.feeRateID==rateID){
                 if(n.sourceType==ModuleNames.bills&&n.data.feeRateID==rateID){
-                    n.data.feeRate=number_util.roundToString(value,feeRate_consts.decimal);
+                    n.data.feeRate=number_util.roundToString(value,getDecimal("feeRate"));
                     return true;
                     return true;
                 }else {
                 }else {
                     return false;
                     return false;
@@ -338,19 +342,23 @@ var FeeRate = {
         FeeRate.prototype.updateFeeRateFromBills=function(value,node){
         FeeRate.prototype.updateFeeRateFromBills=function(value,node){
             var me =this;
             var me =this;
             if(node.sourceType === project.Bills.getSourceType()){
             if(node.sourceType === project.Bills.getSourceType()){
-                var value= number_util.checkNumberValue(value,feeRate_consts.decimal);
-                if(value){
+                var fee_value= number_util.checkNumberValue(value,getDecimal("feeRate"));
+                if(fee_value!=null){
                     var bill = node.data;
                     var bill = node.data;
                     var rate =me.getFeeRateByID(bill.feeRateID);
                     var rate =me.getFeeRateByID(bill.feeRateID);
-                    var data=me.getfbUpdateData(rate,bill,value);
+                    var data=me.getfbUpdateData(rate,bill,fee_value,value);
+                    if(data==null){//只更改清单的值的情况下,由计算程序更新
+                        project.calcProgram.calculate(node);
+                        project.calcProgram.saveNode(node);
+                    }
                     this.setFeeRateToBill(data,function (result) {
                     this.setFeeRateToBill(data,function (result) {
                         if(data.hasOwnProperty('feeRate')){
                         if(data.hasOwnProperty('feeRate')){
-                            rate.rate=value;
-                            me.onFeeRateChange(rate.ID,value);
-                        }else {
+                            rate.rate=fee_value;
+                            me.onFeeRateChange(rate.ID,fee_value);
+                        }/*else {
                             bill.feeRate=value;
                             bill.feeRate=value;
                             projectObj.mainController.refreshTreeNode([node])
                             projectObj.mainController.refreshTreeNode([node])
-                        }
+                        }*/
                     });
                     });
                 }else {
                 }else {
                     projectObj.mainController.refreshTreeNode([node]);
                     projectObj.mainController.refreshTreeNode([node]);
@@ -359,7 +367,7 @@ var FeeRate = {
         };
         };
 
 
         FeeRate.prototype.updateFeeRateFromCalc=function (value,editInfo) {
         FeeRate.prototype.updateFeeRateFromCalc=function (value,editInfo) {
-            var value= number_util.checkNumberValue(value,feeRate_consts.decimal);
+            var value= number_util.checkNumberValue(value,getDecimal("feeRate"));
             if(value){
             if(value){
                 if(editInfo.calcItem.feeRateID){
                 if(editInfo.calcItem.feeRateID){
                     var rate = projectObj.project.FeeRate.getFeeRateByID(editInfo.calcItem.feeRateID);
                     var rate = projectObj.project.FeeRate.getFeeRateByID(editInfo.calcItem.feeRateID);
@@ -396,9 +404,10 @@ var FeeRate = {
             });
             });
         }
         }
 
 
-        FeeRate.prototype.getfbUpdateData=function (rate,bill,value) {
-            var data={};
-            if(bill.feeRateID){
+        FeeRate.prototype.getfbUpdateData=function (rate,bill,value,editText) {
+            var data=null;
+            if(bill.feeRateID&&editText!=null){
+                data = {};
                 data.feeRate={
                 data.feeRate={
                     query:{
                     query:{
                         'ID':this.getActivateFeeRateID(),
                         'ID':this.getActivateFeeRateID(),
@@ -408,8 +417,12 @@ var FeeRate = {
                         'rates.$.rate':value
                         'rates.$.rate':value
                     }
                     }
                 }
                 }
-            }else {
-                data.bills={
+            }else  if(editText==null){
+                bill.feeRateID = null;
+                bill.feeRate =null;
+            }else { //这里只改变当前清单的费率值,不在这里提交后台,交给计算程序处理。
+                bill["feeRate"]=value
+              /*  data.bills={
                     query:{
                     query:{
                         ID:bill.ID,
                         ID:bill.ID,
                         projectID:bill.projectID,
                         projectID:bill.projectID,
@@ -418,7 +431,7 @@ var FeeRate = {
                     doc:{
                     doc:{
                         feeRate:value
                         feeRate:value
                     }
                     }
-                }
+                }*/
             }
             }
             return data;
             return data;
         };
         };
@@ -462,15 +475,17 @@ var FeeRate = {
        
        
 
 
         FeeRate.prototype.setFeeRateToBill=function(data,callback){
         FeeRate.prototype.setFeeRateToBill=function(data,callback){
-            CommonAjax.post('/feeRates/setFeeRateToBill', data, function (data) {
-                callback(data);
-            });
+            if(data){
+                CommonAjax.post('/feeRates/setFeeRateToBill', data, function (data) {
+                    callback(data);
+                });
+            }
         };
         };
         FeeRate.prototype.loadFeeRateToBill=function (node) {
         FeeRate.prototype.loadFeeRateToBill=function (node) {
             if(node.data.feeRateID){
             if(node.data.feeRateID){
                 var feeRate = this.getFeeRateByID(node.data.feeRateID);
                 var feeRate = this.getFeeRateByID(node.data.feeRateID);
                 if(feeRate){
                 if(feeRate){
-                    node.data.feeRate=number_util.roundToString(feeRate.rate,feeRate_consts.decimal);// parseFloat(feeRate.rate).toFixed(feeRate_consts.decimal);
+                    node.data.feeRate=number_util.roundToString(feeRate.rate,getDecimal("feeRate"));// parseFloat(feeRate.rate).toFixed(feeRate_consts.decimal);
                 }
                 }
             }
             }
         };
         };

+ 8 - 7
web/building_saas/main/js/models/main_consts.js

@@ -12,7 +12,6 @@ const ModuleNames = {
     ration_ass:'ration_ass',
     ration_ass:'ration_ass',
     quantity_detail:'quantity_detail',
     quantity_detail:'quantity_detail',
     // volume_price: 'volume_price',
     // volume_price: 'volume_price',
-    projectGLJ: 'project_glj',
     labour_coe: 'labour_coe',
     labour_coe: 'labour_coe',
     calc_program: 'calc_program'
     calc_program: 'calc_program'
 };
 };
@@ -48,9 +47,6 @@ const gljType = {
     EQUIPMENT: 5
     EQUIPMENT: 5
 };
 };
 
 
-const feeRate_consts={
-    decimal:3
-};
 
 
 const CP_Col_Width = {          // 多处计算程序界面的列宽统一设置
 const CP_Col_Width = {          // 多处计算程序界面的列宽统一设置
     rowHeader: 30,
     rowHeader: 30,
@@ -72,7 +68,8 @@ const treeNodeCalcType = {
     ctBillCalcProgram: 2,       // 汇总清单下所有定额的工料机
     ctBillCalcProgram: 2,       // 汇总清单下所有定额的工料机
     ctGatherRationsFees: 3,     // 汇总定额的各个费
     ctGatherRationsFees: 3,     // 汇总定额的各个费
     ctGatherBillsFees: 4,       // 汇总清单的各个费
     ctGatherBillsFees: 4,       // 汇总清单的各个费
-    ctCalcBaseValue: 5
+    ctCalcBaseValue: 5,
+    ctCommonUnitFee: 6
 };
 };
 
 
 const calcAllType = {
 const calcAllType = {
@@ -119,8 +116,12 @@ const rationType = {
 
 
 const leafBillGetFeeType = {
 const leafBillGetFeeType = {
     rationContent: 0,
     rationContent: 0,
-    rationPrice: 1,
-    rationPriceConverse: 2,
+    rationPriceConverse: 1,
+    rationPrice: 2,
     billsPrice: 3
     billsPrice: 3
 };
 };
 
 
+const zanguCalcMode = {
+    common: 0,
+    gatherMaterial: 1
+};

+ 12 - 13
web/building_saas/main/js/models/project.js

@@ -39,6 +39,8 @@ var PROJECT = {
                 } else if (item.moduleName === me.projSetting) {
                 } else if (item.moduleName === me.projSetting) {
                     me._project.projSetting = item.data;
                     me._project.projSetting = item.data;
                     me._project.projSetting.moduleName = me.projSetting;
                     me._project.projSetting.moduleName = me.projSetting;
+                }else if(item.moduleName === ModuleNames.projectGLJ){
+                    me._project.projectGLJ.loadToCache(item.data);
                 }
                 }
             });
             });
             for (module in counter) {
             for (module in counter) {
@@ -79,18 +81,12 @@ var PROJECT = {
             this.FeeRate = FeeRate.createNew(this);
             this.FeeRate = FeeRate.createNew(this);
             // this.VolumePrice = VolumePrice.createNew(this);
             // this.VolumePrice = VolumePrice.createNew(this);
             this.projectGLJ = new ProjectGLJ();
             this.projectGLJ = new ProjectGLJ();
-            this.projectGLJ.loadData();
+           // this.projectGLJ.loadData();
             this.composition = new Composition();
             this.composition = new Composition();
             this.composition.loadData();
             this.composition.loadData();
-            this.Decimal = {
-                common: {
-                    quantity: 4,
-                    unitFee: 2,
-                    totalFee: 2
-                }
-            };
             this.labourCoe = new LabourCoe(this);
             this.labourCoe = new LabourCoe(this);
             this.calcProgram = new CalcProgram(this);
             this.calcProgram = new CalcProgram(this);
+            this.calcBase = calcBase;
 
 
             // this.masterField = {ration: 'billsItemID', volumePrice: 'billsItemID'};
             // this.masterField = {ration: 'billsItemID', volumePrice: 'billsItemID'};
             this.masterField = {ration: 'billsItemID'};
             this.masterField = {ration: 'billsItemID'};
@@ -294,21 +290,23 @@ var PROJECT = {
         };
         };
 
 
         project.prototype.setBillsCalcMode = function (calcMode) {
         project.prototype.setBillsCalcMode = function (calcMode) {
-            this.projSetting.billsCalcMode = calcMode;
+            this.property.billsCalcMode = calcMode;
             this.initCalcFields();
             this.initCalcFields();
         };
         };
 
 
         project.prototype.initCalcFields = function () {
         project.prototype.initCalcFields = function () {
-            let settingConst = this.projSetting.settingConst;
+            // let settingConst = this.projSetting.settingConst;
             if (this.calcFields) {
             if (this.calcFields) {
                 for (let field of this.calcFields) {
                 for (let field of this.calcFields) {
                     // unitFeeCalcFlag
                     // unitFeeCalcFlag
                     if (field.type === 'zangu') {
                     if (field.type === 'zangu') {
                         field.unitFeeFlag = converseUnitFeeFlag;
                         field.unitFeeFlag = converseUnitFeeFlag;
                     } else {   
                     } else {   
-                        if (this.projSetting.billsCalcMode === settingConst.billsCalcMode.rationContent) {
+                        // if (this.projSetting.billsCalcMode === settingConst.billsCalcMode.rationContent) {
+                        if (this.property.billsCalcMode === leafBillGetFeeType.rationContent) {
                             field.unitFeeFlag = rationContentUnitFeeFlag;
                             field.unitFeeFlag = rationContentUnitFeeFlag;
-                        } else if ( this.projSetting.billsCalcMode === settingConst.billsCalcMode.billsPrice) {
+                        // } else if ( this.projSetting.billsCalcMode === settingConst.billsCalcMode.billsPrice) {
+                        } else if ( this.property.billsCalcMode === leafBillGetFeeType.billsPrice) {
                             field.unitFeeFlag = billsPriceUnitFeeFlag;
                             field.unitFeeFlag = billsPriceUnitFeeFlag;
                         } else {
                         } else {
                             field.unitFeeFlag = averageQtyUnitFeeFlag;
                             field.unitFeeFlag = averageQtyUnitFeeFlag;
@@ -316,7 +314,8 @@ var PROJECT = {
                     }
                     }
                     // totalFeeCalcFlag
                     // totalFeeCalcFlag
                     if (field.type === 'common') {
                     if (field.type === 'common') {
-                        if (this.projSetting.billsCalcMode === settingConst.billsCalcMode.rationPriceConverse) {
+                        // if (this.projSetting.billsCalcMode === settingConst.billsCalcMode.rationPriceConverse) {
+                        if (this.property.billsCalcMode === leafBillGetFeeType.rationPriceConverse) {
                             field.totalFeeFlag = sumTotalFeeFlag;
                             field.totalFeeFlag = sumTotalFeeFlag;
                         } else {
                         } else {
                             field.totalFeeFlag = totalFeeFlag;
                             field.totalFeeFlag = totalFeeFlag;

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

@@ -51,6 +51,12 @@ ProjectGLJ.prototype.loadData = function (callback = null) {
     });
     });
 };
 };
 
 
+ProjectGLJ.prototype.loadToCache = function (data) {
+    this.datas = data;
+    projectObj.project.projectGLJ=this;
+}
+
+
 /**
 /**
  * 获取对应工料机数据
  * 获取对应工料机数据
  *
  *

+ 330 - 0
web/building_saas/main/js/views/calc_base_view.js

@@ -0,0 +1,330 @@
+/**
+ * Created by Zhong on 2017/12/1.
+ */
+/*
+* 清单计算基数
+* */
+let calcBaseView = {
+    //可用计算基数的清单固定列映射(与fixedFlag)
+    inputExpr: $('#calcBaseExp'),
+    confirmBtn: $('#calcBaseConf'),
+    noBaseBills: [1, 3],
+    editingCell: null,
+    workBook: null,
+    setting:{
+        header: [
+            {name: '计算基础名称', dataCode: 'base', width: 280, vAlign: 'center', hAlign: 'left'},
+            {name: '金额', dataCode: 'price', width: 120, vAlign: 'center', hAlign: 'left'}
+        ],
+        options: {
+            tabStripVisible:  false,
+            allowCopyPasteExcelStyle : false,
+            allowExtendPasteRange: false,
+            allowUserDragDrop : false,
+            allowUserDragFill: false,
+            scrollbarMaxAlign : true
+        },
+        dateRows: [],
+        locked: {
+            rows: [],
+            cols: [0, 1]
+        }
+    },
+
+    renderSheetFuc: function (sheet, fuc) {
+        sheet.suspendPaint();
+        sheet.suspendEvent();
+        fuc();
+        sheet.resumePaint();
+        sheet.resumeEvent();
+    },
+
+    setOptions: function (workbook, opts) {
+        for(let opt in opts){
+            workbook.options[opt] = opts[opt];
+        }
+    },
+
+    buildHeader: function (sheet, headers) {
+        let me = calcBaseView;
+        let fuc = function () {
+            sheet.options.clipBoardOptions = GC.Spread.Sheets.ClipboardPasteOptions.values;
+            sheet.options.isProtected = true;
+            sheet.setColumnCount(headers.length);
+            sheet.setRowHeight(0, 40, GC.Spread.Sheets.SheetArea.colHeader);
+            for(let i = 0, len = headers.length; i < len; i++){
+                sheet.setValue(0, i, headers[i].name, GC.Spread.Sheets.SheetArea.colHeader);
+                sheet.setColumnWidth(i, headers[i].width, GC.Spread.Sheets.SheetArea.colHeader);
+            }
+        };
+        me.renderSheetFuc(sheet, fuc);
+    },
+
+    buildSheet: function () {
+        if(!this.workBook){
+            this.workBook = new GC.Spread.Sheets.Workbook($('#billsBaseSpread')[0], {sheetCount: 1});
+            this.setOptions(this.workBook, this.setting.options);
+            this.buildHeader(this.workBook.getActiveSheet(), this.setting.header);
+            this.bindEvent(this.workBook);
+        }
+    },
+
+    bindEvent: function (workBook) {
+        const _events = GC.Spread.Sheets.Events;
+        let sheet = workBook.getActiveSheet();
+        sheet.bind(_events.CellDoubleClick, this.onCellDoubleClick);
+    },
+
+    showData(datas){
+        let me = calcBaseView;
+        let sheet = this.workBook.getActiveSheet();
+        let cols = this.setting.header;
+        let fuc = function () {
+            sheet.setRowCount(datas.length);
+            sheet.setFormatter(-1, 1, '@');
+            for(let col = 0, cLen = cols.length; col < cLen; col++){
+                sheet.getRange(-1, col, -1, 1).hAlign(GC.Spread.Sheets.HorizontalAlign[cols[col]['hAlign']]);
+                sheet.getRange(-1, col, -1, 1).hAlign(GC.Spread.Sheets.VerticalAlign[cols[col]['vAlign']]);
+                for(let row = 0, rLen = datas.length; row < rLen; row++){
+                    sheet.setValue(row, col, datas[row][cols[col]['dataCode']]);
+                }
+            }
+        };
+        this.renderSheetFuc(sheet, fuc);
+    },
+
+    onCellDoubleClick: function (sender, args) {
+        let me = calcBaseView;
+        if(args.col === 0){
+            let baseFigure = args.sheet.getValue(args.row, args.col);
+            if(baseFigure.trim() !== ''){
+                //在光标后面插入
+                let insertStr = me.insertStr(baseFigure);
+                me.inputExpr.val(insertStr);
+            }
+        }
+        me.inputExpr.focus();
+    },
+    isDef: function (v) {
+        return v !== undefined && v !== null;
+    },
+    isFlag: function (v) {
+        return this.isDef(v.flagsIndex) && this.isDef(v.flagsIndex.fixed);
+    },
+    ifEdit: function () {
+        var selected = projectObj.project.mainTree.selected;
+        return MainTreeCol.readOnly.forCalcBase(selected)?false:true;
+    },
+    canBase: function (node) {
+        return node.sourceType === projectObj.project.Bills.getSourceType() && node.children.length === 0;
+    },
+    //根据节点获取可用计算基数
+    getFigure: function (node) {
+        let calcBase = projectObj.project.calcBase;
+        let parent = node.parent;
+        if(this.isFlag(node.data) && (node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.SUB_ENGINERRING
+            || node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.CONSTRUCTION_TECH)){
+            return null;
+        }
+        else if(this.isFlag(node.data) && node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.CONSTRUCTION_ORGANIZATION){
+            return calcBase.baseFigureClass.CONSTRUCTION_ORGANIZATION;
+        }
+        else if(this.isFlag(node.data) && node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.OTHER){
+            return calcBase.baseFigureClass.OTHER;
+        }
+        else if(this.isFlag(node.data) && node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.CHARGE){
+            return calcBase.baseFigureClass.CHARGE;
+        }
+        else if(this.isFlag(node.data) && node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.TAX){
+            return calcBase.baseFigureClass.TAX;
+        }
+        else {
+            if(!parent){
+                return calcBase.baseFigureClass.OTHERS;
+            }
+            else {
+                return this.getFigure(parent);
+            }
+        }
+    },
+    //计算基数转换为显示数据Obj to Array
+    toViewData: function (obj) {
+        let rst = [];
+        for(let figure in obj){
+            let figureObj = Object.create(null);
+            figureObj.base = figure;
+            figureObj.price = projectObj.project.calcBase.getBase(figure);
+            rst.push(figureObj);
+        }
+        return rst;
+    },
+
+    initCalctor: function (node) {
+        let me = calcBaseView;
+        //输入框显示原本的
+        if(me.isDef(node.data.calcBase)){
+            me.inputExpr.val(node.data.calcBase);
+        }
+        me.buildSheet();
+        let baseObj = me.getFigure(node);
+        me.showData(me.toViewData(baseObj));
+
+    },
+
+    getInputExpr: function () {
+        return this.inputExpr.val();
+    },
+
+    //四则运算符控制,不可连续出现: ++ +*...
+    arithmeticLeagl: function (v) {
+        let rex = /[\+,\-,\*,\/]{2}/g;
+        return !rex.test(v);
+    },
+
+    //运算符点击显示到运算窗口
+    clickOpr: function (operators) {
+        let me = calcBaseView;
+        for(let i = 0, len = operators.length; i < len; i++){
+            operators[i].bind('click', function () {
+                let v = $(this)[0].textContent;
+                let insertStr = me.insertStr(v);
+                if(me.arithmeticLeagl(insertStr)){
+                    me.inputExpr.val(insertStr);
+                }
+                me.inputExpr.focus();
+            });
+        }
+    },
+
+    //光标处插入(替换选中)
+    insertStr: function (v) {
+        let me = calcBaseView;
+        //在光标后面插入
+        let exp = me.getInputExpr();
+        let startIdx = me.inputExpr[0].selectionStart;
+        let endIdx = me.inputExpr[0].selectionEnd;
+        let startStr = exp.substring(0, startIdx);
+        let endStr = exp.substring(endIdx, exp.length);
+        return startStr + v + endStr;
+    },
+
+    //输入窗口控制
+    inputControl: function () {
+        let me = calcBaseView;
+        me.inputExpr.keydown(function (e) {
+            if(!me.arithmeticLeagl(me.inputExpr.val() + e.key)){
+                return false;
+            }
+        });
+    },
+
+    //确认按钮
+    calcBaseConf: function () {
+        let me = calcBaseView;
+        me.confirmBtn.bind('click', function () {
+            let selected = projectObj.project.mainTree.selected;
+            selected.data.userCalcBase = me.getInputExpr();
+            projectObj.project.calcBase.calculate(selected);
+            if(projectObj.project.calcBase.success){
+                $('#qd-jsjs').modal('hide');
+            }
+        });
+    },
+
+    getCalcBaseCellType:function () {
+        var ns = GC.Spread.Sheets;
+        function CalcBaseCellType() {
+            var init=false;
+        }
+        CalcBaseCellType.prototype = new ns.CellTypes.Text();
+        CalcBaseCellType.prototype.paint = function (ctx, value, x, y, w, h, style, options) {
+            if(value!=null){
+                // ctx.fillText(value,x+3+ctx.measureText(value).width,y+h-3);
+                ctx.fillText(value,x+w,y+h-3);
+            }
+            if(calcBaseView.editingCell){
+                if(calcBaseView.editingCell.row==options.row&&calcBaseView.editingCell.col==options.col){
+                    var image = document.getElementById('f_btn'),imageMagin = 3;
+                    var imageHeight = h-2*imageMagin;
+                    var imageWidth = w*2/7;
+                    var imageX = x + w - imageWidth- imageMagin, imageY = y + h / 2 - imageHeight / 2;
+                    ctx.save();
+                    ctx.drawImage(image, imageX, imageY,imageWidth,imageHeight);
+                    ctx.beginPath();
+                    ctx.arc(imageX+imageWidth/2,imageY+imageHeight/2,1,0,360,false);
+                    ctx.arc(imageX+imageWidth/2-4,imageY+imageHeight/2,1,0,360,false);
+                    ctx.arc(imageX+imageWidth/2+4,imageY+imageHeight/2,1,0,360,false);
+                    ctx.fillStyle="black";//填充颜色,默认是黑色
+                    ctx.fill();//画实心圆
+                    ctx.closePath();
+                    ctx.restore();
+                }
+            }
+        };
+        CalcBaseCellType.prototype.getHitInfo = function (x, y, cellStyle, cellRect, context) {
+            return {
+                x: x,
+                y: y,
+                row: context.row,
+                col: context.col,
+                cellStyle: cellStyle,
+                cellRect: cellRect,
+                sheetArea: context.sheetArea
+            };
+        };
+        CalcBaseCellType.prototype.processMouseDown = function (hitinfo) {
+            let me=calcBaseView;
+            if(me.editingCell==null){
+                var showSelectBtn = true;
+                if(hitinfo.sheet.name()!='calc_detail'){
+                    showSelectBtn=me.ifEdit();
+                }
+                if(showSelectBtn){
+                    me.editingCell={
+                        row:hitinfo.row,
+                        col:hitinfo.col
+                    }
+                    hitinfo.sheet.invalidateLayout();
+                    hitinfo.sheet.repaint();
+                }
+            }else if(hitinfo.row==me.editingCell.row){
+                var offset=hitinfo.cellRect.x+hitinfo.cellRect.width-6;
+                var imageMagin=3;
+                var imageHeight = hitinfo.cellRect.height-2*imageMagin;
+                var imageWidth = hitinfo.cellRect.width*2/7;
+                if(hitinfo.x<offset&&hitinfo.x>offset-imageWidth){
+                    $('#qd-jsjs').modal({show: true});
+                }
+            }
+        };
+        CalcBaseCellType.prototype.processMouseLeave = function (hitinfo) {
+            calcBaseView.editingCell=null;
+            hitinfo.sheet.invalidateLayout();
+            hitinfo.sheet.repaint();
+        }
+        return new CalcBaseCellType();
+    },
+};
+
+$(document).ready(function () {
+   $('#qd-jsjs').on('shown.bs.modal', function () {
+       calcBaseView.initCalctor(projectObj.project.mainTree.selected);
+       calcBaseView.workBook.refresh();
+   });
+
+    $('#qd-jsjs').on('hidden.bs.modal', function () {
+        //清空输入框
+        calcBaseView.inputExpr.val('');
+        calcBaseView.workBook.destroy();
+        calcBaseView.workBook = null;
+    });
+
+    //bind operator click function
+    calcBaseView.clickOpr([$('#addOpr'), $('#subOpr'), $('#mulOpr'), $('#divOpr'), $('#leftOpr'), $('#rightOpr')]);
+
+    //bind input control
+    calcBaseView.inputControl();
+
+    //confirmBtn
+    calcBaseView.calcBaseConf();
+});

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

@@ -26,7 +26,7 @@ let rationPM = {
             {headerName:"费用代号",headerWidth:CP_Col_Width.code, dataCode:"code", dataType: "String"},
             {headerName:"费用代号",headerWidth:CP_Col_Width.code, dataCode:"code", dataType: "String"},
             {headerName:"费用名称",headerWidth:CP_Col_Width.name, dataCode:"name", dataType: "String"},
             {headerName:"费用名称",headerWidth:CP_Col_Width.name, dataCode:"name", dataType: "String"},
             {headerName:"计算基数",headerWidth:CP_Col_Width.dispExprUser, dataCode:"dispExprUser", dataType: "String"},
             {headerName:"计算基数",headerWidth:CP_Col_Width.dispExprUser, dataCode:"dispExprUser", dataType: "String"},
-            {headerName:"费率",headerWidth:CP_Col_Width.feeRate, dataCode:"feeRate", dataType: "Number",hAlign: "right",tofix: feeRate_consts.decimal},
+            {headerName:"费率",headerWidth:CP_Col_Width.feeRate, dataCode:"feeRate", dataType: "Number",hAlign: "right",decimalField:"feeRate"},
             {headerName:"费用类别",headerWidth:CP_Col_Width.displayFieldName, dataCode:"displayFieldName", dataType: "String", hAlign: "center"},
             {headerName:"费用类别",headerWidth:CP_Col_Width.displayFieldName, dataCode:"displayFieldName", dataType: "String", hAlign: "center"},
             {headerName:"基数说明",headerWidth:CP_Col_Width.statement, dataCode:"statement", dataType: "String"},
             {headerName:"基数说明",headerWidth:CP_Col_Width.statement, dataCode:"statement", dataType: "String"},
             {headerName:"备注",headerWidth:CP_Col_Width.memo, dataCode:"memo", dataType: "String"}
             {headerName:"备注",headerWidth:CP_Col_Width.memo, dataCode:"memo", dataType: "String"}

+ 15 - 10
web/building_saas/main/js/views/fee_rate_view.js

@@ -19,7 +19,7 @@ var feeRateObject={
     sheetSetting: {
     sheetSetting: {
         header: [
         header: [
             {headerName: "专业名称", headerWidth: 200, dataCode: "name", dataType: "String"},
             {headerName: "专业名称", headerWidth: 200, dataCode: "name", dataType: "String"},
-            {headerName: "值%", headerWidth: 150, dataCode: "rate", dataType: "Number",hAlign: "right",tofix:feeRate_consts.decimal},
+            {headerName: "值%", headerWidth: 150, dataCode: "rate", dataType: "Number",hAlign: "right",decimalField:"feeRate"},
             {headerName: "备注", dataCode: "memo", dataType: "String"}
             {headerName: "备注", dataCode: "memo", dataType: "String"}
         ],
         ],
         view: {
         view: {
@@ -39,7 +39,6 @@ var feeRateObject={
             id: 'rate',
             id: 'rate',
             caption: '值%',
             caption: '值%',
             dataField: 'rate',
             dataField: 'rate',
-            format: '0.000',
             width: 120,
             width: 120,
             minWidth: 50,
             minWidth: 50,
             allowEditing: true
             allowEditing: true
@@ -113,7 +112,6 @@ var feeRateObject={
             if(!$('#cascadeSet').prop('checked')||params.hasOwnProperty('viewIndex')){
             if(!$('#cascadeSet').prop('checked')||params.hasOwnProperty('viewIndex')){
                 projectObj.project.FeeRate.updateFeeRateByEdit(params,feeRateObject.activateFeeRate);
                 projectObj.project.FeeRate.updateFeeRateByEdit(params,feeRateObject.activateFeeRate);
             }
             }
-
         }
         }
     },
     },
     createSheet:function(){
     createSheet:function(){
@@ -151,10 +149,12 @@ var feeRateObject={
             for (var row = 0; row < data.length; row++) {
             for (var row = 0; row < data.length; row++) {
                 var val = data[row][setting.header[col].dataCode];
                 var val = data[row][setting.header[col].dataCode];
                 if(val&&setting.header[col].dataType === "Number"){
                 if(val&&setting.header[col].dataType === "Number"){
-                    if(setting.header[col].hasOwnProperty('tofix')){
-                        val =parseFloat(val).toFixed(setting.header[col].tofix);
+                    if(setting.header[col].hasOwnProperty('decimalField')){
+                        var decimal = getDecimal(setting.header[col].decimalField);
+                        val =scMathUtil.roundToString(val,decimal);
+                        sheet.setFormatter(-1, col,getFormatter(decimal), GC.Spread.Sheets.SheetArea.viewport);
                     }else {
                     }else {
-                        val =parseFloat(val).toFixed(2);
+                        val =scMathUtil.roundToString(val,2);
                     }
                     }
                 }
                 }
                 sheet.setValue(row, col, val, ch);
                 sheet.setValue(row, col, val, ch);
@@ -253,7 +253,7 @@ var feeRateObject={
         FeeRateEditCellType.prototype.paint = function (ctx, value, x, y, w, h, style, options) {
         FeeRateEditCellType.prototype.paint = function (ctx, value, x, y, w, h, style, options) {
             if(value!=null){
             if(value!=null){
                // ctx.fillText(value,x+3+ctx.measureText(value).width,y+h-3);
                // ctx.fillText(value,x+3+ctx.measureText(value).width,y+h-3);
-                ctx.fillText(value,x+w,y+h-3);
+                ctx.fillText(value,x+w-3,y+h-3);
             }
             }
             if(feeRateObject.editingCell){
             if(feeRateObject.editingCell){
                 if(feeRateObject.editingCell.row==options.row&&feeRateObject.editingCell.col==options.col){
                 if(feeRateObject.editingCell.row==options.row&&feeRateObject.editingCell.col==options.col){
@@ -345,7 +345,7 @@ var feeRateObject={
     },
     },
     ifFeeRateEdit:function () {
     ifFeeRateEdit:function () {
         var selected = projectObj.project.mainTree.selected;
         var selected = projectObj.project.mainTree.selected;
-        return MainTreeCol.readOnly.forCalcBase(selected)?false:true;
+        return MainTreeCol.readOnly.forFeeRate(selected)?false:true;
     },
     },
     createSpreadView:function () {
     createSpreadView:function () {
         if (this.mainViews) {
         if (this.mainViews) {
@@ -358,6 +358,8 @@ var feeRateObject={
         }
         }
         this.activateFeeRate = projectObj.project.FeeRate.getActivateFeeRate();
         this.activateFeeRate = projectObj.project.FeeRate.getActivateFeeRate();
         this.datas = this.activateFeeRate.rates;
         this.datas = this.activateFeeRate.rates;
+        var rateColSetting = _.find(this.columns,{"id":"rate"});
+        rateColSetting?rateColSetting.format=getFormatter(getDecimal("feeRate")):"";
         this.mainViews = new GC.Spread.Views.DataView($('#divFee')[0],
         this.mainViews = new GC.Spread.Views.DataView($('#divFee')[0],
             this.dataSource, this.columns, new GC.Spread.Views.Plugins.GridLayout(this.options));
             this.dataSource, this.columns, new GC.Spread.Views.Plugins.GridLayout(this.options));
         this.mainViews["rowClick"].addHandler(subRateObject.reFreshRateViews);
         this.mainViews["rowClick"].addHandler(subRateObject.reFreshRateViews);
@@ -648,8 +650,11 @@ var feeRateObject={
        var selected = projectObj.project.mainTree.selected;
        var selected = projectObj.project.mainTree.selected;
         projectObj.project.FeeRate.submitFeeRateFromBill(rate,selected.data,function (data) {
         projectObj.project.FeeRate.submitFeeRateFromBill(rate,selected.data,function (data) {
             selected.data.feeRateID=rate.ID.toString();
             selected.data.feeRateID=rate.ID.toString();
-            selected.data.feeRate=parseFloat(rate.rate).toFixed(feeRate_consts.decimal);
-            projectObj.mainController.refreshTreeNode([selected]);
+            selected.data.feeRate=scMathUtil.roundToString(rate.rate,getDecimal("feeRate"));
+            selected.changed = true;
+            projectObj.project.calcProgram.calculate(selected);
+            projectObj.project.calcProgram.saveNode(selected);
+            //projectObj.mainController.refreshTreeNode([selected]);
             $("#fee_rate_tree").modal('hide');
             $("#fee_rate_tree").modal('hide');
         });
         });
     },
     },

+ 51 - 16
web/building_saas/main/js/views/glj_view.js

@@ -18,10 +18,6 @@ var gljOprObj = {
     selectedGLJClass:null,
     selectedGLJClass:null,
     parentNodeIds:{},
     parentNodeIds:{},
     activeTab:'#linkGLJ',
     activeTab:'#linkGLJ',
-    decimalSetting:{
-        marketPrice:2,
-        customQuantity:3
-    },
     setting: {
     setting: {
         header: [
         header: [
             {headerName: "编码", headerWidth: 100, dataCode: "code", dataType: "String", formatter: "@"},
             {headerName: "编码", headerWidth: 100, dataCode: "code", dataType: "String", formatter: "@"},
@@ -29,12 +25,13 @@ var gljOprObj = {
             {headerName: "规格型号", headerWidth: 120, dataCode: "specs", dataType: "String", hAlign: "left"},
             {headerName: "规格型号", headerWidth: 120, dataCode: "specs", dataType: "String", hAlign: "left"},
             {headerName: "单位", headerWidth: 45, dataCode: "unit", dataType: "String", hAlign: "center"},
             {headerName: "单位", headerWidth: 45, dataCode: "unit", dataType: "String", hAlign: "center"},
             {headerName: "类型", headerWidth: 45, dataCode: "shortName", dataType: "String", hAlign: "center"},
             {headerName: "类型", headerWidth: 45, dataCode: "shortName", dataType: "String", hAlign: "center"},
-            {headerName: "定额消耗", headerWidth: 80, dataCode: "rationItemQuantity", dataType: "Number", hAlign: "right",decimalField:"glj.quantity"},    // dataType: "Number", formatter: "0.00"
-            {headerName: "自定消耗", headerWidth: 80, dataCode: "customQuantity", dataType: "Number", hAlign: "right",decimalField:"glj.quantity"},
+            {headerName: "定额消耗", headerWidth: 80, dataCode: "rationItemQuantity", dataType: "Number", hAlign: "right",decimalField:"glj.quantity"},    // dataType: "Number", formatter: "0.00"
+            {headerName: "自定消耗", headerWidth: 80, dataCode: "customQuantity", dataType: "Number", hAlign: "right",decimalField:"glj.quantity"},
             {headerName: "消耗量", headerWidth: 80, dataCode: "quantity", dataType: "Number", hAlign: "right",decimalField:"glj.quantity"},
             {headerName: "消耗量", headerWidth: 80, dataCode: "quantity", dataType: "Number", hAlign: "right",decimalField:"glj.quantity"},
-            {headerName: "基价单价", headerWidth: 80, dataCode: "basePrice", dataType: "Number", hAlign: "right",decimalField:"glj.unitPrice"},
-            {headerName: "调整基价", headerWidth: 80, dataCode: "adjustPrice", dataType: "Number", hAlign: "right",decimalField:"glj.unitPrice"},
-            {headerName: "市场单价", headerWidth: 80, dataCode: "marketPrice", dataType: "Number", hAlign: "right",decimalField:"glj.unitPrice"},
+            {headerName: "总消耗量", headerWidth: 80, dataCode: "totalQuantity", dataType: "Number", hAlign: "right",decimalField:"glj.quantity"},
+            {headerName: "定额价", headerWidth: 80, dataCode: "basePrice", dataType: "Number", hAlign: "right",decimalField:"glj.unitPrice"},
+            {headerName: "调整价", headerWidth: 80, dataCode: "adjustPrice", dataType: "Number", hAlign: "right",decimalField:"glj.unitPrice"},
+            {headerName: "市场价", headerWidth: 80, dataCode: "marketPrice", dataType: "Number", hAlign: "right",decimalField:"glj.unitPrice"},
             {headerName: "是否暂估", headerWidth: 65, dataCode: "isEstimate", dataType: "String", hAlign: "center",vAlign:"center",cellType:"checkBox"}
             {headerName: "是否暂估", headerWidth: 65, dataCode: "isEstimate", dataType: "String", hAlign: "center",vAlign:"center",cellType:"checkBox"}
         ],
         ],
         view: {
         view: {
@@ -68,7 +65,7 @@ var gljOprObj = {
         header:[
         header:[
             {headerName: "名称", headerWidth: 100, dataCode: "name", dataType: "String"},
             {headerName: "名称", headerWidth: 100, dataCode: "name", dataType: "String"},
             {headerName: "计算式", headerWidth: 120, dataCode: "regex", dataType: "String"},
             {headerName: "计算式", headerWidth: 120, dataCode: "regex", dataType: "String"},
-            {headerName: "结果(C)", headerWidth: 120, dataCode: "result", dataType: "Number",formatter:"0.0000",tofix:4},
+            {headerName: "结果(C)", headerWidth: 120, dataCode: "result", dataType: "Number",decimalField:"quantity_detail"},
             {headerName: "累加", headerWidth: 120, dataCode: "isSummation", dataType: "String",cellType:"checkBox"}
             {headerName: "累加", headerWidth: 120, dataCode: "isSummation", dataType: "String",cellType:"checkBox"}
         ],
         ],
         view:{
         view:{
@@ -541,6 +538,8 @@ var gljOprObj = {
      //   $('#dropdown').hide();
      //   $('#dropdown').hide();
     },
     },
     showRationGLJData:function (node) {
     showRationGLJData:function (node) {
+        console.log("showRationGLJData");
+        console.log(+new Date());
         var gljList = [];
         var gljList = [];
         var ration_glj = projectObj.project.ration_glj;
         var ration_glj = projectObj.project.ration_glj;
         node=node?node:projectObj.project.mainTree.selected;
         node=node?node:projectObj.project.mainTree.selected;
@@ -551,12 +550,24 @@ var gljOprObj = {
         }
         }
     },
     },
     showRationGLJSheetData:function (init) {
     showRationGLJSheetData:function (init) {
-        this.sheet.getRange(0,-1,this.sheet.getRowCount(),-1).visible(true);
+        this.sheet.setRowCount(0);
+        console.log("showRationGLJSheetData---init")
+        console.log(+new Date())
+        //this.sheet.getRange(0,-1,this.sheet.getRowCount(),-1).visible(true); //这个方法导致加载缓慢
         this.sheetData=_.sortBy(this.sheetData,'type');
         this.sheetData=_.sortBy(this.sheetData,'type');
-        this.addMixRatioToShow();
+        console.log("addMixRatioToShow");
+        console.log(+new Date())
+        this.sumQuantity();//计算总消耗量
+        this.addMixRatioToShow();//显示组成物信息
+        console.log("start initRationTree");
+        console.log(+new Date());
         this.initRationTree(init);
         this.initRationTree(init);
-        sheetCommonObj.showData(this.sheet,this.setting,this.sheetData);
+        console.log("end initRationTree");
+        console.log(+new Date());
 
 
+        sheetCommonObj.showData(this.sheet,this.setting,this.sheetData);
+        console.log("end show");
+        console.log(+new Date())
     },
     },
     initRationTree:function (init) {
     initRationTree:function (init) {
         this.sheet.getRange(-1, 0, -1, 1).cellType(this.getTreeNodeCellType(this.sheetData));
         this.sheet.getRange(-1, 0, -1, 1).cellType(this.getTreeNodeCellType(this.sheetData));
@@ -569,7 +580,11 @@ var gljOprObj = {
                 }else {
                 }else {
                     collapsed = this.sheetData[i].collapsed==undefined?true:this.sheetData[i].collapsed;
                     collapsed = this.sheetData[i].collapsed==undefined?true:this.sheetData[i].collapsed;
                 }
                 }
-                this.sheet.getRange(i+1, -1, this.sheetData[i].subList.length, -1).visible(!collapsed);// this.sheet.getRange(i+1, -1, this.sheetData[i].subList.length, -1).locked(true);
+                if(collapsed==true){
+                    this.sheet.getRange(i+1, -1, this.sheetData[i].subList.length, -1).visible(false);
+                }
+                //this.sheet.getRange(i+1, -1, this.sheetData[i].subList.length, -1).visible(!collapsed);// this.sheet.getRange(i+1, -1, this.sheetData[i].subList.length, -1).locked(true);
+                //这个方法导致加载缓慢
             }
             }
         }
         }
     },
     },
@@ -584,6 +599,25 @@ var gljOprObj = {
         this.sheetData=this.combineWithProjectGlj(gljList);
         this.sheetData=this.combineWithProjectGlj(gljList);
         this.showRationGLJSheetData(true);
         this.showRationGLJSheetData(true);
     },
     },
+    sumQuantity:function (node) {
+      if(this.sheetData.length>0){
+          node=node?node:projectObj.project.mainTree.selected;
+          let ration = node.data;
+          let quantity = ration.quantity;
+          quantity = (quantity==0||quantity==undefined||quantity==null||quantity=="")?1:quantity;
+          for(let glj of this.sheetData){
+              if(glj.isMixRatio==true){//如果是用于显示的组成物,则不用计算,跳过
+                  continue;
+              }
+              glj.totalQuantity = scMathUtil.roundToString(quantity*glj.quantity,getDecimal("glj.quantity"));
+              if(glj.hasOwnProperty('subList')){//需要计算glj下挂的组成物的总消耗量
+                  for(let subG of glj.subList){
+                      subG.totalQuantity = scMathUtil.roundToString(subG.rationItemQuantity*glj.totalQuantity,getDecimal("glj.quantity"));
+                  }
+              }
+          }
+      }
+    },
     addMixRatioToShow:function () {
     addMixRatioToShow:function () {
         var newList=[];
         var newList=[];
         _.remove(this.sheetData,{'isMixRatio':true});
         _.remove(this.sheetData,{'isMixRatio':true});
@@ -722,7 +756,8 @@ var gljOprObj = {
             if(args.editingText==null){
             if(args.editingText==null){
                 newval="";
                 newval="";
             }else {
             }else {
-                newval = number_util.checkNumberValue(args.editingText,this.decimalSetting[updateField]);
+                var decimal = updateField=='customQuantity'?getDecimal("glj.quantity"):getDecimal("glj.unitPrice");
+                newval = number_util.checkNumberValue(args.editingText,decimal);
                 if(newval==null){
                 if(newval==null){
                     me.sheet.getCell(args.row, args.col).value(recode[updateField]);
                     me.sheet.getCell(args.row, args.col).value(recode[updateField]);
                     return;
                     return;
@@ -1246,7 +1281,7 @@ $(function(){
 function getDecimal(fieldID,node) {
 function getDecimal(fieldID,node) {
     if(node){
     if(node){
         return decimalObj.decimal(fieldID,node);
         return decimalObj.decimal(fieldID,node);
-    }else if(fieldID.indexOf(".")){
+    }else if(fieldID.indexOf(".")!=-1){
         var keyArray = fieldID.split(".");
         var keyArray = fieldID.split(".");
         return decimalObj[keyArray[0]][keyArray[1]];
         return decimalObj[keyArray[0]][keyArray[1]];
     }else {
     }else {

+ 76 - 21
web/building_saas/main/js/views/main_tree_col.js

@@ -30,19 +30,47 @@ let MainTreeCol = {
         }
         }
     },
     },
     readOnly: {
     readOnly: {
+        // CSL, 2017-11-28
         subType: function (node){
         subType: function (node){
             return (node.data.type != 2 && node.data.type != 3);
             return (node.data.type != 2 && node.data.type != 3);
         },
         },
-        // CSL, 2017-11-28
         calcProgramName: function (node) {
         calcProgramName: function (node) {
             if (
             if (
                 node.sourceType === projectObj.project.Ration.getSourceType() ||
                 node.sourceType === projectObj.project.Ration.getSourceType() ||
-                (projectObj.project.calcProgram.isLeafBill(node) && projectObj.project.projSetting.billsCalcMode === leafBillGetFeeType.billsPrice)
+                (projectObj.project.calcProgram.isLeafBill(node) && projectObj.project.property.billsCalcMode === leafBillGetFeeType.billsPrice)
             ) return false
             ) return false
             else return true;
             else return true;
         },
         },
 
 
-        bills: function (node) {
+        commonUnitFee: function(node){
+            return !projectObj.project.calcProgram.isNullBill(node);
+        },
+        //根据节点、父节点类型判断是否可用计算基数
+        calcBaseType: function (node) {
+            function isDef (v) {
+                return v !== undefined && v !== null;
+            }
+            function isFlag (v) {
+                return this.isDef(v.flagsIndex) && this.isDef(v.flagsIndex.fixed);
+            }
+            let calcBase = projectObj.project.calcBase;
+            let parent = node.parent;
+            if(isFlag(node.data) && (node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.SUB_ENGINERRING
+                || node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.CONSTRUCTION_TECH)){
+                return true;
+            }
+            else if(isFlag(node.data) && node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.CONSTRUCTION_ORGANIZATION){
+                return false;
+            }
+            else {
+                if(!parent){
+                    return false;
+                }
+                else {
+                    return this.calcBaseType(parent);
+                }
+            }
+        },        bills: function (node) {
             return node.sourceType === projectObj.project.Bills.getSourceType();
             return node.sourceType === projectObj.project.Bills.getSourceType();
         },
         },
         ration: function (node) {
         ration: function (node) {
@@ -68,7 +96,7 @@ let MainTreeCol = {
         },
         },
         forCalcBase: function (node) {
         forCalcBase: function (node) {
             // to do according to billsParentType
             // to do according to billsParentType
-            return MainTreeCol.readOnly.billsParent(node) || MainTreeCol.readOnly.non_bills(node)||MainTreeCol.readOnly.leafBillsWithDetail(node);
+            return MainTreeCol.readOnly.billsParent(node) || MainTreeCol.readOnly.non_bills(node)||MainTreeCol.readOnly.leafBillsWithDetail(node) ||MainTreeCol.readOnly.calcBaseType(node);
         },
         },
         forUnitFee: function (node) {
         forUnitFee: function (node) {
             return MainTreeCol.readOnly.ration(node) || MainTreeCol.readOnly.billsParent(node) || MainTreeCol.readOnly.leafBillsWithDetail(node);
             return MainTreeCol.readOnly.ration(node) || MainTreeCol.readOnly.billsParent(node) || MainTreeCol.readOnly.leafBillsWithDetail(node);
@@ -78,6 +106,9 @@ let MainTreeCol = {
         },
         },
         forQuantifyDetail:function (node) {
         forQuantifyDetail:function (node) {
             return !(node.sourceType==ModuleNames.ration||!MainTreeCol.readOnly.billsParent(node));
             return !(node.sourceType==ModuleNames.ration||!MainTreeCol.readOnly.billsParent(node));
+        },
+        forFeeRate:function (node) {
+            return MainTreeCol.readOnly.non_bills(node)||MainTreeCol.readOnly.billsParent(node)||MainTreeCol.readOnly.leafBillsWithDetail(node)
         }
         }
     },
     },
     cellType: {
     cellType: {
@@ -96,11 +127,15 @@ let MainTreeCol = {
             return feeRateObject.getFeeRateEditCellType();
             return feeRateObject.getFeeRateEditCellType();
         },
         },
 
 
+        calcBase: function () {
+            return calcBaseView.getCalcBaseCellType();
+        },
+
         // CSL, 2017-11-28
         // CSL, 2017-11-28
         calcProgramName: function (node) {
         calcProgramName: function (node) {
             if (
             if (
                 node.sourceType === projectObj.project.Ration.getSourceType() ||
                 node.sourceType === projectObj.project.Ration.getSourceType() ||
-                (projectObj.project.calcProgram.isLeafBill(node) && projectObj.project.projSetting.billsCalcMode === leafBillGetFeeType.billsPrice)
+                (projectObj.project.calcProgram.isLeafBill(node) && projectObj.project.property.billsCalcMode === leafBillGetFeeType.billsPrice)
             ) {
             ) {
                 var names = new GC.Spread.Sheets.CellTypes.ComboBox();
                 var names = new GC.Spread.Sheets.CellTypes.ComboBox();
                 names.items(projectObj.project.calcProgram.compiledTemplateNames);
                 names.items(projectObj.project.calcProgram.compiledTemplateNames);
@@ -138,22 +173,42 @@ let MainTreeCol = {
             return event;
             return event;
         }
         }
     },
     },
-    getNumberFormatter: function (digit) {
-        switch (digit) {
-            case 1:
-                return '0.#';
-            case 2:
-                return '0.##';
-            case 3:
-                return '0.###';
-            case 4:
-                return '0.####';
-            case 5:
-                return '0.#####';
-            case 6:
-                return '0.######';
-            default:
-                return '0.##';
+    getNumberFormatter: function (digit, align) {    // CSL, 2017-11-30 扩展:小数点是否对齐。
+        if (align) {
+            switch (digit) {
+                case 1:
+                    return '0.0';
+                case 2:
+                    return '0.00';
+                case 3:
+                    return '0.000';
+                case 4:
+                    return '0.0000';
+                case 5:
+                    return '0.00000';
+                case 6:
+                    return '0.000000';
+                default:
+                    return '0.00';
+            };
+        }
+        else{
+            switch (digit) {
+                case 1:
+                    return '0.#';
+                case 2:
+                    return '0.##';
+                case 3:
+                    return '0.###';
+                case 4:
+                    return '0.####';
+                case 5:
+                    return '0.#####';
+                case 6:
+                    return '0.######';
+                default:
+                    return '0.##';
+            };
         }
         }
     }
     }
 };
 };

+ 4 - 2
web/building_saas/main/js/views/project_info.js

@@ -12,9 +12,11 @@ var projectInfoObj = {
                 if (i <= proj.fullFolder.length - 3) {
                 if (i <= proj.fullFolder.length - 3) {
                     fullPath.push(angleRight, '<span class="text-truncate" data-toggle="tooltip" data-placement="bottom" title="', proj.fullFolder[i], '"><i class="fa fa-folder-open-o"></i></span>');
                     fullPath.push(angleRight, '<span class="text-truncate" data-toggle="tooltip" data-placement="bottom" title="', proj.fullFolder[i], '"><i class="fa fa-folder-open-o"></i></span>');
                 } else if (i === proj.fullFolder.length - 2) {
                 } else if (i === proj.fullFolder.length - 2) {
-                    fullPath.push(angleRight, '<span class="text-truncate" data-toggle="tooltip" data-placement="bottom" title="' + proj.fullFolder[i] + '"><i class="fa fa-cubes"></i>' + proj.fullFolder[i] + '</span>');
+                    // 屏蔽原有代码 不显示中间内容
+                    // fullPath.push(angleRight, '<span class="text-truncate" data-toggle="tooltip" data-placement="bottom" title="' + proj.fullFolder[i] + '"><i class="fa fa-cubes"></i>' + proj.fullFolder[i] + '</span>');
                 } else if (i === proj.fullFolder.length - 1) {
                 } else if (i === proj.fullFolder.length - 1) {
-                    fullPath.push(angleRight, '<span class="text-truncate" data-toggle="tooltip" data-placement="bottom" title="' + proj.fullFolder[i] + '"><i class="fa fa-cube"></i>' + proj.fullFolder[i] + '</span>');
+                    // 屏蔽原有代码 不显示中间内容
+                    // fullPath.push(angleRight, '<span class="text-truncate" data-toggle="tooltip" data-placement="bottom" title="' + proj.fullFolder[i] + '"><i class="fa fa-cube"></i>' + proj.fullFolder[i] + '</span>');
                 }
                 }
             }
             }
             fullPath.push(angleRight, '<span class="text-truncate" data-toggle="tooltip" data-placement="bottom" title="' + proj.name + '"><i class="fa fa-sticky-note-o"></i>' + proj.name + '</span>');
             fullPath.push(angleRight, '<span class="text-truncate" data-toggle="tooltip" data-placement="bottom" title="' + proj.name + '"><i class="fa fa-sticky-note-o"></i>' + proj.name + '</span>');

+ 2 - 8
web/building_saas/main/js/views/project_property_basicInfo.js

@@ -142,7 +142,6 @@ let basicInfoView = {
         let me = basicInfoView;
         let me = basicInfoView;
         let items = sheetCommonObj.analyzePasteData(me.setting, args);
         let items = sheetCommonObj.analyzePasteData(me.setting, args);
         let recRows = [];
         let recRows = [];
-        console.log('enter');
         for(let i = 0, len = items.length; i < len; i++){
         for(let i = 0, len = items.length; i < len; i++){
             let row = i + args.cellRange.row;
             let row = i + args.cellRange.row;
             if(me.setting.locked.rows.indexOf(row) !== -1){
             if(me.setting.locked.rows.indexOf(row) !== -1){
@@ -150,9 +149,7 @@ let basicInfoView = {
             }
             }
             else if(me.setting.dateRows.indexOf(row) !== -1){
             else if(me.setting.dateRows.indexOf(row) !== -1){
                 items[i].value = me.filtDate(items[i].value);
                 items[i].value = me.filtDate(items[i].value);
-                console.log(items.value);
                 if(!me.isDef(items[i].value)){
                 if(!me.isDef(items[i].value)){
-                    console.log('aa');
                     recRows.push(row);
                     recRows.push(row);
                 }
                 }
                 else {
                 else {
@@ -163,8 +160,6 @@ let basicInfoView = {
                 me.datas[row].value = items[i].value;
                 me.datas[row].value = items[i].value;
             }
             }
         }
         }
-        console.log(recRows);
-        console.log(me.datas);
         if(recRows.length > 0){
         if(recRows.length > 0){
             me.renderSheetFuc(args.sheet, function () {
             me.renderSheetFuc(args.sheet, function () {
                 for(let i = 0, len = recRows.length; i < len; i++){
                 for(let i = 0, len = recRows.length; i < len; i++){
@@ -248,7 +243,6 @@ let basicInfoView = {
         return false;
         return false;
     },
     },
 
 
-
     a_updateInfo: function (datas) {
     a_updateInfo: function (datas) {
         let me = this;
         let me = this;
         let url = '/pm/api/updateProjects',
         let url = '/pm/api/updateProjects',
@@ -460,9 +454,9 @@ $(document).ready(function () {
         basicInfoView.workBook.refresh();
         basicInfoView.workBook.refresh();
     });
     });
 
 
-    $('#property_ok').bind('click', function () {
+   /* $('#property_ok').bind('click', function () {
         if(basicInfoView.toUpdate(basicInfoView.orgDatas, basicInfoView.datas)){
         if(basicInfoView.toUpdate(basicInfoView.orgDatas, basicInfoView.datas)){
             basicInfoView.a_updateInfo(basicInfoView.toSaveDatas(basicInfoView.datas));
             basicInfoView.a_updateInfo(basicInfoView.toSaveDatas(basicInfoView.datas));
         }
         }
-    });
+    });*/
 });
 });

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

@@ -339,10 +339,10 @@ $(document).ready(function () {
         billsDecimalView.workBook.refresh();
         billsDecimalView.workBook.refresh();
     });
     });
 
 
-    $('#property_ok').bind('click', function () {
+ /*   $('#property_ok').bind('click', function () {
         let newBillsDecimalDatas = billsDecimalView.toBillsDecimalDatas(billsDecimalView.cache);
         let newBillsDecimalDatas = billsDecimalView.toBillsDecimalDatas(billsDecimalView.cache);
         if(billsDecimalView.toUpdate(billsQuanDecimal.datas, newBillsDecimalDatas)){
         if(billsDecimalView.toUpdate(billsQuanDecimal.datas, newBillsDecimalDatas)){
             billsDecimalView.a_update(newBillsDecimalDatas);
             billsDecimalView.a_update(newBillsDecimalDatas);
         }
         }
-    });
+    });*/
 });
 });

+ 14 - 4
web/building_saas/main/js/views/project_property_decimal_view.js

@@ -22,26 +22,36 @@ decimalObj.decimal = function (field, node) {
         if(field === 'feeRate'){
         if(field === 'feeRate'){
             return this[field];
             return this[field];
         }
         }
+        else if (field.sameText('unitFee')) field = 'unitPrice'
+        else if (field.sameText('totalFee')) field = 'totalPrice';
+
         if(isDef(node)){
         if(isDef(node)){
             if(node.sourceType === projectObj.project.Bills.getSourceType()){
             if(node.sourceType === projectObj.project.Bills.getSourceType()){
                 if(field === 'quantity'){
                 if(field === 'quantity'){
                     return billsQuanDecimal.decimal(node.data.unit);
                     return billsQuanDecimal.decimal(node.data.unit);
                 }
                 }
                 else {
                 else {
-                    return this['bills'][field] || this.process;
+                    return returnV(this['bills'][field], this.process);
                 }
                 }
             }
             }
             else if(node.sourceType === projectObj.project.Ration.getSourceType()){
             else if(node.sourceType === projectObj.project.Ration.getSourceType()){
-                return this['ration'][field] || this.process;
+                return returnV(this['ration'][field], this.process);
             }
             }
             else if(node.sourceType === projectObj.project.GLJ.getSourceType()){
             else if(node.sourceType === projectObj.project.GLJ.getSourceType()){
-                return this['glj'][field] || this.process;
+                return returnV(this['glj'][field], this.process);
             }
             }
         }
         }
     }
     }
     return this.process;
     return this.process;
 };
 };
 
 
+function returnV(v, r){
+    if(isDef(v)){
+        return v;
+    }
+    return r;
+}
+
 function isUndef(v) {
 function isUndef(v) {
     return v === undefined || v === null;
     return v === undefined || v === null;
 }
 }
@@ -234,7 +244,7 @@ $(document).ready(function () {
         v_initPanel(v_data);
         v_initPanel(v_data);
     });
     });
     //绑定确定按钮
     //绑定确定按钮
-    e_bindCof($('#property_ok'));
+    //e_bindCof($('#property_ok'));
     //绑定小数位数输入控制
     //绑定小数位数输入控制
     e_validIn($('input', '#poj-settings-decimal'));
     e_validIn($('input', '#poj-settings-decimal'));
 });
 });

+ 20 - 0
web/building_saas/main/js/views/project_property_display_view.js

@@ -0,0 +1,20 @@
+/**
+ * Created by Zhong on 2017/11/24.
+ */
+let projDisplayView = {
+
+    datas: {},//just for view
+
+    init:function () {
+        this.datas = projectInfoObj.projectInfo.property.displaySetting;
+        $("#autoHeight").attr("checked",this.datas.autoHeight);
+        $("#disPlayMainMateria").attr("checked",this.datas.disPlayMainMateria);
+        //$('#disPlayMainMateria').prop('checked')
+    }
+};
+
+$(document).ready(function () {
+    $('#tab_display_setting').on('shown.bs.tab', function () {
+        projDisplayView.init();
+    });
+});

+ 2 - 1
web/building_saas/main/js/views/project_property_labour_coe_view.js

@@ -114,6 +114,7 @@ let labourCoeView = {
                         let cell = me.sheet.getCell(r, c+ 1);
                         let cell = me.sheet.getCell(r, c+ 1);
                         cell.value(v.coe);
                         cell.value(v.coe);
                         cell.tag(v.ID);
                         cell.tag(v.ID);
+                        cell.hAlign(GC.Spread.Sheets.HorizontalAlign.center);
                         break;
                         break;
                     };
                     };
                 };
                 };
@@ -141,7 +142,7 @@ let labourCoeView = {
                 projectObj.project.labourCoe.refreshData(data);
                 projectObj.project.labourCoe.refreshData(data);
                 me.needUpdateDatas.splice(0, me.needUpdateDatas.length);
                 me.needUpdateDatas.splice(0, me.needUpdateDatas.length);
                 projectObj.project.calcProgram.compileAllTemps();
                 projectObj.project.calcProgram.compileAllTemps();
-                projectObj.project.ration.calcAll();
+                projectObj.project.calcProgram.calcAllNodes(calcAllType.catRations);
                 rationPM.buildSheet();
                 rationPM.buildSheet();
                 $("#std_labour_coe_files").val('');
                 $("#std_labour_coe_files").val('');
             });
             });

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

@@ -401,9 +401,9 @@ $(document).ready(function () {
         projFeatureView.workBook.refresh();
         projFeatureView.workBook.refresh();
     });
     });
 
 
-    $('#property_ok').bind('click', function () {
+    /*$('#property_ok').bind('click', function () {
         if(projFeatureView.toUpdate(projFeatureView.orgDatas, projFeatureView.datas)){
         if(projFeatureView.toUpdate(projFeatureView.orgDatas, projFeatureView.datas)){
            projFeatureView.a_updateInfo(projFeatureView.toSaveDatas(projFeatureView.datas));
            projFeatureView.a_updateInfo(projFeatureView.toSaveDatas(projFeatureView.datas));
         }
         }
-    });
+    });*/
 });
 });

+ 116 - 45
web/building_saas/main/js/views/project_view.js

@@ -119,7 +119,7 @@ var projectObj = {
         return value;
         return value;
     },
     },
     checkSpreadEditingText: function (editingText, colSetting) {
     checkSpreadEditingText: function (editingText, colSetting) {
-        if (colSetting.data.field === 'quantity' || colSetting.data.field === 'feesIndex.common.unitFee') {
+        if (colSetting.data.field === 'quantity') {
             return this.checkFormulaValidField(editingText, colSetting);
             return this.checkFormulaValidField(editingText, colSetting);
         }
         }
         else if (colSetting.data.field === 'programID') {
         else if (colSetting.data.field === 'programID') {
@@ -273,9 +273,10 @@ var projectObj = {
             else if(fieldName ==='feeRate'){
             else if(fieldName ==='feeRate'){
                 project.FeeRate.updateFeeRateFromBills(value,node,fieldName);
                 project.FeeRate.updateFeeRateFromBills(value,node,fieldName);
             }
             }
-            else if (fieldName === 'quantity' || fieldName === 'marketUnitFee' || fieldName === 'programID' || fieldName === 'subType' || fieldName === 'calcBase'){
+            else if (fieldName === 'quantity' || fieldName === 'marketUnitFee' || fieldName === 'programID' ||
+                fieldName === 'subType' || fieldName === 'calcBase' || fieldName === 'feesIndex.common.unitFee'){
                 if (fieldName === 'quantity') {
                 if (fieldName === 'quantity') {
-                    if (value) {value = value.toDecimal(decimalObj.decimal(fieldName,node))};
+                   if (value) {value = value.toDecimal(decimalObj.decimal(fieldName,node))};
                    if(project.quantity_detail.quantityEditChecking(value,node,fieldName)){
                    if(project.quantity_detail.quantityEditChecking(value,node,fieldName)){
                        node.data.isFromDetail=0;
                        node.data.isFromDetail=0;
                        project.quantity_detail.cleanQuantityDetail(node,true);
                        project.quantity_detail.cleanQuantityDetail(node,true);
@@ -283,16 +284,33 @@ var projectObj = {
                        projectObj.mainController.refreshTreeNode([node]);
                        projectObj.mainController.refreshTreeNode([node]);
                        return;
                        return;
                    }
                    }
-                } else if (fieldName === 'marketUnitFee') {
+                }
+                else if (fieldName === 'marketUnitFee' || fieldName === 'feesIndex.common.unitFee') {
                     if (value) {value = parseFloat(value).toDecimal(decimalObj.decimal("unitPrice", node))};
                     if (value) {value = parseFloat(value).toDecimal(decimalObj.decimal("unitPrice", node))};
-                } else if (fieldName === 'calcBase') {
-                    if (value) {value = parseFloat(value).toDecimal(decimalObj.decimal("totalPrice", node))};
+                }
+                else if (fieldName === 'calcBase') {
+                    //zhong
+                    if(value){
+                        node.data.userCalcBase = value;
+                        project.calcBase.calculate(node);
+                        if(!project.calcBase.success){
+                            let activeCell = projectObj.mainSpread.getActiveSheet().getSelections()[0];
+                            projectObj.mainSpread.getActiveSheet().setValue(activeCell.row, activeCell.col, node.data.calcBase? node.data.calcBase: '');
+                        }
+                    }
+                    $.bootstrapLoading.end();
+                    return;
+                   // if (value) {value = parseFloat(value).toDecimal(decimalObj.decimal("totalPrice", node))};
                 };
                 };
-
                 node.changed = true;
                 node.changed = true;
-                node.data[fieldName] = value;
+                if (fieldName == 'feesIndex.common.unitFee'){
+                    project.calcProgram.initFeeField(node, 'common');
+                    node.data.feesIndex.common.unitFee = value;
+                }
+                else node.data[fieldName] = value;
                 project.calcProgram.calculate(node);
                 project.calcProgram.calculate(node);
                 project.calcProgram.saveNode(node);
                 project.calcProgram.saveNode(node);
+                gljOprObj.showRationGLJSheetData();
             }
             }
             else {
             else {
                 if (node.sourceType === project.Bills.getSourceType()) {
                 if (node.sourceType === project.Bills.getSourceType()) {
@@ -312,15 +330,16 @@ var projectObj = {
         } else {
         } else {
             projectObj.mainController.refreshTreeNode([node], false);
             projectObj.mainController.refreshTreeNode([node], false);
         }
         }
+        $.bootstrapLoading.end();
     },
     },
     mainSpreadEditEnded: function (sender, info) {
     mainSpreadEditEnded: function (sender, info) {
+        $.bootstrapLoading.start();
         let project = projectObj.project;
         let project = projectObj.project;
         let node = project.mainTree.items[info.row];
         let node = project.mainTree.items[info.row];
         let colSetting = projectObj.mainController.setting.cols[info.col];
         let colSetting = projectObj.mainController.setting.cols[info.col];
         let fieldName = projectObj.mainController.setting.cols[info.col].data.field;
         let fieldName = projectObj.mainController.setting.cols[info.col].data.field;
         // 检查输入类型等
         // 检查输入类型等
         let value = projectObj.checkSpreadEditingText(info.editingText, colSetting);
         let value = projectObj.checkSpreadEditingText(info.editingText, colSetting);
-
         projectObj.updateCellValue(node, value, colSetting);
         projectObj.updateCellValue(node, value, colSetting);
     },
     },
     mainSpreadRangeChanged: function (sender, info) {
     mainSpreadRangeChanged: function (sender, info) {
@@ -339,7 +358,7 @@ var projectObj = {
     checkMainSpread: function () {
     checkMainSpread: function () {
         if (!this.mainSpread) {
         if (!this.mainSpread) {
             this.mainSpread = SheetDataHelper.createNewSpread($('#billsSpread')[0]);
             this.mainSpread = SheetDataHelper.createNewSpread($('#billsSpread')[0]);
-            this.mainSpread.getActiveSheet().selectionPolicy(GC.Spread.Sheets.SelectionPolicy.single);
+            this.mainSpread.getActiveSheet().selectionPolicy(GC.Spread.Sheets.SelectionPolicy.muliRange);
         }
         }
     },
     },
     refreshMainSpread: function () {
     refreshMainSpread: function () {
@@ -351,21 +370,24 @@ var projectObj = {
         var that = this;
         var that = this;
         this.project = PROJECT.createNew(scUrlUtil.GetQueryString('project'), userID);
         this.project = PROJECT.createNew(scUrlUtil.GetQueryString('project'), userID);
         this.project.loadDatas(function (err) {
         this.project.loadDatas(function (err) {
+
             if (!err) {
             if (!err) {
+                that.project.property = projectInfoObj.projectInfo.property;
                 that.project.calcProgram.compileAllTemps();
                 that.project.calcProgram.compileAllTemps();
+                that.project.calcBase.init(that.project);
                 that.project.calcFields = JSON.parse(JSON.stringify(feeType));
                 that.project.calcFields = JSON.parse(JSON.stringify(feeType));
-                that.project.initCalcFields();
+                // that.project.initCalcFields();
                 let str = JSON.stringify(that.project.projSetting.main_tree_col);
                 let str = JSON.stringify(that.project.projSetting.main_tree_col);
                 that.project.projSetting.mainGridSetting = JSON.parse(str);
                 that.project.projSetting.mainGridSetting = JSON.parse(str);
                 that.project.projSetting.mainGridSetting.frozenCols = 4;
                 that.project.projSetting.mainGridSetting.frozenCols = 4;
                 TREE_SHEET_HELPER.initSetting($('#billsSpread')[0], that.project.projSetting.mainGridSetting);
                 TREE_SHEET_HELPER.initSetting($('#billsSpread')[0], that.project.projSetting.mainGridSetting);
                 that.project.projSetting.mainGridSetting.cols.forEach(function (col) {
                 that.project.projSetting.mainGridSetting.cols.forEach(function (col) {
                     // for test.  后端没有绑定,暂时写死用于测试。
                     // for test.  后端没有绑定,暂时写死用于测试。
-                    if (col.data.field == '' && col.head.titleNames[0] == "取费专业") {
+/*                    if (col.data.field == '' && col.head.titleNames[0] == "取费专业") {
                         col.data.field = 'programID';
                         col.data.field = 'programID';
                         col.data.getText = 'getText.calcProgramName';
                         col.data.getText = 'getText.calcProgramName';
                         col.data.cellType = 'cellType.calcProgramName';
                         col.data.cellType = 'cellType.calcProgramName';
-                    };
+                    };*/
 
 
                     col.data.splitFields = col.data.field.split('.');
                     col.data.splitFields = col.data.field.split('.');
                     if (col.data.getText && Object.prototype.toString.apply(col.data.getText) === "[object String]") {
                     if (col.data.getText && Object.prototype.toString.apply(col.data.getText) === "[object String]") {
@@ -378,13 +400,21 @@ var projectObj = {
                         let getCellType = MainTreeCol.getEvent(col.data.cellType);
                         let getCellType = MainTreeCol.getEvent(col.data.cellType);
                         col.data.cellType = getCellType;
                         col.data.cellType = getCellType;
                     }
                     }
-                    if (col.data.digit && Object.prototype.toString.apply(col.data.digit) === "[object String]") {
-                        col.data.decimal = that.project.getDecimal(col.data.digit);
-                        col.data.formatter = MainTreeCol.getNumberFormatter(col.data.decimal);
-                    }
+                    // if (col.data.digit && Object.prototype.toString.apply(col.data.digit) === "[object String]") {
+                    //     col.data.decimal = that.project.getDecimal(col.data.digit);
+                    //     col.data.formatter = MainTreeCol.getNumberFormatter(col.data.decimal);
+                    // }
                     if (col.data.field === 'code') {
                     if (col.data.field === 'code') {
                         col.data.formatter = '@';
                         col.data.formatter = '@';
                     }
                     }
+
+                    // for test digit. CSLAAAAA
+                    if (col.data.field.hasSubStr("totalFee"))
+                       col.data.formatter = MainTreeCol.getNumberFormatter(decimalObj.ration.totalPrice, true)
+                    else if (col.data.field.hasSubStr("unitFee"))
+                        col.data.formatter = MainTreeCol.getNumberFormatter(decimalObj.ration.unitPrice, true)
+                    else if (col.data.field == "quantity")
+                        col.data.formatter = MainTreeCol.getNumberFormatter(decimalObj.ration.quantity, true);
                 });
                 });
 
 
                 that.mainController = TREE_SHEET_CONTROLLER.createNew(that.project.mainTree, that.mainSpread.getActiveSheet(), that.project.projSetting.mainGridSetting);
                 that.mainController = TREE_SHEET_CONTROLLER.createNew(that.project.mainTree, that.mainSpread.getActiveSheet(), that.project.projSetting.mainGridSetting);
@@ -396,6 +426,7 @@ var projectObj = {
                 that.mainSpread.bind(GC.Spread.Sheets.Events.EditEnded, that.mainSpreadEditEnded);
                 that.mainSpread.bind(GC.Spread.Sheets.Events.EditEnded, that.mainSpreadEditEnded);
                 that.mainSpread.bind(GC.Spread.Sheets.Events.RangeChanged, that.mainSpreadRangeChanged);
                 that.mainSpread.bind(GC.Spread.Sheets.Events.RangeChanged, that.mainSpreadRangeChanged);
                 that.loadMainSpreadContextMenu();
                 that.loadMainSpreadContextMenu();
+                that.loadFocusLocation();
             }
             }
             else {
             else {
 
 
@@ -515,6 +546,18 @@ var projectObj = {
         this.project.Bills.updateAll();
         this.project.Bills.updateAll();
         calc = null;
         calc = null;
     }*/
     }*/
+    // 获取上次退出时的焦点位置
+    loadFocusLocation: function() {
+        const projectId = scUrlUtil.GetQueryString('project');
+        let row = getLocalCache('lastRow:' + projectId);
+        let col = getLocalCache('lastCol:' + projectId);
+        if (row !== null && col !== null) {
+            row = parseInt(row);
+            col = parseInt(col);
+            const sheet = this.mainSpread.getActiveSheet();
+            sheet.setSelection(row, col, 1, 1);
+        }
+    },
 };
 };
 
 
 $('#insert').click(function () {
 $('#insert').click(function () {
@@ -598,47 +641,75 @@ $('#poj-set').on('show.bs.modal', function () {
         }
         }
     }
     }
     if (projectObj.project) {
     if (projectObj.project) {
-        let mode = projectObj.project.projSetting.billsCalcMode;
-        let settingConst = projectObj.project.projSetting.settingConst;
-        setCalcFlag($('#rationContent'), settingConst.billsCalcMode.rationContent, mode);
-        setCalcFlag($('#rationPrice'), settingConst.billsCalcMode.rationPrice, mode);
-        setCalcFlag($('#rationPriceConverse'), settingConst.billsCalcMode.rationPriceConverse, mode);
-        setCalcFlag($('#billsPrice'), settingConst.billsCalcMode.billsPrice, mode);
+        // let mode = projectObj.project.projSetting.billsCalcMode;
+        // let settingConst = projectObj.project.projSetting.settingConst;
+        let mode = projectObj.project.property.billsCalcMode ? projectObj.project.property.billsCalcMode : leafBillGetFeeType.rationContent;
+        setCalcFlag($('#rationContent'), leafBillGetFeeType.rationContent, mode);
+        setCalcFlag($('#rationPriceConverse'), leafBillGetFeeType.rationPriceConverse, mode);
+        setCalcFlag($('#rationPrice'), leafBillGetFeeType.rationPrice, mode);
+        setCalcFlag($('#billsPrice'), leafBillGetFeeType.billsPrice, mode);
 
 
-        mode = projectObj.project.projSetting.zanguCalcMode;
-        setCalcFlag($('#zangu_common'), settingConst.zanguCalcMode.common, mode);
-        setCalcFlag($('#zangu_gatherMatherial'), settingConst.zanguCalcMode.gatherMaterial, mode);
+        // mode = projectObj.project.projSetting.zanguCalcMode;
+        mode = projectObj.project.property.zanguCalcMode ? projectObj.project.property.zanguCalcMode : zanguCalcMode.common;
+        setCalcFlag($('#zangu_common'), zanguCalcMode.common, mode);
+        setCalcFlag($('#zangu_gatherMatherial'), zanguCalcMode.gatherMaterial, mode);
     }
     }
 });
 });
 $('#property_ok').click(function () {
 $('#property_ok').click(function () {
+    let properties = [], projectID = parseInt(scUrlUtil.GetQueryString('project'));
     let project = projectObj.project, reCalc= false;
     let project = projectObj.project, reCalc= false;
-    let mode = parseInt($("input[name='calcFlag']:checked").val());
-    let zanguMode = parseInt($("input[name='zangu']:checked").val());
-    if (mode !== project.projSetting.billsCalcMode) {
-        project.setBillsCalcMode(mode);
+    let billMode = parseInt($("input[name='calcFlag']:checked").val());
+    if (billMode !== project.property.billsCalcMode) {
+        // project.setBillsCalcMode(mode);
+        project.property.billsCalcMode = billMode;
         reCalc = true;
         reCalc = true;
-    }
-    if (zanguMode !== project.projSetting.zanguCalcMode) {
-        project.projSetting.zanguCalcMode = zanguMode;
+    };
+
+    let zanguMode = parseInt($("input[name='zangu']:checked").val());
+    if (zanguMode !== project.property.zanguCalcMode) {
+        project.property.zanguCalcMode = zanguMode;
         reCalc = true;
         reCalc = true;
-    }
+    };
+
     if (labourCoeView.needSave()){
     if (labourCoeView.needSave()){
         labourCoeView.save();
         labourCoeView.save();
         reCalc = true;
         reCalc = true;
     }
     }
+
     if (reCalc) {
     if (reCalc) {
-        // projectObj.calculateAll();
-/*        project.pushNow('editBillsCalcMode',
-            [project.projSetting.moduleName, project.Bills.getSourceType()],
-            [{
-                projectID: project.ID(),
-                billsCalcMode: project.projSetting.billsCalcMode
-            }, project.Bills.getUpdateAllData()]
-        );*/
-        project.pushNow('', [project.projSetting.moduleName], [{
+/*        project.pushNow('', [project.projSetting.moduleName], [{
             projectID: project.ID(),
             projectID: project.ID(),
-            billsCalcMode: project.projSetting.billsCalcMode
-        }]);
+            billsCalcMode: project.property.billsCalcMode
+        }]);*/
         project.calcProgram.calcAllNodes(calcAllType.catBills);
         project.calcProgram.calcAllNodes(calcAllType.catBills);
     }
     }
+    //基本信息
+    if(basicInfoView.toUpdate(basicInfoView.orgDatas, basicInfoView.datas)){
+        let updateData = {updateType: 'update', updateData: {ID: projectID, 'property.basicInformation': basicInfoView.toSaveDatas(basicInfoView.datas)}};
+        properties.push(updateData);
+    }
+    //工程特征
+    if(projFeatureView.toUpdate(projFeatureView.orgDatas, projFeatureView.datas)){
+        let updateData = {updateType: 'update', updateData: {ID: projectID, 'property.projectFeature': projFeatureView.toSaveDatas(projFeatureView.datas)}};
+        properties.push(updateData);
+    }
+    //清单工程量精度
+    let newBillsDecimalDatas = billsDecimalView.toBillsDecimalDatas(billsDecimalView.cache);
+    if(billsDecimalView.toUpdate(billsQuanDecimal.datas, newBillsDecimalDatas)){
+        let updateData = {updateType: 'update', updateData: {ID: projectID, 'property.billsQuantityDecimal': newBillsDecimalDatas}};
+        properties.push(updateData);
+    }
+    //小数位数
+    //获取更新的数据
+    let updateDecimal = m_getDecimalData($('input', '#poj-settings-decimal'));
+    if(toUpdateDecimal(decimalObj, updateDecimal)){
+        let updateData = {updateType: 'update', updateData: {ID: projectID, 'property.decimal': updateDecimal}};
+        properties.push(updateData);
+    }
+    console.log(properties);
+    if(properties.length > 0){
+        CommonAjax.post('/pm/api/updateProjects', {user_id: userID, updateData: properties}, function (rstData) {
+            window.location.href = '/main?project=' + projectID;
+        });
+    }
 });
 });

+ 1 - 1
web/building_saas/pm/html/project-management.html

@@ -5,7 +5,7 @@
     <meta charset="utf-8">
     <meta charset="utf-8">
     <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
     <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
     <meta http-equiv="x-ua-compatible" content="ie=edge">
     <meta http-equiv="x-ua-compatible" content="ie=edge">
-    <title>项目管理-Smartcost</title>
+    <title>项目管理-纵横云造价</title>
     <!-- inject:css -->
     <!-- inject:css -->
     <link rel="stylesheet" href="/lib/bootstrap/css/bootstrap.min.css">
     <link rel="stylesheet" href="/lib/bootstrap/css/bootstrap.min.css">
     <link rel="stylesheet" href="/web/building_saas/css/main.css">
     <link rel="stylesheet" href="/web/building_saas/css/main.css">

+ 8 - 8
web/common/html/header.html

@@ -1,16 +1,11 @@
 <nav class="navbar navbar-expand-lg p-0 d-flex">
 <nav class="navbar navbar-expand-lg p-0 d-flex">
-    <span class="header-logo px-2">Smartcost</span>
-    <div class="navbar-text navbar-crumb p-0" id="fullpath">
-        <% if (action !== 'index' || controller !== 'pm') {%>
-        <span class="text-truncate"><a href="/pm">项目管理</a></span>
-        <% } %>
-    </div>
+    <span class="header-logo px-2">纵横云造价</span>
     <ul class="nav navbar-nav px-1">
     <ul class="nav navbar-nav px-1">
         <li class="nav-item">
         <li class="nav-item">
             <a class="nav-link" href="#" aria-expanded="false" data-toggle="modal" data-target="#poj-set"><i class="fa fa-cube"></i> 项目属性</a>
             <a class="nav-link" href="#" aria-expanded="false" data-toggle="modal" data-target="#poj-set"><i class="fa fa-cube"></i> 项目属性</a>
         </li>
         </li>
         <li class="nav-item">
         <li class="nav-item">
-            <a class="nav-link" href="#" aria-expanded="false"><i class="fa fa-sliders"></i> 选项</a>
+            <a class="nav-link" href="#" aria-expanded="false" data-toggle="modal" data-target="#opts-set"><i class="fa fa-sliders"></i> 选项</a>
         </li>
         </li>
         <li class="nav-item dropdown">
         <li class="nav-item dropdown">
             <a class="nav-link dropdown-toggle" href="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fa fa-wrench"></i> 工具</a>
             <a class="nav-link dropdown-toggle" href="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fa fa-wrench"></i> 工具</a>
@@ -32,9 +27,14 @@
             </div>
             </div>
         </li>
         </li>
     </ul>
     </ul>
+    <div class="navbar-text navbar-crumb p-0" id="fullpath">
+        <% if (action !== 'index' || controller !== 'pm') {%>
+        <span class="text-truncate"><a href="/pm">项目管理</a></span>
+        <% } %>
+    </div>
     <div class="ml-auto navbar-text p-0">
     <div class="ml-auto navbar-text p-0">
         <div class="dropdown d-inline-block navbar-nav">
         <div class="dropdown d-inline-block navbar-nav">
-            <button class="btn btn-link btn-sm dropdown-toggle" type="button" data-toggle="dropdown"><%= sessionUser.email %></button>
+            <button class="btn btn-link btn-sm dropdown-toggle" type="button" data-toggle="dropdown"><%= sessionUser.real_name === '' ? sessionUser.email : sessionUser.real_name %></button>
             <div class="dropdown-menu dropdown-menu-right">
             <div class="dropdown-menu dropdown-menu-right">
                 <a class="dropdown-item" href="/user/info" target="_blank">账号资料</a>
                 <a class="dropdown-item" href="/user/info" target="_blank">账号资料</a>
                 <a class="dropdown-item" href="user-buy.html" target="_blank">产品购买</a>
                 <a class="dropdown-item" href="user-buy.html" target="_blank">产品购买</a>

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

@@ -4,7 +4,7 @@
     <meta charset="utf-8">
     <meta charset="utf-8">
     <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
     <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
     <meta http-equiv="x-ua-compatible" content="ie=edge">
     <meta http-equiv="x-ua-compatible" content="ie=edge">
-    <title>用户登录-Smartcost</title>
+    <title>用户登录-纵横云造价</title>
     <!-- inject:css -->
     <!-- inject:css -->
     <link rel="stylesheet" href="/lib/bootstrap/css/bootstrap.min.css">
     <link rel="stylesheet" href="/lib/bootstrap/css/bootstrap.min.css">
     <link rel="stylesheet" href="/web/building_saas/css/main.css">
     <link rel="stylesheet" href="/web/building_saas/css/main.css">

+ 4 - 2
web/users/js/login.js

@@ -21,13 +21,15 @@ $(document).ready(function () {
             data: {"account": account, "pw": pw},
             data: {"account": account, "pw": pw},
             success: function (response) {
             success: function (response) {
                 if (response.error === 0) {
                 if (response.error === 0) {
+                    const url = response.last_page !== null && response.last_page !== '' ?
+                        response.last_page : '/pm';
                     if (response.login_ask === 0) {
                     if (response.login_ask === 0) {
-                        location.href = '/pm';
+                        location.href = url;
                     } else {
                     } else {
                         response.compilation_list = response.compilation_list === undefined || response.compilation_list === '' ?
                         response.compilation_list = response.compilation_list === undefined || response.compilation_list === '' ?
                             null : JSON.parse(response.compilation_list);
                             null : JSON.parse(response.compilation_list);
                         if (response.compilation_list === null || response.compilation_list.length <= 0) {
                         if (response.compilation_list === null || response.compilation_list.length <= 0) {
-                            location.href = '/pm';
+                            location.href = url;
                             return false;
                             return false;
                         }
                         }
                         setVersion(response.compilation_list);
                         setVersion(response.compilation_list);