1821349743@qq.com
2023-04-03 3df221b0a98cde4562471727a6ad41ffafbe39a8
src/main/java/com/product/server/report/service/DataListReportService.java
@@ -42,1648 +42,1650 @@
 */
@Component
public class DataListReportService extends AbstractBaseService {
    @Autowired
    private BaseDao baseDao;
    @Autowired
    private GroupReportService groupReportService;
    @Autowired
    private CommonReportService commonReportService;
    @Autowired
    private QueryFilterService queryFilterService;
    @Autowired
    private RouterService routerService;
   @Autowired
   private BaseDao baseDao;
   @Autowired
   private GroupReportService groupReportService;
   @Autowired
   private CommonReportService commonReportService;
   @Autowired
   private QueryFilterService queryFilterService;
   @Autowired
   private RouterService routerService;
    /**
     * 加载所有缓存
     */
    public void setAllConfig() {
        DataTableEntity reportTypeDte = DataPoolCacheImpl.getInstance().getCacheData(CmnConst.CACHE_REPORT_TYPE);
        if (BaseUtil.dataTableIsEmpty(reportTypeDte)) {
            return;
        }
        List<String> dataListUUIDList = Lists.newArrayList();
        FieldSetEntity fse;
        for (int i = 0; i < reportTypeDte.getRows(); i++) {
            fse = reportTypeDte.getFieldSetEntity(i);
            if ("DataList".equals(fse.getString(CmnConst.TYPE_GROUP))) {
                dataListUUIDList.add(fse.getUUID());
            }
        }
        DataTableEntity reportConfigDte = DataPoolCacheImpl.getInstance().getCacheData(CmnConst.CACHE_REPORT_CONFIG);
        if (reportConfigDte == null) {
            return;
        }
        for (int i = 0; i < reportConfigDte.getRows(); i++) {
            fse = reportConfigDte.getFieldSetEntity(i);
            try {
                if (!dataListUUIDList.contains(fse.getString(CmnConst.TYPE_UUID)) || (StringUtils.isEmpty(fse.getString(CmnConst.FUNCTION_UUID)) && !"1".equals(fse.getString(CmnConst.RELATE_FLAG)))) {
                    continue;
                }
                setConfig(fse.getUUID());
            } catch (Exception e) {
                logger.error(ReportCode.GET_REPORT_CONFIG_FIAL.getText() + ": " + fse.getUUID(), e);
            }
        }
    }
   /**
    * 加载所有缓存
    */
   public void setAllConfig() {
      DataTableEntity reportTypeDte = DataPoolCacheImpl.getInstance().getCacheData(CmnConst.CACHE_REPORT_TYPE);
      if (BaseUtil.dataTableIsEmpty(reportTypeDte)) {
         return;
      }
      List<String> dataListUUIDList = Lists.newArrayList();
      FieldSetEntity fse;
      for (int i = 0; i < reportTypeDte.getRows(); i++) {
         fse = reportTypeDte.getFieldSetEntity(i);
         if ("DataList".equals(fse.getString(CmnConst.TYPE_GROUP))) {
            dataListUUIDList.add(fse.getUUID());
         }
      }
      DataTableEntity reportConfigDte = DataPoolCacheImpl.getInstance().getCacheData(CmnConst.CACHE_REPORT_CONFIG);
      if (reportConfigDte == null) {
         return;
      }
      for (int i = 0; i < reportConfigDte.getRows(); i++) {
         fse = reportConfigDte.getFieldSetEntity(i);
         try {
            if (!dataListUUIDList.contains(fse.getString(CmnConst.TYPE_UUID)) || (StringUtils.isEmpty(fse.getString(CmnConst.FUNCTION_UUID)) && !"1".equals(fse.getString(CmnConst.RELATE_FLAG)))) {
               continue;
            }
            setConfig(fse.getUUID());
         } catch (Exception e) {
            logger.error(ReportCode.GET_REPORT_CONFIG_FIAL.getText() + ": " + fse.getUUID(), e);
         }
      }
   }
    /**
     * 设置报表加载缓存
     *
     * @param reportConfigUUID 报表配置UUID
     */
    public void setConfig(String reportConfigUUID) {
        // 属性获取
        StringBuilder sql = new StringBuilder(128);
        sql.append("select report_area report_area,cell_position_y y,cell_position_x x,attribute_name name,report_type_attr_value value")
                .append("\nfrom (")
                .append("\n    select report_area,cell_position_y,cell_position_x,report_type_attr_value,report_type_attr FROM product_sys_report_config_attribute ca")
                .append("\n    where report_config_uuid=?")
                .append("\n) ca")
                .append("\nleft join (")
                .append("\n    select uuid,attribute_name FROM product_sys_report_type_attribute where type_group='DataList'")
                .append("\n) ta on ca.report_type_attr=ta.uuid")
                .append("\nwhere ta.attribute_name is not null")
                .append("\norder by report_area,cell_position_y,cell_position_x");
        DataTableEntity attrDte = baseDao.listTable(sql.toString(), new Object[]{reportConfigUUID});
        if (BaseUtil.dataTableIsEmpty(attrDte)) {
            throw new BaseException(ReportCode.SET_REPORT_CACHE_FAIL.getValue(), ReportCode.SET_REPORT_CACHE_FAIL.getText());
        }
   /**
    * 设置报表加载缓存
    *
    * @param reportConfigUUID 报表配置UUID
    */
   public void setConfig(String reportConfigUUID) {
      // 属性获取
      StringBuilder sql = new StringBuilder(128);
      sql.append("select report_area report_area,cell_position_y y,cell_position_x x,attribute_name name,report_type_attr_value value")
            .append("\nfrom (")
            .append("\n    select report_area,cell_position_y,cell_position_x,report_type_attr_value,report_type_attr FROM product_sys_report_config_attribute ca")
            .append("\n    where report_config_uuid=?")
            .append("\n) ca")
            .append("\nleft join (")
            .append("\n    select uuid,attribute_name FROM product_sys_report_type_attribute where type_group='DataList'")
            .append("\n) ta on ca.report_type_attr=ta.uuid")
            .append("\nwhere ta.attribute_name is not null")
            .append("\norder by report_area,cell_position_y,cell_position_x");
      DataTableEntity attrDte = baseDao.listTable(sql.toString(), new Object[]{reportConfigUUID});
      if (BaseUtil.dataTableIsEmpty(attrDte)) {
         throw new BaseException(ReportCode.SET_REPORT_CACHE_FAIL.getValue(), ReportCode.SET_REPORT_CACHE_FAIL.getText());
      }
        // 生成obj,放入map,统计分组表头区行数
        FieldSetEntity attrFse;
        Map<Integer, List<JSONObject>> reportConfigMap = Maps.newHashMap();
        List<JSONObject> areaList;
        JSONObject fieldConfigObj;
        int reportArea;
        int x;
        int y;
        int preX = -1;
        int preY = -1;
        int groupAreaRowCount = 0;
        for (int i = 0; i < attrDte.getRows(); i++) {
            attrFse = attrDte.getFieldSetEntity(i);
            if (attrFse.getInteger(CmnConst.ATTR_REPORT_AREA) == null) {
                continue;
            }
            reportArea = attrFse.getInteger(CmnConst.ATTR_REPORT_AREA);
            areaList = reportConfigMap.computeIfAbsent(reportArea, k -> Lists.newArrayList());
            x = attrFse.getInteger(CmnConst.ATTR_X);
            y = attrFse.getInteger(CmnConst.ATTR_Y);
            if (preX != x || preY != y) {
                fieldConfigObj = new JSONObject();
                areaList.add(fieldConfigObj);
            } else {
                fieldConfigObj = areaList.get(areaList.size() - 1);
            }
            fieldConfigObj.put(attrFse.getString(CmnConst.ATTR_NAME), attrFse.getString(CmnConst.ATTR_VALUE));
            fieldConfigObj.put(CmnConst.ATTR_X, x);
            fieldConfigObj.put(CmnConst.ATTR_Y, y);
            fieldConfigObj.put(CmnConst.ATTR_REPORT_AREA, reportArea);
            if (reportArea == 2) {
                groupAreaRowCount = Math.max(groupAreaRowCount, y);
            }
            preX = x;
            preY = y;
        }
      // 生成obj,放入map,统计分组表头区行数
      FieldSetEntity attrFse;
      Map<Integer, List<JSONObject>> reportConfigMap = Maps.newHashMap();
      List<JSONObject> areaList;
      JSONObject fieldConfigObj;
      int reportArea;
      int x;
      int y;
      int preX = -1;
      int preY = -1;
      int groupAreaRowCount = 0;
      for (int i = 0; i < attrDte.getRows(); i++) {
         attrFse = attrDte.getFieldSetEntity(i);
         if (attrFse.getInteger(CmnConst.ATTR_REPORT_AREA) == null) {
            continue;
         }
         reportArea = attrFse.getInteger(CmnConst.ATTR_REPORT_AREA);
         areaList = reportConfigMap.computeIfAbsent(reportArea, k -> Lists.newArrayList());
         x = attrFse.getInteger(CmnConst.ATTR_X);
         y = attrFse.getInteger(CmnConst.ATTR_Y);
         if (preX != x || preY != y) {
            fieldConfigObj = new JSONObject();
            areaList.add(fieldConfigObj);
         } else if (areaList.size() > 0) {
            fieldConfigObj = areaList.get(areaList.size() - 1);
         } else {
            continue;
         }
         fieldConfigObj.put(attrFse.getString(CmnConst.ATTR_NAME), attrFse.getString(CmnConst.ATTR_VALUE));
         fieldConfigObj.put(CmnConst.ATTR_X, x);
         fieldConfigObj.put(CmnConst.ATTR_Y, y);
         fieldConfigObj.put(CmnConst.ATTR_REPORT_AREA, reportArea);
         if (reportArea == 2) {
            groupAreaRowCount = Math.max(groupAreaRowCount, y);
         }
         preX = x;
         preY = y;
      }
        // 清理空格
        List<JSONObject> valueList;
        JSONObject tempObj;
        for (Map.Entry<Integer, List<JSONObject>> entry : reportConfigMap.entrySet()) {
            valueList = entry.getValue();
            for (int i = valueList.size() - 1; i >= 0; i--) {
                tempObj = valueList.get(i);
                if (StringUtils.isEmpty(tempObj.getString(CmnConst.ATTR_FIELD_INFO))) {
                    valueList.remove(i);
                }
            }
        }
      // 清理空格
      List<JSONObject> valueList;
      JSONObject tempObj;
      for (Map.Entry<Integer, List<JSONObject>> entry : reportConfigMap.entrySet()) {
         valueList = entry.getValue();
         for (int i = valueList.size() - 1; i >= 0; i--) {
            tempObj = valueList.get(i);
            if (StringUtils.isEmpty(tempObj.getString(CmnConst.ATTR_FIELD_INFO))) {
               valueList.remove(i);
            }
         }
      }
        // 提取数据区分组字段名称list,对数据区字段obj放入数据区分组字段
        List<JSONObject> dataAreaReportConfigList = reportConfigMap.get(0);
        String fieldName;
        ArrayList<String> dataAreaGroupFieldNameList = Lists.newArrayList();
        if (dataAreaReportConfigList != null) {
            for (int i = 0; i < dataAreaReportConfigList.size(); i++) {
                tempObj = dataAreaReportConfigList.get(i);
                fieldName = fieldInfo2FieldName(tempObj.getString(CmnConst.ATTR_FIELD_INFO));
                if (!dataAreaGroupFieldNameList.isEmpty()) {
                    tempObj.put(CmnConst.ATTR_DATA_AREA_GROUP_FIELD, dataAreaGroupFieldNameList.clone());
                }
                fieldConfigObj = new JSONObject();
                fieldConfigObj.put(fieldName, tempObj);
                dataAreaReportConfigList.set(i, fieldConfigObj);
                if ("1".equals(tempObj.getString(CmnConst.ATTR_IS_GROUP))) {
                    dataAreaGroupFieldNameList.add(fieldName);
                }
            }
        }
      // 提取数据区分组字段名称list,对数据区字段obj放入数据区分组字段
      List<JSONObject> dataAreaReportConfigList = reportConfigMap.get(0);
      String fieldName;
      ArrayList<String> dataAreaGroupFieldNameList = Lists.newArrayList();
      if (dataAreaReportConfigList != null) {
         for (int i = 0; i < dataAreaReportConfigList.size(); i++) {
            tempObj = dataAreaReportConfigList.get(i);
            fieldName = fieldInfo2FieldName(tempObj.getString(CmnConst.ATTR_FIELD_INFO));
            if (!dataAreaGroupFieldNameList.isEmpty()) {
               tempObj.put(CmnConst.ATTR_DATA_AREA_GROUP_FIELD, dataAreaGroupFieldNameList.clone());
            }
            fieldConfigObj = new JSONObject();
            fieldConfigObj.put(fieldName, tempObj);
            dataAreaReportConfigList.set(i, fieldConfigObj);
            if ("1".equals(tempObj.getString(CmnConst.ATTR_IS_GROUP))) {
               dataAreaGroupFieldNameList.add(fieldName);
            }
         }
      }
        // 提取分组表头区分组字段名称list,对分组表头区字段obj放入数据区分组字段、分组表头区分组字段
        List<JSONObject> groupAreaReportConfigList = reportConfigMap.get(2);
        ArrayList<String> groupAreaGroupFieldNameList = Lists.newArrayList();
        JSONObject dataAreaFieldConfigOuterObj;
        JSONObject dataAreaFieldConfigInnerObj;
        JSONObject groupAreaFieldConfigInnerObj;
        if (groupAreaReportConfigList != null) {
            for (int i = 0; i < groupAreaReportConfigList.size(); i++) {
                tempObj = groupAreaReportConfigList.get(i);
                fieldName = fieldInfo2FieldName(tempObj.getString(CmnConst.ATTR_FIELD_INFO));
                if (!dataAreaGroupFieldNameList.isEmpty()) {
                    tempObj.put(CmnConst.ATTR_DATA_AREA_GROUP_FIELD, dataAreaGroupFieldNameList);
                }
                if (!groupAreaGroupFieldNameList.isEmpty()) {
                    tempObj.put(CmnConst.ATTR_GROUP_AREA_GROUP_FIELD, groupAreaGroupFieldNameList.clone());
                }
                fieldConfigObj = new JSONObject();
                fieldConfigObj.put(fieldName, tempObj);
                groupAreaReportConfigList.set(i, fieldConfigObj);
                if ("1".equals(tempObj.getString(CmnConst.ATTR_IS_GROUP))) {
                    groupAreaGroupFieldNameList.add(fieldName);
                }
                // 添加数据区的分组表头区分组字段
                if (dataAreaReportConfigList != null) {
                    for (int j = 0; j < dataAreaReportConfigList.size(); j++) {
                        dataAreaFieldConfigOuterObj = dataAreaReportConfigList.get(j);
                        dataAreaFieldConfigInnerObj = (JSONObject) dataAreaFieldConfigOuterObj.entrySet().iterator().next().getValue();
                        groupAreaFieldConfigInnerObj = tempObj;
                        if (groupAreaFieldConfigInnerObj.getIntValue(CmnConst.ATTR_X) + Math.max(1, groupAreaFieldConfigInnerObj.getIntValue(CmnConst.ATTR_COLSPAN)) - 1 >= dataAreaFieldConfigInnerObj.getIntValue(CmnConst.ATTR_X)
                                && groupAreaFieldConfigInnerObj.getIntValue(CmnConst.ATTR_X) <= dataAreaFieldConfigInnerObj.getIntValue(CmnConst.ATTR_X)) {
                            dataAreaFieldConfigInnerObj.put(CmnConst.ATTR_GROUP_AREA_GROUP_FIELD, groupAreaGroupFieldNameList);
                        }
                    }
                }
            }
        }
      // 提取分组表头区分组字段名称list,对分组表头区字段obj放入数据区分组字段、分组表头区分组字段
      List<JSONObject> groupAreaReportConfigList = reportConfigMap.get(2);
      ArrayList<String> groupAreaGroupFieldNameList = Lists.newArrayList();
      JSONObject dataAreaFieldConfigOuterObj;
      JSONObject dataAreaFieldConfigInnerObj;
      JSONObject groupAreaFieldConfigInnerObj;
      if (groupAreaReportConfigList != null) {
         for (int i = 0; i < groupAreaReportConfigList.size(); i++) {
            tempObj = groupAreaReportConfigList.get(i);
            fieldName = fieldInfo2FieldName(tempObj.getString(CmnConst.ATTR_FIELD_INFO));
            if (!dataAreaGroupFieldNameList.isEmpty()) {
               tempObj.put(CmnConst.ATTR_DATA_AREA_GROUP_FIELD, dataAreaGroupFieldNameList);
            }
            if (!groupAreaGroupFieldNameList.isEmpty()) {
               tempObj.put(CmnConst.ATTR_GROUP_AREA_GROUP_FIELD, groupAreaGroupFieldNameList.clone());
            }
            fieldConfigObj = new JSONObject();
            fieldConfigObj.put(fieldName, tempObj);
            groupAreaReportConfigList.set(i, fieldConfigObj);
            if ("1".equals(tempObj.getString(CmnConst.ATTR_IS_GROUP))) {
               groupAreaGroupFieldNameList.add(fieldName);
            }
            // 添加数据区的分组表头区分组字段
            if (dataAreaReportConfigList != null) {
               for (int j = 0; j < dataAreaReportConfigList.size(); j++) {
                  dataAreaFieldConfigOuterObj = dataAreaReportConfigList.get(j);
                  dataAreaFieldConfigInnerObj = (JSONObject) dataAreaFieldConfigOuterObj.entrySet().iterator().next().getValue();
                  groupAreaFieldConfigInnerObj = tempObj;
                  if (groupAreaFieldConfigInnerObj.getIntValue(CmnConst.ATTR_X) + Math.max(1, groupAreaFieldConfigInnerObj.getIntValue(CmnConst.ATTR_COLSPAN)) - 1 >= dataAreaFieldConfigInnerObj.getIntValue(CmnConst.ATTR_X)
                        && groupAreaFieldConfigInnerObj.getIntValue(CmnConst.ATTR_X) <= dataAreaFieldConfigInnerObj.getIntValue(CmnConst.ATTR_X)) {
                     dataAreaFieldConfigInnerObj.put(CmnConst.ATTR_GROUP_AREA_GROUP_FIELD, groupAreaGroupFieldNameList);
                  }
               }
            }
         }
      }
        // 数据源排序
        StringBuilder sort = new StringBuilder(128);
        JSONObject innerObj;
        if (dataAreaReportConfigList != null) {
            for (JSONObject outerObj : dataAreaReportConfigList) {
                fieldName = outerObj.keySet().iterator().next();
                if (dataAreaGroupFieldNameList.contains(fieldName)) {
                    innerObj = outerObj.getJSONObject(fieldName);
                    sort.append(fieldName).append(StringUtils.isEmpty(innerObj.getString(CmnConst.ATTR_ORDER_BY)) ? "" : " " + innerObj.getString(CmnConst.ATTR_ORDER_BY)).append(",");
                }
            }
        }
        if (groupAreaReportConfigList != null) {
            for (JSONObject outerObj : groupAreaReportConfigList) {
                fieldName = outerObj.keySet().iterator().next();
                if (StringUtils.isEmpty(fieldName)) {
                    continue;
                }
                innerObj = outerObj.getJSONObject(fieldName);
                sort.append(fieldName).append(StringUtils.isEmpty(innerObj.getString(CmnConst.ATTR_ORDER_BY)) ? "" : " " + innerObj.getString(CmnConst.ATTR_ORDER_BY)).append(",");
            }
        }
        if (sort.length() > 0) {
            sort.deleteCharAt(sort.length() - 1);
        }
      // 数据源排序
      StringBuilder sort = new StringBuilder(128);
      JSONObject innerObj;
      if (dataAreaReportConfigList != null) {
         for (JSONObject outerObj : dataAreaReportConfigList) {
            fieldName = outerObj.keySet().iterator().next();
            if (dataAreaGroupFieldNameList.contains(fieldName)) {
               innerObj = outerObj.getJSONObject(fieldName);
               sort.append(fieldName).append(StringUtils.isEmpty(innerObj.getString(CmnConst.ATTR_ORDER_BY)) ? "" : " " + innerObj.getString(CmnConst.ATTR_ORDER_BY)).append(",");
            }
         }
      }
      if (groupAreaReportConfigList != null) {
         for (JSONObject outerObj : groupAreaReportConfigList) {
            fieldName = outerObj.keySet().iterator().next();
            if (StringUtils.isEmpty(fieldName)) {
               continue;
            }
            innerObj = outerObj.getJSONObject(fieldName);
            sort.append(fieldName).append(StringUtils.isEmpty(innerObj.getString(CmnConst.ATTR_ORDER_BY)) ? "" : " " + innerObj.getString(CmnConst.ATTR_ORDER_BY)).append(",");
         }
      }
      if (sort.length() > 0) {
         sort.deleteCharAt(sort.length() - 1);
      }
        // 放入缓存
        RedisUtil.setHash(reportConfigUUID, "sort", sort);
        for (Map.Entry<Integer, List<JSONObject>> entry : reportConfigMap.entrySet()) {
            RedisUtil.setHash(reportConfigUUID, String.valueOf(entry.getKey()), entry.getValue());
        }
    }
      // 放入缓存
      RedisUtil.setHash(reportConfigUUID, "sort", sort);
      for (Map.Entry<Integer, List<JSONObject>> entry : reportConfigMap.entrySet()) {
         RedisUtil.setHash(reportConfigUUID, String.valueOf(entry.getKey()), entry.getValue());
      }
   }
    /**
     * 获取报表
     *
     * @return
     */
    public JSONObject getReport(FieldSetEntity fse) {
        String reportConfigUUID = fse.getUUID();
        DataTableEntity reportConfigDte = DataPoolCacheImpl.getInstance().getCacheData(CmnConst.CACHE_REPORT_CONFIG, new String[]{reportConfigUUID});
        if (BaseUtil.dataTableIsEmpty(reportConfigDte)) {
            throw new BaseException(ReportCode.GET_CACHE_FIAL.getValue(), ReportCode.GET_CACHE_FIAL.getText() + ":" + CmnConst.CACHE_REPORT_CONFIG);
        }
        FieldSetEntity reportConfigFse = reportConfigDte.getFieldSetEntity(0);
        if (!"1".equals(reportConfigFse.getString(CmnConst.IS_VALID))) {
            throw new BaseException(ReportCode.INVALID_REPORT.getValue(), ReportCode.INVALID_REPORT.getText());
        }
   /**
    * 获取报表
    *
    * @return
    */
   public JSONObject getReport(FieldSetEntity fse) {
      String reportConfigUUID = fse.getUUID();
      DataTableEntity reportConfigDte = DataPoolCacheImpl.getInstance().getCacheData(CmnConst.CACHE_REPORT_CONFIG, new String[]{reportConfigUUID});
      if (BaseUtil.dataTableIsEmpty(reportConfigDte)) {
         throw new BaseException(ReportCode.GET_CACHE_FIAL.getValue(), ReportCode.GET_CACHE_FIAL.getText() + ":" + CmnConst.CACHE_REPORT_CONFIG);
      }
      FieldSetEntity reportConfigFse = reportConfigDte.getFieldSetEntity(0);
      if (!"1".equals(reportConfigFse.getString(CmnConst.IS_VALID))) {
         throw new BaseException(ReportCode.INVALID_REPORT.getValue(), ReportCode.INVALID_REPORT.getText());
      }
        DataTableEntity reportTypeDte = DataPoolCacheImpl.getInstance().getCacheData(CmnConst.CACHE_REPORT_TYPE, new String[]{reportConfigFse.getString(CmnConst.TYPE_UUID)});
        if (BaseUtil.dataTableIsEmpty(reportTypeDte)) {
            throw new BaseException(ReportCode.GET_CACHE_FIAL.getValue(), ReportCode.GET_CACHE_FIAL.getText() + ":" + CmnConst.CACHE_REPORT_TYPE);
        }
        FieldSetEntity reportTypeFse = reportTypeDte.getFieldSetEntity(0);
      DataTableEntity reportTypeDte = DataPoolCacheImpl.getInstance().getCacheData(CmnConst.CACHE_REPORT_TYPE, new String[]{reportConfigFse.getString(CmnConst.TYPE_UUID)});
      if (BaseUtil.dataTableIsEmpty(reportTypeDte)) {
         throw new BaseException(ReportCode.GET_CACHE_FIAL.getValue(), ReportCode.GET_CACHE_FIAL.getText() + ":" + CmnConst.CACHE_REPORT_TYPE);
      }
      FieldSetEntity reportTypeFse = reportTypeDte.getFieldSetEntity(0);
        StringBuilder sort = new StringBuilder(128);
        // 获取报表缓存信息
        Map<Integer, List<JSONObject>> reportConfigMap = getReportConfig(reportConfigUUID, sort);
        // 根据具体的function_uuid和button_uuid获取对应的路由,拼凑url
        String url;
        JSONObject valueObj;
        for (Map.Entry<Integer, List<JSONObject>> entry : reportConfigMap.entrySet()) {
            if (entry.getValue() != null) {
                for (JSONObject tempValueObj : entry.getValue()) {
                    if (entry.getValue() != null) {
                        for (Map.Entry<String, Object> innerEntry : tempValueObj.entrySet()) {
                            if (innerEntry.getValue() instanceof JSONObject) {
                                valueObj = (JSONObject) innerEntry.getValue();
                                if (!StringUtils.isEmpty(valueObj.getString(CmnConst.SUB_REPORT))) {
                                    url = valueObj.getString(CmnConst.SUB_REPORT);
                                    if (!StringUtils.isEmpty(valueObj.getString(CmnConst.ATTR_URL_PARAM))) {
                                        url += "?" + valueObj.getString(CmnConst.ATTR_URL_PARAM);
                                    }
                                    valueObj.put(CmnConst.ATTR_URL, url);
                                    valueObj.put("~isSubReport~", true);
                                } else {
                                    if (!StringUtils.isEmpty(valueObj.getString(CmnConst.FUNCTION_UUID)) && !StringUtils.isEmpty(valueObj.getString(CmnConst.BUTTON_UUID))) {
                                        url = routerService.functionSkipByButtonUuid(valueObj.getString(CmnConst.FUNCTION_UUID), valueObj.getString(CmnConst.BUTTON_UUID));
                                        if (StringUtils.isEmpty(url)) {
                                            valueObj.remove(CmnConst.ATTR_URL);
                                        } else {
                                            if (!StringUtils.isEmpty(valueObj.getString(CmnConst.ATTR_URL_PARAM))) {
                                                url += "?" + valueObj.getString(CmnConst.ATTR_URL_PARAM);
                                            }
                                            valueObj.put(CmnConst.ATTR_URL, url);
                                        }
                                    } else {
                                        valueObj.remove(CmnConst.ATTR_URL);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        // 获取报表类型
        String reportType = reportTypeFse.getString(CmnConst.TYPE_NAME);
        // 获取数据源
        DataTableEntity reportSourceDte = DataPoolCacheImpl.getInstance().getCacheData(CmnConst.CACHE_REPORT_DATASOURCE_CONFIG, new String[]{reportConfigFse.getString(CmnConst.DATASOURCE_UUID)});
        if (BaseUtil.dataTableIsEmpty(reportSourceDte)) {
            throw new BaseException(ReportCode.GET_REPORT_DATASOURCE_FIAL.getValue(), ReportCode.GET_REPORT_DATASOURCE_FIAL.getText());
        }
        FieldSetEntity reportSourceFse = reportSourceDte.getFieldSetEntity(0);
        int curPage = fse.getInteger(CmnConst.CPAGE) == null ? 1 : fse.getInteger(CmnConst.CPAGE);
      StringBuilder sort = new StringBuilder(128);
      // 获取报表缓存信息
      Map<Integer, List<JSONObject>> reportConfigMap = getReportConfig(reportConfigUUID, sort);
      // 根据具体的function_uuid和button_uuid获取对应的路由,拼凑url
      String url;
      JSONObject valueObj;
      for (Map.Entry<Integer, List<JSONObject>> entry : reportConfigMap.entrySet()) {
         if (entry.getValue() != null) {
            for (JSONObject tempValueObj : entry.getValue()) {
               if (entry.getValue() != null) {
                  for (Map.Entry<String, Object> innerEntry : tempValueObj.entrySet()) {
                     if (innerEntry.getValue() instanceof JSONObject) {
                        valueObj = (JSONObject) innerEntry.getValue();
                        if (!StringUtils.isEmpty(valueObj.getString(CmnConst.SUB_REPORT))) {
                           url = valueObj.getString(CmnConst.SUB_REPORT);
                           if (!StringUtils.isEmpty(valueObj.getString(CmnConst.ATTR_URL_PARAM))) {
                              url += "?" + valueObj.getString(CmnConst.ATTR_URL_PARAM);
                           }
                           valueObj.put(CmnConst.ATTR_URL, url);
                           valueObj.put("~isSubReport~", true);
                        } else {
                           if (!StringUtils.isEmpty(valueObj.getString(CmnConst.FUNCTION_UUID)) && !StringUtils.isEmpty(valueObj.getString(CmnConst.BUTTON_UUID))) {
                              url = routerService.functionSkipByButtonUuid(valueObj.getString(CmnConst.FUNCTION_UUID), valueObj.getString(CmnConst.BUTTON_UUID));
                              if (StringUtils.isEmpty(url)) {
                                 valueObj.remove(CmnConst.ATTR_URL);
                              } else {
                                 if (!StringUtils.isEmpty(valueObj.getString(CmnConst.ATTR_URL_PARAM))) {
                                    url += "?" + valueObj.getString(CmnConst.ATTR_URL_PARAM);
                                 }
                                 valueObj.put(CmnConst.ATTR_URL, url);
                              }
                           } else {
                              valueObj.remove(CmnConst.ATTR_URL);
                           }
                        }
                     }
                  }
               }
            }
         }
      }
      // 获取报表类型
      String reportType = reportTypeFse.getString(CmnConst.TYPE_NAME);
      // 获取数据源
      DataTableEntity reportSourceDte = DataPoolCacheImpl.getInstance().getCacheData(CmnConst.CACHE_REPORT_DATASOURCE_CONFIG, new String[]{reportConfigFse.getString(CmnConst.DATASOURCE_UUID)});
      if (BaseUtil.dataTableIsEmpty(reportSourceDte)) {
         throw new BaseException(ReportCode.GET_REPORT_DATASOURCE_FIAL.getValue(), ReportCode.GET_REPORT_DATASOURCE_FIAL.getText());
      }
      FieldSetEntity reportSourceFse = reportSourceDte.getFieldSetEntity(0);
      int curPage = fse.getInteger(CmnConst.CPAGE) == null ? 1 : fse.getInteger(CmnConst.CPAGE);
        JSONObject resultObj = new JSONObject();
        // 首次加载,默认添加条件
        if (fse.getBoolean(CmnConst.FIRST_LOAD)) {
            DataTableEntity allFilterDte = getDefaultSearchFilter(reportSourceFse.getUUID());
            Map<String, DataTableEntity> subMap = Maps.newHashMap();
            if (!DataTableEntity.isEmpty(allFilterDte)) {
                subMap.put("systemFieldMeta", allFilterDte);
            }
            DataTableEntity defaultFilterDte = new DataTableEntity();
      JSONObject resultObj = new JSONObject();
      // 首次加载,默认添加条件
      if (fse.getBoolean(CmnConst.FIRST_LOAD)) {
         DataTableEntity allFilterDte = getDefaultSearchFilter(reportSourceFse.getUUID());
         Map<String, DataTableEntity> subMap = Maps.newHashMap();
         if (!DataTableEntity.isEmpty(allFilterDte)) {
            subMap.put("systemFieldMeta", allFilterDte);
         }
         DataTableEntity defaultFilterDte = new DataTableEntity();
            FieldSetEntity tempFse;
            Map<String, Map<String, String>> outerMap = Maps.newHashMap();
            Map<String, String> innerMap;
            for (int i = 0; i < allFilterDte.getRows(); i++) {
                tempFse = allFilterDte.getFieldSetEntity(i);
                if (StringUtils.isEmpty(tempFse.getString(CmnConst.LOGICAL_VALUE))) {
                    continue;
                }
                defaultFilterDte.addFieldSetEntity(tempFse);
                innerMap = Maps.newHashMap();
                innerMap.put(CmnConst.LOGICAL_OPERATOR, tempFse.getString(CmnConst.LOGICAL_OPERATOR));
                innerMap.put(CmnConst.LOGICAL_VALUE, tempFse.getString(CmnConst.LOGICAL_VALUE));
                innerMap.put(CmnConst.FIELD_TYPE, tempFse.getString(CmnConst.FIELD_TYPE));
                outerMap.put(tempFse.getString(CmnConst.FIELD_NAME), innerMap);
            }
            resultObj.put("filterInfo", outerMap);
         FieldSetEntity tempFse;
         Map<String, Map<String, String>> outerMap = Maps.newHashMap();
         Map<String, String> innerMap;
         for (int i = 0; i < allFilterDte.getRows(); i++) {
            tempFse = allFilterDte.getFieldSetEntity(i);
            if (StringUtils.isEmpty(tempFse.getString(CmnConst.LOGICAL_VALUE))) {
               continue;
            }
            defaultFilterDte.addFieldSetEntity(tempFse);
            innerMap = Maps.newHashMap();
            innerMap.put(CmnConst.LOGICAL_OPERATOR, tempFse.getString(CmnConst.LOGICAL_OPERATOR));
            innerMap.put(CmnConst.LOGICAL_VALUE, tempFse.getString(CmnConst.LOGICAL_VALUE));
            innerMap.put(CmnConst.FIELD_TYPE, tempFse.getString(CmnConst.FIELD_TYPE));
            outerMap.put(tempFse.getString(CmnConst.FIELD_NAME), innerMap);
         }
         resultObj.put("filterInfo", outerMap);
            if (!DataTableEntity.isEmpty(defaultFilterDte)) {
                subMap.put("systemSeniorQueryString", defaultFilterDte);
            }
            fse.setSubData(subMap);
        }
         if (!DataTableEntity.isEmpty(defaultFilterDte)) {
            subMap.put("systemSeniorQueryString", defaultFilterDte);
         }
         fse.setSubData(subMap);
      }
        DataTableEntity recordDte = getRecordDte(sort, curPage, reportSourceFse, fse, reportConfigFse, null);
        // 是否添加总合计
        boolean totalStatisticsFlag = "1".equalsIgnoreCase(reportConfigFse.getString(CmnConst.LAST_TOTAL));
        String totalName = totalStatisticsFlag ? (StringUtils.isEmpty(reportConfigFse.getString(CmnConst.TOTAL_NAME)) ? "总计" : reportConfigFse.getString(CmnConst.TOTAL_NAME)) : "";
      DataTableEntity recordDte = getRecordDte(sort, curPage, reportSourceFse, fse, reportConfigFse, null);
      // 是否添加总合计
      boolean totalStatisticsFlag = "1".equalsIgnoreCase(reportConfigFse.getString(CmnConst.LAST_TOTAL));
      String totalName = totalStatisticsFlag ? (StringUtils.isEmpty(reportConfigFse.getString(CmnConst.TOTAL_NAME)) ? "总计" : reportConfigFse.getString(CmnConst.TOTAL_NAME)) : "";
//        JSONObject checkObj = checkRecordDte(recordDte);
//        if (CmnConst.FALSE.equals(checkObj.getString(CmnConst.RETURN_ATTR_RESULT))) {
//            return checkObj;
//        }
        StringBuilder tableStyle = new StringBuilder(32);
        String widthType = reportConfigFse.getString(CmnConst.REPORT_WIDTH_TYPE);
        String width = reportConfigFse.getString(CmnConst.REPORT_WIDTH_VALUE);
        if (!StringUtils.isEmpty(width)) {
            if ("1".equals(widthType)) {
                tableStyle.append(" style=\"width:").append(width).append("%\"");
            } else if ("0".equals(widthType)) {
                tableStyle.append(" style=\"width:").append(width).append("px\"");
            }
        }
      StringBuilder tableStyle = new StringBuilder(32);
      String widthType = reportConfigFse.getString(CmnConst.REPORT_WIDTH_TYPE);
      String width = reportConfigFse.getString(CmnConst.REPORT_WIDTH_VALUE);
      if (!StringUtils.isEmpty(width)) {
         if ("1".equals(widthType)) {
            tableStyle.append(" style=\"width:").append(width).append("%\"");
         } else if ("0".equals(widthType)) {
            tableStyle.append(" style=\"width:").append(width).append("px\"");
         }
      }
        if (CmnConst.REPORT_TYPE_COMMON.equals(reportType)) {
            resultObj.putAll(commonReportService.getReport(recordDte, totalName, reportConfigMap, tableStyle));
        } else if (CmnConst.REPORT_TYPE_GROUP.equals(reportType)) {
            // 特殊处理额外查询内容
            recordDte.addFieldSetEntity(getRecordDte(sort, curPage, reportSourceFse, fse, reportConfigFse, reportConfigMap));
            resultObj.putAll(groupReportService.getReport(recordDte, totalName, reportConfigMap, tableStyle));
        }
      if (CmnConst.REPORT_TYPE_COMMON.equals(reportType)) {
         resultObj.putAll(commonReportService.getReport(recordDte, totalName, reportConfigMap, tableStyle));
      } else if (CmnConst.REPORT_TYPE_GROUP.equals(reportType)) {
         // 特殊处理额外查询内容
         recordDte.addFieldSetEntity(getRecordDte(sort, curPage, reportSourceFse, fse, reportConfigFse, reportConfigMap));
         resultObj.putAll(groupReportService.getReport(recordDte, totalName, reportConfigMap, tableStyle));
      }
        if (CmnConst.FALSE.equals(resultObj.getString(CmnConst.RETURN_ATTR_RESULT))) {
            resultObj.put(CmnConst.RETURN_ATTR_RESULT, true);
            resultObj.put(CmnConst.RETURN_ATTR_MESSAGE, "获取报表失败!");
        } else {
            // 分页参数
            SQLEntity sqlEntity = recordDte.getSqle();
            if ("1".equals(reportConfigFse.getString(CmnConst.IS_PAGE)) && sqlEntity != null) {
                resultObj.put(CmnConst.IS_PAGE, 1);
                resultObj.put(CmnConst.CPAGE, curPage);
                resultObj.put("totalCount", sqlEntity.getTotalCount());
                resultObj.put("totalpage", sqlEntity.getTotalpage());
                resultObj.put("pagesize", StringUtils.isEmpty(reportConfigFse.getString(CmnConst.PAGE_SIZE)) ? 0 : reportConfigFse.getInteger(CmnConst.PAGE_SIZE));
            } else {
                resultObj.put(CmnConst.IS_PAGE, 0);
            }
        }
        if (!DataTableEntity.isEmpty(recordDte)) {
            resultObj.put("current_page_count", recordDte.getRows());
        }
        resultObj.put("systemFieldMeta", getSearchInfo(reportSourceFse.getUUID()));
        resultObj.put("report_type", reportConfigFse.getString("type_uuid"));
      if (CmnConst.FALSE.equals(resultObj.getString(CmnConst.RETURN_ATTR_RESULT))) {
         resultObj.put(CmnConst.RETURN_ATTR_RESULT, true);
         resultObj.put(CmnConst.RETURN_ATTR_MESSAGE, "获取报表失败!");
      } else {
         // 分页参数
         SQLEntity sqlEntity = recordDte.getSqle();
         if ("1".equals(reportConfigFse.getString(CmnConst.IS_PAGE)) && sqlEntity != null) {
            resultObj.put(CmnConst.IS_PAGE, 1);
            resultObj.put(CmnConst.CPAGE, curPage);
            resultObj.put("totalCount", sqlEntity.getTotalCount());
            resultObj.put("totalpage", sqlEntity.getTotalpage());
            resultObj.put("pagesize", StringUtils.isEmpty(reportConfigFse.getString(CmnConst.PAGE_SIZE)) ? 0 : reportConfigFse.getInteger(CmnConst.PAGE_SIZE));
         } else {
            resultObj.put(CmnConst.IS_PAGE, 0);
         }
      }
      if (!DataTableEntity.isEmpty(recordDte)) {
         resultObj.put("current_page_count", recordDte.getRows());
      }
      resultObj.put("systemFieldMeta", getSearchInfo(reportSourceFse.getUUID()));
      resultObj.put("report_type", reportConfigFse.getString("type_uuid"));
//        System.out.println(resultObj.getString("html"));
        return resultObj;
    }
      return resultObj;
   }
    /**
     * 获取报表缓存信息
     *
     * @param reportConfigUUID
     * @param sort
     * @return
     */
    private Map<Integer, List<JSONObject>> getReportConfig(String reportConfigUUID, StringBuilder sort) {
        Object obj;
        Map<Integer, List<JSONObject>> reportConfigMap = Maps.newHashMap();
        List<JSONObject> list;
        for (int i = 0; i < 4; i++) {
            obj = RedisUtil.getHash(reportConfigUUID, String.valueOf(i));
            if (obj == null) {
                continue;
            }
            list = (List<JSONObject>) obj;
            reportConfigMap.put(i, list);
        }
   /**
    * 获取报表缓存信息
    *
    * @param reportConfigUUID
    * @param sort
    * @return
    */
   private Map<Integer, List<JSONObject>> getReportConfig(String reportConfigUUID, StringBuilder sort) {
      Object obj;
      Map<Integer, List<JSONObject>> reportConfigMap = Maps.newHashMap();
      List<JSONObject> list;
      for (int i = 0; i < 4; i++) {
         obj = RedisUtil.getHash(reportConfigUUID, String.valueOf(i));
         if (obj == null) {
            continue;
         }
         list = (List<JSONObject>) obj;
         reportConfigMap.put(i, list);
      }
        if (reportConfigMap.isEmpty()) {
            throw new BaseException(ReportCode.GET_REPORT_CONFIG_FIAL.getValue(), ReportCode.GET_REPORT_CONFIG_FIAL.getText());
        }
        obj = RedisUtil.getHash(reportConfigUUID, "sort");
        if (obj != null) {
            sort.append(obj.toString());
        }
        return reportConfigMap;
    }
      if (reportConfigMap.isEmpty()) {
         throw new BaseException(ReportCode.GET_REPORT_CONFIG_FIAL.getValue(), ReportCode.GET_REPORT_CONFIG_FIAL.getText());
      }
      obj = RedisUtil.getHash(reportConfigUUID, "sort");
      if (obj != null) {
         sort.append(obj.toString());
      }
      return reportConfigMap;
   }
    /**
     * 获取数据源
     *
     * @param sort
     * @param curPage
     * @param reportSourceFse
     * @param fse
     * @param reportConfigFse
     * @return
     */
    private DataTableEntity getRecordDte(StringBuilder sort, int curPage, FieldSetEntity reportSourceFse, FieldSetEntity fse, FieldSetEntity reportConfigFse, Map<Integer, List<JSONObject>> reportConfigMap) {
        boolean spTimeFlag = reportConfigMap != null;
        String sql;
        String sqlText = reportSourceFse.getString(CmnConst.SQL_TEXT);
        DataTableEntity recordDte = new DataTableEntity();
   /**
    * 获取数据源
    *
    * @param sort
    * @param curPage
    * @param reportSourceFse
    * @param fse
    * @param reportConfigFse
    * @return
    */
   private DataTableEntity getRecordDte(StringBuilder sort, int curPage, FieldSetEntity reportSourceFse, FieldSetEntity fse, FieldSetEntity reportConfigFse, Map<Integer, List<JSONObject>> reportConfigMap) {
      boolean spTimeFlag = reportConfigMap != null;
      String sql;
      String sqlText = reportSourceFse.getString(CmnConst.SQL_TEXT);
      DataTableEntity recordDte = new DataTableEntity();
        if (spTimeFlag) {
            // 获取所有的字段
            Set<String> baseFieldSet = Sets.newHashSet();
            Map<String, Map<String, JSONObject>> spTimeStatisticsFieldMap = Maps.newHashMap();
            Set<String> spTimeStatisticsTypeSet = Sets.newHashSet();
            spTimeStatisticsTypeSet.addAll(getFieldAndSpTimeStatisticsTypeSet(baseFieldSet, spTimeStatisticsFieldMap, reportConfigMap.get(0)));
            spTimeStatisticsTypeSet.addAll(getFieldAndSpTimeStatisticsTypeSet(baseFieldSet, spTimeStatisticsFieldMap, reportConfigMap.get(2)));
            Map<String, List<String>> queryFilterMap = queryFilterService.getQueryFilterMore(fse);
            Set<String> selectedFieldSet;
            String headContent;
            DataTableEntity tempDte;
            String curFieldName;
            String curCommonFieldName;
            Map<String, List<String>> tempQueryFilterMap;
            List<String> tempList;
            Map<String, String> tempFieldMap;
            Set<String> tempDateFieldInfoSet;
            JSONObject obj;
      if (spTimeFlag) {
         // 获取所有的字段
         Set<String> baseFieldSet = Sets.newHashSet();
         Map<String, Map<String, JSONObject>> spTimeStatisticsFieldMap = Maps.newHashMap();
         Set<String> spTimeStatisticsTypeSet = Sets.newHashSet();
         spTimeStatisticsTypeSet.addAll(getFieldAndSpTimeStatisticsTypeSet(baseFieldSet, spTimeStatisticsFieldMap, reportConfigMap.get(0)));
         spTimeStatisticsTypeSet.addAll(getFieldAndSpTimeStatisticsTypeSet(baseFieldSet, spTimeStatisticsFieldMap, reportConfigMap.get(2)));
         Map<String, List<String>> queryFilterMap = queryFilterService.getQueryFilterMore(fse);
         Set<String> selectedFieldSet;
         String headContent;
         DataTableEntity tempDte;
         String curFieldName;
         String curCommonFieldName;
         Map<String, List<String>> tempQueryFilterMap;
         List<String> tempList;
         Map<String, String> tempFieldMap;
         Set<String> tempDateFieldInfoSet;
         JSONObject obj;
            for (String spTimeStatisticsType : spTimeStatisticsTypeSet) {
                selectedFieldSet = Sets.newHashSet();
                tempFieldMap = Maps.newHashMap();
                tempDateFieldInfoSet = Sets.newHashSet();
                tempQueryFilterMap = Maps.newHashMap();
                for (Map.Entry<String, JSONObject> outEntry : spTimeStatisticsFieldMap.get(spTimeStatisticsType).entrySet()) {
                    obj = outEntry.getValue();
                    curFieldName = fieldInfo2FieldName(obj.getString(CmnConst.ATTR_RELATE_TIME_FIELD));
                    if ("0".equals(spTimeStatisticsType)) {
                        // 去年同期
                        headContent = CmnConst.ATTR_HEAD_LAST_YEAR;
                    } else if ("1".equals(spTimeStatisticsType)) {
                        // 上期
                        headContent = CmnConst.ATTR_HEAD_PRE_PERIOD;
                    } else {
                        headContent = "";
                    }
                    for (Map.Entry<String, List<String>> entry : queryFilterMap.entrySet()) {
                        tempList = Lists.newArrayList();
                        tempList.addAll(entry.getValue());
                        tempQueryFilterMap.put(entry.getKey(), tempList);
                    }
                    if (queryFilterMap.containsKey(curFieldName)) {
                        if (!tempDateFieldInfoSet.contains(obj.getString(CmnConst.ATTR_RELATE_TIME_FIELD))) {
                            tempDateFieldInfoSet.add(obj.getString(CmnConst.ATTR_RELATE_TIME_FIELD));
                            if ("0".equals(spTimeStatisticsType)) {
                                // 去年同期
                                spDealFilterForLastYear(tempQueryFilterMap, queryFilterMap, curFieldName);
                            } else if ("1".equals(spTimeStatisticsType)) {
                                // 上期
                                spDealFilterForPrePeriod(tempQueryFilterMap, queryFilterMap, curFieldName);
                            }
                        }
                    }
                    curCommonFieldName = fieldInfo2FieldName(obj.getString(CmnConst.ATTR_RELATE_COMMON_FIELD));
                    for (String selectField : baseFieldSet) {
                        if (selectField.equals(curCommonFieldName)) {
                            tempFieldMap.put(curCommonFieldName, curCommonFieldName + " " + headContent + curCommonFieldName);
                        }
                    }
                }
                for (String selectField : baseFieldSet) {
                    selectedFieldSet.add(tempFieldMap.getOrDefault(selectField, selectField));
                }
                sql = replaceSqlContent(sqlText, fse, null, reportConfigFse, curPage, SetUtils.set2String(selectedFieldSet, ","), tempQueryFilterMap);
         for (String spTimeStatisticsType : spTimeStatisticsTypeSet) {
            selectedFieldSet = Sets.newHashSet();
            tempFieldMap = Maps.newHashMap();
            tempDateFieldInfoSet = Sets.newHashSet();
            tempQueryFilterMap = Maps.newHashMap();
            for (Map.Entry<String, JSONObject> outEntry : spTimeStatisticsFieldMap.get(spTimeStatisticsType).entrySet()) {
               obj = outEntry.getValue();
               curFieldName = fieldInfo2FieldName(obj.getString(CmnConst.ATTR_RELATE_TIME_FIELD));
               if ("0".equals(spTimeStatisticsType)) {
                  // 去年同期
                  headContent = CmnConst.ATTR_HEAD_LAST_YEAR;
               } else if ("1".equals(spTimeStatisticsType)) {
                  // 上期
                  headContent = CmnConst.ATTR_HEAD_PRE_PERIOD;
               } else {
                  headContent = "";
               }
               for (Map.Entry<String, List<String>> entry : queryFilterMap.entrySet()) {
                  tempList = Lists.newArrayList();
                  tempList.addAll(entry.getValue());
                  tempQueryFilterMap.put(entry.getKey(), tempList);
               }
               if (queryFilterMap.containsKey(curFieldName)) {
                  if (!tempDateFieldInfoSet.contains(obj.getString(CmnConst.ATTR_RELATE_TIME_FIELD))) {
                     tempDateFieldInfoSet.add(obj.getString(CmnConst.ATTR_RELATE_TIME_FIELD));
                     if ("0".equals(spTimeStatisticsType)) {
                        // 去年同期
                        spDealFilterForLastYear(tempQueryFilterMap, queryFilterMap, curFieldName);
                     } else if ("1".equals(spTimeStatisticsType)) {
                        // 上期
                        spDealFilterForPrePeriod(tempQueryFilterMap, queryFilterMap, curFieldName);
                     }
                  }
               }
               curCommonFieldName = fieldInfo2FieldName(obj.getString(CmnConst.ATTR_RELATE_COMMON_FIELD));
               for (String selectField : baseFieldSet) {
                  if (selectField.equals(curCommonFieldName)) {
                     tempFieldMap.put(curCommonFieldName, curCommonFieldName + " " + headContent + curCommonFieldName);
                  }
               }
            }
            for (String selectField : baseFieldSet) {
               selectedFieldSet.add(tempFieldMap.getOrDefault(selectField, selectField));
            }
            sql = replaceSqlContent(sqlText, fse, null, reportConfigFse, curPage, SetUtils.set2String(selectedFieldSet, ","), tempQueryFilterMap);
                if ("1".equalsIgnoreCase(reportConfigFse.getString(CmnConst.IS_PAGE))) {
                    Integer pageSize = reportConfigFse.getInteger(CmnConst.PAGE_SIZE);
                    tempDte = baseDao.listTable(sql, new Object[]{}, pageSize == null ? Integer.MAX_VALUE : pageSize, curPage);
                } else {
                    tempDte = baseDao.listTable(sql, new Object[]{});
                }
            if ("1".equalsIgnoreCase(reportConfigFse.getString(CmnConst.IS_PAGE))) {
               Integer pageSize = reportConfigFse.getInteger(CmnConst.PAGE_SIZE);
               tempDte = baseDao.listTable(sql, new Object[]{}, pageSize == null ? Integer.MAX_VALUE : pageSize, curPage);
            } else {
               tempDte = baseDao.listTable(sql, new Object[]{});
            }
                recordDte.addFieldSetEntity(tempDte);
            }
        } else {
            sql = replaceSqlContent(sqlText, fse, sort, reportConfigFse, curPage);
            recordDte.addFieldSetEntity(tempDte);
         }
      } else {
         sql = replaceSqlContent(sqlText, fse, sort, reportConfigFse, curPage);
            if ("1".equalsIgnoreCase(reportConfigFse.getString(CmnConst.IS_PAGE))) {
                Integer pageSize = reportConfigFse.getInteger(CmnConst.PAGE_SIZE);
                recordDte = baseDao.listTable(sql, new Object[]{}, pageSize == null ? Integer.MAX_VALUE : pageSize, curPage);
            } else {
                recordDte = baseDao.listTable(sql, new Object[]{});
            }
         if ("1".equalsIgnoreCase(reportConfigFse.getString(CmnConst.IS_PAGE))) {
            Integer pageSize = reportConfigFse.getInteger(CmnConst.PAGE_SIZE);
            recordDte = baseDao.listTable(sql, new Object[]{}, pageSize == null ? Integer.MAX_VALUE : pageSize, curPage);
         } else {
            recordDte = baseDao.listTable(sql, new Object[]{});
         }
        }
        // 加载数据源的参照
        loadPromptData(recordDte, reportSourceFse);
      }
      // 加载数据源的参照
      loadPromptData(recordDte, reportSourceFse);
        return recordDte;
    }
      return recordDte;
   }
    /**
     * 子方法-getRecordDte-加载参照
     *
     * @param recordDte
     * @param reportSourceFse
     */
    private void loadPromptData(DataTableEntity recordDte, FieldSetEntity reportSourceFse) {
        if (BaseUtil.dataTableIsEmpty(recordDte)) {
            return;
        }
        DataTableEntity reportDataSourceSubDte = DataPoolCacheImpl.getInstance().getCacheData(CmnConst.CACHE_REPORT_DATASOURCE_FIELD_CONFIG, new String[]{reportSourceFse.getUUID()});
        FieldSetEntity tempFse;
        String fieldName;
        String promptName;
        for (int i = 0; i < reportDataSourceSubDte.getRows(); i++) {
            tempFse = reportDataSourceSubDte.getFieldSetEntity(i);
            promptName = tempFse.getString(CmnConst.FIELD_PROMPT);
            fieldName = tempFse.getString(CmnConst.FIELD_NAME);
            if (StringUtils.isEmpty(promptName) || StringUtils.isEmpty(fieldName)) {
                continue;
            }
            if (promptName.startsWith("《")) {
                // 普通参照
                promptName = promptName.substring(1, promptName.length() - 1);
                baseDao.copyDictData(recordDte, fieldName, promptName, 0);
            } else {
                // 高级参照
                baseDao.copyPromptData(recordDte, fieldName, promptName);
            }
        }
    }
   /**
    * 子方法-getRecordDte-加载参照
    *
    * @param recordDte
    * @param reportSourceFse
    */
   private void loadPromptData(DataTableEntity recordDte, FieldSetEntity reportSourceFse) {
      if (BaseUtil.dataTableIsEmpty(recordDte)) {
         return;
      }
      DataTableEntity reportDataSourceSubDte = DataPoolCacheImpl.getInstance().getCacheData(CmnConst.CACHE_REPORT_DATASOURCE_FIELD_CONFIG, new String[]{reportSourceFse.getUUID()});
      FieldSetEntity tempFse;
      String fieldName;
      String promptName;
      for (int i = 0; i < reportDataSourceSubDte.getRows(); i++) {
         tempFse = reportDataSourceSubDte.getFieldSetEntity(i);
         promptName = tempFse.getString(CmnConst.FIELD_PROMPT);
         fieldName = tempFse.getString(CmnConst.FIELD_NAME);
         if (StringUtils.isEmpty(promptName) || StringUtils.isEmpty(fieldName)) {
            continue;
         }
         if (promptName.startsWith("《")) {
            // 普通参照
            promptName = promptName.substring(1, promptName.length() - 1);
            baseDao.copyDictData(recordDte, fieldName, promptName, 0);
         } else {
            // 高级参照
            baseDao.copyPromptData(recordDte, fieldName, promptName);
         }
      }
   }
    /**
     * 替换sql中的条件,将其转换为能够直接执行的sql
     *
     * @param sqlText
     * @param fse
     * @param sort
     * @return
     */
    private String replaceSqlContent(String sqlText, FieldSetEntity fse, StringBuilder sort, FieldSetEntity reportConfigFse, int curPage, String selectedFields, Map<String, List<String>> queryFilterMap) {
        queryFilterMap = queryFilterMap == null ? queryFilterService.getQueryFilterMore(fse) : queryFilterMap;
        selectedFields = StringUtils.isEmpty(selectedFields) ? "*" : selectedFields;
        // 替换sql中的系统参数
        sqlText = SystemParamReplace.replaceParams(sqlText, fse);
   /**
    * 替换sql中的条件,将其转换为能够直接执行的sql
    *
    * @param sqlText
    * @param fse
    * @param sort
    * @return
    */
   private String replaceSqlContent(String sqlText, FieldSetEntity fse, StringBuilder sort, FieldSetEntity reportConfigFse, int curPage, String selectedFields, Map<String, List<String>> queryFilterMap) {
      queryFilterMap = queryFilterMap == null ? queryFilterService.getQueryFilterMore(fse) : queryFilterMap;
      selectedFields = StringUtils.isEmpty(selectedFields) ? "*" : selectedFields;
      // 替换sql中的系统参数
      sqlText = SystemParamReplace.replaceParams(sqlText, fse);
        List<String> suitList = getSuitContent(sqlText, CmnConst.REGEXP_ALL_AREA);
        String newContent;
        int signCount = 0;
        Map<String, List<String>> residueQueryFilterMap = Maps.newHashMap();
        queryFilterMap.forEach((k, v) -> {
            residueQueryFilterMap.put(k, v);
        });
        Map<String, String> tempReplaceMap = Maps.newHashMap();
        for (String suitContent : suitList) {
            if (tempReplaceMap.containsKey(suitContent)) {
                continue;
            }
            newContent = spReplaceSqlContent(suitContent, CmnConst.REGEXP_ONLY_VALUE, 0, queryFilterMap, residueQueryFilterMap);
            newContent = spReplaceSqlContent(newContent, CmnConst.REGEXP_EXCEPT_FIELD, 1, queryFilterMap, residueQueryFilterMap);
            newContent = spReplaceSqlContent(newContent, CmnConst.REGEXP_FULL_CONTENT, 2, queryFilterMap, residueQueryFilterMap);
      List<String> suitList = getSuitContent(sqlText, CmnConst.REGEXP_ALL_AREA);
      String newContent;
      int signCount = 0;
      Map<String, List<String>> residueQueryFilterMap = Maps.newHashMap();
      queryFilterMap.forEach((k, v) -> {
         residueQueryFilterMap.put(k, v);
      });
      Map<String, String> tempReplaceMap = Maps.newHashMap();
      for (String suitContent : suitList) {
         if (tempReplaceMap.containsKey(suitContent)) {
            continue;
         }
         newContent = spReplaceSqlContent(suitContent, CmnConst.REGEXP_ONLY_VALUE, 0, queryFilterMap, residueQueryFilterMap);
         newContent = spReplaceSqlContent(newContent, CmnConst.REGEXP_EXCEPT_FIELD, 1, queryFilterMap, residueQueryFilterMap);
         newContent = spReplaceSqlContent(newContent, CmnConst.REGEXP_FULL_CONTENT, 2, queryFilterMap, residueQueryFilterMap);
            if (!suitContent.equals(newContent)) {
                signCount++;
            }
            for (Map.Entry<String, String> entry : tempReplaceMap.entrySet()) {
                suitContent = suitContent.replace(entry.getKey(), entry.getValue());
            }
            tempReplaceMap.put(suitContent, newContent);
            sqlText = sqlText.replace(suitContent, newContent);
        }
        if ("1".equalsIgnoreCase(reportConfigFse.getString(CmnConst.IS_PAGE))) {
            int pageSize = reportConfigFse.getInteger(CmnConst.PAGE_SIZE) == null ? 20 : reportConfigFse.getInteger(CmnConst.PAGE_SIZE);
            sqlText = sqlText.replace(CmnConst.CONTENT_PAGE_AREA, "limit " + ((curPage - 1) * pageSize) + "," + pageSize);
        }
        // 三目表达式
        sqlText = replaceTernaryOperator(sqlText);
        // 清除已经处理的三目外的中括号
        suitList = getSuitContent(sqlText, CmnConst.REGEXP_FILTER_AREA);
        for (String suitContent : suitList) {
            newContent = suitContent.substring(2, suitContent.length() - 2);
            if (getSuitContent(newContent, CmnConst.REGEXP_SP_SIGN_AREA).isEmpty()) {
                sqlText = sqlText.replace(suitContent, newContent);
            }
        }
        // 剔除异常区域
        sqlText = sqlText.replaceAll(CmnConst.REGEXP_FILTER_AREA, "").replaceAll(CmnConst.REGEXP_ALL_TYPE, "null").replaceAll(CmnConst.REGEXP_ALWAYS_TRUE, "");
        String queryFilter = "";
        if (signCount > 0) {
            for (Map.Entry<String, List<String>> entry : residueQueryFilterMap.entrySet()) {
                if (CmnConst.SYSTEM_SENIOR_QUERY_STRING.equals(entry.getKey()) || entry.getValue() == null) {
                    continue;
                }
                if (!StringUtils.isEmpty(queryFilter)) {
                    queryFilter += "and";
                }
                queryFilter += " (" + entry.getValue().get(2) + ") ";
            }
        } else {
            queryFilter = queryFilterMap.isEmpty() ? queryFilterService.getQueryFilter(fse) : queryFilterMap.get(CmnConst.SYSTEM_SENIOR_QUERY_STRING).get(0);
        }
         if (!suitContent.equals(newContent)) {
            signCount++;
         }
         for (Map.Entry<String, String> entry : tempReplaceMap.entrySet()) {
            suitContent = suitContent.replace(entry.getKey(), entry.getValue());
         }
         tempReplaceMap.put(suitContent, newContent);
         sqlText = sqlText.replace(suitContent, newContent);
      }
      if ("1".equalsIgnoreCase(reportConfigFse.getString(CmnConst.IS_PAGE))) {
         int pageSize = reportConfigFse.getInteger(CmnConst.PAGE_SIZE) == null ? 20 : reportConfigFse.getInteger(CmnConst.PAGE_SIZE);
         sqlText = sqlText.replace(CmnConst.CONTENT_PAGE_AREA, "limit " + ((curPage - 1) * pageSize) + "," + pageSize);
      }
      // 三目表达式
      sqlText = replaceTernaryOperator(sqlText);
      // 清除已经处理的三目外的中括号
      suitList = getSuitContent(sqlText, CmnConst.REGEXP_FILTER_AREA);
      for (String suitContent : suitList) {
         newContent = suitContent.substring(2, suitContent.length() - 2);
         if (getSuitContent(newContent, CmnConst.REGEXP_SP_SIGN_AREA).isEmpty()) {
            sqlText = sqlText.replace(suitContent, newContent);
         }
      }
      // 剔除异常区域
      sqlText = sqlText.replaceAll(CmnConst.REGEXP_FILTER_AREA, "").replaceAll(CmnConst.REGEXP_ALL_TYPE, "null").replaceAll(CmnConst.REGEXP_ALWAYS_TRUE, "");
      String queryFilter = "";
      if (signCount > 0) {
         for (Map.Entry<String, List<String>> entry : residueQueryFilterMap.entrySet()) {
            if (CmnConst.SYSTEM_SENIOR_QUERY_STRING.equals(entry.getKey()) || entry.getValue() == null) {
               continue;
            }
            if (!StringUtils.isEmpty(queryFilter)) {
               queryFilter += "and";
            }
            queryFilter += " (" + entry.getValue().get(2) + ") ";
         }
      } else {
         queryFilter = queryFilterMap.isEmpty() ? queryFilterService.getQueryFilter(fse) : queryFilterMap.get(CmnConst.SYSTEM_SENIOR_QUERY_STRING).get(0);
      }
        StringBuilder sql = new StringBuilder(1024);
        sql.append("\nselect ").append(selectedFields).append(" from (\n")
                .append(sqlText)
                .append("\n) t");
        if (!StringUtils.isEmpty(queryFilter)) {
            sql.append("\nwhere ").append(queryFilter);
        }
      StringBuilder sql = new StringBuilder(1024);
      sql.append("\nselect ").append(selectedFields).append(" from (\n")
            .append(sqlText)
            .append("\n) t");
      if (!StringUtils.isEmpty(queryFilter)) {
         sql.append("\nwhere ").append(queryFilter);
      }
//        if (!StringUtils.isEmpty(sort)) {
//            sql.append("\norder by ").append(sort);
//        }
        return sql.toString();
    }
      return sql.toString();
   }
    private String replaceSqlContent(String sqlText, FieldSetEntity fse, StringBuilder sort, FieldSetEntity reportConfigFse, int curPage) {
        return replaceSqlContent(sqlText, fse, sort, reportConfigFse, curPage, null, null);
    }
   private String replaceSqlContent(String sqlText, FieldSetEntity fse, StringBuilder sort, FieldSetEntity reportConfigFse, int curPage) {
      return replaceSqlContent(sqlText, fse, sort, reportConfigFse, curPage, null, null);
   }
    /**
     * 特殊替换sql里面的内容
     *
     * @param suitContent
     * @param regexp
     * @param num
     * @param queryFilterMap
     * @return
     */
    private String spReplaceSqlContent(String suitContent, String regexp, int num, Map<String, List<String>> queryFilterMap, Map<String, List<String>> residueQueryFilterMap) {
        List<String> innerSuitList = getSuitContent(suitContent, regexp);
        String curField;
        String filter;
        String spStatisticsWay;
        String spStatisticsWayValue;
        for (String innerSuitContent : innerSuitList) {
            curField = innerSuitContent.substring(2, innerSuitContent.length() - 2);
            if (curField.contains(" ")) {
                spStatisticsWay = curField.substring(curField.indexOf(" ") + 1, curField.indexOf(":"));
                spStatisticsWayValue = curField.substring(curField.indexOf(":") + 1);
                curField = curField.substring(0, curField.indexOf(" "));
            } else {
                spStatisticsWay = "";
                spStatisticsWayValue = "";
            }
            if (queryFilterMap.get(curField) != null && !queryFilterMap.get(curField).isEmpty()) {
                Map<String, List<String>> tempQueryFilterMap = Maps.newHashMap();
                List<String> tempList;
                for (Map.Entry<String, List<String>> entry : queryFilterMap.entrySet()) {
                    tempList = Lists.newArrayList();
                    if (entry.getValue() == null) {
                        continue;
                    }
                    tempList.addAll(entry.getValue());
                    tempQueryFilterMap.put(entry.getKey(), tempList);
                }
                if ("sp_time_statistics_way".equals(spStatisticsWay)) {
                    if ("0".equals(spStatisticsWayValue)) {
                        // 去年同期
                        spDealFilterForLastYear(tempQueryFilterMap, queryFilterMap, curField);
                    } else if ("1".equals(spStatisticsWayValue)) {
                        // 上期
                        spDealFilterForPrePeriod(tempQueryFilterMap, queryFilterMap, curField);
                    }
                }
                filter = tempQueryFilterMap.get(curField).get(num);
                suitContent = suitContent.replace(innerSuitContent, filter);
                residueQueryFilterMap.remove(curField);
                if (getSuitContent(suitContent, CmnConst.REGEXP_ALL_TYPE).isEmpty() && suitContent.matches(CmnConst.REGEXP_FILTER_AREA)) {
                    suitContent = suitContent.substring(2, suitContent.length() - 2);
                }
            }
        }
        return suitContent;
    }
   /**
    * 特殊替换sql里面的内容
    *
    * @param suitContent
    * @param regexp
    * @param num
    * @param queryFilterMap
    * @return
    */
   private String spReplaceSqlContent(String suitContent, String regexp, int num, Map<String, List<String>> queryFilterMap, Map<String, List<String>> residueQueryFilterMap) {
      List<String> innerSuitList = getSuitContent(suitContent, regexp);
      String curField;
      String filter;
      String spStatisticsWay;
      String spStatisticsWayValue;
      for (String innerSuitContent : innerSuitList) {
         curField = innerSuitContent.substring(2, innerSuitContent.length() - 2);
         if (curField.contains(" ")) {
            spStatisticsWay = curField.substring(curField.indexOf(" ") + 1, curField.indexOf(":"));
            spStatisticsWayValue = curField.substring(curField.indexOf(":") + 1);
            curField = curField.substring(0, curField.indexOf(" "));
         } else {
            spStatisticsWay = "";
            spStatisticsWayValue = "";
         }
         if (queryFilterMap.get(curField) != null && !queryFilterMap.get(curField).isEmpty()) {
            Map<String, List<String>> tempQueryFilterMap = Maps.newHashMap();
            List<String> tempList;
            for (Map.Entry<String, List<String>> entry : queryFilterMap.entrySet()) {
               tempList = Lists.newArrayList();
               if (entry.getValue() == null) {
                  continue;
               }
               tempList.addAll(entry.getValue());
               tempQueryFilterMap.put(entry.getKey(), tempList);
            }
            if ("sp_time_statistics_way".equals(spStatisticsWay)) {
               if ("0".equals(spStatisticsWayValue)) {
                  // 去年同期
                  spDealFilterForLastYear(tempQueryFilterMap, queryFilterMap, curField);
               } else if ("1".equals(spStatisticsWayValue)) {
                  // 上期
                  spDealFilterForPrePeriod(tempQueryFilterMap, queryFilterMap, curField);
               }
            }
            filter = tempQueryFilterMap.get(curField).get(num);
            suitContent = suitContent.replace(innerSuitContent, filter);
            residueQueryFilterMap.remove(curField);
            if (getSuitContent(suitContent, CmnConst.REGEXP_ALL_TYPE).isEmpty() && suitContent.matches(CmnConst.REGEXP_FILTER_AREA)) {
               suitContent = suitContent.substring(2, suitContent.length() - 2);
            }
         }
      }
      return suitContent;
   }
    /**
     * 替换三目表达式内容
     *
     * @param sqlText
     * @return
     */
    private String replaceTernaryOperator(String sqlText) {
        List<String> suitList = getSuitContent(sqlText, CmnConst.REGEXP_ALL_TERNARY_OPERATOR);
        for (String suitContent : suitList) {
            String singleTernaryOperator = suitContent.substring(2, suitContent.length() - 2);
            String executeContent = singleTernaryOperator.replaceAll(CmnConst.REGEXP_ALL_TYPE, "null");
            Object result;
            String value;
            try {
                result = BaseUtil.executeExpression(executeContent);
                value = result.toString();
            } catch (Exception e) {
                SpringMVCContextHolder.getSystemLogger().error(e);
                value = "";
            }
            sqlText = sqlText.replace(suitContent, value);
        }
        return sqlText;
    }
   /**
    * 替换三目表达式内容
    *
    * @param sqlText
    * @return
    */
   private String replaceTernaryOperator(String sqlText) {
      List<String> suitList = getSuitContent(sqlText, CmnConst.REGEXP_ALL_TERNARY_OPERATOR);
      for (String suitContent : suitList) {
         String singleTernaryOperator = suitContent.substring(2, suitContent.length() - 2);
         String executeContent = singleTernaryOperator.replaceAll(CmnConst.REGEXP_ALL_TYPE, "null");
         Object result;
         String value;
         try {
            result = BaseUtil.executeExpression(executeContent);
            value = result.toString();
         } catch (Exception e) {
            SpringMVCContextHolder.getSystemLogger().error(e);
            value = "";
         }
         sqlText = sqlText.replace(suitContent, value);
      }
      return sqlText;
   }
    /**
     * 去年同期
     *
     * @param tempQueryFilterMap
     * @param queryFilterMap
     * @param curFieldName
     */
    private void spDealFilterForLastYear(Map<String, List<String>> tempQueryFilterMap, Map<String, List<String>> queryFilterMap, String curFieldName) {
        List<String> paramList = tempQueryFilterMap.get(curFieldName);
        for (int i = 0; i < paramList.size(); i++) {
            paramList.set(i, paramList.get(i).replace("str_to_date(", "date_add(str_to_date(")
                    .replace("'%Y')", "'%Y'),interval -1 year)")
                    .replace("'%Y-%m')", "'%Y-%m'),interval -1 year)")
                    .replace("'%Y-%m-%d')", "'%Y-%m-%d'),interval -1 year)")
                    .replace("'%Y-%m-%d %H')", "'%Y-%m-%d %H'),interval -1 year)")
                    .replace("'%Y-%m-%d %H:%i')", "'%Y-%m-%d %H:%i'),interval -1 year)")
                    .replace("'%Y-%m-%d %H:%i:%s')", "'%Y-%m-%d %H:%i:%s'),interval -1 year)"));
        }
        tempQueryFilterMap.put(CmnConst.SYSTEM_SENIOR_QUERY_STRING, Collections.singletonList(queryFilterMap.get(CmnConst.SYSTEM_SENIOR_QUERY_STRING).get(0).replace("str_to_date(", "date_add(str_to_date(").replace("'%Y-%m-%d %H:%i:%s')", "'%Y-%m-%d %H:%i:%s'),interval -1 year)")));
    }
   /**
    * 去年同期
    *
    * @param tempQueryFilterMap
    * @param queryFilterMap
    * @param curFieldName
    */
   private void spDealFilterForLastYear(Map<String, List<String>> tempQueryFilterMap, Map<String, List<String>> queryFilterMap, String curFieldName) {
      List<String> paramList = tempQueryFilterMap.get(curFieldName);
      for (int i = 0; i < paramList.size(); i++) {
         paramList.set(i, paramList.get(i).replace("str_to_date(", "date_add(str_to_date(")
               .replace("'%Y')", "'%Y'),interval -1 year)")
               .replace("'%Y-%m')", "'%Y-%m'),interval -1 year)")
               .replace("'%Y-%m-%d')", "'%Y-%m-%d'),interval -1 year)")
               .replace("'%Y-%m-%d %H')", "'%Y-%m-%d %H'),interval -1 year)")
               .replace("'%Y-%m-%d %H:%i')", "'%Y-%m-%d %H:%i'),interval -1 year)")
               .replace("'%Y-%m-%d %H:%i:%s')", "'%Y-%m-%d %H:%i:%s'),interval -1 year)"));
      }
      tempQueryFilterMap.put(CmnConst.SYSTEM_SENIOR_QUERY_STRING, Collections.singletonList(queryFilterMap.get(CmnConst.SYSTEM_SENIOR_QUERY_STRING).get(0).replace("str_to_date(", "date_add(str_to_date(").replace("'%Y-%m-%d %H:%i:%s')", "'%Y-%m-%d %H:%i:%s'),interval -1 year)")));
   }
    /**
     * 上期
     *
     * @param tempQueryFilterMap
     * @param queryFilterMap
     * @param curFieldName
     */
    private void spDealFilterForPrePeriod(Map<String, List<String>> tempQueryFilterMap, Map<String, List<String>> queryFilterMap, String curFieldName) {
        List<String> paramList = tempQueryFilterMap.get(curFieldName);
        String[] timeArr = paramList.get(0).split("~");
        try {
            String startTime = timeArr[0].trim().substring(13, 13 + 19);
            String finalTime = timeArr[1].trim().substring(13, 13 + 19);
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Calendar c1 = Calendar.getInstance();
            c1.setTime(simpleDateFormat.parse(startTime));
            Calendar c2 = Calendar.getInstance();
            c2.setTime(simpleDateFormat.parse(finalTime));
            long millisecond = c2.getTimeInMillis() - c1.getTimeInMillis();
            Calendar c3 = Calendar.getInstance();
            c3.setTimeInMillis(c1.getTimeInMillis() - millisecond);
            String newFinalTime = startTime;
            String newStartTime = simpleDateFormat.format(c3.getTime());
            for (int i = 0; i < paramList.size(); i++) {
                paramList.set(i, paramList.get(i).replace(startTime, newStartTime).replace(finalTime, newFinalTime));
            }
            tempQueryFilterMap.put(CmnConst.SYSTEM_SENIOR_QUERY_STRING, Collections.singletonList(queryFilterMap.get(CmnConst.SYSTEM_SENIOR_QUERY_STRING).get(0).replace(startTime, newStartTime).replace(finalTime, newFinalTime)));
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
   /**
    * 上期
    *
    * @param tempQueryFilterMap
    * @param queryFilterMap
    * @param curFieldName
    */
   private void spDealFilterForPrePeriod(Map<String, List<String>> tempQueryFilterMap, Map<String, List<String>> queryFilterMap, String curFieldName) {
      List<String> paramList = tempQueryFilterMap.get(curFieldName);
      String[] timeArr = paramList.get(0).split("~");
      try {
         String startTime = timeArr[0].trim().substring(13, 13 + 19);
         String finalTime = timeArr[1].trim().substring(13, 13 + 19);
         SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         Calendar c1 = Calendar.getInstance();
         c1.setTime(simpleDateFormat.parse(startTime));
         Calendar c2 = Calendar.getInstance();
         c2.setTime(simpleDateFormat.parse(finalTime));
         long millisecond = c2.getTimeInMillis() - c1.getTimeInMillis();
         Calendar c3 = Calendar.getInstance();
         c3.setTimeInMillis(c1.getTimeInMillis() - millisecond);
         String newFinalTime = startTime;
         String newStartTime = simpleDateFormat.format(c3.getTime());
         for (int i = 0; i < paramList.size(); i++) {
            paramList.set(i, paramList.get(i).replace(startTime, newStartTime).replace(finalTime, newFinalTime));
         }
         tempQueryFilterMap.put(CmnConst.SYSTEM_SENIOR_QUERY_STRING, Collections.singletonList(queryFilterMap.get(CmnConst.SYSTEM_SENIOR_QUERY_STRING).get(0).replace(startTime, newStartTime).replace(finalTime, newFinalTime)));
      } catch (ParseException e) {
         e.printStackTrace();
      }
   }
    /**
     * 获取特殊时间计算类型,注入查询字段
     *
     * @param baseFieldSet
     * @param spTimeStatisticsFieldMap
     * @param dataList
     * @return
     */
    private Set<String> getFieldAndSpTimeStatisticsTypeSet(Set<String> baseFieldSet, Map<String, Map<String, JSONObject>> spTimeStatisticsFieldMap, List<JSONObject> dataList) {
        Set<String> spTimeStatisticsTypeSet = Sets.newHashSet();
        JSONObject curFieldObj;
        String fieldName;
        Map<String, JSONObject> spTimeStatisticsFieldInnerMap;
        List<String> suitList;
        for (JSONObject obj : dataList) {
            for (Map.Entry<String, Object> entry : obj.entrySet()) {
                curFieldObj = (JSONObject) entry.getValue();
                fieldName = fieldInfo2FieldName(curFieldObj.getString(CmnConst.ATTR_FIELD_INFO));
                if ("1".equals(curFieldObj.getString(CmnConst.ATTR_IS_CUSTOM_FIELD))) {
                    if (!StringUtils.isEmpty(curFieldObj.getString(CmnConst.ATTR_SP_TIME_STATISTICS_WAY)) && !StringUtils.isEmpty(curFieldObj.getString(CmnConst.ATTR_RELATE_TIME_FIELD))
                            && !StringUtils.isEmpty(curFieldObj.getString(CmnConst.ATTR_RELATE_COMMON_FIELD))) {
                        if (spTimeStatisticsFieldMap.get(curFieldObj.getString(CmnConst.ATTR_SP_TIME_STATISTICS_WAY)) == null) {
                            spTimeStatisticsFieldInnerMap = Maps.newHashMap();
                            spTimeStatisticsFieldMap.put(curFieldObj.getString(CmnConst.ATTR_SP_TIME_STATISTICS_WAY), spTimeStatisticsFieldInnerMap);
                        } else {
                            spTimeStatisticsFieldInnerMap = spTimeStatisticsFieldMap.get(curFieldObj.getString(CmnConst.ATTR_SP_TIME_STATISTICS_WAY));
                        }
                        spTimeStatisticsFieldInnerMap.put(curFieldObj.getString(CmnConst.ATTR_RELATE_COMMON_FIELD), extendJSONObject(null, curFieldObj, Arrays.asList(CmnConst.ATTR_RELATE_TIME_FIELD, CmnConst.ATTR_RELATE_COMMON_FIELD)));
                        spTimeStatisticsTypeSet.add(curFieldObj.getString(CmnConst.ATTR_SP_TIME_STATISTICS_WAY));
                    } else if (!StringUtils.isEmpty(curFieldObj.getString(CmnConst.ATTR_FORMULA))) {
                        // todo
                        suitList = getSuitContent(curFieldObj.getString(CmnConst.ATTR_FORMULA), "\\{#((?!\\{).)+#\\}");
                        for (String suitContent : suitList) {
                            if (suitContent.matches("\\{#custom_field_\\d+#\\}")) {
                                continue;
                            }
                            baseFieldSet.add(fieldInfo2FieldName(suitContent));
                        }
                    }
                } else {
                    baseFieldSet.add(fieldInfo2FieldName(fieldName));
                }
            }
        }
        return spTimeStatisticsTypeSet;
    }
   /**
    * 获取特殊时间计算类型,注入查询字段
    *
    * @param baseFieldSet
    * @param spTimeStatisticsFieldMap
    * @param dataList
    * @return
    */
   private Set<String> getFieldAndSpTimeStatisticsTypeSet(Set<String> baseFieldSet, Map<String, Map<String, JSONObject>> spTimeStatisticsFieldMap, List<JSONObject> dataList) {
      Set<String> spTimeStatisticsTypeSet = Sets.newHashSet();
      JSONObject curFieldObj;
      String fieldName;
      Map<String, JSONObject> spTimeStatisticsFieldInnerMap;
      List<String> suitList;
      for (JSONObject obj : dataList) {
         for (Map.Entry<String, Object> entry : obj.entrySet()) {
            curFieldObj = (JSONObject) entry.getValue();
            fieldName = fieldInfo2FieldName(curFieldObj.getString(CmnConst.ATTR_FIELD_INFO));
            if ("1".equals(curFieldObj.getString(CmnConst.ATTR_IS_CUSTOM_FIELD))) {
               if (!StringUtils.isEmpty(curFieldObj.getString(CmnConst.ATTR_SP_TIME_STATISTICS_WAY)) && !StringUtils.isEmpty(curFieldObj.getString(CmnConst.ATTR_RELATE_TIME_FIELD))
                     && !StringUtils.isEmpty(curFieldObj.getString(CmnConst.ATTR_RELATE_COMMON_FIELD))) {
                  if (spTimeStatisticsFieldMap.get(curFieldObj.getString(CmnConst.ATTR_SP_TIME_STATISTICS_WAY)) == null) {
                     spTimeStatisticsFieldInnerMap = Maps.newHashMap();
                     spTimeStatisticsFieldMap.put(curFieldObj.getString(CmnConst.ATTR_SP_TIME_STATISTICS_WAY), spTimeStatisticsFieldInnerMap);
                  } else {
                     spTimeStatisticsFieldInnerMap = spTimeStatisticsFieldMap.get(curFieldObj.getString(CmnConst.ATTR_SP_TIME_STATISTICS_WAY));
                  }
                  spTimeStatisticsFieldInnerMap.put(curFieldObj.getString(CmnConst.ATTR_RELATE_COMMON_FIELD), extendJSONObject(null, curFieldObj, Arrays.asList(CmnConst.ATTR_RELATE_TIME_FIELD, CmnConst.ATTR_RELATE_COMMON_FIELD)));
                  spTimeStatisticsTypeSet.add(curFieldObj.getString(CmnConst.ATTR_SP_TIME_STATISTICS_WAY));
               } else if (!StringUtils.isEmpty(curFieldObj.getString(CmnConst.ATTR_FORMULA))) {
                  // todo
                  suitList = getSuitContent(curFieldObj.getString(CmnConst.ATTR_FORMULA), "\\{#((?!\\{).)+#\\}");
                  for (String suitContent : suitList) {
                     if (suitContent.matches("\\{#custom_field_\\d+#\\}")) {
                        continue;
                     }
                     baseFieldSet.add(fieldInfo2FieldName(suitContent));
                  }
               }
            } else {
               baseFieldSet.add(fieldInfo2FieldName(fieldName));
            }
         }
      }
      return spTimeStatisticsTypeSet;
   }
    /**
     * 检测数据源
     *
     * @param recordDte 数据源集合
     * @return
     */
    private JSONObject checkRecordDte(DataTableEntity recordDte) {
        JSONObject resultObj = new JSONObject();
        boolean resultFlag = true;
        if (BaseUtil.dataTableIsEmpty(recordDte)) {
            resultFlag = false;
            resultObj.put(CmnConst.RETURN_ATTR_MESSAGE, "数据源为空!");
        }
        resultObj.put(CmnConst.RETURN_ATTR_RESULT, resultFlag);
        return resultObj;
    }
   /**
    * 检测数据源
    *
    * @param recordDte 数据源集合
    * @return
    */
   private JSONObject checkRecordDte(DataTableEntity recordDte) {
      JSONObject resultObj = new JSONObject();
      boolean resultFlag = true;
      if (BaseUtil.dataTableIsEmpty(recordDte)) {
         resultFlag = false;
         resultObj.put(CmnConst.RETURN_ATTR_MESSAGE, "数据源为空!");
      }
      resultObj.put(CmnConst.RETURN_ATTR_RESULT, resultFlag);
      return resultObj;
   }
    /**
     * 获取查询条件
     *
     * @param reportDatasourceUUID 报表数据源uuid
     * @return
     */
    private JSONArray getSearchInfo(String reportDatasourceUUID) {
        DataTableEntity reportSourceFieldDte = DataPoolCacheImpl.getInstance().getCacheData(CmnConst.CACHE_REPORT_DATASOURCE_FIELD_CONFIG, new String[]{reportDatasourceUUID});
        JSONArray resultArray = new JSONArray();
        if (!BaseUtil.dataTableIsEmpty(reportSourceFieldDte)) {
            FieldSetEntity reportSourceFieldFse;
            JSONObject tempObj;
            reportSourceFieldDte.getData().sort(Comparator.comparing(a -> a.getInteger("id")));
            for (int i = 0; i < reportSourceFieldDte.getRows(); i++) {
                reportSourceFieldFse = reportSourceFieldDte.getFieldSetEntity(i);
                if (!StringUtils.isEmpty(reportSourceFieldFse.getString(CmnConst.SEARCH_TYPE)) && !"-1".equals(reportSourceFieldFse.getString(CmnConst.SEARCH_TYPE))) {
                    tempObj = new JSONObject();
                    resultArray.add(tempObj);
                    tempObj.put("field_name", reportSourceFieldFse.getString(CmnConst.FIELD_NAME));
                    tempObj.put("temp_id", reportSourceFieldFse.getString(CmnConst.FIELD_NAME));
                    tempObj.put("field_show_name", reportSourceFieldFse.getString(CmnConst.FIELD_TEXT));
                    tempObj.put("field_type", "date".equals(reportSourceFieldFse.getString(CmnConst.FIELD_FORMAT)) ? "datetime" : ("num".equals(reportSourceFieldFse.getString(CmnConst.FIELD_FORMAT)) ? "number" : reportSourceFieldFse.getString(CmnConst.FIELD_FORMAT)));
                    tempObj.put("field_reference", reportSourceFieldFse.getString(CmnConst.FIELD_PROMPT));
                    tempObj.put("table_name", reportSourceFieldFse.getString(CmnConst.TABLE_NAME));
                    tempObj.put(CmnConst.SEARCH_TYPE, reportSourceFieldFse.getObject(CmnConst.SEARCH_TYPE));
                    tempObj.put("is_multiple", "2".equals(reportSourceFieldFse.getString(CmnConst.SEARCH_TYPE)));
                }
            }
        }
        return resultArray;
    }
   /**
    * 获取查询条件
    *
    * @param reportDatasourceUUID 报表数据源uuid
    * @return
    */
   private JSONArray getSearchInfo(String reportDatasourceUUID) {
      DataTableEntity reportSourceFieldDte = DataPoolCacheImpl.getInstance().getCacheData(CmnConst.CACHE_REPORT_DATASOURCE_FIELD_CONFIG, new String[]{reportDatasourceUUID});
      JSONArray resultArray = new JSONArray();
      if (!BaseUtil.dataTableIsEmpty(reportSourceFieldDte)) {
         FieldSetEntity reportSourceFieldFse;
         JSONObject tempObj;
         reportSourceFieldDte.getData().sort(Comparator.comparing(a -> a.getInteger("id")));
         for (int i = 0; i < reportSourceFieldDte.getRows(); i++) {
            reportSourceFieldFse = reportSourceFieldDte.getFieldSetEntity(i);
            if (!StringUtils.isEmpty(reportSourceFieldFse.getString(CmnConst.SEARCH_TYPE)) && !"-1".equals(reportSourceFieldFse.getString(CmnConst.SEARCH_TYPE))) {
               tempObj = new JSONObject();
               resultArray.add(tempObj);
               tempObj.put("field_name", reportSourceFieldFse.getString(CmnConst.FIELD_NAME));
               tempObj.put("temp_id", reportSourceFieldFse.getString(CmnConst.FIELD_NAME));
               tempObj.put("field_show_name", reportSourceFieldFse.getString(CmnConst.FIELD_TEXT));
               tempObj.put("field_type", "date".equals(reportSourceFieldFse.getString(CmnConst.FIELD_FORMAT)) ? "datetime" : ("num".equals(reportSourceFieldFse.getString(CmnConst.FIELD_FORMAT)) ? "number" : reportSourceFieldFse.getString(CmnConst.FIELD_FORMAT)));
               tempObj.put("field_reference", reportSourceFieldFse.getString(CmnConst.FIELD_PROMPT));
               tempObj.put("table_name", reportSourceFieldFse.getString(CmnConst.TABLE_NAME));
               tempObj.put(CmnConst.SEARCH_TYPE, reportSourceFieldFse.getObject(CmnConst.SEARCH_TYPE));
               tempObj.put("is_multiple", "2".equals(reportSourceFieldFse.getString(CmnConst.SEARCH_TYPE)));
            }
         }
      }
      return resultArray;
   }
    /**
     * 获取默认查询条件
     *
     * @param reportDatasourceUUID 报表数据源uuid
     * @return
     */
    private DataTableEntity getDefaultSearchFilter(String reportDatasourceUUID) {
        DataTableEntity reportSourceFieldDte = DataPoolCacheImpl.getInstance().getCacheData(CmnConst.CACHE_REPORT_DATASOURCE_FIELD_CONFIG, new String[]{reportDatasourceUUID});
        DataTableEntity dte = new DataTableEntity();
        if (!BaseUtil.dataTableIsEmpty(reportSourceFieldDte)) {
            FieldSetEntity reportSourceFieldFse;
            FieldSetEntity fse;
            for (int i = 0; i < reportSourceFieldDte.getRows(); i++) {
                reportSourceFieldFse = reportSourceFieldDte.getFieldSetEntity(i);
                if (!StringUtils.isEmpty(reportSourceFieldFse.getString(CmnConst.SEARCH_TYPE)) && !"-1".equals(reportSourceFieldFse.getString(CmnConst.SEARCH_TYPE))) {
                    fse = new FieldSetEntity();
                    fse.setTableName("temp_table");
                    fse.setValue("field_name", reportSourceFieldFse.getString(CmnConst.FIELD_NAME));
                    fse.setValue("field_show_name", reportSourceFieldFse.getString(CmnConst.FIELD_TEXT));
                    fse.setValue("field_type", "date".equals(reportSourceFieldFse.getString(CmnConst.FIELD_FORMAT)) ? "datetime" : ("num".equals(reportSourceFieldFse.getString(CmnConst.FIELD_FORMAT)) ? "number" : reportSourceFieldFse.getString(CmnConst.FIELD_FORMAT)));
                    fse.setValue("field_reference", reportSourceFieldFse.getString(CmnConst.FIELD_PROMPT));
                    fse.setValue("table_name", reportSourceFieldFse.getString(CmnConst.TABLE_NAME));
                    fse.setValue(CmnConst.SEARCH_TYPE, reportSourceFieldFse.getObject(CmnConst.SEARCH_TYPE));
                    fse.setValue("is_multiple", "2".equals(reportSourceFieldFse.getString(CmnConst.SEARCH_TYPE)));
                    fse.setValue(CmnConst.LOGICAL_OPERATOR, reportSourceFieldFse.getString(CmnConst.LOGICAL_OPERATOR));
                    fse.setValue(CmnConst.LOGICAL_VALUE, reportSourceFieldFse.getString(CmnConst.LOGICAL_VALUE));
                    dte.addFieldSetEntity(fse);
                }
            }
        }
        return dte;
    }
   /**
    * 获取默认查询条件
    *
    * @param reportDatasourceUUID 报表数据源uuid
    * @return
    */
   private DataTableEntity getDefaultSearchFilter(String reportDatasourceUUID) {
      DataTableEntity reportSourceFieldDte = DataPoolCacheImpl.getInstance().getCacheData(CmnConst.CACHE_REPORT_DATASOURCE_FIELD_CONFIG, new String[]{reportDatasourceUUID});
      DataTableEntity dte = new DataTableEntity();
      if (!BaseUtil.dataTableIsEmpty(reportSourceFieldDte)) {
         FieldSetEntity reportSourceFieldFse;
         FieldSetEntity fse;
         for (int i = 0; i < reportSourceFieldDte.getRows(); i++) {
            reportSourceFieldFse = reportSourceFieldDte.getFieldSetEntity(i);
            if (!StringUtils.isEmpty(reportSourceFieldFse.getString(CmnConst.SEARCH_TYPE)) && !"-1".equals(reportSourceFieldFse.getString(CmnConst.SEARCH_TYPE))) {
               fse = new FieldSetEntity();
               fse.setTableName("temp_table");
               fse.setValue("field_name", reportSourceFieldFse.getString(CmnConst.FIELD_NAME));
               fse.setValue("field_show_name", reportSourceFieldFse.getString(CmnConst.FIELD_TEXT));
               fse.setValue("field_type", "date".equals(reportSourceFieldFse.getString(CmnConst.FIELD_FORMAT)) ? "datetime" : ("num".equals(reportSourceFieldFse.getString(CmnConst.FIELD_FORMAT)) ? "number" : reportSourceFieldFse.getString(CmnConst.FIELD_FORMAT)));
               fse.setValue("field_reference", reportSourceFieldFse.getString(CmnConst.FIELD_PROMPT));
               fse.setValue("table_name", reportSourceFieldFse.getString(CmnConst.TABLE_NAME));
               fse.setValue(CmnConst.SEARCH_TYPE, reportSourceFieldFse.getObject(CmnConst.SEARCH_TYPE));
               fse.setValue("is_multiple", "2".equals(reportSourceFieldFse.getString(CmnConst.SEARCH_TYPE)));
               fse.setValue(CmnConst.LOGICAL_OPERATOR, reportSourceFieldFse.getString(CmnConst.LOGICAL_OPERATOR));
               fse.setValue(CmnConst.LOGICAL_VALUE, reportSourceFieldFse.getString(CmnConst.LOGICAL_VALUE));
               dte.addFieldSetEntity(fse);
            }
         }
      }
      return dte;
   }
    /**
     * 分组区和数据区特殊转换
     *
     * @param list
     * @return
     */
    public Map<String, JSONObject> groupAndDataJSONObject2Map(List<JSONObject> list) {
        Map<String, JSONObject> map = Maps.newLinkedHashMap();
        for (JSONObject jsonObject : list) {
            for (Map.Entry<String, Object> fieldEntry : jsonObject.entrySet()) {
                map.put(fieldEntry.getKey(), (JSONObject) fieldEntry.getValue());
            }
        }
        return map;
    }
   /**
    * 分组区和数据区特殊转换
    *
    * @param list
    * @return
    */
   public Map<String, JSONObject> groupAndDataJSONObject2Map(List<JSONObject> list) {
      Map<String, JSONObject> map = Maps.newLinkedHashMap();
      for (JSONObject jsonObject : list) {
         for (Map.Entry<String, Object> fieldEntry : jsonObject.entrySet()) {
            map.put(fieldEntry.getKey(), (JSONObject) fieldEntry.getValue());
         }
      }
      return map;
   }
    /**
     * 报表-解析-获取头部或者尾部标题Html
     *
     * @param list                    报表配置信息,缓存list
     * @param totalColCount           总列数
     * @param headAndTailTitleDataMap 头部、尾部标题区数据字段map
     * @param locationType            位置类型,head-头部,tail-尾部
     * @return
     */
    public StringBuilder getTitleHtml(List<JSONObject> list, int totalColCount, Map<String, Set<String>> headAndTailTitleDataMap, String locationType) {
        StringBuilder html = new StringBuilder(1024);
        int colspan;
        int preRow = 0;
        int preCol = 0;
        int curRow;
        int curCol;
        String value;
        String style;
        for (JSONObject singleObj : list) {
            curRow = singleObj.getIntValue(CmnConst.ATTR_Y);
            curCol = singleObj.getIntValue(CmnConst.ATTR_X);
            colspan = singleObj.getIntValue(CmnConst.ATTR_COLSPAN);
            colspan = colspan < 0 ? totalColCount : Math.max(1, colspan);
            value = replaceFormDataAndSysData(singleObj.getString(CmnConst.ATTR_SHOW_NAME), headAndTailTitleDataMap, singleObj);
            value = value == null ? "" : value;
            if ("1".equals(singleObj.getString(CmnConst.ATTR_IS_TITLE))) {
                style = " class=\"" + CmnConst.CLASS_TR_REPORT_TITLE + "\"";
            } else {
                if ("head".equals(locationType)) {
                    style = " class=\"" + CmnConst.CLASS_TR_HEAD + "\"";
                } else {
                    style = " class=\"" + CmnConst.CLASS_TR_TAIL + "\"";
                }
            }
            if (preRow < curRow) {
                if (preRow == 0) {
                    html.append("\n<tr ");
                } else {
                    html.append(getAimNumTdPlaceholder(totalColCount - preCol, 1));
                    html.append("\n</tr>\n<tr ");
                }
                html.append(style).append(">\n    ");
                if (preRow == 0 && preCol == 0 && preCol < curCol - 1) {
                    html.append(getAimNumTdPlaceholder(curCol - preCol - 1, 1));
                }
                preCol = curCol;
            }
            if (preCol < curCol - 1) {
                html.append(getAimNumTdPlaceholder(curCol - preCol - 1, 1));
            }
            if ("1".equals(singleObj.getString(CmnConst.ATTR_IS_TITLE))) {
                colspan = totalColCount;
            }
            html.append("<td colspan=\"").append(colspan).append("\">").append(value).append("</td>");
            preRow = curRow;
            preCol = curCol + singleObj.getIntValue(CmnConst.ATTR_COLSPAN) - 1;
            if ("1".equals(singleObj.getString(CmnConst.ATTR_IS_TITLE))) {
                preCol = totalColCount;
            }
        }
        if (html.length() > 5) {
            html.delete(html.length() - 5, html.length());
        }
        html.append(getAimNumTdPlaceholder(totalColCount - preCol, 1));
        html.append("\n</tr>");
        return html;
    }
   /**
    * 报表-解析-获取头部或者尾部标题Html
    *
    * @param list                    报表配置信息,缓存list
    * @param totalColCount           总列数
    * @param headAndTailTitleDataMap 头部、尾部标题区数据字段map
    * @param locationType            位置类型,head-头部,tail-尾部
    * @return
    */
   public StringBuilder getTitleHtml(List<JSONObject> list, int totalColCount, Map<String, Set<String>> headAndTailTitleDataMap, String locationType) {
      StringBuilder html = new StringBuilder(1024);
      int colspan;
      int preRow = 0;
      int preCol = 0;
      int curRow;
      int curCol;
      String value;
      String style;
      for (JSONObject singleObj : list) {
         curRow = singleObj.getIntValue(CmnConst.ATTR_Y);
         curCol = singleObj.getIntValue(CmnConst.ATTR_X);
         colspan = singleObj.getIntValue(CmnConst.ATTR_COLSPAN);
         colspan = colspan < 0 ? totalColCount : Math.max(1, colspan);
         value = replaceFormDataAndSysData(singleObj.getString(CmnConst.ATTR_SHOW_NAME), headAndTailTitleDataMap, singleObj);
         value = value == null ? "" : value;
         if ("1".equals(singleObj.getString(CmnConst.ATTR_IS_TITLE))) {
            style = " class=\"" + CmnConst.CLASS_TR_REPORT_TITLE + "\"";
         } else {
            if ("head".equals(locationType)) {
               style = " class=\"" + CmnConst.CLASS_TR_HEAD + "\"";
            } else {
               style = " class=\"" + CmnConst.CLASS_TR_TAIL + "\"";
            }
         }
         if (preRow < curRow) {
            if (preRow == 0) {
               html.append("\n<tr ");
            } else {
               html.append(getAimNumTdPlaceholder(totalColCount - preCol, 1));
               html.append("\n</tr>\n<tr ");
            }
            html.append(style).append(">\n    ");
            if (preRow == 0 && preCol == 0 && preCol < curCol - 1) {
               html.append(getAimNumTdPlaceholder(curCol - preCol - 1, 1));
            }
            preCol = curCol;
         }
         if (preCol < curCol - 1) {
            html.append(getAimNumTdPlaceholder(curCol - preCol - 1, 1));
         }
         if ("1".equals(singleObj.getString(CmnConst.ATTR_IS_TITLE))) {
            colspan = totalColCount;
         }
         html.append("<td colspan=\"").append(colspan).append("\">").append(value).append("</td>");
         preRow = curRow;
         preCol = curCol + singleObj.getIntValue(CmnConst.ATTR_COLSPAN) - 1;
         if ("1".equals(singleObj.getString(CmnConst.ATTR_IS_TITLE))) {
            preCol = totalColCount;
         }
      }
      if (html.length() > 5) {
         html.delete(html.length() - 5, html.length());
      }
      html.append(getAimNumTdPlaceholder(totalColCount - preCol, 1));
      html.append("\n</tr>");
      return html;
   }
    /**
     * 获取指定数据集中包含的数据区字段集合
     *
     * @param list 指定数据集合
     * @return
     */
    public Set<String> getDataFields(List<JSONObject> list) {
        Set<String> set = Sets.newLinkedHashSet();
        if (list == null) {
            return set;
        }
        String fieldInfo;
        List<String> suitList;
        for (JSONObject tempObj : list) {
            fieldInfo = tempObj.getString(CmnConst.ATTR_FIELD_INFO);
            suitList = getSuitContent(fieldInfo, CmnConst.REGEXP_FORM_FIELD);
            if (!suitList.isEmpty()) {
                for (String singleFieldInfo : suitList) {
                    set.add(fieldInfo2FieldName(singleFieldInfo));
                }
            }
        }
        return set;
    }
   /**
    * 获取指定数据集中包含的数据区字段集合
    *
    * @param list 指定数据集合
    * @return
    */
   public Set<String> getDataFields(List<JSONObject> list) {
      Set<String> set = Sets.newLinkedHashSet();
      if (list == null) {
         return set;
      }
      String fieldInfo;
      List<String> suitList;
      for (JSONObject tempObj : list) {
         fieldInfo = tempObj.getString(CmnConst.ATTR_FIELD_INFO);
         suitList = getSuitContent(fieldInfo, CmnConst.REGEXP_FORM_FIELD);
         if (!suitList.isEmpty()) {
            for (String singleFieldInfo : suitList) {
               set.add(fieldInfo2FieldName(singleFieldInfo));
            }
         }
      }
      return set;
   }
    /**
     * 获取统计map的value
     *
     * @param valueJsonObject        值obj
     * @param dataAreaFieldConfigObj 数据区字段缓存obj
     * @param actualValue            实际值
     * @param type                   统计类型
     * @param lastStageFlag          是否末级(数据区分组字段末级和分组表头区字段都是末级才为末级)
     * @return
     */
    public JSONObject getStatisticsValueObj(JSONObject valueJsonObject, JSONObject dataAreaFieldConfigObj, String actualValue, String type, boolean lastStageFlag) {
        if (valueJsonObject == null) {
            valueJsonObject = new JSONObject();
        }
        if (actualValue.matches(CmnConst.REGEXP_NUMBER)) {
            BigDecimal curValue = new BigDecimal(actualValue);
            if (CmnConst.ATTR_STATISTICS_SUM.equals(type) || CmnConst.ATTR_STATISTICS_AVG.equals(type)) {
                valueJsonObject.put(CmnConst.ATTR_STATISTICS_SUM, valueJsonObject.getBigDecimal(CmnConst.ATTR_STATISTICS_SUM) != null ? valueJsonObject.getBigDecimal(CmnConst.ATTR_STATISTICS_SUM).add(curValue) : curValue);
            }
            if (CmnConst.ATTR_STATISTICS_MAX.equals(type)) {
                valueJsonObject.put(CmnConst.ATTR_STATISTICS_MAX, valueJsonObject.getBigDecimal(CmnConst.ATTR_STATISTICS_MAX) != null && valueJsonObject.getBigDecimal(CmnConst.ATTR_STATISTICS_MAX).compareTo(curValue) > 0 ? valueJsonObject.getBigDecimal(CmnConst.ATTR_STATISTICS_MAX) : curValue);
            }
            if (CmnConst.ATTR_STATISTICS_MIN.equals(type)) {
                valueJsonObject.put(CmnConst.ATTR_STATISTICS_MIN, valueJsonObject.getBigDecimal(CmnConst.ATTR_STATISTICS_MIN) != null && valueJsonObject.getBigDecimal(CmnConst.ATTR_STATISTICS_MIN).compareTo(curValue) < 0 ? valueJsonObject.getBigDecimal(CmnConst.ATTR_STATISTICS_MIN) : curValue);
            }
            if (CmnConst.ATTR_STATISTICS_DEFAULT.equals(type)) {
                valueJsonObject.put(CmnConst.ATTR_STATISTICS_DEFAULT, valueJsonObject.getBigDecimal(CmnConst.ATTR_STATISTICS_SUM) != null ? valueJsonObject.getBigDecimal(CmnConst.ATTR_STATISTICS_SUM).add(curValue) : curValue);
            }
        }
        if (CmnConst.ATTR_STATISTICS_CNT.equals(type) || CmnConst.ATTR_STATISTICS_AVG.equals(type)) {
            valueJsonObject.put(CmnConst.ATTR_STATISTICS_CNT, valueJsonObject.getIntValue(CmnConst.ATTR_STATISTICS_CNT) + 1);
        }
        if (CmnConst.ATTR_STATISTICS_ENUM.equals(type) && !StringUtils.isEmpty(actualValue)) {
            String preEnumValue = valueJsonObject.get(CmnConst.ATTR_STATISTICS_ENUM) == null ? "" : valueJsonObject.getString(CmnConst.ATTR_STATISTICS_ENUM);
            if ("1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_ENUM_TYPE))) {
                if (!checkContain(preEnumValue, actualValue)) {
                    valueJsonObject.put(CmnConst.ATTR_STATISTICS_ENUM, StringUtils.isEmpty(preEnumValue) ? actualValue : preEnumValue + "," + actualValue);
                }
            } else {
                valueJsonObject.put(CmnConst.ATTR_STATISTICS_ENUM, StringUtils.isEmpty(preEnumValue) ? actualValue : preEnumValue + "," + actualValue);
            }
        }
        getAvgValue(valueJsonObject, dataAreaFieldConfigObj, lastStageFlag);
        return valueJsonObject;
    }
   /**
    * 获取统计map的value
    *
    * @param valueJsonObject        值obj
    * @param dataAreaFieldConfigObj 数据区字段缓存obj
    * @param actualValue            实际值
    * @param type                   统计类型
    * @param lastStageFlag          是否末级(数据区分组字段末级和分组表头区字段都是末级才为末级)
    * @return
    */
   public JSONObject getStatisticsValueObj(JSONObject valueJsonObject, JSONObject dataAreaFieldConfigObj, String actualValue, String type, boolean lastStageFlag) {
      if (valueJsonObject == null) {
         valueJsonObject = new JSONObject();
      }
      if (actualValue.matches(CmnConst.REGEXP_NUMBER)) {
         BigDecimal curValue = new BigDecimal(actualValue);
         if (CmnConst.ATTR_STATISTICS_SUM.equals(type) || CmnConst.ATTR_STATISTICS_AVG.equals(type)) {
            valueJsonObject.put(CmnConst.ATTR_STATISTICS_SUM, valueJsonObject.getBigDecimal(CmnConst.ATTR_STATISTICS_SUM) != null ? valueJsonObject.getBigDecimal(CmnConst.ATTR_STATISTICS_SUM).add(curValue) : curValue);
         }
         if (CmnConst.ATTR_STATISTICS_MAX.equals(type)) {
            valueJsonObject.put(CmnConst.ATTR_STATISTICS_MAX, valueJsonObject.getBigDecimal(CmnConst.ATTR_STATISTICS_MAX) != null && valueJsonObject.getBigDecimal(CmnConst.ATTR_STATISTICS_MAX).compareTo(curValue) > 0 ? valueJsonObject.getBigDecimal(CmnConst.ATTR_STATISTICS_MAX) : curValue);
         }
         if (CmnConst.ATTR_STATISTICS_MIN.equals(type)) {
            valueJsonObject.put(CmnConst.ATTR_STATISTICS_MIN, valueJsonObject.getBigDecimal(CmnConst.ATTR_STATISTICS_MIN) != null && valueJsonObject.getBigDecimal(CmnConst.ATTR_STATISTICS_MIN).compareTo(curValue) < 0 ? valueJsonObject.getBigDecimal(CmnConst.ATTR_STATISTICS_MIN) : curValue);
         }
         if (CmnConst.ATTR_STATISTICS_DEFAULT.equals(type)) {
            valueJsonObject.put(CmnConst.ATTR_STATISTICS_DEFAULT, valueJsonObject.getBigDecimal(CmnConst.ATTR_STATISTICS_SUM) != null ? valueJsonObject.getBigDecimal(CmnConst.ATTR_STATISTICS_SUM).add(curValue) : curValue);
         }
      }
      if (CmnConst.ATTR_STATISTICS_CNT.equals(type) || CmnConst.ATTR_STATISTICS_AVG.equals(type)) {
         valueJsonObject.put(CmnConst.ATTR_STATISTICS_CNT, valueJsonObject.getIntValue(CmnConst.ATTR_STATISTICS_CNT) + 1);
      }
      if (CmnConst.ATTR_STATISTICS_ENUM.equals(type) && !StringUtils.isEmpty(actualValue)) {
         String preEnumValue = valueJsonObject.get(CmnConst.ATTR_STATISTICS_ENUM) == null ? "" : valueJsonObject.getString(CmnConst.ATTR_STATISTICS_ENUM);
         if ("1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_ENUM_TYPE))) {
            if (!checkContain(preEnumValue, actualValue)) {
               valueJsonObject.put(CmnConst.ATTR_STATISTICS_ENUM, StringUtils.isEmpty(preEnumValue) ? actualValue : preEnumValue + "," + actualValue);
            }
         } else {
            valueJsonObject.put(CmnConst.ATTR_STATISTICS_ENUM, StringUtils.isEmpty(preEnumValue) ? actualValue : preEnumValue + "," + actualValue);
         }
      }
      getAvgValue(valueJsonObject, dataAreaFieldConfigObj, lastStageFlag);
      return valueJsonObject;
   }
    /**
     * 计算平均值
     *
     * @param valueJsonObject        值obj
     * @param dataAreaFieldConfigObj 数据区字段缓存obj
     * @param lastStageFlag          末级字段标识
     * @return
     */
    public void getAvgValue(JSONObject valueJsonObject, JSONObject dataAreaFieldConfigObj, boolean lastStageFlag) {
        if (CmnConst.ATTR_STATISTICS_AVG.equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_STATISTICS))) {
            Double cnt = valueJsonObject.getDoubleValue(CmnConst.ATTR_STATISTICS_CNT);
            if (!lastStageFlag && "1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_AVG_TYPE))) {
                cnt = valueJsonObject.getDoubleValue(CmnConst.ATTR_STATISTICS_SUB_CNT);
            }
            valueJsonObject.put(CmnConst.ATTR_STATISTICS_AVG, valueJsonObject.getDoubleValue(CmnConst.ATTR_STATISTICS_SUM) / (cnt == 0 ? 1 : cnt));
        }
    }
   /**
    * 计算平均值
    *
    * @param valueJsonObject        值obj
    * @param dataAreaFieldConfigObj 数据区字段缓存obj
    * @param lastStageFlag          末级字段标识
    * @return
    */
   public void getAvgValue(JSONObject valueJsonObject, JSONObject dataAreaFieldConfigObj, boolean lastStageFlag) {
      if (CmnConst.ATTR_STATISTICS_AVG.equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_STATISTICS))) {
         Double cnt = valueJsonObject.getDoubleValue(CmnConst.ATTR_STATISTICS_CNT);
         if (!lastStageFlag && "1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_AVG_TYPE))) {
            cnt = valueJsonObject.getDoubleValue(CmnConst.ATTR_STATISTICS_SUB_CNT);
         }
         valueJsonObject.put(CmnConst.ATTR_STATISTICS_AVG, valueJsonObject.getDoubleValue(CmnConst.ATTR_STATISTICS_SUM) / (cnt == 0 ? 1 : cnt));
      }
   }
    /**
     * 获取头部、尾部标题数据字段
     *
     * @param headAndTailTitleDataMap
     * @param set
     * @param recordFse
     */
    public void getHeadAndTailTitleDataMap(Map<String, Set<String>> headAndTailTitleDataMap, Set<String> set, FieldSetEntity recordFse) {
        for (String fieldName : set) {
            headAndTailTitleDataMap.computeIfAbsent(fieldName, k -> Sets.newLinkedHashSet()).add(recordFse.getString(fieldName));
        }
    }
   /**
    * 获取头部、尾部标题数据字段
    *
    * @param headAndTailTitleDataMap
    * @param set
    * @param recordFse
    */
   public void getHeadAndTailTitleDataMap(Map<String, Set<String>> headAndTailTitleDataMap, Set<String> set, FieldSetEntity recordFse) {
      for (String fieldName : set) {
         headAndTailTitleDataMap.computeIfAbsent(fieldName, k -> Sets.newLinkedHashSet()).add(recordFse.getString(fieldName));
      }
   }
    /**
     * 获取值
     *
     * @param dataAreaFieldConfigObj
     * @param recordFse
     * @param dataAreaFieldName
     * @return
     */
    public String getValue(JSONObject dataAreaFieldConfigObj, FieldSetEntity recordFse, String dataAreaFieldName) {
        String value = null;
   /**
    * 获取值
    *
    * @param dataAreaFieldConfigObj
    * @param recordFse
    * @param dataAreaFieldName
    * @return
    */
   public String getValue(JSONObject dataAreaFieldConfigObj, FieldSetEntity recordFse, String dataAreaFieldName) {
      String value = null;
        if (CmnConst.ATTR_DATA_TYPE_DATE.equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_DATA_TYPE))) {
            String dateFormat = dataAreaFieldConfigObj.getString(CmnConst.ATTR_DATE_FORMAT);
            if (!StringUtils.isEmpty(dateFormat)) {
                value = recordFse.getDate(dataAreaFieldName, dateFormat);
            }
        } else {
            if ("1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_CUSTOM_FIELD))) {
                // 自定义字段
                if (!StringUtils.isEmpty(dataAreaFieldConfigObj.getString(CmnConst.ATTR_FORMULA))) {
                    // 替换系统参数
                    value = SystemParamReplace.systemParamsReplace(dataAreaFieldConfigObj.getString(CmnConst.ATTR_FORMULA));
                    // 替换表单参数,使用double进行计算
                    value = SystemParamReplace.formParamsReplace(value, recordFse, 1);
                    // 去除未被使用的参数
                    value = value.replaceAll("\\/\\{#[\\w]+#}", "/1").replaceAll("\\{#[\\w]+#}", "0");
                    // 求值
                    try {
                        value = BaseUtil.executeExpression(value, Maps.newHashMap()).toString();
                    } catch (Exception e) {
                        SpringMVCContextHolder.getSystemLogger().error(e);
                        value = "";
                    }
                } else {
                    if (!StringUtils.isEmpty(dataAreaFieldConfigObj.getString(CmnConst.ATTR_SP_TIME_STATISTICS_WAY))) {
                        value = recordFse.getString(fieldInfo2FieldName(getFieldInfo(dataAreaFieldConfigObj)));
                    }
                }
            } else {
                // 普通字段+分组字段
                value = recordFse.getString(dataAreaFieldName);
            }
        }
        return StringUtils.isEmpty(value) ? "" : value;
    }
      if (CmnConst.ATTR_DATA_TYPE_DATE.equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_DATA_TYPE))) {
         String dateFormat = dataAreaFieldConfigObj.getString(CmnConst.ATTR_DATE_FORMAT);
         if (!StringUtils.isEmpty(dateFormat)) {
            value = recordFse.getDate(dataAreaFieldName, dateFormat);
         }
      } else {
         if ("1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_CUSTOM_FIELD))) {
            // 自定义字段
            if (!StringUtils.isEmpty(dataAreaFieldConfigObj.getString(CmnConst.ATTR_FORMULA))) {
               // 替换系统参数
               value = SystemParamReplace.systemParamsReplace(dataAreaFieldConfigObj.getString(CmnConst.ATTR_FORMULA));
               // 替换表单参数,使用double进行计算
               value = SystemParamReplace.formParamsReplace(value, recordFse, 1);
               // 去除未被使用的参数
               value = value.replaceAll("\\/\\{#[\\w]+#}", "/1").replaceAll("\\{#[\\w]+#}", "0");
               // 求值
               try {
                  value = BaseUtil.executeExpression(value, Maps.newHashMap()).toString();
               } catch (Exception e) {
                  SpringMVCContextHolder.getSystemLogger().error(e);
                  value = "";
               }
            } else {
               if (!StringUtils.isEmpty(dataAreaFieldConfigObj.getString(CmnConst.ATTR_SP_TIME_STATISTICS_WAY))) {
                  value = recordFse.getString(fieldInfo2FieldName(getFieldInfo(dataAreaFieldConfigObj)));
               }
            }
         } else {
            // 普通字段+分组字段
            value = recordFse.getString(dataAreaFieldName);
         }
      }
      return StringUtils.isEmpty(value) ? "" : value;
   }
    /**
     * 获取字段信息
     *
     * @param dataAreaFieldConfigObj
     * @return
     */
    private String getFieldInfo(JSONObject dataAreaFieldConfigObj) {
        if ("1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_CUSTOM_FIELD))) {
            // 自定义字段
            if (!StringUtils.isEmpty(dataAreaFieldConfigObj.getString(CmnConst.ATTR_SP_TIME_STATISTICS_WAY))) {
                // 特殊时间计算字段
                if ("0".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_SP_TIME_STATISTICS_WAY))) {
                    // 去年同期
                    return fieldName2FieldInfo(CmnConst.ATTR_HEAD_LAST_YEAR + fieldInfo2FieldName(dataAreaFieldConfigObj.getString(CmnConst.ATTR_RELATE_COMMON_FIELD)));
                } else if ("1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_SP_TIME_STATISTICS_WAY))) {
                    // 上期
                    return fieldName2FieldInfo(CmnConst.ATTR_HEAD_PRE_PERIOD + fieldInfo2FieldName(dataAreaFieldConfigObj.getString(CmnConst.ATTR_RELATE_COMMON_FIELD)));
                }
            }
        }
        // 普通字段
        return dataAreaFieldConfigObj.getString(CmnConst.ATTR_FIELD_INFO);
    }
   /**
    * 获取字段信息
    *
    * @param dataAreaFieldConfigObj
    * @return
    */
   private String getFieldInfo(JSONObject dataAreaFieldConfigObj) {
      if ("1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_CUSTOM_FIELD))) {
         // 自定义字段
         if (!StringUtils.isEmpty(dataAreaFieldConfigObj.getString(CmnConst.ATTR_SP_TIME_STATISTICS_WAY))) {
            // 特殊时间计算字段
            if ("0".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_SP_TIME_STATISTICS_WAY))) {
               // 去年同期
               return fieldName2FieldInfo(CmnConst.ATTR_HEAD_LAST_YEAR + fieldInfo2FieldName(dataAreaFieldConfigObj.getString(CmnConst.ATTR_RELATE_COMMON_FIELD)));
            } else if ("1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_SP_TIME_STATISTICS_WAY))) {
               // 上期
               return fieldName2FieldInfo(CmnConst.ATTR_HEAD_PRE_PERIOD + fieldInfo2FieldName(dataAreaFieldConfigObj.getString(CmnConst.ATTR_RELATE_COMMON_FIELD)));
            }
         }
      }
      // 普通字段
      return dataAreaFieldConfigObj.getString(CmnConst.ATTR_FIELD_INFO);
   }
    /**
     * 格式化数据
     *
     * @param dataAreaFieldConfigObj 数据区字段缓存obj
     * @param value                  数据值
     * @return
     */
    public String formatValue(JSONObject dataAreaFieldConfigObj, String value) {
        if (StringUtils.isEmpty(value)) {
            return value;
        }
        if (CmnConst.ATTR_DATA_TYPE_NUM.equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_DATA_TYPE))) {
            int decimalDigits = dataAreaFieldConfigObj.getIntValue(CmnConst.ATTR_DECIMAL_DIGITS);
            String numFormat = dataAreaFieldConfigObj.getString(CmnConst.ATTR_NUM_FORMAT);
            StringBuilder numFormatSb = new StringBuilder(32);
            StringBuilder valueSb = new StringBuilder(32);
            String[] tempValueArr = value.split("\\\\");
            for (String singleValue : tempValueArr) {
                if (StringUtils.isEmpty(singleValue)) {
                    continue;
                }
                if (valueSb.length() > 0) {
                    valueSb.append("\\");
                }
                numFormatSb.setLength(0);
                if ("1".equals(numFormat)) {
                    // 千分位
                    numFormatSb.append("%1$,.").append(decimalDigits).append("f");
                    singleValue = String.format(numFormatSb.toString(), Double.parseDouble(singleValue));
                } else if ("2".equals(numFormat)) {
                    // 百分比
                    numFormatSb.append("0.");
                    for (int i = 0; i < decimalDigits; i++) {
                        numFormatSb.append("0");
                    }
                    numFormatSb.append("%");
                    singleValue = new DecimalFormat(numFormatSb.toString()).format(Double.parseDouble(singleValue));
                } else {
                    numFormatSb.append("%1$.").append(decimalDigits).append("f");
                    singleValue = String.format(numFormatSb.toString(), Double.parseDouble(singleValue));
                }
                valueSb.append(singleValue);
            }
            value = valueSb.toString();
        }
        return value;
    }
   /**
    * 格式化数据
    *
    * @param dataAreaFieldConfigObj 数据区字段缓存obj
    * @param value                  数据值
    * @return
    */
   public String formatValue(JSONObject dataAreaFieldConfigObj, String value) {
      if (StringUtils.isEmpty(value)) {
         return value;
      }
      if (CmnConst.ATTR_DATA_TYPE_NUM.equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_DATA_TYPE))) {
         int decimalDigits = dataAreaFieldConfigObj.getIntValue(CmnConst.ATTR_DECIMAL_DIGITS);
         String numFormat = dataAreaFieldConfigObj.getString(CmnConst.ATTR_NUM_FORMAT);
         StringBuilder numFormatSb = new StringBuilder(32);
         StringBuilder valueSb = new StringBuilder(32);
         String[] tempValueArr = value.split("\\\\");
         for (String singleValue : tempValueArr) {
            if (StringUtils.isEmpty(singleValue)) {
               continue;
            }
            if (valueSb.length() > 0) {
               valueSb.append("\\");
            }
            numFormatSb.setLength(0);
            if ("1".equals(numFormat)) {
               // 千分位
               numFormatSb.append("%1$,.").append(decimalDigits).append("f");
               singleValue = String.format(numFormatSb.toString(), Double.parseDouble(singleValue));
            } else if ("2".equals(numFormat)) {
               // 百分比
               numFormatSb.append("0.");
               for (int i = 0; i < decimalDigits; i++) {
                  numFormatSb.append("0");
               }
               numFormatSb.append("%");
               singleValue = new DecimalFormat(numFormatSb.toString()).format(Double.parseDouble(singleValue));
            } else {
               numFormatSb.append("%1$.").append(decimalDigits).append("f");
               singleValue = String.format(numFormatSb.toString(), Double.parseDouble(singleValue));
            }
            valueSb.append(singleValue);
         }
         value = valueSb.toString();
      }
      return value;
   }
    /**
     * 处理指定单元格的固定宽度
     *
     * @param dataAreaFieldConfigObj
     * @param value
     * @return
     */
    public String dealTdWidth(JSONObject dataAreaFieldConfigObj, String value) {
        StringBuilder dealedValueSb = new StringBuilder(64);
        dealedValueSb.append("<div");
        String width = dataAreaFieldConfigObj == null ? null : dataAreaFieldConfigObj.getString(CmnConst.ATTR_WIDTH);
        if (!StringUtils.isEmpty(width)) {
            dealedValueSb.append(" style=\"width:").append(width).append("px\"");
        }
        dealedValueSb.append(">").append(value).append("</div>");
        return dealedValueSb.toString();
    }
   /**
    * 处理指定单元格的固定宽度
    *
    * @param dataAreaFieldConfigObj
    * @param value
    * @return
    */
   public String dealTdWidth(JSONObject dataAreaFieldConfigObj, String value) {
      StringBuilder dealedValueSb = new StringBuilder(64);
      dealedValueSb.append("<div");
      String width = dataAreaFieldConfigObj == null ? null : dataAreaFieldConfigObj.getString(CmnConst.ATTR_WIDTH);
      if (!StringUtils.isEmpty(width)) {
         dealedValueSb.append(" style=\"width:").append(width).append("px\"");
      }
      dealedValueSb.append(">").append(value).append("</div>");
      return dealedValueSb.toString();
   }
    /**
     * 获取td的属性
     *
     * @param obj        字段缓存obj、数据标题obj、分组标题obj
     * @param collection 属性集合
     * @param type       1-接收的属性,其他(通常为-1)-排除的属性
     * @return
     */
    public StringBuilder getTdAttrByObj(JSONObject obj, Collection<String> collection, int type) {
        StringBuilder attrSb = new StringBuilder(32);
        if (!obj.isEmpty()) {
            String key;
            String value;
            Object objValue;
            if (!StringUtils.isEmpty(obj.getString(CmnConst.ATTR_URL))) {
                for (Map.Entry<String, Object> entry : obj.entrySet()) {
                    key = entry.getKey();
                    objValue = entry.getValue();
                    value = objValue == null ? "" : objValue.toString();
                    if (collection != null) {
                        for (String singleAttrName : collection) {
                            if ((type == 1 && key.equals(singleAttrName)) || (type != 1 && !key.equals(singleAttrName))) {
                                getTdAttrByObjPart(key, value, attrSb);
                            }
                        }
                    } else {
                        getTdAttrByObjPart(key, value, attrSb);
                    }
                }
            }
        }
        return attrSb;
    }
   /**
    * 获取td的属性
    *
    * @param obj        字段缓存obj、数据标题obj、分组标题obj
    * @param collection 属性集合
    * @param type       1-接收的属性,其他(通常为-1)-排除的属性
    * @return
    */
   public StringBuilder getTdAttrByObj(JSONObject obj, Collection<String> collection, int type) {
      StringBuilder attrSb = new StringBuilder(32);
      if (!obj.isEmpty()) {
         String key;
         String value;
         Object objValue;
         if (!StringUtils.isEmpty(obj.getString(CmnConst.ATTR_URL))) {
            for (Map.Entry<String, Object> entry : obj.entrySet()) {
               key = entry.getKey();
               objValue = entry.getValue();
               value = objValue == null ? "" : objValue.toString();
               if (collection != null) {
                  for (String singleAttrName : collection) {
                     if ((type == 1 && key.equals(singleAttrName)) || (type != 1 && !key.equals(singleAttrName))) {
                        getTdAttrByObjPart(key, value, attrSb);
                     }
                  }
               } else {
                  getTdAttrByObjPart(key, value, attrSb);
               }
            }
         }
      }
      return attrSb;
   }
    private void getTdAttrByObjPart(String key, String value, StringBuilder attrSb) {
        if (CmnConst.ATTR_FIELD_INFO.equals(key)) {
            value = fieldInfo2FieldName(value);
        }
        if (CmnConst.ATTR_URL.equals(key)) {
            attrSb.append(" router=\"").append(value).append("\"");
        } else {
            attrSb.append(" ").append(key).append("=\"").append(value).append("\"");
        }
    }
   private void getTdAttrByObjPart(String key, String value, StringBuilder attrSb) {
      if (CmnConst.ATTR_FIELD_INFO.equals(key)) {
         value = fieldInfo2FieldName(value);
      }
      if (CmnConst.ATTR_URL.equals(key)) {
         attrSb.append(" router=\"").append(value).append("\"");
      } else {
         attrSb.append(" ").append(key).append("=\"").append(value).append("\"");
      }
   }
    public StringBuilder getTdAttrByObj(JSONObject obj, Collection<String> collection) {
        return getTdAttrByObj(obj, collection, 1);
    }
   public StringBuilder getTdAttrByObj(JSONObject obj, Collection<String> collection) {
      return getTdAttrByObj(obj, collection, 1);
   }
    public StringBuilder getTdAttrByObj(JSONObject obj) {
        return getTdAttrByObj(obj, null);
    }
   public StringBuilder getTdAttrByObj(JSONObject obj) {
      return getTdAttrByObj(obj, null);
   }
    /**
     * 处理td属性obj中的真实值
     *
     * @param baseObj
     * @param dealObj
     */
    public void getTdAttrObj(JSONObject baseObj, JSONObject dealObj) {
        Object obj = dealObj.get(CmnConst.ATTR_REAL_VALUE);
        if (obj != null) {
            JSONObject realValueObj = (JSONObject) obj;
            realValueObj.forEach((k, v) -> {
                if (baseObj.get(k) != null) {
                    baseObj.put(k, v);
                }
            });
        }
    }
   /**
    * 处理td属性obj中的真实值
    *
    * @param baseObj
    * @param dealObj
    */
   public void getTdAttrObj(JSONObject baseObj, JSONObject dealObj) {
      Object obj = dealObj.get(CmnConst.ATTR_REAL_VALUE);
      if (obj != null) {
         JSONObject realValueObj = (JSONObject) obj;
         realValueObj.forEach((k, v) -> {
            if (baseObj.get(k) != null) {
               baseObj.put(k, v);
            }
         });
      }
   }
    /**
     * 替换表单参数和系统变量
     *
     * @param str                     带处理的字符串
     * @param headAndTailTitleDataMap 头部、尾部标题字段数据map
     * @param singleObj
     * @return
     */
    public String replaceFormDataAndSysData(String str, Map<String, Set<String>> headAndTailTitleDataMap, JSONObject singleObj) {
        if (StringUtils.isEmpty(str)) {
            return "";
        }
        String reuslt = SystemParamReplace.systemParamsReplace(str);
        reuslt = reuslt.replaceAll(CmnConst.REGEXP_SYS_FIELD, "");
        if (!headAndTailTitleDataMap.isEmpty()) {
            List<String> suitList = getSuitContent(reuslt, CmnConst.REGEXP_FORM_FIELD);
            String dataType = singleObj.getString(CmnConst.ATTR_DATA_TYPE);
            int decimalDigits;
            String formatStr = null;
            List<JSONObject> formatList = Lists.newArrayList();
            boolean dateFormatFlag = false;
            boolean numFormatFlag = false;
            int numDealType = -1;
            JSONObject tempObj;
            if (StringUtils.isEmpty(dataType)) {
                dataType = CmnConst.ATTR_DATA_TYPE_STRING;
            } else {
                String[] dataTypeArr = dataType.split(",");
                for (String singleDataType : dataTypeArr) {
                    if (StringUtils.isEmpty(singleDataType)) {
                        continue;
                    }
                    tempObj = new JSONObject();
                    tempObj.put(CmnConst.ATTR_DATA_TYPE, singleDataType);
                    formatList.add(tempObj);
                    if (CmnConst.ATTR_DATA_TYPE_DATE.equals(singleDataType)) {
                        if (!dateFormatFlag) {
                            dateFormatFlag = true;
                            formatStr = singleObj.getString(CmnConst.ATTR_DATE_FORMAT);
                        }
                        tempObj.put("format", formatStr);
                    } else if (CmnConst.ATTR_DATA_TYPE_NUM.equals(singleDataType)) {
                        if (!numFormatFlag) {
                            numFormatFlag = true;
                            decimalDigits = singleObj.getIntValue(CmnConst.ATTR_DECIMAL_DIGITS);
                            String numFormat = singleObj.getString(CmnConst.ATTR_NUM_FORMAT);
                            StringBuilder numFormatSb = new StringBuilder(32);
                            if ("1".equals(numFormat)) {
                                // 千分位
                                numFormatSb.append("%1$,.").append(decimalDigits).append("f");
                                numDealType = 1;
                            } else if ("2".equals(numFormat)) {
                                // 百分比
                                numFormatSb.append("0.");
                                for (int i = 0; i < decimalDigits; i++) {
                                    numFormatSb.append("0");
                                }
                                numFormatSb.append("%");
                                numDealType = 2;
                            } else {
                                numFormatSb.append("%1$.").append(decimalDigits).append("f");
                                numDealType = 1;
                            }
                            formatStr = numFormatSb.toString();
                        }
                        tempObj.put("format", formatStr);
                    }
                }
            }
   /**
    * 替换表单参数和系统变量
    *
    * @param str                     带处理的字符串
    * @param headAndTailTitleDataMap 头部、尾部标题字段数据map
    * @param singleObj
    * @return
    */
   public String replaceFormDataAndSysData(String str, Map<String, Set<String>> headAndTailTitleDataMap, JSONObject singleObj) {
      if (StringUtils.isEmpty(str)) {
         return "";
      }
      String reuslt = SystemParamReplace.systemParamsReplace(str);
      reuslt = reuslt.replaceAll(CmnConst.REGEXP_SYS_FIELD, "");
      if (!headAndTailTitleDataMap.isEmpty()) {
         List<String> suitList = getSuitContent(reuslt, CmnConst.REGEXP_FORM_FIELD);
         String dataType = singleObj.getString(CmnConst.ATTR_DATA_TYPE);
         int decimalDigits;
         String formatStr = null;
         List<JSONObject> formatList = Lists.newArrayList();
         boolean dateFormatFlag = false;
         boolean numFormatFlag = false;
         int numDealType = -1;
         JSONObject tempObj;
         if (StringUtils.isEmpty(dataType)) {
            dataType = CmnConst.ATTR_DATA_TYPE_STRING;
         } else {
            String[] dataTypeArr = dataType.split(",");
            for (String singleDataType : dataTypeArr) {
               if (StringUtils.isEmpty(singleDataType)) {
                  continue;
               }
               tempObj = new JSONObject();
               tempObj.put(CmnConst.ATTR_DATA_TYPE, singleDataType);
               formatList.add(tempObj);
               if (CmnConst.ATTR_DATA_TYPE_DATE.equals(singleDataType)) {
                  if (!dateFormatFlag) {
                     dateFormatFlag = true;
                     formatStr = singleObj.getString(CmnConst.ATTR_DATE_FORMAT);
                  }
                  tempObj.put("format", formatStr);
               } else if (CmnConst.ATTR_DATA_TYPE_NUM.equals(singleDataType)) {
                  if (!numFormatFlag) {
                     numFormatFlag = true;
                     decimalDigits = singleObj.getIntValue(CmnConst.ATTR_DECIMAL_DIGITS);
                     String numFormat = singleObj.getString(CmnConst.ATTR_NUM_FORMAT);
                     StringBuilder numFormatSb = new StringBuilder(32);
                     if ("1".equals(numFormat)) {
                        // 千分位
                        numFormatSb.append("%1$,.").append(decimalDigits).append("f");
                        numDealType = 1;
                     } else if ("2".equals(numFormat)) {
                        // 百分比
                        numFormatSb.append("0.");
                        for (int i = 0; i < decimalDigits; i++) {
                           numFormatSb.append("0");
                        }
                        numFormatSb.append("%");
                        numDealType = 2;
                     } else {
                        numFormatSb.append("%1$.").append(decimalDigits).append("f");
                        numDealType = 1;
                     }
                     formatStr = numFormatSb.toString();
                  }
                  tempObj.put("format", formatStr);
               }
            }
         }
            StringBuilder value = new StringBuilder(128);
            String singleFieldInfo;
            for (int i = 0; i < suitList.size(); i++) {
                singleFieldInfo = suitList.get(i);
                value.setLength(0);
                if (formatList.size() > i) {
                    tempObj = formatList.get(i);
                    if (CmnConst.ATTR_DATA_TYPE_STRING.equals(tempObj.getString(CmnConst.ATTR_DATA_TYPE))) {
                        reuslt = reuslt.replace(singleFieldInfo, SetUtils.set2String(headAndTailTitleDataMap.get(fieldInfo2FieldName(singleFieldInfo)), ","));
                    } else {
                        for (String singleValue : headAndTailTitleDataMap.get(fieldInfo2FieldName(singleFieldInfo))) {
                            if (value.length() > 0) {
                                value.append(",");
                            }
                            if (CmnConst.ATTR_DATA_TYPE_NUM.equals(tempObj.getString(CmnConst.ATTR_DATA_TYPE))) {
                                if (numDealType == 1) {
                                    value.append(String.format(tempObj.getString("format"), Double.parseDouble(singleValue)));
                                } else if (numDealType == 2) {
                                    value.append(new DecimalFormat(tempObj.getString("format")).format(Double.parseDouble(singleValue)));
                                }
                            } else if (CmnConst.ATTR_DATA_TYPE_DATE.equals(tempObj.getString(CmnConst.ATTR_DATA_TYPE))) {
                                SimpleDateFormat restoreDataFormat = new SimpleDateFormat(CmnConst.FULL_DATE_FORMAT);
                                try {
                                    Date date = restoreDataFormat.parse(singleValue);
                                    value.append(new SimpleDateFormat(tempObj.getString("format")).format(date));
                                } catch (ParseException e) {
                                    logger.error(ReportCode.DATE_TRANSFER_FIAL.getText() + ": " + singleValue, e);
                                }
                            }
                        }
                        reuslt = reuslt.replace(singleFieldInfo, value);
                    }
                } else {
                    reuslt = reuslt.replace(singleFieldInfo, SetUtils.set2String(headAndTailTitleDataMap.get(fieldInfo2FieldName(singleFieldInfo)), ","));
                }
         StringBuilder value = new StringBuilder(128);
         String singleFieldInfo;
         for (int i = 0; i < suitList.size(); i++) {
            singleFieldInfo = suitList.get(i);
            value.setLength(0);
            if (formatList.size() > i) {
               tempObj = formatList.get(i);
               if (CmnConst.ATTR_DATA_TYPE_STRING.equals(tempObj.getString(CmnConst.ATTR_DATA_TYPE))) {
                  reuslt = reuslt.replace(singleFieldInfo, SetUtils.set2String(headAndTailTitleDataMap.get(fieldInfo2FieldName(singleFieldInfo)), ","));
               } else {
                  for (String singleValue : headAndTailTitleDataMap.get(fieldInfo2FieldName(singleFieldInfo))) {
                     if (value.length() > 0) {
                        value.append(",");
                     }
                     if (CmnConst.ATTR_DATA_TYPE_NUM.equals(tempObj.getString(CmnConst.ATTR_DATA_TYPE))) {
                        if (numDealType == 1) {
                           value.append(String.format(tempObj.getString("format"), Double.parseDouble(singleValue)));
                        } else if (numDealType == 2) {
                           value.append(new DecimalFormat(tempObj.getString("format")).format(Double.parseDouble(singleValue)));
                        }
                     } else if (CmnConst.ATTR_DATA_TYPE_DATE.equals(tempObj.getString(CmnConst.ATTR_DATA_TYPE))) {
                        SimpleDateFormat restoreDataFormat = new SimpleDateFormat(CmnConst.FULL_DATE_FORMAT);
                        try {
                           Date date = restoreDataFormat.parse(singleValue);
                           value.append(new SimpleDateFormat(tempObj.getString("format")).format(date));
                        } catch (ParseException e) {
                           logger.error(ReportCode.DATE_TRANSFER_FIAL.getText() + ": " + singleValue, e);
                        }
                     }
                  }
                  reuslt = reuslt.replace(singleFieldInfo, value);
               }
            } else {
               reuslt = reuslt.replace(singleFieldInfo, SetUtils.set2String(headAndTailTitleDataMap.get(fieldInfo2FieldName(singleFieldInfo)), ","));
            }
            }
        }
        reuslt = reuslt.replaceAll(CmnConst.REGEXP_FORM_FIELD, "");
        return reuslt;
    }
         }
      }
      reuslt = reuslt.replaceAll(CmnConst.REGEXP_FORM_FIELD, "");
      return reuslt;
   }
    /*==========================工具方法-start==========================*/
   /*==========================工具方法-start==========================*/
    /**
     * 比较v1,v2的大小,若是为数字,则按照数字的方式进行比较
     *
     * @param v1
     * @param v2
     * @return
     */
    public int compare(String v1, String v2) {
        BigDecimal b1;
        BigDecimal b2;
        int d1 = StringUtils.isEmpty(v1) ? -1 : 1;
        int d2 = StringUtils.isEmpty(v2) ? -1 : 1;
        int diffValue = Integer.compare(d1, d2);
        if (diffValue == 0 && d1 != -1) {
            if (v1.matches(CmnConst.REGEXP_NUMBER) && v2.matches(CmnConst.REGEXP_NUMBER)) {
                b1 = new BigDecimal(v1);
                b2 = new BigDecimal(v2);
                diffValue = b1.compareTo(b2);
            } else {
                diffValue = v1.compareTo(v2);
            }
        }
        return diffValue;
    }
   /**
    * 比较v1,v2的大小,若是为数字,则按照数字的方式进行比较
    *
    * @param v1
    * @param v2
    * @return
    */
   public int compare(String v1, String v2) {
      BigDecimal b1;
      BigDecimal b2;
      int d1 = StringUtils.isEmpty(v1) ? -1 : 1;
      int d2 = StringUtils.isEmpty(v2) ? -1 : 1;
      int diffValue = Integer.compare(d1, d2);
      if (diffValue == 0 && d1 != -1) {
         if (v1.matches(CmnConst.REGEXP_NUMBER) && v2.matches(CmnConst.REGEXP_NUMBER)) {
            b1 = new BigDecimal(v1);
            b2 = new BigDecimal(v2);
            diffValue = b1.compareTo(b2);
         } else {
            diffValue = v1.compareTo(v2);
         }
      }
      return diffValue;
   }
    /**
     * 根据正则返回符合条件的内容
     *
     * @param str       字符串
     * @param regexp    正则表达式
     * @param exceptKey 排除关键字(含有该关键字的内容不做处理)
     * @return
     */
    public List<String> getSuitContent(String str, String regexp, String exceptKey) {
        List<String> list = Lists.newArrayList();
        if (StringUtils.isEmpty(str)) {
            return list;
        }
        Pattern pattern = Pattern.compile(regexp);
        Matcher matcher = pattern.matcher(str);
        String curContent;
        while (matcher.find()) {
            curContent = matcher.group();
            if (!StringUtils.isEmpty(exceptKey) && curContent.contains(exceptKey)) {
                continue;
            }
            list.add(curContent);
        }
        return list;
    }
   /**
    * 根据正则返回符合条件的内容
    *
    * @param str       字符串
    * @param regexp    正则表达式
    * @param exceptKey 排除关键字(含有该关键字的内容不做处理)
    * @return
    */
   public List<String> getSuitContent(String str, String regexp, String exceptKey) {
      List<String> list = Lists.newArrayList();
      if (StringUtils.isEmpty(str)) {
         return list;
      }
      Pattern pattern = Pattern.compile(regexp);
      Matcher matcher = pattern.matcher(str);
      String curContent;
      while (matcher.find()) {
         curContent = matcher.group();
         if (!StringUtils.isEmpty(exceptKey) && curContent.contains(exceptKey)) {
            continue;
         }
         list.add(curContent);
      }
      return list;
   }
    public List<String> getSuitContent(String str, String regexp) {
        return getSuitContent(str, regexp, "");
    }
   public List<String> getSuitContent(String str, String regexp) {
      return getSuitContent(str, regexp, "");
   }
    /**
     * 获取指定个数的td占位
     *
     * @param num
     * @return
     */
    public String getAimNumTdPlaceholder(int num, int type) {
        StringBuilder result = new StringBuilder(64);
        if (num <= 0) {
            return result.toString();
        }
        if (type == 0) {
            for (int i = 0; i < num; i++) {
                result.append("<td></td>");
            }
        } else {
            result.append("<td colspan=\"").append(num).append("\"></td>");
        }
        return result.toString();
    }
   /**
    * 获取指定个数的td占位
    *
    * @param num
    * @return
    */
   public String getAimNumTdPlaceholder(int num, int type) {
      StringBuilder result = new StringBuilder(64);
      if (num <= 0) {
         return result.toString();
      }
      if (type == 0) {
         for (int i = 0; i < num; i++) {
            result.append("<td></td>");
         }
      } else {
         result.append("<td colspan=\"").append(num).append("\"></td>");
      }
      return result.toString();
   }
    /**
     * 字段信息转化为字段名称
     *
     * @param fieldInfo 字段信息
     * @return
     */
    public String fieldInfo2FieldName(String fieldInfo) {
        if (StringUtils.isEmpty(fieldInfo)) {
            return "";
        }
        return fieldInfo.replace("{#", "").replace("#}", "");
    }
   /**
    * 字段信息转化为字段名称
    *
    * @param fieldInfo 字段信息
    * @return
    */
   public String fieldInfo2FieldName(String fieldInfo) {
      if (StringUtils.isEmpty(fieldInfo)) {
         return "";
      }
      return fieldInfo.replace("{#", "").replace("#}", "");
   }
    /**
     * 字段名称转化为字段信息
     *
     * @param fieldName 字段名称
     * @return
     */
    public String fieldName2FieldInfo(String fieldName) {
        return "{#" + fieldName + "#}";
    }
   /**
    * 字段名称转化为字段信息
    *
    * @param fieldName 字段名称
    * @return
    */
   public String fieldName2FieldInfo(String fieldName) {
      return "{#" + fieldName + "#}";
   }
    /**
     * 类型转化为list
     *
     * @param o
     * @return
     */
    public List<String> transfer2List(Object o) {
        return o == null ? Lists.newArrayList() : (List<String>) o;
    }
   /**
    * 类型转化为list
    *
    * @param o
    * @return
    */
   public List<String> transfer2List(Object o) {
      return o == null ? Lists.newArrayList() : (List<String>) o;
   }
    /**
     * 浅克隆-JSONObect-指定元素
     *
     * @param aimObj    目标
     * @param sourceObj 源
     * @param aimAttr   目标属性
     * @param type      类型:1-获取目标属性,其他-排除目标属性
     * @return
     */
    public JSONObject extendJSONObject(JSONObject aimObj, JSONObject sourceObj, Collection<String> aimAttr, int type) {
        if (aimObj == null) {
            aimObj = new JSONObject();
        }
        if (aimAttr == null) {
            for (Map.Entry<String, Object> entry : sourceObj.entrySet()) {
                aimObj.put(entry.getKey(), entry.getValue());
            }
        } else {
            if (type == 1) {
                for (String singleAttr : aimAttr) {
                    aimObj.put(singleAttr, sourceObj.get(singleAttr));
                }
            } else {
                for (Map.Entry<String, Object> entry : sourceObj.entrySet()) {
                    if (aimAttr.contains(entry.getKey())) {
                        continue;
                    }
                    aimObj.put(entry.getKey(), entry.getValue());
                }
            }
        }
        return aimObj;
    }
   /**
    * 浅克隆-JSONObect-指定元素
    *
    * @param aimObj    目标
    * @param sourceObj 源
    * @param aimAttr   目标属性
    * @param type      类型:1-获取目标属性,其他-排除目标属性
    * @return
    */
   public JSONObject extendJSONObject(JSONObject aimObj, JSONObject sourceObj, Collection<String> aimAttr, int type) {
      if (aimObj == null) {
         aimObj = new JSONObject();
      }
      if (aimAttr == null) {
         for (Map.Entry<String, Object> entry : sourceObj.entrySet()) {
            aimObj.put(entry.getKey(), entry.getValue());
         }
      } else {
         if (type == 1) {
            for (String singleAttr : aimAttr) {
               aimObj.put(singleAttr, sourceObj.get(singleAttr));
            }
         } else {
            for (Map.Entry<String, Object> entry : sourceObj.entrySet()) {
               if (aimAttr.contains(entry.getKey())) {
                  continue;
               }
               aimObj.put(entry.getKey(), entry.getValue());
            }
         }
      }
      return aimObj;
   }
    public JSONObject extendJSONObject(JSONObject aimObj, JSONObject sourceObj, Collection<String> aimAttr) {
        return extendJSONObject(aimObj, sourceObj, aimAttr, 1);
    }
   public JSONObject extendJSONObject(JSONObject aimObj, JSONObject sourceObj, Collection<String> aimAttr) {
      return extendJSONObject(aimObj, sourceObj, aimAttr, 1);
   }
    /**
     * 检测字符串是否包含检测值
     *
     * @param str        待检测的字符串
     * @param checkValue 检测值
     * @param sign       分割标识
     * @return
     */
    public boolean checkContain(String str, String checkValue, String sign) {
        if (StringUtils.isEmpty(str) || StringUtils.isEmpty(checkValue)) {
            return false;
        }
        return (sign + str + sign).contains(sign + checkValue + sign);
    }
   /**
    * 检测字符串是否包含检测值
    *
    * @param str        待检测的字符串
    * @param checkValue 检测值
    * @param sign       分割标识
    * @return
    */
   public boolean checkContain(String str, String checkValue, String sign) {
      if (StringUtils.isEmpty(str) || StringUtils.isEmpty(checkValue)) {
         return false;
      }
      return (sign + str + sign).contains(sign + checkValue + sign);
   }
    public boolean checkContain(String str, String checkValue) {
        return checkContain(str, checkValue, ",");
    }
   public boolean checkContain(String str, String checkValue) {
      return checkContain(str, checkValue, ",");
   }
    /**
     * 拼接
     *
     * @param obj
     * @param attr
     * @return
     */
    public String concat(JSONObject obj, String attr) {
        return new StringBuilder(512).append(obj).append("_").append(attr).toString();
    }
   /**
    * 拼接
    *
    * @param obj
    * @param attr
    * @return
    */
   public String concat(JSONObject obj, String attr) {
      return new StringBuilder(512).append(obj).append("_").append(attr).toString();
   }
    /**
     * 获取真实值(数据库保存的值),主要是针对使用了参照的值
     *
     * @param recordFse
     * @param fieldName
     * @return
     */
    public String getRealValue(FieldSetEntity recordFse, String fieldName) {
        String tail = "_save_value";
        return recordFse.getString(fieldName + tail);
    }
    /*==========================工具方法-final==========================*/
   /**
    * 获取真实值(数据库保存的值),主要是针对使用了参照的值
    *
    * @param recordFse
    * @param fieldName
    * @return
    */
   public String getRealValue(FieldSetEntity recordFse, String fieldName) {
      String tail = "_save_value";
      return recordFse.getString(fieldName + tail);
   }
   /*==========================工具方法-final==========================*/
    /*==========================静态内容-start==========================*/
   /*==========================静态内容-start==========================*/
    /**
     * 获取报表css
     *
     * @return
     */
    public StringBuilder getCssHtml() {
        StringBuilder cssHtml = new StringBuilder(512);
        cssHtml.append("\n<style rel=\"stylesheet\" type=\"text/css\"> ");
        cssHtml.append("\n    table { ");
        cssHtml.append("\n        margin: 0 auto; ");
        cssHtml.append("\n    } ");
        cssHtml.append("\n    tr, td { ");
        cssHtml.append("\n        text-align: center; ");
        cssHtml.append("\n    } ");
        cssHtml.append("\n    .data_title td, .data_common td, .data_statistics td { ");
        cssHtml.append("\n        border: 1px black solid; ");
        cssHtml.append("\n    } ");
        cssHtml.append("\n    .report_title {background-color: #fde8e8} ");
        cssHtml.append("\n    .head {background-color: #fbeed5} ");
        cssHtml.append("\n    .data_title {background-color: #f0fbd5} ");
        cssHtml.append("\n    .data_statistics {background-color: #d5f6fb} ");
        cssHtml.append("\n    .data_common {background-color: #e8d5fb} ");
        cssHtml.append("\n    .tail {background-color: #fad5fb} ");
        cssHtml.append("\n    .can_turn {cursor: pointer;color: blue} ");
        cssHtml.append("\n</style> ");
        return cssHtml;
    }
   /**
    * 获取报表css
    *
    * @return
    */
   public StringBuilder getCssHtml() {
      StringBuilder cssHtml = new StringBuilder(512);
      cssHtml.append("\n<style rel=\"stylesheet\" type=\"text/css\"> ");
      cssHtml.append("\n    table { ");
      cssHtml.append("\n        margin: 0 auto; ");
      cssHtml.append("\n    } ");
      cssHtml.append("\n    tr, td { ");
      cssHtml.append("\n        text-align: center; ");
      cssHtml.append("\n    } ");
      cssHtml.append("\n    .data_title td, .data_common td, .data_statistics td { ");
      cssHtml.append("\n        border: 1px black solid; ");
      cssHtml.append("\n    } ");
      cssHtml.append("\n    .report_title {background-color: #fde8e8} ");
      cssHtml.append("\n    .head {background-color: #fbeed5} ");
      cssHtml.append("\n    .data_title {background-color: #f0fbd5} ");
      cssHtml.append("\n    .data_statistics {background-color: #d5f6fb} ");
      cssHtml.append("\n    .data_common {background-color: #e8d5fb} ");
      cssHtml.append("\n    .tail {background-color: #fad5fb} ");
      cssHtml.append("\n    .can_turn {cursor: pointer;color: blue} ");
      cssHtml.append("\n</style> ");
      return cssHtml;
   }
    /**
     * 根据统计类型和值返回统计字段描述
     *
     * @param type  统计类型
     * @param value 值
     * @return
     */
    public String getStatisticsDesc(String type, String value) {
        if (CmnConst.ATTR_STATISTICS_SUM.equals(type)) {
            value += "(合计)";
        }
        if (CmnConst.ATTR_STATISTICS_MAX.equals(type)) {
            value += "(峰值)";
        }
        if (CmnConst.ATTR_STATISTICS_MIN.equals(type)) {
            value += "(谷值)";
        }
        if (CmnConst.ATTR_STATISTICS_CNT.equals(type)) {
            value += "(计数)";
        }
        if (CmnConst.ATTR_STATISTICS_AVG.equals(type)) {
            value += "(平均)";
        }
        if (CmnConst.ATTR_STATISTICS_ENUM.equals(type)) {
            value += "(枚举)";
        }
        return value;
    }
    /*==========================静态内容-final==========================*/
   /**
    * 根据统计类型和值返回统计字段描述
    *
    * @param type  统计类型
    * @param value 值
    * @return
    */
   public String getStatisticsDesc(String type, String value) {
      if (CmnConst.ATTR_STATISTICS_SUM.equals(type)) {
         value += "(合计)";
      }
      if (CmnConst.ATTR_STATISTICS_MAX.equals(type)) {
         value += "(峰值)";
      }
      if (CmnConst.ATTR_STATISTICS_MIN.equals(type)) {
         value += "(谷值)";
      }
      if (CmnConst.ATTR_STATISTICS_CNT.equals(type)) {
         value += "(计数)";
      }
      if (CmnConst.ATTR_STATISTICS_AVG.equals(type)) {
         value += "(平均)";
      }
      if (CmnConst.ATTR_STATISTICS_ENUM.equals(type)) {
         value += "(枚举)";
      }
      return value;
   }
   /*==========================静态内容-final==========================*/
}