Browse Source

code sync

TonyKang 8 năm trước cách đây
mục cha
commit
7625a2d2bc

+ 14 - 4
modules/reports/controllers/rpt_cfg_controller.js

@@ -2,11 +2,8 @@
  * Created by Tony on 2017/7/5.
  */
 
-let cache = require('../../../public/cache/cacheUtil');
 let rpt_util = require('../util/rpt_util');
-let Rpt_Cfg_Mdl = require('../models/rpt_cfg');
-
-const RPT_CFG_GRP = 'rpt_cfg';
+let Rpt_Map_Fld_Mdl = require('../models/rpt_mapping_field');
 
 //统一回调函数
 let callback = function(req, res, err, message, data){
@@ -19,5 +16,18 @@ module.exports = {
         rpt_util.getReportCacheByUser(userId, function(rst_cfg){
             callback(req,res,false,"", rst_cfg);
         });
+    },
+
+    getAllMappingFields: function (req, res) {
+        Rpt_Map_Fld_Mdl.find({}, '-_id', {sort: {'seq': 1}}, function(err, mapFields){
+            if(mapFields.length){
+                if (err) {
+                    callback(req,res,true,"no mapping fields were found!", mapFields);
+                } else {
+                    callback(req,res,false,"", mapFields);
+                }
+            }
+        })
+
     }
 };

+ 22 - 0
modules/reports/models/rpt_mapping_field.js

@@ -0,0 +1,22 @@
+/**
+ * Created by Tony on 2017/7/11.
+ */
+let mongoose = require('mongoose');
+let dbm = require("../../../config/db/db_manager");
+let smartcostdb = dbm.getCfgConnection("scConstruct");
+let MapFieldSchema = new mongoose.Schema({
+    "fieldMapGrpName" : String,
+    "dispName": String,
+    "remark" : String,
+    "seq" : Number,
+    "items" : [{
+        mapId: Number,
+        dispName: String,
+        mapExpression: String,
+        descr: String
+    }]
+});
+
+let Rpt_Map_Field_Mdl = smartcostdb.model("rpt_mapping_field", MapFieldSchema, "rpt_mapping_field");
+
+module.exports = Rpt_Map_Field_Mdl;

+ 2 - 0
modules/reports/routes/rpt_tpl_router.js

@@ -11,5 +11,7 @@ rptTplRouter.post('/createDftRptTpl', reportTplController.createDftRptTpl);
 rptTplRouter.post('/getRefRptTpl', reportTplController.getRefRptTpl);
 
 rptTplRouter.post('/getUserRptCfg', reportCfgController.getReportUserCfg);
+rptTplRouter.post('/getMappingFields', reportCfgController.getAllMappingFields);
+//
 
 module.exports = rptTplRouter;

+ 45 - 16
public/calc_util.js

@@ -1,11 +1,16 @@
 /**
  * Created by Tony on 2017/6/21.
  */
