Explorar el Código

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

TonyKang hace 4 años
padre
commit
1672a6569d
Se han modificado 36 ficheros con 582 adiciones y 99 borrados
  1. 1 0
      config/gulpConfig.js
  2. 2 1
      modules/all_models/projects.js
  3. 18 0
      modules/complementary_ration_lib/models/searchModel.js
  4. 1 0
      modules/main/controllers/block_lib_controller.js
  5. 15 1
      modules/main/controllers/project_controller.js
  6. 14 2
      modules/main/facade/block_lib_facade.js
  7. 0 1
      modules/main/facade/info_price_facade.js
  8. 14 1
      modules/main/facade/project_facade.js
  9. 6 5
      modules/main/facade/ration_facade.js
  10. 1 0
      modules/main/routes/project_route.js
  11. 4 0
      modules/pm/facade/pm_facade.js
  12. 1 1
      modules/ration_glj/controllers/ration_glj_controller.js
  13. 4 1
      modules/users/controllers/cld_controller.js
  14. 47 1
      public/web/common_util.js
  15. 8 0
      public/web/gljUtil.js
  16. 9 4
      public/web/sheet/sheet_common.js
  17. 2 1
      web/building_saas/css/custom.css
  18. 31 3
      web/building_saas/main/html/main.html
  19. 8 7
      web/building_saas/main/js/controllers/project_controller.js
  20. 1 0
      web/building_saas/main/js/main.js
  21. 2 1
      web/building_saas/main/js/models/bills.js
  22. 1 1
      web/building_saas/main/js/models/project.js
  23. 25 2
      web/building_saas/main/js/views/block_lib.js
  24. 2 0
      web/building_saas/main/js/views/calc_base_view.js
  25. 22 7
      web/building_saas/main/js/views/glj_col.js
  26. 13 0
      web/building_saas/main/js/views/index_view.js
  27. 1 0
      web/building_saas/main/js/views/main_tree_col.js
  28. 1 0
      web/building_saas/main/js/views/project_glj_view.js
  29. 123 0
      web/building_saas/main/js/views/project_property_compare.js
  30. 24 14
      web/building_saas/main/js/views/project_view.js
  31. 83 25
      web/building_saas/main/js/views/select_FB_view.js
  32. 28 2
      web/building_saas/main/js/views/std_ration_lib.js
  33. 33 4
      web/building_saas/main/js/views/tender_price_view.js
  34. 1 0
      web/building_saas/pm/js/pm_import.js
  35. 7 0
      web/common/components/share/index.js
  36. 29 14
      web/over_write/js/chongqing_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_indicativeInfo.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.js',
         'web/building_saas/main/js/controllers/project_controller.js',

+ 2 - 1
modules/all_models/projects.js

@@ -41,7 +41,8 @@ const ProjectSchema = new Schema({
     "changeMark":String,// 更新标记  feeRate:费率文件发生了改变,unitFile 单件文件发生了改变
     "remark":String, // 备注
     "fileVer": String,  // 创建时程序版本号
-    "lastFileVer": String  // 最新打开并计算时的程序版本号
+    "lastFileVer": String,  // 最新打开并计算时的程序版本号
+    "compareID":Number
 });
 
 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 stdGljModel = mongoose.model('std_glj_lib_gljList');
 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 stdRationModel = require ('../../ration_repository/models/ration_item').Model;
 let gljUtil = require('../../../public/gljUtil');
@@ -91,6 +92,20 @@ class SearchDao{
         }
         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})
     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));
             comGljIds = Array.from(new Set(comGljIds));

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

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

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

@@ -251,5 +251,19 @@ module.exports = {
         } finally {
             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 blModel = mongoose.model('blockLibsModel');
 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 = {
     getLibNames: getLibNames,
@@ -49,13 +53,21 @@ async function getLibNamesAndFirstLib(data) {
     let libNames = await getLibNames(data);
     let lib = null;
     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});
     }
     else{
         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};
 };
 
 

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

