1821349743@qq.com
2023-04-03 3df221b0a98cde4562471727a6ad41ffafbe39a8
picc of version
已修改2个文件
4145 ■■■■ 文件已修改
src/main/java/com/product/server/report/service/DataListReportService.java 3112 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/product/server/report/service/ReportConfigService.java 1033 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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==========================*/
}
src/main/java/com/product/server/report/service/ReportConfigService.java
@@ -8,6 +8,7 @@
import com.product.admin.service.UpdateLoginUserInfoService;
import com.product.common.lang.StringUtils;
import com.product.core.cache.DataPoolCacheImpl;
import com.product.core.config.CoreConst;
import com.product.core.dao.BaseDao;
import com.product.core.entity.DataTableEntity;
import com.product.core.entity.FieldSetEntity;
@@ -24,576 +25,588 @@
import org.springframework.stereotype.Component;
import javax.xml.crypto.Data;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.*;
@Component
public class ReportConfigService extends AbstractBaseService implements IReportConfigService {
    @Autowired
    BaseDao baseDao;
    @Autowired
    CodeService codeService;
    @Autowired
    public QueryFilterService queryFilterService;
    @Autowired
    public DataListReportService dataListReportService;
    @Autowired
    BaseDao baseDao;
    @Autowired
    CodeService codeService;
    @Autowired
    public QueryFilterService queryFilterService;
    @Autowired
    public DataListReportService dataListReportService;
    /**
     * 报表列表
     *
     * @param cpage
     * @param pageSize
     * @return
     */
    public DataTableEntity listReportConfig(Integer cpage, Integer pageSize, FieldSetEntity fse) {
        cpage = cpage == null ? 1 : cpage;
        pageSize = pageSize == null ? 20 : pageSize;
    /**
     * 报表列表
     *
     * @param cpage
     * @param pageSize
     * @return
     */
    public DataTableEntity listReportConfig(Integer cpage, Integer pageSize, FieldSetEntity fse) {
        cpage = cpage == null ? 1 : cpage;
        pageSize = pageSize == null ? 20 : pageSize;
        List<Object> paramList = Lists.newArrayList();
        StringBuilder sql = new StringBuilder(512);
        sql.append("\nSELECT a.uuid,a.type_uuid,a.is_valid,a.org_level_uuid,a.report_name,b.type_name,b.type_group")
                .append("\nFROM product_sys_report_config a")
                .append("\nLEFT JOIN product_sys_report_type_config b ON a.type_uuid = b.uuid")
                .append("\nwhere (function_uuid is null or function_uuid='') ");
        if (!StringUtils.isEmpty(fse.getString(CmnConst.TYPE_UUID))) {
            sql.append("\nand b.type_group=?");
            paramList.add(fse.getString(CmnConst.TYPE_UUID));
        }
        return baseDao.listTable(sql.toString(), paramList.toArray(), pageSize, cpage);
    }
        List<Object> paramList = Lists.newArrayList();
        StringBuilder sql = new StringBuilder(512);
        sql.append("\nSELECT a.uuid,a.type_uuid,a.is_valid,a.org_level_uuid,a.report_name,b.type_name,b.type_group")
                .append("\nFROM product_sys_report_config a")
                .append("\nLEFT JOIN product_sys_report_type_config b ON a.type_uuid = b.uuid")
                .append("\nwhere (function_uuid is null or function_uuid='') ");
        if (!StringUtils.isEmpty(fse.getString(CmnConst.TYPE_UUID))) {
            sql.append("\nand b.type_group=?");
            paramList.add(fse.getString(CmnConst.TYPE_UUID));
        }
        return baseDao.listTable(sql.toString(), paramList.toArray(), pageSize, cpage);
    }
    /**
     * 报表详情
     *
     * @param uuid
     * @return
     */
    public FieldSetEntity findReportConfig(String uuid) {
        StringBuilder sql = new StringBuilder(256);
        sql.append("\nselect report_area,cell_position_y,cell_position_x,attribute_name,report_type_attr_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 attribute_name is not null ")
                .append("\norder by report_area,cell_position_y,cell_position_x");
        DataTableEntity tempDte = baseDao.listTable(sql.toString(), new Object[]{uuid});
        DataTableEntity reportConfigAttrDte = new DataTableEntity();
        FieldSetEntity tempFse;
        FieldSetEntity reportConfigAttrFse = new FieldSetEntity();
        String curReportArea;
        String curX;
        String curY;
        String preReportArea = "";
        String preX = "";
        String preY = "";
        for (int i = 0; i < tempDte.getRows(); i++) {
            tempFse = tempDte.getFieldSetEntity(i);
            curReportArea = tempFse.getString(CmnConst.ATTR_REPORT_AREA);
            curX = tempFse.getString(CmnConst.CELL_POSITION_X);
            curY = tempFse.getString(CmnConst.CELL_POSITION_Y);
            if (curReportArea == null || curX == null || curY == null) {
                continue;
            }
            if (!preReportArea.equals(curReportArea) || !preX.equals(curX) || !preY.equals(curY)) {
                reportConfigAttrFse = new FieldSetEntity();
                reportConfigAttrDte.addFieldSetEntity(reportConfigAttrFse);
                reportConfigAttrFse.setTableName(CmnConst.PRODUCT_SYS_REPORT_CONFIG_ATTRIBUTE);
                reportConfigAttrFse.setValue(CmnConst.ATTR_X, curX);
                reportConfigAttrFse.setValue(CmnConst.ATTR_Y, curY);
                reportConfigAttrFse.setValue(CmnConst.ATTR_REPORT_AREA, curReportArea);
            }
            reportConfigAttrFse.setValue(tempFse.getString(CmnConst.ATTRIBUTE_NAME), tempFse.getString(CmnConst.REPORT_TYPE_ATTR_VALUE));
            preReportArea = curReportArea;
            preX = curX;
            preY = curY;
        }
    /**
     * 报表详情
     *
     * @param uuid
     * @return
     */
    public FieldSetEntity findReportConfig(String uuid) {
        StringBuilder sql = new StringBuilder(256);
        sql.append("\nselect report_area,cell_position_y,cell_position_x,attribute_name,report_type_attr_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 attribute_name is not null ")
                .append("\norder by report_area,cell_position_y,cell_position_x");
        DataTableEntity tempDte = baseDao.listTable(sql.toString(), new Object[]{uuid});
        DataTableEntity reportConfigAttrDte = new DataTableEntity();
        FieldSetEntity tempFse;
        FieldSetEntity reportConfigAttrFse = new FieldSetEntity();
        String curReportArea;
        String curX;
        String curY;
        String preReportArea = "";
        String preX = "";
        String preY = "";
        for (int i = 0; i < tempDte.getRows(); i++) {
            tempFse = tempDte.getFieldSetEntity(i);
            curReportArea = tempFse.getString(CmnConst.ATTR_REPORT_AREA);
            curX = tempFse.getString(CmnConst.CELL_POSITION_X);
            curY = tempFse.getString(CmnConst.CELL_POSITION_Y);
            if (curReportArea == null || curX == null || curY == null) {
                continue;
            }
            if (!preReportArea.equals(curReportArea) || !preX.equals(curX) || !preY.equals(curY)) {
                reportConfigAttrFse = new FieldSetEntity();
                reportConfigAttrDte.addFieldSetEntity(reportConfigAttrFse);
                reportConfigAttrFse.setTableName(CmnConst.PRODUCT_SYS_REPORT_CONFIG_ATTRIBUTE);
                reportConfigAttrFse.setValue(CmnConst.ATTR_X, curX);
                reportConfigAttrFse.setValue(CmnConst.ATTR_Y, curY);
                reportConfigAttrFse.setValue(CmnConst.ATTR_REPORT_AREA, curReportArea);
            }
            reportConfigAttrFse.setValue(tempFse.getString(CmnConst.ATTRIBUTE_NAME), tempFse.getString(CmnConst.REPORT_TYPE_ATTR_VALUE));
            preReportArea = curReportArea;
            preX = curX;
            preY = curY;
        }
        FieldSetEntity reportConfigFse = baseDao.getFieldSetEntity(CmnConst.PRODUCT_SYS_REPORT_CONFIG, uuid, false);
        reportConfigFse.addSubDataTable(reportConfigAttrDte);
        FieldSetEntity reportConfigFse = baseDao.getFieldSetEntity(CmnConst.PRODUCT_SYS_REPORT_CONFIG, uuid, false);
        reportConfigFse.addSubDataTable(reportConfigAttrDte);
        return reportConfigFse;
    }
        return reportConfigFse;
    }
    /**
     * 报表新增
     *
     * @param fse
     * @return
     */
    @Transactional
    public String addReportConfig(FieldSetEntity fse) {
        fse.setValue(CmnConst.CREATED_BY, SpringMVCContextHolder.getCurrentUserId());
        fse.setValue(CmnConst.CREATED_UTC_DATETIME, new Date());
        fse.setValue(CmnConst.IS_VALID, 1);
    /**
     * 报表新增
     *
     * @param fse
     * @return
     */
    @Transactional
    public String addReportConfig(FieldSetEntity fse) {
        fse.setValue(CmnConst.CREATED_BY, SpringMVCContextHolder.getCurrentUserId());
        fse.setValue(CmnConst.CREATED_UTC_DATETIME, new Date());
        fse.setValue(CmnConst.IS_VALID, 1);
        replaceAttrName2UUID(fse);
        replaceAttrName2UUID(fse);
        if (StringUtils.isEmpty(fse.getString(CmnConst.PAGE_SIZE))) {
            fse.setValue(CmnConst.PAGE_SIZE, null);
        }
        if (StringUtils.isEmpty(fse.getString(CmnConst.PAGE_SIZE))) {
            fse.setValue(CmnConst.PAGE_SIZE, null);
        }
        System.out.println(System.currentTimeMillis());
        String uuid = baseDao.add(fse);
        System.out.println(System.currentTimeMillis());
        String uuid = baseDao.add(fse);
        if ("1".equals(fse.getString(CmnConst.RELATE_FLAG))) {
            // 重新设置缓存
            dataListReportService.setConfig(fse.getUUID());
        }
        if ("1".equals(fse.getString(CmnConst.RELATE_FLAG))) {
            // 重新设置缓存
            dataListReportService.setConfig(fse.getUUID());
        }
        return uuid;
    }
        return uuid;
    }
    /**
     * 报表修改
     *
     * @param fse
     * @return
     */
    @Transactional
    public boolean updateReportConfig(FieldSetEntity fse) {
        fse.setValue(CmnConst.UPDATED_BY, SpringMVCContextHolder.getCurrentUserId());
        fse.setValue(CmnConst.UPDATED_UTC_DATETIME, new Date());
    /**
     * 报表修改
     *
     * @param fse
     * @return
     */
    @Transactional
    public boolean updateReportConfig(FieldSetEntity fse) {
        fse.setValue(CmnConst.UPDATED_BY, SpringMVCContextHolder.getCurrentUserId());
        fse.setValue(CmnConst.UPDATED_UTC_DATETIME, new Date());
        replaceAttrName2UUID(fse);
        replaceAttrName2UUID(fse);
        if (StringUtils.isEmpty(fse.getString(CmnConst.PAGE_SIZE))) {
            fse.setValue(CmnConst.PAGE_SIZE, null);
        }
        if (StringUtils.isEmpty(fse.getString(CmnConst.PAGE_SIZE))) {
            fse.setValue(CmnConst.PAGE_SIZE, null);
        }
        boolean result = baseDao.update(fse);
        boolean result = baseDao.update(fse);
        if ("1".equals(fse.getString(CmnConst.RELATE_FLAG)) || !StringUtils.isEmpty(fse.getString(CmnConst.FUNCTION_UUID))) {
            // 重新设置缓存
            dataListReportService.setConfig(fse.getUUID());
        }
        if ("1".equals(fse.getString(CmnConst.RELATE_FLAG)) || !StringUtils.isEmpty(fse.getString(CmnConst.FUNCTION_UUID))) {
            // 重新设置缓存
            dataListReportService.setConfig(fse.getUUID());
        }
        return result;
    }
        return result;
    }
    /**
     * 替换属性名称为uuid
     *
     * @param fse
     */
    private void replaceAttrName2UUID(FieldSetEntity fse) {
        DataTableEntity reportTypeAttrDte = baseDao.listTable(CmnConst.PRODUCT_SYS_REPORT_TYPE_ATTRIBUTE, "type_group='DataList'", new Object[]{}, new Object[]{CmnConst.ATTRIBUTE_NAME, CmnConst.UUID});
        if (!BaseUtil.dataTableIsEmpty(reportTypeAttrDte)) {
            Map<String, String> reportTypeAttrMap = Maps.newHashMap();
            FieldSetEntity tempFse;
            for (int i = 0; i < reportTypeAttrDte.getRows(); i++) {
                tempFse = reportTypeAttrDte.getFieldSetEntity(i);
                reportTypeAttrMap.put(tempFse.getString(CmnConst.ATTRIBUTE_NAME), tempFse.getUUID());
            }
            DataTableEntity preReportAttrDte = baseDao.listTable(CmnConst.PRODUCT_SYS_REPORT_CONFIG_ATTRIBUTE, "report_config_uuid=?", new Object[]{fse.getUUID()});
            Map<JSONObject, String> preReportAttrMap = Maps.newHashMap();
            JSONObject tempObj;
            if (!BaseUtil.dataTableIsEmpty(preReportAttrDte)) {
                for (int i = 0; i < preReportAttrDte.getRows(); i++) {
                    tempFse = preReportAttrDte.getFieldSetEntity(i);
                    tempObj = new JSONObject();
                    tempObj.put(CmnConst.ATTR_REPORT_AREA, tempFse.getString(CmnConst.ATTR_REPORT_AREA));
                    tempObj.put(CmnConst.CELL_POSITION_X, tempFse.getString(CmnConst.CELL_POSITION_X));
                    tempObj.put(CmnConst.CELL_POSITION_Y, tempFse.getString(CmnConst.CELL_POSITION_Y));
                    tempObj.put(CmnConst.REPORT_TYPE_ATTR, tempFse.getString(CmnConst.REPORT_TYPE_ATTR));
                    preReportAttrMap.put(tempObj, tempFse.getUUID());
                }
            }
            DataTableEntity reportAttrDte = fse.getSubDataTable(CmnConst.PRODUCT_SYS_REPORT_CONFIG_ATTRIBUTE);
            if (!BaseUtil.dataTableIsEmpty(reportAttrDte)) {
                String tempUUID;
                for (int i = 0; i < reportAttrDte.getRows(); i++) {
                    tempFse = reportAttrDte.getFieldSetEntity(i);
                    tempFse.setValue("report_type_attr_show_name", tempFse.getString(CmnConst.REPORT_TYPE_ATTR));
                    tempFse.setValue(CmnConst.REPORT_TYPE_ATTR, reportTypeAttrMap.get(tempFse.getString(CmnConst.REPORT_TYPE_ATTR)));
                    tempFse.setValue(CmnConst.CELL_POSITION_X, tempFse.getString(CmnConst.ATTR_X));
                    tempFse.setValue(CmnConst.CELL_POSITION_Y, tempFse.getString(CmnConst.ATTR_Y));
                    String x = tempFse.getString(CmnConst.ATTR_X);
                    tempObj = new JSONObject();
                    tempObj.put(CmnConst.ATTR_REPORT_AREA, tempFse.getString(CmnConst.ATTR_REPORT_AREA));
                    tempObj.put(CmnConst.CELL_POSITION_X, tempFse.getString(CmnConst.CELL_POSITION_X));
                    tempObj.put(CmnConst.CELL_POSITION_Y, tempFse.getString(CmnConst.CELL_POSITION_Y));
                    tempObj.put(CmnConst.REPORT_TYPE_ATTR, tempFse.getString(CmnConst.REPORT_TYPE_ATTR));
    /**
     * 替换属性名称为uuid
     *
     * @param fse
     */
    private void replaceAttrName2UUID(FieldSetEntity fse) {
        DataTableEntity reportTypeAttrDte = baseDao.listTable(CmnConst.PRODUCT_SYS_REPORT_TYPE_ATTRIBUTE, "type_group='DataList'", new Object[]{}, new Object[]{CmnConst.ATTRIBUTE_NAME, CmnConst.UUID});
        if (!BaseUtil.dataTableIsEmpty(reportTypeAttrDte)) {
            Map<String, String> reportTypeAttrMap = Maps.newHashMap();
            FieldSetEntity tempFse;
            for (int i = 0; i < reportTypeAttrDte.getRows(); i++) {
                tempFse = reportTypeAttrDte.getFieldSetEntity(i);
                reportTypeAttrMap.put(tempFse.getString(CmnConst.ATTRIBUTE_NAME), tempFse.getUUID());
            }
            DataTableEntity preReportAttrDte = baseDao.listTable(CmnConst.PRODUCT_SYS_REPORT_CONFIG_ATTRIBUTE, "report_config_uuid=?", new Object[]{fse.getUUID()});
            Map<JSONObject, String> preReportAttrMap = Maps.newHashMap();
            JSONObject tempObj;
            if (!BaseUtil.dataTableIsEmpty(preReportAttrDte)) {
                for (int i = 0; i < preReportAttrDte.getRows(); i++) {
                    tempFse = preReportAttrDte.getFieldSetEntity(i);
                    tempObj = new JSONObject();
                    tempObj.put(CmnConst.ATTR_REPORT_AREA, tempFse.getString(CmnConst.ATTR_REPORT_AREA));
                    tempObj.put(CmnConst.CELL_POSITION_X, tempFse.getString(CmnConst.CELL_POSITION_X));
                    tempObj.put(CmnConst.CELL_POSITION_Y, tempFse.getString(CmnConst.CELL_POSITION_Y));
                    tempObj.put(CmnConst.REPORT_TYPE_ATTR, tempFse.getString(CmnConst.REPORT_TYPE_ATTR));
                    preReportAttrMap.put(tempObj, tempFse.getUUID());
                }
            }
            DataTableEntity reportAttrDte = fse.getSubDataTable(CmnConst.PRODUCT_SYS_REPORT_CONFIG_ATTRIBUTE);
            if (!BaseUtil.dataTableIsEmpty(reportAttrDte)) {
                String tempUUID;
                for (int i = 0; i < reportAttrDte.getRows(); i++) {
                    tempFse = reportAttrDte.getFieldSetEntity(i);
                    tempFse.setValue(CmnConst.REPORT_TYPE_ATTR, reportTypeAttrMap.get(tempFse.getString(CmnConst.REPORT_TYPE_ATTR)));
                    tempFse.setValue(CmnConst.CELL_POSITION_X, tempFse.getString(CmnConst.ATTR_X));
                    tempFse.setValue(CmnConst.CELL_POSITION_Y, tempFse.getString(CmnConst.ATTR_Y));
                    tempUUID = preReportAttrMap.get(tempObj);
                    if (!StringUtils.isEmpty(tempUUID)) {
                        tempFse.setValue(CmnConst.UUID, tempUUID);
                    }
                    if (StringUtils.isEmpty(tempFse.getString(CmnConst.REPORT_TYPE_ATTR_VALUE))) {
                        //属性值是否为空
                        if (StringUtils.isEmpty(tempFse.getUUID())) {
                            //没有保存过的属性
                            reportAttrDte.removeFieldSetEntity(i);
                            i--;
                        } else {
                            //标记为删除
                            tempFse.setValue(CoreConst.SYSTEM_DATA_OPERATE_TYPE, "del");
                        }
                        continue;
                    }
                }
            }
        }
    }
                    tempObj = new JSONObject();
                    tempObj.put(CmnConst.ATTR_REPORT_AREA, tempFse.getString(CmnConst.ATTR_REPORT_AREA));
                    tempObj.put(CmnConst.CELL_POSITION_X, tempFse.getString(CmnConst.CELL_POSITION_X));
                    tempObj.put(CmnConst.CELL_POSITION_Y, tempFse.getString(CmnConst.CELL_POSITION_Y));
                    tempObj.put(CmnConst.REPORT_TYPE_ATTR, tempFse.getString(CmnConst.REPORT_TYPE_ATTR));
    /**
     * 报表删除
     *
     * @param uuid
     * @return
     */
    @Transactional
    public boolean deleteReportConfig(String uuid) {
        return baseDao.delete(CmnConst.PRODUCT_SYS_REPORT_CONFIG, "uuid=?", new Object[]{uuid});
    }
                    tempUUID = preReportAttrMap.get(tempObj);
                    if (!StringUtils.isEmpty(tempUUID)) {
                        tempFse.setValue(CmnConst.UUID, tempUUID);
                    }
                }
            }
        }
    }
    @Autowired
    UpdateLoginUserInfoService updateLoginUserInfoService;
    /**
     * 报表删除
     *
     * @param uuid
     * @return
     */
    @Transactional
    public boolean deleteReportConfig(String uuid) {
        return baseDao.delete(CmnConst.PRODUCT_SYS_REPORT_CONFIG, "uuid=?", new Object[]{uuid});
    }
    /**
     * 取消报表发布
     *
     * @param fse
     * @return
     */
    @Transactional
    public boolean cancelRelease(FieldSetEntity fse) {
        DataTableEntity reportConfigDte = DataPoolCacheImpl.getInstance().getCacheData(CmnConst.CACHE_REPORT_CONFIG, new String[]{fse.getUUID()});
        if (BaseUtil.dataTableIsEmpty(reportConfigDte)) {
            throw new BaseException(ReportCode.GET_REPORT_CONFIG_FIAL.getValue(), ReportCode.GET_REPORT_CONFIG_FIAL.getText());
        }
        FieldSetEntity reportConfigFse = reportConfigDte.getFieldSetEntity(0);
        String functionUUID = reportConfigFse.getString(CmnConst.FUNCTION_UUID);
        if (StringUtils.isEmpty(functionUUID)) {
            return false;
        }
    @Autowired
    UpdateLoginUserInfoService updateLoginUserInfoService;
        DataTableEntity dt = baseDao.listTable(CmnConst.PRODUCT_SYS_FUNCTION_PERMISSION, "function_uuid=?", new Object[]{functionUUID}, new Object[]{"role_uuid uuid"});
        //从角色权限中移除
        baseDao.delete(CmnConst.PRODUCT_SYS_FUNCTION_PERMISSION, "function_uuid=?", new Object[]{functionUUID});
        //删除连线
        baseDao.delete(CmnConst.PRODUCT_SYS_LINK, "function_uuid=?", new Object[]{functionUUID});
        //删除按钮
        baseDao.delete(CmnConst.PRODUCT_SYS_FUNCTION_BUTTONS, "function_uuid=?", new Object[]{functionUUID});
        //删除页面
        baseDao.delete(CmnConst.PRODUCT_SYS_MVC_PAGE, "function_uuid=?", new Object[]{functionUUID});
    /**
     * 取消报表发布
     *
     * @param fse
     * @return
     */
    @Transactional
    public boolean cancelRelease(FieldSetEntity fse) {
        DataTableEntity reportConfigDte = DataPoolCacheImpl.getInstance().getCacheData(CmnConst.CACHE_REPORT_CONFIG, new String[]{fse.getUUID()});
        if (BaseUtil.dataTableIsEmpty(reportConfigDte)) {
            throw new BaseException(ReportCode.GET_REPORT_CONFIG_FIAL.getValue(), ReportCode.GET_REPORT_CONFIG_FIAL.getText());
        }
        FieldSetEntity reportConfigFse = reportConfigDte.getFieldSetEntity(0);
        String functionUUID = reportConfigFse.getString(CmnConst.FUNCTION_UUID);
        if (StringUtils.isEmpty(functionUUID)) {
            return false;
        }
        //删除菜单
        baseDao.delete(CmnConst.PRODUCT_SYS_MENUS, "function_uuid=?", new Object[]{functionUUID});
        //删除功能
        baseDao.delete(CmnConst.PRODUCT_SYS_FUNCTIONS, "uuid=?", new Object[]{functionUUID});
        DataTableEntity dt = baseDao.listTable(CmnConst.PRODUCT_SYS_FUNCTION_PERMISSION, "function_uuid=?", new Object[]{functionUUID}, new Object[]{"role_uuid uuid"});
        //从角色权限中移除
        baseDao.delete(CmnConst.PRODUCT_SYS_FUNCTION_PERMISSION, "function_uuid=?", new Object[]{functionUUID});
        //删除连线
        baseDao.delete(CmnConst.PRODUCT_SYS_LINK, "function_uuid=?", new Object[]{functionUUID});
        //删除按钮
        baseDao.delete(CmnConst.PRODUCT_SYS_FUNCTION_BUTTONS, "function_uuid=?", new Object[]{functionUUID});
        //删除页面
        baseDao.delete(CmnConst.PRODUCT_SYS_MVC_PAGE, "function_uuid=?", new Object[]{functionUUID});
        //数据回写
        fse.setValue(CmnConst.FUNCTION_UUID, "");
        //删除菜单
        baseDao.delete(CmnConst.PRODUCT_SYS_MENUS, "function_uuid=?", new Object[]{functionUUID});
        //删除功能
        baseDao.delete(CmnConst.PRODUCT_SYS_FUNCTIONS, "uuid=?", new Object[]{functionUUID});
        if (!DataTableEntity.isEmpty(dt)) {
            updateLoginUserInfoService.updateUserInfoByUpdateRole(dt.getUuids(), true);
        }
        return baseDao.update(fse);
    }
        //数据回写
        fse.setValue(CmnConst.FUNCTION_UUID, "");
    /**
     * 报表发布
     *
     * @param fse
     * @return
     */
    @Transactional
    public boolean releaseConfig(FieldSetEntity fse) {
        if (!DataTableEntity.isEmpty(dt)) {
            updateLoginUserInfoService.updateUserInfoByUpdateRole(dt.getUuids(), true);
        }
        return baseDao.update(fse);
    }
        FieldSetEntity fseReport = baseDao.getFieldSetEntity(CmnConst.PRODUCT_SYS_REPORT_CONFIG, fse.getUUID(), false);
    /**
     * 报表发布
     *
     * @param fse
     * @return
     */
    @Transactional
    public boolean releaseConfig(FieldSetEntity fse) {
        //创建MVCC保存对象
        FieldSetEntity fseFunction = new FieldSetEntity();
        //1.创建MVC(系统MVC目录下)
        //生成功能编码
        String defaultCode = "001-005";
        fseFunction.setTableName(CmnConst.PRODUCT_SYS_FUNCTIONS);
        codeService.createCode(fseFunction, CmnConst.PRODUCT_SYS_FUNCTIONS, CmnConst.TRICODE, defaultCode);
        fseFunction.setValue(CmnConst.TABLE_UUID, CmnConst.PRODUCT_SYS_REPORT_CONFIG);            //功能关联表
        fseFunction.setValue(CmnConst.FUNCTION_NAME, fseReport.getString(CmnConst.REPORT_NAME));    //功能名称
        fseFunction.setValue(CmnConst.FUNCTION_DESCRIPTION, fseReport.getString(CmnConst.REPORT_NAME));    //功能描述
        fseFunction.setValue(CmnConst.STATUS_UUID, 1);            //是否启用
        fseFunction.setValue(CmnConst.FUNCTION_TYPE_UUID, 1);    //功能类型-业务功能
        fseFunction.setValue(CmnConst.CLIENT_TYPE_UUID, "Web");        //客户端类型
        fseFunction.setValue(CmnConst.VERSION_UUID, "001");
        fseFunction.setValue(CmnConst.DATA_TYPE, 1);// 数据类型
        fseFunction.setValue(CmnConst.TRICODE_PARENT, defaultCode);// 上级模块code
        fseFunction.setValue("terminal_type", 1);
        BaseUtil.createCreatorAndCreationTime(SpringMVCContextHolder.getCurrentUser(), fseFunction);
        FieldSetEntity fseReport = baseDao.getFieldSetEntity(CmnConst.PRODUCT_SYS_REPORT_CONFIG, fse.getUUID(), false);
        //创建按钮保存对象
        DataTableEntity dtButton = new DataTableEntity();
        FieldSetEntity fseButton = new FieldSetEntity();
        fseButton.setTableName(CmnConst.PRODUCT_SYS_FUNCTION_BUTTONS);
        fseButton.setValue(CmnConst.IS_MAIN, 1);        //是否入口
        fseButton.setValue(CmnConst.STATUS_UUID, 1);    //是否启用
        fseButton.setValue(CmnConst.CLIENT_TYPE_UUID, "Web");    //客户端类型
        fseButton.setValue(CmnConst.BUTTON_NAME, "入口");    //按钮名称
        fseButton.setValue(CmnConst.BUTTON_TITLE, "entrance");    //按钮标题
        fseButton.setValue(CmnConst.BUTTON_TYPE, 1);            //按钮类型
        fseButton.setValue(CmnConst.BUTTON_CATEGORY_UUID, "main");    //按钮分类
        fseButton.setValue(CmnConst.ROUTE_NAME, BaseUtil.getPageCode());    //路由名称
        fseButton.setValue(CmnConst.UPLOAD_API_URL, CmnConst.ADDRESS_INIT_INTERFENCE);// 入口接口地址
        fseButton.setValue("terminal_type", 1);
        JSONObject paramObj = new JSONObject();
        paramObj.put(CmnConst.UUID, fse.getUUID());
        fseButton.setValue(CmnConst.PARAMS, paramObj.toString());// 接口参数
        fseButton.setValue(CmnConst.TOP_LOCATION, "100px");
        fseButton.setValue(CmnConst.LEFT_LOCATION, "100px");
        dtButton.setMeta(fseButton.getMeta());
        dtButton.addFieldSetEntity(fseButton);
        //创建MVCC保存对象
        FieldSetEntity fseFunction = new FieldSetEntity();
        //1.创建MVC(系统MVC目录下)
        //生成功能编码
        String defaultCode = "001-005";
        fseFunction.setTableName(CmnConst.PRODUCT_SYS_FUNCTIONS);
        codeService.createCode(fseFunction, CmnConst.PRODUCT_SYS_FUNCTIONS, CmnConst.TRICODE, defaultCode);
        fseFunction.setValue(CmnConst.TABLE_UUID, CmnConst.PRODUCT_SYS_REPORT_CONFIG);            //功能关联表
        fseFunction.setValue(CmnConst.FUNCTION_NAME, fseReport.getString(CmnConst.REPORT_NAME));    //功能名称
        fseFunction.setValue(CmnConst.FUNCTION_DESCRIPTION, fseReport.getString(CmnConst.REPORT_NAME));    //功能描述
        fseFunction.setValue(CmnConst.STATUS_UUID, 1);            //是否启用
        fseFunction.setValue(CmnConst.FUNCTION_TYPE_UUID, 1);    //功能类型-业务功能
        fseFunction.setValue(CmnConst.CLIENT_TYPE_UUID, "Web");        //客户端类型
        fseFunction.setValue(CmnConst.VERSION_UUID, "001");
        fseFunction.setValue(CmnConst.DATA_TYPE, 1);// 数据类型
        fseFunction.setValue(CmnConst.TRICODE_PARENT, defaultCode);// 上级模块code
        fseFunction.setValue("terminal_type", 1);
        BaseUtil.createCreatorAndCreationTime(SpringMVCContextHolder.getCurrentUser(), fseFunction);
        //创建按钮保存对象
        DataTableEntity dtButton = new DataTableEntity();
        FieldSetEntity fseButton = new FieldSetEntity();
        fseButton.setTableName(CmnConst.PRODUCT_SYS_FUNCTION_BUTTONS);
        fseButton.setValue(CmnConst.IS_MAIN, 1);        //是否入口
        fseButton.setValue(CmnConst.STATUS_UUID, 1);    //是否启用
        fseButton.setValue(CmnConst.CLIENT_TYPE_UUID, "Web");    //客户端类型
        fseButton.setValue(CmnConst.BUTTON_NAME, "入口");    //按钮名称
        fseButton.setValue(CmnConst.BUTTON_TITLE, "entrance");    //按钮标题
        fseButton.setValue(CmnConst.BUTTON_TYPE, 1);            //按钮类型
        fseButton.setValue(CmnConst.BUTTON_CATEGORY_UUID, "main");    //按钮分类
        fseButton.setValue(CmnConst.ROUTE_NAME, BaseUtil.getPageCode());    //路由名称
        fseButton.setValue(CmnConst.UPLOAD_API_URL, CmnConst.ADDRESS_INIT_INTERFENCE);// 入口接口地址
        fseButton.setValue("terminal_type", 1);
        JSONObject paramObj = new JSONObject();
        paramObj.put(CmnConst.UUID, fse.getUUID());
        fseButton.setValue(CmnConst.PARAMS, paramObj.toString());// 接口参数
        fseButton.setValue(CmnConst.TOP_LOCATION, "100px");
        fseButton.setValue(CmnConst.LEFT_LOCATION, "100px");
        dtButton.setMeta(fseButton.getMeta());
        dtButton.addFieldSetEntity(fseButton);
        //创建页面保存对象
        DataTableEntity dtPage = new DataTableEntity();
        FieldSetEntity fsePage = new FieldSetEntity();
        fsePage.setTableName(CmnConst.PRODUCT_SYS_MVC_PAGE);
        //创建页面保存对象
        DataTableEntity dtPage = new DataTableEntity();
        FieldSetEntity fsePage = new FieldSetEntity();
        fsePage.setTableName(CmnConst.PRODUCT_SYS_MVC_PAGE);
//        fsePage.setValue(CmnConst.PAGE_NAME, "报表展示");
        fsePage.setValue(CmnConst.PAGE_NAME, fse.getString(CmnConst.MENU_NAME));
        fsePage.setValue(CmnConst.PAGE_TYPE, 2);
        fsePage.setValue(CmnConst.PAGE_URL, CmnConst.ADDRESS_REPORT_SHOW);
        fsePage.setValue(CmnConst.TOP_LOCATION, "300px");
        fsePage.setValue(CmnConst.LEFT_LOCATION, "100px");
        fsePage.setValue(CmnConst.PAGE_OPEN_WITH, 0);
        fsePage.setValue(CmnConst.PAGE_TYPE, 0);
        fsePage.setValue("terminal_type", 1);
        dtPage.addFieldSetEntity(fsePage);
        fsePage.setValue(CmnConst.PAGE_NAME, fse.getString(CmnConst.MENU_NAME));
        fsePage.setValue(CmnConst.PAGE_TYPE, 2);
        fsePage.setValue(CmnConst.PAGE_URL, CmnConst.ADDRESS_REPORT_SHOW);
        fsePage.setValue(CmnConst.TOP_LOCATION, "300px");
        fsePage.setValue(CmnConst.LEFT_LOCATION, "100px");
        fsePage.setValue(CmnConst.PAGE_OPEN_WITH, 0);
        fsePage.setValue(CmnConst.PAGE_TYPE, 0);
        fsePage.setValue("terminal_type", 1);
        dtPage.addFieldSetEntity(fsePage);
        fseFunction.addSubDataTable(dtButton);
        fseFunction.addSubDataTable(dtPage);
        fseFunction.addSubDataTable(dtButton);
        fseFunction.addSubDataTable(dtPage);
        String functionUUID = baseDao.add(fseFunction);
        String functionUUID = baseDao.add(fseFunction);
        //创建连线保存对象
        FieldSetEntity fseLink = new FieldSetEntity();
        fseLink.setTableName(CmnConst.PRODUCT_SYS_LINK);
        fseLink.setValue(CmnConst.LINK_TYPE, 0);        //连线类型
        fseLink.setValue(CmnConst.FUNCTION_UUID, functionUUID);    //所属功能UUID
        fseLink.setValue(CmnConst.LINE_FROM, fseButton.getUUID());    //起始端
        fseLink.setValue(CmnConst.FROM_TYPE, 0);                    //起始端类型
        fseLink.setValue(CmnConst.LINE_TO, fsePage.getUUID());        //结束端
        fseLink.setValue(CmnConst.TO_TYPE, 2);                        //结束端类型
        fseLink.setValue("terminal_type", 1);
        BaseUtil.createCreatorAndCreationTime(SpringMVCContextHolder.getCurrentUser(), fseLink);
        //创建连线保存对象
        FieldSetEntity fseLink = new FieldSetEntity();
        fseLink.setTableName(CmnConst.PRODUCT_SYS_LINK);
        fseLink.setValue(CmnConst.LINK_TYPE, 0);        //连线类型
        fseLink.setValue(CmnConst.FUNCTION_UUID, functionUUID);    //所属功能UUID
        fseLink.setValue(CmnConst.LINE_FROM, fseButton.getUUID());    //起始端
        fseLink.setValue(CmnConst.FROM_TYPE, 0);                    //起始端类型
        fseLink.setValue(CmnConst.LINE_TO, fsePage.getUUID());        //结束端
        fseLink.setValue(CmnConst.TO_TYPE, 2);                        //结束端类型
        fseLink.setValue("terminal_type", 1);
        BaseUtil.createCreatorAndCreationTime(SpringMVCContextHolder.getCurrentUser(), fseLink);
        baseDao.add(fseLink);
        baseDao.add(fseLink);
        // 提取发布的角色相关数据
        List<String> roleUUIDList = Lists.newArrayList();
        List<String> clientUUIDList = Lists.newArrayList();
        String[] singleRoleInfoArr;
        for (String singleRoleInfo : fse.getString(CmnConst.ROLE_UUID).split("#")) {
            singleRoleInfoArr = singleRoleInfo.split(",");
            roleUUIDList.add(singleRoleInfoArr[2]);
            clientUUIDList.add(singleRoleInfoArr[0]);
        }
        // 提取发布的角色相关数据
        List<String> roleUUIDList = Lists.newArrayList();
        List<String> clientUUIDList = Lists.newArrayList();
        String[] singleRoleInfoArr;
        for (String singleRoleInfo : fse.getString(CmnConst.ROLE_UUID).split("#")) {
            singleRoleInfoArr = singleRoleInfo.split(",");
            roleUUIDList.add(singleRoleInfoArr[2]);
            clientUUIDList.add(singleRoleInfoArr[0]);
        }
        // 2.绑定角色(给某一角色赋予该功能)
        for (String roleUUID : roleUUIDList) {
            FieldSetEntity fseFunctionButton = new FieldSetEntity();
            fseFunctionButton.setTableName(CmnConst.PRODUCT_SYS_FUNCTION_PERMISSION);
            fseFunctionButton.setValue(CmnConst.FUNCTION_UUID, functionUUID);// 所属功能UUID
            fseFunctionButton.setValue(CmnConst.BUTTON_UUID, fseButton.getUUID());// 按钮UUID
            fseFunctionButton.setValue(CmnConst.ROLE_UUID, roleUUID);// 所属角色UUID
            baseDao.add(fseFunctionButton);
        }
        // 2.绑定角色(给某一角色赋予该功能)
        for (String roleUUID : roleUUIDList) {
            FieldSetEntity fseFunctionButton = new FieldSetEntity();
            fseFunctionButton.setTableName(CmnConst.PRODUCT_SYS_FUNCTION_PERMISSION);
            fseFunctionButton.setValue(CmnConst.FUNCTION_UUID, functionUUID);// 所属功能UUID
            fseFunctionButton.setValue(CmnConst.BUTTON_UUID, fseButton.getUUID());// 按钮UUID
            fseFunctionButton.setValue(CmnConst.ROLE_UUID, roleUUID);// 所属角色UUID
            baseDao.add(fseFunctionButton);
        }
        // 3.绑定客户角色(给某一客户角色赋予该功能)
        for (String clientUUID : clientUUIDList) {
            DataTableEntity clientDte = DataPoolCacheImpl.getInstance().getCacheData("客户信息", new String[]{clientUUID});
            if (BaseUtil.dataTableIsEmpty(clientDte)) {
                continue;
            }
            FieldSetEntity clientFse = clientDte.getFieldSetEntity(0);
            FieldSetEntity fseClientFunctionButton = new FieldSetEntity();
            fseClientFunctionButton.setTableName(CmnConst.PRODUCT_SYS_FUNCTION_PERMISSION);
            fseClientFunctionButton.setValue(CmnConst.FUNCTION_UUID, functionUUID);// 所属功能UUID
            fseClientFunctionButton.setValue(CmnConst.BUTTON_UUID, fseButton.getUUID());// 按钮UUID
            fseClientFunctionButton.setValue(CmnConst.ROLE_UUID, clientFse.getString(CmnConst.ROLE_UUID));// 所属角色UUID
            baseDao.add(fseClientFunctionButton);
        }
        // 3.绑定客户角色(给某一客户角色赋予该功能)
        for (String clientUUID : clientUUIDList) {
            DataTableEntity clientDte = DataPoolCacheImpl.getInstance().getCacheData("客户信息", new String[]{clientUUID});
            if (BaseUtil.dataTableIsEmpty(clientDte)) {
                continue;
            }
            FieldSetEntity clientFse = clientDte.getFieldSetEntity(0);
            FieldSetEntity fseClientFunctionButton = new FieldSetEntity();
            fseClientFunctionButton.setTableName(CmnConst.PRODUCT_SYS_FUNCTION_PERMISSION);
            fseClientFunctionButton.setValue(CmnConst.FUNCTION_UUID, functionUUID);// 所属功能UUID
            fseClientFunctionButton.setValue(CmnConst.BUTTON_UUID, fseButton.getUUID());// 按钮UUID
            fseClientFunctionButton.setValue(CmnConst.ROLE_UUID, clientFse.getString(CmnConst.ROLE_UUID));// 所属角色UUID
            baseDao.add(fseClientFunctionButton);
        }
        //4.创建菜单(根据前端所选父级菜单)
        FieldSetEntity fseMenu = new FieldSetEntity();
        fseMenu.setTableName(CmnConst.PRODUCT_SYS_MENUS);
        codeService.createCode(fseMenu, CmnConst.PRODUCT_SYS_MENUS, CmnConst.TRICODE, fse.getString(CmnConst.TRICODE_PARENT));
        fseMenu.setValue(CmnConst.TRICODE_PARENT, fse.getString(CmnConst.TRICODE_PARENT));
        fseMenu.setValue(CmnConst.MENU_NAME, fse.getString(CmnConst.MENU_NAME));
        fseMenu.setValue(CmnConst.FUNCTION_UUID, functionUUID);
        fseMenu.setValue(CmnConst.SEQUENCE, fse.getString(CmnConst.SEQUENCE));
        fseMenu.setValue(CmnConst.IS_CATALOG, 0);
        fseMenu.setValue(CmnConst.IS_SHOW, StringUtils.isEmpty(fse.getString(CmnConst.IS_SHOW)) ? 1 : fse.getString(CmnConst.IS_SHOW));
        fseMenu.setValue(CmnConst.MENU_ICON, fse.getString(CmnConst.MENU_ICON));
        BaseUtil.createCreatorAndCreationTime(SpringMVCContextHolder.getCurrentUser(), fseMenu);
        //4.创建菜单(根据前端所选父级菜单)
        FieldSetEntity fseMenu = new FieldSetEntity();
        fseMenu.setTableName(CmnConst.PRODUCT_SYS_MENUS);
        codeService.createCode(fseMenu, CmnConst.PRODUCT_SYS_MENUS, CmnConst.TRICODE, fse.getString(CmnConst.TRICODE_PARENT));
        fseMenu.setValue(CmnConst.TRICODE_PARENT, fse.getString(CmnConst.TRICODE_PARENT));
        fseMenu.setValue(CmnConst.MENU_NAME, fse.getString(CmnConst.MENU_NAME));
        fseMenu.setValue(CmnConst.FUNCTION_UUID, functionUUID);
        fseMenu.setValue(CmnConst.SEQUENCE, fse.getString(CmnConst.SEQUENCE));
        fseMenu.setValue(CmnConst.IS_CATALOG, 0);
        fseMenu.setValue(CmnConst.IS_SHOW, StringUtils.isEmpty(fse.getString(CmnConst.IS_SHOW)) ? 1 : fse.getString(CmnConst.IS_SHOW));
        fseMenu.setValue(CmnConst.MENU_ICON, fse.getString(CmnConst.MENU_ICON));
        BaseUtil.createCreatorAndCreationTime(SpringMVCContextHolder.getCurrentUser(), fseMenu);
        baseDao.add(fseMenu);
        baseDao.add(fseMenu);
        //数据回写
        fseReport.setValue(CmnConst.FUNCTION_UUID, functionUUID);
        //数据回写
        fseReport.setValue(CmnConst.FUNCTION_UUID, functionUUID);
        boolean result = baseDao.update(fseReport);
        boolean result = baseDao.update(fseReport);
        // 重新设置缓存
        dataListReportService.setConfig(fseReport.getUUID());
        // 重新设置缓存
        dataListReportService.setConfig(fseReport.getUUID());
        return result;
    }
        return result;
    }
    /**
     * 报表copy
     *
     * @param uuid
     * @return
     */
    public String copyConfig(String uuid) {
        FieldSetEntity fse = baseDao.getFieldSetEntity(CmnConst.PRODUCT_SYS_REPORT_CONFIG, uuid, true);
        FieldSetEntity fseCopy = fse;
        fseCopy.remove(CmnConst.ID);
        fseCopy.remove(CmnConst.UUID);
        DataTableEntity dtSub = fseCopy.getSubDataTable(CmnConst.PRODUCT_SYS_REPORT_CONFIG_ATTRIBUTE);
        if (dtSub != null && dtSub.getRows() > 0) {
            for (int i = 0; i < dtSub.getRows(); i++) {
                FieldSetEntity fseSub = dtSub.getFieldSetEntity(i);
                fseSub.remove(CmnConst.ID);
                fseSub.remove(CmnConst.UUID);
            }
        }
        return baseDao.add(fseCopy, true);
    }
    /**
     * 报表copy
     *
     * @param uuid
     * @return
     */
    public String copyConfig(String uuid) {
        FieldSetEntity fse = baseDao.getFieldSetEntity(CmnConst.PRODUCT_SYS_REPORT_CONFIG, uuid, true);
        FieldSetEntity fseCopy = fse;
        fseCopy.remove(CmnConst.ID);
        fseCopy.remove(CmnConst.UUID);
        DataTableEntity dtSub = fseCopy.getSubDataTable(CmnConst.PRODUCT_SYS_REPORT_CONFIG_ATTRIBUTE);
        if (dtSub != null && dtSub.getRows() > 0) {
            for (int i = 0; i < dtSub.getRows(); i++) {
                FieldSetEntity fseSub = dtSub.getFieldSetEntity(i);
                fseSub.remove(CmnConst.ID);
                fseSub.remove(CmnConst.UUID);
            }
        }
        return baseDao.add(fseCopy, true);
    }
    /**
     * 配置报表-引用
     *
     * @param fse
     * @return
     */
    public FieldSetEntity quoteReportConfig(FieldSetEntity fse) {
        FieldSetEntity sourceFse = findReportConfig(fse.getUUID());
        sourceFse.setValue(CmnConst.DATASOURCE_UUID, fse.getString(CmnConst.DATASOURCE_UUID));
        sourceFse.remove(new String[]{CmnConst.ID, CmnConst.UUID, CmnConst.CREATED_BY, CmnConst.CREATED_UTC_DATETIME, CmnConst.UPDATED_BY, CmnConst.CREATED_UTC_DATETIME, CmnConst.REPORT_NAME});
        DataTableEntity subDte = sourceFse.getSubDataTable(CmnConst.PRODUCT_SYS_REPORT_CONFIG_ATTRIBUTE);
        FieldSetEntity subFse;
        for (int i = 0; i < subDte.getRows(); i++) {
            subFse = subDte.getFieldSetEntity(i);
            subFse.remove(new String[]{CmnConst.ID, CmnConst.UUID, CmnConst.CREATED_BY, CmnConst.CREATED_UTC_DATETIME, CmnConst.UPDATED_BY, CmnConst.CREATED_UTC_DATETIME});
        }
        return sourceFse;
    }
    /**
     * 配置报表-引用
     *
     * @param fse
     * @return
     */
    public FieldSetEntity quoteReportConfig(FieldSetEntity fse) {
        FieldSetEntity sourceFse = findReportConfig(fse.getUUID());
        sourceFse.setValue(CmnConst.DATASOURCE_UUID, fse.getString(CmnConst.DATASOURCE_UUID));
        sourceFse.remove(new String[]{CmnConst.ID, CmnConst.UUID, CmnConst.CREATED_BY, CmnConst.CREATED_UTC_DATETIME, CmnConst.UPDATED_BY, CmnConst.CREATED_UTC_DATETIME, CmnConst.REPORT_NAME});
        DataTableEntity subDte = sourceFse.getSubDataTable(CmnConst.PRODUCT_SYS_REPORT_CONFIG_ATTRIBUTE);
        FieldSetEntity subFse;
        for (int i = 0; i < subDte.getRows(); i++) {
            subFse = subDte.getFieldSetEntity(i);
            subFse.remove(new String[]{CmnConst.ID, CmnConst.UUID, CmnConst.CREATED_BY, CmnConst.CREATED_UTC_DATETIME, CmnConst.UPDATED_BY, CmnConst.CREATED_UTC_DATETIME});
        }
        return sourceFse;
    }
    /**
     * 获取报表发布信息-发布
     *
     * @return
     */
    public JSONArray getReportReleaseInfo() {
        StringBuilder sql = new StringBuilder(256);
        DataTableEntity aimDte = new DataTableEntity();
        DataTableEntity dte;
        Object[] arr;
        String filter;
        sql.append("select distinct null pid,uuid sid,client_name name FROM product_sys_clients c")
                .append("\ninner join (")
                .append("\n    select client_uuid pid,uuid sid,org_level_name FROM product_sys_org_levels where org_level_status=0 order by org_level_code")
                .append("\n) o on o.pid=c.uuid")
                .append("\ninner join (")
                .append("\n    select org_level_uuid pid,uuid sid,role_name FROM product_sys_role where is_used=1")
                .append("\n) r on r.pid=o.sid");
        // 去掉admin所属客户
    /**
     * 获取报表发布信息-发布
     *
     * @return
     */
    public JSONArray getReportReleaseInfo() {
        StringBuilder sql = new StringBuilder(256);
        DataTableEntity aimDte = new DataTableEntity();
        DataTableEntity dte;
        Object[] arr;
        String filter;
        sql.append("select distinct null pid,uuid sid,client_name name FROM product_sys_clients c")
                .append("\ninner join (")
                .append("\n    select client_uuid pid,uuid sid,org_level_name FROM product_sys_org_levels where org_level_status=0 order by org_level_code")
                .append("\n) o on o.pid=c.uuid")
                .append("\ninner join (")
                .append("\n    select org_level_uuid pid,uuid sid,role_name FROM product_sys_role where is_used=1")
                .append("\n) r on r.pid=o.sid");
        // 去掉admin所属客户
//                .append("\nwhere c.uuid!='4d4679ed-c4c3-41b8-abfe-451a66fd4043'");
        dte = baseDao.listTable(sql.toString(), new Object[]{});
        dte = baseDao.listTable(sql.toString(), new Object[]{});
        aimDte.addFieldSetEntity(dte);
        aimDte.addFieldSetEntity(dte);
        arr = dte.getFieldAllValues("sid");
        filter = BaseUtil.buildQuestionMarkFilter("client_uuid", arr.length, true);
        sql.setLength(0);
        sql.append("\nselect distinct o.* from (")
                .append("\n    select client_uuid pid,uuid sid,org_level_name name FROM product_sys_org_levels where org_level_status=0")
                .append("\n    and ").append(filter)
                .append("\n    order by org_level_code")
                .append("\n) o")
                .append("\ninner join (")
                .append("\n    select org_level_uuid pid,uuid sid,role_name FROM product_sys_role where is_used=1")
                .append("\n) r on r.pid=o.sid");
        dte = baseDao.listTable(sql.toString(), arr);
        aimDte.addFieldSetEntity(dte);
        arr = dte.getFieldAllValues("sid");
        filter = BaseUtil.buildQuestionMarkFilter("client_uuid", arr.length, true);
        sql.setLength(0);
        sql.append("\nselect distinct o.* from (")
                .append("\n    select client_uuid pid,uuid sid,org_level_name name FROM product_sys_org_levels where org_level_status=0")
                .append("\n    and ").append(filter)
                .append("\n    order by org_level_code")
                .append("\n) o")
                .append("\ninner join (")
                .append("\n    select org_level_uuid pid,uuid sid,role_name FROM product_sys_role where is_used=1")
                .append("\n) r on r.pid=o.sid");
        dte = baseDao.listTable(sql.toString(), arr);
        aimDte.addFieldSetEntity(dte);
        arr = dte.getFieldAllValues("sid");
        filter = BaseUtil.buildQuestionMarkFilter("org_level_uuid", arr.length, true);
        sql.setLength(0);
        sql.append("\nselect org_level_uuid pid,uuid sid,role_name name FROM product_sys_role where is_used=1").append(" and ").append(filter);
        dte = baseDao.listTable(sql.toString(), arr);
        aimDte.addFieldSetEntity(dte);
        arr = dte.getFieldAllValues("sid");
        filter = BaseUtil.buildQuestionMarkFilter("org_level_uuid", arr.length, true);
        sql.setLength(0);
        sql.append("\nselect org_level_uuid pid,uuid sid,role_name name FROM product_sys_role where is_used=1").append(" and ").append(filter);
        dte = baseDao.listTable(sql.toString(), arr);
        aimDte.addFieldSetEntity(dte);
        return BaseUtil.dataTableToTreeData(aimDte, "sid", "pid", null, false);
    }
        return BaseUtil.dataTableToTreeData(aimDte, "sid", "pid", null, false);
    }
    /**
     * 获取报表发布信息-发布后查看信息
     *
     * @return
     */
    public JSONObject viewReportReleaseInfo(FieldSetEntity fse) {
        DataTableEntity reportConfigDte = DataPoolCacheImpl.getInstance().getCacheData(CmnConst.CACHE_REPORT_CONFIG, new String[]{fse.getUUID()});
        if (BaseUtil.dataTableIsEmpty(reportConfigDte)) {
            throw new BaseException(ReportCode.GET_REPORT_RELEASE_INFO_FAIL.getValue(), ReportCode.GET_REPORT_RELEASE_INFO_FAIL.getText());
        }
        FieldSetEntity reportConfigFse = reportConfigDte.getFieldSetEntity(0);
        StringBuilder sql = new StringBuilder(256);
        sql.append("\nselect group_concat(single_role_uuid separator '#') role_uuid")
                .append("\nfrom (")
                .append("\n    select concat(client_uuid,',',uuid,',',role_uuid) single_role_uuid")
                .append("\n    FROM product_sys_org_levels o")
                .append("\n    inner join (")
                .append("\n        select org_level_uuid,uuid role_uuid,role_name")
                .append("\n        FROM product_sys_role r")
                .append("\n        inner join (")
                .append("\n            select role_uuid FROM product_sys_function_permission where function_uuid=?")
                .append("\n        ) p on r.uuid=p.role_uuid")
                .append("\n    ) r1 on o.uuid=r1.org_level_uuid")
                .append("\n) t");
        String functionUUID = reportConfigFse.getString(CmnConst.FUNCTION_UUID);
        DataTableEntity dte = baseDao.listTable(sql.toString(), new Object[]{functionUUID});
    /**
     * 获取报表发布信息-发布后查看信息
     *
     * @return
     */
    public JSONObject viewReportReleaseInfo(FieldSetEntity fse) {
        DataTableEntity reportConfigDte = DataPoolCacheImpl.getInstance().getCacheData(CmnConst.CACHE_REPORT_CONFIG, new String[]{fse.getUUID()});
        if (BaseUtil.dataTableIsEmpty(reportConfigDte)) {
            throw new BaseException(ReportCode.GET_REPORT_RELEASE_INFO_FAIL.getValue(), ReportCode.GET_REPORT_RELEASE_INFO_FAIL.getText());
        }
        FieldSetEntity reportConfigFse = reportConfigDte.getFieldSetEntity(0);
        StringBuilder sql = new StringBuilder(256);
        sql.append("\nselect group_concat(single_role_uuid separator '#') role_uuid")
                .append("\nfrom (")
                .append("\n    select concat(client_uuid,',',uuid,',',role_uuid) single_role_uuid")
                .append("\n    FROM product_sys_org_levels o")
                .append("\n    inner join (")
                .append("\n        select org_level_uuid,uuid role_uuid,role_name")
                .append("\n        FROM product_sys_role r")
                .append("\n        inner join (")
                .append("\n            select role_uuid FROM product_sys_function_permission where function_uuid=?")
                .append("\n        ) p on r.uuid=p.role_uuid")
                .append("\n    ) r1 on o.uuid=r1.org_level_uuid")
                .append("\n) t");
        String functionUUID = reportConfigFse.getString(CmnConst.FUNCTION_UUID);
        DataTableEntity dte = baseDao.listTable(sql.toString(), new Object[]{functionUUID});
        FieldSetEntity menuFse = baseDao.getFieldSetEntityByFilter(CmnConst.PRODUCT_SYS_MENUS, "function_uuid=?", new Object[]{functionUUID}, false);
        FieldSetEntity menuFse = baseDao.getFieldSetEntityByFilter(CmnConst.PRODUCT_SYS_MENUS, "function_uuid=?", new Object[]{functionUUID}, false);
        JSONObject resultObj = new JSONObject();
        resultObj.put(CmnConst.UUID, fse.getUUID());
        resultObj.put(CmnConst.ROLE_UUID, dte.getFieldSetEntity(0).getString(CmnConst.ROLE_UUID));
        resultObj.put(CmnConst.TRICODE_PARENT, menuFse.getString(CmnConst.TRICODE_PARENT));
        resultObj.put(CmnConst.MENU_ICON, menuFse.getString(CmnConst.MENU_ICON));
        resultObj.put(CmnConst.MENU_NAME, menuFse.getString(CmnConst.MENU_NAME));
        JSONObject resultObj = new JSONObject();
        resultObj.put(CmnConst.UUID, fse.getUUID());
        resultObj.put(CmnConst.ROLE_UUID, dte.getFieldSetEntity(0).getString(CmnConst.ROLE_UUID));
        resultObj.put(CmnConst.TRICODE_PARENT, menuFse.getString(CmnConst.TRICODE_PARENT));
        resultObj.put(CmnConst.MENU_ICON, menuFse.getString(CmnConst.MENU_ICON));
        resultObj.put(CmnConst.MENU_NAME, menuFse.getString(CmnConst.MENU_NAME));
        return resultObj;
    }
        return resultObj;
    }
    /**
     * 已发布列表界面
     *
     * @param fse
     * @return
     */
    public DataTableEntity releasedListReportConfig(FieldSetEntity fse) {
        String filter = queryFilterService.getQueryFilter(fse);
        StringBuilder sql = new StringBuilder(256);
    /**
     * 已发布列表界面
     *
     * @param fse
     * @return
     */
    public DataTableEntity releasedListReportConfig(FieldSetEntity fse) {
        String filter = queryFilterService.getQueryFilter(fse);
        StringBuilder sql = new StringBuilder(256);
//        sql.append("select * from ( ");
        sql.append("\n    select rc.uuid,rc.report_name,rtc.type_name,t1.role_info,mp.menu_name tricode_parent,m.menu_icon,m.menu_name ");
        sql.append("\n    FROM product_sys_report_config rc ");
        sql.append("\n    inner join ( ");
        sql.append("\n        select function_uuid,group_concat(role_info separator ',') role_info ");
        sql.append("\n        from ( ");
        sql.append("\n            select function_uuid,concat(c.client_name,'/',o.org_level_name,'/',role_name) role_info ");
        sql.append("\n                        FROM product_sys_clients c ");
        sql.append("\n                        inner join product_sys_org_levels o on o.client_uuid=c.uuid ");
        sql.append("\n                        inner join ( ");
        sql.append("\n                                select function_uuid,org_level_uuid,uuid role_uuid,role_name ");
        sql.append("\n                                FROM product_sys_role r ");
        sql.append("\n                                inner join ( ");
        sql.append("\n                                        select function_uuid,role_uuid FROM product_sys_function_permission ");
        sql.append("\n                                ) p on r.uuid=p.role_uuid ");
        sql.append("\n                        ) r1 on o.uuid=r1.org_level_uuid ");
        sql.append("\n        ) t ");
        sql.append("\n        group by function_uuid ");
        sql.append("\n    ) t1 on rc.function_uuid=t1.function_uuid ");
        sql.append("\n    inner join product_sys_menus m on rc.function_uuid=m.function_uuid ");
        sql.append("\n    inner join product_sys_report_type_config rtc on rc.type_uuid=rtc.uuid ");
        sql.append("\n    inner join product_sys_menus mp on m.tricode_parent=mp.tricode ");
        sql.append("\n    select rc.uuid,rc.report_name,rtc.type_name,t1.role_info,mp.menu_name tricode_parent,m.menu_icon,m.menu_name ");
        sql.append("\n    FROM product_sys_report_config rc ");
        sql.append("\n    inner join ( ");
        sql.append("\n        select function_uuid,group_concat(role_info separator ',') role_info ");
        sql.append("\n        from ( ");
        sql.append("\n            select function_uuid,concat(c.client_name,'/',o.org_level_name,'/',role_name) role_info ");
        sql.append("\n                        FROM product_sys_clients c ");
        sql.append("\n                        inner join product_sys_org_levels o on o.client_uuid=c.uuid ");
        sql.append("\n                        inner join ( ");
        sql.append("\n                                select function_uuid,org_level_uuid,uuid role_uuid,role_name ");
        sql.append("\n                                FROM product_sys_role r ");
        sql.append("\n                                inner join ( ");
        sql.append("\n                                        select function_uuid,role_uuid FROM product_sys_function_permission ");
        sql.append("\n                                ) p on r.uuid=p.role_uuid ");
        sql.append("\n                        ) r1 on o.uuid=r1.org_level_uuid ");
        sql.append("\n        ) t ");
        sql.append("\n        group by function_uuid ");
        sql.append("\n    ) t1 on rc.function_uuid=t1.function_uuid ");
        sql.append("\n    inner join product_sys_menus m on rc.function_uuid=m.function_uuid ");
        sql.append("\n    inner join product_sys_report_type_config rtc on rc.type_uuid=rtc.uuid ");
        sql.append("\n    inner join product_sys_menus mp on m.tricode_parent=mp.tricode ");
//        sql.append("\n) t2 ");
        if (!StringUtils.isEmpty(filter)) {
            sql.append(" WHERE " + filter);
        }
        Integer curPage = fse.getInteger(CmnConst.CPAGE);
        Integer pageSize = fse.getInteger(CmnConst.PAGESIZE);
        return baseDao.listTable(sql.toString(), new Object[]{}, pageSize == null ? Integer.MAX_VALUE : pageSize, curPage == null ? 1 : curPage);
    }
        if (!StringUtils.isEmpty(filter)) {
            sql.append(" WHERE " + filter);
        }
        Integer curPage = fse.getInteger(CmnConst.CPAGE);
        Integer pageSize = fse.getInteger(CmnConst.PAGESIZE);
        return baseDao.listTable(sql.toString(), new Object[]{}, pageSize == null ? Integer.MAX_VALUE : pageSize, curPage == null ? 1 : curPage);
    }
}