Kaynağa Gözat

Merge branch '1.0.0_online' of http://192.168.1.12:3000/SmartCost/ConstructionCost into 1.0.0_online

TonyKang 6 yıl önce
ebeveyn
işleme
40a34a0dc0
49 değiştirilmiş dosya ile 1438 ekleme ve 497 silme
  1. 1 0
      config/gulpConfig.js
  2. 1 0
      modules/all_models/compleGlj_glj.js
  3. 7 5
      modules/all_models/engineering_lib.js
  4. 3 0
      modules/all_models/stdRation_ration.js
  5. 1 0
      modules/all_models/std_billsGuidance_lib.js
  6. 15 0
      modules/all_models/user.js
  7. 3 1
      modules/common/const/bills_fixed.js
  8. 1 0
      modules/common/helper/mongoose_helper.js
  9. 4 1
      modules/complementary_glj_lib/controllers/gljController.js
  10. 17 6
      modules/main/facade/ration_facade.js
  11. 9 0
      modules/pm/controllers/pm_controller.js
  12. 1 1
      modules/pm/models/project_model.js
  13. 1 1
      modules/users/controllers/boot_controller.js
  14. 1 0
      modules/users/controllers/login_controller.js
  15. 14 4
      modules/users/models/user_model.js
  16. 1 1
      public/scHintBox.html
  17. 33 1
      public/web/common_util.js
  18. 29 24
      public/web/gljUtil.js
  19. 4 1
      public/web/sheet/sheet_common.js
  20. 24 0
      public/web/tools_const.js
  21. 9 13
      public/web/tree_sheet/tree_sheet_helper.js
  22. 2 0
      web/building_saas/complementary_glj_lib/html/tools-gongliaoji.html
  23. 2 16
      web/building_saas/complementary_glj_lib/js/components.js
  24. 80 30
      web/building_saas/complementary_glj_lib/js/glj.js
  25. 2 2
      web/building_saas/complementary_glj_lib/js/gljComponent.js
  26. 12 1
      web/building_saas/complementary_glj_lib/js/sheetOpr.js
  27. 40 0
      web/building_saas/css/custom.css
  28. 119 131
      web/building_saas/main/html/main.html
  29. 1 1
      web/building_saas/main/js/controllers/block_controller.js
  30. 127 31
      web/building_saas/main/js/models/calc_base.js
  31. 96 67
      web/building_saas/main/js/models/calc_program.js
  32. 1 1
      web/building_saas/main/js/models/installation_fee.js
  33. 12 30
      web/building_saas/main/js/models/main_consts.js
  34. 5 0
      web/building_saas/main/js/models/project.js
  35. 7 7
      web/building_saas/main/js/models/ration.js
  36. 1 0
      web/building_saas/main/js/views/calc_base_view.js
  37. 1 1
      web/building_saas/main/js/views/calc_program_manage.js
  38. 0 26
      web/building_saas/main/js/views/fee_rate_view.js
  39. 30 32
      web/building_saas/main/js/views/glj_view.js
  40. 2 6
      web/building_saas/main/js/views/installation_fee_view.js
  41. 1 1
      web/building_saas/main/js/views/project_glj_view.js
  42. 3 0
      web/building_saas/main/js/views/project_info.js
  43. 1 1
      web/building_saas/main/js/views/project_property_basicInfo.js
  44. 1 2
      web/building_saas/main/js/views/project_view.js
  45. 472 23
      web/building_saas/main/js/views/std_billsGuidance_lib.js
  46. 3 3
      web/building_saas/main/js/views/std_ration_lib.js
  47. 1 0
      web/building_saas/pm/html/project-management.html
  48. 1 0
      web/building_saas/pm/js/pm_newMain.js
  49. 236 26
      web/over_write/js/chongqing_2018.js

+ 1 - 0
config/gulpConfig.js