@@ -50,7 +50,6 @@ async function getOptions(data,compilation){//data 是预留对象,暂时不
 }
 
 async function getClassByAreaID(data,compilation){
-  console.log(data);
   //要先知道根据期数和编办查找库ID
   let newList = [];
   let lib = await infoLibModel.findOne({compilationID:compilation._id,period:data.period})

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

@@ -16,7 +16,8 @@ module.exports = {
     loadSEIProjectData:loadSEIProjectData,
     setSEILibData:setSEILibData,
     getIndexReportData:getIndexReportData,
-    setDefaultItemIncrease:setDefaultItemIncrease
+    setDefaultItemIncrease:setDefaultItemIncrease,
+    getCompareProjects:getCompareProjects,
 };
 
 let mongoose = require('mongoose');
@@ -692,4 +693,16 @@ async function calcProjectGLJQuantity(projectID,projectGLJDatas,property){
     let rationGLJDatas = await ration_glj_model.find({'projectID':projectID});
     let rationDatas = await ration_model.model.find({'projectID':projectID});
     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;
 }

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

@@ -78,11 +78,12 @@ async function addNewRation(data,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) {//这里是只有删除的情况,删除定额的同时删除定额下挂的其它子项目

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

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

+ 4 - 0
modules/pm/facade/pm_facade.js

@@ -2172,6 +2172,10 @@ async function importProject(importObj, userID, compilationID, overWriteUrl) {
             });
         }
         data.property.projectFeature = featureLib ? featureLib.feature : [];
+        // 累进数据
+        if (data.property.progressiveLibID) {
+            data.property.progressiveInterval = await getProgressiveInterval(data.property.progressiveLibID);
+        }
         // 指标信息相关设置
         await project_facade.setSEILibData(data.property);
     }

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

