浏览代码

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

TonyKang 7 年之前
父节点
当前提交
d3308fad32
共有 67 个文件被更改,包括 2005 次插入854 次删除
  1. 6 2
      config/gulpConfig.js
  2. 5 1
      modules/all_models/bills.js
  3. 2 0
      modules/all_models/compilation.js
  4. 2 1
      modules/all_models/project_glj.js
  5. 1 0
      modules/all_models/ration.js
  6. 16 2
      modules/all_models/user.js
  7. 70 5
      modules/bills_lib/models/bills_lib_interfaces.js
  8. 32 11
      modules/complementary_ration_lib/controllers/compleViewController.js
  9. 0 1
      modules/complementary_ration_lib/routes/routes.js
  10. 39 2
      modules/glj/controllers/glj_controller.js
  11. 1 3
      modules/glj/models/glj_list_model.js
  12. 1 0
      modules/glj/routes/glj_router.js
  13. 1 0
      modules/main/facade/ration_facade.js
  14. 7 0
      modules/ration_glj/facade/glj_calculate_facade.js
  15. 5 2
      modules/users/controllers/user_controller.js
  16. 1 1
      modules/users/models/compilation_model.js
  17. 5 2
      modules/users/models/user_model.js
  18. 32 15
      public/scHintBox.html
  19. 21 0
      public/web/commonAlert.js
  20. 57 18
      public/web/gljUtil.js
  21. 2 3
      public/web/tree_sheet/tree_sheet_helper.js
  22. 59 0
      test/public/test_Box.html
  23. 3 3
      web/building_saas/complementary_ration_lib/html/anzhuang.html
  24. 3 3
      web/building_saas/complementary_ration_lib/html/dinge.html
  25. 3 3
      web/building_saas/complementary_ration_lib/html/fuzhu.html
  26. 4 3
      web/building_saas/complementary_ration_lib/html/gongliao.html
  27. 0 11
      web/building_saas/complementary_ration_lib/js/coe.js
  28. 0 12
      web/building_saas/complementary_ration_lib/js/installation.js
  29. 0 12
      web/building_saas/complementary_ration_lib/js/ration.js
  30. 10 0
      web/building_saas/complementary_ration_lib/js/ration_glj.js
  31. 1 12
      web/building_saas/complementary_ration_lib/js/repository_glj.js
  32. 10 1
      web/building_saas/css/custom.css
  33. 3 2
      web/building_saas/css/main.css
  34. 5 5
      web/building_saas/fee_rates/fee_rate.html
  35. 18 17
      web/building_saas/glj/html/project_glj.html
  36. 1 1
      web/building_saas/glj/js/composition.js
  37. 14 21
      web/building_saas/main/html/main.html
  38. 1 1
      web/building_saas/main/html/tender_price.html
  39. 9 2
      web/building_saas/main/js/controllers/block_controller.js
  40. 1 1
      web/building_saas/main/js/controllers/project_controller.js
  41. 12 6
      web/building_saas/main/js/models/bills.js
  42. 135 86
      web/building_saas/main/js/models/calc_base.js
  43. 390 247
      web/building_saas/main/js/models/calc_program.js
  44. 27 2
      web/building_saas/main/js/models/installation_fee.js
  45. 10 4
      web/building_saas/main/js/models/main_consts.js
  46. 66 7
      web/building_saas/main/js/models/project_glj.js
  47. 82 55
      web/building_saas/main/js/models/quantity_detail.js
  48. 30 36
      web/building_saas/main/js/models/ration.js
  49. 4 3
      web/building_saas/main/js/models/ration_glj.js
  50. 70 55
      web/building_saas/main/js/views/character_content_view.js
  51. 42 26
      web/building_saas/main/js/views/glj_view.js
  52. 69 28
      web/building_saas/main/js/views/installation_fee_view.js
  53. 116 43
      web/building_saas/main/js/views/project_glj_view.js
  54. 4 1
      web/building_saas/main/js/views/project_property_basicInfo.js
  55. 3 1
      web/building_saas/main/js/views/project_property_projFeature.js
  56. 140 3
      web/building_saas/main/js/views/project_view.js
  57. 2 0
      web/building_saas/main/js/views/std_billsGuidance_lib.js
  58. 8 3
      web/building_saas/main/js/views/std_bills_lib.js
  59. 22 3
      web/building_saas/main/js/views/sub_view.js
  60. 81 16
      web/building_saas/main/js/views/tender_price_view.js
  61. 2 2
      web/building_saas/main/js/views/zmhs_view.js
  62. 1 1
      web/building_saas/pm/html/project-management-Recycle.html
  63. 13 10
      web/building_saas/pm/html/project-management.html
  64. 12 10
      web/building_saas/pm/js/pm_gc.js
  65. 194 25
      web/building_saas/pm/js/pm_newMain.js
  66. 16 1
      web/common/html/header.html
  67. 3 1
      web/users/js/login.js

+ 6 - 2
config/gulpConfig.js

