瀏覽代碼

09-1 complete solution

TonyKang 7 年之前
父節點
當前提交
0c5172be68

+ 248 - 18
modules/reports/util/rpt_construct_data_util.js

@@ -12,6 +12,14 @@ let treeUtil = require('../../../public/treeUtil');
 let projectConst = consts.projectConst;
 let projectConstList = consts.projectConstList;
 
+const GLJ_TYPE = {
+    Labour: 1,
+    Material: 2,
+    Machine: 3,
+    Main_Material: 4,
+    Equipment: 5
+}
+
 class Rpt_Common{
     initialize(rpt_tpl, currentDataObj) {
         this.template = rpt_tpl;
@@ -152,7 +160,7 @@ class Rpt_Data_Extractor {
                 let srcData = getModuleDataByKey(rawDataObj.prjData, preHandle[JV.PROP_DATA_KEY]);
                 switch(preHandle[JV.PROP_HANDLE_TYPE]) {
                     case JV.PROP_HANDLE_TYPE_SORT:
-                        sortData(srcData, preHandle);
+                        sortData(srcData, preHandle, rawDataObj.prjData);
                         break;
                     case JV.PROP_HANDLE_TYPE_FILTER:
                         filterData(srcData, preHandle, rawDataObj.prjData);
@@ -160,6 +168,12 @@ class Rpt_Data_Extractor {
                     case JV.PROP_HANDLE_TYPE_SUM:
                         summaryData(srcData, preHandle, rawDataObj.prjData);
                         break;
+                    case JV.PROP_HANDLE_TYPE_ADD_DUMMY:
+                        addDummyData(srcData, preHandle);
+                        break;
+                    case JV.PROP_HANDLE_TYPE_ADJUST:
+                        adjustData(srcData, preHandle);
+                        break;
                     default:
                         break;
                 }
@@ -320,7 +334,133 @@ function filterData(sourceData, handleCfg, prjData) {
     // fsUtil.wirteObjToFile(sourceData.data, "D:/GitHome/ConstructionCost/tmp/filteredRst.js");
 }
 
-function sortData(sourceData, sortCfg) {
+function adjustData(sourceData, adjustCfg) {
+    let rstArr = [];
+    for (let item of sourceData.data) {
+        if (item._doc) {
+            rstArr.push(item._doc);
+        } else {
+            rstArr.push(item);
+        }
+    }
+    for (let item of adjustCfg[JV.PROP_ADJUST_COLLECTION]) {
+        for (let rec of rstArr) {
+            if (item[JV.PROP_ADJUST_ACTION] === "prefix") {
+                rec[item.key] = item[JV.PROP_ADJUST_ACTION_VAL] + rec[item.key];
+            } else if (item[JV.PROP_ADJUST_ACTION] === "suffix") {
+                rec[item.key] = rec[item.key] + item[JV.PROP_ADJUST_ACTION_VAL];
+            }
+        }
+    }
+    delete sourceData.data;
+    sourceData.data = rstArr;
+}
+
+function getDupGrpKeyVals(sourceData, segKeys) {
+    let rst = [];
+    function pushKeyVal(item) {
+        let tr = {};
+        for (let i = 0; i < segKeys.length; i++) {
+            tr[segKeys[i]] = item[segKeys[i]];
+        }
+        rst.push(tr);
+    }
+    for (let idx = 0; idx < sourceData.length; idx++) {
+        let itemRec = sourceData[idx];
+        if (idx === 0) {
+            pushKeyVal(itemRec);
+            continue;
+        }
+        let hasDiff = false;
+        for (let i = 0; i < segKeys.length; i++) {
+            if (itemRec[segKeys[i]] !== sourceData[idx - 1][segKeys[i]]) {
+                hasDiff = true;
+                break;
+            }
+        }
+        if (hasDiff) {
+            pushKeyVal(itemRec);
+        }
+    }
+    return rst;
+}
+
+function addDummyData(sourceData, addCfg) {
+    let rstArr = [], tempRstArr = [];
+    for (let item of sourceData.data) {
+        if (item._doc) {
+            tempRstArr.push(item._doc);
+        } else {
+            tempRstArr.push(item);
+        }
+    }
+    for (let item of addCfg[JV.PROP_DUMMY_COLLECTION]) {
+        let newRecStr = JSON.stringify(item[JV.PROP_DUMMY_VAL]), cacheGrpKeyRecs = null;
+        if (item[JV.PROP_FREQUENCY] === "OncePerGrp") {
+            if (!cacheGrpKeyRecs) {
+                cacheGrpKeyRecs = {};
+            }
+            let cacheKey = "";
+            for (let key of item[JV.PROP_GRP_KEYS]) {
+                cacheKey += "_" + key;
+            }
+            if (!cacheGrpKeyRecs[cacheKey]) {
+                cacheGrpKeyRecs[cacheKey] = getDupGrpKeyVals(tempRstArr, item[JV.PROP_GRP_KEYS]);
+            }
+            for (let kv of cacheGrpKeyRecs[cacheKey]) {
+                let rec = JSON.parse(newRecStr);
+                for (let key of item[JV.PROP_GRP_KEYS]) {
+                    rec[key] = kv[key];
+                }
+                rstArr.push(rec);
+            }
+
+        } else if (item[JV.PROP_FREQUENCY] === "Once") {
+            rstArr.push(JSON.parse(newRecStr));
+        }
+    }
+    rstArr = rstArr.concat(tempRstArr);
+    delete sourceData.data;
+    sourceData.data = rstArr;
+}
+
+function getGLJBizType(orgType, orgCode, orgName) {
+    let rst = orgType;
+    if (orgName.indexOf("其他材料费") >= 0) {
+        rst = 299;
+    } else if (orgType === GLJ_TYPE.Labour) {
+        rst = 11;
+        if (orgCode === "000000") rst = 10;
+    } else if (orgType === GLJ_TYPE.Main_Material || orgType === GLJ_TYPE.Equipment) {
+        //未计价材料(主材 + 设备)
+        rst = 30 + orgType;
+    } else if (orgType === GLJ_TYPE.Material || (orgType >= 200 && orgType < 300)) {
+        //材料
+        if (orgCode === "000000") {
+            rst = 20; //2.材料
+        } else if (orgCode === "000000_1") {
+            rst = 30; //(1) 未计价材料
+        } else if (orgCode === "000000_2") {
+            rst = 40; //(2) 辅助材料
+        } else if (orgCode === "000000_3") {
+            rst = 50; //(3) 其他材料费
+        } else {
+            rst = 45; //到这里就只有辅助材料没有预处理了
+        }
+    } else if (orgType === GLJ_TYPE.Machine || (orgType >= 300 && orgType < 400)) {
+        //机械
+        if (orgCode === "000000") {
+            rst = 300; //3.机械
+        } else if (orgType === GLJ_TYPE.Machine) {
+            rst = 300.5;
+        } else {
+            rst = orgType;
+        }
+    }
+    return rst;
+}
+
+function sortData(sourceData, sortCfg, prjData) {
     let rst = sourceData.data, tempRstArr = [];
     let sortType = sortCfg[JV.PROP_SORT_TYPE];
     for (let item of sourceData.data) {
@@ -330,6 +470,56 @@ function sortData(sourceData, sortCfg) {
             tempRstArr.push(item);
         }
     }
+    function private_normal_sort(destArr, sortKeys) {
+        destArr.sort(function(a, b){
+            let compRst = 0;
+            for (let comp of sortKeys) {
+                let reverse = (comp.order === 'ascend')?1:(-1);
+                //
+                if (a[comp.key] > b[comp.key]) {
+                    compRst = reverse;
+                    break;
+                } else if (a[comp.key] < b[comp.key]) {
+                    compRst = -reverse;
+                    break;
+                }
+            }
+            return compRst;
+        });
+    }
+    function private_parent_sort(parentArr, parentKeys, childArr, childKeys) {
+        let tmpRst = {}, rst = [];
+        for (let pItem of parentArr) {
+            let pKey = "key";
+            for (let key of parentKeys) {
+                pKey += "_" + pItem[key];
+            }
+            tmpRst[pKey] = [];
+        }
+        for (let cItem of childArr) {
+            let cKey = "key";
+            for (let key of childKeys) {
+                cKey += "_" + cItem[key];
+            }
+            if (tmpRst[cKey]) {
+                tmpRst[cKey].push(cItem);
+            } else {
+                //unknown child value! should be filtered!
+            }
+        }
+        // childArr.splice(0);
+        for (let pItem of parentArr) {
+            let pKey = "key";
+            for (let key of parentKeys) {
+                pKey += "_" + pItem[key];
+            }
+            rst.push(tmpRst[pKey]);
+            // for (let rItem of tmpRst[pKey]) {
+            //     childArr.push(rItem);
+            // }
+        }
+        return rst;
+    }
     switch (sortType) {
         case "tree":
             rst = treeUtil.buildTreeNodeDirectly(tempRstArr);
@@ -340,23 +530,59 @@ function sortData(sourceData, sortCfg) {
             // fsUtil.wirteObjToFile(sourceData.data, "D:/GitHome/ConstructionCost/tmp/sortedAndFlattedRst.js");
             break;
         case "normal":
-            tempRstArr.sort(function(a, b){
-                let compRst = 0;
-                for (let comp of sortCfg[JV.PROP_SORT_KEYS]) {
-                    let reverse = (comp.order === 'ascend')?1:(-1);
-                    if (a[comp.key] > b[comp.key]) {
-                        compRst = reverse;
-                        break;
-                    } else if (a[comp.key] < b[comp.key]) {
-                        compRst = -reverse;
-                        break;
+            private_normal_sort(tempRstArr, sortCfg[JV.PROP_SORT_KEYS]);
+            delete sourceData.data;
+            sourceData.data = tempRstArr;
+            // fsUtil.wirteObjToFile(sourceData.data, "D:/GitHome/ConstructionCost/tmp/normalSortedRst.js");
+            break;
+        case "accord_to_parent":
+            let pcKey = sortCfg[JV.PROP_PARENT_CHILD_SORT_KEY];
+            let parentSrcData = getModuleDataByKey(prjData, pcKey[JV.PROP_PARENT_DATA_KEY]);
+            if (parentSrcData) {
+                let tempParentArr = [];
+                for (let item of parentSrcData.data) {
+                    if (item._doc) {
+                        tempParentArr.push(item._doc);
+                    } else {
+                        tempParentArr.push(item);
                     }
                 }
-                return compRst;
-            });
+                let sortedRstArr = private_parent_sort(tempParentArr, pcKey[JV.PROP_PARENT_SORT_KEYS], tempRstArr, pcKey[JV.PROP_CHILD_SORT_KEYS]);
+                if (sortCfg[JV.PROP_OTHER_SUB_SORT] && sortCfg[JV.PROP_OTHER_SUB_SORT].length > 0) {
+                    for (let sort of sortCfg[JV.PROP_OTHER_SUB_SORT]) {
+                        if (sort[JV.PROP_SORT_TYPE] === 'normal') {
+                            for (let subArr of sortedRstArr) {
+                                private_normal_sort(subArr, sort[JV.PROP_SORT_KEYS]);
+                            }
+                        } else if (sort[JV.PROP_SORT_TYPE] === 'self_define') {
+                            for (let subArr of sortedRstArr) {
+                                console.log(subArr);
+                                let selfDefFunc = null;
+                                eval('selfDefFunc = ' + sort[JV.PROP_SORT_TYPE_SELF_DEFINE_LOGIC]);
+                                subArr.sort(selfDefFunc);
+                                console.log(subArr);
+                            }
+                        }
+                    }
+                }
+                tempRstArr.splice(0);
+                for (let item of sortedRstArr) {
+                    for (let subItem of item) {
+                        tempRstArr.push(subItem);
+                    }
+                }
+            }
+            delete sourceData.data;
+            sourceData.data = tempRstArr;
+            break;
+        case "self_define":
+            if (sortCfg[JV.PROP_SORT_TYPE_SELF_DEFINE_LOGIC]) {
+                let selfDefFunc = null;
+                eval('selfDefFunc = ' + sortCfg[JV.PROP_SORT_TYPE_SELF_DEFINE_LOGIC]);
+                tempRstArr.sort(selfDefFunc);
+            }
             delete sourceData.data;
             sourceData.data = tempRstArr;
-            // fsUtil.wirteObjToFile(sourceData.data, "D:/GitHome/ConstructionCost/tmp/normalSortedRst.js");
             break;
         default:
             //
@@ -583,7 +809,7 @@ function ext_getArrayItemByKey(arrayKey, itemKey, itemKeyValue, itemRstKey){
 
 }
 
-function ext_getPropertyByForeignId(foreignIdVal, adHocIdKey, propKey) {
+function ext_getPropertyByForeignId(foreignIdVal, adHocIdKey, propKey, dftValIfNotFound) {
     let rst = [], parentObj = this;
     let IdKey = (adHocIdKey)?adHocIdKey:"ID";
     let dtObj = parentObj["myOwnRawDataObj"];
@@ -618,7 +844,9 @@ function ext_getPropertyByForeignId(foreignIdVal, adHocIdKey, propKey) {
                         break;
                     }
                 }
-                // if (!isFound) rst.push[null];
+                if (!isFound) {
+                    rst.push(dftValIfNotFound);
+                }
             }
         } else {
             for (let item of dtObj.data) {
@@ -628,7 +856,9 @@ function ext_getPropertyByForeignId(foreignIdVal, adHocIdKey, propKey) {
                     break;
                 }
             }
-            // if (!isFound) rst.push[null];
+            if (!isFound) {
+                rst.push(dftValIfNotFound);
+            }
         }
     }
     return rst;

+ 9 - 0
public/stringUtil.js

@@ -136,6 +136,15 @@ module.exports = {
         }
         return rst;
     },
+    trim: function(str) {
+        return str.replace(/(^\s*)|(\s*$)/g, "");
+    },
+    leftTrim: function(str) {
+        return str.replace(/(^\s*)/g,"");
+    },
+    rightTrim: function(rst) {
+        return str.replace(/(\s*$)/g,"");
+    },
     convertNumToChinese : function(num, isCurrency) {
         if (!/^\d*(\.\d*)?$/.test(num)) { return "Number is wrong!"; }
         let AA, BB;

+ 16 - 0
public/web/rpt_value_define.js

@@ -47,6 +47,11 @@ const JV = {
 
     NODE_MAP_DATA_HANDLE_INFO: "映射数据预处理",
     PROP_DATA_KEY: "映射数据对象",
+    PROP_PARENT_DATA_KEY: "父映射数据对象",
+    PROP_PARENT_CHILD_SORT_KEY: "父子排序键",
+    PROP_PARENT_SORT_KEYS: "父排序键值集",
+    PROP_CHILD_SORT_KEYS: "子排序键值集",
+    PROP_OTHER_SUB_SORT: "其他子排序",
     PROP_HANDLE_TYPE: "预处理类型",
     PROP_FILTER_KEY: "过滤键值集",
     PROP_FILTER_COMPARE_OBJ: "compareObjKey",
@@ -56,7 +61,18 @@ const JV = {
     PROP_HANDLE_TYPE_FILTER: "过滤",
     PROP_HANDLE_TYPE_SUM: "合计",
     PROP_HANDLE_TYPE_SORT: "排序",
+    PROP_HANDLE_TYPE_ADD_DUMMY: "增加Dummy数据",
+    PROP_HANDLE_TYPE_ADJUST: "数据调整",
+
+    PROP_ADJUST_COLLECTION: "数据调整集",
+    PROP_ADJUST_ACTION: "action",
+    PROP_ADJUST_ACTION_VAL: "actionValue",
+    PROP_DUMMY_COLLECTION: "Dummy数据集",
+    PROP_DUMMY_VAL: "Dummy数据对象值",
+    PROP_FREQUENCY: "频率",
+    PROP_GRP_KEYS: "GrpKeyIds",
     PROP_SORT_TYPE: "排序方式",
+    PROP_SORT_TYPE_SELF_DEFINE_LOGIC: "自定义逻辑",
     PROP_SORT_KEYS: "排序键值集",
     PROP_SUM_GROUP_KEYS: "分组键值集",
     PROP_SUM_SUM_KEYS: "统计键值集",

+ 3 - 2
test/unit/reports/test_tpl_09_1.js

@@ -39,7 +39,8 @@ let demoPrjId = - 1;
 let demoRptId = 226, pagesize = "A4";
 
 let userId_Leng = 1142; //小冷User Id
-demoPrjId = 720; //QA: DW3
+// demoPrjId = 720; //QA: DW3
+demoPrjId = 838; //QA:
 /*/
 let userId_Dft = userId_Leng;
 /*/
@@ -90,7 +91,7 @@ test('测试 - 获取project部分数据: ', function (t) {
                     //     newData.push(JSON.stringify(item));
                     // }
                     // fsUtil.writeArrayToFile(newData, "D:/GitHome/ConstructionCost/tmp/getProjectData_partial.js");
-                    fsUtil.wirteObjToFile(prjObj, "D:/GitHome/ConstructionCost/tmp/getProjectObjectNew.js");
+                    // fsUtil.wirteObjToFile(prjObj, "D:/GitHome/ConstructionCost/tmp/getProjectObjectNew.js");
                     fsUtil.wirteObjToFile(results, "D:/GitHome/ConstructionCost/tmp/getProjectData_partialNew.js");
                     t.pass('pass succeeded!');
                     t.end();