Sfoglia il codice sorgente

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

TonyKang 7 anni fa
parent
commit
5a483db551

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

@@ -66,10 +66,11 @@ class GLJController extends BaseController {
 
             // 先获取对应标段的项目工料机数据
             let gljListModel = new GLJListModel();
-            let [gljList, mixRatioConnectData] = await gljListModel.getListByProjectId(projectId, unitPriceFileId);
+            let [gljList, mixRatioConnectData,mixRationMap] = await gljListModel.getListByProjectId(projectId, unitPriceFileId);
 
             responseData.data.gljList = gljList;
             responseData.data.mixRatioConnectData = mixRatioConnectData;
+            responseData.data.mixRatioMap = mixRationMap;
             responseData.data.usedTenderList = usedTenderList;
             responseData.data.constData = {
                 materialIdList: gljListModel.materialIdList,

+ 7 - 2
modules/glj/models/glj_list_model.js

@@ -76,6 +76,7 @@ class GLJListModel extends BaseModel {
     async getListByProjectId(projectId, unitPriceFileId) {
         let gljData = null;
         let mixRatioConnectData = {};
+        let mixRationMap={};
         try {
             // 首先获取对应标段下所有的项目工料机数据
             let condition = {project_id: projectId};
@@ -138,7 +139,11 @@ class GLJListModel extends BaseModel {
                     } else {
                         mixRatioData[tmp.glj_id] = [tmp];
                     }
-
+                    if(mixRationMap[tmp.connect_code]!=undefined){
+                        mixRationMap[tmp.connect_code].push(tmp);
+                    }else {
+                        mixRationMap[tmp.connect_code]=[tmp];
+                    }
                     if (mixRatioConnectData[tmp.glj_id] !== undefined) {
                         mixRatioConnectData[tmp.glj_id].push(tmp.connect_code);
                     } else {
@@ -160,7 +165,7 @@ class GLJListModel extends BaseModel {
             gljData = [];
         }
 
-        return [gljData, mixRatioConnectData];
+        return [gljData, mixRatioConnectData,mixRationMap];
     }
 
     /**

+ 14 - 1
modules/main/controllers/calc_program_controller.js

@@ -8,7 +8,8 @@ let calcProgramFacade = require('../facade/calc_program_facade');
 module.exports = {
     getProjectCalcProgram: getProjectCalcProgram,
     getStdCalcProgram: getStdCalcProgram,
-    saveCalcItem: saveCalcItem
+    saveCalcItem: saveCalcItem,
+    saveCalcItems: saveCalcItems
 };
 
 async function getProjectCalcProgram(req, res) {
@@ -50,3 +51,15 @@ async function saveCalcItem(req, res) {
     });
     res.json(result);
 };
+
+async function saveCalcItems(req, res) {
+    let result = {error: 0, message: ''};
+
+    calcProgramFacade.saveCalcItems(req.body.data, function (err, msg) {
+        if (err) {
+            result.error = 1;
+        };
+        result.message = msg;
+    });
+    res.json(result);
+};

+ 34 - 2
modules/main/facade/calc_program_facade.js

@@ -18,7 +18,8 @@ module.exports = {
     getStdCalcProgramFile: getStdCalcProgramFile,
     getData: getData,
     save: save,
-    saveCalcItem: saveCalcItem
+    saveCalcItem: saveCalcItem,
+    saveCalcItems: saveCalcItems
 };
 
 async function newProjectCalcProgramFile(data) {
@@ -114,11 +115,42 @@ function saveCalcItem(dataObj, callback) {
             callback( {err:1, msg:'没有找到计算程序文件'} );
         }
     });
+};
 
+// {  projectID: projectID, calcItems: [{templatesID, calcItem}]  }
+function saveCalcItems(datas, callback) {
+    let datasObj = JSON.parse(datas);
+    projectCalcProgramsModel.findOne({projectID: datasObj.projectID}, function (err, data) {
+        if(!err){
+            for (let cI of datasObj.calcItems){
+                for (let i = 0; i < data.templates.length; i++){
+                    if (data.templates[i].ID == cI.templatesID){
+                        for (let j=0; j < data.templates[i].calcItems.length; j++){
+                            if (data.templates[i].calcItems[j].ID == cI.calcItem.ID){
+                                data.templates[i].calcItems[j] = cI.calcItem;
+                                data.save(function (err) {
+                                    if (err) {
+                                        callback({err:1, msg:'本条计算规则保存失败'});
+                                    } else {
+                                        callback({err:0, msg:'本条计算规则保存成功'});
+                                    }
+                                });
+                                break;
+                            };
+                        };
+                        break;
+                    };
+                };
+            };
+        }
+        else {
+            callback( {err:1, msg:'没有找到计算程序文件'} );
+        }
+    });
 };
 
 // for test
 /*let udata = {ID:8, code: '8.8.8', name: '被改成了888', hehe: '增加的属性'};
-saveCalcItem({projectID: 597, templatesID: 4, calcItemID: 8, data: udata}, function (data) {
+saveCalcItem({projectID: 597, templatesID: 4, data: udata}, function (data) {
     console.log({msg:data.msg, data: data.data});
 })*/

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

@@ -12,6 +12,7 @@ module.exports = function (app) {
     cpRouter.post('/getProjectCalcProgram', cpController.getProjectCalcProgram);
     cpRouter.post('/getStdCalcProgram', cpController.getStdCalcProgram);
     cpRouter.post('/saveCalcItem', cpController.saveCalcItem);
+    cpRouter.post('/saveCalcItems', cpController.saveCalcItems);
 
     app.use('/calcProgram',cpRouter);
 }

+ 1 - 1
modules/ration_repository/models/ration_item.js

@@ -47,7 +47,7 @@ var counter = require('../../../public/counter/counter');
 var rationItemDAO = function(){};
 
 rationItemDAO.prototype.getRationItemsBySection = function(sectionId,callback){
-    rationItemModel.find({"sectionId": sectionId, "$or": [{"isDeleted": null}, {"isDeleted": false} ]},function(err,data){
+    rationItemModel.find({"sectionId": sectionId, "$or": [{"isDeleted": null}, {"isDeleted": false} ]}, null, {sort: {code: 1}}, function(err,data){
         if(err) callback(true, "Fail to get items", "")
         else callback(false,"Get items successfully", data);
     })

+ 9 - 1
public/calc_util.js

@@ -268,6 +268,7 @@ class Calculation {
         private_compile_feeType();
         private_compile_calcBase();
         me.compiledTemplates = {};
+        me.saveForReports = [];
     };
 
     compileTemplate(template){
@@ -341,8 +342,13 @@ class Calculation {
                 };
 
                 if (item.feeRateID) {
-                    var cmf = me.compiledFeeRates["feeRate_" + item.feeRateID];
+                    let orgFeeRate = item.feeRate;
+                    let cmf = me.compiledFeeRates["feeRate_" + item.feeRateID];
                     item.feeRate = cmf?cmf.rate:100;
+
+                    if (!orgFeeRate || (orgFeeRate && orgFeeRate != item.feeRate)){
+                        me.saveForReports.push({templatesID: template.ID, calcItem: item});
+                    }
                 };
 
                 // 字段名映射
@@ -372,6 +378,8 @@ class Calculation {
         };
     };
 
+
+
     calculate($treeNode){
         let me = this;
         let templateID = $treeNode.data.programID;

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

@@ -105,7 +105,7 @@ body {
   width:0%;
 }
 .sidebar-bottom,.sidebar-bottom .col-lg-6,.sidebar-bottom .col-lg-12 {
-  height:200px
+  height:300px
 }
 .top-content, .fluid-content {
     overflow: auto;
@@ -234,7 +234,7 @@ body {
     }
 }
 .bottom-content .tab-content .main-data-bottom{
-    height: 200px;
+    height: 300px;
     overflow: auto;
 }
 .bottom-content .tab-content .ovf-hidden{
@@ -309,8 +309,3 @@ body {
   max-width: 200px;
   display: inline-block;
 }
-.gc-column-header-cell{
-    text-align: center!important;
-}
-.modal-lg{max-width: 1000px}
-.modal-feeRate {max-width: 550px}

+ 3 - 2
web/building_saas/glj/js/common_spread.js

@@ -29,11 +29,12 @@ function CommonSpreadJs (header) {
 CommonSpreadJs.prototype.init = function(target) {
 
     let setting = {
-        header: []
+        header: [],
+        view:{rowHeaderWidth:35}
     };
     this.columnInfo = [];
     for(let tmp of this.header) {
-        let width = tmp.field === 'name' ? 200 : 120;
+        let width = tmp.width==undefined ? 120 : tmp.width;
         setting.header.push({headerName: tmp.name, headerWidth: width});
         this.columnInfo.push({name: tmp.field, displayName: tmp.name, visible: tmp.visible, cellType: tmp.cellType, size: width});
     }

+ 2 - 1
web/building_saas/glj/js/project_glj.js

@@ -19,6 +19,7 @@ let GLJTypeConst = [];
 // spreadjs载入数据所需
 let jsonData = [];
 let mixRatioConnectData = [];
+let mixRatioMap={};
 // 单价文件相关
 let usedUnitPriceInfo = {};
 let otherFileData = {};
@@ -215,7 +216,7 @@ function init() {
                 jsonData = tmpData;
             }
             mixRatioConnectData = data.mixRatioConnectData !== undefined ? data.mixRatioConnectData : mixRatioConnectData;
-
+            mixRatioMap = data.mixRatioMap !== undefined ? data.mixRatioMap : mixRatioMap;
             host = data.constData.hostname !== undefined ? data.constData.hostname : '';
             materialIdList = data.constData.materialIdList !== undefined ? data.constData.materialIdList : materialIdList;
             roomId = data.constData.roomId !== undefined ? data.constData.roomId : roomId;

+ 16 - 14
web/building_saas/glj/js/project_glj_spread.js

@@ -40,34 +40,36 @@ ProjectGLJSpread.prototype.init = function () {
     selectBox.items(supplySelect);
     selectBox.editorValueType(GC.Spread.Sheets.CellTypes.EditorValueType.text);
     let header = [
-        {name: '编码', field: 'code', visible: true},
-        {name: '名称', field: 'name', visible: true},
-        {name: '规格型号', field: 'specs', visible: true},
-        {name: '单位', field: 'unit', visible: true},
-        {name: '类型', field: 'unit_price.short_name', visible: true},
+        {name: '编码', field: 'code', visible: true,width:80},
+        {name: '名称', field: 'name', visible: true,width:100},
+        {name: '规格型号', field: 'specs', visible: true,width:120},
+        {name: '单位', field: 'unit', visible: true,width:45},
+        {name: '类型', field: 'unit_price.short_name', visible: true,width:45},
         {name: 'ID', field: 'id', visible: false},
         {name: '类型', field: 'unit_price.type', visible: false},
-        {name: '总消耗量', field: 'quantity', visible: true},
-        {name: '基价单价', field: "unit_price.base_price", visible: true},
-        {name: '调整基价', field: 'adjust_price', visible: true},
-        {name: '市场单价', field: "unit_price.market_price", visible: true, validator: 'number'},
+        {name: '总消耗量', field: 'quantity', visible: true,width:100},
+        {name: '基价单价', field: "unit_price.base_price", visible: true,width:70},
+        {name: '调整基价', field: 'adjust_price', visible: true,width:70},
+        {name: '市场单价', field: "unit_price.market_price", visible: true, validator: 'number',width:70},
         {
             name: '是否暂估',
             field: 'is_evaluate',
             visible: true,
             cellType: new GC.Spread.Sheets.CellTypes.CheckBox(),
             validator: 'boolean'
+            ,width:40
         },
-        {name: '供货方式', field: 'supply', visible: true, cellType: selectBox},
-        {name: '甲供数量', field: 'supply_quantity', visible: true},
-        {name: '交货方式', field: 'delivery', visible: true},
-        {name: '送达地点', field: 'delivery_address', visible: true},
+        {name: '供货方式', field: 'supply', visible: true, cellType: selectBox,width:80},
+        {name: '甲供数量', field: 'supply_quantity', visible: true,width:100},
+        {name: '交货方式', field: 'delivery', visible: true,width:90},
+        {name: '送达地点', field: 'delivery_address', visible: true,width:100},
         {
             name: '不调价',
             field: 'is_adjust_price',
             visible: true,
             cellType: new GC.Spread.Sheets.CellTypes.CheckBox(),
-            validator: 'boolean'
+            validator: 'boolean',
+            width:40
         },
         {name: 'UID', field: 'unit_price.id', visible: false},
         {name: '工料机ID', field: 'glj_id', visible: false},

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

@@ -6,8 +6,8 @@ function autoFlashHeight(){
     var bottomContentHeight = $(".bottom-content").height();
     var toolsBarHeightQ = $(".tools-bar-height-q").height();
     var toolsBarHeightD = $(".tools-bar-height-d").height();
-    $(".main-data-side-q").height($(window).height()-headerHeight-toolsbarHeight-toolsBarHeightQ-202);
-    $(".main-data-side-d").height($(window).height()-headerHeight-toolsbarHeight-toolsBarHeightD-202);
+    $(".main-data-side-q").height($(window).height()-headerHeight-toolsbarHeight-toolsBarHeightQ-302);
+    $(".main-data-side-d").height($(window).height()-headerHeight-toolsbarHeight-toolsBarHeightD-302);
     $(".main-data-top").height($(window).height()-headerHeight-toolsbarHeight-bottomContentHeight-1);
     $(".main-data-full").height($(window).height()-headerHeight-toolsbarHeight-1);
     $(".main-data-full-fl").height($(window).height()-headerHeight-toolsbarHeight-37);

+ 11 - 1
web/building_saas/main/js/models/calc_program.js

@@ -37,11 +37,21 @@ class CalcProgram {
         for (let ct of calcTemplates){
             this.calc.compileTemplate(ct);
         };
+
+        // 存储费率临时数据,报表用。
+        if (this.calc.saveForReports.length > 0){
+            let saveDatas = {};
+            saveDatas.projectID = projectInfoObj.projectInfo.ID;
+            saveDatas.calcItems = this.calc.saveForReports;
+            CommonAjax.post('/calcProgram/saveCalcItems', saveDatas, function (data) {
+                this.calc.saveForReports = [];
+            });
+        };
     };
 
     calculate(treeNode){
         treeNode.data.gljList = this.project.ration_glj.getGljArrByRation(treeNode.data.ID);
         this.calc.calculate(treeNode);
         projectObj.mainController.refreshTreeNode([treeNode]);
-    };
+    }
 }

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

@@ -722,6 +722,7 @@ let pageCCOprObj = {
         theCha.workBook.getSheet(0).setRowCount(0);
         sheetCommonObj.cleanSheet(theCon.workBook.getSheet(0), theCon.setting, -1);
         sheetCommonObj.cleanSheet(theCha.workBook.getSheet(0), theCha.setting, -1);
+        projectObj.mainSpread.focus(true);
     },
     //更新特征及内容数据
     updateCharacterContent: function (findSet, updateObj, txtObj, oprObj) {

+ 5 - 4
web/building_saas/main/js/views/fee_rate_view.js

@@ -214,8 +214,8 @@ var feeRateObject={
                 ctx.restore();
             }
             else {
-                x--;
-                y += h / 2 - 3;
+               // x--;
+                //y += h / 2 - 3;
                 ctx.save();
                 ctx.restore();
             }
@@ -235,7 +235,7 @@ var feeRateObject={
         TreeNodeCellType.prototype.processMouseDown = function (hitinfo) {
             var level = hitinfo.sheet.rowOutlines.getLevel(hitinfo.row);
             var hoffset = (level + 2) * 12 + hitinfo.cellRect.x;
-            if (hitinfo.x < hoffset && hitinfo.x > hoffset - 10) {
+            if (level==-1&&hitinfo.x < hoffset && hitinfo.x > hoffset - 10) {
                 var collapsed = hitinfo.sheet.rowOutlines.isCollapsed(hitinfo.row + 1);
                 hitinfo.sheet.rowOutlines.setCollapsed(hitinfo.row, !collapsed);
                 hitinfo.sheet.invalidateLayout();
@@ -252,7 +252,8 @@ var feeRateObject={
         FeeRateEditCellType.prototype = new ns.CellTypes.Text();
         FeeRateEditCellType.prototype.paint = function (ctx, value, x, y, w, h, style, options) {
             if(value!=null){
-                ctx.fillText(value,x+3+ctx.measureText(value).width,y+h-3);
+               // ctx.fillText(value,x+3+ctx.measureText(value).width,y+h-3);
+                ctx.fillText(value,x+w,y+h-3);
             }
             if(feeRateObject.editingCell){
                 if(feeRateObject.editingCell.row==options.row&&feeRateObject.editingCell.col==options.col){

+ 174 - 14
web/building_saas/main/js/views/glj_view.js

@@ -307,6 +307,8 @@ var gljOprObj = {
             var index= _.indexOf(me.setting.notEditedType,type);
             if(index!=-1){
                 me.sheet.getCell(args.row, args.col, GC.Spread.Sheets.SheetArea.viewport).locked(true);
+            }else {
+                me.sheet.getCell(args.row, args.col, GC.Spread.Sheets.SheetArea.viewport).locked(false);
             }
         }
     },
@@ -487,7 +489,6 @@ var gljOprObj = {
         return rowstr;
 
     },
-
     showDataIfRationSelect:function (node) {
         var isShow = false;
         if(node){
@@ -526,9 +527,25 @@ var gljOprObj = {
             this.showInSheet(gljList);
         }
     },
-    showRationGLJSheetData:function () {
-        this.sheetData=_.sortBy(this.sheetData,'type');
+    showRationGLJSheetData:function (init) {
+        this.sheet.getRange(0,-1,this.sheet.getRowCount(),-1).visible(true);
+        if(init){
+            this.sheetData=_.sortBy(this.sheetData,'type');
+            this.addMixRatioToShow();
+            this.initRationTree();
+        }
         sheetCommonObj.showData(this.sheet,this.setting,this.sheetData);
+
+    },
+    initRationTree:function () {
+        this.sheet.getRange(-1, 0, -1, 1).cellType(this.getTreeNodeCellType(this.sheetData));
+        for(var i =0;i<this.sheetData.length;i++){
+            if(this.sheetData[i].hasOwnProperty('subList')){
+                this.sheet.setTag(i,0,true);
+                this.sheet.getRange(i+1, -1, this.sheetData[i].subList.length, -1).visible(false);
+                this.sheet.getRange(i+1, -1, this.sheetData[i].subList.length, -1).locked(true);
+            }
+        }
     },
     filterGljByRation:function (ration,datas) {
         var gljList=[];
@@ -539,24 +556,62 @@ var gljOprObj = {
     },
     showInSheet:function(gljList){
         this.sheetData=this.combineWithProjectGlj(gljList);
-        this.showRationGLJSheetData();
+        this.showRationGLJSheetData(true);
+    },
+    addMixRatioToShow:function () {
+        var newList=[];
+      for(var i =0;i<this.sheetData.length;i++){
+          newList.push(this.sheetData[i]);
+          if(this.sheetData[i].hasOwnProperty('subList')){
+                newList = newList.concat(this.sheetData[i].subList);
+          }
+      }
+        this.sheetData= newList;
     },
     combineWithProjectGlj:function (ration_gljs) {
-        var projectGljs = projectObj.project.projectGLJ.datas.gljList;
+        var projectGLJData = projectObj.project.projectGLJ.datas;
+        var projectGljs = projectGLJData.gljList;
+        var mixRatioMap = projectGLJData.mixRatioMap;
         if(ration_gljs&&ration_gljs.length>0&&projectGljs&&projectGljs.length>0){
-            ration_gljs.forEach(function (a) {
-                var glj = _.find(projectGljs,{id:a.projectGLJID});
+            for(var i =0;i<ration_gljs.length;i++){
+                var glj = _.find(projectGljs,{'id':ration_gljs[i].projectGLJID});
                 if(glj){
-                    a.basePrice=glj.unit_price.base_price;
-                    a.marketPrice=glj.unit_price.market_price;
-                    a.adjustPrice=glj.adjust_price;
-                    a.isEstimate=glj.is_evaluate;
+                    ration_gljs[i].basePrice=glj.unit_price.base_price;
+                    ration_gljs[i].marketPrice=glj.unit_price.market_price;
+                    ration_gljs[i].adjustPrice=glj.adjust_price;
+                    ration_gljs[i].isEstimate=glj.is_evaluate;
+                    if(mixRatioMap.hasOwnProperty(glj.code)){
+                        var mixRatios = this.getMixRationShowDatas(mixRatioMap[glj.code],projectGljs);
+                        ration_gljs[i].subList = mixRatios;
+                    }
                 }
-            })
+            }
         }
         return ration_gljs;
-    }
-    ,
+    },
+    getMixRationShowDatas:function (mixRatioList,projectGljs) {
+        var temRationGLJs = [];
+        for(var i =0;i<mixRatioList.length;i++){
+            var pg =  _.find(projectGljs,{'code':mixRatioList[i].code});
+            var tem = {
+                code:pg.code,
+                name:pg.name,
+                specs:pg.specs,
+                unit:pg.unit,
+                shortName:pg.unit_price.short_name,
+                rationItemQuantity:mixRatioList[i].consumption,
+               // quantity:mixRatioList[i].consumption,
+                basePrice:pg.unit_price.base_price,
+                marketPrice:pg.unit_price.market_price,
+                adjustPrice:pg.adjust_price,
+                isEstimate:pg.is_evaluate,
+                isMixRatio:true
+            }
+            temRationGLJs.push(tem);
+        }
+        temRationGLJs=_.sortBy(temRationGLJs,'code');
+        return temRationGLJs;
+    },
     showRationCoeData:function (node) {
         var coeList = [];
         var ration_coe= projectObj.project.ration_coe;
@@ -874,6 +929,111 @@ var gljOprObj = {
     },
     refreshView:function () {
         this.showRationGLJData();
+    },
+    getTreeNodeCellType:function (data) {
+        var ns = GC.Spread.Sheets;
+        var rectW = 10;
+        var rectH = 10;
+        var margin = 3;
+        function TreeNodeCellType() {
+        }
+
+        function drowRect(ctx,x,y,w,h) {
+            ctx.save();
+            ctx.strokeStyle = "gray";
+            ctx.translate(0.5,0.5);
+            ctx.beginPath();
+            var rectX = x+margin;
+            var rectY =  y+ Math.round(h/2)-rectH/2;
+            ctx.moveTo(rectX, rectY);
+            ctx.lineTo(rectX, rectY+rectH);
+            ctx.lineTo(rectX+rectW, rectY+rectH);
+            ctx.lineTo(rectX+rectW, rectY);
+            ctx.lineTo(rectX, rectY);
+            ctx.moveTo(rectX+rectW, y+Math.round(h/2));
+            ctx.lineTo(rectX+rectW+5, y+Math.round(h/2));
+            ctx.stroke();
+            ctx.restore();
+        }
+
+        function drowSymbol(ctx,x,y,w,h,collapsed) {
+            ctx.save();
+            ctx.strokeStyle = "#000000";
+            ctx.translate(0.5, 0.5);
+            ctx.beginPath();
+            ctx.moveTo(x+margin+2, y+Math.round(h/2));
+            ctx.lineTo(x+margin+8, y+Math.round(h/2));
+            var rectY =  y+ Math.round(h/2)-rectH/2;
+            if(collapsed){
+                ctx.moveTo(x+margin+rectW/2,rectY+2);
+                ctx.lineTo(x+margin+rectW/2,rectY+2+6);
+            }
+            ctx.stroke();
+            ctx.restore();
+        }
+
+        function drowSubItem(ctx,x,y,w,h,offset,nextItem) {
+            offset+=6;
+            ctx.save();
+            ctx.strokeStyle = "gray";
+            ctx.translate(0.5, 0.5);
+            ctx.beginPath();
+            ctx.moveTo(x+offset, y);
+            ctx.lineTo(x+offset, y+Math.round(h/2));
+            offset+=9;
+            ctx.lineTo(x+offset, y+Math.round(h/2));
+            if(nextItem&&nextItem.isMixRatio){
+                ctx.moveTo(x+offset-9, y+Math.round(h/2));
+                ctx.lineTo(x+offset-9, y+h);
+            }
+            ctx.stroke();
+            ctx.restore();
+            return offset;
+        }
+
+        TreeNodeCellType.prototype = new ns.CellTypes.Text();
+        TreeNodeCellType.prototype.paint = function (ctx, value, x, y, w, h, style, options) {
+            if(value!=null){
+                var offset = margin+rectW+6;
+                var recode = data[options.row];
+                if(recode&&recode.hasOwnProperty('subList')){
+                    drowRect(ctx,x,y,w,h);
+                    var collapsed = options.sheet.getTag(options.row,options.col);
+                    drowSymbol(ctx,x,y,w,h,collapsed);
+                }else if(recode&&recode.isMixRatio){
+                    offset= drowSubItem(ctx,x,y,w,h,offset,data[options.row+1]);
+                    offset+=1;
+                }
+                ctx.fillText(value,x+offset+ctx.measureText(value).width,y+h-5);
+            }
+        };
+        // override getHitInfo to allow cell type get mouse messages
+        TreeNodeCellType.prototype.getHitInfo = function (x, y, cellStyle, cellRect, context) {
+            return {
+                x: x,
+                y: y,
+                row: context.row,
+                col: context.col,
+                cellStyle: cellStyle,
+                cellRect: cellRect,
+                sheetArea: context.sheetArea
+            };
+        }
+        TreeNodeCellType.prototype.processMouseDown = function (hitinfo) {
+            var recode = data[hitinfo.row];
+            if(recode&&recode.hasOwnProperty('subList')){
+               var hoffset= hitinfo.cellRect.x+3;
+                if (hitinfo.x > hoffset && hitinfo.x < hoffset + 10){
+                    var collapsed =  hitinfo.sheet.getTag(hitinfo.row,hitinfo.col,hitinfo.sheetArea);
+                    collapsed = !collapsed;
+                    hitinfo.sheet.setTag(hitinfo.row,hitinfo.col,collapsed);
+                    hitinfo.sheet.getRange(hitinfo.row+1, -1, recode.subList.length, -1).visible(!collapsed);
+                    hitinfo.sheet.invalidateLayout();
+                    hitinfo.sheet.repaint();
+                }
+            }
+        };
+        return new TreeNodeCellType()
     }
 }
 

+ 10 - 5
web/building_saas/main/js/views/glj_view_contextMenu.js

@@ -18,7 +18,7 @@ var gljContextMenu = {
                         var sheetData = gljOprObj.sheetData;
                         var disable = true;
                         if(subSpread.getActiveSheetIndex()==0&&sheetData!=null&&sheetData.length>0&&gljContextMenu.selectedRow<sheetData.length){
-                            disable=false
+                            disable=  sheetData[gljContextMenu.selectedRow].isMixRatio==true?true:false;
                         }
                         return disable;
                     },
@@ -32,11 +32,16 @@ var gljContextMenu = {
                     name: '添加工料机',
                     icon: 'fa-sign-in',
                     disabled: function () {
+                        var disable = true;
                         var selected = projectObj.project.mainTree.selected;
+                        var sheetData = gljOprObj.sheetData;
                         if(selected&&selected.sourceType==ModuleNames.ration){
-                            return false;
+                            disable=false;
                         }
-                        return true;
+                        if(subSpread.getActiveSheetIndex()==0&&sheetData!=null&&sheetData.length>0&&gljContextMenu.selectedRow<sheetData.length){
+                            disable=  sheetData[gljContextMenu.selectedRow].isMixRatio==true?true:false;
+                        }
+                        return disable;
                     },
                     callback:function () {
                         getGLJData('add');
@@ -49,7 +54,7 @@ var gljContextMenu = {
                         var sheetData = gljOprObj.sheetData;
                         var disable = true;
                         if(subSpread.getActiveSheetIndex()==0&&sheetData!=null&&sheetData.length>0&&gljContextMenu.selectedRow<sheetData.length){
-                            disable=false
+                            disable=  sheetData[gljContextMenu.selectedRow].isMixRatio==true?true:false;
                         }
                         return disable;
                     },
@@ -64,7 +69,7 @@ var gljContextMenu = {
                         var sheetData = gljOprObj.sheetData;
                         var disable = true;
                         if(subSpread.getActiveSheetIndex()==0&&sheetData!=null&&sheetData.length>0&&gljContextMenu.selectedRow<sheetData.length){
-                            disable=false
+                            disable=  sheetData[gljContextMenu.selectedRow].isMixRatio==true?true:false;
                         }
                         return disable;
                     },

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

@@ -115,6 +115,8 @@ let colSettingObj = {
         sheet.setColumnCount(setting.headRows, GC.Spread.Sheets.SheetArea.rowHeader);
         sheet.setColumnCount(1);
         sheet.getRange(-1, 0, -1, 1).cellType(this.checkBox).hAlign(GC.Spread.Sheets.HorizontalAlign.center);
+        sheet.getCell(0, 0, GC.Spread.Sheets.SheetArea.colHeader).value('显示');
+        sheet.setColumnWidth(0, 300);
 
         setting.cols.forEach(function (col, index) {
             let i, iCol = 0, cell;

+ 18 - 5
web/building_saas/main/js/views/std_bills_lib.js

@@ -73,16 +73,26 @@ var billsLibObj = {
             }
             return null;
         };
+        let sortJobsAndFeatures = function (arr) {
+            arr.sort(function (a, b) {
+                let rst = 0;
+                if(a.serialNo > b.serialNo) rst = 1;
+                else if(a.serialNo < b.serialNo) rst = -1;
+                return rst;
+            });
+        };
         var getBillsJobs = function (node) {
             var jobs = [], i, jobData = null;
             if (stdBillsJobData && node && node.data.jobs) {
                 for (i = 0; i < node.data.jobs.length; i++) {
                     jobData = findData(node.data.jobs[i], 'id', stdBillsJobData);
                     if (jobData) {
+                        jobData.serialNo = node.data.jobs[i].serialNo;
                         jobs.push(jobData);
                     }
                 }
             }
+            sortJobsAndFeatures(jobs);
             return jobs;
         };
         var getBillsFeatures = function (node) {
@@ -91,10 +101,12 @@ var billsLibObj = {
                 for (i = 0; i < node.data.items.length; i++) {
                     featureData = findData(node.data.items[i], 'id', stdBillsFeatureData);
                     if (featureData) {
+                        featureData.serialNo = node.data.items[i].serialNo;
                         features.push(featureData);
                     }
                 }
             }
+            sortJobsAndFeatures(features);
             return features;
         };
         var showJobs = function (jobs) {
@@ -110,6 +122,7 @@ var billsLibObj = {
             $('#stdBillsRemarkTab').hide();
             billsLibObj.refreshBillsRelaSpread();
             billsLibObj.checkBillsRelaSpread();
+            sortJobsAndFeatures(getBillsJobs(node));
             showJobs(getBillsJobs(node));
             showFeatures(getBillsFeatures(node));
         };
@@ -218,7 +231,7 @@ var billsLibObj = {
         ],
         "defaultRowHeight": 21,
         "cols":[{
-            "width":150,
+            "width":160,
             "readOnly": true,
             "head":{
                 "titleNames":["项目编码"],
@@ -235,7 +248,7 @@ var billsLibObj = {
                 "font":"Arial"
             }
         }, {
-            "width":120,
+            "width":150,
             "readOnly": true,
             "head":{
                 "titleNames":["项目名称"],
@@ -252,7 +265,7 @@ var billsLibObj = {
                 "font":"Arial"
             }
         }, {
-            "width":40,
+            "width":50,
             "readOnly": true,
             "head":{
                 "titleNames":["计量单位"],
@@ -295,7 +308,7 @@ var billsLibObj = {
         "headRowHeight":[25],
         "defaultRowHeight": 21,
         "cols":[{
-            "width":200,
+            "width":160,
             "readOnly":true,
             "head":{
                 "titleNames":["工作内容"],
@@ -319,7 +332,7 @@ var billsLibObj = {
         "headRowHeight":[25],
         "defaultRowHeight": 21,
         "cols":[{
-            "width":200,
+            "width":160,
             "readOnly":true,
             "head":{
                 "titleNames":["项目特征"],

+ 5 - 5
web/building_saas/main/js/views/std_ration_lib.js

@@ -131,7 +131,7 @@ var rationLibObj = {
         "defaultRowHeight": 21,
         "treeCol": 0,
         "cols":[{
-            "width":300,
+            "width":400,
             "readOnly": true,
             "head":{
                 "titleNames":["名称"],
@@ -155,7 +155,7 @@ var rationLibObj = {
         "headRowHeight":[20],
         "defaultRowHeight": 21,
         "cols":[{
-            "width":100,
+            "width":60,
             "readOnly": true,
             "head":{
                 "titleNames":["编码"],
@@ -172,7 +172,7 @@ var rationLibObj = {
                 "font":"Arial"
             }
         }, {
-            "width":180,
+            "width":220,
             "readOnly": true,
             "head":{
                 "titleNames":["名称"],
@@ -189,7 +189,7 @@ var rationLibObj = {
                 "font":"Arial"
             }
         }, {
-            "width":50,
+            "width":55,
             "readOnly":true,
             "head":{
                 "titleNames":["单位"],
@@ -206,7 +206,7 @@ var rationLibObj = {
                 "font":"Arial"
             }
         }, {
-            "width":80,
+            "width":60,
             "readOnly":true,
             "head":{
                 "titleNames":["基价"],