@@ -14,6 +14,7 @@ module.exports = {
         'public/web/gljUtil.js',
         'public/web/PerfectLoad.js',
         'lib/lodash/lodash.js',
+        'public/web/commonAlert.js'
     ],
     common_css:[
         'lib/bootstrap/css/bootstrap.min.css',
@@ -27,15 +28,18 @@ module.exports = {
     ],
     pm_css:[
         'lib/ztree/css/zTreeStyle.css',
-        'lib/spreadjs/sheets/css/gc.spread.sheets.sc.css'
+        'lib/spreadjs/sheets/css/gc.spread.sheets.sc.css',
+        'lib/jquery-contextmenu/jquery.contextMenu.css'
     ],
     pm_jspaths:[
         'public/web/date_util.js',
         'public/web/tree_sheet/tree_sheet_helper.js',
+        'public/web/sheet/sheet_data_helper.js',
         'public/web/common_ajax.js',
         'lib/JSExpressionEval_src/Date.js',
         'web/building_saas/pm/js/**/*.js',
-        'lib/ztree/*.js'
+        'lib/ztree/*.js',
+        'lib/jquery-contextmenu/jquery.contextMenu.min.js'
     ],
     main_css:[
         'lib/ztree/css/zTreeStyle.css',

+ 5 - 1
modules/all_models/bills.js

@@ -27,6 +27,7 @@ let billsSchema = new Schema({
     programID: Number,
     calcBase: String,
     calcBaseValue: String,     // 计算基数表达式的值
+    tenderCalcBaseValue: String,     // 调价后计算基数表达式的值
     // 工程量计算规则
     ruleText: String,
     // 说明
@@ -63,7 +64,10 @@ let billsSchema = new Schema({
     installationKey:String,//用来记录安装增加费的关联字段
     deleteInfo: deleteSchema,
     isEstimate:{type: Number,default:0},       // 1 true 0 false 是否暂估
-    remark:String
+    remark:String,
+    engineeringContent:String,//工程内容
+    serviceContent:String,//服务内容
+    claimVisa:String//签证及索赔依据
 });
 
 mongoose.model("bills", billsSchema);

+ 2 - 0
modules/all_models/compilation.js

@@ -66,6 +66,8 @@ let modelSchema = {
     },
     // 名称
     name: String,
+    //描述
+    description: String,
     // 创建时间
     create_time: Number,
     // 创建者id

+ 2 - 1
modules/all_models/project_glj.js

@@ -100,7 +100,8 @@ let modelSchema = {
         type: Number,
         default: 0
     },
-    ratio_data: Schema.Types.Mixed
+    ratio_data: Schema.Types.Mixed,
+    remark:String
 };
 mongoose.model(collectionName, new Schema(modelSchema, {versionKey: false}));
 

+ 1 - 0
modules/all_models/ration.js

@@ -63,6 +63,7 @@ let rationSchema = new Schema({
     flags: [subSchema.flagsSchema],             // 标记字段
     rationAssList: [rationAssItemSchema],
     content: String,                            // 工作内容
+    annotation: String,                         //附注
     ruleText: String,                            // 计算规则
     prefix: {type: String, default: ''},                              //定额是补充、借用时用  补 借
 

+ 16 - 2
modules/all_models/user.js

@@ -11,6 +11,20 @@ let Schema = mongoose.Schema;
 // 表名
 let collectionName = 'user';
 
+const invalidSchema = new Schema({
+    invalid: Boolean,
+    invalidDate: String,
+    invalidBy: String   //管理者名
+});
+
+const versionSchema = new Schema({
+    compilationId: String,
+    activateCode: String,
+    activatedDate: String,
+    activatedBy: String,
+    invalidInfo: [invalidSchema]
+});
+
 // 表结构
 let schema = {
     ssoId: Number,
@@ -30,8 +44,8 @@ let schema = {
         default: -1
     },
     version: {
-        type: String,
-        default: ''
+        type: [versionSchema],
+        default: []
     },
     company_type: {
         type: Number,

+ 70 - 5
modules/bills_lib/models/bills_lib_interfaces.js

@@ -3031,7 +3031,72 @@ billsLibDao.prototype.edUpdateItem = function(data, callback){
 };
 //
 
-billsLibDao.prototype.getStdBillsByCode = function (data, callback) {
+billsLibDao.prototype.getStdBillsByCode = async function (data, callback) {
+    let findData = function (value, field, Array) {
+        let i = 0;
+        for (i = 0; i < Array.length; i++) {
+            if (value[field] === Array[i][field]) {
+                return Array[i];
+            }
+        }
+        return null;
+    };
+    let MergeData = function (arr) {
+        let result = "", count = 0;
+        for(let i = 0; i < arr.length; i++){
+            if(arr[i].isChecked === true){
+                count += 1;
+                if (count === 1) {
+                    result += count + ". " + arr[i].content;
+                } else {
+                    result += "\n" + count + ". " + arr[i].content;
+                }
+            }
+        }
+        return result;
+    }
+    try{
+        let bills = await Bills.findOne({billsLibId: data.billsLibId, code: data.code, deleted: false}, '-_id');
+        //设置清单备注(父项清单补注)
+        if(bills.ParentID != -1){
+            let parentBills = await Bills.findOne({billsLibId: data.billsLibId, ID: bills.ParentID, deleted: false});
+            if(parentBills && parentBills.recharge){
+                bills.recharge = parentBills.recharge;
+            }
+        }
+        if(bills){
+            //设置项目特征
+            let itemCharacters = await ItemCharacter.find({billsLibId: data.billsLibId, deleted: false}, '-_id');
+            bills._doc.itemCharacter = [];
+            if(itemCharacters && bills.items){
+                for(let item of bills.items){
+                    let itemData = findData(item, 'id', itemCharacters);
+                    if(itemData){
+                        bills._doc.itemCharacter.push(itemData);
+                    }
+                }
+            }
+            bills._doc.itemCharacterText = MergeData(bills._doc.itemCharacter);
+            //设置工作内容
+            let jobContents = await JobContent.find({billsLibId: data.billsLibId, deleted: false}, '-_id');
+            bills._doc.jobContent = [];
+            if(jobContents && bills.jobs){
+                for(let job of bills.jobs){
+                    let jobData = findData(job, 'id', jobContents);
+                    jobData.isChecked = true;
+                    bills._doc.jobContent.push(jobData);
+                }
+            }
+            bills._doc.jobContentText = MergeData(bills._doc.jobContent);
+        }
+        callback(0, '', bills);
+
+    }
+    catch(err){
+        callback(1, err, null);
+    }
+};
+billsLibDao.prototype.getStdBillsByCodet = function (data, callback) {
     let findData = function (value, field, Array) {
         let i = 0;
         for (i = 0; i < Array.length; i++) {
@@ -3067,23 +3132,23 @@ billsLibDao.prototype.getStdBillsByCode = function (data, callback) {
                     if (err) {
                         callback(err, bills);
                     } else {
-                        bills.itemCharacter = [];
+                        bills._doc.itemCharacter = [];
                         if (result && bills && bills.items) {
                             for (let item of bills.items) {
                                 let itemData = findData(item, 'id', result);
                                 if (itemData) {
-                                    bills.itemCharacter.push(JSON.parse(JSON.stringify(itemData)));
+                                    bills._doc.itemCharacter.push(JSON.parse(JSON.stringify(itemData)));
                                 }
                             }
                         }
-                        bills.itemCharacterText = MergeData(bills.itemCharacter);
+                        bills._doc.itemCharacterText = MergeData(bills.itemCharacter);
                         callback(err, bills);
                     }
                 });
             } else {
                 callback(null, bills);
             }
-            
+
         },
         function (bills, callback) {
             if (bills) {

+ 32 - 11
modules/complementary_ration_lib/controllers/compleViewController.js

@@ -11,34 +11,55 @@ let callback = function (req, res, err, msg, data) {
 };
 
 class CompleViewController extends BaseController{
-    redirectMain(req, res){
-        res.render('building_saas/complementary_ration_lib/html/main.html', {
-            userID: req.session.sessionUser.id,
-            compilationId: req.session.sessionCompilation._id
-        });
-    }
-
     redirectRation(req, res){
+        const repId = req.query.repository;
+        const redirectGlj = `/complementaryRation/glj?repository=${repId}`;
+        const redirectCoe = `/complementaryRation/coe?repository=${repId}`;
+        const redirectInstallation = `/complementaryRation/installation?repository=${repId}`;
         res.render('building_saas/complementary_ration_lib/html/dinge.html', {
-            userID: req.session.sessionUser.id
+            userID: req.session.sessionUser.id,
+            redirectGlj: redirectGlj,
+            redirectCoe: redirectCoe,
+            redirectInstallation: redirectInstallation
         });
     }
 
     redirectGljList(req, res){
+        const repId = req.query.repository;
+        const redirectRation = `/complementaryRation/ration?repository=${repId}`;
+        const redirectCoe = `/complementaryRation/coe?repository=${repId}`;
+        const redirectInstallation = `/complementaryRation/installation?repository=${repId}`;
         res.render('building_saas/complementary_ration_lib/html/gongliao.html', {
-            userID: req.session.sessionUser.id
+            userID: req.session.sessionUser.id,
+            redirectRation: redirectRation,
+            redirectCoe: redirectCoe,
+            redirectInstallation: redirectInstallation
         });
     }
 
     redirectCoeList(req, res){
+        const repId = req.query.repository;
+        const redirectRation = `/complementaryRation/ration?repository=${repId}`;
+        const redirectGlj = `/complementaryRation/glj?repository=${repId}`;
+        const redirectInstallation = `/complementaryRation/installation?repository=${repId}`;
         res.render('building_saas/complementary_ration_lib/html/fuzhu.html', {
-            userID: req.session.sessionUser.id
+            userID: req.session.sessionUser.id,
+            redirectRation: redirectRation,
+            redirectGlj: redirectGlj,
+            redirectInstallation: redirectInstallation
         });
     }
 
     redirectInstallation(req, res){
+        const repId = req.query.repository;
+        const redirectRation = `/complementaryRation/ration?repository=${repId}`;
+        const redirectGlj = `/complementaryRation/glj?repository=${repId}`;
+        const redirectCoe = `/complementaryRation/coe?repository=${repId}`;
         res.render('building_saas/complementary_ration_lib/html/anzhuang.html', {
-            userID: req.session.sessionUser.id
+            userID: req.session.sessionUser.id,
+            redirectRation: redirectRation,
+            redirectGlj: redirectGlj,
+            redirectCoe: redirectCoe
         });
     }
 

+ 0 - 1
modules/complementary_ration_lib/routes/routes.js

@@ -17,7 +17,6 @@ let gljController = new GljController();
 let searchController = new SearchController();
 
 module.exports = function (app) {
-    //app.get('/complementaryRation/main', compleViewController.init, compleViewController.redirectMain);
     app.get('/complementaryRation/ration', compleViewController.init, compleViewController.redirectRation);
     app.get('/complementaryRation/glj', compleViewController.init, compleViewController.redirectGljList);
     app.get('/complementaryRation/coe', compleViewController.init, compleViewController.redirectCoeList);

+ 39 - 2
modules/glj/controllers/glj_controller.js

@@ -17,6 +17,7 @@ let glj_type_util = require('../../../public/cache/std_glj_type_util');
 let mongoose = require('mongoose');
 let ration = mongoose.model('ration');
 
+
 const ProjectModel = require('../../pm/models/project_model').project;
 class GLJController extends BaseController {
 
@@ -82,7 +83,7 @@ class GLJController extends BaseController {
         try {
             // 可编辑的字段
             let editableField = ['is_evaluate', 'unit_price.market_price', 'is_adjust_price', 'mix_ratio.consumption',
-                'supply', 'supply_quantity','delivery_address','delivery','materialType','materialCoe','is_main_material'];
+                'supply', 'supply_quantity','delivery_address','delivery','materialType','materialCoe','is_main_material','remark'];
             if (editableField.indexOf(field) < 0) {
                 throw '对应字段不能编辑';
             }
@@ -227,10 +228,46 @@ class GLJController extends BaseController {
             responseData.err = 1;
             responseData.msg = error;
         }
-
         response.json(responseData);
     }
 
+
+    //添加组成物
+    async addMixRatio(request,response){
+
+        let result={
+            error:0
+        };
+        try {
+            let data = request.body.data;
+            data = JSON.parse(data);
+            let gljList = data.gljList, parentInfo = data.parentInfo,mixRatios = [];
+            let projectGljModel = new GLJListModel();
+            let mixRatioModel = new MixRatioModel();
+            for(let g of gljList){
+                let newProjectGLJ = await projectGljModel.addList(g,parentInfo.unit_price_file_id);
+                let mixRatio = {
+                    glj_id:newProjectGLJ.glj_id,
+                    consumption:0,
+                    unit_price_file_id:parentInfo.unit_price_file_id,
+                    connect_key:parentInfo.connect_key,
+                    type: newProjectGLJ.type,
+                    code: newProjectGLJ.code,
+                    specs:newProjectGLJ.specs,
+                    name:newProjectGLJ.name,
+                    unit:newProjectGLJ.unit
+                };
+                newProjectGLJ.ratio_data = await mixRatioModel.add(mixRatio);
+                mixRatios.push(newProjectGLJ);
+            }
+            result.data = mixRatios;
+        }catch (err){
+            logger.err(err);
+            result.error=1;
+            result.message = err.message;
+        }
+        response.json(result);
+    }
     /**
      * 获取项目与单价文件对应的数据
      *

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

@@ -417,7 +417,7 @@ class GLJListModel extends BaseModel {
                     };
                     newMixRatioData.push(tem);
                 }
-                mixInsertResult= mixRatioModel.add(newMixRatioData);
+                mixInsertResult= await mixRatioModel.add(newMixRatioData);
             }
         }
         return gljData;
@@ -771,8 +771,6 @@ class GLJListModel extends BaseModel {
             let u_index = this.getIndex(tmp,['code','name','specs','unit','type'])
             unitPriceData[u_index] = tmp;
         }
-
-
         return [gljData,mixRatioData,unitPriceData];
 
     }

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

@@ -17,6 +17,7 @@ router.post('/getData', gljController.init, gljController.getGljList);
 router.post('/update', gljController.init, gljController.updateData);
 router.post('/get-ratio', gljController.init, gljController.getRatio);
 router.post('/delete-ratio', gljController.init, gljController.deleteMixRatio);
+router.post('/add-ratio', gljController.init, gljController.addMixRatio);
 router.post('/get-project-info', gljController.init, gljController.getProjectInfo);
 router.post('/change-file', gljController.init, gljController.changeUnitPriceFile);
 router.post('/checkUnitFileName', gljController.init, gljController.checkUnitFileName);

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

@@ -88,6 +88,7 @@ async function insertNewRation(newData,firstLibID,std,calQuantity) {//插入新
         newData.unit = std.unit;
         newData.libID = std.rationRepId;
         newData.content = std.jobContent;
+        newData.annotation = std.annotation;
         if (std.chapter) {
             newData.comments = std.chapter.explanation;
             newData.ruleText = std.chapter.ruleText;

+ 7 - 0
modules/ration_glj/facade/glj_calculate_facade.js

@@ -55,6 +55,7 @@ async function calculateQuantity(query,noNeedCal){
                  }
              }
          }
+        gljList = sortRationGLJ(gljList);
          for(let i =0;i<gljList.length;i++ ){
              let r = await calculateQuantityPerGLJ(gljList[i],i,coeList,assList,adjustState,noNeedCal);
              result.glj_result.push(r);
@@ -89,6 +90,12 @@ function generateUpdateTasks(result) {
     return tasks;
 }
 
+function sortRationGLJ(list) {
+    list = _.sortByAll(list, [function (item) {
+        return item.type + "";
+    }, "code"])
+    return list;
+}
 
 async function calculateQuantityPerGLJ(glj,index,coeList,assList,adjustState,noNeedCal) {
     let decimalObject =await decimal_facade.getProjectDecimal(glj.projectID);

+ 5 - 2
modules/users/controllers/user_controller.js

@@ -200,7 +200,7 @@ class UserController extends BaseController {
             let sessionUser = request.session.sessionUser;
             let data = JSON.parse(request.body.data);
             let activateCode = data.activateCode,
-                activateCompilation = data.activateCompilation;
+                compilationId = data.compilationId;
             let isActivated = true;//调激活接口
             if(!isActivated){
                 throw '激活失败';
@@ -208,8 +208,10 @@ class UserController extends BaseController {
             //激活成功,更新入库
             let userObjId = mongoose.Types.ObjectId(sessionUser.id);
             let versionInfo = {};
-            versionInfo.compilationId = activateCompilation;
+            versionInfo.compilationId = compilationId;
             versionInfo.activatedDate = moment(Date.now()).format('YYYY-MM-DD HH:mm:ss');
+            //失效信息{invalid: boolean, invalidDate: String}
+            versionInfo.invalidInfo = null;
             await userModel.addVersion({_id: userObjId}, versionInfo);
             response.json({error: 0, msg: 'success'});
         }
@@ -230,6 +232,7 @@ class UserController extends BaseController {
                 let versionInfo = {};
                 versionInfo.compilationId = compilationId;
                 versionInfo.activatedDate = moment(Date.now()).format('YYYY-MM-DD HH:mm:ss');
+                versionInfo.invalidInfo = null;
                 await userModel.addVersion({_id: mongoose.Types.ObjectId(userId)}, versionInfo);
             }
             else{

+ 1 - 1
modules/users/models/compilation_model.js

@@ -28,7 +28,7 @@ class CompilationModel extends BaseModel {
      */
     async getList() {
         // 筛选字段
-        let field = {_id: 1, name: 1, is_release: 1};
+        let field = {_id: 1, name: 1, is_release: 1, description: 1};
         let compilationData = await this.findDataByCondition({name: {$ne: ''}, is_release: true}, field, false);
 
         return compilationData === null ? [] : compilationData;

+ 5 - 2
modules/users/models/user_model.js

@@ -17,14 +17,17 @@ class UserModel extends BaseModel {
      *
      * @var {object}
      */
-    province = ['广东省', '北京市'];
+    province = ['北京', '天津', '河北', '山西', '内蒙古', '辽宁', '吉林', '黑龙江', '上海', '江苏', '浙江', '安徽',
+        '福建', '江西', '山东', '河南', '湖北', '湖南', '广东', '广西', '海南', '重庆', '四川', '贵州', '云南', '西藏',
+        '陕西', '甘肃', '青海', '宁夏', '新疆', '台湾', '香港', '澳门',];
 
     /**
      * 企业类型
      *
      * @var
      */
-    companyType = ['设计', '施工'];
+    companyType = ['建设单位', '设计单位',  '施工单位', '监理单位', '审核单位', '咨询公司', '招标代理', '住建部', '财政', '审计',
+        '造价管理站', '学校', '个人', '其他'];
 
     /**
      * 企业类型

+ 32 - 15
public/scHintBox.html

@@ -7,12 +7,12 @@
         3、有三个按钮的多分支选择询问框。
         4、输入文本值对话框。
 ----------------------------------------------------------------------------------------------------------------------->
-<div class="modal fade" id="hintBox_form" data-backdrop="static">
+<div class="modal fade" id="hintBox_form" data-backdrop="static" style="z-index: 9999">
     <div class="modal-dialog" role="document">
         <div class="modal-content">
             <div class="modal-header">
                 <h5 id="hintBox_title" class="modal-title">标题</h5>
-                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close" id="hintBox_btn_cross">
                     <span aria-hidden="true">&times;</span>
                 </button>
             </div>
@@ -25,7 +25,7 @@
                 </div>
             </div>
 
-            <div class="modal-footer" style="justify-content: right">
+            <div class="modal-footer" style="justify-content: center">
                 <button type="button" class="btn btn-primary" data-dismiss="modal" id="hintBox_btn_yes">是</button>
                 <button type="button" class="btn btn-primary" data-dismiss="modal" id="hintBox_btn_no">否</button>
                 <button type="button" class="btn btn-secondary" data-dismiss="modal" id="hintBox_btn_cancel">取消</button>
@@ -36,7 +36,6 @@
 
 <script>
     const hintBox = {
-        test: false,
         value: null,
         btnType: {yes: 1, yesNo: 2, yesNoCancel: 3},
         init: function (){
@@ -57,8 +56,7 @@
             );
             $('#hintBox_btn_cancel').click(
                 function () {
-                    if (!hintBox.test)
-                        $.bootstrapLoading.end();
+                    $.bootstrapLoading.end();
                     return;
                 }
             );
@@ -70,6 +68,7 @@
             $('#hintBox_btn_yes').hide();
             $('#hintBox_btn_no').hide();
             $('#hintBox_btn_cancel').hide();
+            $('#hintBox_btn_cross').show();
         },
         font: function(str){
             return `<span style='color:red;font-weight:bold;font-size:15px'> ${str} </span>`;
@@ -80,27 +79,46 @@
             $("#hintBox_value").focus();
             $("#hintBox_value").select();
         },
-        infoBox: function (title, caption, btnType, doYes, doNo) {
+        infoBox: function (title, caption, btnType, doYes, doNo, btnTextArr, showCrossBtn = true) {
             this.init();
+            if (!showCrossBtn)
+                $('#hintBox_btn_cross').hide();
             $('#hintBox_title').text(title);
             $('#hintBox_caption').html(caption);
             $('#hintBox_caption').show();
 
             switch (btnType) {
                 case this.btnType.yes:
-                    $('#hintBox_btn_yes').text('确定');
+                    if (btnTextArr){
+                        $('#hintBox_btn_yes').text(btnTextArr[0]);
+                    }else
+                        $('#hintBox_btn_yes').text('确定');
+
                     $('#hintBox_btn_yes').show();
                     break;
                 case this.btnType.yesNo:
-                    $('#hintBox_btn_yes').text('是');
-                    $('#hintBox_btn_no').text('否');
+                    if (btnTextArr){
+                        $('#hintBox_btn_yes').text(btnTextArr[0]);
+                        $('#hintBox_btn_no').text(btnTextArr[1]);
+                    }else{
+                        $('#hintBox_btn_yes').text('是');
+                        $('#hintBox_btn_no').text('否');
+                    }
+
                     $('#hintBox_btn_yes').show();
                     $('#hintBox_btn_no').show();
                     break;
                 case this.btnType.yesNoCancel:
-                    $('#hintBox_btn_yes').text('是');
-                    $('#hintBox_btn_no').text('否');
-                    $('#hintBox_btn_cancel').text('取消');
+                    if (btnTextArr){
+                        $('#hintBox_btn_yes').text(btnTextArr[0]);
+                        $('#hintBox_btn_no').text(btnTextArr[1]);
+                        $('#hintBox_btn_cancel').text(btnTextArr[2]);
+                    }else{
+                        $('#hintBox_btn_yes').text('是');
+                        $('#hintBox_btn_no').text('否');
+                        $('#hintBox_btn_cancel').text('取消');
+                    }
+
                     $('#hintBox_btn_yes').show();
                     $('#hintBox_btn_no').show();
                     $('#hintBox_btn_cancel').show();
@@ -136,8 +154,7 @@
     };
 
     $('#hintBox_form').on('hide.bs.modal', function() {
-        if (!hintBox.test)
-            $.bootstrapLoading.end();
+        $.bootstrapLoading.end();
         return;
     });
 </script>

+ 21 - 0
public/web/commonAlert.js

@@ -0,0 +1,21 @@
+'use strict';
+
+/**
+ *
+ *
+ * @author Zhong
+ * @date 2018/6/15
+ * @version
+ */
+
+window.alert = function(str) {
+    /*$('#commonAlert').find('p').text(str);
+     $('#commonAlert').modal('show');*/
+    hintBox.infoBox('系统提示', str, 1);
+};
+
+
+!function loadHintBox(){
+    $("body").append('<div id = "hintBox_container"></div>');
+    $("#hintBox_container").load("../../public/scHintBox.html");
+}();

+ 57 - 18
public/web/gljUtil.js

@@ -6,7 +6,7 @@
 
 
 let gljUtil = {
-    calcProjectGLJQuantity:function (projectGLJDatas,rationGLJDatas,rationDatas,billsDatas,q_decimal,_,scMathUtil) {
+    calcProjectGLJQuantity:function (projectGLJDatas,rationGLJDatas,rationDatas,billsDatas,q_decimal,_,scMathUtil,isTender) {
         let project_gljs = projectGLJDatas.gljList;
         let mixRatioMap = projectGLJDatas.mixRatioMap;
         let rations = rationDatas;
@@ -15,16 +15,20 @@ let gljUtil = {
         let rationGljGroup = _.groupBy(rationGLJDatas,'projectGLJID');
         let IDarray =  this.getSubdivisionAndTechBillsLeavesID(billsDatas);//分别取分部分项和技术措施项目的所有叶子清单ID
         let billIDs = IDarray[0],tech_billIDS = IDarray[1];
+        let sField = isTender==true?"tenderSubdivisionQuantity":"subdivisionQuantity";
+        let tField = isTender==true?"tenderTechQuantity":"techQuantity";
+        let qField = isTender==true?"tenderQuantity":"quantity";
+
         for(let pglj of project_gljs ){
             let pg_index = this.getIndex(pglj,this.gljKeyArray);
-            pglj.subdivisionQuantity = 0;
-            pglj.techQuantity = 0;
-            pglj.quantity = 0;
+            pglj[sField] = 0;
+            pglj[tField] = 0;
+            pglj[qField] = 0;
             let gljGroup = rationGljGroup[pglj.id]?rationGljGroup[pglj.id]:[];//定额工料机没有,有可能是定额类型的工料机
-            let result = this.getQuantityPerGLJ(gljGroup,rations,rationMap,pglj,billIDs,tech_billIDS,q_decimal,_,scMathUtil);
-            pglj.subdivisionQuantity = result.subdivisionQuantity;
-            pglj.techQuantity = result.techQuantity;
-            pglj.quantity = result.quantity;
+            let result = this.getQuantityPerGLJ(gljGroup,rations,rationMap,pglj,billIDs,tech_billIDS,q_decimal,_,scMathUtil,isTender);
+            pglj[sField] = result.subdivisionQuantity;
+            pglj[tField] = result.techQuantity;
+            pglj[qField] = result.quantity;
             quantityMap[pg_index] = pglj;
         }
         //计算做为组成物的消耗量
@@ -35,20 +39,17 @@ let gljUtil = {
                 let m_glj = quantityMap[m_index];
                 let p_glj = quantityMap[pkey];
                 if(m_glj&&p_glj){
-                    let quantity = scMathUtil.roundForObj(parseFloat(p_glj.quantity)*parseFloat(m.consumption),q_decimal);
-                    let techQuantity = scMathUtil.roundForObj(parseFloat(p_glj.techQuantity)*parseFloat(m.consumption),q_decimal);
-                    let subdivisionQuantity = scMathUtil.roundForObj(parseFloat(p_glj.subdivisionQuantity)*parseFloat(m.consumption),q_decimal);
-                    m_glj.quantity =  scMathUtil.roundForObj(parseFloat(m_glj.quantity)+quantity,q_decimal);
-                    m_glj.techQuantity =  scMathUtil.roundForObj(parseFloat(m_glj.techQuantity)+techQuantity,q_decimal);
-                    m_glj.subdivisionQuantity =  scMathUtil.roundForObj(parseFloat(m_glj.subdivisionQuantity)+subdivisionQuantity,q_decimal);
-                    if(m_glj.id == 6832){
-                        console.log(m_glj.quantity)
-                    }
+                    let quantity = scMathUtil.roundForObj(parseFloat(p_glj[qField])*parseFloat(m.consumption),q_decimal);
+                    let techQuantity = scMathUtil.roundForObj(parseFloat(p_glj[tField])*parseFloat(m.consumption),q_decimal);
+                    let subdivisionQuantity = scMathUtil.roundForObj(parseFloat(p_glj[sField])*parseFloat(m.consumption),q_decimal);
+                    m_glj[qField] =  scMathUtil.roundForObj(parseFloat(m_glj[qField])+quantity,q_decimal);
+                    m_glj[tField] =  scMathUtil.roundForObj(parseFloat(m_glj[tField])+techQuantity,q_decimal);
+                    m_glj[sField] =  scMathUtil.roundForObj(parseFloat(m_glj[sField])+subdivisionQuantity,q_decimal);
                 }
             }
         }
     },
-    getQuantityPerGLJ : function (ration_glj_list,rations,rationMap,pglj,billIDs,tech_billIDS,q_decimal,_,scMathUtil) {
+    getQuantityPerGLJ : function (ration_glj_list,rations,rationMap,pglj,billIDs,tech_billIDS,q_decimal,_,scMathUtil,isTender) {
         let result={};
         let quantity_sum=0;//工料机汇总消耗量
         let sum = 0;//分部分项总消耗量
@@ -60,6 +61,10 @@ let gljUtil = {
             if(!r_quantity){
                 continue;
             }
+            if(isTender == true){
+                glj_quantity = this.getRationGLJTenderQuantity(rg,tem_ration,q_decimal,scMathUtil);
+                r_quantity = this.getRationTenderQuantity(tem_ration,q_decimal,scMathUtil);
+            }
             let total = scMathUtil.roundForObj(glj_quantity*r_quantity, q_decimal);
             quantity_sum = scMathUtil.roundForObj(quantity_sum+total,q_decimal);
             if(_.includes(billIDs,rg.billsItemID)){//计算分部分项
@@ -73,6 +78,9 @@ let gljUtil = {
             if(ra.type == this.rationType.gljRation&&ra.projectGLJID===pglj.id){
                 let r_quantity = scMathUtil.roundForObj(ra.quantity,q_decimal);
                 r_quantity = r_quantity?r_quantity:0;
+                if(isTender == true){
+                    r_quantity = this.getRationTenderQuantity(ra,q_decimal,scMathUtil);
+                }
                 quantity_sum = scMathUtil.roundForObj(quantity_sum+r_quantity,q_decimal);
                 if(_.includes(billIDs,ra.billsItemID)){//计算分部分项
                     sum = scMathUtil.roundForObj(sum+r_quantity,q_decimal);
@@ -88,6 +96,37 @@ let gljUtil = {
         result.quantity = quantity_sum;
         return result;
     },
+    getRationGLJTenderQuantity:function (ration_glj,ration,q_decimal,scMathUtil) {
+        let coeMap = {
+          1:'labour',  //人工
+          2:'material',//材料
+          3:'machine',//机械
+          4:'main', //主材
+          5:'equipment'//设备
+        };
+        let typeString = ration_glj.type +"";
+        let coeField = "";
+        for(let key in coeMap){
+            if(typeString.indexOf(key)!= -1){
+              coeField = coeMap[key];
+            }
+        }
+        let coe = ration.quantityCoe&&this.isNotEmpty(ration.quantityCoe[coeField])?ration.quantityCoe[coeField]:1;
+        coe = parseFloat(coe);
+        let glj_quantity = scMathUtil.roundForObj(ration_glj.quantity, q_decimal);
+        return scMathUtil.roundForObj(glj_quantity * coe,q_decimal);
+    },
+    getRationTenderQuantity:function (ration,q_decimal,scMathUtil) {
+        let rationQuantityCoe = this.isNotEmpty(ration.rationQuantityCoe)?ration.rationQuantityCoe:1;
+        rationQuantityCoe = parseFloat(rationQuantityCoe);
+        let r_quantity = ration?scMathUtil.roundForObj(ration.quantity,q_decimal):0;
+        return scMathUtil.roundForObj(r_quantity * rationQuantityCoe,q_decimal);
+    },
+
+    isNotEmpty:function (str) {
+        return this.isDef(str) && str!="";
+    },
+
     getSubdivisionAndTechBillsLeavesID:function (billsDatas) {//分别取分部分项和技术措施项目的所有叶子清单ID
          if(typeof (projectObj) !== 'undefined'){//存在,说明在前端调用
              return [projectObj.project.Bills.getSubdivisionProjectLeavesID(),projectObj.project.Bills.getTechLeavesID()];

+ 2 - 3
public/web/tree_sheet/tree_sheet_helper.js

@@ -141,7 +141,7 @@ var TREE_SHEET_HELPER = {
                 var getFieldText2 = function () {
                     var fields = colSetting.data.field.split('.'), iField, data = node.data;
                     for (iField = 0; iField < fields.length; iField++) {
-                        if (data[fields[iField]]) {
+                        if (data[fields[iField]] && data[fields[iField]]!='0') {
                             data = data[fields[iField]];
                         } else {
                             return '';
@@ -302,6 +302,7 @@ var TREE_SHEET_HELPER = {
             };
             // Draw Text
             x = x + (node.depth() + 1) * indent +  node.depth() * levelIndent;
+            w = w - (node.depth() + 1) * indent - node.depth() * levelIndent;
             GC.Spread.Sheets.CellTypes.Text.prototype.paint.apply(this, arguments);
         };
         TreeNodeCellType.prototype.getHitInfo = function (x, y, cellStyle, cellRect, context) {
@@ -323,8 +324,6 @@ var TREE_SHEET_HELPER = {
             let centerX = hitinfo.cellRect.x + offset + node.depth() * indent + node.depth() * levelIndent + indent / 2;
             let centerY = (hitinfo.cellRect.y + offset + (hitinfo.cellRect.y + offset + hitinfo.cellRect.height)) / 2;
             if (hitinfo.x > centerX - halfBoxLength && hitinfo.x < centerX + halfBoxLength && hitinfo.y > centerY - halfBoxLength && hitinfo.y < centerY + halfBoxLength) {
-                console.log(`hitinfo.sheet.name()`);
-                console.log(hitinfo.sheet.name());
                 node.setExpanded(!node.expanded);
                 let sheetName = hitinfo.sheet.name();
                 if(sheetName === 'stdBillsLib_bills'){

+ 59 - 0
test/public/test_Box.html

@@ -0,0 +1,59 @@
+<!--<!DOCTYPE html>-->
+<html>
+<head>
+    <meta charset="UTF-8">
+    <script src="../../lib/jquery/jquery-3.2.1.min.js"></script>
+    <link rel="stylesheet" href="../../lib/bootstrap/css/bootstrap.min.css">
+    <script src="../../lib/bootstrap/bootstrap.min.js"></script>
+    <script src="../../public/web/PerfectLoad.js"></script>
+</head>
+
+<body>
+    <button id = "btnA">按钮A</button>
+    <button id = "btnB">按钮B</button>
+    <button id = "btnC">按钮C</button>
+    <button id = "btnD">按钮D</button>
+
+    <script>
+        !function loadHintBox(){
+            $("body").append('<div id = "hintBox_container"></div>');
+            $("#hintBox_container").load("../../public/scHintBox.html");
+        }();
+
+        $(document).ready(function(){
+            function cbYes() {alert('你点击了yes按键');};
+            function cbNo() {alert('你点击了no按键');}
+
+            $("#btnA").click(function(){
+                let s = hintBox.font('5');
+                hintBox.infoBox('系统提示', `该行已被第 ${s} 行引用,不允许删除!`, 1);
+            });
+
+            $("#btnB").click(function(){
+                hintBox.infoBox('操作确认', '确定要删除当前节点吗?', 2, cbYes, cbNo);
+            });
+
+            $("#btnC").click(function(){
+                hintBox.infoBox('多分支选择', '三个按钮是否继续?', 3, cbYes, cbNo, ['你','我','他']);
+            });
+
+            $("#btnD").click(function(){
+                hintBox.valueBox('请输入新名称222:', '我的模板1xxxx', function () {
+                    let newName = hintBox.value;
+
+                    if (newName == '') {
+                        hintBox.error('名称不能为空!');
+                        return false;
+                    };
+
+                    if (newName == '111') {
+                        hintBox.error(`“${newName}” 已存在,请重新输入!`);
+                        return false;
+                    };
+                });
+            });
+        });
+    </script>
+</body>
+</html>
+

+ 3 - 3
web/building_saas/complementary_ration_lib/html/anzhuang.html

@@ -33,13 +33,13 @@
         <nav class="navbar navbar-toggleable-lg justify-content-between navbar-light p-0">
               <ul class="nav nav-tabs" role="tablist">
                   <li class="nav-item">
-                      <a class="nav-link px-3" id="dinge" href="dinge.html">定额</a>
+                      <a class="nav-link px-3" id="dinge" href="<%= redirectRation %>">定额</a>
                   </li>
                   <li class="nav-item">
-                      <a class="nav-link px-3" id="gongliao" href="gongliao.html">人材机</a>
+                      <a class="nav-link px-3" id="gongliao" href="<%= redirectGlj %>">人材机</a>
                   </li>
                   <li class="nav-item">
-                      <a class="nav-link px-3" id="fuzhu" href="fuzhu.html">子目换算</a>
+                      <a class="nav-link px-3" id="fuzhu" href="<%= redirectCoe %>">子目换算</a>
                   </li>
                   <li class="nav-item">
                       <a class="nav-link active px-3" >安装增加费</a>

+ 3 - 3
web/building_saas/complementary_ration_lib/html/dinge.html

@@ -37,13 +37,13 @@
                 <a class="nav-link active px-3" id ="dinge" >定额</a>
             </li>
             <li class="nav-item">
-                <a class="nav-link px-3" id="gongliao" href="#">人材机</a>
+                <a class="nav-link px-3" id="gongliao" href="<%= redirectGlj %>">人材机</a>
             </li>
             <li class="nav-item">
-                <a class="nav-link px-3" id="fuzhu" href="#">子目换算</a>
+                <a class="nav-link px-3" id="fuzhu" href="<%= redirectCoe %>">子目换算</a>
             </li>
             <li class="nav-item">
-                <a class="nav-link px-3" id="anzhuang" href="#">安装增加费</a>
+                <a class="nav-link px-3" id="anzhuang" href="<%= redirectInstallation %>">安装增加费</a>
             </li>
         </ul>
     </nav>

+ 3 - 3
web/building_saas/complementary_ration_lib/html/fuzhu.html

@@ -32,16 +32,16 @@
         <nav class="navbar navbar-toggleable-lg justify-content-between navbar-light p-0">
               <ul class="nav nav-tabs" role="tablist">
                   <li class="nav-item">
-                      <a class="nav-link px-3" id="drirect-dinge" href="javascript:void(0);">定额</a>
+                      <a class="nav-link px-3" id="drirect-dinge" href="<%= redirectRation %>">定额</a>
                   </li>
                   <li class="nav-item">
-                      <a class="nav-link px-3" id="gongliao" href="javascript:void(0);">人材机</a>
+                      <a class="nav-link px-3" id="gongliao" href="<%= redirectGlj %>">人材机</a>
                   </li>
                   <li class="nav-item">
                       <a class="nav-link active px-3">子目换算</a>
                   </li>
                   <li class="nav-item">
-                      <a class="nav-link px-3" id="anzhuang" href="javascript:void(0);">安装增加费</a>
+                      <a class="nav-link px-3" id="anzhuang" href="<%= redirectInstallation %>">安装增加费</a>
                   </li>
 
                   <li class="nav-item">

文件差异内容过多而无法显示
+ 4 - 3
web/building_saas/complementary_ration_lib/html/gongliao.html


+ 0 - 11
web/building_saas/complementary_ration_lib/js/coe.js

@@ -8,17 +8,6 @@ var pageObj = {
     libID: null,
     gljLibID: null,
     initPage: function (){
-        $("#drirect-dinge").click(function(){
-            $(this).attr('href', "/complementaryRation/ration" + "?repository=" + getQueryString("repository"))
-        });
-
-        $("#gongliao").click(function(){
-            $(this).attr('href', "/complementaryRation/glj" + "?repository=" + getQueryString("repository"))
-        });
-
-        $("#anzhuang").click(function(){
-            $(this).attr('href', "/complementaryRation/installation" + "?repository=" + getQueryString("repository"))
-        });
         var libID = getQueryString("repository");
         let me = this;
         CommonAjax.post('/complementaryRation/api/getRationLibs', {ids: [libID]}, function (rstData) {

+ 0 - 12
web/building_saas/complementary_ration_lib/js/installation.js

@@ -1,18 +1,6 @@
 /**
  * Created by Zhong on 2018/1/19.
  **/
-$("#gongliao").click(function(){
-    $(this).attr('href', "/complementaryRation/glj" + "?repository=" + getQueryString("repository"))
-});
-
-$("#fuzhu").click(function(){
-    $(this).attr('href', "/complementaryRation/coe" + "?repository=" + getQueryString("repository"))
-});
-
-$("#dinge").click(function(){
-    $(this).attr('href', "/complementaryRation/ration" + "?repository=" + getQueryString("repository"))
-});
-
 $(document).ready(function () {
     feeItemObj.buildSheet();
 });

+ 0 - 12
web/building_saas/complementary_ration_lib/js/ration.js

@@ -1,18 +1,6 @@
 /**
  * Created by Tony on 2017/4/28.
  */
-
-$("#gongliao").click(function(){
-    $(this).attr('href', "/complementaryRation/glj" + "?repository=" + getQueryString("repository"))
-});
-
-$("#fuzhu").click(function(){
-    $(this).attr('href', "/complementaryRation/coe" + "?repository=" + getQueryString("repository"))
-});
-
-$("#anzhuang").click(function(){
-    $(this).attr('href', "/complementaryRation/installation" + "?repository=" + getQueryString("repository"))
-});
 const digital = {
     gljPrc: -3,//计算定额基价时单个工料机价格取三位
     rationBasePrc: -2,

+ 10 - 0
web/building_saas/complementary_ration_lib/js/ration_glj.js

@@ -583,6 +583,16 @@ var rationGLJOprObj = {
         var me = this;
         if (me.cache["_GLJ_" + rationID]) {
             sheetCommonObj.cleanData(me.sheet, me.setting, -1);
+            me.cache["_GLJ_" + rationID].sort(function (a, b) {
+                let rst = 0;
+                if(a.code > b.code){
+                    rst = 1;
+                }
+                else if(a.code < b.code){
+                    rst = -1;
+                }
+                return rst;
+            });
             sheetsOprObj.showData(me.sheet, me.setting, me.cache["_GLJ_" + rationID], me.distTypeTree);
         }
     }

+ 1 - 12
web/building_saas/complementary_ration_lib/js/repository_glj.js

@@ -2,22 +2,11 @@
  * Created by Tony on 2017/5/5.
  */
 
-$("#drirect-dinge").click(function(){
-    $(this).attr('href', "/complementaryRation/ration" + "?repository=" + getQueryString("repository"))
-});
-
-$("#fuzhu").click(function(){
-    $(this).attr('href', "/complementaryRation/coe" + "?repository=" + getQueryString("repository"))
-});
-
-$("#anzhuang").click(function(){
-    $(this).attr('href', "/complementaryRation/installation" + "?repository=" + getQueryString("repository"))
-});
-
 var pageOprObj = {
     rationLibName : null,
     rationLibId: null,
     initPage : function(container) {
+        $.bootstrapLoading.start();
         var me = this, rationLibId = getQueryString("repository");//获取定额库参数
         me.rationLibId = rationLibId;
         //getRationLibName

+ 10 - 1
web/building_saas/css/custom.css

@@ -36,5 +36,14 @@ legend.legend{
 
 .filterType{
     padding-left: .75rem;
-    padding-right:0px;
+}
+
+.a_color{
+    color: #007bff;
+}
+
+.filterType a{
+    padding: 8px;
+    padding-top: 7px;
+    padding-bottom: 7px;
 }

+ 3 - 2
web/building_saas/css/main.css

@@ -150,8 +150,9 @@ body {
     height: 30px;
     line-height: 30px;
     background:#F1F1F1;
-    bottom:28px;
-    left:0px;
+    bottom:30px;
+    left:2px;
+    z-index: 999
 }
 .side-tabs .nav-tabs .nav-item {
     z-index: 999

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

@@ -3,7 +3,7 @@
 <div >
 <div class="toolsbar_feeRate px-1 ">
     <div class="form-inline py-1">
-        <label class="mx-2" >当前使用:<span id="feeRateFileName">费率1</span>(<a href="#" id="pop-lv"><span id="projectCount">3</span> 个单位工程使用</a>)
+        <label class="mx-2" >当前使用:<span id="feeRateFileName">费率1</span>(<label class="a_color" id="pop-lv"><span id="projectCount">3</span> 个单位工程使用</label>)
             <a class="btn btn-sm ml-1" href="#" data-toggle="modal" data-target="#change-lv" id="changFeeRateFile"><i class="fa fa-exchange"></i> 选择其他</a>
             <a class="btn btn-sm ml-1" href="#" data-toggle="modal" id="saveAs" data-target="#copy-lv"><i class="fa fa-files-o"></i> 另存单独用</a></label>
     </div>
@@ -73,8 +73,8 @@
 
             </div>
             <div class="modal-footer">
-                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
                 <button type="button"  class="btn btn-primary" data-dismiss="modal" id="changeFeeRateConfirm">确定</button>
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
             </div>
         </div>
     </div>
@@ -103,8 +103,8 @@
                 </div>
             </div>
             <div class="modal-footer">
-                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
                 <button type="button" class="btn btn-primary" id="changeConfirm" data-dismiss="modal">确定</button>
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
             </div>
         </div>
     </div>
@@ -130,8 +130,8 @@
                 </div>
             </div>
             <div class="modal-footer">
-                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
                 <button type="button" class="btn btn-primary" id="saveAsConfirm">确定</button>
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
             </div>
         </div>
     </div>
@@ -156,8 +156,8 @@
                 </div>
             </div>
             <div class="modal-footer">
-                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
                 <button type="button" class="btn btn-primary" data-dismiss="modal" id="renameConfirm" disabled>确定</button>
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
             </div>
         </div>
     </div>

+ 18 - 17
web/building_saas/glj/html/project_glj.html

@@ -5,27 +5,28 @@
 </style>
 <div class="toolsbar px-1">
     <div class="form-inline py-1">
-        <label class="mx-2">当前使用:<span id="current-name"></span>(<a href="#" id="pop-used-list" data-original-title="" title=""><span id="used-project-count">0</span> 个单位工程使用</a>)
+        <label class="mx-2">当前使用:<span id="current-name"></span>(<label class="a_color" id="pop-used-list" data-original-title="" title=""><span id="used-project-count">0</span>个单位工程使用</label>)
             <a class="btn btn-sm ml-1" href="#" data-toggle="modal" data-target="#change-unitFile"><i class="fa fa-exchange"></i> 选择其他</a>
             <a class="btn btn-sm ml-1" href="#" data-toggle="modal" data-target="#unitFile-save-as"><i class="fa fa-files-o"></i> 另存单独用</a></label>
     </div>
 </div>
+
 <div class="container-fluid">
     <div class="row">
         <div class="gl-side col-lg-1 filterType" id='filterType'>
-            <ul class="list-unstyled mt-2 mb-2">
-                <li><a href="javascript:void(0)" id="ALL">所有人材机</a></li>
-                <li class="mb-2 li_sub"><a href="javascript:void(0)" id="LABOUR">人工</a></li>
-                <li class="mb-2 li_sub"><a href="javascript:void(0)" id="GENERAL_MATERIAL">材料</a></li>
-                <li class="mb-2 li_sub"><a href="javascript:void(0)" id="GENERAL_MACHINE">机械</a></li>
-                <li class="mb-2 li_sub"><a href="javascript:void(0)" id="MAIN_MATERIAL">主材</a></li>
-                <li class="mb-2 li_sub"><a href="javascript:void(0)" id="EQUIPMENT">设备</a></li>
-                <li class="mb-2"><a href="javascript:void(0)" id="FBFX">分部分项人材机</a></li>
-                <li class="mb-2"><a href="javascript:void(0)" id="TECH">措施项目人材机</a></li>
-                <li class="mb-2"><a href="javascript:void(0)" id="JGCL">甲供材料</a></li>
-                <li class="mb-2"><a href="javascript:void(0)" id="ZGCL">暂估材料</a></li>
-                <li class="mb-2"><a href="javascript:void(0)" id="SCHZ">三材汇总</a></li>
-                <li class="mb-2"><a href="javascript:void(0)" id="ZYCL">主要材料</a></li>
+            <ul class="nav flex-column nav-pills mt-2 mb-2">
+                <li class="nav-item"><a class="nav-link active" href="#" id="ALL">所有人材机</a></li>
+                <li class="nav-item li_sub"><a class="nav-link" href="javascript:void(0)" id="LABOUR">人工</a></li>
+                <li class="nav-item li_sub"><a class="nav-link" href="javascript:void(0)" id="GENERAL_MATERIAL">材料</a></li>
+                <li class="nav-item li_sub"><a class="nav-link" href="javascript:void(0)" id="GENERAL_MACHINE">机械</a></li>
+                <li class="nav-item li_sub"><a class="nav-link" href="javascript:void(0)" id="MAIN_MATERIAL">主材</a></li>
+                <li class="nav-item li_sub"><a class="nav-link" href="javascript:void(0)" id="EQUIPMENT">设备</a></li>
+                <li class="nav-item"><a class="nav-link" href="javascript:void(0)" id="FBFX">分部分项人材机</a></li>
+                <li class="nav-item"><a class="nav-link" href="javascript:void(0)" id="TECH">措施项目人材机</a></li>
+                <li class="nav-item"><a class="nav-link" href="javascript:void(0)" id="JGCL">甲供材料</a></li>
+                <li class="nav-item"><a class="nav-link" href="javascript:void(0)" id="ZGCL">暂估材料</a></li>
+                <li class="nav-item"><a class="nav-link" href="javascript:void(0)" id="SCHZ">三材汇总</a></li>
+                <li class="nav-item"><a class="nav-link" href="javascript:void(0)" id="ZYCL">主要材料</a></li>
             </ul>
         </div>
         <div class="main-content col p-0 col-lg-11" id="project-glj-main">
@@ -105,8 +106,8 @@
                 </div>
             </div>
             <div class="modal-footer">
-                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
                 <a href="javascript:void(0);" class="btn btn-primary" id="change-file-confirm">确定</a>
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
             </div>
         </div>
     </div>
@@ -129,8 +130,8 @@
                 </div>
             </div>
             <div class="modal-footer">
-                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
                 <button type="button" class="btn btn-primary" id="save-as-confirm">确定</button>
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
             </div>
         </div>
     </div>
@@ -156,8 +157,8 @@
                 </div>
             </div>
             <div class="modal-footer">
-                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
                 <button type="button" class="btn btn-primary" data-dismiss="modal" id="renameUnitFileConfirm" disabled>确定</button>
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
             </div>
         </div>
     </div>

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

@@ -128,7 +128,7 @@ function compositionSuccess(info) {
         }
     }
     if(updateNodes.length>0){
-        projectObj.project.calcProgram.calcRationsAndSave(updateNodes);
+        projectObj.project.calcProgram.calcNodesAndSave(updateNodes);
     }
     gljOprObj.refreshView();
 }

+ 14 - 21
web/building_saas/main/html/main.html

@@ -78,8 +78,8 @@
                       <a class="dropdown-item" href="javascript:void(0);" style="padding: 0rem 1.5rem" id="displayZM">子目</a>
                       <a class="dropdown-item" href="javascript:void(0);" style="padding: 0rem 1.5rem" id="displayZD">最底层</a>
                     </div>
-                     <a href="javascript:void(0)" class="btn btn-sm" id = 'ZLFB_btn'><i class="fa fa-sign-in " aria-hidden="true"></i><span data-toggle="tooltip" data-placement="bottom" title="整理分部"> 整理分部</span></a>
                     </span>
+                      <a href="javascript:void(0)" class="btn btn-sm" id = 'ZLFB_btn'><i class="fa fa-sign-in " aria-hidden="true"></i><span data-toggle="tooltip" data-placement="bottom" title="整理分部"> 整理分部</span></a>
                       <% if (projectData.property.lockBills == true) { %>
                       <a href="javascript:void(0)" class="btn btn-sm" name="lockBills"  title="解锁清单"> <i class="fa fa-unlock-alt" aria-hidden="true"></i> 解锁清单</a>
                       <% } else { %>
@@ -596,8 +596,8 @@
                     </div>
                 </div>
                 <div class="modal-footer">
-                    <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
                     <a href="javascript:void(0);" class="btn btn-primary" id="property_ok" data-dismiss="modal">确定</a>
+                    <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
                 </div>
             </div>
         </div>
@@ -728,8 +728,8 @@
                         </div>
                 </div>
                 <div class="modal-footer">
-                    <button type="button" id="componentsCacnel" class="btn btn-secondary" data-dismiss="modal">取消</button>
                     <a href="javascript:void(0);" id="glj_selected_conf" class="btn btn-primary">确定</a>
+                    <button type="button" id="componentsCacnel" class="btn btn-secondary" data-dismiss="modal">取消</button>
                 </div>
             </div>
         </div>
@@ -759,8 +759,8 @@
                     </div>
                 </div>
                 <div class="modal-footer">
-                    <button type="button" id="classCacnel" class="btn btn-secondary" data-dismiss="modal">取消</button>
                     <button type="button" href="javascript:void(0);" id="class_selected_conf" class="btn btn-primary" disabled >确定</button>
+                    <button type="button" id="classCacnel" class="btn btn-secondary" data-dismiss="modal">取消</button>
                 </div>
             </div>
         </div>
@@ -781,8 +781,8 @@
                         <div class="modal-auto-height col-12" style="overflow: hidden" id="fee_rate_sheet"></div>
                     </div>
                     <div class="modal-footer">
-                        <button type="button" id="frCacnel" class="btn btn-secondary" data-dismiss="modal">取消</button>
                         <a href="javascript:void(0);" id="fee_selected_conf" class="btn btn-primary">确定</a>
+                        <button type="button" id="frCacnel" class="btn btn-secondary" data-dismiss="modal">取消</button>
                     </div>
                 </div>
             </div>
@@ -793,7 +793,7 @@
         <div class="modal-dialog" role="document">
             <div class="modal-content" style="width:670px;">
                 <div class="modal-header">
-                    <h5 class="modal-title">计算基选择</h5>
+                    <h5 class="modal-title">计算基选择</h5>
                     <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                         <span aria-hidden="true">&times;</span>
                     </button>
@@ -848,8 +848,8 @@
 
                 </div>
                 <div class="modal-footer">
-                    <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
                     <a href="javascript:void(0);" class="btn btn-primary" id="calcBaseConf">确定</a>
+                    <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
                 </div>
             </div>
         </div>
@@ -963,8 +963,8 @@
                     </div>
                 </div>
                 <div class="modal-footer">
-                    <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
                     <button type="button" class="btn btn-primary" id="zlfb_confirm">确定</button>
+                    <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
                 </div>
             </div>
         </div>
@@ -1011,9 +1011,9 @@
                     </div>
                 </div>
                 <div class="modal-footer">
+                    <button  class="btn btn-primary" id="calc_installation_fee_confirm">确定</button>
                     <button type="button" class="btn btn-link" id="btn_reset_to_default">恢复默认值</button>
                   <!--  <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>-->
-                    <button  class="btn btn-primary" id="calc_installation_fee_confirm">确定</button>
                 </div>
             </div>
         </div>
@@ -1047,8 +1047,8 @@
                     </div>
                 </div>
                 <div class="modal-footer">
-                    <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
                     <button class="btn btn-primary" id="select_position_confirm">确定</button>
+                    <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
                 </div>
             </div>
         </div>
@@ -1070,8 +1070,8 @@
                     </div>
                 </div>
                 <div class="modal-footer">
-                    <button type="button" class="btn btn-secondary" id="more_feeRule_concel" data-dismiss="modal">取消</button>
                     <button class="btn btn-primary" id="more_feeRule_confirm">确定</button>
+                    <button type="button" class="btn btn-secondary" id="more_feeRule_concel" data-dismiss="modal">取消</button>
                 </div>
             </div>
         </div>
@@ -1092,8 +1092,8 @@
                 </div>
                 </div>
                 <div class="modal-footer">
-                    <button type="button" class="btn btn-secondary" id="modify_feeRule_concel" data-dismiss="modal">取消</button>
                     <button class="btn btn-primary" id="modify_feeRule_confirm">确定</button>
+                    <button type="button" class="btn btn-secondary" id="modify_feeRule_concel" data-dismiss="modal">取消</button>
                 </div>
             </div>
         </div>
@@ -1120,8 +1120,8 @@
                     <button type="button" class="btn btn-primary" id="uploadExample">示例</button>
                 </div>
                 <div class="modal-footer">
-                    <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
                     <a href="javascript:void(0);" class="btn btn-primary" id="uploadConfirm">确定导入</a>
+                    <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
                 </div>
             </div>
         </div>
@@ -1157,8 +1157,8 @@
                     </div>
                 </div>
                 <div class="modal-footer">
-                    <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
                     <button class="btn btn-primary" id="paste_confirm">确定</button>
+                    <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
                 </div>
             </div>
         </div>
@@ -1301,13 +1301,6 @@
            // autoFlashHeight();
         </script>
 
-        <script>
-            !function loadHintBox(){
-                $("body").append('<div id = "hintBox_container"></div>');
-                $("#hintBox_container").load("../../../../public/scHintBox.html");
-            }();
-        </script>
-
         <SCRIPT type="text/javascript">
             <!--
 //            var zNodes =[

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

@@ -8,7 +8,7 @@
         </div>
         <div class="input-group input-group-sm mr-2" style="width:240px">
             <div class="input-group-prepend">
-                <span class="input-group-text" id="inputGroup-sizing-sm">工料机单价调整系数</span>
+                <span class="input-group-text" id="inputGroup-sizing-sm">人材机单价调整系数</span>
             </div>
             <input id = 'gljPriceTenderCoe' type="number" step="0.1" class="form-control" placeholder="请输入系数" value="1">
         </div>

+ 9 - 2
web/building_saas/main/js/controllers/block_controller.js

@@ -272,7 +272,9 @@ let BlockController = {
              //主材设备工料机插入主树
              project.ration_glj.addToMainTree(result.ration_gljs);
              //更新计算程序模板,并进行重新计算
-             project.calcProgram.calcRationsAndSave(rationNodes);
+             project.calcProgram.calcNodesAndSave(rationNodes,function () {
+                 installationFeeObj.calcInstallationFee();
+             });
         })
 
     },
@@ -298,6 +300,11 @@ let BlockController = {
         //更新项目工料机模块信息-计算消耗量
         project.projectGLJ.datas = result.gljData;
         project.projectGLJ.calcQuantity();
+        for(let r of result.rations){
+            if(r.type == rationType.gljRation){//对于工料机类型的定额,要重新设置下市场单价
+                gljOprObj.setGLJPrice(r);
+            }
+        }
     },
 
     addToTree:function (parentID,nextID,bills,rations) {
@@ -487,7 +494,7 @@ let BlockController = {
             billsIDMap[tem_ration.billsItemID]?tem_ration.billsItemID = billsIDMap[tem_ration.billsItemID]:'';
 
             let firstLibID = rationLibObj.getFirstStdRationLibID();
-            if(firstLibID){
+            if(firstLibID&&tem_ration.type == rationType.ration){
                 tem_ration.prefix = projectObj.project.Ration.getRationPrefix(firstLibID,tem_ration);
             }
             return tem_ration;

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

@@ -35,7 +35,7 @@ ProjectController = {
                 sc.setTreeSelected(newNode);
                 TREE_SHEET_HELPER.refreshTreeNodeData(sc.setting, sc.sheet, [newNode], false);
                 sc.sheet.setSelection(newNode.serialNo(), sels[0].col, 1, 1);
-                sc.sheet.showRow(newNode.serialNo(), GC.Spread.Sheets.VerticalPosition.center);
+               // sc.sheet.showRow(newNode.serialNo(), GC.Spread.Sheets.VerticalPosition.center);
             }
             cbTools.refreshFormulaNodes();
         });

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

@@ -202,8 +202,8 @@ var Bills = {
                     data.data.unit = stdBillsData.unit;
                     // 工程量计算规则
                     data.data.ruleText = stdBillsData.ruleText;
-                    // 说明(注)
-                    data.data.comments = stdBillsData.recharge;
+                    // 说明(清单备注)
+                    data.data.comments = stdBillsData.comments;
                     //zhong 特征及内容
                     data.data.jobContent = stdBillsData.jobContent;
                     data.data.itemCharacter = stdBillsData.itemCharacter;
@@ -506,6 +506,15 @@ var Bills = {
                 return false;
             }
         };
+        bills.prototype.isEngineerEst = function (node) {//判断是否是“专业工程暂估价”节点
+            return node && isFlag(node.data)&&node.data.flagsIndex.fixed.flag==fixedFlag.ENGINEERING_ESITIMATE;
+        };
+        bills.prototype.isTotalService = function (node) {//判断是否是“总承包服务费”节点
+            return node && isFlag(node.data)&&node.data.flagsIndex.fixed.flag==fixedFlag.TURN_KEY_CONTRACT;
+        };
+        bills.prototype.isClaimVisa = function (node) {//判断是否是“签证及索赔计价”节点
+            return node && isFlag(node.data)&&node.data.flagsIndex.fixed.flag==fixedFlag.CLAIM_VISA;
+        };
         bills.prototype.isMeasure = function (node) {//判读是否属于措施项目部分
             let rootNode = this.getRootNode(node);
             if(isFlag(rootNode.data)&&rootNode.data.flagsIndex.fixed.flag==fixedFlag.MEASURE){
@@ -740,11 +749,8 @@ var Bills = {
                     if(!isChange) {
                         project.projectGLJ.loadData();
                     }
+                    gljOprObj.refreshView();
                 });
-
-               /* project.calcProgram.calcBillsAndSave(parentNodes,function () {
-                    project.projectGLJ.loadData();
-                });*/
             }, function () {
                 $.bootstrapLoading.end();
             });

+ 135 - 86
web/building_saas/main/js/models/calc_base.js

@@ -315,59 +315,70 @@ let cbTools = {
 };
 
 let baseFigureTemplate = {
-    'FBFXGCF': function () {
+    'FBFXGCF': function (tender) {
+        const totalFeeType = tender ? 'tenderTotalFee' : 'totalFee';
         let bill = calcBase.fixedBills[calcBase.fixedFlag.SUB_ENGINERRING]['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.totalFee) ? bill.feesIndex.common.totalFee : 0;
+        return cbTools.isDef(bill.feesIndex.common) && cbTools.isDef(bill.feesIndex.common[totalFeeType]) ? bill.feesIndex.common[totalFeeType] : 0;
     },
-    'FBFXDEJJRGF': function () {
+    'FBFXDEJJRGF': function (tender) {
+        const totalFeeType = tender ? 'tenderTotalFee' : 'totalFee';
         let bill = calcBase.fixedBills[calcBase.fixedFlag.SUB_ENGINERRING]['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.labour) && cbTools.isDef(bill.feesIndex.labour.totalFee) ? bill.feesIndex.labour.totalFee : 0;
+        return cbTools.isDef(bill.feesIndex.labour) && cbTools.isDef(bill.feesIndex.labour[totalFeeType]) ? bill.feesIndex.labour[totalFeeType] : 0;
     },
-    'FBFXDEJJCLF': function () {
+    'FBFXDEJJCLF': function (tender) {
+        const totalFeeType = tender ? 'tenderTotalFee' : 'totalFee';
         let bill = calcBase.fixedBills[calcBase.fixedFlag.SUB_ENGINERRING]['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.material) && cbTools.isDef(bill.feesIndex.material.totalFee) ? bill.feesIndex.material.totalFee : 0;
+        return cbTools.isDef(bill.feesIndex.material) && cbTools.isDef(bill.feesIndex.material[totalFeeType]) ? bill.feesIndex.material[totalFeeType] : 0;
     },
-    'FBFXDEJJJXF': function () {
+    'FBFXDEJJJXF': function (tender) {
+        const totalFeeType = tender ? 'tenderTotalFee' : 'totalFee';
         let bill = calcBase.fixedBills[calcBase.fixedFlag.SUB_ENGINERRING]['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.machine) && cbTools.isDef(bill.feesIndex.machine.totalFee) ? bill.feesIndex.machine.totalFee : 0;
+        return cbTools.isDef(bill.feesIndex.machine) && cbTools.isDef(bill.feesIndex.machine[totalFeeType]) ? bill.feesIndex.machine[totalFeeType] : 0;
     },
-    'FBFXTZRGF': function () {
+    'FBFXTZRGF': function (tender) {
+        const totalFeeType = tender ? 'tenderTotalFee' : 'totalFee';
         let bill = calcBase.fixedBills[calcBase.fixedFlag.SUB_ENGINERRING]['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.adjustLabour) && cbTools.isDef(bill.feesIndex.adjustLabour.totalFee) ? bill.feesIndex.adjustLabour.totalFee : 0;
+        return cbTools.isDef(bill.feesIndex.adjustLabour) && cbTools.isDef(bill.feesIndex.adjustLabour[totalFeeType]) ? bill.feesIndex.adjustLabour[totalFeeType] : 0;
     },
-    'FBFXTZJSRGF': function () {
+    'FBFXTZJSRGF': function (tender) {
+        const totalFeeType = tender ? 'tenderTotalFee' : 'totalFee';
         let bill = calcBase.fixedBills[calcBase.fixedFlag.SUB_ENGINERRING]['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.adjustMachineLabour) && cbTools.isDef(bill.feesIndex.adjustMachineLabour.totalFee) ? bill.feesIndex.adjustMachineLabour.totalFee : 0;
+        return cbTools.isDef(bill.feesIndex.adjustMachineLabour) && cbTools.isDef(bill.feesIndex.adjustMachineLabour[totalFeeType]) ? bill.feesIndex.adjustMachineLabour[totalFeeType] : 0;
     },
-    'FBFXZCF': function () {
+    'FBFXZCF': function (tender) {
+        const totalFeeType = tender ? 'tenderTotalFee' : 'totalFee';
         let bill = calcBase.fixedBills[calcBase.fixedFlag.SUB_ENGINERRING]['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.mainMaterial) && cbTools.isDef(bill.feesIndex.mainMaterial.totalFee) ? bill.feesIndex.mainMaterial.totalFee : 0;
+        return cbTools.isDef(bill.feesIndex.mainMaterial) && cbTools.isDef(bill.feesIndex.mainMaterial[totalFeeType]) ? bill.feesIndex.mainMaterial[totalFeeType] : 0;
     },
-    'FBFXSBF': function () {
+    'FBFXSBF': function (tender) {
+        const totalFeeType = tender ? 'tenderTotalFee' : 'totalFee';
         let bill = calcBase.fixedBills[calcBase.fixedFlag.SUB_ENGINERRING]['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.equipment) && cbTools.isDef(bill.feesIndex.equipment.totalFee) ? bill.feesIndex.equipment.totalFee : 0;
+        return cbTools.isDef(bill.feesIndex.equipment) && cbTools.isDef(bill.feesIndex.equipment[totalFeeType]) ? bill.feesIndex.equipment[totalFeeType] : 0;
     },
-    'FBFXWJJCLF': function () {
-        return (this['FBFXZCF']() + this['FBFXSBF']()).toDecimal(decimalObj.bills.totalPrice);
+    'FBFXWJJCLF': function (tender) {
+        return (this['FBFXZCF'](tender) + this['FBFXSBF'](tender)).toDecimal(decimalObj.bills.totalPrice);
     },
     //统计分部分项下工料机类型为“人工”的总消耗量
-    'FBFXRGGR': function () {
+    'FBFXRGGR': function (tender) {
+        const totalFeeType = tender ? 'tenderTotalFee' : 'totalFee';
+        const quantityType = tender ? 'tenderQuantity' : 'quantity';
+        //todo 调用subdivisionTenderQuantity
         let projGljs = calcBase.project.projectGLJ.datas.gljList;
         let rst = 0;
         for(let glj of projGljs){
@@ -379,92 +390,105 @@ let baseFigureTemplate = {
         }
         return rst;
     },
-    'FBFXDEJJZJGCF': function () {
-        return (this['FBFXDEJJRGF']() + this['FBFXDEJJCLF']() + this['FBFXDEJJJXF']()).toDecimal(decimalObj.bills.totalPrice);
+    'FBFXDEJJZJGCF': function (tender) {
+        return (this['FBFXDEJJRGF'](tender) + this['FBFXDEJJCLF'](tender) + this['FBFXDEJJJXF'](tender)).toDecimal(decimalObj.bills.totalPrice);
     },
-    'CSXMF': function () {
+    'CSXMF': function (tender) {
+        const totalFeeType = tender ? 'tenderTotalFee' : 'totalFee';
         let bill = calcBase.fixedBills[calcBase.fixedFlag.MEASURE]['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.totalFee) ? bill.feesIndex.common.totalFee : 0;
+        return cbTools.isDef(bill.feesIndex.common) && cbTools.isDef(bill.feesIndex.common[totalFeeType]) ? bill.feesIndex.common[totalFeeType] : 0;
     },
-    'ZZCSXMF': function () {
+    'ZZCSXMF': function (tender) {
+        const totalFeeType = tender ? 'tenderTotalFee' : 'totalFee';
         let bill = calcBase.fixedBills[calcBase.fixedFlag.CONSTRUCTION_ORGANIZATION]['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.totalFee) ? bill.feesIndex.common.totalFee : 0;
+        return cbTools.isDef(bill.feesIndex.common) && cbTools.isDef(bill.feesIndex.common[totalFeeType]) ? bill.feesIndex.common[totalFeeType] : 0;
     },
-    'ZZCSXMDEJJZJGCF': function () {
-        return (this['ZZCSXMDEJJRGF']() + this['ZZCSXMDEJJCLF']() + this['ZZCSXMDEJJJXF']()).toDecimal(decimalObj.bills.totalPrice);
+    'ZZCSXMDEJJZJGCF': function (tender) {
+        return (this['ZZCSXMDEJJRGF'](tender) + this['ZZCSXMDEJJCLF'](tender) + this['ZZCSXMDEJJJXF'](tender)).toDecimal(decimalObj.bills.totalPrice);
     },
-    'ZZCSXMDEJJRGF': function () {
+    'ZZCSXMDEJJRGF': function (tender) {
+        const totalFeeType = tender ? 'tenderTotalFee' : 'totalFee';
         let bill = calcBase.fixedBills[calcBase.fixedFlag.CONSTRUCTION_ORGANIZATION]['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.labour) && cbTools.isDef(bill.feesIndex.labour.totalFee) ? bill.feesIndex.labour.totalFee : 0;
+        return cbTools.isDef(bill.feesIndex.labour) && cbTools.isDef(bill.feesIndex.labour[totalFeeType]) ? bill.feesIndex.labour[totalFeeType] : 0;
     },
-    'ZZCSXMDEJJCLF': function () {
+    'ZZCSXMDEJJCLF': function (tender) {
+        const totalFeeType = tender ? 'tenderTotalFee' : 'totalFee';
         let bill = calcBase.fixedBills[calcBase.fixedFlag.CONSTRUCTION_ORGANIZATION]['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.material) && cbTools.isDef(bill.feesIndex.material.totalFee) ? bill.feesIndex.material.totalFee : 0;
+        return cbTools.isDef(bill.feesIndex.material) && cbTools.isDef(bill.feesIndex.material[totalFeeType]) ? bill.feesIndex.material[totalFeeType] : 0;
     },
-    'ZZCSXMDEJJJXF': function () {
+    'ZZCSXMDEJJJXF': function (tender) {
+        const totalFeeType = tender ? 'tenderTotalFee' : 'totalFee';
         let bill = calcBase.fixedBills[calcBase.fixedFlag.CONSTRUCTION_ORGANIZATION]['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.machine) && cbTools.isDef(bill.feesIndex.machine.totalFee) ? bill.feesIndex.machine.totalFee : 0;
+        return cbTools.isDef(bill.feesIndex.machine) && cbTools.isDef(bill.feesIndex.machine[totalFeeType]) ? bill.feesIndex.machine[totalFeeType] : 0;
     },
-    'JSCSXMF': function () {
+    'JSCSXMF': function (tender) {
+        const totalFeeType = tender ? 'tenderTotalFee' : 'totalFee';
         let bill = calcBase.fixedBills[calcBase.fixedFlag.CONSTRUCTION_TECH]['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.totalFee) ? bill.feesIndex.common.totalFee : 0;
+        return cbTools.isDef(bill.feesIndex.common) && cbTools.isDef(bill.feesIndex.common[totalFeeType]) ? bill.feesIndex.common[totalFeeType] : 0;
     },
-    'JSCSXMDEJJRGF': function () {
+    'JSCSXMDEJJRGF': function (tender) {
+        const totalFeeType = tender ? 'tenderTotalFee' : 'totalFee';
         let bill = calcBase.fixedBills[calcBase.fixedFlag.CONSTRUCTION_TECH]['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.labour) && cbTools.isDef(bill.feesIndex.labour.totalFee) ? bill.feesIndex.labour.totalFee : 0;
+        return cbTools.isDef(bill.feesIndex.labour) && cbTools.isDef(bill.feesIndex.labour[totalFeeType]) ? bill.feesIndex.labour[totalFeeType] : 0;
     },
-    'JSCSXMDEJJCLF': function () {
+    'JSCSXMDEJJCLF': function (tender) {
+        const totalFeeType = tender ? 'tenderTotalFee' : 'totalFee';
         let bill = calcBase.fixedBills[calcBase.fixedFlag.CONSTRUCTION_TECH]['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.material) && cbTools.isDef(bill.feesIndex.material.totalFee) ? bill.feesIndex.material.totalFee : 0;
+        return cbTools.isDef(bill.feesIndex.material) && cbTools.isDef(bill.feesIndex.material[totalFeeType]) ? bill.feesIndex.material[totalFeeType] : 0;
     },
-    'JSCSXMDEJJJXF': function () {
+    'JSCSXMDEJJJXF': function (tender) {
+        const totalFeeType = tender ? 'tenderTotalFee' : 'totalFee';
         let bill = calcBase.fixedBills[calcBase.fixedFlag.CONSTRUCTION_TECH]['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.machine) && cbTools.isDef(bill.feesIndex.machine.totalFee) ? bill.feesIndex.machine.totalFee : 0;
+        return cbTools.isDef(bill.feesIndex.machine) && cbTools.isDef(bill.feesIndex.machine[totalFeeType]) ? bill.feesIndex.machine[totalFeeType] : 0;
     },
-    'JSCSXMTZRGF': function () {
+    'JSCSXMTZRGF': function (tender) {
+        const totalFeeType = tender ? 'tenderTotalFee' : 'totalFee';
         let bill = calcBase.fixedBills[calcBase.fixedFlag.CONSTRUCTION_TECH]['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.adjustLabour) && cbTools.isDef(bill.feesIndex.adjustLabour.totalFee) ? bill.feesIndex.adjustLabour.totalFee : 0;
+        return cbTools.isDef(bill.feesIndex.adjustLabour) && cbTools.isDef(bill.feesIndex.adjustLabour[totalFeeType]) ? bill.feesIndex.adjustLabour[totalFeeType] : 0;
     },
-    'JSCSXMTZJSRGF': function () {
+    'JSCSXMTZJSRGF': function (tender) {
+        const totalFeeType = tender ? 'tenderTotalFee' : 'totalFee';
         let bill = calcBase.fixedBills[calcBase.fixedFlag.CONSTRUCTION_TECH]['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.adjustMachineLabour) && cbTools.isDef(bill.feesIndex.adjustMachineLabour.totalFee) ? bill.feesIndex.adjustMachineLabour.totalFee : 0;
+        return cbTools.isDef(bill.feesIndex.adjustMachineLabour) && cbTools.isDef(bill.feesIndex.adjustMachineLabour[totalFeeType]) ? bill.feesIndex.adjustMachineLabour[totalFeeType] : 0;
     },
-    'JSCSXMZCF': function () {
+    'JSCSXMZCF': function (tender) {
+        const totalFeeType = tender ? 'tenderTotalFee' : 'totalFee';
         let bill = calcBase.fixedBills[calcBase.fixedFlag.CONSTRUCTION_TECH]['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.mainMaterial) && cbTools.isDef(bill.feesIndex.mainMaterial.totalFee) ? bill.feesIndex.mainMaterial.totalFee : 0;
+        return cbTools.isDef(bill.feesIndex.mainMaterial) && cbTools.isDef(bill.feesIndex.mainMaterial[totalFeeType]) ? bill.feesIndex.mainMaterial[totalFeeType] : 0;
     },
-    'JSCSXMSBF': function () {
+    'JSCSXMSBF': function (tender) {
+        const totalFeeType = tender ? 'tenderTotalFee' : 'totalFee';
         let bill = calcBase.fixedBills[calcBase.fixedFlag.CONSTRUCTION_TECH]['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.equipment) && cbTools.isDef(bill.feesIndex.equipment.totalFee) ? bill.feesIndex.equipment.totalFee : 0;
+        return cbTools.isDef(bill.feesIndex.equipment) && cbTools.isDef(bill.feesIndex.equipment[totalFeeType]) ? bill.feesIndex.equipment[totalFeeType] : 0;
     },
-    'JSCSXMWJJCLF': function () {
-        return (this['JSCSXMZCF']() + this['JSCSXMSBF']()).toDecimal(decimalObj.bills.totalPrice);
+    'JSCSXMWJJCLF': function (tender) {
+        return (this['JSCSXMZCF'](tender) + this['JSCSXMSBF'](tender)).toDecimal(decimalObj.bills.totalPrice);
     },
     'JSCSXMRGGR': function () {
         let rst = 0;
@@ -478,36 +502,39 @@ let baseFigureTemplate = {
         }
         return rst;
     },
-    'JSCSXMDEJJZJGCF': function () {
-        return (this['JSCSXMDEJJRGF']() + this['JSCSXMDEJJCLF']() + this['JSCSXMDEJJJXF']()).toDecimal(decimalObj.bills.totalPrice);
+    'JSCSXMDEJJZJGCF': function (tender) {
+        return (this['JSCSXMDEJJRGF'](tender) + this['JSCSXMDEJJCLF'](tender) + this['JSCSXMDEJJJXF'](tender)).toDecimal(decimalObj.bills.totalPrice);
     },
-    'QTXMF': function () {
+    'QTXMF': function (tender) {
+        const totalFeeType = tender ? 'tenderTotalFee' : 'totalFee';
         let bill = calcBase.fixedBills[calcBase.fixedFlag.OTHER]['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.totalFee) ? bill.feesIndex.common.totalFee : 0;
+        return cbTools.isDef(bill.feesIndex.common) && cbTools.isDef(bill.feesIndex.common[totalFeeType]) ? bill.feesIndex.common[totalFeeType] : 0;
     },
-    'GF': function () {
+    'GF': function (tender) {
+        const totalFeeType = tender ? 'tenderTotalFee' : 'totalFee';
         let bill = calcBase.fixedBills[calcBase.fixedFlag.CHARGE]['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.totalFee) ? bill.feesIndex.common.totalFee : 0;
+        return cbTools.isDef(bill.feesIndex.common) && cbTools.isDef(bill.feesIndex.common[totalFeeType]) ? bill.feesIndex.common[totalFeeType] : 0;
     },
-    'SJ': function () {
+    'SJ': function (tender) {
+        const totalFeeType = tender ? 'tenderTotalFee' : 'totalFee';
         let bill = calcBase.fixedBills[calcBase.fixedFlag.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.totalFee) ? bill.feesIndex.common.totalFee : 0;
+        return cbTools.isDef(bill.feesIndex.common) && cbTools.isDef(bill.feesIndex.common[totalFeeType]) ? bill.feesIndex.common[totalFeeType] : 0;
     },
-    'SQGCZJ': function () {//税前工程造价
+    'SQGCZJ': function (tender) {//税前工程造价
         let bill = calcBase.fixedBills[calcBase.fixedFlag.SAFETY_CONSTRUCTION]['bill'];
         if(cbTools.isUnDef(bill) || cbTools.isUnDef(bill.ID)) return 0;
         let node = cbTools.getNodeByID(bill.ID);
         if(cbTools.isUnDef(node)) return 0;
-        return projectObj.project.calcProgram.getBeforeTaxTotalFee([node]);
+        return projectObj.project.calcProgram.getBeforeTaxTotalFee([node], tender);
     },
-    'RCJJC': function () {//人材机价差
-        return (this['RGJC']() + this['CLJC']() + this['JXJC']()).toDecimal(decimalObj.bills.totalPrice);
+    'RCJJC': function (tender) {//人材机价差
+        return (this['RGJC'](tender) + this['CLJC'](tender) + this['JXJC'](tender)).toDecimal(decimalObj.bills.totalPrice);
     },
     'RGJC': function () {//人工价差
         let rst = 0;
@@ -551,8 +578,8 @@ let baseFigureTemplate = {
         }
         return rst;
     },
-    'FBFXRCJJC': function () {//分部分项人材机价差
-        return (this['FBFXRGJC']() + this['FBFXCLJC']() + this['FBFXJXJC']()).toDecimal(decimalObj.bills.totalPrice);
+    'FBFXRCJJC': function (tender) {//分部分项人材机价差
+        return (this['FBFXRGJC'](tender) + this['FBFXCLJC'](tender) + this['FBFXJXJC'](tender)).toDecimal(decimalObj.bills.totalPrice);
     },
     'FBFXRGJC': function () {//分部分项人工价差
         let rst = 0;
@@ -596,8 +623,8 @@ let baseFigureTemplate = {
         }
         return rst;
     },
-    'JSCSXMRCJJC': function () {//技术措施项目人材机价差
-        return (this['JSCSXMRGJC']() + this['JSCSXMCLJC']() + this['JSCSXMJXJC']()).toDecimal(decimalObj.bills.totalPrice);
+    'JSCSXMRCJJC': function (tender) {//技术措施项目人材机价差
+        return (this['JSCSXMRGJC'](tender) + this['JSCSXMCLJC'](tender) + this['JSCSXMJXJC'](tender)).toDecimal(decimalObj.bills.totalPrice);
     },
     'JSCSXMRGJC': function () {//技术措施项目人工价差
         let rst = 0;
@@ -801,76 +828,84 @@ let baseFigureTemplate = {
         }
         return rst;
     },
-    'ZGCLFFZM': function () {//暂估材料费(从子目汇总)
+    'ZGCLFFZM': function (tender) {//暂估材料费(从子目汇总)
+        const totalFeeType = tender ? 'tenderTotalFee' : 'totalFee';
         let bill = calcBase.fixedBills[calcBase.fixedFlag.ENGINEERINGCOST]['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.estimate) && cbTools.isDef(bill.feesIndex.estimate.totalFee) ? bill.feesIndex.estimate.totalFee : 0;
+        return cbTools.isDef(bill.feesIndex.estimate) && cbTools.isDef(bill.feesIndex.estimate[totalFeeType]) ? bill.feesIndex.estimate[totalFeeType] : 0;
     },
     'ZGCLFFGLJ': function () {//暂估材料费(从工料机汇总表汇总)
         return 0;
     },
-    'FBF': function () {//分包费
+    'FBF': function (tender) {//分包费
+        const totalFeeType = tender ? 'tenderTotalFee' : 'totalFee';
         let rst = 0;
         let rations = calcBase.project.Ration.datas;
         for(let ration of rations){
             if(ration.isSubcontract && ration.feesIndex && ration.feesIndex.common){
-                rst = parseFloat(rst + ration.feesIndex.common.totalFee).toDecimal(decimalObj.ration.totalPrice)
+                rst = parseFloat(rst + ration.feesIndex.common[totalFeeType]).toDecimal(decimalObj.ration.totalPrice)
             }
         }
         return rst;
     },
-    'FBDEJJRGF': function () {//分包定额基价人工费
+    'FBDEJJRGF': function (tender) {//分包定额基价人工费
+        const totalFeeType = tender ? 'tenderTotalFee' : 'totalFee';
         let rst = 0;
         let rations = calcBase.project.Ration.datas;
         for(let ration of rations){
             if(ration.isSubcontract && ration.feesIndex && ration.feesIndex.labour){
-                rst = parseFloat(rst + ration.feesIndex.labour.totalFee).toDecimal(decimalObj.ration.totalPrice)
+                rst = parseFloat(rst + ration.feesIndex.labour[totalFeeType]).toDecimal(decimalObj.ration.totalPrice)
             }
         }
         return rst;
     },
-    'FBDEJJCLF': function () {//分包定额基价材料费
+    'FBDEJJCLF': function (tender) {//分包定额基价材料费
+        const totalFeeType = tender ? 'tenderTotalFee' : 'totalFee';
         let rst = 0;
         let rations = calcBase.project.Ration.datas;
         for(let ration of rations){
             if(ration.isSubcontract && ration.feesIndex && ration.feesIndex.material){
-                rst = parseFloat(rst + ration.feesIndex.material.totalFee).toDecimal(decimalObj.ration.totalPrice)
+                rst = parseFloat(rst + ration.feesIndex.material[totalFeeType]).toDecimal(decimalObj.ration.totalPrice)
             }
         }
         return rst;
     },
-    'FBDEJJJXF': function(){//分包定额基价机械费
+    'FBDEJJJXF': function(tender){//分包定额基价机械费
+        const totalFeeType = tender ? 'tenderTotalFee' : 'totalFee';
         let rst = 0;
         let rations = calcBase.project.Ration.datas;
         for(let ration of rations){
             if(ration.isSubcontract && ration.feesIndex && ration.feesIndex.machine){
-                rst = parseFloat(rst + ration.feesIndex.machine.totalFee).toDecimal(decimalObj.ration.totalPrice)
+                rst = parseFloat(rst + ration.feesIndex.machine[totalFeeType]).toDecimal(decimalObj.ration.totalPrice)
             }
         }
         return rst;
     },
-    'FBZCF': function () {//分包主材费
+    'FBZCF': function (tender) {//分包主材费
+        const totalFeeType = tender ? 'tenderTotalFee' : 'totalFee';
         let rst = 0;
         let rations = calcBase.project.Ration.datas;
         for(let ration of rations){
             if(ration.isSubcontract && ration.feesIndex && ration.feesIndex.mainMaterial){
-                rst = parseFloat(rst + ration.feesIndex.mainMaterial.totalFee).toDecimal(decimalObj.ration.totalPrice)
+                rst = parseFloat(rst + ration.feesIndex.mainMaterial[totalFeeType]).toDecimal(decimalObj.ration.totalPrice)
             }
         }
         return rst;
     },
-    'FBSBF': function () {//分包设备费
+    'FBSBF': function (tender) {//分包设备费
+        const totalFeeType = tender ? 'tenderTotalFee' : 'totalFee';
         let rst = 0;
         let rations = calcBase.project.Ration.datas;
         for(let ration of rations){
             if(ration.isSubcontract && ration.feesIndex && ration.feesIndex.equipment){
-                rst = parseFloat(rst + ration.feesIndex.equipment.totalFee).toDecimal(decimalObj.ration.totalPrice)
+                rst = parseFloat(rst + ration.feesIndex.equipment[totalFeeType]).toDecimal(decimalObj.ration.totalPrice)
             }
         }
         return rst;
     },
-    'FBRGGR': function () {//分包人工工日
+    'FBRGGR': function (tender) {//分包人工工日
+        const quantityType = tender ? 'tenderQuantity' : 'quantity';
         let rst = 0;
         let rationObjs = [];//查找定额工料机
         let rations = calcBase.project.Ration.datas;
@@ -879,22 +914,22 @@ let baseFigureTemplate = {
             if(ration.isSubcontract){
                 //定额
                 if(ration.type === rationType.ration){
-                    rationObjs.push({ID: ration.ID, quantity: ration.quantity});
+                    rationObjs.push({ID: ration.ID, quantity: ration[quantityType]});
                 }
                 //量人 type 2, subType 1
                 else if(ration.type === rationType.volumePrice && ration.subType === volumePriceMaps['量人']){
-                    rst = parseFloat(rst + ration.quantity).toDecimal(decimalObj.glj.quantity);
+                    rst = parseFloat(rst + ration[quantityType]).toDecimal(decimalObj.glj.quantity);
                 }
                 //定额类型的人工工料机,type 3, subType 1
                 else if(ration.type === rationType.gljRation && ration.subType === gljType.LABOUR){
-                    rst = parseFloat(rst + ration.quantity).toDecimal(decimalObj.glj.quantity);
+                    rst = parseFloat(rst + ration[quantityType]).toDecimal(decimalObj.glj.quantity);
                 }
             }
         }
         for(let ration of rationObjs){
             for(let glj of rationGljs){
                 if(ration.ID === glj.rationID && glj.type === gljType.LABOUR){
-                    rst = parseFloat(rst + parseFloat(glj.quantity * ration.quantity).toDecimal(decimalObj.glj.quantity)).toDecimal(decimalObj.glj.quantity);
+                    rst = parseFloat(rst + parseFloat(glj[quantityType] * ration.quantity).toDecimal(decimalObj.glj.quantity)).toDecimal(decimalObj.glj.quantity);
                 }
             }
         }
@@ -1325,6 +1360,13 @@ let cbCalctor = {
         }
         return baseFigureTemplate[calcBase.baseFigures[figure]['base']]();
     },
+    //调价后计算基数
+    tenderBase: function (figure) {
+        if(figure === 'NONE'){
+            return 0;
+        }
+        return baseFigureTemplate[calcBase.baseFigures[figure]['base']](true);
+    },
     //ID引用
     ref: function (fExp) {
         let ID = cbParser.getUID([fExp]);
@@ -1400,11 +1442,18 @@ let calcBase = {
             if(!cbTools.isNum(calcBaseValue)){
                 throw '表达式不正确';
             }
+            //调价
+            let tenderCalcExp = calcExp.replace(new RegExp('base', 'g'), 'tenderBase');
+            let tenderCalcBaseValue = eval(tenderCalcExp);
+            if(!cbTools.isNum(tenderCalcBaseValue)){
+                throw '表达式不正确';
+            }
 
             //存储
             me.success = true;
             node.data.calcBase = exp;
             node.data.calcBaseValue = parseFloat(calcBaseValue).toDecimal(decimalObj.decimal('totalPrice', node));
+            node.data.tenderCalcBaseValue = parseFloat(tenderCalcBaseValue).toDecimal(decimalObj.decimal('totalPrice', node));
             node.changed = true;
         }
         catch (err){

文件差异内容过多而无法显示
+ 390 - 247
web/building_saas/main/js/models/calc_program.js


+ 27 - 2
web/building_saas/main/js/models/installation_fee.js

@@ -25,6 +25,10 @@ var installation_fee = {
         installation_fee.prototype.getInstallationFeeByLibID=function(libID){
             return _.find(this.datas,{'libID':libID});
         };
+        installation_fee.prototype.getInstallationFeeByID=function(ID){
+            return _.find(this.datas,{'ID':ID});
+        };
+
         installation_fee.prototype.getFeeRuleByFeeItem = function (feeItem) {
             let installFee = projectObj.project.installation_fee.getInstallationFeeByLibID(feeItem.libID);
             let impacRules = _.filter(installFee.feeRule,{'feeItemId':feeItem.ID});
@@ -169,7 +173,7 @@ var installation_fee = {
            };
            return updateData;
        };
-       installation_fee.prototype.getFeeItemUpdateData = function (libID,itemID,doc) {
+        installation_fee.prototype.getFeeItemUpdateData = function (libID,itemID,doc) {
            let installationFee = this.getInstallationFeeByLibID(libID);
             let updateData = {
                 ID:installationFee.ID,
@@ -179,6 +183,23 @@ var installation_fee = {
             };
             return updateData;
         };
+        installation_fee.prototype.updateInstallation = function (updateData,callback) {
+            let me = this;
+            me.submitInstallationUpdate(updateData,null,function (data) {
+                for(let u of updateData){
+                    let insFee =  me.getInstallationFeeByID(u.ID);
+                    let item = _.find(insFee[u.type],{'ID':u.itemID})
+                    if(item){
+                        for(let key in u.doc){
+                            item[key] = u.doc[key] ;
+                        }
+                    }
+                }
+                if(callback){
+                    callback(data);
+                }
+            });
+        };
        installation_fee.prototype.submitInstallationUpdate = function (updateData,rationInstallations,callback) {
             if(updateData){
                 let data = {'projectID':projectInfoObj.projectInfo.ID,'updateData':updateData};
@@ -695,8 +716,12 @@ var installation_fee = {
                     callback();
                 }
             });
-
         };
+
+
+
+
+
         installation_fee.prototype.resetToDefault = function (callback) {
             let me = this;
             let installFees = [];

+ 10 - 4
web/building_saas/main/js/models/main_consts.js

@@ -21,7 +21,7 @@ const ModuleNames = {
 const gljType = {
     // 人工
     LABOUR: 1,
-    // ==============材料类型=================
+
     // 普通材料
     GENERAL_MATERIAL: 201,
     // 混凝土
@@ -34,15 +34,14 @@ const gljType = {
     COMMERCIAL_CONCRETE: 205,
     // 商品砂浆
     COMMERCIAL_MORTAR: 206,
-    // ==============材料类型=================
-    // ==============机械类型=================
+
     // 机械台班
     GENERAL_MACHINE: 301,
     // 机械组成物
     MACHINE_COMPOSITION: 302,
     // 机上人工
     MACHINE_LABOUR: 303,
-    // ==============机械类型=================
+
     // 主材
     MAIN_MATERIAL: 4,
     // 设备
@@ -115,6 +114,13 @@ const treeNodeCalcType = {
     ctNull: 6
     // ctCommonUnitFee: 6       // 树结点的手工输入综合单价的方式已废弃,现综合单价只读,引入市场单价。
 };
+
+const tenderTypes = {
+  ttCalc: 1,                // 正向调价
+  ttReverseRation: 2,       // 反向调价-调子目
+  ttReverseGLJ: 3          // 反向调价-调工料机
+};
+
 const calcAllType = {
     catAll: 'all',
     catBills: 'bills',

+ 66 - 7
web/building_saas/main/js/models/project_glj.js

@@ -282,9 +282,8 @@ ProjectGLJ.prototype.updatePrice = function (recode, updateField, newval,from,cb
             me.refreshTreeNodePriceIfNeed(glj);//刷新造价书中主树上的定额工料机;
             gljs.push(glj);
             let nodes = me.getImpactRationNodes(gljs);//取到因为改变工料机价格而受影响的定额
-            projectObj.project.calcProgram.calcRationsAndSave(nodes);//触发计算程序
-            socket.emit('unitFileChangeNotify', JSON.stringify(data));
-            projectObj.project.markUpdateProject({projectID:projectObj.project.ID(),'unitFileID':socketObject.getUnitFileRoomID()},"unitFile");
+            projectObj.project.calcProgram.calcNodesAndSave(nodes);//触发计算程序
+            projectGljObject.onUnitFileChange(data);
             if(cb){
                 cb(gljs);
             }
@@ -342,10 +341,9 @@ ProjectGLJ.prototype.batchUpdatePrice = function (changeInfo,callback) {
             let pgljs = me.getProjectGLJs(parentData);
             gljs = gljs.concat(pgljs);
             let nodes = me.getImpactRationNodes(gljs);//取到因为改变工料机价格而受影响的定额
-            projectObj.project.calcProgram.calcRationsAndSave(nodes);//触发计算程序
+            projectObj.project.calcProgram.calcNodesAndSave(nodes);//触发计算程序
             gljOprObj.showRationGLJSheetData();
-            socket.emit('unitFileChangeNotify', JSON.stringify(gljs));
-            projectObj.project.markUpdateProject({projectID:projectObj.project.ID(),'unitFileID':socketObject.getUnitFileRoomID()},"unitFile");
+            projectGljObject.onUnitFileChange(gljs);
             if(callback){
                 callback(gljs);
             }
@@ -412,6 +410,60 @@ ProjectGLJ.prototype.changeFile = function (changeData,callback) {
     });
 };
 
+ProjectGLJ.prototype.addMixRatio = function(selections,callback){
+    let gljList = [],allGLJ = gljOprObj.AllRecode;
+    $("#glj_tree_div").modal('hide');
+    if(selections.length == 0) {
+        return;
+    }
+    for(let glj of allGLJ){
+        let i_key = gljOprObj.getIndex(glj, gljLibKeyArray);
+        if(_.includes(selections,i_key)){
+            let pglj = {
+                project_id: projectObj.project.ID(),
+                glj_id: glj.ID,
+                name: glj.name,
+                code: glj.code,
+                original_code: glj.code,
+                unit: glj.unit,
+                specs: glj.specs,
+                base_price: glj.basePrice,
+                market_price: glj.basePrice,
+                shortName: glj.shortName,
+                type: glj.gljType,
+                adjCoe: glj.adjCoe,
+                from:'std',
+                repositoryId:glj.repositoryId,
+                materialType:glj.materialType,
+                materialCoe:glj.materialCoe,
+            };
+            if (glj.hasOwnProperty("compilationId")) {
+                pglj.from = "cpt";
+                if (glj.code.indexOf('-') != -1) {//这条工料机是用户通过修改名称、规格、型号等保存到补充工料机库的
+                    pglj.original_code = glj.code.split('-')[0];//取-前的编号作为原始编号
+                }
+            }
+            gljList.push(pglj);
+        }
+    }
+    gljList = _.sortByAll(gljList, ['type', 'code']);
+    if(gljList.length == 0) return;
+    let praentInfo = {
+        unit_price_file_id:projectObj.project.property.unitPriceFile.id,
+        connect_key:gljOprObj.getIndex(projectGljObject.selectedProjectGLJ,gljKeyArray)
+    };
+    $.bootstrapLoading.start();
+    CommonAjax.post("/glj/add-ratio", {gljList:gljList,parentInfo:praentInfo}, function (data) {
+        $.bootstrapLoading.end();
+        if(callback){
+            callback(data);
+        }
+    }, function () {
+        $.bootstrapLoading.end();
+    });
+
+}
+
 ProjectGLJ.prototype.checkUnitFileName = function(newVal,callback){
     let property = projectInfoObj.projectInfo.property;
     let data = {
@@ -475,7 +527,7 @@ ProjectGLJ.prototype.changeIsEvaluate=function (id){
             ration_nodes.push(rg);
         }
         ration_nodes.length>0?projectObj.mainController.refreshTreeNode(ration_nodes):"";
-        projectObj.project.calcProgram.calcRationsAndSave(nodes);//触发计算程序
+        projectObj.project.calcProgram.calcNodesAndSave(nodes);//触发计算程序
         return gljs;
     }
 }
@@ -670,4 +722,11 @@ ProjectGLJ.prototype.calcQuantity  = function (init=false){
         }
     }
     changeArray.length > 0 && projectGljObject.calcPartASupplyFeeByProjectGLJs ?projectGljObject.calcPartASupplyFeeByProjectGLJs(changeArray):'';
+};
+
+ProjectGLJ.prototype.calcTenderQuantity  = function (){
+    let rationGLJDatas = projectObj.project.ration_glj.datas;
+    let rationDatas = projectObj.project.Ration.datas;
+    let billsDatas = projectObj.project.Bills.datas;
+    gljUtil.calcProjectGLJQuantity(this.datas,rationGLJDatas,rationDatas,billsDatas,getDecimal("glj.quantity"),_,scMathUtil,true);
 };

+ 82 - 55
web/building_saas/main/js/models/quantity_detail.js

@@ -139,24 +139,29 @@ var quantity_detail = {
                 doc.refreshQuantity=true;
                 if(!selected.data.hasOwnProperty('isFromDetail')||selected.data.isFromDetail==0){
                     if(!args.replace){//为了批量粘贴时不重复提示,普通编辑时不受影响
-                        var c = confirm("确定要使用工程量明细替换原工程量吗?");
-                        if(c){
+                        hintBox.infoBox('操作确认', '确定要使用工程量明细替换原工程量吗?', 2, function () {
                             args.replace = true;
-                        }else {
+                            me.doSaveAction(doc,args,batchCallback);
+                        }, function () {
                             doc.refreshQuantity=false;
-                        }
+                            me.doSaveAction(doc,args,batchCallback);
+                        },['确定','取消']);
+                        return;
                     }
                 }
-
             }
-            var url="";
+            me.doSaveAction(doc,args,batchCallback);
+        };
+
+        quantity_detail.prototype.doSaveAction = function(doc,args,batchCallback){
+            let url="",me = this;
             $.bootstrapLoading.start();
             if(args.hasOwnProperty("insertRecode")){//右键插入或者是通过直接编辑保存
                 url = "/quantity_detail/insertRecode";
             }else{
                 url = "/quantity_detail/save";
             }
-            var callback = function (data) {
+            CommonAjax.post(url,doc,function (data) {
                 $.bootstrapLoading.end();
                 if(doc.refreshQuantity==false){//清空数据
                     me.cleanQuantityDetail();
@@ -165,16 +170,18 @@ var quantity_detail = {
                     if(batchCallback){
                         batchCallback(args)
                     }else if(data.node){
-                      me.refreshRationOrBillNodes(data.node);
+                        me.refreshRationOrBillNodes(data.node);
                     }
                     //gljOprObj.detailSheet.setActiveCell(0,0);
                     //gljOprObj.detailSheet.clearSelection();
                 }
-            }
-            CommonAjax.post(url,doc,callback,function () {
+            },function () {
                 $.bootstrapLoading.end();
             });
         };
+
+
+
         quantity_detail.prototype.refreshRationOrBillNodes=function(node){//工程量明细更新后触发定额或清单工程量改变,进行相应的更新
             var nodes = gljOprObj.refreshTreeNode(node);
             if(nodes.length>0){//触发计算
@@ -183,7 +190,7 @@ var quantity_detail = {
                     console.log(newNode.data.quantity);
                     this.updateBillQuantity(newNode.data.quantity,newNode,newNode.data.quantityEXP);
                 }else {//更新定额所使用的值要用还没转换前的
-                    this.updateRationQuantity(node.data.r_quantity,newNode,newNode.data.quantityEXP);
+                    node.data? this.updateRationQuantity(node.data.r_quantity,newNode,newNode.data.quantityEXP):"";
                 }
             }
         };
@@ -275,7 +282,7 @@ var quantity_detail = {
             return str.replace(regExp, RepText);
         };
         quantity_detail.prototype.updateQuantityDetail=function (args,dataCode,recode,selected,batchCallback) {
-            var doc ={};
+            var doc ={},me = this;
             var query={
                 ID:recode.ID,
                 projectID:recode.projectID
@@ -291,19 +298,21 @@ var quantity_detail = {
                 query.refreshQuantity=true;
                 if(!selected.data.hasOwnProperty('isFromDetail')||selected.data.isFromDetail==0){
                     if(!args.replace){//为了批量粘贴时不重复提示,普通编辑时不受影响
-                        var c = confirm("确定要使用工程量明细替换原工程量吗?");
-                        if(c){
+                        hintBox.infoBox('操作确认', '确定要使用工程量明细替换原工程量吗?', 2, function () {
                             args.replace = true;
-                        }else {
-                            this.cleanQuantityDetail(selected,true);
-                            return;
-                        }
+                            query.index = args.row;
+                            me.updateQuantityRegex(query,doc,args,batchCallback)
+                        }, function () {
+                            me.cleanQuantityDetail(selected,true);
+                        },['确定','取消']);
+                        return;
                     }
                 }
                 query.index = args.row;
-                this.updateQuantityRegex(query,doc,args,batchCallback)
+                me.updateQuantityRegex(query,doc,args,batchCallback);
+
             }else {
-                this.normalUpdate(query,doc,args,batchCallback);
+                me.normalUpdate(query,doc,args,batchCallback);
             }
         };
         quantity_detail.prototype.updateQuantityRegex=function(query,doc,args,batchCallback){
@@ -332,20 +341,28 @@ var quantity_detail = {
             var selected = projectObj.project.mainTree.selected;
             query.refreshQuantity=true;
             if(!selected.data.hasOwnProperty('isFromDetail')||selected.data.isFromDetail==0){
-                var c = confirm("确定要使用工程量明细替换原工程量吗?");
-                if(!c){
+                hintBox.infoBox('操作确认', '确定要使用工程量明细替换原工程量吗?', 2, function () {
+                    summationUpdate(args,detailList,newval,query);
+                }, function () {
                     query.refreshQuantity=false;
-                }
+                    summationUpdate(args,detailList,newval,query);
+                },['确定','取消']);
+                return;
             }
-            if(detailList[args.row].hasOwnProperty('rationID')){
-                query.rationID=detailList[args.row].rationID;
-            }else {
-                query.billID = detailList[args.row].billID
+            summationUpdate(args,detailList,newval,query);
+
+            function summationUpdate(args,detailList,newval,query) {
+                if(detailList[args.row].hasOwnProperty('rationID')){
+                    query.rationID=detailList[args.row].rationID;
+                }else {
+                    query.billID = detailList[args.row].billID
+                }
+                var doc={
+                    isSummation:newval
+                };
+                projectObj.project.quantity_detail.normalUpdate(query,doc);
             }
-            var doc={
-                isSummation:newval
-            };
-            this.normalUpdate(query,doc);
+
         };
         quantity_detail.prototype.commonUpdate = function (url,postData,args,batchCallback) {
             var me = this;
@@ -444,7 +461,7 @@ var quantity_detail = {
                 }
             }
             return invalidate;
-        }
+        };
 
         quantity_detail.prototype.replaceSqr = function(text) {
             var squarRegex = /\([^\^]+\)\^\d+/g;
@@ -511,7 +528,7 @@ var quantity_detail = {
         };
         quantity_detail.prototype.cleanQuantityDetail = function (node,needSave) {
            node =node?node:projectObj.project.mainTree.selected;
-           var query={projectID:node.data.projectID};
+           let query={projectID:node.data.projectID};
             if(node.sourceType === project.Bills.getSourceType()){
                 query.billID = node.data.ID;
                 this.deleteByBills([{type:'delete',data:node.data}]);
@@ -555,10 +572,12 @@ var quantity_detail = {
             if(option==false&&node.sourceType === project.Ration.getSourceType()&&EXPString!='GCLMXHJ'&&EXPString.indexOf("QDL")==-1&&data.unit){//勾选不根据单位转换工程量,且定额是手输的,
                 let times = parseInt(data.unit);
                 if(!isNaN(times)){///如果定额单位可以做转换
-                    if(isNum(EXPString)){//如果表达式中只是数字
-                        node.data.quantityEXP = EXPString+" * "+times;
-                    }else {//如果表达式是一个计算式,则要加一个括号
-                        node.data.quantityEXP = "("+EXPString+") * "+times;
+                    if(node.data.quantityEXP){
+                        if(isNum(EXPString)){//如果表达式中只是数字
+                            node.data.quantityEXP = EXPString+" * "+times;
+                        }else {//如果表达式是一个计算式,则要加一个括号
+                            node.data.quantityEXP = "("+EXPString+") * "+times;
+                        }
                     }
                     if(node.data.contain!=0){
                        let billQuantity = scMathUtil.roundForObj(node.parent.data.quantity,getDecimal("quantity",node.parent));
@@ -574,7 +593,7 @@ var quantity_detail = {
             if(node.sourceType === project.Ration.getSourceType()&&data.unit){
                 let times = parseInt(data.unit);
                 if (isNaN(times)) {
-                    times = 1
+                    times = 1;
                 }
                 value = value * times;
             }
@@ -587,22 +606,30 @@ var quantity_detail = {
                 projectObj.mainController.refreshTreeNode([node]);
             }else {
                 value=value?value:0;
-                setTimeout(function () {//spreadjs事件和提示窗口会有冲突,所以要用延时的方法
-                    if(project.quantity_detail.quantityEditChecking(value,node,fieldName)){
+                if(node.data.hasOwnProperty('isFromDetail')&&node.data.isFromDetail==1){
+                    hintBox.infoBox('操作确认', '已有工程量明细,是否清空明细表,采用手工输入的表达式?', 2, function () {
                         node.data.isFromDetail=0;
-                        project.quantity_detail.cleanQuantityDetail(node,true);
-                        if(node.sourceType === project.Bills.getSourceType()){
-                            me.updateBillQuantity(value,node,null,editingText);
-                        }else {
-                            me.updateRationQuantity(value,node,null,editingText);
-                        }
-                        gljOprObj.refreshView();
-                    }else {
+                        me.updateMainTreeNodeQuantity(value,node,editingText);
+                    }, function () {
                         projectObj.mainController.refreshTreeNode([node]);
-                    }
-                },100);
+                    },['确定','取消']);
+                    return;
+                }
+                me.updateMainTreeNodeQuantity(value,node,editingText);
+            }
+        };
+        quantity_detail.prototype.updateMainTreeNodeQuantity = function(value,node,editingText){
+            let me = this;
+            project.quantity_detail.cleanQuantityDetail(node,true);
+            if(node.sourceType === project.Bills.getSourceType()){
+                me.updateBillQuantity(value,node,null,editingText);
+            }else {
+                me.updateRationQuantity(value,node,null,editingText);
             }
+            gljOprObj.refreshView();
         };
+
+
         quantity_detail.prototype.updateBillQuantity=function (value,node,quantityEXP,editingText) {
             node.data.quantityEXP = quantityEXP?quantityEXP:editingText;
             value = scMathUtil.roundForObj(value,getDecimal("quantity",node));
@@ -646,14 +673,14 @@ var quantity_detail = {
             }
             if(needUpdateChildren.length>0){//清单下的定额工程量发生了改变
                 node.changed = true;//本身发生了改变,需要存储。
-                /*project.calcProgram.calcRationsAndSave(needUpdateChildren, function () {
+                /*project.calcProgram.calcNodesAndSave(needUpdateChildren, function () {
                     project.projectGLJ.loadData();
                 });*/
-                project.calcProgram.calcRationsAndSave(needUpdateChildren, function () {
+                project.calcProgram.calcNodesAndSave(needUpdateChildren, function () {
                     if(project.Bills.isFBFX(node)) { //判断是否属于分部分项工程 ,是的话才需要做计取安装费计算
                         project.installation_fee.calcInstallationFee(function (isChange,rations) {
                             if(isChange){
-                                project.calcProgram.calcRationsAndSave(rations,function () {
+                                project.calcProgram.calcNodesAndSave(rations,function () {
                                     project.projectGLJ.calcQuantity();
                                 });
                             }
@@ -691,7 +718,7 @@ var quantity_detail = {
                 if(project.Bills.isFBFX(node)) { //判断是否属于分部分项工程 ,是的话才需要做计取安装费计算
                     project.installation_fee.calcInstallationFee(function (isChange,rations) {
                         if(isChange){
-                            project.calcProgram.calcRationsAndSave(rations);
+                            project.calcProgram.calcNodesAndSave(rations);
                         }
                     });
                 }
@@ -706,7 +733,7 @@ var quantity_detail = {
             }else {
                 decimal = decimalObj.ration.quantity
             }
-            return;
+            return decimal;
         };
         return new quantity_detail(project);
     }

+ 30 - 36
web/building_saas/main/js/models/ration.js

@@ -424,7 +424,7 @@ var Ration = {
                 }
                 project.projectGLJ.loadData(function () {
                     gljOprObj.showDataIfRationSelect(projectObj.project.mainTree.selected,"-111111111");//这里第二个参数是为了使改前和改后selectedID不一样,删除了的话下方的定额工料机不会刷新
-                    project.calcProgram.calcRationsAndSave(refershNodes);
+                    project.calcProgram.calcNodesAndSave(refershNodes);
                     projectObj.mainController.refreshTreeNode(refershNodes, true);
                     $.bootstrapLoading.end();
                 });
@@ -524,9 +524,9 @@ var Ration = {
                             project.installation_fee.calcInstallationFee(function (isChange,rations) {
                                 if(isChange){
                                     rations = rations.concat(newNodes);
-                                    project.calcProgram.calcRationsAndSave(rations);
+                                    project.calcProgram.calcNodesAndSave(rations);
                                 }else {
-                                    project.calcProgram.calcRationsAndSave(newNodes);
+                                    project.calcProgram.calcNodesAndSave(newNodes);
                                 }
                             });
                         }else {
@@ -550,14 +550,14 @@ var Ration = {
             let needInstall = false;
             if (selected === null) { return; }
             if (selected.sourceType === project.Bills.getSourceType() && selected.depth() > 0) {
-                if (selected.source.children.length > 0) {
+                if(selected.data.type === billType.FB){
+                    return;
+                }
+                else if (selected.source.children.length > 0) {
                     alert('当前清单已有清单子项,不能套用定额。');
                 } else if (selected.data.calcBase&&selected.data.calcBase!="") {
                     alert('当前有基数计算不能插入定额/量价/工料机。');
                 } else {
-                    if(selected.data.type === billType.FB){
-                        return;
-                    }
                     billItemID = selected.source.getID();
                     nextID = selected.tree.rootID();
                     br = this.getBillsSortRation(billItemID);
@@ -604,28 +604,11 @@ var Ration = {
                     project.projectGLJ.loadData(function () {
                         project.ration_glj.addToMainTree(data.ration_gljs);
                         projectObj.mainController.refreshTreeNode([newNode], false);
-                        if(project.Bills.isFBFX(newNode)) { //判断是否属于分部分项工程 ,是的话才需要做计取安装费计算
-                           // let changeNodes = project.calcProgram.calculate(newNode);//先计算不保存,如果计算安装增加费后不用自动计算,则单独调用保存的方法
-                            project.installation_fee.calcInstallationFee(function (isChange,rations) {
-                                if(isChange){
-                                    rations.push(newNode);
-                                    project.calcProgram.calcRationsAndSave(rations);
-                                }else {
-                                    project.calcProgram.calcRationsAndSave([newNode]);
-                                }
-                            });
-                        }else {
-                            project.calcProgram.calcAndSave(newNode);
-                        }
-                     /*   project.calcProgram.calcAndSave(newNode,function () {
+                        project.calcProgram.calcAndSave(newNode,function () {
                             if(project.Bills.isFBFX(newNode)) { //判断是否属于分部分项工程 ,是的话才需要做计取安装费计算
-                                project.installation_fee.calcInstallationFee(function (isChange) {
-                                    if(isChange){
-                                        project.calcProgram.calcAllNodesAndSave();
-                                    }
-                                });
+                                installationFeeObj.calcInstallationFee();
                             }
-                        });*/
+                        });
                         $.bootstrapLoading.end();
                     });
                 })
@@ -670,39 +653,50 @@ var Ration = {
             this.project.endUpdate();
         };
         ration.prototype.updateContain=function (value,node) {
+            let me = this;
             if(isNaN(value)){
                 alert("当前输入的数据类型不正确,请重新输入");
                 projectObj.mainController.refreshTreeNode([node]);
                 return;
             }
-            let billNode = node.parent;
-            let contain = scMathUtil.roundForObj(value,getDecimal("process"));
+
             if(node.data.quantityEXP=="GCLMXHJ"){//如果定额工程量是来自工程量明细
-                var c = confirm('已有工程量明细,是否清空明细表,采用手工输入的表达式?');
-                if(c){
+                hintBox.infoBox('操作确认', '已有工程量明细,是否清空明细表,采用手工输入的表达式?', 2, function () {
                     node.data.isFromDetail=0;
                     project.quantity_detail.cleanQuantityDetail(node,true);
-                }else {
+                    me.doContainUpdate(value,node);
+                }, function () {
                     projectObj.mainController.refreshTreeNode([node]);
-                    return;
-                }
+                },['确定','取消']);
+            }else {
+                me.doContainUpdate(value,node);
             }
+
+        };
+        ration.prototype.doContainUpdate = function (value,node) {
+
+            let billNode = node.parent;
+            let contain = scMathUtil.roundForObj(value,getDecimal("process"));
             let billQuantity = billNode.data.quantity||billNode.data.quantity!=""?billNode.data.quantity:0;
             billQuantity = parseFloat(billQuantity);
             node.data.contain = contain;
             node.data.quantityEXP="QDL*"+contain;
             node.data.quantity=scMathUtil.roundForObj(billQuantity*contain,getDecimal("quantity",node));
-            let times = parseInt(node.data.unit)
+            let times = parseInt(node.data.unit);
             if (!isNaN(times)) {
                 node.data.quantityEXP+='*'+times;
             }
-          //  node.data.quantity = projectObj.project.quantity_detail.autoTransformQuantity(node.data.quantity,node);//按单位做转换
+            //  node.data.quantity = projectObj.project.quantity_detail.autoTransformQuantity(node.data.quantity,node);//按单位做转换
             node.changed = true;
             project.calcProgram.calcAndSave(node, function () {
                 project.projectGLJ.calcQuantity();
             });
             projectObj.mainController.refreshTreeNode(node.children);//刷新子工料机树节点总消耗量
+
+
+
         };
+
         ration.prototype.addRationChecking=function(selected){
             if (selected) {// Vincent, 2018-01-02
                 if(selected.sourceType === project.Ration.getSourceType()){ // 焦点行是定额/量价/工料机,有效显示。

+ 4 - 3
web/building_saas/main/js/models/ration_glj.js

@@ -278,6 +278,9 @@ var ration_glj = {
                     projectObj.mainController.deleteNode(node, next);
                 }
             }
+            project.calcProgram.calcAndSave(rationNode,function () {
+                installationFeeObj.calcInstallationFee();
+            });
         };
         // CSL,2017.05.09
         ration_glj.prototype.modifyQuantity = function (data, newQuantity) {
@@ -446,6 +449,7 @@ var ration_glj = {
                         gljOprObj.refreshView();
                     }
                     $.bootstrapLoading.end();
+                    installationFeeObj.calcInstallationFee();
                 });
             }
             var query = {
@@ -752,7 +756,6 @@ var ration_glj = {
         ration_glj.prototype.transferToNodeData = function (data) {
             data.contain=scMathUtil.roundForObj(data.quantity,getDecimal('glj.quantity'));
             data.subType = data.type;
-            data.marketUnitFee = data.marketPrice;
         };
         ration_glj.prototype.combineRationAndGLJ = function (ration) {
             if (ration) {
@@ -765,8 +768,6 @@ var ration_glj = {
                         ration.isEstimate = glj.is_evaluate;
                     }
                     ration = gljOprObj.setGLJPrice(ration,glj);
-                    ration.basePrice = glj.unit_price.base_price;
-                    ration.marketUnitFee = glj.unit_price.market_price;
                     ration.isAdd = glj.unit_price.is_add;
                     var connect_index = gljOprObj.getIndex(glj, gljKeyArray);
                     if (mixRatioMap.hasOwnProperty(connect_index)) {

+ 70 - 55
web/building_saas/main/js/views/character_content_view.js

@@ -29,6 +29,7 @@ let contentOprObj = {
         sheet.bind(EVENTS.ClipboardPasting, me.onClipboardPasting);
         sheet.bind(EVENTS.ClipboardPasted, me.onClipboardPasted);
         sheet.bind(EVENTS.SelectionChanged, me.onSelectionChanged);
+        workBook.bind(EVENTS.RangeChanged, me.onRangeChanged);
         me.bindTools();
     },
     bindTools: function () {
@@ -202,6 +203,24 @@ let contentOprObj = {
             args.sheet.setValue(args.row, args.col, 0);
         }
     },
+    onRangeChanged: function (sender, args) {
+        let me = contentOprObj;
+        let rangeCell = isDef(args.changedCells[0]) ? args.changedCells[0] : null;
+        if(!rangeCell){
+            return;
+        }
+        let rangeData = isDef(me.currentCache[rangeCell.row]) ? me.currentCache[rangeCell.row] : null;
+        if(!rangeData){
+            return;
+        }
+        if(rangeCell.col === 0){//工作内容
+            me.updateContent(rangeData, '');
+        }
+        else if(rangeCell.col === 1){//输出
+            rangeData.isChecked = false;
+            me.save();
+        }
+    },
     //复制粘贴
     onClipboardPasting: function (sender, args) {
         if(projectInfoObj.projectInfo.property.lockBills){
@@ -232,6 +251,7 @@ let contentOprObj = {
     initSelection: function (row) {
         let me = contentOprObj;
         let disObj = {jobAdd: false, jobInsert: true, jobDel: true, jobUp: true, jobDown: true};
+        disObj.jobAdd = !pageCCOprObj.canAddType();
         if(projectInfoObj.projectInfo.property.lockBills){
             disObj.jobAdd = true;
             disObj.jobInsert = true;
@@ -286,7 +306,7 @@ let contentOprObj = {
                 //控制允许右键菜单在哪个位置出现
                 let target = SheetDataHelper.safeRightClickSelection($triggerElement, e, me.workBook);
                 let sheet = me.workBook.getSheet(0);
-                let addDis = pageCCOprObj.isBillsType() ? false : true,  insertDis = false, delDis = false, upDis = false, downDis = false;
+                let addDis = pageCCOprObj.canAddType() ? false : true,  insertDis = false, delDis = false, upDis = false, downDis = false;
                 if(target.hitTestType === 3){//在表格内&& typeof target.row !== 'undefined' && typeof target.col !== 'undefined'
                     //清单锁定,不可用
                     if(projectInfoObj.projectInfo.property.lockBills){
@@ -581,27 +601,32 @@ let characterOprObj = {
     },
     updateCharacter: function (item, character, value) {
         let me = characterOprObj;
-        if(character){
+        if(character !== null){
             item.character = character;
         }
-        if(value){
-            let isExist = false;
-            for(let i = 0, len = item.eigenvalue.length; i < len; i++){
-                if(item.eigenvalue[i].value === value){
-                    isExist = true;
-                    break;
+        if(value !== null){
+            if(value !== ''){
+                let isExist = false;
+                for(let i = 0, len = item.eigenvalue.length; i < len; i++){
+                    if(item.eigenvalue[i].value === value){
+                        isExist = true;
+                        break;
+                    }
+                }
+                //不存在,新增进eigenvalue,自动打勾输出
+                if(!isExist){
+                    //更新selected
+                    me.insertValue(item, value);
+                    item.isChecked = true;
+                }
+                //存在,选择特征值,自动打勾输出
+                else{
+                    me.changeSelected(item, value);
+                    item.isChecked = true;
                 }
             }
-            //不存在,新增进eigenvalue,自动打勾输出
-            if(!isExist){
-                //更新selected
-                me.insertValue(item, value);
-                item.isChecked = true;
-            }
-            //存在,选择特征值,自动打勾输出
-            else{
-                me.changeSelected(item, value);
-                item.isChecked = true;
+            else {
+                me.unsetSelected(item);
             }
         }
         me.save();
@@ -633,33 +658,15 @@ let characterOprObj = {
     onEditEnded: function (sender, args) {
         let me = characterOprObj, characterTxt;
         let preObj = me.currentCache.length > 0 ?  me.currentCache[me.currentCache.length - 1] : null;
-        if(args.editingText && args.editingText.toString().trim().length > 0){
-            //更新
-            if(args.row < me.currentCache.length){
-                let thisCha = me.currentCache[args.row];
-                if(args.col === 0){//特征
-                   me.updateCharacter(thisCha, args.editingText, null);
-                }
-                else if(args.col === 1){//特征值
-                    me.updateCharacter(thisCha, null, args.editingText);
-                }
-            }
-            /*//新增
-            else{
-                if(args.col === 0){//特征
-                    me.insertCharacter(args.editingText, null);
-                }
-                else if(args.col === 1){//特征值
-                    me.insertCharacter(null, args.editingText);
-                }
-            }*/
-        }
-        else{//恢复
-            if(args.col === 0){
-                args.sheet.setValue(args.row, args.col, me.currentCache.length > args.row ? me.currentCache[args.row].character + '' : '');
+        args.editingText = args.editingText ? args.editingText : '';
+        //更新
+        if(args.row < me.currentCache.length){
+            let thisCha = me.currentCache[args.row];
+            if(args.col === 0){//特征
+                me.updateCharacter(thisCha, args.editingText, null);
             }
-            else if(args.col === 1){
-                args.sheet.setValue(args.row, args.col, me.currentSelectedValue ? me.currentSelectedValue + '' : '');
+            else if(args.col === 1){//特征值
+                me.updateCharacter(thisCha, null, args.editingText);
             }
         }
     },
@@ -696,13 +703,23 @@ let characterOprObj = {
         if(!rangeData){
             return;
         }
-        if(rangeCell.col === 1){//特征值
+        if(rangeCell.col === 0){//特征
+            me.updateCharacter(rangeData, '', null);
+        }
+        else if(rangeCell.col === 1){//特征值
+            me.updateCharacter(rangeData, null, '');
+        }
+        else if(rangeCell.col === 2){
+            rangeData.isChecked = false;
+            me.save();
+        }
+        /*if(rangeCell.col === 1){//特征值
             rangeData.isChecked = false;
             for(let value of rangeData.eigenvalue){
                 value.isSelected = false;
             }
-        }
-        me.save();
+        }*/
+        //me.save();
     },
     //复选框控制输出
     onButtonClicked: function (sender, args) {
@@ -731,12 +748,9 @@ let characterOprObj = {
         }
     },
     initSelection: function (row) {
-        console.log('enter');
         let me = characterOprObj;
         let disObj = {itemAdd: false, itemInsert: true, itemDel: true, itemUp: true, itemDown: true};
-        if(projectObj.project.mainTree.selected.sourceType !== projectObj.project.Bills.getSourceType()){
-            disObj.itemAdd = true;
-        }
+        disObj.itemAdd = !pageCCOprObj.canAddType();
         //清单锁定,不可用
         if(projectInfoObj.projectInfo.property.lockBills){
             disObj.itemAdd = true;
@@ -780,7 +794,7 @@ let characterOprObj = {
                 //控制允许右键菜单在哪个位置出现
                 let target = SheetDataHelper.safeRightClickSelection($triggerElement, e, me.workBook);
                 let sheet = me.workBook.getSheet(0);
-                let addDis = pageCCOprObj.isBillsType() ? false : true, insertDis = false, delDis = false, upDis = false, downDis = false;
+                let addDis = pageCCOprObj.canAddType() ? false : true, insertDis = false, delDis = false, upDis = false, downDis = false;
                 if(target.hitTestType === 3){//在表格内 && typeof target.row !== 'undefined' && typeof target.col !== 'undefined'
                     //清单锁定,则不可用
                     if(projectInfoObj.projectInfo.property.lockBills){
@@ -866,11 +880,12 @@ let pageCCOprObj = {
             item.serialNo = count++;
         }
     },
-    //获得造价书当前焦点行的类型:清单、定额
-    isBillsType: function () {
+    //可以添加的类型:分项、补项、清单
+    canAddType: function () {
         let rst = false;
         let selectedNode = projectObj.mainController.tree.selected;
-        if(selectedNode && selectedNode.sourceType === projectObj.project.Bills.getSourceType()){//为清单
+        if(selectedNode && selectedNode.sourceType === projectObj.project.Bills.getSourceType() &&
+            (selectedNode.data.type === billType.FX || selectedNode.data.type === billType.BX || selectedNode.data.type === billType.BILL)){//为清单
             rst = true
         }
         return rst;

+ 42 - 26
web/building_saas/main/js/views/glj_view.js

@@ -355,14 +355,12 @@ var gljOprObj = {
             args.editingText = args.editingText.replace(/(/g, "(");//替换中文左右括号;
             args.editingText = args.editingText.replace(/)/g, ")");
         }
-        setTimeout(function () {//这里须用延时执行的办法,不然的弹窗确认窗口会和spreadjs 的事件有冲突,造成定额工料机数据不会根据树结点更新的问题
-            if (args.row == detailList.length) {
-                projectObj.project.quantity_detail.saveQuantityDetail(args, me.detailSetting.header[args.col].dataCode, selected,callback);
-            }
-            if (args.row < detailList.length) {
-                projectObj.project.quantity_detail.updateQuantityDetail(args, me.detailSetting.header[args.col].dataCode, detailList[args.row], selected,callback);
-            }
-        }, 100);
+        if (args.row == detailList.length) {
+            projectObj.project.quantity_detail.saveQuantityDetail(args, me.detailSetting.header[args.col].dataCode, selected,callback);
+        }
+        if (args.row < detailList.length) {
+            projectObj.project.quantity_detail.updateQuantityDetail(args, me.detailSetting.header[args.col].dataCode, detailList[args.row], selected,callback);
+        }
 
     },
     onEditGLJSheet: function (args) {
@@ -752,6 +750,7 @@ var gljOprObj = {
         data.marketPrice = result.marketPrice;
         data.basePrice =  result.basePrice;
         data.adjustPrice = result.adjustPrice;
+        data.marketUnitFee = data.marketPrice;//更新树节点市场单价列的值
         return data;
 
     },
@@ -943,6 +942,8 @@ var gljOprObj = {
         }
         if ($('#actionType').val() == 'replace' || $('#actionType').val() == 'm_replace') {
             me.filterLibGLJByType();
+        }else if($('#actionType').val() == 'addMix'){
+            projectGljObject.filterLibGLJForMixRatio();
         }
         //文本筛选
         let searchStr = $('#gljSearchKeyword').val();
@@ -964,7 +965,7 @@ var gljOprObj = {
         }
     },
     setGLJSelection: function (args, newVal) {
-        if ($('#actionType').val() == 'add' || $('#actionType').val() == 'insert') {
+        if ($('#actionType').val() == 'add' || $('#actionType').val() == 'insert'|| $('#actionType').val() == 'addMix') {
             this.addGLJsSelection(args, newVal);
         } else {
             this.replaceGLJSelection(args, newVal);
@@ -1060,7 +1061,6 @@ var gljOprObj = {
             project.projectGLJ.loadData(function () {
                 for(let r_glj of data){
                     r_glj = me.setGLJPrice(r_glj);//设置工料机价格
-                    r_glj.marketUnitFee = r_glj.marketPrice;
                     newNode = project.mainTree.insert(parentNodeID, nextNodeID, r_glj.ID);
                     newNode.source = r_glj;
                     newNode.sourceType = project.Ration.getSourceType();
@@ -1177,7 +1177,7 @@ var gljOprObj = {
             project.projectGLJ.loadData(function () {
                 me.showRationGLJSheetData();
                 var rationNodes = me.refreshStateAfterMreplace(stateList, nodes);
-                project.calcProgram.calcRationsAndSave(rationNodes);
+                project.calcProgram.calcNodesAndSave(rationNodes);
                 $.bootstrapLoading.end();
             });
         })
@@ -1205,7 +1205,9 @@ var gljOprObj = {
         return rationNodes;
     },
     refreshView: function () {
-        this.showRationGLJData();
+        let node = projectObj.project.mainTree.selected;
+        this.showDataIfRationSelect(node,"111111");
+        //this.showRationGLJData();
     },
     //
     refreshTreeNode: function (obj) {
@@ -1309,7 +1311,11 @@ var gljOprObj = {
                     offset = drowSubItem(ctx, x, y, w, h, offset, data[options.row + 1]);
                     offset += 1;
                 }
-                ctx.fillText(value, x + offset + ctx.measureText(value).width, y + h - 5);
+                arguments[2] = x + offset;
+                arguments[4] = w - offset;
+                //x = x + offset;
+                //w = w - offset;
+                GC.Spread.Sheets.CellTypes.Text.prototype.paint.apply(this, arguments);
             }
         };
         // override getHitInfo to allow cell type get mouse messages
@@ -1363,23 +1369,31 @@ $(function () {
             gljOprObj.gljLibSheet.name('glj_lib');
         }
         gljOprObj.gljLibSheetData = gljOprObj.AllRecode;
-        var selected = null;
-        if ($('#actionType').val() == 'add' || $('#actionType').val() == 'insert') {
+        let selections = [],selectMap = {};
+        if ($('#actionType').val() == 'add' || $('#actionType').val() == 'insert') {//插入,添加
             gljOprObj.GLJSelection = [];
-        } else {
-            selected = gljOprObj.sheetData[gljContextMenu.selectedRow];
+        } else if($('#actionType').val() =='m_replace' || $('#actionType').val() == 'replace'){//替换、批量替换
+            let selected = gljOprObj.sheetData[gljContextMenu.selectedRow];
             var connect_key = gljOprObj.getIndex(selected, gljKeyArray);
             gljOprObj.GLJSelection = [connect_key];
+            selectMap[connect_key] = true;
             gljOprObj.filterLibGLJByType();
-        }
-
-        if (selected != null) {
-            var s_key = gljOprObj.getIndex(selected, gljLibKeyArray);
-            var r = _.find(gljOprObj.gljLibSheetData, function (item) {
-                var item_key = gljOprObj.getIndex(item, gljKeyArray);
-                return s_key == item_key;
-            });
-            r ? r.select = 1 : "";
+        }else if($('#actionType').val() =='addMix'){//添加组成物
+            gljOprObj.GLJSelection = [];
+            projectGljObject.filterLibGLJForMixRatio();
+            /*selections = projectGljObject.mixRatioData;  添加组成物的时候先不选中
+            gljOprObj.GLJSelection = [];
+            for(let s of selections){
+                let s_key = gljOprObj.getIndex(s, gljKeyArray);
+                selectMap[s_key] = true;
+                gljOprObj.GLJSelection.push(s_key);
+            }*/
+        }
+        for(let item of gljOprObj.gljLibSheetData){
+            let item_key = gljOprObj.getIndex(item, gljLibKeyArray);
+            if(selectMap[item_key]){
+                item.select = 1 ;
+            }
         }
         gljOprObj.showLibGLJSheetData();
     });
@@ -1424,6 +1438,8 @@ $(function () {
             gljOprObj.doReplaceGLJ();
         } else if ($('#actionType').val() == 'm_replace') {//批量替换工料机
             gljOprObj.doMReplaceGLJ();
+        }else if($('#actionType').val() == 'addMix'){
+            projectGljObject.addMixRatio();
         }
     })
 

+ 69 - 28
web/building_saas/main/js/views/installation_fee_view.js

@@ -271,6 +271,7 @@ let installationFeeObj={
                 me.showFeeDetailData();
             }
         }
+        me.feeItemSheet.repaint();
     },
     onFeeDetailSelectionChange:function (e,info) {
         console.log('detail selection change');
@@ -326,6 +327,24 @@ let installationFeeObj={
         info.newValue = newval;
         me.onFeeItemValueChange(e,info);
     },
+    refreshView:function () {
+        if(this.feeItemSpread == null){
+            this.initInstallationFeeSpread();
+        }else {
+            let sel_f = this.feeItemSheet.getSelections()[0];
+            let sel_d = this.feeDetailSheet.getSelections()[0];
+            this.showFeeItemData();
+            this.feeItemSheet.setSelection(sel_f.row ==-1?0:sel_f.row,sel_f.col,sel_f.rowCount,sel_f.colCount);
+            let oldData = sel_f.row<this.feeItemData.length?this.feeItemData[sel_f.row]:null;
+            if(oldData){
+                this.showFeeDetailData(oldData.libID,oldData.ID);
+            }else {
+                this.showFeeDetailData();
+            }
+            this.feeDetailSheet.setSelection(sel_d.row ==-1?0:sel_d.row,sel_d.col,sel_d.rowCount,sel_d.colCount);
+        }
+
+    },
     showFeeItemData:function () {
         this.feeItemData = this.getFeeItemData(projectObj.project.installation_fee.datas);
         this.feeItemSheet.setRowCount(0);
@@ -338,6 +357,7 @@ let installationFeeObj={
                 this.feeItemSheet.getRange(i,-1, 1, -1, GC.Spread.Sheets.SheetArea.viewport).locked(true);//this.feeItemSheet.getCell(i, 2).locked(true);
                 this.feeItemSheet.getRange(i,2,1,2).cellType(new GC.Spread.Sheets.CellTypes.Text());//费用类型、记取位置两列替换成普通的单元格;
             }
+            this.positionButtonChecking(i,data);
         }
 
     },
@@ -716,8 +736,11 @@ let installationFeeObj={
         }else if(selectedItem.feeType=='分项费用'){
             rootNode = project.Bills.getFBFXNode(controller);
         }
-        allNodes.push(rootNode);
-        controller.tree.getAllSubNode(rootNode.source,allNodes);
+        if(rootNode){
+            allNodes.push(rootNode);
+            controller.tree.getAllSubNode(rootNode.source,allNodes);
+        }
+
         for(let n of allNodes){
             let temData = {
                 ID:n.data.ID,
@@ -796,7 +819,7 @@ let installationFeeObj={
                     me.refreshRationInstallationRow(me.rationInstallSheet.getSelections()[0].row);
                     installation_fee.calcInstallationFee(function (isChange,rations) {
                         if(isChange){
-                            projectObj.project.calcProgram.calcRationsAndSave(rations);
+                            projectObj.project.calcProgram.calcNodesAndSave(rations);
                         }
                     });
                 });
@@ -834,7 +857,7 @@ let installationFeeObj={
             me.refreshRationInstallationRow(riselection.row);
             installation_fee.calcInstallationFee(function (isChange,rations) {
                 if(isChange){
-                    projectObj.project.calcProgram.calcRationsAndSave(rations);
+                    projectObj.project.calcProgram.calcNodesAndSave(rations);
                 }
             });
         });
@@ -925,13 +948,15 @@ let installationFeeObj={
         let dataArray = [];
         let impacRules = projectObj.project.installation_fee.getFeeRuleByFeeItem(feeItem);
         for(let ir of impacRules){
-            let tem_data = {
-                ID:feeItem.installFeeID,
-                itemID:ir.ID,
-                type:'feeRule',
-                doc:{position: recode.code, billID:recode.ID}
-            };
-            dataArray.push(tem_data);
+            if(ir.position !=recode.code || ir.billID != recode.ID){
+                let tem_data = {
+                    ID:feeItem.installFeeID,
+                    itemID:ir.ID,
+                    type:'feeRule',
+                    doc:{position: recode.code, billID:recode.ID}
+                };
+                dataArray.push(tem_data);
+            }
         }
         return [dataArray,impacRules]
     },
@@ -962,12 +987,36 @@ let installationFeeObj={
         }
         projectObj.project.installation_fee.updateFeeItem(doc,feeItem.libID,feeItem.ID,cleanPosition,function () {
             me.feeItemSheet.getCell(info.row, info.col).value(info.newValue);
+            me.positionButtonChecking(info.row,feeItem);
             if(cleanPosition==true){
                 me.feeItemSheet.getCell(info.row, info.col+1).value("");
                 me.showFeeDetailData(feeItem.libID,feeItem.ID);
             }
         });
     },
+    cleanPositionIfNeed:function (settingVal) {
+         let me = this;
+         let updateData = [];
+         let installation_fee = projectObj.project.installation_fee;
+         if(settingVal == 1){//分项费用选为“每个分部单独计取”时,分项费用类型的记取位置应自动清空。
+              for(let item of me.feeItemData){
+                  if(item.feeType == '分项费用'){
+                      if((item.position&&item.position!='')||(item.billID&&item.billID!='')){
+                          updateData.push(installation_fee.getFeeItemUpdateData(item.libID,item.ID,{position:'', billID:''}));
+                      }
+                      let [dataArray,impacRules] = me.getFeeRuleUpdateDataByFeeItem(item,{code: "",ID:''});
+                      dataArray.length >0? updateData = updateData.concat(dataArray):'';
+                  }
+              }
+         }
+        console.log(updateData);
+         if(updateData.length > 0){
+             installation_fee.updateInstallation(updateData,function () {
+                 me.refreshView();
+             })
+         }
+
+    },
     onRationInstallValueChange:function (e,info) {
         let me = installationFeeObj;
         let installation_fee = projectObj.project.installation_fee
@@ -1244,7 +1293,7 @@ let installationFeeObj={
         $('#calc_installation_fee').modal('hide');
         install_fee.calcInstallationFee(function (isChange,rations) {
             if(isChange){
-                projectObj.project.calcProgram.calcRationsAndSave(rations);
+                projectObj.project.calcProgram.calcNodesAndSave(rations);
             }
             installationFeeObj.showRationInstallationData(projectObj.project.mainTree.selected);
             if(callback){
@@ -1298,25 +1347,17 @@ let installationFeeObj={
             //计算安装增加费
             projectObj.project.installation_fee.calcInstallationFee(function (isChange,rations) {
                 if(isChange){
-                    projectObj.project.calcProgram.calcRationsAndSave(rations);
+                    projectObj.project.calcProgram.calcNodesAndSave(rations);
                 }
             });
         })
     },
-    getRationByParentID:function () {
-
-    }
 };
 
 
 $(function () {
     $('#calc_installation_fee').on('shown.bs.modal',function () {
-        if(installationFeeObj.feeItemSpread == null){//初始化显示
-            installationFeeObj.initInstallationFeeSpread();
-        }else {
-            installationFeeObj.showFeeItemData();
-            installationFeeObj.showFeeDetailData();
-        }
+        installationFeeObj.refreshView();
         //radio 值设置
         installationFeeObj.initSettingRadio();
 
@@ -1370,13 +1411,12 @@ $(function () {
             return;
         }
         me.calcInstallationFee(function () {
-
+            gljOprObj.refreshView();
         });
     });
     $('#btn_reset_to_default').click(function (){
         let ifModel =  projectObj.project.installation_fee;
-        let c = confirm("确定恢复系统默认值吗?");
-        if(c){
+        hintBox.infoBox('操作确认', '确定恢复系统默认值吗?', 2, function () {
             ifModel.resetToDefault(function () {
                 installationFeeObj.showFeeItemData();
                 installationFeeObj.showFeeDetailData();
@@ -1384,9 +1424,9 @@ $(function () {
             ifModel.updateInstallSetting("0",function () {
                 installationFeeObj.initSettingRadio();
             });
-        }
-      /*  installationFeeObj.showFeeItemData();
-        installationFeeObj.showFeeDetailData();*/
+        }, function () {
+
+        },['确定','取消']);
     });
 
     $("input[name='install_setting_radios']").each(function(){
@@ -1397,6 +1437,7 @@ $(function () {
                 return;
             }
             projectObj.project.installation_fee.updateInstallSetting(settingVal);
+            installationFeeObj.cleanPositionIfNeed(settingVal);
         });
     });
 

+ 116 - 43
web/building_saas/main/js/views/project_glj_view.js

@@ -26,7 +26,8 @@ projectGljObject={
             {headerName: "三材系数", headerWidth: 100, dataCode: "materialCoe", hAlign: "right", dataType: "Number",validator:"number"},//,decimalField:'material'
             {headerName: "交货方式", headerWidth: 90, dataCode: "delivery", hAlign: "left", dataType: "String"},
             {headerName: "送达地点", headerWidth: 100, dataCode: "delivery_address", hAlign: "left", dataType: "String"},
-            {headerName: "不调价", headerWidth: 55, dataCode: "is_adjust_price", dataType: "String",cellType: "checkBox"}
+            {headerName: "不调价", headerWidth: 55, dataCode: "is_adjust_price", dataType: "String",cellType: "checkBox"},
+            {headerName: "备注", headerWidth: 100, dataCode: "remark", hAlign: "left", dataType: "String"}
         ],
         view: {
             lockColumns: [0,1,2,3,4,5,7]
@@ -137,13 +138,53 @@ projectGljObject={
     getUsedTenderInfo:function() {
         return projectGljObject.usedTenderList.join("<br>");
     },
+    filterLibGLJForMixRatio:function () {
+        let me = this;
+        if(me.selectedProjectGLJ){
+            let showTypes = [];
+            let materialArr = [202, 203, 204];//混凝土、砂浆、配合比,
+            if(me.selectedProjectGLJ.type == gljType.MAIN_MATERIAL){//对于主材,只显示没有组成物并且除了自已的主材
+                showTypes = [gljType.MAIN_MATERIAL];
+            }else if(_.includes(materialArr,me.selectedProjectGLJ.type)){//混凝土、砂浆、配合比
+                showTypes = [gljType.GENERAL_MATERIAL];
+            }else if(me.selectedProjectGLJ.type == gljType.GENERAL_MACHINE){//机械类型可添加机械组成物、机上人工
+                showTypes = [gljType.MACHINE_COMPOSITION,gljType.MACHINE_LABOUR];
+            }
+            gljOprObj.gljLibSheetData = _.filter(gljOprObj.gljLibSheetData, function (item) {
+                if(me.selectedProjectGLJ.type == gljType.MAIN_MATERIAL){
+                    let p_index = gljOprObj.getIndex(me.selectedProjectGLJ,gljKeyArray);
+                    let i_index = gljOprObj.getIndex(item,gljLibKeyArray);
+                    return item.gljType == gljType.MAIN_MATERIAL &&item.component.length == 0 && p_index!=i_index
+                }else {
+                    return _.includes(showTypes,item.gljType);
+                }
+            });
+        }
+    },
+    addMixRatio:function () {
+        let me = this, projectGLJ = projectObj.project.projectGLJ;
+        for(let mix of me.mixRatioData){
+            let m_key = gljOprObj.getIndex(mix, gljKeyArray);
+            let t_index = gljOprObj.GLJSelection.indexOf(m_key);
+            t_index != -1?gljOprObj.GLJSelection.splice(t_index,1):'';
+        }
+        projectGLJ.addMixRatio(gljOprObj.GLJSelection,function (mixRatios) {
+            me.showMixRatioData();//这里添加的组成物的消耗量默认都是0,所以对父工料机的价格不会有影响,不用触发计算
+            projectGLJ.loadData(function () {
+                me.showProjectGljData();
+                gljOprObj.showRationGLJSheetData();
+                me.onUnitFileChange(me.selectedProjectGLJ);
+            });
+
+        });
+    },
     showMixRatioData:function () {
         let me = this,gljId = null,gljType = null;
         let sheet = me.projectGljSpread.getActiveSheet();
         let oldSel = me.mixRatioSheet.getSelections()[0];
         if(sheet.name() == 'projectGljSheet'){//projectGljSheet/materialSheet 工料机汇总和三材汇总表
             let sel = me.projectGljSheet.getSelections()[0];
-            let srow = sel.row == -1?0:sel.row;
+            let srow = sel.row == -1||sel.row == ""?0:sel.row;
             if(me.projectGljSheetData.length>srow){
                 gljId = me.projectGljSheetData[srow].id;
                 gljType = me.projectGljSheetData[srow].type;
@@ -219,7 +260,7 @@ projectGljObject={
         }
         if(dataCode=='basePrice'||dataCode=='marketPrice'||dataCode=='supply'){//有组成物时,市场单价、定额价、供货方式不能修改
             if (data.ratio_data  && data.ratio_data.length > 0){
-               return false;
+                return false;
             }
             if(dataCode=='basePrice'&&data.is_add!=1){//如果不是新增,定额价不可修改。
                 return false;
@@ -227,11 +268,11 @@ projectGljObject={
         }
         if(dataCode == 'supply_quantity'){
             if (data.supply != 1) {// 如果为部分甲供则甲供数量需要可编辑,其它的都不能编辑
-               return false;
+                return false;
             }
         }
         if(dataCode == 'materialCoe'){//三材类别为空时,三材系数应只读,不允许输入。
-            if(data.materialType == undefined || data.materialType == null){
+            if(data.materialType == undefined || data.materialType == null||data.materialType==''){
                 return false;
             }
         }
@@ -270,7 +311,7 @@ projectGljObject={
             changeInfo.push({row:c.row,col:c.col,value:value});
             if(me.projectGljEditChecking(c.row,c.col)==false){//如果不能编辑
                 canChange = false;
-             }
+            }
             if (canChange==true&&!me.checkData(c.col,me.projectGljSetting,value)) {
                 alert('输入的数据类型不对,请重新输入!');
                 canChange = false;
@@ -279,7 +320,7 @@ projectGljObject={
         if(canChange == false){//恢复原来的值
             info.sheetName =="materialTreeSheet"?me.showMaterialTreeData():me.showProjectGljData();
         }else if(info.sheetName =="projectGljSheet"){
-             me.batchUpdatePrice(changeInfo);
+            me.batchUpdatePrice(changeInfo);
         }
     },
     batchUpdatePrice(changeInfo){
@@ -294,7 +335,7 @@ projectGljObject={
     showProjectGljData:function () {
         this.projectGljSpread.setActiveSheetIndex(0);
         let sel = this.projectGljSheet.getSelections()[0];
-        let oldData = sel.row<this.projectGljSheetData.length?this.projectGljSheetData[sel.row]:'';
+        let oldData = sel.row<this.projectGljSheetData.length?this.projectGljSheetData[sel.row]:"";
         let projectGljSheetData = [];
         let gljList = projectObj.project.projectGLJ.datas.gljList;
         gljList = this.filterProjectGLJ(gljList);
@@ -306,7 +347,7 @@ projectGljObject={
         this.projectGljSheet.setRowCount(0);
         sheetCommonObj.showData(this.projectGljSheet, this.projectGljSetting,this.projectGljSheetData);
         this.projectGljSheet.setRowCount(this.projectGljSheetData.length);
-        sel.row = _.findIndex(this.projectGljSheetData,{'id':oldData.id});
+        sel.row = oldData?_.findIndex(this.projectGljSheetData,{'id':oldData.id}):'';
         this.projectGljSheet.setSelection(sel.row==-1?0:sel.row,sel.col,sel.rowCount,sel.colCount);
     },
     showMaterialTreeData:function () {
@@ -488,7 +529,8 @@ projectGljObject={
             is_add:glj.unit_price.is_add,
             bgColour:'white',
             techQuantity:glj.techQuantity,
-            subdivisionQuantity:glj.subdivisionQuantity
+            subdivisionQuantity:glj.subdivisionQuantity,
+            remark:glj.remark
         };
         gljOprObj.setGLJPrice(data,glj);
         data.is_main_material = glj.is_main_material == 1?1:0;
@@ -564,11 +606,12 @@ projectGljObject={
         let prow = parentSheet.getActiveRowIndex();//取父机械或组成物的下标
         let prowData = parentSheet.name() == 'projectGljSheet'?me.projectGljSheetData[prow]:me.materialTree.items[prow].data;
         composition.updateConsumption(updateData,recode,prowData.id,function (sid) {
-           /* if(parentSheet.name() == 'projectGljSheet'){ 之前是单行刷新,父工料机与组成物对应的工料机分开刷,发现这样比整个刷新慢所以先整个刷新,当以后数据量大的时候再测试
-                me.refreshProjectGljRowByID(sid);
-            }*/
+            /* if(parentSheet.name() == 'projectGljSheet'){ 之前是单行刷新,父工料机与组成物对应的工料机分开刷,发现这样比整个刷新慢所以先整个刷新,当以后数据量大的时候再测试
+             me.refreshProjectGljRowByID(sid);
+             }*/
             projectObj.project.projectGLJ.calcQuantity();
             me.refreshParentData(prow,prowData.id,sid);
+            me.onUnitFileChange(recode);
         });
     },
     refreshParentData:function (row,pid,sid) {
@@ -611,12 +654,17 @@ projectGljObject={
             updateNodes = updateNodes.concat(subRations);
         }
         if(updateNodes.length>0){
-            projectObj.project.calcProgram.calcRationsAndSave(updateNodes,function () {
+            projectObj.project.calcProgram.calcNodesAndSave(updateNodes,function () {
                 projectObj.mainController.refreshTreeNode(projectObj.project.mainTree.roots);
+                installationFeeObj.calcInstallationFee();//计算安装增加费
             });
         }
         gljOprObj.refreshView();
     },
+    onUnitFileChange:function (data) {
+        socket.emit('unitFileChangeNotify', JSON.stringify(data));
+        projectObj.project.markUpdateProject({projectID:projectObj.project.ID(),'unitFileID':socketObject.getUnitFileRoomID()},"unitFile");
+    },
     deleteMixRatio:function (row) {
         let me = this, deleteRecode = me.mixRatioData[row];
         let consumption = deleteRecode.consumption;
@@ -628,6 +676,7 @@ projectGljObject={
         projectObj.project.composition.deleteComposition(updateData,deleteRecode,prowData.id,function () {
             me.refreshParentData(prow,prowData.id);
             me.mixRatioSheet.deleteRows(row,1);
+            me.onUnitFileChange(deleteRecode);
         });
     },
     getCompositionSumPrice : function(scene, affectRow, newValue = 0) {
@@ -692,7 +741,6 @@ projectGljObject={
             value= scMathUtil.roundForObj(value,getDecimal('glj.unitPrice'));//修改市场价和修改定额价时需要重新记算很多受影响的树节点,现在改成与定字额工料机那里调相同的方法。
             let editField = dataCode === 'basePrice'?"base_price":"market_price";
             projectObj.project.projectGLJ.updatePrice(recode,editField,value,'pg',callback);
-
         }else {
             let extend = {};
             // 如果是供货方式则需要处理数据
@@ -709,7 +757,8 @@ projectGljObject={
                     value = 0;
                 }
             }
-            if(dataCode === 'materialType' && value == null){//删除三材类别时,清空三材系数
+            if(dataCode === 'materialType' && (value == null || value=="")){//删除三材类别时,清空三材系数
+                value = null;
                 extend.materialCoe = null;
             }
             if(dataCode == 'materialCoe'){
@@ -754,6 +803,22 @@ projectGljObject={
         }
         return result;
     },
+    getProjectGLJSelected:function () {
+        let me = projectGljObject;
+        let sheet = me.projectGljSpread.getActiveSheet();
+        let selectedProjectGLJ = null;
+        if(sheet.name() == 'projectGljSheet'){//projectGljSheet/materialSheet 工料机汇总和三材汇总表
+            let sel = me.projectGljSheet.getSelections()[0];
+            if(sel.row != -1 && me.projectGljSheetData.length>sel.row){
+                selectedProjectGLJ = me.projectGljSheetData[sel.row]
+            }
+        }else if(sheet.name() == 'materialTreeSheet' ){
+            if(me.materialTree.selected){
+                selectedProjectGLJ = me.materialTree.selected.data;
+            }
+        }
+        return selectedProjectGLJ;
+    },
     initRightClick : function() {
         let activeSheet = this.mixRatioSheet;
         let me = this;
@@ -780,11 +845,12 @@ projectGljObject={
                     name: '添加',
                     icon: 'fa-sign-in',
                     disabled: function () {
-                        return me.rightClickTarget.row === undefined;
+                        let projectGLJ = projectGljObject.getProjectGLJSelected();
+                        return !_.includes(compositionTypes,projectGLJ.type);
                     },
                     callback: function (key, opt) {
-                        let row = me.rightClickTarget.row;
-                        console.log(row);
+                        me.selectedProjectGLJ = projectGljObject.getProjectGLJSelected();
+                        getGLJData('addMix');
                     }
                 }
             }
@@ -808,12 +874,12 @@ projectGljObject={
     },
     calcPartASupplyFeeByProjectGLJs: function (projectGLJsArr) {
         for (let pGLJ of projectGLJsArr){
-              if (pGLJ.supply == supplyType.BFJG){
-                  let rations = calcTools.getRationsByProjectGLJ(pGLJ.id);
-                  projectObj.project.calcProgram.calcNodesAndSave(rations, function () {
-                      projectObj.mainController.refreshTreeNode(projectObj.project.mainTree.roots);
-                  });
-              }
+            if (pGLJ.supply == supplyType.BFJG){
+                let rations = calcTools.getRationsByProjectGLJ(pGLJ.id);
+                projectObj.project.calcProgram.calcNodesAndSave(rations, function () {
+                    projectObj.mainController.refreshTreeNode(projectObj.project.mainTree.roots);
+                });
+            }
         }
     },
     checkUnitFileName:function (name,callback) {
@@ -875,23 +941,23 @@ $(function () {
         me.refreshDataSheet();
         loadProjectGljSize();
     });
-  /*  $('#ration_link').on('shown.bs.tab', function (e) {
-        let me = projectGljObject;
-        me.showTag='ration';
-        me.showProjectGljData();
-    });
-    $('#mix_ratio_link').on('shown.bs.tab', function (e) {
-        let me = projectGljObject;
-        me.showTag='mixRatio';
-        me.showProjectGljData();
-        me.initMixRatio();
-    });
-    $('#machine_ratio_link').on('shown.bs.tab', function (e) {
-        let me = projectGljObject;
-        me.showTag='machine';
-        me.showProjectGljData();
-        me.initMixRatio();
-    });*/
+    /*  $('#ration_link').on('shown.bs.tab', function (e) {
+     let me = projectGljObject;
+     me.showTag='ration';
+     me.showProjectGljData();
+     });
+     $('#mix_ratio_link').on('shown.bs.tab', function (e) {
+     let me = projectGljObject;
+     me.showTag='mixRatio';
+     me.showProjectGljData();
+     me.initMixRatio();
+     });
+     $('#machine_ratio_link').on('shown.bs.tab', function (e) {
+     let me = projectGljObject;
+     me.showTag='machine';
+     me.showProjectGljData();
+     me.initMixRatio();
+     });*/
     $('#pop-used-list').popover({
             placement: "bottom",
             html: true,
@@ -1057,7 +1123,14 @@ $(function () {
         });
     });
 
-    $("#filterType").on("click","ul li a",function(){
+    $("#filterType").on("click","ul li a",function(e){
+
+        let children = $('#filterType a');
+        for(let c of children){
+            $(c).removeClass('active');
+        }
+        $(this).addClass('active');
+
         let me = projectGljObject;
         me.displayType = filterType[this.id];
         me.refreshDataSheet();

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

@@ -350,7 +350,10 @@ let basicInfoView = {
                     offset= drowSubItem(ctx,x,y,w,h,offset,data[options.row+1]);
                     offset+=1;
                 }
-                ctx.fillText(value,x+offset+ctx.measureText(value).width,y+h-5);
+                arguments[2] = x + offset;
+                arguments[4] = w - offset;
+                GC.Spread.Sheets.CellTypes.Text.prototype.paint.apply(this, arguments);
+
             }
         };
         // override getHitInfo to allow cell type get mouse messages

+ 3 - 1
web/building_saas/main/js/views/project_property_projFeature.js

@@ -357,7 +357,9 @@ let projFeatureView = {
                     offset= drowSubItem(ctx,x,y,w,h,offset,data[options.row+1]);
                     offset+=1;
                 }
-                ctx.fillText(value,x+offset+ctx.measureText(value).width,y+h-5);
+                arguments[2] = x + offset;
+                arguments[4] = w - offset;
+                GC.Spread.Sheets.CellTypes.Text.prototype.paint.apply(this, arguments);
             }
         };
         // override getHitInfo to allow cell type get mouse messages

+ 140 - 3
web/building_saas/main/js/views/project_view.js

@@ -942,6 +942,37 @@ var projectObj = {
                     callback: function () {
                         BlockController.pasteBlock(project.mainTree.selected);
                     }
+                },
+                "editEngineer": {
+                    name: '编辑工程内容',
+                    icon: 'fa-edit',
+                    visible: function(key, opt){
+                         return project.Bills.isEngineerEst(project.mainTree.selected);//当焦点行是“专业工程暂估价”时,右键可见并有效。
+                    },
+                    callback: function () {
+                        projectObj.editContent(project.mainTree.selected,'engineeringContent');
+                        //BlockController.pasteBlock(project.mainTree.selected);
+                    }
+                },
+                "editService": {
+                    name: '编辑服务内容',
+                    icon: 'fa-edit',
+                    visible: function(key, opt){
+                        return project.Bills.isTotalService(project.mainTree.selected);//当焦点行是“总承包服务费”时,右键可见并有效。
+                    },
+                    callback: function () {
+                        projectObj.editContent(project.mainTree.selected,'serviceContent');
+                    }
+                },
+                "editAccording": {
+                    name: '编辑签证及索赔依据',
+                    icon: 'fa-edit',
+                    visible: function(key, opt){
+                        return project.Bills.isClaimVisa(project.mainTree.selected);//当焦点行是“签证及索赔计价”时,右键可见并有效。
+                    },
+                    callback: function () {
+                        projectObj.editContent(project.mainTree.selected,'claimVisa');
+                    }
                 }
             }
         });
@@ -998,6 +1029,89 @@ var projectObj = {
         if (selectedArea.colCount <= 1 && selectedArea.rowCount <= 1) {
             return false;
         }
+        //获取最左最右坐标
+        let maxCell = {row: selectedArea.row, col: selectedArea.col + selectedArea.colCount};
+        let maxCellX = sheet.getCellRect(maxCell.row, maxCell.col).x ? sheet.getCellRect(maxCell.row, maxCell.col).x : sheet.getCellRect(maxCell.row, maxCell.col - 1).x;
+        let minCell = {row: selectedArea.row, col: selectedArea.col};
+        let minCellX = sheet.getCellRect(minCell.row, minCell.col).x ? sheet.getCellRect(minCell.row, minCell.col).x : sheet.getCellRect(minCell.row, minCell.col + 1).x;
+        // 获取鼠标位置
+        let x = window.event.clientX;
+        let y = window.event.clientY;
+
+        // 匹配数字或小数
+        const regular = /^([0-9]+[.]{1}[0-9]+)$|^([1-9]{1}\d*)$/;
+        // 小数点最高位数
+        let max = 0;
+        let total = 0;
+        let counter = 0;
+        for (let col = selectedArea.col; col < (selectedArea.colCount + selectedArea.col); col++) {
+            for (let row = selectedArea.row; row < (selectedArea.rowCount + selectedArea.row); row++) {
+                const value = sheet.getCell(row, col).text();
+                if (!regular.test(value)) {
+                    continue;
+                }
+                counter++;
+                // 获取当前数据小数位数
+                let pointPosition = value.toString().indexOf(".");
+                pointPosition = pointPosition < 0 ? pointPosition : pointPosition + 1;
+                const current = pointPosition > 0 ? value.toString().substring(pointPosition, value.toString().length).length : 0;
+                max = current > max ? current : max;
+                total += parseFloat(value);
+            }
+        }
+        // 如果不为0则悬浮显示
+        if (total > 0 && counter > 1) {
+            const div = $('<div id="total-tips"><p>合计: <input type="text" id="total" readonly="readonly" style="border: none;"/></p><p><a href="javascript:void(0);">复制</a></p></div>');
+            div.css({
+                position: "absolute",
+                border: "1px #C0C0C0 solid",
+                background: "#fff",
+                boxShadow: "1px 2px 5px rgba(0,0,0,0.4)",
+            });
+            div.children("p").css({
+                textAlign: "center",
+                padding: 8,
+                marginBottom: 2,
+            });
+            div.children("p").first().css({
+                borderBottom: "1px #C0C0C0 solid"
+            });
+            const totalString = total.toFixed(max);
+            // input长度
+            const inputWidth = totalString.length * 8;
+            // 计算是否会超出显示范围
+            const baseWidth = 48;
+            const baseHeight = 81;
+            const canvasWidth = $("#billsSpreadvp_vp").width();
+            const canvasHeight = $("#billsSpreadvp_vp").height();
+            //x = x + baseWidth + inputWidth > canvasWidth ? x - baseWidth - inputWidth : x;
+            x = maxCellX + baseWidth + inputWidth > canvasWidth ? minCellX - baseWidth - inputWidth : maxCellX + baseWidth;
+            y = y + baseHeight > canvasHeight ? y - baseHeight : y;
+            //test
+            let testT = sheet.getParent().hitTest(x, y);
+            //test
+            div.css({
+                left: x,
+                top: y,
+            });
+
+            div.children().children("#total").width(inputWidth).val(totalString);
+            $("body").append(div);
+            // 用于判断是否要关闭窗体
+            setTimeout(function() {
+                isTotalShowing = true;
+            }, 200);
+        };
+    },
+    /*amountAreaNumber: function(e, info) {
+        if (info.newSelections === undefined || info.newSelections.length <= 0) {
+            return false;
+        }
+        const selectedArea = info.newSelections[0];
+        const sheet = info.sheet;
+        if (selectedArea.colCount <= 1 && selectedArea.rowCount <= 1) {
+            return false;
+        }
         // 获取鼠标位置
         let x = window.event.clientX;
         let y = window.event.clientY;
@@ -1050,6 +1164,10 @@ var projectObj = {
             const canvasHeight = $("#billsSpreadvp_vp").height();
             x = x + baseWidth + inputWidth > canvasWidth ? x - baseWidth - inputWidth : x;
             y = y + baseHeight > canvasHeight ? y - baseHeight : y;
+            //test
+            let testT = sheet.getParent().hitTest(x, y);
+            console.log(sheet.getCellRect(0, 0));
+            //test
             div.css({
                 left: x,
                 top: y,
@@ -1062,7 +1180,7 @@ var projectObj = {
                 isTotalShowing = true;
             }, 200);
         };
- },
+ },*/
 
     onButtonClick: function (e, info) {
         let colSetting = projectObj.mainController.setting.cols[info.col];
@@ -1245,6 +1363,25 @@ var projectObj = {
             $("a[name='lockBills']").prop("title","锁定清单");
             $("a[name='lockBills']").html('<i class="fa fa-lock" aria-hidden="true"></i> 锁定清单');
         }
+    },
+    editContent:function (node,fieldID) {//右键编辑工程内容、服务内容、签证及索赔依据
+        let infoText = "请输入";
+        switch (fieldID){
+            case "engineeringContent":
+                infoText +='工程内容:';
+                break;
+            case "serviceContent":
+                infoText +='服务内容:';
+                break;
+            case "claimVisa":
+                infoText +='签证及索赔依据:';
+                break;
+        }
+
+        hintBox.valueBox(infoText, node.data[fieldID], function () {
+            let newValue = hintBox.value;
+            projectObj.updateNodeField(node,newValue,fieldID);
+        });
     }
 
 };
@@ -1294,7 +1431,7 @@ $('#upLevel').click(function () {
         project.Bills.upLevelBills(selected.source);
         controller.upLevel();
         controller.refreshTreeNode([orgParent]);
-        projectObj.project.calcProgram.calcBillsAndSave([selected,orgParent]);
+        projectObj.project.calcProgram.calcNodesAndSave([selected,orgParent]);
     }
 });
 $('#downLevel').click(function () {
@@ -1639,7 +1776,7 @@ function testShow() {
     }
 }
 
-$('#delete_row').on('shown.bs.modal', function (e) {
+$('#delete_row').on('show.bs.modal', function (e) {//这里用show,在shown之前调用,页面不会出现按钮闪现的情况
     var controller = projectObj.mainController, project = projectObj.project;
     var selected = controller.tree.selected, parent = selected.parent;
     var showinfo = "<label>确认要删除当前选中行吗?</label>";

+ 2 - 0
web/building_saas/main/js/views/std_billsGuidance_lib.js

@@ -567,10 +567,12 @@ const billsGuidance = (function () {
                         bills.controller.setTreeSelected(result[0]);
                         billsSheet.setSelection(result[0].serialNo(), sel[0].col, 1, 1);
                         billsInitSel(result[0].serialNo());
+                        billsSheet.showRow(result[0].serialNo(), GC.Spread.Sheets.VerticalPosition.bottom);
                     } else {
                         bills.controller.setTreeSelected(result[resultIndex + 1]);
                         billsSheet.setSelection(result[resultIndex + 1].serialNo(), sel[0].col, 1, 1);
                         billsInitSel(result[resultIndex + 1].serialNo());
+                        billsSheet.showRow(result[resultIndex + 1].serialNo(), GC.Spread.Sheets.VerticalPosition.bottom);
                     }
                 });
             } else {

+ 8 - 3
web/building_saas/main/js/views/std_bills_lib.js

@@ -125,6 +125,10 @@ var billsLibObj = {
         if(projectInfoObj.projectInfo.property.lockBills == true){
             return false;
         }
+        //设置清单备注
+        if(node.parent && node.parent.data.recharge){
+            node.data.comments = node.parent.data.recharge;
+        }
         //特征及内容转化
         pageCCOprObj.setItemContentNode(node, this.getBillsJobs(stdBillsJobData, node), this.getBillsFeatures(stdBillsFeatureData, node), node.data.name);
         if (/\//.test(node.data.unit)) {
@@ -164,9 +168,8 @@ var billsLibObj = {
             $('#stdBillsRemarkTab').hide();
             billsLibObj.refreshBillsRelaSpread();
             billsLibObj.checkBillsRelaSpread();
-            billsLibObj.sortJobsAndFeatures(billsLibObj.getBillsJobs(node));
-            showJobs(billsLibObj.getBillsJobs(node));
-            showFeatures(billsLibObj.getBillsFeatures(node));
+            showJobs(billsLibObj.getBillsJobs(stdBillsJobData, node));
+            showFeatures(billsLibObj.getBillsFeatures(stdBillsFeatureData, node));
         };
         var showBillsRemark = function (node) {
             $('#stdBillsJobTab').hide();
@@ -274,9 +277,11 @@ var billsLibObj = {
                     if (resultIndex === result.length - 1) {
                         stdBillsTreeController.setTreeSelected(result[0]);
                         billsLibObj.stdBillsSpread.getActiveSheet().setSelection(result[0].serialNo(), sel[0].col, 1, 1);
+                        billsLibObj.stdBillsSpread.getActiveSheet().showRow(result[0].serialNo(), GC.Spread.Sheets.VerticalPosition.top);
                     } else {
                         stdBillsTreeController.setTreeSelected(result[resultIndex + 1]);
                         billsLibObj.stdBillsSpread.getActiveSheet().setSelection(result[resultIndex + 1].serialNo(), sel[0].col, 1, 1);
+                        billsLibObj.stdBillsSpread.getActiveSheet().showRow(result[resultIndex + 1].serialNo(), GC.Spread.Sheets.VerticalPosition.bottom);
                     }
                 });
             } else {

+ 22 - 3
web/building_saas/main/js/views/sub_view.js

@@ -316,13 +316,32 @@ let subViewObj = {
         $($(this).attr('href')).show();
     },
     loadComments: function (node) {
+        let comments = [];
+        let commentText = '';
         if (node) {
-            if (node.sourceType === projectObj.project.Bills.getSourceType()) {
-                $('#comments>textarea').val(node.data.comments)
+            if (node.sourceType === projectObj.project.Bills.getSourceType() &&
+                (node.data.type === billType.FX || node.data.type === billType.BX || node.data.type === billType.BILL)) {
+                if(node.data.comments && node.data.comments !== ''){
+                    comments.push('清单注释:');
+                    comments.push(node.data.comments);
+                }
+                if(node.data.ruleText && node.data.ruleText !== ''){
+                    comments.push('工程量计算规则:');
+                    comments.push(node.data.ruleText);
+                }
             } else if (node.sourceType === projectObj.project.Ration.getSourceType()) {
-                $('#comments>textarea').val(node.data.content);
+                if(node.data.content && node.data.content !== ''){
+                    comments.push('工作内容:');
+                    comments.push(node.data.content);
+                }
+                if(node.data.annotation && node.data.annotation !== ''){
+                    comments.push('附注:');
+                    comments.push(node.data.annotation);
+                }
             }
+            commentText = comments.join('\n');
         }
+        $('#comments>textarea').val(commentText);
     },
     saveComments: function (node) {
         let text = $('#comments>textarea').val();

+ 81 - 16
web/building_saas/main/js/views/tender_price_view.js

@@ -13,7 +13,7 @@ let tender_obj={
             {headerName: "类别", headerWidth: 50, dataCode: "subType", hAlign: "center", dataType: "String",spanRows: [2],getText:'getText.subType'},
             {headerName: "项目名称", headerWidth: 200, dataCode: "name",showHint:true, hAlign: "left", dataType: "String",spanRows: [2]},
             {headerName: "计量\n单位", headerWidth: 60, dataCode: "unit", hAlign: "center", dataType: "String",spanRows: [2]},
-            {headerName: "工程量", headerWidth: 120, dataCode: "basePrice", hAlign: "right", dataType: "Number",validator:"number",spanRows: [2]},
+            {headerName: "工程量", headerWidth: 70, dataCode: "quantity", hAlign: "right", dataType: "Number",validator:"number",spanRows: [2],getText:'getText.quantity'},
             {headerName: "不调价", headerWidth: 55, dataCode: "is_adjust_price", hAlign: "center", cellType : "checkBox",dataType: "Number",spanRows: [2]},
             {headerName: ["初始报价","综合单价"], headerWidth: 80, dataCode: "feesIndex.common.unitFee", hAlign: "right", dataType: "Number",validator:"number",spanCols : [2,1]},
             {headerName: ["","综合合价"], headerWidth: 80, dataCode: "feesIndex.common.totalFee", hAlign: "right", dataType: "Number",validator:"number",spanCols : [0,1]},
@@ -26,7 +26,7 @@ let tender_obj={
             {headerName: ["","机械"], headerWidth: 80, dataCode: "quantityCoe.machine", hAlign: "right", dataType: "Number",validator:"number",spanCols : [0,1]},
             {headerName: ["","主材"], headerWidth: 80, dataCode: "quantityCoe.main", hAlign: "right", dataType: "Number",validator:"number",spanCols : [0,1]},
             {headerName: ["","设备"], headerWidth: 80, dataCode: "quantityCoe.equipment", hAlign: "right", dataType: "Number",validator:"number",spanCols : [0,1]},
-            {headerName: "子目工程量\n调整系数", headerWidth: 100, dataCode: "rationQuantityCoe", hAlign: "center", dataType: "Number",spanRows: [2],validator:"number"}
+            {headerName: "子目工程量\n调整系数", headerWidth: 80, dataCode: "rationQuantityCoe", hAlign: "right", dataType: "Number",spanRows: [2],validator:"number"}
         ],
         view: {
             lockColumns: [0,1,2,3,4,6,7,10,11]
@@ -113,8 +113,6 @@ let tender_obj={
             value = scMathUtil.roundForObj(value,getDecimal('process'));
             me.updateChildrenValue(node,dataCode,value,datas,nodes);
         }
-
-
         //在目标造价综合单价中输入数值,按项目属性中的清单单价精度取舍,并清空当前行的目标造价综合合价
         if(dataCode == 'targetUnitFee'){
             value = scMathUtil.roundForObj(value,getDecimal('unitPrice',node));
@@ -167,6 +165,21 @@ let tender_obj={
         scMathUtil.isDef(node.data.targetTotalFee)?updateData.data["targetTotalFee"] = null:'';
         return updateData;
     },
+    cleanTenderPrice:function (updateData,node) {//清空调整后报价
+        if(node.data.fees){
+            for(let i =0; i< node.data.fees.length; i++){
+                node.data.fees[i].tenderUnitFee?updateData.data["fees."+i+'.tenderUnitFee'] = 0:'';
+                node.data.fees[i].tenderTotalFee?updateData.data["fees."+i+'.tenderTotalFee'] = 0:'';
+            }
+        }
+    },
+    cleanCacheCoes: function (){
+        for(let node of tender_obj.tenderTree.items){
+            if (node.data.rationQuantityCoe) node.data.rationQuantityCoe = null;
+            if (node.data.quantityCoe) node.data.quantityCoe = null;
+        };
+    },
+
     calcOptionsChecking:function (option) {//调整选项检查,返回需要更新的数组
         let datas = [];
         let me = tender_obj;
@@ -206,7 +219,7 @@ let tender_obj={
                         if(key == 'ID' || key == 'id'){
                             continue;
                         }
-                        _.set(temObj,key,d.data[key]);
+                        me.setValue(temObj,key,d.data[key])
                     }
                 }
             }
@@ -214,6 +227,35 @@ let tender_obj={
             $.bootstrapLoading.end();
         })
     },
+    setValue:function (obj,key,value) {
+        let keyArray = key.split('.');
+        t_set(obj,value,keyArray,0);
+        function t_set(obj,value,arr,index) {
+            let nextIndex = index + 1;
+            let tkey = arr[index];
+            if(nextIndex < arr.length){
+                if(obj[tkey]==undefined){
+                    obj[tkey] = {};
+                }
+                t_set(obj[tkey],value,arr,nextIndex)
+            }else if(nextIndex == arr.length){
+                obj[tkey] = value;
+            }
+        }
+
+    },
+    refreshTenderTreeByDatas:function (datas) {
+        let me = this;
+        let nodes = [];
+        for(let d of datas){
+            if(d.type == ModuleNames.bills || d.type == ModuleNames.ration){
+                let node = me.tenderTree.getNodeByID(d.data.ID);
+                node?nodes.push(node):'';
+            }
+        }
+        me.tenderController.refreshTreeNode(nodes);
+        me.initPageContent();
+    },
     treeSelectedChanged:function (node) {
         let me = tender_obj;
         //设置选中行底色和恢复前选中行底色
@@ -281,6 +323,12 @@ let tender_obj={
             $('#tenderRationQuantity').removeAttr("disabled");
         }
         //gljPriceTenderCoe
+    },
+    doTenderCalc: function(tender){
+        if (tender != tenderTypes.ttCalc)
+            tender_obj.cleanCacheCoes();
+        let callback = function () { tender_obj.showTenderData() };
+        projectObj.project.calcProgram.calcAllNodesAndSave(calcAllType.catAll, callback, tender);
     }
 };
 
@@ -302,7 +350,21 @@ $(function () {
     });
 
     $('#cleanTender').bind('click',function () {
-       console.log("clean tender")
+        let me = tender_obj,datas = [];
+        for(let node of me.tenderTree.items){
+            let tem_updateData = {type:node.sourceType,data:{}};
+            me.cleanTargetPrice(tem_updateData,node);
+            me.cleanTenderCoe(tem_updateData,node);
+            me.cleanTenderPrice(tem_updateData,node);
+            if(!_.isEmpty(tem_updateData.data)){//如果需要更新
+                tem_updateData.data.ID = node.data.ID;
+                datas.push(tem_updateData);
+            }
+        }
+        datas.push({type:ModuleNames.project,data:{'ID' : projectObj.project.ID(),'property.tenderSetting.gljPriceTenderCoe':1}});//恢复人材机单价调整系数为1。
+        me.updateTenderData(datas,function () {
+            me.refreshTenderTreeByDatas(datas);
+        });
     });
 
     $('#calcPriceOption').change(function(){
@@ -312,15 +374,7 @@ $(function () {
         let updateData = {type:ModuleNames.project,data:{'ID' : projectObj.project.ID(),'property.tenderSetting.calcPriceOption':newVal}};
         datas.push(updateData);
         me.updateTenderData(datas,function () {
-            let nodes = [];
-            for(let d of datas){
-                if(d.type == ModuleNames.bills || d.type == ModuleNames.ration){
-                    let node = me.tenderTree.getNodeByID(d.data.ID);
-                    node?nodes.push(node):'';
-                }
-            }
-            me.tenderController.refreshTreeNode(nodes);
-            me.initPageContent();
+            me.refreshTenderTreeByDatas(datas);
         });
     });
 
@@ -333,7 +387,18 @@ $(function () {
         me.updateTenderData([updateData],function () {
             me.initPageContent();
         });
-    })
+    });
 
+    $('#tenderPrice').on('click', function () {
+        tender_obj.doTenderCalc(tenderTypes.ttCalc);
+    });
+
+    $('#tenderGLJQuantity').on('click', function () {
+        tender_obj.doTenderCalc(tenderTypes.ttReverseGLJ);
+    });
+
+    $('#tenderRationQuantity').on('click', function () {
+        tender_obj.doTenderCalc(tenderTypes.ttReverseRation);
+    });
 
 });

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

@@ -8,8 +8,8 @@ let zmhs_obj = {
     coeSheetData:[],
     coeSetting: {
         header: [
-            {headerName: "调整", headerWidth: 100, dataCode: "isAdjust", dataType: "String", cellType: "checkBox"},
-            {headerName: "条件", headerWidth: 120, dataCode: "name", dataType: "String", cellType: "button"},
+            {headerName: "调整", headerWidth: 45, dataCode: "isAdjust", dataType: "String", cellType: "checkBox"},
+            {headerName: "条件", headerWidth: 150, dataCode: "name", dataType: "String", cellType: "button"},
             {headerName: "内容", headerWidth: 350, dataCode: "content", dataType: "String", hAlign: "left"}
         ],
         view: {

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

@@ -1,5 +1,5 @@
 <div class="toolsbar">
-    <legend class="m-0 pb-1">全部</legend>
+    <legend class="m-0 pb-1">回收站</legend>
 </div>
 <div class="top-content">
   <!--  <div class="main-data-top" id="gc_waiting">

+ 13 - 10
web/building_saas/pm/html/project-management.html

@@ -13,6 +13,7 @@
     <link rel="stylesheet" href="/lib/spreadjs/sheets/css/gc.spread.sheets.sc.css">
     <!--zTree-->
     <link rel="stylesheet" href="/lib/ztree/css/zTreeStyle.css" type="text/css">
+    <link rel="stylesheet" href="/lib/jquery-contextmenu/jquery.contextMenu.css">
     <!-- endinject -->
 
     <script>
@@ -87,7 +88,7 @@
                 <div class="tab-content">
                     <div class="tab-pane active" id="pm_all" role="tabpanel">
                         <div class="toolsbar">
-                            <div class="tools-btn btn-group align-top">
+                            <!--<div class="tools-btn btn-group align-top">
                                 <a href="javascript:void(0);"  id="add-tender-btn" class="btn btn-sm"><i class="fa fa-sticky-note-o"></i>新建单位工程</a>
                                 <div class="btn-group" role="group">
                                     <a href="javascript:void(0);" class="btn btn-sm dropdown-toggle" data-toggle="dropdown"></a>
@@ -99,11 +100,11 @@
                                 </div>
                                 <a href="javascript:void(0);" class="btn btn-sm" id="rename-btn">重命名</a>
                                 <a href="javascript:void(0);" class="btn btn-sm" id="del-btn">删除</a>
-                               <!-- <a href="javascript:void(0);" class="btn btn-sm" id="move-to-btn">移动到...</a>-->
+                               &lt;!&ndash; <a href="javascript:void(0);" class="btn btn-sm" id="move-to-btn">移动到...</a>&ndash;&gt;
                                 <a href="javascript:void(0);" class="btn btn-sm" id="copy-to-btn">复制到...</a>
                                 <a href="" class="btn btn-sm" id="share-btn">共享</a>
                                 <a href="" class="btn btn-sm" id="cooperate-btn">协同</a>
-                            </div>
+                            </div>-->
                             <legend class="m-0 pb-1">全部</legend>
                         </div>
                         <div class="poj-list" id="projSpread">
@@ -228,8 +229,8 @@
                 </form>
             </div>
             <div class="modal-footer">
-                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
                 <a href="javascript:void(0);" class="btn btn-primary" id="addProjOk">确定</a>
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
             </div>
         </div>
     </div>
@@ -255,8 +256,8 @@
                 </form>
             </div>
             <div class="modal-footer">
-                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
                 <a href="javascript:void(0);" class="btn btn-primary" id="add-engineering-confirm">确定</a>
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
             </div>
         </div>
     </div>
@@ -341,8 +342,8 @@
                 </form>
             </div>
             <div class="modal-footer">
-                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
                 <a href="javascript:void(0);" class="btn btn-primary" id="add-tender-confirm">确定</a>
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
             </div>
         </div>
     </div>
@@ -368,8 +369,8 @@
                 </form>
             </div>
             <div class="modal-footer">
-                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
                 <a href="javascript:void(0);" class="btn btn-primary" id="add-folder-confirm">确定</a>
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
             </div>
         </div>
     </div>
@@ -393,8 +394,8 @@
                 </form>
             </div>
             <div class="modal-footer">
-                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
                 <a href="javascript:void(0);" class="btn btn-primary" id="rename-confirm">确定</a>
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
             </div>
         </div>
     </div>
@@ -415,8 +416,8 @@
                 <p class="" id = 'restoreHint'>删除后,你可以在回收站找到它。</p>
             </div>
             <div class="modal-footer">
-                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
                 <a href="javascript:void(0);" class="btn btn-danger" id="delete-confirm">删除</a>
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
             </div>
         </div>
     </div>
@@ -457,8 +458,8 @@
                 </div>
             </div>
             <div class="modal-footer">
-                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
                 <a href="javacript:void(0);" class="btn btn-primary disabled" id="copy-to-confirm" >确定</a>
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
             </div>
         </div>
     </div>
@@ -495,6 +496,7 @@
 <script src="/public/web/date_util.js"></script>
 <script src="/web/building_saas/pm/js/pm_tree.js"></script>
 <script src="/public/web/tree_sheet/tree_sheet_helper.js"></script>
+<script src="/public/web/sheet/sheet_data_helper.js"></script>
 <script type="text/javascript" src="/public/web/common_ajax.js"></script>
 <script src="/lib/JSExpressionEval_src/Date.js"></script>
 <script src="/web/building_saas/pm/js/pm_ajax.js"></script>
@@ -503,6 +505,7 @@
 <!-- zTree -->
 <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/jquery-contextmenu/jquery.contextMenu.min.js"></script>
 <!-- endinject -->
 
 </body>

+ 12 - 10
web/building_saas/pm/js/pm_gc.js

@@ -17,15 +17,15 @@ const gcTreeObj = {
             autoUpdate: false
         },
         header: [
-            {name: '工程列表', dataCode: 'name', width: 800, vAlign: 'center', hAlign: 'left'},
-            {name: '删除日期', dataCode: 'deleteDateTime', width: 170, vAlign: 'center', hAlign: 'left'},
-            {name: '创建日期', dataCode: 'createDateTime', width: 170, vAlign: 'center', hAlign: 'left'},
-            {name: '恢复', dataCode: 'recovery', width: 100, vAlign: 'center', hAlign: 'left'},
-            {name: '彻底删除', dataCode: 'delete', width: 100, vAlign: 'center', hAlign: 'left'},
-            {name: '单价文件', dataCode: 'unitPriceFile', width: 100, vAlign: 'center', hAlign: 'left'},
-            {name: '单价文件-清除', dataCode: 'unitPriceFile_delete', width: 100, vAlign: 'center', hAlign: 'left'},
-            {name: '费率文件', dataCode: 'feeRateFile', width: 100, vAlign: 'center', hAlign: 'left'},
-            {name: '费率文件-清除', dataCode: 'feeRateFile_delete', width: 100, vAlign: 'center', hAlign: 'left'}
+            {name: '工程列表', dataCode: 'name', width: 0.5, vAlign: 'center', hAlign: 'left'},
+            {name: '删除日期', dataCode: 'deleteDateTime', width: 0.1, vAlign: 'center', hAlign: 'left'},
+            {name: '创建日期', dataCode: 'createDateTime', width: 0.1, vAlign: 'center', hAlign: 'left'},
+            {name: '恢复', dataCode: 'recovery', width: 0.05, vAlign: 'center', hAlign: 'left'},
+            {name: '彻底删除', dataCode: 'delete', width: 0.05, vAlign: 'center', hAlign: 'left'},
+            {name: '单价文件', dataCode: 'unitPriceFile', width: 0.05, vAlign: 'center', hAlign: 'left'},
+            {name: '单价文件-清除', dataCode: 'unitPriceFile_delete', width: 0.05, vAlign: 'center', hAlign: 'left'},
+            {name: '费率文件', dataCode: 'feeRateFile', width: 0.05, vAlign: 'center', hAlign: 'left'},
+            {name: '费率文件-清除', dataCode: 'feeRateFile_delete', width: 0.05, vAlign: 'center', hAlign: 'left'}
         ],
         //恢复和彻底删除字体色
         style: {
@@ -68,10 +68,11 @@ const gcTreeObj = {
                 allowResizeRows: true,
                 allowResizeColumns: true
             };
+            let workBookWidth = getWorkBookWidth();
             sheet.setColumnCount(headers.length);
             sheet.setRowHeight(0, 40, GC.Spread.Sheets.SheetArea.colHeader);
             for(let i = 0, len = headers.length; i < len; i++){
-                sheet.setColumnWidth(i, headers[i].width, GC.Spread.Sheets.SheetArea.colHeader);
+                sheet.setColumnWidth(i, workBookWidth * headers[i].width, GC.Spread.Sheets.SheetArea.colHeader);
                 if(headers[i].dataCode === 'unitPriceFile' || headers[i].dataCode === 'feeRateFile'){
                     //合并列
                     sheet.addSpan(0, i, 1, 2, GC.Spread.Sheets.SheetArea.colHeader);
@@ -332,6 +333,7 @@ const gcTreeObj = {
             // Draw Text
             //x = x + (node.depth() + 1) * indent +  node.depth() * levelIndent;
             x = x + (node.depth() + 1) * indent +  node.depth() * levelIndent + imgWidth + 3;
+            w = w - (node.depth() + 1) * indent - node.depth() * levelIndent - imgWidth - 3;
             GC.Spread.Sheets.CellTypes.Text.prototype.paint.apply(this, arguments);
         };
         TreeNodeCellType.prototype.getHitInfo = function (x, y, cellStyle, cellRect, context) {

+ 194 - 25
web/building_saas/pm/js/pm_newMain.js

@@ -39,11 +39,11 @@ const projTreeObj = {
             autoUpdate: false
         },
         header: [
-            {name: '工程列表', dataCode: 'name', width: 800, vAlign: 'center', hAlign: 'left'},
-            {name: '工程造价', dataCode: 'engineeringCost', width: 170, vAlign: 'center', hAlign: 'right'},
-            {name: '单价文件', dataCode: 'unitPriceFile', width: 250, vAlign: 'center', hAlign: 'left'},
-            {name: '费率文件', dataCode: 'feeRateFile', width: 250, vAlign: 'center', hAlign: 'left'},
-            {name: '创建日期', dataCode: 'createDateTime', width: 90, vAlign: 'center', hAlign: 'center'}
+            {name: '工程列表', dataCode: 'name', width: 0.48, vAlign: 'center', hAlign: 'left'},
+            {name: '工程造价', dataCode: 'engineeringCost', width: 0.13, vAlign: 'center', hAlign: 'right'},
+            {name: '单价文件', dataCode: 'unitPriceFile', width: 0.15, vAlign: 'center', hAlign: 'left'},
+            {name: '费率文件', dataCode: 'feeRateFile', width: 0.15, vAlign: 'center', hAlign: 'left'},
+            {name: '创建日期', dataCode: 'createDateTime', width: 0.09, vAlign: 'center', hAlign: 'center'}
         ],
         //选中行颜色
         style: {
@@ -110,9 +110,11 @@ const projTreeObj = {
             };
             sheet.setColumnCount(headers.length);
             sheet.setRowHeight(0, 40, GC.Spread.Sheets.SheetArea.colHeader);
+            let workBookWidth = getWorkBookWidth();
             for(let i = 0, len = headers.length; i < len; i++){
                 sheet.setValue(0, i, headers[i].name, GC.Spread.Sheets.SheetArea.colHeader);
-                sheet.setColumnWidth(i, headers[i].width, GC.Spread.Sheets.SheetArea.colHeader);
+                let width = workBookWidth * headers[i].width;
+                sheet.setColumnWidth(i, width, GC.Spread.Sheets.SheetArea.colHeader);
             }
         };
         me.renderSheetFuc(sheet, fuc);
@@ -124,9 +126,147 @@ const projTreeObj = {
             this.setOptions(newWorkBook, setting.options);
             this.buildHeader(newWorkBook.getActiveSheet(), setting.header);
             this.bindEvent(newWorkBook);
+            this.loadContextMenu()
         }
         return newWorkBook;
     },
+    loadContextMenu: function () {
+        let me = this;
+        $.contextMenu({
+            selector: '#projSpread',
+            build: function ($trigger, e) {
+                let target = SheetDataHelper.safeRightClickSelection($trigger, e, me.workBook);
+                me.initSelection({row: target.row, rowCount: 1}, me.preSelection ? me.preSelection : null, me.workBook.getActiveSheet());
+                return target.hitTestType === GC.Spread.Sheets.SheetArea.viewport || target.hitTestType === GC.Spread.Sheets.SheetArea.rowHeader;
+            },
+            items: {
+                "addFolder": {
+                    name: "新建文件夹",
+                    icon: 'fa-folder-o',
+                    disabled: function () {
+                        return false;
+                    },
+                    callback: function (key, opt) {
+                        $("#add-folder-dialog").modal("show");
+                        setTimeout(function () {
+                            $('#folder-name')[0].focus();
+                        }, 300);
+                    }
+                },
+                "addProject": {
+                    name: "新建建设项目",
+                    icon: 'fa-cubes',
+                    disabled: function () {
+                        return false;
+                    },
+                    callback: function (key, opt) {
+                        $('#add-project-dialog').modal('show');
+                        setTimeout(function () {
+                            $('#project-name')[0].focus();
+                        }, 300);
+                    }
+                },
+                "addEngineering": {
+                    name: "新建单项工程",
+                    icon: 'fa-cube',
+                    disabled: function () {
+                        let node = me.tree.selected;
+                        if(node && node.data.projType !== projectType.folder){
+                            return false;
+                        }
+                        return true;
+                    },
+                    callback: function (key, opt) {
+                        let selectedItem = me.tree.selected;
+                        try {
+                            if(selectedItem !== null  && selectedItem.data.projType !== projectType.folder){
+                                $("#add-engineering-dialog").modal("show");
+                                setTimeout(function () {
+                                    $('#engineering-name')[0].focus();
+                                }, 300);
+                            }
+
+                        } catch (error) {
+                            alert(error);
+                        }
+                    }
+                },
+                "addTender": {
+                    name: "新建单位工程",
+                    icon: 'fa-sticky-note-o',
+                    disabled: function () {
+                        return false;
+                    },
+                    callback: function (key, opt) {
+                        //弹出新建单位工程之前,判断当前使用版本,且当前使用单位工程数是否已到最大值
+                        let selectedItem = me.tree.selected;
+                        $("#add-tender-dialog").modal("show");
+                    }
+                },
+                "spr1": '--------',
+                "rename": {
+                    name: "重命名",
+                    icon: 'fa-edit',
+                    disabled: function () {
+                        return !me.tree.selected;
+                    },
+                    callback: function (key, opt) {
+                        $('#rename-name').val(projTreeObj.tree.selected.data.name ? projTreeObj.tree.selected.data.name : '');
+                        $('#rename-dialog').modal('show');
+                        setTimeout(function () {
+                            $('#rename-name')[0].focus();
+                        }, 300);
+                    }
+                },
+                "delete": {
+                    name: "删除",
+                    icon: 'fa-remove',
+                    disabled: function () {
+                        let node = me.tree.selected;
+                        return !node || (node.data.projType === projectType.folder && node.children.length > 0);
+                    },
+                    callback: function (key, opt) {
+                        if (projTreeObj.tree && projTreeObj.tree.selected) {
+                            $('#del').modal('show');
+                        }
+                    }
+                },
+                "copyTo": {
+                    name: "复制到",
+                    icon: 'fa-copy',
+                    disabled: function () {
+                        let node = me.tree.selected;
+                        return !(node && node.data.projType === projectType.tender);
+                    },
+                    callback: function (key, opt) {
+                        let selectedItem = projTreeObj.tree.selected;
+                        try {
+                            let selectedType = selectedItem !== null && selectedItem.data !== undefined ?
+                                selectedItem.data.projType : '';
+                            if (selectedType !== projectType.tender) {
+                                throw '请选择单位工程进行复制';
+                            }
+                        } catch (error) {
+                            alert(error);
+                            return false;
+                        }
+                        $('#copy-to-dialog').modal('show');
+                    }
+                },
+                "spr2": '--------',
+                "share": {
+                    name: "分享",
+                    icon: 'fa-share',
+                    disabled: function () {
+                        return true;
+                    },
+                    callback: function (key, opt) {
+
+                    }
+                },
+            }
+        });
+    },
     getSelStyle: function (backColor) {
         let style = new GC.Spread.Sheets.Style();
         style.backColor = backColor;
@@ -152,6 +292,7 @@ const projTreeObj = {
     initSelection: function (newSel, oldSel = null,sheet) {
         let me = this;
         let node = me.tree.items[newSel.row];
+        node = node ? node : null;
         //恢复底色
         if(oldSel){
             me.setSelStyle(oldSel, me.setting.style.defalutBackColor,sheet);
@@ -523,6 +664,7 @@ const projTreeObj = {
             // Draw Text
             //x = x + (node.depth() + 1) * indent +  node.depth() * levelIndent;
             x = x + (node.depth() + 1) * indent +  node.depth() * levelIndent + imgWidth + 3;
+            w = w - (node.depth() + 1) * indent - node.depth() * levelIndent - imgWidth - 3;
             GC.Spread.Sheets.CellTypes.Text.prototype.paint.apply(this, arguments);
         };
         TreeNodeCellType.prototype.getHitInfo = function (x, y, cellStyle, cellRect, context) {
@@ -662,9 +804,9 @@ const projTreeObj = {
         let fuc = function(){
             sheet.setRowCount(0);
             sheet.setRowCount(nodes.length);
+            let treeNodeCell = me.getTreeNodeCell(tree);
+            sheet.getRange(-1, 0, -1, 1).cellType(treeNodeCell);
             for(let i = 0; i < nodes.length; i++){
-                let treeNodeCell = me.getTreeNodeCell(tree);
-                sheet.getCell(i, 0).cellType(treeNodeCell);
                 for(let j = 0; j < headers.length; j++){
                     sheet.getRange(-1, j, -1, 1).hAlign(GC.Spread.Sheets.HorizontalAlign[headers[j]['hAlign']]);
                     sheet.getRange(-1, j, -1, 1).vAlign(GC.Spread.Sheets.VerticalAlign[headers[j]['vAlign']]);
@@ -809,7 +951,7 @@ const projTreeObj = {
             refreshNodes = refreshNodes.concat(me.calEngineeringCost(oldProject));
             refreshNodes = refreshNodes.concat(me.calEngineeringCost(parent));
         }
-       // projTreeObj.remove(sheet, fromRow, rCout);
+        // projTreeObj.remove(sheet, fromRow, rCout);
 
         me.renderSheetFuc(sheet, function () {
             sheet.deleteRows(fromRow, rCout);
@@ -821,7 +963,7 @@ const projTreeObj = {
             children.push(newNode);
             for(let c of children){
                 sheet.getCell(c.serialNo(), 0).cellType(me.getTreeNodeCell(me.tree));
-               // me.refreshNodeData(c);
+                // me.refreshNodeData(c);
             }
             refreshNodes = refreshNodes.concat(children);
             me.refreshNodeData(refreshNodes);
@@ -839,6 +981,13 @@ const projTreeObj = {
 };
 
 $(document).ready(function() {
+    //列宽随着屏幕改变
+    $(window).resize(function () {
+        autoPmWdith(projTreeObj.workBook, projTreeObj.setting.header);
+        autoPmWdith(gcTreeObj.workBook, gcTreeObj.setting.header);
+
+    });
+
     init();
     $('#tab_pm_all').on('show.bs.tab', function () {
         if(gcTreeObj.workBook){
@@ -883,13 +1032,13 @@ $(document).ready(function() {
     bindModalsHidden($('#add-project-dialog'), $('#add-engineering-dialog'), $('#add-folder-dialog'), $('#rename-dialog'));
 
     // 新增建设项目点击
-    $('#add-project-btn').click(function () {
+    /*$('#add-project-btn').click(function () {
         let selectedItem = projTreeObj.tree.selected;
         $('#add-project-dialog').modal('show');
         setTimeout(function () {
             $('#project-name')[0].focus();
         }, 300);
-    });
+    });*/
 
     // 新增建设项目操作
     $('#addProjOk').click(function () {
@@ -920,7 +1069,7 @@ $(document).ready(function() {
     });
 
     // 新增单项项目点击
-    $("#add-engineering-btn").click(function() {
+   /* $("#add-engineering-btn").click(function() {
         let selectedItem = projTreeObj.tree.selected;
         try {
             if(selectedItem !== null  && selectedItem.data.projType !== projectType.folder){
@@ -933,7 +1082,7 @@ $(document).ready(function() {
         } catch (error) {
             alert(error);
         }
-    });
+    });*/
 
     // 新增单项工程操作
     $("#add-engineering-confirm").click(function() {
@@ -941,11 +1090,11 @@ $(document).ready(function() {
     });
 
     // 新增单位工程点击
-    $("#add-tender-btn").click(function() {
+    /*$("#add-tender-btn").click(function() {
         //弹出新建单位工程之前,判断当前使用版本,且当前使用单位工程数是否已到最大值
         let selectedItem = projTreeObj.tree.selected;
         $("#add-tender-dialog").modal("show");
-    });
+    });*/
 
     //新建单位工程-建设项目提示
     $('#poj-name').change(function () {
@@ -1041,12 +1190,12 @@ $(document).ready(function() {
     });
 
     // 新增文件夹按钮点击
-    $("#add-folder-btn").click(function() {
+    /*$("#add-folder-btn").click(function() {
         $("#add-folder-dialog").modal("show");
         setTimeout(function () {
             $('#folder-name')[0].focus();
         }, 300);
-    });
+    });*/
 
     // 新增文件夹操作
     $("#add-folder-confirm").click(function() {
@@ -1054,11 +1203,11 @@ $(document).ready(function() {
     });
 
     // 删除按钮点击
-    $('#del-btn').click(function() {
+   /* $('#del-btn').click(function() {
         if (projTreeObj.tree && projTreeObj.tree.selected) {
             $('#del').modal('show');
         }
-    });
+    });*/
 
     // 删除时文字替换
     $('#del').on('show.bs.modal', function() {
@@ -1120,7 +1269,7 @@ $(document).ready(function() {
     });
 
     // 重命名按钮点击
-    $('#rename-btn').click(function() {
+    /*$('#rename-btn').click(function() {
         if (!projTreeObj.tree) {
             return false;
         }
@@ -1133,7 +1282,7 @@ $(document).ready(function() {
         setTimeout(function () {
             $('#rename-name')[0].focus();
         }, 300);
-    });
+    });*/
 
     // 重命名操作
     $("#rename-confirm").click(function() {
@@ -1160,7 +1309,7 @@ $(document).ready(function() {
 
 
     // 复制到按钮点击
-    $('#copy-to-btn').click(function () {
+    /*$('#copy-to-btn').click(function () {
         let selectedItem = projTreeObj.tree.selected;
         try {
             let selectedType = selectedItem !== null && selectedItem.data !== undefined ?
@@ -1173,7 +1322,7 @@ $(document).ready(function() {
             return false;
         }
         $('#copy-to-dialog').modal('show');
-    });
+    });*/
     // 复制到弹层替换
   /*  $('#copy-to-dialog').on('show.bs.modal', function () {
         copytoZTree = ConvertTreeToZtree(projTreeObj.tree, $('#treeDemo2'), null);
@@ -1246,6 +1395,24 @@ $(document).ready(function() {
     });
 });
 
+//获取工作表总宽度
+function getWorkBookWidth(){
+    return workBookWidth = $(window).width() - $('.pm-side').width() - 90;
+}
+
+//根据当前工作表的宽度更改比例
+function autoPmWdith(workBook, headers){
+    if(workBook){
+        const sheet = workBook.getActiveSheet();
+        projTreeObj.renderSheetFuc(sheet, function () {
+            let workBookWidth = getWorkBookWidth();
+            for(let col = 0; col < headers.length; col++){
+                sheet.setColumnWidth(col, workBookWidth * headers[col]['width'], GC.Spread.Sheets.SheetArea.colHeader)
+            }
+        });
+    }
+}
+
 /**
  * 初始化数据
  *
@@ -1842,6 +2009,7 @@ function AddEngineering() {
  */
 function AddTender() {
     try {
+        $('#add-tender-confirm').addClass('disabled');
         let projName = $("#poj-name").val().trim();
         if(projName === ''){
             replaceClass($('#poj-name-info'), 'text-info', 'text-danger');
@@ -1907,6 +2075,7 @@ function AddTender() {
         let engineeringName = $('#tender-engineering').children("option:selected").text();
 
         let callback = function() {
+            $('#add-tender-confirm').removeClass('disabled');
             $("#add-tender-dialog").modal("hide");
             $('#tender-name').val('');
             $("#tender-fee-rate").children("option").removeAttr("selected");
@@ -1984,7 +2153,7 @@ function AddFolder() {
         $('#folder-name').val('');
         setDangerInfo($('#folder-name-info'), '', false);
     };
-    if (selectedItem !== null) {
+    if (selectedItem) {
         // 判断是否超过3层
         if(!withinTreble(selectedItem)){
             alert("文件夹不能超过3层");

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

@@ -1,5 +1,5 @@
 <nav class="navbar navbar-expand-lg p-0 d-flex">
-    <a class="header-logo px-2" href="/pm" style="text-decoration: none;">纵横云价</a>
+    <a class="header-logo px-2" href="/pm" style="text-decoration: none;">纵横云价</a>
     <ul class="nav navbar-nav px-1" id="header-menu" style="display: none;">
         <li class="nav-item">
             <a class="nav-link" href="#" aria-expanded="false" data-toggle="modal" data-target="#poj-set"><i class="fa fa-cube"></i> 项目属性</a>
@@ -87,6 +87,20 @@
         </div>
     </div>
 </div>
+<!--弹出警告-->
+<div style="z-index: 1080;" class="modal fade" id="commonAlert" data-backdrop="false" style="display: none;" aria-hidden="true">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content" style="box-shadow: 0px 0px 5px #888888; width: 450px; height: 140px; left: 50%; transform: translate(-50%, 0%); top: -15px;">
+            <div class="modal-body">
+                <h5 style="margin-left: 10px;">提示</h5>
+                <p style="margin-top: 20px; margin-left: 10px; color: #757575; font-size: 14px"></p>
+                <div style="margin-top: 10px; margin-left: 350px">
+                    <button style="width: 65px; height: 30px; border-radius: 0.2rem; background: #4285F4; color: White; border: hidden; cursor:pointer" href="javascript: void(0);" data-dismiss="modal">确认</button>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
 <!-- inject:js -->
 <script src="/lib/jquery/jquery-3.2.1.min.js"></script>
 <script type="text/javascript" src="/web/building_saas/js/moment.min.js"></script>
@@ -95,4 +109,5 @@
 <script type="text/javascript" src="/public/web/gljUtil.js"></script>
 <script type="text/javascript" src="/public/web/PerfectLoad.js"></script>
 <script type="text/javascript" src="/lib/lodash/lodash.js"></script>
+<script type="text/javascript" src="/public/web/commonAlert.js"></script>
 <!-- endinject -->

+ 3 - 1
web/users/js/login.js

@@ -32,6 +32,7 @@ $(document).ready(function () {
                             location.href = url;
                             return false;
                         }
+                        console.log(response.compilation_list);
                         setVersion(response.compilation_list);
                         $('#ver').modal('show');
                     }
@@ -247,10 +248,11 @@ function cleanError() {
 function setVersion(versionData) {
     let html = '';
     for (let version of versionData) {
+        let description = version.description ? version.description : 'With supporting text below as a natural lead-in to additional content.';
         let tmpHtml = '<div class="col-sm-6">' +
             '<div class="card card-block">' +
             '<h3 class="card-title">'+ version.name +'</h3>' +
-            '<p class="card-text">With supporting text below as a natural lead-in to additional content.</p>' +
+            '<p class="card-text">' + description + '</p>' +
             '<a class="btn btn-primary" href="/boot/'+ version._id.toString() +'">开始使用</a>' +
             '</div>' +
             '</div>';