Selaa lähdekoodia

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

TonyKang 7 vuotta sitten
vanhempi
commit
a93babc586

+ 1 - 0
modules/all_models/bills.js

@@ -57,6 +57,7 @@ let billsSchema = new Schema({
     flags: [subSchema.flagsSchema],
     installationKey:String,//用来记录安装增加费的关联字段
     deleteInfo: deleteSchema,
+    remark:String
 });
 
 mongoose.model("bills", billsSchema);

+ 2 - 1
modules/all_models/projects.js

@@ -29,7 +29,8 @@ const ProjectSchema = new Schema({
         safetyFee: String,
         chargeFee: String
     },
-    "changeMark":String//更新标记  feeRate:费率文件发生了改变,unitFile 单件文件发生了改变
+    "changeMark":String,//更新标记  feeRate:费率文件发生了改变,unitFile 单件文件发生了改变
+    "remark":String //备注
 });
 
 mongoose.model(collectionName, ProjectSchema, collectionName);

+ 2 - 2
modules/all_models/ration.js

@@ -63,8 +63,8 @@ let rationSchema = new Schema({
     specs:String,//规格型号
     shortName:String,//缩写
     customQuantity:String,//自定义消耗
-    adjCoe:Number
-
+    adjCoe:Number,
+    remark:String
 });
 
 let ration = mongoose.model("ration", rationSchema, "ration");

+ 0 - 25
modules/glj/models/glj_list_model.js

@@ -109,31 +109,6 @@ class GLJListModel extends BaseModel {
                // projectGLJIDList: gljIdList 这里是取所有项目工料机,所以也是取所有定额工料机,不需要根据项目工料机ID再过滤
             };
             //为了提高性成计算消耗量功能改成了在前端计算
