Преглед на файлове

Merge branch '1.0.0_online' of http://smartcost.f3322.net:3000/SmartCost/ConstructionCost into 1.0.0_online

zhongzewei преди 6 години
родител
ревизия
78cdb28370
променени са 31 файла, в които са добавени 299 реда и са изтрити 105 реда
  1. 2 0
      config/gulpConfig.js
  2. 1 1
      modules/all_models/stdBills_bills.js
  3. 2 1
      modules/main/facade/ration_facade.js
  4. 1 2
      modules/main/models/project.js
  5. 1 1
      modules/pm/facade/pm_facade.js
  6. 29 8
      modules/reports/rpt_component/jpc_flow_tab.js
  7. 3 2
      public/web/sheet/sheet_common.js
  8. 30 5
      public/web/socket/connection.js
  9. 10 1
      socket.js
  10. 0 11
      socketdocker/socketdockerfile
  11. 3 3
      test/unit/reports/test_rpt_test_template.js
  12. 2 1
      web/building_saas/css/custom.css
  13. 4 2
      web/building_saas/main/html/main.html
  14. 34 2
      web/building_saas/main/js/controllers/material_controller.js
  15. 2 2
      web/building_saas/main/js/main.js
  16. 25 18
      web/building_saas/main/js/models/fee_rate.js
  17. 3 0
      web/building_saas/main/js/models/installation_fee.js
  18. 9 3
      web/building_saas/main/js/models/project.js
  19. 12 2
      web/building_saas/main/js/models/quantity_detail.js
  20. 1 0
      web/building_saas/main/js/views/fee_rate_view.js
  21. 2 2
      web/building_saas/main/js/views/glj_col.js
  22. 13 9
      web/building_saas/main/js/views/glj_view.js
  23. 23 2
      web/building_saas/main/js/views/main_tree_col.js
  24. 20 15
      web/building_saas/main/js/views/project_glj_view.js
  25. 8 2
      web/building_saas/main/js/views/project_view.js
  26. 2 2
      web/building_saas/main/js/views/quantity_edit_view.js
  27. 2 2
      web/building_saas/main/js/views/sub_view.js
  28. 14 0
      web/building_saas/main/js/views/zmhs_view.js
  29. 4 0
      web/building_saas/pm/html/project-management.html
  30. 34 3
      web/building_saas/pm/js/pm_newMain.js
  31. 3 3
      web/building_saas/report/html/rpt_main.html

+ 2 - 0
config/gulpConfig.js