-let calcBaseCodeCollection = ["定额基价材料费", "定额基价机械费", "定额基价人工费"
+let calcBaseCodeCollection = ["定额基价人工费", "定额基价材料费", "定额基价机械费"
     , "定额基价人工费(调整后)", "定额基价材料费(调整后)", "定额基价机械费(调整后)"
     , "市场价格人工费", "市场价格材料费", "市场价格机械费"
     , "定额基价机上人工费", "主材费", "设备费"
 ];
+let dummyCalcBaseCodeTypeCollection = [[2], [6], [64]
+    , [], [], []
+    , [], [], []
+    , [], [], []
+];
 
 let executeObj = {
     currentTpl : null,
@@ -18,26 +23,42 @@ let executeObj = {
         return rst;
     },
     base: function(calcBaseCode) {
-        let me = executeObj, rst = -1,
-            idx = 10 + calcBaseCodeCollection.indexOf(calcBaseCode);
+        let me = executeObj, rst = 0,
+            idx = calcBaseCodeCollection.indexOf(calcBaseCode);
         if (idx >= 0) {
-            //
-        } else {
-            //
+            if (dummyCalcBaseCodeTypeCollection[idx].length > 0) {
+                let tmpSum = 0;
+                for (let glj of me.currentRationItem.rationGljList) {
+                    if (dummyCalcBaseCodeTypeCollection[idx].indexOf(glj["glj"]["gljType"]) >= 0) {
+                        tmpSum += glj["glj"]["basePrice"] * glj["consumeAmt"];
+                    }
+                }
+                rst = tmpSum;
+            } else {
+                //rst = 10 + idx; //随便给个数
+            }
         }
-        rst = idx; //暂时返回值,测试用
+        //rst = idx; //暂时返回值,测试用
         return rst;
     },
     fee: function(feeID) {
-        let me = executeObj, rst = -1;
-        //
-        //rst = parseInt(feeID); //暂时返回值,测试用
-        rst = 0.89;
+        let me = executeObj, rst = 0;
+        /*
+        for (let fee of me.currentFeeRateFile) {
+            if (fee.ID == feeID) {
+                rst = fee.rate;
+                break;
+            }
+        }
+        /*/
+        if (me.compiledFeeRateFile["fee_" + feeID]) rst = me.compiledFeeRateFile["fee_" + feeID].rate;
+        //*/
         return rst;
     },
     factor: function(factorCode) {
         let me = executeObj;
-        //
+        let rst = 0.89; //暂时固定输出,测试用
+        return rst;
     }
 };
 
@@ -120,10 +141,20 @@ class calculation {
                 //console.log(item.compiledExpr);
             }
         };
+        let private_comile_feeFile = function() {
+            if (me.calFee) {
+                me.compiledFee = {};
+                for (let fee of me.calFee) {
+                    me.compiledFee["fee_" + fee.ID] = fee;
+                }
+            }
+        };
+
         if (me.calcTpl && me.calcTpl.calcItems && me.calcTpl.calcItems.length > 0) {
             me.calcTpl.compiledSeq = [];
             me.compileAssistantObj = {};
             //1. first round -> prepare
+            private_comile_feeFile();
             for (let i = 0; i < me.calcTpl.calcItems.length; i++) {
                 let item = me.calcTpl.calcItems[i];
                 me.compileAssistantObj[item.code] = item;
@@ -149,14 +180,12 @@ class calculation {
             let $CE = executeObj;
             $CE.currentRationItem = $RATION;
             $CE.currentTpl = me;
+            $CE.currentFeeRateFile = me.calFee;
+            $CE.compiledFeeRateFile = me.compiledFee;
             for (let idx of me.calcTpl.compiledSeq) {
                 let item = me.calcTpl.calcItems[idx];
                 item.execRst = eval(item.compiledExpr);
             }
-            for (let idx of me.calcTpl.compiledSeq) {
-                let item = me.calcTpl.calcItems[idx];
-                console.log('code: ' + item.code + ' | expression: ' + item.compiledExpr +  ' | result: ' + item.execRst);
-            }
         }
     }
 }

+ 95 - 5
test/calculation/testCalc.js