@@ -158,7 +158,7 @@ async function getGLJData(req, res) {
             libData = engineerID === COMPILATION 
             ? await ration_glj_facade.getLibOptionsForCompilation(compilationId)
             : 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);
             receiveData.forEach(user => {

+ 4 - 1
modules/users/controllers/cld_controller.js

@@ -263,7 +263,10 @@ class CLDController {
             //设置搜索普通用户:
             condition.user_type = 'normal';
             //设置剔除CLD用户列表不显示
-            condition.is_cld = {$in: [null, 0]};
+            let keyword = request.query.keyword;
+            if(keyword === undefined || keyword === '') {
+                condition.is_cld = {$in: [null, 0]};
+            }
 
             //获取注册时间
             let regtime = request.query.regtime;

+ 47 - 1
public/web/common_util.js

@@ -90,4 +90,50 @@ function deletePropNames(object, namesArr) {
     for (let name of namesArr){
         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)
+      }
+    }
+  }

+ 8 - 0
public/web/gljUtil.js

@@ -570,6 +570,7 @@ let gljUtil = {
                 exportName:m.exportName,
                 quantity:0
             };
+            console.log(m.coe);
             if(billsGroup[m.name]) setQuantities(billsGroup[m.name],tem);
 
             datas.push(tem);
@@ -583,6 +584,13 @@ let gljUtil = {
                 quantity = scMathUtil.roundForObj(quantity +  i.quantity,decimal.process);
             }
             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;

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

@@ -333,7 +333,7 @@ var sheetCommonObj = {
             let options = data[row].options ? data[row].options.split("@") : [];
             this.setComboBox(row,data[row].dateCol,sheet,options);
         }
-
+        this.setRowStyle(row, sheet, data[row].bgColour);
         for (var col = 0; col < setting.header.length; col++) {
             //var cell = sheet.getCell(row, col, GC.Spread.Sheets.SheetArea.viewport);
             var val = _.get(data[row],setting.header[col].dataCode);
@@ -386,8 +386,13 @@ var sheetCommonObj = {
                 val = setting.getText[setting.header[col].getText](data[row],val)
             }
             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.fitRow && setting.fitRow.length > 0){//如果有设置特定的某些列才需要自动行高就按设置的来,没有设置就默认所有列
                 for(let dataCode of setting.fitRow){
@@ -401,7 +406,7 @@ var sheetCommonObj = {
             sheet.autoFitRow(row);
         }
         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) {
@@ -1158,7 +1163,7 @@ var sheetCommonObj = {
         return new TreeNodeCellType()
 
         function getTreeLevel(item,data) {
-            if(item.ParentID && item.ParentID!=-1){
+            if(item && item.ParentID && item.ParentID!=-1){
                 let pitem =  _.find(data,{'ID':item.ParentID});
                 return  getTreeLevel(pitem,data) + 1;
             }else {

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

@@ -527,4 +527,5 @@ margin-right: 100px !important;
 
 .inline-wrapper .inline-tools {
   display: inline-block;
-}
+}
+

+ 31 - 3
web/building_saas/main/html/main.html

@@ -896,7 +896,7 @@
                         <select class="form-control form-control-sm col-6" id="select_block_lib_names">
                           <option>我的模板库</option>
                         </select>
-                        <div class="col-6">
+                        <div class="col-6 pl-1 pr-0">
                           <div class="d-inline">
                             <button type="button" class="btn btn-sm btn-secondary" data-toggle="dropdown"
                               aria-haspopup="true" aria-expanded="false" id="btn_block_newFolder">
@@ -938,6 +938,11 @@
                               </form>
                             </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>
@@ -1001,6 +1006,8 @@
                     role="tab" id="tab_poj-settings-basicInfo">基本信息</a></li>
                 <li class="nav-item ml-3"><a class="nav-link" data-toggle="pill" href="#compilationIllustrationP"
                     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 ml-3"><a class="nav-link" data-toggle="pill" href="#poj-settings-projFeature"
                     id="tab_poj-settings-projFeature" role="tab">工程特征</a></li>
@@ -1037,6 +1044,15 @@
                     <textarea class="form-control" rows="15"></textarea>
                   </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="modal-auto-height" style="overflow: hidden" id="projFeatureSpread">
@@ -2016,8 +2032,18 @@
         </div>
         <div class="modal-footer inline-wrapper">
           <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 class="inline-tools">
             <a href="javascript:void(0);" class="btn btn-primary" id="importConfirm">确定导入</a>
@@ -2706,6 +2732,7 @@
               </button>
           </div>
           <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>
           <div class="modal-footer">
@@ -2840,6 +2867,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_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_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.js"></script>
   <script type="text/javascript" src="/web/building_saas/main/js/controllers/project_controller.js"></script>

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

@@ -216,18 +216,18 @@ ProjectController = {
         if (!project || !sheetController) { return null; }
         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; }
         let selected =node|| project.mainTree.selected;
         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){
-            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 parent = node.parent.parent;
         let newBills = {
@@ -236,6 +236,8 @@ ProjectController = {
             'type':billType.FB,
             'projectID':node.data.projectID
         }
+        if(ext) gljUtil.setProperty(newBills,ext);
+        
         if(node.preSibling){//有前兄弟 在当前分项和前兄弟中间新增一行“分部”空行,空行作为分项的父项,原父项变为空行的前兄弟。
             let changeParent = false;
             newBills.ParentID = node.parent.parent?node.parent.parent.getID():-1;
@@ -268,7 +270,6 @@ ProjectController = {
     addFX:function(project, sheetController) {//添加分项
         if (!project || !sheetController) { return null; }
         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)){//选中的是分部或者是分部分项工程,则插入做为最后一个子项
             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 b_nexID = nextSibling==null?-1:nextSibling.source.getID();//主树和清单树,对应的树节点ID不一样
         let m_nexID = nextSibling==null?-1:nextSibling.getID();
         let b_parent = parent==null?-1:parent.source.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);
         if (newNode) {
             newNode.source = newSource;

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

@@ -31,6 +31,7 @@ $(function () {
     });
 
     $('#tab_report').on('shown.bs.tab', function(e){
+        projectObj.project.calcProgram.doTenderCalc();   // 进入报表前先自动调价计算一遍
         sessionStorage.setItem('mainTab', '#tab_report');
         autoFlashHeight();
     });

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

@@ -157,7 +157,7 @@ var Bills = {
             }
             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 that = this, newData = null;
             insertData.forEach(function (data) {
@@ -167,6 +167,7 @@ var Bills = {
                     }
                     data.data.type = type;
                     newData = data.data;
+                    if(ext) gljUtil.setProperty(newData,ext);
                 }
             });
             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){
-                    temObj = this;
+                    temObj = d.isInfo?this.projectInfo:this;
                 }else if (d.type == ModuleNames.ration_glj && d.action == "add"){
                     this[d.type].datas.push(d.data);
                     if(d.projectGLJ) this.projectGLJ.loadNewProjectGLJToCache(d.projectGLJ);

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

@@ -68,12 +68,13 @@ var blockLibObj = {
         }
     },
     cloneType: null,
+    initialShareTip: '',
 
     buildSheet: async function () {
         $.bootstrapLoading.start();
         let me = this;
         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) {
             let result = '';
             for (let lib of libsArr) {
@@ -83,6 +84,10 @@ var blockLibObj = {
         };
         let html = getLibNamesHtml(namesAndLib.libNames);
         $("#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);
         $.bootstrapLoading.end();
     },
@@ -541,7 +546,7 @@ var blockLibObj = {
                     name: '删除',
                     icon: "delete",
                     disabled: function () {
-
+                        return $("#select_block_lib_names option:selected").prop("index") !== 0;
                     },
                     visible: function(key, opt){
                         return true;
@@ -660,13 +665,31 @@ $(document).ready(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(){
             let libID = $("#select_block_lib_names").val();
             let lib = await ajaxPost('/blockLib/getLib', {libID: libID});
             blockLibObj.loadLib(lib);
+            if (userID === lib.userID) {
+                $('#btn_block_share').attr('data-original-title', blockLibObj.initialShareTip);
+            }
         };
         $.bootstrapLoading.start();
         getLib();
         $.bootstrapLoading.end();
     });
+
+    $('#btn_block_share').click(function () {
+        SHARE_TO.initModal(SHARE_TO.Mode.BLOCK_LIB);
+    })
 });

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

@@ -371,9 +371,11 @@ $(document).ready(function () {
             $('#tabCalcBase').tab('show');
         }
         sheetCommonObj.refreshWorkbookDelDefer(calcBaseView.workBook, 100);
+        sheetCommonObj.refreshWorkbookDelDefer(calcBaseView.workBook, 500);
     });
     $('#tabCalcBase').on('shown.bs.tab', function () {
         sheetCommonObj.refreshWorkbookDelDefer(calcBaseView.workBook, 100);
+        sheetCommonObj.refreshWorkbookDelDefer(calcBaseView.workBook, 500);
     });
 
     /*$('#qd-jsjs').on('hidden.bs.modal', function () {

+ 22 - 7
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: "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: 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: "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',
@@ -71,15 +71,26 @@ let gljCol = {
         view: {
             lockColumns: ["code","name","specs","unit","short_name","tenderPrice","adjustPrice","quantity","tenderQuantity","priceFrom"]
         },
-        autoFit:true,
-        fitRow:['priceFrom'],
+       /*  autoFit:true,
+        fitRow:['priceFrom'], */
         frozenCols:4,
         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:{
@@ -295,6 +306,10 @@ let gljCol = {
             }
         };
 
+        colSettingObj.setVisible('feesIndex.common.tenderUnitFee', showFields);
+        colSettingObj.setVisible('feesIndex.common.tenderTotalFee', showFields);
+        colSettingObj.updateColSetting(true);
+
         if (needRefresh){
             if(projectGljObject.projectGljSpread) {
                 projectGljObject.projectGljSheet = projectGljObject.projectGljSpread .getSheet(0);

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

@@ -634,9 +634,22 @@ let indexObj= {
         }
         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) {
       let header = _.find(setting.header,{dataCode:dataCode});
       let unit = this.getIndexUnit();
+      if(dataCode === 'quantity'){
+        let qunit = this.getQuantityUnit();
+        if(qunit) unit = qunit
+      }
       if(!unit || !header )return;
       header.headerName +=`(${unit})`
     }

+ 1 - 0
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;
         if(isFBNode){
            let CELL =sheetCommonObj.getCusButtonCellType(()=>{
+            $("#selectFBFor").val("replace");   
             $('#selectFBDiv').modal('show');
             })
             cell.cellType(CELL); 

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

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

+ 24 - 14
web/building_saas/main/js/views/project_view.js

@@ -379,8 +379,9 @@ var projectObj = {
                     searchStdBillsAndUpdate(stdMatchCode, value);
                     return;
                 } else {
-                    hintBox.infoBox("系统提示","已存在该编码的清单,是否继续?",2,function () {
-                        searchStdBillsAndUpdate(stdMatchCode, value);
+                    hintBox.infoBox("系统提示","已存在该编码的清单,将自动修改编码后3位,是否继续?",2,function () {
+                        let newFormatCode = project.Bills.newFormatCode(stdMatchCode);
+                        searchStdBillsAndUpdate(stdMatchCode, newFormatCode);
                     },function () {
                         me.mainController.refreshTreeNode([node], false);
                     },['确定','取消']);
@@ -926,10 +927,6 @@ var projectObj = {
                 let quantityTime = +new Date();
                 console.log(`计算quantity时间——${quantityTime - mTime}`);
                 //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')
                     overwriteRationCalcBases(that.project.property.taxType);
                 //that.project.calcProgram.compileAllTemps();
@@ -992,6 +989,9 @@ var projectObj = {
                 that.mainController.bind('refreshBaseActn', that.refreshBaseActn);
                 that.mainController.bind(TREE_SHEET_CONTROLLER.eventName.beforeTreeSelectedChange, that.beforeMainTreeSelectedChange);
                 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);
+                subObj.initSubSpread();//初始化主界面下方的表格
                 if(!projectReadOnly){
                     that.mainSpreadEscKey(that.mainSpread, that.mainSpreadEditStarting, that.mainSpreadEditEnded);
                     sheetCommonObj.bindEnterKey(that.mainSpread, that.mainSpreadEnterKey);
@@ -1341,6 +1341,7 @@ var projectObj = {
                         return true;//除了清单,其它类型都只读
                     },
                     callback: function (key, opt) {
+                        /* 2020-12-28 插入前先弹窗选择 
                         let selected = project.mainTree.selected;
                         if(selected.data.type==billType.FX || selected.data.type==billType.BX){
                              //添加成分项的父亲
@@ -1348,8 +1349,9 @@ var projectObj = {
                         }else{//正常添加分部
                             ProjectController.addFB(project, controller);
                             projectObj.selectColAndFocus(project.mainTree.selected);
-                        }
-                       
+                        } */
+                        $("#selectFBFor").val("add");   
+                        $('#selectFBDiv').modal('show');
                     },
                     visible: function(key, opt){
                         if(project.mainTree.selected){
@@ -2151,11 +2153,11 @@ var projectObj = {
             }
             //分部
             if(node.data.type === billType.FB){
-                styleMap = mapping.FB;
+                styleMap = mapping.FX;
             }
             //分项
             else if(node.data.type === billType.FX){
-                styleMap = mapping.FX;
+                styleMap = mapping.FB;
             }
             //补项
             else if(node.data.type === billType.BX){
@@ -3079,13 +3081,13 @@ const uploadType = {general: 'general', lj: 'lj', gld: 'gld'};
 let fileType = uploadType.lj;
 
 $('#uploadLj').click(function () {
-    $('#uploadExample-general').show();
-    $('#uploadExample').text('下载示例2');
+    $('#example-gld').hide();
+    $('#example-general').show();
     fileType = uploadType.lj;
 });
 $('#uploadGld').click(function () {
-    $('#uploadExample-general').hide();
-    $('#uploadExample').text('下载示例');
+    $('#example-general').hide();
+    $('#example-gld').show();
     fileType = uploadType.gld;
 });
 
@@ -3329,6 +3331,12 @@ $('#uploadExample-general').click(function () {
 $('#uploadExample').click(function () {
     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 () {
     //清空导入清单选择文件
@@ -3583,6 +3591,8 @@ function disableTools(){
     $('#stdBillsTab').addClass('disabled');
     //$('#stdRationTab').addClass('disabled');
     $('#blockLibTab').addClass('disabled');
+    // 组价模板分享
+    $('#btn_block_share').prop('disabled', true);
     //人材机汇总,选择其他、另存使用
     $('a[data-target="#change-unitFile"]').remove();
     $('a[data-target="#unitFile-save-as"]').remove();

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

@@ -15,18 +15,12 @@ let selectFBObject = {
             sheetCommonObj.spreadDefaultStyle(this.spread);
             let sheet = this.spread.getSheet(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){
                 sheetCommonObj.disableSpread(this.spread);
             }
         }else{
-            this.spread.repaint();
+            this.spread.refresh();
         }
         
     },
@@ -40,15 +34,61 @@ let selectFBObject = {
     showData:function(){
         let me = selectFBObject;
         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);
+            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){//过滤叶子节点
             let nodeData = node.data;
             let d = {
@@ -58,9 +98,10 @@ let selectFBObject = {
                 name:nodeData.name,
                 unit:nodeData.unit
             }
+            if(parentIDs.includes(d.ID)) d.collapsed = false
             this.datas.push(d);
             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) {
         selectFBObject.initSpread();
         selectFBObject.showData();
+        sheetCommonObj.refreshWorkbookDelDefer(selectFBObject.spread, 200);
     })
     $("#selectFBConfirm").click(async ()=>{
         let data = selectFBObject.getSelectedData();
         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 = {
     searchLimit: 50,
+    searchMode: 0,
     libType: {complementary: 0, std: 1},
     compleRationLibId: 'compleRationLib',
     doAfterGetRationTree: null, //获取章节树回调
@@ -688,6 +689,7 @@ $('#rationSearchKeyword').keyup(function () {
 
 //变换搜索本定额、全部定额状态
 function switchRationSearchMode(mode) {
+    rationLibObj.searchMode = mode;
     rationLibObj.resultCache = [];
     //搜索本定额
     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) {
         if(!rationLibObj.resultSpread){
             let resultSpread = SheetDataHelper.createNewSpread($('.main-data-side-search')[0]);
             rationLibObj.resultSpread = resultSpread;
             bindContextmenuOpr(resultSpread.getActiveSheet());
-            SheetDataHelper.loadSheetHeader(rationLibObj.sectionRationsSetting, resultSpread.getActiveSheet());
+            //SheetDataHelper.loadSheetHeader(rationLibObj.sectionRationsSetting, resultSpread.getActiveSheet());
             if (!projectReadOnly) {
                 resultSpread.bind(GC.Spread.Sheets.Events.CellDoubleClick, rationLibObj.onRationSpreadCellDoubleClick);
             }
@@ -815,7 +840,8 @@ function seachRation(){
         }else {
             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.resultCache = result;
     };

+ 33 - 4
web/building_saas/main/js/views/tender_price_view.js

@@ -46,7 +46,6 @@ let tender_obj={
         me.tenderTreeSetting = me.createTenderTreeSetting();
         TREE_SHEET_HELPER.initSetting($('#tenderSpread')[0], me.tenderTreeSetting);
         me.tenderTreeSetting.setAutoFitRow = MainTreeCol.getEvent("setAutoFitRow");
-        me.createTreeNodes();
     },
     createTreeNodes() {
         let me = this;
@@ -66,7 +65,7 @@ let tender_obj={
 
                 if (calcTools.isRationCategory(newNode))
                     newNode.visible = false;
-                    
+
                 if (mainNode.children.length > 0) {
                     for (let c of mainNode.children) {
                         createTenderNode(c, newNode, null);
@@ -455,6 +454,7 @@ $(function () {
         $(e.relatedTarget.hash).removeClass('active');
         if(!tender_obj.tenderSpread){
             tender_obj.createTree();
+            tender_obj.createTreeNodes();
             tender_obj.initTenderSpread();
             tender_obj.showTenderData();
             tender_obj.initPageContent();
@@ -508,6 +508,14 @@ $(function () {
                 delete projectObj.project.property.needRestoreGgljPriceTenderCoe;
                 $('#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();
             projectObj.project.projectGLJ.calcQuantity();
             // 刷新造价书界面的相关显示。刷新放在这里是为了切换UI时体验更流畅。
@@ -536,9 +544,30 @@ $(function () {
         // datas.push({type:ModuleNames.project,data:{'ID' : projectObj.project.ID(),'property.hasTender': false}});
         me.updateTenderData(datas,function () {
             // 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 () {

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

@@ -268,6 +268,7 @@ const importView = (() => {
             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 : '', // 主要工料指标
+            progressiveLibID: curEngineering.lib.progressive_lib[0] ? curEngineering.lib.progressive_lib[0].id: '', // 累进库
             calcProgram: { name: taxData.program_lib.name, id: taxData.program_lib.id },  //计算程序
             colLibID: taxData.col_lib.id,   //列设置
             templateLibID: taxData.template_lib.id, //清单模板

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

@@ -14,11 +14,13 @@ const SHARE_TO = (() => {
         PROJECT: 1,
         RATION_LIB: 2,
         GLJ_LIB: 3,
+        BLOCK_LIB: 4,
     };
 
     const ModeToLibType = {
         [Mode.RATION_LIB]: ShareLibType.RATION_LIB,
         [Mode.GLJ_LIB]: ShareLibType.GLJ_LIB,
+        [Mode.BLOCK_LIB]: ShareLibType.BLOCK_LIB,
     };
 
     // 当前模式
@@ -274,6 +276,11 @@ const SHARE_TO = (() => {
                 } else {
                     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)) {
                     initRecentView(rst.recentUsers);
                 }

+ 29 - 14
web/over_write/js/chongqing_2018_export.js

@@ -1174,7 +1174,7 @@ const XMLStandard = (function () {
             tender.children.push(loadCSXM(tenderDetail));
             //其他项目清单
             let other = loadOtherBills(tenderDetail);
-            if (other) {
+            if (other && other.children.length) {
                 tender.children.push(other);
             }
             //规费和税金清单
@@ -1630,6 +1630,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
@@ -1644,18 +1653,18 @@ const XMLStandard = (function () {
             }
             //添加暂列金额元素
             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));
             }
             //添加专业工程暂估价元素
             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));
             }
             //添加计日工元素
             let dayWorkNode = detail.Bills.tree.items.find(node => node.getFlag() === fixedFlag.DAYWORK);
             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()));
                 for (let fNode of filterNodes) {
@@ -1672,12 +1681,13 @@ const XMLStandard = (function () {
                         ele = new Machine();
                         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);
                         if (!isValidDepth) {
                             _failList.push(`计日工${ele.name}子项超过一层`);
                         } else {
-                            for (let itemNode of fNode.children) {
+                            for (let itemNode of fNodeChildren) {
                                 ele.children.push(loadDayWorkItem(itemNode, constraints, `${ele.name}计日工项目编号`));
                             }
                             dayWorkEle.children.push(ele);
@@ -1691,33 +1701,36 @@ const XMLStandard = (function () {
             }
             //添加总承包服务费元素
             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层子项:总承包服务费分类-总承包服务费费用项
                 if (!isValidDepth) {
                     _failList.push('总承包服务费子项超过两层');
                 } else {
                     let tkcEle = new TurnKeyContract({fees: tkcNode.data.fees});
                     otherEle.children.push(tkcEle);
-                    loadService(tkcEle, tkcNode.children);
+                    loadService(tkcEle, tkcChildren);
                 }
             }
             //添加索赔计价汇总元素
             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('索赔计价汇总', [
                     {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));
                 }
                 otherEle.children.push(claimEle);
             }
             //添加现场签证计价汇总元素
             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('现场签证计价汇总', [
                     {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));
                 }
                 otherEle.children.push(visaEle);
@@ -1739,7 +1752,8 @@ const XMLStandard = (function () {
                 if (!isValidDepth) {
                     _failList.push('暂列金额子项超过一层');
                 } else {    //加载暂列金额明细
-                    for (let n of node.children) {
+                    const children = filterEmptyNodes(node.children);
+                    for (let n of children) {
                         let pDetailSource = {
                                 row: detail.mainTree.nodes[detail.mainTree.prefix + n.data.ID].serialNo() + 1,
                                 code: n.data.code,
@@ -1765,7 +1779,8 @@ const XMLStandard = (function () {
                 if (!isValidDepth) {
                     _failList.push('专业工程暂估价子项超过一层');
                 } else {    //加载专业工程暂估明细
-                    for (let n of node.children) {
+                    const children = filterEmptyNodes(node.children);
+                    for (let n of children) {
                         let eDetailSource = {
                                 row: detail.mainTree.nodes[detail.mainTree.prefix + n.data.ID].serialNo() + 1,
                                 code: n.data.code,