Procházet zdrojové kódy

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

zhongzewei před 7 roky
rodič
revize
798a7301ed

+ 5 - 3
Dockerfile

@@ -1,14 +1,16 @@
 FROM costbase:2.0
 
-WORKDIR /home/ConstructionCost
+RUN mv /home/ConstructionCost /home/YangHuCost
 
-COPY . /home/ConstructionCost
+WORKDIR /home/YangHuCost
+
+COPY . /home/YangHuCost
 
 RUN cnpm install
 
 RUN gulp build
 
-EXPOSE 6060
+EXPOSE 2060
 
 ENV NODE_ENV=prod
 

+ 5 - 3
Dockerfile_pp

@@ -1,14 +1,16 @@
 FROM costbase:2.0
 
-WORKDIR /home/ConstructionCost
+RUN mv /home/ConstructionCost /home/YangHuCost
 
-COPY . /home/ConstructionCost
+WORKDIR /home/YangHuCost
+
+COPY . /home/YangHuCost
 
 RUN cnpm install
 
 RUN gulp build
 
-EXPOSE 6060
+EXPOSE 2060
 
 ENV NODE_ENV=pp
 

+ 5 - 3
Dockerfile_qa

@@ -1,14 +1,16 @@
 FROM costbase:2.0
 
-WORKDIR /home/ConstructionCost
+RUN mv /home/ConstructionCost /home/YangHuCost
 
-COPY . /home/ConstructionCost
+WORKDIR /home/YangHuCost
+
+COPY . /home/YangHuCost
 
 RUN cnpm install
 
 RUN gulp build
 
-EXPOSE 6060
+EXPOSE 2060
 
 ENV NODE_ENV=qa
 

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 3 - 3
config/config.js


+ 1 - 1
modules/ration_glj/facade/glj_calculate_facade.js

