소스 검색

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

TonyKang 7 년 전
부모
커밋
fd3718d9b3

+ 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]) {

+ 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++) {

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

@@ -149,10 +149,9 @@ body {
 .bottom-tools {
     height: 30px;
     line-height: 30px;
-    background:#fff;
-    bottom:22px;
-    left:22px;
-    z-index: 999
+    background:#F1F1F1;
+    bottom:28px;
+    left:0px;
 }
 .side-tabs .nav-tabs .nav-item {
     z-index: 999

+ 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 准备导入上传

+ 16 - 3
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);
         }
-    });
+    });*/
 });
 
 /**
@@ -190,4 +196,11 @@ function setDefaultSize(tag,eles,type) {
         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;

+ 7 - 5
web/building_saas/main/js/models/calc_program.js

@@ -251,12 +251,12 @@ let calcTools = {
                     if (md.type == gljType.MACHINE_LABOUR) {
                         let q = md["consumption"] ? md["consumption"] : 0;
                         let p = md["basePrice"] ? md["basePrice"] : 0;
-                        mdSum = mdSum + (q * p).toDecimal(decimalObj.ration.unitFee);
-                        mdSum = (mdSum).toDecimal(decimalObj.ration.unitFee);
+                        mdSum = mdSum + (q * p).toDecimal(decimalObj.ration.unitPrice);
+                        mdSum = (mdSum).toDecimal(decimalObj.ration.unitPrice);
                     }
                 }
-                result = result + (glj["quantity"] * mdSum).toDecimal(decimalObj.ration.unitFee);
-                result = (result).toDecimal(decimalObj.ration.unitFee);
+                result = result + (glj["quantity"] * mdSum).toDecimal(decimalObj.ration.unitPrice);
+                result = (result).toDecimal(decimalObj.ration.unitPrice);
             }
         }
         return result;
@@ -1540,7 +1540,9 @@ class CalcProgram {
                 for (let idx of template.compiledSeq) {
                     let calcItem = template.calcItems[idx];
                     $CE.tempCalcItem = calcItem;
-                    let feeRate = parseFloatPlus(calcItem.feeRate) ? parseFloatPlus(calcItem.feeRate).toDecimal(decimalObj.feeRate) : 100;  // 100%
+                    let feeRate = 100;  // 100%
+                    if (calcItem.feeRate != undefined)
+                        feeRate = parseFloat(calcItem.feeRate).toDecimal(decimalObj.feeRate);
                     // console.log(`[${calcItem.ID}]: ${calcItem.compiledExpr}`);   // for test.
                     calcItem.unitFee = (eval(calcItem.compiledExpr) * feeRate * 0.01).toDecimal(decimalObj.decimal('unitPrice', treeNode));   // 如果eval()对清单树有影响,就换成小麦的Expression对象再试
 

+ 7 - 1
web/building_saas/main/js/models/main_consts.js

@@ -215,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'
+
 }
 
 //清单固定行

+ 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);

+ 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){

+ 242 - 51
web/building_saas/main/js/views/project_glj_view.js

@@ -3,6 +3,7 @@
  */
 projectGljObject={
     showTag:'ration',//mixRatio/machine
+    showMixRatioMark:'',
     displayType:filterType.ALL,
     mixRatioType: [gljType.CONCRETE, gljType.MORTAR, gljType.MIX_RATIO,gljType.MAIN_MATERIAL],
     machineType: [gljType.GENERAL_MACHINE],
@@ -22,7 +23,7 @@ projectGljObject={
             {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"}
@@ -33,6 +34,7 @@ projectGljObject={
     },
     projectGljSpread:null,
     projectGljSheet:null,
+    materialTreeSheet:null,
     projectGljSheetData:[],
     mixRatioSetting:{
         header:[
@@ -55,34 +57,24 @@ projectGljObject={
         "headRowHeight":[21],
         "defaultRowHeight": 21,
         "treeCol": 0,
-        "cols":[//left:0,center:1,right:2
-           /* {
-                "width":100,
-                "readOnly": true,
-                "head":{
-                    "titleNames":["具体位置"],
-                    "spanCols":[1],
-                    "spanRows":[1],
-                    "vAlign":[1],
-                    "hAlign":[1],
-                    "font":["Arial"]
-                },
-                "data":{
-                    "field":"selected",
-                    "vAlign":1,
-                    "hAlign":1,
-                    "font":"Arial",
-                    "cellType":function (node) {
-                        if(node.data.canSelect == true){
-                            return new GC.Spread.Sheets.CellTypes.CheckBox();
-                        }
-                    }
-                }
-            }*/
-        ]
+        "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,
@@ -90,7 +82,13 @@ projectGljObject={
     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);
@@ -112,9 +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;
@@ -129,25 +187,29 @@ projectGljObject={
     getUsedTenderInfo:function() {
         return projectGljObject.usedTenderList.join("<br>");
     },
-    showMixRatioData:function (from = 'projectGljSheet') { //projectGljSheet/materialSheet 工料机汇总和三材汇总表
+    showMixRatioData:function () {
         let me = this,gljId = null,gljType = null;
-        /*let consumptionCol =  _.findIndex(me.mixRatioSetting.header, { 'dataCode': 'consumption'});
-        if(me.showTag == 'ration'){
-            return;
-        }*/
-        if(from == 'projectGljSheet'){
+        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;
+            }
         }
         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 =[];
             for(let glj of data){
                 rationList.push(me.getMixRatioSheetData(glj)) ;
@@ -192,7 +254,7 @@ projectGljObject={
             return false;
         }
 
-        if(dataCode=='is_adjust_price'||dataCode=='is_evaluate'||dataCode=='glj.is_main_material'){
+        if(dataCode=='is_adjust_price'||dataCode=='is_evaluate'||dataCode=='is_main_material'){
             return false;
         }
         if(dataCode=='basePrice'||dataCode=='marketPrice'||dataCode=='supply'){//有组成物时,市场单价、定额价、供货方式不能修改
@@ -210,9 +272,26 @@ projectGljObject={
         }
         return true;
     },
-    onProjectGljSelectionChange:function (sender, args) {
+    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;
+        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) {
@@ -254,6 +333,7 @@ projectGljObject={
         });
     },
     showProjectGljData:function () {
+        this.projectGljSpread.setActiveSheetIndex(0);
         let sel = this.projectGljSheet.getSelections()[0];
         let projectGljSheetData = [];
         let gljList = projectObj.project.projectGLJ.datas.gljList;
@@ -268,6 +348,106 @@ projectGljObject={
         this.projectGljSheet.setRowCount(this.projectGljSheetData.length);
         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){
@@ -296,9 +476,6 @@ projectGljObject={
             }else if(me.displayType == filterType.ZYCL){//筛选“主要材料”=“是”的工料机行。
                 return item.is_main_material == 1;
             }
-
-            console.log(item);
-
         }
         return false;
     },
@@ -364,7 +541,8 @@ projectGljObject={
             sheetCommonObj.showRowData(this.projectGljSheet, this.projectGljSetting,row,this.projectGljSheetData);
         }else {
             me.projectGljSheetData.splice(row,1);
-            this.projectGljSheet.deleteRows(row,1);
+            me.projectGljSheet.deleteRows(row,1);
+            me.showMixRatioData();
         }
         //me.projectGljSheetData[row] = me.getSheetDataByGLJ(glj);
 
@@ -379,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);
         }
     },
@@ -476,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 ;
         }
@@ -511,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){
@@ -622,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){
@@ -629,14 +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();
@@ -652,7 +840,7 @@ $(function () {
         me.showTag='machine';
         me.showProjectGljData();
         me.initMixRatio();
-    });
+    });*/
     $('#pop-used-list').popover({
             placement: "bottom",
             html: true,
@@ -772,9 +960,12 @@ $(function () {
     $("#filterType").on("click","ul li a",function(){
         let me = projectGljObject;
         me.displayType = filterType[this.id];
-        me.showProjectGljData();
-        me.showMixRatioData();
-        console.log(this.id);
+        if(me.displayType == filterType.SCHZ){//三材汇总树节点
+            me.showMaterialTreeData();
+        }else {
+            me.showProjectGljData();
+            me.showMixRatioData();
+        }
     });
 
 });

+ 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 () {