Commit 69f9cf040eaf4078124e621a9ce3ce74b1bcfbb8

Authored by xp.Huang
1 parent 45a61abf

fix: 报表导出存在数据异常的情况

... ... @@ -12,4 +12,10 @@ public class CustomDataForExcelDTO {
12 12 List<List<String>> sheetHeads;
13 13 /** sheet的数据 */
14 14 List<?> sheetData;
  15 +
  16 + public CustomDataForExcelDTO(String sheetName, List<List<String>> sheetHeads, List<?> sheetData) {
  17 + this.sheetName = sheetName;
  18 + this.sheetHeads = sheetHeads;
  19 + this.sheetData = sheetData;
  20 + }
15 21 }
... ...
... ... @@ -48,8 +48,7 @@ import java.time.LocalDateTime;
48 48 import java.time.ZoneOffset;
49 49 import java.time.format.DateTimeFormatter;
50 50 import java.util.*;
51   -import java.util.concurrent.CompletableFuture;
52   -import java.util.concurrent.ExecutionException;
  51 +import java.util.concurrent.atomic.AtomicInteger;
53 52 import java.util.stream.Collectors;
54 53
55 54 @Service
... ... @@ -65,6 +64,7 @@ public class TkReportGenerateRecordServiceImpl
65 64 private final TimeseriesService tsService;
66 65 private final FileStorageService fileStorageService;
67 66 private final UserOrganizationMappingService userOrganizationMappingService;
  67 + private volatile HashMap<String,List<CustomDataForExcelDTO>> excelReportMap = new HashMap<>();
