Showing
18 changed files
with
252 additions
and
85 deletions
... | ... | @@ -23,6 +23,7 @@ import org.thingsboard.server.common.data.yunteng.utils.tools.YtPageData; |
23 | 23 | import org.thingsboard.server.controller.BaseController; |
24 | 24 | import org.thingsboard.server.dao.yunteng.service.YtReportFormConfigService; |
25 | 25 | |
26 | +import java.sql.Timestamp; | |
26 | 27 | import java.util.HashMap; |
27 | 28 | |
28 | 29 | import static org.thingsboard.server.common.data.yunteng.constant.QueryConstant.*; |
... | ... | @@ -45,6 +46,8 @@ public class YtReportFormConfigController extends BaseController { |
45 | 46 | @RequestParam(value = "name", required = false) String name, |
46 | 47 | @RequestParam(value = "organizationId", required = false) String organizationId, |
47 | 48 | @RequestParam(value = "status", required = false) Integer status, |
49 | + @RequestParam(value = "startTime", required = false) Long startTime, | |
50 | + @RequestParam(value = "endTime", required = false) Long endTime, | |
48 | 51 | @RequestParam(value = ORDER_FILED, required = false) String orderBy, |
49 | 52 | @RequestParam(value = ORDER_TYPE, required = false) OrderTypeEnum orderType) |
50 | 53 | throws ThingsboardException { |
... | ... | @@ -60,6 +63,14 @@ public class YtReportFormConfigController extends BaseController { |
60 | 63 | if (orderType != null) { |
61 | 64 | queryMap.put(ORDER_TYPE, orderType.name()); |
62 | 65 | } |
66 | + if (null != startTime && null != endTime) { | |
67 | + if (startTime > endTime) { | |
68 | + throw new YtDataValidationException( | |
69 | + ErrorMessage.START_TIME_NOT_MORE_THAN_END_TIME.getMessage()); | |
70 | + } | |
71 | + queryMap.put("startTime", new Timestamp(startTime).toLocalDateTime()); | |
72 | + queryMap.put("endTime", new Timestamp(endTime).toLocalDateTime()); | |
73 | + } | |
63 | 74 | return reportFormConfigService.page(queryMap); |
64 | 75 | } |
65 | 76 | ... | ... |
1 | 1 | package org.thingsboard.server.controller.yunteng; |
2 | 2 | |
3 | +import com.fasterxml.jackson.databind.JsonNode; | |
3 | 4 | import io.swagger.annotations.Api; |
5 | +import io.swagger.annotations.ApiOperation; | |
4 | 6 | import lombok.RequiredArgsConstructor; |
7 | +import org.springframework.http.ResponseEntity; | |
5 | 8 | import org.springframework.security.access.prepost.PreAuthorize; |
6 | 9 | import org.springframework.validation.annotation.Validated; |
7 | 10 | import org.springframework.web.bind.annotation.*; |
11 | +import org.thingsboard.common.util.JacksonUtil; | |
8 | 12 | import org.thingsboard.server.common.data.exception.ThingsboardException; |
9 | 13 | import org.thingsboard.server.common.data.yunteng.common.DeleteGroup; |
10 | 14 | import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; |
15 | +import org.thingsboard.server.common.data.yunteng.core.exception.YtDataValidationException; | |
16 | +import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage; | |
11 | 17 | import org.thingsboard.server.common.data.yunteng.dto.DeleteDTO; |
12 | 18 | import org.thingsboard.server.common.data.yunteng.dto.ReportGenerateRecordDTO; |
19 | +import org.thingsboard.server.common.data.yunteng.dto.request.ExecuteAttributesDTO; | |
20 | +import org.thingsboard.server.common.data.yunteng.dto.request.QueryConditionDTO; | |
13 | 21 | import org.thingsboard.server.common.data.yunteng.enums.OrderTypeEnum; |
14 | 22 | import org.thingsboard.server.common.data.yunteng.utils.tools.ResponseResult; |
15 | 23 | import org.thingsboard.server.common.data.yunteng.utils.tools.YtPageData; |
16 | 24 | import org.thingsboard.server.controller.BaseController; |
25 | +import org.thingsboard.server.dao.yunteng.service.YtReportFormConfigService; | |
17 | 26 | import org.thingsboard.server.dao.yunteng.service.YtReportGenerateRecordService; |
18 | 27 | |
28 | +import java.sql.Timestamp; | |
29 | +import java.util.ArrayList; | |
19 | 30 | import java.util.HashMap; |
31 | +import java.util.List; | |
32 | +import java.util.Map; | |
20 | 33 | |
21 | 34 | import static org.thingsboard.server.common.data.yunteng.constant.QueryConstant.*; |
22 | 35 | |
... | ... | @@ -28,18 +41,31 @@ import static org.thingsboard.server.common.data.yunteng.constant.QueryConstant. |
28 | 41 | public class YtReportGenerateRecordController extends BaseController { |
29 | 42 | |
30 | 43 | private final YtReportGenerateRecordService reportFormGenerateRecordService; |
44 | + private final YtReportFormConfigService ytReportFormConfigService; | |
31 | 45 | |
32 | 46 | @GetMapping(params = {PAGE_SIZE, PAGE}) |
47 | + @ApiOperation("分页") | |
33 | 48 | public YtPageData<ReportGenerateRecordDTO> page( |
34 | - @RequestParam(PAGE_SIZE) int pageSize, | |
35 | - @RequestParam(PAGE) int page, | |
36 | - @RequestParam(value = "reportConfigName", required = false) String reportConfigName, | |
37 | - @RequestParam(value = "executeStatus", required = false) Integer executeStatus, | |
38 | - @RequestParam(value = ORDER_FILED, required = false) String orderBy, | |
39 | - @RequestParam(value = ORDER_TYPE, required = false) OrderTypeEnum orderType) | |
40 | - throws ThingsboardException { | |
49 | + @RequestParam(PAGE_SIZE) int pageSize, | |
50 | + @RequestParam(PAGE) int page, | |
51 | + @RequestParam(value = "reportConfigName", required = false) String reportConfigName, | |
52 | + @RequestParam(value = "executeStatus", required = false) Integer executeStatus, | |
53 | + @RequestParam(value = "startTime", required = false) Long startTime, | |
54 | + @RequestParam(value = "endTime", required = false) Long endTime, | |
55 | + @RequestParam(value = ORDER_FILED, required = false) String orderBy, | |
56 | + @RequestParam(value = ORDER_TYPE, required = false) OrderTypeEnum orderType) | |
57 | + throws ThingsboardException { | |
41 | 58 | |
42 | 59 | HashMap<String, Object> queryMap = new HashMap<>(); |
60 | + if (null != startTime && null != endTime) { | |
61 | + if (startTime > endTime) { | |
62 | + throw new YtDataValidationException( | |
63 | + ErrorMessage.START_TIME_NOT_MORE_THAN_END_TIME.getMessage()); | |
64 | + } | |
65 | + | |
66 | + queryMap.put("startTime", new Timestamp(startTime).toLocalDateTime()); | |
67 | + queryMap.put("endTime", new Timestamp(endTime).toLocalDateTime()); | |
68 | + } | |
43 | 69 | queryMap.put(PAGE_SIZE, pageSize); |
44 | 70 | queryMap.put(PAGE, page); |
45 | 71 | queryMap.put(ORDER_FILED, orderBy); |
... | ... | @@ -53,10 +79,34 @@ public class YtReportGenerateRecordController extends BaseController { |
53 | 79 | } |
54 | 80 | |
55 | 81 | @DeleteMapping |
82 | + @ApiOperation("删除") | |
56 | 83 | public ResponseResult<Boolean> deleteReportGenerateRecord( |
57 | - @Validated({DeleteGroup.class}) @RequestBody DeleteDTO deleteDTO) { | |
84 | + @Validated({DeleteGroup.class}) @RequestBody DeleteDTO deleteDTO) { | |
58 | 85 | return reportFormGenerateRecordService.deleteReportGenerateRecord(deleteDTO) |
59 | - ? ResponseResult.success(FastIotConstants.StateValue.DELETE_SUCCESS) | |
60 | - : ResponseResult.failed(FastIotConstants.StateValue.DELETE_FAILED); | |
86 | + ? ResponseResult.success(FastIotConstants.StateValue.DELETE_SUCCESS) | |
87 | + : ResponseResult.failed(FastIotConstants.StateValue.DELETE_FAILED); | |
88 | + } | |
89 | + | |
90 | + @GetMapping("chart/{id}") | |
91 | + @ApiOperation("获取报表查询条件") | |
92 | + public ResponseEntity getChartQueryCondition(@PathVariable("id") String id) | |
93 | + throws ThingsboardException { | |
94 | + | |
95 | + Map<String, Object> map = new HashMap<>(); | |
96 | + JsonNode json = | |
97 | + reportFormGenerateRecordService.getChartQueryCondition( | |
98 | + id, getCurrentUser().getCurrentTenantId()); | |
99 | + if (json != null) { | |
100 | + QueryConditionDTO queryConditionDTO = | |
101 | + JacksonUtil.convertValue( | |
102 | + json.get(FastIotConstants.CHART_EXECUTE_CONDITION), QueryConditionDTO.class); | |
103 | + List<ExecuteAttributesDTO> list = new ArrayList<>(); | |
104 | + ytReportFormConfigService.getExecuteConditionAndAttribute( | |
105 | + json.get(FastIotConstants.CHART_EXECUTE_ATTRIBUTES), list); | |
106 | + | |
107 | + map.put(FastIotConstants.CHART_EXECUTE_CONDITION, queryConditionDTO); | |
108 | + map.put(FastIotConstants.CHART_EXECUTE_ATTRIBUTES, list); | |
109 | + } | |
110 | + return ResponseEntity.ok(map); | |
61 | 111 | } |
62 | 112 | } | ... | ... |
... | ... | @@ -9,6 +9,8 @@ public interface FastIotConstants { |
9 | 9 | Integer MOBILE_TYPE = 0; |
10 | 10 | Integer PC_TYPE = 1; |
11 | 11 | String FIRST_PAGE_NAME = "第 1 页"; |
12 | + String CHART_EXECUTE_CONDITION = "executeCondition"; | |
13 | + String CHART_EXECUTE_ATTRIBUTES = "executeAttributes"; | |
12 | 14 | class DefaultOrder { |
13 | 15 | public static final String CREATE_TIME="create_time"; |
14 | 16 | } | ... | ... |
... | ... | @@ -71,6 +71,7 @@ public enum ErrorMessage { |
71 | 71 | INVALID_PARAMETER_OR_NOT_MATCH_TENANT(400051,"参数错误或该条数据不属于当前租户"), |
72 | 72 | CRON_INVALID(400052,"cron表达式无效"), |
73 | 73 | EXPORT_CONFIG_NON_EXISTENT(400053,"报表配置不存在或已被删除"), |
74 | + START_TIME_NOT_MORE_THAN_END_TIME(400054,"开始时间不能大于结束时间"), | |
74 | 75 | HAVE_NO_PERMISSION(500002,"没有修改权限"); |
75 | 76 | private final int code; |
76 | 77 | private String message; | ... | ... |
1 | 1 | package org.thingsboard.server.common.data.yunteng.dto; |
2 | + | |
2 | 3 | import io.swagger.annotations.ApiModel; |
3 | 4 | import io.swagger.annotations.ApiModelProperty; |
4 | 5 | import lombok.Data; |
... | ... | @@ -38,25 +39,14 @@ public class ReportFormConfigDTO extends TenantDTO { |
38 | 39 | |
39 | 40 | /** 设备:json数组格式 */ |
40 | 41 | @ApiModelProperty(value = "执行设备及属性", required = true) |
41 | - @Size(message = "至少需要一个执行设备及属性", min = 1,groups = AddGroup.class) | |
42 | + @Size(message = "至少需要一个执行设备及属性", min = 1, groups = AddGroup.class) | |
42 | 43 | private List<ExecuteAttributesDTO> executeAttributes; |
43 | 44 | |
44 | - | |
45 | 45 | /** 数据类型:0历史数据 1聚合数据 */ |
46 | 46 | @ApiModelProperty(value = "数据类型:0原始数据 1聚合数据", required = true) |
47 | 47 | @NotNull(message = "数据类型不能为空", groups = AddGroup.class) |
48 | 48 | private Integer dataType; |
49 | 49 | |
50 | - /** 数据周期:单位毫秒 */ | |
51 | - @ApiModelProperty(value = "开始时间", required = true) | |
52 | - @NotNull(message = "开始时间不能为空", groups = AddGroup.class) | |
53 | - private Long startTs; | |
54 | - | |
55 | - /** 时间间隔:单位毫秒 */ | |
56 | - @ApiModelProperty(value = "结束时间", required = true) | |
57 | - @NotNull(message = "结束时间不能为空", groups = AddGroup.class) | |
58 | - private Long endTs ; | |
59 | - | |
60 | 50 | @ApiModelProperty(value = "查询条件", required = true) |
61 | 51 | @NotNull(message = "查询条件不能为空", groups = AddGroup.class) |
62 | 52 | private QueryConditionDTO queryCondition; | ... | ... |
1 | 1 | package org.thingsboard.server.common.data.yunteng.dto; |
2 | 2 | |
3 | 3 | import com.fasterxml.jackson.annotation.JsonFormat; |
4 | +import com.fasterxml.jackson.databind.JsonNode; | |
4 | 5 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; |
5 | 6 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; |
6 | 7 | import io.swagger.annotations.ApiModelProperty; |
... | ... | @@ -35,6 +36,9 @@ public class ReportGenerateRecordDTO extends TenantDTO { |
35 | 36 | @ApiModelProperty(value = "报表导出地址") |
36 | 37 | private String reportPath; |
37 | 38 | |
39 | + @ApiModelProperty(value = "执行条件") | |
40 | + private JsonNode executeCondition; | |
41 | + | |
38 | 42 | @ApiModelProperty(value = "定时任务ID") |
39 | 43 | private String jobId; |
40 | 44 | } | ... | ... |
... | ... | @@ -4,6 +4,9 @@ import io.swagger.annotations.ApiModel; |
4 | 4 | import io.swagger.annotations.ApiModelProperty; |
5 | 5 | import lombok.Data; |
6 | 6 | import org.thingsboard.server.common.data.kv.Aggregation; |
7 | +import org.thingsboard.server.common.data.yunteng.common.AddGroup; | |
8 | + | |
9 | +import javax.validation.constraints.NotNull; | |
7 | 10 | |
8 | 11 | @Data |
9 | 12 | @ApiModel(value = "查询条件") |
... | ... | @@ -22,4 +25,14 @@ public class QueryConditionDTO { |
22 | 25 | |
23 | 26 | @ApiModelProperty("启用/禁用遥测值到字符串的转换。默认情况下启用转换。设置参数为'true'以禁用转换") |
24 | 27 | private boolean useStrictDataTypes; |
28 | + | |
29 | + /** 数据周期:单位毫秒 */ | |
30 | + @ApiModelProperty(value = "开始时间", required = true) | |
31 | + @NotNull(message = "开始时间不能为空", groups = AddGroup.class) | |
32 | + private Long startTs; | |
33 | + | |
34 | + /** 时间间隔:单位毫秒 */ | |
35 | + @ApiModelProperty(value = "结束时间", required = true) | |
36 | + @NotNull(message = "结束时间不能为空", groups = AddGroup.class) | |
37 | + private Long endTs ; | |
25 | 38 | } | ... | ... |
1 | 1 | package org.thingsboard.server.dao.util.yunteng; |
2 | 2 | |
3 | 3 | import org.apache.commons.lang3.StringUtils; |
4 | +import org.thingsboard.server.common.data.yunteng.dto.ReportFormConfigDTO; | |
4 | 5 | import org.thingsboard.server.common.data.yunteng.dto.ReportGenerateRecordDTO; |
5 | 6 | import org.thingsboard.server.common.data.yunteng.enums.JobGroupEnum; |
6 | 7 | import org.thingsboard.server.common.data.yunteng.utils.SpringBeanUtils; |
7 | 8 | import org.thingsboard.server.dao.yunteng.entities.SysJob; |
9 | +import org.thingsboard.server.dao.yunteng.service.YtReportFormConfigService; | |
8 | 10 | import org.thingsboard.server.dao.yunteng.service.YtReportGenerateRecordService; |
9 | 11 | |
10 | 12 | import java.lang.reflect.InvocationTargetException; |
... | ... | @@ -27,9 +29,12 @@ public class JobInvokeUtil { |
27 | 29 | if (StringUtils.isNotEmpty(sysJob.getSourceId()) |
28 | 30 | && sysJob.getJobGroup().equals(JobGroupEnum.REPORT.toString())) { |
29 | 31 | // 写入报表生成记录 |
32 | + ReportFormConfigDTO formConfigDTO = | |
33 | + SpringBeanUtils.getBean(YtReportFormConfigService.class) | |
34 | + .findReportFormConfigById(sysJob.getSourceId(), sysJob.getTenantId()); | |
30 | 35 | ReportGenerateRecordDTO dto = |
31 | 36 | SpringBeanUtils.getBean(YtReportGenerateRecordService.class) |
32 | - .generateReportRecord(sysJob.getSourceId(), sysJob.getTenantId(), sysJob.getId()); | |
37 | + .generateReportRecord(formConfigDTO, sysJob.getId()); | |
33 | 38 | reportGenerateRecordId = dto.getId(); |
34 | 39 | } |
35 | 40 | List<Object[]> methodParams = getMethodParams(invokeTarget, reportGenerateRecordId); | ... | ... |
... | ... | @@ -40,22 +40,28 @@ public class ReportTask { |
40 | 40 | if (dtoList.size() == FastIotConstants.MagicNumber.ONE) { |
41 | 41 | try { |
42 | 42 | ExecuteAttributesDTO attributesDTO = dtoList.get(0); |
43 | - getTsKvForGenerateExcel(formConfigDTO, attributesDTO, reportGenerateRecordId); | |
43 | + getTsKvForGenerateExcel( | |
44 | + formConfigDTO, attributesDTO, reportGenerateRecordId, dtoList.size()); | |
44 | 45 | |
45 | 46 | } catch (Exception e) { |
46 | 47 | log.error(e.getMessage()); |
47 | 48 | } |
48 | 49 | } else { |
50 | + int surplus = dtoList.size(); | |
49 | 51 | for (ExecuteAttributesDTO dto : dtoList) { |
50 | - getTsKvForGenerateExcel(formConfigDTO, dto, reportGenerateRecordId); | |
52 | + getTsKvForGenerateExcel(formConfigDTO, dto, reportGenerateRecordId, surplus); | |
53 | + surplus--; | |
51 | 54 | } |
52 | 55 | } |
53 | 56 | } |
54 | 57 | } |
55 | 58 | |
56 | 59 | private void getTsKvForGenerateExcel( |
57 | - ReportFormConfigDTO formConfigDTO, ExecuteAttributesDTO dto, String reportGenerateRecordId) { | |
60 | + ReportFormConfigDTO formConfigDTO, | |
61 | + ExecuteAttributesDTO dto, | |
62 | + String reportGenerateRecordId, | |
63 | + int surplus) { | |
58 | 64 | ytReportGenerateRecordService.generateExcelUpdateReportRecord( |
59 | - formConfigDTO, dto, reportGenerateRecordId); | |
65 | + formConfigDTO, dto, reportGenerateRecordId, surplus); | |
60 | 66 | } |
61 | 67 | } | ... | ... |
... | ... | @@ -36,12 +36,6 @@ public class ReportFormConfig extends TenantBaseEntity { |
36 | 36 | /** 数据对比:0原始数据 1聚合数据 */ |
37 | 37 | private Integer dataType; |
38 | 38 | |
39 | - /** 查询开始时间:单位毫秒 */ | |
40 | - private Long startTs; | |
41 | - | |
42 | - /** 查询结束时间:单位毫秒 */ | |
43 | - private Long endTs ; | |
44 | - | |
45 | 39 | @TableField(typeHandler = JacksonTypeHandler.class) |
46 | 40 | private JsonNode queryCondition; |
47 | 41 | ... | ... |
1 | 1 | package org.thingsboard.server.dao.yunteng.entities; |
2 | 2 | |
3 | +import com.baomidou.mybatisplus.annotation.TableField; | |
3 | 4 | import com.baomidou.mybatisplus.annotation.TableName; |
5 | +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; | |
6 | +import com.fasterxml.jackson.databind.JsonNode; | |
4 | 7 | import lombok.Data; |
5 | 8 | import lombok.EqualsAndHashCode; |
6 | 9 | import org.thingsboard.server.common.data.yunteng.constant.ModelConstants; |
... | ... | @@ -32,6 +35,10 @@ public class ReportGenerateRecord extends TenantBaseEntity { |
32 | 35 | /** 报表导出地址 */ |
33 | 36 | private String reportPath; |
34 | 37 | |
38 | + /** 执行条件 */ | |
39 | + @TableField(typeHandler = JacksonTypeHandler.class) | |
40 | + private JsonNode executeCondition; | |
41 | + | |
35 | 42 | /** 定时任务ID */ |
36 | 43 | private String jobId; |
37 | 44 | } | ... | ... |
... | ... | @@ -200,6 +200,10 @@ public class SysJobServiceImpl extends AbstractBaseService<SysJobMapper, SysJob> |
200 | 200 | } else { |
201 | 201 | SysJob job = baseMapper.selectById(jobDTO.getId()); |
202 | 202 | SysJob newJob = jobDTO.getEntity(SysJob.class); |
203 | + if (null == job) { | |
204 | + throw new YtDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage()); | |
205 | + } | |
206 | + newJob.setSourceId(job.getSourceId()); | |
203 | 207 | baseMapper.updateById(newJob); |
204 | 208 | updateSchedulerJob(newJob, job.getJobGroup()); |
205 | 209 | } | ... | ... |
... | ... | @@ -26,7 +26,6 @@ import org.thingsboard.server.dao.yunteng.service.AbstractBaseService; |
26 | 26 | import org.thingsboard.server.dao.yunteng.service.YtReportFormConfigService; |
27 | 27 | import org.thingsboard.server.dao.yunteng.service.YtReportGenerateRecordService; |
28 | 28 | import org.thingsboard.server.dao.yunteng.service.YtSysJobService; |
29 | - | |
30 | 29 | import java.util.*; |
31 | 30 | import java.util.stream.Collectors; |
32 | 31 | |
... | ... | @@ -176,8 +175,8 @@ public class YtReportFromConfigServiceImpl |
176 | 175 | if (isNowExecute) { |
177 | 176 | if (Objects.equals(reportFormConfig.getStatus(), StatusEnum.ENABLE.getIndex())) { |
178 | 177 | // 立即执行报表生成,并创建一条报表执行记录 |
179 | - // 生成Excel,并更新报表执行记录 | |
180 | - generateExcelUpdateReportRecord(reportFormConfig.getDTO(ReportFormConfigDTO.class)); | |
178 | + // 生成Excel,并更新报表执行记录; | |
179 | + generateExcelUpdateReportRecord(getDTOByReportFormConfig(reportFormConfig)); | |
181 | 180 | } |
182 | 181 | } else { |
183 | 182 | createSysJob(reportFormConfig); |
... | ... | @@ -200,7 +199,7 @@ public class YtReportFromConfigServiceImpl |
200 | 199 | if (enableStatus) { |
201 | 200 | // 立即执行报表生成,并创建一条报表执行记录 |
202 | 201 | // 生成Excel,并更新报表执行记录 |
203 | - generateExcelUpdateReportRecord(reportFormConfig.getDTO(ReportFormConfigDTO.class)); | |
202 | + generateExcelUpdateReportRecord(getDTOByReportFormConfig(reportFormConfig)); | |
204 | 203 | } |
205 | 204 | } else { |
206 | 205 | // 修改cron表达式 |
... | ... | @@ -213,7 +212,7 @@ public class YtReportFromConfigServiceImpl |
213 | 212 | if (enableStatus) { |
214 | 213 | // 立即执行报表生成,并创建一条报表执行记录 |
215 | 214 | // 生成Excel,并更新报表执行记录 |
216 | - generateExcelUpdateReportRecord(reportFormConfig.getDTO(ReportFormConfigDTO.class)); | |
215 | + generateExcelUpdateReportRecord(getDTOByReportFormConfig(reportFormConfig)); | |
217 | 216 | } |
218 | 217 | } else { |
219 | 218 | createSysJob(reportFormConfig); |
... | ... | @@ -267,21 +266,10 @@ public class YtReportFromConfigServiceImpl |
267 | 266 | |
268 | 267 | private ReportFormConfigDTO getReportFormConfigDTOByEntity(ReportFormConfig obj) { |
269 | 268 | ReportFormConfigDTO dto = new ReportFormConfigDTO(); |
270 | - obj.copyToDTO(dto, "executeAttributes"); | |
269 | + obj.copyToDTO(dto, FastIotConstants.CHART_EXECUTE_ATTRIBUTES); | |
271 | 270 | JsonNode jsonNode = obj.getExecuteAttributes(); |
272 | 271 | List<ExecuteAttributesDTO> list = new ArrayList<>(); |
273 | - for (JsonNode node : jsonNode) { | |
274 | - ExecuteAttributesDTO attributesDTO = | |
275 | - JacksonUtil.convertValue(node, ExecuteAttributesDTO.class); | |
276 | - List<String> attributes = new ArrayList<>(); | |
277 | - JsonNode attribute = node.get("attributes"); | |
278 | - for (JsonNode key : attribute) { | |
279 | - attributes.add(JacksonUtil.convertValue(key, String.class)); | |
280 | - } | |
281 | - assert attributesDTO != null; | |
282 | - attributesDTO.setAttributes(attributes); | |
283 | - list.add(attributesDTO); | |
284 | - } | |
272 | + getExecuteConditionAndAttribute(jsonNode, list); | |
285 | 273 | QueryConditionDTO queryCondition = |
286 | 274 | JacksonUtil.convertValue(obj.getQueryCondition(), QueryConditionDTO.class); |
287 | 275 | dto.setExecuteAttributes(list); |
... | ... | @@ -295,12 +283,42 @@ public class YtReportFromConfigServiceImpl |
295 | 283 | } |
296 | 284 | // 立即执行报表生成,并创建一条报表执行记录 |
297 | 285 | ReportGenerateRecordDTO recordDTO = |
298 | - ytReportGenerateRecordService.generateReportRecord( | |
299 | - reportFormConfigDTO.getId(), reportFormConfigDTO.getTenantId(), null); | |
286 | + ytReportGenerateRecordService.generateReportRecord(reportFormConfigDTO, null); | |
300 | 287 | // 生成Excel,并更新报表执行记录 |
288 | + int surplus = reportFormConfigDTO.getExecuteAttributes().size(); | |
301 | 289 | for (ExecuteAttributesDTO dto : reportFormConfigDTO.getExecuteAttributes()) { |
302 | 290 | ytReportGenerateRecordService.generateExcelUpdateReportRecord( |
303 | - reportFormConfigDTO, dto, recordDTO.getId()); | |
291 | + reportFormConfigDTO, dto, recordDTO.getId(), surplus); | |
292 | + surplus--; | |
293 | + } | |
294 | + } | |
295 | + | |
296 | + @Override | |
297 | + public void getExecuteConditionAndAttribute( | |
298 | + JsonNode attributeJsonNode, List<ExecuteAttributesDTO> list) { | |
299 | + if (attributeJsonNode.isArray()) { | |
300 | + for (JsonNode node : attributeJsonNode) { | |
301 | + ExecuteAttributesDTO attributesDTO = | |
302 | + JacksonUtil.convertValue(node, ExecuteAttributesDTO.class); | |
303 | + List<String> attributes = new ArrayList<>(); | |
304 | + JsonNode attribute = node.get("attributes"); | |
305 | + for (JsonNode key : attribute) { | |
306 | + attributes.add(JacksonUtil.convertValue(key, String.class)); | |
307 | + } | |
308 | + assert attributesDTO != null; | |
309 | + attributesDTO.setAttributes(attributes); | |
310 | + list.add(attributesDTO); | |
311 | + } | |
304 | 312 | } |
305 | 313 | } |
314 | + | |
315 | + private ReportFormConfigDTO getDTOByReportFormConfig(ReportFormConfig reportFormConfig) { | |
316 | + ReportFormConfigDTO formConfigDTO = reportFormConfig.getDTO(ReportFormConfigDTO.class); | |
317 | + List<ExecuteAttributesDTO> list = new ArrayList<>(); | |
318 | + getExecuteConditionAndAttribute(reportFormConfig.getExecuteAttributes(), list); | |
319 | + formConfigDTO.setExecuteAttributes(list); | |
320 | + formConfigDTO.setQueryCondition( | |
321 | + JacksonUtil.convertValue(reportFormConfig.getQueryCondition(), QueryConditionDTO.class)); | |
322 | + return formConfigDTO; | |
323 | + } | |
306 | 324 | } | ... | ... |
... | ... | @@ -2,6 +2,8 @@ package org.thingsboard.server.dao.yunteng.impl; |
2 | 2 | |
3 | 3 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
4 | 4 | import com.baomidou.mybatisplus.core.metadata.IPage; |
5 | +import com.fasterxml.jackson.databind.JsonNode; | |
6 | +import com.fasterxml.jackson.databind.node.ObjectNode; | |
5 | 7 | import com.google.common.util.concurrent.FutureCallback; |
6 | 8 | import com.google.common.util.concurrent.Futures; |
7 | 9 | import com.google.common.util.concurrent.MoreExecutors; |
... | ... | @@ -36,7 +38,6 @@ import org.thingsboard.server.dao.yunteng.entities.ReportGenerateRecord; |
36 | 38 | import org.thingsboard.server.dao.yunteng.mapper.ReportGenerateRecordMapper; |
37 | 39 | import org.thingsboard.server.dao.yunteng.service.AbstractBaseService; |
38 | 40 | import org.thingsboard.server.dao.yunteng.service.YtOrganizationService; |
39 | -import org.thingsboard.server.dao.yunteng.service.YtReportFormConfigService; | |
40 | 41 | import org.thingsboard.server.dao.yunteng.service.YtReportGenerateRecordService; |
41 | 42 | |
42 | 43 | import java.io.ByteArrayInputStream; |
... | ... | @@ -58,7 +59,6 @@ public class YtReportGenerateRecordServiceImpl |
58 | 59 | |
59 | 60 | private static final String CONTENT_TYPE = |
60 | 61 | "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; |
61 | - private final YtReportFormConfigService ytReportFormConfigService; | |
62 | 62 | private final YtOrganizationService ytOrganizationService; |
63 | 63 | private final TimeseriesService tsService; |
64 | 64 | private final FileStorageService fileStorageService; |
... | ... | @@ -131,9 +131,7 @@ public class YtReportGenerateRecordServiceImpl |
131 | 131 | |
132 | 132 | @Override |
133 | 133 | public ReportGenerateRecordDTO generateReportRecord( |
134 | - String sourceId, String tenantId, String jobId) { | |
135 | - ReportFormConfigDTO reportFormConfigDTO = | |
136 | - ytReportFormConfigService.findReportFormConfigById(sourceId, tenantId); | |
134 | + ReportFormConfigDTO reportFormConfigDTO, String jobId) { | |
137 | 135 | if (null == reportFormConfigDTO) { |
138 | 136 | throw new YtDataValidationException(ErrorMessage.EXPORT_CONFIG_NON_EXISTENT.getMessage()); |
139 | 137 | } |
... | ... | @@ -158,9 +156,29 @@ public class YtReportGenerateRecordServiceImpl |
158 | 156 | |
159 | 157 | @Override |
160 | 158 | public void generateExcelUpdateReportRecord( |
161 | - ReportFormConfigDTO formConfigDTO, ExecuteAttributesDTO dto, String recordId) { | |
162 | - Long startTs = formConfigDTO.getStartTs(); | |
163 | - Long endTs = formConfigDTO.getEndTs(); | |
159 | + ReportFormConfigDTO formConfigDTO, ExecuteAttributesDTO dto, String recordId,int surplus) { | |
160 | + Long startTs = formConfigDTO.getQueryCondition().getStartTs(); | |
161 | + Long endTs = formConfigDTO.getQueryCondition().getEndTs(); | |
162 | + // 如果报表配置是定时执行,获取当前定时任务的执行时间,并计算新的开始时间、结束时间 | |
163 | + if (formConfigDTO.getExecuteWay() == FastIotConstants.MagicNumber.ONE) { | |
164 | + ReportGenerateRecordDTO recordDTO = | |
165 | + findReportGenerateRecordById(recordId, formConfigDTO.getTenantId()); | |
166 | + long differenceTs = endTs - startTs; | |
167 | + endTs = recordDTO.getExecuteTime().toInstant(ZoneOffset.of("+8")).toEpochMilli(); | |
168 | + startTs = endTs - differenceTs; | |
169 | + } | |
170 | + Long finalStartTs = startTs; | |
171 | + Long finalEndTs = endTs; | |
172 | + getTsKvValuesOrGenerateExcel(null, formConfigDTO, finalStartTs, finalEndTs, dto, recordId,surplus); | |
173 | + } | |
174 | + | |
175 | + private void getTsKvValuesOrGenerateExcel( | |
176 | + final DeferredResult<ResponseEntity> result, | |
177 | + ReportFormConfigDTO formConfigDTO, | |
178 | + Long finalStartTs, | |
179 | + Long finalEndTs, | |
180 | + ExecuteAttributesDTO dto, | |
181 | + String recordId,int surplus) { | |
164 | 182 | QueryConditionDTO queryCondition = formConfigDTO.getQueryCondition(); |
165 | 183 | boolean useStrictDataTypes = queryCondition.isUseStrictDataTypes(); |
166 | 184 | Long interval = queryCondition.getInterval(); |
... | ... | @@ -171,15 +189,6 @@ public class YtReportGenerateRecordServiceImpl |
171 | 189 | DeviceId entityId = DeviceId.fromString(dto.getDevice()); |
172 | 190 | String reportTenantId = formConfigDTO.getTenantId(); |
173 | 191 | TenantId tenantId = TenantId.fromUUID(UUID.fromString(reportTenantId)); |
174 | - final DeferredResult<ResponseEntity> result = new DeferredResult<>(); | |
175 | - // 如果报表配置是定时执行,获取当前定时任务的执行时间,并计算新的开始时间、结束时间 | |
176 | - if (formConfigDTO.getExecuteWay() == FastIotConstants.MagicNumber.ONE) { | |
177 | - long differenceTs = endTs - startTs; | |
178 | - endTs = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli(); | |
179 | - startTs = endTs - differenceTs; | |
180 | - } | |
181 | - Long finalStartTs = startTs; | |
182 | - Long finalEndTs = endTs; | |
183 | 192 | List<ReadTsKvQuery> queries = |
184 | 193 | keys.stream() |
185 | 194 | .map( |
... | ... | @@ -187,7 +196,14 @@ public class YtReportGenerateRecordServiceImpl |
187 | 196 | new BaseReadTsKvQuery( |
188 | 197 | key, finalStartTs, finalEndTs, interval, limit, agg, orderBy)) |
189 | 198 | .collect(Collectors.toList()); |
190 | - | |
199 | + queryCondition.setStartTs(finalStartTs); | |
200 | + queryCondition.setEndTs(finalEndTs); | |
201 | + ObjectNode executeCondition = JacksonUtil.newObjectNode(); | |
202 | + executeCondition.replace( | |
203 | + FastIotConstants.CHART_EXECUTE_CONDITION, JacksonUtil.convertValue(queryCondition,JsonNode.class)); | |
204 | + executeCondition.replace( | |
205 | + FastIotConstants.CHART_EXECUTE_ATTRIBUTES, | |
206 | + JacksonUtil.convertValue(formConfigDTO.getExecuteAttributes(),JsonNode.class)); | |
191 | 207 | Futures.addCallback( |
192 | 208 | tsService.findAll(tenantId, entityId, queries), |
193 | 209 | getTsKvListCallback( |
... | ... | @@ -196,17 +212,32 @@ public class YtReportGenerateRecordServiceImpl |
196 | 212 | formConfigDTO.getName(), |
197 | 213 | dto.getName(), |
198 | 214 | recordId, |
199 | - reportTenantId), | |
215 | + reportTenantId, | |
216 | + executeCondition,surplus), | |
200 | 217 | MoreExecutors.directExecutor()); |
201 | 218 | } |
202 | 219 | |
220 | + @Override | |
221 | + public JsonNode getChartQueryCondition(String id, String tenantId) { | |
222 | + ReportGenerateRecord record = | |
223 | + baseMapper.selectOne( | |
224 | + new LambdaQueryWrapper<ReportGenerateRecord>() | |
225 | + .eq(ReportGenerateRecord::getTenantId, tenantId) | |
226 | + .eq(ReportGenerateRecord::getId, id)); | |
227 | + if (null == record) { | |
228 | + throw new YtDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage()); | |
229 | + } | |
230 | + return record.getExecuteCondition(); | |
231 | + } | |
232 | + | |
203 | 233 | private FutureCallback<List<TsKvEntry>> getTsKvListCallback( |
204 | 234 | final DeferredResult<ResponseEntity> response, |
205 | 235 | Boolean useStrictDataTypes, |
206 | 236 | String reportFormName, |
207 | 237 | String deviceName, |
208 | 238 | String reportGenerateRecordId, |
209 | - String tenantId) { | |
239 | + String tenantId, | |
240 | + JsonNode executeCondition,int surplus) { | |
210 | 241 | return new FutureCallback<>() { |
211 | 242 | @Override |
212 | 243 | public void onSuccess(List<TsKvEntry> data) { |
... | ... | @@ -217,8 +248,17 @@ public class YtReportGenerateRecordServiceImpl |
217 | 248 | .computeIfAbsent(entry.getKey(), k -> new ArrayList<>()) |
218 | 249 | .add(new BasicData(entry.getTs(), value)); |
219 | 250 | } |
220 | - response.setResult(new ResponseEntity<>(result, HttpStatus.OK)); | |
221 | - generateExcel(deviceName, reportFormName, result, reportGenerateRecordId, tenantId); | |
251 | + if (null == response) { | |
252 | + generateExcel( | |
253 | + deviceName, | |
254 | + reportFormName, | |
255 | + result, | |
256 | + reportGenerateRecordId, | |
257 | + tenantId, | |
258 | + executeCondition,surplus); | |
259 | + } else { | |
260 | + response.setResult(new ResponseEntity<>(result, HttpStatus.OK)); | |
261 | + } | |
222 | 262 | } |
223 | 263 | |
224 | 264 | @Override |
... | ... | @@ -241,7 +281,8 @@ public class YtReportGenerateRecordServiceImpl |
241 | 281 | String reportFormName, |
242 | 282 | Map<String, List<BasicData>> result, |
243 | 283 | String reportGenerateRecordId, |
244 | - String tenantId) { | |
284 | + String tenantId, | |
285 | + JsonNode executeCondition,int surplus) { | |
245 | 286 | List<List<String>> heads = new ArrayList<>(); |
246 | 287 | List<List<Object>> values = new ArrayList<>(); |
247 | 288 | int firstKey = 0; |
... | ... | @@ -299,7 +340,10 @@ public class YtReportGenerateRecordServiceImpl |
299 | 340 | } else { |
300 | 341 | status = StatusEnum.FAIL.getIndex(); |
301 | 342 | } |
302 | - recordDTO.setExecuteStatus(status); | |
343 | + if(surplus == FastIotConstants.MagicNumber.ONE){ | |
344 | + recordDTO.setExecuteStatus(status); | |
345 | + } | |
346 | + recordDTO.setExecuteCondition(executeCondition); | |
303 | 347 | saveOrUpdateReportGenerateRecord(recordDTO); |
304 | 348 | } |
305 | 349 | } | ... | ... |
1 | 1 | package org.thingsboard.server.dao.yunteng.service; |
2 | 2 | |
3 | +import com.fasterxml.jackson.databind.JsonNode; | |
3 | 4 | import org.quartz.SchedulerException; |
4 | 5 | import org.thingsboard.server.common.data.yunteng.dto.DeleteDTO; |
5 | 6 | import org.thingsboard.server.common.data.yunteng.dto.ReportFormConfigDTO; |
7 | +import org.thingsboard.server.common.data.yunteng.dto.request.ExecuteAttributesDTO; | |
6 | 8 | import org.thingsboard.server.common.data.yunteng.utils.tools.YtPageData; |
7 | 9 | |
10 | +import java.util.List; | |
8 | 11 | import java.util.Map; |
9 | 12 | |
10 | 13 | public interface YtReportFormConfigService { |
... | ... | @@ -19,4 +22,6 @@ public interface YtReportFormConfigService { |
19 | 22 | ReportFormConfigDTO findReportFormConfigById(String id,String tenantId); |
20 | 23 | |
21 | 24 | ReportFormConfigDTO findReportFormConfigById(String id); |
25 | + | |
26 | + void getExecuteConditionAndAttribute(JsonNode attributeJsonNode, List<ExecuteAttributesDTO> list); | |
22 | 27 | } | ... | ... |
1 | 1 | package org.thingsboard.server.dao.yunteng.service; |
2 | 2 | |
3 | +import com.fasterxml.jackson.databind.JsonNode; | |
3 | 4 | import org.thingsboard.server.common.data.yunteng.dto.DeleteDTO; |
4 | 5 | import org.thingsboard.server.common.data.yunteng.dto.ReportFormConfigDTO; |
5 | 6 | import org.thingsboard.server.common.data.yunteng.dto.ReportGenerateRecordDTO; |
... | ... | @@ -21,18 +22,26 @@ public interface YtReportGenerateRecordService { |
21 | 22 | /** |
22 | 23 | * 根据报表配置ID及租户ID生成报表生成记录 |
23 | 24 | * |
24 | - * @param sourceId 报表配置ID | |
25 | - * @param tenantId 租户ID | |
25 | + * @param reportFormConfigDTO 报表配置信息 | |
26 | 26 | * @param jobId 定时任务ID(定时任务执行不能为空) |
27 | 27 | * @return 报表生成记录 |
28 | 28 | */ |
29 | - ReportGenerateRecordDTO generateReportRecord(String sourceId, String tenantId, String jobId); | |
29 | + ReportGenerateRecordDTO generateReportRecord( | |
30 | + ReportFormConfigDTO reportFormConfigDTO, String jobId); | |
30 | 31 | |
31 | 32 | /** |
32 | 33 | * 生成报表记录 |
34 | + * | |
33 | 35 | * @param formConfigDTO 报表配置 |
34 | 36 | * @param dto 执行属性 |
35 | 37 | * @param recordId recordId 记录ID |
38 | + * @param surplus 剩余执行次数 | |
36 | 39 | */ |
37 | - void generateExcelUpdateReportRecord(ReportFormConfigDTO formConfigDTO, ExecuteAttributesDTO dto, String recordId); | |
40 | + void generateExcelUpdateReportRecord( | |
41 | + ReportFormConfigDTO formConfigDTO, | |
42 | + ExecuteAttributesDTO dto, | |
43 | + String recordId, | |
44 | + int surplus); | |
45 | + | |
46 | + JsonNode getChartQueryCondition(String id, String tenantId); | |
38 | 47 | } | ... | ... |
... | ... | @@ -9,8 +9,6 @@ |
9 | 9 | <result property="executeWay" column="execute_way"/> |
10 | 10 | <result property="executeContent" column="execute_content"/> |
11 | 11 | <result property="dataType" column="data_type"/> |
12 | - <result property="startTs" column="start_ts"/> | |
13 | - <result property="endTs" column="end_ts"/> | |
14 | 12 | <result property="status" column="status"/> |
15 | 13 | <result property="remark" column="remark"/> |
16 | 14 | <result property="tenantId" column="tenant_id"/> |
... | ... | @@ -26,7 +24,7 @@ |
26 | 24 | |
27 | 25 | <sql id="columns"> |
28 | 26 | config.id,config.name,config.organization_id,config.execute_way,config.execute_content, |
29 | - config.data_type,config.start_ts,config.end_ts,config.status,config.remark,config.create_time,config.creator, | |
27 | + config.data_type,config.status,config.remark,config.create_time,config.creator, | |
30 | 28 | config.updater,config.update_time,config.tenant_id |
31 | 29 | </sql> |
32 | 30 | <select id="getReportFormConfigPage" resultMap="formConfigDtoMap"> |
... | ... | @@ -48,6 +46,9 @@ |
48 | 46 | #{organizationId} |
49 | 47 | </foreach> |
50 | 48 | </if> |
49 | + <if test="queryMap.startTime !=null and queryMap.endTime !=null"> | |
50 | + AND config.create_time >= #{queryMap.startTime} AND config.create_time < #{queryMap.endTime} | |
51 | + </if> | |
51 | 52 | </where> |
52 | 53 | </select> |
53 | 54 | </mapper> | ... | ... |