Selaa lähdekoodia

Merge branch 'master' of http://smartcost.f3322.net:3000/SmartCost/ConstructionCost

chenshilong 7 vuotta sitten
vanhempi
commit
9716de6724
31 muutettua tiedostoa jossa 779 lisäystä ja 114 poistoa
  1. 5 0
      modules/all_models/project_glj.js
  2. 1 1
      modules/glj/controllers/glj_controller.js
  3. 1 0
      modules/pm/models/project_property_template.js
  4. 67 4
      modules/reports/util/rpt_construct_data_util.js
  5. 24 1
      public/web/id_tree.js
  6. 1 0
      public/web/rpt_value_define.js
  7. 3 2
      public/web/sheet/sheet_data_helper.js
  8. 12 0
      public/web/tree_sheet/tree_sheet_helper.js
  9. 1 1
      test/unit/reports/test_preview_page.js
  10. 106 0
      test/unit/reports/test_tpl_10.js
  11. 4 0
      web/building_saas/css/custom.css
  12. 10 2
      web/building_saas/css/main.css
  13. 29 13
      web/building_saas/glj/html/project_glj.html
  14. 1 1
      web/building_saas/js/global.js
  15. 1 1
      web/building_saas/main/html/main.html
  16. 32 4
      web/building_saas/main/js/main.js
  17. 1 1
      web/building_saas/main/js/models/cache_tree.js
  18. 1 0
      web/building_saas/main/js/models/composition.js
  19. 39 2
      web/building_saas/main/js/models/main_consts.js
  20. 2 0
      web/building_saas/main/js/models/project_glj.js
  21. 2 2
      web/building_saas/main/js/models/ration_glj.js
  22. 1 0
      web/building_saas/main/js/views/calc_program_manage.js
  23. 2 2
      web/building_saas/main/js/views/character_content_view.js
  24. 1 0
      web/building_saas/main/js/views/fee_rate_view.js
  25. 0 1
      web/building_saas/main/js/views/installation_fee_view.js
  26. 319 47
      web/building_saas/main/js/views/project_glj_view.js
  27. 1 0
      web/building_saas/main/js/views/project_property_decimal_view.js
  28. 3 2
      web/building_saas/main/js/views/project_property_projFeature.js
  29. 51 9
      web/building_saas/main/js/views/project_view.js
  30. 36 14
      web/building_saas/main/js/views/std_bills_lib.js
  31. 22 4
      web/building_saas/main/js/views/std_ration_lib.js

+ 5 - 0
modules/all_models/project_glj.js

@@ -91,6 +91,11 @@ let modelSchema = {
     connect_code: String,
     materialType: Number,   //三材类别
     materialCoe: Number,    //三材系数
+    // 是否主要材料 (0为否 1为是)
+    is_main_material: {
+        type: Number,
+        default: 0
+    },
     ratio_data: Schema.Types.Mixed
 };
 mongoose.model(collectionName, new Schema(modelSchema, {versionKey: false}));

+ 1 - 1
modules/glj/controllers/glj_controller.js

