Pārlūkot izejas kodu

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

TonyKang 6 gadi atpakaļ
vecāks
revīzija
2826fc5d49
40 mainītis faili ar 565 papildinājumiem un 248 dzēšanām
  1. 1 0
      modules/all_models/project_glj.js
  2. 1 1
      modules/all_models/ration.js
  3. 1 0
      modules/common/std/std_glj_lib_glj_list_model.js
  4. 3 4
      modules/glj/models/glj_list_model.js
  5. 2 2
      modules/main/facade/ration_facade.js
  6. 11 2
      modules/pm/facade/pm_facade.js
  7. 19 1
      modules/ration_glj/controllers/ration_glj_controller.js
  8. 2 9
      modules/ration_glj/facade/glj_calculate_facade.js
  9. 160 13
      modules/ration_glj/facade/ration_glj_facade.js
  10. 2 0
      modules/ration_glj/routes/ration_glj_route.js
  11. 6 1
      public/gljUtil.js
  12. 6 0
      public/web/scMathUtil.js
  13. 5 5
      public/web/tree_sheet/tree_sheet_helper.js
  14. 1 1
      web/building_saas/complementary_ration_lib/html/anzhuang.html
  15. 1 1
      web/building_saas/complementary_ration_lib/html/dinge.html
  16. 1 1
      web/building_saas/complementary_ration_lib/html/fuzhu.html
  17. 1 1
      web/building_saas/complementary_ration_lib/html/gongliao.html
  18. 1 1
      web/building_saas/complementary_ration_lib/js/coe.js
  19. 1 0
      web/building_saas/css/custom.css
  20. BIN
      web/building_saas/css/login-bg.jpg
  21. 26 4
      web/building_saas/css/main.css
  22. 7 0
      web/building_saas/glj/html/project_glj.html
  23. BIN
      web/building_saas/img/building.png
  24. 1 1
      web/building_saas/js/global.js
  25. 7 7
      web/building_saas/main/html/main.html
  26. 5 1
      web/building_saas/main/js/main.js
  27. 4 6
      web/building_saas/main/js/models/calc_base.js
  28. 74 57
      web/building_saas/main/js/models/calc_program.js
  29. 28 22
      web/building_saas/main/js/models/ration.js
  30. 2 3
      web/building_saas/main/js/models/ration_coe.js
  31. 64 9
      web/building_saas/main/js/models/ration_glj.js
  32. 41 18
      web/building_saas/main/js/views/glj_view.js
  33. 3 3
      web/building_saas/main/js/views/main_tree_col.js
  34. 2 2
      web/building_saas/main/js/views/project_property_indicativeInfo.js
  35. 56 61
      web/building_saas/main/js/views/project_view.js
  36. 8 3
      web/building_saas/main/js/views/std_billsGuidance_lib.js
  37. 2 2
      web/building_saas/pm/html/project-management.html
  38. 2 2
      web/common/html/header.html
  39. BIN
      web/dest/css/login-bg.jpg
  40. 8 4
      web/users/html/login.html

+ 1 - 0
modules/all_models/project_glj.js

@@ -102,6 +102,7 @@ let modelSchema = {
         type: Number,
         default: 1
     },
+    from:{type: String,default:'std'},//std, cpt  来自标准工料机库、补充工料机库
     //以下仅普通材料可用
     grossWeightCoe: Number, //毛重系数
     purchaseStorageRate: Number, //采购保管费率

+ 1 - 1
modules/all_models/ration.js