@@ -221,7 +221,6 @@ let dummyCalcTpl = {
     calType: 3,
     calTypeName: "测试用_重庆",
     compiledSeq: [],
-    intermediateRst: [],
     calcItems: [{
         code: "1",
         name: "基价直接工程费",
@@ -240,14 +239,15 @@ let dummyCalcTpl = {
         code: "1.1.1",
         name: "定额基价人工费",
         dispExpr: "定额基价人工费",
-        expression: "base('定额基价人工费')",
+        //expression: "base('定额基价人工费')",
+        expression: "base('定额基价人工费').toFixed(2)",
         compiledExpr: "",
         statement: "定额基价人工费"
     },{
         code: "1.1.2",
         name: "定额人工单价(基价)调整",
         dispExpr: "1.1.1*[1.89-1]",
-        expression: "@('1.1.1') * fee('1')",
+        expression: "@('1.1.1') * fee('3')",
         compiledExpr: "",
         statement: "定额基价人工费*[定额人工单价(基价)调整系数-1]"
     },{
@@ -282,7 +282,7 @@ let dummyCalcTpl = {
         code: "1.3.2",
         name: "定额人工单价(基价)调整",
         dispExpr: "1.3.1.1*[1.89-1]",
-        expression: "@('1.3.1.1') * fee('1')",
+        expression: "@('1.3.1.1') * fee('30')",
         compiledExpr: "",
         statement: "定额基价人工费*[定额人工单价(基价)调整系数-1]"
     },{
@@ -352,11 +352,101 @@ let dummyCalcTpl = {
     ]
 };
 
+let dummyRation = {
+    "sectionId" : 76,
+    "ID" : 15,
+    "code" : "AA0001",
+    "name" : "人工挖土方",
+    "unit" : "100m3",
+    "basePrice" : 840.84,
+    "caption" : "人工挖土方",
+    "feeType" : 2,
+    "rationGljList" : [
+        {
+            "glj" : {
+                "repositoryId" : 3,
+                "ID" : 17,
+                "code" : "00010201",
+                "name" : "土石方综合工日",
+                "specs" : null,
+                "unit" : "工日",
+                "basePrice" : 22,
+                "gljDistType" : "人工",
+                "gljType" : 2
+            },
+            "consumeAmt" : 38.22,
+            "proportion" : 0
+        },{
+            "glj": {
+                "repositoryId" : 3,
+                "ID" : 68,
+                "code" : "85030207",
+                "name" : "履带式起重机",
+                "specs" : "50t",
+                "unit" : "台班",
+                "basePrice" : 1194.05,
+                "gljDistType" : "机械",
+                "gljType" : 64
+            },
+            "consumeAmt" : 1.22,
+            "proportion" : 0
+        },{
+            "glj": {
+                "repositoryId" : 3,
+                "ID" : 200,
+                "code" : "36290101",
+                "name" : "水",
+                "specs" : "",
+                "unit" : "m3",
+                "basePrice" : 2,
+                "gljDistType" : "材料",
+                "gljType" : 6
+            },
+            "consumeAmt" : 9.2,
+            "proportion" : 0
+        }
+    ],
+    "rationRepId" : 3
+}
+
+/*
 test('计算式测试', function(t){
     calcUtil.init(dummyCalcTpl, dummyFee);
     calcUtil.compile();
-    calcUtil.calculate({});
+    calcUtil.calculate(dummyRation);
+    for (let idx of dummyCalcTpl.compiledSeq) {
+        let item = dummyCalcTpl.calcItems[idx];
+        console.log('code: ' + item.code + ' | expression: ' + item.compiledExpr +  ' | result: ' + item.execRst);
+    }
+    t.pass('just pass for calculation initialization!');
+    t.end();
+})
+
+/*/
+let cnt = 100000;
+test('极限计算式测试:' + cnt + '次', function(t){
+    let dt0 = new Date();
+    calcUtil.init(dummyCalcTpl, dummyFee);
+    calcUtil.compile();
+
+    let exRlist = [];
+
+    let rStr = JSON.stringify(dummyRation);
+    for (let i = 0; i < cnt; i++) {
+        exRlist.push(JSON.parse(rStr));
+    }
+
+    let dt1 = new Date();
+    for (let i = 0; i < cnt; i++) {
+        calcUtil.calculate(exRlist[i]);
+    }
+    let dt2 = new Date();
+    console.log("准备对象时间(毫秒): " + (dt1 - dt0));
+    console.log("总计算时间(毫秒): " + (dt2 - dt1));
+    console.log("总测试时间(毫秒): " + (dt2 - dt0));
     t.pass('just pass for calculation initialization!');
     t.end();
 })
 
+
+//*/

+ 5 - 0
web/maintain/report/css/main.css

@@ -280,6 +280,11 @@ body {
 .form-view {
     border-left:1px solid #ccc;
 }
+.ztree {
+  border-style:solid; 
+  border-width:1px; 
+  border-color:#000;
+}
 .ztree-warp {
   height:200px;
   overflow: auto;

+ 47 - 3
web/maintain/report/js/cfg_const.js

@@ -88,9 +88,13 @@ let fieldMapSetting = {
         enable: true,
         editNameSelectAll: true,
         showRemoveBtn: true,
-        showRenameBtn: true,
+        showRenameBtn: false,
         removeTitle: "删除",
-        renameTitle: "更改名称"
+        renameTitle: "更改名称",
+        drag: {
+            isCopy: false,
+            isMove: true
+        }
     },
     data: {
         keep: {
@@ -110,6 +114,46 @@ let fieldMapSetting = {
         beforeRename: fieldMapTreeOprObj.beforeRename,
         beforeRemove: fieldMapTreeOprObj.onBeforeRemove,
         onRemove: fieldMapTreeOprObj.onRemove,
-        onRename: fieldMapTreeOprObj.onRename
+        onRename: fieldMapTreeOprObj.onRename,
+        beforeDrop: fieldMapTreeOprObj.onBeforeDrop
+    }
+};
+
+let selectableFieldSetting = {
+    view: {
+        showIcon: true,
+        expandSpeed: "",
+        selectedMulti: false
+        //,addDiyDom: selectableFiledTreeOprObj.addDiyDom
+    },
+    edit: {
+        enable: true,
+        editNameSelectAll: false,
+        showRemoveBtn: false,
+        showRenameBtn: false,
+        removeTitle: "删除",
+        renameTitle: "更改名称",
+        drag: {
+            isCopy: true,
+            isMove: false
+        }
+    },
+    data: {
+        keep: {
+            parent:true,
+            leaf:true
+        },
+        key: {
+            children: 'items',
+            name: "Name"
+        },
+        simpleData: {
+            enable: true
+        }
+    },
+    callback:{
+        onClick: selectableFiledTreeOprObj.onClick,
+        beforeDrag: selectableFiledTreeOprObj.onBeforeDrag,
+        beforeDrop: selectableFiledTreeOprObj.onBeforeDrop
     }
 };

+ 94 - 3
web/maintain/report/js/rpt_tpl_field_map.js

@@ -2,6 +2,8 @@
 
 let fieldMapTreeOprObj = {
     treeObj : null,
+    currentNode: null,
+    dataTypeDef: ['string', 'int32', 'int64', 'double', 'currency', 'date', 'image'],
     iniTree: function(rptTpl) {
         var me = this;
         let fieldMapList = me.buildTreeData(rptTpl);
@@ -31,8 +33,32 @@ let fieldMapTreeOprObj = {
 
         return rst;
     },
-    onClick: function () {
-        //
+    onClick: function (event,treeId,treeNode) {
+        let me = fieldMapTreeOprObj;
+        me.currentNode = treeNode;
+        //then refresh the field map tab properties
+        //数据类型
+        switch (me.dataTypeDef.indexOf(treeNode[JV.PROP_DATA_TYPE])) {
+            case 0:
+                $("#fieldDataTypeSelection").get(0).selectedIndex = 0;
+                break;
+            case 1:
+            case 2:
+            case 3:
+            case 4:
+                $("#fieldDataTypeSelection").get(0).selectedIndex = 1;
+                break;
+            case 5:
+                $("#fieldDataTypeSelection").get(0).selectedIndex = 2;
+                break;
+            case 6:
+                $("#fieldDataTypeSelection").get(0).selectedIndex = 3;
+                break;
+            default:
+                $("#fieldDataTypeSelection").get(0).selectedIndex = 0;
+                break;
+        }
+        //映射指标
     },
     onBeforeRemove: function(treeId, treeNode){
         if (treeNode.level === 0) {
@@ -49,6 +75,15 @@ let fieldMapTreeOprObj = {
         }
         return true;
     },
+    onBeforeDrop: function(treeId, treeNodes, targetNode, moveType){
+        let rst = true;
+        if (treeId === 'selectable_field_tree_reversed' || targetNode.level === 0 || moveType === 'inner') {
+            rst = false;
+        } else {
+            //
+        }
+        return rst;
+    },
     onRemove: function () {
         //
     },
@@ -58,4 +93,60 @@ let fieldMapTreeOprObj = {
     extractFieldMaps: function (rptTpl) {
         //
     }
-};
+};
+
+let selectableFiledTreeOprObj = {
+    treeObj : null,
+    currentNode: null,
+    iniTree: function() {
+        let me = this, params = {};
+        params.userId = userID;
+        CommonAjax.postEx("report_tpl_api/getMappingFields", params, 20000, true, function(result){
+                let showRst = [];
+                for (let item of result) {
+                    if (item.items.length > 0) {
+                        showRst.push(item);
+                    }
+                }
+                me.treeObj = $.fn.zTree.init($("#selectable_field_tree_reversed"), selectableFieldSetting, showRst);
+                me.treeObj.expandAll(true);
+                showRst = null;
+            }, null, null
+        );
+    },
+    onClick: function (event,treeId,treeNode) {
+        let me = fieldMapTreeOprObj;
+        me.currentNode = treeNode;
+    },
+    onBeforeDrag: function (treeId, treeNodes) {
+        let rst = true;
+        for (let node of treeNodes) {
+            if (node.level === 0) {
+                rst = false;
+                break;
+            }
+        }
+        return rst;
+    },
+    onBeforeDrop: function(treeId, treeNodes, targetNode, moveType){
+        let rst = true;
+        if (treeId === 'field_map_tree_reversed') {
+            if ( (targetNode.level === 0 && moveType !== 'inner') || (targetNode.level > 0 && moveType === 'inner')) {
+                rst = false;
+            }
+        } else {
+            rst = false;
+        }
+        return rst;
+    },
+    addDiyDom: function (treeId, treeNode) {
+        if (treeNode.level > 0) {
+            let aObj = $("#" + treeNode.tId + "_a");
+            if ($("#diyBtn_"+treeNode.ID).length>0) return;
+            let editStr = "<span>&nbsp(" + treeNode.DataType + ")</span>";
+            aObj.append(editStr);
+            let btn = $("#diyBtn_"+treeNode.ID);
+            if (btn) btn.bind("click", function(){alert("diy Button for " + treeNode.name);});
+        }
+    }
+}

+ 1 - 0
web/maintain/report/js/rpt_tpl_main.js

@@ -4,6 +4,7 @@ let rptTplObj = {
     iniPage: function() {
         zTreeOprObj.getReportTemplateTree(RT.GrpType.CONSTRUCT);
         bandTreeOprObj.getReportTplCfg();
+        selectableFiledTreeOprObj.iniTree();
         preview_util.drawBorder($("#tplCanvas")[0]);
     }
 }

+ 7 - 16
web/maintain/report/rpt_tpl_main.html

@@ -206,25 +206,17 @@
                                             <div class="tab-pane" id="rpttplfieldmap" role="tabpanel">
                                                 <div class="main-data">
                                                     <div class="p-3">
-                                                        <div class="ztree-warp">
+                                                        <label>报表映射指标</label>
+                                                        <div class="tab-content">
                                                             <ul id="field_map_tree_reversed" class="ztree"></ul>
                                                         </div>
-                                                        <div class="row">
-                                                            <div class="form-group col-md-6">
-                                                                <label class="col-form-label">数据类型</label>
-                                                                <select class="form-control" id="fieldDataTypeSelection"><option>String</option><option>Number</option><option>Date</option><option>Img etc</option></select>
-                                                            </div>
-                                                        </div>
-                                                        <div class="form-group">
-                                                            <label>映射指标</label>
-                                                            <div class="input-group">
-                                                                <div class="input-group-addon">类型</div>
-                                                                <select class="form-control input-sm"><option>离散</option><option>主数据</option><option>从数据</option></select>
+                                                        <p/>
+                                                        <div class="tab-content">
+                                                            <label>可映射指标</label>
+                                                            <div class="tab-content">
+                                                                <ul id="selectable_field_tree_reversed" class="ztree"></ul>
                                                             </div>
                                                         </div>
-                                                        <div class="form-group">
-                                                            <select class="form-control" size="5"></select>
-                                                        </div>
                                                     </div>
                                                 </div>
                                             </div>
@@ -286,7 +278,6 @@
                                 </div>
                             </div>
                         </div>
-
                     </div>
                 </div>
             </div>