@@ -42,6 +42,8 @@ module.exports = {
         'public/web/sheet/sheet_common.js',
         'public/web/common_ajax.js',
         'lib/JSExpressionEval_src/Date.js',
+        'web/building_saas/glj/js/socket.io.slim.js',
+        'public/web/socket/connection.js',
         'web/building_saas/pm/js/**/*.js',
         'lib/ztree/*.js',
         'lib/jquery-contextmenu/jquery.contextMenu.min.js'

+ 1 - 1
modules/all_models/stdBills_bills.js

@@ -18,7 +18,7 @@ const stdBills_bills = new Schema({
             jobs: [],
             items: [],
             recharge:String,
-            billsLibId: Number,
+            billsLibId: {type:Number, index: true},
             deleted: Boolean
     },
     {versionKey: false}

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

@@ -188,7 +188,7 @@ async function addRationSubList(stdRation,newRation,needInstall,compilation) {
     let addRationCoeTime = +new Date();
     console.log("添加定额coe时间-----"+(addRationCoeTime - addRationGLJTime));
     let ration_installs = [];
-    if(needInstall){
+    if(needInstall && stdRation.type == 'std'){//只有标准的定额才有安装增加费,补充的定额没有安装增加费
         ration_installs =  await addRationInstallFee(stdRation,newRation);
     }
     let addRationInstallFeeTime = +new Date();
@@ -200,6 +200,7 @@ async function addRationInstallFee(std,newRation) {
     let install_fee_list = [];
     if(std.hasOwnProperty('rationInstList') && std.rationInstList.length > 0){
         let installFee = await installationFeeModel.findOne({'projectID': newRation.projectID});
+        if(!installFee) return;//如果没有找到项目对应的安装增加费,则不添加
         for(let ri of std.rationInstList){
             let feeItem = _.find(installFee.installFeeItem,{'ID':ri.feeItemId});
             let section = _.find(installFee.installSection,{'ID':ri.sectionId});

+ 1 - 2
modules/main/models/project.js

@@ -29,7 +29,6 @@ var moduleMap = {};
 
 moduleMap[projectConsts.BILLS] = billsData;
 moduleMap[projectConsts.RATION] = rationData;
-//moduleMap[projectConsts.GLJ] = GLJData;
 moduleMap[projectConsts.RATION_GLJ] = ration_glj_data;
 moduleMap[projectConsts.RATION_COE] = ration_coe_data;
 moduleMap[projectConsts.RATION_ASS] = ration_ass_data;
@@ -37,13 +36,13 @@ moduleMap[projectConsts.RATION_INSTALLATION] = ration_installation;
 moduleMap[projectConsts.QUANTITY_DETAIL] = quantity_detail_data;
 moduleMap[projCounter.collectionName] = projCounter;
 moduleMap[projSetting.collectionName] = projSetting;
-// moduleMap[volumePriceData.collectionName] = volumePriceData;
 moduleMap[projectConsts.FEERATE] = fee_rate_data;
 moduleMap[projectConsts.LABOUR_COE] = labour_coe_facade;
 moduleMap[projectConsts.CALC_PROGRAM] = calc_program_facade;
 moduleMap[projectConsts.PROJECTGLJ] = new GLJController();
 moduleMap[projectConsts.INSTALLATION_FEE] = installation_facade;
 
+
 var Project = function (){};
 
 Project.prototype.datas = [];

+ 1 - 1
modules/pm/facade/pm_facade.js

@@ -613,7 +613,7 @@ async function getSummaryInfo(projectIDs){
     if(tenders.length > 0){
         for(let tender of tenders){
             tenderIDs.push(tender.ID);
-            IDMapping[tender.ID] = {engineeringCost: 0, subEngineering: 0, measure: 0, safetyConstruction: 0, other: 0, charge: 0, tax: 0, rate: 0, buildingArea: '', perCost: ''};
+            IDMapping[tender.ID] = {engineeringCost: 0, subEngineering: 0, measure: 0, safetyConstruction: 0, other: 0, charge: 0, tax: 0, rate: 0, buildingArea: '', perCost: '',changeMark:tender.changeMark,property:tender.property};
             let buildingArea = getBuildingArea(tender.property.projectFeature);
             if(buildingArea){
                 IDMapping[tender.ID]['buildingArea'] = buildingArea;

+ 29 - 8
modules/reports/rpt_component/jpc_flow_tab.js

@@ -20,11 +20,12 @@ JpcFlowTabSrv.prototype.createNew = function(){
     //grpPageInfo :{"segGrpRecStartIdx": 0, "insertedGrpRecAmt": 0, "preAddPageGrpInfo": null}; //纯属解释参数grpPageInfo结构
     //valueIdx: [isFollowMode, type(normal, auto-height, group), valueIndex, sub-value-index(自动行高特有), total-value-amount(自动行高特有)] //解释 dispValueIdxLst 数据构造
     function private_addPageValue(ValuedIdxLst, sortedSequence, grpSequenceInfo, startRecIdx, maxRecPerPage,page_seg_map, segIdx, pageIdx, grpPageInfo, isFollow, segAutoHeightInfo, prePageLeftAutoHeightRecAmt) {
-        let vIdx = [], preAmt = 0, insertedGrpAmt = 0, grp_lines = 0, followMode = (isFollow)?JV.TYPE_FOLLOW_MODE:-1, nextPageAutoHeightRecAmt = 0;
+        let vIdx = [], vFirstIdx = [], preAmt = 0, insertedGrpAmt = 0, grp_lines = 0, followMode = (isFollow)?JV.TYPE_FOLLOW_MODE:-1, nextPageAutoHeightRecAmt = 0;
         if (grpSequenceInfo && grpPageInfo) {
             if (grpPageInfo[JV.PROP_PRE_ADD_GRP_REC_INFO].length > 0) {
                 for (let grpLineIdx of grpPageInfo[JV.PROP_PRE_ADD_GRP_REC_INFO]) {
-                    vIdx.push([followMode, JV.DISPLAY_VAL_TYPE_GROUP, grpPageInfo[JV.PROP_SEG_GRP_IDX], grpLineIdx]);
+                    //vIdx.push([followMode, JV.DISPLAY_VAL_TYPE_GROUP, grpPageInfo[JV.PROP_SEG_GRP_IDX], grpLineIdx]);
+                    vFirstIdx.push([followMode, JV.DISPLAY_VAL_TYPE_GROUP, grpPageInfo[JV.PROP_SEG_GRP_IDX], grpLineIdx]);
                 }
                 grpPageInfo[JV.PROP_SEG_GRP_IDX]++;
             }
@@ -127,6 +128,10 @@ JpcFlowTabSrv.prototype.createNew = function(){
                 if (private_normal_add_rec(vi)) break;
             }
         }
+        if (vFirstIdx.length > 0) {
+            vIdx = vIdx.concat(vFirstIdx);
+            //备注: 在一开始就加grp的情况下,这些数据应该放在后面才对
+        }
         page_seg_map.push([pageIdx, segIdx]);
         ValuedIdxLst.push(vIdx);
         return nextPageAutoHeightRecAmt;
@@ -502,6 +507,7 @@ JpcFlowTabSrv.prototype.createNew = function(){
                 maxRowRec = JpcFlowTabHelper.getMaxRowsPerPage(bands, rptTpl, me.isEx);
             }
             let handledRowAmt = 0; //handledRowAmt纪录的是真正处理过的显示行数,包含了空白行,主要是为分页用(自动行高)
+            let segRestRecAmt = 0; //一般情况下为0,只有在特殊情况下才需要,如09-x表中,正常流水一页显示不了的时候,就有大问题了
             function private_addPage(segIdx, grpSeqInfo, isFollow, isMix, mixSplitPoint) {
                 private_resetBandArea();
                 me.pageStatusLst.push(pageStatus.slice(0));
@@ -516,6 +522,7 @@ JpcFlowTabSrv.prototype.createNew = function(){
                         redundantRecAmt++;
                     }
                 }
+                let restRecAmt = 0;
                 if (isMix) {
                     //先处理上半部分
                     prePageLeftAutoHeightRecAmt = private_addPageValue(me.dispValueIdxLst, me.segments[segIdx], grpSeqInfo, counterRowRec, mixSplitPoint,me.page_seg_map, segIdx, pageIdx, grpPageInfo, false, me.auto_height_info, prePageLeftAutoHeightRecAmt);
@@ -523,7 +530,7 @@ JpcFlowTabSrv.prototype.createNew = function(){
                         private_chk_handle_rec_amt(dv, false);
                     }
                     //再处理下半部分
-                    let restRecAmt = maxRowRec - me.dispValueIdxLst[me.dispValueIdxLst.length - 1].length; //备注:在一些极端条件下,mixSplitPoint这个分割点不合适处理下半部分数据,以实际生成的value-index数量为准
+                    restRecAmt = maxRowRec - me.dispValueIdxLst[me.dispValueIdxLst.length - 1].length; //备注:在一些极端条件下,mixSplitPoint这个分割点不合适处理下半部分数据,以实际生成的value-index数量为准
                     // private_addPageValue(me.dispValueIdxLst, followTabEx.segments[segIdx], null, counterRowRecEx, maxRowRec - mixSplitPoint, me.page_seg_map, segIdx, pageIdx, null, true, null, 0);
                     private_addPageValue(me.dispValueIdxLst, followTabEx.segments[segIdx], null, counterRowRecEx, restRecAmt, me.page_seg_map, segIdx, pageIdx, null, true, null, 0);
                     for (let dv of me.dispValueIdxLst[me.dispValueIdxLst.length - 1]) {
@@ -548,6 +555,10 @@ JpcFlowTabSrv.prototype.createNew = function(){
                     }
                 }
                 currentRecAmt -= redundantRecAmt; //在自动行高调整场景下,需要减去冗余的数量
+                if (restRecAmt < 0) {
+                    currentRecAmt -= restRecAmt;
+                    segRestRecAmt = restRecAmt;
+                }
             }
             for (let segIdx = 0; segIdx < me.segments.length; segIdx++) {
                 let grpSeqInfo = (me.group_node_info)?me.group_node_info[segIdx]:null;
@@ -555,6 +566,7 @@ JpcFlowTabSrv.prototype.createNew = function(){
                 let grpRecAmtEx = 0;
                 let accAutoHeightAmt = 0; //累计的自动行高数量
                 handledRowAmt = 0; //初始化每一段的已处理纪录行数
+                segRestRecAmt = 0;
                 if (followTabEx && followTabEx.group_node_info) {
                     grpRecAmtEx = followTabEx.group_node_info.length * followTabEx.group_lines_amt;
                 }
@@ -572,10 +584,13 @@ JpcFlowTabSrv.prototype.createNew = function(){
                 let ttlSegRecAmtNormal = me.segments[segIdx].length + grpRecAmt; //正常的segment下的数据长度累计(含grouping data)
                 let ttlSegRecAmt = (followTabEx)?(me.segments[segIdx].length + grpRecAmt + followTabEx.segments[segIdx].length + grpRecAmtEx):(me.segments[segIdx].length + grpRecAmt); //所有的segment下的数据长度累计(包括ex部分)
                 let adHocAutoHeightAmt = 0;
+                let normalContentAmt = 0;
+                let exBuffer = 0;
                 let adHocAutoHeightGrpStartIdx = 0;
                 if (me.auto_height_fields_idx.length > 0) {
                     for (let loop = 0; loop < me.auto_height_info[segIdx].length; loop++) {
                         adHocAutoHeightAmt += (me.auto_height_info[segIdx][loop] - 1);
+                        normalContentAmt++;
                         if (me.group_node_info && me.group_node_info[segIdx]) {
                             if (me.group_node_info[segIdx][adHocAutoHeightGrpStartIdx] === loop) {
                                 adHocAutoHeightGrpStartIdx++;
@@ -584,6 +599,7 @@ JpcFlowTabSrv.prototype.createNew = function(){
                     }
                     ttlSegRecAmtNormal += adHocAutoHeightAmt;
                     ttlSegRecAmt += adHocAutoHeightAmt;
+                    if (adHocAutoHeightAmt > 0) exBuffer = grpRecAmt;
                 }
                 //自动行高调整在多流水合并方式时,只支持前部分(后期需要再加)
                 while (true) {
@@ -604,8 +620,8 @@ JpcFlowTabSrv.prototype.createNew = function(){
                     }
                     if ((ttlSegRecAmtNormal < ttlSegRecAmt) || (followTabEx !== null)) {
                         //有流水拓展,并且是follow mode
-                        // if (currentRecAmt + adHocAutoHeightAmt + maxRowRec > ttlSegRecAmtNormal) {
-                        if (currentRecAmt + accAutoHeightAmt + adHocAutoHeightAmt + maxRowRec > ttlSegRecAmtNormal) {
+                        if (currentRecAmt + accAutoHeightAmt + exBuffer + maxRowRec > ttlSegRecAmtNormal) {
+                        // if (currentRecAmt + accAutoHeightAmt + adHocAutoHeightAmt + maxRowRec > ttlSegRecAmtNormal) {
                             // if (currentRecAmt + adHocAutoHeightAmt >= ttlSegRecAmtNormal) {
                             if (currentRecAmt + accAutoHeightAmt + adHocAutoHeightAmt >= ttlSegRecAmtNormal) {
                                 //纯 followTabEx 数据
@@ -647,7 +663,12 @@ JpcFlowTabSrv.prototype.createNew = function(){
                                         private_addPage(segIdx, grpSeqInfo, false, true, ttlSegRecAmtNormal);
                                     }
                                 } else {
-                                    private_addPage(segIdx, grpSeqInfo, false, true, ttlSegRecAmtNormal);
+                                    //在这里要考虑如果有多页正常的流水数据情况,那么就得考虑这页有多少条普通流水记录,不应该一刀切地用ttlSegRecAmtNormal
+                                    let splitPoint = ttlSegRecAmtNormal - handledRowAmt ;
+                                    // if (splitPoint > (exBuffer + maxRowRec)) {
+                                    //     splitPoint = splitPoint % (exBuffer + maxRowRec);
+                                    // }
+                                    private_addPage(segIdx, grpSeqInfo, false, true, splitPoint);
                                 }
                             }
                         } else {
@@ -684,7 +705,7 @@ JpcFlowTabSrv.prototype.createNew = function(){
                     }
                     //检测是否可退出
                     // if ((currentRecAmt + accAutoHeightAmt + adHocAutoHeightAmt >= ttlSegRecAmt) && (pageIdx % me.multiCols === 0)) {
-                    if (handledRowAmt >= ttlSegRecAmt && (pageIdx % me.multiCols === 0)) {
+                    if (handledRowAmt >= (ttlSegRecAmt + segRestRecAmt) && (pageIdx % me.multiCols === 0)) {
                         //备注:这里必须得考虑多栏的情况,否则会造成pageStatus出界的问题
                         break;
                     }
@@ -904,7 +925,7 @@ JpcFlowTabSrv.prototype.createNew = function(){
                         for (let idx_ex = 0; idx_ex < tab_fields_ex.length; idx_ex++) {
                             let tab_fieldex = tab_fields_ex[idx_ex];
                             let data_fieldex = null, map_data_fieldex = JE.F(tab_fieldex[JV.PROP_FIELD_ID], $CURRENT_RPT);
-                            if (me.disp_fields_ex_idx[idx_ex] !== JV.BLANK_FIELD_INDEX && (typeof me.disp_fields_idx[idx_ex] !== 'object')) {
+                            if (me.disp_fields_ex_idx[idx_ex] !== JV.BLANK_FIELD_INDEX && (typeof me.disp_fields_ex_idx[idx_ex] !== 'object')) {
                                 data_fieldex = data_details_ex[me.disp_fields_ex_idx[idx_ex]];
                             } else {
                                 if (map_data_fieldex) {

+ 3 - 2
public/web/sheet/sheet_common.js

@@ -539,7 +539,7 @@ var sheetCommonObj = {
         };
         return new ComboCellForActiveCell();
     },
-    getTipsCombo:function (forLocked,tips,setting) {
+    getTipsCombo:function (forLocked,tips,setting,node) {
         let getTipsCombo = function () {
             this.clickCom=false;
         };
@@ -550,7 +550,8 @@ var sheetCommonObj = {
                     this.clickCom = false;
                     return;
                 }
-                TREE_SHEET_HELPER.delayShowTips(hitinfo,setting,tips);
+                let text =  typeof tips == 'function'?tips(node):tips;
+                TREE_SHEET_HELPER.delayShowTips(hitinfo,setting,text);
             };
             getTipsCombo.prototype.processMouseLeave = function (hitinfo) {
                 TREE_SHEET_HELPER.hideTipsDiv();

+ 30 - 5
public/web/socket/connection.js

@@ -3,21 +3,35 @@
  */
 socketObject={
   roomInfo : null,
-  connect:function () {
+  messages:[],
+  connect:function (from) {
       // 连接socket服务器
       var hostName = window.location.hostname;
       let me = this;
       let port = window.location.protocol ==='http:'?3300:3301;
       socket = io(window.location.protocol+'//'+hostName+':'+port);
       socket.on('connect', function () {
-          me.roomInfo={
-              feeRate:me.getFeeRateRoomID(),
-              unitFile:me.getUnitFileRoomID()
-          };
+          if(from == 'pm'){
+              me.roomInfo={
+                  userID:userID
+              };
+          }else {
+              me.roomInfo={
+                  feeRate:me.getFeeRateRoomID(),
+                  unitFile:me.getUnitFileRoomID()
+              };
+          }
           socket.emit('join', me.roomInfo);
+          if(me.messages.length > 0){//发送缓存消息;
+              for(let m of me.messages){
+                  socket.emit(m.message, m.data);
+              }
+          }
           console.log('连接成功');
       });
 
+      //=========================================================
+      //造价书页面接收消息部分
       socket.on('feeRateChange', function(data) {
           //data = JSON.parse(data);
 
@@ -48,6 +62,17 @@ socketObject={
               $("#notify").show();
           }
       });
+
+
+      //=============================================================================================
+      //项目管理页面接收消息部分
+
+      socket.on('refreshProjectIcon', function (data) {//收到刷新图标消息
+           if(data.projectID && typeof projTreeObj !== 'undefined') projTreeObj.refreshProjectIcon(data.projectID);
+      });
+      socket.on('fileDataChange', function (data) {//收到单价文件、费率文件内容修改、文件切换、另存(暂时能共用,以后有需要可分离)推送消息
+          if(data.projectID && typeof projTreeObj !== 'undefined') projTreeObj.refreshWhenFileDateChange(data.projectID);
+      });
   },
   getFeeRateRoomID:function (){
       return  projectObj.project.FeeRate.getActivateFeeRateFileID();

+ 10 - 1
socket.js

@@ -22,20 +22,29 @@ socketIO.on('connection', function(socket) {
     });
     // 数据更改通知
     socket.on('unitFileChangeNotify', function(data) {
-        console.log(roomInfo);
         socket.broadcast.to(roomInfo['unitFile']).emit('unitFileChange', data);
+        if(data.userID) socket.broadcast.to(data.userID).emit('fileDataChange', data);
     });
     socket.on('feeRateChangeNotify', function(data) {
         socket.broadcast.to(roomInfo['feeRate']).emit('feeRateChange', data);
+        if(data.userID) socket.broadcast.to(data.userID).emit('fileDataChange', data);
     });
     socket.on('changeNewRoom', function(data) {
         if(data.projectID){//如果有项目ID,则通知同一个项目在其它地方被打开的页面
             socket.broadcast.to(data.oldRoom).emit('changeFileNotify', data);
+            if(data.userID) socket.broadcast.to(data.userID).emit('fileDataChange', data);
+
         }
         socket.leave(data.oldRoom);
         socket.join(data.newRoom);
         roomInfo[data.name]=data.newRoom;
     });
+    socket.on('removeProjectMark', function(data) {
+        if(data.projectID && data.userID){
+            socket.broadcast.to(data.userID).emit('refreshProjectIcon', data);
+        }
+    });
+
     socket.on('disconnect', function () {
         console.log("client disconnect =========="+JSON.stringify(roomInfo));
     });

+ 0 - 11
socketdocker/socketdockerfile

@@ -1,11 +0,0 @@
-FROM server:2.0
-
-COPY . ConstructionCost
-
-WORKDIR ConstructionCost
-
-RUN cnpm install 
-
-EXPOSE 3300
-
-ENTRYPOINT babel-node socket.js

+ 3 - 3
test/unit/reports/test_rpt_test_template.js

@@ -41,7 +41,7 @@ let demoPrjId = - 1;
 // let demoRptId = 389; //10
 // let demoRptId = 280; //11-1 暂列金
 // let demoRptId = 2260; //测试基本信息
-let demoRptId = 479; //12
+let demoRptId = 613; //09-4 2018
 let pagesize = "A4";
 //288: 11-2表(新)
 //279: 04
@@ -52,7 +52,7 @@ let userId_HaiZhu = "5b5a66c4a3c23e000dccdd77"; //海珠user id
 // demoPrjId = 720; //QA: DW3
 //demoPrjId = 1626; //QA:
 // demoPrjId = 2260; //QA:
-demoPrjId = 4568; //QA:
+demoPrjId = 4529; //QA:
 //*/
 let userId_Dft = userId_HaiZhu;
 // let userId_Dft = "5a025c4c15074d134c2b9689";
@@ -98,7 +98,7 @@ test('测试 - 测试模板啦: ', function (t) {
                     let customizeCfg = {"fillZero": true};
                     let pageRst = printCom.outputAsSimpleJSONPageArray(rptTpl, tplData, 1, maxPages, defProperties, customizeCfg);
                     if (pageRst) {
-                        fsUtil.writeObjToFile(pageRst, "D:/GitHome/ConstructionCost/tmp/testBuiltPageResult_测试模板.jsp");
+                        // fsUtil.writeObjToFile(pageRst, "D:/GitHome/ConstructionCost/tmp/testBuiltPageResult_测试模板.jsp");
                         // rpt_xl_util.exportExcel(pageRst, pagesize, "local_test_rpt_excel", true, null, null, function(uuidName){
                         //     console.log("excel uuid: " + uuidName);
                         // });

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

@@ -259,6 +259,7 @@ legend.legend{
 }
 
 .item_spread{
-    width: 30%;
+    width: 29.8%;
     float: left;
+    background: #F1F1F1
 }

+ 4 - 2
web/building_saas/main/html/main.html

@@ -174,10 +174,12 @@
                               <div class="tab-content" id="tabCon">
                                   <div class="tab-pane active" id="subItems" role="tabpanel">
                                       <div class="main-data-bottom ovf-hidden" id="subSpread" style="display: none" tabindex="0"></div>
+                                      <div class="main-data-bottom ovf-hidden" id="rgResize" style="width: 0.2%; height: 100%; resize:horizontal; cursor: w-resize; float: left; background: #F1F1F1"></div>
                                       <div class="main-data-bottom ovf-hidden item_spread" id="replaceM" style="display: none" ></div>
                                       <div class="main-data-bottom ovf-hidden" id="tabZMHS" style="display: none">
-                                          <div class=" main-data-bottom ovf-hidden" style="width: 50%; float: left; margin: 0; padding:0;" id="coeSpread"></div>
-                                          <div class=" main-data-bottom ovf-hidden" style="width: 50%; float: left; margin: 0; padding:0;" id="assSpread"></div>
+                                          <div class=" main-data-bottom ovf-hidden" style="width: 60%; float: left; margin: 0; padding:0;" id="coeSpread"></div>
+                                          <div  id="zmhsResize" style="width: 0.2%; height: 100%; resize:horizontal; cursor: w-resize; float: left; background: #F1F1F1"></div>
+                                          <div class=" main-data-bottom ovf-hidden" style="width: 39.8%; float: left; margin: 0; padding:0;" id="assSpread"></div>
                                       </div>
                                       <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>

+ 34 - 2
web/building_saas/main/js/controllers/material_controller.js

@@ -2,6 +2,7 @@
  * Created by zhang on 2018/9/12.
  */
 let MaterialController = {
+    subSpreadDivWidth:"",
     //规则相关映射
     rule1: function (node) {
         let itemText = node.data.itemCharacterText;
@@ -164,11 +165,15 @@ let MaterialController = {
     showReplaceDiv:function (node) {
         $("#subSpread").addClass("ration_glj_spread");
         $("#replaceM").show();
-        if(node) this.showReplaceSpread(node);//如果不是只刷新页面
+        $("#rgResize").show();// 拖动调整大小功能添加
+        // 2018-11-07 需求变更,这个项目特征替换表格暂时隐藏不删除,以后可能还要用,先把项目初始化这句注释掉
+       // if(node) this.showReplaceSpread(node);//如果不是只刷新页面
+        this.showItemCharacterText(node);//只显示文本
         refreshSubSpread();
     },
     hideReplaceDiv:function(){
         $("#subSpread").removeClass("ration_glj_spread");
+        $("#subSpread").css("width",""); //左右拖动调整表格大小的时候会设置css属性,所以隐藏这个div的时候也要把这个属性给去掉
         $("#replaceM").hide();
         refreshSubSpread();
     },
@@ -201,6 +206,22 @@ let MaterialController = {
         sheetCommonObj.showData(this.sheet, this.setting,this.datas);
         this.sheet.setRowCount(this.datas.length);
     },
+    showItemCharacterText:function (node) {
+        let text="";
+        let selected = node?node:projectObj.project.mainTree.selected;
+        let parent = selected.parent;
+        if(selected&&parent){
+            text = parent.data.itemCharacterText?parent.data.itemCharacterText.replace(/\n/g,"<br>"):"";
+        }
+        if(text == "") {//为空的时候不显示
+            $("#replaceM").hide();
+            $("#subSpread").removeClass("ration_glj_spread");
+            $('#subSpread').css('width','');
+            return;
+        }
+        $('#subSpread').css('width',MaterialController.subSpreadDivWidth);
+        $("#replaceM").html(text);
+    },
     getItems:function(characterText){
         if(!characterText) return;
         let strArray =  characterText.split(/\n/);
@@ -238,4 +259,15 @@ let MaterialController = {
             if(!_.isEmpty(doc)) this.postReplace([{glj:ration_glj,doc:doc}]);
         }
     }
-};
+};
+
+let rg_sideResizeEles = {};
+rg_sideResizeEles.id = 'tabRG';
+rg_sideResizeEles.resize = $('#rgResize');
+rg_sideResizeEles.nearElement = $('#subSpread');
+rg_sideResizeEles.farElement = $('#replaceM');
+rg_sideResizeEles.nav = null;
+slideResize(rg_sideResizeEles, {min: 100, max: $('#tabCon').width()-100}, 'width', function(){
+    MaterialController.subSpreadDivWidth = $('#subSpread').css('width');
+    refreshSubSpread();
+});

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

@@ -32,7 +32,7 @@ $(function () {
     slideResize(getMainResizeEles(), {min: 170, max: 700}, 'height', function() {
         projectObj.mainSpread.refresh();
         refreshSubSpread();
-        zmhs_obj.refresh();
+        //zmhs_obj.refresh();
         $('#comments').find('textarea').height($('#comments').height() - 25);
     });
 
@@ -123,13 +123,13 @@ function slideResize(eles, limit, type, callback) {
             nEleChangeSize = nEleSize + moveSize;
             nEleChangeSize = nEleChangeSize < limit.min ? limit.min : nEleChangeSize;
             nEleChangeSize = nEleChangeSize > limit.max ? limit.max + 9 : nEleChangeSize;
-
             fEleChangeSize = fEleSize - moveSize;
             fEleChangeSize = fEleChangeSize < limit.min ? limit.min : fEleChangeSize;
             fEleChangeSize = fEleChangeSize > limit.max ? limit.max + 9 : fEleChangeSize;
 
             if(type === 'width'){
                 let rePercent = getResizeWidthPercent(nEleChangeSize, fEleChangeSize);
+                console.log(rePercent);
                 eles.nearElement.css(type, rePercent.nearPercent);
                 eles.farElement.css(type, rePercent.farPercent);
             }

+ 25 - 18
web/building_saas/main/js/models/fee_rate.js

@@ -189,6 +189,7 @@ var FeeRate = {
 
         FeeRate.prototype.onFeeRatesChange = function (infos) {//{rateID:'AAAA',value:23}
             let node = project.mainTree.selected;
+            let me = this;
             for(let i of infos){
                 this.refreshCalProgramByRateID(i.rateID,i.value);
                 this.refreshBillsByRateID(i.rateID,i.value);
@@ -199,37 +200,43 @@ var FeeRate = {
                 }
             }
             project.calcProgram.calcAllNodesAndSave(calcAllType.catAll);
-            project.markUpdateProject({projectID:project.ID(),feeRateID:this.getActivateFeeRateFileID()},"feeRate");
-            socket.emit('feeRateChangeNotify', this.getActivateFeeRateFileID());
+            project.markUpdateProject({projectID:project.ID(),feeRateID:this.getActivateFeeRateFileID()},"feeRate",function () {
+                socket.emit('feeRateChangeNotify', {projectID:project.ID(),feeRateID:me.getActivateFeeRateFileID(),userID:userID});
+            });
         };
 
 
         FeeRate.prototype.onFeeRateFileChange=function () {//整个费率文件换了,原费率文件内容不变
             this.refreshCalProgramWhenFeeFileChange();
             this.refreshBillsWhenFeeFileChange();
+            let me = this;
             var node = project.mainTree.selected;
             if(node){
                 if (node.sourceType==='ration' && calcProgramObj.sheet) {
                     calcProgramObj.refreshCalcProgram(node, 3);
                 }
             }
-            project.calcProgram.calcAllNodesAndSave(calcAllType.catAll);
-            if(socketObject.roomInfo){
-                //判断费率文件ID是否改变了
-                if(socketObject.roomInfo.feeRate == this.getActivateFeeRateFileID()){//如果没变,则是重选了标准
-                    project.markUpdateProject({projectID:project.ID(),feeRateID:this.getActivateFeeRateFileID()},"feeRate");
-                    socket.emit('feeRateChangeNotify', socketObject.roomInfo.feeRate);
-                }else {
-                    let data ={
-                        projectID:project.ID(),
-                        oldRoom:socketObject.roomInfo.feeRate,
-                        newRoom:this.getActivateFeeRateFileID(),
-                        name:'feeRate'
-                    };
-                    socket.emit('changeNewRoom',data);
-                    socketObject.roomInfo.feeRate = this.getActivateFeeRateFileID();
+            project.calcProgram.calcAllNodesAndSave(calcAllType.catAll,function () {
+                if(socketObject.roomInfo){
+                    //判断费率文件ID是否改变了
+                    if(socketObject.roomInfo.feeRate == me.getActivateFeeRateFileID()){//如果没变,则是重选了标准
+                        project.markUpdateProject({projectID:project.ID(),feeRateID:me.getActivateFeeRateFileID()},"feeRate",function () {
+                            socket.emit('feeRateChangeNotify', {projectID:project.ID(),feeRateID:socketObject.roomInfo.feeRate,userID:userID});
+                        });
+                    }else {
+                        let data ={
+                            projectID:project.ID(),
+                            oldRoom:socketObject.roomInfo.feeRate,
+                            newRoom:me.getActivateFeeRateFileID(),
+                            userID:userID,
+                            name:'feeRate'
+                        };
+                        socket.emit('changeNewRoom',data);
+                        socketObject.roomInfo.feeRate = me.getActivateFeeRateFileID();
+                    }
                 }
-            }
+            });
+
 
         };
 

+ 3 - 0
web/building_saas/main/js/models/installation_fee.js

@@ -669,6 +669,7 @@ var installation_fee = {
                         unit:'元',
                         type:gljType.LABOUR,
                         basePrice:1,
+                        marketPrice:1,
                         adjCoe:null,
                         from:'std',
                         repositoryId:-1,
@@ -688,6 +689,7 @@ var installation_fee = {
                         unit:'元',
                         type:gljType.GENERAL_MATERIAL,
                         basePrice:1,
+                        marketPrice:1,
                         adjCoe:null,
                         from:'std',
                         repositoryId:-1,
@@ -707,6 +709,7 @@ var installation_fee = {
                         unit:'元',
                         type:gljType.GENERAL_MACHINE,
                         basePrice:1,
+                        marketPrice:1,
                         adjCoe:null,
                         from:'std',
                         repositoryId:-1,

+ 9 - 3
web/building_saas/main/js/models/project.js

@@ -314,8 +314,8 @@ var PROJECT = {
                 tools.modules[moduleName] = obj;
             }
         };
-        project.prototype.markUpdateProject = function (data,type) {
-            CommonAjax.post("/project/markUpdateProject",{updateInfo:data,type:type});
+        project.prototype.markUpdateProject = function (data,type,callback) {
+            CommonAjax.post("/project/markUpdateProject",{updateInfo:data,type:type},callback);
         };
 
         project.prototype.saveProperty = function (propertyName, propertyValue) {
@@ -323,12 +323,18 @@ var PROJECT = {
         };
 
         project.prototype.projectMarkChecking = function () {
+            let me = this;
             let  changeMark = projectInfoObj.projectInfo.changeMark;
             if(changeMark&&changeMark!=''){
                 this.Bills.getEngineeringCostNode(projectObj.mainController).changed = true;
                 this.calcProgram.calcAllNodesAndSave();
-                CommonAjax.post("/project/removeProjectMark",{projectID:this.ID()},function (data) {
+                CommonAjax.post("/project/removeProjectMark",{projectID:me.ID()},function (data) {
                     delete projectInfoObj.projectInfo.changeMark;
+                    if(socket.connected == true){//如果这时候socket已经连接成功,则发送删除标记广播
+                        socket.emit('removeProjectMark',{projectID:me.ID(),userID:userID});
+                    }else {//如果还没连接成功,则放入消息对象缓存,等socket连接成功后发送
+                        socketObject.messages.push({message:'removeProjectMark',data:{projectID:me.ID(),userID:userID}});
+                    }
                 });
             }
         };

+ 12 - 2
web/building_saas/main/js/models/quantity_detail.js

@@ -724,10 +724,15 @@ var quantity_detail = {
 
 
         quantity_detail.prototype.updateBillQuantity=function (value,node,quantityEXP,editingText) {
+            let oldQuantityEXP =  node.data.quantityEXP;
             node.data.quantityEXP = quantityEXP?quantityEXP:editingText;
             value = scMathUtil.roundForObj(value,getDecimal("quantity",node));
-            node.data.quantity = value+"";
-            console.log(value);
+            let newQuantity =  value+"";
+            if(oldQuantityEXP == node.data.quantityEXP && node.data.quantity == newQuantity){ //相当于什么都没改,不用做提交操作
+                projectObj.mainController.refreshTreeNode([node]);//这里要再刷新一下,因为工程量要把手工输入的值刷新为转换后的值再显示
+                return;
+            }
+            node.data.quantity = newQuantity;
             let needUpdateChildren = [];//需更新的子定额
             let gljNodes=[];//当定额工程量改变时需刷新的子工料机
             if(node.children.length>0){//如果有子项
@@ -791,10 +796,15 @@ var quantity_detail = {
             gljOprObj.refreshView();
         };
         quantity_detail.prototype.updateRationQuantity=function(value,node,quantityEXP,editingText){
+            let oldQuantityEXP =  node.data.quantityEXP;
             node.data.quantityEXP = quantityEXP?quantityEXP:editingText;
             //value = scMathUtil.roundForObj(value,getDecimal("ration.quantity"));
             value = project.quantity_detail.autoTransformQuantity(value,node);//先转换再4舍5入
             value = scMathUtil.roundForObj(value,decimalObj.decimal("quantity",node));
+            if(oldQuantityEXP == node.data.quantityEXP && node.data.quantity == value){ //相当于什么都没改,不用做提交操作
+                projectObj.mainController.refreshTreeNode([node]);//这里要再刷新一下,因为工程量要把手工输入的值刷新为转换后的值再显示
+                return;
+            }
             node.data.quantity=value;
             if(node.parent.data.quantity&&node.parent.data.quantity!=0&&node.parent.data.quantity!=""){
                 var billQuantity = scMathUtil.roundForObj(node.parent.data.quantity,getDecimal("quantity",node.parent));

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

@@ -784,6 +784,7 @@ var feeRateObject={
                 projectID:projectObj.project.ID(),
                 oldRoom:socketObject.roomInfo.feeRate,
                 newRoom: FeeRate.getActivateFeeRateFileID(),
+                userID:userID,
                 name:'feeRate'
             };
             socket.emit('changeNewRoom',data);

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

@@ -34,8 +34,8 @@ let gljCol = {
     project_glj_setting:{
         header: [
             {headerName: "编码", headerWidth: 80, dataCode: "code", dataType: "String"},
-            {headerName: "名称", headerWidth: 240, dataCode: "name", dataType: "String",cellType:'tipsCell'},
-            {headerName: "规格型号", headerWidth: 190, dataCode: "specs", hAlign: "left", dataType: "String",cellType:'tipsCell'},
+            {headerName: "名称", headerWidth: 160, dataCode: "name", dataType: "String",cellType:'tipsCell'},
+            {headerName: "规格型号", headerWidth: 160, dataCode: "specs", hAlign: "left", dataType: "String",cellType:'tipsCell'},
             {headerName: "单位", headerWidth: 45, dataCode: "unit", hAlign: "center", dataType: "String"},
             {headerName: "类型", headerWidth: 45, dataCode: "short_name", hAlign: "center", dataType: "String"},
             {headerName: "市场价", headerWidth: 70, dataCode: "marketPrice", hAlign: "right", dataType: "Number",validator:"number"},//,decimalField:"glj.unitPrice"

+ 13 - 9
web/building_saas/main/js/views/glj_view.js

@@ -568,8 +568,8 @@ var gljOprObj = {
         this.detailSheet.getRange(-1, 0, -1, this.detailSetting.header.length).locked(true);//锁住工程量明细的所有列
     },
     showRationGLJData: function (node) {
-        var gljList = [];
-        var ration_glj = projectObj.project.ration_glj;
+        let gljList = [];
+        let ration_glj = projectObj.project.ration_glj;
         node = node ? node : projectObj.project.mainTree.selected;
         if (node.sourceType == ModuleNames.ration) {
             if(node.data.type==rationType.gljRation){
@@ -718,13 +718,13 @@ var gljOprObj = {
         this.sheetData = newList;
     },
     combineWithProjectGlj: function (ration_gljs,needRatio=true) {
-        var projectGLJData = projectObj.project.projectGLJ.datas;
-        var projectGljs = projectGLJData.gljList;
-        var mixRatioMap = projectGLJData.mixRatioMap;
+        let projectGLJData = projectObj.project.projectGLJ.datas;
+        let projectGljs = projectGLJData.gljList;
+        let mixRatioMap = projectGLJData.mixRatioMap;
         if (ration_gljs && ration_gljs.length > 0 && projectGljs && projectGljs.length > 0) {
 
-            for (var i = 0; i < ration_gljs.length; i++) {
-                var glj = _.find(projectGljs, {'id': ration_gljs[i].projectGLJID});
+            for (let i = 0; i < ration_gljs.length; i++) {
+                let glj = _.find(projectGljs, {'id': ration_gljs[i].projectGLJID});
                 if (glj) {
                     if(projectObj.project.projectGLJ.isEstimateType(ration_gljs[i].type )){
                         ration_gljs[i].isEstimate = glj.is_evaluate;
@@ -732,9 +732,9 @@ var gljOprObj = {
                     ration_gljs[i].shortName =projectObj.project.projectGLJ.getShortNameByID(ration_gljs[i].type);
                     ration_gljs[i].isAdd = glj.unit_price.is_add;
                     ration_gljs[i]=this.setGLJPrice(ration_gljs[i],glj);//设置工料机价格
-                    var connect_index = this.getIndex(glj, gljKeyArray);
+                    let connect_index = this.getIndex(glj, gljKeyArray);
                     if (needRatio==true&&mixRatioMap.hasOwnProperty(connect_index)) {
-                        var mixRatios = this.getMixRationShowDatas(mixRatioMap[connect_index], projectGljs);
+                        let mixRatios = this.getMixRationShowDatas(mixRatioMap[connect_index], projectGljs);
                         ration_gljs[i].subList = mixRatios;
                     }
                 }
@@ -864,6 +864,10 @@ var gljOprObj = {
             recode? me.sheet.getCell(args.row, args.col).value(recode[updateField]): me.sheet.getCell(args.row, args.col).value(null);
             return;
         }
+        if(args.editingText){
+            args.editingText = args.editingText.replace(/[\r\n]/g, "");//去掉回车换行等字符;
+            me.sheet.getCell(args.row, args.col).value(args.editingText);
+        }
         if (updateField == 'marketPrice' || updateField == 'customQuantity' || updateField == 'basePrice') {
             if (args.editingText == null) {
                 updateField == 'marketPrice' ? newval = 0 : newval = "";

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

@@ -60,7 +60,7 @@ let MainTreeCol = {
         },
         marketPrice:function (node) {
             if((node.sourceType === projectObj.project.Ration.getSourceType()&&node.data.type!=rationType.ration)||node.sourceType==projectObj.project.ration_glj.getSourceType()){
-                return calcTools.uiGLJPrice(node.data.marketUnitFee);
+                if(node.data.marketUnitFee)  return calcTools.uiGLJPrice(node.data.marketUnitFee);
             }
         },
         feeRate:function (node) {
@@ -255,7 +255,11 @@ let MainTreeCol = {
              if(node.sourceType == ModuleNames.bills &&projectObj.ifItemCharHiden(setting)){//清单、并且项目特征列隐藏的时候悬浮提示
                 tips = node.data.itemCharacterText?node.data.itemCharacterText:'';
              }
-                    let dynamicCombo = sheetCommonObj.getTipsCombo(true,tips,setting);//sheetCommonObj.getDynamicCombo(true);
+            if(node.sourceType == ModuleNames.ration && node.data.type == rationType.ration){//定额类型时,显示人材机,工作内容等
+                //这里的人材机需要进行过滤,在初始化时组装会影响性能,应实时显示
+                tips = MainTreeCol.getRationUnitTips
+            }
+             let dynamicCombo = sheetCommonObj.getTipsCombo(true,tips,setting,node);//sheetCommonObj.getDynamicCombo(true);
             dynamicCombo.itemHeight(10).items(['m', 'm2', 'm3', 'km', 't', 'kg', '台班', '工日', '昼夜', '元', '项', '处', '个', '件',
                 '根', '组', '系统', '台', '套', '株', '丛', '缸', '支', '只', '块', '座', '对', '份', '樘', '攒', '榀']).editable(true);
             return dynamicCombo;
@@ -409,6 +413,23 @@ let MainTreeCol = {
             }
             ;
         }
+    },
+    getRationUnitTips:function (node) {
+        let tips="";
+        let ration_glj = projectObj.project.ration_glj;
+        let gljList = gljOprObj.filterGljByRation(node.data, ration_glj.datas);
+        for(let glj of gljList){
+            tips += `${glj.code} ${glj.name}${glj.specs ? '&nbsp;&nbsp;&nbsp;' + glj.specs : ''}&nbsp;&nbsp&nbsp;${glj.unit}&nbsp;&nbsp;&nbsp;${glj.quantity}<br>`;
+        }
+        if(node.data.content && node.data.content.toString().trim() !== ''){
+            tips += `工作内容:<br>`;
+            tips += `${node.data.content.replace(/\n/g,"<br>")}<br>`;
+        }
+        if(node.data.annotation && node.data.annotation.toString().trim() !== ''){
+            tips += `附注:<br>`;
+            tips += `${node.data.annotation.replace(/\n/g,"<br>")}<br>`;
+        }
+        return tips
     }
 };
 

+ 20 - 15
web/building_saas/main/js/views/project_glj_view.js

@@ -24,8 +24,8 @@ projectGljObject={
     materialSetting:{
         header:[
             {headerName: "编码", headerWidth: 200, dataCode: "code", dataType: "String"},
-            {headerName: "名称", headerWidth: 240, dataCode: "name", dataType: "String"},
-            {headerName: "规格型号", headerWidth: 190, dataCode: "specs", hAlign: "left", dataType: "String"},
+            {headerName: "名称", headerWidth: 160, dataCode: "name", dataType: "String"},
+            {headerName: "规格型号", headerWidth: 160, dataCode: "specs", hAlign: "left", dataType: "String"},
             {headerName: "单位", headerWidth: 45, dataCode: "unit", hAlign: "center", dataType: "String"},
             {headerName: "定额价", headerWidth: 70, dataCode: "basePrice", hAlign: "right", dataType: "Number",validator:"number"},//,decimalField:'glj.unitPrice'
             {headerName: "市场价", headerWidth: 70, dataCode: "marketPrice", hAlign: "right", dataType: "Number",validator:"number"},//,decimalField:"glj.unitPrice"
@@ -806,8 +806,10 @@ projectGljObject={
         gljOprObj.refreshView();
     },
     onUnitFileChange:function (data) {
-        socket.emit('unitFileChangeNotify', JSON.stringify(data));
-        projectObj.project.markUpdateProject({projectID:projectObj.project.ID(),'unitFileID':socketObject.getUnitFileRoomID()},"unitFile");
+        projectObj.project.markUpdateProject({projectID:projectObj.project.ID(),'unitFileID':socketObject.getUnitFileRoomID()},"unitFile",function(){
+            //socket.emit('unitFileChangeNotify', JSON.stringify(data));
+            socket.emit('unitFileChangeNotify', {projectID:projectObj.project.ID(),userID:userID,'unitFileID':socketObject.getUnitFileRoomID()});
+        });
     },
     deleteMixRatio:function (row) {
         let me = this, deleteRecode = me.mixRatioData[row];
@@ -1001,17 +1003,20 @@ projectGljObject={
         projectGljObject.unitPriceFileInit();
         projectGljObject.refreshDataSheet();
         gljOprObj.refreshView();
-        projectObj.project.calcProgram.calcAllNodesAndSave();
-        if(socketObject.roomInfo){
-            let data ={
-                projectID:projectObj.project.ID(),
-                oldRoom:socketObject.roomInfo.unitFile,
-                newRoom:socketObject.getUnitFileRoomID(),
-                name:'unitFile'
-            };
-            socket.emit('changeNewRoom',data);
-            socketObject.roomInfo.unitFile = socketObject.getUnitFileRoomID();
-        }
+        projectObj.project.calcProgram.calcAllNodesAndSave(calcAllType.catAll,function () {
+            if(socketObject.roomInfo){
+                let data ={
+                    projectID:projectObj.project.ID(),
+                    oldRoom:socketObject.roomInfo.unitFile,
+                    newRoom:socketObject.getUnitFileRoomID(),
+                    userID:userID,
+                    name:'unitFile'
+                };
+                socket.emit('changeNewRoom',data);
+                socketObject.roomInfo.unitFile = socketObject.getUnitFileRoomID();
+            }
+        });
+
     },
     calcPartASupplyFeeByProjectGLJs: function (projectGLJsArr) {
         for (let pGLJ of projectGLJsArr){

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

@@ -1184,6 +1184,7 @@ var projectObj = {
                     },
                     callback: function (key, opt) {
                         ProjectController.addFB(project, controller);
+                        projectObj.selectColAndFocus(project.mainTree.selected);
                     },
                     visible: function(key, opt){
                         if(project.mainTree.selected){
@@ -1221,6 +1222,7 @@ var projectObj = {
                     },
                     callback: function (key, opt) {
                         ProjectController.addFX(project, controller);
+                        projectObj.selectColAndFocus(project.mainTree.selected);
                     },
                     visible: function(key, opt){
                         if(project.mainTree.selected){
@@ -1248,6 +1250,7 @@ var projectObj = {
                             }
                         }
                         ProjectController.addBills(project, controller);
+                        projectObj.selectColAndFocus(project.mainTree.selected);
                     },
                      visible: function(key, opt){
                          if(project.mainTree.selected){
@@ -1285,7 +1288,10 @@ var projectObj = {
                         return !project.Ration.canAdd(project.mainTree.selected);
                     },
                     callback: function (key, opt) {
-                        project.Ration.addNewRation(null,rationType.volumePrice,null,true);
+                        project.Ration.addNewRation(null,rationType.volumePrice,function (newNode) {//插入量价不需要自动定位到编号列
+                            projectObj.selectColAndFocus(newNode,null);
+                        },true);
+
                        // ProjectController.addRation(project, controller, rationType.volumePrice);
                     },
                   /*  items:{
@@ -1911,7 +1917,7 @@ var projectObj = {
     },
     selectColAndFocus :function (newNode,field = 'code') {//选中单元格并设置焦点
         if(newNode){
-            projectObj.mainController.sheet.setSelection(newNode.serialNo(), colSettingObj.getColByField(field), 1, 1);  //
+            if(field != null) projectObj.mainController.sheet.setSelection(newNode.serialNo(), colSettingObj.getColByField(field), 1, 1);  //自动定位到编号单元格
             projectObj.mainSpread.focus();
         }
     }

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

@@ -187,10 +187,10 @@ let quantityEditObj = {
     },
     checkingAndUpdate(quantityEXP,node){
         let me = this;
-        if(quantityEXP === node.data.quantityEXP){ //没有变化,不做任何操作
+       /* if(quantityEXP === node.data.quantityEXP){ //没有变化,不做任何操作
             projectObj.mainController.refreshTreeNode([node]);
             return true;
-        }
+        }*/
         quantityEXP = quantityEXP?quantityEXP.toUpperCase():'';//非空判断
         quantityEXP =replaceAll('(','(',quantityEXP);//转换中文左右符号
         quantityEXP =replaceAll(')',')',quantityEXP);

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

@@ -469,11 +469,11 @@ function refreshSubSpread(){
     if(pageCCOprObj.active){
         contentOprObj.workBook.refresh();
         characterOprObj.workBook.refresh();
-    }
-    else{
+    } else{
         if(subSpread) subSpread.refresh();
         if(MaterialController.spread) MaterialController.spread.refresh();
     }
+    if($('#linkZMHS').hasClass('active')) zmhs_obj.refresh();
 }
 
 let subViewObj = {

+ 14 - 0
web/building_saas/main/js/views/zmhs_view.js

@@ -316,3 +316,17 @@ let zmhs_obj = {
         return true;
     }
 };
+
+let zmhs_sideResizeEles = {};
+zmhs_sideResizeEles.id = 'tabZMHS';
+zmhs_sideResizeEles.resize = $('#zmhsResize');
+zmhs_sideResizeEles.evFixedSize = `$(window).width()-$('.main-nav').width()-5`;
+zmhs_sideResizeEles.nearElement = $('#coeSpread');
+zmhs_sideResizeEles.nearSpread = $('#coeSpread');
+zmhs_sideResizeEles.farElement = $('#assSpread');
+zmhs_sideResizeEles.farSpread = $('#assSpread');
+zmhs_sideResizeEles.nav = null;
+slideResize(zmhs_sideResizeEles, {min: 100, max: $('#tabCon').width()-100}, 'width', function(){
+    zmhs_obj.refresh();
+});
+

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

@@ -22,6 +22,7 @@
         // 这里的变量供页面调用
         var userAccount = '<%- userAccount %>';
         var userID = '<%- userID %>';
+        console.log(userID);
     </script>
     <style type="text/css">
         .hidden-area{
@@ -39,6 +40,7 @@
 <img src="/web/dest/css/img/project.png" id="proj_pic" style="display: none">
 <img src="/web/dest/css/img/engineering.png" id="eng_pic" style="display: none">
 <img src="/web/dest/css/img/tender.png" id="tender_pic" style="display: none">
+<img src="/web/dest/css/img/refresh.png" id="refresh_pic" style="display: none">
 <div class="header">
     <div class="top-msg clearfix">
         <div class="alert alert-warning mb-0 py-0" role="alert" style="display: none;">
@@ -683,6 +685,8 @@
 <script src="/public/web/sheet/sheet_common.js"></script>
 <script type="text/javascript" src="/public/web/common_ajax.js"></script>
 <script src="/lib/JSExpressionEval_src/Date.js"></script>
+<script src="/web/building_saas/glj/js/socket.io.slim.js"></script>
+<script src="/public/web/socket/connection.js"></script>
 <script src="/web/building_saas/pm/js/pm_ajax.js"></script>
 <script src="/web/building_saas/pm/js/pm_newMain.js"></script>
 <script src="/web/building_saas/pm/js/pm_gc.js"></script>

+ 34 - 3
web/building_saas/pm/js/pm_newMain.js

@@ -356,7 +356,8 @@ const projTreeObj = {
                     },
                     callback: function (key, opt) {
                         //获取当前节点的建设项目ID
-                        let project = projTreeObj.tree.selected;
+                        projTreeObj.refreshProjectData();
+                      /*  let project = projTreeObj.tree.selected;
                         while (project.data.projType !== projectType.project && project.parent){
                             project = project.parent;
                         }
@@ -368,7 +369,7 @@ const projTreeObj = {
                             }, function () {
                                 $.bootstrapLoading.start();
                             });
-                        }
+                        }*/
                     }
                 }
             }
@@ -738,9 +739,11 @@ const projTreeObj = {
                         imgWidth = 14;
                     }
                     else if(node.data.projType === projectType.tender){
-                        img = document.getElementById('tender_pic');
+                        //如果单位工程不是实时计算结果,则显示刷新标记
+                        img = node.data.changeMark && node.data.changeMark!=""? document.getElementById('refresh_pic'):document.getElementById('tender_pic');
                         imgWidth = 14;
                     }
+
                     ctx.drawImage(img, centerX+indent/2+3, centerY - 7, imgWidth,imgHeight);
                 }
                 // Draw Vertical Line
@@ -1103,6 +1106,31 @@ const projTreeObj = {
             return newNode;
         }
 
+    },
+    refreshProjectData:function (projectID) {
+        //projTreeObj.tree.findNode(4578)
+        //获取当前节点的建设项目ID
+        let project = projectID?projTreeObj.tree.findNode(projectID):projTreeObj.tree.selected;
+        while (project.data.projType !== projectType.project && project.parent){
+            project = project.parent;
+        }
+        if(project && project.data.ID){
+            $.bootstrapLoading.start();
+            CommonAjax.post('/pm/api/getSummaryInfo', {user_id: userID, projectIDs: [project.data.ID]}, function (summaryInfo) {//11-06 zhang 这个接口返回值增加了项目需重新计算标记,项目图标刷新
+                refreshProjSummary(project, summaryInfo);
+                $.bootstrapLoading.end();
+            }, function () {
+                $.bootstrapLoading.start();
+            });
+        }
+    },
+    refreshProjectIcon:function (projectID) {
+        let node = projTreeObj.tree.findNode(projectID);
+        if(node && node.data.changeMark && node.data.changeMark!="") this.refreshProjectData(projectID);
+    },
+    refreshWhenFileDateChange:function(projectID){//当单价文件、费率文件被修改后,刷新页面,共用的项目提示刷新图标
+        //在一次的修改中,同一个建设下,单价文件、费率文件才有共用的情况,而refreshProjectData是传入单位工程ID,刷新整个建设项目,所以,只要传入修改的单位工程ID,刷新建设项目即可
+        this.refreshProjectData(projectID);
     }
 };
 
@@ -1672,6 +1700,7 @@ function init() {
     billValuation = billValuation.replace(/\n/g, '\\n');
     rationValuation = rationValuation.replace(/\n/g, '\\n');
     //init spread and pmTree
+    socketObject.connect('pm');//socket 连接;
     $.bootstrapLoading.start();
     GetAllProjectData(function (datas) {
         //设置工程专业
@@ -3401,6 +3430,8 @@ function refreshProjSummary(project, summaryInfo) {
             node.data.rate = nodeInfo.rate;
             node.data.buildingArea = nodeInfo.buildingArea;
             node.data.perCost = nodeInfo.perCost;
+            node.data.changeMark = nodeInfo.changeMark;
+            if(nodeInfo.property) node.data.property = nodeInfo.property;
         }
     }
     projTreeObj.refreshNodeData(refreshNodes);

+ 3 - 3
web/building_saas/report/html/rpt_main.html

@@ -3,12 +3,12 @@
     <div class="row">
         <div class="col-lg-3 p-0">
             <div class="print-list">
+                <!--
                 <div class="list-tools d-flex justify-content-center">
-                    <!--
-                        <button class="btn btn-outline-primary btn-sm" data-toggle="modal" data-target="#editForm"><i class="fa fa-cog"></i> 管理报表</button>
-                    -->
+                    <button class="btn btn-outline-primary btn-sm" data-toggle="modal" data-target="#editForm"><i class="fa fa-cog"></i> 管理报表</button>
                     <button class="btn btn-outline-primary btn-sm" onclick="zTreeOprObj.getReportTemplateTree()"><i class="fa fa-cog"></i> 刷新</button>
                 </div>
+                -->
                 <div class="form-list">
                     <ul id="rptTplTree" class="ztree"></ul>
                 </div>