@@ -72,7 +72,7 @@ let rationSchema = new Schema({
 
     //工料机特有属性
     projectGLJID:Number,  //项目工料机ID
-    GLJID:Number,//工料机库ID
+    GLJID:Number,//工料机库对应的ID
     original_code:String, //原始编码
     specs:String,//规格型号
     shortName:String,//缩写

+ 1 - 0
modules/common/std/std_glj_lib_glj_list_model.js

@@ -84,6 +84,7 @@ class STDGLJLibGLJListModel extends BaseModel {
         for(let gljData of componentGljData) {
             gljData.connectCode = libGljData.code;
             gljData.consumption = componentConsume[gljData.ID];
+            gljData.from='std';
             componentData.push(gljData);
         }
 

+ 3 - 4
modules/glj/models/glj_list_model.js

@@ -606,7 +606,8 @@ class GLJListModel extends BaseModel {
                     grossWeightCoe:tmp.grossWeightCoe,
                     purchaseStorageRate:tmp.purchaseStorageRate,
                     offSiteTransportLossRate:tmp.offSiteTransportLossRate,
-                    handlingLossRate:tmp.handlingLossRate
+                    handlingLossRate:tmp.handlingLossRate,
+                    from:tmp.from
                 };
                 gljInsertData.push(gljData);
             }
@@ -771,7 +772,7 @@ class GLJListModel extends BaseModel {
             mixRatioData[m_index]=tmp;
         }
         // 查找对应的项目工料机数据
-        let gcondition = {project_id: glj.project_id,code: {"$in": codeList}, name: {"$in": nameList},specs:{"$in": specsList},type:{"$in": typeList},unit:{"$in": unitList} };
+        let gcondition = {project_id: glj.project_id?glj.project_id:glj.projectID,code: {"$in": codeList}, name: {"$in": nameList},specs:{"$in": specsList},type:{"$in": typeList},unit:{"$in": unitList} };
         let gljData = await this.findDataByCondition(gcondition, {_id: 0}, false);
 
         // 查找对应的单价数据
@@ -791,8 +792,6 @@ class GLJListModel extends BaseModel {
             let g_index =  this.getIndex(g,['code','name','specs','unit','type']);
             if(mixRatioData[g_index]) c_gljData.push(g);
         }
-
-
         return [c_gljData,mixRatioData,unitPriceData];
 
     }

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

@@ -339,7 +339,7 @@ function getCustomerCoeData() {
         { amount:1, operator:'*', gljCode:null, coeType:'人工'},
         { amount:1, operator:'*', gljCode:null, coeType:'材料'},
         { amount:1, operator:'*', gljCode:null, coeType:'机械'},
-        { amount:1, operator:'*', gljCode:null, coeType:'主材'},
+       /* { amount:1, operator:'*', gljCode:null, coeType:'主材'},*/
         { amount:1, operator:'*', gljCode:null, coeType:'设备'}
     ];
     return coeList;
@@ -351,7 +351,7 @@ async function getCustomerCoe(projectID,rationID,seq,compilation){//取自定义
     let lastCoe ={
         coeID:-1,
         name : '自定义系数',
-        content:'人工×1,材料×1,机械×1,主材×1,设备×1',
+        content:'人工×1,材料×1,机械×1,设备×1',//主材×1,
         isAdjust:1,
         seq:seq,
         rationID : rationID,

+ 11 - 2
modules/pm/facade/pm_facade.js

@@ -288,12 +288,21 @@ async function copyProjectSetting(originalID,newProjectID) {
 
 async function copyBills(newProjectID,billMap) {
      let uuidMaping = billMap.uuidMaping;//做ID映射
-    for(let doc of billMap.datas){
+     for(let doc of billMap.datas){
          doc.projectID = newProjectID;
          doc.ID = uuidMaping[doc.ID] ? uuidMaping[doc.ID] : -1;
          doc.ParentID = uuidMaping[doc.ParentID] ? uuidMaping[doc.ParentID] : -1;
          doc.NextSiblingID = uuidMaping[doc.NextSiblingID] ? uuidMaping[doc.NextSiblingID] : -1;
-    }
+         //对于有基数计算的节点,需要替换计算基数中引用的ID为新的ID
+         if(doc.calcBase && doc.calcBase != ""){
+             let idArr = scMathUtil.getFIDArr(doc.calcBase);
+             for(let re of idArr){
+                 let oID = re.substr(1);//去掉开头的@字符
+                 if(!uuidMaping[oID]) continue;
+                 doc.calcBase = doc.calcBase.replace(new RegExp(oID, "g"),uuidMaping[oID]);
+             }
+         }
+     }
     await insertMany(billMap.datas,billsModel);
     return billMap.datas;
 }

+ 19 - 1
modules/ration_glj/controllers/ration_glj_controller.js

@@ -15,7 +15,8 @@ module.exports={
     replaceGLJ:replaceGLJ,
     mReplaceGLJ:mReplaceGLJ,
     updateRationGLJByEdit:updateRationGLJByEdit,
-    getGLJClass:getGLJClass
+    getGLJClass:getGLJClass,
+    deleteRationGLJ:deleteRationGLJ
 }
 function createRationGLJ() {
     let gls = mongoose.model('ration_glj');
@@ -99,6 +100,23 @@ async function addGLJ(req, res){
     res.json(result);
 }
 
+async function deleteRationGLJ (req,res) {
+    let result={
+        error:0
+    }
+    try {
+        let data = req.body.data;
+        data = JSON.parse(data);
+        let datas= await ration_glj_facade.deleteRationGLJ(data);
+        result.data=datas;
+    }catch (err){
+        logger.err(err);
+        result.error=1;
+        result.message = err.message;
+    }
+    res.json(result);
+}
+
 async function replaceGLJ(req, res){
     let result={
         error:0

+ 2 - 9
modules/ration_glj/facade/glj_calculate_facade.js

@@ -42,7 +42,7 @@ let coeTypeMap = {
 };
 
 
-async function calculateQuantity(query,noNeedCal,refreshRationName = false){
+async function calculateQuantity(query,noNeedCal=null,refreshRationName = false){
     try {
          let  result ={
              glj_result:[],
@@ -68,8 +68,7 @@ async function calculateQuantity(query,noNeedCal,refreshRationName = false){
          for(let glj of gljList){//先把混凝土,砂浆,配合比有自定义消耗的挑出来
              if(gljUtil.isConcreteType(glj.type)&& !noCustomQuantiyt(glj)) await getMixRatioMap(glj,gljList,coeList,assList,mixRatioMap);
          }
-
-        gljList = sortRationGLJ(gljList);
+        gljList = gljUtil.sortRationGLJ(gljList);
         for(let i =0;i<gljList.length;i++ ){
             let r = await calculateQuantityPerGLJ(gljList[i],gljList,coeList,assList,adjustState,mixRatioMap,noNeedCal);
             result.glj_result.push(r);
@@ -133,12 +132,6 @@ function generateUpdateTasks(result) {
     return tasks;
 }
 
-function sortRationGLJ(list) {
-    list = _.sortByAll(list, [function (item) {
-        return gljUtil.getMainType(item.type);
-    }, "code"])
-    return list;
-}
 
 async function calcWhenNoCustomQuantiyt(decimal,glj,gljList,coeList,assList) {
     let quantity = glj.rationItemQuantity ? scMathUtil.roundTo(parseFloat(glj.rationItemQuantity),-decimal):0;

+ 160 - 13
modules/ration_glj/facade/ration_glj_facade.js

@@ -28,6 +28,9 @@ const stdGljModel = mongoose.model('std_glj_lib_gljList');
 const gljClassModel = mongoose.model('std_glj_lib_gljClass');
 const projectDao = require('../../pm/models/project_model').project;
 const compleClassModel = mongoose.model('complementary_glj_section');
+let gljUtil = require('../../../public/gljUtil');
+
+
 
 module.exports = {
     save: save,
@@ -38,6 +41,7 @@ module.exports = {
     getGLJData: getGLJData,
     getGLJDataByCodes:getGLJDataByCodes,
     addGLJ: addGLJ,
+    deleteRationGLJ:deleteRationGLJ,
     deleteGLJ:deleteGLJ,
     insertAddTypeGLJ:insertAddTypeGLJ,
     replaceGLJ: replaceGLJ,
@@ -636,8 +640,9 @@ async function addGLJ(rgList,compilation) {
 }
 
 async function insertAddTypeGLJ(rgList,compilation) {
-    let newRecodes = [];
+    let newRecodes = [],GLJMap=null;
     let [unitFileId,ext] = await  prepareExtData(rgList[0].projectID,compilation);
+
     for (let g of rgList) {
         let projectGljModel = new GLJListModel();
         let result = await projectGljModel.addList(getGLJSearchInfo(g),unitFileId,ext);
@@ -653,6 +658,14 @@ async function insertAddTypeGLJ(rgList,compilation) {
         g.ID = uuidV1();
         if (result.hasOwnProperty('subList') && result.subList.length > 0) {
             g.subList = getMixRatioShowDatas(result.subList);
+            //对于混凝土,砂浆,配合比,组成物还要插入定额工料机
+            if(gljUtil.isConcreteType(g.type)){
+                if(GLJMap == null){
+                    let oldGLJList = await ration_glj.find({'rationID':g.rationID});
+                    GLJMap = _.indexBy(oldGLJList,"projectGLJID");
+                }
+                addMixRatioToRationGLJ(g,result.subList,newRecodes,GLJMap);
+            }
         }
         newRecodes.push(createNewRecord(g));
     }
@@ -660,6 +673,80 @@ async function insertAddTypeGLJ(rgList,compilation) {
     return newRecodes;
 }
 
+async function deleteRationGLJ(data){
+    let deleteIDs = [data.ID];
+    if(gljUtil.isConcreteType(data.type)){//如果是混凝土、砂浆、配合比,还要删除没有被引用的组成物工料机
+        let projectGljModel = new GLJListModel();
+        let rationGLJList = await ration_glj.find({'rationID':data.rationID});
+        let unitFileId  = await projectDao.getUnitPriceFileId(data.projectID);
+        let projectGLJMap = {},referenceMap={};
+        let deleteMix = [];
+        for(let r of rationGLJList){
+            projectGLJMap[r.projectGLJID] = r;
+            if(gljUtil.isConcreteType(r.type)){
+                if(r.ID == data.ID){//是要删除的工料机
+                    deleteMix = await projectGljModel.getCompositionGLJByData(r,unitFileId);
+                }else {
+                    let comList = await projectGljModel.getCompositionGLJByData(r,unitFileId);
+                    for(let c of comList){
+                        referenceMap[c.id] = c;
+                    }
+                }
+            }
+        }
+        for(let d of deleteMix){
+            //删除不属于其它的组成物并且定额消耗为0
+            if(referenceMap[d.id]) continue;
+            if(projectGLJMap[d.id]&&(projectGLJMap[d.id].rationItemQuantity == '0'||projectGLJMap[d.id].rationItemQuantity == 0)){
+                deleteIDs.push(projectGLJMap[d.id].ID);
+            }
+        }
+        await ration_glj.deleteMany({'ID': {"$in": deleteIDs}});
+    } else{
+        await ration_glj.deleteOne({ID:data.ID});
+    }
+    let calcResult = await glj_calculate_facade.calculateQuantity({
+        projectID: data.projectID,
+        rationID: data.rationID
+    });
+    calcResult.deleteList = deleteIDs;
+    return calcResult;
+}
+
+
+function addMixRatioToRationGLJ(g,subList,newRecodes,GLJMap){
+    let newMap = {};
+    for(let mr of subList ){
+        //先查找该定额下是否已经有了工料机了,有就不用再插入了
+        newMap[mr.id] = mr;//新增的定额工料机映射表
+        if(GLJMap[mr.id]||_.find(newRecodes,{'projectGLJID':mr.id})) continue;
+        //没有的情况下,生成一条定额工料机计录
+        let newMr = {
+            projectID:g.projectID,
+            GLJID:mr.glj_id,
+            rationID:g.rationID,
+            rationItemQuantity:0,
+            quantity:0,
+            name:mr.name,
+            code:mr.code,
+            original_code:mr.original_code,
+            unit:mr.unit,
+            specs:mr.specs,
+            from:mr.from,
+            createType:g.createType,
+            shortName:mr.unit_price.short_name,
+            billsItemID:g.billsItemID,
+            type:mr.type,
+            model:mr.model,
+            repositoryId:g.repositoryId,
+            projectGLJID:mr.id,
+            adjCoe:mr.adjCoe
+        };
+        newMr.ID = uuidV1();
+        newRecodes.push(newMr);
+    }
+    return newMap;
+}
 
 async  function replaceGLJByData(data,compilation) {
     let projectGljModel = new GLJListModel();
@@ -667,7 +754,8 @@ async  function replaceGLJByData(data,compilation) {
     let result = await projectGljModel.addList(getGLJSearchInfo(data),unitFileId,ext);
     let typeString = result.type+'';
     data.projectGLJID = result.id;
-
+    //  CompositionGLJ=await this.getCompositionGLJByData(data,unitPriceFileId);
+    let [newRecodes,deleteList] = await replaceMixRatio(data,result,unitFileId);
     let updateResult = await ration_glj.findOneAndUpdate({ID: data.ID, projectID: data.projectID}, data);//更新定额工料机
     //组装回传数据
     data.marketPrice = result.unit_price.market_price;
@@ -680,24 +768,75 @@ async  function replaceGLJByData(data,compilation) {
     if (result.hasOwnProperty('subList') && result.subList.length > 0) {
         data.subList = getMixRatioShowDatas(result.subList);
     }
-    return data;
+    return {data:data,newRecodes:newRecodes,deleteList:deleteList};
 }
 
+async function replaceMixRatio(g,result,unitFileId){
+    let newRecodes=[],deleteList = [];
+    if(gljUtil.isConcreteType(g.type)){//相同类型的才能替换,所以判断一个就好了
+        let IDMap = {}, projectGLJMap = {},referenceMap={},concreteList=[],newMap={};
+        let projectGljModel = new GLJListModel();
+        let rationGLJList = await ration_glj.find({'rationID':g.rationID});
+        for(let r of rationGLJList){
+            IDMap[r.ID] = r;
+            projectGLJMap[r.projectGLJID] = r;
+            if(gljUtil.isConcreteType(r.type)&&r.ID!=g.ID) concreteList.push(r) //除了本身,记录一下其它混凝土类型
+        }
+        if (result.hasOwnProperty('subList') && result.subList.length > 0){
+            newMap =  addMixRatioToRationGLJ(g,result.subList,newRecodes,projectGLJMap);//先生成要添加的工料机
+        }
+        let oldMixList = await projectGljModel.getCompositionGLJByData(IDMap[g.ID],unitFileId);
+        for(let c of concreteList){//找出要删除的子定额工料机(没人引用,并且定额消耗量为0)
+            let temList = await projectGljModel.getCompositionGLJByData(c,unitFileId);
+            for(let t of temList){
+                referenceMap[t.id] = t;
+            }
+        }
+        for(let o of oldMixList){
+            if(newMap[o.id]||referenceMap[o.id]) continue;//如果两个地方有一个存在,那么就不用删除
+            //没有被其它地方引用并且定额消耗量为0,就删除对应的定额工料机
+            if(projectGLJMap[o.id] && (projectGLJMap[o.id].rationItemQuantity == '0'||projectGLJMap[o.id].rationItemQuantity == 0)) deleteList.push(projectGLJMap[o.id].ID)
+        }
+    }
+
+    if(deleteList.length > 0) await ration_glj.deleteMany({'ID': {"$in": deleteList}});//删除定额工料机
+    if(newRecodes.length > 0)  await ration_glj.insertMany(newRecodes);
+    return [newRecodes,deleteList]
+}
 
 async function replaceGLJ(data,compilation) {
     let rdata = {};
-    data = await  replaceGLJByData(data,compilation);
+    let r_result =await replaceGLJByData(data,compilation);
+    data = r_result.data;
     let stateResult = await glj_calculate_facade.calculateQuantity({
         projectID: data.projectID,
         rationID: data.rationID
-    }, true,true);
+    }, null,true);
     rdata.data = data;
     rdata.adjustState = stateResult.adjustState;
     rdata.name = stateResult.rationName;
+    rdata.newRecodes = r_result.newRecodes;
+    rdata.deleteList = r_result.deleteList;
+    rdata.glj_result = stateResult.glj_result;
     return rdata;
 }
+
+async function replaceMixRatioForMReplace(tasks,result,unitFileId) {
+    let allNewRecodes = [],allDeleteList=[];
+    for(let t of tasks){
+        let tem = _.cloneDeep(t.updateOne.update);
+        tem.ID = t.updateOne.filter.ID;
+        tem.rationID = t.updateOne.filter.rationID;
+        delete t.updateOne.filter.rationID;
+        let [newRecodes,deleteList] = await replaceMixRatio(tem,result,unitFileId);
+        allNewRecodes = allNewRecodes.concat(newRecodes);
+        allDeleteList = allDeleteList.concat(deleteList);
+    }
+    return {newRecodes:allNewRecodes,deleteList:allDeleteList}
+}
+
 async function mReplaceGLJ(data,compilation) {
-    let mresult = {};
+    let mresult = {},mixResult = null,noNeedCal=true;
     let projectGljModel = new GLJListModel();
     let [unitFileId,ext] = await prepareExtData(data.doc.projectID,compilation);
     //
@@ -705,12 +844,16 @@ async function mReplaceGLJ(data,compilation) {
     let typeString = result.type+'';
     let newDoc = {};
     newDoc.projectGLJID = result.id;
-    let rationList = await ration_glj.distinct('rationID', data.query);
+    let rationList = [];//await ration_glj.distinct('rationID', data.query);
     for(let t of data.tasks){
+        rationList.push(t.updateOne.filter.rationID);
         t.updateOne.update.projectGLJID = result.id;//更新项目工料机ID
     }
+    if(gljUtil.isConcreteType(result.unit_price.type)) {
+        mixResult = await replaceMixRatioForMReplace(data.tasks,result,unitFileId);
+        noNeedCal = null;
+    }
     await ration_glj.bulkWrite(data.tasks);
-    //let updateResult = await ration_glj.update(data.query, data.doc, {multi: true});
 
     newDoc.marketPrice = result.unit_price.market_price;
     newDoc.adjustPrice = result.unit_price.base_price;
@@ -722,10 +865,13 @@ async function mReplaceGLJ(data,compilation) {
     if (result.hasOwnProperty('subList') && result.subList.length > 0) {
         newDoc.subList = getMixRatioShowDatas(result.subList);
     }
-    let stateList = await changAdjustState(data, rationList);
+    let [stateList,glj_result] = await changAdjustState(data, rationList,noNeedCal);
     data.doc = newDoc;
     mresult.data = data;
     mresult.stateList = stateList;
+    mresult.newRecodes = mixResult?mixResult.newRecodes:[];
+    mresult.deleteList = mixResult?mixResult.deleteList:[];
+    mresult.glj_result = glj_result;
     return mresult
 }
 
@@ -850,18 +996,19 @@ async function  getRationTypeGLJQuantity(projectID) {
     return rations;
 }
 
-async function changAdjustState(data, rationList) {
-    let stateList = [];
+async function changAdjustState(data, rationList,noNeedCal) {
+    let stateList = [],glj_result=[];
     for (let r of rationList) {
         let stateResult = await glj_calculate_facade.calculateQuantity({
             projectID: data.query.projectID,
             rationID: r
-        }, true,true);
+        }, noNeedCal,true);
         if(stateResult){
             stateList.push({rationID: r, adjustState: stateResult.adjustState,name:stateResult.rationName});
+            glj_result = glj_result.concat(stateResult.glj_result)
         }
     }
-    return stateList;
+    return [stateList,glj_result];
 }
 
 async function getGLJDataByCodes(data,compilation) {

+ 2 - 0
modules/ration_glj/routes/ration_glj_route.js

@@ -15,6 +15,8 @@ module.exports = function (app) {
     rgRouter.post('/mReplaceGLJ',rgController.mReplaceGLJ);
     rgRouter.post('/updateRationGLJByEdit',rgController.updateRationGLJByEdit);
     rgRouter.post('/getGLJClass/:engineerID', rgController.getGLJClass);
+    rgRouter.post('/deleteRationGLJ', rgController.deleteRationGLJ);
+
     app.use('/rationGlj',rgRouter);
 }
 

+ 6 - 1
public/gljUtil.js

@@ -18,7 +18,8 @@ module.exports = {
     getAdjustPrice:getAdjustPrice,
     getMainType:getMainType,
     isConcreteType:isConcreteType,
-    getIndex:getIndex
+    getIndex:getIndex,
+    sortRationGLJ:sortRationGLJ
 };
 
 function calcProjectGLJQuantity(projectGLJDatas,rationGLJDatas,rationDatas,billsDatas,q_decimal) {
@@ -54,4 +55,8 @@ function getIndex(obj, pops) {
 
 function isConcreteType(type) {
     return gljNodeUtil.isConcreteType(type);
+}
+
+function sortRationGLJ(type) {
+    return gljNodeUtil.sortRationGLJ(type);
 }

+ 6 - 0
public/web/scMathUtil.js

@@ -209,6 +209,12 @@ let scMathUtil = {
     },
     isDef:function (v) {
         return v !== undefined && v !== null;
+    },
+    //获取ID引用
+    getFIDArr: function (exp) {
+        let fidRex = /@[\d,a-z,A-Z,-]{36}/g;
+        let fidArr = exp.match(fidRex);
+        return this.isDef(fidArr) ? fidArr : [];
     }
 };
 

+ 5 - 5
public/web/tree_sheet/tree_sheet_helper.js

@@ -727,11 +727,11 @@ var TREE_SHEET_HELPER = {
                 ctx.clearRect(x, y, w, h);
             }
             GC.Spread.Sheets.CellTypes.Text.prototype.paint.apply(this, arguments);
-            if(this.editingCell && hasData(options.row)){
+          /*  if(this.editingCell && hasData(options.row)){ 2019-02-22 图片显示隐藏
                 let centerX = Math.floor(x) + w - 20;
                 let centerY = Math.floor((y + (y + h)) / 2);
                 ctx.drawImage(img, centerX + 3, centerY - 7, imgWidth,imgHeight);
-            }
+            }*/
         };
         QuestionCellType.prototype.getHitInfo = function (x, y, cellStyle, cellRect, context) {
             return {
@@ -745,8 +745,8 @@ var TREE_SHEET_HELPER = {
             };
         };
         QuestionCellType.prototype.processMouseDown = function (hitinfo) {
-            //弹出说明等窗口
-            if(this.editingCell && this.editingCell.row === hitinfo.row){
+            //弹出说明等窗口  2019-02-22 图片显示隐藏,去掉弹出提示
+        /*    if(this.editingCell && this.editingCell.row === hitinfo.row){
                 let offSet = hitinfo.cellRect.x + hitinfo.cellRect.width;
                 if(hitinfo.x < offSet && hitinfo.x > offSet - imgWidth){
                     if(mouseDownCallback && hasData(hitinfo.row)) {
@@ -754,7 +754,7 @@ var TREE_SHEET_HELPER = {
                     }
                     //$('#rationQuestionModal').modal('show');
                 }
-            }
+            }*/
         };
         QuestionCellType.prototype.processMouseEnter = function (hitinfo){
             if(this.editingCell==null){

+ 1 - 1
web/building_saas/complementary_ration_lib/html/anzhuang.html

@@ -38,7 +38,7 @@
                       <a class="nav-link px-3" id="dinge" href="<%= redirectRation %>">定额</a>
                   </li>
                   <li class="nav-item">
-                      <a class="nav-link px-3" id="gongliao" href="<%= redirectGlj %>">人材机</a>
+                      <a class="nav-link px-3" id="gongliao" href="<%= redirectGlj %>">工料机</a>
                   </li>
                   <!--<li class="nav-item">
                       <a class="nav-link px-3" id="fuzhu" href="<%= redirectCoe %>">子目换算</a>

+ 1 - 1
web/building_saas/complementary_ration_lib/html/dinge.html

@@ -68,7 +68,7 @@
                 <a class="nav-link active px-3" id ="dinge" >定额</a>
             </li>
             <li class="nav-item">
-                <a class="nav-link px-3" id="gongliao" href="<%= redirectGlj %>">人材机</a>
+                <a class="nav-link px-3" id="gongliao" href="<%= redirectGlj %>">工料机</a>
             </li>
             <!--<li class="nav-item">
                 <a class="nav-link px-3" id="fuzhu" href="<%= redirectCoe %>">子目换算</a>

+ 1 - 1
web/building_saas/complementary_ration_lib/html/fuzhu.html

@@ -40,7 +40,7 @@
                       <a class="nav-link px-3" id="drirect-dinge" href="<%= redirectRation %>">定额</a>
                   </li>
                   <li class="nav-item">
-                      <a class="nav-link px-3" id="gongliao" href="<%= redirectGlj %>">人材机</a>
+                      <a class="nav-link px-3" id="gongliao" href="<%= redirectGlj %>">工料机</a>
                   </li>
                   <!--<li class="nav-item">
                       <a class="nav-link active px-3">子目换算</a>

+ 1 - 1
web/building_saas/complementary_ration_lib/html/gongliao.html

@@ -43,7 +43,7 @@
                       <a class="nav-link px-3" id="drirect-dinge" href="<%= redirectRation %>">定额</a>
                   </li>
                   <li class="nav-item">
-                      <a class="nav-link active px-3">人材机</a>
+                      <a class="nav-link active px-3">工料机</a>
                   </li>
                 <!--  <li class="nav-item">
                       <a class="nav-link px-3" id="fuzhu" href="<%= redirectCoe %>">子目换算</a>

+ 1 - 1
web/building_saas/complementary_ration_lib/js/coe.js

@@ -515,7 +515,7 @@ let gljAdjOprObj = {
         ],
         comboItems: {
             //调整类型下拉菜单
-            coeType: ['定额', '人工', '材料', '机械', '主材', '设备', '单个工料机'],
+            coeType: ['定额', '人工', '材料', '机械',  '设备', '单个工料机'],
             //操作符下拉菜单
             operator: ['+', '-', '*', '/', '=']
         }

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

@@ -270,6 +270,7 @@ legend.legend{
 #esInput{
     font-size:13px;
     color: black;
+    height: 100%;
 }
 .ration_glj_spread{
     width: 83%;

BIN
web/building_saas/css/login-bg.jpg


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

@@ -26,6 +26,28 @@ a{
     text-indent:26px;
 }
 /*自定义css*/
+.login-body,.login-html{
+    height:100%;
+}
+.login-bg{
+    width: 100%;
+    height: 100%;
+    background: #f2f6f5 url("login-bg.jpg") bottom center no-repeat;
+    background-size: 100% auto;
+    display: inline-block;
+    position: absolute;
+}
+.login-panel {
+    width: 500px;
+    margin: 0 auto;
+    position: absolute;
+    left: 0;
+    right: 0;
+    top: 20%;
+    padding:30px;
+    background:#fff;
+    box-shadow:#333 1px 1px 5px
+}
 .header {
     border-bottom: 1px solid #ccc
 }
@@ -48,6 +70,10 @@ a{
     font-size:16px;
     color:#ff6501;
 }
+.header-logo div.b-title{
+    font-size:24px;
+    color:#ff6501;
+}
 .top-msg{
     position: fixed;
     top:10px;
@@ -366,10 +392,6 @@ a{
 .rn-nav .nav-tabs .nav-link.active span{
     display: inline-block;
 }
-.form-signin {
-    max-width: 500px;
-    margin: 150px auto;
-}
 .poj-list, .side-content ,.form-view{
     overflow: auto;
 }

+ 7 - 0
web/building_saas/glj/html/project_glj.html

@@ -8,7 +8,14 @@
         <label class="mx-2">使用单价文件:<span id="current-name"></span>(<label class="a_color" id="pop-used-list" data-original-title="" title="">与<span id="used-project-count">0</span>个单位工程同步</label>)
             <a class="btn btn-sm ml-1" href="#" data-toggle="modal" data-target="#change-unitFile"><i class="fa fa-exchange"></i> 选择其他</a>
             <a class="btn btn-sm ml-1" href="#" data-toggle="modal" data-target="#unitFile-save-as"><i class="fa fa-files-o"></i> 另存单独用</a></label>
+        <!--<div class="input-group input-group-sm mr-2">
+            <select class="form-control form-control-sm">
+                <option>车船税标准</option>
+                <option>福建车船税标准(2012)</option>
+            </select>
+        </div>-->
     </div>
+
 </div>
 
 <div class="container-fluid">

BIN
web/building_saas/img/building.png


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

@@ -63,7 +63,7 @@ $(function () {
     /*工具提示*/
     $(function () {
         $('[data-toggle="tooltip"]').tooltip();
-        $('[data-submenu]').submenupicker();
+        if( $('[data-submenu]').submenupicker) $('[data-submenu]').submenupicker();
         $('[data-toggle="tooltip"]').click(function () {
             $(this).tooltip('hide');
         })

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

@@ -161,7 +161,7 @@
                           </li>
 
                           <li class="nav-item dropdown">
-                              <a class="nav-link dropdown-toggle more" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">更多</a>
+                              <a class="nav-link dropdown-toggle more" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false" style="display:none">更多</a>
                               <div class="dropdown-menu" id="div_more_dropdown_right">
                                   <!--<a class="dropdown-item  right-nav-link"  href="javascript:void(0)" id = 'locateTab' relaPanel="#locate">查找定位</a>-->
                                   <!--<a class="dropdown-item" data-toggle="tab" href="#sqpz" role="tab">书签批注</a>-->
@@ -255,8 +255,8 @@
                                           <div class=" main-data-bottom ovf-hidden col-auto p-0" id="gljItemTab" style="width: 30px">
                                               <div class="rn-nav d-flex align-items-start flex-column gljSubTab">
                                                   <div id="zmhs_toogle">
-                                                      <div class="d-flex align-items-start flex-column" data-toggle="tooltip" data-placement="left" title="" data-original-title="打开子目换算">
-                                                          <span class="mt-3 ml-2 text-primary">子目换算</span>
+                                                      <div class="d-flex align-items-start flex-column" data-toggle="tooltip" data-placement="left" title="" data-original-title="打开定额调整">
+                                                          <span class="mt-3 ml-2 text-primary">定额调整</span>
                                                           <i class="fa fa-arrow-left mt-auto mb-3 text-primary ml-2"></i>
                                                       </div>
                                                   </div>
@@ -662,9 +662,9 @@
                                 <!--关于计算-->
                                 <div class="tab-pane fade" id="poj-settings-4" role="tabpanel">
                                     <div class="modal-auto-height">
-                                        <fieldset class="form-group">
+                                        <fieldset class="form-group" style="display:none">
                                             <h5>取费方式</h5>
-                                            <div class="form-check" style="display:none">
+                                            <div class="form-check">
                                                 <label class="form-check-label">
                                                     <input class="form-check-input" name="calcFlag" id="rationContent" value="0" type="radio">
                                                     子目含量取费
@@ -677,12 +677,12 @@
                                                 </label>
                                             </div>
                                             <div class="form-check">
-                                                <label class="form-check-label">
+                                                <label class="form-check-label" >
                                                     <input class="form-check-input" name="calcFlag" id="rationPrice" value="2" type="radio">
                                                     子目单价取费(正算):清单综合合价=∑子目综合合价
                                                 </label>
                                             </div>
-                                            <div class="form-check" style="display:none">
+                                            <div class="form-check">
                                                 <label class="form-check-label">
                                                     <input class="form-check-input" name="calcFlag" id="billsPrice" value="3" type="radio">
                                                     清单单价取费

+ 5 - 1
web/building_saas/main/js/main.js

@@ -6,8 +6,12 @@ $(function () {
 
     $("#header-menu").removeAttr('style');
 
-    if (projectInfoObj.projectInfo.property.valuationType == 'bill')
+    if (projectInfoObj.projectInfo.property.valuationType == 'bill'){
         $("#tab_tender_price").css('display', 'none');
+    }
+    else{
+        $("#about-calc").css('display', 'none');
+    };
 
     $('#tab_baobiao').on('shown.bs.tab', function (e) {
         $(e.relatedTarget.hash).removeClass('active');

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

@@ -504,13 +504,13 @@ let baseFigureTemplate = {
                 deductFlags = [fixedFlag.EQUIPMENT_ACQUISITION_FEE, fixedFlag.SPECIAL_COST];
             return cbTools.getFeeWithDeduction(fixedFlag.CONSTRUCTION_INSTALL_FEE, deductFlags, fullFeeField).toDecimal(decimalObj.bills.totalPrice);
         },
-        //{定额建筑安装工程(其中定额设备购置费按 40%计)} (不含专项费用) (定额建筑安装工程设备四十)
+        //{定额建筑安装工程(其中定额设备购置费按 40%计)} (定额建筑安装工程设备四十)
         //扣除设备购置费,再加上设备购置费的40%,扣除汇总算法不四舍五入,相当于汇总当中定额设备购置费就按照了40%计
         'DEJZAZGCSBSS': function (tender) {
             let feeField = 'rationCommon',
                 subFeeField = tender ? 'tenderTotalFee' : 'totalFee',
-                deductFlags = [fixedFlag.EQUIPMENT_ACQUISITION_FEE, fixedFlag.SPECIAL_COST];
-            //建安费扣除定额设备购置费、专项费用
+                deductFlags = [fixedFlag.EQUIPMENT_ACQUISITION_FEE];
+            //建安费扣除定额设备购置费
             let afterDeductFee = cbTools.getFeeWithDeduction(fixedFlag.CONSTRUCTION_INSTALL_FEE, deductFlags, `${feeField}.${subFeeField}`);
             //定额设备购置费
             let equipmentAcFee = cbTools.getBillsFee(deductFlags[0], feeField, subFeeField);
@@ -1042,9 +1042,7 @@ let cbParser = {
     },
     //获取ID引用
     getFIDArr: function (exp) {
-        let fidRex = /@[\d,a-z,A-Z,-]{36}/g;
-        let fidArr = exp.match(fidRex);
-        return cbTools.isDef(fidArr) ? fidArr : [];
+        return scMathUtil.getFIDArr(exp);//统一前后端调用方法
     },
     //获取表达式中的中文式
     getCN: function(expr){

+ 74 - 57
web/building_saas/main/js/models/calc_program.js

@@ -49,7 +49,7 @@ let calcTools = {
     },
     isTotalCostBill: function (treeNode) {
         return treeNode.data.flagsIndex && treeNode.data.flagsIndex.fixed && treeNode.data.flagsIndex.fixed.flag &&
-            treeNode.data.flagsIndex.fixed.flag == fixedFlag.ENGINEERINGCOST;
+            treeNode.data.flagsIndex.fixed.flag == fixedFlag.TOTAL_COST;
     },
     isRationCategory: function(treeNode){
         return treeNode.sourceType === ModuleNames.ration;
@@ -182,9 +182,15 @@ let calcTools = {
                 'tenderUnitFee': 0,
                 'tenderTotalFee': 0
             };
-            treeNode.data.fees.push(fee);
+
+            let newArr = treeNode.data.fees.filter(function (ele) {return ele.fieldName == fieldName});
+            if (newArr.length > 0)
+                fee = newArr[0]
+            else
+                treeNode.data.fees.push(fee);
+
             treeNode.data.feesIndex[fieldName] = fee;
-            treeNode.updateData.fees = _.cloneDeep(treeNode.data.fees);
+            treeNode.updateData.fees = treeNode.data.fees;
             treeNode.changed = true;
         };
     },
@@ -496,17 +502,20 @@ let calcTools = {
             (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.MAIN_MATERIAL && calcTools.inBase(baseName, 'ZCF'))) {
+            let nodeQ = calcTools.uiNodeQty(treeNode) ? calcTools.uiNodeQty(treeNode) : 0;
             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
             }
+            else if (treeNode.data.type == rationType.gljRation){
+                let prc = 0;
+                if (treeNode.data.subType === gljType.EQUIPMENT && calcTools.inBase(baseName, 'SC_SBF'))
+                    prc = gljOprObj.getMarketPrice(treeNode)
+                else
+                    prc = gljOprObj.getBasePrice(treeNode);
+                result = (prc * nodeQ).toDecimal(decimalObj.ration.unitPrice);
+            }
 
-            else if (treeNode.data.type == rationType.gljRation)
-            // result = treeNode.data.basePrice ? parseFloat(treeNode.data.basePrice).toDecimal(decimalObj.ration.unitPrice) : 0;
-            // 这里因为是算基数所以要取基价,但不能直接取basePrice,受限于项目属性的三个选项。
-                result = gljOprObj.getBasePrice(treeNode);
         }
         else if (treeNode.data.subType === gljType.GENERAL_MACHINE && calcTools.inBase(baseName, 'JSRGF')) {
             let glj = {
@@ -643,9 +652,9 @@ let calcTools = {
         else if (this.isLeafBill(treeNode)) {
             if (treeNode.children && treeNode.children.length > 0){
                 // 清单单价计算模式下的叶子清单:取自己的计算程序ID,找到自己的计算程序计算。(汇总清单所有定额的工料机)
-                if (projectObj.project.property.billsCalcMode === leafBillGetFeeType.billsPrice)
-                    return treeNodeCalcType.ctBillCalcProgram;
-                else                                        // 前三种计算模式下的叶子清单:汇总定额的计算程序的费用类别
+                // if (projectObj.project.property.billsCalcMode === leafBillGetFeeType.billsPrice)
+                //     return treeNodeCalcType.ctBillCalcProgram;
+                // else                                        // 前三种计算模式下的叶子清单:汇总定额的计算程序的费用类别
                     return treeNodeCalcType.ctGatherRationsFees;
             }
             else{                                          // 公式计算
@@ -1594,10 +1603,6 @@ class CalcProgram {
         let nQ = calcTools.uiNodeQty(treeNode);
         let nTQ = calcTools.uiNodeTenderQty(treeNode);
 
-        function isBaseFeeType(type){
-            return ['labour', 'material', 'machine', 'mainMaterial', 'equipment'].indexOf(type) > -1;
-        };
-
         /*删掉多余的费用。例如:从其它计算方式(有很多费)切换到公式计算方式(只需要common费),多出来的费要删除。
         fieldNameArr 值取自:遍历treeNode的计算规则,取有绑定的字段名。这些字段名以外的fee是因旧计算多出来的,需要删除。 */
         function deleteUselessFees(treeNode, fieldNameArr){
@@ -1669,36 +1674,29 @@ class CalcProgram {
                             rtf = parseFloatPlus(node.data.feesIndex[ft.type].totalFee).toDecimal(decimalObj.bills.totalPrice);
                             rttf = parseFloatPlus(node.data.feesIndex[ft.type].tenderTotalFee).toDecimal(decimalObj.bills.totalPrice);
                         };
-                        // 取费方式为子目含量,清单行/列的XX单价应 =ROUND( ∑ROUND(定额XX单价*含量,清单单价精度),清单单价精度)
-                        if (me.project.property.billsCalcMode === leafBillGetFeeType.rationContent) {
-                            buf = (buf + (ruf * parseFloatPlus(node.data.contain)).toDecimal(decimalObj.bills.unitPrice)).toDecimal(decimalObj.process);
-                            node.data.tenderContaion = (node.data.tenderQuantity / bq).toDecimal(decimalObj.decimal.process);
-                            btuf = (btuf + (rtuf * parseFloatPlus(node.data.tenderContaion)).toDecimal(decimalObj.bills.unitPrice)).toDecimal(decimalObj.process);
-                        };
+
                         sum_rtf = (sum_rtf + rtf).toDecimal(decimalObj.process);
                         sum_rttf = (sum_rttf + rttf).toDecimal(decimalObj.process);
                     };
 
-                    if (me.project.property.billsCalcMode == leafBillGetFeeType.rationPriceConverse ||
-                        me.project.property.billsCalcMode == leafBillGetFeeType.rationPrice) {
-                        buf = (sum_rtf / bq).toDecimal(decimalObj.process);
-                        btuf = (sum_rttf / btq).toDecimal(decimalObj.process);
+                    buf = (sum_rtf / bq).toDecimal(decimalObj.process);
+                    btuf = (sum_rttf / btq).toDecimal(decimalObj.process);
+                    btf = sum_rtf;
+                    bttf = sum_rttf;
+
+                    if (projectObj.project.property.valuationType != 'bill') {  // 招投标项目, 还要反算
+                        buf = buf.toDecimal(decimalObj.bills.unitPrice);
+                        btuf = btuf.toDecimal(decimalObj.bills.unitPrice);
+                        btf = (buf * nQ).toDecimal(decimalObj.bills.totalPrice);
+                        bttf = (btuf * nQ).toDecimal(decimalObj.bills.totalPrice);
                     };
-                    // if (isBaseFeeType(ft.type) ||
-                    //     (me.project.property.billsCalcMode === leafBillGetFeeType.rationPrice && ft.type == "common")){
-                        btf = sum_rtf;
-                        bttf = sum_rttf;
-                    // }
-                    // else{
-                    //     btf = (buf.toDecimal(decimalObj.bills.unitPrice) * bq).toDecimal(decimalObj.process);
-                    //     bttf = (btuf.toDecimal(decimalObj.bills.unitPrice) * btq).toDecimal(decimalObj.process);
-                    // };
                 };
 
-                ftObj.totalFee = btf.toDecimal(decimalObj.bills.totalPrice);
-                ftObj.tenderTotalFee = bttf.toDecimal(decimalObj.bills.totalPrice);
                 ftObj.unitFee = buf.toDecimal(decimalObj.bills.unitPrice);
                 ftObj.tenderUnitFee = btuf.toDecimal(decimalObj.bills.unitPrice);
+                ftObj.totalFee = btf.toDecimal(decimalObj.bills.totalPrice);
+                ftObj.tenderTotalFee = bttf.toDecimal(decimalObj.bills.totalPrice);
+
 
                 calcTools.checkFeeField(treeNode, ftObj);
 
@@ -1731,23 +1729,40 @@ class CalcProgram {
                 treeNode.changed = true;
             };
 
-            // 第1、2部分以外的叶子清单在没有公式的情况下可以手工修改综合单价并参与计算。
-            // 2017-09-27 需求改了,除了第 1 、 2.2部分以外,都可以手工修改综合单价、综合合价并参与计算
-            if(!calcTools.isFBFX(treeNode) && !calcTools.isTechMeasure(treeNode)){ // if(!calcTools.isInheritFrom(treeNode, [fixedFlag.SUB_ENGINERRING, fixedFlag.MEASURE]))
-                if (treeNode.data.feesIndex && treeNode.data.feesIndex.common){
-                    let ftObj = {};
-                    ftObj.fieldName = 'common';
-                    ftObj.unitFee = parseFloatPlus(treeNode.data.feesIndex.common.unitFee);
-                    ftObj.totalFee = (ftObj.unitFee * nQ).toDecimal(decimalObj.bills.totalPrice);
-                    calcTools.checkFeeField(treeNode, ftObj);
+            // 叶子清单在没有公式的情况下可以手工修改综合单价并参与计算。
+            if (treeNode.data.feesIndex && treeNode.data.feesIndex.common){
+                let uf, tf;
+                let ftObj = {fieldName: 'common'};
+                if (!treeNode.modifyFlag) return;    // 没有改过单价、数量、金额,则不计算,保留上次的计算结果。
+
+                if (treeNode.modifyFlag == 2){    // 修改了清单单价:以单价为准,算金额
+                    uf = parseFloatPlus(treeNode.data.feesIndex.common.unitFee);
+                    if (nQ == 0) nQ = 1;
+                    tf = (uf * nQ).toDecimal(decimalObj.bills.totalPrice);
                 }
-            } else{
-                if (treeNode.data.fees && treeNode.data.fees.length > 0){
-                    treeNode.data.fees = null;
-                    treeNode.data.feesIndex = null;
-                    treeNode.changed = true;
+                else if (treeNode.modifyFlag == 3 || treeNode.modifyFlag == 1){  // 修改了清单金额:以金额为准,算单价。修改了清单数量也一样
+                    tf = parseFloatPlus(treeNode.data.feesIndex.common.totalFee);
+                    uf = nQ ? (tf / nQ) : tf;        // 如果工程量为0或空,综合合单直接填到综合单价
+                    uf = uf.toDecimal(decimalObj.bills.unitPrice);
+                    if (projectObj.project.property.valuationType != 'bill') {  // 招投标项目, 还要反算
+                        let nQ2 = nQ ? nQ : 1;
+                        tf = (uf * nQ2).toDecimal(decimalObj.bills.totalPrice);
+                    };
+                };
+
+                ftObj.unitFee = uf;
+                ftObj.totalFee = tf;
+                calcTools.checkFeeField(treeNode, ftObj);
+
+                if (treeNode.modifyFlag == 2 || treeNode.modifyFlag == 3){
+                    let ftObj2 = {
+                        fieldName: 'rationCommon',
+                        unitFee: uf,
+                        totalFee: tf
+                    };
+                    calcTools.checkFeeField(treeNode, ftObj2);
                 }
-            };
+            }
 
             treeNode.data.calcTemplate = {"calcItems": []};
         }
@@ -1786,8 +1801,8 @@ class CalcProgram {
                 calcTools.initSummaryFee(treeNode);
                 treeNode.data.summaryFees.totalFee = tf;
                 treeNode.data.summaryFees.estimateFee = calcTools.getFee(treeNode, 'estimate.totalFee');
-                treeNode.data.summaryFees.safetyFee = calcTools.getFee(calcTools.getNodeByFlag(fixedFlag.SAFETY_CONSTRUCTION), 'common.totalFee');
-                treeNode.data.summaryFees.chargeFee = calcTools.getFee(calcTools.getNodeByFlag(fixedFlag.CHARGE), 'common.totalFee');
+                // treeNode.data.summaryFees.safetyFee = calcTools.getFee(calcTools.getNodeByFlag(fixedFlag.SAFETY_CONSTRUCTION), 'common.totalFee');
+                // treeNode.data.summaryFees.chargeFee = calcTools.getFee(calcTools.getNodeByFlag(fixedFlag.CHARGE), 'common.totalFee');
             }
 
             treeNode.data.calcTemplate = {"calcItems": []};
@@ -1852,6 +1867,7 @@ class CalcProgram {
 
         if (!calcTools.isTotalCostBill(treeNode))  // 已在上面的分支中计算过
             calcTools.estimateFee(treeNode);
+
         if (treeNode.changed && !changedArr.includes(treeNode)) changedArr.push(treeNode);
     };
 
@@ -1895,6 +1911,7 @@ class CalcProgram {
             for (let node of treeNodes){
                 delete node.changed;
                 delete node.temData;
+                if (node.modifyFlag) delete node.modifyFlag;
                 node.updateData = {};
             };
             if(callback){
@@ -2084,8 +2101,8 @@ class CalcProgram {
         let baseNodes = [], me = this;
         baseNodes.push(calcTools.getNodeByFlag(fixedFlag.SUB_ENGINERRING));
         baseNodes.push(calcTools.getNodeByFlag(fixedFlag.MEASURE));
-        baseNodes.push(calcTools.getNodeByFlag(fixedFlag.OTHER));
-        baseNodes.push(calcTools.getNodeByFlag(fixedFlag.CHARGE));
+        // baseNodes.push(calcTools.getNodeByFlag(fixedFlag.OTHER));
+        // baseNodes.push(calcTools.getNodeByFlag(fixedFlag.CHARGE));
         return me.getTotalFee(baseNodes, excludeNodes, tender);
     };
 

+ 28 - 22
web/building_saas/main/js/models/ration.js

@@ -118,6 +118,8 @@ var Ration = {
             };
             if(rType == rationType.ration){//空定额暂时不输入取费专业
                // newData['programID'] = projectInfoObj.projectInfo.property.engineering;
+            }else if(rType == rationType.volumePrice){//量价取费专业默认为费率为0
+                newData['programID'] = projectObj.project.calcProgram.compiledTemplateMaps["费率为0"];
             }else {
                 if(pEngineer) newData['programID'] = pEngineer;
             }
@@ -545,7 +547,7 @@ var Ration = {
         };
 
 
-        ration.prototype.addNewRation = function (itemQuery,rationType,callback=null,isEmpty=false,priceType) {//priceType 是量价类型
+        ration.prototype.addNewRation = function (itemQuery,rationType,callback=null,isEmpty=false,priceType,needCalcAndSave=true) {//priceType 是量价类型
             let me = this;
             let project = projectObj.project, sheetController = projectObj.mainController;
             let engineering = projectInfoObj.projectInfo.property.engineering;
@@ -595,34 +597,38 @@ var Ration = {
                 CommonAjax.post("/ration/addNewRation",{itemQuery:itemQuery,newData:newData,defaultLibID: rationLibObj.getDefaultStdRationLibID(),calQuantity:calQuantity,brUpdate:brUpdate,needInstall:needInstall},function (data) {
                     //更新缓存
                     me.datas.push(data.ration);
-
                     me.addSubListOfRation(data);
-
                     //插入树节点
                     newSource = data.ration;
-                    newNode = project.mainTree.insert(billItemID, nextID, newSource.ID);
-                    newNode.source = newSource;
-                    newNode.sourceType = project.Ration.getSourceType();
-                    newNode.data = newSource;
-                    project.projectGLJ.loadData(function () {
-                        ProjectController.syncDisplayNewNode(sheetController, newNode);
-                        project.ration_glj.addToMainTree(data.ration_gljs);
-                        projectObj.mainController.refreshTreeNode([newNode], false);
-                        project.calcProgram.calcAndSave(newNode,function () {
-                            if(project.Bills.isFBFX(newNode)) { //判断是否属于分部分项工程 ,是的话才需要做计取安装费计算
-                                installationFeeObj.calcInstallationFee();
-                            }
+                    if(needCalcAndSave == false){
+                        syncNodeOper(data);
+                        if(callback) callback(newNode);
+                    }else {
+                        project.projectGLJ.loadData(function () {
+                            syncNodeOper(data);
+                            project.calcProgram.calcAndSave(newNode,function () {
+                                if(project.Bills.isFBFX(newNode)) { //判断是否属于分部分项工程 ,是的话才需要做计取安装费计算
+                                    installationFeeObj.calcInstallationFee();
+                                }
+                            });
+                            //如果添加规则中,添加内容为定额子目,则更新相关清单
+                            if(callback) callback(newNode);
                         });
-                        //如果添加规则中,添加内容为定额子目,则更新相关清单
-                        if(callback){
-                            callback(newNode);
-                        }
-                        $.bootstrapLoading.end();
-                    });
-                })
+                    }
+                    $.bootstrapLoading.end();
+                });
                 return newNode;
             }
             else return null;
+            function syncNodeOper(data) {//插入后刷新节点操作
+                newNode = project.mainTree.insert(billItemID, nextID, newSource.ID);
+                newNode.source = newSource;
+                newNode.sourceType = project.Ration.getSourceType();
+                newNode.data = newSource;
+                ProjectController.syncDisplayNewNode(sheetController, newNode);
+                project.ration_glj.addToMainTree(data.ration_gljs);
+                projectObj.mainController.refreshTreeNode([newNode], false);
+            }
         };
         ration.prototype.addNewRationFast = function (rationType,callback) {
             let me = this;

+ 2 - 3
web/building_saas/main/js/models/ration_coe.js

@@ -89,7 +89,7 @@ var ration_coe = {
                 if(i==dataLength){
                     newCoe.coeID=-1;
                     newCoe.name = '自定义系数';
-                    newCoe.content='人工×1,材料×1,机械×1,主材×1,设备×1';
+                    newCoe.content='人工×1,材料×1,机械×1,设备×1';
                     newCoe.isAdjust=0;
                     newCoe.coes = this.getCustomerCoeData();
                 }else {
@@ -98,7 +98,7 @@ var ration_coe = {
                 criteria.ration_coe_list.push(newCoe);
             }
             criteria.updateType = 'ut_create';
-            console.log('enterrrrrrrrrrrrrrrrrrrrrr');
+            console.log('enter');
             console.log(criteria);
             return criteria;
         };
@@ -108,7 +108,6 @@ var ration_coe = {
             coeList.push({ amount:1, operator:'*', gljCode:null, coeType:'人工'});
             coeList.push({ amount:1, operator:'*', gljCode:null, coeType:'材料'});
             coeList.push({ amount:1, operator:'*', gljCode:null, coeType:'机械'});
-            coeList.push({ amount:1, operator:'*', gljCode:null, coeType:'主材'});
             coeList.push({ amount:1, operator:'*', gljCode:null, coeType:'设备'});
             return coeList;
         };

+ 64 - 9
web/building_saas/main/js/models/ration_glj.js

@@ -416,16 +416,52 @@ let ration_glj = {
         ration_glj.prototype.updataOrdelete = function (row) {
             let updateData = null;
             if (row.rationItemQuantity == 0) {
-                updateData = this.getUpdateData('ut_delete', {
+               /* updateData = this.getUpdateData('ut_delete', {
                     'ID': row.ID,
                     'projectID': row.projectID
                 }, {rationID: row.rationID});
-                project.pushNow('updateRationGLJ', [this.getSourceType()], updateData)
+                project.pushNow('updateRationGLJ', [this.getSourceType()], updateData)*/
+                this.deleteRationGLJ({ID:row.ID,rationID:row.rationID, projectID: row.projectID,type:row.type});
             } else {
                 this.updateRationGLJByEdit(row, 'customQuantity', 0);
                 //('ut_update',{'ID': row.ID, 'projectID': row.projectID},{'quantity':0,'customQuantity':0});
             }
         };
+
+        ration_glj.prototype.deleteRationGLJ = async function(data){
+            try {
+                let result = await ajaxPost('/rationGlj/deleteRationGLJ',data);
+                console.log(result);
+                let oldData = this.addAndDeleteDatas([],result.deleteList);
+                this.refreshQuantityAfterCalResult(result.glj_result);
+                let rationNode = null;
+                let next = null;
+                let selected = projectObj.project.mainTree.findNode(result.rationID);
+                if (selected.sourceType == ModuleNames.ration) { //如果选中的是定额,说明是右键删除工料机操作,如果选中的是定额工料机,则说明是在造价书主界面中点击了删除按钮
+                    rationNode = selected;
+                } else if (selected.sourceType == ModuleNames.ration_glj) {
+                    rationNode = selected.parent;
+                    next = true;
+                }
+                rationNode.data.adjustState = result.adjustState;
+                projectObj.mainController.refreshTreeNode([rationNode]);
+                gljOprObj.refreshView();
+                for (let o of oldData) {
+                    if (this.needShowToTree(o)) {
+                        let node = me.findGLJNodeByID(o.ID);  //找到对应的树节点
+                        projectObj.mainController.deleteNode(node, next);
+                    }
+                }
+                project.calcProgram.calcAndSave(rationNode,function () {
+                    installationFeeObj.calcInstallationFee();
+                });
+                projectObj.project.projectGLJ.loadData();
+            }catch (e){
+                console.log(e)
+            }
+
+        };
+
         ration_glj.prototype.getUpdateData = function (type, query, doc, callfunction) {
             let updateData = [];
             let newobj = {
@@ -494,12 +530,16 @@ let ration_glj = {
             });
         };
         ration_glj.prototype.refreshAfterQuantityUpdate = function (data, node) {
+            this.refreshQuantityAfterCalResult(data.glj_result);
+            this.refreshRationAfterEdit(data, data.rationID, node);
+        };
+        ration_glj.prototype.refreshQuantityAfterCalResult = function (glj_result) {//后端计算后,前端刷新结果
             let me = this;
-            data.glj_result.forEach(function (item) {
+            glj_result.forEach(function (item) {
                 me.refreshEachItme(item.doc, item.query);
             });
-            me.refreshRationAfterEdit(data, data.rationID, node);
         };
+
         ration_glj.prototype.refreshRationAfterEdit= function(data,rationID,rnode){
             let nodes = [];
             let node = this.refreshRationNode(data.name,data.adjustState,rationID);
@@ -728,13 +768,10 @@ let ration_glj = {
             $.bootstrapLoading.start();
             CommonAjax.post("/rationGlj/replaceGLJ", recode, function (result) {
                 if (result) {
-                    //result.adjustState;
-                    let glj_list = me.datas;
+                    me.setDatasAfterReplace(result);
                     let data = result.data;
-                    let list_index = _.findIndex(glj_list, {'ID': data.ID});
                     let rationNode = projectObj.project.mainTree.findNode(data.rationID);
                     let nodes =  [rationNode];
-                    glj_list[list_index] = data;
                     project.projectGLJ.loadData(function () {//加载完项目工料机再计算
                         gljOprObj.refreshView();
                         if (project.ration_glj.needShowToTree(data)) {//当替换的是主材或设备时,刷新对应的树节点
@@ -758,6 +795,24 @@ let ration_glj = {
             });
         };
 
+        ration_glj.prototype.setDatasAfterReplace = function(result){
+            let me = this;
+            me.addAndDeleteDatas(result.newRecodes,result.deleteList);
+            let list_index = _.findIndex(me.datas, {'ID': result.data.ID});
+            me.datas[list_index] = result.data;
+            me.refreshQuantityAfterCalResult(result.glj_result);
+        };
+
+        ration_glj.prototype.addAndDeleteDatas = function (newRecodes,deleteList) {
+            let oldData = [];
+          if(newRecodes.length > 0 ) this.datas = this.datas.concat(newRecodes);
+          if(deleteList.length > 0) {
+              oldData =  _.remove(this.datas,function (item) {
+                  return  deleteList.indexOf(item.ID)!=-1;
+              });
+          }
+          return oldData;
+        };
         ration_glj.prototype.getReplaceDataByStd = function (oldData,glj) {
             if (oldData.createType===undefined || oldData.createType == 'normal') {// createTypel 默认是normal 只有是定额下带的工料机才需把类型改成替换,其它的保持不变
                 oldData.rcode = oldData.code;
@@ -873,7 +928,7 @@ let ration_glj = {
                     }
                     let task = {
                         updateOne:{
-                            filter : {ID:d.ID},
+                            filter : {ID:d.ID,rationID:d.rationID},
                             update : tem_doc
                         }
                     };

+ 41 - 18
web/building_saas/main/js/views/glj_view.js

@@ -759,6 +759,11 @@ var gljOprObj = {
             return scMathUtil.roundForObj(treeNode.data.marketUnitFee,getDecimal("glj.unitPrice"));
         }
     },
+    getMarketPrice:function (treeNode) {//造价书中的工料机修改的节点要用到
+        let proGLJ =  projectObj.project.projectGLJ;
+        let glj =_.find(proGLJ.datas.gljList, {'id': treeNode.data.projectGLJID});
+        return proGLJ.getMarketPrice(glj);
+    },
     calcPriceDiff:function (glj) {
         let calcOptions=projectInfoObj.projectInfo.property.calcOptions;
         return gljUtil.calcPriceDiff(glj,calcOptions);
@@ -922,7 +927,7 @@ var gljOprObj = {
     updateRationTypeGLJ: function (value, node, fieldName,editingText) {
         let newval;
         let updatePrice = false;
-        if (fieldName == "marketUnitFee") {
+        if (fieldName == "marketUnitFee" || fieldName == "feesIndex.common.unitFee") {
             updatePrice = true;
             if (value == null) {
                 newval = 0;
@@ -930,7 +935,8 @@ var gljOprObj = {
                 var decimal = getDecimal("glj.unitPrice");
                 newval = number_util.checkNumberValue(value, decimal);
             }
-        } else {
+        }
+        else {
             if (value != null) {
                 projectObj.project.projectGLJ.updatePropertyFromMainSpread(node, fieldName, value,editingText);
                 return;
@@ -994,7 +1000,7 @@ var gljOprObj = {
         }
     },
     setGLJSelection: function (args, newVal) {
-        if ($('#actionType').val() == 'add' || $('#actionType').val() == 'insert'|| $('#actionType').val() == 'addMix') {
+        if ($('#actionType').val() == 'add' || $('#actionType').val() == 'insert'|| $('#actionType').val() == 'insertEquipment' || $('#actionType').val() == 'addMix') {
             this.addGLJsSelection(args, newVal);
         } else {
             this.replaceGLJSelection(args, newVal);
@@ -1132,12 +1138,12 @@ var gljOprObj = {
             project.ration_glj.addGLJByLib(gljOprObj.GLJSelection, selected.data, function (result) {
                 if (result) {
                     selected.data.adjustState = result.adjustState;
-                    //project.ration_glj.datas = project.ration_glj.datas.concat(result.newRecodes);//显示和缓存统一,这样的话就不用更新两个位置了
-                    project.ration_glj.datas = project.ration_glj.datas.concat(result.showData);
-                    gljOprObj.sheetData = gljOprObj.sheetData.concat(result.showData);
+                    project.ration_glj.datas = project.ration_glj.datas.concat(result.newRecodes);//显示和缓存统一,这样的话就不用更新两个位置了
+                    //project.ration_glj.datas = project.ration_glj.datas.concat(result.showData);
+                    //gljOprObj.sheetData = gljOprObj.sheetData.concat(result.showData);
                     project.projectGLJ.loadData(function () {
-                        project.ration_glj.addToMainTree(result.showData);
-                        gljOprObj.showRationGLJSheetData();
+                        project.ration_glj.addToMainTree(result.showData);//组成物不会显示到造价书页面
+                        gljOprObj.refreshView();
                         project.calcProgram.calcAndSave(selected);
                         projectObj.mainController.refreshTreeNode([selected]);
                         $.bootstrapLoading.end();
@@ -1158,15 +1164,11 @@ var gljOprObj = {
         project.ration_glj.replaceGLJ(selectCode, oldData, function (result) {
             if (result) {
                 //result.adjustState;
-                let glj_list = projectObj.project.ration_glj.datas;
+                project.ration_glj.setDatasAfterReplace(result);
                 let data = result.data;
-                let index = _.findIndex(gljOprObj.sheetData, {'ID': data.ID});
-                let list_index = _.findIndex(glj_list, {'ID': data.ID});
                 let nodes = [selected];
-                gljOprObj.sheetData[index] = data;
-                glj_list[list_index] = data;
                 project.projectGLJ.loadData(function () {//加载完项目工料机再计算
-                    gljOprObj.showRationGLJSheetData();
+                    gljOprObj.refreshView();
                     let node = project.ration_glj.updateGLJNodeAfterReplace(data);
                     if(node) nodes.push(node);
                     /*if (project.ration_glj.needShowToTree(data)) {//当替换的是主材或设备时,刷新对应的树节点
@@ -1202,6 +1204,12 @@ var gljOprObj = {
             let stateList = result.stateList;
             //let n_index = me.getIndex(data.query, gljKeyArray);
             let nodes = [];
+            let quantityMap = {};
+            for(let gr of result.glj_result){
+                quantityMap[gr.query.ID] = gr.doc;
+            }
+            //添加\删除混凝土组成物定额工料机
+            project.ration_glj.addAndDeleteDatas(result.newRecodes,result.deleteList);
             _.forEach(project.ration_glj.datas, function (t) {
                 //     let t_index = me.getIndex(t, gljKeyArray);
                 if (updateMap[t.ID]) {
@@ -1213,9 +1221,12 @@ var gljOprObj = {
                         node ? nodes.push(node):'';
                     }
                 }
+                if(quantityMap[t.ID]){//更新消耗量
+                    me.updateProperty(t,quantityMap[t.ID]);
+                }
             })
             project.projectGLJ.loadData(function () {
-                me.showRationGLJSheetData();
+                me.refreshView();
                 var rationNodes = me.refreshStateAfterMreplace(stateList, nodes);
                 project.calcProgram.calcNodesAndSave(rationNodes);
                 $.bootstrapLoading.end();
@@ -1428,7 +1439,7 @@ $(function () {
         }
         gljOprObj.gljLibSheetData = gljOprObj.AllRecode;
         let gljClass = 0, selectMap = {};
-        if ($('#actionType').val() == 'add' || $('#actionType').val() == 'insert') {//插入,添加
+        if ($('#actionType').val() == 'add' || $('#actionType').val() == 'insert' || $('#actionType').val() == 'insertEquipment') {//插入,添加
             gljOprObj.GLJSelection = [];
         } else if($('#actionType').val() =='m_replace' || $('#actionType').val() == 'replace'){//替换、批量替换
             let selected = gljOprObj.sheetData[gljContextMenu.selectedRow];
@@ -1463,8 +1474,20 @@ $(function () {
             gljOprObj.gljLibSheet.setActiveCell(index, 0);
             gljOprObj.initSelection({row: index});
             gljOprObj.gljLibSpresd.focus(true);
+        } else if ($('#actionType').val() === 'insertEquipment') {//右键插入设备,人材机选择窗口,应默认固定到分类"养护管理设备"。
+            let locateClass = gljOprObj.treeData.std.find(function (stdClass) {
+                return stdClass.Name === '养护管理设备';
+            });
+            if (locateClass) {
+                gljClass = locateClass.ID;
+                gljOprObj.locateZTree(gljClass);
+                gljOprObj.gljLibSheet.showRow(0, GC.Spread.Sheets.VerticalPosition.top);
+                gljOprObj.gljLibSheet.setActiveCell(0, 0);
+                gljOprObj.initSelection({row: 0});
+            }
+        } else {
+            gljOprObj.showLibGLJSheetData();
         }
-        else gljOprObj.showLibGLJSheetData();
     });
 
     $('#glj_tree_div').on('hidden.bs.modal', function () {
@@ -1511,7 +1534,7 @@ $(function () {
         if (gljOprObj.GLJSelection.length < 1) {
             return;
         }
-        if ($('#actionType').val() == 'insert') {  //造价书页面中插入定额类型的工料机
+        if (['insert', 'insertEquipment'].includes($('#actionType').val())) {  //造价书页面中插入定额类型的工料机
             gljOprObj.doInsertGLJ();
         } else if ($('#actionType').val() == 'add') { //添加工料机
             gljOprObj.doAddGLJ();

+ 3 - 3
web/building_saas/main/js/views/main_tree_col.js

@@ -334,17 +334,17 @@ let MainTreeCol = {
                 let VPType = sheetCommonObj.getDynamicCombo();
                 if(node.sourceType == projectObj.project.Ration.getSourceType()){//是定额类型
                     if(node.data.type == rationType.volumePrice){
-                        VPType.itemHeight(5).items(["人工", "材料", "机械", "主材", "设备"])
+                        VPType.itemHeight(5).items(["人工", "材料", "机械", "设备"])
                         return VPType;
                     }else if(node.data.type == rationType.gljRation){
                         if(!MainTreeCol.readOnly.non_editSubType(node)&&gljOprObj.hasComposition(node.data,true)==false){
-                            VPType.itemHeight(3).items(["材料", "主材", "设备"]);
+                            VPType.itemHeight(3).items(["材料", "设备"]);
                             return VPType;
                         }
                     }
                 }else if(node.sourceType === projectObj.project.ration_glj.getSourceType()){//是工料机类型
                     if(!MainTreeCol.readOnly.non_editSubType(node)&&gljOprObj.hasComposition(node.data)==false){
-                        VPType.itemHeight(3).items(["材料", "主材", "设备"]);
+                        VPType.itemHeight(3).items(["材料",  "设备"]);
                         return VPType;
                     }
                 }

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

@@ -9,8 +9,8 @@ let indicativeInfoObj = {
         header: [
             {name: '名称', dataCode: 'name', width: 200, vAlign: 'center', hAlign: 'left'},
             {name: '金额', dataCode: 'price', width: 120, vAlign: 'center', hAlign: 'right'},
-            {name: '占造价比例(%)', dataCode: 'rate', width: 100, vAlign: 'center', hAlign: 'right'},
-            {name: '单方造价', dataCode: 'perCentiare', width: 80, vAlign: 'center', hAlign: 'right'}
+            {name: '占造价比例(%)', dataCode: 'rate', width: 100, vAlign: 'center', hAlign: 'right'}//,
+            //{name: '单方造价', dataCode: 'perCentiare', width: 80, vAlign: 'center', hAlign: 'right'}
         ],
         options: {
             allowContextMenu: false,

+ 56 - 61
web/building_saas/main/js/views/project_view.js

@@ -440,53 +440,71 @@ var projectObj = {
     },
     updateCellValue: function (node, value, colSetting,editingText) {
         let project = projectObj.project, fieldName = colSetting.data.field;
-        if(node.sourceType==project.ration_glj.getSourceType()){
+        if(node.sourceType == ModuleNames.ration_glj){
             project.ration_glj.updateFromMainSpread(value,node,fieldName);
-        } else if(fieldName === 'remark'){
-            projectObj.updateNodeField(node,value,'remark');
-        } else if(calcTools.isGljRation(node)){
+        }
+        else if(calcTools.isGljRation(node)){
             gljOprObj.updateRationTypeGLJ(value,node,fieldName,editingText);
-        } else if (value !== calcFees.getFee(node.data, fieldName)||fieldName == 'quantity') {//工程量需要进行转换,所以做特殊处理
+        }
+        else if(fieldName === 'remark'){
+            projectObj.updateNodeField(node,value,'remark');
+        }
+        else if(fieldName ==='feeRate' && value==null){
+            project.FeeRate.cleanFeeRateID(node);
+        }
+        else if (value !== calcFees.getFee(node.data, fieldName) || fieldName == 'quantity') {//工程量需要进行转换,所以做特殊处理
             if (fieldName === 'code' && value != '' && !calcTools.isVolumePrice(node)) {
                 projectObj.updateCode(node, value);
-            } else if(fieldName ==='feeRate'){
+            }
+            else if (fieldName === 'unit' && node.sourceType == ModuleNames.bills){
+                node.updateData[fieldName] = value;
+                node.changed = true;
+                if(node.data.quantity){
+                    node.updateData.quantity = scMathUtil.roundForObj(node.data.quantity,getDecimal("quantity",node));//修改清单单位的时候清单工程量要重新4舍5入;
+                }
+                project.calcProgram.calcAndSave(node);
+            }
+            else if(fieldName ==='feeRate'){
                 project.FeeRate.updateFeeRateFromBills(value,node,fieldName);
-            } else if(fieldName ==='contain'){//编辑含量
+            }
+            else if(fieldName ==='contain'){//编辑含量
                 project.Ration.updateContain(value,node);
-            } else if (fieldName === 'quantity' || fieldName === 'marketUnitFee' || fieldName === 'feesIndex.common.unitFee'||fieldName === 'feesIndex.common.totalFee' || fieldName === 'programID' ||
-                fieldName === 'subType' || fieldName === 'calcBase' || fieldName === 'isSubcontract'){
+            }
+            else if (fieldName === 'quantity' ||
+                fieldName === 'marketUnitFee' || fieldName === 'feesIndex.common.unitFee'||fieldName === 'feesIndex.common.totalFee' ||
+                fieldName === 'calcBase' ||
+                fieldName === 'programID' || fieldName === 'subType' || fieldName === 'isSubcontract'){
                 if (fieldName === 'quantity') {
+                    node.modifyFlag = 1;
                     quantityEditObj.checkingAndUpdate(editingText,node);
-                   // project.quantity_detail.editMainTreeNodeQuantity(value,node,fieldName,editingText);
                     return;
-                } else if (fieldName === 'marketUnitFee' || fieldName === 'feesIndex.common.unitFee'||fieldName === 'feesIndex.common.totalFee') {
-                    if(isNaN(value)){//说明输入的是无效的字符
-                        //value == null && editingText!=null && editingText!=""
+                }
+                else if (fieldName === 'marketUnitFee' || fieldName === 'feesIndex.common.unitFee'||fieldName === 'feesIndex.common.totalFee') {
+                    if(isNaN(value)){// 输入的是无效的字符
                         alert("当前输入的数据类型不正确,请重新输入。");
                         projectObj.mainController.refreshTreeNode([node]);
                         return
-                    }
-                    if (value) {
+                    };
+
+                    // if (value) {
                         if(fieldName === 'feesIndex.common.unitFee') {
                             value = parseFloat(value).toDecimal(decimalObj.decimal("unitPrice", node));
+
                             //当前是量价/人材机,综合单价可输入,输入的值读取到市场单价,重算综合单价。
                             if(node.sourceType == ModuleNames.ration && node.data.type != rationType.ration){
                                 fieldName = 'marketUnitFee';
                             }
-                        }
-                        if(fieldName === 'feesIndex.common.totalFee'){//修改了综合合价后,反算综合单价,然后再由计算程序算个综合合价出来
-                            let unitfee = 0;
-                            if(node.data.quantity){//如果工程量为0或空,综合合单直接填到综合单价
-                                let t_quantity = scMathUtil.roundForObj(node.data.quantity,getDecimal("quantity",node));
-                                value = scMathUtil.roundForObj(value,getDecimal("unitPrice", node));
-                                unitfee = scMathUtil.roundForObj(value/t_quantity,getDecimal("totalPrice", node));
-                            }else {
-                                unitfee = scMathUtil.roundForObj(value,getDecimal("totalPrice", node));
+                            else if (node.sourceType == ModuleNames.bills){
+                                node.modifyFlag = 2;
                             }
-                            calcTools.setFieldValue(node, 'feesIndex.common.unitFee', unitfee);
                         }
-                    }
-                } else if (fieldName === 'calcBase') {
+                        else if(fieldName === 'feesIndex.common.totalFee'){
+                            value = scMathUtil.roundForObj(value, getDecimal("totalPrice", node));
+                            node.modifyFlag = 3;
+                        }
+                    // }
+                }
+                else if (fieldName === 'calcBase') {
                     //zhong
                     if(value === undefined ||value === null || value.toString().trim() === ''){
                         value = '';
@@ -505,20 +523,15 @@ var projectObj = {
                     }
                     // if (value) {value = parseFloat(value).toDecimal(decimalObj.decimal("totalPrice", node))};
                 };
+
                 //计算基数赋值要经过解析和标准化,已在calculate里赋值
-                if(fieldName !== 'calcBase'){
+                if(fieldName !== 'calcBase')
                     calcTools.setFieldValue(node, fieldName, value);
-                };
+
                 project.calcProgram.calcAndSave(node);
                 gljOprObj.showRationGLJSheetData();
-            } else if (node.sourceType === project.Bills.getSourceType()&&fieldName === 'unit'){
-                node.updateData[fieldName] = value;
-                node.changed = true;
-                if(node.data.quantity){
-                    node.updateData.quantity = scMathUtil.roundForObj(node.data.quantity,getDecimal("quantity",node));//修改清单单位的时候清单工程量要重新4舍5入;
-                }
-                project.calcProgram.calcAndSave(node);
-            } else {//不涉及计算的,只改updateData的值就好了
+            }
+            else {//不涉及计算的,只改updateData的值就好了
                 node.updateData[fieldName] = value;
                 node.changed = true;
                 if (colSetting.data.wordWrap) {
@@ -527,11 +540,10 @@ var projectObj = {
                 project.calcProgram.calcAndSave(node);
                // projectObj.mainController.refreshTreeNode([node]);
             }
-        } else if(value==null && fieldName ==='feeRate'){
-            project.FeeRate.cleanFeeRateID(node);
-        } else {
-            projectObj.mainController.refreshTreeNode([node], false);
         }
+        else {
+            projectObj.mainController.refreshTreeNode([node], false);
+        };
     },
     mainSpreadLeaveCell: function (sender, info) {
         let colSetting = projectObj.mainController.setting.cols[info.col];
@@ -1082,7 +1094,7 @@ var projectObj = {
                             newCol = codeCol;
                         }
                         sheet.setActiveCell(newRow, newCol);
-                    },true);
+                    },true,null,false);
                 }
             }
             //在定额/量价/人材机的编码单元格回车,焦点应跳动至本行的工程量单元格
@@ -1109,7 +1121,7 @@ var projectObj = {
                             newCol = codeCol;
                         }
                         sheet.setActiveCell(newRow, newCol);
-                    }, true);
+                    }, true,null,false);
                 }
                 //如果其后有定额空行,焦点跳动至定额空行的编码单元格
                 else if(nextSibling && !(isDef(nextSibling.data.code) && nextSibling.data.code.toString().trim() !== '')) {
@@ -1339,25 +1351,15 @@ var projectObj = {
                         if (projectReadOnly) {
                             return true;
                         }
-                        // var selected = project.mainTree.selected;
-                        // return project.Ration.addRationChecking(selected);  // Vincent, 2018-01-02
                         return !project.Ration.canAdd(project.mainTree.selected);
                     },
                     callback: function (key, opt) {
                         let selected = project.mainTree.selected;
-                       /* if(selected.sourceType == ModuleNames.bills){
-                            if(selected.data.type == billType.FX||selected.data.type ==billType.BILL){
-                                if(selected.data.calcBase&&selected.data.calcBase!=""){
-                                    alert("当前有基数计算,不能插入定额/量价/人材机。");
-                                    return;
-                                }
-                            }
-                        }*/
                         if(selected.data.calcBase&&selected.data.calcBase!=""){
                             alert("当前有基数计算,不能插入定额/量价/人材机。");
                             return;
                         }
-                        getGLJData('insert');// ProjectController.addRation(project, controller, rationType.volumePrice);
+                        getGLJData('insertEquipment');// ProjectController.addRation(project, controller, rationType.volumePrice);
                     },
                     visible: function(key, opt){//2018-11-08  新需求,这个按钮先隐藏,有需要再放开
                         let selected = project.mainTree.selected;
@@ -1366,13 +1368,6 @@ var projectObj = {
                         if (belongFlag && belongFlag === fixedFlag.EQUIPMENT_ACQUISITION_FEE) {
                             return true;
                         }
-                        /*if (selected && selected.sourceType == ModuleNames.bills) {
-                            //属于的固定清单
-                            let belongFlag = cbTools.getBelongFlag(selected);
-                            if (belongFlag && belongFlag === fixedFlag.EQUIPMENT_ACQUISITION_FEE) {
-                                return true;
-                            }
-                        }*/
                         return false;
                     }
                 },

+ 8 - 3
web/building_saas/main/js/views/std_billsGuidance_lib.js

@@ -261,12 +261,17 @@ const billsGuidance = (function () {
         * 该清单节点是否可以继续往下递归匹配,即该节点是否还可插入子项(在该层匹配到的时候判断)
         * 1.该底层节点不能含有非清单子项
         * 2.该节点不能含有计算基数
-        * todo 3.数量单价等相关概念做完了再补上
+        * todo 3.数量单价等相关概念,等有了补上
         * @param {Object}billsNode(清单树中的某节点) @return {Boolean}
         * */
         function canRecursive(billsNode) {
-            //不含有子清单节点但却含有子节点,说明该节点含有非清单子项
-            if (billsNode.children > 0 && billsNode.source.children === 0) {
+            //主树节点含有子节点,清单节点不含子节点,说明该节点含有非清单子项
+            //这里需要去mainTree查,不能在清单树查,因为清单树的节点children里只会有清单,就算实际上有定额,这个children里也不含该定额
+            let mainTreeNode = projectObj.project.mainTree.getNodeByID(billsNode.data.ID);
+            if (!mainTreeNode) {
+                return false;
+            }
+            if (mainTreeNode && mainTreeNode.children.length > 0 && billsNode.children.length === 0) {
                 return false;
             } else if (billsNode.data.calcBase) {
                 return false;

+ 2 - 2
web/building_saas/pm/html/project-management.html

@@ -512,10 +512,10 @@
                         <div class="modal-auto-height">
                             <div id="replaceSpread" style="height: 100%"></div>
                         </div>
-                        <div class="custom-control custom-checkbox">
+                        <!--<div class="custom-control custom-checkbox">
                             <input type="checkbox" class="custom-control-input" id="selectSameTypeProject">
                             <label class="custom-control-label" for="selectSameTypeProject">自动勾选同专业工程</label>
-                        </div>
+                        </div>-->
                     </div>
                     <div class="col-6">
                         <h5>更换为</h5>

+ 2 - 2
web/common/html/header.html

@@ -32,7 +32,7 @@
                 <a class="nav-link dropdown-toggle" href="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fa fa-wrench" data-placement="bottom"></i> 工具</a>
                 <div class="dropdown-menu dropdown-menu-right">
                     <a id="compleRationLib" class="dropdown-item compleRationLib" href="/complementaryRation/ration" target="_blank">定额库编辑器</a>
-                    <a id="compleGljLib" class="dropdown-item compleGljLib" href="/complementaryGlj" target="_">人材机库编辑器</a>
+                    <a id="compleGljLib" class="dropdown-item compleGljLib" href="/complementaryGlj" target="_">工料机库编辑器</a>
                 </div>
             </li>
             <% } %>
@@ -76,7 +76,7 @@
                         <button class="dropdown-item dropdown-toggle" type="button" data-toggle="dropdown">工具</button>
                         <div class="dropdown-menu">
                             <a  class="dropdown-item compleRationLib" href="/complementaryRation/ration" target="_blank">定额库编辑器</a>
-                            <a  class="dropdown-item compleGljLib" href="/complementaryGlj" target="_">人材机库编辑器</a>
+                            <a  class="dropdown-item compleGljLib" href="/complementaryGlj" target="_">工料机库编辑器</a>
                         </div>
                     </div>
                     <% } %>

BIN
web/dest/css/login-bg.jpg


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 8 - 4
web/users/html/login.html