68 68
69 69 @Override
70 70 public TkPageData<ReportGenerateRecordDTO> page(
... ... @@ -179,11 +179,14 @@ public class TkReportGenerateRecordServiceImpl
179 179 @Override
180 180 public void generateExcelUpdateReportRecord(ReportFormConfigDTO formConfigDTO,List<ExecuteAttributesDTO> executeAttributes,
181 181 String recordId){
182   - List<CustomDataForExcelDTO> list = new ArrayList<>();
183   - for(ExecuteAttributesDTO dto:executeAttributes){
184   - Long startTs = formConfigDTO.getQueryCondition().getStartTs();
185   - Long endTs = formConfigDTO.getQueryCondition().getEndTs();
186   - //获取当前定时任务的执行时间,并计算新的开始时间、结束时间
  182 + String executeReportKey = formConfigDTO.getTenantId() + "_" + formConfigDTO.getName() + "_"
  183 + + System.currentTimeMillis();
  184 + //剩余执行次数
  185 + AtomicInteger remainTimes = new AtomicInteger(executeAttributes.size());
  186 + Long startTs = formConfigDTO.getQueryCondition().getStartTs();
  187 + Long endTs = formConfigDTO.getQueryCondition().getEndTs();
  188 + //如果是固定周期,均以执行定时任务的时间作为开始-结束时间
  189 + if (formConfigDTO.getQueryCondition().getQueryMode() == FastIotConstants.MagicNumber.ZERO){
187 190 ReportGenerateRecordDTO recordDTO =
188 191 findReportGenerateRecordById(recordId, formConfigDTO.getTenantId());
189 192 long differenceTs = endTs - startTs;
... ... @@ -191,26 +194,18 @@ public class TkReportGenerateRecordServiceImpl
191 194 startTs = endTs - differenceTs;
192 195 formConfigDTO.getQueryCondition().setStartTs(startTs);
193 196 formConfigDTO.getQueryCondition().setEndTs(endTs);
194   - CustomDataForExcelDTO result = getTsKvValuesOrGenerateExcel(formConfigDTO, dto).join();
195   - list.add(result);
196 197 }
197   - // 获取所有结果
198   - ObjectNode executeCondition = JacksonUtil.newObjectNode();
199   - QueryConditionDTO queryCondition = formConfigDTO.getQueryCondition();
200   - executeCondition.replace(
201   - FastIotConstants.CHART_EXECUTE_CONDITION,
202   - JacksonUtil.convertValue(queryCondition, JsonNode.class));
203   - executeCondition.replace(
204   - FastIotConstants.CHART_EXECUTE_ATTRIBUTES,
205   - JacksonUtil.convertValue(formConfigDTO.getExecuteAttributes(), JsonNode.class));
206   - // 汇总所有数据,生成Excel并上传
207   - generateExcelAndUpload(list,formConfigDTO.getName(),recordId,formConfigDTO.getTenantId(),
208   - executeCondition);
  198 + for(ExecuteAttributesDTO dto:executeAttributes){
  199 + getTsKvValuesOrGenerateExcel(formConfigDTO, dto,executeReportKey,remainTimes,recordId);
  200 + }
209 201 }
210 202
211   - private CompletableFuture<CustomDataForExcelDTO> getTsKvValuesOrGenerateExcel(
  203 + private void getTsKvValuesOrGenerateExcel(
212 204 ReportFormConfigDTO formConfigDTO,
213   - ExecuteAttributesDTO dto) {
  205 + ExecuteAttributesDTO dto,
  206 + String executeReportKey,
  207 + AtomicInteger remainTimes,
  208 + String recordId) {
214 209 QueryConditionDTO queryCondition = formConfigDTO.getQueryCondition();
215 210 boolean useStrictDataTypes = queryCondition.isUseStrictDataTypes();
216 211 Long interval = queryCondition.getInterval();
... ... @@ -232,12 +227,10 @@ public class TkReportGenerateRecordServiceImpl
232 227 .collect(Collectors.toList());
233 228 queryCondition.setStartTs(finalStartTs);
234 229 queryCondition.setEndTs(finalEndTs);
235   - CustomDataForExcelDTO result = new CustomDataForExcelDTO();
236 230 Futures.addCallback(
237 231 tsService.findAll(tenantId, entityId, queries),
238   - getTsKvListCallback(result, useStrictDataTypes, dto.getName(), keys),
  232 + getTsKvListCallback(useStrictDataTypes, dto.getName(), keys,executeReportKey,remainTimes,formConfigDTO,recordId),
239 233 MoreExecutors.directExecutor());
240   - return CompletableFuture.supplyAsync(()->result);
241 234 }
242 235
243 236 @Override
... ... @@ -254,10 +247,13 @@ public class TkReportGenerateRecordServiceImpl
254 247 }
255 248
256 249 private FutureCallback<List<TsKvEntry>> getTsKvListCallback(
257   - CustomDataForExcelDTO response,
258 250 Boolean useStrictDataTypes,
259 251 String deviceName,
260   - List<String> keys) {
  252 + List<String> keys,
  253 + String executeReportKey,
  254 + AtomicInteger remainTimes,
  255 + ReportFormConfigDTO formConfigDTO,
  256 + String recordId) {
261 257 return new FutureCallback<>() {
262 258 @Override
263 259 public void onSuccess(List<TsKvEntry> data) {
... ... @@ -277,13 +273,44 @@ public class TkReportGenerateRecordServiceImpl
277 273 }
278 274 }
279 275 generateExcelHeadAndValues(result, deviceName, heads, values);
280   - response.setSheetName(deviceName);
281   - response.setSheetHeads(heads);
282   - response.setSheetData(values);
  276 + List<CustomDataForExcelDTO> list = excelReportMap.get(executeReportKey);
  277 + if(null == list){
  278 + list = new ArrayList<>();
  279 + }
  280 + list.add(new CustomDataForExcelDTO(deviceName,heads,values));
  281 + excelReportMap.put(executeReportKey,list);
  282 + if(remainTimes.get() == 1){
  283 + // 获取所有结果
  284 + ObjectNode executeCondition = JacksonUtil.newObjectNode();
  285 + QueryConditionDTO queryCondition = formConfigDTO.getQueryCondition();
  286 + executeCondition.replace(
  287 + FastIotConstants.CHART_EXECUTE_CONDITION,
  288 + JacksonUtil.convertValue(queryCondition, JsonNode.class));
  289 + executeCondition.replace(
  290 + FastIotConstants.CHART_EXECUTE_ATTRIBUTES,
  291 + JacksonUtil.convertValue(formConfigDTO.getExecuteAttributes(), JsonNode.class));
  292 + // 汇总所有数据,生成Excel并上传
  293 + generateExcelAndUpload(list,formConfigDTO.getName(),recordId,formConfigDTO.getTenantId(),
  294 + executeCondition,true,null);
  295 + //移除数据
  296 + excelReportMap.remove(executeReportKey);
  297 + }else{
  298 + remainTimes.decrementAndGet();
  299 + }
283 300 }
284 301
285 302 @Override
286 303 public void onFailure(@NotNull Throwable e) {
  304 + ObjectNode executeCondition = JacksonUtil.newObjectNode();
  305 + QueryConditionDTO queryCondition = formConfigDTO.getQueryCondition();
  306 + executeCondition.replace(
  307 + FastIotConstants.CHART_EXECUTE_CONDITION,
  308 + JacksonUtil.convertValue(queryCondition, JsonNode.class));
  309 + executeCondition.replace(
  310 + FastIotConstants.CHART_EXECUTE_ATTRIBUTES,
  311 + JacksonUtil.convertValue(formConfigDTO.getExecuteAttributes(), JsonNode.class));
  312 + generateExcelAndUpload(null,formConfigDTO.getName(),recordId,formConfigDTO.getTenantId(),
  313 + executeCondition,false,e.getMessage());
287 314 log.error("Failed to fetch historical data", e);
288 315 }
289 316 };
... ... @@ -339,15 +366,18 @@ public class TkReportGenerateRecordServiceImpl
339 366 String reportFormName,
340 367 String reportGenerateRecordId,
341 368 String tenantId,
342   - JsonNode executeCondition) {
  369 + JsonNode executeCondition,
  370 + boolean needUpload,
  371 + String errorMessage) {
343 372 String response = null;
344   - String errorMessage = null;
345 373 int status = StatusEnum.SUCCESS.getIndex();
346 374 try {
347   - ByteArrayOutputStream byteArrayOutputStream = ExcelUtil.manySheetWrite(list);
348   - String fileName = reportFormName + System.currentTimeMillis() + ".xlsx";
349   - InputStream inputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
350   - response = fileStorageService.uploadFile(fileName, CONTENT_TYPE, inputStream);
  375 + if(needUpload){
  376 + ByteArrayOutputStream byteArrayOutputStream = ExcelUtil.manySheetWrite(list);
  377 + String fileName = reportFormName + System.currentTimeMillis() + ".xlsx";
  378 + InputStream inputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
  379 + response = fileStorageService.uploadFile(fileName, CONTENT_TYPE, inputStream);
  380 + }
351 381 } catch (Exception e) {
352 382 errorMessage = e.getLocalizedMessage();
353 383 }
... ...