1821349743@qq.com
2023-04-08 0d63f52d84e393204af3ba5bce86bdfddf936be8
src/main/java/com/product/server/report/service/CommonReportService.java
@@ -1,6 +1,8 @@
package com.product.server.report.service;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
@@ -11,7 +13,10 @@
import com.product.core.service.support.AbstractBaseService;
import com.product.core.spring.context.SpringMVCContextHolder;
import com.product.server.report.config.CmnConst;
import com.product.server.report.entity.ReportColumn;
import com.product.server.report.entity.ReportEntity;
import com.product.util.BaseUtil;
import com.product.util.SystemParamReplace;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -28,6 +33,47 @@
public class CommonReportService extends AbstractBaseService {
    @Autowired
    private DataListReportService dataListReportService;
   /**
    * 报表-解析
    *
    * @param recordDte           业务数据dte
    * @param totalStatisticsFlag 是否合计标识
    * @param reportConfigMap     报表配置缓存map
    * @param tableStyle
    * @return
    */
   public ReportEntity getReportEntity(DataTableEntity recordDte, String totalName, Map<Integer, List<JSONObject>> reportConfigMap) {
      ReportEntity report = null;
      Map<String, Set<String>> headAndTailTitleDataMap = Maps.newHashMap();
      // 数据区
      report = getDataArea(reportConfigMap, headAndTailTitleDataMap, recordDte, totalName);
      int totalColCount = reportConfigMap.get(0).size();
      // 头部标题区
      List<List<ReportColumn>> headTitleRows = null;
      if (!reportConfigMap.get(1).isEmpty()) {
         headTitleRows = dataListReportService.getTitle(reportConfigMap.get(1), totalColCount, headAndTailTitleDataMap, "head");
      }
      // 底部标题区
      List<List<ReportColumn>> tailTitleRows = null;
      if (!reportConfigMap.get(3).isEmpty()) {
         tailTitleRows = dataListReportService.getTitle(reportConfigMap.get(3), totalColCount, headAndTailTitleDataMap, "tail");
      }
      if (!CollectionUtil.isEmpty(headTitleRows)) {
         List<List<ReportColumn>> reportHeader = report.getReportHeader();
         headTitleRows.addAll(reportHeader);
         report.setReportHeader(headTitleRows);
      }
      if (!CollectionUtil.isEmpty(tailTitleRows)) {
         report.setReportTail(tailTitleRows);
      }
      return report;
   }
    /**
     * 报表-解析
@@ -101,6 +147,346 @@
        dataAreaHtml.append(getDataAreaDataHtml(dataAreaFieldConfigMap, recordDte, headAndTailTitleDataMap, headAndTailFieldSet, statisticsMap, totalName));
        return dataAreaHtml.toString();
    }
   private ReportEntity getDataArea(Map<Integer, List<JSONObject>> reportConfigMap, Map<String, Set<String>> headAndTailTitleDataMap, DataTableEntity recordDte, String totalName) {
      // 数据区字段缓存map
      Map<String, JSONObject> dataAreaFieldConfigMap = dataListReportService.groupAndDataJSONObject2Map(reportConfigMap.get(0));
      // 获取指定数据集中包含的数据区字段集合
      Set<String> headAndTailFieldSet = Sets.newHashSet();
      headAndTailFieldSet.addAll(dataListReportService.getDataFields(reportConfigMap.get(1)));
      headAndTailFieldSet.addAll(dataListReportService.getDataFields(reportConfigMap.get(3)));
      // 统计map
      Map<JSONObject, JSONObject> statisticsMap = Maps.newLinkedHashMap();
      List<ReportColumn> reportHeader = getReportHeader(dataAreaFieldConfigMap);
      List<List<ReportColumn>> reportData = getReportData(dataAreaFieldConfigMap, recordDte, headAndTailTitleDataMap, headAndTailFieldSet, statisticsMap, totalName);
      ReportEntity report = new ReportEntity();
      report.addReportHeader(reportHeader);
      report.setReportData(reportData);
      return report;
   }
   private List<ReportColumn> getReportHeader(Map<String, JSONObject> dataAreaFieldConfigMap) {
      if (CollectionUtil.isEmpty(dataAreaFieldConfigMap)) {
         return null;
      }
      List<ReportColumn> reportColumnList = new ArrayList<>();
      dataAreaFieldConfigMap.forEach((k, v) -> {
         ReportColumn column = new ReportColumn();
         column.setContent(v.getString(CmnConst.ATTR_SHOW_NAME));
         column.setColumnWidth(NumberUtil.isNumber(v.getString(CmnConst.ATTR_WIDTH)) ? NumberUtil.parseInt(v.getString(CmnConst.ATTR_WIDTH)) : 0);
         reportColumnList.add(column);
      });
      return reportColumnList;
   }
   private List<List<ReportColumn>> getReportData(Map<String, JSONObject> dataAreaFieldConfigMap, DataTableEntity recordDte, Map<String, Set<String>> headAndTailTitleDataMap, Set<String> headAndTailFieldSet, Map<JSONObject, JSONObject> statisticsMap, String totalName) {
      List<List<ReportColumn>> reportData = new ArrayList<>();
      // 数据区分组统计字段名称list
      List<String> dataAreaGroupStatisticsFieldNameList = Lists.newArrayList();
      // 数据区分组字段名称list
      List<String> dataAreaGroupFieldNameList = Lists.newArrayList();
      dataAreaFieldConfigMap.forEach((dataAreaFieldName, dataAreaFieldConfigObj) -> {
         if ("1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_GROUP))) {
            dataAreaGroupFieldNameList.add(dataAreaFieldName);
            if ("1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_STATISTICS))) {
               dataAreaGroupStatisticsFieldNameList.add(dataAreaFieldName);
            }
         }
      });
      FieldSetEntity recordFse;
      FieldSetEntity preFse = null;
      String dataAreaFieldName;
      JSONObject dataAreaFieldConfigObj;
      String value;
      JSONObject keyObj;
      Map<String, String> replaceMap = Maps.newHashMap();
      Map<String, String> dataAreaClosestGroupStatisticsFieldValueMap = Maps.newHashMap();
      Map<String, String> dataAreaClosestGroupFieldValueMap = Maps.newHashMap();
      String closestGroupStatisticsFieldName = null;
      String closestGroupFieldName = null;
      String tempFieldName;
      String paramKey;
      boolean combineFlag;
      JSONObject dataAreaGroupFieldRecordObj = new JSONObject();
      for (int i = 0; i < recordDte.getRows(); i++) {
         recordFse = recordDte.getFieldSetEntity(i);
         // 获取头部、尾部标题区数据字段
         dataListReportService.getHeadAndTailTitleDataMap(headAndTailTitleDataMap, headAndTailFieldSet, recordFse);
         combineFlag = true;
         List<ReportColumn> columns = new ArrayList<>();
         for (Map.Entry<String, JSONObject> entry : dataAreaFieldConfigMap.entrySet()) {
            ReportColumn column = new ReportColumn();
            dataAreaFieldName = entry.getKey();
            dataAreaFieldConfigObj = entry.getValue();
            value = dataListReportService.getValue(dataAreaFieldConfigObj, recordFse, dataAreaFieldName);
            // 若是自定义字段,则放入业务数据记录中
            if ("1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_CUSTOM_FIELD))) {
               recordFse.setValue(dataAreaFieldName, value);
            }
            if (dataAreaGroupFieldNameList.contains(dataAreaFieldName)) {
               int curFieldIndex = dataAreaGroupFieldNameList.indexOf(dataAreaFieldName);
               // 记录分组字段
               recordDataAreaGroupField(dataAreaGroupFieldRecordObj, dataAreaGroupFieldNameList, curFieldIndex, recordFse);
               // 分组合字段并
               closestGroupFieldName = dataAreaFieldName;
               if (preFse != null && combineFlag) {
                  if (value.equals(dataAreaClosestGroupFieldValueMap.get(closestGroupFieldName))) {
                     dealReplaceMapAddRowspan(replaceMap, dataAreaGroupFieldNameList.subList(0, curFieldIndex + 1), preFse, true);
                     continue;
                  } else {
                     combineFlag = false;
                  }
               }
               dataAreaClosestGroupFieldValueMap.put(dataAreaFieldName, value);
            }
            // 分组统计
            if (dataAreaGroupStatisticsFieldNameList.contains(dataAreaFieldName)) {
               int minK = dataAreaGroupStatisticsFieldNameList.size();
               for (int j = 0; j < dataAreaGroupStatisticsFieldNameList.size(); j++) {
                  tempFieldName = dataAreaGroupStatisticsFieldNameList.get(j);
                  if (!StringUtils.isEmpty(dataAreaClosestGroupStatisticsFieldValueMap.get(tempFieldName)) && !recordFse.getString(tempFieldName).equals(dataAreaClosestGroupStatisticsFieldValueMap.get(tempFieldName))) {
                     minK = j;
                     break;
                  }
               }
               for (int k = dataAreaGroupStatisticsFieldNameList.size() - 1; k >= minK; k--) {
                  tempFieldName = dataAreaGroupStatisticsFieldNameList.get(k);
                  if (preFse != null && dataAreaClosestGroupStatisticsFieldValueMap.get(tempFieldName) != null) {
                     reportData.add(getDataAreaGroupStatisticsFieldStatisticsRow(dataAreaClosestGroupStatisticsFieldValueMap.get(tempFieldName), statisticsMap, dataAreaFieldConfigMap, tempFieldName, preFse, dataAreaGroupFieldNameList, replaceMap, dataAreaGroupFieldRecordObj));
                     dataAreaClosestGroupStatisticsFieldValueMap.remove(tempFieldName);
                  }
               }
               closestGroupStatisticsFieldName = dataAreaFieldName;
               dataAreaClosestGroupStatisticsFieldValueMap.put(dataAreaFieldName, value);
            }
            // 非分组统计字段(普通+自定义)
            if (!"1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_GROUP)) && !StringUtils.isEmpty(dataAreaFieldConfigObj.getString(CmnConst.ATTR_STATISTICS))) {
               addStatisticsRowInfo(statisticsMap, dataAreaGroupStatisticsFieldNameList, recordFse, dataAreaFieldConfigObj, dataAreaFieldName, value);
            }
            // 自定义统计字段(未指定统计类型,使用基础字段公式进行计算)
            if ("1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_CUSTOM_FIELD))
                  && StringUtils.isEmpty(dataAreaFieldConfigObj.getString(CmnConst.ATTR_STATISTICS))
                  && !StringUtils.isEmpty(dataAreaFieldConfigObj.getString(CmnConst.ATTR_FORMULA))) {
               String formula = dataAreaFieldConfigObj.getString(CmnConst.ATTR_FORMULA);
               List<String> formFieldList = dataListReportService.getSuitContent(formula, CmnConst.REGEXP_FORM_FIELD);
               Map<String, String> formulaMap = Maps.newHashMap();
               boolean statisticsFlag = true;
               JSONObject tempObj;
               for (String formFieldInfo : formFieldList) {
                  tempObj = dataAreaFieldConfigMap.get(dataListReportService.fieldInfo2FieldName(formFieldInfo));
                  if (tempObj == null || StringUtils.isEmpty(tempObj.getString(CmnConst.ATTR_STATISTICS))) {
                     statisticsFlag = false;
                     break;
                  }
                  formulaMap.put(formFieldInfo, tempObj.getString(CmnConst.ATTR_STATISTICS));
               }
               if (statisticsFlag) {
                  addStatisticsRowInfo(statisticsMap, dataAreaGroupStatisticsFieldNameList, recordFse, dataAreaFieldConfigObj, dataAreaFieldName, value, formulaMap);
               }
            }
            if ("1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_GROUP))) {
               keyObj = new JSONObject();
               for (String dataAreaGroupFieldName : dataAreaGroupFieldNameList) {
                  keyObj.put(dataAreaGroupFieldName, recordFse.getString(dataAreaGroupFieldName));
                  if (dataAreaGroupFieldName.equals(dataAreaFieldName)) {
                     keyObj.put(CmnConst.ATTR_FIELD_INFO, dataListReportService.fieldName2FieldInfo(dataAreaGroupFieldName));
                     break;
                  }
               }
               paramKey = dataListReportService.concat(keyObj, CmnConst.ATTR_ROWSPAN);
               column.setRowspan(NumberUtil.parseInt(paramKey));
               replaceMap.put(paramKey, "1");
            }
            // class
            if (!StringUtils.isEmpty(dataAreaFieldConfigObj.getString(CmnConst.ATTR_URL))) {
               //子报表
               String url = dataAreaFieldConfigObj.getString(CmnConst.ATTR_URL);
               url = SystemParamReplace.replaceParams(url, recordFse);
               column.setSubReport("true".equals(dataAreaFieldConfigObj.getString("~isSubReport~")));
               if (!column.isSubReport()) {
                  column.setPenetrate(true);
                  column.setPenetrateProperty(url);
               } else {
                  column.setSubReportProperty(url);
               }
            }
            String attrValue = recordFse.getString(dataAreaFieldName + CmnConst.PROMPT_REAL_VALUE_TAIL);
            if (StringUtils.isEmpty(attrValue)) {
               attrValue = recordFse.getString(dataAreaFieldName);
            }
            column.addProperty(dataAreaFieldName, attrValue);
            // 格式
            value = dataListReportService.formatValue(dataAreaFieldConfigObj, value);
            column.setContent(value);
            columns.add(column);
         }
         reportData.add(columns);
         preFse = recordFse;
      }
      // 补全末尾统计
      if (!StringUtils.isEmpty(closestGroupStatisticsFieldName)) {
         int maxK = -1;
         for (int j = 0; j < dataAreaGroupStatisticsFieldNameList.size(); j++) {
            tempFieldName = dataAreaGroupStatisticsFieldNameList.get(j);
            if (closestGroupStatisticsFieldName.equals(tempFieldName)) {
               maxK = j;
            }
         }
         for (int k = maxK; k >= 0; k--) {
            tempFieldName = dataAreaGroupStatisticsFieldNameList.get(k);
            if (preFse != null) {
               reportData.add(getDataAreaGroupStatisticsFieldStatisticsRow(dataAreaClosestGroupStatisticsFieldValueMap.get(tempFieldName), statisticsMap, dataAreaFieldConfigMap, tempFieldName, preFse, dataAreaGroupFieldNameList, replaceMap, dataAreaGroupFieldRecordObj));
            }
         }
      }
      // 总计
      if (!StringUtils.isEmpty(totalName)) {
         reportData.add(getDataAreaTotalStatistics(statisticsMap, dataAreaFieldConfigMap, dataAreaGroupFieldNameList, preFse, dataAreaGroupFieldRecordObj, totalName));
      }
      for (Map.Entry<String, String> entry : replaceMap.entrySet()) {
         reportData.stream().forEach(item -> {
            item.stream().forEach(column -> {
               column.replace(entry.getKey(), entry.getValue());
            });
         });
      }
      return reportData;
   }
   /**
    * 获取总计行
    *
    * @param statisticsMap               统计map
    * @param dataAreaFieldConfigMap      数据区字段缓存map
    * @param dataAreaGroupFieldNameList  数据区分组字段名称list
    * @param preFse                      最近操作的数据fse
    * @param dataAreaGroupFieldRecordObj 数据区分组字段记录obj
    * @param totalName                   总计名称
    * @return
    */
   private List<ReportColumn> getDataAreaTotalStatistics(Map<JSONObject, JSONObject> statisticsMap, Map<String, JSONObject> dataAreaFieldConfigMap, List<String> dataAreaGroupFieldNameList, FieldSetEntity preFse, JSONObject dataAreaGroupFieldRecordObj, String totalName) {
      List<ReportColumn> columns = new ArrayList<>();
//      StringBuilder html = new StringBuilder(512);
      String dataAreaFieldName;
      JSONObject dataAreaFieldConfigObj;
      String value;
      JSONObject keyObj = new JSONObject();
      String statisticsType;
//      html.append("\n<tr class=\"").append(CmnConst.CLASS_TR_DATA_STATISTICS).append("\">\n    ");
      if (preFse == null) {
         return null;
      }
      int index = 0;
      for (Map.Entry<String, JSONObject> entry : dataAreaFieldConfigMap.entrySet()) {
         ReportColumn column = new ReportColumn();
         index++;
         dataAreaFieldName = entry.getKey();
         if (!dataAreaGroupFieldNameList.contains(dataAreaFieldName)) {
            dataAreaFieldConfigObj = entry.getValue();
            statisticsType = dataAreaFieldConfigObj.getString(CmnConst.ATTR_STATISTICS);
            keyObj.put(CmnConst.ATTR_FIELD_INFO, dataAreaFieldConfigObj.getString(CmnConst.ATTR_FIELD_INFO));
            if ((!"1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_CUSTOM_FIELD)) && StringUtils.isEmpty(statisticsType)) || statisticsMap.get(keyObj) == null) {
               value = "";
            } else {
               JSONObject valueObj = statisticsMap.get(keyObj);
               if (StringUtils.isEmpty(statisticsType)) {
                  statisticsType = CmnConst.ATTR_STATISTICS_DEFAULT;
               }
               if (CmnConst.ATTR_STATISTICS_AVG.equals(statisticsType) && "1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_AVG_TYPE))) {
                  int subCnt = dataAreaGroupFieldRecordObj.size();
                  valueObj.put(CmnConst.ATTR_STATISTICS_SUB_CNT, subCnt);
                  dataListReportService.getAvgValue(valueObj, dataAreaFieldConfigObj, false);
               }
               value = valueObj.getString(statisticsType);
            }
            // 格式
            value = dataListReportService.formatValue(dataAreaFieldConfigObj, value);
            column.setContent(value);
//            html.append("<td>").append(value == null ? "" : value).append("</td>");
         } else {
            if (index == 1) {
               column.setColspan(dataAreaGroupFieldNameList.size());
               column.setContent(totalName);
//               html.append("<td colspan=\"").append(dataAreaGroupFieldNameList.size()).append("\">").append(totalName).append("</td>");
            }
         }
         columns.add(column);
      }
//      html.append("\n</tr>");
      return columns;
   }
   private List<ReportColumn> getDataAreaGroupStatisticsFieldStatisticsRow(String waitStatisticsValue, Map<JSONObject, JSONObject> statisticsMap, Map<String, JSONObject> dataAreaFieldConfigMap,
                                                         String tempFieldName, FieldSetEntity recordFse, List<String> dataAreaGroupFieldNameList, Map<String, String> replaceMap, JSONObject dataAreaGroupFieldRecordObj) {
      List<ReportColumn> columns = new ArrayList<>();
//      StringBuilder html = new StringBuilder();
//      html.append("\n<tr class=\"").append(CmnConst.CLASS_TR_DATA_STATISTICS).append("\">\n    ");
      String dataAreaFieldName;
      JSONObject dataAreaFieldConfigObj;
      boolean flag = false;
      JSONObject keyObj = new JSONObject();
      String value;
      String statisticsType;
      int index = 0;
      List<String> needAddRowspanDataAreaGroupFieldNameList = Lists.newArrayList();
      for (Map.Entry<String, JSONObject> entry : dataAreaFieldConfigMap.entrySet()) {
         ReportColumn column = new ReportColumn();
         index++;
         dataAreaFieldName = entry.getKey();
         if (!flag) {
            if (dataAreaGroupFieldNameList.contains(dataAreaFieldName)) {
               keyObj.put(dataAreaFieldName, recordFse.getString(dataAreaFieldName));
               if (dataAreaFieldName.equals(tempFieldName)) {
                  column.setColspan(dataAreaGroupFieldNameList.size() - index + 1);
                  column.setContent(waitStatisticsValue + CmnConst.STATISTICS_NAME);
               }
               if (!flag) {
                  needAddRowspanDataAreaGroupFieldNameList.add(dataAreaFieldName);
               }
            }
         } else {
            dataAreaFieldConfigObj = entry.getValue();
            statisticsType = dataAreaFieldConfigObj.getString(CmnConst.ATTR_STATISTICS);
            if (!"1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_CUSTOM_FIELD)) && StringUtils.isEmpty(statisticsType)) {
               if (!"1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_GROUP))) {
//                  html.append("<td></td>");
               }
            } else {
               keyObj.put(CmnConst.ATTR_FIELD_INFO, dataListReportService.fieldName2FieldInfo(dataAreaFieldName));
               if (statisticsMap.get(keyObj) == null) {
                  value = "";
               } else {
                  JSONObject valueObj = statisticsMap.get(keyObj);
                  if (StringUtils.isEmpty(statisticsType)) {
                     statisticsType = CmnConst.ATTR_STATISTICS_DEFAULT;
                  }
                  if (CmnConst.ATTR_STATISTICS_AVG.equals(statisticsType) && "1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_AVG_TYPE))) {
                     int subCnt = getAimSubCnt(keyObj, dataAreaGroupFieldNameList, dataAreaGroupFieldRecordObj);
                     valueObj.put(CmnConst.ATTR_STATISTICS_SUB_CNT, subCnt);
                     dataListReportService.getAvgValue(valueObj, dataAreaFieldConfigObj, false);
                  }
                  value = valueObj.getString(statisticsType);
               }
               // 格式
               value = dataListReportService.formatValue(dataAreaFieldConfigObj, value);
               column.setContent(value);
//               html.append("<td>").append(value == null ? "" : value).append("</td>");
            }
         }
         columns.add(column);
      }
//      html.append("\n</tr>");
      dealReplaceMapAddRowspan(replaceMap, needAddRowspanDataAreaGroupFieldNameList, recordFse, false);
      return null;
   }
    /**
     * 获取标题
@@ -305,6 +691,7 @@
    /**
     * 添加分组统计信息
    *
     * @param statisticsMap                         统计map
     * @param dataAreaGroupStatisticsFieldNameList  数据区分组统计字段名称list
     * @param recordFse                             业务数据fse
@@ -338,12 +725,14 @@
            statisticsMap.put(keyObj, dataListReportService.getStatisticsValueObj(valueObj, dataAreaFieldConfigObj, statisticsValue, statisticsType, true));
        }
    }
    private void addStatisticsRowInfo(Map<JSONObject, JSONObject> statisticsMap, List<String> dataAreaGroupStatisticsFieldNameList, FieldSetEntity recordFse, JSONObject dataAreaFieldConfigObj, String dataAreaFieldName, String value) {
        addStatisticsRowInfo(statisticsMap, dataAreaGroupStatisticsFieldNameList, recordFse, dataAreaFieldConfigObj, dataAreaFieldName, value, null);
    }
    /**
     * 获取统计行的公式计算值
    *
     * @param statisticsMap         统计map
     * @param formulaMap            公式map
     * @param formulaFieldKeyObj    公式字段keyobj