Kaynağa Gözat

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

laiguoran 4 yıl önce
ebeveyn
işleme
5df5128438
70 değiştirilmiş dosya ile 1533 ekleme ve 333 silme
  1. 1 0
      config/gulpConfig.js
  2. 4 2
      logs/online_logs.js
  3. 2 1
      modules/all_models/projects.js
  4. 18 0
      modules/complementary_ration_lib/models/searchModel.js
  5. 4 0
      modules/import/controllers/import_controller.js
  6. 1 0
      modules/import/routes/import_route.js
  7. 1 0
      modules/main/controllers/block_lib_controller.js
  8. 15 1
      modules/main/controllers/project_controller.js
  9. 14 2
      modules/main/facade/block_lib_facade.js
  10. 1 2
      modules/main/facade/info_price_facade.js
  11. 14 1
      modules/main/facade/project_facade.js
  12. 49 13
      modules/main/facade/ration_facade.js
  13. 1 0
      modules/main/models/project_consts.js
  14. 1 0
      modules/main/routes/project_route.js
  15. 4 4
      modules/options/models/optionTypes.js
  16. 22 0
      modules/pm/controllers/pm_controller.js
  17. 38 20
      modules/pm/facade/pm_facade.js
  18. 44 0
      modules/pm/models/project_model.js
  19. 2 0
      modules/pm/routes/pm_route.js
  20. 1 1
      modules/ration_glj/controllers/ration_glj_controller.js
  21. 18 2
      modules/reports/controllers/rpt_controller.js
  22. 10 1
      modules/reports/rpt_component/helper/jpc_helper_field.js
  23. 79 3
      modules/reports/util/rpt_construct_data_util.js
  24. 11 1
      public/gljUtil.js
  25. 47 1
      public/web/common_util.js
  26. 141 11
      public/web/gljUtil.js
  27. 35 9
      public/web/scMathUtil.js
  28. 12 5
      public/web/sheet/sheet_common.js
  29. 1 1
      public/web/sheet/sheet_data_helper.js
  30. 1 1
      web/building_saas/complementary_glj_lib/html/tools-gongliaoji.html
  31. 3 1
      web/building_saas/complementary_glj_lib/js/glj.js
  32. 1 1
      web/building_saas/complementary_ration_lib/html/dinge.html
  33. 6 5
      web/building_saas/css/custom.css
  34. 2 2
      web/building_saas/css/main.css
  35. 107 34
      web/building_saas/main/html/main.html
  36. 6 5
      web/building_saas/main/js/controllers/block_controller.js
  37. 5 5
      web/building_saas/main/js/controllers/material_controller.js
  38. 8 7
      web/building_saas/main/js/controllers/project_controller.js
  39. 8 1
      web/building_saas/main/js/main.js
  40. 2 1
      web/building_saas/main/js/models/bills.js
  41. 1 1
      web/building_saas/main/js/models/project.js
  42. 8 0
      web/building_saas/main/js/models/project_glj.js
  43. 1 1
      web/building_saas/main/js/models/ration_glj.js
  44. 1 1
      web/building_saas/main/js/views/billsElf.js
  45. 25 2
      web/building_saas/main/js/views/block_lib.js
  46. 3 0
      web/building_saas/main/js/views/calc_base_view.js
  47. 1 0
      web/building_saas/main/js/views/character_content_view.js
  48. 25 10
      web/building_saas/main/js/views/glj_col.js
  49. 10 3
      web/building_saas/main/js/views/glj_view.js
  50. 13 0
      web/building_saas/main/js/views/index_view.js
  51. 3 2
      web/building_saas/main/js/views/main_tree_col.js
  52. 6 6
      web/building_saas/main/js/views/material_adjust_view.js
  53. 1 0
      web/building_saas/main/js/views/project_glj_view.js
  54. 123 0
      web/building_saas/main/js/views/project_property_compare.js
  55. 60 41
      web/building_saas/main/js/views/project_view.js
  56. 2 0
      web/building_saas/main/js/views/quantity_edit_view.js
  57. 83 25
      web/building_saas/main/js/views/select_FB_view.js
  58. 28 2
      web/building_saas/main/js/views/std_ration_lib.js
  59. 18 4
      web/building_saas/main/js/views/sub_view.js
  60. 34 5
      web/building_saas/main/js/views/tender_price_view.js
  61. 145 1
      web/building_saas/main/js/views/zlfb_view.js
  62. 22 0
      web/building_saas/pm/js/pm_ajax.js
  63. 7 6
      web/building_saas/pm/js/pm_import.js
  64. 38 17
      web/building_saas/pm/js/pm_newMain.js
  65. 0 1
      web/building_saas/pm/js/pm_tree.js
  66. 62 38
      web/building_saas/report/js/rpt_main.js
  67. 1 1
      web/building_saas/unit_price_file/index.html
  68. 7 0
      web/common/components/share/index.js
  69. 64 21
      web/over_write/js/chongqing_2018_export.js
  70. 1 1
      web/over_write/js/guangdong_2018_export.js

+ 1 - 0
config/gulpConfig.js

@@ -143,6 +143,7 @@ module.exports = {
         'web/building_saas/main/js/views/project_property_projFeature.js',
         'web/building_saas/main/js/views/project_property_projFeature.js',
         'web/building_saas/main/js/views/project_property_indicativeInfo.js',
         'web/building_saas/main/js/views/project_property_indicativeInfo.js',
         'web/building_saas/main/js/views/project_property_display_view.js',
         'web/building_saas/main/js/views/project_property_display_view.js',
+        'web/building_saas/main/js/views/project_property_compare.js',
         'web/building_saas/main/js/main_ajax.js',
         'web/building_saas/main/js/main_ajax.js',
         'web/building_saas/main/js/main.js',
         'web/building_saas/main/js/main.js',
         'web/building_saas/main/js/controllers/project_controller.js',
         'web/building_saas/main/js/controllers/project_controller.js',

+ 4 - 2
logs/online_logs.js

@@ -18,13 +18,15 @@ async function saveOnlineTime(req) {
         let start = req.session.online_start_time;
         let start = req.session.online_start_time;
         if(start === undefined) return req.session.online_start_time ==end;
         if(start === undefined) return req.session.online_start_time ==end;
         let online_times =  end - start;
         let online_times =  end - start;
-        //1秒内只记一次就好
+        //0.5秒内只记一次就好
         if(online_times < 500) return;//如果间隔太短,则忽略
         if(online_times < 500) return;//如果间隔太短,则忽略
         if(online_times > interval_time ){//如果间隔超过有效时长,则不累加这次时长,从头开始算
         if(online_times > interval_time ){//如果间隔超过有效时长,则不累加这次时长,从头开始算
             req.session.online_start_time = end;
             req.session.online_start_time = end;
             return
             return
         }
         }
         if(!req.session.sessionUser||!req.session.sessionCompilation) return;
         if(!req.session.sessionUser||!req.session.sessionCompilation) return;
+        //先设置session再更新,在多个服务器多请求的情况下,update完再设置回session可能会造成多算时间
+        req.session.online_start_time = end;
         let dataString = moment(end).format('YYYY-MM-DD');
         let dataString = moment(end).format('YYYY-MM-DD');
         let condition = {userID:req.session.sessionUser.id,compilationID:req.session.sessionCompilation._id,dateString:dataString};
         let condition = {userID:req.session.sessionUser.id,compilationID:req.session.sessionCompilation._id,dateString:dataString};
         let userCondition = {_id: mongoose.Types.ObjectId(req.session.sessionUser.id)};
         let userCondition = {_id: mongoose.Types.ObjectId(req.session.sessionUser.id)};
@@ -43,5 +45,5 @@ async function saveOnlineTime(req) {
         console.log("统计登录时间错误,online_times值:"+online_times);
         console.log("统计登录时间错误,online_times值:"+online_times);
         console.log(e);
         console.log(e);
     }
     }
-    req.session.online_start_time = end;
+    
 }
 }

+ 2 - 1
modules/all_models/projects.js

@@ -41,7 +41,8 @@ const ProjectSchema = new Schema({
     "changeMark":String,// 更新标记  feeRate:费率文件发生了改变,unitFile 单件文件发生了改变
     "changeMark":String,// 更新标记  feeRate:费率文件发生了改变,unitFile 单件文件发生了改变
     "remark":String, // 备注
     "remark":String, // 备注
     "fileVer": String,  // 创建时程序版本号
     "fileVer": String,  // 创建时程序版本号
-    "lastFileVer": String  // 最新打开并计算时的程序版本号
+    "lastFileVer": String,  // 最新打开并计算时的程序版本号
+    "compareID":Number
 });
 });
 
 
 mongoose.model(collectionName, ProjectSchema, collectionName);
 mongoose.model(collectionName, ProjectSchema, collectionName);

+ 18 - 0
modules/complementary_ration_lib/models/searchModel.js

@@ -6,6 +6,7 @@ const compleRationModel = mongoose.model('complementary_ration_items');
 const complementaryGljModel = mongoose.model('complementary_glj_lib');
 const complementaryGljModel = mongoose.model('complementary_glj_lib');
 const stdGljModel = mongoose.model('std_glj_lib_gljList');
 const stdGljModel = mongoose.model('std_glj_lib_gljList');
 const compleRationSectionTreeModel = mongoose.model('complementary_ration_section_tree');
 const compleRationSectionTreeModel = mongoose.model('complementary_ration_section_tree');
+const rationLibModel = mongoose.model('std_ration_lib_map');
 let stdSectionTreeModel = require ('../../ration_repository/models/ration_section_tree').Model;
 let stdSectionTreeModel = require ('../../ration_repository/models/ration_section_tree').Model;
 let stdRationModel = require ('../../ration_repository/models/ration_item').Model;
 let stdRationModel = require ('../../ration_repository/models/ration_item').Model;
 let gljUtil = require('../../../public/gljUtil');
 let gljUtil = require('../../../public/gljUtil');
@@ -91,6 +92,20 @@ class SearchDao{
         }
         }
         return ration;
         return ration;
     }
     }
+    // 设置定额所属定额库数据
+    async setRationLibName(stdRations, compleRations) {
+        const rationLibIDSet = new Set();
+        stdRations.forEach(ration => {
+            rationLibIDSet.add(ration.rationRepId);
+        });
+        const rationLibNameList = await rationLibModel.find({ ID: { $in: [...rationLibIDSet] } }, '-_id dispName ID').lean();
+        const rationLibNameMap = {};
+        rationLibNameList.forEach(lib => rationLibNameMap[lib.ID] = lib.dispName);
+        stdRations.forEach(ration => {
+            ration.rationLibName = rationLibNameMap[ration.rationRepId];
+        });
+        compleRations.forEach(ration => ration.rationLibName = '我的补充定额');
+    }
     //@param {Object}skip({std: Number, comple: Number})
     //@param {Object}skip({std: Number, comple: Number})
     async findRation(userId, compilationId, rationRepId, keyword, skip, callback){
     async findRation(userId, compilationId, rationRepId, keyword, skip, callback){
         //每次限制结果数
         //每次限制结果数
@@ -162,6 +177,9 @@ class SearchDao{
                 }
                 }
             }
             }
 
 
+            // 设置定额所属定额库名称
+            await this.setRationLibName(stdRations, compleRations);
+
             //设置悬浮信息
             //设置悬浮信息
             stdGljIds = Array.from(new Set(stdGljIds));
             stdGljIds = Array.from(new Set(stdGljIds));
             comGljIds = Array.from(new Set(comGljIds));
             comGljIds = Array.from(new Set(comGljIds));

+ 4 - 0
modules/import/controllers/import_controller.js

@@ -17,6 +17,10 @@ let controller = {
         let data = req.body;
         let data = req.body;
         return await pm_facade.importChongqingProject(data);
         return await pm_facade.importChongqingProject(data);
     },
     },