@@ -82,7 +82,7 @@ class GLJController extends BaseController {
         try {
             // 可编辑的字段
             let editableField = ['is_evaluate', 'unit_price.market_price', 'is_adjust_price', 'mix_ratio.consumption',
-                'supply', 'supply_quantity','delivery_address','delivery','materialType','materialCoe'];
+                'supply', 'supply_quantity','delivery_address','delivery','materialType','materialCoe','is_main_material'];
             if (editableField.indexOf(field) < 0) {
                 throw '对应字段不能编辑';
             }

+ 1 - 0
modules/pm/models/project_property_template.js

@@ -116,6 +116,7 @@ const projectFeature = [
     {dispName: '基础类型', key: 'baseType', value: ''},
     {dispName: '建筑特征', key: 'buildingFeature', value: ''},
     {dispName: '建筑面积(m2)', key: 'buildingArea', value: ''},
+    {dispName: '其中地下室建筑面积(m2)', key: 'basementBuildingArea', value: ''},
     {dispName: '总层数', key: 'totalFloors', value: ''},
     {dispName: '地下室层数(+/-0.00以下)', key: 'basementFloors', value: ''},
     {dispName: '建筑层数(+/-0.00以下)', key: 'buildingFloors', value: ''},

+ 67 - 4
modules/reports/util/rpt_construct_data_util.js

@@ -7,6 +7,7 @@ let $JE = require('../rpt_component/jpc_rte');
 let consts = require('../../../modules/main/models/project_consts');
 
 let fsUtil = require("../../../public/fsUtil");
+let stringUtil = require("../../../public/stringUtil");
 
 let treeUtil = require('../../../public/treeUtil');
 let projectConst = consts.projectConst;
@@ -102,6 +103,13 @@ class Rpt_Common{
         }
         return rst;
     };
+    FormatString(arrVal, formatStr){
+        let rst = [];
+        for (let val of arrVal) {
+            rst.push(stringUtil.replaceAll(formatStr, '%S', val));
+        }
+        return rst;
+    };
 }
 
 class Rpt_Data_Extractor {
@@ -191,6 +199,9 @@ class Rpt_Data_Extractor {
         $PROJECT.MAIN["myOwnRawDataObj"] = rawDataObj.prj._doc;
         $PROJECT.MAIN.getProperty = ext_mainGetPropety;
         $PROJECT.MAIN.getFee = ext_mainGetFee;
+        for (let item of rawDataObj.prjData) {
+            setupFunc($PROJECT.DETAIL, item.moduleName, item);
+        }
         if (tpl[JV.NODE_MAP_DATA_HANDLE_INFO]) {
             for (let preHandle of tpl[JV.NODE_MAP_DATA_HANDLE_INFO]) {
                 let srcData = getModuleDataByKey(rawDataObj.prjData, preHandle[JV.PROP_DATA_KEY]);
@@ -220,9 +231,6 @@ class Rpt_Data_Extractor {
                 }
             }
         }
-        for (let item of rawDataObj.prjData) {
-            setupFunc($PROJECT.DETAIL, item.moduleName, item);
-        }
         let rptDataObj = {};
         rptDataObj[JV.DATA_DISCRETE_DATA] = [];
         rptDataObj[JV.DATA_MASTER_DATA] = [];
@@ -716,16 +724,39 @@ function sortData(sourceData, sortCfg, prjData) {
             let addLevel = true;
             rst = treeUtil.buildTreeNodeDirectly(tempRstArr, addLevel);
             let newTopArr = [];
-            if (sortCfg[JV.PROP_FILTER_TOP_BILLS_NODES] && sortCfg[JV.PROP_FILTER_TOP_BILLS_NODES].length > 0) {
+            if ((sortCfg[JV.PROP_FILTER_TOP_BILLS_NODES] && sortCfg[JV.PROP_FILTER_TOP_BILLS_NODES].length > 0) ||
+                (sortCfg[JV.PROP_FILTER_OTHER_BILLS_NODES] && sortCfg[JV.PROP_FILTER_OTHER_BILLS_NODES].length > 0)) {
+                let local_check_bills = function(tItem) {
+                    let chkDtl = false;
+                    if (tItem.flags && tItem.flags.length > 0) {
+                        for (let flagItem of tItem.flags) {
+                            if (sortCfg[JV.PROP_FILTER_OTHER_BILLS_NODES].indexOf(flagItem.flag) >= 0) {
+                                newTopArr.push(tItem);
+                                chkDtl = true;
+                                break;
+                            }
+                        }
+                    }
+                    if (!chkDtl && tItem.items && tItem.items.length > 0) {
+                        for (let dtlItem of tItem.items) {
+                            local_check_bills(dtlItem);
+                        }
+                    }
+                };
                 for (let topItem of rst) {
+                    let chkTop = false;
                     if (topItem.flags && topItem.flags.length > 0) {
                         for (let flagItem of topItem.flags) {
                             if (sortCfg[JV.PROP_FILTER_TOP_BILLS_NODES].indexOf(flagItem.flag) >= 0) {
                                 newTopArr.push(topItem);
+                                chkTop = true;
                                 break;
                             }
                         }
                     }
+                    if (!chkTop && sortCfg[JV.PROP_FILTER_OTHER_BILLS_NODES] && sortCfg[JV.PROP_FILTER_OTHER_BILLS_NODES].length > 0) {
+                        local_check_bills(topItem);
+                    }
                 }
             } else {
                 newTopArr = rst;
@@ -800,7 +831,9 @@ function sortData(sourceData, sortCfg, prjData) {
 function setupFunc(obj, prop, ownRawObj) {
     obj[prop] = {};
     obj[prop]["myOwnRawDataObj"] = ownRawObj;
+    obj[prop]["myOwnOrgRawDataObj"] = ownRawObj.data;
     obj[prop].getProperty = ext_getPropety;
+    obj[prop].getPropertyByRefId = ext_getPropertyByRefId;
     obj[prop].getFee = ext_getFee;
     obj[prop].getPropertyByForeignId = ext_getPropertyByForeignId;
     obj[prop].getArrayValues = ext_getArrayValues;
@@ -920,6 +953,36 @@ function ext_getPropety(propKey) {
     return rst;
 }
 
+function ext_getPropertyByRefId(baseKey, refIDKey, propertyKey){
+    let rst = [], parentObj = this;
+    let dtObj = parentObj["myOwnRawDataObj"];
+    let orgDtObj = parentObj["myOwnOrgRawDataObj"];
+    if (baseKey && refIDKey && propertyKey && dtObj) {
+        for (let dItem of dtObj.data) {
+            let doc = (dItem._doc === null || dItem._doc === undefined)?dItem:dItem._doc;
+            let tmpRst = doc[baseKey];
+            if (typeof tmpRst === "string" && tmpRst[0] === "@") {
+                let refKey = tmpRst.slice(1);
+                let hasGetRef = false;
+                for (let orgDItem of orgDtObj) {
+                    let oDoc = (orgDItem._doc === null || orgDItem._doc === undefined)?orgDItem:orgDItem._doc;
+                    if (oDoc[refIDKey] === refKey) {
+                        rst.push(oDoc[propertyKey]);
+                        hasGetRef = true;
+                        break;
+                    }
+                }
+                if (!hasGetRef) {
+                    rst.push(tmpRst);
+                }
+            } else {
+                rst.push(tmpRst);
+            }
+        }
+    }
+    return rst;
+}
+
 function ext_mainGetFee(feeKey, dtlFeeKey) {
     let rst = [];
     let parentObj = this;

+ 24 - 1
public/web/id_tree.js

@@ -501,7 +501,6 @@ var idTree = {
             }
             return iCount;
         };
-
         Tree.prototype.insert = function (parentID, nextSiblingID) {
             var newID = this.newNodeID(), node = null, data = {};
             var parent = parentID == -1 ? null : this.nodes[this.prefix + parentID];
@@ -689,6 +688,30 @@ var idTree = {
             }
         };
 
+        Tree.prototype.getExpState = function (nodes) {
+            let sessionExpanded = [];
+            function getStat(items){
+                for(let item of items){
+                    sessionExpanded.push(item.expanded ? 1 : 0);
+                }
+            }
+            getStat(nodes);
+            let expState = sessionExpanded.join('');
+            return expState;
+        };
+
+        //节点根据展开收起列表'010101'展开收起
+        Tree.prototype.setExpandedByState = function (nodes, expState) {
+            let expStateArr = expState.split('');
+            for(let i = 0; i < nodes.length; i++){
+                let expanded = expStateArr[i] == 1 ? true : false;
+                if(nodes[i].expanded === expanded){
+                    continue;
+                }
+                nodes[i].setExpanded(expanded);
+            }
+        };
+
         /*Tree.prototype.editedData = function (field, id, newText) {
             var node = this.findNode(id), result = {allow: false, nodes: []};
             if (this.event[this.eventType.editedData]) {

+ 1 - 0
public/web/rpt_value_define.js

@@ -55,6 +55,7 @@ const JV = {
     PROP_HANDLE_TYPE: "预处理类型",
     PROP_FILTER_KEYS: "过滤键值集",
     PROP_FILTER_TOP_BILLS_NODES: "清单顶节点集",
+    PROP_FILTER_OTHER_BILLS_NODES: "其他清单节点集",
     PROP_FILTER_COMPARE_OBJ: "compareObjKey",
     PROP_FILTER_COMPARE_OBJ_KEY: "compareObjIdKey",
     PROP_FILTER_COMPARE_VAL: "compareValue",

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

@@ -45,8 +45,9 @@ var SheetDataHelper = {
     initSetting: function (obj, setting) {
         setting.pos = this.getObjPos(obj);
     },
-    createNewSpread: function (obj) {
-        var spread = new GC.Spread.Sheets.Workbook(obj, {sheetCount: 1});
+    createNewSpread: function (obj,sheetCount) {
+        sheetCount = sheetCount?sheetCount:1;
+        var spread = new GC.Spread.Sheets.Workbook(obj, {sheetCount: sheetCount});
         spread.options.tabStripVisible = false;
         spread.options.scrollbarMaxAlign = true;
         spread.options.cutCopyIndicatorVisible = false;

+ 12 - 0
public/web/tree_sheet/tree_sheet_helper.js

@@ -106,6 +106,9 @@ var TREE_SHEET_HELPER = {
             let iRow = node.serialNo();
             if(typeof projectObj !== 'undefined'){
                 let nodeStyle = projectObj.getNodeColorStyle(sheet, node);
+                if(node.data.bgColour){
+                    nodeStyle.backColor = node.data.bgColour;
+                }
                 if(nodeStyle){
                     sheet.setStyle(iRow, -1, nodeStyle);
                 }
@@ -319,7 +322,16 @@ var TREE_SHEET_HELPER = {
             let centerX = hitinfo.cellRect.x + offset + node.depth() * indent + node.depth() * levelIndent + indent / 2;
             let centerY = (hitinfo.cellRect.y + offset + (hitinfo.cellRect.y + offset + hitinfo.cellRect.height)) / 2;
             if (hitinfo.x > centerX - halfBoxLength && hitinfo.x < centerX + halfBoxLength && hitinfo.y > centerY - halfBoxLength && hitinfo.y < centerY + halfBoxLength) {
+                console.log(`hitinfo.sheet.name()`);
+                console.log(hitinfo.sheet.name());
                 node.setExpanded(!node.expanded);
+                let sheetName = hitinfo.sheet.name();
+                if(sheetName === 'stdBillsLib_bills'){
+                    sessionStorage.setItem('stdBillsLibExpState', billsLibObj.stdBillsTree.getExpState(billsLibObj.stdBillsTree.items));
+                }
+                else if(sheetName === 'stdRationLib_chapter'){
+                    sessionStorage.setItem('stdRationLibExpState', rationLibObj.tree.getExpState(rationLibObj.tree.items));
+                }
                 TREE_SHEET_HELPER.massOperationSheet(hitinfo.sheet, function () {
                     let iCount = node.posterityCount(), i, child;
                     for (i = 0; i < iCount; i++) {

+ 1 - 1
test/unit/reports/test_preview_page.js

@@ -24,7 +24,7 @@ cfgCacheUtil.setupDftCache();
 let fsUtil = require("../../../public/fsUtil");
 
 // let demoPrjId = - 1;
-let demoRptId = 232; //重庆09年建筑 09表
+let demoRptId = 275; //重庆09年建筑 09表
 // let demoRptId = 229; //重庆09年建筑 封2表
 
 let pagesize = "A4";

+ 106 - 0
test/unit/reports/test_tpl_10.js

@@ -0,0 +1,106 @@
+/**
+ * Created by Tony on 2018/5/22.
+ */
+/**
+ * Created by Tony on 2018/5/11.
+ */
+
+let test = require('tape');
+import JpcEx from "../../../modules/reports/rpt_component/jpc_ex";
+import JV from "../../../modules/reports/rpt_component/jpc_value_define";
+let config = require("../../../config/config.js");
+config.setupDb(process.env.NODE_ENV);
+let mongoose = require("mongoose");
+let fileUtils = require("../../../modules/common/fileUtils");
+let path = require('path');
+let dbm = require("../../../config/db/db_manager");
+let rpt_cfg = require('./rpt_cfg');
+dbm.connect(process.env.NODE_ENV);
+
+//统一引用models
+fileUtils.getGlobbedFiles('../../../modules/all_models/*.js').forEach(function(modelPath) {
+    require(path.resolve(modelPath));
+});
+
+//config.setupCache();
+let cfgCacheUtil = require("../../../config/cacheCfg");
+cfgCacheUtil.setupDftCache();
+
+let fsUtil = require("../../../public/fsUtil");
+
+let demoPrjId = - 1;
+let demoRptId = 245, pagesize = "A4";
+
+// let userId_Leng = "59cdf14a0034a1000ba52b97"; //小冷User Id 换成_id了 QQ号
+let userId_Leng = "5acac1e885bf55000bd055ba"; //小冷User Id2
+// demoPrjId = 720; //QA: DW3
+//demoPrjId = 1626; //QA:
+demoPrjId = 2260; //QA:
+//*/
+let userId_Dft = userId_Leng;
+/*/
+ let userId_Dft = "595328da1934dc327cad08eb";
+ //*/
+
+let rptTplFacade = require("../../../modules/reports/facade/rpt_template_facade");
+let rptTplDataFacade = require("../../../modules/reports/facade/rpt_tpl_data_facade");
+
+import rptDataExtractor from "../../../modules/reports/util/rpt_construct_data_util";
+
+let fs = require('fs');
+//设置Date Format函数
+fs.readFile(__dirname.slice(0, __dirname.length - 18) + '/public/web/date_util.js', 'utf8', 'r', function (err, data) {
+    eval(data);
+});
+
+test('测试 - 测试模板: 表-11 ', function (t) {
+    rptTplFacade.getRptTemplate(demoRptId).then(function(rptTpl) {
+        let rptDataUtil = new rptDataExtractor();
+        rptDataUtil.initialize(rptTpl._doc);
+        let filter = rptDataUtil.getDataRequestFilter();
+        console.log(filter);
+        //正常应该根据报表模板定义的数据类型来请求数据
+        rptTplDataFacade.prepareProjectData(userId_Dft, demoPrjId, filter, function (err, msg, rawDataObj) {
+            if (!err) {
+                try {
+                    // fsUtil.writeObjToFile(rawDataObj, "D:/GitHome/ConstructionCost/tmp/rptTplRawDataObject_建筑10表.jsp");
+                    let tplData = rptDataUtil.assembleData(rawDataObj);
+                    // fsUtil.writeObjToFile(tplData, "D:/GitHome/ConstructionCost/tmp/rptTplAssembledData_建筑10表.jsp");
+                    //it's time to build the report!!!
+                    let printCom = JpcEx.createNew();
+                    rptTpl[JV.NODE_MAIN_INFO][JV.NODE_PAGE_INFO][JV.PROP_PAGE_SIZE] = pagesize;
+                    let defProperties = rpt_cfg;
+                    let dftOption = JV.PAGING_OPTION_NORMAL;
+                    printCom.initialize(rptTpl);
+                    printCom.analyzeData(rptTpl, tplData, defProperties, dftOption);
+                    let maxPages = printCom.totalPages;
+                    let pageRst = printCom.outputAsSimpleJSONPageArray(rptTpl, tplData, 1, maxPages, defProperties);
+                    if (pageRst) {
+                        // fsUtil.writeObjToFile(pageRst, "D:/GitHome/ConstructionCost/tmp/testBuiltPageResult_建筑10表.jsp");
+                    } else {
+                        console.log("oh! no pages were created!");
+                    }
+                } catch (ex) {
+                    console.log(ex);
+                    t.pass('pass with exception!');
+                    t.end();
+                }
+
+                t.pass('pass succeeded!');
+                t.end();
+            } else {
+                console.log(msg);
+                t.pass('pass with error!');
+                t.end();
+            }
+        })
+    });
+});
+
+test('close the connection', function (t) {
+    setTimeout(function () {
+        mongoose.disconnect();
+        t.pass('closing db connection');
+        t.end();
+    }, 1000);
+});

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

@@ -29,3 +29,7 @@ legend.legend{
 .toolsbar_feeRate {
     border-bottom: 1px solid #ccc
 }
+
+.li_sub {
+    margin-left: 14px;
+}

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

@@ -150,8 +150,8 @@ body {
     height: 30px;
     line-height: 30px;
     background:#F1F1F1;
-    bottom:30px;
-    left:5px;
+    bottom:28px;
+    left:0px;
 }
 .side-tabs .nav-tabs .nav-item {
     z-index: 999
@@ -267,10 +267,18 @@ body {
         transform: translateX(10px);
     }
 }
+.gl-side{
+    border-right:1px solid #ccc;
+    width:150px
+}
 .bottom-content .tab-content .main-data-bottom{
     height: 300px;
     overflow: auto;
 }
+.bottom-content .main-data-bottom2{
+    height: 331px;
+    overflow: hidden;
+}
 .bottom-content .tab-content .ovf-hidden{
     overflow: hidden;
 }

+ 29 - 13
web/building_saas/glj/html/project_glj.html

@@ -12,33 +12,49 @@
 </div>
 <div class="container-fluid">
     <div class="row">
-        <div class="col-lg-12 p-0" id="project-glj-main">
+        <div class="gl-side col-lg-1" id='filterType'>
+            <ul class="list-unstyled ml-3 mt-2 mb-2">
+                <li><a href="javascript:void(0)" id="ALL">所有工料机</a></li>
+                <li class="mb-2 li_sub"><a href="javascript:void(0)" id="LABOUR">人工</a></li>
+                <li class="mb-2 li_sub"><a href="javascript:void(0)" id="GENERAL_MATERIAL">材料</a></li>
+                <li class="mb-2 li_sub"><a href="javascript:void(0)" id="GENERAL_MACHINE">机械</a></li>
+                <li class="mb-2 li_sub"><a href="javascript:void(0)" id="MAIN_MATERIAL">主材</a></li>
+                <li class="mb-2 li_sub"><a href="javascript:void(0)" id="EQUIPMENT">设备</a></li>
+                <li class="mb-2"><a href="javascript:void(0)" id="FBFX">分部分项工料机</a></li>
+                <li class="mb-2"><a href="javascript:void(0)" id="TECH">措施分项工料机</a></li>
+                <li class="mb-2"><a href="javascript:void(0)" id="JGCL">甲供材料</a></li>
+                <li class="mb-2"><a href="javascript:void(0)" id="ZGCL">暂估材料</a></li>
+                <li class="mb-2"><a href="javascript:void(0)" id="SCHZ">三材汇总</a></li>
+                <li class="mb-2"><a href="javascript:void(0)" id="ZYCL">主要材料</a></li>
+            </ul>
+        </div>
+        <div class="main-content col p-0 col-lg-11" id="project-glj-main">
             <div class="top-content">
-                <div class="main-data-top" style="width: 100%" id="project_glj_sheet">
+                <div class="main-data-top" style="width: 100% " id="project_glj_sheet">
                 </div>
             </div>
             <div class="resize"></div>
             <div class="bottom-content">
                 <ul class="nav nav-tabs" role="tablist">
-                    <li class="nav-item">
+                  <!--  <li class="nav-item">
                         <a class="nav-link active" data-toggle="tab" data-name="ration_sheet" id="ration_link" href="#glj_de_div" role="tab">相关定额</a>
-                    </li>
-                    <li class="nav-item">
-                        <a class="nav-link" data-toggle="tab" data-name="mix_ratio_sheet" id="mix_ratio_link" href="#ph_div" role="tab">配合比表</a>
-                    </li>
-                    <li class="nav-item">
+                    </li>-->
+                   <!-- <li class="nav-item">
+                        <a class="nav-link active" data-toggle="tab" data-name="mix_ratio_sheet" id="mix_ratio_link" href="#ph_div" role="tab">组成物</a> 配合比、机械单价表合并
+                    </li>-->
+                   <!-- <li class="nav-item">
                         <a class="nav-link" data-toggle="tab" data-name="machine_sheet" id="machine_ratio_link" href="#ph_div" role="tab">机械单价</a>
-                    </li>
+                    </li>-->
                 </ul>
                 <!-- Tab panes -->
                 <div class="tab-content">
-                    <div class="tab-pane active" id="glj_de_div" role="tabpanel">
+                    <!--<div class="tab-pane active" id="glj_de_div" role="tabpanel">
                         <div class="main-data-bottom ovf-hidden">
                             相关定额
                         </div>
-                    </div>
-                    <div class="tab-pane" id="ph_div" role="tabpanel">
-                        <div class="main-data-bottom" id="mix_ratio_sheet">
+                    </div>-->
+                    <div class="tab-pane active" id="ph_div" role="tabpanel">
+                        <div class="main-data-bottom" id="mix_ratio_sheet" style="overflow:hidden">
                         </div>
                     </div>
              <!--       <div class="tab-pane" id="jx_div" role="tabpanel">

+ 1 - 1
web/building_saas/js/global.js

@@ -16,7 +16,7 @@ function autoFlashHeight(){
     $('#glj_tree_div .modal-content').width($(window).width() < 1020 + 20 ? $(window).width() - 20 : 1020);
     //$("#main .main-data-top").height($(window).height()-headerHeight-toolsbarHeight-bottomContentHeight-1);
     $("#billsSpread").height($(window).height()-headerHeight-toolsbarHeight-mainBottomContentHeight-1);
-    $("#project_glj_sheet").height($(window).height()-headerHeight-toolsbarHeight-gljBottomContentHeight-25);
+    $("#project_glj_sheet").height($(window).height()-headerHeight-toolsbarHeight-gljBottomContentHeight-50);
     $(".main-data-full").height($(window).height()-headerHeight-toolsbarHeight-1);
     $(".main-data-full-fl").height($(window).height()-headerHeight-toolsbarHeight-37);
     $(".main-data-full-feeRate").height($(window).height()-headerHeight-78);

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

@@ -1066,7 +1066,7 @@
                 <div class="modal-body">
                     <div class="custom-file">
                         <input type="file" class="custom-file-input" id="customFile" lang="zh" accept=".xls,.xlsx">
-                        <label class="custom-file-label" for="customFile">请选择上传文件</label>
+                        <label class="custom-file-label" for="customFile" style="white-space: nowrap; overflow: hidden;">请选择上传文件</label>
                     </div>
                     <div class="alert alert-success mt-3" id="uploadAlert" role="alert" style="display: none;">
                         广东XXXX项目清单.xlsx 准备导入上传

+ 32 - 4
web/building_saas/main/js/main.js

@@ -27,6 +27,8 @@ $(function () {
     });
 
     $('#tab_zaojiashu').on('shown.bs.tab', function (e) {
+        //设置sessionStorage,重载时用
+        sessionStorage.setItem('mainTab', '#tab_zaojiashu');
         $(e.relatedTarget.hash).removeClass('active');
         $("#subItems").addClass('active');
         $(gljOprObj.activeTab).addClass('active');
@@ -34,19 +36,23 @@ $(function () {
         projectObj.refreshMainSpread();
     });
 
+    $('#tab_report').on('shown.bs.tab', function(e){
+        sessionStorage.setItem('mainTab', '#tab_report');
+    });
+
     slideResize(mainResizeEles, {min: 170, max: 700}, 'height', function() {
         projectObj.mainSpread.refresh();
         refreshSubSpread();
     });
 
-    const projectId = scUrlUtil.GetQueryString('project');
+    /*const projectId = scUrlUtil.GetQueryString('project');
     // 绑定点击事件
     projectObj.mainSpread.bind(GC.Spread.Sheets.Events.CellClick, function(sender, info) {
         if (info.row !== undefined && projectId !== undefined) {
             setLocalCache('lastRow:' + projectId, info.row);
             setLocalCache('lastCol:' + projectId, info.col);
         }
-    });
+    });*/
 });
 
 /**
@@ -151,8 +157,9 @@ function loadSize(eles, type, callback) {
     let nearSize = getLocalCache(`near${type}:${tag}`);
     let farSize = getLocalCache(`far${type}:${tag}`);
     if (nearSize === null || farSize === null) {
-        eles.nearSpread[type](o_nearSize);
-        eles.farSpread[type](o_farSize);
+        setDefaultSize(tag,eles,type);//zhang 2018-05-21
+       /* eles.nearSpread[type](o_nearSize);
+        eles.farSpread[type](o_farSize);*/
     }else {
         nearSize = parseFloat(nearSize);
         farSize = parseFloat(farSize);
@@ -176,3 +183,24 @@ function getResizeWidthPercent(nearSize, farSize){
     let farPercent = (farSize / (resizeWidth + nearSize + farSize) * 100) + '%';
     return {nearPercent, farPercent};
 }
+
+function setDefaultSize(tag,eles,type) {
+    let o_nearSize = eles.nearSpread[type]();
+    let o_farSize = eles.farSpread[type]();
+    if(tag == "#main"){
+        eles.nearSpread[type](o_nearSize);  //工料机汇总和main页面处理方式不同
+        eles.farSpread[type](o_farSize);
+    }else if(tag == "#project-glj-main"){
+        o_nearSize = parseFloat(o_nearSize);
+        o_farSize = parseFloat(o_farSize);
+        eles.nearSpread[type](o_nearSize - o_farSize + 30);
+        eles.farSpread[type](o_farSize);
+    }
+}
+
+/*window.onunload=show;  页面唯一性可以用session storage 来做
+
+function show()
+{
+    return "exit"
+};*/

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

@@ -70,7 +70,7 @@ var cacheTree = {
                     children.splice(iIndex, children.length - iIndex);
                 }
             },
-            // ��nodes������addNodes, λ�ô�index��ʼ
+            // 在parent.children/tree.roots中增加nodes, 位置从index开始
             addNodes: function (tree, parent, nodes, iIndex) {
                 var children = parent ? parent.children : tree.roots;
                 var pre, next, i;

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

@@ -113,6 +113,7 @@ Composition.prototype.updateConsumptionInCache = function (pid,recode,updateData
         changValue = operationWithRound(parentGlj.quantity,changValue,"glj.quantity","*");
         let oldQuantity =  scMathUtil.roundForObj(mglj.quantity,decimal);
         mglj.quantity = scMathUtil.roundForObj(oldQuantity+changValue,decimal);
+        recode.consumption = newValue;
         projectObj.project.projectGLJ.quantityChangeMap[mglj.id] = mglj.quantity;
         let p_key = gljOprObj.getIndex(parentGlj,gljKeyArray);
         let m_list = projectObj.project.projectGLJ.datas.mixRatioMap[p_key];

+ 39 - 2
web/building_saas/main/js/models/main_consts.js

@@ -78,7 +78,8 @@ const compositionTypes = [
     gljType.MAIN_MATERIAL,
     gljType.CONCRETE,
     gljType.MORTAR,
-    gljType.MIX_RATIO
+    gljType.MIX_RATIO,
+    gljType.GENERAL_MACHINE
 ];
 
 const notEditType = [
@@ -214,7 +215,13 @@ const materialTypeMap = {
     GJ: 2,
     MC: 3,
     SN: 4,
-    SZ: 5
+    SZ: 5,
+    1:'GC',
+    2:'GJ',
+    3:'MC',
+    4:'SN',
+    5:'SZ'
+
 }
 
 //清单固定行
@@ -344,6 +351,36 @@ const blockType ={
     BX:5//补项
 };
 
+const filterType = {
+    ALL:'0',
+    LABOUR:'1',
+    GENERAL_MATERIAL:'2',
+    GENERAL_MACHINE:'3',
+    MAIN_MATERIAL:'4',
+    EQUIPMENT:'5',
+    FBFX:'6',
+    TECH:'7',
+    JGCL:'8',
+    ZGCL:'9',
+    SCHZ:'10',
+    ZYCL:'11'
+};
+const filterTypeArray = ['1','2','3','4','5'];
+/*
+<li><a href="javascript:void(0)">所有工料机</a></li>
+    <li class="mb-2 li_sub"><a href="javascript:void(0)" id="labor">人工</a></li>
+    <li class="mb-2 li_sub"><a href="javascript:void(0)">材料</a></li>
+    <li class="mb-2 li_sub"><a href="javascript:void(0)">机械</a></li>
+    <li class="mb-2 li_sub"><a href="javascript:void(0)">主材</a></li>
+    <li class="mb-2 li_sub"><a href="javascript:void(0)">设备</a></li>
+    <li class="mb-2"><a href="javascript:void(0)">分部分项工料机</a></li>
+    <li class="mb-2"><a href="javascript:void(0)">措施分项工料机</a></li>
+    <li class="mb-2"><a href="javascript:void(0)">甲供材料</a></li>
+    <li class="mb-2"><a href="javascript:void(0)">暂估材料</a></li>
+    <li class="mb-2"><a href="javascript:void(0)">三材汇总</a></li>
+    <li class="mb-2"><a href="javascript:void(0)">主要材料</a></li>
+*/
+
 const installFeeType = ['子目费用','分项费用','措施费用'];
 const installSectionBase = ['分别按人材机乘系数','人工','材料','机械'];
 const supplyComboMap = [{text:"自行采购",value:0},{text:"完全甲供",value:2},{text:"部分甲供",value:1},{text:"甲定乙供",value:3}];//后来调整了下拉选项的顺序,为了不改之前的业务逻辑,这里的值对换了一下

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

@@ -9,6 +9,7 @@ function ProjectGLJ() {
     this.datas = null;
     this.isLoading = false;
     this.quantityChangeMap=null;
+    this.getRatioId = null;
 }
 
 /**
@@ -381,6 +382,7 @@ ProjectGLJ.prototype.pGljUpdate= function (data,callback) {
 };
 
 ProjectGLJ.prototype.getRatioData=function(id,callback){
+    this.getRatioId = id;
     if(id){
         CommonAjax.specialPost( '/glj/get-ratio',{id: id, project_id: scUrlUtil.GetQueryString('project')},function (response) {
             let ratios = JSON.parse(response.data);

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

@@ -610,8 +610,8 @@ var ration_glj = {
                     type: glj.gljType,
                     adjCoe: glj.adjCoe,
                     createType: 'add',
-                    materialType:ration_glj.materialType,
-                    materialCoe:ration_glj.materialCoe,
+                    materialType:glj.materialType,
+                    materialCoe:glj.materialCoe,
                     repositoryId: glj.repositoryId
                 }
                 if (glj.hasOwnProperty("compilationId")) {

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

@@ -431,6 +431,7 @@ let calcProgramManage = {
 
 $(document).ready(function(){
     $('#tab_calc_program_manage').on('shown.bs.tab', function (e) {
+        sessionStorage.setItem('mainTab', '#tab_calc_program_manage');
         $(e.relatedTarget.hash).removeClass('active');
         calcProgramManage.buildSheet();
     });

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

@@ -337,7 +337,7 @@ let contentOprObj = {
                             "insert": {name: "插入", disabled: insertDis, icon: "fa-sign-in", callback: function (key, opt) {
                                 me.insertContent(sheet, sheet.getActiveRowIndex(), '');
                             }},
-                            "add": {name: "添加", disabled: addDis, icon: "context-menu-icon context-menu-icon-add", callback: function (key, opt) {
+                            "add": {name: "添加", disabled: addDis, icon: "fa-plus", callback: function (key, opt) {
                                 me.insertContent(sheet, me.currentCache.length, '');
                             }},
                             "delete": {name: "删除", disabled: delDis, icon: "fa-remove", callback: function (key, opt) {
@@ -827,7 +827,7 @@ let characterOprObj = {
                             "insert": {name: "插入", disabled: insertDis, icon: "fa-sign-in", callback: function (key, opt) {
                                 me.insertCharacter(sheet, sheet.getActiveRowIndex(), '');
                             }},
-                            "add": {name: "添加", disabled: addDis, icon: "context-menu-icon context-menu-icon-add", callback: function (key, opt) {
+                            "add": {name: "添加", disabled: addDis, icon: "fa-plus", callback: function (key, opt) {
                                 me.insertCharacter(sheet, me.currentCache.length, '');
                             }},
                             "delete": {name: "删除", disabled: delDis, icon: "fa-remove", callback: function (key, opt) {

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

@@ -790,6 +790,7 @@ $(function(){
     );
 
     $('#tab_fee_rate').on('shown.bs.tab', function (e) {
+        sessionStorage.setItem('mainTab', '#tab_fee_rate');
         let me = feeRateObject;
         $(e.relatedTarget.hash).removeClass('active');
         if(me.mainFeeRateSpread == null){

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

@@ -217,7 +217,6 @@ let installationFeeObj={
                 }
             }
         ]
-
     },
     positionData:null,
     positionSelectedObject:null,

+ 319 - 47
web/building_saas/main/js/views/project_glj_view.js

@@ -3,6 +3,8 @@
  */
 projectGljObject={
     showTag:'ration',//mixRatio/machine
+    showMixRatioMark:'',
+    displayType:filterType.ALL,
     mixRatioType: [gljType.CONCRETE, gljType.MORTAR, gljType.MIX_RATIO,gljType.MAIN_MATERIAL],
     machineType: [gljType.GENERAL_MACHINE],
     projectGljSetting:{
@@ -17,10 +19,11 @@ projectGljObject={
             {headerName: "调整价", headerWidth: 70, dataCode: "adjustPrice", hAlign: "right", dataType: "Number",decimalField:"glj.unitPrice"},
             {headerName: "市场价", headerWidth: 70, dataCode: "marketPrice", hAlign: "right", dataType: "Number",decimalField:"glj.unitPrice",validator:"number"},
             {headerName: "是否暂估", headerWidth: 60, dataCode: "is_evaluate", hAlign: "center", dataType: "String",cellType:'checkBox'},
+            {headerName: "主要材料", headerWidth: 60, dataCode: "is_main_material", hAlign: "center", dataType: "String",cellType:'checkBox'},
             {headerName: "供货方式", headerWidth: 80, dataCode: "supply", hAlign: "center", dataType: "String",cellType:'comboBox',editorValueType:true,options:supplyComboMap},
             {headerName: "甲供数量", headerWidth: 100, dataCode: "supply_quantity", hAlign: "right", dataType: "Number",validator:"number"},
             {headerName: "三材类别", headerWidth: 80, dataCode: "materialType", hAlign: "center", dataType: "String",cellType:'comboBox',editorValueType:true,options:materialComboMap},
-            {headerName: "三材系数", headerWidth: 100, dataCode: "materialCoe", hAlign: "right", dataType: "Number",decimalField:'material'},
+            {headerName: "三材系数", headerWidth: 100, dataCode: "materialCoe", hAlign: "right", dataType: "Number",decimalField:'material',validator:"number"},
             {headerName: "交货方式", headerWidth: 90, dataCode: "delivery", hAlign: "left", dataType: "String"},
             {headerName: "送达地点", headerWidth: 100, dataCode: "delivery_address", hAlign: "left", dataType: "String"},
             {headerName: "不调价", headerWidth: 55, dataCode: "is_adjust_price", dataType: "String",cellType: "checkBox"}
@@ -31,6 +34,7 @@ projectGljObject={
     },
     projectGljSpread:null,
     projectGljSheet:null,
+    materialTreeSheet:null,
     projectGljSheetData:[],
     mixRatioSetting:{
         header:[
@@ -41,19 +45,50 @@ projectGljObject={
             {headerName: "定额价", headerWidth: 120, dataCode: "basePrice", hAlign: "right", dataType: "Number",decimalField:'glj.unitPrice',validator:"number"},
             {headerName: "调整价", headerWidth: 120, dataCode: "adjustPrice", hAlign: "right", dataType: "Number",decimalField:"glj.unitPrice"},
             {headerName: "市场价", headerWidth: 120, dataCode: "marketPrice", hAlign: "right", dataType: "Number",decimalField:"glj.unitPrice",validator:"number"},
-            {headerName: "量", headerWidth: 120, dataCode: "consumption", hAlign: "right", dataType: "Number",decimalField:"glj.quantity",validator:"number"}
+            {headerName: "消耗量", headerWidth: 120, dataCode: "consumption", hAlign: "right", dataType: "Number",decimalField:"glj.quantity",validator:"number"}
         ],
         view: {
             lockColumns: [0,1,2,3,4,5,6]
         }
     },
+    materialTreeSetting:{
+        "emptyRows":0,
+        "headRows":1,
+        "headRowHeight":[21],
+        "defaultRowHeight": 21,
+        "treeCol": 0,
+        "cols":[]
+    },
+    materialSetting:{
+        header:[
+            {headerName: "编码", headerWidth: 200, dataCode: "code", dataType: "String"},
+            {headerName: "名称", headerWidth: 160, dataCode: "name", dataType: "String"},
+            {headerName: "规格型号", headerWidth: 120, dataCode: "specs", hAlign: "left", dataType: "String"},
+            {headerName: "单位", headerWidth: 45, dataCode: "unit", hAlign: "center", dataType: "String"},
+            {headerName: "定额价", headerWidth: 70, dataCode: "basePrice", hAlign: "right", dataType: "Number",decimalField:'glj.unitPrice',validator:"number"},
+            {headerName: "市场价", headerWidth: 70, dataCode: "marketPrice", hAlign: "right", dataType: "Number",decimalField:"glj.unitPrice",validator:"number"},
+            {headerName: "总消耗量", headerWidth: 100, dataCode: "quantity", hAlign: "right", dataType: "Number",decimalField:'glj.quantity'},
+            {headerName: "三材系数", headerWidth: 100, dataCode: "materialCoe", hAlign: "right", dataType: "Number",decimalField:'material',validator:"number"},
+            {headerName: "三材量", headerWidth: 100, dataCode: "materialQuantity", hAlign: "right", dataType: "Number",decimalField:'glj.quantity'},
+            {headerName: "三材类别", headerWidth: 80, dataCode: "materialType", hAlign: "center", dataType: "String",cellType:'comboBox',editorValueType:true,options:materialComboMap}
+        ],
+        view: {
+            lockColumns: [0,1,2,3,6,8]
+        }
+    },
     mixRatioSpread:null,
     mixRatioSheet:null,
     mixRatioData:[],
     usedTenderList:[],
     usedUnitPriceInfo:null,
     initProjectGljSpread:function () {
-        this.projectGljSpread = SheetDataHelper.createNewSpread($("#project_glj_sheet")[0]);
+        if(!this.projectGljSpread){
+            this.projectGljSpread = SheetDataHelper.createNewSpread($("#project_glj_sheet")[0],2);
+        }
+        this.initProjectGljSheet();
+        this.initMaterialTreeSheet();
+    },
+    initProjectGljSheet:function () {
         this.projectGljSheet = this.projectGljSpread .getSheet(0);
         this.initSheet(this.projectGljSheet,this.projectGljSetting);
         this.projectGljSheet.bind(GC.Spread.Sheets.Events.SelectionChanged,this.onProjectGljSelectionChange);
@@ -75,6 +110,69 @@ projectGljObject={
         this.initSheet(this.mixRatioSheet,this.mixRatioSetting);
         this.mixRatioSheet.name('mixRatioSheet');
     },
+    initMaterialTreeSheet:function () {
+        this.materialTreeSheet = this.projectGljSpread.getSheet(1);
+        this.materialTreeSetting = this.createMaterialTreeSheetSetting();
+        this.materialTree = cacheTree.createNew(this);
+        this.materialTreeController = TREE_SHEET_CONTROLLER.createNew(this.materialTree, this.materialTreeSheet, this.materialTreeSetting);
+        this.materialTreeController.bind(TREE_SHEET_CONTROLLER.eventName.treeSelectedChanged, this.onSelectionChange);
+        this.materialTreeSheet.bind(GC.Spread.Sheets.Events.EditStarting,this.onMaterialTreeEditStarting);
+        this.materialTreeSheet.name('materialTreeSheet');
+    },
+    createMaterialTreeSheetSetting:function () {
+        for(let h of this.materialSetting.header){
+            this.materialTreeSetting.cols.push(getSettingCol(h))
+        }
+        for(let l of this.materialSetting.view.lockColumns){
+            this.materialTreeSetting.cols[l].readOnly = true;
+        }
+        return this.materialTreeSetting;
+
+        function getSettingCol(header) {
+            let aMap ={left:0,center:1,right:2};
+            let hAlign = header.hAlign?aMap[header.hAlign]:0;
+            let col = {
+                "width":header.headerWidth?header.headerWidth:100,
+                "head":{
+                    "titleNames":[header.headerName],
+                    "spanCols":[1],
+                    "spanRows":[1],
+                    "vAlign":[1],
+                    "hAlign":[1],
+                    "font":["Arial"]
+                },
+                "data": {
+                    "field": header.dataCode,
+                    "vAlign": 1,
+                    "hAlign": hAlign,
+                    "font": "Arial"
+                }
+            };
+            if(header.cellType){
+                col.data.cellType = getCellType(header);
+            }
+            return col;
+        }
+
+        
+        function getCellType(header) {
+            return function () {
+                if(header.cellType === "checkBox"){
+                    return new GC.Spread.Sheets.CellTypes.CheckBox();
+                }
+                if(header.cellType === "comboBox"){
+                    let dynamicCombo = sheetCommonObj.getDynamicCombo(true);
+                    if(header.options){
+                        dynamicCombo.itemHeight(header.options.length).items(header.options);
+                        if(header.editorValueType==true){
+                            dynamicCombo.editorValueType(GC.Spread.Sheets.CellTypes.EditorValueType.value);
+                        }
+                    }
+                    return dynamicCombo
+                }
+            }
+        }
+    },
     unitPriceFileInit:function() {
         let me = this;
         let projectGLJ = projectObj.project.projectGLJ;
@@ -90,23 +188,29 @@ projectGljObject={
         return projectGljObject.usedTenderList.join("<br>");
     },
     showMixRatioData:function () {
-        let me = this,gljId = null;
-        let consumptionCol =  _.findIndex(me.mixRatioSetting.header, { 'dataCode': 'consumption'});
-        if(me.showTag == 'ration'){
-            return;
-        }else if(me.showTag == 'mixRatio'){
-            me.mixRatioSheet.setValue(0, consumptionCol, '用量', GC.Spread.Sheets.SheetArea.colHeader);
-        }else if(me.showTag == 'machine'){
-            me.mixRatioSheet.setValue(0, consumptionCol, '消耗量', GC.Spread.Sheets.SheetArea.colHeader);
+        let me = this,gljId = null,gljType = null;
+        let sheet = me.projectGljSpread.getActiveSheet();
+        if(sheet.name() == 'projectGljSheet'){//projectGljSheet/materialSheet 工料机汇总和三材汇总表
+            let sel = me.projectGljSheet.getSelections()[0];
+            let srow = sel.row == -1?0:sel.row;
+            if(me.projectGljSheetData.length>srow){
+                gljId = me.projectGljSheetData[srow].id;
+                gljType = me.projectGljSheetData[srow].type;
+            }
+        }else if(sheet.name() == 'materialTreeSheet' ){
+            if(this.materialTree.selected){
+                gljId = this.materialTree.selected.data.id;
+                gljType = this.materialTree.selected.data.type;
+            }
         }
-        let sel = me.projectGljSheet.getSelections()[0];
-        let srow = sel.row == -1?0:sel.row;
-        if(me.projectGljSheetData.length>srow){
-            gljId = me.projectGljSheetData[srow].id;
+        if(compositionTypes.indexOf(gljType)==-1){//如果不是有组成物的类型,工料机id设置为空,组成物表设置为空
+            gljId = null
         }
         projectObj.project.projectGLJ.getRatioData(gljId,function (data) {
+            if(gljId !== projectObj.project.projectGLJ.getRatioId){//两个id不一致说明不是最新的请求,不用往下执行。
+                return;
+            }
             let rationList =[];
-            console.log(data);
             for(let glj of data){
                 rationList.push(me.getMixRatioSheetData(glj)) ;
             }
@@ -132,7 +236,6 @@ projectGljObject={
         gljOprObj.setGLJPrice(data,glj);
         return data;
     },
-
     onProjectGljEditStarting:function (sender, args) {
         let me = projectGljObject;
         let row = args.row;
@@ -151,7 +254,7 @@ projectGljObject={
             return false;
         }
 
-        if(dataCode=='is_adjust_price'||dataCode=='is_evaluate'){
+        if(dataCode=='is_adjust_price'||dataCode=='is_evaluate'||dataCode=='is_main_material'){
             return false;
         }
         if(dataCode=='basePrice'||dataCode=='marketPrice'||dataCode=='supply'){//有组成物时,市场单价、定额价、供货方式不能修改
@@ -169,10 +272,26 @@ projectGljObject={
         }
         return true;
     },
+    onSelectionChange:function (){
+        let me = projectGljObject;
+        me.showMixRatioData();
+        me.materialTreeSheet.repaint();
+    },
+    onMaterialTreeEditStarting:function (sender, args) {
+        let me = projectGljObject;
+        let selected = me.materialTree.selected;
+        if(selected && (selected.data.ParentID == -1 || selected.data.id == 'GJ')){//三材类别项不能编辑
+            args.cancel = true;
+        }
 
+    },
     onProjectGljSelectionChange:function (sender, args) {
         let me = projectGljObject;
-        me.showMixRatioData();
+        let newSel = args.newSelections[0];
+        let oldSel = args.oldSelections?args.oldSelections[0]:{};
+        if(newSel.row != oldSel.row){
+            me.showMixRatioData();
+        }
         me.projectGljSheet.repaint();
     },
     onProjectGljRangeChange:function (sender,info) {
@@ -213,9 +332,8 @@ projectGljObject={
             me.projectGljSheet.setSelection(selected.row,selected.col,selected.rowCount,selected.colCount);
         });
     },
-
-
     showProjectGljData:function () {
+        this.projectGljSpread.setActiveSheetIndex(0);
         let sel = this.projectGljSheet.getSelections()[0];
         let projectGljSheetData = [];
         let gljList = projectObj.project.projectGLJ.datas.gljList;
@@ -228,27 +346,139 @@ projectGljObject={
         this.projectGljSheet.setRowCount(0);
         sheetCommonObj.showData(this.projectGljSheet, this.projectGljSetting,this.projectGljSheetData);
         this.projectGljSheet.setRowCount(this.projectGljSheetData.length);
-        this.projectGljSheet.setSelection(sel.row,sel.col,sel.rowCount,sel.colCount);
+        this.projectGljSheet.setSelection(sel.row==-1?0:sel.row,sel.col,sel.rowCount,sel.colCount);
+    },
+    showMaterialTreeData:function () {
+        this.projectGljSpread.setActiveSheetIndex(1);
+        let sel = this.materialTreeSheet.getSelections()[0];
+        let selNode = this.materialTree.selected;
+        let gljList = projectObj.project.projectGLJ.datas.gljList;
+        gljList = _.sortByAll(gljList, [ 'code']);
+        this.createMaterialTree(gljList);
+        this.materialTreeController.showTreeData();
+        this.materialTreeSheet.setSelection(sel.row==-1?0:sel.row,sel.col,sel.rowCount,sel.colCount);
+        this.materialTreeController.setTreeSelected(selNode);
+    },
+    createMaterialTree:function (gljList) {
+        let me = projectGljObject;
+        let q_decimal = getDecimal("glj.quantity");
+        let GC = {id:'GC',name:materialType[materialTypeMap.GC],code:'GC',unit:'t',ParentID:-1,NextSiblingID:'MC'};//000001
+        let GJ = {id:'GJ',name:materialType[materialTypeMap.GJ],code:'GJ',unit:'t',ParentID:'GC',NextSiblingID:-1};
+        let MC = {id:'MC',name:materialType[materialTypeMap.MC],code:'MC',unit:'t',ParentID:-1,NextSiblingID:'SN'};
+        let SN = {id:'SN',name:materialType[materialTypeMap.SN],code:'SN',unit:'m3',ParentID:-1,NextSiblingID:'SZ'};
+        let SZ = {id:'SZ',name:materialType[materialTypeMap.SZ],code:'BZZ',unit:'千块',ParentID:-1,NextSiblingID:-1};
+        let rootDatas= [GC,GJ,MC,SN,SZ];
+        let parentMap = {};
+        let sumMap = {};
+        this.materialTree.nodes={},this.materialTree.selected = null,this.materialTree.roots = [],this.materialTree.items=[];
+        for(let r of rootDatas){
+            let baseNode = null;
+            if(r.id == 'GJ'){
+                baseNode = createMaterialNode(r,parentMap['GC'],null);//钢筋的父节点为钢材
+            }else {
+                baseNode = createMaterialNode(r,null,null);
+            }
+            parentMap[r.id] = baseNode;
+        }
+        for(let g of gljList){
+            if(g.quantity !== 0 && g.quantity !== '0'){
+                if(g.materialType){
+                    let tem = me.getMaterialSheetDataByGLJ(g);
+                    if(tem.materialQuantity){
+                        sumMap[g.materialType] = sumMap[g.materialType]?sumMap[g.materialType] + tem.materialQuantity:tem.materialQuantity;
+                        tem.materialQuantity = scMathUtil.roundToString(tem.materialQuantity,q_decimal);//转成string
+                    }
+                    if(g.materialType == materialTypeMap.GC){ //钢材的下一节点是钢筋
+                        createMaterialNode(tem,parentMap['GC'],parentMap['GJ']);
+                    }else {
+                        createMaterialNode(tem,parentMap[materialTypeMap[g.materialType]]);
+                    }
+                }
+            }
+        }
+
+        for(let mkey in sumMap){
+            if(mkey == materialTypeMap.GC && sumMap[materialTypeMap.GJ]){//钢材汇总要加上钢筋的总量
+                parentMap['GC'].data.materialQuantity = scMathUtil.roundToString(sumMap[mkey]+sumMap[materialTypeMap.GJ],q_decimal);
+            }else {
+                parentMap[materialTypeMap[mkey]].data.materialQuantity = scMathUtil.roundToString(sumMap[mkey],q_decimal);
+            }
+        }
+
+        this.materialTree.sortTreeItems();
+
+        function createMaterialNode(data,parent,next) {
+            let newNode = me.materialTree.addNode(parent, next, data.id);
+            newNode.data = data;
+            return newNode;
+        }
+    },
+
+    getMaterialSheetDataByGLJ:function (glj) {
+        let q_decimal = getDecimal("glj.quantity");
+        let m_decimal = getDecimal("material");
+        let p_decimal = getDecimal("glj.unitPrice");
+        let projectGLJ = projectObj.project.projectGLJ;
+        let data ={
+            id:glj.id,
+            code:glj.code,
+            name:glj.name,
+            specs:glj.specs,
+            unit:glj.unit,
+            type:glj.type,
+            short_name:projectGLJ.getShortNameByID(glj.type),
+            quantity:scMathUtil.roundToString(glj.quantity,q_decimal),
+            supply:glj.supply,
+            supply_quantity:glj.supply_quantity,
+            materialType:glj.materialType,
+            delivery:glj.delivery,
+            delivery_address:glj.delivery_address,
+            is_adjust_price:glj.is_adjust_price,
+            ratio_data:glj.ratio_data,
+            is_add:glj.unit_price.is_add,
+            bgColour:'white'
+        };
+        if(glj.materialCoe){
+            data.materialCoe = scMathUtil.roundToString(glj.materialCoe,m_decimal);
+            data.materialQuantity = scMathUtil.roundForObj(glj.materialCoe * glj.quantity,q_decimal);//还要做汇总,汇总完再转成string
+        }
+        gljOprObj.setGLJPrice(data,glj);
+        data.basePrice = scMathUtil.roundToString(data.basePrice,p_decimal);
+        data.marketPrice = scMathUtil.roundToString(data.marketPrice,p_decimal);
+
+        return data;
     },
     filterProjectGLJ:function (gljList) {
         let me = projectGljObject;
         if(gljList.length>0){
             gljList = _.filter(gljList,function (item) {
-                if(item.quantity !== 0 && item.quantity !== '0'){//过滤掉消耗量为0的工料机
-                    //showTag:'ration',//mixRatio/machine
-                    if(me.showTag == 'ration'){
-                        return true;
-                    }else if(me.showTag == 'mixRatio'){
-                        return _.includes(me.mixRatioType,item.type)
-                    }else if(me.showTag == 'machine'){
-                        return _.includes(me.machineType,item.type)
-                    }
-                }
-                return false;
+                return me.displayTypeFilter(item);
             });
         }
         return gljList;
     },
+    displayTypeFilter:function (item) {
+        let me = this;
+        if(item.quantity !== 0 && item.quantity !== '0'){//过滤掉消耗量为0的工料机
+            if(me.displayType == filterType.ALL){//所有工料机
+                return true;
+            }else if(filterTypeArray.indexOf(me.displayType) != -1){//人工、材料、机械、主材、设备
+                let typeString = item.type+"";
+                return typeString.startsWith(me.displayType);
+            }else if(me.displayType == filterType.FBFX){//“分部分项总消耗量”≠0的工料机行
+                return item.subdivisionQuantity !== 0 && item.subdivisionQuantity !== '0';
+            }else if(me.displayType == filterType.TECH){//筛选“措施项目总消耗量”≠0的工料机行
+                return item.techQuantity !== 0 && item.techQuantity !== '0';
+            }else if(me.displayType == filterType.JGCL){//筛选“供货方式”=“完全甲供”或“部分甲供”的工料机行
+                return item.supply == supplyType.WQJG || item.supply == supplyType.BFJG;
+            }else if(me.displayType == filterType.ZGCL){//筛选“是否暂估”=“是”的工料机行。
+                return item.is_evaluate == 1;
+            }else if(me.displayType == filterType.ZYCL){//筛选“主要材料”=“是”的工料机行。
+                return item.is_main_material == 1;
+            }
+        }
+        return false;
+    },
     getSheetDataByGLJ:function (glj) {
         let projectGLJ = projectObj.project.projectGLJ;
         let materialIdList = projectGLJ.datas.constData.materialIdList;
@@ -274,6 +504,10 @@ projectGljObject={
         };
         gljOprObj.setGLJPrice(data,glj);
 
+
+        data.is_main_material = glj.is_main_material == 1?1:0;
+
+
         //供货方式为完全甲供时设置甲供数量为总消耗量
         if (data.supply == 2) {
             data.supply_quantity = glj.quantity;
@@ -298,10 +532,21 @@ projectGljObject={
         let me = projectGljObject;
         let rowData = me.projectGljSheetData[row];
         let glj = projectObj.project.projectGLJ.getByID(rowData.id);
+        let newRow = null;
         if(glj){
-            me.projectGljSheetData[row] = me.getSheetDataByGLJ(glj);
+            newRow = me.getSheetDataByGLJ(glj);
+        }
+        if(me.displayTypeFilter(newRow) == true){
+            me.projectGljSheetData[row] = newRow;
+            sheetCommonObj.showRowData(this.projectGljSheet, this.projectGljSetting,row,this.projectGljSheetData);
+        }else {
+            me.projectGljSheetData.splice(row,1);
+            me.projectGljSheet.deleteRows(row,1);
+            me.showMixRatioData();
         }
-        sheetCommonObj.showRowData(this.projectGljSheet, this.projectGljSetting,row,this.projectGljSheetData);
+        //me.projectGljSheetData[row] = me.getSheetDataByGLJ(glj);
+
+
     },
     initSheet: function (sheet,setting) {
         var me = this;
@@ -312,7 +557,7 @@ projectGljObject={
         let me = projectGljObject;
         if(info.sheetName=='projectGljSheet'){
             me.onProjectGLJValueChange(e,info);
-        }if(info.sheetName == 'mixRatioSheet'){
+        }else if(info.sheetName == 'mixRatioSheet'){
             me.onMixRatioValueChange(e,info);
         }
     },
@@ -333,7 +578,8 @@ projectGljObject={
         let prow= projectGljObject.projectGljSheet.getActiveRowIndex();//取父机械或组成物的下标
         let prowData = projectGljObject.projectGljSheetData[prow];
         composition.updateConsumption(updateData,recode,prowData.id,function (sid) {
-           me.refreshParentData(prow,prowData.id,sid);
+            me.refreshProjectGljRowByID(sid);
+            me.refreshParentData(prow,prowData.id,sid);
         });
     },
     refreshParentData:function (row,pid,sid) {
@@ -370,7 +616,6 @@ projectGljObject={
         }
         gljOprObj.refreshView();
     },
-
     deleteMixRatio:function (row) {
         let me = this, deleteRecode = me.mixRatioData[row];
         let consumption = deleteRecode.consumption;
@@ -409,8 +654,13 @@ projectGljObject={
         let dataCode = me.projectGljSetting.header[col].dataCode;
         let recode = me.projectGljSheetData[row];
         let value = info.newValue;
+        if(info.newValue == undefined ){
+            return;
+        }
         if (!me.checkData(col,me.projectGljSetting,value)) {
-            alert('输入的数据类型不对,请重新输入!');
+            setTimeout(function () {//为了不与click事件冲突
+                alert('输入的数据类型不对,请重新输入!');
+            },200);
             me.refreshProjectGljRow(row);
             return ;
         }
@@ -419,10 +669,7 @@ projectGljObject={
             info.sheet.suspendEvent();
             me.refreshProjectGljRow(row);
             for(let g of impactList){
-                let index = _.findIndex(me.projectGljSheetData, { 'id': g.id });
-                if(index>=0&&index != row){
-                    me.refreshProjectGljRow(index);
-                }
+                me.refreshProjectGljRowByID(g.id,row);
             }
             info.sheet.resumeEvent();
             info.sheet.resumePaint();
@@ -447,7 +694,7 @@ projectGljObject={
             if(dataCode === 'supply_quantity'){//修改数量需做4舍5入
                 value= value.toDecimal(getDecimal('glj.quantity'));
             }
-            if(dataCode === 'is_evaluate'||dataCode === 'is_adjust_price'){
+            if(dataCode === 'is_evaluate'||dataCode === 'is_adjust_price'||dataCode === 'is_main_material'){
                 if(value == true){
                     value = 1;
                 }else if(value == false){
@@ -459,6 +706,13 @@ projectGljObject={
             projectGLJ.pGljUpdate(updateData,callback);
         };
     },
+    refreshProjectGljRowByID:function (ID,row) {//row 可以不传,如果row 和 index 相等就不刷新
+        let me = this;
+        let index = _.findIndex(me.projectGljSheetData, { 'id': ID});
+        if(index>=0&&index != row){
+            me.refreshProjectGljRow(index);
+        }
+    },
     getSupplyQuantity : function(supplyType, quantity) {
         // 自行采购和甲定乙供则把甲供数量设置为0,其余情况则设置为当前总消耗量
         let supplyQuantity = supplyType == 0 || supplyType == 3 ? 0 : quantity;
@@ -551,6 +805,7 @@ $(function () {
         projectGljObject.mixRatioSpread?projectGljObject.mixRatioSpread.refresh():'';
     });
     $('#tab_project_glj').on('shown.bs.tab', function (e) {
+        sessionStorage.setItem('mainTab', '#tab_project_glj');
         let me = projectGljObject;
         $(e.relatedTarget.hash).removeClass('active');
         if(me.projectGljSpread==null){
@@ -558,13 +813,18 @@ $(function () {
         }
         me.unitPriceFileInit();
         //projectObj.project.projectGLJ.calcQuantity(); 在工程量有更新的地方调用
-        me.showProjectGljData();
+        if(me.displayType == filterType.SCHZ){//三材汇总树节点
+            me.showMaterialTreeData();
+        }else {
+            me.showProjectGljData();
+        }
+        me.initMixRatio();
         loadSize(pojGljResizeEles, 'height', function () {
             me.projectGljSpread.refresh();
             me.mixRatioSpread?me.mixRatioSpread.refresh():'';
         });
     });
-    $('#ration_link').on('shown.bs.tab', function (e) {
+  /*  $('#ration_link').on('shown.bs.tab', function (e) {
         let me = projectGljObject;
         me.showTag='ration';
         me.showProjectGljData();
@@ -580,7 +840,7 @@ $(function () {
         me.showTag='machine';
         me.showProjectGljData();
         me.initMixRatio();
-    });
+    });*/
     $('#pop-used-list').popover({
             placement: "bottom",
             html: true,
@@ -696,6 +956,18 @@ $(function () {
             $("#unitFile-save-as").modal("hide");
         });
     });
+
+    $("#filterType").on("click","ul li a",function(){
+        let me = projectGljObject;
+        me.displayType = filterType[this.id];
+        if(me.displayType == filterType.SCHZ){//三材汇总树节点
+            me.showMaterialTreeData();
+        }else {
+            me.showProjectGljData();
+            me.showMixRatioData();
+        }
+    });
+
 });
 
 

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

@@ -9,6 +9,7 @@ let defaultDecimal = {
         bills: {editable: true, data: {unitPrice: 2, totalPrice: 2}},
         ration: {editable: true, data: {quantity: 3, unitPrice: 2, totalPrice: 2}},
         glj: {editable: true, data: {quantity: 3, unitPrice: 2}},
+        material: {editable: false, data: 5},
         feeRate: {editable: true, data: 2},
         quantity_detail: {editable: false, data: 4},
         process: {editable: false, data: 6}

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

@@ -25,7 +25,7 @@ let projFeatureView = {
             {row: 3, key: 'baseType', items: ['带基', '框排架柱距6m以内', '框排架柱距6m以外', '满基筏式', '满基板式', '满基箱式', '独立基础']},
             {row: 4, key: 'buildingFeature', items: ['点式', '凹式', '凸式', 'Y式', '其他']}
         ],
-        numRows: [5, 6, 7, 8, 9, 10, 11, 12, 13],
+        numRows: [5, 6, 7, 8, 9, 10, 11, 12, 13, 14],
         dateRows: [],
         locked: {
             rows: [0],
@@ -136,7 +136,8 @@ let projFeatureView = {
             if(me.setting.numRows.indexOf(args.row) !== -1){//控制数值
                 if(!me.isNum(v)){
                     alert('只能输入数值');
-                    args.sheet.setValue(args.row, args.col, me.datas[args.row].value && me.isNum(me.datas[args.row].value) ? me.datas[args.row].value : '');
+                    v = me.datas[args.row].value && me.isNum(me.datas[args.row].value) ? me.datas[args.row].value : '';
+                    args.sheet.setValue(args.row, args.col, v);
                 }
             }
             me.datas[args.row].value = v;

+ 51 - 9
web/building_saas/main/js/views/project_view.js

@@ -483,6 +483,7 @@ var projectObj = {
     },
     //repaint 动态下拉框
     mainSpreadEnterCell: function (sender, info) {
+        console.log('enterCell');
         let colSetting = projectObj.mainController.setting.cols[info.col];
         if(colSetting.data.field === 'unit' || (projectObj.lastCol&&projectObj.lastCol.data.field === 'unit')||colSetting.data.field ==='subType'
             || (projectObj.lastCol&&projectObj.lastCol.data.field === 'subType') || colSetting.data.field === 'programID' ||(projectObj.lastCol&&projectObj.lastCol.data.field === 'programID')){
@@ -681,6 +682,9 @@ var projectObj = {
                 installationFeeObj.engineeringTypeChecking();//检查是否安装工程
                 autoFlashHeight();
                 projectObj.refreshMainSpread();
+                //定位到会话中的选项
+                let mainTabFocus = sessionStorage.getItem('mainTab') ? sessionStorage.getItem('mainTab') : '#tab_zaojiashu';
+                $(`${mainTabFocus}`).click();
                 $.bootstrapLoading.end();
             }
             else {
@@ -1573,13 +1577,37 @@ $('#property_ok').click(function () {
             mixDatas.labourCoes.updateData || mixDatas.rations.length > 0 || mixDatas.bills.length > 0;
     }
 
+    function needToReload(mixDatas){
+        if(Object.keys(mixDatas.labourCoes).length > 0){
+            return true;
+        }
+        if(Object.keys(mixDatas.properties).length > 0){
+            if(mixDatas.properties.hasOwnProperty('property.billsCalcMode') ||
+                mixDatas.properties.hasOwnProperty('property.zanguCalcMode') ||
+                mixDatas.properties.hasOwnProperty('property.calcOptions')||
+                mixDatas.properties.hasOwnProperty('property.billsQuantityDecimal')||
+                mixDatas.properties.hasOwnProperty('property.decimal')||
+                mixDatas.properties.hasOwnProperty('property.displaySetting')){
+                return true;
+            }
+        }
+        return false;
+    }
+
     if(hasMixData()){
         CommonAjax.post('/pm/api/updateMixDatas', {user_id: userID, mixDataArr: mixDatas}, function (rstData) {
-/*            if (changedNodes.length > 0) {
-                for (let node of changedNodes){delete node.changed};
-            };
-            if (mixDatas.labourCoes.updateData) labourCoeView.refresh();*/
-            window.location.href = '/main?project=' + projectID;
+            //需要重载页面
+            if(needToReload(mixDatas)){
+                window.location.href = '/main?project=' + projectID;
+            }
+            else{
+                if(mixDatas.properties.hasOwnProperty('property.basicInformation')){
+                    basicInfoView.orgDatas = basicInfoView.toViewDatas(mixDatas.properties['property.basicInformation']);
+                }
+                if(mixDatas.properties.hasOwnProperty('property.projectFeature')){
+                    projFeatureView.orgDatas = projFeatureView.toViewDatas(mixDatas.properties['property.projectFeature']);
+                }
+            }
         });
     }
 });
@@ -1752,11 +1780,11 @@ function ifCanDelete() {
 $('#customFile').change(function () {
     let file = $(this)[0];
     if(file.files.length > 0){
-        $('#uploadAlert').text(`${file.files[0].name} 准备导入上传`);
-        $('#uploadAlert').show();
+        $('.custom-file-label').text(`${file.files[0].name} 准备导入上传`);
+        $('#uploadAlert').hide();
     }
     else{
-        $('#uploadAlert').hide();
+        $('.custom-file-label').text(`请选择上传文件`);
     }
 });
 //从excel导入清单
@@ -1813,10 +1841,23 @@ $('#uploadConfirm').click(function () {
         });
     }
     catch (err){
-        alert(err);
+        //alert(err);
+        showUploadAlert(false, err);
         $(me).removeClass('disabled');
     }
 });
+function showUploadAlert(success, msg){
+    if(!success){
+        $('#uploadAlert').removeClass('alert-success');
+        $('#uploadAlert').addClass('alert-danger');
+    }
+    else{
+        $('#uploadAlert').removeClass('alert-danger');
+        $('#uploadAlert').addClass('alert-success');
+    }
+    $('#uploadAlert').text(msg);
+    $('#uploadAlert').show();
+}
 //导入后更新操作
 function doAfterImport(resData){
     if(resData){
@@ -1907,6 +1948,7 @@ $(function () {
     $('#import').on('show.bs.modal', function(){
         $('#customFile').val('');
         $('#uploadAlert').hide();
+        $('.custom-file-label').text(`请选择上传文件`);
     });
 
     $("#billsSpread").mouseover(function(){

+ 36 - 14
web/building_saas/main/js/views/std_bills_lib.js

@@ -4,6 +4,7 @@
  */
 
 var billsLibObj = {
+    stdBillsTree: null,
     stdBillsSpread: null,
     stdBillsJobSpread: null,
     stdBillsFeatureSpread: null,
@@ -13,6 +14,7 @@ var billsLibObj = {
     checkBillsSpread: function () {
         if (!this.stdBillsSpread) {
             this.stdBillsSpread = SheetDataHelper.createNewSpread($('#stdBillsSpread')[0]);
+            this.stdBillsSpread.getSheet(0).name('stdBillsLib_bills');
             // 刷新setting中记录的spread的位置
             this.refreshSettingForHint();
         }
@@ -64,8 +66,12 @@ var billsLibObj = {
         select.empty();
 
         let bills_lib = projectInfoObj.projectInfo.engineeringInfo.bill_lib;
+        let selectedBillsLib = sessionStorage.getItem('stdBillsLib');
         bills_lib.forEach(function (data) {
             var option = $('<option>').val(data.id).text(data.name);
+            if(selectedBillsLib && data.id == selectedBillsLib){
+                option.attr('selected', 'selected');
+            }
             select.append(option);
         });
         if (select.children.length !== 0) {
@@ -75,8 +81,11 @@ var billsLibObj = {
     loadStdBills: function (stdBillsLibID) {
         var that = this;
         var stdBillsJobData, stdBillsFeatureData, stdBills;
-        var stdBillsTree  = idTree.createNew({id: 'ID', pid: 'ParentID', nid: 'NextSiblingID', rootId: -1, autoUpdate: true});
-        var stdBillsTreeController = TREE_SHEET_CONTROLLER.createNew(stdBillsTree, billsLibObj.stdBillsSpread.getActiveSheet(), billsLibObj.stdBillsTreeSetting);
+        if(that.stdBillsTree){
+            that.stdBillsTree = null;
+        }
+        that.stdBillsTree  = idTree.createNew({id: 'ID', pid: 'ParentID', nid: 'NextSiblingID', rootId: -1, autoUpdate: true});
+        var stdBillsTreeController = TREE_SHEET_CONTROLLER.createNew(that.stdBillsTree, billsLibObj.stdBillsSpread.getActiveSheet(), billsLibObj.stdBillsTreeSetting);
         var findData = function (value, field, Array) {
             var i = 0;
             for (i = 0; i < Array.length; i++) {
@@ -164,25 +173,31 @@ var billsLibObj = {
         });
         CommonAjax.post('/stdBillsEditor/getBills', {userId: userID, billsLibId: stdBillsLibID}, function (datas) {
             stdBills = datas;
-            stdBillsTree.loadDatas(stdBills);
+            that.stdBillsTree.loadDatas(stdBills);
+            //读取展开收起状态
+            let currentExpState = sessionStorage.getItem('stdBillsLibExpState');
+            if(currentExpState){
+                that.stdBillsTree.setExpandedByState(that.stdBillsTree.items, currentExpState);
+            }
             //非叶子节点默认收起
-            stdBillsTree.setRootExpanded(stdBillsTree.roots, false);
-
+            else{
+                that.stdBillsTree.setRootExpanded(that.stdBillsTree.roots, false);
+            }
             stdBillsTreeController.showTreeData();
             billsLibObj.setTagForHint(datas);
-            showBillsRela(stdBillsTree.firstNode());
+            showBillsRela(that.stdBillsTree.firstNode());
 
             stdBillsTreeController.bind(TREE_SHEET_CONTROLLER.eventName.treeSelectedChanged, showBillsRela);
             that.stdBillsSpread.unbind(GC.Spread.Sheets.Events.CellDoubleClick);
             that.stdBillsSpread.bind(GC.Spread.Sheets.Events.CellDoubleClick, function (sender, args) {
-                let selectNode = stdBillsTree.items[args.row];
+                let selectNode = that.stdBillsTree.items[args.row];
                 let name = selectNode.data.name;
-                if (stdBillsTree.items[args.row].children.length === 0) {
+                if (that.stdBillsTree.items[args.row].children.length === 0) {
                     if(projectInfoObj.projectInfo.property.lockBills == true){
                         return;
                     }
                     //特征及内容转化
-                    pageCCOprObj.setItemContentNode(stdBillsTree.items[args.row], getBillsJobs(stdBillsTree.items[args.row]), getBillsFeatures(stdBillsTree.items[args.row]), name);
+                    pageCCOprObj.setItemContentNode(that.stdBillsTree.items[args.row], getBillsJobs(that.stdBillsTree.items[args.row]), getBillsFeatures(that.stdBillsTree.items[args.row]), name);
                     if (/\//.test(selectNode.data.unit)) {
                         let existB = projectObj.project.Bills.sameStdCodeBillsData(selectNode.data.code);
                         if (existB) {
@@ -200,14 +215,16 @@ var billsLibObj = {
                 }
                 else{
                     let me = billsLibObj;
-                    let node = stdBillsTree.items[args.row];
+                    let node = that.stdBillsTree.items[args.row];
                     if (!node || node.children.length === 0)
                         return;
                     node.setExpanded(!node.expanded);
+                    //设置展开收起状态
+                    sessionStorage.setItem('stdBillsLibExpState', that.stdBillsTree.getExpState(that.stdBillsTree.items));
                     TREE_SHEET_HELPER.massOperationSheet(args.sheet, function () {
                         let iCount = node.posterityCount(), i, child;
                         for (i = 0; i < iCount; i++) {
-                            child = stdBillsTree.items[args.row + i + 1];
+                            child = that.stdBillsTree.items[args.row + i + 1];
                             args.sheet.setRowVisible(args.row + i + 1, child.visible, args.sheetArea);
                         }
                         args.sheet.invalidateLayout();
@@ -224,7 +241,7 @@ var billsLibObj = {
 
             if (!keyword || keyword === '') {return}
 
-            var result = stdBillsTree.items.filter(function (item) {
+            var result = that.stdBillsTree.items.filter(function (item) {
                 var codeIs = item.data.code ? item.data.code.indexOf(keyword) !== -1 : false;
                 var nameIs = item.data.name ? item.data.name.indexOf(keyword) !== -1 : false;
                 return codeIs || nameIs;
@@ -243,7 +260,7 @@ var billsLibObj = {
 
                 $('#nextStdBills').show();
                 $('#nextStdBills').click(function () {
-                    var cur = stdBillsTree.selected, resultIndex = result.indexOf(cur), sel = billsLibObj.stdBillsSpread.getActiveSheet().getSelections();
+                    var cur = that.stdBillsTree.selected, resultIndex = result.indexOf(cur), sel = billsLibObj.stdBillsSpread.getActiveSheet().getSelections();
                     if (resultIndex === result.length - 1) {
                         stdBillsTreeController.setTreeSelected(result[0]);
                         billsLibObj.stdBillsSpread.getActiveSheet().setSelection(result[0].serialNo(), sel[0].col, 1, 1);
@@ -423,7 +440,12 @@ $('#stdBillsLibSelect').change(function () {
 
     var select = $(this);
     if (this.children.length !== 0) {
-        billsLibObj.loadStdBills(select.val());
+        //设置sessionStorage
+        let billsLibId  = select.val();
+        sessionStorage.setItem('stdBillsLib', billsLibId);
+        //清除展开收起状态sessionStorage
+        sessionStorage.removeItem('stdBillsLibExpState');
+        billsLibObj.loadStdBills(billsLibId);
     }
 });
 

+ 22 - 4
web/building_saas/main/js/views/std_ration_lib.js

@@ -14,6 +14,7 @@ var rationLibObj = {
     checkSpread: function () {
         if (!this.rationChapterSpread) {
             this.rationChapterSpread = SheetDataHelper.createNewSpread($('#stdRationChapter')[0]);
+            this.rationChapterSpread.getSheet(0).name('stdRationLib_chapter');
             this.rationChapterSpread.bind(GC.Spread.Sheets.Events.CellDoubleClick, this.onChapterSpreadCellDoubleClick);
         }
         if (!this.sectionRationsSpread) {
@@ -36,8 +37,14 @@ var rationLibObj = {
         select.empty();
 
         let ration_lib = projectInfoObj.projectInfo.engineeringInfo.ration_lib;
+        let selectedRationLib = sessionStorage.getItem('stdRationLib');
         ration_lib.forEach(function (data) {
-            select.append($('<option>').val(data.id).text(data.name));
+            let option = $('<option>').val(data.id).text(data.name);
+            //select.append($('<option>').val(data.id).text(data.name));
+            if(selectedRationLib && data.id == selectedRationLib){
+                option.attr('selected', 'selected');
+            }
+            select.append(option);
         });
         if (select[0].options.length !== 0) {
             rationLibObj.loadStdRation(select.val());
@@ -50,8 +57,15 @@ var rationLibObj = {
             that.tree = rationChapterTree;
             var rationChapterTreeController = TREE_SHEET_CONTROLLER.createNew(rationChapterTree, that.rationChapterSpread.getActiveSheet(), that.rationChapterTreeSetting);
             rationChapterTree.loadDatas(datas);
-            //非叶子节点默认收起
-            that.tree.setRootExpanded(that.tree.roots, false);
+            //读取展开收起状态
+            let currentExpState = sessionStorage.getItem('stdRationLibExpState');
+            if(currentExpState){
+                that.tree.setExpandedByState(that.tree.items, currentExpState);
+            }
+            else {
+                //非叶子节点默认收起
+                that.tree.setRootExpanded(that.tree.roots, false);
+            }
             rationChapterTreeController.showTreeData();
 
             rationChapterTreeController.bind(TREE_SHEET_CONTROLLER.eventName.treeSelectedChanged, function (node) {
@@ -78,6 +92,7 @@ var rationLibObj = {
         if (!node || node.children.length === 0)
             return;
         node.setExpanded(!node.expanded);
+        sessionStorage.setItem('stdRationLibExpState', me.tree.getExpState(me.tree.items));
         TREE_SHEET_HELPER.massOperationSheet(args.sheet, function () {
             let iCount = node.posterityCount(), i, child;
             for (i = 0; i < iCount; i++) {
@@ -309,7 +324,10 @@ $('#stdRationTab').bind('click', function () {
 $('#stdRationLibSelect').change(function () {
     var select = $(this);
     if (this.children.length !== 0) {
-        rationLibObj.loadStdRation(select.val());
+        let rationLibId = select.val();
+        sessionStorage.setItem('stdRationLib', rationLibId);
+        sessionStorage.removeItem('stdRationLibExpState');
+        rationLibObj.loadStdRation(rationLibId);
     }
 });
 $('#rationSearch').click(function () {