소스 검색

Merge branch '1.0.0_online' of http://smartcost.f3322.net:3000/SmartCost/ConstructionCost into 1.0.0_online

zhongzewei 6 년 전
부모
커밋
ab343c6fd0

+ 36 - 0
logs/online_logs.js

@@ -0,0 +1,36 @@
+/**
+ * Created by zhang on 2019/4/12.
+ */
+module.exports = {
+    saveOnlineTime:saveOnlineTime
+};
+
+let mongoose = require("mongoose");
+import moment from "moment";
+let logs_model = mongoose.model("online_logs");
+
+async function saveOnlineTime(req) {
+    let interval_time = 10 * 60 *1000;
+    let start = req.session.online_start_time;
+    let end = + new Date();
+    let online_times =  end - start;
+    //1秒内只记一次就好
+    if(online_times < 500) return;//如果间隔太短,则忽略
+    if(online_times > interval_time ){//如果间隔超过有效时长,则不累加这次时长,从头开始算
+        req.session.online_start_time = end;
+        return
+    }
+    if(!req.session.sessionUser||!req.session.sessionCompilation) return;
+    let dataString = moment(end).format('YYYY-MM-DD');
+    let condition = {userID:req.session.sessionUser.id,compilationID:req.session.sessionCompilation._id,dateString:dataString};
+    let record = await logs_model.findOne(condition);
+    if(record){ //如果找到,则累加
+        await logs_model.update(condition,{$inc:{'online_times' : online_times }});
+    }else {//如果没找到,则新增一条记录
+        condition["online_times"] = online_times;
+        let today = moment(dataString).toDate();
+        condition["dateTime"] = +today;
+        await logs_model.create(condition);
+    }
+    req.session.online_start_time = end;
+}

+ 17 - 0
modules/all_models/online_logs.js

@@ -0,0 +1,17 @@
+/**
+ * Created by zhang on 2019/4/12.
+ */
+//用户在线时长统计
+
+let mongoose = require("mongoose");
+let Schema = mongoose.Schema;
+
+// 表结构
+let schema = {
+    userID: String,
+    compilationID: String,
+    dateString: String,
+    dateTime:Number,//dateString转换回毫秒数对应的数值,方便查询
+    online_times: Number
+};
+mongoose.model("online_logs", new Schema(schema, {versionKey: false}),"online_logs");

+ 3 - 1
modules/all_models/user.js

@@ -83,6 +83,8 @@ let schema = {
     used_list: {
         type: [userdList],
         default: []
-    }
+    },
+    // 是否邮箱已通过验证
+    isUserActive: Number
 };
 mongoose.model(collectionName, new Schema(schema, {versionKey: false}));

+ 8 - 6
modules/complementary_ration_lib/models/compleRationModel.js

@@ -12,6 +12,7 @@ import async from 'async';
 let stdRationModel = require ('../../ration_repository/models/ration_item').Model;
 let counter = require('../../../public/counter/counter');
 const scMathUtil = require('../../../public/scMathUtil').getUtil();