+    importExampleProject:async function(req){
+        let data = req.body;
+        return await pm_facade.importExampleProject(data);
+    },
     copyConstructionProject:async function(req){
     copyConstructionProject:async function(req){
       let data = req.body;
       let data = req.body;
       return await pm_facade.copyConstructionProject(data);
       return await pm_facade.copyConstructionProject(data);

+ 1 - 0
modules/import/routes/import_route.js

@@ -13,6 +13,7 @@ module.exports = function (app) {
     importRouter.post('/getDataForInterface',importController.action);
     importRouter.post('/getDataForInterface',importController.action);
     importRouter.post('/loadSEIProjectData',importController.action);
     importRouter.post('/loadSEIProjectData',importController.action);
     importRouter.post('/importChongqingProject',importController.action);
     importRouter.post('/importChongqingProject',importController.action);
+    importRouter.post('/importExampleProject',importController.action);
     importRouter.post('/copyConstructionProject',importController.action);
     importRouter.post('/copyConstructionProject',importController.action);
     importRouter.post('/prepareInitialData',importController.action);
     importRouter.post('/prepareInitialData',importController.action);
     importRouter.get('/test',function (req,res) {
     importRouter.get('/test',function (req,res) {

+ 1 - 0
modules/main/controllers/block_lib_controller.js

@@ -11,6 +11,7 @@ module.exports = {
         try {
         try {
             let funcName = req.url.replace(/\//g, "");
             let funcName = req.url.replace(/\//g, "");
             let dataObj = JSON.parse(req.body.data);
             let dataObj = JSON.parse(req.body.data);
+            dataObj.sessionUser = req.session.sessionUser;
             result.data = await blFacade[funcName](dataObj);
             result.data = await blFacade[funcName](dataObj);
         } catch (err) {
         } catch (err) {
             console.log(err);
             console.log(err);

+ 15 - 1
modules/main/controllers/project_controller.js

@@ -251,5 +251,19 @@ module.exports = {
         } finally {
         } finally {
             res.json(responseData);
             res.json(responseData);
         }
         }
-    }
+    },
+    getCompareProjects:async function(req,res){
+        let result={
+            error:0
+        };
+        try {
+
+            result = await project_facade.getCompareProjects(req.session.sessionUser.id, req.session.sessionCompilation._id);
+        } catch (err) {
+            console.log(err.stack);
+            result.error=1;
+            result.message = err.message;
+        }
+        res.json(result);
+    },
 };
 };

+ 14 - 2
modules/main/facade/block_lib_facade.js

@@ -5,6 +5,10 @@
 let mongoose = require('mongoose');
 let mongoose = require('mongoose');
 let blModel = mongoose.model('blockLibsModel');
 let blModel = mongoose.model('blockLibsModel');
 let uuid = require('../../../public/web/uuid');
 let uuid = require('../../../public/web/uuid');
+const UserModel = require('../../users/models/user_model');
+const userInstance = new UserModel();
+const pmFacade = require('../../pm/facade/pm_facade');
+const { ShareLibType } = require('../../../public/common_constants');
 
 
 module.exports = {
 module.exports = {
     getLibNames: getLibNames,
     getLibNames: getLibNames,
@@ -49,13 +53,21 @@ async function getLibNamesAndFirstLib(data) {
     let libNames = await getLibNames(data);
     let libNames = await getLibNames(data);
     let lib = null;
     let lib = null;
     if (libNames.length == 0){
     if (libNames.length == 0){
-        lib = await copyTemplateLib(data.userID, data.userName, data.compilationID);
+        lib = await copyTemplateLib(data.userID, data.sessionUser.real_name, data.compilationID);
         libNames.push({libID: lib.libID, libName: lib.libName});
         libNames.push({libID: lib.libID, libName: lib.libName});
     }
     }
     else{
     else{
         lib = await getLib(libNames[0]);
         lib = await getLib(libNames[0]);
     }
     }
-    return {libNames: libNames, firstLib: lib};
+    // 别人分享的组价模板
+    const receiveLibs = await pmFacade.getReceiveLibList(data.userID, data.compilationID, ShareLibType.BLOCK_LIB);
+    const userIDList = receiveLibs.map(user => user._id);
+    const receiveLibNames = await blModel.find({userID: { $in: userIDList }, compilationID: data.compilationID}, ["libID","libName","-_id"]);
+    libNames.push(...receiveLibNames);
+    // 分享给别人
+    const shareList = await pmFacade.getLibShareList(data.userID, data.compilationID, ShareLibType.BLOCK_LIB);
+    
+    return {libNames: libNames, firstLib: lib, shareList};
 };
 };
 
 
 
 

+ 1 - 2
modules/main/facade/info_price_facade.js

@@ -50,7 +50,6 @@ async function getOptions(data,compilation){//data 是预留对象,暂时不
 }
 }
 
 
 async function getClassByAreaID(data,compilation){
 async function getClassByAreaID(data,compilation){
-  console.log(data);
   //要先知道根据期数和编办查找库ID
   //要先知道根据期数和编办查找库ID
   let newList = [];
   let newList = [];
   let lib = await infoLibModel.findOne({compilationID:compilation._id,period:data.period})
   let lib = await infoLibModel.findOne({compilationID:compilation._id,period:data.period})
@@ -225,7 +224,7 @@ async function getDataByFuzzyMatch(keyword, data){
 
 
   for (let info of allInfoPrice) { 
   for (let info of allInfoPrice) { 
     //specs
     //specs
-    let mstring = info.name + info.spec;
+    let mstring = info.name + info.specs;
     mstring = mstring.replace(/混凝土/g, "砼");
     mstring = mstring.replace(/混凝土/g, "砼");
     info.mstring = mstring;
     info.mstring = mstring;
     let matchCount = 0;
     let matchCount = 0;

+ 14 - 1
modules/main/facade/project_facade.js

@@ -16,7 +16,8 @@ module.exports = {
     loadSEIProjectData:loadSEIProjectData,
     loadSEIProjectData:loadSEIProjectData,
     setSEILibData:setSEILibData,
     setSEILibData:setSEILibData,
     getIndexReportData:getIndexReportData,
     getIndexReportData:getIndexReportData,
-    setDefaultItemIncrease:setDefaultItemIncrease
+    setDefaultItemIncrease:setDefaultItemIncrease,
+    getCompareProjects:getCompareProjects,
 };
 };
 
 
 let mongoose = require('mongoose');
 let mongoose = require('mongoose');
@@ -692,4 +693,16 @@ async function calcProjectGLJQuantity(projectID,projectGLJDatas,property){
     let rationGLJDatas = await ration_glj_model.find({'projectID':projectID});
     let rationGLJDatas = await ration_glj_model.find({'projectID':projectID});
     let rationDatas = await ration_model.model.find({'projectID':projectID});
     let rationDatas = await ration_model.model.find({'projectID':projectID});
     gljUtil.calcProjectGLJQuantity(projectGLJDatas,rationGLJDatas,rationDatas,[],q_decimal)
     gljUtil.calcProjectGLJQuantity(projectGLJDatas,rationGLJDatas,rationDatas,[],q_decimal)
+}
+
+
+async function getCompareProjects(userID, compilationID){
+    let projects = await projectsModel.find({
+        '$or': [{
+            'userID': userID,
+            'compilation': compilationID,
+            'deleteInfo': null
+        }, {'userID': userID, 'compilation': compilationID, 'deleteInfo.deleted': {'$in': [null, false]}}]
+    }, 'ID ParentID NextSiblingID name projType compareID', {lean: true});
+   return projects;
 }
 }

+ 49 - 13
modules/main/facade/ration_facade.js

@@ -78,11 +78,12 @@ async function addNewRation(data,compilation) {
 }
 }
 
 
 async function addMultiRation(datas,compilation) {
 async function addMultiRation(datas,compilation) {
-    const task = [];
-    for (const data of datas) {
-        task.push(addNewRation(data, compilation));
-    }
-    return await Promise.all(task);
+  let rst = [];
+  for(let data of datas){
+      let r = await addNewRation(data,compilation);
+      rst.push(r);
+  }
+  return rst;
 }
 }
 
 
 async function deleteMultiRation(rations) {//这里是只有删除的情况,删除定额的同时删除定额下挂的其它子项目
 async function deleteMultiRation(rations) {//这里是只有删除的情况,删除定额的同时删除定额下挂的其它子项目
@@ -589,13 +590,13 @@ async function getProjectGLJinfo(projectID,t_newRationGLJList,gljKeyMap,gljCodes
     let rkey = getIndex(ration_glj);
     let rkey = getIndex(ration_glj);
     let pglj = projectGLJMap[rkey];
     let pglj = projectGLJMap[rkey];
     let subList = [];
     let subList = [];
-    setUnitPrice(pglj,unitPriceMap);
+    await setUnitPrice(pglj,unitPriceMap,ration_glj);
     if(existMixRatioMap[rkey]){//如果有组成物
     if(existMixRatioMap[rkey]){//如果有组成物
       for(let m of existMixRatioMap[rkey]){
       for(let m of existMixRatioMap[rkey]){
          let mpglj = projectGLJMap[getIndex(m)]
          let mpglj = projectGLJMap[getIndex(m)]
          if(mpglj){
          if(mpglj){
           let cglj = _.clone(mpglj); 
           let cglj = _.clone(mpglj); 
-          setUnitPrice(cglj,unitPriceMap);
+          await setUnitPrice(cglj,unitPriceMap);
           cglj.ratio_data = m;
           cglj.ratio_data = m;
           subList.push(cglj);
           subList.push(cglj);
          }else{
          }else{
@@ -616,13 +617,48 @@ async function getProjectGLJinfo(projectID,t_newRationGLJList,gljKeyMap,gljCodes
 
 
 
 
 
 
-  function setUnitPrice(p,unitPriceMap){
-    p.unit_price = unitPriceMap[getIndex(p)];
+  async function setUnitPrice(p,unitPriceMap,ration_glj){
+    let unitPrice =  unitPriceMap[getIndex(p)];
+    if(unitPrice){
+      p.unit_price = unitPrice;
+    }else{
+      unitPrice = newPriceDataFromPGlj(p,unitPriceFileId);
+      if(ration_glj){
+        unitPrice.base_price = ration_glj.basePrice;
+        unitPrice.market_price = ration_glj.marketPrice;
+      }
+      await unitPriceModel.insertMany([unitPrice]);
+      p.unit_price =unitPrice
+    }
+   
   }
   }
 
 
 }
 }
 
 
-
+function newPriceDataFromPGlj(np,unitPriceFileId){
+  let insertData = {
+    code: np.code,
+    base_price: np.base_price,
+    market_price: np.market_price,
+    unit_price_file_id: unitPriceFileId,
+    name: np.name,
+    taxRate:np.taxRate,
+    specs:np.specs?np.specs:'',
+    original_code:np.original_code,
+    unit:np.unit?np.unit:'',
+    type: np.type,
+    short_name: np.shortName !== undefined ? np.shortName : '',
+    glj_id: np.glj_id,
+    is_add:0,
+    grossWeightCoe:np.grossWeightCoe,
+    purchaseStorageRate:np.purchaseStorageRate,
+    offSiteTransportLossRate:np.offSiteTransportLossRate,
+    handlingLossRate:np.handlingLossRate
+  };
+  if(np.from=='cpt') insertData.is_add=1;//如果是来自补充工料机,则都添加新增标记
+  if(insertData.code != insertData.original_code) insertData.is_add=1;//添加的时候如果是复制整块来的,可能在源项目中是新增的工料机,这里也要添上(暂时可能还用不到)
+  return insertData;
+}
 
 
 async function getUnitPriceData(newProjectGLJList,gljCodes,unitPriceFileId){
 async function getUnitPriceData(newProjectGLJList,gljCodes,unitPriceFileId){
   let unitPriceMap = {};
   let unitPriceMap = {};
@@ -635,8 +671,8 @@ async function getUnitPriceData(newProjectGLJList,gljCodes,unitPriceFileId){
   for(let np of newProjectGLJList){
   for(let np of newProjectGLJList){
     let pkey = getIndex(np);
     let pkey = getIndex(np);
     if(unitPriceMap[pkey]) continue;
     if(unitPriceMap[pkey]) continue;
-
-    let insertData = {
+    let insertData = newPriceDataFromPGlj(np,unitPriceFileId)
+    /* let insertData = {
       code: np.code,
       code: np.code,
       base_price: np.base_price,
       base_price: np.base_price,
       market_price: np.market_price,
       market_price: np.market_price,
@@ -656,7 +692,7 @@ async function getUnitPriceData(newProjectGLJList,gljCodes,unitPriceFileId){
       handlingLossRate:np.handlingLossRate
       handlingLossRate:np.handlingLossRate
     };
     };
     if(np.from=='cpt') insertData.is_add=1;//如果是来自补充工料机,则都添加新增标记
     if(np.from=='cpt') insertData.is_add=1;//如果是来自补充工料机,则都添加新增标记
-    if(insertData.code != insertData.original_code) insertData.is_add=1;//添加的时候如果是复制整块来的,可能在源项目中是新增的工料机,这里也要添上(暂时可能还用不到)
+    if(insertData.code != insertData.original_code) insertData.is_add=1;//添加的时候如果是复制整块来的,可能在源项目中是新增的工料机,这里也要添上(暂时可能还用不到) */
     newUnitPriceList.push(insertData);
     newUnitPriceList.push(insertData);
     unitPriceMap[pkey] = insertData;
     unitPriceMap[pkey] = insertData;
   }
   }

+ 1 - 0
modules/main/models/project_consts.js

@@ -42,6 +42,7 @@ let projectConstList = [
     // 'volume_price',
     // 'volume_price',
     'feeRate',
     'feeRate',
     'labour_coe',
     'labour_coe',
+    'contractor_list',
     'calc_program'
     'calc_program'
 ];
 ];
 
 

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

@@ -21,6 +21,7 @@ module.exports = function (app) {
     projectRouter.post('/loadSEIProjectData', projectController.loadSEIProjectData);
     projectRouter.post('/loadSEIProjectData', projectController.loadSEIProjectData);
     projectRouter.post('/getDecodedData', projectController.getDecodedData);
     projectRouter.post('/getDecodedData', projectController.getDecodedData);
     projectRouter.post('/getEncodedData', projectController.getEncodedData);
     projectRouter.post('/getEncodedData', projectController.getEncodedData);
+    projectRouter.get('/getCompareProjects', projectController.getCompareProjects);
     app.use('/project',projectRouter);
     app.use('/project',projectRouter);
 };
 };
 
 

+ 4 - 4
modules/options/models/optionTypes.js

@@ -15,8 +15,8 @@ const optionSetting = {
         DEFAULT: {
         DEFAULT: {
             backColor: 'White',
             backColor: 'White',
             foreColor: 'Black',
             foreColor: 'Black',
-            stringFont: '0.9rem Arial',
-            numFont: '0.9rem Arial'
+            stringFont: '14px Arial',
+            numFont: '14px Arial'
         },
         },
         SELECTED: {
         SELECTED: {
             backColor: '#FFFACD',
             backColor: '#FFFACD',
@@ -27,8 +27,8 @@ const optionSetting = {
         DXFY: {
         DXFY: {
             backColor: 'default',
             backColor: 'default',
             foreColor: 'default',
             foreColor: 'default',
-            stringFont: 'bold 0.9rem Arial',
-            numFont: 'bold 0.9rem Arial'
+            stringFont: 'bold 14px Arial',
+            numFont: 'bold 14px Arial'
         },
         },
         FB: {
         FB: {
             backColor: '#C4CAFB',
             backColor: '#C4CAFB',

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

@@ -84,6 +84,13 @@ module.exports = {
             callback(req, res, err, message, data);
             callback(req, res, err, message, data);
         });
         });
     },
     },
+    getAllUnitProjects: async function (req, res) {
+        const rootProjectID = JSON.parse(req.body.data).rootProjectID;
+        await ProjectsData.getAllUnitProjects(req.session.sessionUser.id, req.session.sessionCompilation._id, rootProjectID, function (err, message, data) {
+            console.log(err);
+            callback(req, res, err, message, data);
+        });
+    },
     updateProjects: async function (req, res) {
     updateProjects: async function (req, res) {
         let data = JSON.parse(req.body.data);
         let data = JSON.parse(req.body.data);
         try {
         try {
@@ -957,6 +964,21 @@ module.exports = {
         }
         }
         res.json(result);
         res.json(result);
     },
     },
+    importExampleProject: async function (req, res) {
+        let data = JSON.parse(req.body.data);
+        let result = {
+            error: 0
+        };
+        try {
+            data.session = req.session;
+            result.data = await redirectToImportServer(data, "importExampleProject", req);
+        } catch (err) {
+            console.log(err);
+            result.error = 1;
+            result.message = err.message;
+        }
+        res.json(result);
+    },
     copyConstructionProject: async function (req, res) {
     copyConstructionProject: async function (req, res) {
       let data = JSON.parse(req.body.data);
       let data = JSON.parse(req.body.data);
       let result = {
       let result = {

+ 38 - 20
modules/pm/facade/pm_facade.js

@@ -54,6 +54,7 @@ module.exports={
     uploadToken:uploadToken,
     uploadToken:uploadToken,
     downLoadProjectFile:downLoadProjectFile,
     downLoadProjectFile:downLoadProjectFile,
     importChongqingProject:importChongqingProject,
     importChongqingProject:importChongqingProject,
+    importExampleProject:importExampleProject,
     importProcessChecking:importProcessChecking,
     importProcessChecking:importProcessChecking,
     copyConstructionProject,
     copyConstructionProject,
     importInterface,
     importInterface,
@@ -1769,32 +1770,45 @@ async function importChongqingProject(data) {
     };
     };
     await importLogsModel.create(log_data);
     await importLogsModel.create(log_data);
     doImport(data.user_id,data.session.sessionCompilation._id,data.session.sessionCompilation.adProjects,data.key);
     doImport(data.user_id,data.session.sessionCompilation._id,data.session.sessionCompilation.adProjects,data.key);
+     return "start importing";
+}
+
+//加载例题
+async function importExampleProject(data) {
 
 
+    let log_data = {
+        key:data.key,
+        content: '正在导入例题,请稍候……',
+        userID:data.user_id,
+        compilationID: data.session.sessionCompilation._id,
+        status:"start",
+        create_time:+new Date()
+    };
+    await importLogsModel.create(log_data);
+    doImport(data.user_id,data.session.sessionCompilation._id,data.session.sessionCompilation.example,data.key);
      return "start importing";
      return "start importing";
-    async function doImport(user_id,compilationId,projectIDs,key) {
-        let doc = {status:"finish"};
-        try {
-           let r = await copyExample(user_id,compilationId,projectIDs);
-           if(r == false){
-               doc.errorMsg = "导入失败,请检查项目是否存在!";
-               doc.status = "error";
-           } else {
-               doc.projectID = r;
-           }
-        }catch (error){
-            console.log(error);
-            doc.errorMsg = "导入失败,请检查项目是否存在!";
-            doc.status = "error";
-        }finally {
-            await importLogsModel.update({key:key},doc);
-        }
-    }
 }
 }
 
 
-function testTimeout(time) {
-    return new Promise(resolve => setTimeout(resolve, time));
+async function doImport(user_id,compilationId,projectIDs,key) {
+    let doc = {status:"finish"};
+    try {
+       let r = await copyExample(user_id,compilationId,projectIDs);
+       if(r == false){
+           doc.errorMsg = "导入失败,请检查项目是否存在!";
+           doc.status = "error";
+       } else {
+           doc.projectID = r;
+       }
+    }catch (error){
+        console.log(error);
+        doc.errorMsg = "导入失败,请检查项目是否存在!";
+        doc.status = "error";
+    }finally {
+        await importLogsModel.update({key:key},doc);
+    }
 }
 }
 
 
+
 //用户第一次进入费用定额的数据准备
 //用户第一次进入费用定额的数据准备
 async function prepareInitialData(userId, compilation, example) {
 async function prepareInitialData(userId, compilation, example) {
     let first = await isFirst(userId, compilation);
     let first = await isFirst(userId, compilation);
@@ -2172,6 +2186,10 @@ async function importProject(importObj, userID, compilationID, overWriteUrl) {
             });
             });
         }
         }
         data.property.projectFeature = featureLib ? featureLib.feature : [];
         data.property.projectFeature = featureLib ? featureLib.feature : [];
+        // 累进数据
+        if (data.property.progressiveLibID) {
+            data.property.progressiveInterval = await getProgressiveInterval(data.property.progressiveLibID);
+        }
         // 指标信息相关设置
         // 指标信息相关设置
         await project_facade.setSEILibData(data.property);
         await project_facade.setSEILibData(data.property);
     }
     }

+ 44 - 0
modules/pm/models/project_model.js

@@ -54,6 +54,50 @@ let optionModel = mongoose.model('options');
 function ProjectsDAO() {
 function ProjectsDAO() {
 }
 }
 
 
+ProjectsDAO.prototype.getAllUnitProjects = async function (userId, compilation, rootPrjID, callback) {
+    //根据root project id获取所有的非删除单位工程
+    try {//
+        let projects = await Projects.find({
+            '$or': [
+                {
+                'userID': userId,
+                'compilation': compilation,
+                'property.rootProjectID': rootPrjID,
+                'deleteInfo': null
+                }, 
+                {
+                    'userID': userId, 
+                    'compilation': compilation, 
+                    'property.rootProjectID': rootPrjID,
+                    'deleteInfo.deleted': {'$in': [null, false]}
+                }
+            ]
+        }, '-_id', {lean: true});
+        let projIDs= [];
+        const allIDs = [];
+        for(let project of projects){
+            allIDs.push(project.ID);
+            if(project.projType === projectType.project){
+                projIDs.push(project.ID);
+            }
+        }
+        // 设置分享信息 
+        const shareMap = await pmFacade.getShareInfoMap(allIDs);
+        projects.forEach(project => {
+            project.shareInfo = shareMap[project.ID] || [];
+        });
+        // 当前费用定额未读的分享的条目数量
+        
+        // 设置汇总字段
+        let summaryInfo = await pmFacade.getSummaryInfo(projIDs);
+        pmFacade.setupSummaryFields(summaryInfo, projects);
+        callback(0, '', projects);
+    }
+    catch (err) {
+        callback(1, 'Error', null);
+    }
+}
+    
 ProjectsDAO.prototype.getUserProjects = async function (userId, compilation, callback) {
 ProjectsDAO.prototype.getUserProjects = async function (userId, compilation, callback) {
     try {//
     try {//
         let projects = await Projects.find({
         let projects = await Projects.find({

+ 2 - 0
modules/pm/routes/pm_route.js

@@ -29,6 +29,7 @@ module.exports = function (app) {
     pmRouter.post('/prepareInitialData', pmController.prepareInitialData);
     pmRouter.post('/prepareInitialData', pmController.prepareInitialData);
 
 
     pmRouter.post('/getProjects', pmController.getProjects);
     pmRouter.post('/getProjects', pmController.getProjects);
+    pmRouter.post('/getAllUnitProjects', pmController.getAllUnitProjects);
     pmRouter.post('/getSummaryInfo', pmController.getSummaryInfo);
     pmRouter.post('/getSummaryInfo', pmController.getSummaryInfo);
 
 
     /*
     /*
@@ -69,6 +70,7 @@ module.exports = function (app) {
     pmRouter.post('/exportProject', pmController.exportProject);
     pmRouter.post('/exportProject', pmController.exportProject);
     pmRouter.post('/importProject', pmController.importProject);
     pmRouter.post('/importProject', pmController.importProject);
     pmRouter.post('/importChongqingProject', pmController.importChongqingProject);
     pmRouter.post('/importChongqingProject', pmController.importChongqingProject);
+    pmRouter.post('/importExampleProject', pmController.importExampleProject);
     pmRouter.post('/copyConstructionProject',systemMiddleware.tenderNumberChecking,pmController.copyConstructionProject);
     pmRouter.post('/copyConstructionProject',systemMiddleware.tenderNumberChecking,pmController.copyConstructionProject);
     pmRouter.post('/importProcessChecking', pmController.importProcessChecking);
     pmRouter.post('/importProcessChecking', pmController.importProcessChecking);
     pmRouter.post('/getBasicInfo', pmController.getBasicInfo);
     pmRouter.post('/getBasicInfo', pmController.getBasicInfo);

+ 1 - 1
modules/ration_glj/controllers/ration_glj_controller.js

@@ -158,7 +158,7 @@ async function getGLJData(req, res) {
             libData = engineerID === COMPILATION 
             libData = engineerID === COMPILATION 
             ? await ration_glj_facade.getLibOptionsForCompilation(compilationId)
             ? await ration_glj_facade.getLibOptionsForCompilation(compilationId)
             : await ration_glj_facade.getLibOptions(engineerID);
             : await ration_glj_facade.getLibOptions(engineerID);
-            libData.push({ name: '补充工料机', gljLibId: COMPLEMENTARY_LIB });
+            libData.push({ name: '我的补充人材机库', gljLibId: COMPLEMENTARY_LIB });
             // 设置被分享的人材机库
             // 设置被分享的人材机库
             const receiveData = await pmFacade.getReceiveLibList(userID, compilationId, ShareLibType.GLJ_LIB);
             const receiveData = await pmFacade.getReceiveLibList(userID, compilationId, ShareLibType.GLJ_LIB);
             receiveData.forEach(user => {
             receiveData.forEach(user => {

+ 18 - 2
modules/reports/controllers/rpt_controller.js

@@ -23,6 +23,7 @@ const rpt_svg_util = require("../util/rpt_svg_util");
 const fs = require("fs");
 const fs = require("fs");
 const strUtil = require("../../../public/stringUtil");
 const strUtil = require("../../../public/stringUtil");
 const rptDataExtractor = require("../util/rpt_construct_data_util");
 const rptDataExtractor = require("../util/rpt_construct_data_util");
+
 //统一回调函数
 //统一回调函数
 let callback = function(req, res, err, data){
 let callback = function(req, res, err, data){
     if(err){
     if(err){
@@ -261,8 +262,9 @@ async function getAllPagesCommon(user_id, prj_id, prj_ids, rpt_id, pageSize, ori
                     cb('Exception occurs while on going...', null);
                     cb('Exception occurs while on going...', null);
                 }
                 }
             };
             };
-        if (flag !== undefined && flag !== null && flag.constructSumType === 'constructSum') {
-                //这个直接取本项目的建设项目下所有的单位工程的数据,然后合并
+        if (flag !== undefined && flag !== null && (flag.constructSumType === 'constructSum' || flag.auditType === 'audit_compare')) {
+                //备注:原先这个功能是为了合并建设项目下所有的单位工程的数据,
+                //     现在发现就是通用型,审核对比也可以用这个逻辑把数据合并在一起再处理(审核对比的处理逻辑放在模板计算式里)
                 try {
                 try {
                     console.log('准备取建设项目下所有单位工程数据:');
                     console.log('准备取建设项目下所有单位工程数据:');
                     const _combineData = function(destData, srcData) {
                     const _combineData = function(destData, srcData) {
@@ -283,6 +285,20 @@ async function getAllPagesCommon(user_id, prj_id, prj_ids, rpt_id, pageSize, ori
                             destData[JV.DATA_DETAIL_DATA_EX][idx] = destData[JV.DATA_DETAIL_DATA_EX][idx].concat(srcData[JV.DATA_DETAIL_DATA_EX][idx]);
                             destData[JV.DATA_DETAIL_DATA_EX][idx] = destData[JV.DATA_DETAIL_DATA_EX][idx].concat(srcData[JV.DATA_DETAIL_DATA_EX][idx]);
                         }
                         }
                     };
                     };
+                    // let multiRawData = rptTplDataFacade.prepareMultiProjectData(user_id, prj_ids, filter);
+                    // //终于出来结果了 !_! (multiRawData是多个单位工程的原始数据!)
+                    // if (multiRawData.length > 0) {
+                    //     //考虑到工料机的数据还需要再计算,所以还不能直接用,需要每个工程都处理一遍后,再合并
+                    //     let tplData = rptDataUtil.assembleData(multiRawData[0]);
+                    //     for (let idx = 1; idx < multiRawData.length; idx++) {
+                    //         let tmpData = rptDataUtil.assembleData(multiRawData[idx]);
+                    //         _combineData(tplData, tmpData);
+                    //     }
+                    //     _createPntPageData(tplData, rptTpl);
+                    // } else {
+                    //     cb('Have errors while on going...', null);
+                    // }
+
                     rptTplDataFacade.prepareMultiProjectData(user_id, prj_ids, filter).then(function(multiRawData) {
                     rptTplDataFacade.prepareMultiProjectData(user_id, prj_ids, filter).then(function(multiRawData) {
                         //终于出来结果了 !_! (multiRawData是多个单位工程的原始数据!)
                         //终于出来结果了 !_! (multiRawData是多个单位工程的原始数据!)
                         if (multiRawData.length > 0) {
                         if (multiRawData.length > 0) {

+ 10 - 1
modules/reports/rpt_component/helper/jpc_helper_field.js

@@ -70,7 +70,16 @@ let JpcFieldHelper = {
             if (showZero && showZero === 'F') {
             if (showZero && showZero === 'F') {
                 const val = parseFloat(cell[JV.PROP_VALUE]);
                 const val = parseFloat(cell[JV.PROP_VALUE]);
                 if (val === 0) {
                 if (val === 0) {
-                    cell[JV.PROP_VALUE] = '';
+                    let chkRst = true;
+                    if (typeof cell[JV.PROP_VALUE] === 'string' && cell[JV.PROP_VALUE].length > 1) {
+                        for (let idx = 0; idx < cell[JV.PROP_VALUE].length; idx++) {
+                            if (cell[JV.PROP_VALUE][idx] !== '0' && cell[JV.PROP_VALUE][idx] !== '.') {
+                                chkRst = false;
+                                break;
+                            }
+                        }
+                    }
+                    if (chkRst) cell[JV.PROP_VALUE] = '';
                 }
                 }
             }
             }
         }
         }

+ 79 - 3
modules/reports/util/rpt_construct_data_util.js

@@ -16,7 +16,11 @@ const gljUtil = require('../../../public/gljUtil');
 const gljType = require('../../common/const/glj_type_const');
 const gljType = require('../../common/const/glj_type_const');
 // const pm_facade = require('../../pm/facade/pm_facade');
 // const pm_facade = require('../../pm/facade/pm_facade');
 const GLJID_PRE = `gljId_`, COMPONENT_GLJID_PRE = `componetGljId_`;
 const GLJID_PRE = `gljId_`, COMPONENT_GLJID_PRE = `componetGljId_`;
-
+//import common_const = require('../../../public/common_constants');
+const { fixedFlag, supplyType, supplyText } = require('../../../public/common_constants');
+const _ = require('lodash');
+// const { last } = require('lodash');
+const scMathUtil = require('../../../public/scMathUtil').getUtil();
 
 
 const GLJ_TYPE = {
 const GLJ_TYPE = {
     Labour: 1,
     Labour: 1,
@@ -121,6 +125,23 @@ class Rpt_Common{
         }
         }
         return rst;
         return rst;
     };
     };
+    getSupplyType(srcValArr) {
+        let rst = [];
+        for (const val of srcValArr) {
+            let hasKey = false;
+            for (const propKey in supplyType) {
+                if (supplyType[propKey] === val) {
+                    hasKey = true;
+                    rst.push(supplyText[propKey]);
+                    break;
+                }
+            }
+            if (!hasKey) {
+                rst.push('未知方式');
+            }
+        }
+        return rst;    
+    };
 }
 }
 
 
 class Rpt_Data_Extractor {
 class Rpt_Data_Extractor {
@@ -147,7 +168,7 @@ class Rpt_Data_Extractor {
                                 if (rst.indexOf(projectConst.LABOUR_COE < 0)) rst.push(projectConst.LABOUR_COE);
                                 if (rst.indexOf(projectConst.LABOUR_COE < 0)) rst.push(projectConst.LABOUR_COE);
                             }
                             }
                             if (key === projectConst.PROJECTGLJ) {
                             if (key === projectConst.PROJECTGLJ) {
-                                if (rst.indexOf(projectConst.LABOUR_COE < 0)) rst.push(projectConst.LABOUR_COE);
+                                if (rst.indexOf(projectConst.LABOUR_COE) < 0) rst.push(projectConst.LABOUR_COE);
                                 if (rst.indexOf(projectConst.RATION_GLJ) < 0) rst.push(projectConst.RATION_GLJ);
                                 if (rst.indexOf(projectConst.RATION_GLJ) < 0) rst.push(projectConst.RATION_GLJ);
                                 if (field[JV.PROP_FIELD_EXP_MAP].indexOf("'quantity'") > 0 ||
                                 if (field[JV.PROP_FIELD_EXP_MAP].indexOf("'quantity'") > 0 ||
                                     field[JV.PROP_FIELD_EXP_MAP].indexOf("'subdivisionQuantity'") > 0 ||
                                     field[JV.PROP_FIELD_EXP_MAP].indexOf("'subdivisionQuantity'") > 0 ||
@@ -156,6 +177,18 @@ class Rpt_Data_Extractor {
                                     if (rst.indexOf(projectConst.BILLS) < 0) rst.push(projectConst.BILLS);
                                     if (rst.indexOf(projectConst.BILLS) < 0) rst.push(projectConst.BILLS);
                                 }
                                 }
                             }
                             }
+                            if (key === projectConst.CONTRACTOR_LIST) {
+                                if (rst.indexOf(projectConst.PROJECTGLJ) < 0) {
+                                    rst.push(projectConst.PROJECTGLJ); //为了算指标:承包人主要材料设备_变值权重B
+                                }
+                                if (rst.indexOf(projectConst.BILLS) < 0) {
+                                    rst.push(projectConst.BILLS); //为了算指标:承包人主要材料设备_变值权重B
+                                }
+                                if (rst.indexOf(projectConst.LABOUR_COE) < 0) {
+                                    rst.push(projectConst.LABOUR_COE); //为了算:造价信息差额调整专用指标
+                                }
+                                
+                            }
                         }
                         }
                     }
                     }
                 } else if (key === projectConst.PROJECTGLJ) {
                 } else if (key === projectConst.PROJECTGLJ) {
@@ -245,6 +278,7 @@ class Rpt_Data_Extractor {
         let tpl = this.rptTpl;
         let tpl = this.rptTpl;
         this.COMMON.initialize(tpl, rawDataObj);
         this.COMMON.initialize(tpl, rawDataObj);
         $PROJECT.COMMON = this.COMMON;
         $PROJECT.COMMON = this.COMMON;
+        // fsUtil.writeObjToFile(rawDataObj, "D:/GitHome/temp/建筑Rawdata.js");
         if (rawDataObj.hasOwnProperty(`prj`)) {
         if (rawDataObj.hasOwnProperty(`prj`)) {
             setupMainFunc($PROJECT, `MAIN`, rawDataObj.prj._doc);
             setupMainFunc($PROJECT, `MAIN`, rawDataObj.prj._doc);
             // $PROJECT.MAIN["myOwnRawDataObj"] = rawDataObj.prj._doc;
             // $PROJECT.MAIN["myOwnRawDataObj"] = rawDataObj.prj._doc;
@@ -269,11 +303,52 @@ class Rpt_Data_Extractor {
             let rationGLJDatas = getModuleDataByKey(rawDataObj.prjData, "ration_glj");
             let rationGLJDatas = getModuleDataByKey(rawDataObj.prjData, "ration_glj");
             let rationDatas = getModuleDataByKey(rawDataObj.prjData, "ration");
             let rationDatas = getModuleDataByKey(rawDataObj.prjData, "ration");
             let billsDatas = getModuleDataByKey(rawDataObj.prjData, "bills");
             let billsDatas = getModuleDataByKey(rawDataObj.prjData, "bills");
+            let contractorDatas = getModuleDataByKey(rawDataObj.prjData, "contractor_list");
             let decimal = rawDataObj.prj.property.decimal.glj.quantity;
             let decimal = rawDataObj.prj.property.decimal.glj.quantity;
             let calcOptions = rawDataObj.prj.property.calcOptions;
             let calcOptions = rawDataObj.prj.property.calcOptions;
             if (projectGLJDatas && rationGLJDatas && rationDatas && billsDatas) {
             if (projectGLJDatas && rationGLJDatas && rationDatas && billsDatas) {
                 gljUtil.calcProjectGLJQuantity(projectGLJDatas.data, rationGLJDatas.data, rationDatas.data, billsDatas.data, decimal, true);
                 gljUtil.calcProjectGLJQuantity(projectGLJDatas.data, rationGLJDatas.data, rationDatas.data, billsDatas.data, decimal, true);
             }
             }
+            if (contractorDatas && projectGLJDatas && billsDatas) {
+                let ttlFee = 0;
+                for (const bd of billsDatas.data) {
+                    let doc = bd._doc ? bd._doc : bd;
+                    let hasTtl = false;
+                    if (doc.flags && doc.flags.length > 0) {
+                        for (const flag of doc.flags) {
+                            let flagDoc = flag._doc ? flag._doc : flag;
+                            if (flagDoc.flag === fixedFlag.ENGINEERINGCOST) {
+                                hasTtl = true;
+                                break;
+                            }
+                        }
+                    }
+                    if (hasTtl) {
+                        for (const fee of bd.fees) {
+                            let feeDoc = fee._doc ? fee._doc : fee;                            
+                            if (feeDoc.fieldName === 'common') {
+                                // console.log(feeDoc);
+                                ttlFee = feeDoc.totalFee;
+                                break;
+                            }
+                        }
+                        break;
+                    }
+                }
+                // fsUtil.writeObjToFile(gljUtil.getPriceCoeDatas(projectGLJDatas.data.gljList, contractorDatas.data, ttlFee, rawDataObj.prj.property, _, scMathUtil), "D:/GitHome/temp/建筑承包人Rawdata1.js");
+                // fsUtil.writeObjToFile(gljUtil.getPirceInfoDatas(projectGLJDatas.data.gljList, contractorDatas.data, labourCoeDatas, rawDataObj.prj.property, _, scMathUtil), "D:/GitHome/temp/建筑承包人Rawdata2.js");
+                if (rawDataObj.prj.property.gljAdjustType === 'priceInfo') {
+                    // console.log('造价信息差额调整结果:');
+                    // console.log(coeRst);
+                    let coeRst = gljUtil.getPirceInfoDatas(projectGLJDatas.data.gljList, contractorDatas.data, labourCoeDatas, rawDataObj.prj.property, _, scMathUtil);
+                    contractorDatas.data = coeRst;
+                } else {
+                    let coeRst = gljUtil.getPriceCoeDatas(projectGLJDatas.data.gljList, contractorDatas.data, ttlFee, rawDataObj.prj.property, _, scMathUtil);
+                    console.log('价格指数差额调整结果:');
+                    console.log(coeRst);
+                    contractorDatas.data = coeRst;
+                }
+            }
             if (projectGLJDatas && rationGLJDatas && labourCoeDatas) {
             if (projectGLJDatas && rationGLJDatas && labourCoeDatas) {
                 //考虑调价情况
                 //考虑调价情况
                 const newAdjPriceArr = [];
                 const newAdjPriceArr = [];
@@ -1222,6 +1297,7 @@ function assembleFields(fieldList, rstDataArr, $PROJECT) {
 
 
 function shielded_exec_env($PROJECT, $ME, rptDataItemObj) {
 function shielded_exec_env($PROJECT, $ME, rptDataItemObj) {
     if ($ME[JV.PROP_FIELD_EXP_MAP]) {
     if ($ME[JV.PROP_FIELD_EXP_MAP]) {
+        // console.log('$ME[JV.PROP_FIELD_EXP_MAP]: ' + $ME[JV.PROP_FIELD_EXP_MAP]);
         rptDataItemObj.push(eval($ME[JV.PROP_FIELD_EXP_MAP]));
         rptDataItemObj.push(eval($ME[JV.PROP_FIELD_EXP_MAP]));
     }
     }
 }
 }
@@ -1691,4 +1767,4 @@ function replaceActDataArr(dtObj, newArr) {
     }
     }
 }
 }
 
 
-module.exports = Rpt_Data_Extractor;
+module.exports = Rpt_Data_Extractor;

+ 11 - 1
public/gljUtil.js

@@ -22,7 +22,9 @@ module.exports = {
     getEconomicDatas:getEconomicDatas,
     getEconomicDatas:getEconomicDatas,
     getMainMaterialDatas:getMainMaterialDatas,
     getMainMaterialDatas:getMainMaterialDatas,
     getQuantityDatas:getQuantityDatas,
     getQuantityDatas:getQuantityDatas,
-    getTenderPriceCoe:getTenderPriceCoe
+    getTenderPriceCoe:getTenderPriceCoe,
+    getPriceCoeDatas:getPriceCoeDatas,
+    getPirceInfoDatas: getPirceInfoDatas,
 };
 };
 
 
 function calcProjectGLJQuantity(projectGLJDatas,rationGLJDatas,rationDatas,billsDatas,q_decimal) {
 function calcProjectGLJQuantity(projectGLJDatas,rationGLJDatas,rationDatas,billsDatas,q_decimal) {
@@ -75,4 +77,12 @@ function getQuantityDatas(engineerFeatures,mainQuantities,billsList,fixedFlag,_,
 
 
 function getTenderPriceCoe(glj,tproperty){
 function getTenderPriceCoe(glj,tproperty){
   return gljNodeUtil.getTenderPriceCoe(glj,tproperty);
   return gljNodeUtil.getTenderPriceCoe(glj,tproperty);
+}
+
+function getPriceCoeDatas(pgljList, contractorList, totalFee, tprojectProperty,_,scMathUtil){
+   return gljNodeUtil.getPriceCoeDatas(pgljList, contractorList, totalFee, tprojectProperty,_,scMathUtil);
+}
+
+function getPirceInfoDatas(projectGLJList, contractor_list, labourCoeDatas, projectProperty, _, scMathUtil) {
+    return gljNodeUtil.getPirceInfoDatas(projectGLJList, contractor_list, labourCoeDatas, projectProperty, _, scMathUtil);
 }
 }

+ 47 - 1
public/web/common_util.js

@@ -90,4 +90,50 @@ function deletePropNames(object, namesArr) {
     for (let name of namesArr){
     for (let name of namesArr){
         if (object[name]) delete object[name];
         if (object[name]) delete object[name];
     };
     };
-};
+};
+
+
+function sortTreeChildren(lists) {//树结构排序
+    let IDMap ={},nextMap = {}, firstNode = null,newList=[];
+    for(let l of lists){
+        if(l.children&&l.children.length > 0) l.children = sortTreeChildren(l.children);//递规排序
+        IDMap[l.ID] = l;
+        if(l.NextSiblingID!=-1) nextMap[l.NextSiblingID] = l;
+    }
+    for(let t of lists){
+        if(!nextMap[t.ID]){ //如果在下一节点映射没找到,则是第一个节点
+            firstNode = t;
+            break;
+        }
+    }
+    if(firstNode){
+        newList.push(firstNode);
+        delete IDMap[firstNode.ID];
+        setNext(firstNode,newList);
+    }
+    //容错处理,如果链断了的情况,直接添加到后面
+    for(let key in IDMap){
+        if(IDMap[key]) newList.push(IDMap[key])
+    }
+    return newList;
+
+    function setNext(node,array) {
+        if(node.NextSiblingID != -1){
+            let next = IDMap[node.NextSiblingID];
+            if(next){
+                array.push(next);
+                delete IDMap[next.ID];
+                setNext(next,array);
+            }
+        }
+    }
+} 
+
+function setTreeChildren(children,list,parentMap){//按顺序设置树节点
+    for(let c of children){
+      list.push(c);
+      if(parentMap[c.ID]){
+        setTreeChildren(parentMap[c.ID],list,parentMap)
+      }
+    }
+  }

+ 141 - 11
public/web/gljUtil.js

@@ -218,9 +218,16 @@ let gljUtil = {
             let p =0;
             let p =0;
             for(let ratio of glj.ratio_data){
             for(let ratio of glj.ratio_data){
                 let rIndex = gljUtil.getIndex(ratio);
                 let rIndex = gljUtil.getIndex(ratio);
-                let tem =  _.find(projectGLJDatas.gljList,function(item){
-                    return rIndex == gljUtil.getIndex(item)
-                });
+                let tem = null;
+                if(projectGLJDatas.gljMap){
+                    tem = projectGLJDatas.gljMap[rIndex]
+                }
+                if(!tem){
+                    tem =  _.find(projectGLJDatas.gljList,function(item){
+                        return rIndex == gljUtil.getIndex(item)
+                    });
+                }
+              
                 if(tem){
                 if(tem){
                     let tem_marketPrice = this.getMarketPrice(tem,projectGLJDatas,calcOptions,decimalObj,true,_,scMathUtil);  //let priceData=this.getGLJPrice(tem,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,true,_,scMathUtil);
                     let tem_marketPrice = this.getMarketPrice(tem,projectGLJDatas,calcOptions,decimalObj,true,_,scMathUtil);  //let priceData=this.getGLJPrice(tem,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,true,_,scMathUtil);
                     let temP = scMathUtil.roundForObj(
                     let temP = scMathUtil.roundForObj(
@@ -282,9 +289,15 @@ let gljUtil = {
             let p =0;
             let p =0;
             for(let ratio of glj.ratio_data){
             for(let ratio of glj.ratio_data){
                 let rIndex = gljUtil.getIndex(ratio);
                 let rIndex = gljUtil.getIndex(ratio);
-                let tem =  _.find(projectGLJDatas.gljList,function(item){
-                    return rIndex == gljUtil.getIndex(item);
-                });
+                let tem = null;
+                if(projectGLJDatas.gljMap){
+                    tem = projectGLJDatas.gljMap[rIndex]
+                }
+                if(!tem){
+                    tem =  _.find(projectGLJDatas.gljList,function(item){
+                        return rIndex == gljUtil.getIndex(item);
+                    });
+                }
                 if(tem){
                 if(tem){
                     let priceData=this.getGLJPrice(tem,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,true,_,scMathUtil);
                     let priceData=this.getGLJPrice(tem,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,true,_,scMathUtil);
                     let temP = scMathUtil.roundForObj(priceData.adjustPrice*scMathUtil.roundForObj(ratio.consumption,quantity_decimal),process_decimal);
                     let temP = scMathUtil.roundForObj(priceData.adjustPrice*scMathUtil.roundForObj(ratio.consumption,quantity_decimal),process_decimal);
@@ -314,16 +327,23 @@ let gljUtil = {
     isDef:function (v) {
     isDef:function (v) {
         return v !== undefined && v !== null;
         return v !== undefined && v !== null;
     },
     },
+    nullString(key){
+        return (key === undefined || key === null || key === '') ? 'null' : key
+      },
     getIndex(obj, pops){
     getIndex(obj, pops){
         let t_index = '';
         let t_index = '';
         let k_arr = [];
         let k_arr = [];
         if(!pops) pops = this.gljKeyArray;
         if(!pops) pops = this.gljKeyArray;
-        for (let p of pops) {
-            let tmpK = (obj[p] == undefined || obj[p] == null || obj[p] == '') ? 'null' : obj[p];
-            k_arr.push(tmpK);
+        if(pops.length === 5){
+            return `${this.nullString(obj[pops[0]])}|-|${this.nullString(obj[pops[1]])}|-|${this.nullString(obj[pops[2]])}|-|${this.nullString(obj[pops[3]])}|-|${this.nullString(obj[pops[4]])}`
+        }else{
+            for (let p of pops) {
+                let tmpK = (obj[p] == undefined || obj[p] == null || obj[p] == '') ? 'null' : obj[p];
+                k_arr.push(tmpK);
+            }
+            t_index = k_arr.join("|-|");
+            return t_index;
         }
         }
-        t_index = k_arr.join("|-|");
-        return t_index;
     },
     },
     getGljTypeSeq:function () {
     getGljTypeSeq:function () {
         let gljType = this.gljType;
         let gljType = this.gljType;
@@ -570,6 +590,7 @@ let gljUtil = {
                 exportName:m.exportName,
                 exportName:m.exportName,
                 quantity:0
                 quantity:0
             };
             };
+            console.log(m.coe);
             if(billsGroup[m.name]) setQuantities(billsGroup[m.name],tem);
             if(billsGroup[m.name]) setQuantities(billsGroup[m.name],tem);
 
 
             datas.push(tem);
             datas.push(tem);
@@ -583,6 +604,13 @@ let gljUtil = {
                 quantity = scMathUtil.roundForObj(quantity +  i.quantity,decimal.process);
                 quantity = scMathUtil.roundForObj(quantity +  i.quantity,decimal.process);
             }
             }
             data.quantity = gljUtil.calUnitWidthCoe(quantity,false,engineerFeatures,_,scMathUtil);
             data.quantity = gljUtil.calUnitWidthCoe(quantity,false,engineerFeatures,_,scMathUtil);
+             //主要工程量指标另外加了一个系数
+            let f = _.find(engineerFeatures,{index:true});
+            if(f){
+                let quantityCoe = gljUtil.isDef(f.quantityCoe)?f.quantityCoe:1;
+                data.quantity = scMathUtil.roundForObj(data.quantity*quantityCoe,3);
+            }
+           
         }
         }
 
 
         return datas;
         return datas;
@@ -626,6 +654,108 @@ let gljUtil = {
       let infoPrice = info[fieldArray[0]];
       let infoPrice = info[fieldArray[0]];
       if(!this.isDef(infoPrice)) infoPrice= info[fieldArray[1]];//信息价只有一个价格(含税价/不含税价),则不分计税方式,套用仅有的价格。
       if(!this.isDef(infoPrice)) infoPrice= info[fieldArray[1]];//信息价只有一个价格(含税价/不含税价),则不分计税方式,套用仅有的价格。
       return parseFloat(infoPrice);
       return parseFloat(infoPrice);
+    },
+    getPirceInfoDatas: function (projectGLJList, contractor_list, labourCoeDatas, projectProperty, _, scMathUtil) {
+        let datas = [];
+        let pgljList = projectGLJList;
+        let contractorList = contractor_list;
+        let calcOptions=projectProperty.calcOptions;
+        let decimalObj = projectProperty.decimal; 
+        let billsDecimal = decimalObj.bills.totalPrice;
+        let gljMap = _.indexBy(pgljList, 'id');
+        for (let e of contractorList) {
+            let t = {
+            ID: e.ID,
+            projectID: e.projectID,
+            is_related: e.is_related, //关联,1关,0不关
+            projectGLJID: e.projectGLJID, //关联工料机ID
+            seq: e.seq, //序号
+            code: e.code,
+            name: e.name,
+            specs: e.specs,
+            unit: e.unit,
+            type: e.type,
+            marketPrice: e.market_price,
+            quantity: e.quantity,
+            remark: e.remark,
+            supply: e.supply,
+            riskCoe: e.riskCoe,
+            is_evaluate: 0,
+            standardPrice: e.standardPrice
+            };
+            let pglj = gljMap[e.projectGLJID];
+            /*
+            if (e.is_related && pglj) {
+                gljOprObj.setGLJPrice(t, pglj);
+                t.vender = pglj.vender;
+                t.supply = pglj.supply;
+                t.is_evaluate = pglj.is_evaluate;
+                t.quantity = pglj.quantity;
+            }
+            /*/
+            if (e.is_related && pglj) {
+                let tenderCoe = gljUtil.getTenderPriceCoe(pglj,projectProperty);
+                let result = gljUtil.getGLJPrice(pglj, {gljList:pgljList}, calcOptions, labourCoeDatas, decimalObj, false, _, scMathUtil, tenderCoe);
+                t.marketPrice = result.marketPrice;
+                t.tenderPrice = result.tenderPrice;
+                t.basePrice =  result.basePrice;
+                t.adjustPrice = result.adjustPrice;
+                t.marketUnitFee = t.marketPrice;//更新树节点市场单价列的值
+                t.taxRate = pglj.unit_price.taxRate;//税率
+                  
+                t.vender = pglj.vender;
+                t.supply = pglj.supply;
+                t.quantity = pglj.quantity;
+                t.is_evaluate = pglj.is_evaluate;
+            }
+            //*/
+            t.totalPrice = scMathUtil.roundForObj(parseFloat(t.quantity) * parseFloat(t.marketPrice), billsDecimal);
+            datas.push(t);
+        }
+        return _.sortByAll(datas, 'code');
+    },
+    getPriceCoeDatas: function (projectGLJList, contractor_list, totalFee, projectProperty,_,scMathUtil) {
+        let datas = [];
+        let pgljList = projectGLJList ;
+        let contractorList = contractor_list ;
+        let decimalObj = projectProperty.decimal;  
+        let calcOptions=projectProperty.calcOptions;
+        let billsDecimal =  decimalObj.bills.totalPrice ;
+        let gljMap = _.indexBy(pgljList, 'id');
+        for (let e of contractorList) {
+          let t = {
+            ID: e.ID,
+            projectID: e.projectID,
+            is_related: e.is_related, //关联,1关,0不关
+            projectGLJID: e.projectGLJID, //关联工料机ID
+            seq: e.seq, //序号
+            code: e.code,
+            name: e.name,
+            specs: e.specs,
+            unit: e.unit,
+            type: e.type,
+            marketPrice: e.market_price,
+            quantity: e.quantity,
+            remark: e.remark,
+            supply: e.supply,
+            is_evaluate: 0,
+            FO: e.FO,
+            FI: e.FI
+          };
+          let pglj = gljMap[e.projectGLJID];
+          if (e.is_related && pglj) {
+            let tenderCoe = gljUtil.getTenderPriceCoe(pglj,projectProperty);
+            t.marketPrice = gljUtil.getMarketPrice(pglj,{gljList:pgljList},calcOptions,decimalObj,false,_,scMathUtil,tenderCoe);
+            t.vender = pglj.vender;
+            t.supply = pglj.supply;
+            t.quantity = pglj.quantity;
+            t.is_evaluate = pglj.is_evaluate;
+          }
+          t.totalPrice = scMathUtil.roundForObj(parseFloat(t.quantity) * parseFloat(t.marketPrice), billsDecimal);
+          if (totalFee !== 0) t.varWeight = scMathUtil.roundForObj(t.totalPrice / totalFee, 2);
+          datas.push(t);
+        }
+        return _.sortByAll(datas, 'code');
     },      
     },      
     fixedFlag : {
     fixedFlag : {
         // 分部分项工程
         // 分部分项工程

+ 35 - 9
public/web/scMathUtil.js

@@ -170,19 +170,44 @@ let scMathUtil = {
     isNumber : function (obj) {
     isNumber : function (obj) {
         return obj === +obj;
         return obj === +obj;
     },
     },
+
+    floatLength:function(num){
+        let lenght = 0;
+        let str =`${num}`;//me.isNumber(num)?num+"":num;
+        let sub = str.split(".")
+        if(sub.length == 2){
+            return sub[1].length;
+        }
+        return lenght
+    },
+
+    innerRound:function(num,lenght,decimal){
+        let value;
+        let pre = 1;
+        if(lenght === 0) return num;
+        if(num<0) pre = -1;//负数的时候先变成正数
+        num = num*pre;
+        let n = Math.pow(10,lenght);
+        value = Math.round(num * n)
+        if(lenght <= decimal){
+            return value/n*pre
+        }else{
+            value = Math.round(value/Math.pow(10,lenght-decimal))
+            return value/Math.pow(10,decimal)*pre
+        }
+    },
+
     roundForObj:function(obj,decimal){
     roundForObj:function(obj,decimal){
         let me = this;
         let me = this;
-        let value;
         if(obj === undefined || obj === null || isNaN(obj)) return 0;
         if(obj === undefined || obj === null || isNaN(obj)) return 0;
-        let n = Math.pow(10,decimal);
+        let lenght = 10;
+        let value;
         if(me.isNumber(obj)){
         if(me.isNumber(obj)){
-          value = Math.round(obj * n) / n;
-          //value = me.roundTo(obj,-decimal)
-        }else {
-          value = Math.round(Number(obj) * n) / n;
-          //value = me.roundTo(Number(obj),-decimal);
+            value =  me.innerRound(obj,lenght,decimal);
+        }else{
+            value = me.innerRound(Number(obj),lenght,decimal);
         }
         }
-        return value
+        return value;
     },
     },
     roundToString:function(obj,decimal){
     roundToString:function(obj,decimal){
         let me = this;
         let me = this;
@@ -222,5 +247,6 @@ Number.prototype.toDecimal = function (ADigit) {
     // var s = scMathUtil.roundTo(this, digit);
     // var s = scMathUtil.roundTo(this, digit);
     // console.log('Number: ' + this + '   Digit: ' + digit + '    Result: ' + s);
     // console.log('Number: ' + this + '   Digit: ' + digit + '    Result: ' + s);
     // return parseFloat(s);
     // return parseFloat(s);
-    return scMathUtil.roundTo(this, digit);
+    //scMathUtil.roundTo(this, digit);
+    return scMathUtil.roundForObj(this, -digit); 
 };
 };

+ 12 - 5
public/web/sheet/sheet_common.js

@@ -76,7 +76,9 @@ var sheetCommonObj = {
         };
         };
         let spanSetting =   sheetCommonObj.transferToTreeSetting(setting,temSetting);
         let spanSetting =   sheetCommonObj.transferToTreeSetting(setting,temSetting);
         TREE_SHEET_HELPER.loadSheetHeader(spanSetting,sheet,rowCount);
         TREE_SHEET_HELPER.loadSheetHeader(spanSetting,sheet,rowCount);
-
+      /*   sheet.options.protectionOptions = {
+            allowResizeColumns: true//列宽可拖动
+        }; */
     },
     },
 
 
 
 
@@ -333,7 +335,7 @@ var sheetCommonObj = {
             let options = data[row].options ? data[row].options.split("@") : [];
             let options = data[row].options ? data[row].options.split("@") : [];
             this.setComboBox(row,data[row].dateCol,sheet,options);
             this.setComboBox(row,data[row].dateCol,sheet,options);
         }
         }
-
+        this.setRowStyle(row, sheet, data[row].bgColour);
         for (var col = 0; col < setting.header.length; col++) {
         for (var col = 0; col < setting.header.length; col++) {
             //var cell = sheet.getCell(row, col, GC.Spread.Sheets.SheetArea.viewport);
             //var cell = sheet.getCell(row, col, GC.Spread.Sheets.SheetArea.viewport);
             var val = _.get(data[row],setting.header[col].dataCode);
             var val = _.get(data[row],setting.header[col].dataCode);
@@ -386,8 +388,13 @@ var sheetCommonObj = {
                 val = setting.getText[setting.header[col].getText](data[row],val)
                 val = setting.getText[setting.header[col].getText](data[row],val)
             }
             }
             sheet.setValue(row, col, val, ch);
             sheet.setValue(row, col, val, ch);
+            if(setting.getStyle && setting.getStyle(data[row],row,null,setting.header[col].dataCode)){
+                let cstyle = setting.getStyle(data[row],row,null,setting.header[col].dataCode);
+                if(cstyle){
+                    sheet.setStyle(row, col,cstyle);
+                }   
+            }
         }
         }
-        this.setRowStyle(row,sheet,data[row].bgColour);
         if(setting.autoFit==true){//设置自动行高
         if(setting.autoFit==true){//设置自动行高
             if(setting.fitRow && setting.fitRow.length > 0){//如果有设置特定的某些列才需要自动行高就按设置的来,没有设置就默认所有列
             if(setting.fitRow && setting.fitRow.length > 0){//如果有设置特定的某些列才需要自动行高就按设置的来,没有设置就默认所有列
                 for(let dataCode of setting.fitRow){
                 for(let dataCode of setting.fitRow){
@@ -401,7 +408,7 @@ var sheetCommonObj = {
             sheet.autoFitRow(row);
             sheet.autoFitRow(row);
         }
         }
         if(setting.getStyle && setting.getStyle(data[row],row,sheet.getActiveRowIndex())){
         if(setting.getStyle && setting.getStyle(data[row],row,sheet.getActiveRowIndex())){
-          sheet.setStyle(row, -1, setting.getStyle(data[row]));
+          sheet.setStyle(row, -1, setting.getStyle(data[row],row,sheet.getActiveRowIndex()));
         }
         }
     },
     },
     checkData : function(col,setting, value) {
     checkData : function(col,setting, value) {
@@ -1158,7 +1165,7 @@ var sheetCommonObj = {
         return new TreeNodeCellType()
         return new TreeNodeCellType()
 
 
         function getTreeLevel(item,data) {
         function getTreeLevel(item,data) {
-            if(item.ParentID && item.ParentID!=-1){
+            if(item && item.ParentID && item.ParentID!=-1){
                 let pitem =  _.find(data,{'ID':item.ParentID});
                 let pitem =  _.find(data,{'ID':item.ParentID});
                 return  getTreeLevel(pitem,data) + 1;
                 return  getTreeLevel(pitem,data) + 1;
             }else {
             }else {

+ 1 - 1
public/web/sheet/sheet_data_helper.js

@@ -333,7 +333,7 @@ var SheetDataHelper = {
                     $(div).css("position", "absolute")
                     $(div).css("position", "absolute")
                         .css("border", "1px #C0C0C0 solid")
                         .css("border", "1px #C0C0C0 solid")
                         .css("box-shadow", "1px 2px 5px rgba(0,0,0,0.4)")
                         .css("box-shadow", "1px 2px 5px rgba(0,0,0,0.4)")
-                        .css("font", "0.9rem Calibri")
+                        .css("font", "14px Calibri")
                         .css("background", "Black")
                         .css("background", "Black")
                         .css("color", "White")
                         .css("color", "White")
                         .css("padding", 5)
                         .css("padding", 5)

+ 1 - 1
web/building_saas/complementary_glj_lib/html/tools-gongliaoji.html

@@ -20,7 +20,7 @@
     <style type="text/css">
     <style type="text/css">
         .ztree * {
         .ztree * {
             font-family: Calibri;
             font-family: Calibri;
-            font-size: 0.9rem;
+            font-size: 14px;
         }
         }
         .modal-lg{max-width: 1000px}
         .modal-lg{max-width: 1000px}
     </style>
     </style>

+ 3 - 1
web/building_saas/complementary_glj_lib/js/glj.js

@@ -788,7 +788,9 @@ let repositoryGljObj = {
         // 输入编号、名称、规格时,如果输入回车符或粘贴回车符,提交时应转换为空格。
         // 输入编号、名称、规格时,如果输入回车符或粘贴回车符,提交时应转换为空格。
         let deESCFields = ['code', 'name', 'specs'];
         let deESCFields = ['code', 'name', 'specs'];
         if (deESCFields.includes(me.setting.header[args.col]['dataCode'])) {
         if (deESCFields.includes(me.setting.header[args.col]['dataCode'])) {
-            args.editingText = me.isDef(args.editingText) ? args.editingText.toString().replace(/[\r\n]/g, ' ') : '';
+            args.editingText = me.isDef(args.editingText) 
+                ? args.editingText.toString().replace(/[\r\n]/g, ' ').replace(/\s$/, '')
+                : '';
             args.sheet.setValue(args.row, args.col, args.editingText);
             args.sheet.setValue(args.row, args.col, args.editingText);
         }
         }
         let rObj = sheetOpr.combineRowData(me.workBook.getSheet(0), me.setting, args.row, me),
         let rObj = sheetOpr.combineRowData(me.workBook.getSheet(0), me.setting, args.row, me),

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

@@ -37,7 +37,7 @@
         }
         }
         .ztree * {
         .ztree * {
             font-family: Calibri;
             font-family: Calibri;
-            font-size: 0.9rem;
+            font-size: 14px;
         }
         }
         .nav-tabs .nav-item.show .nav-link, .nav-tabs .nav-link.active{
         .nav-tabs .nav-item.show .nav-link, .nav-tabs .nav-link.active{
             border: 2px solid #ff6501;
             border: 2px solid #ff6501;

+ 6 - 5
web/building_saas/css/custom.css

@@ -27,13 +27,13 @@ div.resize-x{
   cursor: w-resize;
   cursor: w-resize;
   float: left;
   float: left;
 }
 }
-/*.zlfb-check{
+.zlfb-check{
   margin-left: 20px;
   margin-left: 20px;
-}*/
+}
 legend.legend{
 legend.legend{
   display:block;
   display:block;
   width:auto;
   width:auto;
-  font-size:0.9rem;
+  font-size:14px;
   top:-15px;
   top:-15px;
   background: white;
   background: white;
 }
 }
@@ -83,7 +83,7 @@ legend.legend{
   line-height: 18px;
   line-height: 18px;
   border-radius:4px;
   border-radius:4px;
   text-align:left;
   text-align:left;
-  font:0.9rem Calibri;
+  font:14px Calibri;
   box-shadow:2px 2px 6px #ccc;
   box-shadow:2px 2px 6px #ccc;
   color:#fff;
   color:#fff;
 }
 }
@@ -527,4 +527,5 @@ margin-right: 100px !important;
 
 
 .inline-wrapper .inline-tools {
 .inline-wrapper .inline-tools {
   display: inline-block;
   display: inline-block;
-}
+}
+

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

@@ -1,7 +1,7 @@
 /*building SAAS 0.1*/
 /*building SAAS 0.1*/
 /*bootstrap 初始化*/
 /*bootstrap 初始化*/
 body {
 body {
-  font-size: 0.9rem;
+  font-size: 14px;
   overflow: hidden;
   overflow: hidden;
   font-family: "Helvetica Neue","Hiragino Sans GB",stheiti,"Microsoft Yahei","微软雅黑",tahoma,sans-serif
   font-family: "Helvetica Neue","Hiragino Sans GB",stheiti,"Microsoft Yahei","微软雅黑",tahoma,sans-serif
 }
 }
@@ -9,7 +9,7 @@ a{
 outline: none
 outline: none
 }
 }
 .dropdown-menu {
 .dropdown-menu {
-  font-size: 0.9rem
+  font-size: 14px
 }
 }
 .btn.disabled, .btn:disabled {
 .btn.disabled, .btn:disabled {
 color:#999
 color:#999

+ 107 - 34
web/building_saas/main/html/main.html

@@ -31,7 +31,7 @@
   <style type="text/css">
   <style type="text/css">
     .ztree * {
     .ztree * {
       font-family: Calibri;
       font-family: Calibri;
-      font-size: 0.9rem;
+      font-size: 14px;
     }
     }
   </style>
   </style>
   <script>
   <script>
@@ -137,8 +137,18 @@
                     <a class="dropdown-item btn-sm" href="javascript:void(0);" id="displayZM">子目</a>
                     <a class="dropdown-item btn-sm" href="javascript:void(0);" id="displayZM">子目</a>
                     <a class="dropdown-item btn-sm" href="javascript:void(0);" id="displayZD">最底层</a>
                     <a class="dropdown-item btn-sm" href="javascript:void(0);" id="displayZD">最底层</a>
                   </div>
                   </div>
-                  <a href="javascript:void(0);" id="ZLFB_btn" class="dropdown-item" data-placement="bottom"
-                    style="display: none;"><i class="fa fa-retweet" aria-hidden="true"></i> 整理分部</a>
+                  <!-- <a href="javascript:void(0);" id="ZLFB_btn" class="dropdown-item" data-placement="bottom"><i class="fa fa-retweet" aria-hidden="true"></i> 整理清单</a> -->
+                  <a  href="javascript:void(0);" id="ZLFB_MENU" data-toggle="dropdown"  class="dropdown-item dropdown-toggle"><i class="fa fa-retweet" aria-hidden="true"></i> 整理清单</a>
+                  <div style="position: relative;">
+                    <div id="ZLFB_MENU_sub" class="dropdown-menu dropdown-menu-left"
+                    style="min-width: 6.5rem; position: absolute; transform: translate3d(158px, 3px, 0px); top: -40px; left: 0px; will-change: transform;"
+                    x-placement="right-start">
+                    <a class="dropdown-item btn-sm" href="javascript:void(0);" id="ZLFB_btn" >分部整理</a>
+                    <a class="dropdown-item btn-sm" href="javascript:void(0);" id="ZLQD_btn" >清单整理</a>
+                  
+                  </div>
+                  </div>
+
                   <% if (region === '重庆市' || region === '广东省') { %>
                   <% if (region === '重庆市' || region === '广东省') { %>
                   <a id="interface-dropdown" href="javascript:void(0);" data-toggle="dropdown"
                   <a id="interface-dropdown" href="javascript:void(0);" data-toggle="dropdown"
                     class="dropdown-item dropdown-toggle"><i class="fa fa-list-ol"></i> 数据接口...</a>
                     class="dropdown-item dropdown-toggle"><i class="fa fa-list-ol"></i> 数据接口...</a>
@@ -387,13 +397,13 @@
                         <div class=" ovf-hidden" style="" id="mbzmSpread"></div>
                         <div class=" ovf-hidden" style="" id="mbzmSpread"></div>
                       </div>
                       </div>
                       <div class="main-data-bottom ovf-hidden" style="display: none" id="comments">
                       <div class="main-data-bottom ovf-hidden" style="display: none" id="comments">
-                        <textarea style="font-size: 0.9rem" class="form-control" rows="8" readonly=""></textarea>
+                        <textarea style="font-size: 14px" class="form-control" rows="8" readonly=""></textarea>
                       </div>
                       </div>
                       <div id="tzjnrCon" class="container-fluid main-data-bottom"
                       <div id="tzjnrCon" class="container-fluid main-data-bottom"
-                        style="background: #F1F1F1; overflow: hidden">
+                        style="float: left; width: 66%; background: #F1F1F1; overflow: hidden">
                         <div class="row" style="overflow: hidden">
                         <div class="row" style="overflow: hidden">
                           <div class="p-0" id="contentDiv" style="width: 90%; float: left">
                           <div class="p-0" id="contentDiv" style="width: 90%; float: left">
-                            <div id="jobDiv" style="width: 33%; height: 100%;float: left">
+                            <div id="jobDiv" style="width: 39%; height: 100%;float: left">
                               <div class="main-data-bottom ovf-hidden" id="jobSpread"
                               <div class="main-data-bottom ovf-hidden" id="jobSpread"
                                 style="width: 99%; float: left; position: relative">
                                 style="width: 99%; float: left; position: relative">
                                 <!--工具栏-->
                                 <!--工具栏-->
@@ -417,7 +427,7 @@
                               </div>
                               </div>
                               <div class="resize-x" id="TZJNRResize"></div>
                               <div class="resize-x" id="TZJNRResize"></div>
                             </div>
                             </div>
-                            <div id="itemDiv" style="width: 67%; height: 100%; float: left;">
+                            <div id="itemDiv" style="width: 61%; height: 100%; float: left;">
                               <div class="main-data-bottom ovf-hidden" id="itemSpread" style="position: relative;">
                               <div class="main-data-bottom ovf-hidden" id="itemSpread" style="position: relative;">
                                 <!--工具栏-->
                                 <!--工具栏-->
                                 <div class="bottom-tznrTools btn-group position-absolute">
                                 <div class="bottom-tznrTools btn-group position-absolute">
@@ -896,7 +906,7 @@
                         <select class="form-control form-control-sm col-6" id="select_block_lib_names">
                         <select class="form-control form-control-sm col-6" id="select_block_lib_names">
                           <option>我的模板库</option>
                           <option>我的模板库</option>
                         </select>
                         </select>
-                        <div class="col-6">
+                        <div class="col-6 pl-1 pr-0">
                           <div class="d-inline">
                           <div class="d-inline">
                             <button type="button" class="btn btn-sm btn-secondary" data-toggle="dropdown"
                             <button type="button" class="btn btn-sm btn-secondary" data-toggle="dropdown"
                               aria-haspopup="true" aria-expanded="false" id="btn_block_newFolder">
                               aria-haspopup="true" aria-expanded="false" id="btn_block_newFolder">
@@ -938,6 +948,11 @@
                               </form>
                               </form>
                             </div>
                             </div>
                           </div>
                           </div>
+                          <div class="d-inline">
+                            <button type="button" class="btn btn-sm btn-secondary"
+                              id="btn_block_share" data-toggle="tooltip" data-placement="bottom" data-original-title="">
+                              分享
+                          </div>
                         </div>
                         </div>
                       </div>
                       </div>
                     </div>
                     </div>
@@ -1001,6 +1016,8 @@
                     role="tab" id="tab_poj-settings-basicInfo">基本信息</a></li>
                     role="tab" id="tab_poj-settings-basicInfo">基本信息</a></li>
                 <li class="nav-item ml-3"><a class="nav-link" data-toggle="pill" href="#compilationIllustrationP"
                 <li class="nav-item ml-3"><a class="nav-link" data-toggle="pill" href="#compilationIllustrationP"
                     role="tab" id="tab_compilation_illustration_p">编制说明</a></li>
                     role="tab" id="tab_compilation_illustration_p">编制说明</a></li>
+                 <li class="nav-item ml-3"><a class="nav-link" data-toggle="pill" href="#auditCompareTab"
+                      role="tab" id="tab_compare">审核对比</a></li>
                 <li class="nav-item"><a class="nav-link disabled">单位工程信息</a></li>
                 <li class="nav-item"><a class="nav-link disabled">单位工程信息</a></li>
                 <li class="nav-item ml-3"><a class="nav-link" data-toggle="pill" href="#poj-settings-projFeature"
                 <li class="nav-item ml-3"><a class="nav-link" data-toggle="pill" href="#poj-settings-projFeature"
                     id="tab_poj-settings-projFeature" role="tab">工程特征</a></li>
                     id="tab_poj-settings-projFeature" role="tab">工程特征</a></li>
@@ -1037,6 +1054,15 @@
                     <textarea class="form-control" rows="15"></textarea>
                     <textarea class="form-control" rows="15"></textarea>
                   </div>
                   </div>
                 </div>
                 </div>
+                <!--审核对比-->
+                <div class="tab-pane fade" id="auditCompareTab" role="tabpanel">
+                  <div class="modal-auto-height">
+                    <P>选择送审的项目:</P>
+                    <select class="form-control form-control-sm" style="width: 100%; font-size: .875rem" id="audiCompareID">
+                    </select>
+                    <div style="overflow: hidden;height: 330px;" id="compareProjectSpread"></div>
+                  </div>
+                </div>
                 <!--工程特征-->
                 <!--工程特征-->
                 <div class="tab-pane fade" id="poj-settings-projFeature" role="tabpanel">
                 <div class="tab-pane fade" id="poj-settings-projFeature" role="tabpanel">
                   <div class="modal-auto-height" style="overflow: hidden" id="projFeatureSpread">
                   <div class="modal-auto-height" style="overflow: hidden" id="projFeatureSpread">
@@ -1450,7 +1476,7 @@
           </div>
           </div>
         </div>
         </div>
         <div class="modal-footer" style="position: relative;">
         <div class="modal-footer" style="position: relative;">
-          <a href="/complementaryGlj" target="_blank" class="btn btn-primary"
+          <a href=<%- "/complementaryGlj/" + userID %> target="_blank" class="btn btn-primary"
             style="position: absolute; left: 20px">新增人材机</a>
             style="position: absolute; left: 20px">新增人材机</a>
           <a href="javascript:void(0);" id="glj_selected_conf" class="btn btn-primary">确定</a>
           <a href="javascript:void(0);" id="glj_selected_conf" class="btn btn-primary">确定</a>
           <a href="javascript:void(0);" id="replace_next_btn" class="btn btn-primary">下一步</a>
           <a href="javascript:void(0);" id="replace_next_btn" class="btn btn-primary">下一步</a>
@@ -1786,48 +1812,38 @@
     <div class="modal-dialog" role="document">
     <div class="modal-dialog" role="document">
       <div class="modal-content">
       <div class="modal-content">
         <div class="modal-header">
         <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">
           <button type="button" class="close" data-dismiss="modal" aria-label="Close">
             <span aria-hidden="true">&times;</span>
             <span aria-hidden="true">&times;</span>
           </button>
           </button>
         </div>
         </div>
         <div class="modal-body">
         <div class="modal-body">
-          <div class="form-check">
-            <input class="form-check-input zlfb-check" type="checkbox" id="bill_first">
+        
+          <div class="form-check zlfb-check">
+            <input class="form-check-input " type="checkbox"  id="bill_first">
             <label class="form-check-label">
             <label class="form-check-label">
               需要专业分部标题
               需要专业分部标题
             </label>
             </label>
           </div>
           </div>
-          <div class="form-check">
-            <input class="form-check-input zlfb-check" type="checkbox" checked id="bill_second">
+          <div class="form-check zlfb-check">
+            <input class="form-check-input " type="checkbox" checked  id="bill_second">
             <label class="form-check-label">
             <label class="form-check-label">
               需要章分部标题
               需要章分部标题
             </label>
             </label>
           </div>
           </div>
-          <div class="form-check">
-            <input class="form-check-input zlfb-check" type="checkbox" id="bill_third">
+          <div class="form-check zlfb-check">
+            <input class="form-check-input " type="checkbox"  id="bill_third">
             <label class="form-check-label">
             <label class="form-check-label">
               需要节分部标题
               需要节分部标题
             </label>
             </label>
           </div>
           </div>
-          <div class="form-check">
-            <input class="form-check-input zlfb-check" type="checkbox" checked disabled value="">
+          <div class="form-check zlfb-check">
+            <input class="form-check-input " type="checkbox" checked disabled>
             <label class="form-check-label">
             <label class="form-check-label">
               删除自定义分部标题
               删除自定义分部标题
             </label>
             </label>
           </div>
           </div>
-          <div class="form-check">
-            <input class="form-check-input zlfb-check" type="checkbox" checked id="bill_resort">
-            <label class="form-check-label">
-              清单排序
-            </label>
-          </div>
-          <div class="form-check">
-            <input class="form-check-input zlfb-check" type="checkbox" id="bill_recode">
-            <label class="form-check-label">
-              清单重新编码
-            </label>
-          </div>
+      
           <div class="card mt-3">
           <div class="card mt-3">
             <div class="card-body p-2">
             <div class="card-body p-2">
               <h5 class="card-title">操作说明</h5>
               <h5 class="card-title">操作说明</h5>
@@ -1836,8 +1852,6 @@
                 勾选“需要章分部标题”,表示分部整理时需要添加章标题;</br>
                 勾选“需要章分部标题”,表示分部整理时需要添加章标题;</br>
                 勾选“需要节分部标题”,表示分部整理时需要添加节标题;</br>
                 勾选“需要节分部标题”,表示分部整理时需要添加节标题;</br>
                 勾选“删除自定义分部标题”,将首先删除已有自定义分部标题,然后再执行分部整理;</br>
                 勾选“删除自定义分部标题”,将首先删除已有自定义分部标题,然后再执行分部整理;</br>
-                勾选“清单排序”,表示分部整理后对每个分部下的清单进行排序;</br>
-                勾选“清单重新编码”,表示分部整理后对每个分部下的清单重新生成流水号;
               </p>
               </p>
             </div>
             </div>
           </div>
           </div>
@@ -1850,6 +1864,53 @@
     </div>
     </div>
   </div>
   </div>
 
 
+<!--弹出 整理清单-->
+<div class="modal fade" id="zlqd" data-backdrop="static">
+  <div class="modal-dialog" role="document">
+    <div class="modal-content">
+      <div class="modal-header">
+        <h5 class="modal-title">清单整理</h5>
+        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+          <span aria-hidden="true">&times;</span>
+        </button>
+      </div>
+      <div class="modal-body">
+        <div class="form-check ">
+          <input class="form-check-input " type="checkbox" checked id="bill_resort">
+          <label class="form-check-label">
+            清单排序
+          </label>
+        </div>
+        <div class="form-check">
+          <input class="form-check-input" type="checkbox" id="bill_recode">
+          <label class="form-check-label">
+            清单重新编码
+          </label>
+          <label class="form-check-label">
+            起始编码
+          </label>
+          <input type="number" value="1" id="bill_recode_start" style="width: 50px;">
+        
+        </div>
+        <div class="card mt-3">
+          <div class="card-body p-2">
+            <h5 class="card-title">操作说明</h5>
+            <p class="card-text">
+              勾选“清单排序”,表示分部整理后对每个分部下的清单进行排序;</br>
+              勾选“清单重新编码”,表示分部整理后对每个分部下的清单重新生成流水号;
+            </p>
+          </div>
+        </div>
+      </div>
+      <div class="modal-footer">
+        <button type="button" class="btn btn-primary" id="zlqd_confirm">确定</button>
+        <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
+      </div>
+    </div>
+  </div>
+</div>
+
+
   <!--弹出 计取安装费用-->
   <!--弹出 计取安装费用-->
   <div class="modal fade" id="calc_installation_fee" data-backdrop="static">
   <div class="modal fade" id="calc_installation_fee" data-backdrop="static">
     <div class="modal-dialog modal-lg" style="max-width: 1100px" role="document">
     <div class="modal-dialog modal-lg" style="max-width: 1100px" role="document">
@@ -2016,8 +2077,18 @@
         </div>
         </div>
         <div class="modal-footer inline-wrapper">
         <div class="modal-footer inline-wrapper">
           <div class="inline-tools">
           <div class="inline-tools">
-            <button type="button" class="btn btn-primary" id="uploadExample-general">下载示例1</button>
-            <button type="button" class="btn btn-primary" id="uploadExample">下载示例2</button>
+            <div class="inline-tools btn-group" id="example-general">
+              <button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+                下载示例 <span class="caret"></span>
+              </button>
+              <ul class="dropdown-menu">
+                <li><a class="dropdown-item" href="javascript:;" id="uploadExample-general">下载通用Excel格式</a></li>
+                <li><a class="dropdown-item" href="javascript:;" id="uploadExample-lj">下载分部分项计价表格式</a></li>
+              </ul>
+            </div>
+            <div class="inline-tools hide-area" id="example-gld">
+              <button type="button" class="btn btn-primary" id="uploadExample-gld">下载示例</button>
+            </div>
           </div>
           </div>
           <div class="inline-tools">
           <div class="inline-tools">
             <a href="javascript:void(0);" class="btn btn-primary" id="importConfirm">确定导入</a>
             <a href="javascript:void(0);" class="btn btn-primary" id="importConfirm">确定导入</a>
@@ -2706,6 +2777,7 @@
               </button>
               </button>
           </div>
           </div>
           <div class="modal-body" style="height: 450px;padding: 0px">
           <div class="modal-body" style="height: 450px;padding: 0px">
+            <input type="hidden" id = "selectFBFor">
               <div class="ovf-hidden full-h" id="selectFBSheet" style="height: 100%;"></div>
               <div class="ovf-hidden full-h" id="selectFBSheet" style="height: 100%;"></div>
           </div>
           </div>
           <div class="modal-footer">
           <div class="modal-footer">
@@ -2840,6 +2912,7 @@
   <script type="text/javascript" src="/web/building_saas/main/js/views/project_property_projFeature.js"></script>
   <script type="text/javascript" src="/web/building_saas/main/js/views/project_property_projFeature.js"></script>
   <script type="text/javascript" src="/web/building_saas/main/js/views/project_property_indicativeInfo.js"></script>
   <script type="text/javascript" src="/web/building_saas/main/js/views/project_property_indicativeInfo.js"></script>
   <script type="text/javascript" src="/web/building_saas/main/js/views/project_property_display_view.js"></script>
   <script type="text/javascript" src="/web/building_saas/main/js/views/project_property_display_view.js"></script>
+  <script type="text/javascript" src="/web/building_saas/main/js/views/project_property_compare.js"></script>
   <script type="text/javascript" src="/web/building_saas/main/js/main_ajax.js"></script>
   <script type="text/javascript" src="/web/building_saas/main/js/main_ajax.js"></script>
   <script type="text/javascript" src="/web/building_saas/main/js/main.js"></script>
   <script type="text/javascript" src="/web/building_saas/main/js/main.js"></script>
   <script type="text/javascript" src="/web/building_saas/main/js/controllers/project_controller.js"></script>
   <script type="text/javascript" src="/web/building_saas/main/js/controllers/project_controller.js"></script>

+ 6 - 5
web/building_saas/main/js/controllers/block_controller.js

@@ -505,7 +505,7 @@ let BlockController = {
 
 
     preparePasteData : function (datas,billsIDMap,firstParentID,lastNextID,selected) {
     preparePasteData : function (datas,billsIDMap,firstParentID,lastNextID,selected) {
         let me = this;
         let me = this;
-        me.datas = _.cloneDeep(projectObj.project.Bills.datas);
+        me.datas = _.clone(projectObj.project.Bills.datas);
         let bills = [],rations=[],ration_gljs = [],ration_coes = [],quantity_details = [],ration_installations = [],ration_templates=[];
         let bills = [],rations=[],ration_gljs = [],ration_coes = [],quantity_details = [],ration_installations = [],ration_templates=[];
         let firstBillIDs = [],lastBillID = null;//记录第一层清单的ID,和第一层的最后一个清单ID
         let firstBillIDs = [],lastBillID = null;//记录第一层清单的ID,和第一层的最后一个清单ID
         let firstIDMap = {};
         let firstIDMap = {};
@@ -705,10 +705,11 @@ let BlockController = {
         let EXPString = ration.quantityEXP+"";
         let EXPString = ration.quantityEXP+"";
         if(EXPString.indexOf("QDL") != -1){
         if(EXPString.indexOf("QDL") != -1){
             if(EXPString=="QDL"){//定额的工程量是直接通过清单量填进来的;
             if(EXPString=="QDL"){//定额的工程量是直接通过清单量填进来的;
-                let  t_unit = ration.unit?ration.unit.replace(/^\d+/,""):"";
-                if(t_unit!=billsUnit){//如果定额的单位去除前面的数字后不等于清单单位,定额工程量保持不变
-                    return ;
-                }
+              // 冷姐姐说,克隆、复制整块与插入新定额逻辑分开。前者不管单位直接根据清单数量计算定额工程量。2021-01-12
+              // let  t_unit = ration.unit?ration.unit.replace(/^\d+/,""):"";
+                // if(t_unit!=billsUnit){//如果定额的单位去除前面的数字后不等于清单单位,定额工程量保持不变
+                //     return ;
+                // }
                 let times = parseInt(ration.unit);
                 let times = parseInt(ration.unit);
                 if(isNaN(times)){
                 if(isNaN(times)){
                     times = 1;
                     times = 1;

+ 5 - 5
web/building_saas/main/js/controllers/material_controller.js

@@ -215,22 +215,22 @@ let MaterialController = {
         sheetCommonObj.showData(this.sheet, this.setting,this.datas);
         sheetCommonObj.showData(this.sheet, this.setting,this.datas);
         this.sheet.setRowCount(this.datas.length);
         this.sheet.setRowCount(this.datas.length);
     },
     },
-    showItemCharacterText:function (node,eleID = 'itemCharacterText') {
+    showItemCharacterText:function (node, selector = '#itemCharacterText') {
         let text="";
         let text="";
         let selected = node?node:projectObj.project.mainTree.selected;
         let selected = node?node:projectObj.project.mainTree.selected;
         let parent = selected.parent;
         let parent = selected.parent;
-        if(eleID != 'itemCharacterText'){//如果是清单精灵里显示的,parent就是本身
+        if(selector != '#itemCharacterText'){//如果是清单精灵里显示的,parent就是本身
             parent = selected
             parent = selected
             $("#xmtz_billID").val(selected.data.ID);
             $("#xmtz_billID").val(selected.data.ID);
         }
         }
         if(selected&&parent) text = parent.data.itemCharacterText;
         if(selected&&parent) text = parent.data.itemCharacterText;
         
         
-        if(eleID != 'itemCharacterText'){
-          $("#"+eleID).val(text);
+        if(selector != '#itemCharacterText'){
+          $(selector).val(text);
         }else{
         }else{
           text = parent.data.itemCharacterText?parent.data.itemCharacterText.replace(/\n/g,"<br>"):"";
           text = parent.data.itemCharacterText?parent.data.itemCharacterText.replace(/\n/g,"<br>"):"";
           text = text.replace(/\s/g,"&nbsp;");
           text = text.replace(/\s/g,"&nbsp;");
-          $("#"+eleID).html(text);
+          $(selector).html(text);
         }  
         }  
       
       
 
 

+ 8 - 7
web/building_saas/main/js/controllers/project_controller.js

@@ -216,18 +216,18 @@ ProjectController = {
         if (!project || !sheetController) { return null; }
         if (!project || !sheetController) { return null; }
         this.addSpecialBill(project, sheetController,null, project.mainTree.selected.nextSibling,true,billType.DXFY);
         this.addSpecialBill(project, sheetController,null, project.mainTree.selected.nextSibling,true,billType.DXFY);
     },
     },
-    addFB:function(project, sheetController,node) {//添加分部
+    addFB:function(project, sheetController,node,ext) {//添加分部
         if (!project || !sheetController) { return null; }
         if (!project || !sheetController) { return null; }
         let selected =node|| project.mainTree.selected;
         let selected =node|| project.mainTree.selected;
         if(selected.parent==null&&isFlag(selected.data)&&selected.data.flagsIndex.fixed.flag==fixedFlag.SUB_ENGINERRING){//选中的是分部分项,则插入做为最后一个子项
         if(selected.parent==null&&isFlag(selected.data)&&selected.data.flagsIndex.fixed.flag==fixedFlag.SUB_ENGINERRING){//选中的是分部分项,则插入做为最后一个子项
-            return this.addSpecialBill(project, sheetController,selected, null,true,billType.FB);
+            return this.addSpecialBill(project, sheetController,selected, null,true,billType.FB,ext);
         }
         }
         if(selected.parent){
         if(selected.parent){
-            return this.addSpecialBill(project, sheetController,selected.parent, selected.nextSibling,true,billType.FB);
+            return this.addSpecialBill(project, sheetController,selected.parent, selected.nextSibling,true,billType.FB,ext);
         }
         }
 
 
     },
     },
-    addFXParent:async function(node){
+    addFXParent:async function(node,ext){
         let datas = [];
         let datas = [];
         //let parent = node.parent.parent;
         //let parent = node.parent.parent;
         let newBills = {
         let newBills = {
@@ -236,6 +236,8 @@ ProjectController = {
             'type':billType.FB,
             'type':billType.FB,
             'projectID':node.data.projectID
             'projectID':node.data.projectID
         }
         }
+        if(ext) gljUtil.setProperty(newBills,ext);
+        
         if(node.preSibling){//有前兄弟 在当前分项和前兄弟中间新增一行“分部”空行,空行作为分项的父项,原父项变为空行的前兄弟。
         if(node.preSibling){//有前兄弟 在当前分项和前兄弟中间新增一行“分部”空行,空行作为分项的父项,原父项变为空行的前兄弟。
             let changeParent = false;
             let changeParent = false;
             newBills.ParentID = node.parent.parent?node.parent.parent.getID():-1;
             newBills.ParentID = node.parent.parent?node.parent.parent.getID():-1;
@@ -268,7 +270,6 @@ ProjectController = {
     addFX:function(project, sheetController) {//添加分项
     addFX:function(project, sheetController) {//添加分项
         if (!project || !sheetController) { return null; }
         if (!project || !sheetController) { return null; }
         let selected = project.mainTree.selected;
         let selected = project.mainTree.selected;
-        console.log(selected);
         if(selected.data.type==billType.FB||(selected.parent==null&&isFlag(selected.data)&&selected.data.flagsIndex.fixed.flag==fixedFlag.SUB_ENGINERRING)){//选中的是分部或者是分部分项工程,则插入做为最后一个子项
         if(selected.data.type==billType.FB||(selected.parent==null&&isFlag(selected.data)&&selected.data.flagsIndex.fixed.flag==fixedFlag.SUB_ENGINERRING)){//选中的是分部或者是分部分项工程,则插入做为最后一个子项
             return this.addSpecialBill(project, sheetController,selected, null,true,billType.FX);
             return this.addSpecialBill(project, sheetController,selected, null,true,billType.FX);
         }
         }
@@ -278,14 +279,14 @@ ProjectController = {
             }
             }
         }
         }
     },
     },
-    addSpecialBill(project,sheetController,parent,nextSibling,isUserAdd,type){
+    addSpecialBill(project,sheetController,parent,nextSibling,isUserAdd,type,ext){
         let newSource = null, newNode = null;
         let newSource = null, newNode = null;
         let b_nexID = nextSibling==null?-1:nextSibling.source.getID();//主树和清单树,对应的树节点ID不一样
         let b_nexID = nextSibling==null?-1:nextSibling.source.getID();//主树和清单树,对应的树节点ID不一样
         let m_nexID = nextSibling==null?-1:nextSibling.getID();
         let m_nexID = nextSibling==null?-1:nextSibling.getID();
         let b_parent = parent==null?-1:parent.source.getID();
         let b_parent = parent==null?-1:parent.source.getID();
         let m_parent = parent==null?-1:parent.getID();
         let m_parent = parent==null?-1:parent.getID();
 
 
-        newSource = project.Bills.insertSpecialBill(b_parent, b_nexID,isUserAdd,type);
+        newSource = project.Bills.insertSpecialBill(b_parent, b_nexID,isUserAdd,type,ext);
         newNode = project.mainTree.insert(m_parent,m_nexID, newSource.data.ID);
         newNode = project.mainTree.insert(m_parent,m_nexID, newSource.data.ID);
         if (newNode) {
         if (newNode) {
             newNode.source = newSource;
             newNode.source = newSource;

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

@@ -30,9 +30,16 @@ $(function () {
         //refreshSubSpread();
         //refreshSubSpread();
     });
     });
 
 
-    $('#tab_report').on('shown.bs.tab', function(e){
+    $('#tab_report').on('shown.bs.tab', function(e){   
         sessionStorage.setItem('mainTab', '#tab_report');
         sessionStorage.setItem('mainTab', '#tab_report');
         autoFlashHeight();
         autoFlashHeight();
+        $.bootstrapLoading.start();
+        setTimeout(function(){
+            projectObj.project.calcProgram.doTenderCalc();   // 进入报表前先自动调价计算一遍
+            $.bootstrapLoading.end();
+        }, 100);
+       
+    
     });
     });
     let mainResizeEles = getMainResizeEles();
     let mainResizeEles = getMainResizeEles();
     SlideResize.verticalSlide(mainResizeEles.eleObj, mainResizeEles.limit, function(){
     SlideResize.verticalSlide(mainResizeEles.eleObj, mainResizeEles.limit, function(){

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

@@ -157,7 +157,7 @@ var Bills = {
             }
             }
             return updateData;
             return updateData;
         };
         };
-        bills.prototype.insertSpecialBill=function(parentId, nextSiblingId,isUserAdd,type){
+        bills.prototype.insertSpecialBill=function(parentId, nextSiblingId,isUserAdd,type,ext){
             var insertData = this.tree.getInsertData(parentId, nextSiblingId, true);
             var insertData = this.tree.getInsertData(parentId, nextSiblingId, true);
             var that = this, newData = null;
             var that = this, newData = null;
             insertData.forEach(function (data) {
             insertData.forEach(function (data) {
@@ -167,6 +167,7 @@ var Bills = {
                     }
                     }
                     data.data.type = type;
                     data.data.type = type;
                     newData = data.data;
                     newData = data.data;
+                    if(ext) gljUtil.setProperty(newData,ext);
                 }
                 }
             });
             });
             this.project.pushNow('insertBills', [this.getSourceType(), this.project.projCounter()],
             this.project.pushNow('insertBills', [this.getSourceType(), this.project.projCounter()],

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

@@ -599,7 +599,7 @@ var PROJECT = {
                         }
                         }
                     }
                     }
                 }else if(d.type == ModuleNames.project){
                 }else if(d.type == ModuleNames.project){
-                    temObj = this;
+                    temObj = d.isInfo?this.projectInfo:this;
                 }else if (d.type == ModuleNames.ration_glj && d.action == "add"){
                 }else if (d.type == ModuleNames.ration_glj && d.action == "add"){
                     this[d.type].datas.push(d.data);
                     this[d.type].datas.push(d.data);
                     if(d.projectGLJ) this.projectGLJ.loadNewProjectGLJToCache(d.projectGLJ);
                     if(d.projectGLJ) this.projectGLJ.loadNewProjectGLJToCache(d.projectGLJ);

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

@@ -1,3 +1,5 @@
+
+
 /**
 /**
  * 工料机汇总相关数据
  * 工料机汇总相关数据
  *
  *
@@ -82,6 +84,11 @@ ProjectGLJ.prototype.refreshByDatas = function(datas){
 
 
 ProjectGLJ.prototype.loadToCache = function (data) {
 ProjectGLJ.prototype.loadToCache = function (data) {
     this.datas = data;
     this.datas = data;
+    this.datas.gljMap =  {};
+    for(let g of this.datas.gljList){
+       this.datas.gljMap[gljUtil.getIndex(g)]=g;
+    }
+
 }
 }
 
 
 /**
 /**
@@ -1001,6 +1008,7 @@ ProjectGLJ.prototype.loadNewProjectGLJToCache = function (data,tIDMap) {//把新
     let uIndex = gljUtil.getIndex(data.unit_price);
     let uIndex = gljUtil.getIndex(data.unit_price);
     if(!unitPriceMap[uIndex])  unitPriceMap[uIndex] = data.unit_price;
     if(!unitPriceMap[uIndex])  unitPriceMap[uIndex] = data.unit_price;
     this.datas.gljList.push(data);
     this.datas.gljList.push(data);
+    this.datas.gljMap[gljUtil.getIndex(data)]= data;
     IDMap[data.id] = data;
     IDMap[data.id] = data;
     return data;
     return data;
 };
 };

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

@@ -102,7 +102,7 @@ let ration_glj = {
                 }
                 }
             }
             }
 
 
-            result = gljOprObj.combineWithProjectGlj(result);
+            result = gljOprObj.combineWithProjectGlj(result,false);
 
 
             if (!needOneBill) return result;
             if (!needOneBill) return result;
 
 

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

@@ -668,7 +668,7 @@ const BillsSub = (function() {
             let options = getOptions(node.data, bills.selected.sub.datas);
             let options = getOptions(node.data, bills.selected.sub.datas);
             top = options.length > 6 ? top - 6 * height : top - options.length * height;
             top = options.length > 6 ? top - 6 * height : top - options.length * height;
             let $editInput = $(`<div style="height: ${height}px; background: ${cellStyle.backColor};overflow: hidden; white-space: nowrap; text-overflow: ellipsis">${node.data.options}</div>`),
             let $editInput = $(`<div style="height: ${height}px; background: ${cellStyle.backColor};overflow: hidden; white-space: nowrap; text-overflow: ellipsis">${node.data.options}</div>`),
-                $optDiv = $(`<div style="position: fixed; width: ${cellRect.width}px; top: ${top}px;background: ${cellStyle.backColor};border: 1px solid; overflow: auto; height: ${options.length > 6 ? height*6+5 : height*options.length+5}px; font-size: 0.9rem;"></div>`);
+                $optDiv = $(`<div style="position: fixed; width: ${cellRect.width}px; top: ${top}px;background: ${cellStyle.backColor};border: 1px solid; overflow: auto; height: ${options.length > 6 ? height*6+5 : height*options.length+5}px; font-size: 14px;"></div>`);
             for(let opt of options){
             for(let opt of options){
                 let $opt = $(`<div title="${opt.name ? opt.name : ''}" class="elf-options" style="cursor: pointer; height: ${height}px;overflow: hidden; white-space: nowrap; text-overflow: ellipsis"></div>`),
                 let $opt = $(`<div title="${opt.name ? opt.name : ''}" class="elf-options" style="cursor: pointer; height: ${height}px;overflow: hidden; white-space: nowrap; text-overflow: ellipsis"></div>`),
                     $optInput = $(`<input rank="${opt.rank}" value="${opt.ID}" style="cursor: pointer; margin-left: 5px; vertical-align: middle" type="checkbox" 
                     $optInput = $(`<input rank="${opt.rank}" value="${opt.ID}" style="cursor: pointer; margin-left: 5px; vertical-align: middle" type="checkbox" 

+ 25 - 2
web/building_saas/main/js/views/block_lib.js

@@ -68,12 +68,13 @@ var blockLibObj = {
         }
         }
     },
     },
     cloneType: null,
     cloneType: null,
+    initialShareTip: '',
 
 
     buildSheet: async function () {
     buildSheet: async function () {
         $.bootstrapLoading.start();
         $.bootstrapLoading.start();
         let me = this;
         let me = this;
         let namesAndLib = await ajaxPost('/blockLib/getLibNamesAndFirstLib',
         let namesAndLib = await ajaxPost('/blockLib/getLibNamesAndFirstLib',
-            {userID: userID, userName: $("#link_userName").text(), compilationID: projectObj.project.projectInfo.compilation});
+            {userID: userID, compilationID: projectObj.project.projectInfo.compilation});
         function getLibNamesHtml(libsArr) {
         function getLibNamesHtml(libsArr) {
             let result = '';
             let result = '';
             for (let lib of libsArr) {
             for (let lib of libsArr) {
@@ -83,6 +84,10 @@ var blockLibObj = {
         };
         };
         let html = getLibNamesHtml(namesAndLib.libNames);
         let html = getLibNamesHtml(namesAndLib.libNames);
         $("#select_block_lib_names").html(html);
         $("#select_block_lib_names").html(html);
+        this.initialShareTip = namesAndLib.shareList && namesAndLib.shareList.length
+            ? namesAndLib.shareList.reduce((acc, user) => acc += ` ${user.real_name}`, '已分享给')
+            : '';
+        $('#btn_block_share').attr('data-original-title', this.initialShareTip);
         await me.loadLib(namesAndLib.firstLib);
         await me.loadLib(namesAndLib.firstLib);
         $.bootstrapLoading.end();
         $.bootstrapLoading.end();
     },
     },
@@ -541,7 +546,7 @@ var blockLibObj = {
                     name: '删除',
                     name: '删除',
                     icon: "delete",
                     icon: "delete",
                     disabled: function () {
                     disabled: function () {
-
+                        return $("#select_block_lib_names option:selected").prop("index") !== 0;
                     },
                     },
                     visible: function(key, opt){
                     visible: function(key, opt){
                         return true;
                         return true;
@@ -660,13 +665,31 @@ $(document).ready(function(){    // 这里不需要处理异步:因为不需
     });
     });
 
 
     $("#select_block_lib_names").change(function() {
     $("#select_block_lib_names").change(function() {
+        const index = $("#select_block_lib_names option:selected").prop("index");
+        if (index !== 0) {
+            // 只读
+            $('#btn_block_newFolder').hide();
+            $('#btn_block_reName').hide();
+            $('#btn_block_share').prop('disabled', true);
+        } else {
+            $('#btn_block_newFolder').show();
+            $('#btn_block_reName').show();
+            $('#btn_block_share').prop('disabled', false);
+        }
         async function getLib(){
         async function getLib(){
             let libID = $("#select_block_lib_names").val();
             let libID = $("#select_block_lib_names").val();
             let lib = await ajaxPost('/blockLib/getLib', {libID: libID});
             let lib = await ajaxPost('/blockLib/getLib', {libID: libID});
             blockLibObj.loadLib(lib);
             blockLibObj.loadLib(lib);
+            if (userID === lib.userID) {
+                $('#btn_block_share').attr('data-original-title', blockLibObj.initialShareTip);
+            }
         };
         };
         $.bootstrapLoading.start();
         $.bootstrapLoading.start();
         getLib();
         getLib();
         $.bootstrapLoading.end();
         $.bootstrapLoading.end();
     });
     });
+
+    $('#btn_block_share').click(function () {
+        SHARE_TO.initModal(SHARE_TO.Mode.BLOCK_LIB);
+    })
 });
 });

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

@@ -291,6 +291,7 @@ let calcBaseView = {
             if(!toggle || toggle !== 'calcBase'){
             if(!toggle || toggle !== 'calcBase'){
                 return;
                 return;
             }
             }
+            debugger;
             //bills
             //bills
             if(me.curType === me.type.bills){
             if(me.curType === me.type.bills){
                 let selected = projectObj.project.mainTree.selected;
                 let selected = projectObj.project.mainTree.selected;
@@ -371,9 +372,11 @@ $(document).ready(function () {
             $('#tabCalcBase').tab('show');
             $('#tabCalcBase').tab('show');
         }
         }
         sheetCommonObj.refreshWorkbookDelDefer(calcBaseView.workBook, 100);
         sheetCommonObj.refreshWorkbookDelDefer(calcBaseView.workBook, 100);
+        sheetCommonObj.refreshWorkbookDelDefer(calcBaseView.workBook, 500);
     });
     });
     $('#tabCalcBase').on('shown.bs.tab', function () {
     $('#tabCalcBase').on('shown.bs.tab', function () {
         sheetCommonObj.refreshWorkbookDelDefer(calcBaseView.workBook, 100);
         sheetCommonObj.refreshWorkbookDelDefer(calcBaseView.workBook, 100);
+        sheetCommonObj.refreshWorkbookDelDefer(calcBaseView.workBook, 500);
     });
     });
 
 
     /*$('#qd-jsjs').on('hidden.bs.modal', function () {
     /*$('#qd-jsjs').on('hidden.bs.modal', function () {

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

@@ -1297,6 +1297,7 @@ let pageCCOprObj = {
                     });
                     });
                 }
                 }
             }
             }
+            MaterialController.showItemCharacterText(null, "#tzCharacterText");
         });
         });
 
 
     },
     },

+ 25 - 10
web/building_saas/main/js/views/glj_col.js

@@ -44,7 +44,7 @@ let gljCol = {
             {headerName: "单位", headerWidth: 45, dataCode: "unit", hAlign: "center", dataType: "String",spanRows: [2]},
             {headerName: "单位", headerWidth: 45, dataCode: "unit", hAlign: "center", dataType: "String",spanRows: [2]},
             {headerName: "类型", headerWidth: 45, dataCode: "short_name", hAlign: "center", dataType: "String",spanRows: [2]},
             {headerName: "类型", headerWidth: 45, dataCode: "short_name", hAlign: "center", dataType: "String",spanRows: [2]},
             {headerName: "市场价", headerWidth: 70, dataCode: "marketPrice", hAlign: "right", dataType: "Number",validator:"number",spanRows: [2]},//,decimalField:"glj.unitPrice"
             {headerName: "市场价", headerWidth: 70, dataCode: "marketPrice", hAlign: "right", dataType: "Number",validator:"number",spanRows: [2]},//,decimalField:"glj.unitPrice"
-            {headerName: "价格来源", headerWidth: 90, dataCode: "priceFrom", dataType: "String",spanRows: [2]},
+            {headerName: "价格来源", headerWidth: 90, dataCode: "priceFrom", dataType: "String",spanRows: [2],cellType:"tipsCell"},
             {headerName: "税率", headerWidth: 70, dataCode: "taxRate", hAlign: "right", dataType: "Number",validator:"number",spanRows: [2]},//,decimalField:"glj.unitPrice"
             {headerName: "税率", headerWidth: 70, dataCode: "taxRate", hAlign: "right", dataType: "Number",validator:"number",spanRows: [2]},//,decimalField:"glj.unitPrice"
             {headerName: "调整价", headerWidth: 70, dataCode: "adjustPrice", hAlign: "right", dataType: "Number",spanRows: [2]},//,decimalField:"glj.unitPrice"
             {headerName: "调整价", headerWidth: 70, dataCode: "adjustPrice", hAlign: "right", dataType: "Number",spanRows: [2]},//,decimalField:"glj.unitPrice"
             {headerName: "定额价", headerWidth: 70, dataCode: "basePrice", hAlign: "right", dataType: "Number",validator:"number",spanRows: [2]},//decimalField:'glj.unitPrice',
             {headerName: "定额价", headerWidth: 70, dataCode: "basePrice", hAlign: "right", dataType: "Number",validator:"number",spanRows: [2]},//decimalField:'glj.unitPrice',
@@ -71,15 +71,26 @@ let gljCol = {
         view: {
         view: {
             lockColumns: ["code","name","specs","unit","short_name","tenderPrice","adjustPrice","quantity","tenderQuantity","priceFrom"]
             lockColumns: ["code","name","specs","unit","short_name","tenderPrice","adjustPrice","quantity","tenderQuantity","priceFrom"]
         },
         },
-        autoFit:true,
-        fitRow:['priceFrom'],
+       /*  autoFit:true,
+        fitRow:['priceFrom'], */
         frozenCols:4,
         frozenCols:4,
         headRows:2,
         headRows:2,
-        getStyle:function (data,row,activeRow) {
-          if(row == activeRow){//选中黄色显示
-              return {backColor:"#FFFACD"};
+        getStyle:function (data,row,activeRow,dataCode) {
+          let style = {};
+          if(row === activeRow){//选中黄色显示
+            style = new GC.Spread.Sheets.Style();
+            style.backColor = "#FFFACD";
+            style.borderLeft = new GC.Spread.Sheets.LineBorder("#D4D4D4", GC.Spread.Sheets.LineStyle.thin);
+            style.borderTop = new GC.Spread.Sheets.LineBorder("#D4D4D4", GC.Spread.Sheets.LineStyle.thin);
+            style.borderRight = new GC.Spread.Sheets.LineBorder("#D4D4D4", GC.Spread.Sheets.LineStyle.thin);
+            style.borderBottom = new GC.Spread.Sheets.LineBorder("#D4D4D4", GC.Spread.Sheets.LineStyle.thin);
           }
           }
-          return null;
+          if(dataCode === "marketPrice"){
+              if(data.marketPrice == data.basePrice) style.foreColor = 'black';//改回相等的时候,要改回来
+              if(data.marketPrice > data.basePrice) style.foreColor = 'red';
+              if(data.marketPrice < data.basePrice) style.foreColor = 'green';
+          }
+          return _.isEmpty(style)?null:style;
       },
       },
     },
     },
     mixRatio_Setting:{
     mixRatio_Setting:{
@@ -250,7 +261,7 @@ let gljCol = {
             setting.view.lockColumns = newArray;
             setting.view.lockColumns = newArray;
         }
         }
     },
     },
-    initGljCol: function (showAdjustPrice, showTenderFields) {
+    initGljCol: function (showAdjustPrice, showTenderFields,init=false) {
       let me = gljCol;
       let me = gljCol;
       if (showAdjustPrice !== true) {
       if (showAdjustPrice !== true) {
         me.removeCol('adjustPrice', me.ration_glj_setting);
         me.removeCol('adjustPrice', me.ration_glj_setting);
@@ -263,7 +274,7 @@ let gljCol = {
         me.removeCol('priceFrom', me.project_glj_setting);
         me.removeCol('priceFrom', me.project_glj_setting);
       } 
       } 
       
       
-      me.showTenderFields(showTenderFields, false);
+      me.showTenderFields(showTenderFields, false,init);
 
 
       gljOprObj.setting = me.ration_glj_setting;
       gljOprObj.setting = me.ration_glj_setting;
       projectGljObject.projectGljSetting = me.project_glj_setting;
       projectGljObject.projectGljSetting = me.project_glj_setting;
@@ -271,7 +282,7 @@ let gljCol = {
       me.setScopeFormater();
       me.setScopeFormater();
       gljOprObj.scopeSetting = me.scopeSetting;
       gljOprObj.scopeSetting = me.scopeSetting;
     },
     },
-    showTenderFields: function (showFields = false, needRefresh = false){
+    showTenderFields: function (showFields = false, needRefresh = false,init=false){
         let me = gljCol;
         let me = gljCol;
 
 
         let PGLJHeader = me.project_glj_setting.header;
         let PGLJHeader = me.project_glj_setting.header;
@@ -295,6 +306,10 @@ let gljCol = {
             }
             }
         };
         };
 
 
+        colSettingObj.setVisible('feesIndex.common.tenderUnitFee', showFields);
+        colSettingObj.setVisible('feesIndex.common.tenderTotalFee', showFields);
+        colSettingObj.updateColSetting(true,init);
+
         if (needRefresh){
         if (needRefresh){
             if(projectGljObject.projectGljSpread) {
             if(projectGljObject.projectGljSpread) {
                 projectGljObject.projectGljSheet = projectGljObject.projectGljSpread .getSheet(0);
                 projectGljObject.projectGljSheet = projectGljObject.projectGljSpread .getSheet(0);

+ 10 - 3
web/building_saas/main/js/views/glj_view.js

@@ -855,9 +855,16 @@ var gljOprObj = {
         var temRationGLJs = [];
         var temRationGLJs = [];
         for (var i = 0; i < mixRatioList.length; i++) {
         for (var i = 0; i < mixRatioList.length; i++) {
             let mIndex = gljOprObj.getIndex(mixRatioList[i],gljKeyArray);
             let mIndex = gljOprObj.getIndex(mixRatioList[i],gljKeyArray);
-            var pg = _.find(projectGljs, function (item) {
-                return gljOprObj.getIndex(item,gljKeyArray) == mIndex
-            });//改关联关系
+            let pgljMap = projectObj.project.projectGLJ.datas.gljMap;
+            let pg = null;
+            if(pgljMap){
+                pg = pgljMap[mIndex];
+            }
+            if(!pg){//兼容旧数据,以防万一
+                pg = _.find(projectGljs, function (item) {
+                    return gljOprObj.getIndex(item,gljKeyArray) == mIndex
+                });//改关联关系
+            }
             if(pg){
             if(pg){
                 let tem = {
                 let tem = {
                     mixRatioId:mixRatioList[i].id,
                     mixRatioId:mixRatioList[i].id,

+ 13 - 0
web/building_saas/main/js/views/index_view.js

@@ -634,9 +634,22 @@ let indexObj= {
         }
         }
         return null;
         return null;
     },
     },
+    getQuantityUnit:function () {
+        let features  = projectObj.project.property.engineerFeatures;
+        if(features){
+            for(let f of features){
+                if(f.index == true && f.quantityUnit && f.quantityUnit!="") return f.quantityUnit;
+            }
+        }
+        return null;
+    },
     setHeaderUnit:function (setting,dataCode) {
     setHeaderUnit:function (setting,dataCode) {
       let header = _.find(setting.header,{dataCode:dataCode});
       let header = _.find(setting.header,{dataCode:dataCode});
       let unit = this.getIndexUnit();
       let unit = this.getIndexUnit();
+      if(dataCode === 'quantity'){
+        let qunit = this.getQuantityUnit();
+        if(qunit) unit = qunit
+      }
       if(!unit || !header )return;
       if(!unit || !header )return;
       header.headerName +=`(${unit})`
       header.headerName +=`(${unit})`
     }
     }

+ 3 - 2
web/building_saas/main/js/views/main_tree_col.js

@@ -630,6 +630,7 @@ let MainTreeCol = {
         let isFBNode = node.sourceType == ModuleNames.bills&&node.data.type == billType.FB;
         let isFBNode = node.sourceType == ModuleNames.bills&&node.data.type == billType.FB;
         if(isFBNode){
         if(isFBNode){
            let CELL =sheetCommonObj.getCusButtonCellType(()=>{
            let CELL =sheetCommonObj.getCusButtonCellType(()=>{
+            $("#selectFBFor").val("replace");   
             $('#selectFBDiv').modal('show');
             $('#selectFBDiv').modal('show');
             })
             })
             cell.cellType(CELL); 
             cell.cellType(CELL); 
@@ -695,7 +696,7 @@ let colSettingObj = {
         }
         }
         return false;
         return false;
     },
     },
-    updateColSetting: function (skipSetValue = false) {
+    updateColSetting: function (skipSetValue = false,init=false) {
         let mainSheet = projectObj.mainSpread.getActiveSheet();
         let mainSheet = projectObj.mainSpread.getActiveSheet();
         if(!skipSetValue){
         if(!skipSetValue){
             let sheet = this.settingSpread.getActiveSheet();
             let sheet = this.settingSpread.getActiveSheet();
@@ -710,7 +711,7 @@ let colSettingObj = {
             mainSheet.showColumn(projectObj.project.projSetting.mainGridSetting.frozenCols, GC.Spread.Sheets.HorizontalPosition.left);
             mainSheet.showColumn(projectObj.project.projSetting.mainGridSetting.frozenCols, GC.Spread.Sheets.HorizontalPosition.left);
         });
         });
         //refresh nodes to autoFitRow
         //refresh nodes to autoFitRow
-        projectObj.mainController.refreshTreeNode(projectObj.project.mainTree.roots, true);
+       if(init===false) projectObj.mainController.refreshTreeNode(projectObj.project.mainTree.roots, true);
         if(!skipSetValue){
         if(!skipSetValue){
             //列设置将项目特征和工作内容都取消打钩后,更新快速列设置
             //列设置将项目特征和工作内容都取消打钩后,更新快速列设置
             if(!this.getVisible('itemCharacterText')){
             if(!this.getVisible('itemCharacterText')){

+ 6 - 6
web/building_saas/main/js/views/material_adjust_view.js

@@ -434,17 +434,17 @@ let materialAdjustObj = {
     }
     }
     return _.sortByAll(datas, 'code');
     return _.sortByAll(datas, 'code');
   },
   },
-  getPriceCoeDatas: function (projectGLJList, contractor_list, totalFee, decimalObj) {
-    let datas = [];
+  getPriceCoeDatas: function (projectGLJList, contractor_list, totalFee, projectProperty) {
     let pgljList = projectGLJList ? projectGLJList : projectObj.project.projectGLJ.datas.gljList;
     let pgljList = projectGLJList ? projectGLJList : projectObj.project.projectGLJ.datas.gljList;
     let contractorList = contractor_list ? contractor_list : projectObj.project.contractor_list.datas;
     let contractorList = contractor_list ? contractor_list : projectObj.project.contractor_list.datas;
-    let billsDecimal = decimalObj ? decimalObj.bills.totalPrice : getDecimal('bills.totalPrice');
-    let gljMap = _.indexBy(pgljList, 'id');
+    let tprojectProperty = projectProperty?projectProperty:projectObj.project.projectInfo.property;
     if (!gljUtil.isDef(totalFee)) {
     if (!gljUtil.isDef(totalFee)) {
       let node = projectObj.project.Bills.getEngineeringCostNode(projectObj.mainController);
       let node = projectObj.project.Bills.getEngineeringCostNode(projectObj.mainController);
       totalFee = node && node.data.feesIndex && node.data.feesIndex.common ? node.data.feesIndex.common.totalFee : 0;
       totalFee = node && node.data.feesIndex && node.data.feesIndex.common ? node.data.feesIndex.common.totalFee : 0;
     }
     }
-    for (let e of contractorList) {
+    return gljUtil.getPriceCoeDatas(pgljList, contractorList, totalFee, tprojectProperty,_,scMathUtil)
+
+    /* for (let e of contractorList) {
       let t = {
       let t = {
         ID: e.ID,
         ID: e.ID,
         projectID: e.projectID,
         projectID: e.projectID,
@@ -476,7 +476,7 @@ let materialAdjustObj = {
       if (totalFee !== 0) t.varWeight = scMathUtil.roundForObj(t.totalPrice / totalFee, 2);
       if (totalFee !== 0) t.varWeight = scMathUtil.roundForObj(t.totalPrice / totalFee, 2);
       datas.push(t);
       datas.push(t);
     }
     }
-    return _.sortByAll(datas, 'code');
+    return _.sortByAll(datas, 'code'); */
   },
   },
   getCommonObject: function (glj) {
   getCommonObject: function (glj) {
     let data = {
     let data = {

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

@@ -683,6 +683,7 @@ let projectGljObject = {
       } else {
       } else {
         style.backColor = "White";
         style.backColor = "White";
       }
       }
+      console.log(style);
       me.projectGljSheet.setStyle(orow, -1, style);
       me.projectGljSheet.setStyle(orow, -1, style);
       me.projectGljRowChang();
       me.projectGljRowChang();
     } else {
     } else {

+ 123 - 0
web/building_saas/main/js/views/project_property_compare.js

@@ -0,0 +1,123 @@
+let compareObject = {
+    setting:{
+        header: [
+            {headerName: "审定", headerWidth: 240, dataCode: "name", dataType: "String"},
+            {headerName: "送审", headerWidth: 240, dataCode: "compare", dataType: "String"}
+        ],
+        view:{ lockColumns: ["name","compare"]}
+    },
+    initSpread:function(){
+        if(!this.spread){
+            this.spread = SheetDataHelper.createNewSpread($("#compareProjectSpread")[0]);
+            sheetCommonObj.spreadDefaultStyle(this.spread);
+            let sheet = this.spread.getSheet(0);
+            sheetCommonObj.initSheet(sheet,this.setting,0);
+        }else{
+            this.spread.repaint();
+        }
+    },
+    showDatas:function(){
+        this.getCompareDatas();
+        sheetCommonObj.showTreeData(this.spread.getSheet(0), this.setting,this.datas);
+    },
+    datas:[],
+    getCompareDatas:function(){
+        let datas = [];
+        let me = compareObject;
+        let compareID = projectObj.project.projectInfo.compareID;
+        let rootProjectID = projectObj.project.property.rootProjectID;
+        if(gljUtil.isNotEmpty(compareID)){
+            let rootProject = _.find(me.projects,{'ID':rootProjectID});
+            let compareProject = _.find(me.projects,{'ID':compareID});
+            rootProject.compare = compareProject.name;
+            rootProject.matchID = compareID; 
+            rootProject.collapsed = false;
+            datas.push(rootProject);
+
+            setDatas(rootProjectID,compareID,datas);
+        }
+        this.datas = datas;
+        function setDatas(nID,cID,mdatas){
+            let nameMap = {};
+            if(cID && me.parentMap[cID]){
+                for(let c of me.parentMap[cID]){
+                    nameMap[c.name] = c;
+                }
+            }
+            if(me.parentMap[nID]){
+                for(let n of me.parentMap[nID]){
+                    if(nameMap[n.name]){//找到同名的项目时,匹配上
+                       n.compare = n.name;
+                       n.matchID = nameMap[n.name].ID             
+                    }
+                    n.collapsed = false;
+                    mdatas.push(n);
+                    setDatas(n.ID,n.matchID,mdatas)
+                }
+            }
+        }
+    },
+    initProjectDatas:async function(){
+        let projects = await ajaxGet("/project/getCompareProjects");
+        let parentMap=_.groupBy(projects, 'ParentID');
+        for(let key in parentMap){
+            parentMap[key] = sortTreeChildren(parentMap[key]);
+        }
+        compareObject.parentMap = parentMap;
+        compareObject.projects = projects;
+        let rootParjects = parentMap['-1'];
+        let options = [];
+        for(let r of rootParjects){
+            [newPath,project] =  setProjectPath(r,parentMap,"");
+            if(newPath && project)options.push({path:newPath,ID:project.ID})
+        }   
+        compareObject.options = options;
+        let rootProject  = _.find(projects,{'ID':projectObj.project.property.rootProjectID});
+        projectObj.project.projectInfo.compareID = rootProject.compareID;
+
+        function setProjectPath(project,parentMap,namePath){
+            let newPath = project.ParentID == -1?project.name:`${namePath}/${project.name}`;
+            if(project.projType === commonConstants.projectType.Project) return [newPath,project];
+            
+            if(parentMap[project.ID]){
+                for(let c of parentMap[project.ID]){
+                   return setProjectPath(c,parentMap,newPath)
+                }
+            }
+        }
+    },
+    getCompareID:async function(){
+        if(!this.parentMap){
+           await this.initProjectDatas();
+        }
+        this.getCompareDatas();
+        for(let d of this.datas){
+            if(d.ID == projectObj.project.ID()) return d.matchID;
+        }
+        return null;
+    } 
+}
+
+$(document).ready(function () {
+    $('#tab_compare').on('shown.bs.tab', async function () {
+        await compareObject.initProjectDatas();
+        let optionString = `<option value=""></option>`;
+        for(let o of compareObject.options){
+            if(o.ID === projectObj.project.property.rootProjectID) continue;
+            optionString += `<option value="${o.ID}">${o.path}</option>`
+        }
+        $("#audiCompareID").html(optionString);
+        $("#audiCompareID").val(projectObj.project.projectInfo.compareID);
+        compareObject.initSpread();
+        compareObject.showDatas();
+    });
+    $("#audiCompareID").change(async function(){
+        //compareID 保存在建设项目上,为方便使用,获取后挂在projectInfo上
+        let updateData = {type:ModuleNames.project,isInfo:true,data:{'ID' : projectObj.project.property.rootProjectID,compareID:parseInt(this.value)}};
+        $.bootstrapLoading.start();
+        await projectObj.project.syncUpdateNodesAndRefresh([updateData]);
+        compareObject.showDatas();
+        $.bootstrapLoading.end();
+    })
+
+})

+ 60 - 41
web/building_saas/main/js/views/project_view.js

@@ -300,25 +300,7 @@ var projectObj = {
                 let libId = projectObj.project.projectInfo.engineeringInfo.bill_lib[0].id;
                 let libId = projectObj.project.projectInfo.engineeringInfo.bill_lib[0].id;
                 CommonAjax.post('/stdBillsEditor/getStdBillsByCode', {userId: userID, billsLibId: libId, code: stdCode}, function (data) {
                 CommonAjax.post('/stdBillsEditor/getStdBillsByCode', {userId: userID, billsLibId: libId, code: stdCode}, function (data) {
                     if (data) {
                     if (data) {
-                        function sortItems(serialItems, items){
-                            for(let item of items){
-                                for(let serialItem of serialItems){
-                                    if(item.id === serialItem.id){
-                                        item.serialNo = serialItem.serialNo;
-                                    }
-                                }
-                            }
-                            items.sort(function (a, b) {
-                                let rst = 0;
-                                if(a.serialNo > b.serialNo){
-                                    rst = 1;
-                                }
-                                else if(a.serialNo < b.serialNo){
-                                    rst = -1;
-                                }
-                                return rst;
-                            });
-                        }
+                        
                         function updateBeforeInsert(node, data) {
                         function updateBeforeInsert(node, data) {
                             node.data.name = data.name;
                             node.data.name = data.name;
                             if(node.data.type == billType.BX){//从清单库中找到标准清单的话,要把补项改成分项
                             if(node.data.type == billType.BX){//从清单库中找到标准清单的话,要把补项改成分项
@@ -379,8 +361,9 @@ var projectObj = {
                     searchStdBillsAndUpdate(stdMatchCode, value);
                     searchStdBillsAndUpdate(stdMatchCode, value);
                     return;
                     return;
                 } else {
                 } else {
-                    hintBox.infoBox("系统提示","已存在该编码的清单,是否继续?",2,function () {
-                        searchStdBillsAndUpdate(stdMatchCode, value);
+                    hintBox.infoBox("系统提示","已存在该编码的清单,将自动修改编码后3位,是否继续?",2,function () {
+                        let newFormatCode = project.Bills.newFormatCode(stdMatchCode);
+                        searchStdBillsAndUpdate(stdMatchCode, newFormatCode);
                     },function () {
                     },function () {
                         me.mainController.refreshTreeNode([node], false);
                         me.mainController.refreshTreeNode([node], false);
                     },['确定','取消']);
                     },['确定','取消']);
@@ -926,10 +909,6 @@ var projectObj = {
                 let quantityTime = +new Date();
                 let quantityTime = +new Date();
                 console.log(`计算quantity时间——${quantityTime - mTime}`);
                 console.log(`计算quantity时间——${quantityTime - mTime}`);
                 //that.project.property = projectObj.project.projectInfo.property;  改在doAfterLoad的时候设置
                 //that.project.property = projectObj.project.projectInfo.property;  改在doAfterLoad的时候设置
-                gljCol.initGljCol(that.project.projSetting.glj_col?that.project.projSetting.glj_col.showAdjustPrice:false,
-                    that.project.property.tenderSetting.showTenderFields?that.project.property.tenderSetting.showTenderFields:false);
-                subObj.initSubSpread();//初始化主界面下方的表格
-
                 if (typeof overwriteRationCalcBases === 'function')
                 if (typeof overwriteRationCalcBases === 'function')
                     overwriteRationCalcBases(that.project.property.taxType);
                     overwriteRationCalcBases(that.project.property.taxType);
                 //that.project.calcProgram.compileAllTemps();
                 //that.project.calcProgram.compileAllTemps();
@@ -986,12 +965,16 @@ var projectObj = {
                 });
                 });
                 let startShowTime = +new Date();
                 let startShowTime = +new Date();
                 that.mainController = TREE_SHEET_CONTROLLER.createNew(that.project.mainTree, that.mainSpread.getActiveSheet(), that.project.projSetting.mainGridSetting);
                 that.mainController = TREE_SHEET_CONTROLLER.createNew(that.project.mainTree, that.mainSpread.getActiveSheet(), that.project.projSetting.mainGridSetting);
-                that.mainController.showTreeData();
+               
                 let endShowTime = +new Date();
                 let endShowTime = +new Date();
                 console.log(`show data时间——${endShowTime - startShowTime}`);
                 console.log(`show data时间——${endShowTime - startShowTime}`);
                 that.mainController.bind('refreshBaseActn', that.refreshBaseActn);
                 that.mainController.bind('refreshBaseActn', that.refreshBaseActn);
                 that.mainController.bind(TREE_SHEET_CONTROLLER.eventName.beforeTreeSelectedChange, that.beforeMainTreeSelectedChange);
                 that.mainController.bind(TREE_SHEET_CONTROLLER.eventName.beforeTreeSelectedChange, that.beforeMainTreeSelectedChange);
                 that.mainController.bind(TREE_SHEET_CONTROLLER.eventName.treeSelectedChanged, that.treeSelectedChanged);
                 that.mainController.bind(TREE_SHEET_CONTROLLER.eventName.treeSelectedChanged, that.treeSelectedChanged);
+                gljCol.initGljCol(that.project.projSetting.glj_col?that.project.projSetting.glj_col.showAdjustPrice:false,
+                  that.project.property.tenderSetting.showTenderFields?that.project.property.tenderSetting.showTenderFields:false,true);
+                  that.mainController.showTreeData();
+                subObj.initSubSpread();//初始化主界面下方的表格
                 if(!projectReadOnly){
                 if(!projectReadOnly){
                     that.mainSpreadEscKey(that.mainSpread, that.mainSpreadEditStarting, that.mainSpreadEditEnded);
                     that.mainSpreadEscKey(that.mainSpread, that.mainSpreadEditStarting, that.mainSpreadEditEnded);
                     sheetCommonObj.bindEnterKey(that.mainSpread, that.mainSpreadEnterKey);
                     sheetCommonObj.bindEnterKey(that.mainSpread, that.mainSpreadEnterKey);
@@ -1341,6 +1324,7 @@ var projectObj = {
                         return true;//除了清单,其它类型都只读
                         return true;//除了清单,其它类型都只读
                     },
                     },
                     callback: function (key, opt) {
                     callback: function (key, opt) {
+                        /* 2020-12-28 插入前先弹窗选择 
                         let selected = project.mainTree.selected;
                         let selected = project.mainTree.selected;
                         if(selected.data.type==billType.FX || selected.data.type==billType.BX){
                         if(selected.data.type==billType.FX || selected.data.type==billType.BX){
                              //添加成分项的父亲
                              //添加成分项的父亲
@@ -1348,8 +1332,9 @@ var projectObj = {
                         }else{//正常添加分部
                         }else{//正常添加分部
                             ProjectController.addFB(project, controller);
                             ProjectController.addFB(project, controller);
                             projectObj.selectColAndFocus(project.mainTree.selected);
                             projectObj.selectColAndFocus(project.mainTree.selected);
-                        }
-                       
+                        } */
+                        $("#selectFBFor").val("add");   
+                        $('#selectFBDiv').modal('show');
                     },
                     },
                     visible: function(key, opt){
                     visible: function(key, opt){
                         if(project.mainTree.selected){
                         if(project.mainTree.selected){
@@ -1776,7 +1761,12 @@ var projectObj = {
                     name: '造价计算',
                     name: '造价计算',
                     icon: 'fa-calculator',
                     icon: 'fa-calculator',
                     callback: function () {
                     callback: function () {
-                        project.calcProgram.calcAllNodesAndSave();
+                        $.bootstrapLoading.start();
+                        setTimeout(function(){
+                            project.calcProgram.calcAllNodesAndSave();
+                            $.bootstrapLoading.end();
+                        },100)
+                        
                     },
                     },
                     disabled: function () {
                     disabled: function () {
                         if (projectReadOnly) {
                         if (projectReadOnly) {
@@ -2151,11 +2141,11 @@ var projectObj = {
             }
             }
             //分部
             //分部
             if(node.data.type === billType.FB){
             if(node.data.type === billType.FB){
-                styleMap = mapping.FB;
+                styleMap = mapping.FX;
             }
             }
             //分项
             //分项
             else if(node.data.type === billType.FX){
             else if(node.data.type === billType.FX){
-                styleMap = mapping.FX;
+                styleMap = mapping.FB;
             }
             }
             //补项
             //补项
             else if(node.data.type === billType.BX){
             else if(node.data.type === billType.BX){
@@ -2165,15 +2155,18 @@ var projectObj = {
             else if(node.data.type === billType.BILL){
             else if(node.data.type === billType.BILL){
                 //非叶子节点的清单
                 //非叶子节点的清单
                 if(node.source.children.length > 0){
                 if(node.source.children.length > 0){
-                    styleMap = mapping.UNLEAFBILL;
+                    styleMap = mapping.UNCBBILL;
+                    // styleMap = mapping.UNLEAFBILL;
                 }
                 }
                 //未使用基数计算的叶子节点的清单
                 //未使用基数计算的叶子节点的清单
                 else if(node.source.children.length === 0 && (!isDef(node.data.calcBase) || node.data.calcBase === '')){
                 else if(node.source.children.length === 0 && (!isDef(node.data.calcBase) || node.data.calcBase === '')){
-                    styleMap = mapping.UNCBBILL;
+                    // styleMap = mapping.UNCBBILL;
+                    styleMap = mapping.UNLEAFBILL;
                 }
                 }
                 //使用基数计算的叶子节点的清单
                 //使用基数计算的叶子节点的清单
                 else if(node.source.children.length === 0 && isDef(node.data.calcBase && node.data.calcBaseValue !== '')){
                 else if(node.source.children.length === 0 && isDef(node.data.calcBase && node.data.calcBaseValue !== '')){
-                    styleMap = mapping.CBBILL;
+                    // styleMap = mapping.CBBILL;
+                    styleMap = mapping.UNLEAFBILL;
                 }
                 }
             }
             }
         }
         }
@@ -2212,7 +2205,7 @@ var projectObj = {
         if(_ && !_.isEmpty(node.data.bookmarkBackground)) style.backColor = "#"+ node.data.bookmarkBackground;//设置书签和批注背景色
         if(_ && !_.isEmpty(node.data.bookmarkBackground)) style.backColor = "#"+ node.data.bookmarkBackground;//设置书签和批注背景色
         //大项费用加粗(数字与中文字符大小不一问题由字体造成,暂时不考虑分别设置大小)
         //大项费用加粗(数字与中文字符大小不一问题由字体造成,暂时不考虑分别设置大小)
        /* if(node.sourceType === this.project.Bills.getSourceType() && node.data.type === billType.DXFY){
        /* if(node.sourceType === this.project.Bills.getSourceType() && node.data.type === billType.DXFY){
-            style.font = 'bold 0.9rem Arial';
+            style.font = 'bold 14px Arial';
         }*/
         }*/
         style.borderLeft = new GC.Spread.Sheets.LineBorder("#D4D4D4", GC.Spread.Sheets.LineStyle.thin);
         style.borderLeft = new GC.Spread.Sheets.LineBorder("#D4D4D4", GC.Spread.Sheets.LineStyle.thin);
         style.borderTop = new GC.Spread.Sheets.LineBorder("#D4D4D4", GC.Spread.Sheets.LineStyle.thin);
         style.borderTop = new GC.Spread.Sheets.LineBorder("#D4D4D4", GC.Spread.Sheets.LineStyle.thin);
@@ -2240,7 +2233,7 @@ var projectObj = {
             'programID',
             'programID',
             'ruleText'
             'ruleText'
         ];
         ];
-        style.font = 'bold 0.9rem Arial';
+        style.font = 'bold 14px Arial';
         return style;
         return style;
     },
     },
    //设置节点style
    //设置节点style
@@ -2543,6 +2536,20 @@ $('#interface-dropdown').click(function() {
     return false;
     return false;
 });
 });
 
 
+let enterZLFB = false
+$('#ZLFB_MENU').mouseenter(function () {
+    enterZLFB = true;
+    $('#ZLFB_MENU_sub').addClass('show');
+});
+
+$('#ZLFB_MENU').mouseleave(function () {
+    enterZLFB = false;
+});
+
+$('#ZLFB_MENU').click(function() {
+    return false;
+});
+
 $('#moreMenu > a').mouseenter(function () {
 $('#moreMenu > a').mouseenter(function () {
     if (!enterDisplayA) {
     if (!enterDisplayA) {
         $('#subDisplay').removeClass('show');
         $('#subDisplay').removeClass('show');
@@ -2550,9 +2557,13 @@ $('#moreMenu > a').mouseenter(function () {
     if (!enterInterfaceDropdown) {
     if (!enterInterfaceDropdown) {
         $('#interface-dropdown-sub').removeClass('show');
         $('#interface-dropdown-sub').removeClass('show');
     }
     }
+    if(!enterZLFB){
+        $('#ZLFB_MENU_sub').removeClass('show');
+    }
 });
 });
 
 
 
 
+
 $('#displayDXFY').click(function () {
 $('#displayDXFY').click(function () {
    displayLevel(projectObj.project.mainTree.items, 0, 'DXFY')
    displayLevel(projectObj.project.mainTree.items, 0, 'DXFY')
 });
 });
@@ -3079,13 +3090,13 @@ const uploadType = {general: 'general', lj: 'lj', gld: 'gld'};
 let fileType = uploadType.lj;
 let fileType = uploadType.lj;
 
 
 $('#uploadLj').click(function () {
 $('#uploadLj').click(function () {
-    $('#uploadExample-general').show();
-    $('#uploadExample').text('下载示例2');
+    $('#example-gld').hide();
+    $('#example-general').show();
     fileType = uploadType.lj;
     fileType = uploadType.lj;
 });
 });
 $('#uploadGld').click(function () {
 $('#uploadGld').click(function () {
-    $('#uploadExample-general').hide();
-    $('#uploadExample').text('下载示例');
+    $('#example-general').hide();
+    $('#example-gld').show();
     fileType = uploadType.gld;
     fileType = uploadType.gld;
 });
 });
 
 
@@ -3329,6 +3340,12 @@ $('#uploadExample-general').click(function () {
 $('#uploadExample').click(function () {
 $('#uploadExample').click(function () {
     window.location.href = `/bills/downloadExamp?type=${fileType === uploadType.lj ? uploadType.lj : uploadType.gld}`;
     window.location.href = `/bills/downloadExamp?type=${fileType === uploadType.lj ? uploadType.lj : uploadType.gld}`;
 });
 });
+$('#uploadExample-lj').click(function () {
+    window.location.href = `/bills/downloadExamp?type=${uploadType.lj}`;
+});
+$('#uploadExample-gld').click(function () {
+    window.location.href = `/bills/downloadExamp?type=${uploadType.gld}`;
+});
 
 
 $(function () {
 $(function () {
     //清空导入清单选择文件
     //清空导入清单选择文件
@@ -3401,7 +3418,7 @@ $(function () {
         $('#clone_option_name').prop("checked", false);
         $('#clone_option_name').prop("checked", false);
         $('#clone_option_unit').prop("checked", true);
         $('#clone_option_unit').prop("checked", true);
         $('#clone_option_quantity').prop("checked", true);
         $('#clone_option_quantity').prop("checked", true);
-        $('#clone_option_noCover').prop("checked", true);
+        $('#clone_option_cover').prop("checked", true);
     });
     });
 
 
     $("#btn_block_createBlocks").click(async function () {
     $("#btn_block_createBlocks").click(async function () {
@@ -3583,6 +3600,8 @@ function disableTools(){
     $('#stdBillsTab').addClass('disabled');
     $('#stdBillsTab').addClass('disabled');
     //$('#stdRationTab').addClass('disabled');
     //$('#stdRationTab').addClass('disabled');
     $('#blockLibTab').addClass('disabled');
     $('#blockLibTab').addClass('disabled');
+    // 组价模板分享
+    $('#btn_block_share').prop('disabled', true);
     //人材机汇总,选择其他、另存使用
     //人材机汇总,选择其他、另存使用
     $('a[data-target="#change-unitFile"]').remove();
     $('a[data-target="#change-unitFile"]').remove();
     $('a[data-target="#unitFile-save-as"]').remove();
     $('a[data-target="#unitFile-save-as"]').remove();

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

@@ -179,6 +179,8 @@ let quantityEditObj = {
         }
         }
         try {
         try {
             let value = undefined;
             let value = undefined;
+            //2021-1-14 工程量表达式中,允许输入“{、}”,花括号内的内容不参与计算,用户输入备注。如:“QDL*0.23{厚度}”、“10{长度}*5.8{宽度}”。
+            evalString = replaceAll("\{[^\}]*\}","",evalString);//[^\}] 表示匹配非}
             if(evalString&&evalString!=""){
             if(evalString&&evalString!=""){
                 let exp = new Expression('');
                 let exp = new Expression('');
                 exp.Expression(evalString);
                 exp.Expression(evalString);

+ 83 - 25
web/building_saas/main/js/views/select_FB_view.js

@@ -15,18 +15,12 @@ let selectFBObject = {
             sheetCommonObj.spreadDefaultStyle(this.spread);
             sheetCommonObj.spreadDefaultStyle(this.spread);
             let sheet = this.spread.getSheet(0);
             let sheet = this.spread.getSheet(0);
             sheetCommonObj.initSheet(sheet,this.setting,0);
             sheetCommonObj.initSheet(sheet,this.setting,0);
-              /*   sheet.bind(GC.Spread.Sheets.Events.SelectionChanged,this.onSelectionChange);
-                sheet.bind(GC.Spread.Sheets.Events.ValueChanged, this.onEngineerInfoValueChange);
-                sheet.bind(GC.Spread.Sheets.Events.RangeChanged, this.onEngineerInfoRangeChange);
-                sheet.name('engineerInfo'); */
-               
-          
-
+              /*   sheet.bind(GC.Spread.Sheets.Events.SelectionChanged,this.onSelectionChange); */
             if(projectReadOnly){
             if(projectReadOnly){
                 sheetCommonObj.disableSpread(this.spread);
                 sheetCommonObj.disableSpread(this.spread);
             }
             }
         }else{
         }else{
-            this.spread.repaint();
+            this.spread.refresh();
         }
         }
         
         
     },
     },
@@ -40,15 +34,61 @@ let selectFBObject = {
     showData:function(){
     showData:function(){
         let me = selectFBObject;
         let me = selectFBObject;
         billsGuidance.initBillsLibs(()=>{
         billsGuidance.initBillsLibs(()=>{
-            if(me.datas.length==0){
-                for(let r of billsGuidance.bills.tree.roots){
-                    selectFBObject.setDatas(r);
-                }
+            let parentIDs = [];
+            let node = me.getSelectedNode();
+            if(node) parentIDs = me.getAllParentIDs(node);
+            this.datas = [];
+            for(let r of billsGuidance.bills.tree.roots){
+                selectFBObject.setDatas(r,parentIDs);
             }
             }
             sheetCommonObj.showTreeData(me.spread.getSheet(0), me.setting, me.datas);
             sheetCommonObj.showTreeData(me.spread.getSheet(0), me.setting, me.datas);
+            let row = me.getSelectedRow(node);
+            me.spread.getSheet(0).setSelection(row,0,1,1);
+            me.spread.getSheet(0).showRow(row, GC.Spread.Sheets.VerticalPosition.center);
         });
         });
     },
     },
-    setDatas:function(node){
+
+    getSelectedRow:function(node){
+        let row = 0;//要选中的行;   
+        if(node){
+            return _.findIndex(this.datas,{'ID':node.data.ID}) 
+        }
+        return row;
+    },
+
+    getSelectedNode:function(){
+        let node = null;
+        if($("#selectFBFor").val() == "replace") return node;
+      //如果是添加分部,则应选中对应的节点
+        /*1.当前定位在“分项”,则弹出“选择分部”窗口,并且默认定位在:根据分项编号的前9位查找清单规则中的父项。如果查找不到父项,则默认定位在第一行。 */
+        let selected = projectObj.project.mainTree.selected;
+        if(selected.data.type==billType.FX || selected.data.type==billType.BX){
+            let code = selected.data.code;
+            if(code.length === 12){
+                let matchCode =  code.substring(0,9);
+                for(let i of billsGuidance.bills.tree.items){
+                    if (i.data.code == matchCode) return i.parent;
+                } 
+            } 
+        }
+        return node;
+    },
+    getAllParentIDs:function(node){
+        let list = [];
+        getID(node,list);
+        return list;
+        function getID(node,l){
+            if(node.parent){
+                l.push(node.parent.data.ID); 
+                getID(node.parent,l)
+            }
+        }
+
+
+    },
+
+
+    setDatas:function(node,parentIDs){
         if(node.children.length > 0){//过滤叶子节点
         if(node.children.length > 0){//过滤叶子节点
             let nodeData = node.data;
             let nodeData = node.data;
             let d = {
             let d = {
@@ -58,9 +98,10 @@ let selectFBObject = {
                 name:nodeData.name,
                 name:nodeData.name,
                 unit:nodeData.unit
                 unit:nodeData.unit
             }
             }
+            if(parentIDs.includes(d.ID)) d.collapsed = false
             this.datas.push(d);
             this.datas.push(d);
             for(let c of node.children){
             for(let c of node.children){
-                this.setDatas(c)
+                this.setDatas(c,parentIDs)
             }
             }
         }
         }
     }
     }
@@ -70,20 +111,37 @@ $(function () {
     $('#selectFBDiv').on('shown.bs.modal', function (e) {
     $('#selectFBDiv').on('shown.bs.modal', function (e) {
         selectFBObject.initSpread();
         selectFBObject.initSpread();
         selectFBObject.showData();
         selectFBObject.showData();
+        sheetCommonObj.refreshWorkbookDelDefer(selectFBObject.spread, 200);
     })
     })
     $("#selectFBConfirm").click(async ()=>{
     $("#selectFBConfirm").click(async ()=>{
         let data = selectFBObject.getSelectedData();
         let data = selectFBObject.getSelectedData();
         if(!data) return;
         if(!data) return;
-        let selected = projectObj.project.mainTree.selected;
-        let datas = [{
-            type:'bills',
-            data:{
-                ID:selected.data.ID,
-                name:data.name,
-                code:data.code,
-                unit:data.unit
-            }
-          }]
-          await projectObj.project.syncUpdateNodesAndRefresh(datas);
+        let project = projectObj.project;
+        let controller =  projectObj.mainController;
+        let selected = project.mainTree.selected;
+        if($("#selectFBFor").val() == "replace"){
+            let datas = [{
+                type:'bills',
+                data:{
+                    ID:selected.data.ID,
+                    name:data.name,
+                    code:data.code,
+                    unit:data.unit
+                }
+              }]
+              await project.syncUpdateNodesAndRefresh(datas);
+        }else{
+            let ext = {name:data.name,code:data.code};
+            if(selected.data.type==billType.FX || selected.data.type==billType.BX){
+                //添加成分项的父亲
+                ProjectController.addFXParent(selected,ext);   
+           }else{//正常添加分部
+               ProjectController.addFB(project, controller,null,ext);
+               projectObj.selectColAndFocus(project.mainTree.selected);
+           }
+        } 
+
+ 
+     
     })
     })
 })
 })

+ 28 - 2
web/building_saas/main/js/views/std_ration_lib.js

@@ -6,6 +6,7 @@
 
 
 var rationLibObj = {
 var rationLibObj = {
     searchLimit: 50,
     searchLimit: 50,
+    searchMode: 0,
     libType: {complementary: 0, std: 1},
     libType: {complementary: 0, std: 1},
     compleRationLibId: 'compleRationLib',
     compleRationLibId: 'compleRationLib',
     doAfterGetRationTree: null, //获取章节树回调
     doAfterGetRationTree: null, //获取章节树回调
@@ -688,6 +689,7 @@ $('#rationSearchKeyword').keyup(function () {
 
 
 //变换搜索本定额、全部定额状态
 //变换搜索本定额、全部定额状态
 function switchRationSearchMode(mode) {
 function switchRationSearchMode(mode) {
+    rationLibObj.searchMode = mode;
     rationLibObj.resultCache = [];
     rationLibObj.resultCache = [];
     //搜索本定额
     //搜索本定额
     if(mode === 0){
     if(mode === 0){
@@ -802,12 +804,35 @@ function seachRation(){
             }
             }
         });
         });
     };
     };
+    const searchCurRationSetting = _.cloneDeep(rationLibObj.sectionRationsSetting);
+    // 搜索全部定额,表格需要多显示一列定额库
+    const searchAllRationSetting = _.cloneDeep(rationLibObj.sectionRationsSetting);
+    searchAllRationSetting.cols.push({
+        "width": 100,
+        "readOnly": true,
+        "showHint": true,
+        "head": {
+            "titleNames": ["定额库"],
+            "spanCols": [1],
+            "spanRows": [1],
+            "vAlign": [1],
+            "hAlign": [1],
+            "font": ["Arial"]
+        },
+        "data": {
+            "field": "rationLibName",
+            "vAlign": 1,
+            "hAlign": 0,
+            "font": "Arial"
+        }
+    });
+    const rationSetting = rationLibObj.searchMode === 0 ? searchCurRationSetting : searchAllRationSetting;
     var showResult = function (result) {
     var showResult = function (result) {
         if(!rationLibObj.resultSpread){
         if(!rationLibObj.resultSpread){
             let resultSpread = SheetDataHelper.createNewSpread($('.main-data-side-search')[0]);
             let resultSpread = SheetDataHelper.createNewSpread($('.main-data-side-search')[0]);
             rationLibObj.resultSpread = resultSpread;
             rationLibObj.resultSpread = resultSpread;
             bindContextmenuOpr(resultSpread.getActiveSheet());
             bindContextmenuOpr(resultSpread.getActiveSheet());
-            SheetDataHelper.loadSheetHeader(rationLibObj.sectionRationsSetting, resultSpread.getActiveSheet());
+            //SheetDataHelper.loadSheetHeader(rationLibObj.sectionRationsSetting, resultSpread.getActiveSheet());
             if (!projectReadOnly) {
             if (!projectReadOnly) {
                 resultSpread.bind(GC.Spread.Sheets.Events.CellDoubleClick, rationLibObj.onRationSpreadCellDoubleClick);
                 resultSpread.bind(GC.Spread.Sheets.Events.CellDoubleClick, rationLibObj.onRationSpreadCellDoubleClick);
             }
             }
@@ -815,7 +840,8 @@ function seachRation(){
         }else {
         }else {
             rationLibObj.resultSpread.refresh();
             rationLibObj.resultSpread.refresh();
         }
         }
-        SheetDataHelper.loadSheetData(rationLibObj.sectionRationsSetting, rationLibObj.resultSpread.getActiveSheet(), result);
+        SheetDataHelper.loadSheetHeader(rationSetting, rationLibObj.resultSpread.getActiveSheet());
+        SheetDataHelper.loadSheetData(rationSetting, rationLibObj.resultSpread.getActiveSheet(), result);
         rationLibObj.setTagForHint(rationLibObj.resultSpread.getActiveSheet(), result);
         rationLibObj.setTagForHint(rationLibObj.resultSpread.getActiveSheet(), result);
         rationLibObj.resultCache = result;
         rationLibObj.resultCache = result;
     };
     };

+ 18 - 4
web/building_saas/main/js/views/sub_view.js

@@ -142,11 +142,24 @@ let subObj = {
         let tabID = "";
         let tabID = "";
         if($('#qdzy').is(':visible')) tabID = "qdzy";
         if($('#qdzy').is(':visible')) tabID = "qdzy";
         if($('#qdjl').is(':visible')) tabID = "qdjl";
         if($('#qdjl').is(':visible')) tabID = "qdjl";
+        if($('#tzjnrCon').is(':visible')) tabID = "tznr";
         if(tabID == "") return;
         if(tabID == "") return;
         //总宽度
         //总宽度
         let totalWidth = $('#subItems').width();
         let totalWidth = $('#subItems').width();
         //人材机和项目特征文本比例
         //人材机和项目特征文本比例
         const openWidth = 30;//打开项目特征工具条
         const openWidth = 30;//打开项目特征工具条
+        if (tabID === 'tznr') {
+            if (this.showQDSubTab) {
+                $('#tzjnrCon').css('width', '66%');
+                $('#xmtzTextDiv').css('width', '34%');
+                $('#tzSubDiv').css('width', 'calc(100% - 38px)');
+            } else {
+                const tznrWidthRate = (totalWidth - openWidth) / totalWidth;
+                $('#xmtzTextDiv').css('width', '');
+                $('#tzjnrCon').css('width', `${tznrWidthRate * 100}%`);
+            }
+            return;
+        }
         const tab_tem = (305+openWidth+10)/totalWidth;//tab显示框默认宽度:305(表格宽度) + 30(工具条宽度)+10(resize div 宽度)
         const tab_tem = (305+openWidth+10)/totalWidth;//tab显示框默认宽度:305(表格宽度) + 30(工具条宽度)+10(resize div 宽度)
         //默认比例
         //默认比例
         let textPercent = tab_tem * 100 + '%',//'15%',
         let textPercent = tab_tem * 100 + '%',//'15%',
@@ -185,8 +198,7 @@ let subObj = {
         return jl_sideResizeEles;
         return jl_sideResizeEles;
     },
     },
     initQDSubTab:function () {
     initQDSubTab:function () {
-   
-      if(!($('#linkQDJL').hasClass('active') || $('#linkQDZY').hasClass('active')))   return;
+      if(!($('#linkQDJL').hasClass('active') || $('#linkQDZY').hasClass('active') || $('#linkTZJNR').hasClass('active')))   return;
       if(this.showQDSubTab == true){
       if(this.showQDSubTab == true){
           $("#tzSubDiv").show();
           $("#tzSubDiv").show();
           $("#tzrgResize").show();
           $("#tzrgResize").show();
@@ -194,7 +206,7 @@ let subObj = {
           $("#tzSubDiv").hide();
           $("#tzSubDiv").hide();
           $("#tzrgResize").hide();
           $("#tzrgResize").hide();
       }
       }
-      this.initTZItemWidth();
+        this.initTZItemWidth();
     },
     },
     showGljSubTabData:function () {
     showGljSubTabData:function () {
         this.initGljSubTab();
         this.initGljSubTab();
@@ -209,7 +221,7 @@ let subObj = {
     },
     },
     showQDSubTabData:function () {
     showQDSubTabData:function () {
         this.initQDSubTab();
         this.initQDSubTab();
-        MaterialController.showItemCharacterText(null,"tzCharacterText");
+        MaterialController.showItemCharacterText(null,"#tzCharacterText");
         if (gljOprObj.activeTab !== gljOprObj.preActiveTab) {   //提供焦点变换性能 2019年4月12日
         if (gljOprObj.activeTab !== gljOprObj.preActiveTab) {   //提供焦点变换性能 2019年4月12日
             refreshSubSpread();
             refreshSubSpread();
         }
         }
@@ -404,6 +416,8 @@ $("#linkTZJNR").click(function () {
     gljOprObj.activeTab='#linkTZJNR';
     gljOprObj.activeTab='#linkTZJNR';
     $("#subItems").children().hide();
     $("#subItems").children().hide();
     $("#tzjnrCon").show();
     $("#tzjnrCon").show();
+    $("#xmtzTextDiv").show();
+    subObj.showQDSubTabData();
     $("#add-rule p").not(":first").css('margin-bottom', 4);
     $("#add-rule p").not(":first").css('margin-bottom', 4);
     pageCCOprObj.active = true;
     pageCCOprObj.active = true;
     adaptiveTzjnrWidth();
     adaptiveTzjnrWidth();

+ 34 - 5
web/building_saas/main/js/views/tender_price_view.js

@@ -46,7 +46,6 @@ let tender_obj={
         me.tenderTreeSetting = me.createTenderTreeSetting();
         me.tenderTreeSetting = me.createTenderTreeSetting();
         TREE_SHEET_HELPER.initSetting($('#tenderSpread')[0], me.tenderTreeSetting);
         TREE_SHEET_HELPER.initSetting($('#tenderSpread')[0], me.tenderTreeSetting);
         me.tenderTreeSetting.setAutoFitRow = MainTreeCol.getEvent("setAutoFitRow");
         me.tenderTreeSetting.setAutoFitRow = MainTreeCol.getEvent("setAutoFitRow");
-        me.createTreeNodes();
     },
     },
     createTreeNodes() {
     createTreeNodes() {
         let me = this;
         let me = this;
@@ -66,7 +65,7 @@ let tender_obj={
 
 
                 if (calcTools.isRationCategory(newNode))
                 if (calcTools.isRationCategory(newNode))
                     newNode.visible = false;
                     newNode.visible = false;
-                    
+
                 if (mainNode.children.length > 0) {
                 if (mainNode.children.length > 0) {
                     for (let c of mainNode.children) {
                     for (let c of mainNode.children) {
                         createTenderNode(c, newNode, null);
                         createTenderNode(c, newNode, null);
@@ -420,7 +419,7 @@ let tender_obj={
         // 量价类,工料机消耗量调整系数不允许输入
         // 量价类,工料机消耗量调整系数不允许输入
         let treeNode = me.tenderTree.items[row];
         let treeNode = me.tenderTree.items[row];
         if (calcTools.isVolumePrice(treeNode) || calcTools.isGljRation(treeNode)){
         if (calcTools.isVolumePrice(treeNode) || calcTools.isGljRation(treeNode)){
-            if ([11,12,13,14,15].includes(col))
+            if ([10,11,12,13,14].includes(col))
                 return false;
                 return false;
         };
         };
         return true;
         return true;
@@ -455,6 +454,7 @@ $(function () {
         $(e.relatedTarget.hash).removeClass('active');
         $(e.relatedTarget.hash).removeClass('active');
         if(!tender_obj.tenderSpread){
         if(!tender_obj.tenderSpread){
             tender_obj.createTree();
             tender_obj.createTree();
+            tender_obj.createTreeNodes();
             tender_obj.initTenderSpread();
             tender_obj.initTenderSpread();
             tender_obj.showTenderData();
             tender_obj.showTenderData();
             tender_obj.initPageContent();
             tender_obj.initPageContent();
@@ -508,6 +508,14 @@ $(function () {
                 delete projectObj.project.property.needRestoreGgljPriceTenderCoe;
                 delete projectObj.project.property.needRestoreGgljPriceTenderCoe;
                 $('#gljPriceTenderCoe').val(1);
                 $('#gljPriceTenderCoe').val(1);
             }
             }
+
+            if ($('#cbShowTenderFields').prop("checked") == false){
+              $('#cbShowTenderFields').prop("checked", true);
+              projectObj.project.saveProperty('tenderSetting.showTenderFields', true);
+              projectObj.project.property.tenderSetting.showTenderFields = true;
+              gljCol.showTenderFields(true, true);
+            }
+
             tender_obj.showTenderData();
             tender_obj.showTenderData();
             projectObj.project.projectGLJ.calcQuantity();
             projectObj.project.projectGLJ.calcQuantity();
             // 刷新造价书界面的相关显示。刷新放在这里是为了切换UI时体验更流畅。
             // 刷新造价书界面的相关显示。刷新放在这里是为了切换UI时体验更流畅。
@@ -536,9 +544,30 @@ $(function () {
         // datas.push({type:ModuleNames.project,data:{'ID' : projectObj.project.ID(),'property.hasTender': false}});
         // datas.push({type:ModuleNames.project,data:{'ID' : projectObj.project.ID(),'property.hasTender': false}});
         me.updateTenderData(datas,function () {
         me.updateTenderData(datas,function () {
             // me.refreshTenderTreeByDatas(datas);
             // me.refreshTenderTreeByDatas(datas);
-            $('#calcTender').trigger('click');
-        });
+          let callback = function () {
+            if (projectObj.project.property.needRestoreGgljPriceTenderCoe){         // 入库存储,清理标记,刷新UI显示
+              projectObj.project.saveProperty('tenderSetting.gljPriceTenderCoe', 1);
+              delete projectObj.project.property.needRestoreGgljPriceTenderCoe;
+              $('#gljPriceTenderCoe').val(1);
+            }
 
 
+            if ($('#cbShowTenderFields').prop("checked") == true){
+              $('#cbShowTenderFields').prop("checked", false);
+              projectObj.project.saveProperty('tenderSetting.showTenderFields', false);
+              projectObj.project.property.tenderSetting.showTenderFields = false;
+              gljCol.showTenderFields(false, true);
+            }
+
+            tender_obj.showTenderData();
+            projectObj.project.projectGLJ.calcQuantity();
+            // 刷新造价书界面的相关显示。刷新放在这里是为了切换UI时体验更流畅。
+            if($('#linkJSCX').hasClass('active'))
+              calcProgramObj.refreshCalcProgram(projectObj.project.mainTree.selected, 2)
+            if($('#linkGLJ').hasClass('active'))
+              gljOprObj.refreshView();
+          };
+          projectObj.project.calcProgram.doTenderCalc(callback);
+        });
     });
     });
 
 
     $('#cbShowTenderFields').on('click', function () {
     $('#cbShowTenderFields').on('click', function () {

+ 145 - 1
web/building_saas/main/js/views/zlfb_view.js

@@ -65,7 +65,7 @@ let zlfb_object={
         let controller = projectObj.mainController, project = projectObj.project;
         let controller = projectObj.mainController, project = projectObj.project;
         let Bill = project.Bills;
         let Bill = project.Bills;
         let FBFX = Bill.getFBFXNode(controller);//取分部分项工程节点;
         let FBFX = Bill.getFBFXNode(controller);//取分部分项工程节点;
-        let resort = $('#bill_resort').prop('checked'),recode=$('#bill_recode').prop('checked'),first=$('#bill_first').prop('checked');
+        let resort = true,recode=false,first=$('#bill_first').prop('checked');//清单排序和重新编码放到另外的页面
         let second =$('#bill_second').prop('checked'), third =$('#bill_third').prop('checked');
         let second =$('#bill_second').prop('checked'), third =$('#bill_third').prop('checked');
         let needSelf = first==true||second==true||third==true;//需要补充分部节点;
         let needSelf = first==true||second==true||third==true;//需要补充分部节点;
         if(me.sectionInfo){
         if(me.sectionInfo){
@@ -146,6 +146,142 @@ let zlfb_object={
             me.submitRequest(newDataMap,allNewNode,updateData,FBFX,controller);
             me.submitRequest(newDataMap,allNewNode,updateData,FBFX,controller);
         }
         }
     },
     },
+    ZLQD:async function(){//只清单排序或者重新编码
+        //
+        let me = this;
+        let selected = projectObj.project.mainTree.selected;
+        let resort = $('#bill_resort').prop('checked'),recode=$('#bill_recode').prop('checked')
+        let startNum = parseInt($('#bill_recode_start').val());
+        let FBNodes = [],updateMap = {},codeMap={};
+        let recoverMap = {};//排序失败后用来恢复原状的缓存
+        let tree = projectObj.mainController.tree;
+        if(resort||recode){
+            //先找出需要排序和重新编码的节点
+            for(let node of tree.items){
+                if(node.sourceType===ModuleNames.bills){
+                    if(node.data.type == billType.FB && node.children.length > 1){//有两个以上的才需要排序
+                        let subType = node.children[0].data.type;
+                        if(subType ===  billType.FX || subType ===  billType.BX){
+                            FBNodes.push(node);
+                            recoverMap[node.data.ID] = node.children;
+                        } 
+                   } 
+                } 
+            }   
+            try {
+                if(resort){//如果需要重新排序  -- 重新排序还必须得先改变缓存,如果勾选了重新编码,顺序依赖于排好序的清单
+                    for(let FB of FBNodes){
+                        me.resortChildren(FB,updateMap)
+                    }
+                    tree.sortTreeItems(tree);
+                }
+        
+                if(recode){
+                    if(!(startNum >= 1)){
+                        return alert("起始编码必须大于1!")
+                    } 
+                    for(let node of tree.items){
+                        if(node.data.billsLibId){
+                            let l_code = me.getLibCode(node.data.code); 
+                            if(l_code !== false){
+                                if(codeMap[l_code]){
+                                    codeMap[l_code]+=1;
+                                }else {
+                                    codeMap[l_code]=startNum;
+                                }
+                                newCode = l_code+me.getEndCode(codeMap[l_code],3);
+                                if(updateMap[node.data.ID]){
+                                    updateMap[node.data.ID].data.code = newCode;
+                                }else{
+                                    updateMap[node.data.ID] =  {
+                                        type:'bills',
+                                        data:{
+                                               projectID:node.data.projectID,
+                                               ID:node.data.ID,
+                                               code :newCode
+                                            } 
+                                        };
+                                }
+                            }
+                        }
+                    }
+
+                }
+        
+                let datas = [];
+                for(let ID in updateMap){
+                    datas.push(updateMap[ID]);
+                }
+               if(datas.length > 0) await projectObj.project.syncUpdateNodesAndRefresh(datas);
+
+               projectObj.mainController.refreshTreeNode(FBNodes,true);
+               this.refreshVisable(FBNodes);
+               let sel = projectObj.mainController.sheet.getSelections()[0];
+               sel.row = selected.serialNo();
+               projectObj.mainController.sheet.setSelection(sel.row,sel.col,sel.rowCount,sel.colCount);
+               projectObj.mainController.setTreeSelected(selected);
+            } catch (error) {
+                alert('清单排序/重新编码失败,请重试!');
+                console.log(error);
+                //恢复排序
+                for(let FB of FBNodes){
+                    me.resortChildren(FB,{},recoverMap[FB.data.ID]);
+                }
+                tree.sortTreeItems(tree);
+                this.refreshVisable(FBNodes);
+            } 
+         
+         
+        }
+    },
+    refreshVisable:function (FBNodes) {
+      let sheet =  projectObj.mainController.sheet;
+      let tree = projectObj.mainController.tree;
+      sheet.suspendPaint();
+      sheet.suspendEvent();
+      for(let pnode of FBNodes){
+        TREE_SHEET_HELPER.refreshChildrenVisiable(sheet,tree,pnode,pnode.serialNo());
+        for(let node of pnode.children){
+            TREE_SHEET_HELPER.refreshChildrenVisiable(sheet,tree,node,node.serialNo());
+        }  
+      } 
+      sheet.resumeEvent();
+      sheet.resumePaint();  
+    },
+
+
+    resortChildren:function(node,updateMap,recoverChildren){
+        if(recoverChildren){
+            node.children = recoverChildren;
+        }else{
+            node.children = _.sortBy(node.children,'data.code');
+        } 
+       for(let i=0;i<node.children.length;i++){
+           let subNode = node.children[i];
+           let tem = {
+            type:'bills',
+            data:{
+                projectID:subNode.data.projectID,
+                ID:subNode.data.ID,
+                } 
+            }; 
+            if(i===0){
+                subNode.preSibling == 0;
+            }else{
+                subNode.preSibling = node.children[i-1];
+            }
+
+           if(i == node.children.length-1){//如果是最后一个节点
+            tem.data.NextSiblingID=-1;
+            subNode.nextSibling = null
+           }else{
+            tem.data.NextSiblingID= node.children[i+1].data.ID;
+            subNode.nextSibling = node.children[i+1];
+           }
+          updateMap[subNode.data.ID] = tem
+       } 
+    },
+
     addSubNode:function (parentNode,oldChildren,allNewNode,controller) {
     addSubNode:function (parentNode,oldChildren,allNewNode,controller) {
         for(let c of oldChildren){
         for(let c of oldChildren){
             let newChild = controller.tree.insert(parentNode.getID(), -1,c.getID());
             let newChild = controller.tree.insert(parentNode.getID(), -1,c.getID());
@@ -300,6 +436,7 @@ let zlfb_object={
 
 
 
 
 $(function () {
 $(function () {
+
     $('#zlfb_confirm').click(function (){
     $('#zlfb_confirm').click(function (){
         $("#zlfb").modal('hide');
         $("#zlfb").modal('hide');
         zlfb_object.reorganizeNodes();
         zlfb_object.reorganizeNodes();
@@ -308,4 +445,11 @@ $(function () {
         zlfb_object.sectionInfo=null;
         zlfb_object.sectionInfo=null;
     })
     })
 
 
+    $('#ZLQD_btn').click(function () {
+        $("#zlqd").modal('show');
+    });
+    $('#zlqd_confirm').click(function (){
+        $("#zlqd").modal('hide');
+        zlfb_object.ZLQD();
+    });
 });
 });

+ 22 - 0
web/building_saas/pm/js/pm_ajax.js

@@ -23,6 +23,28 @@ var GetAllProjectData = function (callback) {
         }
         }
     });
     });
 }
 }
+// 获取建设项目下全部单位工程数据
+var GetAllUnitProjectData = function (params, callback) {
+    $.ajax({
+        type:"POST",
+        url: '/pm/api/getAllUnitProjects',
+        data: {'data': params},
+        dataType: 'json',
+        cache: false,
+        timeout: 50000,
+        success: function(result){
+            if (result.error === 0) {
+                callback(result.data);
+                //Tree = $.fn.treeTable.init(table, ProjTreeSetting, result.data);
+            } else {
+                alert('error: ' + result.message);
+            }
+        },
+        error: function(jqXHR, textStatus, errorThrown){
+            alert('error ' + textStatus + " " + errorThrown);
+        }
+    });
+}
 // 更新数据到服务器
 // 更新数据到服务器
 var UpdateProjectData = function (updateData, callback, errCB) {
 var UpdateProjectData = function (updateData, callback, errCB) {
     const tenderCount = updateData.filter(item => item.updateType === 'new' && item.updateData.projType === projectType.tender).length;
     const tenderCount = updateData.filter(item => item.updateType === 'new' && item.updateData.projType === projectType.tender).length;

+ 7 - 6
web/building_saas/pm/js/pm_import.js

@@ -261,13 +261,14 @@ const importView = (() => {
             feeStandardName: curEngineering.lib.feeName,    //费用标准
             feeStandardName: curEngineering.lib.feeName,    //费用标准
             engineering: curEngineering.lib.engineering,    //定额取费专业
             engineering: curEngineering.lib.engineering,    //定额取费专业
             projectEngineering: curEngineering.lib.projectEngineering,  //单位工程取费专业
             projectEngineering: curEngineering.lib.projectEngineering,  //单位工程取费专业
-            featureLibID: curEngineering.lib.feature_lib[0] ? curEngineering.lib.feature_lib[0].id : '',    //工程特征
+            featureLibID: curEngineering.lib.feature_lib && curEngineering.lib.feature_lib[0] ? curEngineering.lib.feature_lib[0].id : '',    //工程特征
             indexName: curEngineering.lib.indexName,    // 指标名称
             indexName: curEngineering.lib.indexName,    // 指标名称
-            engineerInfoLibID: curEngineering.lib.engineer_info_lib[0] ? curEngineering.lib.engineer_info_lib[0].id : '',   // 工程信息指标
-            engineerFeatureLibID: curEngineering.lib.engineer_feature_lib[0] ? curEngineering.lib.engineer_feature_lib[0].id : '',  //工程特征指标
-            economicLibID: curEngineering.lib.economic_lib[0] ? curEngineering.lib.economic_lib[0].id : '',    // 主要经济指标
-            mainQuantityLibID: curEngineering.lib.main_quantity_lib[0] ? curEngineering.lib.main_quantity_lib[0].id : '',   // 主要工程量指标
-            materialLibID: curEngineering.lib.material_lib[0] ? curEngineering.lib.material_lib[0].id : '', // 主要工料指标
+            engineerInfoLibID: curEngineering.lib.engineer_info_lib && curEngineering.lib.engineer_info_lib[0] ? curEngineering.lib.engineer_info_lib[0].id : '',   // 工程信息指标
+            engineerFeatureLibID: curEngineering.lib.engineer_feature_lib && curEngineering.lib.engineer_feature_lib[0] ? curEngineering.lib.engineer_feature_lib[0].id : '',  //工程特征指标
+            economicLibID: curEngineering.lib.economic_lib && curEngineering.lib.economic_lib[0] ? curEngineering.lib.economic_lib[0].id : '',    // 主要经济指标
+            mainQuantityLibID: curEngineering.lib.main_quantity_lib && curEngineering.lib.main_quantity_lib[0] ? curEngineering.lib.main_quantity_lib[0].id : '',   // 主要工程量指标
+            materialLibID: curEngineering.lib.material_lib && curEngineering.lib.material_lib[0] ? curEngineering.lib.material_lib[0].id : '', // 主要工料指标
+            progressiveLibID: curEngineering.lib.progressive_lib && curEngineering.lib.progressive_lib[0] ? curEngineering.lib.progressive_lib[0].id: '', // 累进库
             calcProgram: { name: taxData.program_lib.name, id: taxData.program_lib.id },  //计算程序
             calcProgram: { name: taxData.program_lib.name, id: taxData.program_lib.id },  //计算程序
             colLibID: taxData.col_lib.id,   //列设置
             colLibID: taxData.col_lib.id,   //列设置
             templateLibID: taxData.template_lib.id, //清单模板
             templateLibID: taxData.template_lib.id, //清单模板

+ 38 - 17
web/building_saas/pm/js/pm_newMain.js

@@ -474,6 +474,17 @@ const projTreeObj = {
                 $("#import").modal('show');
                 $("#import").modal('show');
                 projTreeObj.getUploadToken();
                 projTreeObj.getUploadToken();
             }
             }
+        },
+        importExampleProject:{
+            name: "加载例题",
+            icon: 'fa-refresh',
+            visible: function () {
+                return false;
+            },
+            callback: function (key, opt) {
+
+                projTreeObj.importExampleProjects();
+            }
         }
         }
     },
     },
     //全部-开始(新建)按钮弹出菜单(新建单位工程)
     //全部-开始(新建)按钮弹出菜单(新建单位工程)
@@ -507,7 +518,8 @@ const projTreeObj = {
                 "manageFiles": me.contextMenuItems.manageFiles,
                 "manageFiles": me.contextMenuItems.manageFiles,
                 "refreshSummary": me.contextMenuItems.refreshSummary,
                 "refreshSummary": me.contextMenuItems.refreshSummary,
                 "exportProject":me.contextMenuItems.exportProject,
                 "exportProject":me.contextMenuItems.exportProject,
-                "importProject":me.contextMenuItems.importProject
+                "importProject":me.contextMenuItems.importProject,
+                "importExampleProject":me.contextMenuItems.importExampleProject
             }
             }
         });
         });
     },
     },
@@ -1763,6 +1775,30 @@ const projTreeObj = {
             }
             }
         }
         }
         this.initTree(true, callback, expandCallback);
         this.initTree(true, callback, expandCallback);
+    },
+    importExampleProjects:async function(isChongqing=false){
+        if (STATE.importing) {
+            return;
+        }
+        let textBody = '正在导入例题,请稍候……'
+        let url = 'importExampleProject';
+        STATE.importing = true;
+        if(isChongqing){
+            $('#welcomePage').modal('hide');
+            textBody = "正在导入测评项目,请稍候……";
+            url = 'importChongqingProject';
+        } 
+        try {
+            let key = uuid.v1();
+            $.bootstrapLoading.progressStart("欢迎使用大司空云计价",true);
+            $("#progress_modal_body").text(textBody);
+            let result = await ajaxPost(`/pm/api/${url}`,{user_id: userID,key:key});
+            importProcessChecking(key, null, (projectData) => handleProjectAfterChecking(projectData));
+        }catch (error){
+            alert(error);
+        }finally {
+            STATE.importing = false;
+        }
     }
     }
 };
 };
 // 新建项目必填项提示框设置“ 比如:注:为响应重庆地区指标采集标准数据要求,以上工程信息及特征必填项为必填项,请正确填写。”
 // 新建项目必填项提示框设置“ 比如:注:为响应重庆地区指标采集标准数据要求,以上工程信息及特征必填项为必填项,请正确填写。”
@@ -4823,22 +4859,7 @@ function refreshProjSummary(project, summaryInfo) {
 $(function () {
 $(function () {
     if(isShow)  $('#welcomePage').modal('show');//是否显示欢迎页
     if(isShow)  $('#welcomePage').modal('show');//是否显示欢迎页
     $('#importChongqing').click(async function () {
     $('#importChongqing').click(async function () {
-        if (STATE.importing) {
-            return;
-        }
-        STATE.importing = true;
-        $('#welcomePage').modal('hide');
-        try {
-            let key = uuid.v1();
-            $.bootstrapLoading.progressStart("欢迎使用大司空云计价",true);
-            $("#progress_modal_body").text("正在导入测评项目,请稍候……");
-            let result = await ajaxPost("/pm/api/importChongqingProject",{user_id: userID,key:key});
-            importProcessChecking(key, null, (projectData) => handleProjectAfterChecking(projectData));
-        }catch (error){
-            alert(error);
-        }finally {
-            STATE.importing = false;
-        }
+      await  projTreeObj.importExampleProjects(true);
     })
     })
 });
 });
 
 

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

@@ -570,7 +570,6 @@ const pmTree = {
         })()
         })()
 
 
         let tree = new Tree(setting);
         let tree = new Tree(setting);
-        sessionStorage.setItem('projects_tree_data', JSON.stringify(arrData)); // 报表用,不要删除
         tree.loadData(arrData);
         tree.loadData(arrData);
         return tree;
         return tree;
 
 

+ 62 - 38
web/building_saas/report/js/rpt_main.js

@@ -3,6 +3,7 @@
  */
  */
 'use strict'
 'use strict'
 
 
+
 const PRE_PAGE_OFFSET = 150;
 const PRE_PAGE_OFFSET = 150;
 const NEXT_PAGE_OFFSET = 160;
 const NEXT_PAGE_OFFSET = 160;
 const FIRST_PAGE_OFFSET = 50;
 const FIRST_PAGE_OFFSET = 50;
@@ -28,11 +29,18 @@ let rptTplObj = {
                 JpcJsPDFHelper.initialize('p', 'pt', 'a4');
                 JpcJsPDFHelper.initialize('p', 'pt', 'a4');
             }
             }
             //收集本单位工程所属的建设项目下所有单位工程id用
             //收集本单位工程所属的建设项目下所有单位工程id用
-            me.project_tree = tree_Data_Helper.buildTreeNodeDirectly(JSON.parse(sessionStorage.getItem('projects_tree_data')), false);
-            // console.log(me.getAllPrjIds());
-            // projectObj.project.projectInfo.ID
-            // dynamicLoadJs('/lib/jspdf/SmartSimsun-normal.js');
-            // dynamicLoadJs('/lib/jspdf/SmartSimsun-bold.js', me.pdfFontSimsunCallBack);
+            // GetAllProjectData(function (datas) {
+            //     //
+            // }
+            let params = {
+                rootProjectID: projectObj.project.property.rootProjectID,
+                user_id: userID
+            };
+            CommonAjax.post("pm/api/getAllUnitProjects", params, function(result) {
+                // console.log(result);
+                me.project_tree = result;
+                // console.log(me.getAllPrjIds());
+            });
         }
         }
     },
     },
     
     
@@ -40,32 +48,8 @@ let rptTplObj = {
         let me = this;
         let me = this;
         let rst = [];
         let rst = [];
         if (me.project_tree) {
         if (me.project_tree) {
-            const _chkIfHasCurrentPrjId = function(nodeItem) {
-                let chkRst = (nodeItem.ID === projectObj.project.projectInfo.ID);
-                if (!chkRst && nodeItem.items && nodeItem.items.length > 0) {
-                    for (const subItem of nodeItem.items) {
-                        chkRst = _chkIfHasCurrentPrjId(subItem);
-                        if (chkRst) {
-                            break;
-                        }
-                    }
-                }
-                return chkRst;
-            };
-            const _retrievAllDtlPrjIds = function(parentNode) {
-                if (parentNode.items === null || parentNode.items === undefined || parentNode.items.length === 0) {
-                    rst.push(parentNode.ID);
-                } else {
-                    for (const subNode of parentNode.items) {
-                        _retrievAllDtlPrjIds(subNode);
-                    }
-                }
-            };
-            for (let topNode of me.project_tree) {
-                if (_chkIfHasCurrentPrjId(topNode)) {
-                    _retrievAllDtlPrjIds(topNode);
-                    break;
-                }
+            for (let prj of me.project_tree) {
+                rst.push(prj.ID);
             }
             }
         }
         }
         return rst;
         return rst;
@@ -262,7 +246,7 @@ let zTreeOprObj = {
     onCheck: function(event, treeId, treeNode) {
     onCheck: function(event, treeId, treeNode) {
         zTreeOprObj.countChkedRptTpl();
         zTreeOprObj.countChkedRptTpl();
     },
     },
-    onClick: function(event,treeId,treeNode) {
+    onClick: async function(event,treeId,treeNode) {
         let me = zTreeOprObj;
         let me = zTreeOprObj;
         if (treeNode.nodeType === TPL_TYPE_TEMPLATE && treeNode.refId > 0) {
         if (treeNode.nodeType === TPL_TYPE_TEMPLATE && treeNode.refId > 0) {
             let params = {};
             let params = {};
@@ -273,9 +257,25 @@ let zTreeOprObj = {
             params.custCfg = me.reportPageCfg;
             params.custCfg = me.reportPageCfg;
             params.flag = null;
             params.flag = null;
             if (treeNode.hasOwnProperty('flags')) {
             if (treeNode.hasOwnProperty('flags')) {
+                if (treeNode.flags.hasOwnProperty('auditType') && treeNode.flags.auditType === 'audit_compare') {
+                    let pids = [];
+                    let comp_pid = await compareObject.getCompareID(); //返回单个对应的project ID
+                    if (comp_pid !== null) {
+                        pids.push(projectObj.project.projectInfo.ID);
+                        pids.push(comp_pid);
+                        params.prj_ids = pids;
+                    } else {
+                        /*
+                        params.prj_ids = [25062, 25082]; // hard code 测试项目:酉阳县东部沿海产业转移承接基地建设项目(一期)一标段 + 审定
+                        /*/
+                        alert('未设置审核对比项目!');
+                        exit;
+                        //*/
+                    }
+                } else {
+                    params.prj_ids = rptTplObj.getAllPrjIds();
+                }
                 params.flag = treeNode.flags;
                 params.flag = treeNode.flags;
-                params.prj_ids = rptTplObj.getAllPrjIds();
-                // params.prj_ids = [projectObj.project.projectInfo.ID]; //测试
             }
             }
             me.currentNode = treeNode;
             me.currentNode = treeNode;
             me.requestReport(params);
             me.requestReport(params);
@@ -612,10 +612,10 @@ let rptControlObj = {
             me.getPDFEx();
             me.getPDFEx();
         } else {
         } else {
             $("#ini_PDF_Btn").trigger("click");
             $("#ini_PDF_Btn").trigger("click");
-            dynamicLoadJs('/lib/jspdf/SmartSimsun-normal.js',"normal", me.getPdfFontCallback);
-            dynamicLoadJs('/lib/jspdf/SmartSimsun-bold.js',"bold", me.getPdfFontCallback);
-            // dynamicLoadJs('https://d2.smartcost.com.cn/cach/SmartSimsun-normal.js', 'normal', me.getPdfFontCallback);
-            // dynamicLoadJs('https://d2.smartcost.com.cn/cach/SmartSimsun-bold.js', 'bold', me.getPdfFontCallback);
+            // dynamicLoadJs('/lib/jspdf/SmartSimsun-normal.js',"normal", me.getPdfFontCallback);
+            // dynamicLoadJs('/lib/jspdf/SmartSimsun-bold.js',"bold", me.getPdfFontCallback);
+            dynamicLoadJs('https://d2.smartcost.com.cn/cach/SmartSimsun-normal.js', 'normal', me.getPdfFontCallback);
+            dynamicLoadJs('https://d2.smartcost.com.cn/cach/SmartSimsun-bold.js', 'bold', me.getPdfFontCallback);
         }
         }
     },
     },
     getPDFEx: function () {
     getPDFEx: function () {
@@ -842,4 +842,28 @@ function dynamicLoadCss(url) {
     link.rel = 'stylesheet';
     link.rel = 'stylesheet';
     link.href = url;
     link.href = url;
     head.appendChild(link);
     head.appendChild(link);
+}
+
+function _getCommonParams(treeNode) {
+    let rstParmas = {};
+    rstParmas.pageSize = rptControlObj.getCurrentPageSize();
+    rstParmas.rpt_tpl_id = treeNode.refId;
+    if (zTreeOprObj.checkedRptTplNodes && zTreeOprObj.checkedRptTplNodes.length > 0) {
+        let refRptTplIds = [];
+        for (let node of zTreeOprObj.checkedRptTplNodes) {
+            refRptTplIds.push(node.refId);
+            let flag = null;
+            if (node.hasOwnProperty('flags')) {
+                flag = node.flags;
+                params.prj_ids = rptTplObj.getAllPrjIds();
+            }
+            flags.push(flag);
+        }
+        params.rpt_ids = refRptTplIds;
+    }
+    params.prj_id = projectObj.project.projectInfo.ID;
+
+    rstParmas.prj_id = projectObj.project.projectInfo.ID;
+    // rstParmas.custCfg = me.reportPageCfg;
+    return rstParmas;
 }
 }

+ 1 - 1
web/building_saas/unit_price_file/index.html

@@ -31,7 +31,7 @@
     <style type="text/css">
     <style type="text/css">
         .ztree * {
         .ztree * {
             font-family: Calibri;
             font-family: Calibri;
-            font-size: 0.9rem;
+            font-size: 14px;
         }
         }
     </style>
     </style>
 
 

+ 7 - 0
web/common/components/share/index.js

@@ -14,11 +14,13 @@ const SHARE_TO = (() => {
         PROJECT: 1,
         PROJECT: 1,
         RATION_LIB: 2,
         RATION_LIB: 2,
         GLJ_LIB: 3,
         GLJ_LIB: 3,
+        BLOCK_LIB: 4,
     };
     };
 
 
     const ModeToLibType = {
     const ModeToLibType = {
         [Mode.RATION_LIB]: ShareLibType.RATION_LIB,
         [Mode.RATION_LIB]: ShareLibType.RATION_LIB,
         [Mode.GLJ_LIB]: ShareLibType.GLJ_LIB,
         [Mode.GLJ_LIB]: ShareLibType.GLJ_LIB,
+        [Mode.BLOCK_LIB]: ShareLibType.BLOCK_LIB,
     };
     };
 
 
     // 当前模式
     // 当前模式
@@ -274,6 +276,11 @@ const SHARE_TO = (() => {
                 } else {
                 } else {
                     curSharedUsers = curSharedUsers.filter(user => user._id !== receiver);
                     curSharedUsers = curSharedUsers.filter(user => user._id !== receiver);
                 }
                 }
+                if (libType === ShareLibType.BLOCK_LIB) {
+                    const shareTip = curSharedUsers.length ?  curSharedUsers.reduce((acc, user) => acc += ` ${user.real_name}`, '已分享给') : '';
+                    blockLibObj.initialShareTip = shareTip;
+                    $('#btn_block_share').attr('data-original-title', shareTip);
+                }
                 if (Array.isArray(rst.recentUsers)) {
                 if (Array.isArray(rst.recentUsers)) {
                     initRecentView(rst.recentUsers);
                     initRecentView(rst.recentUsers);
                 }
                 }

+ 64 - 21
web/over_write/js/chongqing_2018_export.js

@@ -1073,7 +1073,7 @@ const XMLStandard = (function () {
             return [{
             return [{
                 data: project,
                 data: project,
                 exportKind: exportKind,
                 exportKind: exportKind,
-                fileName: `重庆标准交换数据(${FILE_KIND_TEXT[exportKind]}).QTF`
+                fileName: `${projectData.name}(${FILE_KIND_TEXT[exportKind]}).QTF`
             }];
             }];
         }
         }
         //单位工程内的人材机ID: 用于代码映射关系 //单位工程级别,C+数组下标 <==> gljID
         //单位工程内的人材机ID: 用于代码映射关系 //单位工程级别,C+数组下标 <==> gljID
@@ -1174,7 +1174,7 @@ const XMLStandard = (function () {
             tender.children.push(loadCSXM(tenderDetail));
             tender.children.push(loadCSXM(tenderDetail));
             //其他项目清单
             //其他项目清单
             let other = loadOtherBills(tenderDetail);
             let other = loadOtherBills(tenderDetail);
-            if (other) {
+            if (other && other.children.length) {
                 tender.children.push(other);
                 tender.children.push(other);
             }
             }
             //规费和税金清单
             //规费和税金清单
@@ -1206,7 +1206,7 @@ const XMLStandard = (function () {
                     let engineeringCostNode = tenderDetail.Bills.tree.roots.find(node => node.getFlag() === fixedFlag.ENGINEERINGCOST);
                     let engineeringCostNode = tenderDetail.Bills.tree.roots.find(node => node.getFlag() === fixedFlag.ENGINEERINGCOST);
                     if (engineeringCostNode) {
                     if (engineeringCostNode) {
                         let ecTotalFee = _util.getFee(engineeringCostNode.data.fees, 'common.totalFee');
                         let ecTotalFee = _util.getFee(engineeringCostNode.data.fees, 'common.totalFee');
-                        let exponentialGljs = materialAdjustObj.getPriceCoeDatas(projectGLJList, contractorList, ecTotalFee, decimalObj);
+                        let exponentialGljs = materialAdjustObj.getPriceCoeDatas(projectGLJList, contractorList, ecTotalFee, tenderDetail.projectInfo.property);
                         if (exponentialGljs.length) {
                         if (exponentialGljs.length) {
                             // 变值权重B累加
                             // 变值权重B累加
                             let totalVarWeight = exponentialGljs.reduce((acc, cur) => acc += cur.varWeight || 0, 0);
                             let totalVarWeight = exponentialGljs.reduce((acc, cur) => acc += cur.varWeight || 0, 0);
@@ -1499,11 +1499,38 @@ const XMLStandard = (function () {
             }
             }
             //是否有清单分类,分部分项下,清单分类和清单项目不可同层存在,如果有了清单分类,则提示其他清单项目:
             //是否有清单分类,分部分项下,清单分类和清单项目不可同层存在,如果有了清单分类,则提示其他清单项目:
             //清单xx行应是清单分类,其下必须有清单项目
             //清单xx行应是清单分类,其下必须有清单项目
+            function loadSubFBFX(nodes) {
+                const rst = [];
+                nodes.forEach(node => {
+                    if (node.data.type === billType.FB) {
+                        //创建清单分部节点
+                        const fbSource = {
+                            row: detail.mainTree.nodes[detail.mainTree.prefix + node.data.ID].serialNo() + 1,
+                            code: node.data.code,
+                            name: node.data.name,
+                            fees: node.data.fees,
+                            remark: node.data.remark
+                        };
+                        const fb = new FBBills(fbSource);
+                        rst.push(fb);
+                        if (node.children.length) {
+                            fb.children.push(...loadSubFBFX(node.children));
+                        } else {
+                            _failList.push(`第${fbSource.row}行清单分部下至少要有一条清单。`);
+                        }
+                    } else {
+                        const fx = loadBills(node, detail);
+                        rst.push(fx);
+                    }
+                });
+                return rst;
+            }
             let hasBillsClass = subEngNode.children && subEngNode.children.some(node => node.children && node.children.length);
             let hasBillsClass = subEngNode.children && subEngNode.children.some(node => node.children && node.children.length);
             for (let node of subEngNode.children) {
             for (let node of subEngNode.children) {
                 if (node.data.type === billType.FB) {
                 if (node.data.type === billType.FB) {
+                    fbfxBills.children.push(...loadSubFBFX([node]));
                     //创建清单分部节点
                     //创建清单分部节点
-                    let fbSource = {
+                   /*  let fbSource = {
                         row: detail.mainTree.nodes[detail.mainTree.prefix + node.data.ID].serialNo() + 1,
                         row: detail.mainTree.nodes[detail.mainTree.prefix + node.data.ID].serialNo() + 1,
                         code: node.data.code,
                         code: node.data.code,
                         name: node.data.name,
                         name: node.data.name,
@@ -1511,7 +1538,7 @@ const XMLStandard = (function () {
                         remark: node.data.remark
                         remark: node.data.remark
                     };
                     };
                     if (node.children.length === 0) {
                     if (node.children.length === 0) {
-                        _failList.push(`第${fbSource.row}行清单分部下至少要有一条清单项目。`);
+                        _failList.push(`第${fbSource.row}行清单分部下至少要有一条分部或分项。`);
                     }
                     }
                     let fbBills = new FBBills(fbSource);
                     let fbBills = new FBBills(fbSource);
                     fbfxBills.children.push(fbBills);
                     fbfxBills.children.push(fbBills);
@@ -1520,15 +1547,16 @@ const XMLStandard = (function () {
                         //detail.mainTree.nodes[detail.mainTree.prefix + node.data.ID].serialNo() + 1,
                         //detail.mainTree.nodes[detail.mainTree.prefix + node.data.ID].serialNo() + 1,
                         let fx = loadBills(subNode, detail);
                         let fx = loadBills(subNode, detail);
                         fbBills.children.push(fx);
                         fbBills.children.push(fx);
-                    }
+                    } */
                 } else {
                 } else {
                     //第一层有了分部,不能有分项
                     //第一层有了分部,不能有分项
                     if (hasBillsClass) {
                     if (hasBillsClass) {
                         let row = detail.mainTree.nodes[detail.mainTree.prefix + node.data.ID].serialNo() + 1;
                         let row = detail.mainTree.nodes[detail.mainTree.prefix + node.data.ID].serialNo() + 1;
                         _failList.push(`第${row}行清单应是清单分部,其下必须有清单项目。<span style="color: red">(错误清单结构)</span>`);
                         _failList.push(`第${row}行清单应是清单分部,其下必须有清单项目。<span style="color: red">(错误清单结构)</span>`);
                     }
                     }
-                    let fxBills = loadBills(node, detail);
-                    fbfxBills.children.push(fxBills);
+                    fbfxBills.children.push(...loadSubFBFX([node]));
+                    /* let fxBills = loadBills(node, detail);
+                    fbfxBills.children.push(fxBills); */
                 }
                 }
             }
             }
             return fbfxBills;
             return fbfxBills;
@@ -1630,6 +1658,15 @@ const XMLStandard = (function () {
                 }
                 }
             }
             }
         }
         }
+
+        // 过滤其他项目子清单空行
+        // 空行判断条件:编码、名称、单位都是空,综合合价=0或空,则判断为空行。
+        function filterEmptyNodes(nodes) {
+            return nodes.filter(c => {
+                return c.data.code || c.data.name || c.data.unit || _util.getFee(c.data.fees, 'common.totalFee');
+            });
+        }
+
         /*
         /*
          * 加载其他项目清单,要出现此节点,需要遵循标准条件(至少含有一条相关明细)
          * 加载其他项目清单,要出现此节点,需要遵循标准条件(至少含有一条相关明细)
          * @param {Object}detail
          * @param {Object}detail
@@ -1644,18 +1681,18 @@ const XMLStandard = (function () {
             }
             }
             //添加暂列金额元素
             //添加暂列金额元素
             let provisionalNode = detail.Bills.tree.items.find(node => node.getFlag() === fixedFlag.PROVISIONAL);
             let provisionalNode = detail.Bills.tree.items.find(node => node.getFlag() === fixedFlag.PROVISIONAL);
-            if (provisionalNode && provisionalNode.children.length > 0) {
+            if (provisionalNode && _util.getFee(provisionalNode.data.fees, 'common.totalFee') && filterEmptyNodes(provisionalNode.children).length > 0) {
                 otherEle.children.push(loadProvisional(provisionalNode));
                 otherEle.children.push(loadProvisional(provisionalNode));
             }
             }
             //添加专业工程暂估价元素
             //添加专业工程暂估价元素
             let engEstimateNode = detail.Bills.tree.items.find(node => node.getFlag() === fixedFlag.ENGINEERING_ESITIMATE);
             let engEstimateNode = detail.Bills.tree.items.find(node => node.getFlag() === fixedFlag.ENGINEERING_ESITIMATE);
-            if (engEstimateNode && engEstimateNode.children.length > 0) {
+            if (engEstimateNode && _util.getFee(engEstimateNode.data.fees, 'common.totalFee') && filterEmptyNodes(engEstimateNode.children).length > 0) {
                 otherEle.children.push(loadEngEstimate(engEstimateNode));
                 otherEle.children.push(loadEngEstimate(engEstimateNode));
             }
             }
             //添加计日工元素
             //添加计日工元素
             let dayWorkNode = detail.Bills.tree.items.find(node => node.getFlag() === fixedFlag.DAYWORK);
             let dayWorkNode = detail.Bills.tree.items.find(node => node.getFlag() === fixedFlag.DAYWORK);
             let dayWorkEle = new DayWork({fees: dayWorkNode.data.fees});
             let dayWorkEle = new DayWork({fees: dayWorkNode.data.fees});
-            if (dayWorkNode && dayWorkNode.children.length > 0) {
+            if (dayWorkNode && _util.getFee(dayWorkNode.data.fees, 'common.totalFee') && dayWorkNode.children.length > 0) {
                 //要显示计日工元素,人工、材料、施工机械,最少有一条含有子项(计日工项目)
                 //要显示计日工元素,人工、材料、施工机械,最少有一条含有子项(计日工项目)
                 let filterNodes = dayWorkNode.children.filter(node => [fixedFlag.LABOUR, fixedFlag.MATERIAL, fixedFlag.MACHINE].includes(node.getFlag()));
                 let filterNodes = dayWorkNode.children.filter(node => [fixedFlag.LABOUR, fixedFlag.MATERIAL, fixedFlag.MACHINE].includes(node.getFlag()));
                 for (let fNode of filterNodes) {
                 for (let fNode of filterNodes) {
@@ -1672,12 +1709,13 @@ const XMLStandard = (function () {
                         ele = new Machine();
                         ele = new Machine();
                         constraints = curTenderEle.constraints.machineDayWorkCode;
                         constraints = curTenderEle.constraints.machineDayWorkCode;
                     }
                     }
-                    if (fNode.children.length > 0) {
+                    const fNodeChildren = filterEmptyNodes(fNode.children);
+                    if (_util.getFee(fNode.data.fees, 'common.totalFee') && fNodeChildren.length > 0) {
                         let isValidDepth = _util.validDepth(1, fNode);
                         let isValidDepth = _util.validDepth(1, fNode);
                         if (!isValidDepth) {
                         if (!isValidDepth) {
                             _failList.push(`计日工${ele.name}子项超过一层`);
                             _failList.push(`计日工${ele.name}子项超过一层`);
                         } else {
                         } else {
-                            for (let itemNode of fNode.children) {
+                            for (let itemNode of fNodeChildren) {
                                 ele.children.push(loadDayWorkItem(itemNode, constraints, `${ele.name}计日工项目编号`));
                                 ele.children.push(loadDayWorkItem(itemNode, constraints, `${ele.name}计日工项目编号`));
                             }
                             }
                             dayWorkEle.children.push(ele);
                             dayWorkEle.children.push(ele);
@@ -1691,33 +1729,36 @@ const XMLStandard = (function () {
             }
             }
             //添加总承包服务费元素
             //添加总承包服务费元素
             let tkcNode = detail.Bills.tree.items.find(node => node.getFlag() === fixedFlag.TURN_KEY_CONTRACT);
             let tkcNode = detail.Bills.tree.items.find(node => node.getFlag() === fixedFlag.TURN_KEY_CONTRACT);
-            if (tkcNode && tkcNode.children.length > 0) {  //必须要有子项才显示总承包服务费元素
+            const tkcChildren = filterEmptyNodes(tkcNode.children);
+            if (tkcNode && _util.getFee(tkcNode.data.fees, 'common.totalFee') && tkcChildren.length > 0) {  //必须要有子项才显示总承包服务费元素
                 let isValidDepth = _util.validDepth(2, tkcNode);  //最多2层子项:总承包服务费分类-总承包服务费费用项
                 let isValidDepth = _util.validDepth(2, tkcNode);  //最多2层子项:总承包服务费分类-总承包服务费费用项
                 if (!isValidDepth) {
                 if (!isValidDepth) {
                     _failList.push('总承包服务费子项超过两层');
                     _failList.push('总承包服务费子项超过两层');
                 } else {
                 } else {
                     let tkcEle = new TurnKeyContract({fees: tkcNode.data.fees});
                     let tkcEle = new TurnKeyContract({fees: tkcNode.data.fees});
                     otherEle.children.push(tkcEle);
                     otherEle.children.push(tkcEle);
-                    loadService(tkcEle, tkcNode.children);
+                    loadService(tkcEle, tkcChildren);
                 }
                 }
             }
             }
             //添加索赔计价汇总元素
             //添加索赔计价汇总元素
             let claimNode = detail.Bills.tree.items.find(node => node.getFlag() === fixedFlag.CLAIM);
             let claimNode = detail.Bills.tree.items.find(node => node.getFlag() === fixedFlag.CLAIM);
-            if (claimNode && claimNode.children.length > 0) {   //必须要有子项才能显示索赔计价汇总元素
+            const claimChildren = filterEmptyNodes(claimNode.children);
+            if (claimNode && _util.getFee(claimNode.data.fees, 'common.totalFee') && claimChildren.length > 0) {   //必须要有子项才能显示索赔计价汇总元素
                 let claimEle = new XML_EXPORT_BASE.Element('索赔计价汇总', [
                 let claimEle = new XML_EXPORT_BASE.Element('索赔计价汇总', [
                     {name: '金额', value: _util.getFee(claimNode.data.fees, 'common.totalFee')}]);
                     {name: '金额', value: _util.getFee(claimNode.data.fees, 'common.totalFee')}]);
-                for (let n of claimNode.children) {
+                for (let n of claimChildren) {
                     claimEle.children.push(new ClaimVisaFeeItem(n.data));
                     claimEle.children.push(new ClaimVisaFeeItem(n.data));
                 }
                 }
                 otherEle.children.push(claimEle);
                 otherEle.children.push(claimEle);
             }
             }
             //添加现场签证计价汇总元素
             //添加现场签证计价汇总元素
             let visaNode = detail.Bills.tree.items.find(node => node.getFlag() === fixedFlag.VISA);
             let visaNode = detail.Bills.tree.items.find(node => node.getFlag() === fixedFlag.VISA);
-            if (visaNode && visaNode.children.length > 0) {     //必须要有子项才能显示现场签证计价汇总元素
+            const visaChildren = filterEmptyNodes(visaNode.children);
+            if (visaNode && _util.getFee(visaNode.data.fees, 'common.totalFee') && visaChildren.length > 0) {     //必须要有子项才能显示现场签证计价汇总元素
                 let visaEle = new XML_EXPORT_BASE.Element('现场签证计价汇总', [
                 let visaEle = new XML_EXPORT_BASE.Element('现场签证计价汇总', [
                     {name: '金额', value: _util.getFee(visaNode.data.fees, 'common.totalFee')}
                     {name: '金额', value: _util.getFee(visaNode.data.fees, 'common.totalFee')}
                 ]);
                 ]);
-                for (let n of visaNode.children) {
+                for (let n of visaChildren) {
                     visaEle.children.push(new ClaimVisaFeeItem(n.data));
                     visaEle.children.push(new ClaimVisaFeeItem(n.data));
                 }
                 }
                 otherEle.children.push(visaEle);
                 otherEle.children.push(visaEle);
@@ -1739,7 +1780,8 @@ const XMLStandard = (function () {
                 if (!isValidDepth) {
                 if (!isValidDepth) {
                     _failList.push('暂列金额子项超过一层');
                     _failList.push('暂列金额子项超过一层');
                 } else {    //加载暂列金额明细
                 } else {    //加载暂列金额明细
-                    for (let n of node.children) {
+                    const children = filterEmptyNodes(node.children);
+                    for (let n of children) {
                         let pDetailSource = {
                         let pDetailSource = {
                                 row: detail.mainTree.nodes[detail.mainTree.prefix + n.data.ID].serialNo() + 1,
                                 row: detail.mainTree.nodes[detail.mainTree.prefix + n.data.ID].serialNo() + 1,
                                 code: n.data.code,
                                 code: n.data.code,
@@ -1765,7 +1807,8 @@ const XMLStandard = (function () {
                 if (!isValidDepth) {
                 if (!isValidDepth) {
                     _failList.push('专业工程暂估价子项超过一层');
                     _failList.push('专业工程暂估价子项超过一层');
                 } else {    //加载专业工程暂估明细
                 } else {    //加载专业工程暂估明细
-                    for (let n of node.children) {
+                    const children = filterEmptyNodes(node.children);
+                    for (let n of children) {
                         let eDetailSource = {
                         let eDetailSource = {
                                 row: detail.mainTree.nodes[detail.mainTree.prefix + n.data.ID].serialNo() + 1,
                                 row: detail.mainTree.nodes[detail.mainTree.prefix + n.data.ID].serialNo() + 1,
                                 code: n.data.code,
                                 code: n.data.code,

+ 1 - 1
web/over_write/js/guangdong_2018_export.js

@@ -2804,7 +2804,7 @@ const XMLStandard = (function () {
             // 总承包人价格指数调整法数据
             // 总承包人价格指数调整法数据
             const engineeringCostNode = tenderDetail.Bills.tree.roots.find(node => node.getFlag() === fixedFlag.ENGINEERINGCOST);
             const engineeringCostNode = tenderDetail.Bills.tree.roots.find(node => node.getFlag() === fixedFlag.ENGINEERINGCOST);
             const ecTotalFee = _util.getFee(engineeringCostNode.data.fees, 'common.totalFee');
             const ecTotalFee = _util.getFee(engineeringCostNode.data.fees, 'common.totalFee');
-            const coeDatas = materialAdjustObj.getPriceCoeDatas(gljList, contractorList, ecTotalFee, decimalObj);
+            const coeDatas = materialAdjustObj.getPriceCoeDatas(gljList, contractorList, ecTotalFee, tenderDetail.projectInfo.property);
             return gljList
             return gljList
                 .filter(glj => !!+glj.quantity) // 总消耗量为0不导出
                 .filter(glj => !!+glj.quantity) // 总消耗量为0不导出
                 .map(glj => {
                 .map(glj => {