|
@@ -0,0 +1,649 @@
|
|
|
+package com.example.opc_da.validate.reportTable;
|
|
|
+
|
|
|
+import cn.hutool.core.collection.CollUtil;
|
|
|
+import com.alibaba.fastjson.JSONArray;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.cqcy.ei.influxdb.entity.Item;
|
|
|
+import com.cqcy.ei.influxdb.service.InFluxDBService;
|
|
|
+import com.example.opc_common.enums.ResultEnum;
|
|
|
+import com.example.opc_common.exception.CustomException;
|
|
|
+import com.example.opc_common.util.Blank;
|
|
|
+import com.example.opc_common.util.ConstantStr;
|
|
|
+import com.example.opc_da.config.SpringContextUtils;
|
|
|
+import com.example.opc_da.task.ReportTableBasicItemEnum;
|
|
|
+import org.jetbrains.annotations.NotNull;
|
|
|
+
|
|
|
+import javax.validation.constraints.NotBlank;
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.time.LocalTime;
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
+import java.time.temporal.TemporalAdjusters;
|
|
|
+import java.util.*;
|
|
|
+import java.util.function.Function;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+import java.util.stream.Stream;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 自动报表验证抽象类
|
|
|
+ */
|
|
|
+public abstract class AutomaticReportTableValidate implements ReportTableValidate {
|
|
|
+
|
|
|
+ private static final String timePattern = "yyyy-MM-dd HH:mm:ss.SSS";
|
|
|
+
|
|
|
+ InFluxDBService inFluxDBService = SpringContextUtils.getBean(InFluxDBService.class);
|
|
|
+ String bucket = SpringContextUtils.getYamlProperty("influxdb.bucket");
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将自动报表的reportTableData解析出来,并赋值相应的数据
|
|
|
+ *
|
|
|
+ * @param reportTableDataStr 报表字符串
|
|
|
+ * @param referTime 参考时间
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ protected String resolveAutoTableData(@NotBlank String reportTableDataStr, LocalDateTime referTime) {
|
|
|
+ //解析自动报表结构
|
|
|
+ JSONObject reportTableData = JSONObject.parseObject(reportTableDataStr);
|
|
|
+ //得到sheet数据
|
|
|
+ JSONObject sheet = reportTableData.getJSONObject("sheet");
|
|
|
+ reportTableData.put("sheet", resolveAutoTableSheetData(sheet, referTime));
|
|
|
+
|
|
|
+ //得到chart数据
|
|
|
+ JSONObject chart = reportTableData.getJSONObject("chart");
|
|
|
+ reportTableData.put("chart", resolveAutoTableChartData(chart, referTime));
|
|
|
+
|
|
|
+ //将生成的数据重新转换为json
|
|
|
+ return reportTableData.toJSONString();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 解析周期报表sheet数据
|
|
|
+ *
|
|
|
+ * @param sheet
|
|
|
+ * @param referTime 参考时间
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private JSONObject resolveAutoTableSheetData(JSONObject sheet, LocalDateTime referTime) {
|
|
|
+ JSONArray sheetData = sheet.getJSONArray("data");
|
|
|
+ //遍历sheet所有单元格,并存为Map<tableId,Map<uid,JSONObject>>格式
|
|
|
+ Map<String, Map<String, JSONObject>> sheetTableMap = getAutoStringMapMap(sheetData);
|
|
|
+
|
|
|
+ //遍历生成的sheetTableMap,根据配置获取数据,并存为Map<tableId, Map<uid,List<Item>>>格式
|
|
|
+ Map<String, Map<String, List<Item>>> sheetTableDataMap = new HashMap<>();
|
|
|
+ for (Map.Entry<String, Map<String, JSONObject>> sheetTable : sheetTableMap.entrySet()) {
|
|
|
+ sheetTableDataMap.put(sheetTable.getKey(),
|
|
|
+ generateSheetTableDataMap(sheetTable.getValue(), referTime));
|
|
|
+ }
|
|
|
+
|
|
|
+ //sheet数据最后往Json中存为data[0].data,回填数据
|
|
|
+ echoSheet(sheetData, sheetTableDataMap);
|
|
|
+ sheet.put("data", sheetData);
|
|
|
+ return sheet;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 回填表格数据
|
|
|
+ *
|
|
|
+ * @param sheetData
|
|
|
+ * @param sheetTableDataMap
|
|
|
+ */
|
|
|
+ private static void echoSheet(JSONArray sheetData, Map<String, Map<String, List<Item>>> sheetTableDataMap) {
|
|
|
+ for (int i = 0; i < sheetData.size(); i++) {
|
|
|
+ JSONArray row = sheetData.getJSONArray(i);
|
|
|
+ for (int j = 0; j < row.size(); j++) {
|
|
|
+ JSONObject rowCol = row.getJSONObject(j);
|
|
|
+ if (Blank.isNotEmpty(rowCol)) {
|
|
|
+ //能解析的数据才赋值
|
|
|
+ try {
|
|
|
+ JSONObject rowColJson = JSONObject.parseObject(rowCol.getString("v"));
|
|
|
+ String type = rowColJson.getString("type");
|
|
|
+ String tableId = rowColJson.getString("tableId");
|
|
|
+ //如果类型为数据,则存入数据
|
|
|
+ if (type.equals("data")) {
|
|
|
+ JSONObject rowColData = rowColJson.getJSONObject("data");
|
|
|
+ String uid = rowColData.getString("uid");
|
|
|
+ if (Blank.isNotEmpty(uid)) {
|
|
|
+ List<Item> itemList = sheetTableDataMap.get(tableId).get(uid);
|
|
|
+ String value = itemList.get(0).getValue();
|
|
|
+ rowCol.put("v", value);
|
|
|
+ rowCol.put("m", value);
|
|
|
+ itemList.remove(0);
|
|
|
+ }
|
|
|
+ //如果类型为时间,则存入时间
|
|
|
+ } else if (type.equals("datatime")) {
|
|
|
+ List<Item> itemList = sheetTableDataMap.get(tableId).entrySet().stream().findFirst().get().getValue();
|
|
|
+ String time = itemList.get(0).getTime();
|
|
|
+ rowCol.put("v", time);
|
|
|
+ rowCol.put("m", time);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ String v = rowCol.getString("v");
|
|
|
+ String regex = "^\\$\\{.*\\}$";
|
|
|
+ //赋值基础数据项
|
|
|
+ if (v.matches(regex)) {
|
|
|
+ String basicItem = v.substring(2, v.length() - 1);
|
|
|
+ ReportTableBasicItemEnum reportTableBasicItemEnum = Arrays.stream(ReportTableBasicItemEnum.values())
|
|
|
+ .filter(b -> b.name().equals(basicItem)).findFirst().get();
|
|
|
+ if (Blank.isNotEmpty(reportTableBasicItemEnum)) {
|
|
|
+ String value = reportTableBasicItemEnum.getValue();
|
|
|
+ rowCol.put("v", value);
|
|
|
+ rowCol.put("m", value);
|
|
|
+ } else {
|
|
|
+ rowCol.put("v", "");
|
|
|
+ rowCol.put("m", "");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 遍历sheet所有单元格,并存为Map<tableId,Map<uid,JSONObject>>格式
|
|
|
+ *
|
|
|
+ * @param sheetData
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @NotNull
|
|
|
+ private static Map<String, Map<String, JSONObject>> getAutoStringMapMap(JSONArray sheetData) {
|
|
|
+ Map<String, Map<String, JSONObject>> sheetTableMap = new HashMap<>();
|
|
|
+ for (int i = 0; i < sheetData.size(); i++) {
|
|
|
+ JSONArray row = sheetData.getJSONArray(i);
|
|
|
+ for (int j = 0; j < row.size(); j++) {
|
|
|
+ JSONObject rowCol = row.getJSONObject(j);
|
|
|
+ if (Blank.isNotEmpty(rowCol)) {
|
|
|
+ try {
|
|
|
+ JSONObject rowColJson = JSONObject.parseObject(rowCol.getString("v"));
|
|
|
+ String tableId = rowColJson.getString("tableId");
|
|
|
+ String type = rowColJson.getString("type");
|
|
|
+ if (type.equals("data")) {
|
|
|
+ JSONObject rowColData = rowColJson.getJSONObject("data");
|
|
|
+ String uid = rowColData.getString("uid");
|
|
|
+ Map<String, JSONObject> sheetUidMap = sheetTableMap.get(tableId);
|
|
|
+ if (Blank.isEmpty(sheetUidMap)) sheetUidMap = new HashMap<>();
|
|
|
+ //得到所有sheet数据生成条件
|
|
|
+ if (Blank.isEmpty(sheetUidMap.get(uid)) && Blank.isNotEmpty(uid)) {
|
|
|
+ sheetUidMap.put(uid, rowColJson);
|
|
|
+ sheetTableMap.put(tableId, sheetUidMap);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return sheetTableMap;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param sheetUidMap
|
|
|
+ * @param referTime
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public Map<String, List<Item>> generateSheetTableDataMap(
|
|
|
+ Map<String, JSONObject> sheetUidMap, LocalDateTime referTime) {
|
|
|
+ //得到单个区域所有的数据项配置信息
|
|
|
+ List<JSONObject> tableJsonObjectList = sheetUidMap.values().stream().collect(Collectors.toList());
|
|
|
+ //对数据项配置信息,通过报表数据策略id,数据切换类型,开始时间,结束时间,取值类型进行分组
|
|
|
+ //Map<分组条件Json,分组后集合List<JSONObject>>
|
|
|
+ Map<JSONObject, List<JSONObject>> jsonMap = tableJsonObjectList.stream()
|
|
|
+ .collect(Collectors.groupingBy(getSheetJSONObjectFunction()));
|
|
|
+
|
|
|
+ //将单个区域数据项配置信息,转换为Map<uid,上面的jsonMap键>格式
|
|
|
+ Map<String, JSONObject> uidMap = tableJsonObjectList.stream()
|
|
|
+ .collect(Collectors.toMap(j -> j.getJSONObject("data").getString("uid"),
|
|
|
+ getSheetJSONObjectFunction()));
|
|
|
+
|
|
|
+ //通过分组的信息,查询数据,并再分组,Map<JSONObject,Map<uid,List<Item>>
|
|
|
+ //遍历分组之后的jsonMap,
|
|
|
+ Map<JSONObject, Map<String, List<Item>>> sheetItemMap = new HashMap<>();
|
|
|
+ for (Map.Entry<JSONObject, List<JSONObject>> json : jsonMap.entrySet()) {
|
|
|
+ //查询单个分组集合的数据,并转换为Map<policyItemId,List<Item>>,然后回填到sheetItemMap中
|
|
|
+ JSONObject jsonObject = json.getKey();
|
|
|
+ List<JSONObject> jsonObjectList = json.getValue();
|
|
|
+
|
|
|
+ //查询单个分组集合的数据
|
|
|
+ List<Item> itemList = getItems(referTime, jsonObjectList, jsonObject);
|
|
|
+ //转换为Map<policyItemId,List<Item>>,然后回填到sheetItemMap中
|
|
|
+ sheetItemMap.put(jsonObject, itemList.stream().collect(Collectors.groupingBy(i -> i.getName())));
|
|
|
+ }
|
|
|
+ //将单个区域的数据项,生成Map<uid,List<Item>>结构数据
|
|
|
+ Map<String, List<Item>> sheetUidDataMap = new HashMap<>();
|
|
|
+ for (Map.Entry<String, JSONObject> sheetUid : sheetUidMap.entrySet()) {
|
|
|
+ JSONObject jsonObject = sheetUid.getValue();
|
|
|
+ String uid = sheetUid.getKey();
|
|
|
+ String itemId = jsonObject.getJSONObject("data").getString("itemId");
|
|
|
+ Map<String, List<Item>> stringListMap = sheetItemMap.get(uidMap.get(uid));
|
|
|
+ List<Item> itemList = stringListMap.get(itemId);
|
|
|
+ //通过计算得到新的集合
|
|
|
+ sheetUidDataMap.put(uid, countUidData(jsonObject, itemList, referTime));
|
|
|
+ }
|
|
|
+ return sheetUidDataMap;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算单个uid,分割之后的数据
|
|
|
+ *
|
|
|
+ * @param jsonObject
|
|
|
+ * @param itemList
|
|
|
+ * @param referTime
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private List<Item> countUidData(JSONObject jsonObject, List<Item> itemList, LocalDateTime referTime) {
|
|
|
+ JSONObject setting = jsonObject.getJSONObject("setting");
|
|
|
+ String bucketType = setting.getString("bucketType");
|
|
|
+
|
|
|
+ //根据上面时间类型,生成sTime,eTime
|
|
|
+ LocalDateTime sTime = getSheetStartTime(setting, referTime);
|
|
|
+ LocalDateTime eTime = getSheetEndTime(setting, referTime);
|
|
|
+ //0数据集,1单值
|
|
|
+ String dataValueType = setting.getString("dataValueType");
|
|
|
+ //取值模式0平均值,1最大值,2最小值,3瞬时值
|
|
|
+ String valueTakingMode = setting.getString("valueTakingMode");
|
|
|
+ //时段值
|
|
|
+ Integer bucketValue = setting.getInteger("bucketValue");
|
|
|
+ return splitData(dataValueType, itemList, sTime, eTime,
|
|
|
+ valueTakingMode, bucketType, bucketValue);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询单个分组的所有数据
|
|
|
+ *
|
|
|
+ * @param referTime 参考时间
|
|
|
+ * @param jsonObjectList
|
|
|
+ * @param jsonObject
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private List<Item> getItems(LocalDateTime referTime, List<JSONObject> jsonObjectList, JSONObject jsonObject) {
|
|
|
+ //得到单个分组的所有数据项id
|
|
|
+ List<String> policyItemIdList = jsonObjectList.stream()
|
|
|
+ .map(j -> j.getJSONObject("data").getString("itemId"))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ //得到单个分组的配置信息
|
|
|
+ JSONObject data = jsonObject.getJSONObject("data");
|
|
|
+ String policyId = data.getString("policyId");
|
|
|
+
|
|
|
+ JSONObject setting = jsonObject.getJSONObject("setting");
|
|
|
+ String valueType = setting.getString("valueType");
|
|
|
+
|
|
|
+ //根据上面时间类型,生成sTime,eTime
|
|
|
+ LocalDateTime sTime = getSheetStartTime(setting, referTime);
|
|
|
+ LocalDateTime eTime = getSheetEndTime(setting, referTime);
|
|
|
+ //根据配置信息查询过滤数据库的所有数据
|
|
|
+ return inFluxDBService.queryHistory(bucket, policyId, sTime, eTime, policyItemIdList, valueType);
|
|
|
+ }
|
|
|
+
|
|
|
+ @NotNull
|
|
|
+ private static Function<JSONObject, JSONObject> getSheetJSONObjectFunction() {
|
|
|
+ return j -> {
|
|
|
+ JSONObject data = j.getJSONObject("data");
|
|
|
+ JSONObject jsonObject = new JSONObject();
|
|
|
+ JSONObject dataJsonObject = new JSONObject();
|
|
|
+ dataJsonObject.put("policyId", data.get("policyId"));
|
|
|
+
|
|
|
+ JSONObject setting = j.getJSONObject("setting");
|
|
|
+ JSONObject setJsonObject = new JSONObject();
|
|
|
+ setJsonObject.put("valueType", setting.getString("valueType"));
|
|
|
+
|
|
|
+ setJsonObject.put("bucketType", setting.getString("bucketType"));
|
|
|
+
|
|
|
+ setJsonObject.put("timeType1", setting.getString("timeType1"));
|
|
|
+ setJsonObject.put("timeValue1", setting.getString("timeValue1"));
|
|
|
+ setJsonObject.put("dateTimeType1", setting.getString("dateTimeType1"));
|
|
|
+ setJsonObject.put("startTime", setting.getString("startTime"));
|
|
|
+
|
|
|
+ setJsonObject.put("timeType2", setting.getString("timeType2"));
|
|
|
+ setJsonObject.put("timeValue2", setting.getString("timeValue2"));
|
|
|
+ setJsonObject.put("dateTimeType2", setting.getString("dateTimeType2"));
|
|
|
+ setJsonObject.put("endTime", setting.getString("endTime"));
|
|
|
+
|
|
|
+ jsonObject.put("data", dataJsonObject);
|
|
|
+ jsonObject.put("setting", setJsonObject);
|
|
|
+ return jsonObject;
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取sheet单个区域的开始时间
|
|
|
+ *
|
|
|
+ * @param setting sheet单个区域的配置
|
|
|
+ * @param referTime 参考时间
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private LocalDateTime getSheetStartTime(JSONObject setting, LocalDateTime referTime) {
|
|
|
+ String bucketType = setting.getString("bucketType");
|
|
|
+ String timeType1 = setting.getString("timeType1");
|
|
|
+ Integer timeValue1 = setting.getInteger("timeValue1");
|
|
|
+ String dateTimeType1 = setting.getString("dateTimeType1");
|
|
|
+ String startTime = setting.getString("startTime");
|
|
|
+ return generateCycleTime(referTime, bucketType, timeType1, timeValue1, dateTimeType1, startTime);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取sheet单个区域的结束时间
|
|
|
+ *
|
|
|
+ * @param setting sheet单个区域的配置
|
|
|
+ * @param referTime 参考时间
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private LocalDateTime getSheetEndTime(JSONObject setting, LocalDateTime referTime) {
|
|
|
+ String bucketType = setting.getString("bucketType");
|
|
|
+
|
|
|
+ String timeType2 = setting.getString("timeType2");
|
|
|
+ Integer timeValue2 = setting.getInteger("timeValue2");
|
|
|
+ String dateTimeType2 = setting.getString("dateTimeType2");
|
|
|
+ String endTime = setting.getString("endTime");
|
|
|
+ LocalDateTime localDateTime = generateCycleTime(referTime, bucketType, timeType2, timeValue2, dateTimeType2, endTime);
|
|
|
+ return localDateTime.isBefore(LocalDateTime.now()) ? localDateTime : LocalDateTime.now();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 解析周期报表chart数据
|
|
|
+ *
|
|
|
+ * @param chart
|
|
|
+ * @param referTime 参考时间
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private JSONObject resolveAutoTableChartData(JSONObject chart, LocalDateTime referTime) {
|
|
|
+ for (Map.Entry<String, Object> entry : chart.entrySet()) {
|
|
|
+ String entryKey = entry.getKey();
|
|
|
+ //获取统计图的配置信息
|
|
|
+ chart.put(entryKey, generateChartJson(chart.getJSONObject(entryKey), referTime));
|
|
|
+ }
|
|
|
+ return chart;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据统计图配置信息,生成数据,并覆盖原来的模拟值,返回json'
|
|
|
+ *
|
|
|
+ * @param chartJson
|
|
|
+ * @param referTime
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private JSONObject generateChartJson(JSONObject chartJson, LocalDateTime referTime) {
|
|
|
+ JSONObject dataForm = chartJson.getJSONObject("dataForm");
|
|
|
+ JSONArray items = chartJson.getJSONArray("items");
|
|
|
+// String policyId = dataForm.getString("policyId");
|
|
|
+ String policyId = dataForm.getString("chart-item-group");
|
|
|
+
|
|
|
+ String valueType = dataForm.getString("valueType");
|
|
|
+ String bucketType = dataForm.getString("bucketType");
|
|
|
+
|
|
|
+ //根据配置信息,生成统计图的开始和结束时间
|
|
|
+ LocalDateTime sTime = getChartStartTime(dataForm, referTime);
|
|
|
+ LocalDateTime eTime = getChartEndTime(dataForm, referTime);
|
|
|
+ //获取统计图配置的所有数据项
|
|
|
+ List<String> policyItemIdList = items.stream().map(v -> ((JSONObject) v).getString("value")).collect(Collectors.toList());
|
|
|
+ //根据开始、结束时间、数据项等相关信息,查询过滤数据库中的数据
|
|
|
+ List<Item> itemList = inFluxDBService.queryHistory(bucket, policyId, sTime, eTime, policyItemIdList, valueType);
|
|
|
+ //将得到的数据转换为Map<ItemId,List<Item>> 格式
|
|
|
+ Map<String, List<Item>> itemDataMap = itemList.stream().collect(Collectors.groupingBy(i -> i.getName()));
|
|
|
+ String valueTakingMode = dataForm.getString("valueTakingMode");
|
|
|
+ Integer bucketValue = dataForm.getInteger("bucketValue");
|
|
|
+ //得到series的数据
|
|
|
+ //将生成的数据回传到chart中去
|
|
|
+ JSONObject chartData = chartJson.getJSONObject("chartData");
|
|
|
+ JSONArray series = chartData.getJSONArray("series");
|
|
|
+ String chartType = series.getJSONObject(0).getString("type");
|
|
|
+ //如果为柱状图或折线图
|
|
|
+ if (chartType.equals(ConstantStr.LINE_CHART) || chartType.equals(ConstantStr.BAR_CHART)) {
|
|
|
+ //所有时间数据,组成x轴
|
|
|
+ List<String> allXaiosList = new ArrayList<>();
|
|
|
+ List<List<List<String>>> serieDataList = new ArrayList<>();
|
|
|
+ //遍历数据项
|
|
|
+ for (String policyItemId : policyItemIdList) {
|
|
|
+ List<Item> validDataList = splitData(null, itemDataMap.get(policyItemId), sTime, eTime, valueTakingMode, bucketType, bucketValue);
|
|
|
+ allXaiosList.addAll(validDataList.stream().map(Item::getTime).collect(Collectors.toList()));
|
|
|
+ //生成series的数据
|
|
|
+ serieDataList.add(validDataList.stream().map(i ->
|
|
|
+ Stream.of(i.getTime(), i.getValue()).collect(Collectors.toList())
|
|
|
+ ).collect(Collectors.toList()));
|
|
|
+ }
|
|
|
+ //得到x轴时间去重数据
|
|
|
+ List<String> xAxisList = allXaiosList.stream().distinct().sorted().collect(Collectors.toList());
|
|
|
+
|
|
|
+ for (int i = 0; i < series.size(); i++) {
|
|
|
+ JSONObject serieJsonObject = series.getJSONObject(i);
|
|
|
+ serieJsonObject.put("data", serieDataList.get(i));
|
|
|
+ }
|
|
|
+ JSONObject xAxis = chartData.getJSONArray("xAxis").getJSONObject(0);
|
|
|
+ xAxis.put("data", xAxisList);
|
|
|
+ //如果为饼图
|
|
|
+ } else if (chartType.equals(ConstantStr.PIE_CHART)) {
|
|
|
+ //因为饼图只有一个数据项
|
|
|
+ List<Item> validDataList = itemDataMap.get(policyItemIdList.get(0));
|
|
|
+ //生成series的数据
|
|
|
+ List<JSONObject> serieDataList = validDataList.stream().map(v -> {
|
|
|
+ JSONObject jsonObject = new JSONObject();
|
|
|
+ jsonObject.put("value", v.getValue());
|
|
|
+ jsonObject.put("name", v.getTime());
|
|
|
+ return jsonObject;
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ series.getJSONObject(0).put("data", serieDataList);
|
|
|
+ }
|
|
|
+ return chartJson;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取chart单个统计图的开始时间
|
|
|
+ *
|
|
|
+ * @param dataForm chart单个统计图的配置
|
|
|
+ * @param referTime 参考时间
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private LocalDateTime getChartStartTime(JSONObject dataForm, LocalDateTime referTime) {
|
|
|
+ String bucketType = dataForm.getString("bucketType");
|
|
|
+
|
|
|
+ String chartTimeType1 = dataForm.getString("chartTimeType1");
|
|
|
+ Integer chartTimeValue1 = dataForm.getInteger("chartTimeValue1");
|
|
|
+ String chartDateTimeType1 = dataForm.getString("chartDateTimeType1");
|
|
|
+ String chartSettingData1 = dataForm.getString("chartSettingData1");
|
|
|
+ return generateCycleTime(referTime, bucketType, chartTimeType1,
|
|
|
+ chartTimeValue1, chartDateTimeType1, chartSettingData1);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取chart单个统计图的结束时间
|
|
|
+ *
|
|
|
+ * @param dataForm chart单个统计图的配置
|
|
|
+ * @param referTime 参考时间
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private LocalDateTime getChartEndTime(JSONObject dataForm, LocalDateTime referTime) {
|
|
|
+ String bucketType = dataForm.getString("bucketType");
|
|
|
+
|
|
|
+ String chartTimeType2 = dataForm.getString("chartTimeType2");
|
|
|
+ Integer chartTimeValue2 = dataForm.getInteger("chartTimeValue2");
|
|
|
+ String chartDateTimeType2 = dataForm.getString("chartDateTimeType2");
|
|
|
+ String chartSettingData2 = dataForm.getString("chartSettingData2");
|
|
|
+ LocalDateTime localDateTime = generateCycleTime(referTime, bucketType, chartTimeType2,
|
|
|
+ chartTimeValue2, chartDateTimeType2, chartSettingData2);
|
|
|
+ return localDateTime.isBefore(LocalDateTime.now()) ? localDateTime : LocalDateTime.now();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成周期报表时间方法
|
|
|
+ *
|
|
|
+ * @param referTime 参考时间,如果时间为空,则是查实时数据,不为空,则查历史数据
|
|
|
+ * @param bucketType 时段类型:0月,1天,2时,3粉,4秒
|
|
|
+ * @param timeType 0当,1次
|
|
|
+ * @param timeValue 值
|
|
|
+ * @param dateTimeType
|
|
|
+ * @param dateTimeValue
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private LocalDateTime generateCycleTime(LocalDateTime referTime, String bucketType, String timeType, Integer timeValue,
|
|
|
+ String dateTimeType, String dateTimeValue) {
|
|
|
+ if (Blank.isNotEmpty(referTime)) {
|
|
|
+ if (bucketType.equals(ConstantStr.PERIOD_TIME_MONTH)) {
|
|
|
+ //如果时段类型选择为月
|
|
|
+ if (timeType.equals(ConstantStr.TYPE_LAST)) {
|
|
|
+ //参考时间的上一年 指定月 第一天
|
|
|
+ return referTime.minusYears(1).withMonth(timeValue).with(TemporalAdjusters.firstDayOfMonth());
|
|
|
+ } else if (timeType.equals(ConstantStr.TYPE_CURRENT)) {
|
|
|
+ //参考时间的本年 指定月 第一天
|
|
|
+ return referTime.withMonth(timeValue).with(TemporalAdjusters.firstDayOfMonth());
|
|
|
+ }
|
|
|
+ } else if (bucketType.equals(ConstantStr.PERIOD_TIME_DAY)) {
|
|
|
+ //如果时段类型选择为日
|
|
|
+ if (timeType.equals(ConstantStr.TYPE_LAST)) {
|
|
|
+ //参考时间的本年 上一月 指定天
|
|
|
+ return referTime.minusMonths(1).withDayOfMonth(timeValue);
|
|
|
+ } else if (timeType.equals(ConstantStr.TYPE_CURRENT)) {
|
|
|
+ //参考时间的本年 本月 指定天
|
|
|
+ return referTime.withDayOfMonth(timeValue);
|
|
|
+ }
|
|
|
+ } else if (bucketType.equals(ConstantStr.PERIOD_TIME_HOUR) ||
|
|
|
+ bucketType.equals(ConstantStr.PERIOD_TIME_MINUTE) ||
|
|
|
+ bucketType.equals(ConstantStr.PERIOD_TIME_SECOND)) {
|
|
|
+ //如果时段类型选择为时,分,秒
|
|
|
+ if (dateTimeType.equals(ConstantStr.TYPE_LAST)) {
|
|
|
+ //参考时间的本年 本月 下一天 指定时分秒
|
|
|
+ return referTime.minusDays(1).with(LocalTime.parse(dateTimeValue, DateTimeFormatter.ofPattern("HH:mm:ss")));
|
|
|
+ } else if (dateTimeType.equals(ConstantStr.TYPE_CURRENT)) {
|
|
|
+ //参考时间的本年 本月 本天 指定时分秒
|
|
|
+ return referTime.with(LocalTime.parse(dateTimeValue, DateTimeFormatter.ofPattern("HH:mm:ss")));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ referTime = LocalDateTime.now();
|
|
|
+ if (bucketType.equals(ConstantStr.PERIOD_TIME_MONTH)) {
|
|
|
+ //如果时段类型选择为月
|
|
|
+ if (timeType.equals(ConstantStr.TYPE_LAST)) {
|
|
|
+ //参考时间的本年 指定月 第一天
|
|
|
+ return referTime.withMonth(timeValue).with(TemporalAdjusters.firstDayOfMonth());
|
|
|
+ } else if (timeType.equals(ConstantStr.TYPE_CURRENT)) {
|
|
|
+ //参考时间的下一年 指定月 第一天
|
|
|
+ return referTime.plusYears(1).withMonth(timeValue).with(TemporalAdjusters.firstDayOfMonth());
|
|
|
+ }
|
|
|
+ } else if (bucketType.equals(ConstantStr.PERIOD_TIME_DAY)) {
|
|
|
+ //如果时段类型选择为日
|
|
|
+ if (timeType.equals(ConstantStr.TYPE_LAST)) {
|
|
|
+ //参考时间的本年 本月 指定天
|
|
|
+ return referTime.withDayOfMonth(timeValue);
|
|
|
+ } else if (timeType.equals(ConstantStr.TYPE_CURRENT)) {
|
|
|
+ //参考时间的本年 下一月 指定天
|
|
|
+ return referTime.plusMonths(1).withDayOfMonth(timeValue);
|
|
|
+ }
|
|
|
+ } else if (bucketType.equals(ConstantStr.PERIOD_TIME_HOUR) ||
|
|
|
+ bucketType.equals(ConstantStr.PERIOD_TIME_MINUTE) ||
|
|
|
+ bucketType.equals(ConstantStr.PERIOD_TIME_SECOND)) {
|
|
|
+ //如果时段类型选择为时,分,秒
|
|
|
+ if (dateTimeType.equals(ConstantStr.TYPE_LAST)) {
|
|
|
+ //参考时间的本年 本月 本天 指定时分秒
|
|
|
+ return referTime.with(LocalTime.parse(dateTimeValue, DateTimeFormatter.ofPattern("HH:mm:ss")));
|
|
|
+ } else if (dateTimeType.equals(ConstantStr.TYPE_CURRENT)) {
|
|
|
+ //参考时间的本年 本月 下一天 指定时分秒
|
|
|
+ return referTime.plusDays(1).with(LocalTime.parse(dateTimeValue, DateTimeFormatter.ofPattern("HH:mm:ss")));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return LocalDateTime.now();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 通过开始时间和结束时间分割数据,并计算
|
|
|
+ *
|
|
|
+ * @param dataValueType 0数据集,1单值,空也为数据集
|
|
|
+ * @param itemList 全部数据项集合
|
|
|
+ * @param startDateTime 开始时间
|
|
|
+ * @param endDateTime 结束时间
|
|
|
+ * @param valueTakingMode 取值模式:0平均值,1最大值,2最小值,3瞬时值,4求和,5计数
|
|
|
+ * @param bucketType 时段类型:0天,1时,2分,3秒
|
|
|
+ * @param bucketValue 时段值
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private List<Item> splitData(String dataValueType, List<Item> itemList, LocalDateTime startDateTime, LocalDateTime endDateTime,
|
|
|
+ String valueTakingMode, String bucketType, Integer bucketValue) {
|
|
|
+ List<Item> newItemList = new ArrayList<>();
|
|
|
+ //获取数据集
|
|
|
+ if (Blank.isEmpty(dataValueType) || dataValueType.equals(ConstantStr.DATA_SET)) {
|
|
|
+ LocalDateTime sDateTime = startDateTime;
|
|
|
+ LocalDateTime eDateTime;
|
|
|
+ //如果sDateTime小于endDateTime
|
|
|
+ while (sDateTime.isBefore(endDateTime)) {
|
|
|
+ if (bucketType.equals(ConstantStr.PERIOD_TIME_MONTH)) {
|
|
|
+ eDateTime = sDateTime.plusMonths(bucketValue);
|
|
|
+ } else if (bucketType.equals(ConstantStr.PERIOD_TIME_DAY)) {
|
|
|
+ eDateTime = sDateTime.plusDays(bucketValue);
|
|
|
+ } else if (bucketType.equals(ConstantStr.PERIOD_TIME_HOUR)) {
|
|
|
+ eDateTime = sDateTime.plusHours(bucketValue);
|
|
|
+ } else if (bucketType.equals(ConstantStr.PERIOD_TIME_MINUTE)) {
|
|
|
+ eDateTime = sDateTime.plusMinutes(bucketValue);
|
|
|
+ } else if (bucketType.equals(ConstantStr.PERIOD_TIME_SECOND)) {
|
|
|
+ eDateTime = sDateTime.plusSeconds(bucketValue);
|
|
|
+ } else {
|
|
|
+ throw new CustomException(ResultEnum.REQUEST_WRONGPARAMS.getRespCode(), "时段类型错误");
|
|
|
+ }
|
|
|
+ List<String> valueList = new ArrayList<>();
|
|
|
+ if (CollUtil.isNotEmpty(itemList)) {
|
|
|
+ for (int i = 0; i < itemList.size(); i++) {
|
|
|
+ Item item = itemList.get(i);
|
|
|
+ LocalDateTime itemDateTime = LocalDateTime.parse(item.getTime(), DateTimeFormatter.ofPattern(timePattern));
|
|
|
+ if (sDateTime.isAfter(itemDateTime)) {
|
|
|
+ itemList.remove(i);
|
|
|
+ i--;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (itemDateTime.isBefore(eDateTime)) {
|
|
|
+ valueList.add(item.getValue());
|
|
|
+ itemList.remove(i);
|
|
|
+ i--;
|
|
|
+ } else {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //求出每段应该返回的值
|
|
|
+ newItemList.add(new Item()
|
|
|
+ .value(countData(valueList, valueTakingMode))
|
|
|
+ .time(sDateTime.format(DateTimeFormatter.ofPattern(timePattern))));
|
|
|
+ sDateTime = eDateTime;
|
|
|
+ }
|
|
|
+ return newItemList;
|
|
|
+ } else if (dataValueType.equals(ConstantStr.SINGLE_VALUE)) {
|
|
|
+ newItemList.add(new Item()
|
|
|
+ .value(countData(itemList.stream().map(i ->
|
|
|
+ i.getValue()).collect(Collectors.toList()), valueTakingMode))
|
|
|
+ .time(startDateTime.format(DateTimeFormatter.ofPattern(timePattern))));
|
|
|
+ }
|
|
|
+ return newItemList;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将传入的集合数据组,通过不同的取值模式,算出来
|
|
|
+ *
|
|
|
+ * @param valueList 数据集合
|
|
|
+ * @param valueTakingMode 取值模式:0平均值,1最大值,2最小值,3瞬时值,4求和,5计数
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static String countData(List<String> valueList, String valueTakingMode) {
|
|
|
+ if (CollUtil.isNotEmpty(valueList)) {
|
|
|
+ try {
|
|
|
+ if (valueTakingMode.equals(ConstantStr.AVERAGE_VALUE)) {
|
|
|
+ return valueList.stream().mapToDouble(Double::valueOf).average().getAsDouble() + "";
|
|
|
+ }
|
|
|
+ if (valueTakingMode.equals(ConstantStr.MAX_VALUE)) {
|
|
|
+ return valueList.stream().mapToDouble(Double::valueOf).max().getAsDouble() + "";
|
|
|
+ }
|
|
|
+ if (valueTakingMode.equals(ConstantStr.MIN_VALUE)) {
|
|
|
+ return valueList.stream().mapToDouble(Double::valueOf).min().getAsDouble() + "";
|
|
|
+ }
|
|
|
+ if (valueTakingMode.equals(ConstantStr.INSTANTANEOUS_VALUE)) {
|
|
|
+ return valueList.get(0);
|
|
|
+ }
|
|
|
+ if (valueTakingMode.equals(ConstantStr.SUM_VALUE)) {
|
|
|
+ return valueList.stream().mapToDouble(Double::valueOf).sum() + "";
|
|
|
+ }
|
|
|
+ if (valueTakingMode.equals(ConstantStr.COUNT_VALUE)) {
|
|
|
+ return valueList.stream().count() + "";
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+}
|