Commit 95a0d8a55d1e575e18ec9c362da089a96d123685

Authored by 黄 x
1 parent c13654b6

fix: fix empty data generate excel bug [DEFECT-603]

... ... @@ -124,6 +124,19 @@ public class YtReportFormConfigController extends BaseController {
124 124 private ResponseResult<ReportFormConfigDTO> saveOrUpdate(ReportFormConfigDTO configDTO)
125 125 throws ThingsboardException, SchedulerException {
126 126 configDTO.setTenantId(getCurrentUser().getCurrentTenantId());
  127 + Long startTs = configDTO.getQueryCondition().getStartTs();
  128 + Long endTs = configDTO.getQueryCondition().getEndTs();
  129 + if (null == startTs || null == endTs) {
  130 + throw new YtDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
  131 + }
  132 + if (startTs < 946656000000L || endTs < 946656000000L) {
  133 + throw new YtDataValidationException(
  134 + ErrorMessage.START_TIME_OR_END_TIME_EXCEPTION.getMessage());
  135 + }
  136 + if (startTs > endTs) {
  137 + throw new YtDataValidationException(
  138 + ErrorMessage.START_TIME_NOT_MORE_THAN_END_TIME.getMessage());
  139 + }
127 140 ReportFormConfigDTO newDTO = reportFormConfigService.saveOrUpdateReportFormConfig(configDTO);
128 141 return ResponseResult.success(newDTO);
129 142 }
... ...
... ... @@ -72,6 +72,7 @@ public enum ErrorMessage {
72 72 CRON_INVALID(400052,"cron表达式无效"),
73 73 EXPORT_CONFIG_NON_EXISTENT(400053,"报表配置不存在或已被删除"),
74 74 START_TIME_NOT_MORE_THAN_END_TIME(400054,"开始时间不能大于结束时间"),
  75 + START_TIME_OR_END_TIME_EXCEPTION(400055,"开始时间或结束时间异常"),
75 76 HAVE_NO_PERMISSION(500002,"没有修改权限");
76 77 private final int code;
77 78 private String message;
... ...
... ... @@ -26,13 +26,15 @@ public class QueryConditionDTO {
26 26 @ApiModelProperty("启用/禁用遥测值到字符串的转换。默认情况下启用转换。设置参数为'true'以禁用转换")
27 27 private boolean useStrictDataTypes;
28 28
29   - /** 数据周期:单位毫秒 */
30   - @ApiModelProperty(value = "开始时间", required = true)
  29 + @ApiModelProperty(value = "开始时间:单位毫秒", required = true)
31 30 @NotNull(message = "开始时间不能为空", groups = AddGroup.class)
32 31 private Long startTs;
33 32
34   - /** 时间间隔:单位毫秒 */
35   - @ApiModelProperty(value = "结束时间", required = true)
  33 + @ApiModelProperty(value = "结束时间:单位毫秒", required = true)
36 34 @NotNull(message = "结束时间不能为空", groups = AddGroup.class)
37 35 private Long endTs ;
  36 +
  37 + @ApiModelProperty(value = "查询方式:0 周期查询 1自定查询", required = true)
  38 + @NotNull(message = "查询方式不能为空", groups = AddGroup.class)
  39 + private Integer queryMode;
38 40 }
... ...
... ... @@ -156,7 +156,7 @@ public class YtReportGenerateRecordServiceImpl
156 156
157 157 @Override
158 158 public void generateExcelUpdateReportRecord(
159   - ReportFormConfigDTO formConfigDTO, ExecuteAttributesDTO dto, String recordId,int surplus) {
  159 + ReportFormConfigDTO formConfigDTO, ExecuteAttributesDTO dto, String recordId, int surplus) {
160 160 Long startTs = formConfigDTO.getQueryCondition().getStartTs();
161 161 Long endTs = formConfigDTO.getQueryCondition().getEndTs();
162 162 // 如果报表配置是定时执行,获取当前定时任务的执行时间,并计算新的开始时间、结束时间
... ... @@ -166,19 +166,18 @@ public class YtReportGenerateRecordServiceImpl
166 166 long differenceTs = endTs - startTs;
167 167 endTs = recordDTO.getExecuteTime().toInstant(ZoneOffset.of("+8")).toEpochMilli();
168 168 startTs = endTs - differenceTs;
  169 + formConfigDTO.getQueryCondition().setStartTs(startTs);
  170 + formConfigDTO.getQueryCondition().setEndTs(endTs);
169 171 }
170   - Long finalStartTs = startTs;
171   - Long finalEndTs = endTs;
172   - getTsKvValuesOrGenerateExcel(null, formConfigDTO, finalStartTs, finalEndTs, dto, recordId,surplus);
  172 + getTsKvValuesOrGenerateExcel(null, formConfigDTO, dto, recordId, surplus);
173 173 }
174 174
175 175 private void getTsKvValuesOrGenerateExcel(
176 176 final DeferredResult<ResponseEntity> result,
177 177 ReportFormConfigDTO formConfigDTO,
178   - Long finalStartTs,
179   - Long finalEndTs,
180 178 ExecuteAttributesDTO dto,
181   - String recordId,int surplus) {
  179 + String recordId,
  180 + int surplus) {
182 181 QueryConditionDTO queryCondition = formConfigDTO.getQueryCondition();
183 182 boolean useStrictDataTypes = queryCondition.isUseStrictDataTypes();
184 183 Long interval = queryCondition.getInterval();
... ... @@ -189,6 +188,8 @@ public class YtReportGenerateRecordServiceImpl
189 188 DeviceId entityId = DeviceId.fromString(dto.getDevice());
190 189 String reportTenantId = formConfigDTO.getTenantId();
191 190 TenantId tenantId = TenantId.fromUUID(UUID.fromString(reportTenantId));
  191 + Long finalStartTs = queryCondition.getStartTs();
  192 + Long finalEndTs = queryCondition.getEndTs();
192 193 List<ReadTsKvQuery> queries =
193 194 keys.stream()
194 195 .map(
... ... @@ -200,10 +201,11 @@ public class YtReportGenerateRecordServiceImpl
200 201 queryCondition.setEndTs(finalEndTs);
201 202 ObjectNode executeCondition = JacksonUtil.newObjectNode();
202 203 executeCondition.replace(
203   - FastIotConstants.CHART_EXECUTE_CONDITION, JacksonUtil.convertValue(queryCondition,JsonNode.class));
  204 + FastIotConstants.CHART_EXECUTE_CONDITION,
  205 + JacksonUtil.convertValue(queryCondition, JsonNode.class));
204 206 executeCondition.replace(
205 207 FastIotConstants.CHART_EXECUTE_ATTRIBUTES,
206   - JacksonUtil.convertValue(formConfigDTO.getExecuteAttributes(),JsonNode.class));
  208 + JacksonUtil.convertValue(formConfigDTO.getExecuteAttributes(), JsonNode.class));
207 209 Futures.addCallback(
208 210 tsService.findAll(tenantId, entityId, queries),
209 211 getTsKvListCallback(
... ... @@ -213,7 +215,9 @@ public class YtReportGenerateRecordServiceImpl
213 215 dto.getName(),
214 216 recordId,
215 217 reportTenantId,
216   - executeCondition,surplus),
  218 + executeCondition,
  219 + surplus,
  220 + keys),
217 221 MoreExecutors.directExecutor());
218 222 }
219 223
... ... @@ -237,7 +241,9 @@ public class YtReportGenerateRecordServiceImpl
237 241 String deviceName,
238 242 String reportGenerateRecordId,
239 243 String tenantId,
240   - JsonNode executeCondition,int surplus) {
  244 + JsonNode executeCondition,
  245 + int surplus,
  246 + List<String> keys) {
241 247 return new FutureCallback<>() {
242 248 @Override
243 249 public void onSuccess(List<TsKvEntry> data) {
... ... @@ -255,7 +261,9 @@ public class YtReportGenerateRecordServiceImpl
255 261 result,
256 262 reportGenerateRecordId,
257 263 tenantId,
258   - executeCondition,surplus);
  264 + executeCondition,
  265 + surplus,
  266 + keys);
259 267 } else {
260 268 response.setResult(new ResponseEntity<>(result, HttpStatus.OK));
261 269 }
... ... @@ -282,39 +290,18 @@ public class YtReportGenerateRecordServiceImpl
282 290 Map<String, List<BasicData>> result,
283 291 String reportGenerateRecordId,
284 292 String tenantId,
285   - JsonNode executeCondition,int surplus) {
  293 + JsonNode executeCondition,
  294 + int surplus,
  295 + List<String> keys) {
286 296 List<List<String>> heads = new ArrayList<>();
287 297 List<List<Object>> values = new ArrayList<>();
288   - int firstKey = 0;
289   - for (String key : result.keySet()) {
290   - List<String> headValue = new ArrayList<>();
291   - headValue.add(deviceName);
292   - headValue.add(key + "采集值");
293   - List<String> tsValue = new ArrayList<>();
294   - tsValue.add(deviceName);
295   - tsValue.add(key + "采集时间");
296   - heads.add(headValue);
297   - heads.add(tsValue);
298   - List<BasicData> basicData = result.get(key);
299   - for (int i = 0; i < basicData.size(); i++) {
300   - BasicData item = basicData.get(i);
301   - List<Object> listValue;
302   - if (firstKey == 0) {
303   - listValue = new ArrayList<>();
304   - } else {
305   - listValue = values.get(i);
306   - }
307   - Object value = item.getValue();
308   - listValue.add(value);
309   - DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
310   - Timestamp t = new Timestamp(item.getTs());
311   - listValue.add(t.toLocalDateTime().format(dtf));
312   - if (firstKey == 0) {
313   - values.add(listValue);
314   - }
  298 + if (result.isEmpty()) {
  299 + for (String key : keys) {
  300 + List<BasicData> data = new ArrayList<>();
  301 + result.put(key, data);
315 302 }
316   - firstKey++;
317 303 }
  304 + generateExcelHeadAndValues(result, deviceName, heads, values);
318 305 ByteArrayOutputStream byteArrayOutputStream =
319 306 ExcelUtil.noModelWrite(reportFormName, heads, values);
320 307 String fileName = reportFormName + System.currentTimeMillis() + ".xlsx";
... ... @@ -340,11 +327,48 @@ public class YtReportGenerateRecordServiceImpl
340 327 } else {
341 328 status = StatusEnum.FAIL.getIndex();
342 329 }
343   - if(surplus == FastIotConstants.MagicNumber.ONE){
  330 + if (surplus == FastIotConstants.MagicNumber.ONE) {
344 331 recordDTO.setExecuteStatus(status);
345 332 }
346 333 recordDTO.setExecuteCondition(executeCondition);
347 334 saveOrUpdateReportGenerateRecord(recordDTO);
348 335 }
349 336 }
  337 +
  338 + private void generateExcelHeadAndValues(
  339 + Map<String, List<BasicData>> result,
  340 + String deviceName,
  341 + List<List<String>> heads,
  342 + List<List<Object>> values) {
  343 + int firstKey = 0;
  344 + for (String key : result.keySet()) {
  345 + List<String> headValue = new ArrayList<>();
  346 + headValue.add(deviceName);
  347 + headValue.add(key + "采集值");
  348 + List<String> tsValue = new ArrayList<>();
  349 + tsValue.add(deviceName);
  350 + tsValue.add(key + "采集时间");
  351 + heads.add(headValue);
  352 + heads.add(tsValue);
  353 + List<BasicData> basicData = result.get(key);
  354 + for (int i = 0; i < basicData.size(); i++) {
  355 + BasicData item = basicData.get(i);
  356 + List<Object> listValue;
  357 + if (firstKey == 0) {
  358 + listValue = new ArrayList<>();
  359 + } else {
  360 + listValue = values.get(i);
  361 + }
  362 + Object value = item.getValue();
  363 + listValue.add(value);
  364 + DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
  365 + Timestamp t = new Timestamp(item.getTs());
  366 + listValue.add(t.toLocalDateTime().format(dtf));
  367 + if (firstKey == 0) {
  368 + values.add(listValue);
  369 + }
  370 + }
  371 + firstKey++;
  372 + }
  373 + }
350 374 }
... ...