-           /* let quantityData = [];//await RationGLJFacade.getQuantityByProjectGLJ(condition); 为了提高性成计算消耗量功能改成了在前端计算
-            let rationTypeQuantity = [];//await RationGLJFacade.getRationTypeGLJQuantity(projectId);
-            let quantityList = {};
-            // 整理数据 得到总定额消耗量
-            for (let tmp of quantityData) {
-                let tmpNum = parseFloat(tmp.rationQuantity);
-                tmpNum = isNaN(tmpNum) ||tmpNum==0? 0 : tmpNum;
-                let tmp_con_key = keyMap[tmp.projectGLJID];
-
-                if (quantityList[tmp_con_key] === undefined) {
-                    quantityList[tmp_con_key] = scMathUtil.roundTo(tmp.quantity * tmpNum,-quantity_decimal);
-                } else {
-                    quantityList[tmp_con_key] = scMathUtil.roundTo(quantityList[tmp_con_key]+tmp.quantity * tmpNum,-quantity_decimal);
-                }
-            }
-            //计算定额类型工料机的消耗量
-            for(let rq of rationTypeQuantity){
-                let rq_key = keyMap[rq.projectGLJID];
-                let rq_quantity= scMathUtil.roundForObj(rq.quantity,quantity_decimal);
-                if(quantityList[rq_key] === undefined){
-                    quantityList[rq_key] =  scMathUtil.roundTo(rq_quantity,-quantity_decimal);
-                }else {
-                    quantityList[rq_key] = scMathUtil.roundTo(quantityList[rq_key]+rq_quantity,-quantity_decimal);
-                }
-            }*/
             // 整理获取有组成物的项目工料机的数据
             let connect_keys = [];
             for(let tmp of gljData) {

+ 7 - 2
modules/main/controllers/calc_program_controller.js

@@ -62,12 +62,17 @@ async function saveCalcItem(req, res) {
 };
 
 async function saveCalcItems(req, res) {
-    let result = {error: 0, message: ''};
+    let result = {};
 
     calcProgramFacade.saveCalcItems(req.body.data, function (err, msg) {
         if (err) {
             result.error = 1;
-        };
+            result.data = 0;
+        }
+        else{
+            result.error = 0;
+            result.data = 1;
+        }
         result.message = msg;
         res.json(result);
     });

+ 3 - 0
modules/main/controllers/project_controller.js

@@ -12,6 +12,9 @@ var callback = function(req, res, err, message, data){
 
 module.exports = {
     save: function (req, res) {
+        if(typeof req.body.data === 'object'){
+            req.body.data = JSON.stringify(req.body.data);
+        }
         var data = JSON.parse(req.body.data);
         Project.save(data, function (err, message, result) {
             if (err) {

+ 3 - 0
modules/main/controllers/ration_controller.js

@@ -54,6 +54,9 @@ async function addNewRation(req,res) {
     }
     try {
         let data = req.body.data;
+        if(typeof data === 'object'){
+            data = JSON.stringify(data);
+        }
         data = JSON.parse(data);
         result.data = await ration_facade.addNewRation(data);
     }catch (err){

+ 22 - 23
modules/main/facade/calc_program_facade.js

@@ -105,19 +105,19 @@ function saveCalcItem(dataObj, callback) {
                     for (let j=0; j < data.templates[i].calcItems.length; j++){
                         if (data.templates[i].calcItems[j].ID == dataObj.calcItem.ID){
                             data.templates[i].calcItems[j] = dataObj.calcItem;
-                            data.save(function (err) {
-                                if (err) {
-                                    callback(1, '本条计算规则保存失败');
-                                } else {
-                                    callback(0, '本条计算规则保存成功');
-                                }
-                            });
                             break;
                         };
                     };
                     break;
                 };
             };
+            data.save(function (err) {
+                if (err) {
+                    callback(1, '本条计算规则保存失败');
+                } else {
+                    callback(0, '本条计算规则保存成功');
+                }
+            });
         }
         else {
             callback(1, '没有找到计算程序文件');
@@ -136,13 +136,6 @@ function saveCalcItems(datas, callback) {
                         for (let j=0; j < data.templates[i].calcItems.length; j++){
                             if (data.templates[i].calcItems[j].ID == cI.calcItem.ID){
                                 data.templates[i].calcItems[j] = cI.calcItem;
-                                data.save(function (err) {
-                                    if (err) {
-                                        callback({err:1, msg:'本条计算规则保存失败'});
-                                    } else {
-                                        callback({err:0, msg:'本条计算规则保存成功'});
-                                    }
-                                });
                                 break;
                             };
                         };
@@ -150,9 +143,16 @@ function saveCalcItems(datas, callback) {
                     };
                 };
             };
+            data.save(function (err) {
+                if (err) {
+                    callback(1, '本条计算规则保存失败');
+                } else {
+                    callback(0, '本条计算规则保存成功');
+                }
+            });
         }
         else {
-            callback( {err:1, msg:'没有找到计算程序文件'} );
+            callback(1, '没有找到计算程序文件');
         }
     });
 };
@@ -172,17 +172,16 @@ function updateTemplate(dataObj, callback) {
                         data.templates[i].custom = dataObj.custom;
                     if (dataObj.calcItems)
                         data.templates[i].calcItems = dataObj.calcItems;
-                    data.save(function (err) {
-                        if (err) {
-                            callback(1, '计算模板保存失败');
-                        } else {
-                            callback(0, '计算模板保存成功');
-                        }
-                    });
-
                     break;
                 };
             };
+            data.save(function (err) {
+                if (err) {
+                    callback(1, '计算模板保存失败');
+                } else {
+                    callback(0, '计算模板保存成功');
+                }
+            });
         }
         else {
             callback(1, '没有找到计算程序文件');

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

@@ -123,6 +123,7 @@ async function updateNodes(datas){
     let nodeGroups = _.groupBy(datas,'type');
     let rationTasks = [];
     let billTasks = [];
+    let asyncTasks = [];
     for(let type in nodeGroups){
         for(let node of nodeGroups[type]){
             if(type == projectConsts.BILLS){
@@ -132,19 +133,15 @@ async function updateNodes(datas){
             }
         }
     }
-
-    if(rationTasks.length>0){
-         await ration_model.model.bulkWrite(rationTasks);
-    }
-    if(billTasks.length>0){
-         await  bill_model.model.bulkWrite(billTasks);
-    }
+    rationTasks.length>0?asyncTasks.push(ration_model.model.bulkWrite(rationTasks)):'';
+    billTasks.length>0?asyncTasks.push(bill_model.model.bulkWrite(billTasks)):"";
+    return  asyncTasks.length>0?await Promise.all(asyncTasks):"";
 
     function getTask(node) {
         let task={
             updateOne:{
                 filter:{
-                    projectID: node.data.projectID,
+                    //projectID: node.data.projectID, 现在复制项目也重新生成一个新的ID了,所以ID是唯一的
                     ID: node.data.ID,
                     deleteInfo: null
                 },

+ 113 - 0
public/scHintBox.html

@@ -0,0 +1,113 @@
+<!----------------------------------------------------------------------------------------------------------------------
+    chenshilong, 2018-04-29
+    自定义对话框,通用,用于替代系统对话框。系统自带的比较简陋,最严重的是一旦被浏览器屏蔽则无法再弹出。
+    自定义对话框包括:
+        1、只有一个按钮的信息提示框。
+        2、有两个按钮的操作确认询问框。
+        3、有三个按钮的操作确认询问框。
+        4、输入文本值对话框。
+----------------------------------------------------------------------------------------------------------------------->
+
+<div class="modal fade" id="hintBox" data-backdrop="static">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+
+            <div class="modal-header">
+                <h5 class="modal-title" id="hintBox_title">标题</h5>
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">&times;</span>
+                </button>
+            </div>
+
+            <div class="modal-body">
+                <div id = "hintBox_info" style="margin:5px 10px 10px 10px;">提示明细</div>
+                <div style="margin:5px 10px 5px 10px;">
+                    <input type="text" class="form-control" value="" id="hintBox_value"/>
+                </div>
+            </div>
+
+            <div class="modal-footer" style="justify-content: right">
+                <button type="button" class="btn btn-primary" data-dismiss="modal" id="hintBox_btn_yes">是</button>
+                <button type="button" class="btn btn-primary" data-dismiss="modal" id="hintBox_btn_no">否</button>
+                <button type="button" class="btn btn-secondary" data-dismiss="modal" id="hintBox_btn_cancel">取消</button>
+            </div>
+        </div>
+    </div>
+</div>
+
+<script>
+    G_HINTBOX_VALUE = null;
+    hintBoxButtonType = {yes: 1, yesNo: 2, yesNoCancel: 3};
+    function speFont(str){
+        return `<span style='color:red;font-weight:bold;font-size:15px'> ${str} </span>`;
+    };
+
+    function hintBox(title, caption, btnType, doYes, doNo) {
+        $('#hintBox_title').text(title);
+        $('#hintBox_info').html(caption);
+
+        $('#hintBox_value').hide();
+        $('#hintBox_info').show();
+        $('#hintBox_btn_yes').show();
+        $('#hintBox_btn_yes').text('是');
+        $("#hintBox_btn_yes").unbind();
+        $('#hintBox_btn_no').show();
+        $('#hintBox_btn_no').text('否');
+        $('#hintBox_btn_no').unbind();
+        $('#hintBox_btn_cancel').show();
+        $('#hintBox_btn_cancel').text('取消');
+        $('#hintBox_btn_cancel').unbind();
+
+        switch (btnType) {
+            case hintBoxButtonType.yes:
+                $('#hintBox_btn_yes').text('确定');
+                $('#hintBox_btn_no').hide();
+                $('#hintBox_btn_cancel').hide();
+                break;
+            case hintBoxButtonType.yesNo:
+                $('#hintBox_btn_cancel').hide();
+                break;
+        }
+
+        if (doYes){
+            $('#hintBox_btn_yes').click(doYes);
+        }
+
+        if (doNo){
+            $('#hintBox_btn_no').click(doNo);
+        }
+
+        $('#hintBox_btn_cancel').click(
+            function () {return;}
+        );
+
+        $("#hintBox").modal({show:true});
+    };
+
+    function hintBoxValue(title, value, doYes) {
+        $('#hintBox_title').text(title);
+
+        $('#hintBox_info').hide();
+        G_HINTBOX_VALUE = value;
+
+        $('#hintBox_value').show();
+        $('#hintBox_value').val(value);
+        $("#hintBox_value").unbind();
+        $("#hintBox_value").change(
+            function () {
+                G_HINTBOX_VALUE = $('#hintBox_value').val();
+            }
+        );
+
+        $('#hintBox_btn_yes').show();
+        $('#hintBox_btn_yes').text('确定');
+        $('#hintBox_btn_yes').unbind();
+        $('#hintBox_btn_yes').click(doYes);   // doYes不能给参数
+
+        $('#hintBox_btn_no').hide();
+        $('#hintBox_btn_cancel').hide();
+
+        $("#hintBox").modal({show:true});
+    };
+</script>
+

+ 10 - 9
public/web/scMathUtil.js

@@ -5,6 +5,12 @@
  *
  * zhangyin 2018-02-28
  * 采用重复一次四舍五入解决浮点精度误差后,10000次roundTo的时间为94毫秒。
+ *
+ * zhangyin 2018-04-28
+ * 因为js中的浮点数本身就有误差,经过运算后误差被放大,用加尾数的方式也不能消除。所以必须采用另一种思路。
+ * 考虑误差会被放大,因此放弃一位有效位数来消除误差,二进制有效位数50位,十进制有效位数15位。
+ * 原重复四舍五入的方法有缺陷,放弃。
+ * 10000次roundTo时间恢复到47毫秒
  */
 
 let scMathUtil = {
@@ -68,7 +74,8 @@ let scMathUtil = {
         let sResult2 = '';
         if (fNum > 0){
             // 双精度浮点数,尾数总长52位,因为第一位总是1,存储时已经被隐藏,所以有效位数为53位
-            const floatLength = 53;
+            // 由于js未对浮点数做优化,所以在有运算的情况下,误差会被放大,因此放弃一位有效位数来消除误差,二进制有效位数50位,十进制有效位数15位
+            const floatLength = 50;
 
             let iLength;
             // js的bug,浮点数直接取小数可能不能获得精确值,只有转成字符串,截取字符串中的小数段
@@ -155,16 +162,10 @@ let scMathUtil = {
         };
         return result;
     },
-    reRoundTo: function(num, digit){
-        let me = this;
-        return me.innerRoundTo(me.binToFloat(me.incMantissa(me.floatToBin(num))), digit);
-    },
-    // zhangyin 2018-02-28
-    // 经过运算后的浮点数,误差可能更大,加尾数也不能消除。目前采用笨办法,将有效位数加一位再四舍五入一次,以消除浮点误差。
-    // 此办法效率较低,没有别的更好办法时暂时用着
+
     roundTo: function(num, digit){
         let me = this;
-        return me.reRoundTo(me.reRoundTo(num, digit - 1), digit);
+        return me.innerRoundTo(me.binToFloat(me.incMantissa(me.floatToBin(num))), digit);
     },
     isNumber : function (obj) {
         return obj === +obj;

+ 9 - 2
web/building_saas/main/html/calc_program_manage.html

@@ -5,14 +5,14 @@
     <meta charset="utf-8">
     <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
     <meta http-equiv="x-ua-compatible" content="ie=edge">
+    <script src="../../../../public/web/common_util.js"></script>
 </head>
 
 <body>
     <div style="">
         <img id="f_btn" src="/web/dest/css/img/feeRate_btn.jpg" alt="" style="display: none" />
     </div>
-    <div class="toolsbar px-1">
-    </div>
+    <div class="toolsbar px-1" />
     <div class="container-fluid">
         <div class="row">
             <div class="col-lg-2 p-0">
@@ -25,6 +25,13 @@
             </div>
         </div>
     </div>
+
+    <script>
+        !function loadHintBox(){
+            $("body").append('<div id = "div_hintBox"></div>');
+            $("#div_hintBox").load("../../../../public/scHintBox.html");
+        }();
+    </script>
 </body>
 
 

+ 1 - 1
web/building_saas/main/js/controllers/project_controller.js

@@ -147,7 +147,7 @@ ProjectController = {
             this.addSpecialBill(project, sheetController,selected, null,true,billType.FX);
         }
         if(selected.parent){
-            if(selected.data.type==billType.FX){
+            if(selected.data.type==billType.FX||selected.data.type==billType.BX){
                 this.addSpecialBill(project, sheetController,selected.parent, selected.nextSibling,true,billType.FX);
             }
         }

+ 4 - 2
web/building_saas/main/js/models/calc_program.js

@@ -1044,8 +1044,10 @@ class CalcProgram {
             let saveDatas = {};
             saveDatas.projectID = projectInfoObj.projectInfo.ID;
             saveDatas.calcItems = me.saveForReports;
-            CommonAjax.post('/calcProgram/saveCalcItems', saveDatas, function (data) {
-                me.saveForReports = [];
+            CommonAjax.post('/calcProgram/saveCalcItems', saveDatas, function (result) {
+                if (result){
+                    me.saveForReports = [];
+                };
             });
         };
     };

+ 1 - 1
web/building_saas/main/js/models/ration.js

@@ -589,7 +589,7 @@ var Ration = {
                 if(selected.sourceType === project.Ration.getSourceType()){ // 焦点行是定额/量价/工料机,有效显示。
                     return false;
                 }else if(selected.sourceType === project.Bills.getSourceType()){
-                    if(selected.data.type == billType.FX){//焦点行是分项,有效显示。
+                    if(selected.data.type == billType.FX||selected.data.type == billType.BX){//焦点行是分项,有效显示。
                         return false
                     }
                     if(selected.data.type == billType.BILL && selected.source.children.length === 0){//焦点行是清单,且没有子项,有效显示。

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

@@ -6,7 +6,6 @@ let calcProgramManage = {
     datas: [],
     mainSpread: null,
     detailSpread: null,
-
     mainSetting: {
         header:[
             // {headerName:"ID",headerWidth:80,dataCode:"ID", hAlign: "center"},
@@ -19,7 +18,6 @@ let calcProgramManage = {
             rowHeaderWidth: CP_Col_Width.rowHeader
         }
     },
-
     detailSetting: {
         header:[
             // {headerName:"ID",headerWidth:80,dataCode:"ID", hAlign: "center"},
@@ -93,7 +91,7 @@ let calcProgramManage = {
         let dataCode = me.detailSetting.header[args.col].dataCode;
 
         if (dataCode == 'feeRate') {
-            projectObj.project.FeeRate.updateFeeRateFromCalc(args.editingText,editInfo);
+            projectObj.project.FeeRate.updateFeeRateFromCalc(args.newValue, editInfo);
             $.bootstrapLoading.end();
             return;
         };
@@ -310,6 +308,13 @@ let calcProgramManage = {
                     name: '删除行',
                     icon: 'fa-remove',
                     callback: function () {
+                        // function cbYes() {alert('你点击了yes按键');};
+                        // function cbNo() {alert('你点击了no按键');}
+                        // function cbOK() {alert(`你输入的值为:${G_HINTBOX_VALUE}`);};
+                        //
+                        // // hintBox('操作确认', '确定要删除当前节点吗?', 2, cbYes, cbNo);
+                        // hintBoxValue('请输入新名称:', '我的模板1', cbOK);
+                        // return;
                         $.bootstrapLoading.start();
                         let template = calcProgramManage.getSelectionInfo().template;
                         let idx = calcProgramManage.detailSpread.getActiveSheet().getActiveRowIndex();

+ 22 - 6
web/building_saas/main/js/views/project_view.js

@@ -36,7 +36,7 @@ var projectObj = {
         gljOprObj.showDataIfRationSelect(node);
         if (activeSubSheetIs(subSheetIndex.ssiCalcProgram)) {
             calcProgramObj.showData(node);
-        };
+        }
         //zhong 2017-9-1 特征及内容
         if(pageCCOprObj.active){
             pageCCOprObj.mainActiveCell = projectObj.mainSpread.getActiveSheet().getSelections()[0];//mainSpread焦点单元格
@@ -373,15 +373,31 @@ var projectObj = {
             };*/
         }
     },
+    updateRemark : function (node,value) {
+        console.log(value);
+        if(node.data.remark == value){
+            return;
+        }
+        let data =  {
+            type:node.sourceType,
+            data:{
+                ID:node.data.ID,
+                remark:value
+            }
+        };
+        projectObj.project.updateNodes([data],function () {
+            node.data.remark = value;
+        })
+    },
     updateCellValue: function (node, value, colSetting,editingText) {
         let project = projectObj.project, fieldName = colSetting.data.field;
         if(node.sourceType==project.ration_glj.getSourceType()){
             project.ration_glj.updateFromMainSpread(value,node,fieldName);
-        }
-        else if(calcTools.isGljRation(node)){
+        }else if(fieldName === 'remark'){
+            projectObj.updateRemark(node,value);
+        }  else if(calcTools.isGljRation(node)){
             gljOprObj.updateRationTypeGLJ(value,node,fieldName);
-        }
-        else if (value !== calcFees.getFee(node.data, fieldName)||fieldName == 'quantity') {//工程量需要进行转换,所以做特殊处理
+        } else if (value !== calcFees.getFee(node.data, fieldName)||fieldName == 'quantity') {//工程量需要进行转换,所以做特殊处理
             if (fieldName === 'code' && !calcTools.isVolumePrice(node)) {
                 projectObj.updateCode(node, value);
             }
@@ -707,7 +723,7 @@ var projectObj = {
                     disabled: function () {
                         let selected = project.mainTree.selected;
                         if(projectObj.project.isBillsLocked()== false&& selected&&selected.sourceType==project.Bills.getSourceType()){
-                            if(selected.data.type==billType.FX){//焦点行是分项,有效显示
+                            if(selected.data.type==billType.FX||selected.data.type==billType.BX){//焦点行是分项,有效显示
                                 return false
                             }
                             if(selected.data.type==billType.FB){//点行是分部,

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

@@ -16,7 +16,7 @@ let zlfb_object={
                 if(tem_node.data.type == billType.FB){
                     FB_nodes.push(tem_node);
                 }
-                if(tem_node.data.type == billType.FX){
+                if(tem_node.data.type == billType.FX||tem_node.data.type == billType.BX){
                     FX_nodes.push(tem_node);
                     let l_code = zlfb_object.getLibCode(tem_node.data.code);
                     if(tem_node.data.billsLibId&&l_code!=false){