+let gljUtil = require('../../../public/gljUtil');
 
 class CompleRatoinDao {
     async updateRation(userID, compilationId, updateData, callback){
@@ -157,8 +158,8 @@ class CompleRatoinDao {
             if(comGljIds.length > 0) {
                 comGljs = await complementaryGljModel.find({userId: userId, ID: {$in: comGljIds}});
             }
-            let gljDatas = stdGljs.concat(comGljs);
-            gljDatas.sort(function (a, b) {
+            let gljDatas = gljUtil.sortRationGLJ(stdGljs.concat(comGljs),true);
+          /*  gljDatas.sort(function (a, b) {
                 let aV = a.gljType + a.code,
                     bV = b.gljType + b.code;
                 if(aV > bV) {
@@ -167,7 +168,7 @@ class CompleRatoinDao {
                     return -1;
                 }
                 return 0;
-            });
+            });*/
             if(ration.jobContent && ration.jobContent.toString().trim() !== ''){
                 hintsArr.push(`<label class="nomargin font_blue">工作内容:`);
                 hintsArr = hintsArr.concat(ration.jobContent.split('\n'));
@@ -245,8 +246,8 @@ class CompleRatoinDao {
             if(stdGljIds.length > 0) {
                 stdGljs = await stdGljModel.find({ID: {$in: stdGljIds}});
             }
-            let gljDatas = stdGljs;
-            gljDatas.sort(function (a, b) {
+            let gljDatas =  gljUtil.sortRationGLJ(stdGljs,true);
+        /*    gljDatas.sort(function (a, b) {
                 let aV = a.gljType + a.code,
                     bV = b.gljType + b.code;
                 if(aV > bV) {
@@ -255,7 +256,8 @@ class CompleRatoinDao {
                     return -1;
                 }
                 return 0;
-            });
+            });*/
+            gljDatas = gljUtil.sortRationGLJ(gljDatas,true);
             if(ration.jobContent && ration.jobContent.toString().trim() !== ''){
                 hintsArr.push(`<label class="nomargin font_blue">工作内容:`);
                 hintsArr = hintsArr.concat(ration.jobContent.split('\n'));

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

@@ -139,6 +139,7 @@ class LoginController {
 
             // 正确登录后 存入session
             let userData = responseData[0];
+            console.log(userData.isUserActive);
 
             if (userData.mobile === '') {
                 return response.json({error: 2,ssoId: userData.id});
@@ -186,6 +187,7 @@ class LoginController {
                 username: userData.username,
                 email: userData.useremail,
                 mobile: userData.mobile,
+                isUserActive: userData.isUserActive,
             };
 
             request.session.sessionUser = sessionUser;
@@ -223,6 +225,7 @@ class LoginController {
             console.log(error);
             return response.json({error: 1, msg: error});
         }
+        request.session.online_start_time = +new Date();
         console.log(`${request.session.sessionUser.real_name}--id:${request.session.sessionUser.id}--登录了系统`);
         response.json({
             error: 0,

+ 2 - 1
modules/users/controllers/user_controller.js

@@ -101,7 +101,8 @@ class UserController extends BaseController {
             // 获取登录信息
             let logModel = new LogModel();
             let logCount = await logModel.count();
-            let pageSize = 3;
+            logCount = logCount > 30 ? 30 : logCount;
+            let pageSize = 10;
             logList = await logModel.getLog(sessionUser.id, LogType.LOGIN_LOG, page, pageSize);
 
             // 分页数据

+ 3 - 2
modules/users/models/log_model.js

@@ -63,7 +63,8 @@ class LogModel extends BaseModel {
         ip = ip.split(':');
         ip = ip[3] === undefined ? '' : ip[3];
 
-        let ipInfo = '127.0.0.1';//await this.getIpInfoFromApi(ip);
+        // let ipInfo = '127.0.0.1';//await this.getIpInfoFromApi(ip);
+        let ipInfo = await this.getIpInfoFromApi(ip);
 
         let userAgentObject = new UAParser(request.headers['user-agent']);
         let osInfo = userAgentObject.getOS();
@@ -153,4 +154,4 @@ class LogModel extends BaseModel {
     }
 }
 
-export default LogModel;
+export default LogModel;

+ 3 - 1
modules/users/models/user_model.js

@@ -137,7 +137,8 @@ class UserModel extends BaseModel {
                 email : userData.email,
                 mobile : userData.mobile,
                 ssoId : userData.ssoId,
-                latest_login:userData.latest_login
+                latest_login:userData.latest_login,
+                isUserActive: userData.isUserActive,
             };
             let updateResult = await this.updateUser(condition,UpdateData);
             if (updateResult.ok === 1) {
@@ -240,6 +241,7 @@ class UserModel extends BaseModel {
             mobile: userData.mobile,
             create_time: new Date().getTime(),
             latest_login: new Date().getTime(),
+            isUserActive: userData.isUserActive,
         };
         return this.db.create(insertData);
     }

+ 6 - 1
public/gljUtil.js

@@ -16,7 +16,8 @@ module.exports = {
     getMarketPrice:getMarketPrice,
     getBasePrice:getBasePrice,
     getAdjustPrice:getAdjustPrice,
-    getGljTypeSeq:getGljTypeSeq
+    getGljTypeSeq:getGljTypeSeq,
+    sortRationGLJ:sortRationGLJ
 };
 
 function calcProjectGLJQuantity(projectGLJDatas,rationGLJDatas,rationDatas,billsDatas,q_decimal) {
@@ -45,4 +46,8 @@ function calcPriceDiff(glj,calcOptions) {
 
 function getGljTypeSeq() {
     return gljNodeUtil.getGljTypeSeq();
+}
+
+function sortRationGLJ(list,std) {
+    return gljNodeUtil.sortRationGLJ(list,std);
 }

+ 4 - 3
public/web/gljUtil.js

@@ -302,10 +302,11 @@ let gljUtil = {
                 gljType.MACHINE_COMPOSITION,gljType.MACHINE_LABOUR,gljType.FUEL_POWER_FEE,gljType.DEPRECIATION_FEE,gljType.INSPECTION_FEE,gljType.MAINTENANCE,
                 gljType.DISMANTLING_FREIGHT_FEE,gljType.VERIFICATION_FEE,gljType.OTHER_FEE,gljType.EQUIPMENT,gljType.MANAGEMENT_FEE,gljType.PROFIT,gljType.GENERAL_RISK_FEE]
     },
-    sortRationGLJ:function (list) {
+    sortRationGLJ:function (list,std) {
         list = _.sortByAll(list, [function (item) {
-            return _.indexOf(gljTypeSeq,item.type)
-        }, "code"])
+            let typeField = std == true?"gljType":"type";
+            return _.indexOf(gljUtil.getGljTypeSeq(),item[typeField])
+        }, "code"]);
         return list;
     },
     getTotalQuantity:function(glj,ration,rd,gd){

+ 4 - 1
server.js

@@ -23,6 +23,8 @@ fileUtils.getGlobbedFiles('./modules/all_models/*.js').forEach(function(modelPat
 //config.setupCache();
 let cfgCacheUtil = require("./config/cacheCfg");
 cfgCacheUtil.setupDftCache();
+let online_logs = require("./logs/online_logs");
+
 
 let app = express();
 let _rootDir = __dirname;
@@ -54,7 +56,7 @@ app.use(session({
 }));
 
 // 登录状态全局判断
-app.use(function (req, res, next) {
+app.use(async function (req, res, next) {
     let url = req.originalUrl;
     // if (/^\/login/.test(url) || /\.map|\.ico$/.test(url) || /^\/sms/.test(url) || /^\/cld/.test(url) || /^\/captcha/.test(url)  || /^\/accountIsPro/.test(url)) {
     if (/^\/login/.test(url) || /\.map|\.ico$/.test(url) || /^\/sms/.test(url) || /^\/cld/.test(url) || /^\/captcha/.test(url)) {
@@ -87,6 +89,7 @@ app.use(function (req, res, next) {
             return res.redirect('/login');
         }
         next();
+        await online_logs.saveOnlineTime(req);//记录登录时长
     }
 });
 

+ 47 - 93
web/building_saas/main/js/models/calc_program.js

@@ -594,49 +594,50 @@ let calcTools = {
         if (treeNode.data.type != rationType.volumePrice && treeNode.data.type != rationType.gljRation) return;
         let result = 0, me = this;
 
-        let rcj = (treeNode.data.subType === gljType.LABOUR && calcTools.inBase(baseName, 'RGF')) ||
-            (baseMaterialTypes.includes(treeNode.data.subType) && calcTools.inBase(baseName, 'CLF')) ||
-            (treeNode.data.subType === gljType.GENERAL_MACHINE && calcTools.inBase(baseName, 'JXF'));
-
-        if (typeof isJX2017 != 'undefined') {
-            rcj = rcj || (treeNode.data.subType === gljType.LABOUR && calcTools.inBase(baseName, 'SC_RGF')) ||
-                (baseMaterialTypes.includes(treeNode.data.subType) && calcTools.inBase(baseName, 'SC_CLF')) ||
-                (treeNode.data.subType === gljType.GENERAL_MACHINE && calcTools.inBase(baseName, 'SC_JXF'))
-        };
-
-        if (rcj ||
-            (treeNode.data.subType === gljType.MAIN_MATERIAL && calcTools.inBase(baseName, 'ZCF')) ||
-            (treeNode.data.subType === gljType.EQUIPMENT && calcTools.inBase(baseName, 'SBF'))) {
-            if (treeNode.data.type == rationType.volumePrice)
-                result = treeNode.data.marketUnitFee ? parseFloat(treeNode.data.marketUnitFee).toDecimal(decimalObj.ration.unitPrice) : 0
-            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);
+        function isRCJZC(treeNode, baseName) {         // 基数名称中是否包含人材机主设,且树结点类型要匹配一致
+            let rst = (treeNode.data.subType === gljType.LABOUR && baseName.includes('人工')) ||    // 人工费、市场人工费
+                (baseMaterialTypes.includes(treeNode.data.subType) && baseName.includes('材料')) ||
+                (treeNode.data.subType === gljType.GENERAL_MACHINE && (baseName.includes('机械') || baseName.includes('机具'))) ||
+                (treeNode.data.subType === gljType.MAIN_MATERIAL && baseName.includes('主材')) ||
+                (treeNode.data.subType === gljType.EQUIPMENT && baseName.includes('设备'));
+            return rst;
         }
-        else if (treeNode.data.subType === gljType.GENERAL_MACHINE && calcTools.inBase(baseName, 'JSRGF')) {
-            let glj = {
-                'code': treeNode.data.code,
-                'name': treeNode.data.name,
-                'specs': treeNode.data.specs,
-                'unit': treeNode.data.unit,
-                'quantity': 1,
-                'type': treeNode.data.subType      // 注意:这里要取subType
-            };
-            result = me.machineDetailFee(treeNode, [glj], [], gljType.MACHINE_LABOUR, isTender);
+
+        if (baseName.includes('甲供') || baseName.includes('甲定') || baseName.includes('分包')) {
+            result = 0;
+        }
+        else if (baseName.includes('价差')) {
+            if (treeNode.data.type == rationType.gljRation) {
+                if (isRCJZC(treeNode, baseName)) {
+                    let aprice = me.uiGLJPrice(treeNode.data.basePrice);   // 量价虚拟的工料机不可能有发文,这里直接取定额价。
+                    let mprice = me.uiGLJPrice(treeNode.data.marketUnitFee);
+                    result = (mprice - aprice).toDecimal(decimalObj.ration.unitPrice);
+                }
+            }
         }
-        else if (
-            (treeNode.data.type == rationType.gljRation) &&
-            ((treeNode.data.subType === gljType.LABOUR && calcTools.inBase(baseName, 'JC_RGF')) ||
-                (baseMaterialTypes.includes(treeNode.data.subType) && calcTools.inBase(baseName, 'JC_CLF')) ||
-                (treeNode.data.subType === gljType.GENERAL_MACHINE && calcTools.inBase(baseName, 'JC_JXF')) ||
-                (treeNode.data.subType === gljType.MAIN_MATERIAL && calcTools.inBase(baseName, 'JC_ZCF')) ||
-                (treeNode.data.subType === gljType.EQUIPMENT && calcTools.inBase(baseName, 'JC_SBF')))
-        ) {
-            let aprice = me.uiGLJPrice(treeNode.data.basePrice);   // 量价虚拟的工料机不可能有发文,这里直接取定额价。
-            let mprice = me.uiGLJPrice(treeNode.data.marketUnitFee);
-            result = (mprice - aprice).toDecimal(decimalObj.ration.unitPrice);
+        else if (baseName.includes('机上人工')) {
+            if (treeNode.data.subType === gljType.GENERAL_MACHINE) {
+                let glj = {
+                    'code': treeNode.data.code,
+                    'name': treeNode.data.name,
+                    'specs': treeNode.data.specs,
+                    'unit': treeNode.data.unit,
+                    'quantity': 1,
+                    'type': treeNode.data.subType      // 注意:这里要取subType
+                };
+                result = me.machineDetailFee(treeNode, [glj], [], gljType.MACHINE_LABOUR, isTender);
+            }
         }
+        else {
+            if (isRCJZC(treeNode, baseName)) {
+                if (treeNode.data.type == rationType.volumePrice)
+                    result = treeNode.data.marketUnitFee ? parseFloat(treeNode.data.marketUnitFee).toDecimal(decimalObj.ration.unitPrice) : 0
+                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);
+            }
+        };
         return result;
     },
     partASupplyFee: function (treeNode, baseName, isTender, isRationPirce = true) {
@@ -650,22 +651,20 @@ let calcTools = {
             supplyT = [supplyType.JDYG];
 
         let gljT = [], compT = [];
-        if (calcTools.inBase(baseName, 'JG_RGF') || calcTools.inBase(baseName, 'JD_RGF')){
-            gljT = [gljType.LABOUR];
-        }
-        else if (calcTools.inBase(baseName, 'JG_CLF') || calcTools.inBase(baseName, 'JD_CLF')){             // 甲供、甲定材料
+        if (baseName.includes('人工')) gljT = [gljType.LABOUR];       // 含人工的:如甲供人工、甲定人工
+        else if (baseName.includes('材料')){
             gljT = baseMaterialTypes;
             compT = compositionTypes;
         }
-        else if (calcTools.inBase(baseName, 'JG_JXF') || calcTools.inBase(baseName, 'JD_JXF')) {            // 甲供、甲定机械
+        else if (baseName.includes('机械') || baseName.includes('机具')) {
             gljT = baseMachineTypes;
             compT = [gljType.GENERAL_MACHINE, gljType.INSTRUMENT, gljType.OTHER_MACHINE_USED];              // 取并集,兼容重庆2018新定额
         }
-        else if (calcTools.inBase(baseName, 'JG_ZCF') || calcTools.inBase(baseName, 'JD_ZCF')) {            // 甲供、甲定主材
+        else if (baseName.includes('主材')) {
             gljT = [gljType.MAIN_MATERIAL];
             compT = [gljType.MAIN_MATERIAL];
         }
-        else if (calcTools.inBase(baseName, 'JG_SBF') || calcTools.inBase(baseName, 'JD_SBF')) {           // 甲供、甲定设备
+        else if (baseName.includes('设备')) {
             gljT = [gljType.EQUIPMENT];
         };
         // alert(JSON.stringify(projectGLJ.testGLJs()));
@@ -951,52 +950,7 @@ let calcTools = {
                   return o.value;
               }
         };
-    },
-    inBase(baseName, kindName){
-        return rationCalcBasesNameKinds[kindName].includes(baseName);
-    }
-};
-
-let rationCalcBasesNameKinds = {
-    RGF:        ['定额基价人工费', '定额人工费'],
-    CLF:        ['定额基价材料费', '定额材料费'],
-    QTCLF:      ['定额其他材料费'],
-    JXF:        ['定额基价机械费', '定额机械费', '定额施工机具使用费'],
-    JSRGF:      ['定额基价机上人工费'],
-    ZCF:        ['主材费', '市场价主材费'],
-    SBF:        ['设备费'],
-    RGGR:       ['人工工日'],
-    ZGCLF:      ['暂估材料费'],
-
-    // 市场价人工费、市场价材料费、市场价机械费。江西用,跟重庆区分开,概念上不太统一,这里要注意区分。
-    SC_RGF:     ['人工费'],
-    SC_CLF:     ['材料费'],
-    SC_JXF:     ['机械费'],
-
-    JC_RGF:     ['人工费价差'],
-    JC_CLF:     ['材料费价差'],
-    JC_JXF:     ['机械费价差'],
-    JC_ZCF:     ['主材费价差'],
-    JC_SBF:     ['设备费价差'],
-
-    JG_RGF:     ['甲供定额基价人工费', '甲供定额人工费', '甲供人工费'],
-    JG_CLF:     ['甲供定额基价材料费', '甲供定额材料费', '甲供材料费'],
-    JG_JXF:     ['甲供定额基价机械费', '甲供定额机械费', '甲供机械费', '甲供定额施工机具费'],
-    JG_ZCF:     ['甲供主材费'],
-    JG_SBF:     ['甲供设备费'],
-
-    JD_RGF:     ['甲定定额基价人工费', '甲定定额人工费', '甲定人工费'],
-    JD_CLF:     ['甲定定额基价材料费', '甲定定额材料费', '甲定材料费'],
-    JD_JXF:     ['甲定定额基价机械费', '甲定定额机械费', '甲定机械费', '甲定定额施工机具费'],
-    JD_ZCF:     ['甲定主材费'],
-    JD_SBF:     ['甲定设备费'],
-
-    FB_RGF:     ['分包定额基价人工费', '分包人工费'],
-    FB_CLF:     ['分包定额基价材料费', '分包材料费'],
-    FB_JXF:     ['分包定额基价机械费', '分包机械费'],
-    FB_ZCF:     ['分包主材费'],
-    FB_SBF:     ['分包设备费'],
-    FB_RGGR:    ['分包人工工日']
+     }
 };
 
 let rationCalcBases = {

+ 8 - 5
web/building_saas/main/js/models/ration.js

@@ -421,7 +421,7 @@ var Ration = {
                        node.data.feesIndex = {};
                        //删除定额节点下的主材和设备节点
                        project.ration_glj.removeNodeByRation(recode.ration,projectObj.mainController);
-                       project.Ration.deleteSubListOfRation(recode.ration);//删除旧定额下的相关记录
+                       project.Ration.deleteSubListOfRation(recode.ration,cleanzmhs);//删除旧定额下的相关记录
                        //添加新的记录
                        project.Ration.addSubListOfRation(recode);
 
@@ -707,12 +707,15 @@ var Ration = {
             }
             else return null;
         };
-        ration.prototype.deleteSubListOfRation = function(ration){
+        ration.prototype.deleteSubListOfRation = function(ration,cleanzmhs=false){
             projectObj.project.ration_glj.deleteByRation(ration);
             projectObj.project.ration_coe.deleteByRation(ration);
-            projectObj.project.quantity_detail.deleteByRation(ration);
-            projectObj.project.ration_installation.deleteByRation(ration);
-            projectObj.project.ration_template.deleteByRation(ration);
+            if(cleanzmhs == false){
+                projectObj.project.ration_installation.deleteByRation(ration);
+                projectObj.project.quantity_detail.deleteByRation(ration);
+                projectObj.project.ration_template.deleteByRation(ration);
+            }
+
         };
         ration.prototype.addSubListOfRation = function (data) {
              project.ration_glj.addDatasToList(data.ration_gljs);

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

@@ -200,7 +200,8 @@ var feeRateObject={
         }
     },
     initFeeRateEditDiv:function(optionValue){//“0” 手工输入; “1” 选择费率
-        let radioValue = optionValue,feeRateValue;
+        let radioValue = 1,feeRateValue;
+        $("#customFeeRate").val("");//先清空输入
         if(!gljUtil.isDef(optionValue)){
             let fID = 0;
             if ($("#calc_program_manage").is(":visible")){
@@ -210,10 +211,13 @@ var feeRateObject={
                 fID = projectObj.project.mainTree.selected.data.feeRateID;
                 feeRateValue = projectObj.project.mainTree.selected.data.feeRate;
             }
-            radioValue = fID?"1":"0";
-            $("#customFeeRate").val(feeRateValue);
+            if(fID){
+                feeRateValue = projectObj.project.FeeRate.getFeeRateByID(fID).rate;
+            }
+            if(!fID&&gljUtil.isDef(feeRateValue)) radioValue = 0; //2019-04-18 只有在没有费率ID,但是有费率值的情况下才显示自定义费率页,其它所有的情况都显示费率选择页面
+            if(!isNaN(feeRateValue))$("#customFeeRate").val(feeRateValue);
         }
-        $("input[name='editFeeRateOptions'][value='"+radioValue+"']").attr("checked",true);
+        $("input[name='editFeeRateOptions'][value='"+radioValue+"']").prop("checked",true);
         if(radioValue == "0"){
             $("#selfDiv").show();
             $("#fee_rate_sheet").hide();

+ 71 - 5
web/over_write/js/neimenggu_2017.js

@@ -7,13 +7,11 @@
     cpFeeTypes = [
         {type: 'marketLabour', name: '市场价人工费'},
         {type: 'marketMaterial', name: '市场价材料费'},
-        {type: 'marketMachine', name: '市场价机械费'},
-        {type: 'equipment', name: '设备费'},
+        {type: 'marketMachine', name: '施工机具使用费'},
         {type: 'mainMaterial', name: '主材费'},
+        {type: 'equipment', name: '设备费'},
         {type: 'manage', name: '管理费'},
         {type: 'profit', name: '利润'},
-        {type: 'risk', name: '风险费'},
-        {type: 'safeMeasures', name: '安全文明施工费'},
         {type: 'safeAndEnvironment', name: '安全文明施工与环境保护费'},
         {type: 'tempFacility', name: '临时设施费'},
         {type: 'rain', name: '雨季施工增加费'},
@@ -22,10 +20,78 @@
         {type: 'secondHandling', name: '二次搬运费'},
         {type: 'specialArea', name: '特殊地区施工增加费'},
         {type: 'night', name: '夜间施工增加费'},
+        // {type: 'safeMeasures', name: '安全文明施工费'},
         {type: 'basement', name: '白天在地下室施工增加费'},
         {type: 'winter', name: '冬季施工增加费'},
+        {type: 'risk', name: '风险费'},
         {type: 'force', name: '规费'},
         {type: 'tax', name: '税金'},
         {type: 'common', name: '工程造价'}
     ];
-})();
+})();
+
+function overwriteRationCalcBases (taxType){
+    if (typeof rationCalcBases == 'undefined') return;
+    for (let key in rationCalcBases) delete rationCalcBases[key];
+
+    rationCalcBases['人工费'] = function (node, isTender) {
+        return calcTools.rationBaseFee(node, [gljType.LABOUR], priceTypes.ptMarketPrice, isTender);
+    };
+    rationCalcBases['材料费'] = function (node, isTender) {
+        return calcTools.rationBaseFee(node, baseMaterialTypes, priceTypes.ptMarketPrice, isTender);
+    };
+    rationCalcBases['施工机具使用费'] = function (node, isTender) {
+        return calcTools.rationBaseFee(node, baseMachineTypes, priceTypes.ptMarketPrice, isTender);
+    };
+    rationCalcBases['主材费'] = function (node, isTender) {
+        return calcTools.rationBaseFee(node, [gljType.MAIN_MATERIAL], 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);
+    };
+    rationCalcBases['定额材料费'] = function (node, isTender) {
+        return calcTools.rationBaseFee(node, baseMaterialTypes, priceTypes.ptBasePrice, isTender);
+    };
+    rationCalcBases['定额施工机具使用费'] = function (node, isTender) {
+        return calcTools.rationBaseFee(node, baseMachineTypes, priceTypes.ptBasePrice, isTender);
+    };
+    rationCalcBases['人工工日'] = function (node, isTender) {
+        return calcTools.labourDays(node, isTender);
+    };
+    rationCalcBases['甲供人工费'] = function (node, isTender) {
+        return calcTools.partASupplyFee(node, '甲供人工费', isTender, false);
+    };
+    rationCalcBases['甲供材料费'] = function (node, isTender) {
+        return calcTools.partASupplyFee(node, '甲供材料费', isTender, false);
+    };
+    rationCalcBases['甲供施工机具使用费'] = function (node, isTender) {
+        return calcTools.partASupplyFee(node, '甲供施工机具使用费', isTender, false);
+    };
+    rationCalcBases['甲供主材费'] = function (node, isTender) {
+        return calcTools.partASupplyFee(node, '甲供主材费', isTender, false);
+    };
+    rationCalcBases['甲供设备费'] = function (node, isTender) {
+        return calcTools.partASupplyFee(node, '甲供设备费', isTender, false);
+    };
+    rationCalcBases['甲定人工费'] = function (node, isTender) {
+        return calcTools.partASupplyFee(node, '甲定人工费', isTender, false);
+    };
+    rationCalcBases['甲定材料费'] = function (node, isTender) {
+        return calcTools.partASupplyFee(node, '甲定材料费', isTender, false);
+    };
+    rationCalcBases['甲定施工机具使用费'] = function (node, isTender) {
+        return calcTools.partASupplyFee(node, '甲定施工机具使用费', isTender, false);
+    };
+    rationCalcBases['甲定主材费'] = function (node, isTender) {
+        return calcTools.partASupplyFee(node, '甲定主材费', isTender, false);
+    };
+    rationCalcBases['甲定设备费'] = function (node, isTender) {
+        return calcTools.partASupplyFee(node, '甲定设备费', isTender, false);
+    };
+    rationCalcBases['暂估材料费'] = function (node, isTender) {
+        return calcTools.estimateFee(node, true, isTender);
+    };
+};

+ 37 - 26
web/users/html/user-safe.html

@@ -11,9 +11,6 @@
     <link rel="stylesheet" href="/lib/font-awesome/font-awesome.min.css">
     <link rel="shortcut icon" href="/web/building_saas/css/favicon.ico">
     <link rel="icon" type="image/gif" href="/web/building_saas/css/animated_favicon1.gif">
-    <!-- JS. -->
-    <!--<script type="text/javascript" src="/lib/bootstrap/bootstrap-paginator.js"></script>-->
-    <!--<script src="/web/building_saas/js/global.js"></script>-->
 </head>
 
 <body>
@@ -41,48 +38,60 @@
                     </ul>
                 </div>
             </div>
-            <div class="col-lg-10">
+            <div class="col-lg-10 side-content">
                 <div class="col-lg-4">
                     <legend class="my-3">账号安全</legend>
                     <from>
                         <div class="form-group">
                             <label class="form-control-label">登录密码</label>
                             <div class="form-control-static">
-                                <button class="btn btn-secondary btn-sm">修改密码</button>
+                                <a class="btn btn-outline-primary btn-sm" href="https://sso.smartcost.com.cn/chpasswd" target="_blank">修改密码</a>
                             </div>
                         </div>
                         <div class="form-group">
                             <label class="form-control-label">邮箱地址</label>
-                            <p class="form-control-static mb-0"><%= userData.email %><span
-                                    class="badge badge-default">未验证</span></p>
-                            <button class="btn btn-secondary btn-sm">验证邮箱</button>
-                            <button class="btn btn-secondary btn-sm">更换邮箱</button>
-                            <p class="form-control-static mb-0"><%= userData.email %><span
-                                    class="badge badge-success">已验证</span></p>
-                            <button class="btn btn-secondary btn-sm">更换邮箱</button>
+                            <% if (userData.email !== '') { %>
+                            <p class="form-control-static mb-0"><%= userData.email %><% if (userData.isUserActive === 0) { %><span
+                                    class="badge badge-default">未验证</span><% } else { %><span
+                                    class="badge badge-success">已验证</span><% } %></p>
+                            <% if (userData.isUserActive === 0) { %><a class="btn btn-outline-primary btn-sm" target="_blank" href="https://sso.smartcost.com.cn/profile">验证邮箱</a>
+                            <a class="btn btn-outline-primary btn-sm" target="_blank" href="https://sso.smartcost.com.cn/nactchm">更换邮箱</a>
+                            <% } else { %>
+                            <a class="btn btn-outline-primary btn-sm" href="https://sso.smartcost.com.cn/changeMail" target="_blank">更换邮箱</a>
+                            <% } %>
+                            <% } else { %>
+                            <a class="btn btn-outline-primary btn-sm" href="https://sso.smartcost.com.cn/addMail" target="_blank">添加邮箱</a>
+                            <% } %>
                         </div>
                         <div class="form-group">
                             <label class="form-control-label">手机号码</label>
-                            <p class="form-control-static mb-0"><%= userData.mobile %></p>
-                            <button class="btn btn-secondary btn-sm">更换手机</button>
-                            <div class="form-control-static">
-                                <button class="btn btn-secondary btn-sm">添加手机</button>
-                            </div>
+                            <p class="form-control-static mb-0"><%= userData.mobile %> <span class="badge badge-success">已验证</span></p>
+                            <a class="btn btn-outline-primary btn-sm" href="https://sso.smartcost.com.cn/changeMobile" target="_blank">更换手机</a>
                         </div>
                         <div class="form-group">
                             <label class="form-control-label">异常登录提醒</label>
                             <div class="form-control-static">
-                                <label class="custom-control custom-checkbox" data-toggle="modal"
-                                       data-target="#phoneTips">
-                                    <input type="checkbox" class="custom-control-input">
-                                    <span class="custom-control-indicator"></span>
-                                    <span class="custom-control-description">开启</span>
-                                </label>
+                                <div class="custom-control custom-checkbox" >
+                                    <input type="checkbox" class="custom-control-input" id="customCheck1">
+                                    <label class="custom-control-label" for="customCheck1" >开启</label>
+                                </div>
                                 <p class="text-muted">
                                     账号出现异常登录时将给你的手机号码发送通知。
                                 </p>
                             </div>
                         </div>
+                        <div class="form-group">
+                            <label class="form-control-label">关闭账号登录</label>
+                            <div class="form-control-static">
+                                <div class="custom-control custom-checkbox" >
+                                    <input type="checkbox" class="custom-control-input" id="customCheck2">
+                                    <label class="custom-control-label" for="customCheck2" >关闭</label>
+                                </div>
+                                <p class="text-muted">
+                                    关闭账号登录后,只能通过短信验证码方式登录。
+                                </p>
+                            </div>
+                        </div>
                     </from>
                 </div>
                 <div class="mt-5">
@@ -128,8 +137,10 @@
     </div>
 </div>
 </body>
-<!--<script type="text/javascript">-->
-    <!--autoFlashHeight();-->
-<!--</script>-->
+<script src="/web/building_saas/js/global.js"></script>
+<script src="/web/users/js/user.js"></script>
+<script type="text/javascript">
+    autoFlashHeight();
+</script>
 
 </html>