浏览代码

Merge branch 'master' of http://192.168.1.41:3000/SmartCost/YangHuCost

TonyKang 5 年之前
父节点
当前提交
9e2148ffcd
共有 32 个文件被更改,包括 790 次插入183 次删除
  1. 14 0
      config/config.js
  2. 2 1
      modules/all_models/project_glj.js
  3. 2 1
      modules/all_models/user.js
  4. 19 0
      modules/all_models/welcome_setting.js
  5. 6 6
      modules/main/controllers/ration_controller.js
  6. 10 6
      modules/main/facade/bill_facade.js
  7. 5 3
      modules/main/facade/project_facade.js
  8. 20 14
      modules/main/facade/ration_facade.js
  9. 4 0
      modules/pm/controllers/pm_controller.js
  10. 29 2
      modules/pm/facade/pm_facade.js
  11. 12 7
      modules/ration_glj/facade/ration_glj_facade.js
  12. 90 2
      modules/users/controllers/cld_controller.js
  13. 1 0
      modules/users/controllers/login_controller.js
  14. 62 0
      modules/users/facade/online_facade.js
  15. 14 0
      modules/users/models/compilation_model.js
  16. 106 0
      modules/users/models/user_model.js
  17. 4 0
      modules/users/routes/cld_route.js
  18. 1 1
      web/building_saas/main/html/main.html
  19. 3 3
      web/building_saas/main/js/controllers/block_controller.js
  20. 14 8
      web/building_saas/main/js/models/project_glj.js
  21. 32 36
      web/building_saas/main/js/models/ration.js
  22. 15 16
      web/building_saas/main/js/models/ration_glj.js
  23. 30 33
      web/building_saas/main/js/views/glj_view.js
  24. 9 9
      web/building_saas/main/js/views/mbzm_view.js
  25. 1 0
      web/building_saas/main/js/views/project_glj_view.js
  26. 1 0
      web/building_saas/main/js/views/project_view.js
  27. 2 2
      web/building_saas/main/js/views/zmhs_view.js
  28. 20 0
      web/building_saas/pm/html/project-management.html
  29. 6 0
      web/building_saas/pm/js/pm_newMain.js
  30. 1 0
      web/building_saas/pm/js/pm_share.js
  31. 254 32
      web/over_write/js/anhui_2019.js
  32. 1 1
      web/users/html/user-info.html

+ 14 - 0
config/config.js

@@ -16,6 +16,20 @@ module.exports = {
         },
         importURL:"192.168.1.184:2050"
     },
+    qa_outer: {
+        server: "smartcost.in.8866.org",
+        port: "26904",
+        options:{
+            user:'smartcost',
+            pass:'smartcost3850888',
+            auth: {
+                "authdb": "admin"
+            },
+            connectTimeoutMS: 100000,
+            useMongoClient: true
+        },
+        importURL:"192.168.1.184:6050"
+    },
     test_auth: {
             server: "120.78.150.216",
             port: "27017",

+ 2 - 1
modules/all_models/project_glj.js

@@ -110,7 +110,8 @@ let modelSchema = {
     transportLossQuantity: Number,    //场外运输损耗量(实际)
     //以下仅普通材料可用
     ratio_data: Schema.Types.Mixed,
-    remark:String
+    remark:String,
+    subList:[Schema.Types.Mixed]
 };
 mongoose.model(collectionName, new Schema(modelSchema, {versionKey: false}));
 

+ 2 - 1
modules/all_models/user.js

@@ -104,6 +104,7 @@ let schema = {
     isLoginValid: {
         type: Number,
         default: 0
-    }
+    },
+    welcomeShowTime:String
 };
 mongoose.model(collectionName, new Schema(schema, {versionKey: false}));

+ 19 - 0
modules/all_models/welcome_setting.js

@@ -0,0 +1,19 @@
+/**
+ * Created by zhang on 2020/2/14.
+ */
+
+let mongoose = require("mongoose");
+
+let Schema = mongoose.Schema;
+let collectionName = 'welcome_setting';
+let modelSchema = {
+    // ID
+    ID: {
+        type: String,
+        index: true
+    },
+    compilationId: String,
+    showType:{type:Number,default:0},// 1 每天一次 2 每次登录显示,0 关闭
+    context:String
+};
+mongoose.model(collectionName, new Schema(modelSchema, {versionKey: false, collection: collectionName}));

+ 6 - 6
modules/main/controllers/ration_controller.js

