浏览代码

交叉表排序补漏

Tony Kang 10 月之前
父节点
当前提交
905620e77b
共有 2 个文件被更改,包括 76 次插入66 次删除
  1. 70 63
      app/reports/rpt_component/helper/jpc_helper_cross_tab.js
  2. 6 3
      app/reports/rpt_component/jpc_cross_tab.js

+ 70 - 63
app/reports/rpt_component/helper/jpc_helper_cross_tab.js

@@ -1,12 +1,14 @@
-let JV = require('../jpc_value_define');
-let JE = require('../jpc_rte');
-let JpcCommonHelper = require('./jpc_helper_common');
+'use strict';
 
-let JpcCrossTabHelper = {
-    getColIDX: function(cl, val) {
+const JV = require('../jpc_value_define');
+const JE = require('../jpc_rte');
+const JpcCommonHelper = require('./jpc_helper_common');
+
+const JpcCrossTabHelper = {
+    getColIDX(cl, val) {
         let rst = -1;
         for (let i = 0; i < cl.length; i++) {
-            let ca = cl[i];
+            const ca = cl[i];
             for (let j = 0; j < ca.length; j++) {
                 if (ca[j] == val) {
                     rst = i;
@@ -19,15 +21,15 @@ let JpcCrossTabHelper = {
         }
         return rst;
     },
-    pushToSeg: function(segArr, dataSeq, segIdx, sIdx, eIdx) {
-        let arrIdx = [];
+    pushToSeg(segArr, dataSeq, segIdx, sIdx, eIdx) {
+        const arrIdx = [];
         for (let k = sIdx; k < eIdx; k++) {
             arrIdx.push(dataSeq[segIdx][k]);
         }
         segArr.push(arrIdx);
     },
-    sortFieldValue: function(sIDX, eIDX, sortOrder, dataField, dataValSeq) {
-        let tmpSeq = [];
+    sortFieldValue(sIDX, eIDX, sortOrder, dataField, dataValSeq) {
+        const tmpSeq = [];
         if ((sortOrder) && (sortOrder !== JV.TAB_FIELD_PROP_SORT_VAL_NOSORT)) {
             if (sIDX >= 0 && eIDX >= sIDX && dataValSeq.length > eIDX) {
                 let reversed = 1;
@@ -40,7 +42,7 @@ let JpcCrossTabHelper = {
                 tmpSeq.sort(function(idx1, idx2) {
                     let rst = 0;
                     // if (isNaN(parseFloat(dataField[idx1])) || isNaN(parseFloat(dataField[idx1]))) {
-                    if (typeof (dataField[idx1]) === 'string' || typeof (dataField[idx1]) === 'string' ) {
+                    if (typeof (dataField[idx1]) === 'string' || typeof (dataField[idx1]) === 'string') {
                         if (dataField[idx1] > dataField[idx2]) {
                             rst = reversed;
                         } else if (dataField[idx1] < dataField[idx2]) {
@@ -64,7 +66,7 @@ let JpcCrossTabHelper = {
         }
         return tmpSeq;
     },
-    checkIfEqual: function(dataFields, seq1, seq2) {
+    checkIfEqual(dataFields, seq1, seq2) {
         let rst = true;
         for (let i = 0; i < dataFields.length; i++) {
             if ((dataFields[i][seq1] !== dataFields[i][seq2])) {
@@ -74,38 +76,40 @@ let JpcCrossTabHelper = {
         }
         return rst;
     },
-    sortTabFields: function(tabFields, fieldSeqs, data_details, dataSeq, $CURRENT_RPT) {
-        let me = this;
-        let sIDX = 0, eIDX = -1, isFirstSort = true;
+    sortTabFields(tabFields, fieldSeqs, data_details, dataSeq, $CURRENT_RPT) {
+        const me = this;
+        let sIDX = 0,
+            eIDX = -1,
+            isFirstSort = true;
         for (let i = 0; i < tabFields.length; i++) {
-            let tabField = tabFields[i];
+            const tabField = tabFields[i];
             if (tabField[JV.TAB_FIELD_PROP_SORT] !== JV.TAB_FIELD_PROP_SORT_VAL_NOSORT) {
                 if (isFirstSort) {
                     isFirstSort = false;
-                    //first field, should sort all data items
+                    // first field, should sort all data items
                     for (let j = 0; j < dataSeq.length; j++) {
                         sIDX = 0;
                         eIDX = dataSeq[j].length - 1;
-                        //sort the field value here
-                        if (typeof(fieldSeqs[i]) === "object") {
-                            let exFirstField = JE.F(fieldSeqs[i][JV.PROP_ID], $CURRENT_RPT);
+                        // sort the field value here
+                        if (typeof (fieldSeqs[i]) === 'object') {
+                            const exFirstField = JE.F(fieldSeqs[i][JV.PROP_ID], $CURRENT_RPT);
                             if (exFirstField) {
                                 me.sortFieldValue(sIDX, eIDX, tabField[JV.TAB_FIELD_PROP_SORT], exFirstField[JV.PROP_AD_HOC_DATA], dataSeq[j]);
                             } else {
-                                //不排序(健壮性)
+                                // 不排序(健壮性)
                             }
                         } else {
-                            me.sortFieldValue(sIDX, eIDX, tabField[JV.TAB_FIELD_PROP_SORT],data_details[fieldSeqs[i]], dataSeq[j]);
+                            me.sortFieldValue(sIDX, eIDX, tabField[JV.TAB_FIELD_PROP_SORT], data_details[fieldSeqs[i]], dataSeq[j]);
                         }
                         // me.sortFieldValue(sIDX, eIDX, tabField[JV.TAB_FIELD_PROP_SORT],data_details[fieldSeqs[i]], dataSeq[j]);
                     }
                 } else {
-                    //then sort the rest fields one by one
+                    // then sort the rest fields one by one
                     for (let j = 0; j < dataSeq.length; j++) {
-                        let chkFields = [];
+                        const chkFields = [];
                         for (let k = 0; k < i; k++) {
-                            if (typeof(fieldSeqs[k]) === "object") {
-                                let exField = JE.F(fieldSeqs[k][JV.PROP_ID], $CURRENT_RPT);
+                            if (typeof (fieldSeqs[k]) === 'object') {
+                                const exField = JE.F(fieldSeqs[k][JV.PROP_ID], $CURRENT_RPT);
                                 if (exField) {
                                     chkFields.push(exField[JV.PROP_AD_HOC_DATA]);
                                 } else {
@@ -122,23 +126,23 @@ let JpcCrossTabHelper = {
                                 eIDX = m - 1;
                             } else if (m == dataSeq[j].length - 1) {
                                 eIDX = m;
-                            };
+                            }
                             if (eIDX >= sIDX) {
                                 if (eIDX != sIDX) {
-                                    if (typeof(fieldSeqs[i]) === "object") {
-                                        let exOtherField = JE.F(fieldSeqs[i][JV.PROP_ID], $CURRENT_RPT);
+                                    if (typeof (fieldSeqs[i]) === 'object') {
+                                        const exOtherField = JE.F(fieldSeqs[i][JV.PROP_ID], $CURRENT_RPT);
                                         if (exOtherField) {
                                             me.sortFieldValue(sIDX, eIDX, tabField[JV.TAB_FIELD_PROP_SORT], exOtherField[JV.PROP_AD_HOC_DATA], dataSeq[j]);
                                         } else {
-                                            //不排序(健壮性)
+                                            // 不排序(健壮性)
                                         }
                                     } else {
-                                        me.sortFieldValue(sIDX, eIDX, tabField[JV.TAB_FIELD_PROP_SORT],data_details[fieldSeqs[i]], dataSeq[j]);
+                                        me.sortFieldValue(sIDX, eIDX, tabField[JV.TAB_FIELD_PROP_SORT], data_details[fieldSeqs[i]], dataSeq[j]);
                                     }
                                     // me.sortFieldValue(sIDX, eIDX, tabField[JV.TAB_FIELD_PROP_SORT],data_details[fieldSeqs[i]], dataSeq[j]);
                                 }
                                 sIDX = m;
-                                eIDX = m - 1; //for protection purpose
+                                eIDX = m - 1; // for protection purpose
                             }
                         }
                     }
@@ -146,48 +150,51 @@ let JpcCrossTabHelper = {
             }
         }
     },
-    getMaxRowsPerPage: function(bands, rptTpl) {
+    getMaxRowsPerPage(bands, rptTpl) {
         let rst = 1;
-        let band = bands[rptTpl[JV.NODE_CROSS_INFO][JV.NODE_CROSS_ROW][JV.PROP_BAND_NAME]];
+        const band = bands[rptTpl[JV.NODE_CROSS_INFO][JV.NODE_CROSS_ROW][JV.PROP_BAND_NAME]];
         if (band) {
-            rst =  getMaxTabCntPerPage(rptTpl, JV.NODE_CROSS_ROW, JV.PROP_CMN_HEIGHT, band.Bottom - band.Top);
+            rst = getMaxTabCntPerPage(rptTpl, JV.NODE_CROSS_ROW, JV.PROP_CMN_HEIGHT, band.Bottom - band.Top);
         }
         return rst;
     },
-    getMaxColsPerPage: function(bands, rptTpl) {
+    getMaxColsPerPage(bands, rptTpl) {
         let rst = 1;
-        let band = bands[rptTpl[JV.NODE_CROSS_INFO][JV.NODE_CROSS_COL][JV.PROP_BAND_NAME]];
+        const band = bands[rptTpl[JV.NODE_CROSS_INFO][JV.NODE_CROSS_COL][JV.PROP_BAND_NAME]];
         if (band) {
-            rst =  getMaxTabCntPerPage(rptTpl, JV.NODE_CROSS_COL, JV.PROP_CMN_WIDTH, band.Right - band.Left);
+            rst = getMaxTabCntPerPage(rptTpl, JV.NODE_CROSS_COL, JV.PROP_CMN_WIDTH, band.Right - band.Left);
         }
         return rst;
     },
-    getActualRowsHeight: function(bands, rptTpl, segments, page) {
+    getActualRowsHeight(bands, rptTpl, segments, page) {
         let rst = 1;
-        let band = bands[rptTpl[JV.NODE_CROSS_INFO][JV.NODE_CROSS_ROW][JV.PROP_BAND_NAME]];
+        const band = bands[rptTpl[JV.NODE_CROSS_INFO][JV.NODE_CROSS_ROW][JV.PROP_BAND_NAME]];
         if (band) {
-            rst =  getActualContentAreaMeasurement(rptTpl, JV.NODE_CROSS_ROW, JV.PROP_CMN_HEIGHT, band.Bottom - band.Top, segments, page);
+            rst = getActualContentAreaMeasurement(rptTpl, JV.NODE_CROSS_ROW, JV.PROP_CMN_HEIGHT, band.Bottom - band.Top, segments, page);
         }
         return rst;
     },
-    getActualColsWidth: function(bands, rptTpl, segments, page) {
+    getActualColsWidth(bands, rptTpl, segments, page) {
         let rst = 1;
-        let band = bands[rptTpl[JV.NODE_CROSS_INFO][JV.NODE_CROSS_COL][JV.PROP_BAND_NAME]];
+        const band = bands[rptTpl[JV.NODE_CROSS_INFO][JV.NODE_CROSS_COL][JV.PROP_BAND_NAME]];
         if (band) {
-            rst =  getActualContentAreaMeasurement(rptTpl, JV.NODE_CROSS_COL, JV.PROP_CMN_WIDTH, band.Right - band.Left, segments, page);
+            rst = getActualContentAreaMeasurement(rptTpl, JV.NODE_CROSS_COL, JV.PROP_CMN_WIDTH, band.Right - band.Left, segments, page);
         }
         return rst;
     },
-    chkTabEnd: function(tabType, rptTpl, bands, sortedSequence, segIdx, preRec, nextRec) {
-        let me = this, rst = true;
-        let remainAmt = preRec + nextRec - sortedSequence[segIdx].length;
+    chkTabEnd(tabType, rptTpl, bands, sortedSequence, segIdx, preRec, nextRec) {
+        let me = this,
+            rst = true;
+        const remainAmt = preRec + nextRec - sortedSequence[segIdx].length;
         rst = me.hasEnoughSpace(tabType, rptTpl, bands, remainAmt);
         return rst;
     },
-    hasEnoughSpace: function (tabType, rptTpl, bands, remainAmt) {
+    hasEnoughSpace(tabType, rptTpl, bands, remainAmt) {
         if (remainAmt < 0) return false;
-        let rst = true, measurement = 1.0, douDiffForCompare = 0.00001;
-        let unitFactor = JpcCommonHelper.getUnitFactor(rptTpl);
+        let rst = true,
+            measurement = 1.0,
+            douDiffForCompare = 0.00001;
+        const unitFactor = JpcCommonHelper.getUnitFactor(rptTpl);
         let band = null;
         if (rptTpl[JV.NODE_CROSS_INFO][tabType]) {
             band = bands[rptTpl[JV.NODE_CROSS_INFO][tabType][JV.PROP_BAND_NAME]];
@@ -195,19 +202,19 @@ let JpcCrossTabHelper = {
         if (band != null && band != undefined) {
             if (tabType === JV.NODE_CROSS_ROW_SUM || tabType === JV.NODE_CROSS_ROW_EXT) {
                 measurement = 1.0 * rptTpl[JV.NODE_CROSS_INFO][JV.NODE_CROSS_ROW][JV.PROP_CMN_HEIGHT] * unitFactor;
-                let spareHeight = measurement * remainAmt;
-                let douH = 1.0 * (band.Bottom - band.Top);
+                const spareHeight = measurement * remainAmt;
+                const douH = 1.0 * (band.Bottom - band.Top);
                 rst = (spareHeight >= douH) || (spareHeight - douH <= douDiffForCompare);
             } else if (tabType === JV.NODE_CROSS_COL_SUM) {
                 measurement = 1.0 * rptTpl[JV.NODE_CROSS_INFO][JV.NODE_CROSS_COL][JV.PROP_CMN_WIDTH] * unitFactor;
-                let spareWidth = measurement * remainAmt;
-                let douW = 1.0 * (band.Right - band.Left);
+                const spareWidth = measurement * remainAmt;
+                const douW = 1.0 * (band.Right - band.Left);
                 rst = (spareWidth >= douW) || (spareWidth - douW <= douDiffForCompare);
             }
         }
         return rst;
     },
-    initialPageStatus: function (pageStatus) {
+    initialPageStatus(pageStatus) {
         pageStatus[JV.STATUS_NORMAL] = true;
         pageStatus[JV.STATUS_REPORT_START] = false;
         pageStatus[JV.STATUS_REPORT_END] = false;
@@ -216,16 +223,16 @@ let JpcCrossTabHelper = {
         pageStatus[JV.STATUS_GROUP] = false;
         pageStatus[JV.STATUS_CROSS_ROW_END] = false;
         pageStatus[JV.STATUS_CROSS_COL_END] = false;
-    }
+    },
 };
 
 function getMaxTabCntPerPage(rptTpl, tabNodeName, tabMeasurePropName, measureForCal) {
     let rst = 1;
     if (rptTpl[JV.NODE_CROSS_INFO][tabNodeName]) {
-        let tab = rptTpl[JV.NODE_CROSS_INFO][tabNodeName];
+        const tab = rptTpl[JV.NODE_CROSS_INFO][tabNodeName];
         let maxFieldMeasure = 1.0;
         if (JV.CAL_TYPE_ABSTRACT === JpcCommonHelper.getPosCalculationType(tab[JV.PROP_CALCULATION])) {
-            let unitFactor = JpcCommonHelper.getUnitFactor(rptTpl);
+            const unitFactor = JpcCommonHelper.getUnitFactor(rptTpl);
             maxFieldMeasure = 1.0 * rptTpl[JV.NODE_CROSS_INFO][tabNodeName][tabMeasurePropName] * unitFactor;
         } else {
             maxFieldMeasure = measureForCal * rptTpl[JV.NODE_CROSS_INFO][tabNodeName][tabMeasurePropName] / JV.HUNDRED_PERCENT;
@@ -234,15 +241,15 @@ function getMaxTabCntPerPage(rptTpl, tabNodeName, tabMeasurePropName, measureFor
     }
     if (rst <= 0) rst = 1;
     return rst;
-};
+}
 
 function getActualContentAreaMeasurement(rptTpl, tabNodeName, tabMeasurePropName, measureForCal, segments, page) {
     let rst = 1;
     if (rptTpl[JV.NODE_CROSS_INFO][tabNodeName]) {
-        let tab = rptTpl[JV.NODE_CROSS_INFO][tabNodeName];
+        const tab = rptTpl[JV.NODE_CROSS_INFO][tabNodeName];
         let maxFieldMeasure = 1.0;
         if (JV.CAL_TYPE_ABSTRACT === JpcCommonHelper.getPosCalculationType(tab[JV.PROP_CALCULATION])) {
-            let unitFactor = JpcCommonHelper.getUnitFactor(rptTpl);
+            const unitFactor = JpcCommonHelper.getUnitFactor(rptTpl);
             maxFieldMeasure = 1.0 * rptTpl[JV.NODE_CROSS_INFO][tabNodeName][tabMeasurePropName] * unitFactor;
         } else {
             maxFieldMeasure = measureForCal * rptTpl[JV.NODE_CROSS_INFO][tabNodeName][tabMeasurePropName] / JV.HUNDRED_PERCENT;
@@ -252,6 +259,6 @@ function getActualContentAreaMeasurement(rptTpl, tabNodeName, tabMeasurePropName
         }
     }
     return rst;
-};
+}
 
-module.exports = JpcCrossTabHelper;
+module.exports = JpcCrossTabHelper;

+ 6 - 3
app/reports/rpt_component/jpc_cross_tab.js

@@ -121,7 +121,6 @@ JpcCrossTabSrv.prototype.createNew = function() {
             const data_details = dataObj[JV.DATA_DETAIL_DATA];
             JpcCrossTabHelper.sortTabFields(fields, rstFieldsIdx, data_details, dataSeq, $CURRENT_RPT);
             // 2. distinguish sort tab fields value
-            let b1 = false;
             for (let i = 0; i < dataSeq.length; i++) {
                 sIDX = 0;
                 const segArr = [];
@@ -129,17 +128,20 @@ JpcCrossTabSrv.prototype.createNew = function() {
                     JpcCrossTabHelper.pushToSeg(segArr, dataSeq, i, 0, 1);
                 } else {
                     for (let j = 1; j < dataSeq[i].length; j++) {
-                        b1 = false;
+                        let b1 = false;
+                        let isOutofDataRange = false;
                         for (let k = 0; k < rstFieldsIdx.length; k++) {
                             if (fields[k].hasOwnProperty(JV.TAB_FIELD_PROP_SORT)) {
                                 // 只有被选择了作为排序字段的才进入排序及优化
                                 if (typeof rstFieldsIdx[k] === 'object') {
                                     const map_data_field = JE.F(rstFieldsIdx[k][JV.PROP_ID], $CURRENT_RPT);
+                                    isOutofDataRange = map_data_field[JV.PROP_AD_HOC_DATA].length <= dataSeq[i][j - 1];
                                     if (map_data_field[JV.PROP_AD_HOC_DATA][dataSeq[i][j - 1]] !== map_data_field[JV.PROP_AD_HOC_DATA][dataSeq[i][j]]) {
                                         b1 = true;
                                         break;
                                     }
                                 } else {
+                                    isOutofDataRange = data_details[rstFieldsIdx[k]].length <= dataSeq[i][j - 1];
                                     if (data_details[rstFieldsIdx[k]][dataSeq[i][j - 1]] !== data_details[rstFieldsIdx[k]][dataSeq[i][j]]) {
                                         b1 = true;
                                         break;
@@ -153,7 +155,8 @@ JpcCrossTabSrv.prototype.createNew = function() {
                             if (j === dataSeq[i].length - 1) {
                                 JpcCrossTabHelper.pushToSeg(segArr, dataSeq, i, j, dataSeq[i].length);
                             }
-                        } else if (j === dataSeq[i].length - 1) {
+                        } else if (j === dataSeq[i].length - 1 && !isOutofDataRange) {
+                            // 还需要判断数据是否出界,如果出界,则不能塞进来
                             JpcCrossTabHelper.pushToSeg(segArr, dataSeq, i, sIDX, dataSeq[i].length);
                         }
                     }