@@ -132,7 +132,7 @@ function generateUpdateTasks(result) {
 
 function sortRationGLJ(list) {
     list = _.sortByAll(list, [function (item) {
-        return _.indexOf(gljUtil.getGljTypeSeq(),item.type);
+        return gljUtil.getMainType(item.type);
     }, "code"])
     return list;
 }

+ 6 - 1
modules/reports/controllers/rpt_controller.js

@@ -255,7 +255,12 @@ function getAllPagesCommon(user_id, prj_id, rpt_id, pageSize, orientation, custo
                         printCom.initialize(rptTpl);
                         printCom.analyzeData(rptTpl, tplData, defProperties, dftOption, outputType);
                         let maxPages = printCom.totalPages;
-                        let pageRst = printCom.outputAsSimpleJSONPageArray(rptTpl, tplData, 1, maxPages, defProperties, customizeCfg);
+                        let pageRst = null;
+                        if (maxPages > 0) {
+                            pageRst = printCom.outputAsSimpleJSONPageArray(rptTpl, tplData, 1, maxPages, defProperties, customizeCfg);
+                        } else {
+                            pageRst = printCom.outputAsPreviewPage(rptTpl, defProperties);
+                        }
                         if (pageRst) {
                             // fsUtil.writeObjToFile(pageRst, "D:/GitHome/ConstructionCost/tmp/testBuiltPageResult.jsp");
                             cb(null, pageRst);

+ 8 - 3
public/gljUtil.js

@@ -16,7 +16,8 @@ module.exports = {
     getMarketPrice:getMarketPrice,
     getBasePrice:getBasePrice,
     getAdjustPrice:getAdjustPrice,
-    getGljTypeSeq:getGljTypeSeq
+    getMainType:getMainType,
+    isConcreteType:isConcreteType
 };
 
 function calcProjectGLJQuantity(projectGLJDatas,rationGLJDatas,rationDatas,billsDatas,q_decimal) {
@@ -43,6 +44,10 @@ function calcPriceDiff(glj,calcOptions) {
     gljNodeUtil.calcPriceDiff(glj,calcOptions);
 }
 
-function getGljTypeSeq() {
-    return gljNodeUtil.getGljTypeSeq();
+function getMainType() {
+    return gljNodeUtil.getMainType();
+}
+
+function isConcreteType(type) {
+    return gljNodeUtil.isConcreteType(type);
 }

+ 19 - 8
public/web/gljUtil.js

@@ -295,17 +295,26 @@ let gljUtil = {
         t_index = k_arr.join("|-|");
         return t_index;
     },
-    getGljTypeSeq:function () {
-        let gljType = this.gljType;
-        return   [gljType.LABOUR,gljType.MAIN_MATERIAL,gljType.CONCRETE,gljType.MORTAR,gljType.MIX_RATIO,gljType.COMMERCIAL_CONCRETE,
-            gljType.COMMERCIAL_MORTAR,gljType.GENERAL_MATERIAL,gljType.OTHER_MATERIAL,gljType.GENERAL_MACHINE,gljType.INSTRUMENT,gljType.OTHER_MACHINE_USED,
-            gljType.MACHINE_COMPOSITION,gljType.MACHINE_LABOUR,gljType.FUEL_POWER_FEE,gljType.DEPRECIATION_FEE,gljType.INSPECTION_FEE,gljType.MAINTENANCE,
-            gljType.DISMANTLING_FREIGHT_FEE,gljType.VERIFICATION_FEE,gljType.OTHER_FEE,gljType.EQUIPMENT,gljType.MANAGEMENT_FEE,gljType.PROFIT,gljType.GENERAL_RISK_FEE]
+    getMainType:function (type) {
+        let str = type + "";
+        return parseInt(str.substr(0,1));
     },
     sortRationGLJ:function (list) {
         list = _.sortByAll(list, [function (item) {
-            return _.indexOf(gljTypeSeq,item.type)
-        }, "code"])
+            return gljUtil.getMainType(item.type);
+        }, "code"]);
+        return list;
+    },
+    sortMixRatio:function (list) {
+        return _.sortByAll(list, ["code"]);
+    },
+    //项目工料机 混凝土、砂浆、配合比排序与定额工料机不一样,同时,type取值的地方不一样
+    sortProjectGLJ:function (list) {
+        let specialMap = {202:9,203:10,204:11};//混凝土、砂浆、配合比 排到最后
+        list = _.sortByAll(list, [function (item) {
+            if(gljUtil.isConcreteType(item.unit_price.type)) return specialMap[item.unit_price.type];
+            return gljUtil.getMainType(item.unit_price.type);
+        }, "code"]);
         return list;
     },
     isConcreteType:function (type) {
@@ -342,6 +351,8 @@ let gljUtil = {
         COMMERCIAL_CONCRETE: 205,                   // 商品混凝土
         COMMERCIAL_MORTAR: 206,                     // 商品砂浆
         OTHER_MATERIAL: 207,                        // 其它材料
+        PURCHASE_COMPONENT: 208,                    // 外购砼构件
+        GREEN_SEEDLING: 209,                        // 绿化苗木
         // ==============材料类型 ↑=================
         // ==============机械类型 ↓=================
         GENERAL_MACHINE: 301,                       // 机械台班

+ 39 - 1
public/web/treeDataHelper.js

@@ -18,7 +18,7 @@ let tree_Data_Helper = {
             return tmpNodeRst;
         };
         let private_buildNodeData = function(parentItem, idArr, treeLevel, tbID) {
-            let iter = [], nextNode = private_getStartNode(idArr);
+            let iter = [], nextNode = private_getStartNode(idArr), pushedIds = [];
             while (nextNode !== null && nextNode !== undefined ) {
                 if (parentItem) {
                     parentItem[CHILDREN_NODE].push(nextNode);
@@ -26,6 +26,7 @@ let tree_Data_Helper = {
                     rst.push(nextNode);
                 }
                 iter.push(nextNode);
+                pushedIds.push(nextNode[NODE_ID]);
                 nextNode[TOP_BILL_ID] = tbID;
                 if (parentItem === null) {
                     nextNode[TOP_BILL_ID] = nextNode[NODE_ID];
@@ -40,7 +41,44 @@ let tree_Data_Helper = {
                 }
                 if (addLevel) nextNode[TREE_LEVEL] = treeLevel;
                 nextNode = tmpNodes[prefix + nextNode[NEXT_ID]];
+                if (nextNode === null || nextNode === undefined) {
+                    //备注: 考虑到实际数据的健壮性,有些节点会掉链子,需要用 parentItem[SUB_ID] 比对已经加上的节点,如发现加上的节点数量不够,那就得在这里补充上去
+                    if (parentItem) {
+                        if (parentItem[SUB_ID].length > iter.length) {
+                            for (let subId of parentItem[SUB_ID]) {
+                                if (pushedIds.indexOf(subId) < 0) {
+                                    let restNode = tmpNodes[prefix + subId];
+                                    if (addLevel) restNode[TREE_LEVEL] = treeLevel;
+                                    restNode[TOP_BILL_ID] = tbID;
+                                    parentItem[CHILDREN_NODE].push(restNode);
+                                    iter.push(restNode);
+                                }
+                            }
+                        }
+                    } else {
+                        if (idArr.length > iter.length) {
+                            for (let topId of idArr) {
+                                if (pushedIds.indexOf(topId) < 0) {
+                                    let restNode = tmpNodes[prefix + topId];
+                                    if (addLevel) restNode[TREE_LEVEL] = treeLevel;
+                                    restNode[TOP_BILL_ID] = restNode[NODE_ID];
+                                    if (restNode.flags && restNode.flags.length > 0) {
+                                        for (let flag of restNode.flags) {
+                                            if (flag.fieldName === "fixed") {
+                                                restNode[TOP_BILL_ID] = flag.flag;
+                                                break;
+                                            }
+                                        }
+                                    }
+                                    rst.push(restNode);
+                                    iter.push(restNode);
+                                }
+                            }
+                        }
+                    }
+                }
             }
+            pushedIds = [];
             for (let i = 0; i < iter.length; i++) {
                 let rtbID = tbID;
                 if (parentItem === null) {

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

@@ -343,9 +343,7 @@ function filterProjectGLJ(jsonData) {
 
 function sortProjectGLJ(jsonData) {
     if (jsonData.length > 0) {
-        jsonData = _.sortByAll(jsonData, [function (item) {
-            return _.indexOf(gljTypeSeq,item.unit_price.type);
-        }, 'code']);
+        jsonData = gljUtil.sortProjectGLJ(jsonData)
     }
     return jsonData
 }

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

@@ -193,7 +193,7 @@
                                       <a class="nav-link sub-item" id="linkQDJL" data-toggle="tab" href="#subSpread" role="tab">清单精灵</a>
                                   </li>
                                   <li class="nav-item" id="GLJ_div">
-                                      <a class="nav-link sub-item active" id="linkGLJ" data-toggle="tab" href="#subSpread" role="tab">人材机</a>
+                                      <a class="nav-link sub-item active" id="linkGLJ" data-toggle="tab" href="#subSpread" role="tab">工料机</a>
                                   </li>
                               <!--    <li class="nav-item">
                                       <a class="nav-link" id="linkFZTJ" data-toggle="tab" href="#subSpread" role="tab">附注条件</a>
@@ -481,7 +481,7 @@
                                               </div>
                                               <div class="form-check form-check-inline">
                                                   <input class="form-check-input" type="radio" name="content_type" id="raion_glj" value="ration_glj">
-                                                  <label class="form-check-label" for="raion_glj">人材机</label>
+                                                  <label class="form-check-label" for="raion_glj">工料机</label>
                                               </div>
                                               <!--<div class="form-check form-check-inline">
                                                   <input class="form-check-input" type="radio" name="inlineRadioOptions" id="bookmark" value="option4">
@@ -922,7 +922,7 @@
                                                     </div>
                                                 </div>
                                             </div>
-                                            <h5 class="mt-3">人材机</h5>
+                                            <h5 class="mt-3">工料机</h5>
                                             <div class="row m-0">
                                                 <div class="col-sm-3">
                                                     <div class="input-group input-group-sm mb-2">
@@ -1275,7 +1275,7 @@
                                             <a id="cb_QTXM" href="javascript:void(0)">其他项目</a>
                                         </li>
                                         <li class="py-1">
-                                            <a id="cb_RCJ" href="javascript:void(0)">人材机</a>
+                                            <a id="cb_RCJ" href="javascript:void(0)">工料机</a>
                                         </li>
                                         <li class="py-1">
                                             <a id="cb_FBF" href="javascript:void(0)">分包费</a>

+ 30 - 19
web/building_saas/main/js/models/calc_program.js

@@ -294,6 +294,7 @@ let calcTools = {
     machineDetailFee: function (treeNode, gljArr, masterTypeFilter, detailType, isTender) {
         if (!gljArr) return 0;
         let result = 0;
+        let nodeQ = calcTools.uiNodeQty(treeNode) ? calcTools.uiNodeQty(treeNode) : 0;
         for (let glj of gljArr) {
             if (baseMachineMasterTypes.includes(glj.type)){
                 // 机型不符
@@ -318,7 +319,7 @@ let calcTools = {
                         mdSum = (mdSum).toDecimal(decimalObj.glj.unitPriceHasMix);
                     }
                 }
-                result = (result + (gljQ * mdSum).toDecimal(decimalObj.process)).toDecimal(decimalObj.process)
+                result = (result + (nodeQ * gljQ * mdSum).toDecimal(decimalObj.process)).toDecimal(decimalObj.process)
             }
         }
         result = (result).toDecimal(decimalObj.ration.totalPrice);
@@ -467,13 +468,16 @@ let calcTools = {
         let rcj = (treeNode.data.subType === gljType.LABOUR && calcTools.inBase(baseName, 'RGF')) ||
             (baseMaterialTypes.includes(treeNode.data.subType) && calcTools.inBase(baseName, 'CLF')) ||
             (treeNode.data.subType === gljType.GENERAL_MACHINE && calcTools.inBase(baseName, 'JXF')) ||
+            (treeNode.data.subType === gljType.EQUIPMENT && calcTools.inBase(baseName, 'SBF')) ||
+
             (treeNode.data.subType === gljType.LABOUR && calcTools.inBase(baseName, 'SC_RGF')) ||
             (baseMaterialTypes.includes(treeNode.data.subType) && calcTools.inBase(baseName, 'SC_CLF')) ||
-            (treeNode.data.subType === gljType.GENERAL_MACHINE && calcTools.inBase(baseName, 'SC_JXF'));
+            (treeNode.data.subType === gljType.GENERAL_MACHINE && calcTools.inBase(baseName, 'SC_JXF')) ||
+            (treeNode.data.subType === gljType.EQUIPMENT && calcTools.inBase(baseName, 'SC_SBF'));
 
         if (rcj ||
-            (treeNode.data.subType === gljType.MAIN_MATERIAL && calcTools.inBase(baseName, 'ZCF')) ||
-            (treeNode.data.subType === gljType.EQUIPMENT && calcTools.inBase(baseName, 'SBF'))) {
+            (treeNode.data.subType === gljType.MAIN_MATERIAL && calcTools.inBase(baseName, 'ZCF'))
+            ) {
             if (treeNode.data.type == rationType.volumePrice){
                 let nodeQ = calcTools.uiNodeQty(treeNode) ? calcTools.uiNodeQty(treeNode) : 0;
                 result = treeNode.data.marketUnitFee ? (parseFloat(treeNode.data.marketUnitFee) * nodeQ).toDecimal(decimalObj.ration.unitPrice) : 0
@@ -827,7 +831,7 @@ let rationCalcBasesNameKinds = {
     JXF:        ['定额基价机械费', '定额机械费', '定额施工机具使用费', '定额施工机械使用费'],
     JSRGF:      ['定额基价机上人工费', '定额施工机械人工费'],
     ZCF:        ['主材费', '市场价主材费'],
-    SBF:        ['设备费', '市场价设备费'],
+    SBF:        ['定额设备费'],
     RGGR:       ['人工工日'],
     ZGCLF:      ['暂估材料费'],
 
@@ -836,6 +840,7 @@ let rationCalcBasesNameKinds = {
     SC_CLF:     ['材料费'],
     SC_JXF:     ['机械费', '施工机具使用费', '施工机械使用费'],
     SC_JSRGF:   ['施工机械人工费'],
+    SC_SBF:     ['设备费', '市场价设备费', '设备购置费'],
 
     JC_RGF:     ['人工费价差'],
     JC_CLF:     ['材料费价差'],
@@ -876,8 +881,14 @@ let rationCalcBases = {
     '施工机械人工费': function (node, isTender) {
         return calcTools.machineDetailFee(node, node.data.gljList, [], gljType.MACHINE_LABOUR, isTender);
     },
-    '商品砼费': function (node, isTender) {
-        return calcTools.rationBaseFee(node, [gljType.COMMERCIAL_CONCRETE, gljType.COMMERCIAL_MORTAR], priceTypes.ptMarketPrice, isTender);
+    '定额商品砼费': function (node, isTender) {
+        return calcTools.rationBaseFee(node, [gljType.COMMERCIAL_CONCRETE, gljType.COMMERCIAL_MORTAR], priceTypes.ptBasePrice, isTender);
+    },
+    '定额外购砼构件费': function (node, isTender) {
+        return calcTools.rationBaseFee(node, [gljType.PURCHASE_COMPONENT], priceTypes.ptBasePrice, isTender);
+    },
+    '定额绿化苗木费': function (node, isTender) {
+        return calcTools.rationBaseFee(node, [gljType.GREEN_SEEDLING], priceTypes.ptBasePrice, isTender);
     },
     '设备购置费': function (node, isTender) {
         return calcTools.rationBaseFee(node, [gljType.EQUIPMENT], priceTypes.ptMarketPrice, isTender);
@@ -1570,26 +1581,26 @@ class CalcProgram {
         fieldNameArr 值取自:遍历treeNode的计算规则,取有绑定的字段名。这些字段名以外的fee是因旧计算多出来的,需要删除。 */
         function deleteUselessFees(treeNode, fieldNameArr){
             if (fieldNameArr){   // 用于计算程序没有绑定的费用类别,不要同步到清单,而清单因为以前计算过该类别又有值,需删除。如切换取费类别,旧费要清掉。
-                for (var i = 0; i < treeNode.data.fees.length; i++) {
-                    let fee = treeNode.data.fees[i];
-                    if ((fee.fieldName != 'estimate') && !fieldNameArr.includes(fee.fieldName)){
-                        treeNode.data.fees.splice(i, 1);
-                        delete treeNode.data.feesIndex[fee.fieldName];
+                treeNode.data.fees = _.filter(treeNode.data.fees, function (item) {
+                    if(!fieldNameArr.includes(item.fieldName)){
+                        delete treeNode.data.feesIndex[item.fieldName];
                         treeNode.changed = true;
+                        return false;
                     }
-                }
+                    return true;
+                });
             }
             else{   // 总造价清单只留common, estimate两个费用类别。其它公式清单只留common。
                 let reserveArr = calcTools.isTotalCostBill(treeNode)? ['common', 'estimate']:['common'];
                 if (treeNode.data.fees && treeNode.data.fees.length > 0){
-                    let feesArr = treeNode.data.fees;
-                    for (let i = 0; i < feesArr.length; i++) {
-                        if (!reserveArr.includes(feesArr[i].fieldName)) {
-                            delete treeNode.data.feesIndex[feesArr[i].fieldName];
-                            feesArr.splice(i, 1);
+                    treeNode.data.fees = _.filter(treeNode.data.fees, function (item) {
+                        if(!reserveArr.includes(item.fieldName)){
+                            delete treeNode.data.feesIndex[item.fieldName];
                             treeNode.changed = true;
+                            return false;
                         }
-                    }
+                        return true;
+                    });
                 };
             };
         };

+ 6 - 4
web/building_saas/main/js/models/fee_rate.js

@@ -217,10 +217,12 @@ var FeeRate = {
         FeeRate.prototype.onFeeRatesChange = function (infos) {//{rateID:'AAAA',value:23}
             let node = project.mainTree.selected;
             let me = this;
+            let rateMap = {};
             for(let i of infos){
-                this.refreshCalProgramByRateID(i.rateID,i.value);
+                rateMap[i.rateID] = i.value;
                 this.refreshBillsByRateID(i.rateID,i.value);
             }
+            this.refreshCalProgramByRateID(rateMap);
             if(node){
                 if (node.sourceType==='ration' && calcProgramObj.sheet) {
                     calcProgramObj.refreshCalcProgram(node, 3);
@@ -304,12 +306,12 @@ var FeeRate = {
             project.calcProgram.compileAllTemps();
             calcProgramManage.refreshDetailSheet();
         }
-        FeeRate.prototype.refreshCalProgramByRateID=function (rateID,value) {
+        FeeRate.prototype.refreshCalProgramByRateID=function (rateMap) {
             var templates = project.calcProgram.datas.templates;
             for(var i =0;i<templates.length;i++){
                 _.forEach(templates[i].calcItems,function (item) {
-                    if(item.feeRateID==rateID){
-                        item.feeRate = value;
+                    if(rateMap[item.feeRateID]){
+                        item.feeRate = rateMap[item.feeRateID];
                     }
                 })
             }

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

@@ -20,10 +20,6 @@ const ModuleNames = {
 };
 
 let gljType = gljUtil.gljType;
-let gljTypeSeq =gljUtil.getGljTypeSeq(); /*[gljType.LABOUR,gljType.MAIN_MATERIAL,gljType.CONCRETE,gljType.MORTAR,gljType.MIX_RATIO,gljType.COMMERCIAL_CONCRETE,
-    gljType.COMMERCIAL_MORTAR,gljType.GENERAL_MATERIAL,gljType.OTHER_MATERIAL,gljType.GENERAL_MACHINE,gljType.INSTRUMENT,gljType.OTHER_MACHINE_USED,
-    gljType.MACHINE_COMPOSITION,gljType.MACHINE_LABOUR,gljType.FUEL_POWER_FEE,gljType.DEPRECIATION_FEE,gljType.INSPECTION_FEE,gljType.MAINTENANCE,
-    gljType.DISMANTLING_FREIGHT_FEE,gljType.VERIFICATION_FEE,gljType.OTHER_FEE,gljType.EQUIPMENT,gljType.MANAGEMENT_FEE,gljType.PROFIT,gljType.GENERAL_RISK_FEE];*/
 
 // 计算基数 [定额基价材料费] 要用到的材料类型。
 const baseMaterialTypes = [
@@ -281,7 +277,7 @@ let cpFeeTypes = [
     {type: 'marketLabour', name: '人工费'},
     {type: 'marketMaterial', name: '材料费'},
     {type: 'marketMachine', name: '施工机械使用费'},
-    {type: 'marketEquipment', name: '设备费'},
+    {type: 'marketEquipment', name: '设备购置费'},
     {type: 'marketDirect', name: '直接费'},
     {type: 'labour', name: '定额人工费'},
     {type: 'material', name: '定额材料费'},
@@ -295,8 +291,8 @@ let cpFeeTypes = [
     {type: 'force', name: '规费'},
     {type: 'profit', name: '利润'},
     {type: 'tax', name: '税金'},
-    {type: 'rationCommon', name: '定额建安费'},
-    {type: 'common', name: '建安费'}
+    {type: 'common', name: '建安费'},
+    {type: 'rationCommon', name: '定额建安费'}
     // {type: 'fee1', name: '费用1'},
     // {type: 'fee2', name: '费用2'}
 ];

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

@@ -591,9 +591,9 @@ var feeRateObject={
                          let lastRate = null;
                          temP.value = scMathUtil.roundForObj(value,getDecimal("feeRate")) ;
                          for(let v of valueMaps){
-                            if(parseFloat(v.value)<parseFloat(value)){
+                            if(parseFloat(v.ID)<parseFloat(value)){
                                 ltRate = v;
-                            }else if(parseFloat(v.value)>parseFloat(value)){
+                            }else if( gtRate==null && parseFloat(v.ID)>parseFloat(value)){
                                 gtRate = v;
                             }
                             lastRate = v;

+ 1 - 1
web/building_saas/main/js/views/glj_view.js

@@ -811,7 +811,7 @@ var gljOprObj = {
             }
             temRationGLJs.push(tem);
         }
-        temRationGLJs = gljUtil.sortRationGLJ(temRationGLJs);
+        temRationGLJs = gljUtil.sortMixRatio(temRationGLJs);
         return temRationGLJs;
     },
     showQuantityDetailData: function (node) {

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

@@ -92,6 +92,7 @@ projectGljObject={
         this.mixRatioSheet = this.mixRatioSpread .getSheet(0);
         this.initSheet(this.mixRatioSheet,this.mixRatioSetting);
         this.mixRatioSheet.name('mixRatioSheet');
+        this.mixRatioSheet.bind(GC.Spread.Sheets.Events.EditStarting,this.onMixRatioEditStarting);
         this.mixRatioSheet.bind(GC.Spread.Sheets.Events.RangeChanged, this.onMixRatioRangeChange);
         if(projectReadOnly){
             if(this.mixRatioSetting.view.lockColumns){
@@ -198,7 +199,7 @@ projectGljObject={
             for(let glj of data){
                 ratioList.push(me.getMixRatioSheetData(glj)) ;
             }
-            ratioList = gljUtil.sortRationGLJ(ratioList);
+            ratioList = gljUtil.sortMixRatio(ratioList);
             me.mixRatioData = ratioList;
             me.mixRatioSheet.setRowCount(0);
             sheetCommonObj.showData(me.mixRatioSheet, me.mixRatioSetting,me.mixRatioData);
@@ -345,6 +346,14 @@ projectGljObject={
             me.batchUpdateProjectGLJ(changeInfo,info.sheetName);
         }
     },
+    onMixRatioEditStarting:function (sender,info) {
+        let me = projectGljObject,row = info.row, col = info.col;
+        let parentSheet =  me.projectGljSpread.getActiveSheet();
+        let prow = parentSheet.getActiveRowIndex();//取父机械或组成物的下标
+        let prowData = parentSheet.name() == 'projectGljSheet'?me.projectGljSheetData[prow]:me.materialTree.items[prow].data;
+        console.log(prowData);
+        if(gljUtil.isConcreteType(prowData.type))  info.cancel = true;
+    },
     onMixRatioRangeChange:function (sender,info){
         let me = projectGljObject;
         let canChange = true;
@@ -705,6 +714,8 @@ projectGljObject={
                 data.bgColour = "#E0E0E0";
             }
         }
+        if(gljUtil.isConcreteType(glj.type)) data.bgColour = "#E0E0E0";//混凝土、砂浆、配合比的底色显示为 灰色#E0E0E0,灰色底色提醒用户不可修改。
+
         return data;
     },
     refreshProjectGljRow:function (row) {