Commit 69f9cf040eaf4078124e621a9ce3ce74b1bcfbb8

Authored by xp.Huang
1 parent 45a61abf

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

@@ -12,4 +12,10 @@ public class CustomDataForExcelDTO { @@ -12,4 +12,10 @@ public class CustomDataForExcelDTO {
12 List<List<String>> sheetHeads; 12 List<List<String>> sheetHeads;
13 /** sheet的数据 */ 13 /** sheet的数据 */
14 List<?> sheetData; 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,8 +48,7 @@ import java.time.LocalDateTime;
48 import java.time.ZoneOffset; 48 import java.time.ZoneOffset;
49 import java.time.format.DateTimeFormatter; 49 import java.time.format.DateTimeFormatter;
50 import java.util.*; 50 import java.util.*;
51 -import java.util.concurrent.CompletableFuture;  
52 -import java.util.concurrent.ExecutionException; 51 +import java.util.concurrent.atomic.AtomicInteger;
53 import java.util.stream.Collectors; 52 import java.util.stream.Collectors;
54 53
55 @Service 54 @Service
@@ -65,6 +64,7 @@ public class TkReportGenerateRecordServiceImpl @@ -65,6 +64,7 @@ public class TkReportGenerateRecordServiceImpl
65 private final TimeseriesService tsService; 64 private final TimeseriesService tsService;
66 private final FileStorageService fileStorageService; 65 private final FileStorageService fileStorageService;
67 private final UserOrganizationMappingService userOrganizationMappingService; 66 private final UserOrganizationMappingService userOrganizationMappingService;
  67 + private volatile HashMap<String,List<CustomDataForExcelDTO>> excelReportMap = new HashMap<>();
68 68
69 @Override 69 @Override
70 public TkPageData<ReportGenerateRecordDTO> page( 70 public TkPageData<ReportGenerateRecordDTO> page(
@@ -179,11 +179,14 @@ public class TkReportGenerateRecordServiceImpl @@ -179,11 +179,14 @@ public class TkReportGenerateRecordServiceImpl
179 @Override 179 @Override
180 public void generateExcelUpdateReportRecord(ReportFormConfigDTO formConfigDTO,List<ExecuteAttributesDTO> executeAttributes, 180 public void generateExcelUpdateReportRecord(ReportFormConfigDTO formConfigDTO,List<ExecuteAttributesDTO> executeAttributes,
181 String recordId){ 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 ReportGenerateRecordDTO recordDTO = 190 ReportGenerateRecordDTO recordDTO =
188 findReportGenerateRecordById(recordId, formConfigDTO.getTenantId()); 191 findReportGenerateRecordById(recordId, formConfigDTO.getTenantId());
189 long differenceTs = endTs - startTs; 192 long differenceTs = endTs - startTs;
@@ -191,26 +194,18 @@ public class TkReportGenerateRecordServiceImpl @@ -191,26 +194,18 @@ public class TkReportGenerateRecordServiceImpl
191 startTs = endTs - differenceTs; 194 startTs = endTs - differenceTs;
192 formConfigDTO.getQueryCondition().setStartTs(startTs); 195 formConfigDTO.getQueryCondition().setStartTs(startTs);
193 formConfigDTO.getQueryCondition().setEndTs(endTs); 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 ReportFormConfigDTO formConfigDTO, 204 ReportFormConfigDTO formConfigDTO,
213 - ExecuteAttributesDTO dto) { 205 + ExecuteAttributesDTO dto,
  206 + String executeReportKey,
  207 + AtomicInteger remainTimes,
  208 + String recordId) {
214 QueryConditionDTO queryCondition = formConfigDTO.getQueryCondition(); 209 QueryConditionDTO queryCondition = formConfigDTO.getQueryCondition();
215 boolean useStrictDataTypes = queryCondition.isUseStrictDataTypes(); 210 boolean useStrictDataTypes = queryCondition.isUseStrictDataTypes();
216 Long interval = queryCondition.getInterval(); 211 Long interval = queryCondition.getInterval();
@@ -232,12 +227,10 @@ public class TkReportGenerateRecordServiceImpl @@ -232,12 +227,10 @@ public class TkReportGenerateRecordServiceImpl
232 .collect(Collectors.toList()); 227 .collect(Collectors.toList());
233 queryCondition.setStartTs(finalStartTs); 228 queryCondition.setStartTs(finalStartTs);
234 queryCondition.setEndTs(finalEndTs); 229 queryCondition.setEndTs(finalEndTs);
235 - CustomDataForExcelDTO result = new CustomDataForExcelDTO();  
236 Futures.addCallback( 230 Futures.addCallback(
237 tsService.findAll(tenantId, entityId, queries), 231 tsService.findAll(tenantId, entityId, queries),
238 - getTsKvListCallback(result, useStrictDataTypes, dto.getName(), keys), 232 + getTsKvListCallback(useStrictDataTypes, dto.getName(), keys,executeReportKey,remainTimes,formConfigDTO,recordId),
239 MoreExecutors.directExecutor()); 233 MoreExecutors.directExecutor());
240 - return CompletableFuture.supplyAsync(()->result);  
241 } 234 }
242 235
243 @Override 236 @Override
@@ -254,10 +247,13 @@ public class TkReportGenerateRecordServiceImpl @@ -254,10 +247,13 @@ public class TkReportGenerateRecordServiceImpl
254 } 247 }
255 248
256 private FutureCallback<List<TsKvEntry>> getTsKvListCallback( 249 private FutureCallback<List<TsKvEntry>> getTsKvListCallback(
257 - CustomDataForExcelDTO response,  
258 Boolean useStrictDataTypes, 250 Boolean useStrictDataTypes,
259 String deviceName, 251 String deviceName,
260 - List<String> keys) { 252 + List<String> keys,
  253 + String executeReportKey,
  254 + AtomicInteger remainTimes,
  255 + ReportFormConfigDTO formConfigDTO,
  256 + String recordId) {
261 return new FutureCallback<>() { 257 return new FutureCallback<>() {
262 @Override 258 @Override
263 public void onSuccess(List<TsKvEntry> data) { 259 public void onSuccess(List<TsKvEntry> data) {
@@ -277,13 +273,44 @@ public class TkReportGenerateRecordServiceImpl @@ -277,13 +273,44 @@ public class TkReportGenerateRecordServiceImpl
277 } 273 }
278 } 274 }
279 generateExcelHeadAndValues(result, deviceName, heads, values); 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 @Override 302 @Override
286 public void onFailure(@NotNull Throwable e) { 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 log.error("Failed to fetch historical data", e); 314 log.error("Failed to fetch historical data", e);
288 } 315 }
289 }; 316 };
@@ -339,15 +366,18 @@ public class TkReportGenerateRecordServiceImpl @@ -339,15 +366,18 @@ public class TkReportGenerateRecordServiceImpl
339 String reportFormName, 366 String reportFormName,
340 String reportGenerateRecordId, 367 String reportGenerateRecordId,
341 String tenantId, 368 String tenantId,
342 - JsonNode executeCondition) { 369 + JsonNode executeCondition,
  370 + boolean needUpload,
  371 + String errorMessage) {
343 String response = null; 372 String response = null;
344 - String errorMessage = null;  
345 int status = StatusEnum.SUCCESS.getIndex(); 373 int status = StatusEnum.SUCCESS.getIndex();
346 try { 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 } catch (Exception e) { 381 } catch (Exception e) {
352 errorMessage = e.getLocalizedMessage(); 382 errorMessage = e.getLocalizedMessage();
353 } 383 }