@@ -30,9 +30,9 @@ let controller = {
         let start = +new Date();
         let result = await ration_facade.addNewRation(data,req.session.sessionCompilation);
         //合并取项目工料机数据的情求,用于刷新项目工料机数据,当有添加、替换项目工料机的情况,才需要刷新
-        if(result.ration_gljs && result.ration_gljs.length > 0 && data.newData){
+      /*  if(result.ration_gljs && result.ration_gljs.length > 0 && data.newData){
             result.projectGLJDatas =  await getProjectGLJData(data.newData.projectID);
-        }
+        }*/
         let end = +new Date();
         console.log("实际插入时间为-------------------------------"+(end-start));
         return result
@@ -43,9 +43,9 @@ let controller = {
         console.log(data);
         let result = await ration_facade.updateMaterialRation(data,req.session.sessionCompilation);
         //合并取项目工料机数据的情求,用于刷新项目工料机数据,当有添加、替换项目工料机的情况,才需要刷新
-        if(result.ration_gljs && result.ration_gljs.length > 0){
+       /* if(result.ration_gljs && result.ration_gljs.length > 0){
             result.projectGLJDatas =  await getProjectGLJData(data.projectID);
-        }
+        }*/
         return result
     },
     addMultiRation: async function (req) {
@@ -100,9 +100,9 @@ let controller = {
         data = JSON.parse(data);
         let result = await ration_facade.updateCoeAdjust(data,req.session.sessionCompilation);
         //合并取项目工料机数据的情求,用于刷新项目工料机数据,当有添加、替换项目工料机的情况,才需要刷新
-        if(result.add.length > 0 || result.replace.length > 0){
+        /*if(result.add.length > 0 || result.replace.length > 0){
             result.projectGLJDatas =  await getProjectGLJData(data.projectID);
-        }
+        }*/
         return result
 
     }

+ 10 - 6
modules/main/facade/bill_facade.js

@@ -80,10 +80,11 @@ module.exports={
         let [rationsAndRationGLJ,resultMap] = await Promise.all(pasteTasks);
 
         let gljController = new GLJController();
-        let projectGLJ = await gljController.getProjectGLJsByProjectID(data.projectID);
+        //let projectGLJ = await gljController.getProjectGLJsByProjectID(data.projectID);
         resultMap.rations = rationsAndRationGLJ.rations;
         resultMap.ration_gljs = rationsAndRationGLJ.new_ration_gljs;
-        resultMap.gljData = projectGLJ.data;
+        resultMap.projectGLJList = rationsAndRationGLJ.projectGLJList;
+        //resultMap.gljData = projectGLJ.data;
         return resultMap;
     },
     createNewBills:async function(newDatas){
@@ -163,7 +164,7 @@ async function pasteOtherData(data) {
 
 async function pasteRationsAndRationGLJ (rations,ration_gljs,compilation) {
     let projectGljModel = new GLJListModel();
-    let gljMap = {}, new_ration_gljs=[],projectID=null;
+    let gljMap = {}, new_ration_gljs=[],projectID=null,projectGLJList=[];
     if(rations.length > 0) projectID = rations[0].projectID;
     if(projectID==null && ration_gljs.length > 0) projectID = ration_gljs[0].projectID;
     if(projectID == null) return {rations:rations,new_ration_gljs:new_ration_gljs};
@@ -171,22 +172,24 @@ async function pasteRationsAndRationGLJ (rations,ration_gljs,compilation) {
     //先根据定额类型的工料机,插入到项目工料机中
     for(let r of rations){
         if(r.type == rationType.gljRation){
-            await getProjectGLJ(r,rationKeyArray,gljMap,unitFileId,ext);
+            let tg = await getProjectGLJ(r,rationKeyArray,gljMap,unitFileId,ext);
+            projectGLJList.push(tg)
         }
     }
 
     for(let rg of ration_gljs){
-        await getProjectGLJ(rg,gljKeyArray,gljMap,unitFileId,ext);
+        let tg = await getProjectGLJ(rg,gljKeyArray,gljMap,unitFileId,ext);
         let temRecord = ration_glj_facade.createNewRecord(rg);
         rg.rcode?temRecord.rcode = rg.rcode:'';
         rg.hasOwnProperty("customQuantity")?temRecord.customQuantity = rg.customQuantity:'';
         new_ration_gljs.push(temRecord);
+        projectGLJList.push(tg);
     }
 
     rations.length>0?await insertMany(rations,ration_Model):'';
     new_ration_gljs.length>0?await insertMany(new_ration_gljs,ration_glj_Model):'';
 
-    return {rations:rations,new_ration_gljs:new_ration_gljs};
+    return {rations:rations,new_ration_gljs:new_ration_gljs,projectGLJList:projectGLJList};
 
     async function getProjectGLJ (glj,keyArray,gljMap,unitFileId,ext) {
         let keyIndex = projectGljModel.getIndex(glj,keyArray);
@@ -199,6 +202,7 @@ async function pasteRationsAndRationGLJ (rations,ration_gljs,compilation) {
             gljMap[keyIndex] = pgljResult;
         }
         setResult(glj,pgljResult);
+        return pgljResult;
     }
 
 

+ 5 - 3
modules/main/facade/project_facade.js

@@ -40,6 +40,7 @@ const projectDao = require('../../pm/models/project_model').project;
 
 async function calcInstallationFee(data) {
     let result={};
+    let projectGLJList = [];
     let billTasks  = generateTasks(data.bills,data.useID);
     let rationTasks = generateTasks(data.ration,data.useID);
     if(billTasks.length>0){
@@ -85,7 +86,8 @@ async function calcInstallationFee(data) {
     if(data.ration.add.length>0){//新增的安装子目要增加对应的工料机
         for(let nr of data.ration.add){
             for(let tkey in nr.glj){
-                newGljList.push(await addInstallationGLJ(nr.glj[tkey]));
+                let [newRecode,projectGLJ] = await addInstallationGLJ(nr.glj[tkey]);
+                newGljList.push(newRecode);
             }
         }
     }
@@ -99,9 +101,9 @@ async function calcInstallationFee(data) {
 
 async function addInstallationGLJ(glj) {
     glj.ID = uuidV1();
-    let info = await ration_glj_facade.getInfoFromProjectGLJ(glj);
+    let [info,projectGLJ ] = await ration_glj_facade.getInfoFromProjectGLJ(glj);
     let newRecode  = ration_glj_facade.createNewRecord(info);
-    return newRecode;
+    return [newRecode,projectGLJ];
 }
 
 

+ 20 - 14
modules/main/facade/ration_facade.js

@@ -96,14 +96,14 @@ async function deleteMaterialRation(data) {
 async function modifyMaterialRation(data,compilation) {
     let model = data.type == "freight"?freightCalcModel:originaltCalcModel;
     if(data.field == "code"){
-        let [newRation,ration_gljs] = await getNewMaterialRationDatas(data,compilation);
+        let [newRation,ration_gljs,projectGLJList] = await getNewMaterialRationDatas(data,compilation);
         let quantity = data.rations[data.row].quantity;
         newRation.quantity = quantity;
         data.rations[data.row] = newRation;
         _.remove(data.ration_gljs,{rationID:data.rationID});
         data.ration_gljs = data.ration_gljs.concat(ration_gljs);
         await  model.update({'ID':data.parentID},{rations:data.rations,ration_gljs:data.ration_gljs});
-        return {ration:newRation,ration_gljs:ration_gljs}
+        return {ration:newRation,ration_gljs:ration_gljs,projectGLJList:projectGLJList}
     }else {
         let doc = {},pre = "rations.$.";
         let field = pre+data.field;
@@ -125,10 +125,10 @@ async function modifyMaterialRation(data,compilation) {
 }
 
 async function addMaterialRation(data,compilation) {
-    let [newRation,ration_gljs] = await getNewMaterialRationDatas(data,compilation);
+    let [newRation,ration_gljs,projectGLJList] = await getNewMaterialRationDatas(data,compilation);
     let model = data.type == "freight"?freightCalcModel:originaltCalcModel;
     await model.update({ID:data.parentID},{$push:{rations:newRation,ration_gljs:{$each:ration_gljs}}});
-    return{ration:newRation,ration_gljs:ration_gljs};
+    return{ration:newRation,ration_gljs:ration_gljs,projectGLJList:projectGLJList};
 }
 
 async function getNewMaterialRationDatas(data,compilation){
@@ -137,8 +137,8 @@ async function getNewMaterialRationDatas(data,compilation){
     if(!stdRation) throw  "找不到指定的定额!";//new Error("找不到指定的定额!");
 
     let newRation = await createNewMaterialRation(stdRation,data.quantityDecimal,data.projectID);
-    let ration_gljs = await addRationGLJ(stdRation,newRation,compilation,true,data.connect_key);
-    return [newRation,ration_gljs];
+    let [ration_gljs,projectGLJList] = await addRationGLJ(stdRation,newRation,compilation,true,data.connect_key);
+    return [newRation,ration_gljs,projectGLJList];
 }
 
 
@@ -296,7 +296,7 @@ async function replaceRation(nodeInfo,stdRation,defaultLibID,projectID,calQuanti
 
 async function addRationSubList(stdRation,newRation,needInstall,compilation,cleanzmhs=false) {
     let startTime = +new Date();
-    let ration_gljs = await addRationGLJ(stdRation,newRation,compilation);
+    let [ration_gljs,projectGLJList] = await addRationGLJ(stdRation,newRation,compilation);
     let addRationGLJTime = +new Date();
     console.log("添加定额工料机时间-----"+(addRationGLJTime - startTime));
     let ration_coes = await addRationCoe(stdRation,newRation,compilation);
@@ -313,7 +313,7 @@ async function addRationSubList(stdRation,newRation,needInstall,compilation,clea
         //添加定额模板子目
         ration_template = await addRationTemplate(stdRation,newRation);
     }
-    return {ration:newRation,ration_gljs:ration_gljs,ration_coes:ration_coes,ration_installations:ration_installations,ration_templates:ration_template?[ration_template]:[]};
+    return {ration:newRation,ration_gljs:ration_gljs,ration_coes:ration_coes,ration_installations:ration_installations,ration_templates:ration_template?[ration_template]:[],projectGLJList:projectGLJList};
 }
 
 async function addRationInstallFee(std,newRation) {
@@ -480,6 +480,7 @@ function getExtendData(property,compilation) {
 async function addRationGLJ(std,newRation,compilation,isMaterial,connect_key) {
     let newRationGLJList = [];
     let rationGLJShowList = [];
+    let projectGLJList = [];
     let unitPriceFileId = 0;
     let property = await projectDao.getProjectProperty(newRation.projectID);
     if(property){
@@ -526,10 +527,11 @@ async function addRationGLJ(std,newRation,compilation,isMaterial,connect_key) {
             let std_glj = getStdGlj(sub,stdGLJMap,cptGLJMap,{},ext);
             if(std_glj){
                 ration_glj_facade.setPropertyFromStd(newGLJ,std_glj);
-                let info =  await ration_glj_facade.getInfoFromProjectGLJ(newGLJ,unitPriceFileId,ext);
+                let [info,projectGLJ] =  await ration_glj_facade.getInfoFromProjectGLJ(newGLJ,unitPriceFileId,ext);
                 newGLJ = ration_glj_facade.createNewRecord(info);
                 newRationGLJList.push(newGLJ);
                 rationGLJShowList.push(info);
+                projectGLJList.push(projectGLJ);
             }
             //let InfoFromProjectGLJ = +new Date();
             //console.log("找到项目工料机时间-------------------------------"+(InfoFromProjectGLJ - std_gljTime));
@@ -537,7 +539,7 @@ async function addRationGLJ(std,newRation,compilation,isMaterial,connect_key) {
     }
     let before = +new Date();
     console.log("总查询时间为-------------------------------"+(before-first));
-    if(isMaterial == true) return newRationGLJList;//如果是材料计算的工料机,这里返回就可以了
+    if(isMaterial == true) return [newRationGLJList,projectGLJList];//如果是材料计算的工料机,这里返回就可以了
 
     if(newRationGLJList.length>0){
         await ration_glj.insertMany(newRationGLJList);
@@ -545,7 +547,7 @@ async function addRationGLJ(std,newRation,compilation,isMaterial,connect_key) {
     let after = +new Date();
     console.log("实际插入时间为-------------------------------"+(after-before));
     console.log("总操作时间为-------------------------------"+(after-first));
-    return rationGLJShowList;
+    return [rationGLJShowList,projectGLJList];
 }
 
 function getStdGlj(sub,stdGLJMap,cptGLJMap,newGLJ,ext) {
@@ -585,10 +587,13 @@ async function deleteSubListByQuery(delete_query,cleanzmhs=false) {
 }
 
 async function updateCoeAdjust(data,compilation) {
-    let replace = [];
+    let replace = [],projectGLJList=[];
     await ration_coe.update({ID:data.ID},data.doc);
     //添加单个工料机的情况
-    if (data.add.length > 0)   await ration_glj_facade.insertAddTypeGLJ(data.add,compilation);
+    if (data.add.length > 0){
+        let [tg,pl] = await ration_glj_facade.insertAddTypeGLJ(data.add,compilation);
+        if(pl.length > 0) projectGLJList = projectGLJList.concat(pl);
+    }
     if(data.delete.length > 0) await ration_glj_facade.deleteGLJ(data.delete);
 
     //替换工料机的情况
@@ -596,6 +601,7 @@ async function updateCoeAdjust(data,compilation) {
         for(let r of data.replace){
             let r_result = await  ration_glj_facade.replaceGLJByData(r,compilation);
             replace.push(r_result.data) ;
+            projectGLJList.push(r_result.projectGLJ);
             if(r_result.newRecodes.length > 0) data.add = data.add.concat(r_result.newRecodes);
             if(r_result.deleteList.length > 0) data.delete = data.delete.concat(r_result.deleteList);
         }
@@ -614,7 +620,7 @@ async function updateCoeAdjust(data,compilation) {
         adjustState:cal_result.adjustState,
         name:cal_result.rationName
     };
-    return {coe:coe,ration_glj:ration_glj,ration:ration,add:data.add,delete:data.delete,replace:replace}
+    return {coe:coe,ration_glj:ration_glj,ration:ration,add:data.add,delete:data.delete,replace:replace,projectGLJList:projectGLJList}
 
 }
 

+ 4 - 0
modules/pm/controllers/pm_controller.js

@@ -307,8 +307,12 @@ module.exports = {
         rationValuation = await engineeringLibModel.getLib(rationValuation);
         let absoluteUrl = compilationData.overWriteUrl ? request.app.locals.rootDir + compilationData.overWriteUrl : request.app.locals.rootDir;
         let overWriteUrl = fs.existsSync(absoluteUrl) && fs.statSync(absoluteUrl).isFile()? compilationData.overWriteUrl : null;
+        //欢迎页显示控制
+        let [isShow,context] = await pm_facade.getWelcomeInfo(sessionCompilation._id,request.session.sessionUser);
         let renderData = {
             isFirst: isFirst,
+            isShow:isShow,
+            context:context,
             userAccount: request.session.userAccount,
             userID: request.session.sessionUser.id,
             compilationData: JSON.stringify(sessionCompilation),

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

@@ -40,7 +40,8 @@ module.exports={
     uploadToken:uploadToken,
     downLoadProjectFile:downLoadProjectFile,
     importProcessChecking:importProcessChecking,
-    isTenderOverrun
+    isTenderOverrun,
+    getWelcomeInfo:getWelcomeInfo
 };
 
 
@@ -79,6 +80,7 @@ let compleGljSectionTModel = mongoose.model('complementary_glj_section_templates
 let progressiveModel = mongoose.model('std_progressive_lib');
 let importLogsModel = mongoose.model("import_logs");
 const shareListModel = mongoose.model('share_list');
+let welcomeModel = mongoose.model("welcome_setting");
 
 
 let featureLibModel =  mongoose.model("std_project_feature_lib");
@@ -1099,7 +1101,7 @@ async function isFirst(userId, compilationId) {
     if (userData) {
         isFirst = !_.find(userData.used_list, function (o) {
             return o.compilationId === compilationId;
-        });;
+        })
     }
     return isFirst;
 }
@@ -1692,4 +1694,29 @@ async function isTenderOverrun(tenderCount, session) {
     const limit = systemSetting[type].project;
     const curTenderCount = await projectModel.count({userID, compilation, projType: 'Tender', '$or':[{deleteInfo: null}, {'deleteInfo.completeDeleted': false}]});
     return tenderCount + curTenderCount > limit;
+}
+
+async function getWelcomeInfo(compilationId,sessionUser) {
+    let setting = await welcomeModel.findOne({compilationId:compilationId});
+    let isShow = false;
+    let context = "";
+    if(setting){
+        if(setting.showType == 0) return [false,""];//关闭
+        context = setting.context;
+        if(setting.showType == 1){//每天一次
+            let dataString =moment(Date.now()).tz("Asia/Shanghai").format('YYYY-MM-DD');//今天的日期字符串
+            let userInfo =await userModel.findOne({_id: mongoose.Types.ObjectId(sessionUser.id)});
+            if (dataString != userInfo.welcomeShowTime){//今天没登录过
+                isShow = true;
+                await userModel.update({_id: mongoose.Types.ObjectId(sessionUser.id)},{welcomeShowTime:dataString})
+            }
+        }else if(setting.showType == 2){//每次登录显示
+            isShow = sessionUser.newLogin?true:false;
+            sessionUser.newLogin = false
+        }
+
+    }
+
+    return [isShow,context]
+
 }

+ 12 - 7
modules/ration_glj/facade/ration_glj_facade.js

@@ -145,10 +145,10 @@ function get_lib_glj_info(ration_glj) {
                 ration_glj.repositoryId = glj.repositoryId;
                 ration_glj.adjCoe = glj.adjCoe;
                 getInfoFromProjectGLJ(ration_glj).then(function (info) {
-                    if (info) {
+                    if (info&&info.length>0) {
                         let tem = {};
-                        tem.newRecode = createNewRecord(info);
-                        tem.showData = info;
+                        tem.newRecode = createNewRecord(info[0]);
+                        tem.showData = info[0];
                         result.datas.push(tem);
                         cb(null, result);
                     } else {
@@ -207,7 +207,7 @@ async function getInfoFromProjectGLJ(ration_glj,unitPriceFileId,ext) {
         if (result.hasOwnProperty('subList') && result.subList.length > 0) {
             ration_glj.subList = getMixRatioShowDatas(result.subList);
         }
-        return ration_glj;
+        return [ration_glj,result];
     } catch (err) {
         logger.err(err);
         return null;
@@ -654,12 +654,13 @@ function setPropertyFromStd(newGLJ,std_glj) {
 
 async function addGLJ(rgList,compilation) {
     if (rgList.length <= 0) return {};
-    let newRecodes = await insertAddTypeGLJ(rgList,compilation);
+    let [newRecodes,projectGLJList] = await insertAddTypeGLJ(rgList,compilation);
     let stateResult = await glj_calculate_facade.calculateQuantity({
         projectID: rgList[0].projectID,
         rationID: rgList[0].rationID
     });
     let result = {
+        projectGLJList:projectGLJList,
         newRecodes: newRecodes,
         showData: rgList,
         adjustState: stateResult.adjustState
@@ -669,6 +670,7 @@ async function addGLJ(rgList,compilation) {
 
 async function insertAddTypeGLJ(rgList,compilation) {
     let newRecodes = [],GLJMap=null;
+    let projectGLJList = [];
     let [unitFileId,ext] = await  prepareExtData(rgList[0].projectID,compilation);
 
     for (let g of rgList) {
@@ -696,9 +698,10 @@ async function insertAddTypeGLJ(rgList,compilation) {
             }
         }
         newRecodes.push(createNewRecord(g));
+        projectGLJList.push(result);
     }
     await ration_glj.insertMany(newRecodes);
-    return newRecodes;
+    return [newRecodes,projectGLJList];
 }
 
 async function deleteRationGLJ(data){
@@ -792,7 +795,7 @@ async  function replaceGLJByData(data,compilation) {
         let updateResult = await ration_glj.findOneAndUpdate({ID: data.ID, projectID: data.projectID}, data);//更新定额工料机
     }
 
-    return {data:data,newRecodes:newRecodes,deleteList:deleteList};
+    return {data:data,newRecodes:newRecodes,deleteList:deleteList,projectGLJ:result};
 }
 
 
@@ -853,6 +856,7 @@ async function replaceGLJ(data,compilation) {
         rationID: data.rationID
     }, null,true);
     rdata.data = data;
+    rdata.projectGLJ = r_result.projectGLJ;
     rdata.adjustState = stateResult.adjustState;
     rdata.name = stateResult.rationName;
     rdata.newRecodes = r_result.newRecodes;
@@ -911,6 +915,7 @@ async function mReplaceGLJ(data,compilation) {
     mresult.newRecodes = mixResult?mixResult.newRecodes:[];
     mresult.deleteList = mixResult?mixResult.deleteList:[];
     mresult.glj_result = glj_result;
+    mresult.projectGLJ = result;
     return mresult
 }
 

+ 90 - 2
modules/users/controllers/cld_controller.js

@@ -11,6 +11,7 @@
 import CLDModel from "../models/cld_model";
 import UserModel from "../models/user_model"
 import CompilationModel from "../models/compilation_model";
+let online_facade = require('../facade/online_facade')
 
 class CLDController {
 
@@ -62,10 +63,12 @@ class CLDController {
             if (userData === null || userData === '') {
                 throw '不存在该建筑用户';
             }
+            let userList = [userData];
+            await online_facade.setOnlineTimes(userList, {});
             userData = JSON.parse(JSON.stringify(userData));
 
-            userData.company_scale = userData.company_scale === null || userData.company_scale === undefined ? '' : userModel.companyScale[userData.company_scale] + '人';
-            userData.company_type = userData.company_type === null || userData.company_type === undefined ? '' : userModel.companyType[userData.company_type];
+            userData.company_scale = userData.company_scale === null || userData.company_scale === undefined || userData.company_scale === -1 ? '' : userModel.companyScale[userData.company_scale] + '人';
+            userData.company_type = userData.company_type === null || userData.company_type === undefined || userData.company_type === -1 ? '' : userModel.companyType[userData.company_type];
             userData.province = userModel.province[userData.province];
 
             let date = new Date(userData.create_time);
@@ -213,6 +216,91 @@ class CLDController {
             response.json({error: 1, msg: err});
         }
     }
+
+    /**
+     * 获取用户列表分页
+     * @param request
+     * @param response
+     * @returns {Promise<void>}
+     */
+    async getUserList(request, response) {
+        let userModel = new UserModel();
+        let total = 0;
+        let pageSize = 12;
+        let pageData = {};
+        let userList = [];
+        let compilationList =[];
+        let filter = request.query;
+        try {
+            //获取编办列表
+            let  compilationModel = new CompilationModel();
+            compilationList = await compilationModel.getCompilationList({_id: 1, name: 1, is_release: 1});
+            let condition = userModel.getFilterCondition(request);
+            //设置搜索普通用户:
+            condition.user_type = 'normal';
+
+            //获取注册时间
+            let regtime = request.query.regtime;
+            if(regtime !== '' && regtime !== undefined){
+                filter.regtimeMsg = userModel.getDayMsg(regtime);
+            }
+
+            //获取注册时间
+            let loginTime = request.query.loginTime;
+            if(loginTime !== '' && loginTime !== undefined){
+                filter.loginMsg = userModel.getDayMsg(loginTime);
+            }
+
+            // 排序方式
+            let sortType = request.query.sortType !== '' && request.query.sortType !== undefined ? request.query.sortType : -1;
+
+            // 排序条件
+            let sortField = request.query.sortField;
+            let sort = sortField !== '' && sortField !== undefined && sortField === 'latest_login' ? {latest_login: sortType}: {_id: sortType};
+
+            // 获取用户总数
+            total = await userModel.count(condition);
+
+            // 分页数据
+            let page = request.query.page === undefined ? 1 : request.query.page;
+            pageSize = request.query.pageSize === undefined ? 12 : parseInt(request.query.pageSize);
+            pageData = {
+                current: page,
+                total: total,
+                queryData: response.locals.urlQuery
+            };
+            // console.log("取用户信息=========================");
+            // console.log(condition);
+            // 获取用户列表
+            userList = await userModel.getList(condition, page, pageSize, sort);
+            await online_facade.setOnlineTimes(userList,condition);
+            response.json({error: 0, msg: 'success', data: {
+                userInfo: userList,
+                pageData: pageData,
+                compilationList:compilationList,
+            }});
+        } catch (error) {
+            response.json({error: 1, msg: error});
+        }
+    }
+
+    async getUserOnlineInfo(request, response){
+        let filter = JSON.parse(request.body.data);
+        let responseData = {
+            error: 0,
+            msg: '',
+            data: null
+        };
+        try{
+            let info = await online_facade.getOnlineInfo(filter);
+            responseData.data = info;
+        } catch (error) {
+            console.log(error);
+            responseData.error = error.code;
+            responseData.msg = error.err;
+        }
+        response.json(responseData);
+    }
 }
 
 export default CLDController;

+ 1 - 0
modules/users/controllers/login_controller.js

@@ -241,6 +241,7 @@ class LoginController {
                 mobile: userData.mobile,
                 qq: userData.qq,
                 isUserActive: userData.isUserActive,
+                newLogin:true
             };
 
             request.session.sessionUser = sessionUser;

+ 62 - 0
modules/users/facade/online_facade.js

@@ -0,0 +1,62 @@
+/**
+ * Created by zhang on 2019/4/16.
+ */
+
+module.exports = {
+    setOnlineTimes:setOnlineTimes,
+    getOnlineInfo:getOnlineInfo
+};
+
+let mongoose = require("mongoose");
+let logs_model = mongoose.model("online_logs");
+
+async function getOnlineInfo(filter) {
+    let datas = [];
+    let logs = await logs_model.find(filter);
+    let less = 0;
+    for(let l of logs){
+        let d = getTimeString(l.online_times);
+        let online_times = d.s;
+        less += d.less;
+        if(online_times!=""){
+            datas.push({dateString:l.dateString,dateTime:l.online_times,online_times:online_times})
+        }
+    }
+    if(datas.length>1){//大于2个才把不够1分钟的累积到最后一条记录
+        let last =  datas[datas.length - 1];
+        last.online_times = getTimeString(last.dateTime + less).s;
+    }
+
+    return datas;
+}
+
+
+async function setOnlineTimes(userList,condition){
+    for(let u of userList){
+        let filter = {'userID':u._id.toString()};
+        if(u.latest_used) filter["compilationID"] = u.latest_used;
+        if(condition.latest_login && condition.latest_login == ""){
+            let startTime = condition.latest_login['$gte']; //- 24*60*60*1000 //往前推一天  {'$gte': startTime, '$lt': endTime}latest_login
+            filter['dateTime'] = {'$gte': startTime, '$lt':  condition.latest_login['$lt']}
+        }
+
+        let result =  await logs_model.aggregate([
+            {$match: filter},
+            {$group: {_id: "$userID", total: {$sum: "$online_times"}}}
+        ]);
+        u._doc.filter = JSON.stringify(filter);
+        if(result.length > 0)  u._doc.online_times = getTimeString(result[0].total).s;
+        u._doc.online_list = await this.getOnlineInfo(filter);
+    }
+}
+
+
+function getTimeString(times) {
+    let s = "",perHour = 1000 * 60 * 60,perMin = 1000 * 60;
+    let hour = parseInt(times/perHour);
+    let min = parseInt((times % perHour)/perMin);
+    let less =  (times % perHour)%perMin;//不够一分钟的时间
+    if(hour > 0) s = s+`${hour}小时`;
+    if(min > 0)  s= s+`${min}分钟`;
+    return {s:s,less:less}
+}

+ 14 - 0
modules/users/models/compilation_model.js

@@ -26,6 +26,20 @@ class CompilationModel extends BaseModel {
      *
      * @return {Promise}
      */
+    async getCompilationList(fields = null) {
+        // 筛选字段
+        let field = fields == null ?{_id: 1, name: 1, is_release: 1, categoryID: 1, description: 1,overWriteUrl: 1,example: 1, "ration_valuation.id": 1, "ration_valuation.name": 1, "ration_valuation.enable": 1,
+            "bill_valuation.id": 1, "bill_valuation.name": 1, "bill_valuation.enable": 1}:fields;
+        let compilationData = await this.findDataByCondition({name: {$ne: ''}}, field, false);
+
+        return compilationData === null ? [] : compilationData;
+    }
+
+    /**
+     * 获取编办列表
+     *
+     * @return {Promise}
+     */
     async getList() {
         // 筛选字段
         let field = {_id: 1, name: 1, is_release: 1, description: 1, categoryID: 1};

+ 106 - 0
modules/users/models/user_model.js

@@ -36,6 +36,13 @@ class UserModel extends BaseModel {
      */
     companyScale = ['1-50', '50-100', '100-500', '500+'];
 
+    /**
+     * 最近天数
+     *
+     * @var
+     */
+    dayMsg = ['所有', '最近24小时', '最近3天', '最近7天', '最近30天'];
+
 
     /**
      * 构造函数
@@ -276,6 +283,7 @@ class UserModel extends BaseModel {
             username: userData.username,
             email: userData.email,
             mobile: userData.mobile,
+            qq: userData.qq,
             create_time: new Date().getTime(),
             latest_login: new Date().getTime(),
             isUserActive: userData.isUserActive,
@@ -385,6 +393,104 @@ class UserModel extends BaseModel {
         return users;
     }
 
+    /**
+     * 获取列表
+     *
+     * @param {object} condition
+     * @param {number} page
+     * @param {Number} pageSize
+     * @return {promise}
+     */
+    async getList(condition = null, page = 1, pageSize = 30, sort = {_id:-1}) {
+        page = parseInt(page);
+        page = page <= 1 ? 1 : page;
+        let option = {pageSize: pageSize, offset: parseInt((page - 1) * pageSize), sort: sort};
+
+        let userList = await this.db.find(condition, null, option);
+        userList = userList.length > 0 ? userList : [];
+
+        return userList;
+    }
+
+    /**
+     * 获取过滤条件
+     *
+     * @return {Object}
+     */
+    getFilterCondition(request) {
+        let condition = {};
+        let regtime = request.query.regtime;
+        regtime = regtime !== '' && regtime !== undefined ? parseInt(regtime) : 0;
+        if (regtime !== 0) {
+            condition.create_time = this.getTimestamp(regtime);
+        }
+
+        //最近登录时间
+        let loginTime = request.query.loginTime;
+        loginTime = loginTime !== '' && loginTime !== undefined ? parseInt(loginTime) : 0;
+        if (loginTime !== 0) {
+            condition.latest_login = this.getTimestamp(loginTime);
+        }
+
+        let version = request.query.version;
+        if(version !== '' && version !== undefined) {
+            condition.version = version;
+        }
+        // 已升级费用定额
+        let upGrade = request.query.upGrade;
+        if(upGrade !== '' && upGrade !== undefined){
+            condition.upgrade_list = {"$elemMatch":{"compilationID":upGrade,"isUpgrade":true}};
+        }
+
+        // 最近使用费用定额
+        let latestUsed = request.query.latestUsed;
+        if(latestUsed !== '' && latestUsed !== undefined){
+            condition.latest_used = latestUsed;
+        }
+
+        let keyword = request.query.keyword;
+        if (keyword !== '' && keyword !== undefined) {
+            condition.$or = [{real_name : {$regex: keyword}},{email : {$regex: keyword}},{mobile : {$regex: keyword}},{company : {$regex: keyword}}];
+        }
+
+        return condition;
+    }
+
+    /**
+     * 获取时间戳区间
+     *
+     * @return {Object}
+     */
+    getTimestamp(type) {
+        let startTime = '';
+        switch (type) {
+            case 1 :
+                startTime = Date.parse(new Date())-86400*1000;
+                break;
+            case 2 :
+                startTime = Date.parse(new Date())-86400*1000*3;
+                break;
+            case 3 :
+                startTime = Date.parse(new Date())-86400*1000*7;
+                break;
+            case 4 :
+                startTime = Date.parse(new Date())-86400*1000*30;
+                break;
+            default :
+                break;
+        }
+        let endTime =  Date.parse(new Date());
+        return startTime === '' ? '' : {'$gte': startTime, '$lt': endTime};
+    }
+
+    /**
+     * 获取daymsg
+     *
+     */
+    getDayMsg(index){
+        return this.dayMsg[index];
+    }
+
 }
 
 export default UserModel;

+ 4 - 0
modules/users/routes/cld_route.js

@@ -26,5 +26,9 @@ module.exports = function (app) {
 
     router.get('/getUsersInfo', cldController.getUsersInfo);
 
+    router.get('/getUserList', cldController.getUserList);
+
+    router.post('/getUserOnlineInfo', cldController.getUserOnlineInfo);
+
     app.use('/cld',router)
 };

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

@@ -95,7 +95,7 @@
                             <a id="uploadGld" class="dropdown-item" href="#import" data-toggle="modal" data-target="#import">导入广联达算量Excel清单</a>
                         </div>-->
                     </span>
-                    <a href="javascript:void(0)" class="btn btn-light btn-sm" id="insertRation" data-toggle="tooltip" data-placement="bottom" data-original-title="插入定额"><i class="fa fa-sign-in" aria-hidden="true"></i></a>
+                   <!-- <a href="javascript:void(0)" class="btn btn-light btn-sm" id="insertRation" data-toggle="tooltip" data-placement="bottom" data-original-title="插入定额"><i class="fa fa-sign-in" aria-hidden="true"></i></a>-->
                     <!--2018-11-15 隐藏删除按钮   <a href="javascript:void(0)" class="btn btn-light btn-sm" id="delete" data-toggle="tooltip" data-placement="bottom" data-original-title="删除"><i class="fa fa-remove" aria-hidden="true"></i></a>-->
                     <a href="javascript:void(0)" class="btn btn-light btn-sm" id="upLevel" data-toggle="tooltip" data-placement="bottom" data-original-title="升级"><i class="fa fa-arrow-left" aria-hidden="true"></i></a>
                     <a href="javascript:void(0)"  class="btn btn-light btn-sm" id="downLevel" data-toggle="tooltip" data-placement="bottom" data-original-title="降级"><i class="fa fa-arrow-right" aria-hidden="true"></i></a>

+ 3 - 3
web/building_saas/main/js/controllers/block_controller.js

@@ -355,9 +355,9 @@ let BlockController = {
                 }
             }
         }
-        //更新项目工料机模块信息-计算消耗量
-        project.projectGLJ.datas = result.gljData;
-        project.projectGLJ.calcQuantity();
+        //更新项目工料机模块信息-计算消耗量 ---修改了加载方式
+       /* project.projectGLJ.datas = result.gljData;
+        project.projectGLJ.calcQuantity();*/
         for(let r of result.rations){
             if(r.type == rationType.gljRation){//对于工料机类型的定额,要重新设置下市场单价
                 gljOprObj.setGLJPrice(r);

+ 14 - 8
web/building_saas/main/js/models/project_glj.js

@@ -816,7 +816,7 @@ ProjectGLJ.prototype.updateMaterialRation = async function (datas){
         let lists = datas.type == "freight"?this.datas.freightList:this.datas.originalList;
         $.bootstrapLoading.start();
         let result =  await ajaxPost('/ration/updateMaterialRation',datas);
-        if(datas.actionType=="add" && result.projectGLJDatas) this.refreshByDatas(result.projectGLJDatas);//这一步已经更新了运费和原价数据
+        if(datas.actionType=="add" && result.projectGLJList) this.loadNewProjectGLJToCaches(result.projectGLJList,true);//这一步已经更新了运费和原价数据
         if(datas.actionType == "delete"){
            let parent = _.find(lists,{ID:datas.parentID}) ;
            if(parent){
@@ -828,8 +828,8 @@ ProjectGLJ.prototype.updateMaterialRation = async function (datas){
             let parent = _.find(lists,{ID:datas.parentID}) ;
             let ration = parent?_.find(parent.rations,{ID:datas.rationID}):null;
             if(ration){
-                if(datas.field == "code" && result.projectGLJDatas){
-                    this.refreshByDatas(result.projectGLJDatas);
+                if(datas.field == "code" && result.projectGLJList){
+                    this.loadNewProjectGLJToCaches(result.projectGLJList,true);
                 }else {
                     ration[datas.field] = datas.value;
                     if(datas.ext){
@@ -1705,18 +1705,23 @@ ProjectGLJ.prototype.calcTenderQuantity  = function (){
     gljUtil.calcProjectGLJQuantity(this.datas,rationGLJDatas,rationDatas,billsDatas,getDecimal("glj.quantity"),_,scMathUtil,true);
 };
 
-ProjectGLJ.prototype.loadNewProjectGLJToCaches = function (datas) {
+ProjectGLJ.prototype.loadNewProjectGLJToCaches = function (datas,calquantity = false) {
+    if(!datas) return;
+    let gljIDMap = {};
     for (let d of datas){
-        this.loadNewProjectGLJToCache(d);
+        if(d) this.loadNewProjectGLJToCache(d,gljIDMap);
     }
+    if(datas.length > 0 &&  calquantity)  this.calcQuantity();
 };
 
-ProjectGLJ.prototype.loadNewProjectGLJToCache = function (data) {//把新插入的项目工料机数据增加至缓存中
+ProjectGLJ.prototype.loadNewProjectGLJToCache = function (data,tIDMap) {//把新插入的项目工料机数据增加至缓存中
+    if(!data) return;
     let project_gljs = this.datas.gljList;
     let unitPriceMap = this.datas.unitPriceMap;
     let mixRatioMap = this.datas.mixRatioMap;
     let mixRatioConnectData = this.datas.mixRatioConnectData;
-    let tem =  _.find(project_gljs,{'id':data.id});
+    let IDMap = !_.isEmpty(tIDMap)?tIDMap:_.indexBy(project_gljs,'id');
+    let tem =  IDMap[data.id];
     if(tem) return tem; //判断该工料机是否已经存在,是的话不用再次添加
     //查看是否有组成物,有组成物的话先添加组成物信息
     data.ratio_data=[];
@@ -1727,7 +1732,7 @@ ProjectGLJ.prototype.loadNewProjectGLJToCache = function (data) {//把新插入
             mixRatioMap[ratio.connect_key]?mixRatioMap[ratio.connect_key].push(ratio):mixRatioMap[ratio.connect_key] = [ratio];
             let rIndex = gljUtil.getIndex(ratio);
             mixRatioConnectData[rIndex]?mixRatioConnectData[rIndex].push(ratio.connect_key):mixRatioConnectData[rIndex] = [ratio.connect_key];
-            this.loadNewProjectGLJToCache(s);
+            this.loadNewProjectGLJToCache(s,IDMap);
         }
         delete data.subList;
     }
@@ -1735,5 +1740,6 @@ ProjectGLJ.prototype.loadNewProjectGLJToCache = function (data) {//把新插入
     let uIndex = gljUtil.getIndex(data.unit_price);
     if(!unitPriceMap[uIndex])  unitPriceMap[uIndex] = data.unit_price;
     this.datas.gljList.push(data);
+    IDMap[data.id] = data;
     return data;
 };

+ 32 - 36
web/building_saas/main/js/models/ration.js

@@ -426,19 +426,16 @@ var Ration = {
                        project.ration_glj.removeNodeByRation(recode.ration,projectObj.mainController);
                        project.Ration.deleteSubListOfRation(recode.ration,cleanzmhs);//删除旧定额下的相关记录
                        //添加新的记录
-                       project.Ration.addSubListOfRation(recode);
-
-
+                       project.Ration.addSubListOfRation(recode,false);
                        project.ration_glj.addToMainTree(recode.ration_gljs);
                    }
                 }
-                project.projectGLJ.loadData(function () {
-                    mbzm_obj.nodeChanged = true;//子目模板关联刷新
-                    gljOprObj.showDataIfRationSelect(projectObj.project.mainTree.selected,"-111111111");//这里第二个参数是为了使改前和改后selectedID不一样,删除了的话下方的定额工料机不会刷新
-                    project.calcProgram.calcNodesAndSave(refershNodes);
-                    projectObj.mainController.refreshTreeNode(refershNodes, true);
-                    $.bootstrapLoading.end();
-                });
+                project.projectGLJ.calcQuantity();
+                mbzm_obj.nodeChanged = true;//子目模板关联刷新
+                gljOprObj.showDataIfRationSelect(projectObj.project.mainTree.selected,"-111111111");//这里第二个参数是为了使改前和改后selectedID不一样,删除了的话下方的定额工料机不会刷新
+                project.calcProgram.calcNodesAndSave(refershNodes);
+                projectObj.mainController.refreshTreeNode(refershNodes, true);
+                $.bootstrapLoading.end();
 
                 if(data.length < nodeInfo.length && nodeInfo[data.length].newCode!=null){//说明有部分定额编号没找到记录
                     alert('当前库中找不到定额"' + nodeInfo[data.length].newCode + '"');
@@ -512,7 +509,7 @@ var Ration = {
                     //更新缓存
                     for(let data of rstData){
                         me.datas.push(data.ration);
-                        me.addSubListOfRation(data);
+                        me.addSubListOfRation(data,false);
                         //插入树节点
                         newSource = data.ration;
                         newNode = project.mainTree.insert(billItemID, nextID, newSource.ID);
@@ -523,29 +520,28 @@ var Ration = {
                         newNode.data = newSource;
                         ProjectController.syncDisplayNewNode(sheetController, newNode);
                     }
-                    project.projectGLJ.loadData(function () {
-                        for(let data of rstData){
-                            project.ration_glj.addToMainTree(data.ration_gljs);
-                        }
-                        projectObj.mainController.refreshTreeNode(newNodes, false);
-                        if(project.Bills.isFBFX(newNodes[0])) { //判断是否属于分部分项工程 ,是的话才需要做计取安装费计算
-                            project.installation_fee.calcInstallationFee(function (isChange,rations) {
-                                if(isChange){
-                                    rations = rations.concat(newNodes);
-                                    project.calcProgram.calcNodesAndSave(rations);
-                                }else {
-                                    project.calcProgram.calcNodesAndSave(newNodes);
-                                }
-                            });
-                        }else {
-                            project.calcProgram.calcNodesAndSave(newNodes);
-                        }
-                        if(callback){
-                            callback();
-                        }
-                        showLoding = false;
-                        $.bootstrapLoading.end();
-                    });
+                    project.projectGLJ.calcQuantity();
+                    for(let data of rstData){
+                        project.ration_glj.addToMainTree(data.ration_gljs);
+                    }
+                    projectObj.mainController.refreshTreeNode(newNodes, false);
+                    if(project.Bills.isFBFX(newNodes[0])) { //判断是否属于分部分项工程 ,是的话才需要做计取安装费计算
+                        project.installation_fee.calcInstallationFee(function (isChange,rations) {
+                            if(isChange){
+                                rations = rations.concat(newNodes);
+                                project.calcProgram.calcNodesAndSave(rations);
+                            }else {
+                                project.calcProgram.calcNodesAndSave(newNodes);
+                            }
+                        });
+                    }else {
+                        project.calcProgram.calcNodesAndSave(newNodes);
+                    }
+                    if(callback){
+                        callback();
+                    }
+                    showLoding = false;
+                    $.bootstrapLoading.end();
                 })
             }
         };
@@ -614,7 +610,6 @@ var Ration = {
                         syncNodeOper(data);
                         if(callback) callback(newNode);
                     }else {
-                        if(data.projectGLJDatas) projectObj.project.projectGLJ.refreshByDatas(data.projectGLJDatas);
                         syncNodeOper(data);
                         if (newNode.parent.data.calcFlag)  newNode.parent.updateData.calcFlag = null;    // 删除定额时不用改Flag,反正添加定额时已经改好了。
                         project.calcProgram.calcAndSave(newNode,function () {
@@ -720,12 +715,13 @@ var Ration = {
                 projectObj.project.ration_template.deleteByRation(ration);
             }
         };
-        ration.prototype.addSubListOfRation = function (data) {
+        ration.prototype.addSubListOfRation = function (data,calquantity = true) {
              project.ration_glj.addDatasToList(data.ration_gljs);
              project.ration_coe.addDatasToList(data.ration_coes);
              project.ration_installation.addDatasToList(data.ration_installations);
              project.ration_template.addDatasToList(data.ration_templates);
              project.quantity_detail.addDatasToList(data.quantity_details);
+            if(data.projectGLJList ) projectObj.project.projectGLJ.loadNewProjectGLJToCaches(data.projectGLJList,calquantity);
         };
 
         ration.prototype.replaceRation = function (ration, std) {

+ 15 - 16
web/building_saas/main/js/models/ration_glj.js

@@ -752,23 +752,21 @@ let ration_glj = {
                     let data = result.data;
                     let rationNode = projectObj.project.mainTree.findNode(data.rationID);
                     let nodes =  [rationNode];
-                    project.projectGLJ.loadData(function () {//加载完项目工料机再计算
-                        gljOprObj.refreshView();
-                        if (project.ration_glj.needShowToTree(data)) {//当替换的是主材或设备时,刷新对应的树节点
-                            let node = project.ration_glj.findGLJNodeByID(data.ID);
-                            if (node) {
-                                project.ration_glj.transferToNodeData(data);
-                                node.source = data;
-                                node.data = data;
-                            }
-                            node ? nodes.push(node) : "";
+                    gljOprObj.refreshView();
+                    if (project.ration_glj.needShowToTree(data)) {//当替换的是主材或设备时,刷新对应的树节点
+                        let node = project.ration_glj.findGLJNodeByID(data.ID);
+                        if (node) {
+                            project.ration_glj.transferToNodeData(data);
+                            node.source = data;
+                            node.data = data;
                         }
-                        rationNode.data.adjustState = result.adjustState;
-                        rationNode.data.name = result.name;
-                        projectObj.mainController.refreshTreeNode(nodes);
-                        project.calcProgram.calcAndSave(rationNode);
-                        $.bootstrapLoading.end();
-                    });
+                        node ? nodes.push(node) : "";
+                    }
+                    rationNode.data.adjustState = result.adjustState;
+                    rationNode.data.name = result.name;
+                    projectObj.mainController.refreshTreeNode(nodes);
+                    project.calcProgram.calcAndSave(rationNode);
+                    $.bootstrapLoading.end();
                 }
             }, function () {
                 $.bootstrapLoading.end();
@@ -781,6 +779,7 @@ let ration_glj = {
             let list_index = _.findIndex(me.datas, {'ID': result.data.ID});
             if(result.data) me.datas[list_index] = result.data;
             me.refreshQuantityAfterCalResult(result.glj_result);
+            if(result.projectGLJ) project.projectGLJ.loadNewProjectGLJToCaches([result.projectGLJ],true);
         };
 
         ration_glj.prototype.addAndDeleteDatas = function (newRecodes,deleteList) {

+ 30 - 33
web/building_saas/main/js/views/glj_view.js

@@ -1167,13 +1167,12 @@ var gljOprObj = {
                     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);//组成物不会显示到造价书页面
-                        project.calcProgram.calcAndSave(selected);
-                        projectObj.mainController.refreshTreeNode([selected]);
-                        gljOprObj.refreshView();
-                        $.bootstrapLoading.end();
-                    });
+                    project.projectGLJ.loadNewProjectGLJToCaches(result.projectGLJList,true);
+                    project.ration_glj.addToMainTree(result.showData);//组成物不会显示到造价书页面
+                    project.calcProgram.calcAndSave(selected);
+                    projectObj.mainController.refreshTreeNode([selected]);
+                    gljOprObj.refreshView();
+                    $.bootstrapLoading.end();
                 }
             });//doc.rationID=selected.data.ID;
         }
@@ -1215,26 +1214,24 @@ var gljOprObj = {
                 project.ration_glj.setDatasAfterReplace(result);
                 let data = result.data;
                 let nodes = [selected];
-                project.projectGLJ.loadData(function () {//加载完项目工料机再计算
-                    let node = project.ration_glj.updateGLJNodeAfterReplace(data);
-                    if(node) nodes.push(node);
-                    /*if (project.ration_glj.needShowToTree(data)) {//当替换的是主材或设备时,刷新对应的树节点
-                     var node = project.ration_glj.findGLJNodeByID(data.ID);
-                     if (node) {
-                     project.ration_glj.transferToNodeData(data);
-                     node.source = data;
-                     node.data = data;
-                     }
-                     node ? nodes.push(node) : "";
-                     }*/
-                    //project.ration_glj.addToMainTree(data);
-                    selected.data.adjustState = result.adjustState;
-                    selected.data.name = result.name;
-                    projectObj.mainController.refreshTreeNode(nodes);
-                    project.calcProgram.calcAndSave(selected);
-                    gljOprObj.refreshView();
-                    $.bootstrapLoading.end();
-                });
+                let node = project.ration_glj.updateGLJNodeAfterReplace(data);
+                if(node) nodes.push(node);
+                /*if (project.ration_glj.needShowToTree(data)) {//当替换的是主材或设备时,刷新对应的树节点
+                 var node = project.ration_glj.findGLJNodeByID(data.ID);
+                 if (node) {
+                 project.ration_glj.transferToNodeData(data);
+                 node.source = data;
+                 node.data = data;
+                 }
+                 node ? nodes.push(node) : "";
+                 }*/
+                //project.ration_glj.addToMainTree(data);
+                selected.data.adjustState = result.adjustState;
+                selected.data.name = result.name;
+                projectObj.mainController.refreshTreeNode(nodes);
+                project.calcProgram.calcAndSave(selected);
+                gljOprObj.refreshView();
+                $.bootstrapLoading.end();
             }
         })
     },
@@ -1272,12 +1269,12 @@ var gljOprObj = {
                     me.updateProperty(t,quantityMap[t.ID]);
                 }
             })
-            project.projectGLJ.loadData(function () {
-                var rationNodes = me.refreshStateAfterMreplace(stateList, nodes);
-                project.calcProgram.calcNodesAndSave(rationNodes);
-                me.refreshView();
-                $.bootstrapLoading.end();
-            });
+            project.projectGLJ.loadNewProjectGLJToCaches([result.projectGLJ],true);
+            var rationNodes = me.refreshStateAfterMreplace(stateList, nodes);
+            project.calcProgram.calcNodesAndSave(rationNodes);
+            me.refreshView();
+            $.bootstrapLoading.end();
+
         })
     },
     updateProperty: function (obj, doc) {

+ 9 - 9
web/building_saas/main/js/views/mbzm_view.js

@@ -157,7 +157,7 @@ let mbzm_obj={
             if(result.rationResult){
                 for(let rr of result.rationResult){
                     nodeDatas.ration.add.push(rr.ration);//定额datas数据的push在addNodes里面做
-                    projectObj.project.Ration.addSubListOfRation(rr);//添加定额子项缓存
+                    projectObj.project.Ration.addSubListOfRation(rr,false);//添加定额子项缓存
                 }
             }
             //对于新插入的清单:
@@ -174,15 +174,15 @@ let mbzm_obj={
                 }
                 projectObj.mainController.refreshTreeNode(refreshNodes, false);
             }
-            projectObj.project.projectGLJ.loadData(function () {
-                $.bootstrapLoading.end();
-                cbTools.refreshFormulaNodes();
-                //更新计算程序模板,并进行重新计算
-                projectObj.project.calcProgram.calcNodesAndSave(calRations,function () {
-                    installationFeeObj.calcInstallationFee();
-                });
-                mbzm_obj.showApplySuccess();
+            projectObj.project.projectGLJ.calcQuantity();
+            $.bootstrapLoading.end();
+            cbTools.refreshFormulaNodes();
+            //更新计算程序模板,并进行重新计算
+            projectObj.project.calcProgram.calcNodesAndSave(calRations,function () {
+                installationFeeObj.calcInstallationFee();
             });
+            mbzm_obj.showApplySuccess();
+
         })
     },
     showApplySuccess:function () {

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

@@ -56,6 +56,7 @@ projectGljObject={
             sheetCommonObj.spreadDefaultStyle(this.projectGljSpread);
         }
         this.projectGljSpread.bind(GC.Spread.Sheets.Events.RangeChanged, this.onProjectGljRangeChange);
+        this.projectGljSpread.getActiveSheet().options.frozenlineColor = '#ababab';
         this.initProjectGljSheet();
         this.initMaterialTreeSheet();
         //打开别人分享的项目,只读

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

@@ -866,6 +866,7 @@ var projectObj = {
             this.mainSpread.getActiveSheet().selectionPolicy(GC.Spread.Sheets.SelectionPolicy.muliRange);
             this.mainSpread.getActiveSheet().name('mainSheet');
             this.mainSpread.getActiveSheet().options.isProtected = true;
+            this.mainSpread.getActiveSheet().options.frozenlineColor = '#ababab';
         }
     },
     refreshMainSpread: function () {

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

@@ -262,8 +262,8 @@ let zmhs_obj = {
         projectObj.mainController.refreshTreeNode(nodes, false);
         let rationID = result.ration.ID;
         ration_glj.updateCacheAfterAdjust(result.ration_glj);
-        if(result.projectGLJDatas){//有添加、替换、工料机等需重新加载的情况
-            projectObj.project.projectGLJ.refreshByDatas(result.projectGLJDatas);
+        if(result.projectGLJList && result.projectGLJList.length > 0){//有添加、替换、工料机等需重新加载的情况
+            projectObj.project.projectGLJ.loadNewProjectGLJToCaches(result.projectGLJList,true);
             if(result.add && result.add.length > 0) ration_glj.addToMainTree(result.add);//这个方法有再去项目工料机那里取价格,所以要在回调里调用,不像替换工料的情况
             ration_glj.reCalcWhenGLJChange({rationID:rationID});
             if(result.delete && result.delete.length > 0 && calcInstall) installationFeeObj.calcInstallationFee();//如果是删除节点的话,

+ 20 - 0
web/building_saas/pm/html/project-management.html

@@ -21,6 +21,8 @@
         var userAccount = '<%- userAccount %>';
         var userID = '<%- userID %>';
         let isFirst = JSON.parse('<%- isFirst %>');
+        let isShow = JSON.parse('<%- isShow %>');
+
     </script>
     <style type="text/css">
         .hidden-area{
@@ -717,6 +719,24 @@
     </div>
 </div>
 
+<!--弹出信息-->
+<div class="modal fade" id="welcomePage" data-backdrop="static">
+    <div class="modal-dialog modal-lg" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">欢迎使用纵横公路养护云造价</h5>
+                <button type="button" class="close text-danger" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">&times;</span>
+                </button>
+            </div>
+            <div class="modal-body" id="welcomeBody">
+                <div style="max-height:465px">
+                     <%- context %>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
 
 <!-- JS. -->
 <script src = "/lib/spreadjs/sheets/gc.spread.sheets.all.11.1.2.min.js"></script>

+ 6 - 0
web/building_saas/pm/js/pm_newMain.js

@@ -2289,6 +2289,7 @@ function initProjects(callback) {
             projTreeObj.tree.selected = projTreeObj.tree.items[0];
             projTreeObj.workBook = projTreeObj.buildSheet(projTreeObj.workBook,'projSpread',projTreeObj.setting);
             const sheet = projTreeObj.workBook.getSheet(0);
+            sheet.options.frozenlineColor = '#ababab';
             sheet.frozenColumnCount(2);
             sheet.name('projectSheet');
             sheetCommonObj.spreadDefaultStyle(projTreeObj.workBook);
@@ -4133,3 +4134,8 @@ function refreshProjSummary(project, summaryInfo) {
     }
     projTreeObj.refreshNodeData(refreshNodes);
 }
+
+
+$(function () {
+   if(isShow)  $('#welcomePage').modal('show');//是否显示欢迎页
+});

+ 1 - 0
web/building_saas/pm/js/pm_share.js

@@ -47,6 +47,7 @@ const pmShare = (function () {
         },
         sheet: {
             isProtected: true,
+            frozenlineColor : '#ababab',
             protectionOptions: {allowResizeRows: true, allowResizeColumns: true},
             clipBoardOptions: GC.Spread.Sheets.ClipboardPasteOptions.values
         }

+ 254 - 32
web/over_write/js/anhui_2019.js

@@ -4,7 +4,7 @@
 
 let isAH2019 = true;
 
-function overwriteRationCalcBases (){
+function overwriteRationCalcBases() {
     if (typeof rationCalcBases == 'undefined') return;
     for (let key in rationCalcBases) delete rationCalcBases[key];
 
@@ -20,9 +20,9 @@ function overwriteRationCalcBases (){
     rationCalcBases['施工机械人工费'] = function (node, isTender) {
         return calcTools.machineDetailFee(node, node.data.gljList, [], gljType.MACHINE_LABOUR, isTender);
     };
-   /* rationCalcBases['设备购置费'] = function (node, isTender) {
-        return calcTools.rationBaseFee(node, [gljType.EQUIPMENT], priceTypes.ptMarketPrice, isTender);
-    };*/
+    /* rationCalcBases['设备购置费'] = function (node, isTender) {
+         return calcTools.rationBaseFee(node, [gljType.EQUIPMENT], priceTypes.ptMarketPrice, isTender);
+     };*/
 
     rationCalcBases['定额人工费'] = function (node, isTender) {
         return calcTools.rationBaseFee(node, [gljType.LABOUR], priceTypes.ptBasePrice, isTender);
@@ -33,43 +33,265 @@ function overwriteRationCalcBases (){
     rationCalcBases['定额施工机械使用费'] = function (node, isTender) {
         return calcTools.rationBaseFee(node, baseMachineTypes, priceTypes.ptBasePrice, isTender);
     };
-/*    rationCalcBases['定额商品砼费'] = function (node, isTender) {
-        return calcTools.rationBaseFee(node, [gljType.COMMERCIAL_CONCRETE, gljType.COMMERCIAL_MORTAR], priceTypes.ptBasePrice, isTender);
-    };
-    rationCalcBases['定额设备费'] = function (node, isTender) {
-        return calcTools.rationBaseFee(node, [gljType.EQUIPMENT], priceTypes.ptBasePrice, isTender);
-    };
-    rationCalcBases['定额外购砼构件费'] = function (node, isTender) {
-        return calcTools.rationBaseFee(node, [gljType.PURCHASE_COMPONENT], priceTypes.ptBasePrice, isTender);
-    };
-    rationCalcBases['定额绿化苗木费'] = function (node, isTender) {
-        return calcTools.rationBaseFee(node, [gljType.GREEN_SEEDLING], priceTypes.ptBasePrice, isTender);
-    };*/
+    /*    rationCalcBases['定额商品砼费'] = function (node, isTender) {
+            return calcTools.rationBaseFee(node, [gljType.COMMERCIAL_CONCRETE, gljType.COMMERCIAL_MORTAR], priceTypes.ptBasePrice, isTender);
+        };
+        rationCalcBases['定额设备费'] = function (node, isTender) {
+            return calcTools.rationBaseFee(node, [gljType.EQUIPMENT], priceTypes.ptBasePrice, isTender);
+        };
+        rationCalcBases['定额外购砼构件费'] = function (node, isTender) {
+            return calcTools.rationBaseFee(node, [gljType.PURCHASE_COMPONENT], priceTypes.ptBasePrice, isTender);
+        };
+        rationCalcBases['定额绿化苗木费'] = function (node, isTender) {
+            return calcTools.rationBaseFee(node, [gljType.GREEN_SEEDLING], priceTypes.ptBasePrice, isTender);
+        };*/
 };
 
 (function overwriteFeeTypes() {
     if (typeof cpFeeTypes == 'undefined') return;
     cpFeeTypes = [
-        {type: 'marketLabour', name: '人工费'},
-        {type: 'marketMaterial', name: '材料费'},
-        {type: 'marketMachine', name: '施工机械使用费'},
-        {type: 'marketMachineLabour', name: '施工机械人工费'},
+        { type: 'marketLabour', name: '人工费' },
+        { type: 'marketMaterial', name: '材料费' },
+        { type: 'marketMachine', name: '施工机械使用费' },
+        { type: 'marketMachineLabour', name: '施工机械人工费' },
         // {type: 'marketEquipment', name: '设备购置费'},
-        {type: 'marketDirect', name: '直接费'},
+        { type: 'marketDirect', name: '直接费' },
 
-        {type: 'labour', name: '定额人工费'},
-        {type: 'material', name: '定额材料费'},
-        {type: 'machine', name: '定额施工机械使用费'},
+        { type: 'labour', name: '定额人工费' },
+        { type: 'material', name: '定额材料费' },
+        { type: 'machine', name: '定额施工机械使用费' },
         // {type: 'equipment', name: '定额设备购置费'},
-        {type: 'direct', name: '定额直接费'},
+        { type: 'direct', name: '定额直接费' },
 
-        {type: 'measure', name: '措施费'},
-        {type: 'manage', name: '企业管理费'},
-        {type: 'force', name: '规费'},
-        {type: 'profit', name: '利润'},
-        {type: 'tax', name: '税金'},
-        {type: 'common', name: '建筑安装工程费'},
-        {type: 'rationCommon', name: '定额建筑安装工程费'}//,
+        { type: 'measure', name: '措施费' },
+        { type: 'manage', name: '企业管理费' },
+        { type: 'force', name: '规费' },
+        { type: 'profit', name: '利润' },
+        { type: 'tax', name: '税金' },
+        { type: 'common', name: '建筑安装工程费' },
+        { type: 'rationCommon', name: '定额建筑安装工程费' }//,
         // {type: 'safeProduce', name: '安全生产费'}
     ];
 })();
+
+// 清单基数,工程量清单的基数没有变化,只修改预算的
+// 清单基数-预算
+if (typeof baseFigureMap !== 'undefined' && baseFigureMap.budget) {
+    baseFigureMap.budget = {
+        // 显示:除清单固定类别是“建筑安装工程费”的以外部分可显示。
+        '建筑安装工程费': {
+            base: 'JZAZGCF',
+            fixedFlag: fixedFlag.CONSTRUCTION_INSTALL_FEE,
+            filter: [fixedFlag.CONSTRUCTION_INSTALL_FEE],
+            pick: false,
+        },
+        // 显示:仅清单固定类别是“安全生产费”的可显示。
+        '建筑安装工程费(不含安全生产费)': {
+            base: 'JZAZGCFBHSC',
+            fixedFlag: null,
+            filter: [fixedFlag.SAFE_COST],
+            pick: true
+        },
+        // 显示:仅清单固定类别是“安全生产费”的可显示。
+        '建筑安装工程费(不含设备费)': {
+            base: 'JZAZGCFBHSB',
+            fixedFlag: fixedFlag.CONSTRUCTION_INSTALL_FEE,
+            filter: [fixedFlag.SAFE_COST],
+            pick: true
+        },
+        // 显示:除清单固定类别是“建筑安装工程费”的以外部分可显示。
+        '定额建筑安装工程费': {
+            base: 'DEJZAZGCF',
+            fixedFlag: fixedFlag.CONSTRUCTION_INSTALL_FEE,
+            filter: [fixedFlag.CONSTRUCTION_INSTALL_FEE],
+            pick: false
+        },
+        // 显示:仅清单固定类别是“施工场地建设费”的可显示。
+        '定额建筑安装工程费(不含定额设备购置费及专项管理费)': {
+            base: 'DEJZAZGCFBHSBZXGLF',
+            fixedFlag: fixedFlag.CONSTRUCTION_INSTALL_FEE,
+            filter: [fixedFlag.CONSTRUCTION_PLANT_COST],
+            pick: true,
+        },
+        // 显示:仅清单固定类别是“养护工程其他费用”的可显示。
+        '定额建筑安装工程费(不含专项管理费)': {
+            base: 'DEJZAZGCFBHZXGLF',
+            fixedFlag: fixedFlag.CONSTRUCTION_INSTALL_FEE,
+            filter: [fixedFlag.MAINTENANCE_EXPENSES],
+            pick: true,
+        },
+        // 显示:除清单固定类别是“建筑安装工程费”、“土地使用及拆迁补偿费”的以外部分可显示。
+        '土地使用及拆迁补偿费': {
+            base: 'TDSYJCQBCF',
+            fixedFlag: fixedFlag.LAND_USED_DEMOLITION,
+            filter: [fixedFlag.CONSTRUCTION_INSTALL_FEE, fixedFlag.LAND_USED_DEMOLITION],
+            pick: false,
+        },
+        // 显示:除清单固定类别是“建筑安装工程费”、“土地使用及拆迁补偿费”、“工程建设其他费用”的以外部分可显示。
+        '工程建设其他费用': {
+            base: 'GCJSQTFY',
+            fixedFlag: fixedFlag.MAINTENANCE_EXPENSES,
+            filter: [fixedFlag.CONSTRUCTION_INSTALL_FEE, fixedFlag.LAND_USED_DEMOLITION, fixedFlag.MAINTENANCE_EXPENSES],
+            pick: false,
+        },
+        // 显示:仅清单固定类别是“施工场地建设费”的可显示。
+        '施工场地建设费': {
+            base: 'SGCDJSF',
+            fixedFlag: null,
+            filter: [fixedFlag.CONSTRUCTION_PLANT_COST],
+            pick: true,
+        },
+        // 显示:仅清单固定类别是“养护工程其他费用”部分可显示。
+        '养护单位管理费': {
+            base: 'YHDWGLF',
+            fixedFlag: null,
+            filter: [fixedFlag.MAINTENANCE_EXPENSES],
+            pick: true,
+        },
+        // 显示:仅清单固定类别是“养护工程其他费用”部分可显示。
+        '养护项目信息化费': {
+            base: 'YHXMXXHF',
+            fixedFlag: null,
+            filter: [fixedFlag.MAINTENANCE_EXPENSES],
+            pick: true,
+        },
+        // 显示:仅清单固定类别是“养护工程其他费用”部分可显示。
+        '工程监理费': {
+            base: 'GCJLF',
+            fixedFlag: null,
+            filter: [fixedFlag.MAINTENANCE_EXPENSES],
+            pick: true,
+        },
+        // 显示:只有清单固定类别是“养护工程其他费用”部分可显示。
+        '设计文件审查费': {
+            base: 'SJWJSCF',
+            fixedFlag: null,
+            filter: [fixedFlag.MAINTENANCE_EXPENSES],
+            pick: true,
+        },
+        // 显示:只有清单固定类别是“养护工程其他费用”部分可显示。
+        '前期工作费': {
+            base: 'QQGZF',
+            fixedFlag: null,
+            filter: [fixedFlag.MAINTENANCE_EXPENSES],
+            pick: true,
+        },
+        // 显示:仅“价差预备费”可显示
+        '价差预备费': {
+            base: 'JCYBF',
+            fixedFlag: null,
+            filter: [fixedFlag.SPREAD_BUDGET_FEE],
+            pick: true,
+        },
+    }
+}
+
+// 清单基数-预算
+if (typeof baseFigureTemplate !== 'undefined' && baseFigureTemplate.budget) {
+    baseFigureTemplate.budget = {
+        // 建筑安装工程费 算法:取清单固定类别是“建筑安装工程费”的金额。
+        JZAZGCF(tender) {
+            const feeField = 'common';
+            const subFeeField = tender ? 'tenderTotalFee' : 'totalFee';
+            return cbTools.getBillsFee(fixedFlag.CONSTRUCTION_INSTALL_FEE, feeField, subFeeField);
+        },
+        // 建筑安装工程费(不含安全生产费) 算法:取清单固定类别是“建筑安装工程费”的金额,扣除“安全生产费”的金额。
+        JZAZGCFBHSC(tender) {
+            const fullFeeField = tender ? 'common.tenderTotalFee' : 'common.totalFee';
+            const deductFlags = [fixedFlag.SAFE_COST];
+            return cbTools.getFeeWithDeduction(fixedFlag.CONSTRUCTION_INSTALL_FEE, deductFlags, fullFeeField).toDecimal(decimalObj.bills.totalPrice);
+        },
+        // 建筑安装工程费(不含设备费) 算法:取清单固定类别是“建筑安装工程费”的金额,扣除设备的金额。
+        JZAZGCFBHSB(tender) {
+            const fullFeeField = tender ? 'common.tenderTotalFee' : 'common.totalFee';
+            const deductFlags = [fixedFlag.EQUIPMENT_ACQUISITION_FEE];
+            return cbTools.getFeeWithDeduction(fixedFlag.CONSTRUCTION_INSTALL_FEE, deductFlags, fullFeeField).toDecimal(decimalObj.bills.totalPrice);
+        },
+        // 定额建筑安装工程费 算法:取清单固定类别是“建筑安装工程费”的定额建安费。
+        DEJZAZGCF(tender) {
+            const feeField = 'rationCommon';
+            const subFeeField = tender ? 'tenderTotalFee' : 'totalFee';
+            return cbTools.getBillsFee(fixedFlag.CONSTRUCTION_INSTALL_FEE, feeField, subFeeField);
+        },
+        // 定额建筑安装工程费(不含定额设备购置费及专项管理费) 算法:取清单固定类别是“建筑安装工程费”的“定额建安费”,扣除设备的“定额设备费”,扣除“专项费用”的“定额建安费”。
+        DEJZAZGCFBHSBZXGLF(tender) {
+            const fullFeeField = tender ? 'rationCommon.tenderTotalFee' : 'rationCommon.totalFee';
+            const deductFlags = [fixedFlag.EQUIPMENT_ACQUISITION_FEE, fixedFlag.SAFE_COST];
+            //建安费扣除设备费
+            return cbTools.getFeeWithDeduction(fixedFlag.CONSTRUCTION_INSTALL_FEE, deductFlags, fullFeeField).toDecimal(decimalObj.bills.totalPrice);
+        },
+        // 定额建筑安装工程费(不含专项管理费) 算法:取清单固定类别是“建筑安装工程费”的“定额建安费”,扣除“专项费用”的“定额建安费”。
+        DEJZAZGCFBHZXGLF(tender) {
+            const fullFeeField = tender ? 'rationCommon.tenderTotalFee' : 'rationCommon.totalFee';
+            const deductFlags = [fixedFlag.SAFE_COST];
+            //建安费扣除设备费
+            return cbTools.getFeeWithDeduction(fixedFlag.CONSTRUCTION_INSTALL_FEE, deductFlags, fullFeeField).toDecimal(decimalObj.bills.totalPrice);
+        },
+        // 土地使用及拆迁补偿费 算法:取清单固定类别是“土地使用及拆迁补偿费”的金额。
+        TDSYJCQBCF(tender) {
+            const feeField = 'common';
+            const subFeeField = tender ? 'tenderTotalFee' : 'totalFee';
+            return cbTools.getBillsFee(fixedFlag.LAND_USED_DEMOLITION, feeField, subFeeField);
+        },
+        // 工程建设其他费用 算法:取清单固定类别是“养护工程其他费用”的金额。
+        GCJSQTFY(tender) {
+            const feeField = 'common';
+            const subFeeField = tender ? 'tenderTotalFee' : 'totalFee';
+            return cbTools.getBillsFee(fixedFlag.MAINTENANCE_EXPENSES, feeField, subFeeField);
+        },
+        // 施工场地建设费 算法:以{定额建筑安装工程费(不含定额设备购置费及专项管理费) }为基数,采用累进办法计算。
+        SGCDJSF(tender) {
+            const baseFee = this['DEJZAZGCFBHSBZXGLF'](tender);
+            return cbTools.getProgressiveFee(baseFee, '施工场地建设费');
+        },
+        // 养护单位管理费 算法:以{定额建筑安装工程费(不含专项管理费) }为基数,采用累进办法计算。
+        YHDWGLF(tender) {
+            const baseFee = this['DEJZAZGCFBHZXGLF'](tender);
+            return cbTools.getProgressiveFee(baseFee, '养护单位管理费');
+        },
+        // 养护项目信息化费 算法:以{定额建筑安装工程费}为基数,采用累进办法计算。(不足20000元时按20000元计算)
+        YHXMXXHF(tender) {
+            const baseFee = this['DEJZAZGCF'](tender);
+            const fee = cbTools.getProgressiveFee(baseFee, '信息化费');
+            return fee > 0 && fee < 20000 ? 20000 : fee;
+        },
+        // 工程监理费 算法:以{定额建筑安装工程费(不含专项管理费) }为基数,采用累进办法计算。(不足20000元时按20000元计算)
+        GCJLF(tender) {
+            const baseFee = this['DEJZAZGCFBHZXGLF'](tender);
+            const fee = cbTools.getProgressiveFee(baseFee, '工程监理费');
+            return fee > 0 && fee < 20000 ? 20000 : fee;
+        },
+        // 设计文件审查费 算法:以{定额建筑安装工程费(不含专项管理费) }为基数,采用累进办法计算。
+        SJWJSCF(tender) {
+            const baseFee = this['DEJZAZGCFBHZXGLF'](tender);
+            return cbTools.getProgressiveFee(baseFee, '设计文件审查费');
+        },
+        // 前期工作费 算法:以{定额建筑安装工程费(不含专项管理费) }为基数,采用累进办法计算。(不足30000元时按30000元计算)
+        QQGZF(tender) {
+            const baseFee = this['DEJZAZGCFBHZXGLF'](tender);
+            const fee = cbTools.getProgressiveFee(baseFee, '前期工作费');
+            return fee > 0 && fee < 30000 ? 30000 : fee;
+        },
+        /*  价差预备费 算法:以建筑安装工程费为基数,按设计文件编制年始至养护项目工程竣工年终的年数和年工程造价增涨率计算。
+            价差预备费 P * [(1+i)^(n-1) -1]
+            P——建筑安装工程费总额(元);
+            i——年工程造价增涨率(%);
+            n——设计文件编制年至养护项目开工年+养护项目建设期限(年)。
+        */
+        JCYBF(tender) {
+            //建筑安装工程费作为基数
+            const installFee = this['JZAZGCF'](tender);
+            //年造价增涨
+            const costGrowthRate = calcBase.project.property.costGrowthRate 
+                ? calcBase.project.property.costGrowthRate 
+                : 0;
+            //增涨计费年限
+            const growthPeriod = projectObj.project.property.growthPeriod 
+                ? calcBase.project.property.growthPeriod 
+                : 0;
+            //= P * [(1+i)^(n-1) -1]
+            return (installFee * (Math.pow(1 + costGrowthRate, growthPeriod - 1) - 1)).toDecimal(decimalObj.bills.totalPrice);
+        }
+
+    };
+}

+ 1 - 1
web/users/html/user-info.html

@@ -76,7 +76,7 @@
                             </select>
                         </div>
                         <div class="form-group">
-                            <label class="form-control-label">联系人</label>
+                            <label class="form-control-label">账号姓名</label>
                             <input class="form-control" value="<%= userData.real_name %>" placeholder="输入您的姓名" id="name" name="real_name" autocomplete="off">
                         </div>
                         <div class="form-group">