@@ -164,6 +164,7 @@ module.exports = {
         'public/web/id_tree.js',
         'public/web/tree_sheet/tree_sheet_controller.js',
         'public/web/tree_sheet/tree_sheet_helper.js',
+        'public/web/tools_const.js',
         'public/web/ration_glj_units.js',
         'web/building_saas/complementary_glj_lib/js/glj.js',
         'web/building_saas/complementary_glj_lib/js/gljClassTree.js',

+ 1 - 0
modules/all_models/compleGlj_glj.js

@@ -26,6 +26,7 @@ const comple_glj = new Schema({
     basePrice: String,
     gljClass: Number,
     gljType: Number,
+    model: Number,
     shortName: String,
     component: [comple_gljComponent]
 }, {versionKey: false});

+ 7 - 5
modules/all_models/engineering_lib.js

@@ -59,12 +59,14 @@ let modelSchema = {
     valuationID:{type:String,index: true},
     //工程专业名称
     name:String,
+    //费用标准
+    feeName:String,
     //前端是否显示
-    visible:{
-        type: Boolean,
-        default: false
-    },
-    engineering:Number
+    visible:{type: Boolean, default: false},
+    //取费专业
+    engineering:Number,
+    //是否计算安装增加费
+    isInstall:{type: Boolean, default: false}
 };
 mongoose.model(collectionName, new Schema(modelSchema, {versionKey: false, collection: collectionName}));
 

+ 3 - 0
modules/all_models/stdRation_ration.js

@@ -34,6 +34,9 @@ const rationItemSchema = new Schema({
     name: String,
     unit: String,
     basePrice: Number,
+    labourPrice: Number,
+    materialPrice: Number,
+    machinePrice: Number,
     sectionId: Number,
     rationRepId: Number,
     caption: String,

+ 1 - 0
modules/all_models/std_billsGuidance_lib.js

@@ -12,6 +12,7 @@ const mongoose = require('mongoose');
 const Schema = mongoose.Schema;
 
 const stdBillsGuidanceLib = new Schema({
+    type: Number, //1:清单指引, 2:清单精灵
     ID: String, //uuid
     compilationId: String,
     compilationName: String,

+ 15 - 0
modules/all_models/user.js

@@ -25,6 +25,13 @@ const versionSchema = new Schema({
     invalidInfo: [invalidSchema]
 });
 
+let upgrade = mongoose.Schema({
+    compilationID:String,//编办ID
+    upgrade_time:Number,
+    isUpgrade:Boolean,
+    remark:String//描述:广东办刘飞 2018-06-17 启用/关闭
+}, { _id: false })
+
 // 表结构
 let schema = {
     ssoId: Number,
@@ -55,7 +62,15 @@ let schema = {
         type: Number,
         default: -1
     },
+    // 最后登录时间
+    latest_login: {
+        type: Number,
+        default: 0
+    },
+    //最近使用编办
+    latest_used:String,
     create_time: Number,
+    upgrade_list:[upgrade],
     user_type:{
         type:String,
         default:'normal'//  normal : 普通用户,test:测试用户

+ 3 - 1
modules/common/const/bills_fixed.js

@@ -39,7 +39,9 @@ const fixedFlag = {
     // 税金
     TAX: 18,
     //工程造价
-    ENGINEERINGCOST: 19
+    ENGINEERINGCOST: 19,
+    //增值税
+    ADDED_VALUE_TAX: 20
 };
 
 export default fixedFlag;

+ 1 - 0
modules/common/helper/mongoose_helper.js

@@ -221,6 +221,7 @@ class MongooseHelper {
         if (condition === null || condition._id === undefined) {
             return condition;
         }
+        condition._id = condition._id.toString();
         let result = mongoose.Types.ObjectId(condition._id);
         condition._id = result;
 

+ 4 - 1
modules/complementary_glj_lib/controllers/gljController.js

@@ -33,12 +33,15 @@ class GljController extends BaseController{
             let engineeringInfo = await engineeringLibModel.findDataByCondition({'valuationID': {"$in": valuationIDs},"glj_lib.0": {$exists:1}});//数组大于0
             gljLibId = engineeringInfo.glj_lib.length > 0 && typeof engineeringInfo.glj_lib !== 'undefined' ? engineeringInfo.glj_lib[0].id : null;
         }
+        let overWriteUrl = req.session.sessionCompilation && req.session.sessionCompilation.overWriteUrl &&
+                            req.session.sessionCompilation._id !== '5b4d581023a924000b760f2d' ? req.session.sessionCompilation.overWriteUrl : null;
         res.render('building_saas/complementary_glj_lib/html/tools-gongliaoji.html',{
             userID: req.session.sessionUser.id,
             gljLibId: gljLibId,
             compilationId: sessionCompilation._id,
             versionName: req.session.sessionCompilation.name + '免费版',
-            LicenseKey:config.getLicenseKey(process.env.NODE_ENV)
+            LicenseKey:config.getLicenseKey(process.env.NODE_ENV),
+            overWriteUrl: overWriteUrl,
         });
     }
     getGljDistType (req, res) {

+ 17 - 6
modules/main/facade/ration_facade.js

@@ -364,17 +364,21 @@ async function  updateRation(std,firstLibID,rationID,billsItemID,projectID,calQu
     else if(std.rationRepId === firstLibID && ration.from === 'cpt') {
         ration.prefix = '补';
     }
-    ration.programID = std.feeType;
+    if(std.feeType == undefined || std.feeType == null || std.feeType ==''){//定额取费专业为空的情况下,取项目属性中的定额取费专业ID
+        ration.programID = await getProgramForProject(projectID);
+    }else {
+        ration.programID = std.feeType;
+    }
     ration.rationAssList = createRationAss(std);//生成辅助定额
     if(calQuantity){
        await CalculateQuantity(ration,billsItemID,projectID);
     }
 
- let unsetObject = {
-     "marketUnitFee":1,
-     'marketTotalFee':1,
-     "maskName":1
- }
+     let unsetObject = {
+         "marketUnitFee":1,
+         'marketTotalFee':1,
+         "maskName":1
+     }
     let newRation = await ration_model.model.findOneAndUpdate({ID:rationID,projectID:projectID},{"$set":ration,"$unset":unsetObject},{new: true});//;
     return newRation;
 }
@@ -409,6 +413,7 @@ async function setEmptyRation(projectID,rationID){
     ration.quantityCoe = {};
     ration.rationQuantityCoe="";
     ration.tenderQuantity = "";
+    ration.programID = null;
     let newRation = await ration_model.model.findOneAndUpdate({ID:rationID,projectID:projectID},{"$set":ration},{new: true});//;
     return {ration:newRation,ration_gljs:[],ration_coes:[],ration_installs:[]};
 }
@@ -439,6 +444,12 @@ async function CalculateQuantity (ration,billsItemID,projectID) {
     ration.contain =  scMathUtil.roundForObj(ration.quantity/billsQuantity,6);
 };
 
+
+async function getProgramForProject(projectID){
+    let project = await projectModel.findOne({ID:projectID});
+    return project.property.engineering;
+}
+
 function FilterNumberFromUnit (unit) {
     let reg = new RegExp('^[0-9]+');
     if (reg.test(unit)) {

+ 9 - 0
modules/pm/controllers/pm_controller.js

@@ -22,6 +22,7 @@ let pm_facade = require('../facade/pm_facade');
 const userModel = mongoose.model('user');
 let config = require("../../../config/config.js");
 const optionModel = mongoose.model('options');
+const stdBillsGuidanceLibModel = mongoose.model('std_billsGuidance_lib');
 
 //统一回调函数
 let callback = function(req, res, err, message, data){
@@ -185,6 +186,14 @@ module.exports = {
                 let strData = JSON.stringify(data);
                 let projInfo = JSON.parse(strData);
                 if (engineeringInfo !== null) {
+                    if(engineeringInfo.billsGuidance_lib){
+                        for(let billsGuidanceLib of engineeringInfo.billsGuidance_lib){
+                            let stdBillsGuidanceLib = await stdBillsGuidanceLibModel.findOne({ID: billsGuidanceLib.id});
+                            if(stdBillsGuidanceLib){
+                                billsGuidanceLib.type = stdBillsGuidanceLib.type ? stdBillsGuidanceLib.type : 1;
+                            }
+                        }
+                    }
                     projInfo.engineeringInfo = engineeringInfo;
                 }
                 //读取建设项目的基本信息

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

@@ -175,7 +175,7 @@ ProjectsDAO.prototype.updateUserProjects = async function (userId, compilationId
                     //计算选项
                     data.updateData.property.calcOptions = calcOptions;
                     //安装增加费
-                    if(parseInt(data.updateData.property.engineering)==4){
+                    if(data.updateData.property.isInstall == true || data.updateData.property.isInstall=='true'){//判断是否安装工程
                         await installationFacade.copyInstallationFeeFromLib(data.updateData.ID,data.updateData.property.engineering_id);
                     }
                     //锁定清单

+ 1 - 1
modules/users/controllers/boot_controller.js

@@ -29,8 +29,8 @@ class BootController extends BaseController {
         if (sessionCompilation === undefined && compilationId !== '') {
             let compilationModel = new CompilationModel();
             let compilationData = await compilationModel.getCompilationById(compilationId);
-
             request.session.sessionCompilation = compilationData;
+            if(sessionUser.latest_used !== compilationId) userModel.updateLatestUsed(sessionUser.id,compilationId);
         }
 
         // 判断是否已填写信息

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

@@ -90,6 +90,7 @@ class LoginController {
                 preferenceSetting.select_version !== '') {
                 let compilationData = await compilationModel.getCompilationById(preferenceSetting.select_version);
                 request.session.sessionCompilation = compilationData;
+                if(request.session.sessionUser.latest_used !== preferenceSetting.select_version) await userModel.updateLatestUsed(request.session.sessionUser.id,preferenceSetting.select_version);
             }
 
         } catch (error) {

+ 14 - 4
modules/users/models/user_model.js

@@ -30,7 +30,7 @@ class UserModel extends BaseModel {
         '造价管理站', '学校', '个人', '其他'];
 
     /**
-     * 企业类型
+     * 企业规模
      *
      * @var
      */
@@ -91,6 +91,7 @@ class UserModel extends BaseModel {
         let userDataFromDb2 = await this.findDataBySsoId(userData.ssoId);
         let userDataFromDb = await this.findDataByName(userData.username);  //后面新增的账号可淘汰这方法,当前使用是为了兼容旧的账号
         let result = false;
+        userData.latest_login = new Date().getTime();
         if (userDataFromDb === null && userDataFromDb2 === null) {
             // 不存在用户则入库
             this.setScene();//恢复场景,用户有可能公司real_name等信息为空,不能设置为必填
@@ -103,7 +104,8 @@ class UserModel extends BaseModel {
             let UpdateData = {
                 email : userData.email,
                 mobile : userData.mobile,
-                ssoId : userData.ssoId
+                ssoId : userData.ssoId,
+                latest_login:userData.latest_login
             };
             let updateResult = await this.updateUser(condition,UpdateData);
             if (updateResult.ok === 1) {
@@ -113,6 +115,7 @@ class UserModel extends BaseModel {
         }
         request.session.sessionUser.id = userDataFromDb._id;
         request.session.sessionUser.real_name = userDataFromDb.real_name;
+        request.session.sessionUser.latest_used = userDataFromDb.latest_used;//设置最近使用的编办
 
         return result;
     }
@@ -196,17 +199,24 @@ class UserModel extends BaseModel {
         return this.db.create(insertData);
     }
 
+    //更新最近使用编办ID
+    async updateLatestUsed(userID,compilationID){
+        if(userID && compilationID){
+            return await this.db.update({'_id':userID},{'latest_used':compilationID});
+        }
+    }
+
     /**
      * 更新用户数据
      *
      * @param {object} updateData
      * @return {Promise}
      */
-    updateUser(condition, updateData) {
+    async updateUser(condition, updateData) {
         if (Object.keys(condition).length <= 0 || Object.keys(updateData).length <= 0) {
             return null;
         }
-        return this.db.update(condition, updateData);
+        return await this.db.update(condition, updateData);
     }
 
     async addVersion(condition, versionInfo){

+ 1 - 1
public/scHintBox.html

@@ -170,7 +170,7 @@
     };
 
     $('#hintBox_form').on('hide.bs.modal', function() {
-        $.bootstrapLoading.end();
+        if($.bootstrapLoading) $.bootstrapLoading.end();
         return;
     });
 </script>

+ 33 - 1
public/web/common_util.js

@@ -41,6 +41,11 @@ Array.prototype.hasSubArr = function (subArr){
     return true;
 };
 
+Array.prototype.delete = function (elem){
+    let idx = this.findIndex(function (e){return e == elem});
+    if (idx != -1) this.splice(idx, 1);
+};
+
 function seqString(num,length){
     var numstr = num.toString();
     var l=numstr.length;
@@ -56,4 +61,31 @@ function customRowHeader(sheet, dataLength) {
     for (let i = 0; i < dataLength; i++) {
         sheet.setValue(i, 0, `F${i + 1}`, GC.Spread.Sheets.SheetArea.rowHeader);
     }
-}
+};
+
+function changePropNames(object, oldNames, newNames) {
+    if (!object) return;
+    for (let i = 0; i < oldNames.length; i++) {
+        if (object[oldNames[i]]){
+            object[newNames[i]] = object[oldNames[i]];
+            delete object[oldNames[i]];
+        };
+    }
+};
+
+function changePropNames(object, oldNames, newNames) {
+    if (!object) return;
+    for (let i = 0; i < oldNames.length; i++) {
+        if (object[oldNames[i]]){
+            object[newNames[i]] = object[oldNames[i]];
+            delete object[oldNames[i]];
+        };
+    }
+};
+
+function deletePropNames(object, namesArr) {
+    if (!object) return;
+    for (let name of namesArr){
+        if (object[name]) delete object[name];
+    };
+};

+ 29 - 24
public/web/gljUtil.js

@@ -300,30 +300,35 @@ let gljUtil = {
         CONSTRUCTION_TECH: 3
     },
     gljType : {
-        LABOUR: 1, // 人工
-        // ==============材料类型=================
-        GENERAL_MATERIAL: 201,  // 普通材料
-        CONCRETE: 202, // 混凝土
-        MORTAR: 203,// 砂浆
-        MIX_RATIO: 204,// 配合比
-        COMMERCIAL_CONCRETE: 205,// 商品混凝土
-        COMMERCIAL_MORTAR: 206,// 商品砂浆
-        OTHER_MATERIAL: 207, // 其它材料
-        // ==============机械类型=================
-        GENERAL_MACHINE: 301,// 机械台班
-        MACHINE_COMPOSITION: 302,// 机械组成物
-        MACHINE_LABOUR: 303,// 机上人工
-        INSTRUMENT: 304,// 仪器仪表
-        FUEL_POWER_FEE:305,//燃料动力费
-        DEPRECIATION_FEE:306,//折旧费
-        INSPECTION_FEE:307,//检修费
-        MAINTENANCE:308,//维护费
-        DISMANTLING_FREIGHT_FEE:309,//安拆费及场外运费
-        VERIFICATION_FEE:310,//校验费
-        OTHER_FEE:311,//其他费用
-        // ==============机械类型=================
-        MAIN_MATERIAL: 4,// 主材
-        EQUIPMENT: 5// 设备
+        LABOUR: 1,                                  // 人工
+        // ==============材料类型 ↓=================
+        GENERAL_MATERIAL: 201,                      // 普通材料
+        CONCRETE: 202,                              // 混凝土
+        MORTAR: 203,                                // 砂浆
+        MIX_RATIO: 204,                             // 配合比
+        COMMERCIAL_CONCRETE: 205,                   // 商品混凝土
+        COMMERCIAL_MORTAR: 206,                     // 商品砂浆
+        OTHER_MATERIAL: 207,                        // 其它材料
+        // ==============材料类型 ↑=================
+        // ==============机械类型 ↓=================
+        GENERAL_MACHINE: 301,                       // 机械台班
+        MACHINE_COMPOSITION: 302,                   // 机械组成物
+        MACHINE_LABOUR: 303,                        // 机上人工
+        INSTRUMENT: 304,                            // 仪器仪表
+        FUEL_POWER_FEE:305,                         // 燃料动力费
+        DEPRECIATION_FEE:306,                       // 折旧费
+        INSPECTION_FEE:307,                         // 检修费
+        MAINTENANCE:308,                            // 维护费
+        DISMANTLING_FREIGHT_FEE:309,                // 安拆费及场外运费
+        VERIFICATION_FEE:310,                       // 校验费
+        OTHER_FEE:311,                              // 其他费用
+        OTHER_MACHINE_USED:312,                     // 其他施工机具使用费
+        // ==============机械类型 ↑=================
+        MAIN_MATERIAL: 4,                           // 主材
+        EQUIPMENT: 5,                               // 设备
+        MANAGEMENT_FEE: 6,                          // 企业管理费
+        PROFIT: 7,                                  // 利润
+        GENERAL_RISK_FEE: 8                         // 一般风险费
     },
     notEditType : [202,203,204,301,304,4],
     gljKeyArray : ['code','name','specs','unit','type'],

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

@@ -499,7 +499,10 @@ var sheetCommonObj = {
         sheet.suspendPaint();
         let combo = me.getDynamicCombo();
         for(let i = 0, len = rowCount; i < len; i++){
-            if(itemsHeight) combo.itemHeight(itemsHeight);
+            if(itemsHeight) {
+                combo.itemHeight(itemsHeight);
+                combo._maxDropDownItems = itemsHeight + 5;
+            }
             if(itemsType === 'value') combo.items(items).editorValueType(GC.Spread.Sheets.CellTypes.EditorValueType.value);
             else if(itemsType === 'text') combo.items(items).editorValueType(GC.Spread.Sheets.CellTypes.EditorValueType.text);
             else combo.items(items);

+ 24 - 0
public/web/tools_const.js

@@ -0,0 +1,24 @@
+'use strict';
+
+/**
+ *
+ *
+ * @author Zhong
+ * @date 2018/8/16
+ * @version
+ */
+//允许使用的工料机类型:人工、普通材料、混凝土、砂浆、配合比、商品混凝土、商品砂浆、机械台班、机械组成物、机上人工、主材、设备
+let allowGljType = [1, 201, 202, 203, 204, 205, 206, 301, 302, 303, 4, 5];
+
+//允许含有组成物的工料机类型:混凝土、砂浆、配合比、机械台班、主材
+let allowComponent = [202, 203, 204, 301, 4];
+//可以作为组成物的工料机类型:普通材料、机械组成物、机上人工、主材
+let componentType = [201, 302, 303, 4];
+//允许含有组成物的机械工料机类型:机械台班
+let machineAllowComponent = [301];
+//可以作为机械工料机组成物的工料机类型:机械组成物、机上人工
+let machineComponent = [302, 303];
+//允许含有组成物的材料工料机类型:混凝土、砂浆、配合比
+let materialAllowComponent = [202, 203, 204];
+//可以作为材料工料机组成物的工料机类型:普通材料
+let materialComponent = [201];

+ 9 - 13
public/web/tree_sheet/tree_sheet_helper.js

@@ -482,14 +482,8 @@ var TREE_SHEET_HELPER = {
                 let div = $('#autoTip')[0];
                 if (!div) {
                     div = document.createElement("div");
-                    $(div).css("position", "absolute")
-                        .css("border", "1px #000000 solid")
-                        .css("box-shadow", "1px 2px 5px rgba(0,0,0,0)")
-                        .css("font", "0.9rem Calibri")
-                        .css("background", "#000000")
-  						.css("color",'#FFFFFF')
-                        .css("padding", 5)
-                        .attr("id", 'autoTip');
+                    $(div).addClass("message-box");
+                    $(div) .attr("id", 'autoTip');
                     $(div).hide();
                     document.body.insertBefore(div, null);
                 }
@@ -499,7 +493,7 @@ var TREE_SHEET_HELPER = {
                     setting.pos = SheetDataHelper.getObjPos(hitinfo.sheet.getParent().qo);
                 }
                 if(text) text = replaceAll(/[\n]/,'<br>',text);
-                $(this._toolTipElement).html(text);
+                $(this._toolTipElement).html(`<span>${text}</span><div class="triangle-border tb-border"></div><div class="triangle-border tb-background"></div>`);
                 //清单指引、清单库做特殊处理
                 if($(hitinfo.sheet.getParent().qo).attr('id') === 'stdBillsSpread' || $(hitinfo.sheet.getParent().qo).attr('id') === 'billsGuidance_bills'){
                     $(this._toolTipElement).css('top', '').css('left', '').css('width', '');
@@ -507,10 +501,12 @@ var TREE_SHEET_HELPER = {
                     if($(this._toolTipElement).width() < hitinfo.x){
                         marginLeftMouse = hitinfo.x - $(this._toolTipElement).width();
                     }
-                    $(this._toolTipElement).css("top", setting.pos.y + hitinfo.y + 15).css("left", marginLeftMouse ? setting.pos.x + marginLeftMouse : setting.pos.x);
-                }
-                else {
-                    $(this._toolTipElement).css("top", setting.pos.y + hitinfo.cellRect.y ).css("left", setting.pos.x + hitinfo.cellRect.x + hitinfo.cellRect.width);
+                    $(this._toolTipElement).css("top", setting.pos.y + hitinfo.cellRect.y  -$(this._toolTipElement).height() -20).css("left", marginLeftMouse ? setting.pos.x + marginLeftMouse : setting.pos.x);
+                } else {
+                    //计算显示的初始位置
+                    let top = setting.pos.y + hitinfo.cellRect.y -$(this._toolTipElement).height() -26;
+                    let left =  setting.pos.x + hitinfo.cellRect.x;
+                    $(this._toolTipElement).css("top", top).css("left", left);
                 }
                 $(this._toolTipElement).show("fast");
                 TREE_SHEET_HELPER.tipDiv = 'show';//做个标记

+ 2 - 0
web/building_saas/complementary_glj_lib/html/tools-gongliaoji.html

@@ -148,6 +148,7 @@
     <script type="text/javascript" src="/public/web/QueryParam.js"></script>
     <script type="text/javascript" src="/lib/lodash/lodash.js"></script>
     <script type="text/javascript" src="/public/web/id_tree.js"></script>
+    <script type="text/javascript" src="/public/web/tools_const.js"></script>
     <script type="text/javascript" src="/public/web/tree_sheet/tree_sheet_controller.js"></script>
     <script type="text/javascript" src="/public/web/tree_sheet/tree_sheet_helper.js"></script>
     <script type="text/javascript" src="/public/web/ration_glj_units.js"></script>
@@ -160,6 +161,7 @@
     <script type="text/javascript" src="/web/building_saas/complementary_glj_lib/js/sheetOpr.js"></script>
     <script type="text/javascript" src="/public/web/storageUtil.js"></script>
     <!--endinject-->
+    <script type="text/javascript" src="<%= overWriteUrl %>"></script>
     <SCRIPT type="text/javascript">
         let userId = "<%= userID%>";
         let compilationId = "<%= compilationId%>";

+ 2 - 16
web/building_saas/complementary_glj_lib/js/components.js

@@ -73,13 +73,10 @@ let componentOprObj = {
         }
     },
     setShowGljList: function (gljList, clearChecked) {
-        //初始为所有工料机,机械类型可添加机械组成物、机上人工,混凝土,砂浆、配合比可添加普通材料
-        let machineArr = [302, 303];
-        let materialArr = [202, 203, 204];//混凝土、砂浆、配合比, 201普通材料
         let that = repositoryGljObj, me = componentOprObj;
             for(let i = 0; i < gljList.length; i++){
-                if(that.currentGlj.gljType === 301 && machineArr.indexOf(gljList[i].gljType) !== -1 ||
-                    materialArr.indexOf(that.currentGlj.gljType) !== -1 && gljList[i].gljType === 201 ||
+                if(machineAllowComponent.includes(that.currentGlj.gljType) && machineComponent.includes(gljList[i].gljType) ||
+                    materialAllowComponent.includes(that.currentGlj.gljType) && gljList[i].gljType === 201 ||
                     that.currentGlj.gljType === 4 && gljList[i].gljType === 4 && (!gljList[i].component || gljList[i].component.length === 0) && gljList[i].ID !== that.currentGlj.ID){
                     //去除与已添加的组成物重复的条目
                     let isExist = false;
@@ -123,7 +120,6 @@ let componentOprObj = {
     },
     filterDatasAndShow: function () {
         let me = componentOprObj, re = repositoryGljObj;
-        let materialArr = [202, 203, 204];//混凝土、砂浆、配合比, 201普通材料
         let val = $("input[name='glj']:checked").val();
         me.radiosSelected = val;
         //选择改变,数据重新筛选显示
@@ -164,20 +160,10 @@ let componentOprObj = {
     //监听radios选择事件
     radiosChange: function () {
         let me = componentOprObj, re = repositoryGljObj;
-        let materialArr = [202, 203, 204];//混凝土、砂浆、配合比, 201普通材料
         $('.glj-radio').change(function () {
             me.filterDatasAndShow();
         });
     },
-
-    //获得选择的组成物
-    getComponents: function () {
-        let rst = [];
-        let me = componentOprObj;
-        for(let i = 0; i < me.showGljList.length; i++){
-
-        }
-    },
     getParentCache: function (nodes) {
         let me = componentOprObj, rst = [];
         for(let i = 0; i < me.showGljList.length; i++){

+ 80 - 30
web/building_saas/complementary_glj_lib/js/glj.js

@@ -35,11 +35,10 @@ let repositoryGljObj = {
     gljList: [],
     stdGljList:[],
     complementaryGljList: [],
-    allowComponent: [202, 203, 204, 301, 4],//可带组成物类型:混凝土、砂浆、配合比、机械台班、主材
-    componentGljType: [201, 302, 303, 4],//可成为组成物的工料机类型: 普通材料、 机械组成物、 机上人工、主材
+    machineModel: {textArr: ['特', '大', '中', '小'], comboItems: [{text: '特', value: 1}, {text: '大', value: 2},{text: '中', value: 3}, {text: '小', value: 4}]},
+    machineModelIdx: {'1': '特', '2': '大', '3': '中', '4': '小'},
     distTypeTree: null,//add
     setting: {
-
         header:[
             {headerName:"编码",headerWidth:80,dataCode:"code", dataType: "String", formatter: "@", hAlign: "left", vAlign: "center"},
             {headerName:"名称",headerWidth:160,dataCode:"name", dataType: "String", hAlign: "left", vAlign: "center"},
@@ -47,6 +46,7 @@ let repositoryGljObj = {
             {headerName:"单位",headerWidth:45,dataCode:"unit", dataType: "String", hAlign: "center", vAlign: "center"},
             {headerName:"定额价",headerWidth:80,dataCode:"basePrice", dataType: "Number", formatter: "0.00", hAlign: "right", vAlign: "center"},
             {headerName:"类型",headerWidth:90,dataCode:"gljType", dataType: "String", hAlign: "center", vAlign: "center"},
+            {headerName:"机型",headerWidth:60,dataCode:"model", dataType: "Number", hAlign: "center", vAlign: "center"},
             {headerName:"是否新增",headerWidth:60,dataCode:"isComplementary", hAlign: "center", vAlign: "center"}
         ],
         view:{
@@ -86,16 +86,20 @@ let repositoryGljObj = {
                 data: typeData,
                 children: [],
                 parent: null
+            };
+            if(allowGljType.includes(typeData.ID)){
+                distTypeTree.distTypes[distTypeTree.prefix + typeData.ID] = typeObj;
+                distTypeTree.distTypesArr.push(typeObj);
             }
-            distTypeTree.distTypes[distTypeTree.prefix + typeData.ID] = typeObj;
-            distTypeTree.distTypesArr.push(typeObj);
         });
         gljDistType.forEach(function (typeData) {
-            distType = distTypeTree.distTypes[distTypeTree.prefix + typeData.ID];
-            let parent = distTypeTree.distTypes[distTypeTree.prefix + typeData.ParentID];
-            if(parent){
-                distType.parent = parent;
-                parent.children.push(distType);
+            if(allowGljType.includes(typeData.ID)){
+                distType = distTypeTree.distTypes[distTypeTree.prefix + typeData.ID];
+                let parent = distTypeTree.distTypes[distTypeTree.prefix + typeData.ParentID];
+                if(parent){
+                    distType.parent = parent;
+                    parent.children.push(distType);
+                }
             }
         });
         distTypeTree.distTypesArr.forEach(function (distTypeObj) {
@@ -164,8 +168,10 @@ let repositoryGljObj = {
                 }
             }
             sheetOpr.cleanData(me.workBook.getSheet(0), me.setting, -1);
-            sheetOpr.showData(me.workBook.getSheet(0), me.setting, cacheSection, me.distTypeTree);
+            sheetOpr.showData(me.workBook.getSheet(0), me.setting, cacheSection, me.distTypeTree, me.machineModelIdx);
             sheetCommonObj.setDynamicCombo(me.workBook.getActiveSheet(), 0, 5, me.workBook.getActiveSheet().getRowCount(), me.distTypeTree.comboDatas, false, 'text');
+            sheetCommonObj.setDynamicCombo(me.workBook.getActiveSheet(), 0, 6, me.workBook.getActiveSheet().getRowCount(), me.machineModel.comboItems, false, 'text');
+
 
             cacheSection = null;
         }
@@ -334,7 +340,7 @@ let repositoryGljObj = {
             if(row < me.currentCache.length){
                 //标记当前工料机
                 me.currentGlj = me.currentCache[row];
-                if(me.allowComponent.indexOf(me.currentCache[row].gljType) !== -1){
+                if(allowComponent.includes(me.currentCache[row].gljType)){
                     //展示数据
                     if(me.currentGlj.component.length > 0){
                         me.currentComponent = me.getCurrentComponent(me.currentGlj.component);
@@ -430,8 +436,8 @@ let repositoryGljObj = {
         me.orgCode = me.workBook.getSheet(0).getValue(args.row, 0);
         if(args.row < me.currentCache.length){
             me.currentGlj = me.currentCache[args.row];
-            if(args.col === 0 || (args.col === 4 && me.allowComponent.indexOf(me.currentGlj.gljType) !== -1 && me.currentGlj.component.length > 0)
-                || args.col === 6){
+            if(args.col === 0 || (args.col === 4 && allowComponent.includes(me.currentGlj.gljType) && me.currentGlj.component.length > 0)
+                || (args.col === 6 && me.currentGlj.gljType !== 301) || args.col === 7){
                 args.cancel = true;
             }
             else {
@@ -467,19 +473,24 @@ let repositoryGljObj = {
                                /* if(me.allowComponent.indexOf(rObj.gljType) !== -1){
                                     rObj.basePrice = 0;
                                 }*/
-                                if(me.componentGljType.indexOf(me.currentEditingGlj.gljType) !== -1 &&
-                                    !(me.currentEditingGlj.gljType === 302 && rObj.gljType === 303) && !(me.currentEditingGlj.gljType === 303 && rObj.gljType === 302)){//修改了原本是组成物的工料机
-                                    //寻找所有引用了此组成物的工料机,并从组成物中删去此工料机,并重算单价
-                                    let updateGljs = me.getUpdateGljs(rObj, true);
-                                    if(updateGljs.updateArr.length > 0 || updateGljs.updateBasePrcArr.length > 0){
-                                        for(let i = 0; i < updateGljs.updateArr.length; i++){
-                                            updateArr.push(updateGljs.updateArr[i]);
-                                        }
-                                        for(let i = 0; i < updateGljs.updateBasePrcArr.length; i++){
-                                            updateArr.push(updateGljs.updateBasePrcArr[i]);
-                                        }
+                            //工料机类型不为机械台班时,清空机型
+                            if(me.currentEditingGlj.gljType === 301 && rObj.gljType !== 301 && me.currentEditingGlj.model){
+                                rObj.model = null;
+                            }
+                            if(componentType.includes(me.currentEditingGlj.gljType) &&
+                                !(machineComponent.includes(me.currentEditingGlj.gljType) && machineComponent.includes(rObj.gljType))
+                                && !(materialComponent.includes(me.currentEditingGlj.gljType) && materialComponent.includes(rObj.gljType))){//修改了原本是组成物的工料机
+                                //寻找所有引用了此组成物的工料机,并从组成物中删去此工料机,并重算单价
+                                let updateGljs = me.getUpdateGljs(rObj, true);
+                                if(updateGljs.updateArr.length > 0 || updateGljs.updateBasePrcArr.length > 0){
+                                    for(let i = 0; i < updateGljs.updateArr.length; i++){
+                                        updateArr.push(updateGljs.updateArr[i]);
+                                    }
+                                    for(let i = 0; i < updateGljs.updateBasePrcArr.length; i++){
+                                        updateArr.push(updateGljs.updateBasePrcArr[i]);
                                     }
                                 }
+                            }
                             sheetOpr.cleanData(that.workBook.getSheet(0), that.setting, 5);
                         }
                         else if(rObj.basePrice !== me.currentEditingGlj.basePrice){//修改了单价,可修改单价的必为可成为组成物的
@@ -610,7 +621,7 @@ let repositoryGljObj = {
                                     for(let col = sels[i].col; col <= maxCol; col++){
                                         if(me.setting.header[col].dataCode === 'basePrice'){
                                             //如果类型不为混凝土、砂浆、配合比、机械,才可删除单价 basePrice = 0
-                                            if(me.allowComponent.indexOf(updateObj.gljType) === -1){
+                                            if(!allowComponent.includes(updateObj.gljType)){
                                                 canUpdate = true;
                                                 updateObj[me.setting.header[col].dataCode] = 0;
                                                 updateBasePrcArr.push({gljId: updateObj.ID, gljType: updateObj.gljType, basePrice: 0});
@@ -717,9 +728,12 @@ let repositoryGljObj = {
                     pasteObj.gljType = me.distTypeTree.comboDatas[i].value;
                     isExsit = true;
                     reCalBasePrc = true;
-                    //
-                    if(me.componentGljType.indexOf(tempObj.gljType) !== -1 &&
-                        !(tempObj.gljType === 302 && pasteObj.gljType === 303) && !(tempObj.gljType === 303 && pasteObj.gljType === 302)){//修改了原本是组成物的工料机
+                    if(pasteObj.gljType !== 301 && tempObj.gljType === 301){
+                        tempObj.model = null;
+                    }
+                    if(componentType.includes(tempObj.gljType)&&
+                        !(machineComponent.includes(tempObj.gljType) && machineComponent.includes(pasteObj.gljType)) &&
+                        !(materialComponent.includes(tempObj.gljType) && materialComponent.includes(pasteObj.gljType))){//修改了原本是组成物的工料机
                         //寻找所有引用了此组成物的工料机,并从组成物中删去此工料机,并重算单价
                         let updateGljs = me.getUpdateGljs(tempObj, true);
                         if(updateGljs.updateArr.length > 0 || updateGljs.updateBasePrcArr.length > 0){
@@ -758,6 +772,29 @@ let repositoryGljObj = {
                 }
             }
         }
+        if(typeof pasteObj.model !== 'undefined'){
+            if(!me.machineModel.textArr.includes(pasteObj.model)){
+                isValid = false;
+            }
+            else {
+                let existsModel = false;
+                if((typeof pasteObj.gljType !== 'undefined' && pasteObj.gljType === 301) ||
+                    (tempObj.gljType && tempObj.gljType === 301)){
+                    me.machineModel.comboItems.forEach(function (item) {
+                        if(item.text === pasteObj.model){
+                            tempObj.model = item.value;
+                            existsModel = true;
+                        }
+                    });
+                    if(!existsModel){
+                        isValid = false;
+                    }
+                }
+                else {
+                    isValid = false;
+                }
+            }
+        }
         if(isValid){
             rst.updateGlj.push(tempObj);
             if(reCalBasePrc){
@@ -808,6 +845,16 @@ let repositoryGljObj = {
             }
 
         }
+        if(typeof pasteObj.model !== 'undefined' && pasteObj.model){
+            if(!me.machineModel.textArr.includes(pasteObj.model) || pasteObj.gljType !== 301){
+                return false;
+            }
+            me.machineModel.comboItems.forEach(function (item) {
+                if(item.text === pasteObj.model){
+                    pasteObj.model = item.value;
+                }
+            });
+        }
         pasteObj.basePrice = !isNaN(parseFloat(pasteObj.basePrice)) && (pasteObj.basePrice && typeof pasteObj.basePrice !== 'undefined') ? parseFloat(pasteObj.basePrice) : 0;
         if(!me.parentNodeIds["_pNodeId_" + me.gljCurTypeId]){
             pasteObj.gljClass = me.gljCurTypeId;
@@ -831,7 +878,7 @@ let repositoryGljObj = {
                 for(let i = 0, len = info.cellRange.rowCount; i < len; i++){
                     let row = i + info.cellRange.row;
                     if(row < me.currentCache.length){
-                        if(me.allowComponent.indexOf(me.currentCache[row].gljType) !== -1){
+                        if(allowComponent.includes(me.currentCache[row].gljType)){
                             rst = false;
                         }
                     }
@@ -924,6 +971,9 @@ let repositoryGljObj = {
                             let gljType = me.currentCache[resumeArr[i]][me.setting.header[col].dataCode];
                             sheet.setValue(resumeArr[i], col, me.distTypeTree.distTypes["gljType" + gljType].data.fullName);
                         }
+                        else if(me.setting.header[col].dataCode === 'model'){
+                            sheet.setValue(resumeArr[i], col, me.currentCache[resumeArr[i]][me.setting.header[col].dataCode] ? me.machineModelIdx[me.currentCache[resumeArr[i]][me.setting.header[col].dataCode]]: '');
+                        }
                         else{
                             sheet.setValue(resumeArr[i], col, me.currentCache[resumeArr[i]][me.setting.header[col].dataCode]);
                         }

+ 2 - 2
web/building_saas/complementary_glj_lib/js/gljComponent.js

@@ -71,7 +71,7 @@ let gljComponentOprObj = {
                     //控制按钮是否可用
                     let insertDis = false,
                         delDis = false;
-                    if(!(that.currentGlj && that.allowComponent.indexOf(that.currentGlj.gljType) !== -1) || (that.currentGlj.gljType === 4 && that.isComponent(that.currentGlj.ID, that.stdGljList.concat(that.complementaryGljList)))){
+                    if(!(that.currentGlj && allowComponent.includes(that.currentGlj.gljType)) || (that.currentGlj.gljType === 4 && that.isComponent(that.currentGlj.ID, that.stdGljList.concat(that.complementaryGljList)))){
                         insertDis = true;
                     }
                     if(!that.currentGlj || typeof that.currentComponent === 'undefined' || (typeof that.currentComponent !== 'undefined' && target.row >= that.currentComponent.length)){//右键定位在有组成物的行,删除键才显示可用
@@ -211,7 +211,7 @@ let gljComponentOprObj = {
         let thatRow = that.workBook.getSheet(0).getSelections()[0].row;
         if(thatRow < that.currentCache.length){
             that.currentGlj = that.currentCache[thatRow];
-            if(me.setting.view.lockedCols.indexOf(args.col) !== -1 || that.allowComponent.indexOf(that.currentGlj.gljType) === -1 ||
+            if(me.setting.view.lockedCols.indexOf(args.col) !== -1 || !allowComponent.includes(that.currentGlj.gljType) ||
                 (that.currentGlj.gljType === 4 && that.isComponent(that.currentGlj.ID, that.stdGljList.concat(that.complementaryGljList))) ||
                 (args.col === 4 && (!that.currentComponent|| args.row >= that.currentComponent.length))){
                 args.cancel = true;

+ 12 - 1
web/building_saas/complementary_glj_lib/js/sheetOpr.js

@@ -111,7 +111,7 @@ let sheetOpr = {
             area.vAlign(GC.Spread.Sheets.VerticalAlign.center);
         }
     },
-    showData: function(sheet, setting, data, distTypeTree) {
+    showData: function(sheet, setting, data, distTypeTree, machineModelIdx) {
         var me = this, ch = GC.Spread.Sheets.SheetArea.viewport;
         sheet.suspendPaint();
         sheet.suspendEvent();
@@ -139,6 +139,9 @@ let sheetOpr = {
                     let distTypeVal =  distTypeTree.distTypes[distTypeTree.prefix + data[row].gljType].data.fullName;
                     sheet.setValue(row, col, distTypeVal, ch);
                 }
+                else if(setting.header[col].dataCode === 'model' && data[row].model){
+                    sheet.setValue(row, col, machineModelIdx ? machineModelIdx[data[row].model] : '');
+                }
                 else {
                     sheet.setValue(row, col, data[row][setting.header[col].dataCode], ch);
                     sheet.setTag(row, 0, data[row].ID, ch);
@@ -195,6 +198,7 @@ let sheetOpr = {
         var rst = {};
         let comboBoxCellType = sheet.getCellType(row, 5);
         let items = comboBoxCellType.items();
+        let machineItems = sheet.getCellType(row, 6).items();
         for (var col = 0; col < setting.header.length; col++) {
             if(setting.header[col].dataCode === 'gljType'){
                 items.forEach(function(item){
@@ -206,6 +210,13 @@ let sheetOpr = {
                     }
                 });
             }
+            else if(setting.header[col].dataCode === 'model'){
+                machineItems.forEach(function(item){
+                    if(sheet.getValue(row, col) === item.text){
+                        rst[setting.header[col].dataCode] = item.value;
+                    }
+                });
+            }
             else if (setting.header[col].dataCode === 'code'){
                 if(repositoryGljObj){
                     let stdGljList = repositoryGljObj.stdGljList,

+ 40 - 0
web/building_saas/css/custom.css

@@ -59,4 +59,44 @@ legend.legend{
 .modal-quantity-edit-height {
     height: 200px;
     overflow-y: auto;
+}
+
+.message-box {
+    position:absolute;
+    background:#000;
+    padding:8px 10px;
+    line-height: 18px;
+    border-radius:4px;
+    text-align:left;
+    font:0.9rem Calibri;
+    box-shadow:2px 2px 6px #ccc;
+    color:#fff;
+}
+.triangle-border {
+    position:absolute;
+    left:10px;
+    overflow:hidden;
+    width:0;
+    height:0;
+    border-width:6px;
+    border-style:solid dashed dashed dashed;
+}
+.tb-border {
+    bottom:-12px;
+    border-color:#000 transparent transparent transparent;
+}
+.tb-background {
+    bottom:-11px;
+    border-color:#000 transparent transparent transparent;
+}
+
+.tb-border_up {
+    top:-12px;
+    border-color:transparent transparent #000 transparent;
+}
+.tb-background_up {
+    top:-11px;
+    border-color:transparent transparent #000 transparent;}
+.elf-options:hover{
+    background-color: #CCCCCC;
 }

+ 119 - 131
web/building_saas/main/html/main.html

@@ -1455,144 +1455,132 @@
     <script src = "/lib/spreadjs/sheets/gc.spread.sheets.all.11.1.2.min.js"></script>
     <script src="/lib/spreadjs/sheets/interop/gc.spread.excelio.11.1.2.min.js"></script>
     <script>GC.Spread.Sheets.LicenseKey =  '<%- LicenseKey %>';</script>
-
     <script type="text/javascript" src="/lib/jquery-ui/jquery-ui-datepickerCN.js"></script>
     <script type="text/javascript" src="/lib/jquery-contextmenu/jquery.contextMenu.js"></script>
     <script type="text/javascript" src="/lib/jquery-contextmenu/jquery.ui.position.js"></script>
-
-        <script src="/lib/spreadjs/views/gc.spread.views.dataview.10.0.0.min.js" type="text/javascript"></script>
-        <script type="text/javascript" src="/lib/ztree/jquery.ztree.core.js"></script>
-        <script type="text/javascript" src="/lib/ztree/jquery.ztree.excheck.js"></script>
-        <!--<script src="/lib/spreadjs/views/common/gc.spread.common.10.0.0.min.js" type="text/javascript"></script>-->
-        <script src="/lib/spreadjs/views/plugins/gc.spread.views.gridlayout.10.0.0.min.js" type="text/javascript"></script>
-        <script src="/lib/js-xlsx/xlsx.core.min.js"></script>
-        <script src="/lib/lz-string/lz-string.min.js"></script>
-        <!-- inject:js -->
-        <!--<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="/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/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/composition_spread.js"></script>
-        <script type="text/javascript" src="/web/building_saas/glj/js/project_glj_spread.js"></script>
-
-        <script src="/web/building_saas/glj/js/socket.io.slim.js"></script>
-        <script src="/public/web/socket/connection.js"></script>
-        <script src="/public/web/uuid.js"></script>
-
-        <script type="text/javascript" src="/public/web/sheet/sheet_common.js"></script>
-
-        <!--expression calculate-->
-        <script src="/lib/JSExpressionEval_src/Date.js"></script>
-        <script src="/lib/JSExpressionEval_src/Stack.js"></script>
-        <script src="/lib/JSExpressionEval_src/Tokanizer.js"></script>
-        <script src="/lib/JSExpressionEval_src/Evaluator.js"></script>
-        <!--end expression calculate-->
-        <!--<script type="text/javascript" src="/lib/jquery-ui/jquery-ui.min.js"></script>
-        <script type="text/javascript" src="/lib/jquery-ui/jquery-ui-datepickerCN.js"></script>
-        <script type="text/javascript" src="/lib/jquery-contextmenu/jquery.contextMenu.js"></script>
-        <script type="text/javascript" src="/lib/jquery-contextmenu/jquery.ui.position.js"></script>-->
+    <script src="/lib/spreadjs/views/gc.spread.views.dataview.10.0.0.min.js" type="text/javascript"></script>
+    <script type="text/javascript" src="/lib/ztree/jquery.ztree.core.js"></script>
+    <script type="text/javascript" src="/lib/ztree/jquery.ztree.excheck.js"></script>
+    <!--<script src="/lib/spreadjs/views/common/gc.spread.common.10.0.0.min.js" type="text/javascript"></script>-->
+    <script src="/lib/spreadjs/views/plugins/gc.spread.views.gridlayout.10.0.0.min.js" type="text/javascript"></script>
+    <script src="/lib/js-xlsx/xlsx.core.min.js"></script>
+    <script src="/lib/lz-string/lz-string.min.js"></script>
+    <!-- inject:js -->
+    <!--<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="/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/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/composition_spread.js"></script>
+    <script type="text/javascript" src="/web/building_saas/glj/js/project_glj_spread.js"></script>
+    <script src="/web/building_saas/glj/js/socket.io.slim.js"></script>
+    <script src="/public/web/socket/connection.js"></script>
+    <script src="/public/web/uuid.js"></script>
+    <script type="text/javascript" src="/public/web/sheet/sheet_common.js"></script>
+    <!--expression calculate-->
+    <script src="/lib/JSExpressionEval_src/Date.js"></script>
+    <script src="/lib/JSExpressionEval_src/Stack.js"></script>
+    <script src="/lib/JSExpressionEval_src/Tokanizer.js"></script>
+    <script src="/lib/JSExpressionEval_src/Evaluator.js"></script>
+    <!--end expression calculate-->
+    <!--<script type="text/javascript" src="/lib/jquery-ui/jquery-ui.min.js"></script>
+    <script type="text/javascript" src="/lib/jquery-ui/jquery-ui-datepickerCN.js"></script>
+    <script type="text/javascript" src="/lib/jquery-contextmenu/jquery.contextMenu.js"></script>
+    <script type="text/javascript" src="/lib/jquery-contextmenu/jquery.ui.position.js"></script>-->
         <!--<script type="text/javascript" src="/lib/lodash/lodash.js"></script>-->
     <!-- Common -->
-        <script type="text/javascript" src="/public/web/common_ajax.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/sheet/sheet_common.js"></script>
+    <script type="text/javascript" src="/public/web/common_ajax.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/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 -->
 
-        <!-- 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 -->
-
-        <!-- SpreadJs -->
-
-        <!--<script src="/lib/spreadjs/views/locale/gc.spread.views.dataview.locale.zh-CN.10.0.0.min.js" type="text/javascript"></script>-->
-        <!-- Model -->
-
-        <script type="text/javascript" src="/web/building_saas/main/js/models/project.js"></script>
-        <script type="text/javascript" src="/web/building_saas/main/js/models/bills.js"></script>
-        <script type="text/javascript" src="/web/building_saas/main/js/models/ration.js"></script>
-        <script type="text/javascript" src="/web/building_saas/main/js/models/glj.js"></script>
-        <script type="text/javascript" src="/web/building_saas/main/js/models/project_glj.js"></script>
-        <script type="text/javascript" src="/web/building_saas/main/js/models/composition.js"></script>
-        <script type="text/javascript" src="/web/building_saas/main/js/models/fee_rate.js"></script>
-        <script type="text/javascript" src="/web/building_saas/main/js/models/ration_glj.js"></script>
-        <script type="text/javascript" src="/web/building_saas/main/js/models/ration_coe.js"></script>
-        <script type="text/javascript" src="/web/building_saas/main/js/models/ration_ass.js"></script>
-        <script type="text/javascript" src="/web/building_saas/main/js/models/ration_installation.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/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/models/installation_fee.js"></script>
-        <script type="text/javascript" src="/web/building_saas/main/js/views/calc_program_manage.js"></script>
+    <!-- SpreadJs -->
 
-
-
-        <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/calc/calc_fees.js"></script>
-        <!--<script type="text/javascript" src="/web/building_saas/main/js/calc/ration_calc.js"></script>-->
-        <!--<script type="text/javascript" src="/web/building_saas/main/js/calc/bills_calc.js"></script>-->
-        <!--<script type="text/javascript" src="/public/calc_util.js"></script>-->
-        <!-- Controller -->
-        <script type="text/javascript" src="/public/web/tree_sheet/tree_sheet_controller.js"></script>
-        <script type="text/javascript" src="/public/web/tree_sheet/tree_sheet_helper.js"></script>
-        <script type="text/javascript" src="/public/web/sheet/sheet_data_helper.js"></script>
-
-        <!-- view -->
-        <script type="text/javascript" src="/web/building_saas/main/js/views/glj_col.js"></script>
-        <script type="text/javascript" src="/web/building_saas/main/js/views/main_tree_col.js"></script>
-        <script type="text/javascript" src="/web/building_saas/main/js/views/project_info.js"></script>
-        <script type="text/javascript" src="/web/building_saas/main/js/views/project_view.js"></script>
-        <script type="text/javascript" src="/web/building_saas/main/js/views/options_view.js"></script>
-        <script type="text/javascript" src="/web/building_saas/main/js/views/project_property_bills_quantity_decimal.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_projFeature.js"></script>
-        <script type="text/javascript" src="/web/building_saas/main/js/views/project_property_indicativeInfo.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.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/block_controller.js"></script>
-        <script type="text/javascript" src="/web/building_saas/main/js/views/side_tools.js"></script>
-        <script type="text/javascript" src="/web/building_saas/main/js/views/std_billsGuidance_lib.js"></script>
-        <script type="text/javascript" src="/web/building_saas/main/js/views/std_bills_lib.js"></script>
-        <script type="text/javascript" src="/web/building_saas/main/js/views/std_ration_lib.js"></script>
-        <script type="text/javascript" src="/web/building_saas/main/js/models/quantity_detail.js"></script>
-        <script type="text/javascript" src="/web/building_saas/main/js/views/glj_view_contextMenu.js"></script>
-        <script type="text/javascript" src="/web/building_saas/main/js/views/calc_program_view.js"></script>
-        <script type="text/javascript" src='/web/building_saas/main/js/views/confirm_modal.js'></script>
-        <script type="text/javascript" src='/web/building_saas/main/js/views/zlfb_view.js'></script>
-        <script type="text/javascript" src='/web/building_saas/main/js/views/installation_fee_view.js'></script>
-        <script type="text/javascript" src='/web/building_saas/main/js/views/project_glj_view.js'></script>
-        <script type="text/javascript" src="/web/building_saas/main/js/views/importBills.js"></script>
-        <!--报表-->
-        <script type="text/javascript" src="/public/web/rpt_tpl_def.js"></script>
-        <script type="text/javascript" src="/public/web/treeDataHelper.js"></script>
-        <script type="text/javascript" src="/public/web/ztree_common.js"></script>
-        <script type="text/javascript" src="/web/building_saas/report/js/rpt_main.js"></script>
-        <script type="text/javascript" src="/web/building_saas/report/js/rpt_cfg_const.js"></script>
-        <script type="text/javascript" src="/web/building_saas/report/js/jpc_output_value_define.js"></script>
-        <script type="text/javascript" src="/web/building_saas/report/js/jpc_output.js"></script>
-        <script type="text/javascript" src="/web/building_saas/report/js/rpt_print.js"></script>
-        <script type="text/javascript" src="/web/building_saas/main/js/views/character_content_view.js"></script>
-        <script type="text/javascript" src="/web/building_saas/main/js/views/glj_view.js"></script>
-        <script type="text/javascript" src="/web/building_saas/main/js/views/zmhs_view.js"></script>
-        <script type="text/javascript" src="/web/building_saas/main/js/views/tender_price_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/quantity_edit_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/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/complementary_ration_lib/js/main.js"></script>
-         <script type="text/javascript" src="/public/web/storageUtil.js"></script>
-        <!-- endinject -->
+    <!--<script src="/lib/spreadjs/views/locale/gc.spread.views.dataview.locale.zh-CN.10.0.0.min.js" type="text/javascript"></script>-->
+    <!-- Model -->
+    <script type="text/javascript" src="/web/building_saas/main/js/models/project.js"></script>
+    <script type="text/javascript" src="/web/building_saas/main/js/models/bills.js"></script>
+    <script type="text/javascript" src="/web/building_saas/main/js/models/ration.js"></script>
+    <script type="text/javascript" src="/web/building_saas/main/js/models/glj.js"></script>
+    <script type="text/javascript" src="/web/building_saas/main/js/models/project_glj.js"></script>
+    <script type="text/javascript" src="/web/building_saas/main/js/models/composition.js"></script>
+    <script type="text/javascript" src="/web/building_saas/main/js/models/fee_rate.js"></script>
+    <script type="text/javascript" src="/web/building_saas/main/js/models/ration_glj.js"></script>
+    <script type="text/javascript" src="/web/building_saas/main/js/models/ration_coe.js"></script>
+    <script type="text/javascript" src="/web/building_saas/main/js/models/ration_ass.js"></script>
+    <script type="text/javascript" src="/web/building_saas/main/js/models/ration_installation.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/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/models/installation_fee.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="/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/ration_calc.js"></script>-->
+    <!--<script type="text/javascript" src="/web/building_saas/main/js/calc/bills_calc.js"></script>-->
+    <!--<script type="text/javascript" src="/public/calc_util.js"></script>-->
+    <!-- Controller -->
+    <script type="text/javascript" src="/public/web/tree_sheet/tree_sheet_controller.js"></script>
+    <script type="text/javascript" src="/public/web/tree_sheet/tree_sheet_helper.js"></script>
+    <script type="text/javascript" src="/public/web/sheet/sheet_data_helper.js"></script>
+    <!-- view -->
+    <script type="text/javascript" src="/web/building_saas/main/js/views/glj_col.js"></script>
+    <script type="text/javascript" src="/web/building_saas/main/js/views/main_tree_col.js"></script>
+    <script type="text/javascript" src="/web/building_saas/main/js/views/project_info.js"></script>
+    <script type="text/javascript" src="/web/building_saas/main/js/views/project_view.js"></script>
+    <script type="text/javascript" src="/web/building_saas/main/js/views/options_view.js"></script>
+    <script type="text/javascript" src="/web/building_saas/main/js/views/project_property_bills_quantity_decimal.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_projFeature.js"></script>
+    <script type="text/javascript" src="/web/building_saas/main/js/views/project_property_indicativeInfo.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.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/block_controller.js"></script>
+    <script type="text/javascript" src="/web/building_saas/main/js/views/side_tools.js"></script>
+    <script type="text/javascript" src="/web/building_saas/main/js/views/std_billsGuidance_lib.js"></script>
+    <script type="text/javascript" src="/web/building_saas/main/js/views/std_bills_lib.js"></script>
+    <script type="text/javascript" src="/web/building_saas/main/js/views/std_ration_lib.js"></script>
+    <script type="text/javascript" src="/web/building_saas/main/js/models/quantity_detail.js"></script>
+    <script type="text/javascript" src="/web/building_saas/main/js/views/glj_view_contextMenu.js"></script>
+    <script type="text/javascript" src="/web/building_saas/main/js/views/calc_program_view.js"></script>
+    <script type="text/javascript" src='/web/building_saas/main/js/views/confirm_modal.js'></script>
+    <script type="text/javascript" src='/web/building_saas/main/js/views/zlfb_view.js'></script>
+    <script type="text/javascript" src='/web/building_saas/main/js/views/installation_fee_view.js'></script>
+    <script type="text/javascript" src='/web/building_saas/main/js/views/project_glj_view.js'></script>
+    <script type="text/javascript" src="/web/building_saas/main/js/views/importBills.js"></script>
+    <!--报表-->
+    <script type="text/javascript" src="/public/web/rpt_tpl_def.js"></script>
+    <script type="text/javascript" src="/public/web/treeDataHelper.js"></script>
+    <script type="text/javascript" src="/public/web/ztree_common.js"></script>
+    <script type="text/javascript" src="/web/building_saas/report/js/rpt_main.js"></script>
+    <script type="text/javascript" src="/web/building_saas/report/js/rpt_cfg_const.js"></script>
+    <script type="text/javascript" src="/web/building_saas/report/js/jpc_output_value_define.js"></script>
+    <script type="text/javascript" src="/web/building_saas/report/js/jpc_output.js"></script>
+    <script type="text/javascript" src="/web/building_saas/report/js/rpt_print.js"></script>
+    <script type="text/javascript" src="/web/building_saas/main/js/views/character_content_view.js"></script>
+    <script type="text/javascript" src="/web/building_saas/main/js/views/glj_view.js"></script>
+    <script type="text/javascript" src="/web/building_saas/main/js/views/zmhs_view.js"></script>
+    <script type="text/javascript" src="/web/building_saas/main/js/views/tender_price_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/quantity_edit_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/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/complementary_ration_lib/js/main.js"></script>
+    <script type="text/javascript" src="/public/web/storageUtil.js"></script>
+    <!-- endinject -->
 
     <% if (overWriteUrl != undefined) { %>
          <script type="text/javascript" src="<%= overWriteUrl%>"></script>

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

@@ -244,7 +244,7 @@ let BlockController = {
                 let billsQuantity = scMathUtil.roundForObj(parent.data.quantity,getDecimal("quantity",parent));
                 this.calcRationQuantityAndContain(billsQuantity,d);
                 //如果粘贴位置不属于分部分项工程,或者不是安装工程,则把安装增加费内容置空
-                if(!Bills.isFBFX(parent)|| projectInfoObj.projectInfo.property.engineering!=engineeringType.BUILD_IN){
+                if(!Bills.isFBFX(parent)|| !project.isInstall()){
                     d.ration_installations = [];
                 }
             }

+ 127 - 31
web/building_saas/main/js/models/calc_base.js

@@ -77,7 +77,7 @@ let cbTools = {
         if(this.isUnDef(exp) || exp === ''){
             return rst;
         }
-        if(exp.includes('{税前工程造价}')){
+       /* if(exp.includes('{税前工程造价}')){
             let findChildNodes = [];
             let subEngingeering = this.findBill(fixedFlag.SUB_ENGINERRING) ? this.getNodeByID(this.findBill(fixedFlag.SUB_ENGINERRING).ID) : null,
                 measure = this.findBill(fixedFlag.MEASURE) ? this.getNodeByID(this.findBill(fixedFlag.MEASURE).ID) : null,
@@ -101,14 +101,29 @@ let cbTools = {
                 ids.push(cNode.data.ID);
             }
             rst = rst.concat(childrenNodes);
-        }
+        }*/
         //获取表达式中的基数和行引用
         let figureF = cbParser.getFigureF(cbParser.getFigure(exp), cbParser.getUID(cbParser.getFIDArr(exp)));
         for(let i = 0, len = figureF.length; i < len; i++){
             let figure = figureF[i];
             if(figure.type === 'base' && cbTools.isDef(calcBase.baseFigures[figure.value])){
                 let bill = this.isDef(calcBase.baseFigures[figure.value]['fixedBill']) ? calcBase.baseFigures[figure.value]['fixedBill']['bill'] : null;
-                if(this.isDef(bill) && ids.indexOf(bill.ID) === -1){
+                let figureMultiRef = calcBase.baseFigures[figure.value]['multiRef'];
+                if(this.isDef(figureMultiRef)){
+                    let findChildNodes = [];
+                    for(let flag of figureMultiRef){
+                        let refBill = this.findBill(flag);
+                        if(refBill){
+                            findChildNodes.push(refBill);
+                        }
+                    }
+                    let childrenNodes = calcTools.getChildrenFormulaNodes(node, formulaNodesArr, findChildNodes);
+                    for(let cNode of childrenNodes){
+                        ids.push(cNode.data.ID);
+                    }
+                    rst = rst.concat(childrenNodes);
+                }
+                else if(this.isDef(bill) && ids.indexOf(bill.ID) === -1){
                     let node = this.getNodeByID(bill.ID);
                     if(this.isDef(node)){
                         ids.push(node.data.ID);
@@ -154,6 +169,52 @@ let cbTools = {
     },
     //生成清单基数计算分类模板
     setBaseFigureClass: function (baseFigures, mapObj) {
+        for(let figureClass in figureClassTemplate){
+            mapObj[figureClass] = Object.create(null);
+        }
+        let needFixedBillsClass = ['FBFX', 'CXSM', 'QTXM', 'GF', 'SJ'];
+        //不需要关联节点的、但是下挂在固定清单分类下的基数
+        let noneFixedBillsFigures = ['JZMJ'];
+        //安全文明施工专项费用只有税金和工程造价能用
+        for(let figure in baseFigures){
+            if(!noneFixedBillsFigures.includes(baseFigures[figure]['base'])){
+                //过滤相关清单固定行不存在的
+                if(needFixedBillsClass.includes(baseFigures[figure]['class']) && !baseFigures[figure]['fixedBill']){
+                    continue;
+                }
+            }
+            for(let figureClass in figureClassTemplate){
+                let figureClassFilter = figureClassTemplate[figureClass]['filter'];
+                if(!figureClassFilter.includes(baseFigures[figure]['base'])){
+                    mapObj[figureClass][figure] = baseFigures[figure];
+                }
+            }
+            /*if(filter.indexOf(baseFigures[figure]['base']) === -1){
+                mapObj['CONSTRUCTION_ORGANIZATION'][figure] = baseFigures[figure];
+            }
+            if(baseFigures[figure]['base'] !== 'QTXMF' && baseFigures[figure]['base'] !== 'SQGCZJ' && baseFigures[figure]['base'] !== 'AQWMSGZXF'){
+                mapObj['OTHER'][figure] = baseFigures[figure];
+            }
+            if(baseFigures[figure]['base'] !== 'GF' && baseFigures[figure]['base'] !== 'SQGCZJ' && baseFigures[figure]['base'] !== 'AQWMSGZXF'){
+                mapObj['CHARGE'][figure] = baseFigures[figure];
+            }
+            if(baseFigures[figure]['base'] !== 'SJ' && baseFigures[figure]['base'] !== 'SQGCZJ'){
+                mapObj['TAX'][figure] = baseFigures[figure];
+            }
+            if(baseFigures[figure]['base'] !== 'SQGCZJ'){
+                mapObj['ENGINEERINGCOST'][figure] = baseFigures[figure];
+            }
+            if(baseFigures[figure]['base'] !== 'SQGCZJ' && baseFigures[figure]['base'] !== 'AQWMSGZXF'){
+                mapObj['OTHERS'][figure] = baseFigures[figure];
+            }
+            if(baseFigures[figure]['base'] === 'SQGCZJ'){
+                mapObj['SAFETY_CONSTRUCTION'][figure] = baseFigures[figure];
+            }*/
+        }
+       // mapObj['SAFETY_CONSTRUCTION'] = Object.assign(mapObj['SAFETY_CONSTRUCTION'], mapObj['CONSTRUCTION_ORGANIZATION']);
+
+    },
+    /*setBaseFigureClass: function (baseFigures, mapObj) {
         mapObj['CONSTRUCTION_ORGANIZATION'] = Object.create(null);
         mapObj['SAFETY_CONSTRUCTION'] = Object.create(null);
         mapObj['OTHER'] = Object.create(null);
@@ -197,7 +258,7 @@ let cbTools = {
         }
         mapObj['SAFETY_CONSTRUCTION'] = Object.assign(mapObj['SAFETY_CONSTRUCTION'], mapObj['CONSTRUCTION_ORGANIZATION']);
 
-    },
+    },*/
     getFigure: function (node) {
         let calcBase = projectObj.project.calcBase;
         let parent = node.parent;
@@ -205,6 +266,28 @@ let cbTools = {
             || node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.CONSTRUCTION_TECH)){
             return null;
         }
+        if(this.isFlag(node.data)){
+            for(let figureClass in figureClassTemplate){
+                let figureClassFlag = figureClassTemplate[figureClass]['flag'];
+                if(figureClassFlag && node.data.flagsIndex.fixed.flag === figureClassFlag){
+                    return calcBase.baseFigureClass[figureClass]
+                }
+            }
+        }
+        if(!parent){
+            return calcBase.baseFigureClass.OTHERS;
+        }
+        else {
+            return this.getFigure(parent);
+        }
+    },
+    /*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;
         }
@@ -231,7 +314,7 @@ let cbTools = {
                 return this.getFigure(parent);
             }
         }
-    },
+    },*/
     getBaseBill: function (node) {
         let calcBase = projectObj.project.calcBase;
         let parent = node.parent;
@@ -275,8 +358,19 @@ let cbTools = {
             for(let i = 0, len = bases.length; i < len; i++){
                 //基数是跟清单直接关联的
                 if(bases[i]['type'] === 'base' && cbTools.isDef(calcBase.baseFigures[bases[i]['value']])){
+                    let figureMultiRef= calcBase.baseFigures[bases[i]['value']]['multiRef'];
+                    //重构后:
+                    if(cbTools.isDef(figureMultiRef)){
+                        for(let flag of figureMultiRef){
+                            let bills = cbTools.findBill(flag);
+                            if(cbTools.isDef(bills)){
+                                block.push(bills.ID);
+                            }
+                        }
+                    }
+
                     //税前工程造价算法用了分部分项、项目措施(已排除)、其他项目、规费里的底层价格,相当于引用了4条固定清单,特殊处理
-                    if(bases[i]['value'] === '税前工程造价'){
+                   /* if(bases[i]['value'] === '税前工程造价'){
                         let subEngineering = cbTools.findBill(calcBase.fixedFlag.SUB_ENGINERRING),
                             other = cbTools.findBill(calcBase.fixedFlag.OTHER),
                             charge = cbTools.findBill(calcBase.fixedFlag.CHARGE);
@@ -289,7 +383,7 @@ let cbTools = {
                         if(charge){
                             block.push(charge.ID);
                         }
-                    }
+                    }*/
                     else if(cbTools.isDef(calcBase.baseFigures[bases[i]['value']]['fixedBill'])){
                         block.push(calcBase.baseFigures[bases[i]['value']]['fixedBill']['bill']['ID']);
                     }
@@ -1120,7 +1214,18 @@ let baseFigureTemplate = {
     }
 };
 
+let figureClassTemplate = {
+    'CONSTRUCTION_ORGANIZATION': {flag: fixedFlag.CONSTRUCTION_ORGANIZATION, filter: ['CSXMF', 'ZZCSXMF', 'ZZCSXMDEJJZJGCF', 'ZZCSXMDEJJRGF', 'ZZCSXMDEJJCLF', 'ZZCSXMDEJJJXF', 'QTXMF', 'GF', 'SJ', 'SQGCZJ', 'AQWMSGZXF']},
+    'SAFETY_CONSTRUCTION': {flag: fixedFlag.SAFETY_CONSTRUCTION, filter: ['CSXMF', 'ZZCSXMF', 'ZZCSXMDEJJZJGCF', 'ZZCSXMDEJJRGF', 'ZZCSXMDEJJCLF', 'ZZCSXMDEJJJXF', 'QTXMF', 'GF', 'SJ', 'AQWMSGZXF']},
+    'OTHER': {flag: fixedFlag.OTHER, filter: ['QTXMF', 'SQGCZJ', 'AQWMSGZXF']},
+    'CHARGE': {flag: fixedFlag.CHARGE, filter: ['GF', 'SQGCZJ', 'AQWMSGZXF']},
+    'TAX': {flag: fixedFlag.TAX, filter: ['SJ', 'SQGCZJ']},
+    'ENGINEERINGCOST': {flag: fixedFlag.ENGINEERINGCOST, filter: ['SQGCZJ']},
+    'OTHERS': {flag: fixedFlag.ENGINEERINGCOST, filter: ['SQGCZJ', 'AQWMSGZXF']},
+};
+
 //基数的值不是通过清单节点获得的,则该基数的fixedBill为空,如价差、甲供、分包; class:分类,用于基数选择界面分类显示
+//基数本身不与清单节点关联、但是其由与清单关联的节点四则运算得到,则拥有字段multiRef: [flags...]
 let baseFigureMap = {
     //与清单直接关联=======
     '分部分项工程费': {base: 'FBFXGCF', fixedFlag: fixedFlag.SUB_ENGINERRING, class: 'FBFX'},
@@ -1157,7 +1262,7 @@ let baseFigureMap = {
     '安全文明施工专项费': {base: 'AQWMSGZXF', fixedFlag: fixedFlag.SAFETY_CONSTRUCTION, class: 'CSXM'},
     //不于清单直接关联==========
     '建筑面积': {base: 'JZMJ', class: 'FBFX'},
-    '税前工程造价': {base: 'SQGCZJ', class: 'SQGCZJ'},//安全文明施工专项费用使用
+    '税前工程造价': {base: 'SQGCZJ', class: 'SQGCZJ', multiRef: [fixedFlag.SUB_ENGINERRING, fixedFlag.OTHER, fixedFlag.CHARGE]},//安全文明施工专项费用使用
     '人材机价差': {base: 'RCJJC', class: 'RCJ'},
     '人工价差': {base: 'RGJC', class: 'RCJ'},
     '材料价差': {base: 'CLJC', class: 'RCJ'},
@@ -1275,7 +1380,18 @@ let cbAnalyzer = {
             let figure = figureF[i];
             let billsIDs = [];
             if(figure.type === 'base' && cbTools.isDef(baseFigures[figure.value])){
-                if(figure.value === '税前工程造价'){
+                //重构后:
+                //多重引用基数
+                let figureMultiRef = baseFigures[figure.value]['multiRef'];
+                if(cbTools.isDef(figureMultiRef)){
+                    for(let flag of figureMultiRef){
+                        let bills = cbTools.findBill(flag);
+                        if(bills){
+                            billsIDs.push(bills.ID);
+                        }
+                    }
+                }
+              /*  if(figure.value === '税前工程造价'){
                     //税前工程造价算法在措施项目已排除自身,税前工程造价与措施项目无会造成循环的引用关系
                     let subEngineering = cbTools.findBill(calcBase.fixedFlag.SUB_ENGINERRING),
                         other = cbTools.findBill(calcBase.fixedFlag.OTHER),
@@ -1289,7 +1405,7 @@ let cbAnalyzer = {
                     if(charge){
                         billsIDs.push(charge.ID);
                     }
-                }
+                }*/
                 else {
                     billsIDs = cbTools.isDef(baseFigures[figure.value]['fixedBill']) ? [baseFigures[figure.value]['fixedBill']['bill']['ID']] : [];
                 }
@@ -1358,27 +1474,7 @@ let cbAnalyzer = {
         if(this.cycleCalc(node, calcBase.baseFigures, exp)){
             throw '出现循环计算';
         }
-       /*  if(this.cycleCalc(node, cbTools.getFigure(node), exp)){
-            throw '出现循环计算';
-        }*/
         return exp;
-     /*   if(this.inputLegal(exp)){
-            if(this.arithmeticLegal(exp)){
-                if(this.baseLegal(cbTools.getFigure(node), exp)){
-                    if(this.fLegal(calcBase.project.mainTree.items, exp)){
-                        //转换成ID引用
-                        exp = cbParser.toIDExpr(exp);
-                        if(!this.cycleCalc(node, cbTools.getFigure(node), exp)){
-                            return exp;
-                        }
-                    }
-                    else {
-                        calcBase.errMsg = '行引用不合法';
-                    }
-                }
-            }
-        }
-        return null;*/
     }
 };
 
@@ -1627,7 +1723,7 @@ let calcBase = {
     //清单可选基数映射,分两类:组织措施项目:排除父项和计算的父项; 其他项目、规费、税金、工程造价,及新增部分:显示所有计算基数
     baseFigureClass: Object.create(null),
     //初始化
-    init: function (project) {
+    init: function (project) {//
         let me = this;
         me.project = project;
         me.fixedFlag = fixedFlag;

+ 96 - 67
web/building_saas/main/js/models/calc_program.js

@@ -347,11 +347,15 @@ let calcTools = {
 
         return result;
     },
-    machineLabourFee: function (treeNode, gljArr, isTender) {
+    // masterTypeFilter 过滤机械机型:[]全部, [1,2]特大机械  [3,4]中小机械。  detailType 如机上人工费、机械折旧费等
+    machineDetailFee: function (treeNode, gljArr, masterTypeFilter, detailType, isTender) {
         if (!gljArr) return 0;
         let result = 0;
         for (let glj of gljArr) {
-            if (glj.type == gljType.GENERAL_MACHINE) {
+            if (baseMachineMasterTypes.includes(glj.type)){
+                // 机型不符
+                if ((masterTypeFilter.length > 0) && (glj.model && !masterTypeFilter.includes(glj.model))) break;
+
                 let gljQ;
                 if (isTender){
                     calcTools.calcGLJTenderQty(treeNode, glj);
@@ -364,7 +368,7 @@ let calcTools = {
                 if (!mds) mds = [];
                 let mdSum = 0;
                 for (let md of mds) {
-                    if (md.type == gljType.MACHINE_LABOUR) {
+                    if (md.type == detailType) {
                         let q = md["consumption"] ? md["consumption"] : 0;
                         let p = md["basePrice"] ? md["basePrice"] : 0;
                         mdSum = mdSum + (q * p).toDecimal(decimalObj.glj.unitPriceHasMix);
@@ -519,11 +523,11 @@ let calcTools = {
         if (treeNode.data.type != rationType.volumePrice && treeNode.data.type != rationType.gljRation) return;
         let result = 0, me = this;
         if (
-            (treeNode.data.subType === gljType.LABOUR && baseName === calcBaseNames.DEJJRGF) ||
-            (baseMaterialTypes.includes(treeNode.data.subType) && baseName === calcBaseNames.DEJJCLF) ||
-            (treeNode.data.subType === gljType.GENERAL_MACHINE && baseName === calcBaseNames.DEJJJXF) ||
-            (treeNode.data.subType === gljType.MAIN_MATERIAL && baseName === calcBaseNames.ZCF) ||
-            (treeNode.data.subType === gljType.EQUIPMENT && baseName === calcBaseNames.SBF)) {
+            (treeNode.data.subType === gljType.LABOUR && baseName === rationCalcBasesNameMap.DEJJRGF) ||
+            (baseMaterialTypes.includes(treeNode.data.subType) && baseName === rationCalcBasesNameMap.DEJJCLF) ||
+            (treeNode.data.subType === gljType.GENERAL_MACHINE && baseName === rationCalcBasesNameMap.DEJJJXF) ||
+            (treeNode.data.subType === gljType.MAIN_MATERIAL && baseName === rationCalcBasesNameMap.ZCF) ||
+            (treeNode.data.subType === gljType.EQUIPMENT && baseName === rationCalcBasesNameMap.SBF)) {
             if (treeNode.data.type == rationType.volumePrice)
                 result = treeNode.data.marketUnitFee ? parseFloat(treeNode.data.marketUnitFee).toDecimal(decimalObj.ration.unitPrice) : 0
             else if (treeNode.data.type == rationType.gljRation)
@@ -531,7 +535,7 @@ let calcTools = {
                 // 这里因为是算基数所以要取基价,但不能直接取basePrice,受限于项目属性的三个选项。
                 result = gljOprObj.getBasePrice(treeNode);
         }
-        else if (treeNode.data.subType === gljType.GENERAL_MACHINE && baseName === calcBaseNames.DEJJJSRGF) {
+        else if (treeNode.data.subType === gljType.GENERAL_MACHINE && baseName === rationCalcBasesNameMap.DEJJJSRGF) {
             let glj = {
                 'code': treeNode.data.code,
                 'name': treeNode.data.name,
@@ -540,15 +544,15 @@ let calcTools = {
                 'quantity': 1,
                 'type': treeNode.data.subType      // 注意:这里要取subType
             };
-            result = me.machineLabourFee(treeNode, [glj], isTender);
+            result = me.machineDetailFee(treeNode, [glj], [], gljType.MACHINE_LABOUR, isTender);
         }
         else if (
             (treeNode.data.type == rationType.gljRation) &&
-            ((treeNode.data.subType === gljType.LABOUR && baseName === calcBaseNames.RGFJC) ||
-                (baseMaterialTypes.includes(treeNode.data.subType) && baseName === calcBaseNames.CLFJC) ||
-                (treeNode.data.subType === gljType.GENERAL_MACHINE && baseName === calcBaseNames.JXFJC) ||
-                (treeNode.data.subType === gljType.MAIN_MATERIAL && baseName === calcBaseNames.ZCFJC) ||
-                (treeNode.data.subType === gljType.EQUIPMENT && baseName === calcBaseNames.SBFJC))
+            ((treeNode.data.subType === gljType.LABOUR && baseName === rationCalcBasesNameMap.RGFJC) ||
+                (baseMaterialTypes.includes(treeNode.data.subType) && baseName === rationCalcBasesNameMap.CLFJC) ||
+                (treeNode.data.subType === gljType.GENERAL_MACHINE && baseName === rationCalcBasesNameMap.JXFJC) ||
+                (treeNode.data.subType === gljType.MAIN_MATERIAL && baseName === rationCalcBasesNameMap.ZCFJC) ||
+                (treeNode.data.subType === gljType.EQUIPMENT && baseName === rationCalcBasesNameMap.SBFJC))
         ) {
             let aprice = me.uiGLJPrice(treeNode.data.basePrice);   // 量价虚拟的工料机不可能有发文,这里直接取定额价。
             let mprice = me.uiGLJPrice(treeNode.data.marketUnitFee);
@@ -567,22 +571,26 @@ let calcTools = {
             supplyT = [supplyType.JDYG];
 
         let gljT = [], compT = [];
-        if (baseName == calcBaseNames.JGDEJJRGF || baseName == calcBaseNames.JDDEJJRGF){
+        if ([rationCalcBasesNameMap.JGDEJJRGF, rationCalcBasesNameMap.JDDEJJRGF].includes(baseName)){               // 甲供、甲定人工
             gljT = [gljType.LABOUR];
         }
-        else if (baseName == calcBaseNames.JGDEJJCLF || baseName == calcBaseNames.JDDEJJCLF){
+        else if ([rationCalcBasesNameMap.JGDEJJCLF, rationCalcBasesNameMap.JDDEJJCLF].includes(baseName)){          // 甲供、甲定材料
             gljT = baseMaterialTypes;
             compT = compositionTypes;
         }
-        else if (baseName == calcBaseNames.JGDEJJJXF || baseName == calcBaseNames.JDDEJJJXF){
+        else if ([rationCalcBasesNameMap.JGDEJJJXF, rationCalcBasesNameMap.JDDEJJJXF].includes(baseName)){          // 甲供、甲定机械
             gljT = baseMachineTypes;
             compT = [gljType.GENERAL_MACHINE];
         }
-        else if (baseName == calcBaseNames.JGZCF || baseName == calcBaseNames.JDZCF){
+        else if ([rationCalcBasesNameMap.JGDESGJJF, rationCalcBasesNameMap.JDDESGJJF].includes(baseName)){          // 甲供、甲定机械(重庆2018新定额)
+            gljT = baseMachineTypes;
+            compT = baseMachineTypes_CQ_2018_JX;
+        }
+        else if ([rationCalcBasesNameMap.JGZCF, rationCalcBasesNameMap.JDZCF].includes(baseName)){                  // 甲供、甲定主材
             gljT = [gljType.MAIN_MATERIAL];
             compT = [gljType.MAIN_MATERIAL];
         }
-        else if (baseName == calcBaseNames.JGSBF || baseName == calcBaseNames.JDSBF){
+        else if ([rationCalcBasesNameMap.JGSBF, rationCalcBasesNameMap.JDSBF].includes(baseName)){                  // 甲供、甲定设备
             gljT = [gljType.EQUIPMENT];
         };
         // alert(JSON.stringify(projectGLJ.testGLJs()));
@@ -836,10 +844,37 @@ let calcTools = {
             return projectObj.project.projectGLJ.getDataByID(glj.projectGLJID);
         }
         else return null;
+    },
+    labourDays(node, isTender){
+        if (!node.data.gljList) return 0;
+        let rst = 0;
+        calcTools.uiNodeQty(node);
+        for (let glj of node.data.gljList) {
+            if (glj.type == gljType.LABOUR) {
+                let gljQ;
+                if (isTender){
+                    calcTools.calcGLJTenderQty(node, glj);
+                    gljQ = glj.tenderQuantity;
+                }
+                else
+                    gljQ = glj.quantity;
+
+                rst = rst + (gljQ * calcTools.uiNodeQty(node)).toDecimal(decimalObj.process);
+                rst = rst.toDecimal(decimalObj.process);
+            }
+        };
+        return rst.toDecimal(decimalObj.glj.quantity);
+    },
+    getProjectFeatureProperty(propertyKey){
+        for (let o of projectObj.project.property.projectFeature){
+              if (o.key == propertyKey){
+                  return o.value;
+              }
+        };
     }
 };
 
-const calcBaseNames = {
+let rationCalcBasesNameMap = {
     DEJJRGF: '定额基价人工费',
     DEJJCLF: '定额基价材料费',
     DEJJJXF: '定额基价机械费',
@@ -871,7 +906,7 @@ const calcBaseNames = {
     FBRGGR: '分包人工工日'
 };
 
-const rationCalcBases = {
+let rationCalcBases = {
     '定额基价人工费': function (node, isTender) {
         return calcTools.rationBaseFee(node, [gljType.LABOUR], priceTypes.ptBasePrice, isTender);
     },
@@ -882,7 +917,7 @@ const rationCalcBases = {
         return calcTools.rationBaseFee(node, [gljType.GENERAL_MACHINE], priceTypes.ptBasePrice, isTender);
     },
     '定额基价机上人工费': function (node, isTender) {
-        return calcTools.machineLabourFee(node, node.data.gljList, isTender);
+        return calcTools.machineDetailFee(node, node.data.gljList, [], gljType.MACHINE_LABOUR, isTender);
     },
     '人工费价差': function (node, isTender) {
         return calcTools.rationBaseFee(node, [gljType.LABOUR], priceTypes.ptDiffPrice, isTender);
@@ -906,82 +941,76 @@ const rationCalcBases = {
         return calcTools.rationBaseFee(node, [gljType.EQUIPMENT], priceTypes.ptBasePrice, isTender);
     },
     '人工工日': function (node, isTender) {
-        if (!node.data.gljList) return 0;
-        let rst = 0;
-
-        calcTools.uiNodeQty(node)
-        for (let glj of node.data.gljList) {
-            if (glj.type == gljType.LABOUR) {
-                let gljQ;
-                if (isTender){
-                    calcTools.calcGLJTenderQty(node, glj);
-                    gljQ = glj.tenderQuantity;
-                }
-                else
-                    gljQ = glj.quantity;
-
-                rst = rst + (gljQ * calcTools.uiNodeQty(node)).toDecimal(decimalObj.process);
-                rst = rst.toDecimal(decimalObj.process);
-            }
-        };
-        return rst.toDecimal(decimalObj.glj.quantity);
+        return calcTools.labourDays(node, isTender);
     },
     '甲供定额基价人工费': function (node, isTender) {
-        return calcTools.partASupplyFee(node, calcBaseNames.JGDEJJRGF, isTender);
+        return calcTools.partASupplyFee(node, rationCalcBasesNameMap.JGDEJJRGF, isTender);
     },
     '甲供定额基价材料费': function (node, isTender) {
-        return calcTools.partASupplyFee(node, calcBaseNames.JGDEJJCLF, isTender);
+        return calcTools.partASupplyFee(node, rationCalcBasesNameMap.JGDEJJCLF, isTender);
     },
     '甲供定额基价机械费': function (node, isTender) {
-        return calcTools.partASupplyFee(node, calcBaseNames.JGDEJJJXF, isTender);
+        return calcTools.partASupplyFee(node, rationCalcBasesNameMap.JGDEJJJXF, isTender);
     },
     '甲供主材费': function (node, isTender) {
-        return calcTools.partASupplyFee(node, calcBaseNames.JGZCF, isTender);
+        return calcTools.partASupplyFee(node, rationCalcBasesNameMap.JGZCF, isTender);
     },
     '甲供设备费': function (node, isTender) {
-        return calcTools.partASupplyFee(node, calcBaseNames.JGSBF, isTender);
+        return calcTools.partASupplyFee(node, rationCalcBasesNameMap.JGSBF, isTender);
     },
     '甲定定额基价人工费': function (node, isTender) {
-        return calcTools.partASupplyFee(node, calcBaseNames.JDDEJJRGF, isTender);
+        return calcTools.partASupplyFee(node, rationCalcBasesNameMap.JDDEJJRGF, isTender);
     },
     '甲定定额基价材料费': function (node, isTender) {
-        return calcTools.partASupplyFee(node, calcBaseNames.JDDEJJCLF, isTender);
+        return calcTools.partASupplyFee(node, rationCalcBasesNameMap.JDDEJJCLF, isTender);
     },
     '甲定定额基价机械费': function (node, isTender) {
-        return calcTools.partASupplyFee(node, calcBaseNames.JDDEJJJXF, isTender);
+        return calcTools.partASupplyFee(node, rationCalcBasesNameMap.JDDEJJJXF, isTender);
     },
     '甲定主材费': function (node, isTender) {
-        return calcTools.partASupplyFee(node, calcBaseNames.JDZCF, isTender);
+        return calcTools.partASupplyFee(node, rationCalcBasesNameMap.JDZCF, isTender);
     },
     '甲定设备费': function (node, isTender) {
-        return calcTools.partASupplyFee(node, calcBaseNames.JDSBF, isTender);
+        return calcTools.partASupplyFee(node, rationCalcBasesNameMap.JDSBF, isTender);
     },
     '暂估材料费': function (node, isTender) {
         return calcTools.estimateFee(node, true, isTender);
     },
     '分包定额基价人工费': function (node, isTender) {
-        if (node.data.isSubcontract) return this.定额基价人工费(node, isTender)
-        else return 0;
+        if (node.data.isSubcontract)
+            return calcTools.rationBaseFee(node, [gljType.LABOUR], priceTypes.ptBasePrice, isTender)
+        else
+            return 0;
     },
     '分包定额基价材料费': function (node, isTender) {
-        if (node.data.isSubcontract) return this.定额基价材料费(node, isTender)
-        else return 0;
+        if (node.data.isSubcontract)
+            return calcTools.rationBaseFee(node, baseMaterialTypes, priceTypes.ptBasePrice, isTender)
+        else
+            return 0;
     },
     '分包定额基价机械费': function (node, isTender) {
-        if (node.data.isSubcontract) return this.定额基价机械费(node, isTender)
-        else return 0;
+        if (node.data.isSubcontract)
+            return calcTools.rationBaseFee(node, [gljType.GENERAL_MACHINE], priceTypes.ptBasePrice, isTender)
+        else
+            return 0;
     },
     '分包主材费': function (node, isTender) {
-        if (node.data.isSubcontract) return this.主材费(node, isTender)
-        else return 0;
+        if (node.data.isSubcontract)
+            return calcTools.rationBaseFee(node, [gljType.MAIN_MATERIAL], priceTypes.ptBasePrice, isTender)
+        else
+            return 0;
     },
     '分包设备费': function (node, isTender) {
-        if (node.data.isSubcontract) return this.设备费(node, isTender)
-        else return 0;
+        if (node.data.isSubcontract)
+            return calcTools.rationBaseFee(node, [gljType.EQUIPMENT], priceTypes.ptBasePrice, isTender)
+        else
+            return 0;
     },
     '分包人工工日': function (node, isTender) {
-        if (node.data.isSubcontract) return this.人工工日(node, isTender)
-        else return 0;
+        if (node.data.isSubcontract)
+            return calcTools.labourDays(node, isTender)
+        else
+            return 0;
     }
 };
 
@@ -1759,12 +1788,12 @@ class CalcProgram {
                     } ;
                 };
             };
-
-            if (treeNode.data.programID == undefined) treeNode.data.programID = projectInfoObj.projectInfo.property.engineering;
+            // 2018-08-27   zhang  插入空定额的时候,取费专业也为空
+           // if (treeNode.data.programID == undefined) treeNode.data.programID = projectInfoObj.projectInfo.property.engineering;
             let template = me.compiledTemplates[treeNode.data.programID];
             treeNode.data.calcTemplate = template;
 
-            if (treeNode && template.hasCompiled) {
+            if (treeNode && template && template.hasCompiled) {//2018-08-27 空行的时候,取费专业为空,template也为空,加入template非空判断
                 let $CE = executeObj;
                 $CE.treeNode = treeNode;
                 $CE.template = template;

+ 1 - 1
web/building_saas/main/js/models/installation_fee.js

@@ -235,7 +235,7 @@ var installation_fee = {
             let FBMap = {};//保存分部下对应的补项
             let usedBXMap = {};//有使用到的补项
             let startTime =  +new Date();
-            if(engineering!=engineeringType.BUILD_IN){//如果不是安装工程,则不用计算
+            if(!projectObj.project.isInstall()){//如果不是安装工程,则不用计算
                 if(callback) callback(false);
                 return;
             }

+ 12 - 30
web/building_saas/main/js/models/main_consts.js

@@ -18,32 +18,7 @@ const ModuleNames = {
     installation_fee:'installation_fee'
 };
 
-let gljType = {//这里还是要有所有的类型
-    LABOUR: 1, // 人工
-    // ==============材料类型=================
-    GENERAL_MATERIAL: 201,  // 普通材料
-    CONCRETE: 202, // 混凝土
-    MORTAR: 203,// 砂浆
-    MIX_RATIO: 204,// 配合比
-    COMMERCIAL_CONCRETE: 205,// 商品混凝土
-    COMMERCIAL_MORTAR: 206,// 商品砂浆
-    OTHER_MATERIAL: 207, // 其它材料
-    // ==============机械类型=================
-    GENERAL_MACHINE: 301,// 机械台班
-    MACHINE_COMPOSITION: 302,// 机械组成物
-    MACHINE_LABOUR: 303,// 机上人工
-    INSTRUMENT: 304,// 仪器仪表
-    FUEL_POWER_FEE:305,//燃料动力费
-    DEPRECIATION_FEE:306,//折旧费
-    INSPECTION_FEE:307,//检修费
-    MAINTENANCE:308,//维护费
-    DISMANTLING_FREIGHT_FEE:309,//安拆费及场外运费
-    VERIFICATION_FEE:310,//校验费
-    OTHER_FEE:311,//其他费用
-    // ==============机械类型=================
-    MAIN_MATERIAL: 4,// 主材
-    EQUIPMENT: 5// 设备
-};
+let gljType = gljUtil.gljType;
 // 计算基数 [定额基价材料费] 要用到的材料类型。
 const baseMaterialTypes = [
     gljType.GENERAL_MATERIAL,
@@ -59,6 +34,11 @@ const baseMachineTypes = [
     gljType.MACHINE_COMPOSITION,
     gljType.MACHINE_LABOUR
 ];
+
+const baseMachineMasterTypes = [
+    gljType.GENERAL_MACHINE
+];
+
 // 全部材料类型。用于暂估等 (多了主材和设备)
 const allMaterialTypes = [
     gljType.GENERAL_MATERIAL,
@@ -254,7 +234,9 @@ const fixedFlag = {
     // 税金
     TAX: 18,
     //工程造价
-    ENGINEERINGCOST: 19
+    ENGINEERINGCOST: 19,
+    //增值税
+    ADDED_VALUE_TAX: 20
 };
 
 const gljKeyArray =['code','name','specs','unit','type'];
@@ -320,8 +302,8 @@ const cpFeeTypes = [
     // {type: 'fee9', name: '费用9'}
 
 ];
-
-const engineeringType = {
+//8-27 zhang 这个已经不能用来判断工程类型了
+/*const engineeringType = {
     // 建筑工程
     ARCHITECTURE: 1,
     // 装饰工程
@@ -350,7 +332,7 @@ const engineeringType = {
     BUILDING_REPAIR: 13,
     // 安装修缮工程
     BUILD_IN_REPAIR: 14
-};
+};*/
 const blockType ={
     RATION:1,//定额
     FB:2,//分部

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

@@ -400,6 +400,11 @@ var PROJECT = {
                 }
             })
         };
+        //判断项目是否安装工程
+        project.prototype.isInstall = function () {
+            return projectInfoObj.projectInfo.property.isInstall?true:false;//如果是undefinded 就也返回false
+        };
+
         /*        project.prototype.setBillsCalcMode = function (calcMode) {
                     this.property.billsCalcMode = calcMode;
                     this.initCalcFields();

+ 7 - 7
web/building_saas/main/js/models/ration.js

@@ -114,11 +114,11 @@ var Ration = {
             newData['type'] = rType;
             if (rType == rationType.volumePrice){
                 newData['subType'] = gljType.GENERAL_MATERIAL;   // 默认的量价类型为材料
-                newData['programID'] = projectInfoObj.projectInfo.property.engineering;
+                //newData['programID'] = projectInfoObj.projectInfo.property.engineering;
             };
-            if(rType == rationType.install){//是安装增加费生成的定额
+           /* if(rType == rationType.install){//是安装增加费生成的定额
                 newData['programID'] = projectInfoObj.projectInfo.property.engineering;
-            }
+            }*/
             return newData;
         };
 
@@ -395,7 +395,7 @@ var Ration = {
             }
             for(let r of recodes){
                 let needInstall = false;
-                if(engineering==engineeringType.BUILD_IN) {//如果是安装工程,要看需不需要生成安装增加费
+                if(projectObj.project.isInstall()) {//如果是安装工程,要看需不需要生成安装增加费
                     needInstall = project.Bills.isFBFX(r.node);
                 }
                 r.value===null||r.value===undefined?"":r.value = r.value.replace(/[\s\r\n]/g, "");//去掉空格回车换行等字符
@@ -470,7 +470,7 @@ var Ration = {
             };
             if(billItemID){
                 let calQuantity = optionsOprObj.getOption(optionsOprObj.optionsTypes.GENERALOPTS, 'rationQuanACToBillsQuan');
-                if(engineering==engineeringType.BUILD_IN) {//如果是安装工程,要看需不需要生成安装增加费
+                if(projectObj.project.isInstall()) {//如果是安装工程,要看需不需要生成安装增加费
                     let billsNode = project.mainTree.getNodeByID(billItemID);
                     needInstall = project.Bills.isFBFX(billsNode);//在分部分项插入的定额才需要定额安装增加费
                 }
@@ -588,7 +588,7 @@ var Ration = {
                         brUpdate.push({projectID:newData.projectID,ID:br[i].ID,serialNo:br[i].serialNo});
                     }
                 }
-                if(engineering==engineeringType.BUILD_IN) {//如果是安装工程,要看需不需要生成安装增加费
+                if(projectObj.project.isInstall()) {//如果是安装工程,要看需不需要生成安装增加费
                     let billsNode = project.mainTree.getNodeByID(billItemID);
                     needInstall = project.Bills.isFBFX(billsNode);//在分部分项插入的定额才需要定额安装增加费
                 }
@@ -667,7 +667,7 @@ var Ration = {
                         brUpdate.push({projectID:newData.projectID,ID:br[i].ID,serialNo:br[i].serialNo});
                     }
                 }
-                if(engineering==engineeringType.BUILD_IN) {//如果是安装工程,要看需不需要生成安装增加费
+                if(projectObj.project.isInstall()) {//如果是安装工程,要看需不需要生成安装增加费
                     let billsNode = project.mainTree.getNodeByID(billItemID);
                 }
                 $.bootstrapLoading.start();

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

@@ -213,6 +213,7 @@ let calcBaseView = {
                 }
             }
             let bnArr = Object.keys(rationCalcBases);
+            bnArr.sort();
             let baseArr = [];
             for (let bn of bnArr) {
                 baseArr.push({base: bn})

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

@@ -53,7 +53,7 @@ let calcProgramManage = {
         me.detailSpread = sheetCommonObj.buildSheet($('#detailSpread')[0], me.detailSetting, me.datas[0].calcItems.length);
         sheetCommonObj.spreadDefaultStyle(me.detailSpread);
         let arr = projectObj.project.calcProgram.compiledFeeTypeNames.slice();
-        // arr.splice(arr.findIndex(function (e){return e == '暂估费'}), 1);
+        // arr.delete('暂估费');
         let fieldName = new GC.Spread.Sheets.CellTypes.ComboBox();
         fieldName.items(arr);
         me.detailSpread.getSheet(0).getRange(-1, 4, -1, 1).cellType(fieldName);

+ 0 - 26
web/building_saas/main/js/views/fee_rate_view.js

@@ -502,32 +502,6 @@ var feeRateObject={
     },
 
     onMainFeeRateSheetValueChange:function (e,info) {
-  /*      let me = feeRateObject,updateData = {},feeRate = projectObj.project.FeeRate;
-        let recode = me.mainFeeRateData[info.row];
-        let fieldID = me.mainFeeRateSetting.header[info.col].dataCode;
-        let value = info.newValue;
-        if(fieldID == 'rate'&&value != null){
-            let checkResult = scMathUtil.isNumOrFormula(value);
-            if(checkResult!=null){
-                value = scMathUtil.roundForObj(checkResult,getDecimal("feeRate"));
-            }else {
-                alert('当前输入的数据类型不正确,请重新输入。');
-                me.mainFeeRateSheet.setValue(info.row, info.col, info.oldValue);
-                return;
-            }
-        }
-        if(recode[fieldID] == value){//没有改变
-            return;
-        }
-        updateData[fieldID] = value;
-        $.bootstrapLoading.start();
-         feeRate.updateFeeRateByID(recode.ID,updateData,function () {
-             me.mainFeeRateSheet.setValue(info.row, info.col, value);
-             if(fieldID == 'rate'){
-                feeRate.onFeeRateChange(recode.ID,value);
-            }
-            $.bootstrapLoading.end();
-        })*/
         feeRateObject.updateFeerateWhenCellsChange([info]);
     },
     onMainFeeRateRangeChanged:function (e,info) {

+ 30 - 32
web/building_saas/main/js/views/glj_view.js

@@ -934,7 +934,6 @@ var gljOprObj = {
             projectObj.project.projectGLJ.updatePriceFromRG(node.data, "marketPrice", newval);
             return
         }
-
         projectObj.mainController.refreshTreeNode([node]);
     },
     updateIsEstimate:function (args, newval) {
@@ -1143,20 +1142,20 @@ var gljOprObj = {
         }
     },
     doReplaceGLJ: function () {
-        var me = this;
-        var oldData = me.sheetData[gljContextMenu.selectedRow];
-        var project = projectObj.project;
-        var selectCode = gljOprObj.GLJSelection[0];
-        var selected = projectObj.project.mainTree.selected;
+        let me = this;
+        let oldData = me.sheetData[gljContextMenu.selectedRow];
+        let project = projectObj.project;
+        let selectCode = gljOprObj.GLJSelection[0];
+        let selected = projectObj.project.mainTree.selected;
         $("#glj_tree_div").modal('hide');
         project.ration_glj.replaceGLJ(selectCode, oldData, function (result) {
             if (result) {
                 //result.adjustState;
-                var glj_list = projectObj.project.ration_glj.datas;
-                var data = result.data;
-                var index = _.findIndex(gljOprObj.sheetData, {'ID': data.ID});
-                var list_index = _.findIndex(glj_list, {'ID': data.ID});
-                var nodes = [selected];
+                let glj_list = projectObj.project.ration_glj.datas;
+                let data = result.data;
+                let index = _.findIndex(gljOprObj.sheetData, {'ID': data.ID});
+                let list_index = _.findIndex(glj_list, {'ID': data.ID});
+                let nodes = [selected];
                 gljOprObj.sheetData[index] = data;
                 glj_list[list_index] = data;
                 project.projectGLJ.loadData(function () {//加载完项目工料机再计算
@@ -1220,10 +1219,10 @@ var gljOprObj = {
         });
     },
     refreshStateAfterMreplace: function (stateList, gljNodes) {
-        var nodes = [];
-        var rationNodes = [];
+        let nodes = [];
+        let rationNodes = [];
         _.forEach(stateList, function (s) {
-            var node = _.find(projectObj.project.mainTree.items, function (n) {
+            let node = _.find(projectObj.project.mainTree.items, function (n) {
                 return n.sourceType == ModuleNames.ration && n.data.ID == s.rationID;
             })
             if (node) {
@@ -1245,8 +1244,8 @@ var gljOprObj = {
         if (!obj) {
             return;
         }
-        var objectArray = [];
-        var nodes = [];
+        let objectArray = [];
+        let nodes = [];
         if (obj instanceof Array) {
             objectArray.concat(obj);
         } else {
@@ -1272,10 +1271,10 @@ var gljOprObj = {
         return node;
     },
     getTreeNodeCellType: function (data,comboboxOptions) {
-        var ns = GC.Spread.Sheets;
-        var rectW = 10;
-        var rectH = 10;
-        var margin = 3;
+        let ns = GC.Spread.Sheets;
+        let rectW = 10;
+        let rectH = 10;
+        let margin = 3;
 
         function TreeNodeCellType() {
         }
@@ -1284,8 +1283,8 @@ var gljOprObj = {
             ctx.strokeStyle = "gray";
             ctx.translate(0.5, 0.5);
             ctx.beginPath();
-            var rectX = x + margin;
-            var rectY = y + Math.round(h / 2) - rectH / 2;
+            let rectX = x + margin;
+            let rectY = y + Math.round(h / 2) - rectH / 2;
             ctx.moveTo(rectX, rectY);
             ctx.lineTo(rectX, rectY + rectH);
             ctx.lineTo(rectX + rectW, rectY + rectH);
@@ -1303,7 +1302,7 @@ var gljOprObj = {
             ctx.beginPath();
             ctx.moveTo(x + margin + 2, y + Math.round(h / 2));
             ctx.lineTo(x + margin + 8, y + Math.round(h / 2));
-            var rectY = y + Math.round(h / 2) - rectH / 2;
+            let rectY = y + Math.round(h / 2) - rectH / 2;
             if (collapsed) {
                 ctx.moveTo(x + margin + rectW / 2, rectY + 2);
                 ctx.lineTo(x + margin + rectW / 2, rectY + 2 + 6);
@@ -1341,11 +1340,11 @@ var gljOprObj = {
                 ctx.clearRect(x, y, w, h);
             }
             if (value != null) {
-                var offset = margin + rectW + 6;
-                var recode = data[options.row];
+                let offset = margin + rectW + 6;
+                let recode = data[options.row];
                 if (recode && recode.hasOwnProperty('subList')) {
                     drowRect(ctx, x, y, w, h);
-                    var collapsed = recode.collapsed == undefined ? true : recode.collapsed;//options.sheet.getTag(options.row,options.col);
+                    let collapsed = recode.collapsed == undefined ? true : recode.collapsed;//options.sheet.getTag(options.row,options.col);
                     drowSymbol(ctx, x, y, w, h, collapsed);
                 } else if (recode && recode.isMixRatio) {
                     offset = drowSubItem(ctx, x, y, w, h, offset, data[options.row + 1]);
@@ -1374,11 +1373,11 @@ var gljOprObj = {
             }
         };
         TreeNodeCellType.prototype.processMouseDown = function (hitinfo) {
-            var recode = data[hitinfo.row];
+            let recode = data[hitinfo.row];
             if (recode && recode.hasOwnProperty('subList')) {
-                var hoffset = hitinfo.cellRect.x + 3;
+                let hoffset = hitinfo.cellRect.x + 3;
                 if (hitinfo.x > hoffset && hitinfo.x < hoffset + 10) {
-                    var collapsed = recode.collapsed == undefined ? true : recode.collapsed;
+                    let collapsed = recode.collapsed == undefined ? true : recode.collapsed;
                     collapsed = !collapsed
                     recode.collapsed = collapsed;
                     //hitinfo.sheet.setTag(hitinfo.row,hitinfo.col,collapsed);
@@ -1417,7 +1416,6 @@ var gljOprObj = {
         gljOprObj.filterLibGLJSheetData();
         gljOprObj.showLibGLJSheetData();
     }
-
 }
 
 $(function () {
@@ -1438,7 +1436,7 @@ $(function () {
             gljOprObj.GLJSelection = [];
         } else if($('#actionType').val() =='m_replace' || $('#actionType').val() == 'replace'){//替换、批量替换
             let selected = gljOprObj.sheetData[gljContextMenu.selectedRow];
-            var connect_key = gljOprObj.getIndex(selected, gljKeyArray);
+            let connect_key = gljOprObj.getIndex(selected, gljKeyArray);
             gljOprObj.GLJSelection = [connect_key];
             selectMap[connect_key] = true;
             gljOprObj.filterLibGLJByType();
@@ -1488,7 +1486,7 @@ $(function () {
             gljOprObj.filterLibGLJSheetData();
             gljOprObj.showLibGLJSheetData();
         }
-    })
+    });
 /*    //工料机搜索
     $('#gljSearchKeyword').change(function () {
         gljOprObj.filterLibGLJSheetData();

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

@@ -225,11 +225,7 @@ let installationFeeObj={
         $("#calc_installation_fee").modal({show:true});
     },
     engineeringTypeChecking:function () {
-        let property = projectInfoObj.projectInfo.property;
-        let engineering = property.engineering;
-        if(engineering==engineeringType.BUILD_IN){//如果是安装工程,则显示
-            $('#AZZJF_div').show();
-        }
+        if(projectObj.project.isInstall()) $('#AZZJF_div').show();//如果是安装工程,则显示
     },
     initInstallationFeeSpread:function(){
         //初始化费用项表格
@@ -1248,7 +1244,7 @@ let installationFeeObj={
         let installSetting = projectInfoObj.projectInfo.property.installSetting;
         let install_fee = projectObj.project.installation_fee;
         let autoCreate = false;
-        if(engineering!=engineeringType.BUILD_IN){//如果不是安装工程,则不用计算
+        if(!projectObj.project.isInstall()){//如果不是安装工程,则不用计算
             return;
         }
         //可执行检查

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

@@ -140,7 +140,7 @@ projectGljObject={
                 showTypes = [gljType.MAIN_MATERIAL];
             }else if(_.includes(gljUtil.hasCompMaterial,me.selectedProjectGLJ.type)){//混凝土、砂浆、配合比
                 showTypes = [gljType.GENERAL_MATERIAL];
-            }else if(me.selectedProjectGLJ.type == gljType.GENERAL_MACHINE){//机械中有组成物的类型可添加机械组成物、机上人工
+            }else if(_.includes(gljUtil.hasCompMachine,me.selectedProjectGLJ.type)){//me.selectedProjectGLJ.type == gljType.GENERAL_MACHINE//机械中有组成物的类型
                 showTypes = gljUtil.machineComposition;
             }
             gljOprObj.gljLibSheetData = _.filter(gljOprObj.gljLibSheetData, function (item) {

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

@@ -46,6 +46,9 @@ var projectInfoObj = {
                 if(!data.engineeringInfo.billsGuidance_lib || data.engineeringInfo.billsGuidance_lib.length === 0){
                     $('#stdBillsGuidanceTab').addClass('disabled');
                 }
+                else {
+                    $('#stdBillsGuidanceTab').text(data.engineeringInfo.billsGuidance_lib[0].type === 1 ? '清单指引' : '清单精灵');
+                }
 
                 //init decimal
                 setDecimal(decimalObj, data.property.decimal);

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

@@ -312,7 +312,7 @@ let basicInfoView = {
         function TreeNodeCellType() {
         }
 
-        function drowRect(ctx,x,y,w,h) {
+        function drowRect(ctx,x,y,w,h) {///
             ctx.save();
             ctx.strokeStyle = "gray";
             ctx.translate(0.5,0.5);

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

@@ -1277,8 +1277,7 @@ var projectObj = {
                         installationFeeObj.showCalcInstallSettingDiv();
                     },
                     visible: function(key, opt){
-                        let engineering = projectInfoObj.projectInfo.property.engineering;
-                        return engineering==engineeringType.BUILD_IN;
+                        return projectObj.project.isInstall();
                     }
                 },
                 "delete": {

+ 472 - 23
web/building_saas/main/js/views/std_billsGuidance_lib.js

@@ -9,7 +9,10 @@
  */
 
 const billsGuidance = (function () {
-
+    let currentLib = null;
+    //库类型
+    const libType = {'guidance': 1, 'elf': 2}; //清单指引、清单精灵
+    const libTypeText = {1: '清单指引', 2: '清单精灵'};
     const libSel = $('#stdBillsGuidanceLibSelect');
     //工作内容
     let stdBillsJobData = [];
@@ -114,7 +117,7 @@ const billsGuidance = (function () {
                             canAdd = ProjectController.addBills(projectObj.project, projectObj.mainController, std);
                             if(canAdd !== null || canAdd !== false){
                                 //插入选中的定额
-                                let addRationDatas = getInsertRationData(getCheckedRows());
+                                let addRationDatas = currentLib.type && currentLib.type === libType.elf ? getInsertElfRationData() : getInsertRationData(getCheckedRows());
                                 insertRations(addRationDatas);
                             }
                             if(canAdd === false && $.bootstrapLoading.isLoading()){
@@ -125,7 +128,7 @@ const billsGuidance = (function () {
                                 canAdd = ProjectController.addBills(projectObj.project, projectObj.mainController, std);
                                 if(canAdd !== null || canAdd !== false){
                                     //插入选中的定额
-                                    let addRationDatas = getInsertRationData(getCheckedRows());
+                                    let addRationDatas = currentLib.type && currentLib.type === libType.elf ? getInsertElfRationData() : getInsertRationData(getCheckedRows());
                                     insertRations(addRationDatas);
                                 }
                                 if(canAdd === false && $.bootstrapLoading.isLoading()){
@@ -142,7 +145,7 @@ const billsGuidance = (function () {
                         let insert = billsLibObj.insertBills(stdBillsJobData, stdBillsFeatureData, node);
                         if(insert){
                             //插入选中的定额
-                            let addRationDatas = getInsertRationData(getCheckedRows());
+                            let addRationDatas = currentLib.type && currentLib.type === libType.elf ? getInsertElfRationData() : getInsertRationData(getCheckedRows());
                             insertRations(addRationDatas);
                         }
                     }
@@ -263,6 +266,73 @@ const billsGuidance = (function () {
             }
         }
     };
+    const elfItem = {
+        dom: $('#billsGuidance_items'),
+        workBook: null,
+        tree: null,
+        controller: null,
+        treeSetting: {
+            treeCol: 0,
+            emptyRows: 0,
+            headRows: 1,
+            headRowHeight: [40],
+            defaultRowHeight: 21,
+            cols: [
+                {
+                    width: 250,
+                    readOnly: true,
+                    head: {
+                        titleNames: ["施工工序"],
+                        spanCols: [1],
+                        spanRows: [1],
+                        vAlign: [1],
+                        hAlign: [1],
+                        font: ["Arial"]
+                    },
+                    data: {
+                        field: "name",
+                        vAlign: 1,
+                        hAlign: 1,
+                        font: "Arial"
+                    }
+                },
+                {
+                    width: 250,
+                    readOnly: false,
+                    head: {
+                        titleNames: ["选项"],
+                        spanCols: [1],
+                        spanRows: [1],
+                        vAlign: [1],
+                        hAlign: [1],
+                        font: ["Arial"]
+                    },
+                    data: {
+                        field: "options",
+                        vAlign: 1,
+                        hAlign: 0,
+                        font: "Arial"
+                    }
+                }
+            ]
+        },
+        headers: [
+            {name: '施工工序', dataCode: 'name', width: 250, vAlign: 'center', hAlign: 'center', formatter: '@'},
+            {name: '选项', dataCode: 'options', width: 250, vAlign: 'center', hAlign: 'left', formatter: '@'},
+        ],
+        events: {
+            CellClick: function (sender, args) {
+                if(elfItem.headers[args.col]['dataCode'] === 'options' && args.sheetArea === 3){
+                    if(!args.sheet.getCell(args.row, args.col).locked() && !args.sheet.isEditing()){
+                        args.sheet.startEdit();
+                    }
+                }
+            },
+            ClipboardPasting: function (sender, info) {
+                info.cancel = true;
+            }
+        }
+    };
     const options = {
         workBook: {
             tabStripVisible:  false,
@@ -348,6 +418,11 @@ const billsGuidance = (function () {
                 sheet.getRange(-1, 0, -1, 1).locked(false);
                 sheet.getRange(-1, 1, -1, 1).locked(true);
             }
+            if(module === elfItem){
+                sheet.options.isProtected = true;
+                sheet.getRange(-1, 0, -1, 1).locked(true);
+                sheet.getRange(-1, 1, -1, 1).locked(false);
+            }
             setOptions(module.workBook, options);
             buildHeader(module.workBook.getActiveSheet(), module.headers);
             bindEvent(module.workBook, module.events);
@@ -393,6 +468,18 @@ const billsGuidance = (function () {
             }
         }
     }
+    //清单精灵表焦点控制
+    //@param {Number}row @return {void}
+    function elfItemInitSel(row){
+        let billsNode = bills.tree.selected;
+        let node = null;
+        if(billsNode && billsNode.elf.tree){
+            node = billsNode.elf.tree.items[row];
+            if(node){
+                billsNode.elf.tree.selected = node;
+            }
+        }
+    }
     //根据项目指引的类型设置单元格类型,定额类型的项目指引为复选框
     //@param {Array}nodes @return {void}
     function setItemCellType(nodes){
@@ -409,9 +496,17 @@ const billsGuidance = (function () {
     //清单表焦点控制
     //@param {Number}row @return {void}
     function billsInitSel(row){
+        if(currentLib.type && currentLib.type === libType.elf){
+            billsSelElf(row);
+        }else {
+            billsSelGuidance(row);
+        }
+    }
+    //清单焦点变换-清单指引操作
+    //@param {Number}row @return {void}
+    function billsSelGuidance(row){
         let guideSheet = guideItem.workBook.getActiveSheet();
         cleanData(guideSheet, guideItem.headers, -1);
-        refreshInsertRation();
         if(!bills.tree){
             return;
         }
@@ -420,6 +515,7 @@ const billsGuidance = (function () {
             return;
         }
         bills.tree.selected = node;
+        refreshInsertRation();
         if(!node.guidance.tree){
             CommonAjax.post('/billsGuidance/api/getItemsByBills', {guidanceLibID: libSel.val(), billsID: node.getID()}, function (rstData) {
                 initTree(node.guidance, guideSheet, guideItem.treeSetting, rstData);
@@ -435,6 +531,292 @@ const billsGuidance = (function () {
             guideItemInitSel(guideSheet.getActiveRowIndex() ? guideSheet.getActiveRowIndex() : 0);
         }
     }
+    //清单焦点变换-清单精灵操作
+    //@param {Number}row @return {void}
+    function billsSelElf(row) {
+        let elfSheet = elfItem.workBook.getActiveSheet();
+        cleanData(elfSheet, elfItem.headers, -1);
+        if(!bills.tree){
+            return;
+        }
+        let node = bills.tree.items[row];
+        if(!node){
+            return;
+        }
+        bills.tree.selected = node;
+        refreshInsertRation();
+        if(!node.elf.tree){
+            CommonAjax.post('/billsGuidance/api/getItemsByBills', {guidanceLibID: libSel.val(), billsID: node.getID()}, function (rstData) {
+                //定额数据删除编号信息
+                for(let rData of rstData){
+                    if(rData.type === itemType.ration){
+                        let nameArr = rData.name.split(' ');
+                        if(nameArr.length > 0){
+                            nameArr.splice(0, 1);
+                            rData.name = nameArr.join(' ');
+                        }
+                    }
+                }
+                node.elf.datas = rstData;
+                //第一层节点数据
+                let firstLevelDatas = _.filter(rstData, function (data) {
+                    return data.ParentID == -1;
+                });
+                //初始数据的选项显示请选择
+                for(let fData of firstLevelDatas){
+                    let options = getOptions(fData, rstData);
+                    fData.options = options.length > 0 ? '请选择' : '';
+                }
+                initTree(node.elf, elfSheet, elfItem.treeSetting, firstLevelDatas);
+                setOptionsCellType(node.elf.tree.items);
+                //elfSheet.getRange(-1, 1, -1, 1).cellType(getOptionsCellType(null, null, null));
+                //setItemCellType(node.guidance.tree.items);
+                //项目指引初始焦点
+                elfItemInitSel(elfSheet.getActiveRowIndex() ? elfSheet.getActiveRowIndex() : 0);
+            });
+        }
+        else{
+            node.elf.controller.showTreeData();
+            //elfSheet.getRange(-1, 1, -1, 1).cellType(getOptionsCellType(null, null, null));
+            setOptionsCellType(node.elf.tree.items);
+            //项目指引初始焦点
+            elfItemInitSel(elfSheet.getActiveRowIndex() ? elfSheet.getActiveRowIndex() : 0);
+        }
+    }
+    //获取施工工序含有的选项(即当前施工工序的子项),获取的顺序按照NextSiblingID排序
+    //@param {Object}process {Array}datas @return {Array}
+    function getOptions(process, datas) {
+        let rst = [];
+        if(!process || !process.ID){
+            return [];
+        }
+        let options = _.filter(datas, function (data) {
+            return data.ParentID == process.ID;
+        });
+        if(options.length === 0){
+            return [];
+        }
+        //根据NextSiblingID排序
+        let IDMapping = {};
+        for(let opt of options){
+            IDMapping[opt.ID] = {self: opt, next: null, pre: null};
+        }
+        for(let opt of options){
+            let next = IDMapping[opt.NextSiblingID] ? IDMapping[opt.NextSiblingID] : null;
+            if(next){
+                next.pre = IDMapping[opt.ID];
+                IDMapping[opt.ID]['next'] = next;
+            }
+        }
+        let first = null,
+            rank = 0;
+        for(let ID in IDMapping){
+            let obj = IDMapping[ID];
+            if(!obj.pre){
+                first = obj;
+            }
+        }
+        while(first){
+            rank++;
+            first.self.rank = rank;
+            rst.push(first.self);
+            first = first.next;
+        }
+
+        return rst;
+    }
+    //设置清单精灵选项单元格
+    //@param {Array}nodes @return {void}
+    function setOptionsCellType(nodes) {
+        let elfSheet = elfItem.workBook.getActiveSheet();
+        for(let node of nodes){
+            if(node.data.options !== ''){
+                elfSheet.getCell(node.serialNo(), 1).locked(false).cellType(getOptionsCellType());
+            }
+            else {
+                elfSheet.getCell(node.serialNo(), 1).locked(true).cellType(new GC.Spread.Sheets.CellTypes.Base());
+            }
+        }
+    }
+    //获取选项下拉多选单元格
+    //@param {void} @return {void}
+    function getOptionsCellType() {
+        let me = this;
+        let elfSheet= elfItem.workBook.getActiveSheet();
+        function OptionsCellType() {
+            this.isEscKey=false;
+            this.displayText='';
+        }
+        function getHtml(node, cellRect, cellStyle) {
+            if(!node){
+                return '';
+            }
+            let height = cellRect.height;
+            let htmlArr = [];
+            let options = getOptions(node.data, bills.tree.selected.elf.datas);
+            let optionsTitle = node.data.options.split(';').join('\n');
+            htmlArr.push(`<div title="${optionsTitle}" style="height: ${height}px; background: ${cellStyle.backColor};overflow: hidden; white-space: nowrap; text-overflow: ellipsis">${node.data.options}</div><div style="background: ${cellStyle.backColor};border: 1px solid; overflow: auto; height: ${options.length > 6 ? height*6 : height*options.length+5}px; font-size: 0.9rem;">`);
+            for(let opt of options){
+                htmlArr.push(`<div title="${opt.name ? opt.name : ''}" class="elf-options" style="height: ${height}px;overflow: hidden; white-space: nowrap; text-overflow: ellipsis">
+                        <input rank="${opt.rank}" value="${opt.ID}" style="margin-left: 5px; vertical-align: middle" type="checkbox" 
+                    ${node.data.optionChecked && _.find(node.data.optionChecked, {ID: opt.ID}) ? 'checked' : ''}> ${opt.name ? opt.name : ''}</div>`);
+            }
+            htmlArr.push(`</div>`);
+            return htmlArr.join('');
+        }
+        //选择后处理
+        function doAfterSel(node) {
+            let checkedSels = $('.elf-options').find('input:checked');
+            let checkedNameArr = [],
+                optionChecked= [];
+            for(let checkSel of checkedSels){
+                let opt = _.cloneDeep(_.find(bills.tree.selected.elf.datas, {ID: $(checkSel).val()}));
+                opt.rank = $(checkSel).attr('rank');
+                checkedNameArr.push(opt.name);
+                optionChecked.push(opt);
+            }
+            this.displayText = checkedNameArr.length > 0 ? checkedNameArr.join(';') : '请选择';
+            node.data.options = this.displayText;
+            node.data.optionChecked = optionChecked;
+            //删除节点
+            let deleteInfo = getDeleteInfo(node, optionChecked);
+            for(let dInfo of deleteInfo){
+                if(node.tree.delete(dInfo.node)){
+                    elfSheet.deleteRows(dInfo.deleteRow, dInfo.deleteCount);
+                }
+            }
+            //插入节点
+            for(let perCheked of optionChecked){
+                let exist = false;
+                for(let subNode of node.children){
+                    if(subNode.data.ID === perCheked.ID){
+                        exist = true;
+                    }
+                }
+                //不重复且不为定额时插入
+                if(!exist && perCheked.type !== itemType.ration){
+                    insertNodeByData(node, perCheked);
+                }
+            }
+            TREE_SHEET_HELPER.refreshTreeNodeData(elfItem.treeSetting, elfSheet, node.tree.items, false);
+            setOptionsCellType(node.tree.items);
+            refreshInsertRation();
+        }
+        //获取删除节点信息
+        function getDeleteInfo(node, optionChecked) {
+            let rst = [];
+            for(let subNode of node.children){
+                let exist = false;
+                for(let perChecked of optionChecked){
+                    if(subNode.data.ID === perChecked.ID){
+                        exist = true;
+                    }
+                }
+                if(!exist){
+                    let deleteRow = subNode.serialNo(),
+                        deleteCount = subNode.posterityCount() + 1;
+                    rst.push({node: subNode, deleteRow: deleteRow, deleteCount: deleteCount});
+                }
+            }
+            return rst;
+        }
+        //插入单个节点,node:当前操作的节点
+        function insertNodeByData(node, data) {
+            let sameDepthNodes = node.children;
+            let insertNextSiblingID = -1,
+                insertParentID = node.data.ID;
+            data.options = getOptions(data, bills.tree.selected.elf.datas).length > 0 ? '请选择' : '';
+            //确定插入位置
+            for(let subNode of sameDepthNodes){
+                if(data.rank < subNode.data.rank){
+                   insertNextSiblingID = subNode.data.ID;
+                   break;
+                }
+            }
+            let newNode = node.tree.insertByData(data, insertParentID, insertNextSiblingID);
+            elfSheet.addRows(newNode.serialNo(), 1);
+            node.tree.selected = newNode;
+            elfSheet.setSelection(newNode.serialNo(), elfSheet.getSelections()[0].col, 1, 1);
+
+        }
+        OptionsCellType.prototype = new GC.Spread.Sheets.CellTypes.Base();
+
+        OptionsCellType.prototype.createEditorElement = function (context) {
+            let element = document.createElement("div");//这里创建的,会自动销毁
+            return element
+        };
+        OptionsCellType.prototype.activateEditor = function (editorContext, cellStyle, cellRect, context) {
+            if (editorContext) {
+                let $editor = $(editorContext);
+                $editor.css("position", "fixed");
+                $editor.css("background", "white");
+                $editor.css("width", cellRect.width);
+                $editor.attr("gcUIElement", "gcEditingInput");
+                let node = bills.tree.selected.elf.tree.items[elfSheet.getActiveRowIndex()];
+                $editor.html(getHtml(node, cellRect, cellStyle));
+            }
+        }
+        OptionsCellType.prototype.deactivateEditor = function (editorContext, context) {
+
+        };
+        OptionsCellType.prototype.setEditorValue = function (editor, value, context) {
+            this.displayText = value;
+        };
+        OptionsCellType.prototype.getEditorValue = function (editor, context) {
+            let me = this;
+            let node = bills.tree.selected.elf.tree.items[elfSheet.getActiveRowIndex()];
+            if(this.isEscKey !=true){
+                renderSheetFunc(elfSheet, function () {
+                    doAfterSel.call(me, node);
+                });
+            }
+            this.isEscKey = false;
+            return this.displayText;
+        };
+        OptionsCellType.prototype.updateEditor = function (editorContext, cellStyle, cellRect, context) {
+
+        };
+        OptionsCellType.prototype.isReservedKey = function (e, context) {
+            //cell type handle tab key by itself
+            this.isEscKey = e.keyCode === GC.Spread.Commands.Key.esc;
+            return false;
+        };
+       /* OptionsCellType.prototype.paint = function (ctx, value, x, y, w, h, style, options) {
+            if(style.backColor){
+                ctx.fillStyle = style.backColor;
+                ctx.fillRect(x, y, w, h);
+                ctx.save();
+            }
+            //边长
+            const l = 7;
+            let leftPointX = x + w - 15,
+                rightPointX = leftPointX + l,
+                middlePointX = (leftPointX + rightPointX)/2;
+            const cos30 = Math.cos(2*Math.PI * 30 / 360);
+            let hL = l * cos30;
+            let beginY = y + h/2 - hL;
+            ctx.beginPath();
+            ctx.moveTo(leftPointX, beginY);
+            ctx.lineTo(rightPointX, beginY);
+            ctx.lineTo(middlePointX, beginY + hL);
+            ctx.fillStyle = 'black';
+            ctx.fill();
+            ctx.save();
+        };*/
+        // override getHitInfo to allow cell type get mouse messages
+        OptionsCellType.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
+            };
+        };
+        return new OptionsCellType();
+    }
     //初始化清单的工作内容和项目特征
     //@param {Number}billsLibId @return {void}
     function initJobAndCharacter(billsLibId){
@@ -473,12 +855,34 @@ const billsGuidance = (function () {
         //获取清单
         $.bootstrapLoading.start();
         CommonAjax.post('/billsGuidance/api/getLibWithBills', {libID: libID}, function(rstData){
+            currentLib = rstData.guidanceLib;
+            if(guideItem.workBook){
+                guideItem.workBook.destroy();
+                guideItem.workBook = null;
+            }
+            if(elfItem.workBook){
+                elfItem.workBook.destroy();
+                elfItem.workBook = null;
+            }
+            initViews();
             //获取清单库中的工作内容和项目特征
             initJobAndCharacter(rstData.guidanceLib.billsLibId);
             initTree(bills, bills.workBook.getActiveSheet(), bills.treeSetting, rstData.bills);
-            //每一棵项目指引树挂在清单节点上
-            for(let node of bills.tree.items){
-                node.guidance = {tree: null, controller: null};
+            //清单精灵
+            if(rstData.guidanceLib.type && rstData.guidanceLib.type == libType.elf){
+                $('#stdBillsGuidanceTab').text('清单精灵');
+                //每一个清单节点下挂载一棵清单精灵树
+                for(let node of bills.tree.items){
+                    node.elf = {tree: null, controller: null, datas: []}; //挂载全部数据,数据不一定全成为树节点
+                }
+            }
+            //清单指引
+            else {
+                $('#stdBillsGuidanceTab').text('清单指引');
+                //每一棵项目指引树挂在清单节点上
+                for(let node of bills.tree.items){
+                    node.guidance = {tree: null, controller: null};
+                }
             }
             setTagForHint(bills.tree.items);
             //默认初始节点
@@ -515,7 +919,13 @@ const billsGuidance = (function () {
             $('#billsGuidance_bills').height(height / 2);
             $('#billsGuidance_items').height(height / 2);
         }
-        let modules = [bills, guideItem];
+        let modules = [bills];
+        if(currentLib.type && currentLib.type === libType.elf){
+            modules.push(elfItem);
+        }
+        else {
+            modules.push(guideItem);
+        }
         initWorkBooks(modules);
 
     }
@@ -532,6 +942,31 @@ const billsGuidance = (function () {
         }
         return rst;
     }
+    //获取清单精灵生成的定额数据
+    //@return {Array}
+    function getInsertElfRationData(){
+        let rst = [];
+        if(!bills.tree.selected){
+            return [];
+        }
+        if(!bills.tree.selected.elf){
+            return [];
+        }
+        let tree = bills.tree.selected.elf.tree;
+        if(!tree){
+            return [];
+        }
+        for(let node of tree.items){
+            if(node.children.length === 0 && node.data.optionChecked){//定额数据只能在最底层节点中
+                for(let perChecked of node.data.optionChecked){
+                    if(perChecked.type === itemType.ration){
+                        rst.push({itemQuery: {userID: userID, ID: perChecked.rationID}, rationType: rationType.ration});
+                    }
+                }
+            }
+        }
+        return rst;
+    }
     //获取选中的定额数据
     //@param {Array}rows @return {Array}
     function getInsertRationData(rows){
@@ -550,14 +985,16 @@ const billsGuidance = (function () {
         if(addRationDatas.length > 0){
             projectObj.project.Ration.addMultiRation(addRationDatas, function () {
                 //恢复
-                let sheet = guideItem.workBook.getActiveSheet();
-                renderSheetFunc(sheet, function () {
-                    for(let row = 0; row < sheet.getRowCount(); row++){
-                        if(sheet.getValue(row, 0)){
-                            sheet.setValue(row, 0, false);
+                if(!currentLib.type || currentLib.type === libType.guidance){
+                    let sheet = guideItem.workBook.getActiveSheet();
+                    renderSheetFunc(sheet, function () {
+                        for(let row = 0; row < sheet.getRowCount(); row++){
+                            if(sheet.getValue(row, 0)){
+                                sheet.setValue(row, 0, false);
+                            }
                         }
-                    }
-                });
+                    });
+                }
                 refreshInsertRation();
                 projectObj.setActiveCell('quantity', true);
             });
@@ -565,12 +1002,22 @@ const billsGuidance = (function () {
     }
     //更新插入定额按钮有效性
     function refreshInsertRation(){
-        //勾选了定额,插入定额按钮才有效
-        if(getCheckedRows().length > 0){
-            $('#guidanceInsertRation').removeClass('disabled');
+        if(currentLib.type && currentLib.type === libType.elf){
+            if(getInsertElfRationData().length > 0){
+                $('#guidanceInsertRation').removeClass('disabled');
+            }
+            else {
+                $('#guidanceInsertRation').addClass('disabled');
+            }
         }
         else {
-            $('#guidanceInsertRation').addClass('disabled');
+            //勾选了定额,插入定额按钮才有效
+            if(getCheckedRows().length > 0){
+                $('#guidanceInsertRation').removeClass('disabled');
+            }
+            else {
+                $('#guidanceInsertRation').addClass('disabled');
+            }
         }
     }
     //展开至搜索出来点的节点
@@ -614,7 +1061,7 @@ const billsGuidance = (function () {
         });
         //插入定额
         $('#guidanceInsertRation').click(function () {
-            let addRationDatas = getInsertRationData(getCheckedRows());
+            let addRationDatas = currentLib.type && currentLib.type === libType.elf ? getInsertElfRationData() : getInsertRationData(getCheckedRows());
             insertRations(addRationDatas);
         });
         //插入清单
@@ -627,7 +1074,7 @@ const billsGuidance = (function () {
                 let insert = billsLibObj.insertBills(stdBillsJobData, stdBillsFeatureData, bills.tree.selected);
                 if(insert){
                     //插入选中的定额
-                    let addRationDatas = getInsertRationData(getCheckedRows());
+                    let addRationDatas = currentLib.type && currentLib.type === libType.elf ? getInsertElfRationData() : getInsertRationData(getCheckedRows());
                     insertRations(addRationDatas);
                 }
             }
@@ -718,12 +1165,14 @@ const billsGuidance = (function () {
         if(guideItem.workBook){
             guideItem.workBook.refresh();
         }
+        if(elfItem.workBook){
+            elfItem.workBook.refresh();
+        }
     }
 
     return {initViews, bindBtn, refreshWorkBook, refreshInsertRation, bills};
 })();
 
 $(document).ready(function(){
-    billsGuidance.initViews();
     billsGuidance.bindBtn();
 });

+ 3 - 3
web/building_saas/main/js/views/std_ration_lib.js

@@ -78,10 +78,10 @@ var rationLibObj = {
             rationChapterTreeController.showTreeData();
 
             rationChapterTreeController.bind(TREE_SHEET_CONTROLLER.eventName.treeSelectedChanged, function (node) {
-                rationLibObj.loadSectionRations(node.getID());
+                rationLibObj.loadSectionRations(node && node.children.length === 0 ? node.getID() : null);
             });
 
-            if (rationChapterTree.firstNode()) {
+            if (rationChapterTree.firstNode() && rationChapterTree.firstNode().length === 0) {
                 rationLibObj.loadSectionRations(rationChapterTree.firstNode().getID());
             } else {
                 rationLibObj.loadSectionRations();
@@ -223,7 +223,7 @@ var rationLibObj = {
         sheet.setActiveCell(row, 0);
         sheet.showRow(row, GC.Spread.Sheets.VerticalPosition.center);
         let sectionNode = me.tree.items[row] || null;
-        me.loadSectionRations(sectionNode ? sectionNode.data.ID : null);
+        me.loadSectionRations(sectionNode && sectionNode.children.length === 0 ? sectionNode.data.ID : null);
     },
     locateAtRation: function(code){
         let me = rationLibObj;

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

@@ -9,6 +9,7 @@
     <!-- inject: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/custom.css">
     <link rel="stylesheet" href="/lib/font-awesome/font-awesome.min.css">
     <link rel="stylesheet" href="/lib/spreadjs/sheets/css/gc.spread.sheets.sc.css">
     <!--zTree-->

+ 1 - 0
web/building_saas/pm/js/pm_newMain.js

@@ -1169,6 +1169,7 @@ $(document).ready(function() {
         $("#valuation").html(html);
         //$("#tender-engineering").html('<option value="">请选择对应的工程专业</option>');
         let engineeringList = getEngineeringList();
+        console.log(engineeringList);
         let engineeringHtml = getEngineeringHtml(engineeringList);
         $("#tender-engineering").html(engineeringHtml);
         changeEngineering();

+ 236 - 26
web/over_write/js/chongqing_2018.js

@@ -1,35 +1,245 @@
 /**
  * Created by zhang on 2018/8/14.
  */
-if(gljType){
-    gljType = {
-        LABOUR: 1,// 人工
-        GENERAL_MATERIAL: 201, // 普通材料
-        CONCRETE: 202,// 混凝土
-        MORTAR: 203,// 砂浆
-        MIX_RATIO: 204,// 配合比
-        COMMERCIAL_CONCRETE: 205, // 商品混凝土
-        COMMERCIAL_MORTAR: 206, // 商品砂浆
-        OTHER_MATERIAL: 207, // 其它材料
-        GENERAL_MACHINE: 301,// 机械台班
-        MACHINE_LABOUR: 303, // 机上人工
-        INSTRUMENT: 304,// 仪器仪表
-        FUEL_POWER_FEE:305,//燃料动力费
-        DEPRECIATION_FEE:306,//折旧费
-        INSPECTION_FEE:307,//检修费
-        MAINTENANCE:308,//维护费
-        DISMANTLING_FREIGHT_FEE:309,//安拆费及场外运费
-        VERIFICATION_FEE:310,//校验费
-        OTHER_FEE:311,//其他费用
-        MAIN_MATERIAL: 4// 主材
-    };
-}
-
-if(projectGljObject){
+
+if(typeof projectGljObject !== 'undefined'){
     projectGljObject.displayTypeMap=[
         {ID:'LABOUR',text:'人工'},
         {ID:'GENERAL_MATERIAL',text:'材料'},
         {ID:'GENERAL_MACHINE',text:'施工机具'},//重庆2018定额中去掉了主材,机械的显示改为了施工机具
         {ID:'MAIN_MATERIAL',text:'主材'}
     ];
-}
+}
+if(typeof gljUtil !== 'undefined'){
+    gljUtil.hasCompMachine = [301,304];//有组成物的机械
+    gljUtil.machineComposition = [303,305,306,307,308,309,310,311];//可以做为机械组成物的类型
+}
+
+//允许使用的工料机类型:人工、普通材料、混凝土、砂浆、配合比、商品混凝土、商品砂浆、其他材料费、机械台班、机上人工、仪器仪表、燃料动力费、折旧费、
+// 检修费、维护费、安拆费及场外运费、校验费、其他费用、主材、企业管理费、利润、一般风险费
+if(typeof allowGljType !== 'undefined'){
+    allowGljType = [1, 201, 202, 203, 204, 205, 206, 207, 301, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 4, 6, 7, 8];
+}
+if(typeof allowComponent !== 'undefined'){
+    //允许含有组成物的工料机类型:混凝土、砂浆、配合比、机械台班、仪器仪表、主材
+    allowComponent = [202, 203, 204, 301, 304, 4];
+}
+if(typeof componentType !== 'undefined'){
+    //可以作为组成物的工料机类型:普通材料、机上人工、燃料动力费、折旧费、检修费、维护费、安拆费及场外运费、校验费、其他费用、主材
+    componentType = [201, 303, 305, 306, 307, 308, 309, 310, 311, 4];
+}
+if(typeof machineAllowComponent !== 'undefined'){
+    //允许含有组成物的机械工料机类型:机械台班、仪器仪表
+    machineAllowComponent = [301, 304];
+}
+if(typeof machineComponent !== 'undefined'){
+    //可以作为机械工料机组成物的工料机类型:机械组成物、机上人工、燃料动力费、折旧费、检修费、维护费、安拆费及场外运费、校验费、其他费用
+    machineComponent = [303, 305, 306, 307, 308, 309, 310, 311];
+}
+if(typeof materialAllowComponent !== 'undefined'){
+    //允许含有组成物的材料工料机类型:混凝土、砂浆、配合比
+    materialAllowComponent = [202, 203, 204];
+}
+if(typeof materialComponent !== 'undefined'){
+    //可以作为材料工料机组成物的工料机类型:普通材料
+    materialComponent = [201];
+}
+
+// CSL, 2018-08-21 计算程序、基数 的覆盖。---------------------------------------------------------------------------------
+const baseMachineTypes_CQ_2018_JX = [           // 重庆2018新定额施工机具之三大机械类型
+    gljType.GENERAL_MACHINE,
+    gljType.INSTRUMENT,
+    gljType.OTHER_MACHINE_USED
+];
+
+baseMaterialTypes.push(gljType.OTHER_MATERIAL);
+allMaterialTypes.delete(gljType.EQUIPMENT);
+baseMachineTypes.delete(gljType.MACHINE_COMPOSITION);
+baseMachineTypes.push(gljType.INSTRUMENT, gljType.FUEL_POWER_FEE, gljType.DEPRECIATION_FEE,
+    gljType.INSPECTION_FEE, gljType.MAINTENANCE, gljType.DISMANTLING_FREIGHT_FEE,
+    gljType.VERIFICATION_FEE, gljType.OTHER_FEE, gljType.OTHER_MACHINE_USED);
+baseMachineMasterTypes.push(gljType.INSTRUMENT);
+
+if (rationCalcBases){
+    changePropNames(rationCalcBases,
+        ['定额基价人工费', '定额基价材料费', '甲供定额基价人工费', '甲供定额基价材料费', '甲定定额基价人工费', '甲定定额基价材料费', '分包定额基价人工费','分包定额基价材料费'],
+        ['定额人工费', '定额材料费', '甲供定额人工费', '甲供定额材料费', '甲定定额人工费', '甲定定额材料费', '分包定额人工费','分包定额材料费']
+    );
+    deletePropNames(rationCalcBases, [
+        '定额基价机械费', '定额基价机上人工费', '机械费价差', '主材费价差', '设备费价差','甲供定额基价机械费','甲定定额基价机械费',
+        '设备费', '甲供设备费', '甲定设备费', '分包设备费', '分包定额基价机械费']);
+
+    rationCalcBases['定额其他材料费'] = function (node, isTender) {
+        return calcTools.rationBaseFee(node, [gljType.OTHER_MATERIAL], priceTypes.ptBasePrice, isTender);
+    },
+    rationCalcBases['定额施工机具使用费'] = function (node, isTender) {
+        return calcTools.rationBaseFee(node, baseMachineTypes_CQ_2018_JX, priceTypes.ptBasePrice, isTender);
+    },
+    rationCalcBases['计价材料价差'] = function (node, isTender) {
+        let baseMaterialTypesWithoutOtherMaterial = [
+            gljType.GENERAL_MATERIAL,
+            gljType.CONCRETE,
+            gljType.MORTAR,
+            gljType.MIX_RATIO,
+            gljType.COMMERCIAL_CONCRETE,
+            gljType.COMMERCIAL_MORTAR
+        ];
+        return calcTools.rationBaseFee(node, baseMaterialTypesWithoutOtherMaterial, priceTypes.ptDiffPrice, isTender);
+    },
+    rationCalcBases['机上人工费价差'] = function (node, isTender) {
+        return calcTools.rationBaseFee(node, [gljType.MACHINE_LABOUR], priceTypes.ptDiffPrice, isTender);
+    };
+    rationCalcBases['主材费(市场价)'] = function (node, isTender) {
+        return calcTools.rationBaseFee(node, [gljType.MAIN_MATERIAL], priceTypes.ptMarketPrice, isTender);
+    };
+    rationCalcBases['机械燃料动力费价差'] = function (node, isTender) {
+        return calcTools.rationBaseFee(node, [gljType.FUEL_POWER_FEE], priceTypes.ptDiffPrice, isTender);
+    };
+    rationCalcBases['机械折旧费'] = function (node, isTender) {
+        return calcTools.machineDetailFee(node, node.data.gljList, [], baseMachineMasterTypes,
+            gljType.DEPRECIATION_FEE, isTender);
+    };
+    rationCalcBases['特大机械检修费'] = function (node, isTender) {
+        return calcTools.machineDetailFee(node, node.data.gljList, [1, 2], baseMachineMasterTypes,
+            gljType.INSPECTION_FEE, isTender);
+    };
+    rationCalcBases['中小机械检修费'] = function (node, isTender) {
+        return calcTools.machineDetailFee(node, node.data.gljList, [3, 4], baseMachineMasterTypes,
+            gljType.INSPECTION_FEE, isTender);
+    };
+    rationCalcBases['特大机械维护费'] = function (node, isTender) {
+        return calcTools.machineDetailFee(node, node.data.gljList, [1, 2], baseMachineMasterTypes,
+            gljType.MAINTENANCE, isTender);
+    };
+    rationCalcBases['中小机械维护费'] = function (node, isTender) {
+        return calcTools.machineDetailFee(node, node.data.gljList, [3, 4], baseMachineMasterTypes,
+            gljType.MAINTENANCE, isTender);
+    };
+    rationCalcBases['机械安拆费及场外运输费'] = function (node, isTender) {
+        return calcTools.machineDetailFee(node, node.data.gljList, [], baseMachineMasterTypes,
+            gljType.DISMANTLING_FREIGHT_FEE, isTender);
+    };
+    rationCalcBases['机械燃料动力费'] = function (node, isTender) {
+        return calcTools.machineDetailFee(node, node.data.gljList, [], baseMachineMasterTypes,
+            gljType.FUEL_POWER_FEE, isTender);
+    };
+    rationCalcBases['定额仪器仪表费'] = function (node, isTender) {
+        return calcTools.rationBaseFee(node, [gljType.INSTRUMENT], priceTypes.ptBasePrice, isTender);
+    },
+    rationCalcBases['定额其他施工机具使用费'] = function (node, isTender) {
+        return calcTools.rationBaseFee(node, [gljType.OTHER_MACHINE_USED], priceTypes.ptBasePrice, isTender);
+    },
+    rationCalcBases['甲供定额施工机具费'] = function (node, isTender) {
+        return calcTools.partASupplyFee(node, rationCalcBasesNameMap.JGDESGJJF, isTender);
+    };
+    rationCalcBases['甲定定额施工机具费'] = function (node, isTender) {
+        return calcTools.partASupplyFee(node, rationCalcBasesNameMap.JDDESGJJF, isTender);
+    };
+    rationCalcBases['分包定额施工机具费'] = function (node, isTender) {
+        if (node.data.isSubcontract)
+            return calcTools.rationBaseFee(node, [gljType.GENERAL_MACHINE, gljType.INSTRUMENT, gljType.OTHER_MACHINE_USED], priceTypes.ptBasePrice, isTender)
+        else
+            return 0;
+    };
+    rationCalcBases['建筑面积'] = function (node, isTender) {
+        return calcTools.getProjectFeatureProperty('buildingArea');
+    };
+};
+
+if (rationCalcBasesNameMap) {
+    let str = '基价';
+    for (let pn in rationCalcBasesNameMap){
+        if (rationCalcBasesNameMap[pn].includes(str))
+            rationCalcBasesNameMap[pn] = rationCalcBasesNameMap[pn].replace(new RegExp(str, "g"), '');
+    };
+
+    rationCalcBasesNameMap.DEQTCLF = '定额其他材料费';
+    rationCalcBasesNameMap.DESGJJSYF = '定额施工机具使用费';
+    rationCalcBasesNameMap.JJCLJC = '计价材料价差';
+    rationCalcBasesNameMap.JSRGFJC = '机上人工费价差';
+    rationCalcBasesNameMap.JXRLDLFJC = '机械燃料动力费价差';
+    rationCalcBasesNameMap.JXZJF = '机械折旧费';
+    rationCalcBasesNameMap.TDJXJXF = '特大机械检修费';
+    rationCalcBasesNameMap.ZXJXJXF = '中小机械检修费';
+    rationCalcBasesNameMap.TDJXWHF = '特大机械维护费';
+    rationCalcBasesNameMap.ZXJXWHF = '中小机械维护费';
+    rationCalcBasesNameMap.XXACJCWYSF = '机械安拆费及场外运输费';
+    rationCalcBasesNameMap.JXRLDLF = '机械燃料动力费';
+    rationCalcBasesNameMap.DEYQYBF = '定额仪器仪表费';
+    rationCalcBasesNameMap.DEQTSGJJSYF = '定额其他施工机具使用费';
+    rationCalcBasesNameMap.JGDESGJJF = '甲供定额施工机具费';
+    rationCalcBasesNameMap.JDDESGJJF = '甲定定额施工机具费';
+    rationCalcBasesNameMap.FGDESGJJF = '分包定额施工机具费';
+    rationCalcBasesNameMap.ZCF_SCJ = '主材费(市场价)';
+    rationCalcBasesNameMap.JZMJ = '建筑面积';
+};
+
+
+//清单计算基数相关
+if(typeof baseFigureMap !== 'undefined'){
+    let oldNames = [
+        '分部分项定额基价人工费',
+        '分部分项定额基价材料费',
+        '分部分项定额基价机械费',
+        '组织措施项目定额基价人工费',
+        '组织措施项目定额基价材料费',
+        '组织措施项目定额基价机械费',
+        '技术措施项目定额基价人工费',
+        '技术措施项目定额基价材料费',
+        '技术措施项目定额基价机械费',
+        '机械价差',
+        '分部分项机械价差',
+    ];
+    let newNames = [
+        '分部分项定额人工费',
+        '分部分项定额材料费',
+        '分部分项定额施工机具使用费',
+        '组织措施项目定额人工费',
+        '组织措施项目定额材料费',
+        '组织措施项目定额施工机具使用费',
+        '技术措施项目定额人工费',
+        '技术措施项目定额材料费',
+        '技术措施项目定额施工机具使用费',
+        '施工机具使用费价差',
+        '分部分项施工机具使用费价差',
+    ];
+    changePropNames(baseFigureMap, oldNames, newNames);
+    let deleteNames = [
+        '分部分项定额基价直接工程费',
+        '分部分项调整人工费',
+        '分部分项调整机上人工费',
+        '分部分项设备费',
+        '分部分项未计价材料费',
+        '组织措施项目定额基价直接工程费',
+        '技术措施项目定额基价直接工程费',
+        '技术措施项目调整人工费',
+        '技术措施项目调整机上人工费',
+        '技术措施项目设备费',
+        '技术措施项目未计价材料费',
+        '分包费',
+        '分包定额基价人工费',
+        '分包定额基价材料费',
+        '分包定额基价机械费',
+        '分包主材费',
+        '分包设备费',
+        '分包人工工日',
+    ];
+    deletePropNames(baseFigureMap, deleteNames);
+    baseFigureMap['增值税'] = {base: 'ZZS', class: 'SJ', fixedFlag: fixedFlag.ADDED_VALUE_TAX};
+}
+if(typeof baseFigureTemplate !== 'undefined'){
+    baseFigureTemplate['ZZS'] =  function (tender) {//增值税
+        if(cbTools.isUnDef(calcBase.fixedBills[fixedFlag.ADDED_VALUE_TAX])){
+            return 0;
+        }
+        const totalFeeType = tender ? 'tenderTotalFee' : 'totalFee';
+        let bill = calcBase.fixedBills[fixedFlag.ADDED_VALUE_TAX]['bill'];
+        if(cbTools.isUnDef(bill)) return 0;
+        if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
+        return cbTools.isDef(bill.feesIndex.common) && cbTools.isDef(bill.feesIndex.common[totalFeeType]) ? bill.feesIndex.common[totalFeeType] : 0;
+    };
+}
+if(typeof figureClassTemplate !== 'undefined'){
+    figureClassTemplate['ADDED_VALUE_TAX'] = {flag: fixedFlag.ADDED_VALUE_TAX, filter: ['SJ', 'ZZS', 'SQGCZJ']}
+}
+