diff --git a/src/main/java/cn/lihongjie/coal/base/dto/TreeDto.java b/src/main/java/cn/lihongjie/coal/base/dto/TreeDto.java index df4b4b2f..9965eca7 100644 --- a/src/main/java/cn/lihongjie/coal/base/dto/TreeDto.java +++ b/src/main/java/cn/lihongjie/coal/base/dto/TreeDto.java @@ -80,10 +80,19 @@ public class TreeDto { TreeDto dto = new TreeDto(); - dto.setId(getId(x)); - dto.setName(getName(x)); - dto.setCode(getCode(x)); - dto.setChildren(getChildren(x)); + if (x instanceof String) { + + dto.setName(x.toString()); + dto.setCode(x.toString()); + dto.setId(x.toString()); + dto.setChildren(new ArrayList<>()); + } else { + + dto.setId(getId(x)); + dto.setName(getName(x)); + dto.setCode(getCode(x)); + dto.setChildren(getChildren(x)); + } return dto; } @@ -91,7 +100,7 @@ public class TreeDto { if (x instanceof TreeDto) { List list = ((TreeDto) x).getChildren(); - if (list == null){ + if (list == null) { return new ArrayList<>(); } return list.stream().map(TreeDto::buildTree).toList(); diff --git a/src/main/java/cn/lihongjie/coal/pdcDeviceData/controller/PdcDeviceDataController.java b/src/main/java/cn/lihongjie/coal/pdcDeviceData/controller/PdcDeviceDataController.java index f068f3ab..3f804023 100644 --- a/src/main/java/cn/lihongjie/coal/pdcDeviceData/controller/PdcDeviceDataController.java +++ b/src/main/java/cn/lihongjie/coal/pdcDeviceData/controller/PdcDeviceDataController.java @@ -5,6 +5,7 @@ import cn.lihongjie.coal.annotation.SysLog; import cn.lihongjie.coal.base.dto.CommonQuery; import cn.lihongjie.coal.base.dto.IdRequest; import cn.lihongjie.coal.pdcDeviceData.dto.CreatePdcDeviceDataDto; +import cn.lihongjie.coal.pdcDeviceData.dto.GetReportRequest; import cn.lihongjie.coal.pdcDeviceData.dto.PdcDeviceDataDto; import cn.lihongjie.coal.pdcDeviceData.dto.UpdatePdcDeviceDataDto; import cn.lihongjie.coal.pdcDeviceData.service.PdcDeviceDataService; @@ -51,4 +52,9 @@ public class PdcDeviceDataController { public Page list(@RequestBody CommonQuery request) { return this.service.list(request); } + + @PostMapping("/getReport") + public Object getReport(@RequestBody GetReportRequest request) { + return this.service.getReport(request); + } } diff --git a/src/main/java/cn/lihongjie/coal/pdcDeviceData/dto/GetReportRequest.java b/src/main/java/cn/lihongjie/coal/pdcDeviceData/dto/GetReportRequest.java new file mode 100644 index 00000000..3626b81c --- /dev/null +++ b/src/main/java/cn/lihongjie/coal/pdcDeviceData/dto/GetReportRequest.java @@ -0,0 +1,20 @@ +package cn.lihongjie.coal.pdcDeviceData.dto; + +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; + +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +public class GetReportRequest { + + @NotNull + @NotEmpty + private String deviceGroup; + + private LocalDateTime startTime = LocalDateTime.now().toLocalDate().atStartOfDay(); + + private LocalDateTime endTime = LocalDateTime.now().toLocalDate().atStartOfDay().plusDays(1); +} diff --git a/src/main/java/cn/lihongjie/coal/pdcDeviceData/service/PdcDeviceDataService.java b/src/main/java/cn/lihongjie/coal/pdcDeviceData/service/PdcDeviceDataService.java index 075ec539..7a296f2e 100644 --- a/src/main/java/cn/lihongjie/coal/pdcDeviceData/service/PdcDeviceDataService.java +++ b/src/main/java/cn/lihongjie/coal/pdcDeviceData/service/PdcDeviceDataService.java @@ -3,14 +3,22 @@ package cn.lihongjie.coal.pdcDeviceData.service; import cn.lihongjie.coal.base.dto.CommonQuery; import cn.lihongjie.coal.base.dto.IdRequest; import cn.lihongjie.coal.base.service.BaseService; +import cn.lihongjie.coal.common.Ctx; +import cn.lihongjie.coal.common.JpaUtils; import cn.lihongjie.coal.dbFunctions.DbFunctionService; import cn.lihongjie.coal.pdcDeviceData.dto.CreatePdcDeviceDataDto; +import cn.lihongjie.coal.pdcDeviceData.dto.GetReportRequest; import cn.lihongjie.coal.pdcDeviceData.dto.PdcDeviceDataDto; import cn.lihongjie.coal.pdcDeviceData.dto.UpdatePdcDeviceDataDto; import cn.lihongjie.coal.pdcDeviceData.entity.PdcDeviceDataEntity; import cn.lihongjie.coal.pdcDeviceData.mapper.PdcDeviceDataMapper; import cn.lihongjie.coal.pdcDeviceData.repository.PdcDeviceDataRepository; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import jakarta.persistence.Query; +import jakarta.persistence.Tuple; + import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -21,6 +29,10 @@ import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.time.Duration; +import java.util.List; +import java.util.Map; + @Service @Slf4j @Transactional @@ -71,4 +83,71 @@ public class PdcDeviceDataService return page.map(this.mapper::toDto); } + + @PersistenceContext EntityManager em; + + public List getReport(GetReportRequest request) { + + Query nativeQuery = + em.createNativeQuery( + """ + + with tmp as (select d.device_id, + max(pdc.code) as code , + max(pdc.name) as name , + pdc.coal_type, + time_bucket_gapfill(:bucket, d.time) as tb, + (max(d.total_data)) as total_data + from t_pdc_device_data d + left join t_pdc_device pdc on d.device_id = pdc.id + + + WHERE d.time > :startTime + AND d.time < :endTime + and pdc.device_group = :deviceGroup + and pdc.organization_id = :organizationId + group by d.device_id, pdc.coal_type, tb + order by tb), + tmp2 as (select *, + round(cast(tmp.total_data - lag(tmp.total_data, 1, null) + over (partition by tmp.device_id order by tmp.tb ) as numeric), + 3) as diff + + from tmp), + tmp3 as (select * + from tmp2 + where coal_type = '2'), + tmp4 as (select * + from tmp2 + where coal_type != '2'), + + tmp5 as (select tmp4.*, + tmp3.diff as ym_diff, + round(case when tmp3.diff is null or tmp3.diff = 0 then 0 else tmp4.diff / tmp3.diff * 100 end, + 2) as percent + from tmp4 + left join tmp3 on tmp4.tb = tmp3.tb) + + select * + from tmp5 + + """, + Tuple.class); + nativeQuery.setParameter("startTime", request.getStartTime()); + nativeQuery.setParameter("endTime", request.getEndTime()); + nativeQuery.setParameter("deviceGroup", request.getDeviceGroup()); + + Duration duration = Duration.between(request.getStartTime(), request.getEndTime()); + + // 最多返回100条数据用于绘图, 最少10s一个点 + var maxBucket = Math.max(10, duration.getSeconds() / 100); + + nativeQuery.setParameter("bucket", maxBucket + " seconds"); + nativeQuery.setParameter("organizationId", Ctx.currentUser().getOrganizationId()); + + List list = + JpaUtils.convertTuplesToMap( + nativeQuery.getResultList(), JpaUtils.underscoreToCamelCase); + return list; + } } diff --git a/src/main/java/cn/lihongjie/coal/pdcDeviceRealTimeData/controller/PdcDeviceRealTimeDataController.java b/src/main/java/cn/lihongjie/coal/pdcDeviceRealTimeData/controller/PdcDeviceRealTimeDataController.java index 1a61b165..f324613a 100644 --- a/src/main/java/cn/lihongjie/coal/pdcDeviceRealTimeData/controller/PdcDeviceRealTimeDataController.java +++ b/src/main/java/cn/lihongjie/coal/pdcDeviceRealTimeData/controller/PdcDeviceRealTimeDataController.java @@ -17,6 +17,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; +import java.util.Map; @RestController @RequestMapping("/pdcDeviceRealTimeData") @@ -54,7 +55,7 @@ public class PdcDeviceRealTimeDataController { @PostMapping("/getRealTimeReport") - public List getRealTimeReport(@RequestBody GetRealTImeReportRequest request) { + public List getRealTimeReport(@RequestBody GetRealTImeReportRequest request) { return this.service.getRealTimeReport(request); } } diff --git a/src/main/java/cn/lihongjie/coal/pdcDeviceRealTimeData/dto/GetRealTImeReportRequest.java b/src/main/java/cn/lihongjie/coal/pdcDeviceRealTimeData/dto/GetRealTImeReportRequest.java index 89ee7a56..18a6ff50 100644 --- a/src/main/java/cn/lihongjie/coal/pdcDeviceRealTimeData/dto/GetRealTImeReportRequest.java +++ b/src/main/java/cn/lihongjie/coal/pdcDeviceRealTimeData/dto/GetRealTImeReportRequest.java @@ -12,5 +12,5 @@ public class GetRealTImeReportRequest { private LocalDateTime startTime; - private LocalDateTime endTime; +// private LocalDateTime endTime; } diff --git a/src/main/java/cn/lihongjie/coal/pdcDeviceRealTimeData/repository/PdcDeviceRealTimeDataRepository.java b/src/main/java/cn/lihongjie/coal/pdcDeviceRealTimeData/repository/PdcDeviceRealTimeDataRepository.java index 032778db..be3a4aa5 100644 --- a/src/main/java/cn/lihongjie/coal/pdcDeviceRealTimeData/repository/PdcDeviceRealTimeDataRepository.java +++ b/src/main/java/cn/lihongjie/coal/pdcDeviceRealTimeData/repository/PdcDeviceRealTimeDataRepository.java @@ -4,6 +4,7 @@ import cn.lihongjie.coal.base.dao.BaseRepository; import cn.lihongjie.coal.pdcDeviceRealTimeData.entity.PdcDeviceRealTimeDataEntity; import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; import java.util.List; @@ -17,4 +18,7 @@ public interface PdcDeviceRealTimeDataRepository "select id from t_pdc_device_real_time_data dd inner join t_pdc_device d on dd.device_id = d.id where d.id in :deviceIds and (extract(epoch from (now() - dd.last_save_time)) / 60) >= d.data_save_interval ", nativeQuery = true) List findNeedToSaveData(List deviceIds); + + @Query("select d.id from PdcDeviceEntity d where d.deviceGroup = :deviceGroup and d.organizationId = :organizationId") + List findDeviceIdsByGroup(@Param("deviceGroup") String deviceGroup, @Param("organizationId") String organizationId); } diff --git a/src/main/java/cn/lihongjie/coal/pdcDeviceRealTimeData/service/PdcDeviceRealTimeDataService.java b/src/main/java/cn/lihongjie/coal/pdcDeviceRealTimeData/service/PdcDeviceRealTimeDataService.java index d3ab9ede..3f5af34d 100644 --- a/src/main/java/cn/lihongjie/coal/pdcDeviceRealTimeData/service/PdcDeviceRealTimeDataService.java +++ b/src/main/java/cn/lihongjie/coal/pdcDeviceRealTimeData/service/PdcDeviceRealTimeDataService.java @@ -34,6 +34,7 @@ import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; @Service @@ -112,45 +113,46 @@ public class PdcDeviceRealTimeDataService }); } - public List getRealTimeReport( + public List getRealTimeReport( GetRealTImeReportRequest request) { + List deviceIds = this.repository.findDeviceIdsByGroup(request.getDeviceGroup(), Ctx.currentUser().getOrganizationId()); + + if (deviceIds.isEmpty()){ + return List.of(); + } + Query nativeQuery = em.createNativeQuery( """ - - with tmp1 as ( - - select d.device_id as device_id, max(p.coal_type) as coal_type, max(total_data) - min(total_data) as time_total from t_pdc_device_data d - left join t_pdc_device p on d.device_id = p.id - where d.organization_id = :organizationId - and d.time >= :startTime - and d.time <= :endTime - group by d.device_id - - ) - - - select rtd.*, d.id as device_id, d.name as device_name, d.device_group as device_group, d.coal_type as device_coal_type, - sum(t1.time_total ) as time_total, - sum(t1.time_total) / (select sum(time_total) from tmp1 where tmp1.coal_type = '0') as time_percent - - - from t_pdc_device_real_time_data rtd + with tmp as ( + + select dd.device_id, min(dd.total_data) as min_total, max(dd.total_data) as max_total from t_pdc_device_data dd + + where dd.device_id in :deviceIds and dd.time >= :startTime and dd.time <= :endTime + group by dd.device_id + ) + , + tmp2 as (select rtd.*, d.coal_type as coal_type, d.name as device_name, d.code as device_code, d.device_group as device_group, round(cast(rtd.total_data - tmp.min_total as numeric), 3) as time_total + from t_pdc_device_real_time_data rtd inner join t_pdc_device d on rtd.device_id = d.id - left join tmp1 t1 on rtd.device_id = t1.device_id - - - where d.device_group = :deviceGroup and d.organization_id = :organizationId + inner join tmp on rtd.device_id = tmp.device_id) + + + + select a.*, round(cast(coalesce(b.time_total, (a.time_total / (b.time_total * 100.0)), 0 ) as numeric),3)as time_percent from tmp2 a left join tmp2 b on b.coal_type = '2' + + + - """, + """, Tuple.class); - nativeQuery.setParameter("deviceGroup", request.getDeviceGroup()); - nativeQuery.setParameter("organizationId", Ctx.currentUser().getOrganizationId()); + + nativeQuery.setParameter("deviceIds", deviceIds); nativeQuery.setParameter( "startTime", request.getStartTime() != null @@ -158,9 +160,7 @@ public class PdcDeviceRealTimeDataService : LocalDateTime.now().toLocalDate().atStartOfDay()); nativeQuery.setParameter( "endTime", - request.getEndTime() != null - ? request.getEndTime() - : LocalDateTime.now().toLocalDate().atTime(23, 59, 59)); + LocalDateTime.now().toLocalDate().atTime(23, 59, 59)); List list = JpaUtils.convertTuplesToMap( diff --git a/src/main/resources/db/migration/V41__pdcDataTrigger.sql b/src/main/resources/db/migration/V41__pdcDataTrigger.sql new file mode 100644 index 00000000..37507d15 --- /dev/null +++ b/src/main/resources/db/migration/V41__pdcDataTrigger.sql @@ -0,0 +1 @@ +drop trigger if exists move_pdc_realtime_data_trigger on t_pdc_device_real_time_data; \ No newline at end of file diff --git a/src/main/resources/scripts/dict/enum/pdcDeviceGroupDict.groovy b/src/main/resources/scripts/dict/enum/pdcDeviceGroupDict.groovy new file mode 100644 index 00000000..7e5e0e16 --- /dev/null +++ b/src/main/resources/scripts/dict/enum/pdcDeviceGroupDict.groovy @@ -0,0 +1,17 @@ + +package scripts.dict + + +import cn.lihongjie.coal.pdcDevice.controller.PdcDeviceController +import org.springframework.context.ApplicationContext + +ApplicationContext ioc = ioc + +def controller = ioc.getBean(PdcDeviceController.class) + + + + +return controller.deviceGroups() + +