From 9c9c0eabd37eb6a4524f4ed7e4cbe00edfc24b8e Mon Sep 17 00:00:00 2001 From: lishuai Date: Wed, 1 Jan 2025 14:02:01 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=89=E4=BC=8F=E5=85=85=E7=94=B5=E7=AB=99?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=202025=E5=B9=B41=E6=9C=881=E6=97=A514:01:49?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- application/pom.xml | 4 + .../src/main/resources/application.yml | 15 +- .../core/event/SimulateSocketEvent.java | 32 + modules/pom.xml | 2 + .../alert/controller/AlertController.java | 103 +++ .../thing/qingyuan/alert/dto/AlertDTO.java | 70 ++ .../qingyuan/alert/entity/AlertEntity.java | 113 +++ .../qingyuan/alert/excel/AlertExcel.java | 64 ++ .../qingyuan/alert/mapper/AlertMapper.java | 18 + .../qingyuan/alert/service/AlertService.java | 19 + .../alert/service/impl/AlertServiceImpl.java | 97 +++ .../controller/DeviceController.java | 108 +++ .../qingyuan/basedevice/dto/DeviceDTO.java | 53 ++ .../basedevice/entity/DeviceEntity.java | 82 ++ .../basedevice/excel/DeviceExcel.java | 46 ++ .../basedevice/mapper/DeviceMapper.java | 18 + .../basedevice/service/IotDeviceService.java | 18 + .../service/impl/IotDeviceServiceImpl.java | 36 + .../config/StationProperties.java | 41 + .../controller/ChargeOrderHeadController.java | 65 ++ .../controller/ChargeStatisticController.java | 44 + .../controller/StationInfoController.java | 91 ++ .../dto/ChargeOrderDetailsDTO.java | 84 ++ .../chargeStation/dto/ChargeOrderHeadDTO.java | 83 ++ .../dto/ChargeStatisticReportResp.java | 84 ++ .../dto/ChargeStatisticRequest.java | 94 +++ .../chargeStation/dto/ConnectorInfoDTO.java | 64 ++ .../dto/ConnectorStatusInfo.java | 18 + .../chargeStation/dto/EquipmentInfoDTO.java | 64 ++ .../qingyuan/chargeStation/dto/IdNameDTO.java | 11 + .../dto/SimpleThingRelationDTO.java | 17 + .../dto/StationDeviceDetail.java | 26 + .../chargeStation/dto/StationInfoDTO.java | 86 ++ .../chargeStation/dto/StationOrderAgg.java | 81 ++ .../chargeStation/dto/StationSimpleDTO.java | 43 + .../chargeStation/dto/StationSimpleInfo.java | 28 + .../entity/ChargeOrderDetailsEntity.java | 81 ++ .../entity/ChargeOrderHeadEntity.java | 70 ++ .../entity/ConnectorInfoEntity.java | 66 ++ .../entity/EquipmentInfoEntity.java | 80 ++ .../entity/StationInfoEntity.java | 105 +++ .../excel/ChargeStatisticExcel.java | 106 +++ .../mapper/ChargeOrderDetailsMapper.java | 23 + .../mapper/ChargeOrderHeadMapper.java | 18 + .../mapper/ConnectorInfoMapper.java | 32 + .../mapper/EquipmentInfoMapper.java | 24 + .../mapper/StationInfoMapper.java | 22 + .../service/ChargeOrderDetailsService.java | 20 + .../service/ChargeOrderHeadService.java | 21 + .../service/ChargeStatisticService.java | 18 + .../service/ConnectorInfoService.java | 23 + .../service/EquipmentInfoService.java | 22 + .../service/StationInfoService.java | 55 ++ .../impl/ChargeOrderDetailsServiceImpl.java | 57 ++ .../impl/ChargeOrderHeadServiceImpl.java | 108 +++ .../impl/ChargeStatisticServiceImpl.java | 135 +++ .../impl/ConnectorInfoServiceImpl.java | 51 ++ .../impl/EquipmentInfoServiceImpl.java | 53 ++ .../service/impl/StationInfoServiceImpl.java | 389 +++++++++ .../chargeStation/task/StationTask.java | 272 ++++++ .../controller/ManageBoardController.java | 112 +++ .../controller/ManageChargeController.java | 80 ++ .../controller/PlantController.java | 96 +++ .../manageboard/dto/ChargeTotalInfo.java | 20 + .../manageboard/dto/ChargingGunState.java | 22 + .../qingyuan/manageboard/dto/DataParam.java | 22 + .../qingyuan/manageboard/dto/DataReq.java | 28 + .../qingyuan/manageboard/dto/FindParam.java | 15 + .../manageboard/dto/GunDataParam.java | 20 + .../manageboard/dto/GunReportParam.java | 17 + .../qingyuan/manageboard/dto/MapParam.java | 16 + .../qingyuan/manageboard/dto/PVParam.java | 20 + .../qingyuan/manageboard/dto/PVReport.java | 68 ++ .../qingyuan/manageboard/dto/PlantDTO.java | 55 ++ .../manageboard/dto/PlantInfoReq.java | 57 ++ .../qingyuan/manageboard/dto/PlantReq.java | 32 + .../manageboard/dto/ReductionStatistics.java | 36 + .../manageboard/dto/SiteTypeInfo.java | 30 + .../manageboard/dto/StationInfoReq.java | 61 ++ .../qingyuan/manageboard/dto/TotalInfo.java | 27 + .../qingyuan/manageboard/dto/YOYDataReq.java | 39 + .../manageboard/entity/PlantEntity.java | 90 ++ .../manageboard/mapper/PlantMapper.java | 18 + .../service/ManageBoardService.java | 29 + .../service/ManageChargeService.java | 25 + .../manageboard/service/PlantService.java | 25 + .../service/impl/ManageBoardServiceImpl.java | 551 +++++++++++++ .../service/impl/ManageChargeServiceImpl.java | 557 +++++++++++++ .../service/impl/PlantServiceImpl.java | 107 +++ .../controller/PhotovoltaicController.java | 129 +++ .../dto/PhotovoltaicConsumptionDTO.java | 33 + .../photovoltaic/dto/PhotovoltaicDTO.java | 45 + .../dto/PhotovoltaicOverviewDTO.java | 36 + .../dto/PhotovoltaicReportDTO.java | 43 + .../service/PhotovoltaicService.java | 45 + .../service/impl/PhotovoltaicServiceImpl.java | 776 ++++++++++++++++++ .../IotEnergyConsumptionTargetController.java | 100 +++ .../controller/IotValueAddedController.java | 101 +++ .../dto/IotAddedDateDTO.java | 26 + .../dto/IotDataValueDTO.java | 26 + .../dto/IotEnergyConsumptionTargetDTO.java | 41 + .../dto/IotEnergyValueDTO.java | 50 ++ .../consumptionTarget/dto/IotValueAddDTO.java | 47 ++ .../dto/iotValueAddedDTO.java | 40 + .../IotEnergyConsumptionTargetEntity.java | 63 ++ .../entity/IotValueAddedEntity.java | 63 ++ .../IotEnergyConsumptionTargetMapper.java | 36 + .../mapper/IotValueAddedMapper.java | 39 + .../IotEnergyConsumptionTargetService.java | 32 + .../service/IotValueAddedService.java | 34 + ...IotEnergyConsumptionTargetServiceImpl.java | 342 ++++++++ .../impl/IotValueAddedServiceImpl.java | 292 +++++++ .../DetailsMonitoringController.java | 114 +++ .../dto/CarbonEmissionTrendDTO.java | 19 + .../detailsMonitoring/dto/CleanEnergyDTO.java | 17 + .../dto/EnergyConsumptionDTO.java | 29 + .../dto/EnergyConsumptionTrendDTO.java | 19 + .../detailsMonitoring/dto/EnergyDTO.java | 23 + .../detailsMonitoring/dto/EnergyTrendDTO.java | 18 + .../detailsMonitoring/dto/EnterprisesDTO.java | 44 + .../dto/TypeEnergyUsedDTO.java | 21 + .../service/DetailsMonitoringService.java | 58 ++ .../impl/DetailsMonitoringServiceImpl.java | 765 +++++++++++++++++ .../controller/RegionBoardController.java | 114 +++ ...gionEnergyConsumptionReportController.java | 136 +++ .../RegionEnergyWarningController.java | 188 +++++ .../dto/RegionAreaConsumptionDTO.java | 43 + .../regionalboard/dto/RegionAreaInfoDTO.java | 19 + .../dto/RegionConsumptionDTO.java | 27 + .../dto/RegionConsumptionTargetDTO.java | 22 + .../dto/RegionEnergyBaseExportExcel.java | 48 ++ .../dto/RegionEnergyBaseReportDTO.java | 50 ++ .../RegionEnergyConsumptionAnalyseDTO.java | 44 + .../dto/RegionEnergyConsumptionDTO.java | 31 + .../RegionEnergyConsumptionExportExcel.java | 40 + .../dto/RegionEnergyConsumptionReportDTO.java | 40 + .../dto/RegionEnergyDetailExportExcel.java | 30 + .../dto/RegionEnergyWarningDataDTO.java | 49 ++ .../dto/RegionEnergyWarningExcel.java | 39 + .../dto/RegionEnergyWarningExcel1.java | 39 + .../dto/RegionEnergyWarningRequestDTO.java | 33 + .../dto/RegionIndustryCarbonDTO.java | 30 + .../regionalboard/dto/RegionIndustryDTO.java | 28 + .../dto/RegionIndustryInfoDTO.java | 23 + .../regionalboard/dto/RegionLinkDTO.java | 33 + .../dto/RegionMonthConsumptionDTO.java | 24 + .../dto/RegionMonthEnergyConsumptionDTO.java | 29 + .../regionalboard/dto/RegionNodeDTO.java | 18 + .../dto/RegionOrgConsumptionCompareDTO.java | 38 + .../dto/RegionSubNodeRespDTO.java | 20 + .../dto/RegionTotalCarbonDTO.java | 23 + .../dto/RegionTotalConsumptionAnalyseDTO.java | 23 + .../regionalboard/dto/RegionTotalDataDTO.java | 49 ++ .../dto/RegionUnitConsumptionDTO.java | 32 + .../dto/RegionWarningCountDTO.java | 24 + ...RegionYearEnergyConsumptionAnalyseDTO.java | 29 + .../service/RegionBoardService.java | 33 + .../RegionEnergyConsumptionReportService.java | 18 + .../service/RegionEnergyWarningService.java | 29 + .../service/impl/RegionBoardServiceImpl.java | 671 +++++++++++++++ ...ionEnergyConsumptionReportServiceImpl.java | 530 ++++++++++++ .../impl/RegionEnergyWarningServiceImpl.java | 643 +++++++++++++++ .../com/thing/qingyuan/screen/ScreenData.java | 70 ++ .../qingyuan/screen/StationChargeStatus.java | 123 +++ .../qingyuan/screen/StationChargeTrend.java | 170 ++++ .../qingyuan/screen/StationDailyInfo.java | 76 ++ .../thing/qingyuan/screen/StationMapData.java | 106 +++ .../screen/StationMonthChargeAnalysis.java | 59 ++ .../screen/StationMonthUsageAnalysis.java | 44 + .../thing/qingyuan/screen/StationRank.java | 80 ++ .../thing/qingyuan/screen/StationSummary.java | 64 ++ .../thing/qingyuan/screen/StationTsValue.java | 51 ++ .../controller/StationScreenController.java | 104 +++ .../screen/service/StationScreenService.java | 29 + .../impl/StationScreenServiceImpl.java | 179 ++++ .../thing/qingyuan/util/CalculationUtil.java | 77 ++ .../main/resources/application-changshu.yml | 11 + .../ChargeOrderDetailsMapper.xml | 18 + .../chargeStation/ConnectorInfoMapper.xml | 56 ++ .../chargeStation/EquipmentInfoMapper.xml | 15 + .../chargeStation/StationInfoMapper.xml | 22 + .../IotEnergyConsumptionTargetMapper.xml | 126 +++ .../consumptionTarget/IotValueAddedMapper.xml | 129 +++ .../model/thread/ThingModelExecutor.java | 24 + .../SimulateSocketEventListener.java | 110 +++ pom.xml | 10 +- 187 files changed, 14698 insertions(+), 10 deletions(-) create mode 100644 common/core/src/main/java/com/thing/common/core/event/SimulateSocketEvent.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/alert/controller/AlertController.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/alert/dto/AlertDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/alert/entity/AlertEntity.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/alert/excel/AlertExcel.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/alert/mapper/AlertMapper.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/alert/service/AlertService.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/alert/service/impl/AlertServiceImpl.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/basedevice/controller/DeviceController.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/basedevice/dto/DeviceDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/basedevice/entity/DeviceEntity.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/basedevice/excel/DeviceExcel.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/basedevice/mapper/DeviceMapper.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/basedevice/service/IotDeviceService.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/basedevice/service/impl/IotDeviceServiceImpl.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/config/StationProperties.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/controller/ChargeOrderHeadController.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/controller/ChargeStatisticController.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/controller/StationInfoController.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/ChargeOrderDetailsDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/ChargeOrderHeadDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/ChargeStatisticReportResp.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/ChargeStatisticRequest.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/ConnectorInfoDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/ConnectorStatusInfo.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/EquipmentInfoDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/IdNameDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/SimpleThingRelationDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/StationDeviceDetail.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/StationInfoDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/StationOrderAgg.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/StationSimpleDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/StationSimpleInfo.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/entity/ChargeOrderDetailsEntity.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/entity/ChargeOrderHeadEntity.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/entity/ConnectorInfoEntity.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/entity/EquipmentInfoEntity.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/entity/StationInfoEntity.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/excel/ChargeStatisticExcel.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/mapper/ChargeOrderDetailsMapper.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/mapper/ChargeOrderHeadMapper.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/mapper/ConnectorInfoMapper.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/mapper/EquipmentInfoMapper.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/mapper/StationInfoMapper.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/ChargeOrderDetailsService.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/ChargeOrderHeadService.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/ChargeStatisticService.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/ConnectorInfoService.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/EquipmentInfoService.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/StationInfoService.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/impl/ChargeOrderDetailsServiceImpl.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/impl/ChargeOrderHeadServiceImpl.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/impl/ChargeStatisticServiceImpl.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/impl/ConnectorInfoServiceImpl.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/impl/EquipmentInfoServiceImpl.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/impl/StationInfoServiceImpl.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/task/StationTask.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/controller/ManageBoardController.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/controller/ManageChargeController.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/controller/PlantController.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/ChargeTotalInfo.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/ChargingGunState.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/DataParam.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/DataReq.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/FindParam.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/GunDataParam.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/GunReportParam.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/MapParam.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/PVParam.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/PVReport.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/PlantDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/PlantInfoReq.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/PlantReq.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/ReductionStatistics.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/SiteTypeInfo.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/StationInfoReq.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/TotalInfo.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/YOYDataReq.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/entity/PlantEntity.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/mapper/PlantMapper.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/service/ManageBoardService.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/service/ManageChargeService.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/service/PlantService.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/service/impl/ManageBoardServiceImpl.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/service/impl/ManageChargeServiceImpl.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/service/impl/PlantServiceImpl.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/photovoltaic/controller/PhotovoltaicController.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/photovoltaic/dto/PhotovoltaicConsumptionDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/photovoltaic/dto/PhotovoltaicDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/photovoltaic/dto/PhotovoltaicOverviewDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/photovoltaic/dto/PhotovoltaicReportDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/photovoltaic/service/PhotovoltaicService.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/photovoltaic/service/impl/PhotovoltaicServiceImpl.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/controller/IotEnergyConsumptionTargetController.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/controller/IotValueAddedController.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/dto/IotAddedDateDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/dto/IotDataValueDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/dto/IotEnergyConsumptionTargetDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/dto/IotEnergyValueDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/dto/IotValueAddDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/dto/iotValueAddedDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/entity/IotEnergyConsumptionTargetEntity.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/entity/IotValueAddedEntity.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/mapper/IotEnergyConsumptionTargetMapper.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/mapper/IotValueAddedMapper.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/service/IotEnergyConsumptionTargetService.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/service/IotValueAddedService.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/service/impl/IotEnergyConsumptionTargetServiceImpl.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/service/impl/IotValueAddedServiceImpl.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/controller/DetailsMonitoringController.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/dto/CarbonEmissionTrendDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/dto/CleanEnergyDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/dto/EnergyConsumptionDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/dto/EnergyConsumptionTrendDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/dto/EnergyDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/dto/EnergyTrendDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/dto/EnterprisesDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/dto/TypeEnergyUsedDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/service/DetailsMonitoringService.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/service/impl/DetailsMonitoringServiceImpl.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/controller/RegionBoardController.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/controller/RegionEnergyConsumptionReportController.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/controller/RegionEnergyWarningController.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionAreaConsumptionDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionAreaInfoDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionConsumptionDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionConsumptionTargetDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyBaseExportExcel.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyBaseReportDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyConsumptionAnalyseDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyConsumptionDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyConsumptionExportExcel.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyConsumptionReportDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyDetailExportExcel.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyWarningDataDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyWarningExcel.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyWarningExcel1.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyWarningRequestDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionIndustryCarbonDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionIndustryDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionIndustryInfoDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionLinkDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionMonthConsumptionDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionMonthEnergyConsumptionDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionNodeDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionOrgConsumptionCompareDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionSubNodeRespDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionTotalCarbonDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionTotalConsumptionAnalyseDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionTotalDataDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionUnitConsumptionDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionWarningCountDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionYearEnergyConsumptionAnalyseDTO.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/service/RegionBoardService.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/service/RegionEnergyConsumptionReportService.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/service/RegionEnergyWarningService.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/service/impl/RegionBoardServiceImpl.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/service/impl/RegionEnergyConsumptionReportServiceImpl.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/service/impl/RegionEnergyWarningServiceImpl.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/screen/ScreenData.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationChargeStatus.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationChargeTrend.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationDailyInfo.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationMapData.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationMonthChargeAnalysis.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationMonthUsageAnalysis.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationRank.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationSummary.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationTsValue.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/screen/controller/StationScreenController.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/screen/service/StationScreenService.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/screen/service/impl/StationScreenServiceImpl.java create mode 100644 modules/qingyuan/src/main/java/com/thing/qingyuan/util/CalculationUtil.java create mode 100644 modules/qingyuan/src/main/resources/application-changshu.yml create mode 100644 modules/qingyuan/src/main/resources/mapper/chargeStation/ChargeOrderDetailsMapper.xml create mode 100644 modules/qingyuan/src/main/resources/mapper/chargeStation/ConnectorInfoMapper.xml create mode 100644 modules/qingyuan/src/main/resources/mapper/chargeStation/EquipmentInfoMapper.xml create mode 100644 modules/qingyuan/src/main/resources/mapper/chargeStation/StationInfoMapper.xml create mode 100644 modules/qingyuan/src/main/resources/mapper/regionalenterprises/consumptionTarget/IotEnergyConsumptionTargetMapper.xml create mode 100644 modules/qingyuan/src/main/resources/mapper/regionalenterprises/consumptionTarget/IotValueAddedMapper.xml create mode 100644 modules/thing/src/main/java/com/thing/thing/model/thread/ThingModelExecutor.java create mode 100644 modules/thing/src/main/java/com/thing/websocket/SimulateSocketEventListener.java diff --git a/README.md b/README.md index 1ed46dd..5f2a4b7 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ .pom文件,yml文件整合 .删除不需要的私有化定制代码 .本地队列驱动优化 - .移除[changshu]模块 + .移除[qingyuan]模块 .移除 老旧的[gateway]模块 .[publicorg]模块 有涉及设备管理相关代码,暂时保留 diff --git a/application/pom.xml b/application/pom.xml index d45a2d4..4372fe7 100644 --- a/application/pom.xml +++ b/application/pom.xml @@ -137,6 +137,10 @@ com.thing.modules filter-rule + + com.thing.modules + qingyuan + com.thing.modules cqc-service diff --git a/application/src/main/resources/application.yml b/application/src/main/resources/application.yml index bc695bb..c4fc54a 100644 --- a/application/src/main/resources/application.yml +++ b/application/src/main/resources/application.yml @@ -1,5 +1,5 @@ server: - port: 18080 + port: 8080 servlet: context-path: /thing spring: @@ -62,7 +62,7 @@ database: # 数据源及mybatis、mybatis-flex配置 mybatis-flex: #是否开启审计日志打印 - auditEnable: false + auditEnable: true #mapper 包扫描路径 typeAliasesPackage: com.thing.**.mapper #mapper 扫描路径 @@ -82,14 +82,21 @@ mybatis-flex: #物管理数据源 pg-thing: type: com.zaxxer.hikari.HikariDataSource - url: jdbc:postgresql://127.0.0.1:25432/pub_guowang_v1 + url: jdbc:postgresql://127.0.0.1:15432/thing driver-class-name: org.postgresql.Driver username: postgres password: sddt8888 #遥测数据数据眼 pg-tskv: type: com.zaxxer.hikari.HikariDataSource - url: jdbc:postgresql://127.0.0.1:25432/pub_guowang_v1 + url: jdbc:postgresql://127.0.0.1:15432/thing + driver-class-name: org.postgresql.Driver + username: postgres + password: sddt8888 + systemCollect: + # 指定为HikariDataSource + type: com.zaxxer.hikari.HikariDataSource + url: jdbc:postgresql://192.168.188.184:5432/systemCollect driver-class-name: org.postgresql.Driver username: postgres password: sddt8888 diff --git a/common/core/src/main/java/com/thing/common/core/event/SimulateSocketEvent.java b/common/core/src/main/java/com/thing/common/core/event/SimulateSocketEvent.java new file mode 100644 index 0000000..bf7bd47 --- /dev/null +++ b/common/core/src/main/java/com/thing/common/core/event/SimulateSocketEvent.java @@ -0,0 +1,32 @@ +package com.thing.common.core.event; + + +import com.thing.common.data.dto.QueueMsgDTO; +import com.thing.common.data.event.AbstractQueueEvent; + +import java.io.Serial; +import java.util.List; + +/** + * @author zhenghh. 2023-03-14 + **/ +public class SimulateSocketEvent extends AbstractQueueEvent { + + + @Serial + private static final long serialVersionUID = -7524682936528507783L; + + public SimulateSocketEvent(Object source, List list) { + super(source, list); + } + +// /** +// * 事件类型 +// * +// * @return type +// */ +// @Override +// public QueueEventType getEventType() { +// return QueueEventType.SOCKET; +// } +} diff --git a/modules/pom.xml b/modules/pom.xml index eb93403..cf42015 100644 --- a/modules/pom.xml +++ b/modules/pom.xml @@ -21,6 +21,8 @@ calculation mock fix + qingyuan + publicorg alarm filter-rule diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/alert/controller/AlertController.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/alert/controller/AlertController.java new file mode 100644 index 0000000..0efbc62 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/alert/controller/AlertController.java @@ -0,0 +1,103 @@ +package com.thing.qingyuan.alert.controller; + +import com.thing.qingyuan.alert.dto.AlertDTO; +import com.thing.qingyuan.alert.service.AlertService; +import com.thing.common.core.annotation.LogOperation; +import com.thing.common.core.constants.Constant; +import com.thing.common.core.validator.AssertUtils; +import com.thing.common.core.validator.ValidatorUtils; +import com.thing.common.core.validator.group.AddGroup; +import com.thing.common.core.validator.group.DefaultGroup; +import com.thing.common.core.validator.group.UpdateGroup; +import com.thing.common.core.web.response.PageData; +import com.thing.common.core.web.response.Result; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Map; + +/** +* 告警记录 +* +* @author xc +* @since 3.0 2024-01-31 +*/ +@RestController +@RequestMapping("alert") +@Tag(name="告警记录") +@RequiredArgsConstructor +public class AlertController { + + private final AlertService alertService; + + @GetMapping("page") + @Operation(summary="分页") + @Parameters({ + @Parameter(name = Constant.PAGE, description = "当前页码,从1开始") , + @Parameter(name = Constant.LIMIT, description = "每页显示记录数") , + @Parameter(name = Constant.ORDER_FIELD, description = "排序字段") , + @Parameter(name = Constant.ORDER, description = "排序方式,可选值(asc、desc)"), + @Parameter(name = "name", description = "告警名称"), + @Parameter(name = "level", description = "告警等级"), + @Parameter(name = "status", description = "处理状态"), + @Parameter(name = "startTime", description = "告警开始时间窗口"), + @Parameter(name = "endTime", description = "告警结束时间窗口"), + @Parameter(name = "plantIds", description = "光伏场站id列表"), + }) + public Result> page(@RequestParam Map params){ + PageData page = alertService.handlePage(params); + return new Result>().ok(page); + } + + @GetMapping("{id}") + @Operation(summary="信息") + public Result get(@PathVariable("id") Long id){ + AlertDTO data = alertService.getByIdAs(id, AlertDTO.class); + return new Result().ok(data); + } + + @PostMapping + @Operation(summary="保存") + @LogOperation("保存") + public Result save(@RequestBody AlertDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class); + alertService.saveDto(dto); + return new Result<>(); + } + + @PutMapping + @Operation(summary="修改") + @LogOperation("修改") + public Result update(@RequestBody AlertDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class); + alertService.updateDto(dto); + return new Result<>(); + } + + @DeleteMapping + @Operation(summary="删除") + @LogOperation("删除") + public Result delete(@RequestBody Long[] ids){ + //效验数据 + AssertUtils.isArrayEmpty(ids, "id"); + alertService.batchDelete(ids); + return new Result<>(); + } + + @GetMapping("export") + @Operation(summary="导出") + @LogOperation("导出") + public void export( @RequestParam Map params, HttpServletResponse response) throws Exception { + List list = alertService.listAs(params, AlertDTO.class); + //ExcelUtils.exportExcelToTarget(response, null, "告警记录", list, AlertExcel.class); + } + +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/alert/dto/AlertDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/alert/dto/AlertDTO.java new file mode 100644 index 0000000..dd5638b --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/alert/dto/AlertDTO.java @@ -0,0 +1,70 @@ +package com.thing.qingyuan.alert.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** +* 告警记录 +* +* @author xc +* @since 3.0 2024-01-31 +*/ +@Data +@Schema( name= "告警记录") +public class AlertDTO implements Serializable { + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "主键") + private Long plantAlertId; + @Schema(description = "电站id") + private Long plantId; + @Schema(description = "电站名称") + private String plantName; + @Schema(description = "设备id") + private Long deviceId; + @Schema(description = "设备名称") + private String deviceName; + @Schema(description = "状态id:1.未处理;2.已处理;3.已恢复") + private Integer status; + @Schema(description = "状态文本:1.未处理;2.已处理;3.已恢复") + private String statusLabel; + @Schema(description = "采集器sn") + private String collectorSn; + @Schema(description = "逆变器sn") + private String deviceSn; + @Schema(description = "报警等级id: 01.故障 02.警告 03.提示") + private Integer alertLevel; + @Schema(description = "报警等级文本: 01.故障 02.警告 03.提示") + private String alertLevelLabel; + @Schema(description = "报警名称") + private String alertName; + @Schema(description = "报警代码") + private String alertCode; + @Schema(description = "报警影响面") + private Integer alertEffect; + @Schema(description = "报警影响面文本") + private String alertEffectLabel; + @Schema(description = "报警发生时间") + private String startTimeOrigin; + @Schema(description = "报警发生时间") + private String startTime; + @Schema(description = "报警恢复时间") + private String endTimeOrigin; + @Schema(description = "报警恢复时间") + private String endTime; + @Schema(description = "报警发生时间") + private String startTimeForCharts; + @Schema(description = "报警恢复时间") + private String endTimeForCharts; + @Schema(description = "持续时间") + private String duration; + @Schema(description = "拟解决方案") + private String solution; + @Schema(description = "时区") + private Integer timeZoneOffset; + +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/alert/entity/AlertEntity.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/alert/entity/AlertEntity.java new file mode 100644 index 0000000..adb7c50 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/alert/entity/AlertEntity.java @@ -0,0 +1,113 @@ +package com.thing.qingyuan.alert.entity; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.Table; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serial; +import java.io.Serializable; + +/** + * 告警记录 + * + * @author xc + * @since 3.0 2024-01-31 + */ +@Data +@EqualsAndHashCode(callSuper=false) +@Table("alert") +public class AlertEntity implements Serializable { + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @Id + private Long plantAlertId; + /** + * 电站id + */ + private Long plantId; + /** + * 设备id + */ + private Long deviceId; + /** + * 状态id:1.未处理;2.已处理;3.已恢复 + */ + private Integer status; + /** + * 状态文本:1.未处理;2.已处理;3.已恢复 + */ + private String statusLabel; + /** + * 采集器sn + */ + private String collectorSn; + /** + * 逆变器sn + */ + private String deviceSn; + /** + * 报警等级id: 01.故障 02.警告 03.提示 + */ + private Integer alertLevel; + /** + * 报警等级文本: 01.故障 02.警告 03.提示 + */ + private String alertLevelLabel; + /** + * 报警名称 + */ + private String alertName; + /** + * 报警代码 + */ + private String alertCode; + /** + * 报警影响面 + */ + private Integer alertEffect; + /** + * 报警影响面文本 + */ + private String alertEffectLabel; + /** + * 报警发生时间 + */ + private String startTimeOrigin; + /** + * 报警发生时间 + */ + private String startTime; + /** + * 报警恢复时间 + */ + private String endTimeOrigin; + /** + * 报警恢复时间 + */ + private String endTime; + /** + * 报警发生时间 + */ + private String startTimeForCharts; + /** + * 报警恢复时间 + */ + private String endTimeForCharts; + /** + * 持续时间 + */ + private String duration; + /** + * 拟解决方案 + */ + private String solution; + /** + * 时区 + */ + private Integer timeZoneOffset; +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/alert/excel/AlertExcel.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/alert/excel/AlertExcel.java new file mode 100644 index 0000000..89102b5 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/alert/excel/AlertExcel.java @@ -0,0 +1,64 @@ +package com.thing.qingyuan.alert.excel; + +import com.alibaba.excel.annotation.ExcelProperty; +import com.alibaba.excel.annotation.write.style.ColumnWidth; +import com.alibaba.excel.annotation.write.style.ContentRowHeight; +import com.alibaba.excel.annotation.write.style.HeadRowHeight; +import lombok.Data; + +/** + * 告警记录 + * + * @author xc + * @since 3.0 2024-01-31 + */ +@Data +@ContentRowHeight(20) +@HeadRowHeight(20) +@ColumnWidth(25) +public class AlertExcel { + @ExcelProperty(value = "主键", index = 0) + private Long plantAlertId; + @ExcelProperty(value = "电站id", index = 1) + private Long plantId; + @ExcelProperty(value = "设备id", index = 2) + private Long deviceId; + @ExcelProperty(value = "状态id:1.未处理;2.已处理;3.已恢复", index = 3) + private Integer status; + @ExcelProperty(value = "状态文本:1.未处理;2.已处理;3.已恢复", index = 4) + private String statusLabel; + @ExcelProperty(value = "采集器sn", index = 5) + private String collectorSn; + @ExcelProperty(value = "逆变器sn", index = 6) + private String deviceSn; + @ExcelProperty(value = "报警等级id: 01.故障 02.警告 03.提示", index = 7) + private Integer alertLevel; + @ExcelProperty(value = "报警等级文本: 01.故障 02.警告 03.提示", index = 8) + private String alertLevelLabel; + @ExcelProperty(value = "报警名称", index = 9) + private String alertName; + @ExcelProperty(value = "报警代码", index = 10) + private String alertCode; + @ExcelProperty(value = "报警影响面", index = 11) + private Integer alertEffect; + @ExcelProperty(value = "报警影响面文本", index = 12) + private String alertEffectLabel; + @ExcelProperty(value = "报警发生时间", index = 13) + private String startTimeOrigin; + @ExcelProperty(value = "报警发生时间", index = 14) + private String startTime; + @ExcelProperty(value = "报警恢复时间", index = 15) + private String endTimeOrigin; + @ExcelProperty(value = "报警恢复时间", index = 16) + private String endTime; + @ExcelProperty(value = "报警发生时间", index = 17) + private String startTimeForCharts; + @ExcelProperty(value = "报警恢复时间", index = 18) + private String endTimeForCharts; + @ExcelProperty(value = "持续时间", index = 19) + private String duration; + @ExcelProperty(value = "拟解决方案", index = 20) + private String solution; + @ExcelProperty(value = "时区", index = 21) + private Integer timeZoneOffset; +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/alert/mapper/AlertMapper.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/alert/mapper/AlertMapper.java new file mode 100644 index 0000000..eaf0bf8 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/alert/mapper/AlertMapper.java @@ -0,0 +1,18 @@ +package com.thing.qingyuan.alert.mapper; + +import com.mybatisflex.annotation.UseDataSource; +import com.thing.qingyuan.alert.entity.AlertEntity; +import com.thing.common.orm.mapper.PowerBaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** +* 告警记录 +* +* @author xc +* @since 3.0 2024-01-31 +*/ +@Mapper +@UseDataSource("systemCollect") +public interface AlertMapper extends PowerBaseMapper { + +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/alert/service/AlertService.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/alert/service/AlertService.java new file mode 100644 index 0000000..622afd0 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/alert/service/AlertService.java @@ -0,0 +1,19 @@ +package com.thing.qingyuan.alert.service; + +import com.thing.qingyuan.alert.dto.AlertDTO; +import com.thing.qingyuan.alert.entity.AlertEntity; +import com.thing.common.core.web.response.PageData; +import com.thing.common.orm.service.IBaseService; + +import java.util.Map; + +/** + * 告警记录 + * + * @author xc + * @since 3.0 2024-01-31 + */ +public interface AlertService extends IBaseService { + + PageData handlePage(Map params); +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/alert/service/impl/AlertServiceImpl.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/alert/service/impl/AlertServiceImpl.java new file mode 100644 index 0000000..afc3c5e --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/alert/service/impl/AlertServiceImpl.java @@ -0,0 +1,97 @@ +package com.thing.qingyuan.alert.service.impl; + +import cn.hutool.core.map.MapUtil; +import com.mybatisflex.core.query.QueryWrapper; +import com.thing.qingyuan.alert.dto.AlertDTO; +import com.thing.qingyuan.alert.entity.AlertEntity; +import com.thing.qingyuan.alert.mapper.AlertMapper; +import com.thing.qingyuan.alert.service.AlertService; +import com.thing.qingyuan.basedevice.entity.DeviceEntity; +import com.thing.qingyuan.basedevice.service.IotDeviceService; +import com.thing.qingyuan.manageboard.entity.PlantEntity; +import com.thing.qingyuan.manageboard.service.PlantService; +import com.thing.common.core.web.response.PageData; +import com.thing.common.orm.service.impl.BaseServiceImpl; +import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +import static com.thing.qingyuan.alert.entity.table.AlertEntityTableDef.ALERT_ENTITY; + +/** + * 告警记录 + * + * @author xc + * @since 3.0 2024-01-31 + */ +@Service +@RequiredArgsConstructor +public class AlertServiceImpl extends BaseServiceImpl + implements AlertService { + + private final PlantService plantService; + private final IotDeviceService deviceService; + + @Override + public QueryWrapper getWrapper(Map params) { + QueryWrapper wrapper = new QueryWrapper(); + String alertName = MapUtil.getStr(params, "name"); + Integer alertLevel = MapUtil.getInt(params, "level"); + String statusLabel = MapUtil.getStr(params, "status"); + String startTime = MapUtil.getStr(params, "startTime"); + String endTime = MapUtil.getStr(params, "endTime"); + String plantIds = MapUtil.getStr(params, "plantIds"); + + wrapper.eq(AlertEntity::getAlertName, alertName, StringUtils.isNotBlank(alertName)) + .eq(AlertEntity::getAlertLevel, alertLevel, Objects.nonNull(alertLevel)) + .eq(AlertEntity::getStatusLabel, statusLabel, StringUtils.isNotBlank(statusLabel)); + + if(StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)){ + startTime += " UTC+08:00"; + endTime += " UTC+08:00"; + wrapper.and(ALERT_ENTITY.START_TIME.between(startTime, endTime) + .or(ALERT_ENTITY.END_TIME.between(startTime, endTime))); + } + + if (StringUtils.isNotBlank(plantIds)) { + List plantIdList = + Arrays.stream(plantIds.split(",")) + .map(Long::valueOf) + .toList(); + wrapper.in(AlertEntity::getPlantId, plantIdList); + } + wrapper.isNotNull(AlertEntity::getStartTimeOrigin); + return wrapper; + } + + @Override + public PageData handlePage(Map params) { + PageData pageData = getPageData(params, AlertDTO.class); + List list = pageData.getList(); + if (list.isEmpty()) { + return pageData; + } + Set plantIds = list.stream().map(AlertDTO::getPlantId).collect(Collectors.toSet()); + Set deviceIds = list.stream().map(AlertDTO::getDeviceId).collect(Collectors.toSet()); + Map plantMap = + plantService.getMapper().selectListByIds(plantIds).stream() + .collect( + Collectors.toMap( + PlantEntity::getPlantId, PlantEntity::getPlantName)); + Map deviceMap = + deviceService.getMapper().selectListByIds(deviceIds).stream() + .filter(e -> Objects.nonNull(e.getAlias())) + .collect( + Collectors.toMap( + DeviceEntity::getDeviceId, DeviceEntity::getAlias)); + list.forEach( + item -> { + item.setPlantName(plantMap.get(item.getPlantId())); + item.setDeviceName(deviceMap.get(item.getDeviceId())); + }); + return pageData; + } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/basedevice/controller/DeviceController.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/basedevice/controller/DeviceController.java new file mode 100644 index 0000000..046b757 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/basedevice/controller/DeviceController.java @@ -0,0 +1,108 @@ +//package com.thing.qingyuan.basedevice.controller; +// +//import com.thing.qingyuan.basedevice.dto.DeviceDTO; +//import com.thing.qingyuan.basedevice.service.IotDeviceService; +//import com.thing.common.core.annotation.LogOperation; +//import com.thing.common.core.constants.Constant; +//import com.thing.common.core.validator.AssertUtils; +//import com.thing.common.core.validator.ValidatorUtils; +//import com.thing.common.core.validator.group.AddGroup; +//import com.thing.common.core.validator.group.DefaultGroup; +//import com.thing.common.core.validator.group.UpdateGroup; +//import com.thing.common.core.web.response.PageData; +//import com.thing.common.core.web.response.Result; +//import io.swagger.v3.oas.annotations.Operation; +//import io.swagger.v3.oas.annotations.Parameter; +//import io.swagger.v3.oas.annotations.Parameters; +//import io.swagger.v3.oas.annotations.tags.Tag; +//import jakarta.servlet.http.HttpServletResponse; +//import lombok.RequiredArgsConstructor; +//import org.springframework.web.bind.annotation.*; +// +//import java.util.List; +//import java.util.Map; +// +///** +// * 设备信息表 +// * +// * @author xc +// * @since 3.0 2024-01-30 +// */ +//@RestController +//@RequestMapping("v1/device/info") +//@Tag(name = "设备信息表") +//@RequiredArgsConstructor +//public class DeviceController { +// +// private final IotDeviceService iotDeviceService; +// +// @GetMapping("page") +// @Operation(summary = "分页") +// @Parameters({ +// @Parameter(name = Constant.PAGE, description = "当前页码,从1开始"), +// @Parameter(name = Constant.LIMIT, description = "每页显示记录数"), +// @Parameter(name = Constant.ORDER_FIELD, description = "排序字段"), +// @Parameter(name = Constant.ORDER, description = "排序方式,可选值(asc、desc)") +// }) +// public Result> page(@RequestParam Map params) { +// PageData page = iotDeviceService.getPageData(params, DeviceDTO.class); +// return new Result>().ok(page); +// } +// +// @GetMapping("{id}") +// @Operation(summary = "信息") +// public Result get(@PathVariable("id") Long id) { +// DeviceDTO data = iotDeviceService.getByIdAs(id, DeviceDTO.class); +// return new Result().ok(data); +// } +// +// @PostMapping +// @Operation(summary = "保存") +// @LogOperation("保存") +// public Result save(@RequestBody DeviceDTO dto) { +// //效验数据 +// ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class); +// iotDeviceService.saveDto(dto); +// return new Result<>(); +// } +// +// @PutMapping +// @Operation(summary = "修改") +// @LogOperation("修改") +// public Result update(@RequestBody DeviceDTO dto) { +// //效验数据 +// ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class); +// iotDeviceService.updateDto(dto); +// return new Result<>(); +// } +// +// @DeleteMapping +// @Operation(summary = "删除") +// @LogOperation("删除") +// public Result delete(@RequestBody Long[] ids) { +// //效验数据 +// AssertUtils.isArrayEmpty(ids, "id"); +// iotDeviceService.batchDelete(ids); +// return new Result<>(); +// } +// +// @GetMapping("export") +// @Operation(summary = "导出") +// @LogOperation("导出") +// public void export(@RequestParam Map params, HttpServletResponse response) throws Exception { +// List list = iotDeviceService.listAs(params, DeviceDTO.class); +// //ExcelUtils.exportExcelToTarget(response, null, "设备信息表", list, DeviceExcel.class); +// } +// +// @GetMapping("{plantId}/{type}") +// @Operation(summary = "根据电站id和类型查询 1.采集器\n" + +// "2.逆变器\n" + +// "3.电表\n" + +// "4.EPM\n" + +// "5.气象仪") +// public Result> getDeviceByType(@PathVariable("plantId") Long plantId,@PathVariable("type") Integer type) { +// List deviceDTOS = iotDeviceService.findByPlantId(plantId, type); +// return new Result>().ok(deviceDTOS); +// } +// +//} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/basedevice/dto/DeviceDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/basedevice/dto/DeviceDTO.java new file mode 100644 index 0000000..6d08a45 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/basedevice/dto/DeviceDTO.java @@ -0,0 +1,53 @@ +package com.thing.qingyuan.basedevice.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * 设备信息表 + * + * @author xc + * @since 3.0 2024-01-30 + */ +@Data +@Schema(name = "设备信息表") +public class DeviceDTO implements Serializable { + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "设备ID") + private Long deviceId; + @Schema(description = "设备类型: 1.采集器 2.逆变器 3.电表 4.EPM 5.气象仪") + private Integer deviceType; + @Schema(description = "设备类型2: 与 productKey及deviceType2 关联") + private Integer deviceType2; + @Schema(description = "设备SN 逆变器sn") + private String deviceSn; + @Schema(description = "设备首次上电日期") + private String firstReportTime; + @Schema(description = "设备状态: 01.正常 02.离线 3.报警 4.故障 5.自定义报警 逆变器状态") + private Integer status; + @Schema(description = "产品代码 ") + private String productKey; + @Schema(description = "设备当前实时关联的电站ID") + private Long plantId; + @Schema(description = "设备最后上电日期") + private String lastReportTime; + @Schema(description = "设备上级连接父设备") + private Long upDeviceId; + @Schema(description = "记录创建时间") + private String createTime; + @Schema(description = "父设备sn 采集器sn") + private String upDeviceSn; + @Schema(description = "01.正常 02.离线 3.报警 4.故障 5.自定义报警 采集器状态 ") + private Integer upStatus; + @Schema(description = "01.正常 02.离线 3.报警 4.故障 5.自定义报警 采集器状态 ") + private String upAlias; + @Schema(description = "设备别名") + private String alias; + @Schema(description = "网络状态") + private String netWorkType="4G"; +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/basedevice/entity/DeviceEntity.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/basedevice/entity/DeviceEntity.java new file mode 100644 index 0000000..1410f3e --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/basedevice/entity/DeviceEntity.java @@ -0,0 +1,82 @@ +package com.thing.qingyuan.basedevice.entity; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.Table; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serial; +import java.io.Serializable; + +/** + * 设备信息表 + * + * @author xc + * @since 3.0 2024-01-30 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Table(value = "device",dataSource = "systemCollect") +public class DeviceEntity implements Serializable { + @Serial + private static final long serialVersionUID = 1L; + + /** + * 设备ID + */ + @Id + private Long deviceId; + /** + * 设备类型: + * 1.采集器 + * 2.逆变器 + * 3.电表 + * 4.EPM + * 5.气象仪 + */ + private Integer deviceType; + /** + * 设备类型2: 与 productKey及deviceType2 关联 + */ + private Integer deviceType2; + /** + * 设备SN + */ + private String deviceSn; + /** + * 设备首次上电日期 + */ + private String firstReportTime; + /** + * 设备状态: 01.正常 02.离线 3.报警 4.故障 5.自定义报警 + */ + private Integer status; + /** + * 产品代码 + */ + private String productKey; + /** + * 设备当前实时关联的电站ID + */ + private Long plantId; + /** + * 设备最后上电日期 + */ + private String lastReportTime; + /** + * 设备上级连接父设备 + */ + private Long upDeviceId; + /** + * 记录创建时间 + */ + private String createTime; + /** + * 父设备sn + */ + private String upDeviceSn; + /** + * 设备别名 + */ + private String alias; +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/basedevice/excel/DeviceExcel.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/basedevice/excel/DeviceExcel.java new file mode 100644 index 0000000..1d14758 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/basedevice/excel/DeviceExcel.java @@ -0,0 +1,46 @@ +package com.thing.qingyuan.basedevice.excel; + +import com.alibaba.excel.annotation.ExcelProperty; +import com.alibaba.excel.annotation.write.style.ColumnWidth; +import com.alibaba.excel.annotation.write.style.ContentRowHeight; +import com.alibaba.excel.annotation.write.style.HeadRowHeight; +import lombok.Data; + +/** + * 设备信息表 + * + * @author xc + * @since 3.0 2024-01-30 + */ +@Data +@ContentRowHeight(20) +@HeadRowHeight(20) +@ColumnWidth(25) +public class DeviceExcel { + @ExcelProperty(value = "设备ID", index = 0) + private Long deviceId; + @ExcelProperty(value = "设备类型:1.采集器2.逆变器3.电表4.EPM5.气象仪", index = 1) + private Integer deviceType; + @ExcelProperty(value = "设备类型2: 与 productKey及deviceType2 关联", index = 2) + private Integer deviceType2; + @ExcelProperty(value = "设备SN", index = 3) + private String deviceSn; + @ExcelProperty(value = "设备首次上电日期", index = 4) + private String firstReportTime; + @ExcelProperty(value = "设备状态: 01.正常 02.离线 3.报警 4.故障 5.自定义报警", index = 5) + private Integer status; + @ExcelProperty(value = "产品代码 ", index = 6) + private String productKey; + @ExcelProperty(value = "设备当前实时关联的电站ID", index = 7) + private Long plantId; + @ExcelProperty(value = "设备最后上电日期", index = 8) + private String lastReportTime; + @ExcelProperty(value = "设备上级连接父设备", index = 9) + private Long upDeviceId; + @ExcelProperty(value = "记录创建时间", index = 10) + private String createTime; + @ExcelProperty(value = "父设备sn", index = 11) + private String upDeviceSn; + @ExcelProperty(value = "设备别名", index = 12) + private String alias; +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/basedevice/mapper/DeviceMapper.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/basedevice/mapper/DeviceMapper.java new file mode 100644 index 0000000..b14572a --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/basedevice/mapper/DeviceMapper.java @@ -0,0 +1,18 @@ +package com.thing.qingyuan.basedevice.mapper; + +import com.mybatisflex.annotation.UseDataSource; +import com.thing.qingyuan.basedevice.entity.DeviceEntity; +import com.thing.common.orm.mapper.PowerBaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** +* 设备信息表 +* +* @author xc +* @since 3.0 2024-01-30 +*/ +@Mapper +@UseDataSource("systemCollect") +public interface DeviceMapper extends PowerBaseMapper { + +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/basedevice/service/IotDeviceService.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/basedevice/service/IotDeviceService.java new file mode 100644 index 0000000..c02d912 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/basedevice/service/IotDeviceService.java @@ -0,0 +1,18 @@ +package com.thing.qingyuan.basedevice.service; + +import com.thing.qingyuan.basedevice.dto.DeviceDTO; +import com.thing.qingyuan.basedevice.entity.DeviceEntity; +import com.thing.common.orm.service.IBaseService; + +import java.util.List; + +/** + * 设备信息表 + * + * @author xc + * @since 3.0 2024-01-30 + */ +public interface IotDeviceService extends IBaseService { + List findByPlantId(Long plantId,Integer type); + +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/basedevice/service/impl/IotDeviceServiceImpl.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/basedevice/service/impl/IotDeviceServiceImpl.java new file mode 100644 index 0000000..8363906 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/basedevice/service/impl/IotDeviceServiceImpl.java @@ -0,0 +1,36 @@ +package com.thing.qingyuan.basedevice.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.mybatisflex.core.query.QueryWrapper; +import com.thing.qingyuan.basedevice.dto.DeviceDTO; +import com.thing.qingyuan.basedevice.entity.DeviceEntity; +import com.thing.qingyuan.basedevice.mapper.DeviceMapper; +import com.thing.qingyuan.basedevice.service.IotDeviceService; +import com.thing.common.orm.service.impl.BaseServiceImpl; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * 设备信息表 + * + * @author xc + * @since 3.0 2024-01-30 + */ +@Service("IotDeviceServiceImpl") +public class IotDeviceServiceImpl extends BaseServiceImpl implements IotDeviceService { + + @Override + public QueryWrapper getWrapper(Map params) { + QueryWrapper wrapper = new QueryWrapper(); + return wrapper; + } + + + @Override + public List findByPlantId(Long plantId,Integer type) { + QueryWrapper queryWrapper = QueryWrapper.create().eq(DeviceEntity::getPlantId, plantId).eq(DeviceEntity::getDeviceType,type, ObjectUtil::isNotNull); + return mapper.selectListByQueryAs(queryWrapper,DeviceDTO.class); + } +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/config/StationProperties.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/config/StationProperties.java new file mode 100644 index 0000000..295d37f --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/config/StationProperties.java @@ -0,0 +1,41 @@ +package com.thing.qingyuan.chargeStation.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Objects; + +/** + * @author SiYang + * @date 2024/01/29 14:17 + * @description 充电站配置属性 + */ +@Data +@Component +@ConfigurationProperties(prefix = "qingyuan.charge-station") +public class StationProperties { + + private Long relationId; + + private List operators; + + @Data + public static class Operator { + private String id; + private String name; + } + + public String getOperatorNameById(String id) { + Operator operator = getOperatorById(id); + return Objects.isNull(operator) ? null : operator.getName(); + } + + private Operator getOperatorById(String id) { + return operators.stream() + .filter(e -> Objects.equals(id, e.getId())) + .findFirst() + .orElse(null); + } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/controller/ChargeOrderHeadController.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/controller/ChargeOrderHeadController.java new file mode 100644 index 0000000..943f188 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/controller/ChargeOrderHeadController.java @@ -0,0 +1,65 @@ +package com.thing.qingyuan.chargeStation.controller; + +import com.thing.common.core.constants.Constant; +import com.thing.common.core.web.response.PageData; +import com.thing.common.core.web.response.Result; +import com.thing.qingyuan.chargeStation.dto.ChargeOrderHeadDTO; +import com.thing.qingyuan.chargeStation.service.ChargeOrderHeadService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.*; + +import java.util.Map; + +/** +* 充电桩订单头 +* +* @author system system@lrd.com +* @since 5.1 2024-01-23 +*/ +@RestController +@RequestMapping("chargeStation/order/head") +@Tag(name="充电桩订单头") +@RequiredArgsConstructor +public class ChargeOrderHeadController { + + private final ChargeOrderHeadService chargeOrderHeadService; + + @GetMapping("page") + @Operation(summary="分页") + @Parameters({ + @Parameter(name = Constant.PAGE, description = "当前页码,从1开始", required = true) , + @Parameter(name = Constant.LIMIT, description = "每页显示记录数", required = true) , + @Parameter(name = Constant.ORDER_FIELD, description = "排序字段") , + @Parameter(name = Constant.ORDER, description = "排序方式,可选值(asc、desc)"), + @Parameter(name = Constant.BEGIN_TIME, description = "开始时间"), + @Parameter(name = Constant.END_TIME, description = "结束时间"), + @Parameter(name = "startChargeSeq", description = "订单号"), + @Parameter(name = "stationId", description = "充电站编码"), + @Parameter(name = "equipmentId", description = "充电桩编码"), + @Parameter(name = "connectorId", description = "充电枪编码"), + }) + public Result> page(@Parameter(hidden = true) @RequestParam Map params){ + String order = StringUtils.isBlank((String) params.get(Constant.ORDER)) ? "desc" : (String) params.get(Constant.ORDER); + String orderField = StringUtils.isBlank((String) params.get(Constant.ORDER_FIELD)) ? "start_time" : (String) params.get(Constant.ORDER_FIELD); + params.put(Constant.ORDER, order); + params.put(Constant.ORDER_FIELD, orderField); + PageData page = chargeOrderHeadService.handlePage(params); + return new Result>().ok(page); + } + + @GetMapping("{startChargeSeq}") + @Operation(summary="充电详情") + @Parameters({ + @Parameter(name = "startChargeSeq", description = "订单号"), + }) + public Result get(@PathVariable("startChargeSeq") String startChargeSeq){ + ChargeOrderHeadDTO data = chargeOrderHeadService.getDetails(startChargeSeq); + return new Result().ok(data); + } + +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/controller/ChargeStatisticController.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/controller/ChargeStatisticController.java new file mode 100644 index 0000000..51f27a8 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/controller/ChargeStatisticController.java @@ -0,0 +1,44 @@ +package com.thing.qingyuan.chargeStation.controller; + +import com.thing.qingyuan.chargeStation.dto.ChargeStatisticReportResp; +import com.thing.qingyuan.chargeStation.dto.ChargeStatisticRequest; +import com.thing.qingyuan.chargeStation.service.ChargeStatisticService; +import com.thing.common.core.web.response.Result; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +/** + * 充电统计 + * + * @author system system@lrd.com + * @since 5.1 2024-01-23 + */ +@RestController +@RequestMapping("chargeStation/statistic") +@Tag(name = "充电统计") +@RequiredArgsConstructor +public class ChargeStatisticController { + + private final ChargeStatisticService service; + + @PostMapping("report") + @Operation(summary = "充电统计报表") + public Result> page(@RequestBody ChargeStatisticRequest request) { + List data = service.getReport(request); + return new Result>().ok(data); + } + + @PostMapping("report/export") + @Operation(summary="充电统计报表导出") + public void export(@RequestBody ChargeStatisticRequest request, HttpServletResponse response) { + service.export(request, response); + } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/controller/StationInfoController.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/controller/StationInfoController.java new file mode 100644 index 0000000..976b412 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/controller/StationInfoController.java @@ -0,0 +1,91 @@ +package com.thing.qingyuan.chargeStation.controller; + +import cn.hutool.core.map.MapUtil; +import com.thing.qingyuan.chargeStation.dto.IdNameDTO; +import com.thing.qingyuan.chargeStation.dto.StationDeviceDetail; +import com.thing.qingyuan.chargeStation.dto.StationInfoDTO; +import com.thing.qingyuan.chargeStation.dto.StationSimpleInfo; +import com.thing.qingyuan.chargeStation.service.StationInfoService; +import com.thing.common.core.constants.Constant; +import com.thing.common.core.web.response.PageData; +import com.thing.common.core.web.response.Result; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; +import java.util.Map; + +/** + * 充电站信息 + * + * @author ssy 2337720667@qq.com + * @since 3.0 2024-01-23 + */ +@RestController +@RequestMapping("chargeStation/station") +@Tag(name = "充电站信息") +@RequiredArgsConstructor +public class StationInfoController { + + private final StationInfoService stationInfoService; + + @GetMapping("page") + @Operation(summary = "分页") + @Parameters({ + @Parameter(name = Constant.PAGE, description = "当前页码,从1开始", required = true), + @Parameter(name = Constant.LIMIT, description = "每页显示记录数", required = true), + @Parameter(name = Constant.ORDER_FIELD, description = "排序字段"), + @Parameter(name = Constant.ORDER, description = "排序方式,可选值(asc、desc)"), + @Parameter(name = "areaCode", description = "区域编码"), + @Parameter(name = "operatorId", description = "运营商id"), + @Parameter(name = "keyword", description = "充电站名称关键字"), + }) + public Result> page(@Parameter(hidden = true) @RequestParam Map params) { + params.putIfAbsent(Constant.ORDER_FIELD, "station_id"); + PageData page = stationInfoService.handlePage(params); + return new Result>().ok(page); + } + + @GetMapping("simple/list") + @Operation(summary="简要信息列表") + public Result> simpleList(){ + List list = stationInfoService.simpleList(); + return new Result>().ok(list); + } + + @GetMapping("pile/or/gun/idName") + @Operation(summary="充电桩或充电枪的id-name列表") + @Parameters({ + @Parameter(name = "type", description = "pile:充电桩, gun:充电枪"), + @Parameter(name = "pid", description = "上级id"), + }) + public Result> getIdNameList(@Parameter(hidden = true) @RequestParam Map params) { + List list = stationInfoService.getIdNameList(params); + return new Result>().ok(list); + } + + @GetMapping("details") + @Operation(summary = "信息") + @Parameters({ + @Parameter(name = "stationId", description = "充电站编码(id)"), + }) + public Result getDetails(@Parameter(hidden = true) @RequestParam Map params) { + String stationId = MapUtil.getStr(params, "stationId"); + StationDeviceDetail data = stationInfoService.getDetails(stationId); + return new Result().ok(data); + } + + @GetMapping("generate/thing/config") + @Operation(summary = "一键生成物模型、物实体、物指标、物关系、数据源配置") + public Result get() { + stationInfoService.generateThingConfig(); + return new Result<>(); + } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/ChargeOrderDetailsDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/ChargeOrderDetailsDTO.java new file mode 100644 index 0000000..e147ffc --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/ChargeOrderDetailsDTO.java @@ -0,0 +1,84 @@ +package com.thing.qingyuan.chargeStation.dto; + +import com.thing.common.core.utils.DateTimeUtils; +import com.thing.common.data.proto.QueueProto; +import com.thing.common.data.proto.QueueProto.DataProto; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +/** +* 充电桩订单明细 +* +* @author system system@lrd.com +* @since 5.1 2024-01-23 +*/ +@Data +@Schema(description = "充电桩订单明细") +public class ChargeOrderDetailsDTO implements Serializable { + @Serial + private static final long serialVersionUID = 1L; + + private Long id; + @Schema(description = "充电订单号;运营商ID+唯一编号") + private String startChargeSeq; + @Schema(description = "充电设备接口编码") + private String connectorId; + @Schema(description = "结束时间;格式,yyyy-MM-dd HH: mm: ss") + private String endTime; + @Schema(description = "开始时间") + private String startTime; + @Schema(description = "A相电流") + private BigDecimal currentA; + @Schema(description = "B相电流") + private BigDecimal currentB; + @Schema(description = "C相电流") + private BigDecimal currentC; + @Schema(description = "A相电压") + private BigDecimal voltageA; + @Schema(description = "B相电压") + private BigDecimal voltageB; + @Schema(description = "C相电压") + private BigDecimal voltageC; + @Schema(description = "电池剩余电量,单位:%") + private BigDecimal soc; + @Schema(description = "时段充电量,单位:度(kwh)") + private BigDecimal totalPower; + + public List toProtoDataList() { + List dataProtoList = new ArrayList<>(); + Long ts = DateTimeUtils.convertTimeToLong(endTime); + dataProtoList.add(toProtoData(connectorId, "A8", currentA, ts)); + dataProtoList.add(toProtoData(connectorId, "A9", currentB, ts)); + dataProtoList.add(toProtoData(connectorId, "A10", currentC, ts)); + dataProtoList.add(toProtoData(connectorId, "A1", voltageA, ts)); + dataProtoList.add(toProtoData(connectorId, "A2", voltageB, ts)); + dataProtoList.add(toProtoData(connectorId, "A3", voltageC, ts)); + dataProtoList.add(toProtoData(connectorId, "A203", soc, ts)); + dataProtoList.add(toProtoData(connectorId, "A229", totalPower, ts)); + return dataProtoList.stream().filter(Objects::nonNull).collect(Collectors.toList()); + } + + private DataProto toProtoData(String thingCode, String key, BigDecimal val, Long ts) { + if(Objects.isNull(val)){ + return null; + } + return DataProto.newBuilder() + .setTskvProto( + QueueProto.TsKvProto.newBuilder() + .setThingCode(thingCode) + .setKey(key) + .setVal(val.toPlainString()) + .setTs(ts) + .build()) + .build(); + } + +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/ChargeOrderHeadDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/ChargeOrderHeadDTO.java new file mode 100644 index 0000000..e396a48 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/ChargeOrderHeadDTO.java @@ -0,0 +1,83 @@ +package com.thing.qingyuan.chargeStation.dto; + +import com.thing.qingyuan.chargeStation.entity.ChargeOrderDetailsEntity; +import com.thing.common.core.utils.DateTimeUtils; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.List; +import java.util.Objects; + +/** +* 充电桩订单头 +* +* @author system system@lrd.com +* @since 5.1 2024-01-23 +*/ +@Data +@Accessors(chain = true) +@Schema(description = "充电桩订单头") +public class ChargeOrderHeadDTO implements Serializable { + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "充电订单号;运营商ID+唯一编号") + private String startChargeSeq; + + @Schema(description = "充电站id") + private String stationId; + @Schema(description = "充电站名称") + private String stationName; + @Schema(description = "充电桩id") + private String equipmentId; + @Schema(description = "充电桩名称") + private String equipmentName; + @Schema(description = "充电枪id") + private String connectorId; + @Schema(description = "充电枪名称") + private String connectorName; + + @Schema(description = "开始充电时间;格式,yyyy-MM-dd HH: mm: ss") + private String startTime; + @Schema(description = "结束充电时间;格式,yyyy-MM-dd HH: mm: ss") + private String endTime; + + @Schema(description = "累计充电量;单位:度, 小数点后2位") + private BigDecimal totalPower; + @Schema(description = "总电费;单位:元, 小数点后2位") + private BigDecimal elecMoney; + @Schema(description = "总服务费;单位:元, 小数点后2位") + private BigDecimal seviceMoney; + @Schema(description = "累计总金额;单位:元, 小数点后2位") + private BigDecimal totalMoney; + + @Schema(description = "充电结束原因;0: 用户手动停止充电; 1:客户归属地运营商平台停止充电; 2: BMS停止充电; 3: 充电机设备故障; 4:连接器断开; 5~99: 自定义") + private Integer stopReason; + @Schema(description = "时段数N;范围:0~32") + private Integer sumPeriod; + + @Schema(description = "充电订单状态;1:启动中; 2:充电中; 3:停止中; 4:已结束; 5:未知") + private Integer startChargeSeqStat; + + + @Schema(description = "订单详情: 电池电量(%)、A相电流、B相电流、C相电流 ...") + private List details; + + public Long getDuration(){ + return Objects.isNull(endTime) + ? System.currentTimeMillis() - getStartTs() + : getEndTs() - getStartTs(); + } + + public Long getStartTs(){ + return DateTimeUtils.convertTimeToLong(startTime); + } + + public Long getEndTs(){ + return DateTimeUtils.convertTimeToLong(endTime); + } +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/ChargeStatisticReportResp.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/ChargeStatisticReportResp.java new file mode 100644 index 0000000..a4f2867 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/ChargeStatisticReportResp.java @@ -0,0 +1,84 @@ +package com.thing.qingyuan.chargeStation.dto; + +import com.thing.common.core.utils.DateTimeUtils; +import com.thing.common.data.tskv.TsKvDTO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; +import org.springframework.util.CollectionUtils; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.TreeMap; + +/** + * @author SiYang + * @date 2024/01/31 17:31 + * @description 充电统计报表数据 + */ +@Data +@Accessors(chain = true) +public class ChargeStatisticReportResp { + @Schema(description = "物id") + private Long thingId; + + @Schema(description = "物名称") + private String thingName; + + @Schema(description = "物编码") + private String thingCode; + + @Schema(description = "属性名称") + private String attrName; + + @Schema(description = "属性编码") + private String attrCode; + + @Schema(description = "属性单位") + private String unit; + + @Schema(description = "时间类型") + private String timeType; + + @Schema(description = "合计数据") + private BigDecimal total; + + @Schema(description = "数据") + private Map data; + + public ChargeStatisticReportResp initData(List timeList) { + if (Objects.isNull(data)) { + data = new TreeMap<>(); + } + timeList.forEach(t -> data.put(DateTimeUtils.parse(t), null)); + return this; + } + + public ChargeStatisticReportResp fillData(List tskvList) { + if(CollectionUtils.isEmpty(tskvList)){ + return this; + } + if (Objects.isNull(data)) { + data = new TreeMap<>(); + } + tskvList.forEach(tskv -> data.put(tskv.getTs(), tskv.getVal())); + return this; + } + + public ChargeStatisticReportResp calculateTotal() { + BigDecimal total = + data.values().stream() + .filter(Objects::nonNull) + .map( + dataStr -> + BigDecimal.valueOf(Double.parseDouble(dataStr)) + .setScale(2, RoundingMode.HALF_UP)) + .reduce(BigDecimal::add) + .orElse(BigDecimal.ZERO); + return this.setTotal(total); + } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/ChargeStatisticRequest.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/ChargeStatisticRequest.java new file mode 100644 index 0000000..a66a5ed --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/ChargeStatisticRequest.java @@ -0,0 +1,94 @@ +package com.thing.qingyuan.chargeStation.dto; + +import com.thing.common.core.exception.SysException; +import com.thing.common.core.utils.DateTimeUtils; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +/** + * @author SiYang + * @date 2024/01/31 17:16 + * @description 充电统计请求 + */ +@Data +@Schema(description = "充电统计请求参数") +public class ChargeStatisticRequest { + @Schema(description = "关系id") + private Long rootId; + + @Schema(description = "顶级物id列表") + private List rootThingIds; + + @Schema(description = "物id列表") + private List thingIds; + + @Schema(description = "报表类型=> 充电量: 1; 充电时长: 2; 充电次数: 3") + private Integer reportType; + + @Schema(description = "时间类型:day ,month, year, any") + private String timeType; + + @Schema(description = "开始时间") + private String beginTime; + + @Schema(description = "结束时间") + private String endTime; + + public String getAttrType() { + return switch (timeType) { + case "day" -> "hh"; + case "month", "any" -> "dd"; + case "year" -> "mm"; + default -> throw new SysException( + "unSupport timeType, pls choose from [month, year, any]"); + }; + } + + /** 充电量: A29; 充电时长: A201; 充电次数: A202 */ + public String getBaseAttrCode(){ + return switch (reportType) { + case 1 -> "A29"; + case 2 -> "A201"; + case 3 -> "A202"; + default -> throw new SysException( + "unSupport reportType, pls choose from [1, 2, 3]"); + }; + } + + public String getAttrCode() { + return getBaseAttrCode() + getAttrType(); + } + + public Long getStartTs() { + return DateTimeUtils.convertTimeToLong(beginTime); + } + + public Long getEndTs() { + return DateTimeUtils.convertTimeToLong(endTime); + } + + public List generateAllDateTime() { + List dateTimeList = new ArrayList<>(); + LocalDateTime begin = getBeginDateTime().withHour(0).withMinute(0).withSecond(0).withNano(0); + LocalDateTime end = getEndDateTime(); + while (begin.isBefore(end) || begin.isEqual(end)) { + dateTimeList.add(begin); + begin = "year".equals(timeType) ? begin.plusMonths(1) : begin.plusDays(1); + } + return dateTimeList; + } + + private LocalDateTime getBeginDateTime() { + return DateTimeUtils.parseDateTime(beginTime); + } + + private LocalDateTime getEndDateTime() { + LocalDateTime dateTime = DateTimeUtils.parseDateTime(endTime); + LocalDateTime currentDateTime = LocalDateTime.now(); + return dateTime.isBefore(currentDateTime) ? dateTime : currentDateTime; + } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/ConnectorInfoDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/ConnectorInfoDTO.java new file mode 100644 index 0000000..f670f56 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/ConnectorInfoDTO.java @@ -0,0 +1,64 @@ +package com.thing.qingyuan.chargeStation.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 充电枪 + * + * @author system system@lrd.com + * @since 5.1 2024-01-29 + */ +@Data +@Schema(description = "充电枪") +public class ConnectorInfoDTO implements Serializable { + @Serial private static final long serialVersionUID = 1L; + + @Schema(description = "充电设备接口编码") + private String connectorId; + + private String couplerType; + + @Schema(description = "额定电压下限") + private Integer voltageLowerLimits; + + private String qrCode; + + @Schema( + description = + "充电设备接口类型内唯 1:家用插座(模式2);2: 交流接口插座(模式3, 连接方式B);3:交流接口插头(带枪线,模式3,连接方式C);4:直流5: 无线充电座; 6:其他") + private Integer connectorType; + + @Schema(description = "额定电压上限") + private Integer voltageUpperLimits; + + @Schema(description = "家标准1: 2011: 2: 2015") + private Integer nationalStandard; + + @Schema(description = "充电设备接口名称") + private String connectorName; + + private Integer ratedCurrent; + + @Schema(description = "额定电流") + private BigDecimal current; + + @Schema(description = "额定功率") + private BigDecimal power; + + @Schema(description = "充电桩Id") + private String equipmentId; + + @Schema(description = "充电设备接口状态 0:离网;1:空闲;2:占用(未充电);3:占用(充电中); 4:占用(预约锁定); 255:故障") + private Integer status; + + @Schema(description = "地锁状态 0: 未知;10: 已解锁;50: 已上锁") + private Integer lockStatus; + + @Schema(description = "车位状态 0:未知;10:空闲;50:占用") + private Integer parkStatus; +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/ConnectorStatusInfo.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/ConnectorStatusInfo.java new file mode 100644 index 0000000..7a187ad --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/ConnectorStatusInfo.java @@ -0,0 +1,18 @@ +package com.thing.qingyuan.chargeStation.dto; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + + +@Data +@Schema(description = "充电枪统计信息") +public class ConnectorStatusInfo { + + @Schema(description = "状态") + private String status; + @Schema(description = "数量") + private Integer num; + + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/EquipmentInfoDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/EquipmentInfoDTO.java new file mode 100644 index 0000000..9130099 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/EquipmentInfoDTO.java @@ -0,0 +1,64 @@ +package com.thing.qingyuan.chargeStation.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Objects; + +/** +* 充电桩 +* +* @author system system@lrd.com +* @since 5.1 2024-01-29 +*/ +@Data +@Accessors(chain = true) +@Schema(description = "充电桩") +public class EquipmentInfoDTO implements Serializable { + @Serial + private static final long serialVersionUID = 1L; + + private String equipmentApplication; + private Integer equipmentStatus; + @Schema(description = "设备生产商名称") + private String manufacturerName; + private String openDate; + private BigDecimal equipmentPower; + @Schema(description = "设备编码") + private String equipmentId; + @Schema(description = "设备生产商组织机 构代码") + private String manufacturerId; + private Integer nationalStandard; + @Schema(description = "充电设备经度") + private BigDecimal equipmentLng; + private String openForBusinessDate; + @Schema(description = "充电枪数量") + private Integer gunNum; + @Schema(description = "设备类型1:直流设备; 2:交流设备;3:交直流一体设备;4:无线设备;5:其他") + private Integer equipmentType; + @Schema(description = "充电设备纬度") + private BigDecimal equipmentLat; + private BigDecimal voltage; + private Integer newNationalStandard; + @Schema(description = "充电设备名称") + private String equipmentName; + @Schema(description = "设备生产日期") + private String productionDate; + @Schema(description = "设备型号") + private String equipmentModel; + private BigDecimal current; + @Schema(description = "充电设备总功率单位:kW") + private BigDecimal power; + private String stationId; + + public EquipmentInfoDTO add(EquipmentInfoDTO another) { + if (Objects.isNull(another)) return this; + return setGunNum(gunNum + another.getGunNum()) + .setEquipmentPower(equipmentPower.add(another.getEquipmentPower())) + .setPower(power.add(another.getPower())); + } +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/IdNameDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/IdNameDTO.java new file mode 100644 index 0000000..6b676a6 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/IdNameDTO.java @@ -0,0 +1,11 @@ +package com.thing.qingyuan.chargeStation.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class IdNameDTO { + private String id; + private String name; +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/SimpleThingRelationDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/SimpleThingRelationDTO.java new file mode 100644 index 0000000..0e67a9e --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/SimpleThingRelationDTO.java @@ -0,0 +1,17 @@ +package com.thing.qingyuan.chargeStation.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; + +/** + * @author SiYang + * @date 2024/01/30 16:14 + * @description 极简物关系 + */ +@Data +@AllArgsConstructor +public class SimpleThingRelationDTO { + private String fromCode; + private String toCode; + private String toName; +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/StationDeviceDetail.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/StationDeviceDetail.java new file mode 100644 index 0000000..f6a287c --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/StationDeviceDetail.java @@ -0,0 +1,26 @@ +package com.thing.qingyuan.chargeStation.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @author SiYang + * @date 2024/01/29 13:29 + * @description 充电站的设备详情,包含充电桩、充电枪 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class StationDeviceDetail { + /** 充电站id */ + private String stationId; + + /** 充电桩列表 */ + private List pileList; + + /** 充电枪列表 */ + private List gunList; +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/StationInfoDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/StationInfoDTO.java new file mode 100644 index 0000000..2a464c0 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/StationInfoDTO.java @@ -0,0 +1,86 @@ +package com.thing.qingyuan.chargeStation.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; + +/** +* 充电站信息 +* +* @author ssy 2337720667@qq.com +* @since 3.0 2024-01-23 +*/ +@Data +@Schema(description = "充电站信息") +public class StationInfoDTO implements Serializable { + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "填写内容为参照GB/T2260 2007 ") + private String areaCode; + @Schema(description = "详细地址 ") + private String address; + @Schema(description = "能够联系场站工作人员进行协助的联系电话") + private String stationTel; + @Schema(description = "平台服务电话, 例如400的电话") + private String serviceTel; + @Schema(description = "1:公共; 50:个人;100:公交(专用);101:环卫(专用);102:物流(专用);103:出租车(专用);255:其他") + private Integer stationType; + @Schema(description = ":未知; 1:建设中:5:关闭下线;6:维护中;50:正常使用") + private Integer stationStatus; + @Schema(description = "可停放进行充电的车位总数,默认: 0未知") + private Integer parkNums; + @Schema(description = "GCJ-02坐标系") + private BigDecimal stationLng; + @Schema(description = "GCJ-02坐标系") + private BigDecimal stationLat; + @Schema(description = "描述性文字, 用千引导车主找到充电车位") + private String siteGuide; + @Schema(description = "1:居民区; 2:公共机构;3:企事业单位;4:写字楼;5:工业园区;6:交通枢纽;7:大型文体设施;8:城市绿地;9:大型建筑配建停车场;10:路边停车位;11:城际高速服务区;255:其他") + private Integer construction; + @Schema(description = "描述该站点接受的车大小以及类型, 如大巳、 物流车、 私家乘用车、 出租车等") + private String matchCars; + @Schema(description = "车位楼层以及数擢信息") + private String parkInfo; + @Schema(description = "营业时间描述") + private String busineHours; + @Schema(description = "充电费描述") + private String electricityFee; + @Schema(description = "服务费率描述") + private String serviceFee; + @Schema(description = "停车费率描述") + private String parkFee; + @Schema(description = "支付方式:刷卡、线上、现金。其中电子钱包类卡为刷卡,身份鉴权卡、微信/支付宝、APP为线上 ") + private String payment; + @Schema(description = "充电设备是否需要提前预约后才能使用。0为不支持预约; 1 为支持预约。不填默认为0") + private Integer supportOrder; + @Schema(description = "其他备注信息") + private String remark; + @Schema(description = "充电站Id 接口文档没有但是接口有") + private String stationId; + @Schema(description = "运营商id") + private String operatorId; + @Schema(description = "运营商名称") + private String operatorName; + @Schema(description = "设备所有者id") + private String equipmentOwnerId; + @Schema(description = "充电站名称") + private String stationName; + @Schema(description = "国家") + private String countryCode; + @Schema(description = "省") + private String province; + @Schema(description = "市") + private String city; + @Schema(description = "区") + private String area; + + @Schema(description = "装机功率: sum(充电桩功率)") + private Double totalPilePower; + @Schema(description = "调节功率") + private Double regulatingPower; + +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/StationOrderAgg.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/StationOrderAgg.java new file mode 100644 index 0000000..6b4582f --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/StationOrderAgg.java @@ -0,0 +1,81 @@ +package com.thing.qingyuan.chargeStation.dto; + +import com.thing.common.data.proto.QueueProto; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * @author SiYang + * @date 2024/01/23 15:54 + * @description 充电站订单汇总数据 + * 充电量: A29 totalPower + * 充电时长: A201 endTime - startTime + * 充电次数: A202 count(order) + * 充电金额: A204 totalMoney + */ +@Data +@Accessors(chain = true) +@NoArgsConstructor +public class StationOrderAgg { + /** 设备编号: 站(stationId), 桩(equipmentId), 枪(connectorId) */ + private String deviceCode; + + /** 汇总充电金额:A204xx */ + private BigDecimal fee = BigDecimal.ZERO; + + /** 汇总充电电量:A29xx */ + private BigDecimal energy = BigDecimal.ZERO; + + /** 汇总充电次数:A202xx */ + private Integer count = 0; + + /** 汇总充电时长:A201xx */ + private Long duration = 0L; + + public StationOrderAgg(String deviceCode) { + this.deviceCode = deviceCode; + } + + public StationOrderAgg add(ChargeOrderHeadDTO order) { + if (Objects.isNull(order)) return this; + return setFee(fee.add(order.getTotalMoney())) + .setEnergy(energy.add(order.getTotalPower())) + .setCount(count + 1) + .setDuration(duration + order.getDuration()); + } + + public StationOrderAgg add(StationOrderAgg another) { + if (Objects.isNull(another)) return this; + return setFee(fee.add(another.getFee())) + .setEnergy(energy.add(another.getEnergy())) + .setCount(count + another.getCount()) + .setDuration(duration + another.getDuration()); + } + + public List toProtoData(Long ts, String suffix) { + List list = new ArrayList<>(); + list.add(toProtoData("A204" + suffix, fee.toPlainString(), ts)); + list.add(toProtoData("A29" + suffix, energy.toPlainString(), ts)); + list.add(toProtoData("A202" + suffix, count.toString(), ts)); + list.add(toProtoData("A201" + suffix, duration.toString(), ts)); + return list; + } + + private QueueProto.DataProto toProtoData(String key, String val, Long ts) { + return QueueProto.DataProto.newBuilder() + .setTskvProto( + QueueProto.TsKvProto.newBuilder() + .setThingCode(deviceCode) + .setKey(key) + .setVal(val) + .setTs(ts) + .build()) + .build(); + } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/StationSimpleDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/StationSimpleDTO.java new file mode 100644 index 0000000..3485d52 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/StationSimpleDTO.java @@ -0,0 +1,43 @@ +package com.thing.qingyuan.chargeStation.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 充电站信息 + * + * @author ssy 2337720667@qq.com + * @since 3.0 2024-01-23 + */ +@Data +@Schema(description = "充电站简要信息") +public class StationSimpleDTO { + @Schema(description = "充电站id") + private String stationId; + + @Schema(description = "充电站名称") + private String stationName; + + @Schema(description = "经度") + private BigDecimal stationLng; + + @Schema(description = "纬度") + private BigDecimal stationLat; + + @Schema(description = "充电枪总数") + private Integer totalGunCount; + + @Schema(description = "离线枪数量") + private Integer offLineCount; + + @Schema(description = "空闲枪数量") + private Integer freeCount; + + @Schema(description = "正在充电的枪数量") + private Integer inChargingCount; + + @Schema(description = "故障枪数量") + private Integer errorCount; +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/StationSimpleInfo.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/StationSimpleInfo.java new file mode 100644 index 0000000..cede21c --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/dto/StationSimpleInfo.java @@ -0,0 +1,28 @@ +package com.thing.qingyuan.chargeStation.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * @author SiYang + * @date 2024/01/29 13:54 + * @description 充电站简化信息:用于下拉查询 + */ +@Data +@Accessors(chain = true) +@Schema(description = "充电站简化信息") +public class StationSimpleInfo { + @Schema(description = "充电站id ") + private String stationId; + @Schema(description = "充电站名称 ") + private String stationName; + @Schema(description = "地区编码 ") + private String areaCode; + @Schema(description = "地区名称 ") + private String areaName; + @Schema(description = "运营商id ") + private String operatorId; + @Schema(description = "运营商名称 ") + private String operatorName; +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/entity/ChargeOrderDetailsEntity.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/entity/ChargeOrderDetailsEntity.java new file mode 100644 index 0000000..567e1b4 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/entity/ChargeOrderDetailsEntity.java @@ -0,0 +1,81 @@ +package com.thing.qingyuan.chargeStation.entity; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.Table; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 充电桩订单明细 + * + * @author system system@lrd.com + * @since 5.1 2024-01-23 + */ +@Data +@EqualsAndHashCode(callSuper=false) +@Table("charge_details") +public class ChargeOrderDetailsEntity implements Serializable { + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @Id + private Long id; + + /** + * 充电订单号;运营商ID+唯一编号 + * @see ChargeOrderHeadEntity#startChargeSeq + */ + private String startChargeSeq; + /** + * 充电设备接口编码 + */ + private String connectorId; + /** + * 结束时间;格式,yyyy-MM-dd HH: mm: ss + */ + private String endTime; + /** + * 开始时间 + */ + private String startTime; + /** + * A相电流 + */ + private BigDecimal currentA; + /** + * B相电流 + */ + private BigDecimal currentB; + /** + * C相电流 + */ + private BigDecimal currentC; + /** + * A相电压 + */ + private BigDecimal voltageA; + /** + * B相电压 + */ + private BigDecimal voltageB; + /** + * C相电压 + */ + private BigDecimal voltageC; + /** + * 电池剩余电量,单位:% + */ + private BigDecimal soc; + /** + * 时段充电量,单位:度(kwh) + */ + private BigDecimal totalPower; + +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/entity/ChargeOrderHeadEntity.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/entity/ChargeOrderHeadEntity.java new file mode 100644 index 0000000..0e7c898 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/entity/ChargeOrderHeadEntity.java @@ -0,0 +1,70 @@ +package com.thing.qingyuan.chargeStation.entity; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.Table; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 充电桩订单头 + * + * @author system system@lrd.com + * @since 5.1 2024-01-23 + */ +@Data +@EqualsAndHashCode(callSuper=false) +@Table("notification_charge_order_info") +public class ChargeOrderHeadEntity implements Serializable { + @Serial + private static final long serialVersionUID = 1L; + + /** + * 充电订单号;运营商ID+唯一编号 + */ + @Id + private String startChargeSeq; + /** + * 充电设备接口编码 + */ + private String connectorId; + /** + * 开始充电时间;格式,yyyy-MM-dd HH: mm: ss + */ + private String startTime; + /** + * 结束充电时间;格式,yyyy-MM-dd HH: mm: ss + */ + private String endTime; + /** + * 累计充电量;单位:度, 小数点后2位 + */ + private BigDecimal totalPower; + /** + * 总电费;单位:元, 小数点后2位 + */ + private BigDecimal elecMoney; + /** + * 总服务费;单位:元, 小数点后2位 + */ + private BigDecimal seviceMoney; + /** + * 累计总金额;单位:元, 小数点后2位 + */ + private BigDecimal totalMoney; + /** + * 充电结束原因;0: 用户手动停止充电; 1:客户归属地运营商平台停止充电; 2: BMS停止充电; 3: 充电机设备故障; 4:连接器断开; 5~99: 自定义 + */ + private Integer stopReason; + /** + * 时段数N;范围:0~32 + */ + private Integer sumPeriod; + /** + * 充电订单状态;1:启动中; 2:充电中; 3:停止中; 4:已结束; 5:未知 + */ + private Integer startChargeSeqStat; +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/entity/ConnectorInfoEntity.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/entity/ConnectorInfoEntity.java new file mode 100644 index 0000000..ea0bc30 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/entity/ConnectorInfoEntity.java @@ -0,0 +1,66 @@ +package com.thing.qingyuan.chargeStation.entity; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.Table; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 充电枪 + * + * @author system system@lrd.com + * @since 5.1 2024-01-29 + */ +@Data +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = false) +@Table("connector_info") +public class ConnectorInfoEntity implements Serializable { + @Serial private static final long serialVersionUID = 1L; + + /** 充电设备接口编码 */ + @Id private String connectorId; + + private String couplerType; + + /** 额定电压下限 */ + private Integer voltageLowerLimits; + + private String qrCode; + + /** 充电设备接口类型内唯 1:家用插座(模式2);2: 交流接口插座(模式3, 连接方式B);3:交流接口插头(带枪线,模式3,连接方式C);4:直流5: 无线充电座; 6:其他 */ + private Integer connectorType; + + /** 额定电压上限 */ + private Integer voltageUpperLimits; + + /** 家标准1: 2011: 2: 2015 */ + private Integer nationalStandard; + + /** 充电设备接口名称 */ + private String connectorName; + + private Integer ratedCurrent; + + /** 额定电流 */ + private BigDecimal current; + + /** 额定功率 */ + private BigDecimal power; + + private String equipmentId; + + /** 充电设备接口状态 0:离网;1:空闲;2:占用(未充电);3:占用(充电中); 4:占用(预约锁定); 255:故障 */ + private Integer status; + + /** 地锁状态 0: 未知;10: 已解锁;50: 已上锁 */ + private Integer lockStatus; + + /** 车位状态 0:未知;10:空闲;50:占用 */ + private Integer parkStatus; +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/entity/EquipmentInfoEntity.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/entity/EquipmentInfoEntity.java new file mode 100644 index 0000000..37d8570 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/entity/EquipmentInfoEntity.java @@ -0,0 +1,80 @@ +package com.thing.qingyuan.chargeStation.entity; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.Table; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 充电桩 + * + * @author system system@lrd.com + * @since 5.1 2024-01-29 + */ +@Data +@EqualsAndHashCode(callSuper=false) +@Table("equipment_info") +public class EquipmentInfoEntity implements Serializable { + @Serial + private static final long serialVersionUID = 1L; + + /** + * 设备编码 + */ + @Id + private String equipmentId; + private String equipmentApplication; + private Integer equipmentStatus; + /** + * 设备生产商名称 + */ + private String manufacturerName; + private String openDate; + private BigDecimal equipmentPower; + /** + * 设备生产商组织机 构代码 + */ + private String manufacturerId; + private Integer nationalStandard; + /** + * 充电设备经度 + */ + private BigDecimal equipmentLng; + private String openForBusinessDate; + /** + * 充电枪数量 + */ + private Integer gunNum; + /** + * 设备类型1:直流设备;2:交流设备;3:交直流一体设备;4:无线设备;5:其他 + */ + private Integer equipmentType; + /** + * 充电设备纬度 + */ + private BigDecimal equipmentLat; + private BigDecimal voltage; + private Integer newNationalStandard; + /** + * 充电设备名称 + */ + private String equipmentName; + /** + * 设备生产日期 + */ + private String productionDate; + /** + * 设备型号 + */ + private String equipmentModel; + private BigDecimal current; + /** + * 充电设备总功率单位:kW + */ + private BigDecimal power; + private String stationId; +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/entity/StationInfoEntity.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/entity/StationInfoEntity.java new file mode 100644 index 0000000..d2a9d94 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/entity/StationInfoEntity.java @@ -0,0 +1,105 @@ +package com.thing.qingyuan.chargeStation.entity; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.Table; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 充电站信息 + * + * @author ssy 2337720667@qq.com + * @since 3.0 2024-01-23 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Table("station_info") +public class StationInfoEntity implements Serializable { + @Serial private static final long serialVersionUID = 1L; + + /** 填写内容为参照GB/T2260 2007 */ + private String areaCode; + + /** 详细地址 */ + private String address; + + /** 能够联系场站工作人员进行协助的联系电话 */ + private String stationTel; + + /** 平台服务电话, 例如400的电话 */ + private String serviceTel; + + /** 1:公共;50:个人;100:公交(专用);101:环卫(专用);102:物流(专用);103:出租车(专用);255:其他 */ + private Integer stationType; + + /** :未知;1:建设中:5:关闭下线;6:维护中;50:正常使用 */ + private Integer stationStatus; + + /** 可停放进行充电的车位总数,默认: 0未知 */ + private Integer parkNums; + + /** GCJ-02坐标系 */ + private BigDecimal stationLng; + + /** GCJ-02坐标系 */ + private BigDecimal stationLat; + + /** 描述性文字, 用千引导车主找到充电车位 */ + private String siteGuide; + + /** + * 1:居民区;2:公共机构;3:企事业单位;4:写字楼;5:工业园区;6:交通枢纽;7:大型文体设施;8:城市绿地;9:大型建筑配建停车场;10:路边停车位;11:城际高速服务区;255:其他 + */ + private Integer construction; + + /** 描述该站点接受的车大小以及类型, 如大巳、 物流车、 私家乘用车、 出租车等 */ + private String matchCars; + + /** 车位楼层以及数擢信息 */ + private String parkInfo; + + /** 营业时间描述 */ + private String busineHours; + + /** 充电费描述 */ + private String electricityFee; + + /** 服务费率描述 */ + private String serviceFee; + + /** 停车费率描述 */ + private String parkFee; + + /** 支付方式:刷卡、线上、现金。其中电子钱包类卡为刷卡,身份鉴权卡、微信/支付宝、APP为线上 */ + private String payment; + + /** 充电设备是否需要提前预约后才能使用。0为不支持预约; 1 为支持预约。不填默认为0 */ + private Integer supportOrder; + + /** 其他备注信息 */ + private String remark; + + /** 充电站Id 接口文档没有但是接口有 */ + @Id + private String stationId; + + /** 运营商id */ + private String operatorId; + + /** 设备所属方id */ + private String equipmentOwnerId; + /** 充电站名称 */ + private String stationName; + /** 充电站国家代码 */ + private String countryCode; + /** 省 */ + private String province; + /** 市 */ + private String city; + /** 区 */ + private String area; +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/excel/ChargeStatisticExcel.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/excel/ChargeStatisticExcel.java new file mode 100644 index 0000000..1c334c1 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/excel/ChargeStatisticExcel.java @@ -0,0 +1,106 @@ +package com.thing.qingyuan.chargeStation.excel; + + import com.thing.qingyuan.chargeStation.dto.ChargeStatisticReportResp; +import com.thing.common.core.annotation.CustomExcel; +import com.thing.common.core.annotation.CustomExcelCollection; +import com.thing.common.core.utils.DateTimeUtils; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import org.springframework.util.CollectionUtils; + +import java.time.LocalDateTime; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author SiYang + * @date 2024/02/01 14:17 + * @description 充电统计 + */ +@Data +@Accessors(chain = true) +@NoArgsConstructor +@AllArgsConstructor +public class ChargeStatisticExcel { + + @CustomExcel(name = "结构", width = 25) + private String thingName; + + private String attrName; + + private String attrUnit; + + @CustomExcel(columnNameGenerator = "dataColNameGenerator", width = 15, orderNum = 1) + private String total; + + @CustomExcelCollection + private List data; + + @SuppressWarnings("unused") + private String dataColNameGenerator() { + return attrName + "(" + attrUnit + ")"; + } + + public static List convert(List sources) { + if (CollectionUtils.isEmpty(sources)) { + return Collections.emptyList(); + } + return sources.stream() + .map( + source -> { + Map dataMap = source.getData(); + List dataList = new ArrayList<>(); + dataMap.forEach( + (k, v) -> + dataList.add( + new TsVal() + .setTs(DateTimeUtils.parseDateTime(k)) + .setTimeType(source.getTimeType()) + .setVal(Optional.ofNullable(v).orElse("--")))); + return new ChargeStatisticExcel() + .setThingName(source.getThingName() + source.getAttrCode()) + .setAttrName(source.getAttrName()) + .setAttrUnit(source.getUnit()) + .setTotal(source.getTotal().toString()) + .setData(dataList); + }) + .collect(Collectors.toList()); + } + + @Data + @Accessors(chain = true) + @NoArgsConstructor + @AllArgsConstructor + public static class TsVal { + private String timeType; + + private LocalDateTime ts; + + @CustomExcel(columnNameGenerator = "dataColNameGenerator", width = 12, orderGenerator = "colOrderGenerator") + private String val; + + @SuppressWarnings("unused") + private String dataColNameGenerator() { + return switch (timeType) { + case "month" -> ts.getDayOfMonth() + "日"; + case "year" -> ts.getMonthValue() + "月"; + default -> null; + }; + } + + @SuppressWarnings("unused") + private int colOrderGenerator(){ + int orderNum = 2; + switch (timeType) { + case "month" -> orderNum += (31 - ts.getDayOfMonth()); + case "year" -> orderNum += (12 - ts.getMonthValue()); + default -> { + } + } + return orderNum; + } + + } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/mapper/ChargeOrderDetailsMapper.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/mapper/ChargeOrderDetailsMapper.java new file mode 100644 index 0000000..1dd44cd --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/mapper/ChargeOrderDetailsMapper.java @@ -0,0 +1,23 @@ +package com.thing.qingyuan.chargeStation.mapper; + +import com.mybatisflex.annotation.UseDataSource; +import com.thing.qingyuan.chargeStation.dto.ChargeOrderDetailsDTO; +import com.thing.qingyuan.chargeStation.entity.ChargeOrderDetailsEntity; +import com.thing.common.orm.mapper.PowerBaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** +* 充电桩订单明细 +* +* @author system system@lrd.com +* @since 5.1 2024-01-23 +*/ +@Mapper +@UseDataSource("systemCollect") +public interface ChargeOrderDetailsMapper extends PowerBaseMapper { + + List getLatestDetails(@Param("start") String start, @Param("end") String end); +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/mapper/ChargeOrderHeadMapper.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/mapper/ChargeOrderHeadMapper.java new file mode 100644 index 0000000..768e1b2 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/mapper/ChargeOrderHeadMapper.java @@ -0,0 +1,18 @@ +package com.thing.qingyuan.chargeStation.mapper; + +import com.mybatisflex.annotation.UseDataSource; +import com.thing.qingyuan.chargeStation.entity.ChargeOrderHeadEntity; +import com.thing.common.orm.mapper.PowerBaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** +* 充电桩订单头 +* +* @author system system@lrd.com +* @since 5.1 2024-01-23 +*/ +@Mapper +@UseDataSource("systemCollect") +public interface ChargeOrderHeadMapper extends PowerBaseMapper { + +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/mapper/ConnectorInfoMapper.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/mapper/ConnectorInfoMapper.java new file mode 100644 index 0000000..bf27f0b --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/mapper/ConnectorInfoMapper.java @@ -0,0 +1,32 @@ +package com.thing.qingyuan.chargeStation.mapper; + +import com.mybatisflex.annotation.UseDataSource; +import com.thing.qingyuan.chargeStation.dto.ConnectorStatusInfo; +import com.thing.qingyuan.chargeStation.entity.ConnectorInfoEntity; +import com.thing.common.orm.mapper.PowerBaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** +* 充电枪 +* +* @author system system@lrd.com +* @since 5.1 2024-01-29 +*/ +@Mapper +@UseDataSource("systemCollect") +public interface ConnectorInfoMapper extends PowerBaseMapper { + + + + List getStatusByStationId(String stationId); + + + Integer getCountByStationIds(List stationIds); + + List getStatusByStationIds(List stationIds); + + List simpleList(@Param("stationId") String stationId); +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/mapper/EquipmentInfoMapper.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/mapper/EquipmentInfoMapper.java new file mode 100644 index 0000000..a56713a --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/mapper/EquipmentInfoMapper.java @@ -0,0 +1,24 @@ +package com.thing.qingyuan.chargeStation.mapper; + +import com.mybatisflex.annotation.UseDataSource; +import com.thing.qingyuan.chargeStation.entity.EquipmentInfoEntity; +import com.thing.common.orm.mapper.PowerBaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** +* 充电桩 +* +* @author system system@lrd.com +* @since 5.1 2024-01-29 +*/ +@Mapper +@UseDataSource("systemCollect") +public interface EquipmentInfoMapper extends PowerBaseMapper { + + List> sumPower(@Param("stationIds") Collection stationIds); +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/mapper/StationInfoMapper.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/mapper/StationInfoMapper.java new file mode 100644 index 0000000..4ad25b9 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/mapper/StationInfoMapper.java @@ -0,0 +1,22 @@ +package com.thing.qingyuan.chargeStation.mapper; + +import com.mybatisflex.annotation.UseDataSource; +import com.thing.qingyuan.chargeStation.dto.StationSimpleDTO; +import com.thing.qingyuan.chargeStation.entity.StationInfoEntity; +import com.thing.common.orm.mapper.PowerBaseMapper; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** +* 充电站信息 +* +* @author ssy 2337720667@qq.com +* @since 3.0 2024-01-23 +*/ +@Mapper +@UseDataSource("systemCollect") +public interface StationInfoMapper extends PowerBaseMapper { + + List getSimpleListWithGunStatus(); +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/ChargeOrderDetailsService.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/ChargeOrderDetailsService.java new file mode 100644 index 0000000..e48f8ca --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/ChargeOrderDetailsService.java @@ -0,0 +1,20 @@ +package com.thing.qingyuan.chargeStation.service; + +import com.thing.qingyuan.chargeStation.dto.ChargeOrderDetailsDTO; +import com.thing.qingyuan.chargeStation.entity.ChargeOrderDetailsEntity; +import com.thing.common.orm.service.IBaseService; + +import java.util.List; + +/** + * 充电桩订单明细 + * + * @author system system@lrd.com + * @since 5.1 2024-01-23 + */ +public interface ChargeOrderDetailsService extends IBaseService { + + List findByHeadId(String startChargeSeq); + + List getLatestDetails(String start, String end); +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/ChargeOrderHeadService.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/ChargeOrderHeadService.java new file mode 100644 index 0000000..402d440 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/ChargeOrderHeadService.java @@ -0,0 +1,21 @@ +package com.thing.qingyuan.chargeStation.service; + +import com.thing.qingyuan.chargeStation.dto.ChargeOrderHeadDTO; +import com.thing.qingyuan.chargeStation.entity.ChargeOrderHeadEntity; +import com.thing.common.core.web.response.PageData; +import com.thing.common.orm.service.IBaseService; + +import java.util.Map; + +/** + * 充电桩订单头 + * + * @author system system@lrd.com + * @since 5.1 2024-01-23 + */ +public interface ChargeOrderHeadService extends IBaseService { + + PageData handlePage(Map params); + + ChargeOrderHeadDTO getDetails(String startChargeSeq); +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/ChargeStatisticService.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/ChargeStatisticService.java new file mode 100644 index 0000000..0664e7b --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/ChargeStatisticService.java @@ -0,0 +1,18 @@ +package com.thing.qingyuan.chargeStation.service; + +import com.thing.qingyuan.chargeStation.dto.ChargeStatisticReportResp; +import com.thing.qingyuan.chargeStation.dto.ChargeStatisticRequest; +import jakarta.servlet.http.HttpServletResponse; + +import java.util.List; + +/** + * @author SiYang + * @date 2024/01/31 17:33 + * @description 充电统计服务 + */ +public interface ChargeStatisticService { + List getReport(ChargeStatisticRequest request); + + void export(ChargeStatisticRequest request, HttpServletResponse response); +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/ConnectorInfoService.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/ConnectorInfoService.java new file mode 100644 index 0000000..e18a2bf --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/ConnectorInfoService.java @@ -0,0 +1,23 @@ +package com.thing.qingyuan.chargeStation.service; + +import com.thing.qingyuan.chargeStation.dto.ConnectorInfoDTO; +import com.thing.qingyuan.chargeStation.entity.ConnectorInfoEntity; +import com.thing.common.orm.service.IBaseService; + +import java.util.Collection; +import java.util.List; + +/** + * 充电枪 + * + * @author system system@lrd.com + * @since 5.1 2024-01-29 + */ +public interface ConnectorInfoService extends IBaseService { + + List getByEquipmentIds(Collection equipmentIds); + + List simpleList(String stationId); + + Integer getCountByStationIds(List stationIds); +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/EquipmentInfoService.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/EquipmentInfoService.java new file mode 100644 index 0000000..d98472e --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/EquipmentInfoService.java @@ -0,0 +1,22 @@ +package com.thing.qingyuan.chargeStation.service; + +import com.thing.qingyuan.chargeStation.dto.EquipmentInfoDTO; +import com.thing.qingyuan.chargeStation.entity.EquipmentInfoEntity; +import com.thing.common.orm.service.IBaseService; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * 充电桩 + * + * @author system system@lrd.com + * @since 5.1 2024-01-29 + */ +public interface EquipmentInfoService extends IBaseService { + + List getByStationId(String stationId); + + Map sumPower(Collection stationIds); +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/StationInfoService.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/StationInfoService.java new file mode 100644 index 0000000..56a455f --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/StationInfoService.java @@ -0,0 +1,55 @@ +package com.thing.qingyuan.chargeStation.service; + +import com.thing.qingyuan.chargeStation.dto.*; +import com.thing.qingyuan.chargeStation.entity.StationInfoEntity; +import com.thing.common.core.web.response.PageData; +import com.thing.common.orm.service.IBaseService; +import com.thing.qingyuan.manageboard.dto.MapParam; + +import java.util.List; +import java.util.Map; + +/** + * 充电站信息 + * + * @author ssy 2337720667@qq.com + * @since 3.0 2024-01-23 + */ +public interface StationInfoService extends IBaseService { + + + PageData handlePage(Map params); + + /** + * 查询充电站的简要信息列表 + */ + List simpleList(); + + /** + * 获取充电站下的充电桩列表和充电枪列表 + * + * @param stationId 充电站id + * @return 充电站设备详情 + */ + StationDeviceDetail getDetails(String stationId); + + /** + * 在当前租户下生成充电站配置: + * 1. 物模型 + * 2. 物实体 + * 3. 物指标 + * 4. 物关系 + * 5. 数据源配置 + */ + void generateThingConfig(); + + Map> findByParam(MapParam mapParam); + + List findByName(String plantName, String area); + + List getSimpleList(); + + List getSimpleListWithGunStatus(); + + List getIdNameList(Map params); +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/impl/ChargeOrderDetailsServiceImpl.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/impl/ChargeOrderDetailsServiceImpl.java new file mode 100644 index 0000000..778b106 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/impl/ChargeOrderDetailsServiceImpl.java @@ -0,0 +1,57 @@ +package com.thing.qingyuan.chargeStation.service.impl; + +import cn.hutool.core.map.MapUtil; +import com.mybatisflex.core.query.QueryWrapper; +import com.thing.qingyuan.chargeStation.dto.ChargeOrderDetailsDTO; +import com.thing.qingyuan.chargeStation.entity.ChargeOrderDetailsEntity; +import com.thing.qingyuan.chargeStation.entity.ChargeOrderHeadEntity; +import com.thing.qingyuan.chargeStation.mapper.ChargeOrderDetailsMapper; +import com.thing.qingyuan.chargeStation.service.ChargeOrderDetailsService; +import com.thing.common.orm.service.impl.BaseServiceImpl; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * 充电桩订单明细 + * + * @author system system@lrd.com + * @since 5.1 2024-01-23 + */ +@Service +@RequiredArgsConstructor +public class ChargeOrderDetailsServiceImpl extends BaseServiceImpl implements ChargeOrderDetailsService { + + @Override + public QueryWrapper getWrapper(Map params) { + QueryWrapper wrapper = new QueryWrapper(); + String orderNo = MapUtil.getStr(params, "orderNo"); + String beginTime = MapUtil.getStr(params, "beginTime"); + String endTime = MapUtil.getStr(params, "endTime"); + + wrapper.eq(ChargeOrderHeadEntity::getStartChargeSeq, orderNo); + if (Objects.nonNull(beginTime) && Objects.nonNull(endTime)) { + wrapper.between(ChargeOrderHeadEntity::getStartTime, beginTime, endTime) + .between(ChargeOrderHeadEntity::getEndTime, beginTime, endTime); + } + + return wrapper; + } + + @Override + public List findByHeadId(String startChargeSeq) { + return list( + QueryWrapper.create() + .eq(ChargeOrderDetailsEntity::getStartChargeSeq, startChargeSeq) + .orderBy(ChargeOrderDetailsEntity::getEndTime) + .asc()); + } + + @Override + public List getLatestDetails(String start, String end) { + return mapper.getLatestDetails(start, end); + } +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/impl/ChargeOrderHeadServiceImpl.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/impl/ChargeOrderHeadServiceImpl.java new file mode 100644 index 0000000..51dc46d --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/impl/ChargeOrderHeadServiceImpl.java @@ -0,0 +1,108 @@ +package com.thing.qingyuan.chargeStation.service.impl; + +import cn.hutool.core.map.MapUtil; +import com.mybatisflex.core.paginate.Page; +import com.mybatisflex.core.query.QueryWrapper; +import com.thing.qingyuan.chargeStation.dto.ChargeOrderHeadDTO; +import com.thing.qingyuan.chargeStation.entity.ChargeOrderDetailsEntity; +import com.thing.qingyuan.chargeStation.entity.ChargeOrderHeadEntity; +import com.thing.qingyuan.chargeStation.entity.EquipmentInfoEntity; +import com.thing.qingyuan.chargeStation.entity.StationInfoEntity; +import com.thing.qingyuan.chargeStation.mapper.ChargeOrderHeadMapper; +import com.thing.qingyuan.chargeStation.service.*; +import com.thing.common.core.constants.Constant; +import com.thing.common.core.web.response.PageData; +import com.thing.common.orm.service.impl.BaseServiceImpl; +import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +import static com.thing.qingyuan.chargeStation.entity.table.ChargeOrderHeadEntityTableDef.CHARGE_ORDER_HEAD_ENTITY; +import static com.thing.qingyuan.chargeStation.entity.table.ConnectorInfoEntityTableDef.CONNECTOR_INFO_ENTITY; +import static com.thing.qingyuan.chargeStation.entity.table.EquipmentInfoEntityTableDef.EQUIPMENT_INFO_ENTITY; +import static com.thing.qingyuan.chargeStation.entity.table.StationInfoEntityTableDef.STATION_INFO_ENTITY; + +/** + * 充电桩订单头 + * + * @author system system@lrd.com + * @since 5.1 2024-01-23 + */ +@Service +@RequiredArgsConstructor +public class ChargeOrderHeadServiceImpl extends BaseServiceImpl implements ChargeOrderHeadService { + + private final ChargeOrderDetailsService chargeOrderDetailsService; + + @Override + public QueryWrapper getWrapper(Map params){ + return new QueryWrapper(); + } + + @Override + public PageData handlePage(Map params) { + Page page = getPage(params, ChargeOrderHeadDTO.class); + return selectPage(page, params); + } + + @Override + public ChargeOrderHeadDTO getDetails(String startChargeSeq) { + ChargeOrderHeadDTO orderHead = getByIdAs(startChargeSeq, ChargeOrderHeadDTO.class); + fillDetail(orderHead); + return orderHead; + } + + private PageData selectPage(Page page, Map params) { + String startChargeSeq = MapUtil.getStr(params, "startChargeSeq"); + String stationId = MapUtil.getStr(params, "stationId"); + String equipmentId = MapUtil.getStr(params, "equipmentId"); + String connectorId = MapUtil.getStr(params, "connectorId"); + String beginTime = MapUtil.getStr(params, "beginTime"); + String endTime = MapUtil.getStr(params, "endTime"); + String order = MapUtil.getStr(params, Constant.ORDER); + String orderField = MapUtil.getStr(params, Constant.ORDER_FIELD); + + QueryWrapper queryWrapper = + QueryWrapper.create() + .select( + CHARGE_ORDER_HEAD_ENTITY.ALL_COLUMNS, + CONNECTOR_INFO_ENTITY.CONNECTOR_NAME, + EQUIPMENT_INFO_ENTITY.EQUIPMENT_ID, + EQUIPMENT_INFO_ENTITY.EQUIPMENT_NAME, + STATION_INFO_ENTITY.STATION_ID, + STATION_INFO_ENTITY.STATION_NAME) + .from(CHARGE_ORDER_HEAD_ENTITY) + .innerJoin(CONNECTOR_INFO_ENTITY).on(CHARGE_ORDER_HEAD_ENTITY.CONNECTOR_ID.eq(CONNECTOR_INFO_ENTITY.CONNECTOR_ID)) + .innerJoin(EQUIPMENT_INFO_ENTITY).on(CONNECTOR_INFO_ENTITY.EQUIPMENT_ID.eq(EQUIPMENT_INFO_ENTITY.EQUIPMENT_ID)) + .innerJoin(STATION_INFO_ENTITY).on(EQUIPMENT_INFO_ENTITY.STATION_ID.eq(STATION_INFO_ENTITY.STATION_ID)) + .eq(ChargeOrderHeadEntity::getStartChargeSeq, startChargeSeq, StringUtils.isNotBlank(startChargeSeq)) + .eq(ChargeOrderHeadEntity::getConnectorId, connectorId, StringUtils.isNotBlank(connectorId)) + .eq(StationInfoEntity::getStationId, stationId, StringUtils.isNotBlank(stationId)) + .eq(EquipmentInfoEntity::getEquipmentId, equipmentId, StringUtils.isNotBlank(equipmentId)); + + if (StringUtils.isNotBlank(beginTime) && StringUtils.isNotBlank(endTime)) { + queryWrapper.and(CHARGE_ORDER_HEAD_ENTITY.START_TIME.between(beginTime, endTime) + .or(CHARGE_ORDER_HEAD_ENTITY.END_TIME.between(beginTime, endTime))); + } + + queryWrapper.orderBy(orderField, "asc".equals(order)); + + Page paginate = + mapper.paginateAs(page, queryWrapper, ChargeOrderHeadDTO.class); + return new PageData<>(paginate.getRecords(), paginate.getTotalRow()); + } + + /** + * 补充属性和值, 属性说明:CurrentA~C: 电流(A); VoltageA~C: 电压(V) + * + * @param orderHead 充电枪订单头 + */ + private void fillDetail(ChargeOrderHeadDTO orderHead) { + List details = + chargeOrderDetailsService.findByHeadId(orderHead.getStartChargeSeq()); + orderHead.setDetails(details); + } +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/impl/ChargeStatisticServiceImpl.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/impl/ChargeStatisticServiceImpl.java new file mode 100644 index 0000000..f13c235 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/impl/ChargeStatisticServiceImpl.java @@ -0,0 +1,135 @@ +package com.thing.qingyuan.chargeStation.service.impl; + +import cn.afterturn.easypoi.excel.ExcelExportUtil; +import cn.afterturn.easypoi.excel.entity.ExportParams; +import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity; +import com.thing.qingyuan.chargeStation.dto.ChargeStatisticReportResp; +import com.thing.qingyuan.chargeStation.dto.ChargeStatisticRequest; +import com.thing.qingyuan.chargeStation.excel.ChargeStatisticExcel; +import com.thing.qingyuan.chargeStation.service.ChargeStatisticService; +import com.thing.common.core.utils.excel.ExcelUtils; +import com.thing.common.core.utils.export.ExcelEntityGenerator; +import com.thing.common.data.tskv.TsKvDTO; +import com.thing.common.tskv.service.TsKvService; +import com.thing.thing.dict.dto.IotThingDictDTO; +import com.thing.thing.dict.entity.IotThingDictEntity; +import com.thing.thing.dict.service.IotThingDictService; + +import com.thing.thing.dictRelation.service.IotThingDictRelationService; +import com.thing.thing.entity.dto.IotThingViewDTO; +import com.thing.thing.entity.entity.IotThingEntity; +import com.thing.thing.entity.service.IotThingEntityService; +import com.thing.thing.relation.root.service.IotThingRelationRootService; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.poi.ss.usermodel.Workbook; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author SiYang + * @date 2024/01/31 17:34 + * @description 充电统计服务实现 + */ +@Service +@RequiredArgsConstructor +public class ChargeStatisticServiceImpl implements ChargeStatisticService { + + private final TsKvService tsKvService; + private final IotThingDictService thingDictService; + private final IotThingDictRelationService thingDictRelationService; + private final IotThingEntityService thingEntityService; + private final IotThingRelationRootService relationRootService; + + @Override + public List getReport(ChargeStatisticRequest request) { + // 物信息 + List thingIds = request.getThingIds(); + List things = thingEntityService.findByIds(thingIds); + Set thingCodes = things.stream().map(IotThingViewDTO::getEntityCode).collect(Collectors.toSet()); + + // 属性信息 + IotThingDictDTO dict = thingDictService.findDictByCode(request.getBaseAttrCode()); + + // 查询tskv + List tskvList = + tsKvService.findTsKvByCodesAndAttrs( + thingCodes, + Collections.singletonList(request.getAttrCode()), + request.getStartTs(), + request.getEndTs(), + false); + Map> thingTskvListMap = + tskvList.stream().collect(Collectors.groupingBy(TsKvDTO::getThingCode)); + + // 数据组装 + List unsortedResult = assemble(things, dict, request, thingTskvListMap); + + // 按深度优先排序 + return relationRootService.sortInDiffRootThingIds( + request.getRootId(), + request.getRootThingIds(), + new HashSet<>(thingIds), + unsortedResult, + res -> res.stream().collect(Collectors.groupingBy(ChargeStatisticReportResp::getThingId))); + } + + @Override + public void export(ChargeStatisticRequest request, HttpServletResponse response) { + // 报表原始数据 + List report = getReport(request); + + // 数据类型转换 + List excelDataList = ChargeStatisticExcel.convert(report); + + // 生成表头 & 生成数据集合 + List excelExportEntities = ExcelEntityGenerator.generateExportEntity(new ArrayList<>(excelDataList)); + List> dataCollection = ExcelEntityGenerator.generateDataCollection(new ArrayList<>(excelDataList)); + + // 导出 + Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(null, "充电统计报表"), excelExportEntities, dataCollection); + ExcelUtils.downLoadExcel("充电统计报表.xls", response, workbook); + } + + private List assemble( + List things, + IotThingDictDTO dict, + ChargeStatisticRequest request, + Map> thingTskvListMap) { + return things.stream() + .map( + t -> { + List tskvList = thingTskvListMap.get(t.getEntityCode()); + if (CollectionUtils.isNotEmpty(tskvList) && request.getReportType().equals(2)) { + tskvList.forEach( + e -> { + String msVal = e.getVal(); + if (StringUtils.isNotBlank(msVal)) { + BigDecimal hourVal = + new BigDecimal(msVal) + .divide(BigDecimal.valueOf(60 * 60 * 1000), 2, RoundingMode.HALF_UP); + e.setVal(hourVal.toPlainString()); + } + }); + } + return new ChargeStatisticReportResp() + .setThingId(t.getEntityId()) + .setThingName(t.getEntityName()) + .setThingCode(t.getEntityCode()) + .setAttrName(dict.getName()) + .setAttrCode(dict.getCode()) + .setUnit(dict.getUnit()) + .setTimeType(request.getTimeType()) + .initData(request.generateAllDateTime()) + .fillData(tskvList) + .calculateTotal(); + }) + .toList(); + } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/impl/ConnectorInfoServiceImpl.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/impl/ConnectorInfoServiceImpl.java new file mode 100644 index 0000000..767baf6 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/impl/ConnectorInfoServiceImpl.java @@ -0,0 +1,51 @@ +package com.thing.qingyuan.chargeStation.service.impl; + +import com.mybatisflex.core.query.QueryWrapper; +import com.thing.qingyuan.chargeStation.dto.ConnectorInfoDTO; +import com.thing.qingyuan.chargeStation.entity.ConnectorInfoEntity; +import com.thing.qingyuan.chargeStation.mapper.ConnectorInfoMapper; +import com.thing.qingyuan.chargeStation.service.ConnectorInfoService; +import com.thing.common.orm.service.impl.BaseServiceImpl; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * 充电枪 + * + * @author system system@lrd.com + * @since 5.1 2024-01-29 + */ +@Service +@RequiredArgsConstructor +public class ConnectorInfoServiceImpl extends BaseServiceImpl implements ConnectorInfoService { + + @Override + public QueryWrapper getWrapper(Map params){ + QueryWrapper wrapper = new QueryWrapper(); + return wrapper; + } + + @Override + public List getByEquipmentIds(Collection equipmentIds) { + return mapper.selectListByQueryAs( + QueryWrapper.create() + .in(ConnectorInfoEntity::getEquipmentId, equipmentIds) + .orderBy(ConnectorInfoEntity::getEquipmentId) + .asc(), + ConnectorInfoDTO.class); + } + + @Override + public List simpleList(String stationId) { + return mapper.simpleList(stationId); + } + + @Override + public Integer getCountByStationIds(List stationIds) { + return mapper.getCountByStationIds(stationIds); + } +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/impl/EquipmentInfoServiceImpl.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/impl/EquipmentInfoServiceImpl.java new file mode 100644 index 0000000..f228a63 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/impl/EquipmentInfoServiceImpl.java @@ -0,0 +1,53 @@ +package com.thing.qingyuan.chargeStation.service.impl; + +import cn.hutool.core.map.MapUtil; +import com.mybatisflex.core.query.QueryWrapper; +import com.thing.qingyuan.chargeStation.dto.EquipmentInfoDTO; +import com.thing.qingyuan.chargeStation.entity.EquipmentInfoEntity; +import com.thing.qingyuan.chargeStation.mapper.EquipmentInfoMapper; +import com.thing.qingyuan.chargeStation.service.EquipmentInfoService; +import com.thing.common.orm.service.impl.BaseServiceImpl; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 充电桩 + * + * @author system system@lrd.com + * @since 5.1 2024-01-29 + */ +@Service +public class EquipmentInfoServiceImpl extends BaseServiceImpl implements EquipmentInfoService { + + @Override + public QueryWrapper getWrapper(Map params) { + QueryWrapper wrapper = new QueryWrapper(); + String stationId = MapUtil.getStr(params, "stationId"); + wrapper.eq(EquipmentInfoEntity::getStationId, stationId, StringUtils.isNotBlank(stationId)); + return wrapper; + } + + @Override + public List getByStationId(String stationId) { + return mapper.selectListByQueryAs( + QueryWrapper.create().eq(EquipmentInfoEntity::getStationId, stationId), + EquipmentInfoDTO.class); + } + + @Override + public Map sumPower(Collection stationIds) { + List> stationPowerMapList = mapper.sumPower(stationIds); + Map res = new HashMap<>(); + for (Map map : stationPowerMapList) { + String stationId = (String) map.get("stationId"); + Double totalPower = Double.valueOf("" + map.get("totalPower")); + res.put(stationId, totalPower); + } + return res; + } +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/impl/StationInfoServiceImpl.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/impl/StationInfoServiceImpl.java new file mode 100644 index 0000000..9db85e0 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/service/impl/StationInfoServiceImpl.java @@ -0,0 +1,389 @@ +package com.thing.qingyuan.chargeStation.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.map.MapUtil; +import com.mybatisflex.core.query.QueryWrapper; +import com.thing.qingyuan.chargeStation.config.StationProperties; +import com.thing.qingyuan.chargeStation.dto.*; +import com.thing.qingyuan.chargeStation.entity.ConnectorInfoEntity; +import com.thing.qingyuan.chargeStation.entity.EquipmentInfoEntity; +import com.thing.qingyuan.chargeStation.entity.StationInfoEntity; +import com.thing.qingyuan.chargeStation.mapper.StationInfoMapper; +import com.thing.qingyuan.chargeStation.service.ConnectorInfoService; +import com.thing.qingyuan.chargeStation.service.EquipmentInfoService; +import com.thing.qingyuan.chargeStation.service.StationInfoService; +import com.thing.common.core.enumeration.TemplateMark; +import com.thing.common.core.utils.ConvertUtils; +import com.thing.common.core.validator.AssertUtils; +import com.thing.common.core.web.response.PageData; +import com.thing.common.orm.service.impl.BaseServiceImpl; +import com.thing.event.ThingRelationDetailSaveEvent; +import com.thing.qingyuan.manageboard.dto.MapParam; +import com.thing.sys.security.context.UserContext; +import com.thing.thing.dictRelation.service.IotThingDictRelationService; +import com.thing.thing.entity.entity.IotThingEntity; +import com.thing.thing.entity.service.IotThingEntityService; +import com.thing.thing.model.service.IotThingModelService; +import com.thing.thing.model.thread.ThingModelExecutor; +import com.thing.thing.relation.detail.service.IotThingRelationDetailService; +import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +import static com.thing.qingyuan.chargeStation.entity.table.StationInfoEntityTableDef.STATION_INFO_ENTITY; + +/** + * 充电站信息 + * + * @author ssy 2337720667@qq.com + * @since 3.0 2024-01-23 + */ +@Service +@RequiredArgsConstructor +public class StationInfoServiceImpl extends BaseServiceImpl implements StationInfoService { + private final StationProperties stationProperties; + private final ThingModelExecutor thingModelExecutor; + private final EquipmentInfoService equipmentInfoService; + private final ConnectorInfoService connectorInfoService; + private final IotThingModelService iotThingModelService; + private final IotThingEntityService iotThingEntityService; + private final ApplicationEventPublisher applicationEventPublisher; + private final IotThingDictRelationService iotThingDictRelationService; + private final IotThingRelationDetailService iotThingRelationDetailService; + + private static final String STATION_TEMPLATE_TYPE = "Station"; + private static final String PILE_TEMPLATE_TYPE = "Pile"; + private static final String GUN_TEMPLATE_TYPE = "Gun"; + + @Override + public QueryWrapper getWrapper(Map params) { + QueryWrapper wrapper = new QueryWrapper(); + String areaCode = MapUtil.getStr(params, "areaCode"); + String operatorId = MapUtil.getStr(params, "operatorId"); + String keyword = MapUtil.getStr(params, "keyword"); + + wrapper.eq(StationInfoEntity::getAreaCode, areaCode, StringUtils.isNotBlank(areaCode)) + .eq(StationInfoEntity::getOperatorId, operatorId, StringUtils.isNotBlank(operatorId)) + .like(StationInfoEntity::getStationName, keyword, StringUtils.isNotBlank(keyword)); + return wrapper; + } + + @Override + public PageData handlePage(Map params) { + PageData page = getPageData(params, StationInfoDTO.class); + List list = page.getList(); + fillExtendData(list); + return page; + } + + private void fillExtendData(List list) { + Set stationIds = list.stream().map(StationInfoDTO::getStationId).collect(Collectors.toSet()); + Map stationPowerMap = equipmentInfoService.sumPower(stationIds); + list.forEach( + e -> { + e.setOperatorName(stationProperties.getOperatorNameById(e.getOperatorId())); + e.setTotalPilePower(stationPowerMap.get(e.getStationId())); + }); + } + + @Override + public List simpleList() { + List list = list(); + return list.stream() + .map( + e -> + new StationSimpleInfo() + .setStationId(e.getStationId()) + .setStationName(e.getStationName()) + .setAreaCode(e.getAreaCode()) + .setAreaName(e.getArea()) + .setOperatorId(e.getOperatorId()) + .setOperatorName( + stationProperties.getOperatorNameById(e.getOperatorId()))) + .collect(Collectors.toList()); + } + + @Override + public StationDeviceDetail getDetails(String stationId) { + List pileList = equipmentInfoService.getByStationId(stationId); + Set equipmentIds = pileList.stream().map(EquipmentInfoDTO::getEquipmentId).collect(Collectors.toSet()); + List gunList = connectorInfoService.getByEquipmentIds(equipmentIds); + return new StationDeviceDetail(stationId, pileList, gunList); + } + + /** + * 在当前租户下生成充电站配置: + * 1. 物模型 + * 2. 物实体 + * 3. 物指标 + * 4. 物关系 + * 5. 数据源配置 + */ + @Override + public void generateThingConfig() { + Long tenantCode = UserContext.getTenantCode(); + + // 站 + List stationList = list(); + List stationSimpleRelations = stationConvert2SimpleRelation(stationList); + doGenerate(stationSimpleRelations, STATION_TEMPLATE_TYPE, tenantCode); + + // 桩 + List pileList = equipmentInfoService.list(); + List pileSimpleRelations = pileConvert2SimpleRelation(pileList); + doGenerate(pileSimpleRelations, PILE_TEMPLATE_TYPE, tenantCode); + + // 枪 + List gunList = connectorInfoService.list(); + List gunSimpleRelations = gunConvert2SimpleRelation(gunList); + doGenerate(gunSimpleRelations, GUN_TEMPLATE_TYPE, tenantCode); + } + + @Override + public Map> findByParam(MapParam mapParam) { + QueryWrapper wrapper = new QueryWrapper(); + if(mapParam.getType().equals("2")){ + wrapper.eq(StationInfoEntity::getProvince,mapParam.getCityName()); + List dtos = ConvertUtils.sourceToTarget(this.list(wrapper),StationInfoDTO.class); + return dtos.stream() + .collect(Collectors.groupingBy(StationInfoDTO::getCity)); + }else if(mapParam.getType().equals("3")){ + wrapper.eq(StationInfoEntity::getCity,mapParam.getCityName()); + List dtos = ConvertUtils.sourceToTarget(this.list(wrapper),StationInfoDTO.class); + return dtos.stream() + .collect(Collectors.groupingBy(StationInfoDTO::getCity)); + }else if(mapParam.getType().equals("4")){ + wrapper.eq(StationInfoEntity::getArea,mapParam.getCityName()); + List dtos = ConvertUtils.sourceToTarget(this.list(wrapper),StationInfoDTO.class); + return dtos.stream() + .collect(Collectors.groupingBy(StationInfoDTO::getCity)); + }else { + List dtos = ConvertUtils.sourceToTarget(this.list(wrapper),StationInfoDTO.class); + return dtos.stream() + .collect(Collectors.groupingBy(StationInfoDTO::getProvince)); + } + } + + @Override + public List findByName(String plantName, String area) { + QueryWrapper wrapper = new QueryWrapper(); + wrapper.like(StationInfoEntity::getStationName,plantName,StringUtils.isNotEmpty(plantName)); + wrapper.like(StationInfoEntity::getArea,area,StringUtils.isNotEmpty(area)); + return ConvertUtils.sourceToTarget(this.list(wrapper),StationInfoDTO.class); + } + + @Override + public List getSimpleList() { + QueryWrapper queryWrapper = + QueryWrapper.create() + .select(STATION_INFO_ENTITY.STATION_ID, STATION_INFO_ENTITY.STATION_NAME) + .from(STATION_INFO_ENTITY); + return list(queryWrapper); + } + + @Override + public List getSimpleListWithGunStatus() { + return mapper.getSimpleListWithGunStatus(); + } + + @Override + public List getIdNameList(Map params) { + String type = MapUtil.getStr(params, "type"); + String pid = MapUtil.getStr(params, "pid"); + boolean pidValid = StringUtils.isNotBlank(pid); + if ("pile".equals(type)) { + List piles = + equipmentInfoService.list( + QueryWrapper.create() + .eq(EquipmentInfoEntity::getStationId, pid, pidValid)); + return piles.stream() + .map(p -> new IdNameDTO(p.getEquipmentId(), p.getEquipmentName())) + .toList(); + } else { + List guns = + connectorInfoService.list( + QueryWrapper.create() + .eq(ConnectorInfoEntity::getEquipmentId, pid, pidValid)); + return guns.stream() + .map(g -> new IdNameDTO(g.getConnectorId(), g.getConnectorName())) + .toList(); + } + } + + private void doGenerate(List simpleRelations, String templateType, Long tenantCode){ + Map thingMap = + simpleRelations.stream().collect(Collectors.toMap(SimpleThingRelationDTO::getToCode, SimpleThingRelationDTO::getToName)); + Set thingCodes = thingMap.keySet(); + // 新增物模型【异步】 + // thingModelExecutor.execute(() -> iotThingModelService.batchSaveWithCodes(thingCodes)); + + // 新增物实体【同步】 + // iotThingEntityService.batchSaveWithThingMap(thingMap, templateType, tenantCode); + + AssertUtils.isBlank(templateType, "物模板不存在,请配置物模板"); + + // 同步物指标【异步】 + // thingModelExecutor.execute(() -> syncDict(templateType, tenantCode)); + + // 生成物关系【同步】 + // 查询出当前租户下,类型为${templateType}且不在任何物关系中的物实体 + // List nonRelationThings = iotThingEntityService.selectNonRelationThings(tenantCode, templateType); + /*if (!CollectionUtil.isEmpty(nonRelationThings)) { + // 需要新增的物关系 + if (STATION_TEMPLATE_TYPE.equals(templateType)) { + createTopRelationDetails(nonRelationThings, tenantCode); + } else { + createSubRelationDetails(nonRelationThings, simpleRelations, tenantCode); + } + }*/ + + // 生成数据源【异步】 + List things = + iotThingEntityService.list( + QueryWrapper.create().eq(IotThingEntity::getTenantCode, tenantCode)); + generateThingSource(things, tenantCode); + } + + /* private void createTopRelationDetails(List things, Long tenantCode){ + Long maxSort = iotThingRelationDetailService.getMaxSort(stationProperties.getRelationId()); + List details = new ArrayList<>(); + for (IotThingEntity thing : things) { + IotThingRelationDetailEntity detail = + new IotThingRelationDetailEntity() + .setSort(++maxSort) + .setFromId(stationProperties.getRelationId()) + .setToId(thing.getId()) + .setToCode(thing.getCode()) + .setToName(thing.getName()) + .setRootId(stationProperties.getRelationId()) + .setRootThingId(thing.getId()); + details.add(detail); + } + iotThingRelationDetailService.saveBatch(details); + }*/ + + /** + * 创建物关系详情 + * + * @param things 本次新创建的物模板 + * @param simpleRelations 携带所有物的父级id + * @param tenantCode 租户编码 + */ + /* private void createSubRelationDetails(List things, List simpleRelations, Long tenantCode) { + Set toCodes = things.stream().map(IotThingEntity::getCode).collect(Collectors.toSet()); + List validSimpleRelations = + simpleRelations.stream().filter(e -> toCodes.contains(e.getToCode())).toList(); + Map codeMap = + validSimpleRelations.stream() + .collect( + Collectors.toMap( + SimpleThingRelationDTO::getToCode, + SimpleThingRelationDTO::getFromCode)); + Set fromCodes = + validSimpleRelations.stream() + .map(SimpleThingRelationDTO::getFromCode) + .collect(Collectors.toSet()); + List fromThings = findUnTemplateThings(fromCodes, tenantCode); + Map fromtCodeIdMap = + fromThings.stream() + .collect( + Collectors.toMap( + IotThingEntity::getCode, + IotThingEntity::getId, + (v1, v2) -> v1)); + Map fromIdMaxSortMap = iotThingRelationDetailService.getMaxSortMap(fromtCodeIdMap.values()); + Map fromIdRootThingIdMap = iotThingRelationDetailService.getRootThingIds(fromtCodeIdMap.values()); + + List details = new ArrayList<>(); + for (IotThingEntity thing : things) { + String fromCode = codeMap.get(thing.getCode()); + Long fromId = fromtCodeIdMap.get(fromCode); + Long maxSort = Optional.ofNullable(fromIdMaxSortMap.get(fromId)).orElse(0L); + long newMaxSort = maxSort + 1; + fromIdMaxSortMap.put(fromId, newMaxSort); + IotThingRelationDetailEntity detail = + new IotThingRelationDetailEntity() + .setSort(newMaxSort) + .setFromId(fromId) + .setToId(thing.getId()) + .setToCode(thing.getCode()) + .setToName(thing.getName()) + .setRootId(stationProperties.getRelationId()) + .setRootThingId(fromIdRootThingIdMap.get(fromId)); + details.add(detail); + } + iotThingRelationDetailService.saveBatch(details); + }*/ + + /** + * 基于物模板同步物实体的属性,只有新创建的物才会进行属性同步 + * @param templateType 物模板类型 + * @param tenantCode 租户编码 + */ + /* private void syncDict(String templateType, Long tenantCode){ + // 查询当前租户下,类型为${templateType}且没有任何属性的物实体 + List things = iotThingEntityService.selectNonAttrThings(tenantCode, templateType); + if (CollectionUtil.isEmpty(things)) return; + List templateDictRelations = iotThingDictRelationService.findByTemplate(templateType); + List targetDictList = + things.stream() + .map(t -> templateDictRelations.stream() + .map(d -> { + IotThingDictRelationEntity targetDict = new IotThingDictRelationEntity(); + BeanUtils.copyProperties(d, targetDict); + targetDict.setId(null); + targetDict.setFromId(t.getId()); + return targetDict; + }) + .collect(Collectors.toList())) + .flatMap(Collection::stream) + .toList(); + iotThingDictRelationService.saveBatch(targetDictList); + }*/ + + private List stationConvert2SimpleRelation(List stationList) { + return stationList.stream() + .map(e -> new SimpleThingRelationDTO(null, e.getStationId(), e.getStationName())) + .toList(); + } + + private List pileConvert2SimpleRelation(List pileList) { + return pileList.stream() + .map(e -> new SimpleThingRelationDTO(e.getStationId(), e.getEquipmentId(), e.getEquipmentName())) + .toList(); + } + + private List gunConvert2SimpleRelation(List gunList) { + return gunList.stream() + .map(e -> new SimpleThingRelationDTO(e.getEquipmentId(), e.getConnectorId(), e.getConnectorName())) + .toList(); + } + + private void generateThingSource(List things, Long tenantCode){ + List thingIds = + things.stream().map(IotThingEntity::getId).collect(Collectors.toList()); + applicationEventPublisher.publishEvent( + new ThingRelationDetailSaveEvent( + this, + stationProperties.getRelationId(), + thingIds, + tenantCode)); + } + + private List findUnTemplateThings(Collection codes, Long tenantCode) { + return iotThingEntityService + .getMapper() + .selectListByQuery( + QueryWrapper.create() + .in(IotThingEntity::getCode, codes) + .eq(IotThingEntity::getTenantCode, tenantCode) + .eq(IotThingEntity::getTemplateMark, TemplateMark.NO.getValue())); + } + + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/task/StationTask.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/task/StationTask.java new file mode 100644 index 0000000..87af8e2 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/chargeStation/task/StationTask.java @@ -0,0 +1,272 @@ +package com.thing.qingyuan.chargeStation.task; + +import com.alibaba.fastjson.JSONObject; +import com.mybatisflex.core.query.QueryWrapper; +import com.thing.qingyuan.chargeStation.dto.ChargeOrderDetailsDTO; +import com.thing.qingyuan.chargeStation.dto.ChargeOrderHeadDTO; +import com.thing.qingyuan.chargeStation.dto.StationOrderAgg; +import com.thing.qingyuan.chargeStation.entity.ChargeOrderHeadEntity; +import com.thing.qingyuan.chargeStation.entity.ConnectorInfoEntity; +import com.thing.qingyuan.chargeStation.entity.EquipmentInfoEntity; +import com.thing.qingyuan.chargeStation.service.ChargeOrderDetailsService; +import com.thing.qingyuan.chargeStation.service.ChargeOrderHeadService; +import com.thing.qingyuan.chargeStation.service.ConnectorInfoService; +import com.thing.qingyuan.chargeStation.service.EquipmentInfoService; +import com.thing.common.core.utils.DateTimeUtils; +import com.thing.common.data.event.QueueConsumerEvent; +import com.thing.common.data.proto.QueueProto.DataProto; +import com.thing.quartz.timetask.task.ITask; +import com.thing.queue.util.Topics; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.Pair; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author SiYang + * @date 2024/02/01 16:59 + * @description 每日订单数据汇总 + */ +@Slf4j +@RequiredArgsConstructor +@Component("StationTask") +public class StationTask implements ITask { + private final ConnectorInfoService gunService; + private final EquipmentInfoService pileService; + private final ChargeOrderHeadService orderHeadService; + private final ApplicationEventPublisher eventPublisher; + private final ChargeOrderDetailsService orderDetailsService; + + /** + * 1. 查询完成时间在昨日的订单数据 + * 2. 按枪的维度汇总数据 + * 3. 按桩的维度再次汇总 + * 4. 按站的维度再次汇总 + * 5. 推送数据 + * @param params json格式,支持字段如下: + * - startTime: 订单结束时间的起始时间窗口 (yyyy-MM-dd HH:mm:ss) + * - endTime: 订单结束时间的结束时间窗口 (yyyy-MM-dd HH:mm:ss) + */ + @Override + public void run(String params) { + getDayList(params).forEach(timePair -> { + handleSequence(timePair); + handleAgg(timePair); + }); + } + + /** + * 时序数据推送,电流、电压、剩余电量、充电量 + * @param timePair 某天的开始时间和结束时间 + */ + private void handleSequence(Pair timePair) { + Pair latestTimePair = convert2LatestTime(timePair.getLeft()); + List orderDetails = getOrderDetails(latestTimePair); + List dataProtoList = + orderDetails.stream() + .map(ChargeOrderDetailsDTO::toProtoDataList) + .flatMap(List::stream) + .toList(); + if (!dataProtoList.isEmpty()) { + eventPublisher.publishEvent( + new QueueConsumerEvent(Topics.V1_TSKV_HISTORY.getValue(), dataProtoList)); + } + } + + + + /** + * 按指定时间聚合数据 + * @param timePair 某天的开始时间和结束时间 + */ + private void handleAgg(Pair timePair){ + // 计算本次汇总数据所在的时间戳 + Long ts = DateTimeUtils.convertTimeToLong(timePair.getLeft()); + + // 查询本次汇总数据所需使用的订单列表 + List orders = getOrders(timePair); + + // 汇总枪 + Map> gunOrderMap = + orders.stream().collect(Collectors.groupingBy(ChargeOrderHeadDTO::getConnectorId)); + Map gunDailyAggMap = aggGunOrders(gunOrderMap, ts); + + // 汇总桩 + Map> pileGunIdMap = getPileGunIdMap(gunOrderMap.keySet()); + Map pileDailyAggMap = aggSubDeviceData(pileGunIdMap, gunDailyAggMap, ts); + + // 汇总站 + Map> stationPileIdMap = getStationPileIdMap(pileGunIdMap.keySet()); + aggSubDeviceData(stationPileIdMap, pileDailyAggMap, ts); + } + + /** + * 跨天任务支持 + * + * @param params 任务参数 + * @return 每天的起始和结束时间列表 + */ + private List> getDayList(String params) { + List> dayList = new ArrayList<>(); + // 默认计算: 当前时间在00:05分前,那么计算昨日数据, 否则计算今日数据。目的:防止遗漏临界情况下的订单 + if (StringUtils.isBlank(params)) { + LocalDateTime currentTime = LocalDateTime.now(); + LocalDate today = currentTime.toLocalDate(); + boolean calculateYesterday = currentTime.getHour() == 0 && currentTime.getMinute() <= 5; + String start = getDayStart(calculateYesterday ? today.minusDays(1) : today); + String end = getDayStart(calculateYesterday ? today : today.plusDays(1)); + dayList.add(Pair.of(start, end)); + return dayList; + } + + // 按参数解析出多天的起始和结束时间 + JSONObject jsonObject = JSONObject.parseObject(params); + LocalDateTime startTime = getDayStart(jsonObject.getString("startTime")); + LocalDateTime endTime = DateTimeUtils.parseDateTime(jsonObject.getString("endTime")); + while (!startTime.isAfter(endTime)) { + String start = startTime.format(DateTimeUtils.DATE_TIME_PATTERN); + String end = getDayStart(startTime.toLocalDate().plusDays(1)); + dayList.add(Pair.of(start, end)); + startTime = startTime.plusDays(1); + } + return dayList; + } + + private Pair convert2LatestTime(String dateTime) { + LocalDateTime localDateTime = DateTimeUtils.parseDateTime(dateTime); + LocalDateTime now = LocalDateTime.now(); + LocalDateTime formatTime = + localDateTime + .withHour(now.getHour()) + .withMinute(now.getMinute()) + .withSecond(now.getSecond()); + String start; + if (formatTime.getHour() == 0 && formatTime.getMinute() <= 10) { + start = getDayStart(formatTime.toLocalDate()); + } else { + start = formatTime.minusMinutes(10).format(DateTimeUtils.DATE_TIME_PATTERN); + } + String end = formatTime.format(DateTimeUtils.DATE_TIME_PATTERN); + return Pair.of(start, end); + } + + private List getOrders(Pair timePair) { + return orderHeadService.listAs( + QueryWrapper.create() + .between( + ChargeOrderHeadEntity::getEndTime, + timePair.getLeft(), + timePair.getRight()), + ChargeOrderHeadDTO.class); + } + + private List getOrderDetails(Pair timePair) { + return orderDetailsService.getLatestDetails(timePair.getLeft(), timePair.getRight()); + } + + private Map> getPileGunIdMap(Collection gunIds) { + if (gunIds.isEmpty()) return new HashMap<>(1); + List gunList = gunService.listByIds(gunIds); + return gunList.stream() + .collect( + Collectors.groupingBy( + ConnectorInfoEntity::getEquipmentId, + Collectors.mapping( + ConnectorInfoEntity::getConnectorId, Collectors.toList()))); + } + + private Map> getStationPileIdMap(Collection pileIds) { + if(pileIds.isEmpty()) return new HashMap<>(1); + List pileList = pileService.listByIds(pileIds); + return pileList.stream() + .collect( + Collectors.groupingBy( + EquipmentInfoEntity::getStationId, + Collectors.mapping( + EquipmentInfoEntity::getEquipmentId, Collectors.toList()))); + } + + /** + * 仅针对充电枪的聚合 + * + * @param orderMap 订单按充电枪id分组后的map + * @param ts 汇总数据所在时间戳 + * @return 充电枪的汇总数据 + */ + private Map aggGunOrders( + Map> orderMap, Long ts) { + Map orderAggMap = new HashMap<>(); + orderMap.forEach( + (gunId, orderList) -> { + StationOrderAgg orderAgg = + orderList.stream() + .reduce( + new StationOrderAgg(gunId), + StationOrderAgg::add, + (x, y) -> null); + orderAggMap.put(gunId, orderAgg); + }); + List orderAggList = new ArrayList<>(orderAggMap.values()); + publish(orderAggList, ts); + return orderAggMap; + } + + /** + * 将子设备的聚合数据进一步聚合,成为父设备的聚合数据 + * + * @param deviceCodeMap 父设备id, 子设备id列表组成的map + * @param subDeviceAggMap 子设备的聚合数据map + * @param ts 数据所在时间戳 + * @return 父设备的聚合数据 + */ + private Map aggSubDeviceData( + Map> deviceCodeMap, + Map subDeviceAggMap, + Long ts) { + Map parentDeviceAggMap = new HashMap<>(); + deviceCodeMap.forEach( + (parentDeviceId, subDeviceIdList) -> { + List subDeviceAggList = + subDeviceIdList.stream().map(subDeviceAggMap::get).toList(); + StationOrderAgg parentDeviceAgg = + subDeviceAggList.stream() + .reduce(StationOrderAgg::add) + .orElse(new StationOrderAgg()); + parentDeviceAgg.setDeviceCode(parentDeviceId); + parentDeviceAggMap.put(parentDeviceId, parentDeviceAgg); + }); + List orderAggList = new ArrayList<>(parentDeviceAggMap.values()); + publish(orderAggList, ts); + return parentDeviceAggMap; + } + + private void publish(List orderAggList, Long ts) { + if (CollectionUtils.isEmpty(orderAggList)) return; + List protoList = + orderAggList.stream() + .map(orderAgg -> orderAgg.toProtoData(ts, "am")) + .flatMap(Collection::stream) + .toList(); + if (!protoList.isEmpty()) { + eventPublisher.publishEvent( + new QueueConsumerEvent(Topics.V1_TSKV_HISTORY.getValue(), protoList)); + } + } + + private String getDayStart(LocalDate date) { + return LocalDateTime.of(date, LocalTime.MIN).format(DateTimeUtils.DATE_TIME_PATTERN); + } + + private LocalDateTime getDayStart(String date) { + return DateTimeUtils.parseDateTime(date).toLocalDate().atStartOfDay(); + } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/controller/ManageBoardController.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/controller/ManageBoardController.java new file mode 100644 index 0000000..fc9943c --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/controller/ManageBoardController.java @@ -0,0 +1,112 @@ +package com.thing.qingyuan.manageboard.controller; + +import com.mybatisflex.core.query.QueryWrapper; +import com.thing.qingyuan.alert.dto.AlertDTO; +import com.thing.qingyuan.basedevice.dto.DeviceDTO; +import com.thing.qingyuan.basedevice.entity.DeviceEntity; +import com.thing.qingyuan.basedevice.mapper.DeviceMapper; +import com.thing.qingyuan.manageboard.dto.*; +import com.thing.qingyuan.manageboard.service.ManageBoardService; +import com.thing.qingyuan.screen.ScreenData; +import com.thing.common.core.utils.excel.ExcelUtils; +import com.thing.common.core.web.response.Result; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + + +/** + * 管理端主平台 + */ +@RestController +@RequestMapping("manage/board") +@Tag(name="管理端主平台") +@RequiredArgsConstructor +public class ManageBoardController { + + private final ManageBoardService boardService; + + private final DeviceMapper deviceMapper; + + @PostMapping ("map") + @Operation(summary="管理端主平台-光伏地图") + private Result> mapInfoByNameAndType(@RequestBody MapParam mapParam){ + return boardService.mapInfoByNameAndType(mapParam); + } + + @GetMapping ("plantList") + @Operation(summary="管理端主平台-光伏项目下拉列表") + private Result> plantList(){ + return boardService.plantList(); + } + + @PostMapping ("plantInfoList") + @Operation(summary="管理端主平台,光伏子平台-光伏项目发电量,上网量,减排量等信息,可按名称模糊过滤") + private Result> plantInfoList(@RequestBody FindParam param){ + return boardService.plantInfoList(param); + } + + @GetMapping ("totalInfo") + @Operation(summary="管理端主平台-光伏项目数量,总装机容量,发电量,收益等统计信息") + private Result totalInfo(){ + return boardService.totalInfo(); + } + + @PostMapping ("reduction") + @Operation(summary="管理端主平台-光伏节能减排信息") + private Result reduction(){ + return boardService.reduction(); + } + + @GetMapping ("alertList") + @Operation(summary="管理端主平台,光伏子平台-光伏项目告警记录列表") + private Result> alertList(){ + return boardService.alertList(); + } + + @PostMapping ("findListByAttrCodeAndType") + @Operation(summary="管理端主平台,月/年得电量用量查询") + private Result findListByAttrCodeAndType(@RequestBody DataParam dataParam){ + return boardService.findListByAttrCodeAndType(dataParam); + } + + @PostMapping ("findYOYList") + @Operation(summary="管理端主平台,年发电量同比分析") + private Result> findYOYList(@RequestBody DataParam dataParam){ + return boardService.findYOYList(dataParam); + } + + @PostMapping ("pVReport") + @Operation(summary="管理端主平台,光伏数据报表") + private Result> pVReport(@RequestBody PVParam param){ + return boardService.pVReport(param); + } + + @PostMapping ("pVReportExport") + @Operation(summary="管理端主平台,光伏数据报表导出") + private void pVReportExport(@RequestBody PVParam param, HttpServletResponse response) { + ExcelUtils.exportExcel(boardService.pVReport(param).getData(), "光伏数据报表", null, PVReport.class, "光伏报表.xls", response); + } + + @GetMapping("deviceInfoByPlantId/{id}") + @Operation(summary="逆变器列表查询") + private Result> deviceInfoByPlantId(@PathVariable("id") Long id){ + QueryWrapper queryWrapper = QueryWrapper.create().eq(DeviceEntity::getPlantId, id).eq(DeviceEntity::getDeviceType,2); + List result = deviceMapper.selectListByQueryAs(queryWrapper,DeviceDTO.class); + result.forEach(temp->{ + DeviceDTO dto = deviceMapper.selectOneByQueryAs(QueryWrapper.create().eq(DeviceEntity::getDeviceId, temp.getUpDeviceId()),DeviceDTO.class); + try { + temp.setUpStatus(dto.getStatus()); + temp.setUpAlias(dto.getAlias()); + } catch (Exception e) { + temp.setUpStatus(1); + } + }); + + return new Result>().ok(result); + } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/controller/ManageChargeController.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/controller/ManageChargeController.java new file mode 100644 index 0000000..6c7f5dc --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/controller/ManageChargeController.java @@ -0,0 +1,80 @@ +package com.thing.qingyuan.manageboard.controller; + + +import com.thing.qingyuan.manageboard.dto.*; +import com.thing.qingyuan.manageboard.service.ManageChargeService; +import com.thing.qingyuan.screen.ScreenData; +import com.thing.common.core.utils.excel.ExcelUtils; +import com.thing.common.core.web.response.Result; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("charge/board") +@Tag(name="管理端主平台,充电站") +@RequiredArgsConstructor +public class ManageChargeController { + + + private final ManageChargeService manageChargeService; + + + @PostMapping("map") + @Operation(summary="管理端主平台-充电站地图") + private Result> mapInfoByNameAndType(@RequestBody MapParam mapParam){ + return manageChargeService.mapInfoByNameAndType(mapParam); + } + + @GetMapping("totalInfo") + @Operation(summary="管理端主平台-充电站数量,充电枪数量,年度充电量,年度充电金额等信息") + private Result totalInfo(){ + return manageChargeService.totalInfo(); + } + + @GetMapping("siteTypeInfo") + @Operation(summary="管理端主平台-年度站点类型分析") + private Result> siteTypeInfo(){ + return manageChargeService.siteTypeInfo(); + } + + @GetMapping("chargingGunState") + @Operation(summary="管理端主平台-充电枪实时状态") + private Result> chargingGunState(){ + return manageChargeService.chargingGunState(); + } + + @PostMapping("stationInfo") + @Operation(summary="管理端主平台-充电站详情") + private Result> stationInfo(@RequestBody FindParam param){ + return manageChargeService.stationInfo(param); + } + + @PostMapping ("findListByAttrCodeAndType") + @Operation(summary="管理端主平台,月充电分析/年度充电时常趋势") + private Result findListByAttrCode(@RequestBody GunDataParam dataParam){ + return manageChargeService.findListByAttrCode(dataParam); + } + + @PostMapping ("findYOYList") + @Operation(summary="管理端主平台,年发电量同比分析") + private Result> findYOYList(@RequestBody GunDataParam dataParam){ + return manageChargeService.findYOYList(dataParam); + } + + @PostMapping ("gunReport") + @Operation(summary="管理端主平台,光伏数据报表") + private Result> gunReport(@RequestBody PVParam param){ + return manageChargeService.gunReport(param); + } + + @PostMapping ("gunReportExport") + @Operation(summary="管理端主平台,充电站数据报表导出") + private void gunReportExport(@RequestBody PVParam param, HttpServletResponse response) { + ExcelUtils.exportExcel(manageChargeService.gunReport(param).getData(), "充电站数据报表", null, StationInfoReq.class, "充电站报表.xls", response); + } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/controller/PlantController.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/controller/PlantController.java new file mode 100644 index 0000000..d50fba4 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/controller/PlantController.java @@ -0,0 +1,96 @@ +package com.thing.qingyuan.manageboard.controller; + +import com.thing.qingyuan.manageboard.dto.PlantDTO; +import com.thing.qingyuan.manageboard.service.PlantService; +import com.thing.common.core.annotation.LogOperation; +import com.thing.common.core.constants.Constant; +import com.thing.common.core.web.response.PageData; +import com.thing.common.core.web.response.Result; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Map; + +/** +* 光伏项目点位信息 +* +* @author xc +* @since 3.0 2024-01-29 +*/ +@RestController +@RequestMapping("plant") +@Tag(name="光伏项目基础信息") +@RequiredArgsConstructor +public class PlantController { + private final PlantService plantService; + + @GetMapping("page") + @Operation(summary="分页") + @Parameters({ + @Parameter(name = Constant.PAGE, description = "当前页码,从1开始") , + @Parameter(name = Constant.LIMIT, description = "每页显示记录数") , + @Parameter(name = Constant.ORDER_FIELD, description = "排序字段") , + @Parameter(name = Constant.ORDER, description = "排序方式,可选值(asc、desc)"), + @Parameter(name = "buildDate", description = "建站日期"), + @Parameter(name = "area", description = "区域"), + @Parameter(name = "key", description = "站点idor名称") + }) + public Result> page(@RequestParam Map params){ + PageData page = plantService.getPageData(params, PlantDTO.class); + return new Result>().ok(page); + } + + @GetMapping("{id}") + @Operation(summary="信息") + public Result get(@PathVariable("id") Long id){ + PlantDTO data = plantService.getByIdAs(id, PlantDTO.class); + return new Result().ok(data); + } + + @GetMapping("list") + @Operation(summary="电站列表信息") + public Result> list(@RequestParam Map params){ + List plantDTOS = plantService.listAs(params, PlantDTO.class); + return new Result>().ok(plantDTOS); + } + + @PostMapping + @Operation(summary="保存") + @LogOperation("保存") + public Result save(@RequestBody PlantDTO dto){ + plantService.saveDto(dto); + return new Result<>(); + } + + @PutMapping + @Operation(summary="修改") + @LogOperation("修改") + public Result update(@RequestBody PlantDTO dto){ + plantService.updateDto(dto); + return new Result<>(); + } + + @DeleteMapping + @Operation(summary="删除") + @LogOperation("删除") + public Result delete(@RequestBody Long[] ids){ + plantService.batchDelete(ids); + return new Result<>(); + } + + + @GetMapping("export") + @Operation(summary="导出") + @LogOperation("导出") + public void export( @RequestParam Map params, HttpServletResponse response) throws Exception { + List list = plantService.listAs(params, PlantDTO.class); + //ExcelUtils.exportExcelToTarget(response, null, "光伏项目点位信息", list, PlantExcel.class); + } + +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/ChargeTotalInfo.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/ChargeTotalInfo.java new file mode 100644 index 0000000..2d17ef0 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/ChargeTotalInfo.java @@ -0,0 +1,20 @@ +package com.thing.qingyuan.manageboard.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +@Data +@Schema( description= "充电站统计信息") +public class ChargeTotalInfo { + @Schema( description= "充电站数量") + private Integer stationCount; + @Schema( description= "充电枪数量") + private Integer connectorCount; + @Schema( description= "年度充电量") + private BigDecimal yearCharge; + @Schema( description= "年充电金额") + private BigDecimal yearMoney; + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/ChargingGunState.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/ChargingGunState.java new file mode 100644 index 0000000..164203e --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/ChargingGunState.java @@ -0,0 +1,22 @@ +package com.thing.qingyuan.manageboard.dto; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Schema(description = "充电枪实时状态") +@AllArgsConstructor +@NoArgsConstructor +public class ChargingGunState { + + @Schema(description = "充电枪状态名称") + private String stateName; + @Schema(description = "充电桩状态编码") + private String stateCode; + @Schema(description = "数量") + private Integer num; + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/DataParam.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/DataParam.java new file mode 100644 index 0000000..f8b60f7 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/DataParam.java @@ -0,0 +1,22 @@ +package com.thing.qingyuan.manageboard.dto; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +@Schema(description = "查询入参") +public class DataParam { + + @Schema(description = "物编码") + private String thingCode; + @Schema(description = "属性编码 月 传A29dd,年传A29mm") + private String attrCode; + @Schema(description = "属性类型,dd 月,mm年") + private String attrType; + + private Long startTime; + + private Long endTime; + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/DataReq.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/DataReq.java new file mode 100644 index 0000000..c5bfb8c --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/DataReq.java @@ -0,0 +1,28 @@ +package com.thing.qingyuan.manageboard.dto; + +import com.thing.common.data.tskv.TsKvDTO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +@Data +@Schema(description = "用量查询,响应结果") +public class DataReq { + @Schema(description = "用量结果集合") + private List tskvs; + @Schema(description = "属性信息") + private AttrInfo attrInfo; + + @Schema(description = "属性信息") + @Data + public static class AttrInfo{ + @Schema(description = "属性编码") + private String attrCode; + @Schema(description = "属性名称") + private String attrName; + @Schema(description = "属性单位") + private String attrUint; + } + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/FindParam.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/FindParam.java new file mode 100644 index 0000000..dd93343 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/FindParam.java @@ -0,0 +1,15 @@ +package com.thing.qingyuan.manageboard.dto; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +@Schema(description = "模糊查找入参") +public class FindParam { + + @Schema(description = "项目名称/站点名称") + private String plantName; + + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/GunDataParam.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/GunDataParam.java new file mode 100644 index 0000000..54cf847 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/GunDataParam.java @@ -0,0 +1,20 @@ +package com.thing.qingyuan.manageboard.dto; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +@Schema(description = "查询入参") +public class GunDataParam { + + @Schema(description = "属性编码 充电电量: 月A29dd,年A29mm,充电时长月A201dd,年A201mm,充电次数 A202dd") + private String attrCode; + @Schema(description = "属性类型,dd 月,mm年") + private String attrType; + + private Long startTime; + + private Long endTime; + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/GunReportParam.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/GunReportParam.java new file mode 100644 index 0000000..003bfdd --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/GunReportParam.java @@ -0,0 +1,17 @@ +package com.thing.qingyuan.manageboard.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +@Schema(description = "充电站报表查询入参") +public class GunReportParam { + @Schema(description = "区域") + private String area; + @Schema(description = "站点名称") + private String stationName; + @Schema(description = "时间 月 入参 yyyy-MM 年入参 yyyy") + private String date; + @Schema(description = "时间类型 dd月,mm年") + private String dateType; +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/MapParam.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/MapParam.java new file mode 100644 index 0000000..a75af58 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/MapParam.java @@ -0,0 +1,16 @@ +package com.thing.qingyuan.manageboard.dto; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +@Schema(description = "地图统计信息请求入参") +public class MapParam { + + @Schema(description = "城市名称,全国的时候不传") + private String cityName; + @Schema(description = "类型,1全国,2全省,3全市") + private String type; + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/PVParam.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/PVParam.java new file mode 100644 index 0000000..c212c6c --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/PVParam.java @@ -0,0 +1,20 @@ +package com.thing.qingyuan.manageboard.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +@Schema(description = "光伏报表查询入参") +public class PVParam { + + @Schema(description = "区域") + private String area; + @Schema(description = "项目名称") + private String plantName; + @Schema(description = "时间 月 入参 yyyy-MM 年入参 yyyy") + private String date; + @Schema(description = "时间类型 dd月,mm年") + private String dateType; + + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/PVReport.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/PVReport.java new file mode 100644 index 0000000..abaaf23 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/PVReport.java @@ -0,0 +1,68 @@ +package com.thing.qingyuan.manageboard.dto; + + +import cn.afterturn.easypoi.excel.annotation.Excel; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +@Data +@Schema(description = "光伏项目报表") +public class PVReport { + @Schema(description = "电站Id") + private Long plantId; + @Excel(name = "序号") + private String sortStr; + @Schema(description = "电站名称") + @Excel(name = "项目名称") + private String plantName; + @Schema(description = "所属区县") + @Excel(name = "区域") + private String area; + @Schema(description = "电站装机容量 (单位:MWp)") + @Excel(name = "装机容量(MWp)") + private BigDecimal capacity = BigDecimal.ZERO; + @Schema(description = "理论发电量") + @Excel(name = "理论发电量(kWh)") + private BigDecimal theoryEnergyPhotovoltaic = BigDecimal.ZERO; + @Schema(description = "发电量") + @Excel(name = "发电量(kWh)") + private BigDecimal energyPhotovoltaic = BigDecimal.ZERO; + @Schema(description = "综合效率") + @Excel(name = "综合效率(%)") + private BigDecimal oee = BigDecimal.ZERO; + @Schema(description = "消纳量") + @Excel(name = "消纳量(kWh)") + private BigDecimal consumption = BigDecimal.ZERO; + @Schema(description = "上网电量") + @Excel(name = "上网电量(kWh)") + private BigDecimal internetUsage= BigDecimal.ZERO; + @Schema(description = "减排量") + @Excel(name = "减排量(kgCO₂)") + private BigDecimal co2 = BigDecimal.ZERO; + @Schema(description = "建站日期") + private String buildDate; + @Schema(description = "所属国家") + private String country; + @Schema(description = "所属省份") + private String province; + @Schema(description = "所属城市") + private String city; + @Schema(description = "电站所在具体地址") + private String address; + @Schema(description = "电站状态(1 正常 2 离线 3报警)") + private Integer status; + @Schema(description = "衰减率") + private BigDecimal attenuation = BigDecimal.ZERO; + @Schema(description = "日照时常") + private BigDecimal sunshine = BigDecimal.ZERO; + private Integer sort; + + public String getSortStr() { + if(sort==-1){ + return "--"; + } + return sort.toString(); + } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/PlantDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/PlantDTO.java new file mode 100644 index 0000000..87879d5 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/PlantDTO.java @@ -0,0 +1,55 @@ +package com.thing.qingyuan.manageboard.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; + +/** +* 光伏项目点位信息 +* +* @author xc +* @since 3.0 2024-01-29 +*/ +@Data +@Schema( description= "光伏项目点位信息") +public class PlantDTO implements Serializable { + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "电站Id") + private Long plantId; + @Schema(description = "电站名称") + private String plantName; + @Schema(description = "建站日期(yyyy-MM-dd)") + private String buildDate; + @Schema(description = "所属国家") + private String country; + @Schema(description = "所属省份") + private String province; + @Schema(description = "所属城市") + private String city; + @Schema(description = "所属区县") + private String area; + @Schema(description = "电站所在具体地址") + private String address; + @Schema(description = "电站状态(1 正常 2 离线 3报警)") + private Integer status; + @Schema(description = "电站装机容量 (单位:kWp)") + private BigDecimal capacity; + @Schema(description = "电站最后同步数据时间") + private String lastReportTime; + @Schema(description = "经度") + private BigDecimal longitude; + @Schema(description = "纬度") + private BigDecimal latitude; + @Schema(description = "并网日期(yyyy-MM-dd)") + private String gridDate; + @Schema(description = "衰减率") + private BigDecimal attenuation; + @Schema(description = "日照时常") + private BigDecimal sunshine; + +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/PlantInfoReq.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/PlantInfoReq.java new file mode 100644 index 0000000..a008652 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/PlantInfoReq.java @@ -0,0 +1,57 @@ +package com.thing.qingyuan.manageboard.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; + +/** +* 光伏项目点位信息 +* +* @author xc +* @since 3.0 2024-01-29 +*/ +@Data +@Schema( description= "光伏项目发电量,上网量,减排量等信息") +@AllArgsConstructor +@NoArgsConstructor +public class PlantInfoReq implements Serializable { + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "电站Id") + private Long plantId; + @Schema(description = "电站名称") + private String plantName; + @Schema(description = "建站日期") + private String buildDate; + @Schema(description = "装机容量 (单位:kWp)") + private BigDecimal capacity; + @Schema(description = "年发电量(单位:万kWh)") + private BigDecimal powerGeneration; + @Schema(description = "年上网量 (单位:万kWh)") + private BigDecimal internetUsage; + @Schema(description = "年减排量 (单位:tCO₂)") + private BigDecimal minusTCO2; + @Schema(description = "所属国家") + private String country; + @Schema(description = "所属省份") + private String province; + @Schema(description = "所属城市") + private String city; + @Schema(description = "所属区县") + private String area; + @Schema(description = "电站所在具体地址") + private String address; + @Schema(description = "电站状态(1 正常 2 离线 3报警)") + private Integer status; + @Schema(description = "衰减率") + private BigDecimal attenuation; + @Schema(description = "日照时常") + private BigDecimal sunshine; + +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/PlantReq.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/PlantReq.java new file mode 100644 index 0000000..e9be8cf --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/PlantReq.java @@ -0,0 +1,32 @@ +package com.thing.qingyuan.manageboard.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serial; +import java.io.Serializable; + +/** +* 光伏项目点位信息 +* +* @author xc +* @since 3.0 2024-01-29 +*/ +@Data +@Schema( description= "光伏项目点位信息") +@AllArgsConstructor +@NoArgsConstructor +public class PlantReq implements Serializable { + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "电站Id") + private Long plantId; + @Schema(description = "电站名称") + private String plantName; + @Schema(description = "序号") + private Integer sort = 0; + +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/ReductionStatistics.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/ReductionStatistics.java new file mode 100644 index 0000000..686d050 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/ReductionStatistics.java @@ -0,0 +1,36 @@ +package com.thing.qingyuan.manageboard.dto; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + +@Data +@Schema( description= "节能减排统计") +@NoArgsConstructor +@AllArgsConstructor +public class ReductionStatistics { + @Schema(description = "年度信息") + private ReductionInfo nowYearInfo; + @Schema(description = "总信息") + private ReductionInfo totalInfo; + + @Data + @AllArgsConstructor + @NoArgsConstructor + public static class ReductionInfo { + + @Schema(description = "属性主键") + private BigDecimal tce; + + @Schema(description = "属性名称") + private BigDecimal co2; + + @Schema(description = "属性值") + private BigDecimal tree; + + } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/SiteTypeInfo.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/SiteTypeInfo.java new file mode 100644 index 0000000..3d34c4f --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/SiteTypeInfo.java @@ -0,0 +1,30 @@ +package com.thing.qingyuan.manageboard.dto; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + +@Data +@Schema(description = "站点类型分析结果") +@NoArgsConstructor +@AllArgsConstructor +public class SiteTypeInfo { + + @Schema( description= "站点类型名称") + private String siteTypeName; + @Schema( description= "站点类型编码") + private String siteTypeCode; + @Schema( description= "年度充电量") + private BigDecimal yearCharge; + @Schema( description= "占比") + private BigDecimal proportion; + + + + + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/StationInfoReq.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/StationInfoReq.java new file mode 100644 index 0000000..67dcbb6 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/StationInfoReq.java @@ -0,0 +1,61 @@ +package com.thing.qingyuan.manageboard.dto; + + +import cn.afterturn.easypoi.excel.annotation.Excel; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +@Data +@Schema(description = "充电站详情") +public class StationInfoReq { + + @Schema(description = "充电站名称") + private String stationId; + @Excel(name = "序号") + private String sortStr; + @Schema(description = "充电站名称") + @Excel(name = "站点名称") + private String stationName; + @Schema(description = "运营商id") + private String operatorId; + @Schema(description = "区") + @Excel(name = "区域") + private String area; + @Schema(description = "运营商名称") + @Excel(name = "运营商") + private String operatorName; + @Schema( description= "充电枪数量") + @Excel(name = "充电枪数量") + private Integer gunCount = 0; + @Schema( description= "日充电量") + private BigDecimal dayCharge; + @Schema( description= "年度充电量/充电电量") + @Excel(name = "充电电量(kWh)") + private BigDecimal yearCharge = BigDecimal.ZERO; + @Schema( description= "枪均充电量") + @Excel(name = "枪均充电量(kWh/个)") + private BigDecimal gunCharge = BigDecimal.ZERO; + @Schema( description= "年度充电时常/充电时常") + @Excel(name = "充电时常(h)") + private BigDecimal yearOften = BigDecimal.ZERO; + @Schema( description= "枪均充电时常") + @Excel(name = "枪均充电时常(h/个)") + private BigDecimal gunChargeCount = BigDecimal.ZERO; + @Schema( description= "年度充电次数/充电次数") + @Excel(name = "充电次数(次)") + private BigDecimal yearChargeCount = BigDecimal.ZERO; + @Schema( description= "枪均充电次数") + @Excel(name = "枪均充电次数(次/个)") + private BigDecimal gunOften; + @Schema( description= "序号") + private Integer sort=0; + + public String getSortStr() { + if(sort==-1){ + return "--"; + } + return sort.toString(); + } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/TotalInfo.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/TotalInfo.java new file mode 100644 index 0000000..93df2ba --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/TotalInfo.java @@ -0,0 +1,27 @@ +package com.thing.qingyuan.manageboard.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serial; +import java.math.BigDecimal; + +@Data +@Schema( description= "光伏项目统计信息") +public class TotalInfo { + + + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "光伏数量") + private Integer num =0; + @Schema(description = "电站装机容量 (单位:MWp)") + private BigDecimal capacity = BigDecimal.ZERO; + @Schema(description = "年发电量(单位:万kWh)") + private BigDecimal electricityUsage = BigDecimal.ZERO; + @Schema(description = "年度收益(单位:万元)") + private BigDecimal income = BigDecimal.ZERO; + + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/YOYDataReq.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/YOYDataReq.java new file mode 100644 index 0000000..526e721 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/dto/YOYDataReq.java @@ -0,0 +1,39 @@ +package com.thing.qingyuan.manageboard.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; +import java.math.RoundingMode; + +@Data +@Schema(description = "年发电量同比") +public class YOYDataReq { + @Schema(description = "时间") + private Long ts; + @Schema(description = "今年发/冲电量") + private BigDecimal nowYearVal; + @Schema(description = "去年发/冲电量") + private BigDecimal lastYearVal; + @Schema(description = "同比") + private String yoy; + @Schema(description = "属性单位") + private String unit; + @Schema(description = "属性名称") + private String attrName; + @Schema(description = "属性编码") + private String attrCode; + + + public String getYoy() { + if(nowYearVal.compareTo(BigDecimal.ZERO)==0){ + return "--"; + } + BigDecimal difference = nowYearVal.subtract(lastYearVal); + try { + return difference.divide(lastYearVal, 4, RoundingMode.HALF_UP).toString(); + } catch (Exception e) { + return "--"; + } + } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/entity/PlantEntity.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/entity/PlantEntity.java new file mode 100644 index 0000000..b4910db --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/entity/PlantEntity.java @@ -0,0 +1,90 @@ +package com.thing.qingyuan.manageboard.entity; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.Table; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 光伏项目点位信息 + * + * @author xc + * @since 3.0 2024-01-29 + */ +@Data +@EqualsAndHashCode(callSuper=false) +@Table(value = "plant",dataSource = "systemCollect") +public class PlantEntity implements Serializable { + @Serial + private static final long serialVersionUID = 1L; + + /** + * 电站Id + */ + @Id + private Long plantId; + /** + * 电站名称 + */ + private String plantName; + /** + * 建站日期(yyyy-MM-dd) + */ + private String buildDate; + /** + * 所属国家 + */ + private String country; + /** + * 所属省份 + */ + private String province; + /** + * 所属城市 + */ + private String city; + /** + * 所属区县 + */ + private String area; + /** + * 电站所在具体地址 + */ + private String address; + /** + * 电站状态(1 正常 2 离线 3报警) + */ + private Integer status; + /** + * 电站装机容量 (单位:kWp) + */ + private BigDecimal capacity; + /** + * 电站最后同步数据时间 + */ + private String lastReportTime; + /** + * 经度 + */ + private BigDecimal longitude; + /** + * 纬度 + */ + private BigDecimal latitude; + /** + * 并网日期(yyyy-MM-dd) + */ + private String gridDate; + /** + * 衰减率 + */ + private BigDecimal attenuation; + /** + * 日照时常 + */ + private BigDecimal sunshine; +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/mapper/PlantMapper.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/mapper/PlantMapper.java new file mode 100644 index 0000000..6846fc6 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/mapper/PlantMapper.java @@ -0,0 +1,18 @@ +package com.thing.qingyuan.manageboard.mapper; + +import com.mybatisflex.annotation.UseDataSource; +import com.thing.qingyuan.manageboard.entity.PlantEntity; +import com.thing.common.orm.mapper.PowerBaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** +* 光伏项目点位信息 +* +* @author xc +* @since 3.0 2024-01-29 +*/ +@Mapper +@UseDataSource("systemCollect") +public interface PlantMapper extends PowerBaseMapper { + +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/service/ManageBoardService.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/service/ManageBoardService.java new file mode 100644 index 0000000..01fa366 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/service/ManageBoardService.java @@ -0,0 +1,29 @@ +package com.thing.qingyuan.manageboard.service; + +import com.thing.qingyuan.alert.dto.AlertDTO; +import com.thing.qingyuan.manageboard.dto.*; +import com.thing.qingyuan.screen.ScreenData; +import com.thing.common.core.web.response.Result; + +import java.util.List; + +public interface ManageBoardService { + + Result> mapInfoByNameAndType(MapParam mapParam); + + Result> plantList(); + + Result> plantInfoList(FindParam param); + + Result totalInfo(); + + Result reduction(); + + Result> alertList(); + + Result findListByAttrCodeAndType(DataParam dataParam); + + Result> findYOYList(DataParam dataParam); + + Result> pVReport(PVParam param); +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/service/ManageChargeService.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/service/ManageChargeService.java new file mode 100644 index 0000000..3e2e16b --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/service/ManageChargeService.java @@ -0,0 +1,25 @@ +package com.thing.qingyuan.manageboard.service; + +import com.thing.qingyuan.manageboard.dto.*; +import com.thing.qingyuan.screen.ScreenData; +import com.thing.common.core.web.response.Result; + +import java.util.List; + +public interface ManageChargeService { + Result> mapInfoByNameAndType(MapParam mapParam); + + Result totalInfo(); + + Result> siteTypeInfo(); + + Result> chargingGunState(); + + Result> stationInfo(FindParam param); + + Result findListByAttrCode(GunDataParam dataParam); + + Result> findYOYList(GunDataParam dataParam); + + Result> gunReport(PVParam param); +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/service/PlantService.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/service/PlantService.java new file mode 100644 index 0000000..cdebed7 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/service/PlantService.java @@ -0,0 +1,25 @@ +package com.thing.qingyuan.manageboard.service; + + +import com.thing.qingyuan.manageboard.dto.MapParam; +import com.thing.qingyuan.manageboard.dto.PlantDTO; +import com.thing.qingyuan.manageboard.dto.PlantInfoReq; +import com.thing.qingyuan.manageboard.entity.PlantEntity; +import com.thing.common.orm.service.IBaseService; + +import java.util.List; +import java.util.Map; + +/** + * 光伏项目点位信息 + * + * @author xc + * @since 3.0 2024-01-29 + */ +public interface PlantService extends IBaseService { + + Map> findByParam(MapParam mapParam); + + List findByName(String plantName,String area); + +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/service/impl/ManageBoardServiceImpl.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/service/impl/ManageBoardServiceImpl.java new file mode 100644 index 0000000..95e9a20 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/service/impl/ManageBoardServiceImpl.java @@ -0,0 +1,551 @@ +package com.thing.qingyuan.manageboard.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.thing.carbon.energyrepory.dto.EnergyTimeLabelData; +import com.thing.qingyuan.alert.dto.AlertDTO; +import com.thing.qingyuan.alert.service.AlertService; +import com.thing.qingyuan.manageboard.dto.*; +import com.thing.qingyuan.manageboard.entity.PlantEntity; +import com.thing.qingyuan.manageboard.service.ManageBoardService; +import com.thing.qingyuan.manageboard.service.PlantService; +import com.thing.qingyuan.screen.ScreenData; +import com.thing.qingyuan.util.CalculationUtil; +import com.thing.common.core.enumeration.AttributeTypeEnum; +import com.thing.common.core.utils.ConvertUtils; +import com.thing.common.core.utils.DateTimeUtils; +import com.thing.common.core.web.response.Result; +import com.thing.common.data.tskv.TsKvDTO; +import com.thing.common.tskv.service.TsKvService; +import com.thing.thing.dict.dto.IotThingDictDTO; +import com.thing.thing.dict.service.IotThingDictService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.*; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +public class ManageBoardServiceImpl implements ManageBoardService { + + + private final PlantService plantService; + + private final TsKvService tskvService; + + private final AlertService alertService; + + private final IotThingDictService iotThingDictService; + @Override + public Result> mapInfoByNameAndType(MapParam mapParam) { + List result = new ArrayList<>(); + Map> infoList = plantService.findByParam(mapParam); + if(mapParam.getType().equals("3")||mapParam.getType().equals("4")){ + //全市的话,按个统计 + List dtos =infoList.values().stream() + .flatMap(List::stream) + .toList(); + this.getAttrDataWithArea(dtos,result); + }else { + infoList.forEach((key, value) -> { + ScreenData screenData = new ScreenData(); + screenData.setName(key); + this.getAttrDataWithCity(value,screenData); + result.add(screenData); + }); + } + return new Result>().ok(result); + } + + @Override + public Result> plantList() { + List reqs = new ArrayList<>(); + PlantReq req = new PlantReq(1000l,"总发电量",999); + reqs.add(req); + reqs.addAll(ConvertUtils.sourceToTarget(plantService.list(),PlantReq.class)); + return new Result>().ok(reqs); + } + + @Override + public Result> plantInfoList(FindParam param) { + List reqs = plantService.findByName(param.getPlantName(),null); + reqs.forEach(temp->{ + List tsKvDTOS = tskvService.findLatestByCodeAndAttrs(temp.getPlantId().toString(),List.of("A29yy","A30yy"),false); + Map> map = tsKvDTOS.stream() + .collect(Collectors.groupingBy(TsKvDTO::getAttrKey)); + BigDecimal a29yy = BigDecimal.ZERO; // 初始化a29yy + BigDecimal a30yy = BigDecimal.ZERO; // 初始化a30yy + BigDecimal co2 = BigDecimal.ZERO; // 初始化a30yy + + for (Map.Entry> entry : map.entrySet()) { + String key = entry.getKey(); + List val = entry.getValue(); + if (key.equals("A29yy")) { + a29yy = val.stream().findFirst().map(dto -> new BigDecimal(dto.getVal())).orElse(BigDecimal.ZERO); + try { + co2 = a29yy.multiply(BigDecimal.valueOf(0.000475)).setScale(4, RoundingMode.HALF_UP); + a29yy = a29yy.divide(BigDecimal.valueOf(10000),4,RoundingMode.HALF_UP); + } catch (Exception e) { + a29yy=BigDecimal.ZERO; + co2=BigDecimal.ZERO; + } + } else if (key.equals("A30yy")) { + a30yy = val.stream().findFirst().map(dto -> new BigDecimal(dto.getVal())).orElse(BigDecimal.ZERO); + try { + a30yy = a30yy.divide(BigDecimal.valueOf(10000L), 4,RoundingMode.UP); + } catch (Exception e) { + a30yy= BigDecimal.ZERO; + } + } + } + temp.setInternetUsage(a30yy); + temp.setPowerGeneration(a29yy); + temp.setMinusTCO2(co2); + }); + reqs.sort((p1, p2) -> p2.getPowerGeneration().compareTo(p1.getPowerGeneration())); + return new Result>().ok(reqs); + } + + @Override + public Result totalInfo() { + TotalInfo result = new TotalInfo(); + List list = plantService.list(); + BigDecimal sumA29yy = nowTotalA29yy(); + BigDecimal totalCapacity = list.stream() + .map(PlantEntity::getCapacity) + .reduce(BigDecimal.ZERO, BigDecimal::add); + result.setNum(list.size()); + result.setElectricityUsage(sumA29yy.setScale(4,RoundingMode.UP)); + result.setCapacity(totalCapacity); + //todo 这里先写死为光伏租户得物编码,后续再调整 + List kvDTOS = tskvService.findLatestByCodeAndAttrs("CO_1751771289957244928",List.of("A301"),false); + if(!kvDTOS.isEmpty()){ + result.setIncome(BigDecimal.valueOf(Long.parseLong(kvDTOS.stream().findFirst().get().getVal()))); + } + return new Result().ok(result); + } + + @Override + public Result reduction() { + BigDecimal nowTotalA29yy = this.nowTotalA29yy(); + BigDecimal allTotalA29yy = this.AllTotalA29yy(); + BigDecimal tceRatio = BigDecimal.valueOf(0.0004); + BigDecimal co2Ratio = BigDecimal.valueOf(0.000475); + BigDecimal treeRatio = BigDecimal.valueOf(18.3).divide(BigDecimal.valueOf(40),8,RoundingMode.UP).multiply(BigDecimal.valueOf(1000)); + + ReductionStatistics.ReductionInfo nowYearInfo = new ReductionStatistics.ReductionInfo(); + nowYearInfo.setTce(nowTotalA29yy.multiply(tceRatio).setScale(4,RoundingMode.UP)); + nowYearInfo.setCo2(nowTotalA29yy.multiply(co2Ratio).setScale(4,RoundingMode.UP)); + nowYearInfo.setTree(nowYearInfo.getCo2().multiply(treeRatio).setScale(4,RoundingMode.UP)); + + ReductionStatistics.ReductionInfo allInfo = new ReductionStatistics.ReductionInfo(); + allInfo.setTce(allTotalA29yy.multiply(tceRatio).setScale(4,RoundingMode.UP)); + allInfo.setCo2(allTotalA29yy.multiply(co2Ratio).setScale(4,RoundingMode.UP)); + allInfo.setTree(allInfo.getCo2().multiply(treeRatio).setScale(4,RoundingMode.UP)); + ReductionStatistics result = new ReductionStatistics(nowYearInfo,allInfo); + + return new Result().ok(result); + } + + @Override + public Result> alertList() { + List alertDTOS = alertService.listAs(new HashMap<>(),AlertDTO.class); + alertDTOS.sort((p1, p2) -> p2.getStartTime().compareTo(p1.getStartTime())); + return new Result>().ok(alertDTOS); + } + + + @Override + public Result findListByAttrCodeAndType(DataParam dataParam) { + DataReq req = new DataReq(); + Long startTime; + Long endTime; + if(ObjectUtil.isNotEmpty(dataParam.getStartTime())&&ObjectUtil.isNotEmpty(dataParam.getEndTime())&&dataParam.getStartTime()!=0){ + startTime = dataParam.getStartTime(); + endTime = dataParam.getEndTime(); + }else { + if(dataParam.getAttrType().equals("dd")){ + startTime= DateTimeUtils.getMonthBeginTimestamp(System.currentTimeMillis()); + }else { + startTime = DateTimeUtils.getYearBeginTimestamp(System.currentTimeMillis()); + } + endTime = DateTimeUtils.getMonthEndTimestamp(System.currentTimeMillis()); + } + AttributeTypeEnum attributeTypeEnum = AttributeTypeEnum.match(dataParam.getAttrType()); + Instant instant = Instant.ofEpochMilli(startTime); + LocalDateTime dateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()); + List timeRange = attributeTypeEnum.getTimeRange(dateTime); + List energyTimeLabelData = this.generateEmptyData(timeRange, dataParam.getAttrType()); + List tskvs = new ArrayList<>(); + if (dataParam.getThingCode().equals("1000")) { + List list = plantService.list(); + List entityCodes = list.stream().map(PlantEntity::getPlantId).map(String::valueOf).toList(); + tskvs = tskvService.findTsKvByCodesAndAttrs(entityCodes,List.of(dataParam.getAttrCode()),startTime,endTime,false); + }else { + tskvs = tskvService.findTsKvByCodeAndAttr(dataParam.getThingCode(),dataParam.getAttrCode(),startTime,endTime,false); + } + Map> tsMap = tskvs.stream() + .collect(Collectors.groupingBy(TsKvDTO::getTs)); + List allInfo = new ArrayList<>(); + energyTimeLabelData.forEach(temp->{ + if(ObjectUtil.isNotEmpty(tsMap.get(temp.getTs()))){ + BigDecimal val = tsMap.get(temp.getTs()).stream().map(dto -> new BigDecimal(dto.getVal())) + .reduce(BigDecimal.ZERO, BigDecimal::add); + TsKvDTO tskv = new TsKvDTO(dataParam.getThingCode(),dataParam.getAttrCode(),temp.getTs(),val.setScale(4,RoundingMode.UP).toString()); + allInfo.add(tskv); + }else { + TsKvDTO tskv = new TsKvDTO(dataParam.getThingCode(),dataParam.getAttrCode(),temp.getTs(),BigDecimal.ZERO.toString()); + allInfo.add(tskv); + } + }); + req.setTskvs(allInfo); + DataReq.AttrInfo attrInfo = new DataReq.AttrInfo(); + IotThingDictDTO dictDTO = iotThingDictService.findDictByCode(dataParam.getAttrCode()); + attrInfo.setAttrCode(dictDTO.getCode()); + attrInfo.setAttrName(dictDTO.getName()); + attrInfo.setAttrUint(dictDTO.getUnit()); + req.setAttrInfo(attrInfo); + return new Result().ok(req); + } + + @Override + public Result> findYOYList(DataParam dataParam) { + List result = new ArrayList<>(); + + DataReq nowYearList = this.findListByAttrCodeAndType(dataParam).getData(); + dataParam.setStartTime(DateTimeUtils.fistDayOfLastYear()); + dataParam.setEndTime(DateTimeUtils.lastDayOfLastYear()); + DataReq lastYearList = this.findListByAttrCodeAndType(dataParam).getData(); + List last = lastYearList.getTskvs(); + Map> groupedMap = last.stream() + .collect(Collectors.groupingBy(dto -> Instant.ofEpochMilli(dto.getTs()) + .atZone(ZoneId.systemDefault()) + .toLocalDateTime() + .getMonth().getValue())); + + nowYearList.getTskvs().forEach(temp->{ + YOYDataReq req = new YOYDataReq(); + LocalDate date = LocalDate.ofEpochDay(temp.getTs() / 86400000); // 将毫秒时间戳转换为 LocalDate 对象 + Integer month = date.getMonthValue(); + req.setTs(temp.getTs()); + req.setAttrName(nowYearList.getAttrInfo().getAttrName()); + req.setAttrCode(nowYearList.getAttrInfo().getAttrCode()); + req.setUnit(nowYearList.getAttrInfo().getAttrUint()); + List tsKvDTOS = groupedMap.get(month); + if(ObjectUtil.isNotEmpty(tsKvDTOS)){ + req.setLastYearVal(new BigDecimal(tsKvDTOS.stream().findFirst().get().getVal())); + } + req.setNowYearVal(new BigDecimal(temp.getVal())); + result.add(req); + }); + return new Result>().ok(result); + } + + @Override + public Result> pVReport(PVParam param) { + List reqs = plantService.findByName(param.getPlantName(),param.getArea()); + List result = ConvertUtils.sourceToTarget(reqs,PVReport.class); + LocalDateTime startTime = getBeginTime(param.getDateType(),param.getDate()); + Instant instant = startTime.atZone(ZoneId.systemDefault()).toInstant(); + long startTs = instant.toEpochMilli(); + long endTs = startTs+1000L; + PVReport total = new PVReport(); + total.setPlantName("合计"); + total.setArea("--"); + total.setSort(-1); + int sort = 1; + for (PVReport report : result) { + if(param.getDateType().equals("dd")){ + getDataWithMonth(report,startTs,endTs,total); + }else { + getDataWithYear(report,startTs,endTs,total); + } + report.setSort(sort++); + } + total.setOee(total.getOee().divide(BigDecimal.valueOf(result.size()),4,RoundingMode.UP)); + result.add(total); + result.sort(Comparator.comparing(PVReport::getSort)); + return new Result>().ok(result); + } + + /** + * 按月份统计报表 + * @param report + */ + private void getDataWithYear(PVReport report,Long startTs,Long endTs,PVReport total){ + //间隔年份 + Integer yearsPassed = DateTimeUtils.yearsPassed(report.getBuildDate()); + //日照时常 + BigDecimal hour = report.getSunshine(); + BigDecimal theoryPowerGeneration = CalculationUtil.theoryPowerGeneration(report.getCapacity(),hour,report.getAttenuation(),yearsPassed); + report.setTheoryEnergyPhotovoltaic(theoryPowerGeneration); + List tsKvDTOS = tskvService.findTsKvByCodeAndAttrs(report.getPlantId().toString(),List.of("A29yy","A30yy"),startTs,endTs,false); + Map> map = tsKvDTOS.stream() + .collect(Collectors.groupingBy(TsKvDTO::getAttrKey)); + BigDecimal a29yy = BigDecimal.ZERO; + BigDecimal a30yy = BigDecimal.ZERO; + for (Map.Entry> entry : map.entrySet()) { + String key = entry.getKey(); + List val = entry.getValue(); + if (key.equals("A29yy")) { + a29yy = val.stream().findFirst().map(dto -> new BigDecimal(dto.getVal())).orElse(BigDecimal.ZERO); + } else if (key.equals("A30yy")) { + a30yy = val.stream().findFirst().map(dto -> new BigDecimal(dto.getVal())).orElse(BigDecimal.ZERO); + } + } + report.setInternetUsage(a30yy.setScale(4,RoundingMode.UP)); + report.setEnergyPhotovoltaic(a29yy.setScale(4,RoundingMode.UP)); + report.setConsumption(a29yy.subtract(a30yy).setScale(4,RoundingMode.UP)); + try { + report.setOee(a29yy.divide(report.getTheoryEnergyPhotovoltaic(),4,RoundingMode.UP).multiply(new BigDecimal(100))); + } catch (Exception e) { + report.setOee(BigDecimal.ZERO); + } + report.setCo2(a29yy.multiply(BigDecimal.valueOf(0.475)).setScale(4,RoundingMode.UP)); + total.setEnergyPhotovoltaic(total.getEnergyPhotovoltaic().add(report.getEnergyPhotovoltaic()).setScale(4,RoundingMode.UP)); + total.setCapacity(total.getCapacity().add(report.getCapacity()).setScale(4,RoundingMode.UP)); + total.setOee(total.getOee().add(report.getOee()).setScale(4,RoundingMode.UP)); + total.setConsumption(total.getConsumption().add(report.getConsumption()).setScale(4,RoundingMode.UP)); + total.setInternetUsage(total.getInternetUsage().add(report.getInternetUsage()).setScale( 4,RoundingMode.UP)); + total.setCo2(total.getCo2().add(report.getCo2()).setScale(4,RoundingMode.UP)); + total.setTheoryEnergyPhotovoltaic(total.getTheoryEnergyPhotovoltaic().add(report.getTheoryEnergyPhotovoltaic()).setScale(4,RoundingMode.UP)); + } + + + + + /** + * 按月份统计报表 + * @param report + */ + private void getDataWithMonth(PVReport report,Long startTs,Long endTs,PVReport total){ + //间隔年份 + Integer yearsPassed = DateTimeUtils.yearsPassed(report.getBuildDate()); + //日照时常 + BigDecimal hour = report.getSunshine().divide(BigDecimal.valueOf(12),4,RoundingMode.UP); + BigDecimal theoryPowerGeneration = CalculationUtil.theoryPowerGeneration(report.getCapacity(),hour,report.getAttenuation(),yearsPassed); + report.setTheoryEnergyPhotovoltaic(theoryPowerGeneration); + List tsKvDTOS = tskvService.findTsKvByCodeAndAttrs(report.getPlantId().toString(),List.of("A29mm","A30mm"),startTs,endTs,false); + Map> map = tsKvDTOS.stream() + .collect(Collectors.groupingBy(TsKvDTO::getAttrKey)); + BigDecimal a29mm = BigDecimal.ZERO; // 初始化a29yy + BigDecimal a30mm = BigDecimal.ZERO; // 初始化a16 + for (Map.Entry> entry : map.entrySet()) { + String key = entry.getKey(); + List val = entry.getValue(); + if (key.equals("A29mm")) { + a29mm = val.stream().findFirst().map(dto -> new BigDecimal(dto.getVal())).orElse(BigDecimal.ZERO); + } else if (key.equals("A30mm")) { + a30mm = val.stream().findFirst().map(dto -> new BigDecimal(dto.getVal())).orElse(BigDecimal.ZERO); + } + } + report.setInternetUsage(a30mm.setScale(4,RoundingMode.UP)); + report.setEnergyPhotovoltaic(a29mm.setScale(4,RoundingMode.UP)); + report.setConsumption(a29mm.subtract(a30mm).setScale(4,RoundingMode.UP)); + try { + report.setOee(a29mm.divide(report.getTheoryEnergyPhotovoltaic(),4,RoundingMode.UP).multiply(new BigDecimal(100))); + } catch (Exception e) { + report.setOee(BigDecimal.ZERO); + } + report.setCo2(a29mm.multiply(BigDecimal.valueOf(0.475)).setScale(4,RoundingMode.UP)); + total.setEnergyPhotovoltaic(total.getEnergyPhotovoltaic().add(report.getEnergyPhotovoltaic()).setScale(4,RoundingMode.UP)); + total.setCapacity(total.getCapacity().add(report.getCapacity()).setScale(4,RoundingMode.UP)); + total.setOee(total.getOee().add(report.getOee()).setScale(4,RoundingMode.UP)); + total.setConsumption(total.getConsumption().add(report.getConsumption()).setScale(4,RoundingMode.UP)); + total.setInternetUsage(total.getInternetUsage().add(report.getInternetUsage()).setScale(4,RoundingMode.UP)); + total.setCo2(total.getCo2().add(report.getCo2()).setScale(4,RoundingMode.UP)); + total.setTheoryEnergyPhotovoltaic(total.getTheoryEnergyPhotovoltaic().add(report.getTheoryEnergyPhotovoltaic()).setScale(4,RoundingMode.UP)); + } + + + /** + * 本年,所有光伏项目总发电量 + * @return + */ + private BigDecimal nowTotalA29yy(){ + List list = plantService.list(); + List entityCodes = list.stream().map(PlantEntity::getPlantId).map(String::valueOf).toList(); + List tsKvDTOS = tskvService.findLatestByCodesAndAttrs(entityCodes,List.of("A29yy"),false); + return tsKvDTOS.stream() + .map(dto -> new BigDecimal(dto.getVal())) + .reduce(BigDecimal.ZERO, BigDecimal::add); + } + + /** + * 光伏项目所有历史发电量总合 + * @return + */ + private BigDecimal AllTotalA29yy(){ + List list = plantService.list(); + List entityCodes = list.stream().map(PlantEntity::getPlantId).map(String::valueOf).toList(); + List tsKvDTOS = tskvService.findTsKvByCodesAndAttrs(entityCodes,List.of("A29yy"),1701360000000L,System.currentTimeMillis(),false); + return tsKvDTOS.stream() + .map(dto -> new BigDecimal(dto.getVal())) + .reduce(BigDecimal.ZERO, BigDecimal::add); + } + + + /** + * 区统计 + * @param dtos + */ + private void getAttrDataWithArea(List dtos,List result){ + dtos.forEach(temp->{ + ScreenData screenData = new ScreenData(); + List data = new ArrayList<>(); + screenData.setName(temp.getPlantName()); + screenData.setLon(temp.getLongitude()); + screenData.setLat(temp.getLatitude()); + List tsKvDTOS = tskvService.findLatestByCodeAndAttrs(temp.getPlantId().toString(),List.of("A29yy","A16"),false); + Map> map = tsKvDTOS.stream() + .collect(Collectors.groupingBy(TsKvDTO::getAttrKey)); + BigDecimal a29yy = BigDecimal.ZERO; // 初始化a29yy + BigDecimal a16 = BigDecimal.ZERO; // 初始化a16 + for (Map.Entry> entry : map.entrySet()) { + String key = entry.getKey(); + List val = entry.getValue(); + if (key.equals("A29yy")) { + a29yy = val.stream().findFirst().map(dto -> new BigDecimal(dto.getVal())).orElse(BigDecimal.ZERO); + try { + a29yy = a29yy.divide(BigDecimal.valueOf(10000), 4,RoundingMode.UP); + } catch (Exception e) { + a29yy=BigDecimal.ZERO; + } + } else if (key.equals("A16")) { + a16 = val.stream().findFirst().map(dto -> new BigDecimal(dto.getVal())).orElse(BigDecimal.ZERO); + try { + a16 = a16.divide(BigDecimal.valueOf(1000L), 4,RoundingMode.UP); + } catch (Exception e) { + a16= BigDecimal.ZERO; + } + } + } + //装机容量 + BigDecimal capacity = temp.getCapacity(); + ScreenData.AttrData capacityData = new ScreenData.AttrData(); + capacityData.setAttrName("装机容量"); + capacityData.setAttrValue(String.valueOf(capacity)); + capacityData.setAttrUnit("kWp"); + data.add(capacityData); + ScreenData.AttrData a29yyData = new ScreenData.AttrData(); + a29yyData.setAttrName("年发电量"); + a29yyData.setAttrValue(a29yy.toString()); + a29yyData.setAttrUnit("万kWh"); + data.add(a29yyData); + ScreenData.AttrData a16Data = new ScreenData.AttrData(); + a16Data.setAttrName("发电功率"); + a16Data.setAttrValue(a16.toString()); + a16Data.setAttrUnit("KW"); + data.add(a16Data); + ScreenData.AttrData cop = new ScreenData.AttrData(); + cop.setAttrName("性能比"); + try { + cop.setAttrValue(String.valueOf(a16.divide(capacity,RoundingMode.UP).multiply(BigDecimal.valueOf(100)))); + } catch (Exception e) { + cop.setAttrValue(BigDecimal.ZERO.toString()); + } + cop.setAttrUnit("%"); + data.add(cop); + screenData.setData(data); + result.add(screenData); + }); + } + + /** + * 省,市 统计 + * @param dtos + * @param screenData + */ + private void getAttrDataWithCity(List dtos,ScreenData screenData){ + List data = new ArrayList<>(); + + BigDecimal totalCapacity = dtos.stream() + .map(PlantDTO::getCapacity) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + List thingCodes = dtos.stream() + .map(dto -> String.valueOf(dto.getPlantId())) + .toList(); + List attrCode = List.of("A29yy"); + List tsKvDTOS = tskvService.findLatestByCodesAndAttrs(thingCodes,attrCode,false); + BigDecimal sumA29yy = tsKvDTOS.stream() + .map(dto -> new BigDecimal(dto.getVal())) + .reduce(BigDecimal.ZERO, BigDecimal::add); + try { + sumA29yy.divide(BigDecimal.valueOf(10000)); + } catch (Exception e) { + sumA29yy=BigDecimal.ZERO; + } + ScreenData.AttrData numData = new ScreenData.AttrData(); + numData.setAttrName("站点数量"); + numData.setAttrValue(String.valueOf(dtos.size())); + numData.setAttrUnit("个"); + data.add(numData); + + ScreenData.AttrData zjrl = new ScreenData.AttrData(); + zjrl.setAttrName("装机容量"); + zjrl.setAttrValue(String.valueOf(totalCapacity)); + zjrl.setAttrUnit("kWp"); + data.add(zjrl); + + ScreenData.AttrData sum = new ScreenData.AttrData(); + sum.setAttrName("年发电量"); + sum.setAttrValue(String.valueOf(sumA29yy)); + sum.setAttrUnit("万kWh"); + data.add(sum); + screenData.setData(data); + } + + + + + + /** + * 按指定时间范围生成全量空数据 + * @param timeRange 时间范围 + * @param attrType 属性类型 + * @return 空数据列表 + */ + private List generateEmptyData( + List timeRange, String attrType) { + return timeRange.stream() + .map( + t -> + new EnergyTimeLabelData( + DateTimeUtils.parse(t), + EnergyTimeLabelData.getByAttrType(attrType), + null)) + .collect(Collectors.toList()); + } + + + + + @SuppressWarnings("Duplicates") + public LocalDateTime getBeginTime(String dateType,String dateStr) { + AttributeTypeEnum attributeTypeEnum = AttributeTypeEnum.match(dateType); + switch (attributeTypeEnum) { + case am, hh -> { + // yyyy-MM-dd + return DateTimeUtils.parseDateTime(dateStr + " 00:00:00"); + } + case dd -> { + // yyyy-MM + return DateTimeUtils.parseDateTime(dateStr + "-01 00:00:00"); + } + case mm -> { + // yyyy + return DateTimeUtils.parseDateTime(dateStr + "-01-01 00:00:00"); + } + default -> { + } + } + return null; + } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/service/impl/ManageChargeServiceImpl.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/service/impl/ManageChargeServiceImpl.java new file mode 100644 index 0000000..07d9e8e --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/service/impl/ManageChargeServiceImpl.java @@ -0,0 +1,557 @@ +package com.thing.qingyuan.manageboard.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.thing.carbon.energyrepory.dto.EnergyTimeLabelData; +import com.thing.qingyuan.chargeStation.config.StationProperties; +import com.thing.qingyuan.chargeStation.dto.ConnectorStatusInfo; +import com.thing.qingyuan.chargeStation.dto.StationInfoDTO; +import com.thing.qingyuan.chargeStation.entity.StationInfoEntity; +import com.thing.qingyuan.chargeStation.mapper.ConnectorInfoMapper; +import com.thing.qingyuan.chargeStation.service.StationInfoService; +import com.thing.qingyuan.manageboard.dto.*; +import com.thing.qingyuan.manageboard.service.ManageChargeService; +import com.thing.qingyuan.screen.ScreenData; +import com.thing.common.core.constants.Constant; +import com.thing.common.core.enumeration.AttributeTypeEnum; +import com.thing.common.core.utils.ConvertUtils; +import com.thing.common.core.utils.DateTimeUtils; +import com.thing.common.core.web.response.Result; +import com.thing.common.data.tskv.TsKvDTO; +import com.thing.common.tskv.service.TsKvService; +import com.thing.thing.dict.dto.IotThingDictDTO; +import com.thing.thing.dict.service.IotThingDictService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.*; +import java.util.stream.Collectors; + + +@Service +@RequiredArgsConstructor +public class ManageChargeServiceImpl implements ManageChargeService { + + private final TsKvService tskvService; + + private final IotThingDictService iotThingDictService; + + private final StationInfoService stationInfoService; + + private final ConnectorInfoMapper connectorInfoMapper; + private final StationProperties stationProperties; + + @Override + public Result> mapInfoByNameAndType(MapParam mapParam) { + List result = new ArrayList<>(); + Map> infoList = stationInfoService.findByParam(mapParam); + if(mapParam.getType().equals("3")||mapParam.getType().equals("4")){ + //全市的话,按个统计 + List dtos =infoList.values().stream() + .flatMap(List::stream) + .toList(); + this.getAttrDataWithArea(dtos,result); + }else { + infoList.forEach((key, value) -> { + ScreenData screenData = new ScreenData(); + screenData.setName(key); + this.getAttrDataWithCity(value,screenData); + result.add(screenData); + }); + } + return new Result>().ok(result); + } + + @Override + public Result totalInfo() { + ChargeTotalInfo result = new ChargeTotalInfo(); + List dtos = stationInfoService.list(); + List stationIds = dtos.stream() + .map(dto -> String.valueOf(dto.getStationId())) + .toList(); + Integer connectorCount = connectorInfoMapper.getCountByStationIds(stationIds); + result.setStationCount(dtos.size()); + result.setConnectorCount(connectorCount); + List tsKvDTOS = tskvService.findLatestByCodesAndAttrs(stationIds, List.of("A29yy", "A204yy"), false); + Map> map = tsKvDTOS.stream() + .collect(Collectors.groupingBy(TsKvDTO::getAttrKey)); + BigDecimal a29yy = sumValuesForKey(map, "A29yy"); + BigDecimal a204yy = sumValuesForKey(map, "A204yy"); + result.setYearCharge(a29yy); + result.setYearMoney(a204yy); + return new Result().ok(result); + } + + /** + * 根据key的值 获取对应的属性合 + * @param map + * @param key + * @return + */ + private BigDecimal sumValuesForKey(Map> map, String key) { + return map.getOrDefault(key, List.of()).stream() + .map(dto -> new BigDecimal(dto.getVal())) + .reduce(BigDecimal.ZERO, BigDecimal::add) + .setScale(4, RoundingMode.UP); + } + + @Override + public Result> siteTypeInfo() { + List dtos = stationInfoService.list(); + Map> map = dtos.stream() + .collect(Collectors.groupingBy(StationInfoEntity::getStationType)); + BigDecimal totalA29 = BigDecimal.ZERO; + List result = new ArrayList<>(); + for (Map.Entry> entry : map.entrySet()) { + Integer key = entry.getKey(); + List val = entry.getValue(); + List stationIds = val.stream() + .map(dto -> String.valueOf(dto.getStationId())) + .toList(); + List tsKvDTOS = tskvService.findLatestByCodesAndAttrs(stationIds, List.of("A29yy"), false); + + BigDecimal a29yy = tsKvDTOS.stream() + .map(dto -> new BigDecimal(dto.getVal())) + .reduce(BigDecimal.ZERO, BigDecimal::add); + BigDecimal yearPower = a29yy.divide(BigDecimal.valueOf(100), 4, RoundingMode.UP); + + String name = Constant.CARTYPES.get(key); + SiteTypeInfo info = new SiteTypeInfo(name, key.toString(), yearPower, BigDecimal.ZERO); + result.add(info); + totalA29 = totalA29.add(yearPower); + } + // 计算比例 + if (totalA29.compareTo(BigDecimal.ZERO) > 0) { + for (SiteTypeInfo siteTypeInfo : result) { + BigDecimal proportion = siteTypeInfo.getYearCharge().divide(totalA29, 4, RoundingMode.UP); + siteTypeInfo.setProportion(proportion.multiply(new BigDecimal("100"))); + } + } + // 补全没有数据的类型 + List finalResult = Constant.CARTYPES.entrySet().stream() + .map(entry -> result.stream() + .filter(r -> r.getSiteTypeCode().equals(entry.getKey().toString())) + .findFirst() + .orElse(new SiteTypeInfo(entry.getValue(), entry.getKey().toString(), BigDecimal.ZERO, BigDecimal.ZERO))) + .collect(Collectors.toList()); + return new Result>().ok(finalResult); + } + + @Override + public Result> chargingGunState() { + List result = new ArrayList<>(); + List dtos = stationInfoService.list(); + List stationIds = dtos.stream().map(dto -> String.valueOf(dto.getStationId())).toList(); + List statusInfos = connectorInfoMapper.getStatusByStationIds(stationIds); + Map map = statusInfos.stream() + .collect(Collectors.toMap(ConnectorStatusInfo::getStatus, ConnectorStatusInfo::getNum, (a, b) -> b)); + for (Map.Entry entry : Constant.STATUS_MAP.entrySet()) { + String key = entry.getKey(); + String val= entry.getValue(); + Integer count = map.get(key); + if(ObjectUtil.isNotEmpty(count)){ + result.add(new ChargingGunState(val,key,count)); + }else { + result.add(new ChargingGunState(val,key,0)); + } + } + return new Result>().ok(result); + } + + @Override + public Result> stationInfo(FindParam param) { + List dtos = stationInfoService.findByName(param.getPlantName(),null); + List reqs = new ArrayList<>(); + dtos.forEach(temp->{ + StationInfoReq req = new StationInfoReq(); + req.setStationName(temp.getStationName()); + List tsKvDTOS =tskvService.findLatestByCodeAndAttrs(temp.getStationId(),List.of("A29dd","A29yy","A201yy","A202yy"),false); + Map sumMap = new HashMap<>(); + for (TsKvDTO dto : tsKvDTOS) { + String key = dto.getAttrKey(); + BigDecimal val = new BigDecimal(dto.getVal()); + sumMap.put(key, sumMap.getOrDefault(key, BigDecimal.ZERO).add(val)); + } + BigDecimal a29dd = sumMap.getOrDefault("A29dd", BigDecimal.ZERO).setScale(4, RoundingMode.UP); + // 年度数据单位换算 + BigDecimal a29yy = sumMap.getOrDefault("A29yy", BigDecimal.ZERO).divide(BigDecimal.valueOf(1000), 4, RoundingMode.UP); + BigDecimal a201yy = sumMap.getOrDefault("A201yy", BigDecimal.ZERO).divide(BigDecimal.valueOf(1000), 4, RoundingMode.UP); + BigDecimal a202yy = sumMap.getOrDefault("A202yy", BigDecimal.ZERO).divide(BigDecimal.valueOf(1000), 4, RoundingMode.UP); + req.setDayCharge(a29dd); + req.setYearCharge(a29yy); + req.setYearOften(a201yy); + req.setYearChargeCount(a202yy); + reqs.add(req); + }); + return new Result>().ok(reqs); + } + + @Override + public Result findListByAttrCode(GunDataParam dataParam) { + DataReq req = new DataReq(); + Long startTime; + Long endTime; + if(ObjectUtil.isNotEmpty(dataParam.getStartTime())&&ObjectUtil.isNotEmpty(dataParam.getEndTime())&&dataParam.getStartTime()!=0){ + startTime = dataParam.getStartTime(); + endTime = dataParam.getEndTime(); + }else { + if(dataParam.getAttrType().equals("dd")){ + startTime= DateTimeUtils.getMonthBeginTimestamp(System.currentTimeMillis()); + }else { + startTime = DateTimeUtils.getYearBeginTimestamp(System.currentTimeMillis()); + } + endTime = DateTimeUtils.getMonthEndTimestamp(System.currentTimeMillis()); + } + AttributeTypeEnum attributeTypeEnum = AttributeTypeEnum.match(dataParam.getAttrType()); + Instant instant = Instant.ofEpochMilli(startTime); + LocalDateTime dateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()); + List timeRange = attributeTypeEnum.getTimeRange(dateTime); + List energyTimeLabelData = this.generateEmptyData(timeRange, dataParam.getAttrType()); + List tskvs = new ArrayList<>(); + List dtos = stationInfoService.list(); + List entityCodes = dtos.stream().map(StationInfoEntity::getStationId).map(String::valueOf).toList(); + tskvs = tskvService.findTsKvByCodesAndAttrs(entityCodes,List.of(dataParam.getAttrCode()),startTime,endTime,false); + Map> tsMap = tskvs.stream() + .collect(Collectors.groupingBy(TsKvDTO::getTs)); + List allInfo = new ArrayList<>(); + energyTimeLabelData.forEach(temp->{ + if(ObjectUtil.isNotEmpty(tsMap.get(temp.getTs()))){ + BigDecimal val = tsMap.get(temp.getTs()).stream().map(dto -> new BigDecimal(dto.getVal())) + .reduce(BigDecimal.ZERO, BigDecimal::add); + String value = dataUnitConvert(dataParam.getAttrCode(), val).toPlainString(); + TsKvDTO tskv = new TsKvDTO("all",dataParam.getAttrCode(),temp.getTs(),value); + allInfo.add(tskv); + }else { + TsKvDTO tskv = new TsKvDTO("all",dataParam.getAttrCode(),temp.getTs(),BigDecimal.ZERO.toString()); + allInfo.add(tskv); + } + }); + req.setTskvs(allInfo); + DataReq.AttrInfo attrInfo = new DataReq.AttrInfo(); + IotThingDictDTO dictDTO = iotThingDictService.findDictByCode(dataParam.getAttrCode()); + if(ObjectUtil.isNotEmpty(dictDTO)){ + attrInfo.setAttrCode(dictDTO.getCode()); + attrInfo.setAttrName(dictDTO.getName()); + attrInfo.setAttrUint(dictDTO.getUnit()); + req.setAttrInfo(attrInfo); + } + return new Result().ok(req); + } + + private BigDecimal dataUnitConvert(String attrCode, BigDecimal value) { + if (attrCode.startsWith("A201")) { + return value.divide(BigDecimal.valueOf(60 * 60 * 1000), 4, RoundingMode.HALF_UP); + } + if (attrCode.equals("A29mm")) { + return value.divide(BigDecimal.valueOf(1000), 4, RoundingMode.HALF_UP); + } + return value; + } + + @Override + public Result> findYOYList(GunDataParam dataParam) { + List result = new ArrayList<>(); + DataReq nowYearList = this.findListByAttrCode(dataParam).getData(); + dataParam.setStartTime(DateTimeUtils.fistDayOfLastYear()); + dataParam.setEndTime(DateTimeUtils.lastDayOfLastYear()); + DataReq lastYearList = this.findListByAttrCode(dataParam).getData(); + List last = lastYearList.getTskvs(); + Map> groupedMap = last.stream() + .collect(Collectors.groupingBy(dto -> Instant.ofEpochMilli(dto.getTs()) + .atZone(ZoneId.systemDefault()) + .toLocalDateTime() + .getMonth().getValue())); + nowYearList.getTskvs().forEach(temp->{ + YOYDataReq req = new YOYDataReq(); + LocalDate date = LocalDate.ofEpochDay(temp.getTs() / 86400000); // 将毫秒时间戳转换为 LocalDate 对象 + Integer month = date.getMonthValue(); + req.setTs(temp.getTs()); + req.setAttrName(nowYearList.getAttrInfo().getAttrName()); + req.setAttrCode(nowYearList.getAttrInfo().getAttrCode()); + req.setUnit(nowYearList.getAttrInfo().getAttrUint()); + List tsKvDTOS = groupedMap.get(month); + if(ObjectUtil.isNotEmpty(tsKvDTOS)){ + req.setLastYearVal(new BigDecimal(tsKvDTOS.stream().findFirst().get().getVal())); + } + req.setNowYearVal(new BigDecimal(temp.getVal())); + result.add(req); + }); + return new Result>().ok(result); + } + + @Override + public Result> gunReport(PVParam param) { + List reqs = stationInfoService.findByName(param.getPlantName(),param.getArea()); + reqs.forEach(r->{ + r.setOperatorName(stationProperties.getOperatorNameById(r.getOperatorId())); + }); + List result = ConvertUtils.sourceToTarget(reqs,StationInfoReq.class); + LocalDateTime startTime = getBeginTime(param.getDateType(),param.getDate()); + Instant instant = startTime.atZone(ZoneId.systemDefault()).toInstant(); + long startTs = instant.toEpochMilli(); + long endTs = startTs+1000L; + StationInfoReq total = new StationInfoReq(); + total.setStationName("合计"); + total.setArea("--"); + total.setSort(-1); + int sort = 1; + for (StationInfoReq report : result) { + //充电枪数量 + int count = connectorInfoMapper.getCountByStationIds(List.of(report.getStationId())); + report.setGunCount(count); + if(param.getDateType().equals("dd")){ + getDataWithMonth(report,startTs,endTs,total); + }else { + getDataWithYear(report,startTs,endTs,total); + } + report.setSort(sort++); + } + try { + total.setGunCharge(total.getYearCharge().divide(BigDecimal.valueOf(total.getGunCount()),4,RoundingMode.UP)); + } catch (Exception e) { + total.setGunCharge(BigDecimal.ZERO); + } + try { + total.setGunOften(total.getYearChargeCount().divide(BigDecimal.valueOf(total.getGunCount()),4,RoundingMode.UP)); + } catch (Exception e) { + total.setGunOften(BigDecimal.ZERO); + } + try { + total.setGunChargeCount(total.getYearOften().divide(BigDecimal.valueOf(total.getGunCount()),4,RoundingMode.UP)); + } catch (Exception e) { + total.setGunCharge(BigDecimal.ZERO); + } + result.add(total); + result.sort(Comparator.comparing(StationInfoReq::getSort)); + return new Result>().ok(result); + } + + private void getDataWithYear(StationInfoReq report, long startTs, long endTs, StationInfoReq total) { + List tsKvDTOS =tskvService.findTsKvByCodeAndAttrs(report.getStationId(),List.of("A29yy","A201yy","A202yy"),startTs,endTs,false); + Map sumMap = new HashMap<>(); + for (TsKvDTO dto : tsKvDTOS) { + String key = dto.getAttrKey(); + BigDecimal val = new BigDecimal(dto.getVal()); + sumMap.put(key, sumMap.getOrDefault(key, BigDecimal.ZERO).add(val)); + } + BigDecimal a29yy = sumMap.getOrDefault("A29yy", BigDecimal.ZERO).setScale(4, RoundingMode.UP); + BigDecimal a201yy = sumMap.getOrDefault("A201yy", BigDecimal.ZERO).setScale(4, RoundingMode.UP); + BigDecimal a202yy = sumMap.getOrDefault("A202yy", BigDecimal.ZERO).setScale(4, RoundingMode.UP); + BigDecimal a201hh = BigDecimal.ZERO; + try { + a201hh = a201yy.divide(BigDecimal.valueOf(60 * 60 * 1000), 1, RoundingMode.HALF_UP); + } catch (Exception e) { + } + report.setYearCharge(a29yy); + report.setYearOften(a201hh); + report.setYearChargeCount(a202yy); + try { + report.setGunCharge(a29yy.divide(BigDecimal.valueOf(report.getGunCount()),4,RoundingMode.UP)); + } catch (Exception e) { + report.setGunCharge(BigDecimal.ZERO); + } + try { + report.setGunOften(a202yy.divide(BigDecimal.valueOf(report.getGunCount()),4,RoundingMode.UP)); + } catch (Exception e) { + report.setGunOften(BigDecimal.ZERO); + } + try { + report.setGunChargeCount(a201hh.divide(BigDecimal.valueOf(report.getGunCount()),4,RoundingMode.UP)); + } catch (Exception e) { + report.setGunCharge(BigDecimal.ZERO); + } + total.setYearOften(total.getYearOften().add(report.getYearOften())); + total.setYearOften(total.getYearOften().add(report.getYearOften())); + total.setYearChargeCount(total.getYearChargeCount().add(report.getYearChargeCount())); + total.setGunCount(total.getGunCount()+report.getGunCount()); + } + + /** + * 按月份统计报表 + * @param report + */ + private void getDataWithMonth(StationInfoReq report,Long startTs,Long endTs,StationInfoReq total){ + List tsKvDTOS =tskvService.findTsKvByCodeAndAttrs(report.getStationId(),List.of("A29mm","A201mm","A202mm"),startTs,endTs,false); + Map sumMap = new HashMap<>(); + for (TsKvDTO dto : tsKvDTOS) { + String key = dto.getAttrKey(); + BigDecimal val = new BigDecimal(dto.getVal()); + sumMap.put(key, sumMap.getOrDefault(key, BigDecimal.ZERO).add(val)); + } + BigDecimal a29mm = sumMap.getOrDefault("A29mm", BigDecimal.ZERO).setScale(4, RoundingMode.UP); + BigDecimal a201mm = sumMap.getOrDefault("A201mm", BigDecimal.ZERO).setScale(4, RoundingMode.UP); + BigDecimal a202mm = sumMap.getOrDefault("A202mm", BigDecimal.ZERO).setScale(4, RoundingMode.UP); + report.setYearCharge(a29mm); + report.setYearChargeCount(a202mm); + BigDecimal a201hh = BigDecimal.ZERO; + try { + a201hh = a201mm.divide(BigDecimal.valueOf(60 * 60 * 1000), 1, RoundingMode.HALF_UP); + } catch (Exception e) { + } + report.setYearOften(a201hh); + try { + report.setGunCharge(a29mm.divide(BigDecimal.valueOf(report.getGunCount()),4,RoundingMode.UP)); + } catch (Exception e) { + report.setGunCharge(BigDecimal.ZERO); + } + try { + report.setGunOften(a202mm.divide(BigDecimal.valueOf(report.getGunCount()),4,RoundingMode.UP)); + } catch (Exception e) { + report.setGunOften(BigDecimal.ZERO); + } + try { + report.setGunChargeCount(a201hh.divide(BigDecimal.valueOf(report.getGunCount()),4,RoundingMode.UP)); + } catch (Exception e) { + report.setGunCharge(BigDecimal.ZERO); + } + total.setYearCharge(total.getYearCharge().add(report.getYearCharge())); + total.setYearOften(total.getYearOften().add(report.getYearOften())); + total.setYearChargeCount(total.getYearChargeCount().add(report.getYearChargeCount())); + total.setGunCount(total.getGunCount()+report.getGunCount()); + } + + + + /** + * 区域统计 + * @param dtos + * @param result + */ + private void getAttrDataWithArea(List dtos, List result) { + dtos.forEach(temp->{ + ScreenData screenData = new ScreenData(); + List data = new ArrayList<>(); + screenData.setName(temp.getStationName()); + screenData.setLon(temp.getStationLng()); + screenData.setLat(temp.getStationLat()); + List list = connectorInfoMapper.getStatusByStationId(temp.getStationId()); + int sum = list.stream() + .mapToInt(ConnectorStatusInfo::getNum) + .sum(); + int num = list. stream() + .filter(info -> info.getStatus().equals("3")) + .mapToInt(ConnectorStatusInfo::getNum) + .findFirst() + .orElse(0); + data.add(initAttrData("充电枪数量",sum,"个")); + data.add(initAttrData("正在充电",num,"个")); + + List tsKvDTOS =tskvService.findLatestByCodeAndAttrs(temp.getStationId(),List.of("A29dd","A201dd","A202dd"),false); + Map sumMap = new HashMap<>(); + for (TsKvDTO dto : tsKvDTOS) { + String key = dto.getAttrKey(); + BigDecimal val = new BigDecimal(dto.getVal()); + sumMap.put(key, sumMap.getOrDefault(key, BigDecimal.ZERO).add(val)); + } + + BigDecimal a29dd = sumMap.getOrDefault("A29dd", BigDecimal.ZERO).setScale(4, RoundingMode.UP); + BigDecimal a201dd = sumMap.getOrDefault("A201dd", BigDecimal.ZERO).divide(BigDecimal.valueOf(3600),4,RoundingMode.UP); + BigDecimal a202dd = sumMap.getOrDefault("A202dd", BigDecimal.ZERO).setScale(4, RoundingMode.UP); + data.add(initAttrData("今日充电量",a29dd,"kWh")); + data.add(initAttrData("今日充电时长",a201dd,"h")); + data.add(initAttrData("今日充电次数",a202dd,"次")); + screenData.setData(data); + result.add(screenData); + }); + } + + /** + * 省市统计 + * @param screenData + */ + private void getAttrDataWithCity(List dtos, ScreenData screenData) { + List data = new ArrayList<>(); + List thingCodes = dtos.stream() + .map(dto -> String.valueOf(dto.getStationId())) + .toList(); + int totalNum=0; + int runNum=0; + for (StationInfoDTO dto : dtos) { + List list = connectorInfoMapper.getStatusByStationId(dto.getStationId()); + int num = list. stream() + .filter(info -> info.getStatus().equals("3")) + .mapToInt(ConnectorStatusInfo::getNum) + .findFirst() + .orElse(0); + runNum=runNum+num; + int sum = list.stream() + .mapToInt(ConnectorStatusInfo::getNum) + .sum(); + totalNum = totalNum+sum; + } + data.add(initAttrData("充电枪数量",totalNum,"个")); + data.add(initAttrData("正在充电",runNum,"个")); + List tsKvDTOS =tskvService.findLatestByCodesAndAttrs(thingCodes,List.of("A29dd","A201dd","A202dd"),false); + Map sumMap = new HashMap<>(); + for (TsKvDTO dto : tsKvDTOS) { + String key = dto.getAttrKey(); + BigDecimal val = new BigDecimal(dto.getVal()); + sumMap.put(key, sumMap.getOrDefault(key, BigDecimal.ZERO).add(val)); + } + BigDecimal a29dd = sumMap.getOrDefault("A29dd", BigDecimal.ZERO).setScale(4, RoundingMode.UP); + BigDecimal a201dd = sumMap.getOrDefault("A201dd", BigDecimal.ZERO).setScale(4, RoundingMode.UP); + BigDecimal a202dd = sumMap.getOrDefault("A202dd", BigDecimal.ZERO).setScale(4, RoundingMode.UP); + data.add(initAttrData("今日充电量",a29dd,"kWh")); + data.add(initAttrData("今日充电时长",a201dd,"h")); + data.add(initAttrData("今日充电次数",a202dd,"次")); + screenData.setData(data); + } + + + private ScreenData.AttrData initAttrData(String name,Object val,String unit){ + ScreenData.AttrData attrData = new ScreenData.AttrData(); + attrData.setAttrName(name); + attrData.setAttrValue(val.toString()); + attrData.setAttrUnit(unit); + return attrData; + } + + + /** + * 按指定时间范围生成全量空数据 + * @param timeRange 时间范围 + * @param attrType 属性类型 + * @return 空数据列表 + */ + private List generateEmptyData( + List timeRange, String attrType) { + return timeRange.stream() + .map( + t -> + new EnergyTimeLabelData( + DateTimeUtils.parse(t), + EnergyTimeLabelData.getByAttrType(attrType), + null)) + .collect(Collectors.toList()); + } + + + + + @SuppressWarnings("Duplicates") + public LocalDateTime getBeginTime(String dateType,String dateStr) { + AttributeTypeEnum attributeTypeEnum = AttributeTypeEnum.match(dateType); + switch (attributeTypeEnum) { + case am, hh -> { + // yyyy-MM-dd + return DateTimeUtils.parseDateTime(dateStr + " 00:00:00"); + } + case dd -> { + // yyyy-MM + return DateTimeUtils.parseDateTime(dateStr + "-01 00:00:00"); + } + case mm -> { + // yyyy + return DateTimeUtils.parseDateTime(dateStr + "-01-01 00:00:00"); + } + default -> { + } + } + return null; + } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/service/impl/PlantServiceImpl.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/service/impl/PlantServiceImpl.java new file mode 100644 index 0000000..13604d9 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/manageboard/service/impl/PlantServiceImpl.java @@ -0,0 +1,107 @@ +package com.thing.qingyuan.manageboard.service.impl; + +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.ObjectUtil; +import com.mybatisflex.core.query.QueryColumn; +import com.mybatisflex.core.query.QueryWrapper; +import com.thing.qingyuan.manageboard.dto.MapParam; +import com.thing.qingyuan.manageboard.dto.PlantDTO; +import com.thing.qingyuan.manageboard.dto.PlantInfoReq; +import com.thing.qingyuan.manageboard.entity.PlantEntity; +import com.thing.qingyuan.manageboard.mapper.PlantMapper; +import com.thing.qingyuan.manageboard.service.PlantService; +import com.thing.common.core.utils.ConvertUtils; +import com.thing.common.orm.service.impl.BaseServiceImpl; +import com.thing.sys.security.context.UserContext; +import com.thing.thing.entity.dto.IotThingEntityDTO; +import com.thing.thing.entity.service.IotThingEntityService; +import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +import static com.mybatisflex.core.query.QueryMethods.column; + +/** + * 光伏项目点位信息 + * + * @author xc + * @since 3.0 2024-01-29 + */ +@Service +@RequiredArgsConstructor +public class PlantServiceImpl extends BaseServiceImpl implements PlantService { + + @Autowired + IotThingEntityService iotThingEntityService; + + + @Override + public QueryWrapper getWrapper(Map params){ + QueryWrapper wrapper = new QueryWrapper(); + QueryColumn name= column("plant_name"); + QueryColumn id = column("plant_id"); + String buildDate = MapUtil.getStr(params,"buildDate"); + String area = MapUtil.getStr(params,"area"); + String key = MapUtil.getStr(params,"key"); + Long idParam= null; + try { + idParam = Long.parseLong(key); + } catch (NumberFormatException ignored) { + } + wrapper.eq("build_date",buildDate,StringUtils.isNotEmpty(buildDate)); + wrapper.like("area",area,StringUtils.isNotEmpty(area)); + if(StringUtils.isNotEmpty(key)){ + wrapper.and(name.like(key).or(id.eq(idParam))); + } + return wrapper; + } + + + @Override + public Map> findByParam(MapParam mapParam) { + QueryWrapper wrapper = new QueryWrapper(); + if (mapParam.getType().equals("2")) { + wrapper.eq(PlantEntity::getProvince, mapParam.getCityName()); + } else if (mapParam.getType().equals("3")) { + wrapper.eq(PlantEntity::getCity, mapParam.getCityName()); + } else if (mapParam.getType().equals("4")) { + wrapper.eq(PlantEntity::getArea, mapParam.getCityName()); + } + List dtos = ConvertUtils.sourceToTarget(this.list(wrapper), PlantDTO.class); + dtos.forEach(temp->{ + Optional optional = iotThingEntityService.findEntityByCode(String.valueOf(temp.getPlantId()), UserContext.getRealTenantCode(), true); + if(optional.isPresent()){ + temp.setPlantName(optional.get().getName()); + } + }); + if (mapParam.getType().equals("2") || mapParam.getType().equals("3") || mapParam.getType().equals("4")) { + return dtos.stream().collect(Collectors.groupingBy(PlantDTO::getCity)); + } else { + return dtos.stream().collect(Collectors.groupingBy(PlantDTO::getProvince)); + } + } + + @Override + public List findByName(String plantName,String area) { + QueryWrapper wrapper = new QueryWrapper(); + wrapper.like(PlantEntity::getPlantName,plantName,StringUtils.isNotEmpty(plantName)); + wrapper.like(PlantEntity::getArea,area,StringUtils.isNotEmpty(area)); + + List entities = this.list(wrapper); + entities.forEach(temp->{ + Optional optional = iotThingEntityService.findEntityByCode(String.valueOf(temp.getPlantId()), UserContext.getRealTenantCode(), true); + if(optional.isPresent()){ + temp.setPlantName(optional.get().getName()); + } + }); + + return ConvertUtils.sourceToTarget(entities,PlantInfoReq.class); + } + +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/photovoltaic/controller/PhotovoltaicController.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/photovoltaic/controller/PhotovoltaicController.java new file mode 100644 index 0000000..918729f --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/photovoltaic/controller/PhotovoltaicController.java @@ -0,0 +1,129 @@ +package com.thing.qingyuan.photovoltaic.controller; + +import com.thing.common.core.annotation.LogOperation; +import com.thing.common.core.web.response.Result; +import com.thing.common.data.tskv.TsKvDTO; +import com.thing.qingyuan.chargeStation.dto.ChargeStatisticRequest; +import com.thing.qingyuan.photovoltaic.dto.PhotovoltaicDTO; +import com.thing.qingyuan.photovoltaic.dto.PhotovoltaicOverviewDTO; +import com.thing.qingyuan.photovoltaic.dto.PhotovoltaicReportDTO; +import com.thing.qingyuan.photovoltaic.service.PhotovoltaicService; +import com.thing.qingyuan.screen.ScreenData; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Map; + +/** + * 光伏项目点位信息 + * + * @author xc + * @since 3.0 2024-01-29 + */ +@RestController +@RequestMapping("photovoltaic") +@Tag(name="光伏项目点位信息") +@RequiredArgsConstructor +public class PhotovoltaicController { + + private final PhotovoltaicService photovoltaicService; + + + @GetMapping("overview") + @Operation(summary="获取光伏概览数据信息") + public Result getOverview(){ + PhotovoltaicOverviewDTO data = photovoltaicService.getOverview(); + return new Result().ok(data); + } + + @GetMapping("{plantId}") + @Operation(summary="获取电站信息") + public Result get(@PathVariable("plantId") Long plantId){ + PhotovoltaicDTO data = photovoltaicService.findById(plantId); + return new Result().ok(data); + } + + @GetMapping("video/{plantId}") + @Operation(summary="获取视频信息") + public Result getVideo(@PathVariable("plantId") Long plantId){ + PhotovoltaicDTO data = photovoltaicService.findById(plantId); + return new Result().ok(data); + } + + + @GetMapping("heatMap") + @Operation(summary="获取热力图信息") + public Result> getHeatMap(){ + List heatMap = photovoltaicService.getHeatMap(); + return new Result>().ok(heatMap); + } + + @GetMapping("powerAnalysis/{plantId}/{type}") + @Operation(summary="发电分析") + public Result>> powerAnalysis(@PathVariable("plantId") Long plantId,@PathVariable("type") String type){ + Map> resultData = photovoltaicService.getPowerAnalysis(plantId,type); + return new Result>>().ok(resultData); + } + + @GetMapping("electricPowerAnalysis/{plantId}/{type}") + @Operation(summary="发电消纳分析") + public Result>> electricPowerAnalysis(@PathVariable("plantId") Long plantId,@PathVariable("type") String type){ + Map> resultData = photovoltaicService.getElectricPowerAnalysis(plantId,type); + return new Result>>().ok(resultData); + } + + @GetMapping("inverter/{code}") + @Operation(summary="逆变器详情") + public Result>> inverterDetails(@PathVariable String code){ + Map> resultData = photovoltaicService.getInverterDetails(code); + return new Result>>().ok(resultData); + } + + @PostMapping("report/electric") + @Operation(summary="发电报表") + public Result> reportElectric(@RequestBody ChargeStatisticRequest chargeStatisticRequest){ + List reportElectric = photovoltaicService.getReportElectric(chargeStatisticRequest); + return new Result>().ok(reportElectric); + } + + @PostMapping("report/electric/export") + @Operation(summary="发电报表导出") + @LogOperation("发电报表导出") + public void electricExport( @RequestBody ChargeStatisticRequest chargeStatisticRequest, HttpServletResponse response) throws Exception { + photovoltaicService.electricExport(chargeStatisticRequest, response); + } + + @PostMapping("report/consumption") + @Operation(summary="上网消纳量报表") + public Result> reportConsumption(@RequestBody ChargeStatisticRequest chargeStatisticRequest){ + List reportElectric = photovoltaicService.getReportConsumption(chargeStatisticRequest); + return new Result>().ok(reportElectric); + } + + @PostMapping("report/consumption/export") + @Operation(summary="上网消纳量报表导出") + @LogOperation("上网消纳量报表导出") + public void reportElectric(@RequestBody ChargeStatisticRequest chargeStatisticRequest,HttpServletResponse response){ + photovoltaicService.consumptionExport(chargeStatisticRequest, response); + } + +/* @GetMapping("page") + @Operation(summary="分页") + @Parameters({ + @Parameter(name = Constant.PAGE, description = "当前页码,从1开始") , + @Parameter(name = Constant.LIMIT, description = "每页显示记录数") , + @Parameter(name = Constant.ORDER_FIELD, description = "排序字段") , + @Parameter(name = Constant.ORDER, description = "排序方式,可选值(asc、desc)"), + @Parameter(name = Constant.ORDER, description = "排序方式,可选值(asc、desc)") + }) + public Result> page(@RequestParam Map params){ + PageData page = photovoltaicService.getP(params, PlantDTO.class); + return new Result>().ok(page); + }*/ + + +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/photovoltaic/dto/PhotovoltaicConsumptionDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/photovoltaic/dto/PhotovoltaicConsumptionDTO.java new file mode 100644 index 0000000..cae2d9e --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/photovoltaic/dto/PhotovoltaicConsumptionDTO.java @@ -0,0 +1,33 @@ +package com.thing.qingyuan.photovoltaic.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; + +/** +* 光伏项目概览数据信息 +* +* @author xc +* @since 3.0 2024-01-29 +*/ +@Data +@Schema( description= "消纳报表数据信息") +public class PhotovoltaicConsumptionDTO implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "发电量") + private BigDecimal electricityUsage = BigDecimal.ZERO; + @Schema(description = "消纳量") + private BigDecimal consumptionUsage = BigDecimal.ZERO; + @Schema(description = "上网量") + private BigDecimal internetUsage = BigDecimal.ZERO; + @Schema(description = "消纳率") + private BigDecimal consumptionRate = BigDecimal.ZERO; + @Schema(description = "时间") + private Long ts ; +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/photovoltaic/dto/PhotovoltaicDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/photovoltaic/dto/PhotovoltaicDTO.java new file mode 100644 index 0000000..2320aac --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/photovoltaic/dto/PhotovoltaicDTO.java @@ -0,0 +1,45 @@ +package com.thing.qingyuan.photovoltaic.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; + +/** +* 光伏项目点位信息 +* +* @author xc +* @since 3.0 2024-01-29 +*/ +@Data +@Schema( description= "光伏项目点位信息") +public class PhotovoltaicDTO implements Serializable { + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "电站Id") + private Long plantId; + @Schema(description = "电站名称") + private String plantName; + @Schema(description = "电站装机容量 (单位:kWp)") + private BigDecimal capacity; + @Schema(description = "经度") + private Object longitude; + @Schema(description = "纬度") + private Object latitude; + @Schema(description = "逆变器数量") + private Integer inverterNum = 0; + @Schema(description = "今日发电量") + private BigDecimal electricityUsage = BigDecimal.ZERO; + @Schema(description = "今日上网量") + private BigDecimal internetUsage = BigDecimal.ZERO; + @Schema(description = "今日减碳量") + private BigDecimal carbonUsage = BigDecimal.ZERO; + @Schema(description = "检测点运行正常") + private BigDecimal pointNormal = BigDecimal.ZERO; + @Schema(description = "检测点运行总量") + private BigDecimal pointTotal = BigDecimal.ZERO; + +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/photovoltaic/dto/PhotovoltaicOverviewDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/photovoltaic/dto/PhotovoltaicOverviewDTO.java new file mode 100644 index 0000000..59074d8 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/photovoltaic/dto/PhotovoltaicOverviewDTO.java @@ -0,0 +1,36 @@ +package com.thing.qingyuan.photovoltaic.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; + +/** +* 光伏项目概览数据信息 +* +* @author xc +* @since 3.0 2024-01-29 +*/ +@Data +@Schema( description= "光伏项目概览数据信息") +public class PhotovoltaicOverviewDTO implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "光伏数量") + private BigDecimal num = BigDecimal.ZERO; + @Schema(description = "电站装机容量 (单位:kWp)") + private BigDecimal capacity = BigDecimal.ZERO; + @Schema(description = "年发电量(单位:kWp)") + private BigDecimal electricityUsage = BigDecimal.ZERO; + @Schema(description = "年上网量(单位:kWp)") + private BigDecimal internetUsage = BigDecimal.ZERO; + @Schema(description = "年节能量(单位:tce)") + private BigDecimal energySaveUsage = BigDecimal.ZERO; + @Schema(description = "年减排量(单位:tCO2)") + private BigDecimal reductionUsage = BigDecimal.ZERO; + +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/photovoltaic/dto/PhotovoltaicReportDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/photovoltaic/dto/PhotovoltaicReportDTO.java new file mode 100644 index 0000000..072adc0 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/photovoltaic/dto/PhotovoltaicReportDTO.java @@ -0,0 +1,43 @@ +package com.thing.qingyuan.photovoltaic.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.List; +import java.util.Map; + +/** +* 光伏项目概览数据信息 +* +* @author xc +* @since 3.0 2024-01-29 +*/ +@Data +@Schema( description= "光伏和消纳报表数据信息") +public class PhotovoltaicReportDTO implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "物的id") + private Long thingId; + @Schema(description = "结构编码") + private String code; + @Schema(description = "结构名称") + private String name; + @Schema(description = "发电总量 (单位:kwh)") + private BigDecimal electricityUsage = BigDecimal.ZERO; + @Schema(description = "光伏报表数据,key: ts,val ") + private List> plantDataList; + @Schema(description = "消纳报表总量数据") + private PhotovoltaicConsumptionDTO consumptionTotal; + @Schema(description = "消纳报表数据") + private List consumptionDataList; + @Schema(description = "时间列表:暂时后端使用") + private List timeList; + + +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/photovoltaic/service/PhotovoltaicService.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/photovoltaic/service/PhotovoltaicService.java new file mode 100644 index 0000000..94ea616 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/photovoltaic/service/PhotovoltaicService.java @@ -0,0 +1,45 @@ +package com.thing.qingyuan.photovoltaic.service; + + +import com.thing.common.data.tskv.TsKvDTO; +import com.thing.qingyuan.chargeStation.dto.ChargeStatisticRequest; +import com.thing.qingyuan.photovoltaic.dto.PhotovoltaicDTO; +import com.thing.qingyuan.photovoltaic.dto.PhotovoltaicOverviewDTO; +import com.thing.qingyuan.photovoltaic.dto.PhotovoltaicReportDTO; +import com.thing.qingyuan.screen.ScreenData; +import jakarta.servlet.http.HttpServletResponse; + +import java.util.List; +import java.util.Map; + +/** + * 光伏项目点位信息 + * + * @author xc + * @since 3.0 2024-01-29 + */ +public interface PhotovoltaicService { + + + PhotovoltaicOverviewDTO getOverview(); + + PhotovoltaicDTO findById(Long plantId); + + List findVideoById(Long plantId); + + List getHeatMap(); + + Map> getPowerAnalysis(Long plantId, String type); + + Map> getElectricPowerAnalysis(Long plantId, String type); + + Map> getInverterDetails(String code); + + List getReportElectric(ChargeStatisticRequest chargeStatisticRequest); + + void electricExport(ChargeStatisticRequest chargeStatisticRequest, HttpServletResponse response); + + List getReportConsumption(ChargeStatisticRequest chargeStatisticRequest); + + void consumptionExport(ChargeStatisticRequest chargeStatisticRequest, HttpServletResponse response); +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/photovoltaic/service/impl/PhotovoltaicServiceImpl.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/photovoltaic/service/impl/PhotovoltaicServiceImpl.java new file mode 100644 index 0000000..61fa020 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/photovoltaic/service/impl/PhotovoltaicServiceImpl.java @@ -0,0 +1,776 @@ +package com.thing.qingyuan.photovoltaic.service.impl; + +import cn.afterturn.easypoi.excel.ExcelExportUtil; +import cn.afterturn.easypoi.excel.entity.ExportParams; +import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.comparator.CompareUtil; +import cn.hutool.core.util.ObjectUtil; +import com.google.common.collect.Lists; +import com.thing.common.core.enumeration.ThingAttrType; +import com.thing.common.core.enumeration.TimeType; +import com.thing.common.core.exception.SysException; +import com.thing.common.core.utils.DateTimeUtils; +import com.thing.common.core.utils.excel.ExcelUtils; +import com.thing.common.data.tskv.TsKvDTO; +import com.thing.common.tskv.service.TsKvService; +import com.thing.qingyuan.basedevice.dto.DeviceDTO; +import com.thing.qingyuan.basedevice.service.IotDeviceService; +import com.thing.qingyuan.chargeStation.dto.ChargeStatisticRequest; +import com.thing.qingyuan.manageboard.entity.PlantEntity; +import com.thing.qingyuan.manageboard.service.PlantService; +import com.thing.qingyuan.photovoltaic.dto.PhotovoltaicConsumptionDTO; +import com.thing.qingyuan.photovoltaic.dto.PhotovoltaicDTO; +import com.thing.qingyuan.photovoltaic.dto.PhotovoltaicOverviewDTO; +import com.thing.qingyuan.photovoltaic.dto.PhotovoltaicReportDTO; +import com.thing.qingyuan.photovoltaic.service.PhotovoltaicService; +import com.thing.qingyuan.screen.ScreenData; +import com.thing.qingyuan.util.CalculationUtil; + +import com.thing.sys.security.context.UserContext; +import com.thing.thing.entity.dto.IotThingEntityDTO; +import com.thing.thing.entity.entity.IotThingEntity; +import com.thing.thing.entity.service.IotThingEntityService; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.poi.ss.usermodel.Workbook; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * 光伏项目点位信息 + * + * @author xc + * @since 3.0 2024-01-29 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class PhotovoltaicServiceImpl implements PhotovoltaicService { + + private final PlantService plantService; + private final IotThingEntityService thingEntityService; + private final TsKvService tsKvService; + private final IotDeviceService iotDeviceService; + + + private final static BigDecimal coefficient = BigDecimal.ONE.divide(BigDecimal.TEN.pow(3)); + private final static BigDecimal reductionFactor = new BigDecimal("0.475"); + private final static BigDecimal energySaveFactor = new BigDecimal("0.4"); + private final static String attrA16 = "A16"; + private final static String attrA29 = "A29"; + private final static String attrA29dd = "A29dd"; + private final static String attrA29mm = "A29mm"; + private final static String attrA30 = "A30"; + private final static String attrA30hh = "A30hh"; + private final static String attrA30dd = "A30dd"; + private final static String attrA30mm = "A30mm"; + private final static String attrA30yy = "A30yy"; + private final static String attrA29yy = "A29yy"; + private final static Long ONE_DAY = 86400000L; + + @Override + public PhotovoltaicOverviewDTO getOverview() { + PhotovoltaicOverviewDTO photovoltaicOverviewDTO = new PhotovoltaicOverviewDTO(); + List list = plantService.list(); + if (CollectionUtils.isNotEmpty(list)) { + photovoltaicOverviewDTO.setNum(new BigDecimal(CollectionUtils.size(list))); + BigDecimal capacity = list.stream().map(PlantEntity::getCapacity).reduce(BigDecimal.ZERO, BigDecimal::add); + photovoltaicOverviewDTO.setCapacity(capacity); + + List entityCodes = list.stream().map(PlantEntity::getPlantId).map(Object::toString).toList(); + Optional> thingEntities = thingEntityService.findByCodes(entityCodes, UserContext.getRealTenantCode(), true); + if (thingEntities.isPresent()) { + List tsKvDTOList = tsKvService.findLatestByCodesAndAttrs(thingEntities.get().stream().map(IotThingEntityDTO::getCode).toList(), Lists.newArrayList(attrA29yy, attrA30yy), false); + if (CollectionUtils.isNotEmpty(tsKvDTOList)) { + //年发电总量 + BigDecimal electricityUsage = tsKvDTOList.stream().filter(s -> StringUtils.equals(s.getAttrKey(), attrA29yy)).map(s -> new BigDecimal(s.getVal())).reduce(BigDecimal.ZERO, BigDecimal::add); + BigDecimal performance = CalculationUtil.getPerformance(electricityUsage, new BigDecimal(10000), 2); + photovoltaicOverviewDTO.setElectricityUsage(performance); + BigDecimal internetUsage = tsKvDTOList.stream().filter(s -> StringUtils.equals(s.getAttrKey(), attrA30yy)).map(s -> new BigDecimal(s.getVal())).reduce(BigDecimal.ZERO, BigDecimal::add); + photovoltaicOverviewDTO.setInternetUsage(internetUsage); + //年节能量 + BigDecimal energySaveUsage = CalculationUtil.getCarbonUsage(electricityUsage, energySaveFactor, coefficient, 2); + photovoltaicOverviewDTO.setEnergySaveUsage(energySaveUsage); + //年减排量 + BigDecimal reductionUsage = CalculationUtil.getCarbonUsage(electricityUsage, reductionFactor, coefficient, 2); + photovoltaicOverviewDTO.setReductionUsage(reductionUsage); + } + } + } + return photovoltaicOverviewDTO; + } + + @Override + public PhotovoltaicDTO findById(Long plantId) { + PhotovoltaicDTO photovoltaicDTO = plantService.getByIdAs(plantId, PhotovoltaicDTO.class); + if (ObjectUtil.isNull(photovoltaicDTO)) { + throw new SysException("电站信息不存在,请重新选择"); + } + Optional entityByCode = thingEntityService.findEntityByCode(String.valueOf(photovoltaicDTO.getPlantId()), UserContext.getRealTenantCode(), true); + if (entityByCode.isEmpty()) { + throw new SysException("当前电站实体不存在,请重新选择"); + } + List deviceDTOS = iotDeviceService.findByPlantId(photovoltaicDTO.getPlantId(), 2); + //逆变器数量 + photovoltaicDTO.setInverterNum(CollectionUtils.size(deviceDTOS)); + //今日发电量(A29dd)和今日上网量(??) + List tsKvDTOList = tsKvService.findLatestByCodeAndAttrs(String.valueOf(photovoltaicDTO.getPlantId()), Lists.newArrayList(attrA29dd, attrA30dd), false); + if (CollectionUtils.isNotEmpty(tsKvDTOList)) { + BigDecimal a29dd = tsKvDTOList.stream() + .filter(s -> StringUtils.equals(attrA29dd, s.getAttrKey())) + .map(s -> new BigDecimal(s.getVal())/*.divide(new BigDecimal("1000"),2, RoundingMode.UP)*/) + .findFirst() + .orElse(BigDecimal.ZERO); + photovoltaicDTO.setElectricityUsage(a29dd); + //今日减碳排量 + // BigDecimal carbonUsage = CalculationUtil.getCarbonUsage(a29dd, reductionFactor, coefficient, 2); + BigDecimal carbonUsage = CalculationUtil.getCarbonUsage(a29dd, reductionFactor, BigDecimal.ONE, 2); + photovoltaicDTO.setCarbonUsage(carbonUsage); + //今日上网量 + BigDecimal internetUsage = tsKvDTOList.stream() + .filter(s -> StringUtils.equals(attrA30dd, s.getAttrKey())) + .map(s -> new BigDecimal(s.getVal())) + .findFirst() + .orElse(BigDecimal.ZERO); + photovoltaicDTO.setInternetUsage(internetUsage); + } + //调用大华视频接口,获取检测点数,获取正常和总数 + return photovoltaicDTO; + } + + @Override + public List findVideoById(Long plantId) { + //调用大华视频接口,获取最新视频数据 + return null; + } + + @Override + public List getHeatMap() { + List list = plantService.list(); + if (CollectionUtils.isEmpty(list)) { + throw new SysException("光伏信息不存在"); + } + List entityCodes = list.stream().map(PlantEntity::getPlantId).map(String::valueOf).toList(); + Optional> entityDTOList = thingEntityService.findByCodes(entityCodes, UserContext.getRealTenantCode(), true); + if (entityDTOList.isEmpty()) { + throw new SysException("光伏信息不存在"); + } + return list.stream().flatMap(s -> { + ScreenData screenData = new ScreenData(); + IotThingEntityDTO iotThingEntity = entityDTOList.get().stream().filter(t -> StringUtils.equals(s.getPlantId().toString(), t.getCode())).findFirst().orElse(null); + if(ObjectUtil.isNotNull(iotThingEntity)){ + screenData.setId(s.getPlantId()); + screenData.setName(iotThingEntity.getName()); + screenData.setLon(s.getLongitude()); + screenData.setLat(s.getLatitude()); + List attrDataList = Lists.newArrayList(); + //装机容量单独处理 + ScreenData.AttrData attrCapacity = getAttr(null, "capacity", "装机容量", "kWp", s.getCapacity()); + attrDataList.add(attrCapacity); + //日发电量,日上网量,实时功率 + List tsKvDTOList = tsKvService.findLatestByCodeAndAttrs(String.valueOf(s.getPlantId()), Lists.newArrayList(attrA29dd, attrA30dd, attrA16), false); + //发电功率 + ScreenData.AttrData attr16 = getAttr(tsKvDTOList, attrA16, "发电功率", "W", BigDecimal.ZERO); + attrDataList.add(attr16); + //日发电量 + ScreenData.AttrData attrA29 = getAttr(tsKvDTOList, attrA29dd, "日发电量", "kWh", BigDecimal.ZERO); + attrDataList.add(attrA29); + BigDecimal dayUsage = filterAttrVal(tsKvDTOList, attrA29dd); + screenData.setMeasure(dayUsage); + //日上网量 + ScreenData.AttrData attrA30 = getAttr(tsKvDTOList, attrA30dd, "日上网量", "kWh", BigDecimal.ZERO); + attrDataList.add(attrA30); + //性能比 + ScreenData.AttrData performance = getAttr(null, "performance", "性能比", "", + CalculationUtil.getPerformance(filterAttrVal(tsKvDTOList, attrA16).divide(new BigDecimal("1000")), s.getCapacity(), 2)); + attrDataList.add(performance); + screenData.setData(attrDataList); + return Stream.of(screenData); + } + return null; + }).collect(Collectors.toList()); + } + + @Override + public Map> getPowerAnalysis(Long plantId, String type) { + Map> result = new HashMap<>(); + Optional entityByCode = thingEntityService.findEntityByCode(plantId.toString(), UserContext.getRealTenantCode(), true); + //获取今天的开始时间和结束时间 + String dayBeginTime = DateTimeUtils.getDayBeginTime(); + Long startTimeT = DateTimeUtils.convertTimeToLong(dayBeginTime); + //获取昨天的开始时间和结束时间 + Long endTimeT = startTimeT + ONE_DAY - 1; + Long startTimeY = startTimeT - ONE_DAY; + Long endTimeY = startTimeT - 1; + String attrCode; + if (StringUtils.equals(type, "2")) { + attrCode = attrA30hh; + } else { + attrCode = attrA16; + } + List tsKvDTOST = tsKvService.findTsKvByCodeAndAttr(entityByCode.get().getCode(), attrCode, startTimeT, endTimeT, true); + tsKvDTOST.forEach(temp->{ + temp.setTs(getStartOfHour(temp.getTs())); + }); + List distinctAndSortedTsKvDTOST = tsKvDTOST.stream() + // 按 ts 字段去重,保留每个 ts 的第一个出现的对象 + .collect(Collectors.collectingAndThen( + Collectors.toMap( + TsKvDTO::getTs, // 假设 TsKvDTO 有 getTs() 方法 + tsKvDTO -> tsKvDTO, + (existing, replacement) -> existing), + map -> map.values().stream().sorted( + (o1, o2) -> o1.getTs().compareTo(o2.getTs()) // 按 ts 字段升序排序 + ).collect(Collectors.toList()) + )); + List tsKvDTOSY = tsKvService.findTsKvByCodeAndAttr(entityByCode.get().getCode(), attrCode, startTimeY, endTimeY, true); + tsKvDTOSY.forEach(temp->{ + temp.setTs(getStartOfHour(temp.getTs())); + }); + List distinctAndSortedTsKvDTOSY = tsKvDTOSY.stream() + // 按 ts 字段去重,保留每个 ts 的第一个出现的对象 + .collect(Collectors.collectingAndThen( + Collectors.toMap( + TsKvDTO::getTs, // 假设 TsKvDTO 有 getTs() 方法 + tsKvDTO -> tsKvDTO, + (existing, replacement) -> existing), + map -> map.values().stream().sorted( + (o1, o2) -> o1.getTs().compareTo(o2.getTs()) // 按 ts 字段升序排序 + ).collect(Collectors.toList()) + )); + List yyTskv = Lists.newArrayList(); + for (int i = 0; i < distinctAndSortedTsKvDTOSY.size(); i++) { + //本期的数据 + TsKvDTO tsKvDTOY = distinctAndSortedTsKvDTOSY.get(i); + Long ts = tsKvDTOY.getTs(); + //同期的数据 + List tsKvDTOT = distinctAndSortedTsKvDTOST.stream().filter(s->s.getTs().compareTo(ts) == 0 ).toList(); + if(CollectionUtil.isEmpty(tsKvDTOT)){ + TsKvDTO yy = new TsKvDTO(tsKvDTOY.getThingCode(), tsKvDTOY.getAttrKey(), ts, "0"); + yyTskv.add(yy); + }else{ + BigDecimal yoy = CalculationUtil.getYOY(new BigDecimal(tsKvDTOT.get(0).getVal()), new BigDecimal(tsKvDTOY.getVal())); + TsKvDTO yy = new TsKvDTO(tsKvDTOY.getThingCode(), tsKvDTOY.getAttrKey(), ts, yoy.toString()); + yyTskv.add(yy); + + } + tsKvDTOY.setVal(new BigDecimal(tsKvDTOY.getVal()).divide(new BigDecimal(1000),2,RoundingMode.HALF_UP).toString()); + } + for (int i = 0; i < distinctAndSortedTsKvDTOST.size(); i++) { + //本期的数据 + TsKvDTO tsKvDTOY = distinctAndSortedTsKvDTOST.get(i); + tsKvDTOY.setVal(new BigDecimal(tsKvDTOY.getVal()).divide(new BigDecimal(1000),2,RoundingMode.HALF_UP).toString()); + } + result.put("today", distinctAndSortedTsKvDTOST); + result.put("yesterday", distinctAndSortedTsKvDTOSY); + result.put("yy", yyTskv); + return result; + } + + + + /** + * 获取指定时间戳所在的整点时间戳 + * + * @param timestamp 时间戳 + * @return 整点时间戳 + */ + public static long getStartOfHour(long timestamp) { + // 将时间戳截断到整点(小时) + return (timestamp / 3600000) * 3600000; + } + + + @Override + public Map> getElectricPowerAnalysis(Long plantId, String type) { + Map> result = new HashMap<>(); + Optional entityByCode = thingEntityService.findEntityByCode(plantId.toString(), UserContext.getRealTenantCode(), true); + if (StringUtils.endsWithIgnoreCase(type, ThingAttrType.YY.getTime().getName())) { + String yearBeginTime = DateTimeUtils.getYearBeginTime(); + Long startTime = DateTimeUtils.convertTimeToLong(yearBeginTime); + String yearEndTime = DateTimeUtils.getYearEndTime(); + Long endTime = DateTimeUtils.convertTimeToLong(yearEndTime); + //时间列表 + List intervalTimeList = DateTimeUtils.getIntervalMonthList(startTime, endTime, 1); + consumption(entityByCode.get(), startTime, endTime, intervalTimeList, attrA29mm, attrA30mm, 1, TimeType.MONTH, result); + } + if (StringUtils.endsWithIgnoreCase(type, ThingAttrType.MM.getTime().getName())) { + String monthBeginTime = DateTimeUtils.getMonthBeginTime(); + Long startTime = DateTimeUtils.convertTimeToLong(monthBeginTime); + String monthEndTime = DateTimeUtils.getMonthEndTime(); + Long endTime = DateTimeUtils.convertTimeToLong(monthEndTime); + List intervalTimeList = DateTimeUtils.getIntervalDayList(startTime, endTime, 1); + consumption(entityByCode.get(), startTime, endTime, intervalTimeList, attrA29dd, attrA30dd, 1, TimeType.DAY, result); + } + return result; + } + + @Override + public Map> getInverterDetails(String code) { + return null; + } + + @Override + public List getReportElectric(ChargeStatisticRequest chargeStatisticRequest) { + List resultList = new ArrayList<>(); + List thingIds = chargeStatisticRequest.getThingIds(); + List entities = thingEntityService.findEntityByIds(thingIds); + if (CollectionUtils.isEmpty(entities)) { + return resultList; + } + List codes = entities.stream().map(IotThingEntityDTO::getCode).toList(); + String attrType = chargeStatisticRequest.getAttrType(); + Long startTime = 0L; + Long endTime = 0L; + List timeList = new ArrayList<>(); + String timeType = chargeStatisticRequest.getTimeType(); + if (StringUtils.equalsIgnoreCase(TimeType.DAY.getName(), timeType)) { + String dayBeginTime = DateTimeUtils.getDayBeginTime(chargeStatisticRequest.getBeginTime()); + startTime = DateTimeUtils.dateToTimestamp(dayBeginTime); + endTime = startTime + ONE_DAY - 1; + timeList = DateTimeUtils.getIntervalList(startTime, endTime, 60 * 60 * 1000); + } + if (StringUtils.equalsIgnoreCase(TimeType.MONTH.getName(), timeType)) { + String monthBeginTime = DateTimeUtils.getMonthBeginTime(chargeStatisticRequest.getBeginTime()); + String monthEndTime = DateTimeUtils.getMonthEndTime(chargeStatisticRequest.getBeginTime()); + startTime = DateTimeUtils.dateToTimestamp(monthBeginTime); + endTime = DateTimeUtils.dateToTimestamp(monthEndTime); + timeList = DateTimeUtils.getIntervalDayList(startTime, endTime, 1); + } + if (StringUtils.equalsIgnoreCase(TimeType.YEAR.getName(), timeType)) { + String monthBeginTime = DateTimeUtils.getYearBeginTime(chargeStatisticRequest.getBeginTime()); + String monthEndTime = DateTimeUtils.getYearEndTime(chargeStatisticRequest.getBeginTime()); + startTime = DateTimeUtils.convertTimeToLong(monthBeginTime); + endTime = DateTimeUtils.convertTimeToLong(monthEndTime); + timeList = DateTimeUtils.getIntervalMonthList(startTime, endTime, 1); + } + if (StringUtils.equalsIgnoreCase(TimeType.ANY.getName(), timeType)) { + startTime = DateTimeUtils.dateToTimestamp(chargeStatisticRequest.getBeginTime()); + endTime = DateTimeUtils.dateToTimestamp(chargeStatisticRequest.getEndTime()); + } + long currentTime = DateTimeUtils.getCurrentTime(); + //去除超过的时间 + timeList.removeIf(s -> CompareUtil.compare(s, currentTime) > 0); + List tsKvList = tsKvService.findTsKvByCodesAndAttrs(codes, Lists.newArrayList(attrA29 + attrType), startTime, endTime, false); + + List finalTimeList = timeList; + if (CollectionUtils.isEmpty(tsKvList)) { + return entities.stream().map(e -> { + PhotovoltaicReportDTO reportDTO = new PhotovoltaicReportDTO(); + reportDTO.setThingId(e.getId()); + reportDTO.setCode(e.getCode()); + reportDTO.setName(e.getName()); + reportDTO.setTimeList(finalTimeList); + return reportDTO; + }).toList(); + } + + return entities.stream().map(e -> { + PhotovoltaicReportDTO reportDTO = new PhotovoltaicReportDTO(); + reportDTO.setThingId(e.getId()); + reportDTO.setCode(e.getCode()); + reportDTO.setName(e.getName()); + reportDTO.setTimeList(finalTimeList); + //过滤数据 + List dataList = tsKvList.stream().filter(tsKvDTO -> StringUtils.equals(tsKvDTO.getThingCode(), e.getCode())).toList(); + + List> collect = Lists.newArrayList(); + for (int i = 0; i < finalTimeList.size(); i++) { + int finalI = i; + List list; + if(i== (finalTimeList.size()-1)){ + list = dataList.stream().filter(s -> CompareUtil.compare(s.getTs(), finalTimeList.get(finalI)) >= 0 ) + .toList(); + }else { + list = dataList.stream().filter(s -> CompareUtil.compare(s.getTs(), finalTimeList.get(finalI)) >= 0 && CompareUtil.compare(s.getTs(), finalTimeList.get(finalI + 1)) < 0).toList(); + } + BigDecimal total = list.stream().map(s -> new BigDecimal(s.getVal())).reduce(BigDecimal.ZERO, BigDecimal::add); + collect.addAll(list.stream().map(data -> Map.of("ts", finalTimeList.get(finalI), "val", total)).toList()); + + } + reportDTO.setPlantDataList(collect); + BigDecimal total = dataList.stream().map(s -> new BigDecimal(s.getVal())).reduce(BigDecimal.ZERO, BigDecimal::add); + reportDTO.setElectricityUsage(total); + return reportDTO; + }).toList(); + } + + @Override + public void electricExport(ChargeStatisticRequest chargeStatisticRequest, HttpServletResponse response) { + List reportDTOList = getReportElectric(chargeStatisticRequest); + //获取动态时间 + List timeList = reportDTOList.get(0).getTimeList(); + //创建表头 + List tableHeaderList = getTableHeader(timeList, chargeStatisticRequest.getTimeType()); + + if (CollectionUtils.isEmpty(reportDTOList)) { + ExportParams exportParams = new ExportParams("发电统计报表", "发电统计"); + Workbook workbook = ExcelExportUtil.exportExcel(exportParams, tableHeaderList, Lists.newArrayList()); + ExcelUtils.downLoadExcel("发电统计报表.xls", response, workbook); + } + List> dataList = new ArrayList<>(); + for (PhotovoltaicReportDTO photovoltaicReportDTO : reportDTOList) { + Map valMap = new HashMap<>(); + valMap.put("name", photovoltaicReportDTO.getName()); + valMap.put("electricityUsage", photovoltaicReportDTO.getElectricityUsage()); + List> plantDataList = photovoltaicReportDTO.getPlantDataList(); + if (CollectionUtils.isNotEmpty(plantDataList)) { + for (Map plantData : plantDataList) { + Long ts = MapUtils.getLong(plantData, "ts"); + String val = MapUtils.getString(plantData, "val"); + valMap.put(String.valueOf(ts), val); + } + } + dataList.add(valMap); + } + ExportParams exportParams = new ExportParams("发电统计报表", "发电统计"); + Workbook workbook = ExcelExportUtil.exportExcel(exportParams, tableHeaderList, dataList); + ExcelUtils.downLoadExcel("发电统计报表.xls", response, workbook); + } + + @Override + public List getReportConsumption(ChargeStatisticRequest chargeStatisticRequest) { + List resultList = new ArrayList<>(); + List thingIds = chargeStatisticRequest.getThingIds(); + List entities = thingEntityService.findEntityByIds(thingIds); + if (CollectionUtils.isEmpty(entities)) { + return resultList; + } + List codes = entities.stream().map(IotThingEntityDTO::getCode).toList(); + String attrType = chargeStatisticRequest.getAttrType(); + Long startTime = 0L; + Long endTime = 0L; + List timeList = new ArrayList<>(); + String timeType = chargeStatisticRequest.getTimeType(); + if (StringUtils.equalsIgnoreCase(TimeType.DAY.getName(), timeType)) { + String dayBeginTime = DateTimeUtils.getDayBeginTime(chargeStatisticRequest.getBeginTime()); + startTime = DateTimeUtils.dateToTimestamp(dayBeginTime); + endTime = startTime + ONE_DAY - 1; + timeList = DateTimeUtils.getIntervalList(startTime, endTime, 60 * 60 * 1000); + } + if (StringUtils.equalsIgnoreCase(TimeType.MONTH.getName(), timeType)) { + String monthBeginTime = DateTimeUtils.getMonthBeginTime(chargeStatisticRequest.getBeginTime()); + String monthEndTime = DateTimeUtils.getMonthEndTime(chargeStatisticRequest.getBeginTime()); + startTime = DateTimeUtils.dateToTimestamp(monthBeginTime); + endTime = DateTimeUtils.dateToTimestamp(monthEndTime); + timeList = DateTimeUtils.getIntervalDayList(startTime, endTime, 1); + } + + if (StringUtils.equalsIgnoreCase(TimeType.YEAR.getName(), timeType)) { + String monthBeginTime = DateTimeUtils.getYearBeginTime(chargeStatisticRequest.getBeginTime()); + String monthEndTime = DateTimeUtils.getYearEndTime(chargeStatisticRequest.getBeginTime()); + startTime = DateTimeUtils.convertTimeToLong(monthBeginTime); + endTime = DateTimeUtils.convertTimeToLong(monthEndTime); + timeList = DateTimeUtils.getIntervalMonthList(startTime, endTime, 1); + } + if (StringUtils.equalsIgnoreCase(TimeType.ANY.getName(), timeType)) { + startTime = DateTimeUtils.dateToTimestamp(chargeStatisticRequest.getBeginTime()); + endTime = DateTimeUtils.dateToTimestamp(chargeStatisticRequest.getEndTime()); + } + + long currentTime = DateTimeUtils.getCurrentTime(); + //去除超过的时间 + timeList.removeIf(s -> CompareUtil.compare(s, currentTime) > 0); + //发电量 + List tsKvList29 = getFillDataList(codes, attrA29 + attrType, startTime, endTime, timeList); + //上网量 + List tsKvList30 = getFillDataList(codes, attrA30 + attrType, startTime, endTime, timeList); + //获取总量 + List finalTimeList = timeList; + entities.forEach(e -> { + PhotovoltaicReportDTO photovoltaicReportDTO = new PhotovoltaicReportDTO(); + photovoltaicReportDTO.setThingId(e.getId()); + photovoltaicReportDTO.setCode(e.getCode()); + photovoltaicReportDTO.setName(e.getName()); + photovoltaicReportDTO.setTimeList(finalTimeList); + List list29 = tsKvList29.stream().filter(tsKvDTO -> StringUtils.equals(tsKvDTO.getThingCode(), e.getCode()) && StringUtils.startsWith(tsKvDTO.getAttrKey(), attrA29)).toList(); + BigDecimal reduce29 = list29.stream().map(s -> new BigDecimal(s.getVal())).reduce(BigDecimal.ZERO, BigDecimal::add); + List list30 = tsKvList30.stream().filter(tsKvDTO -> StringUtils.equals(tsKvDTO.getThingCode(), e.getCode()) && StringUtils.startsWith(tsKvDTO.getAttrKey(), attrA30)).toList(); + BigDecimal reduce30 = list30.stream().map(s -> new BigDecimal(s.getVal())).reduce(BigDecimal.ZERO, BigDecimal::add); + //消纳量 = 发电量 - 上网量 + BigDecimal consumption = reduce29.subtract(reduce30); + //消纳率 + BigDecimal performance = CalculationUtil.getPerformance(consumption, reduce29, 4); + PhotovoltaicConsumptionDTO consumptionTotal = new PhotovoltaicConsumptionDTO(); + consumptionTotal.setElectricityUsage(reduce29); + consumptionTotal.setInternetUsage(reduce30); + consumptionTotal.setConsumptionUsage(consumption); + consumptionTotal.setConsumptionRate(performance); + photovoltaicReportDTO.setConsumptionTotal(consumptionTotal); + //时间段的消纳报表数据 + List consumptionDTOList = Lists.newArrayList(); + + for (int i = 0; i < finalTimeList.size(); i++) { + int finalI = i; + List list2; + List list3; + if(i== (finalTimeList.size()-1)){ + list2 = list29.stream().filter(s -> CompareUtil.compare(s.getTs(), finalTimeList.get(finalI)) >= 0 ) + .toList(); + list3 = list30.stream().filter(s -> CompareUtil.compare(s.getTs(), finalTimeList.get(finalI)) >= 0 ) + .toList(); + }else { + list2 = list29.stream().filter(s -> CompareUtil.compare(s.getTs(), finalTimeList.get(finalI)) >= 0 && CompareUtil.compare(s.getTs(), finalTimeList.get(finalI + 1)) < 0) + .toList(); + list3 = list30.stream().filter(s -> CompareUtil.compare(s.getTs(), finalTimeList.get(finalI)) >= 0 && CompareUtil.compare(s.getTs(), finalTimeList.get(finalI + 1)) < 0) + .toList(); + } + BigDecimal reduce2 = list2.stream().map(s -> new BigDecimal(s.getVal())).reduce(BigDecimal.ZERO, BigDecimal::add); + BigDecimal reduce3 = list3.stream().map(s -> new BigDecimal(s.getVal())).reduce(BigDecimal.ZERO, BigDecimal::add); + PhotovoltaicConsumptionDTO consumptionDTO = new PhotovoltaicConsumptionDTO(); + consumptionDTO.setElectricityUsage(reduce2); + consumptionDTO.setInternetUsage(reduce3); + BigDecimal subtract = reduce2.subtract(reduce3); + consumptionDTO.setConsumptionUsage(subtract); + consumptionDTO.setConsumptionRate(CalculationUtil.getPerformance(subtract, reduce2, 4)); + consumptionDTO.setTs(finalTimeList.get(finalI)); + consumptionDTOList.add(consumptionDTO); + } + photovoltaicReportDTO.setConsumptionDataList(consumptionDTOList); + resultList.add(photovoltaicReportDTO); + }); + return resultList; + } + + @Override + public void consumptionExport(ChargeStatisticRequest chargeStatisticRequest, HttpServletResponse response) { + try { + List reportDTOList = getReportConsumption(chargeStatisticRequest); + //获取动态时间 + List timeList = reportDTOList.get(0).getTimeList(); + //创建表头 + List tableHeaderList = getConsumptionTableHeader(timeList, chargeStatisticRequest.getTimeType()); + if (CollectionUtils.isEmpty(reportDTOList)) { + ExportParams exportParams = new ExportParams("上网消纳报表", "上网消纳"); + Workbook workbook = ExcelExportUtil.exportExcel(exportParams, tableHeaderList, Lists.newArrayList()); + ExcelUtils.downLoadExcel("上网消纳报表.xls", response, workbook); + } + List> dataList = new ArrayList<>(); + for (PhotovoltaicReportDTO photovoltaicReportDTO : reportDTOList) { + Map valMap = new HashMap<>(); + valMap.put("name", photovoltaicReportDTO.getName()); + //发电总量的数据 + PhotovoltaicConsumptionDTO consumptionTotal = photovoltaicReportDTO.getConsumptionTotal(); + List> yhxxList = new ArrayList<>(); + Map yhxxMap = new HashMap<>(); + yhxxMap.put("electricityUsage", consumptionTotal.getElectricityUsage()); + yhxxMap.put("consumptionUsage", consumptionTotal.getConsumptionUsage()); + yhxxMap.put("internetUsage", consumptionTotal.getInternetUsage()); + yhxxMap.put("consumptionRate", consumptionTotal.getConsumptionRate()); + yhxxList.add(yhxxMap); + valMap.put("electricityUsage", yhxxList); + //动态时间量 + List consumptionDataList = photovoltaicReportDTO.getConsumptionDataList(); + consumptionDataList.forEach(c -> { +// int time = 0; +// if (StringUtils.equalsIgnoreCase(TimeType.DAY.getName(), chargeStatisticRequest.getTimeType())){ +// time = DateTimeUtils.parseDateTime(c.getTs()).getHour(); +// } +// if (StringUtils.equalsIgnoreCase(TimeType.MONTH.getName(), chargeStatisticRequest.getTimeType())){ +// time = DateTimeUtils.parseDateTime(c.getTs()).getDayOfMonth(); +// } +// if (StringUtils.equalsIgnoreCase(TimeType.YEAR.getName(), chargeStatisticRequest.getTimeType())){ +// time = DateTimeUtils.parseDateTime(c.getTs()).getMonth().getValue(); +// } + List> yhxxList1 = new ArrayList<>(); + Map yhxxMap1 = new HashMap<>(); + yhxxMap1.put("electricityUsage", c.getElectricityUsage()); + yhxxMap1.put("consumptionUsage", c.getConsumptionUsage()); + yhxxMap1.put("internetUsage", c.getInternetUsage()); + yhxxMap1.put("consumptionRate", c.getConsumptionRate()); + yhxxList1.add(yhxxMap1); + valMap.put(String.valueOf(c.getTs()), yhxxList1); + }); + dataList.add(valMap); + } + ExportParams exportParams = new ExportParams("发电统计报表", "发电统计"); + Workbook workbook = ExcelExportUtil.exportExcel(exportParams, tableHeaderList, dataList); + ExcelUtils.downLoadExcel("发电统计报表.xls", response, workbook); + } catch (Exception e) { + log.error("222222", e); + } + } + + private List getFillDataList(List codes, String attr, Long startTime, Long endTime, List timeList) { + List tsKvList29 = tsKvService.findTsKvByCodesAndAttrs(codes, Lists.newArrayList(attr), startTime, endTime, false); + return codes.stream().flatMap(s -> fillData(timeList, tsKvList29, s, attr).stream()).toList(); + } + + private void consumption(IotThingEntityDTO thingEntityDTO, Long startTime, Long endTime, List intervalTimeList, String attrA29, String attrA30, Integer interval, TimeType timeType, Map> result) { + //月发电量 + List tsKvYYList = tsKvService.findTsKvByCodeAndAttr(thingEntityDTO.getCode(), attrA29, startTime, endTime, true); + //补全数据 + List tsKvDTOS = fillData(intervalTimeList, tsKvYYList, thingEntityDTO.getCode(), attrA29); + //月上网量 + List tsKvYY30List = tsKvService.findTsKvByCodeAndAttr(thingEntityDTO.getCode(), attrA30, startTime, endTime, true); + //List tsKvYY30List = tsKvService.findTsKvIntervalAggByCodeAndAttr(thingEntityDTO.getCode(), attrA30, startTime, endTime, AggType.SUM, interval, timeType, true); + //补全数据 + List tsKv30DTOS = fillData(intervalTimeList, tsKvYY30List, thingEntityDTO.getCode(), attrA30); + //消纳量 + List consumptionTskv = Lists.newArrayList(); + List consumptionTskvRate = Lists.newArrayList(); + for (int i = 0; i < tsKvDTOS.size(); i++) { + TsKvDTO tsKvDTO29 = tsKvDTOS.get(i); + tsKvDTO29.setVal(new BigDecimal(tsKvDTO29.getVal())/*.divide(new BigDecimal(1000), 2, BigDecimal.ROUND_HALF_UP)*/.toPlainString()); + TsKvDTO tsKvDTO30 = tsKv30DTOS.get(i); + //消纳量 + BigDecimal consumption = new BigDecimal(tsKvDTO29.getVal()).subtract(new BigDecimal(tsKvDTO30.getVal())); + TsKvDTO tsKv = new TsKvDTO(thingEntityDTO.getCode(), "consumption", tsKvDTO29.getTs(), consumption.toString()); + consumptionTskv.add(tsKv); + //消纳比 + BigDecimal consumptionPerformance = CalculationUtil.getPerformance(consumption, new BigDecimal(tsKvDTO29.getVal()), 4); + TsKvDTO tsKvDTO = new TsKvDTO(thingEntityDTO.getCode(), "consumptionRate", tsKvDTO29.getTs(), consumptionPerformance.toString()); + consumptionTskvRate.add(tsKvDTO); + } + result.put("A29", tsKvDTOS); + result.put("consumption",consumptionTskv); + result.put("consumptionRate", consumptionTskvRate); + } + + + private ScreenData.AttrData getAttr(List tsKvDTOList, String attrCode, String attrName, String attrUnit, BigDecimal defaultVal) { + ScreenData.AttrData attrData = new ScreenData.AttrData(); + attrData.setAttrCode(attrCode); + attrData.setAttrName(attrName); + attrData.setAttrUnit(attrUnit); + if (CollectionUtils.isNotEmpty(tsKvDTOList)) { + if(attrCode.startsWith(attrA29)){ + //attrData.setAttrValue(filterAttrVal(tsKvDTOList, attrCode).toString()); + attrData.setAttrValue(filterAttrVal(tsKvDTOList, attrCode)/*.divide(new BigDecimal("1000"),2, RoundingMode.UP)*/.toPlainString()); + }else { + attrData.setAttrValue(filterAttrVal(tsKvDTOList, attrCode).divide(new BigDecimal("1000"),2, RoundingMode.UP).toPlainString()); + } + } else { + attrData.setAttrValue(defaultVal.toString()); + } + return attrData; + } + + private static BigDecimal filterAttrVal(List tsKvDTOList, String attrCode) { + return tsKvDTOList.stream() + .filter(d -> StringUtils.equals(attrCode, d.getAttrKey())) + .map(d -> new BigDecimal(d.getVal())) + .findFirst() + .orElse(BigDecimal.ZERO); + } + + private static List fillData(List intervalTimeList, List tsKvList, String code, String attr) { + if (CollectionUtils.isEmpty(tsKvList)) { + return intervalTimeList.stream() + .map(s -> new TsKvDTO(code, attr, s, "0")) + .collect(Collectors.toList()); + } + if(CollectionUtils.isEmpty(intervalTimeList)){ + return tsKvList; + } + List handleList = tsKvList.stream().filter(d -> StringUtils.equals(code, d.getThingCode()) && StringUtils.equals(attr, d.getAttrKey())).toList(); + Map>> groupedMap = handleList.stream() + .collect(Collectors.groupingBy(TsKvDTO::getThingCode, + Collectors.groupingBy(TsKvDTO::getAttrKey))); + List result = new ArrayList<>(); + for (Map.Entry>> stringMapEntry : groupedMap.entrySet()) { + String thingCode = stringMapEntry.getKey(); + for (Map.Entry> stringListEntry : stringMapEntry.getValue().entrySet()) { + String attrKey = stringListEntry.getKey(); + List value = stringListEntry.getValue(); + List existingTimestamps = value.stream().map(TsKvDTO::getTs).toList(); + for (Long timestamp : intervalTimeList) { + if (existingTimestamps.contains(timestamp)) { + TsKvDTO tsKvDTO1 = value.stream() + .filter(tsKvDTO -> tsKvDTO.getTs().equals(timestamp)) + .findAny().orElse(null); + //电力要/1000 + if (ObjectUtil.isNotNull(tsKvDTO1) && tsKvDTO1.getAttrKey().startsWith(attrA16)) { + BigDecimal performance = CalculationUtil.getPerformance(new BigDecimal(tsKvDTO1.getVal()), new BigDecimal(1000), 2); + tsKvDTO1.setVal(performance.toString()); + } + result.add(tsKvDTO1); + } else { + result.add(new TsKvDTO(thingCode, attrKey, timestamp, "0")); + } + } + } + } + return result; + } + + private List getConsumptionTableHeader(List timeList, String timeType) { + List paramCols = new ArrayList<>(); + ExcelExportEntity colEntity1 = new ExcelExportEntity("结构", "name"); + colEntity1.setNeedMerge(true); + paramCols.add(colEntity1); + ExcelExportEntity colEntity2 = new ExcelExportEntity("发电总量(kWh)", "electricityUsage"); + List yyxxList = new ArrayList<>(); + yyxxList.add(new ExcelExportEntity("发电量", "electricityUsage")); + yyxxList.add(new ExcelExportEntity("消纳量", "consumptionUsage")); + yyxxList.add(new ExcelExportEntity("上网量", "internetUsage")); + yyxxList.add(new ExcelExportEntity("消纳率", "consumptionRate")); + colEntity2.setList(yyxxList); + paramCols.add(colEntity2); + //动态表头集合 + paramCols.addAll(new ArrayList<>(timeList.stream() + .flatMap(c -> { + ExcelExportEntity excelExportEntity = null; + if (StringUtils.equalsIgnoreCase(TimeType.DAY.getName(), timeType)) { + int hour = DateTimeUtils.parseDateTime(c).getHour(); + excelExportEntity = new ExcelExportEntity(hour + "时", String.valueOf(c)); + } + if (StringUtils.equalsIgnoreCase(TimeType.MONTH.getName(), timeType)) { + int day = DateTimeUtils.parseDateTime(c).getDayOfMonth(); + excelExportEntity = new ExcelExportEntity(day + "日", String.valueOf(c)); + } + if (StringUtils.equalsIgnoreCase(TimeType.YEAR.getName(), timeType)) { + int month = DateTimeUtils.parseDateTime(c).getMonth().getValue(); + excelExportEntity = new ExcelExportEntity(month + "月", String.valueOf(c)); + } + List yyxxList1 = new ArrayList<>(); + yyxxList1.add(new ExcelExportEntity("发电量", "electricityUsage")); + yyxxList1.add(new ExcelExportEntity("消纳量", "consumptionUsage")); + yyxxList1.add(new ExcelExportEntity("上网量", "internetUsage")); + yyxxList1.add(new ExcelExportEntity("消纳率", "consumptionRate")); + if (ObjectUtil.isNotNull(excelExportEntity)) { + excelExportEntity.setList(yyxxList1); + return Stream.of(excelExportEntity); + } + return Stream.empty(); + }).toList())); + return paramCols; + } + + private List getTableHeader(List timeList, String timeType) { + List paramCols = new ArrayList<>(); + ExcelExportEntity colEntity1 = new ExcelExportEntity("结构", "name"); + paramCols.add(colEntity1); + ExcelExportEntity colEntity2 = new ExcelExportEntity("发电总量(kWh)", "electricityUsage"); + paramCols.add(colEntity2); + //动态表头集合 + paramCols.addAll(new ArrayList<>(timeList.stream() + .flatMap(c -> { + if (StringUtils.equalsIgnoreCase(TimeType.DAY.getName(), timeType)) { + int hour = DateTimeUtils.parseDateTime(c).getHour(); + return Stream.of(new ExcelExportEntity(hour + "时", String.valueOf(c))); + } + if (StringUtils.equalsIgnoreCase(TimeType.MONTH.getName(), timeType)) { + int day = DateTimeUtils.parseDateTime(c).getDayOfMonth(); + return Stream.of(new ExcelExportEntity(day + "日", String.valueOf(c))); + } + if (StringUtils.equalsIgnoreCase(TimeType.YEAR.getName(), timeType)) { + int month = DateTimeUtils.parseDateTime(c).getMonth().getValue(); + return Stream.of(new ExcelExportEntity(month + "月", String.valueOf(c))); + } + return Stream.empty(); + }).toList())); + return paramCols; + } + +} \ No newline at end of file diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/controller/IotEnergyConsumptionTargetController.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/controller/IotEnergyConsumptionTargetController.java new file mode 100644 index 0000000..b87345e --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/controller/IotEnergyConsumptionTargetController.java @@ -0,0 +1,100 @@ +package com.thing.qingyuan.regionalenterprises.consumptionTarget.controller; + + +import com.thing.qingyuan.regionalenterprises.consumptionTarget.dto.IotEnergyConsumptionTargetDTO; +import com.thing.qingyuan.regionalenterprises.consumptionTarget.dto.IotEnergyValueDTO; +import com.thing.qingyuan.regionalenterprises.consumptionTarget.service.IotEnergyConsumptionTargetService; +import com.thing.common.core.annotation.LogOperation; +import com.thing.common.core.constants.Constant; +import com.thing.common.core.validator.AssertUtils; +import com.thing.common.core.validator.ValidatorUtils; +import com.thing.common.core.validator.group.AddGroup; +import com.thing.common.core.validator.group.DefaultGroup; +import com.thing.common.core.validator.group.UpdateGroup; +import com.thing.common.core.web.response.PageData; +import com.thing.common.core.web.response.Result; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.Map; + +@RestController +@RequestMapping("target") +@Tag(name = "工业增加值") +public class IotEnergyConsumptionTargetController { + + @Autowired + private IotEnergyConsumptionTargetService iotEnergyConsumptionTargetService; + + @GetMapping("page") + @Operation(summary="分页") + @Parameters({ + @Parameter(name = Constant.PAGE,description ="当前页码,从1开始") , + @Parameter(name = Constant.LIMIT,description ="每页显示记录数") , + @Parameter(name = Constant.ORDER_FIELD,description ="排序字段") , + @Parameter(name = "regionCode",description ="区域"), + @Parameter(name = "industryType",description ="行业"), + @Parameter(name = "name",description ="企业名称"), + @Parameter(name = "year",description ="年份"), + + }) + public Result> page(@Parameter(hidden = true) @RequestParam Map params){ + PageData pageData = iotEnergyConsumptionTargetService.pageList(params); + return new Result>().ok(pageData); + } + +// @GetMapping("list") +// @Operation(summary="列表") +// @Parameters({ +// @Parameter(name = Constant.PAGE,description ="当前页码,从1开始") , +// @Parameter(name = Constant.LIMIT,description ="每页显示记录数") , +// @Parameter(name = Constant.ORDER_FIELD,description ="排序字段") , +// @Parameter(name = Constant.ORDER,description ="排序方式,可选值(asc、desc)") +// }) +// public Result> list(@RequestParam Map params){ +// List list = iotEnergyConsumptionTargetService.findAllList(params); +// return new Result>().ok(list); +// } +// + @GetMapping("{id}") + @Operation(summary="信息") + public Result get(@PathVariable("id") Long id){ + IotEnergyValueDTO data = iotEnergyConsumptionTargetService.getByIds(id); + return new Result().ok(data); + } + + @PostMapping + @Operation(summary="保存") + @LogOperation("保存") + public Result save(@RequestBody IotEnergyValueDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class); + iotEnergyConsumptionTargetService.addTarget(dto); + return new Result<>(); + } + + @PutMapping + @Operation(summary="修改") + @LogOperation("修改") + public Result update(@RequestBody IotEnergyValueDTO dto){ + // 效验数据 + ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class); + iotEnergyConsumptionTargetService.updateList(dto); + return new Result<>(); + } + + @DeleteMapping + @Operation(summary="删除") + @LogOperation("删除") + public Result delete(@RequestBody Long[] ids){ + // 效验数据 + AssertUtils.isArrayEmpty(ids, "id"); + iotEnergyConsumptionTargetService.deleteByids(ids); + return new Result<>(); + } + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/controller/IotValueAddedController.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/controller/IotValueAddedController.java new file mode 100644 index 0000000..8a16630 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/controller/IotValueAddedController.java @@ -0,0 +1,101 @@ +package com.thing.qingyuan.regionalenterprises.consumptionTarget.controller; + + +import com.thing.qingyuan.regionalenterprises.consumptionTarget.dto.IotValueAddDTO; +import com.thing.qingyuan.regionalenterprises.consumptionTarget.dto.iotValueAddedDTO; +import com.thing.qingyuan.regionalenterprises.consumptionTarget.service.IotValueAddedService; +import com.thing.common.core.annotation.LogOperation; +import com.thing.common.core.constants.Constant; +import com.thing.common.core.validator.AssertUtils; +import com.thing.common.core.validator.ValidatorUtils; +import com.thing.common.core.validator.group.AddGroup; +import com.thing.common.core.validator.group.DefaultGroup; +import com.thing.common.core.validator.group.UpdateGroup; +import com.thing.common.core.web.response.PageData; +import com.thing.common.core.web.response.Result; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.Map; + +@RestController +@RequestMapping("valueAdded") +@Tag(name = "能碳指标") +public class IotValueAddedController { + + @Autowired + private IotValueAddedService iotValueAddedService; + + @GetMapping("page") + @Operation(summary="分页") + @Parameters({ + @Parameter(name = Constant.PAGE,description ="当前页码,从1开始") , + @Parameter(name = Constant.LIMIT,description ="每页显示记录数") , + @Parameter(name = Constant.ORDER_FIELD,description ="排序字段") , + @Parameter(name = "regionCode",description ="区域"), + @Parameter(name = "industryType",description ="行业"), + @Parameter(name = "name",description ="企业名称"), + @Parameter(name = "year",description ="年份"), + + }) + public Result> page(@Parameter(hidden = true) @RequestParam Map params){ + PageData pageData = iotValueAddedService.pageList(params); + return new Result>().ok(pageData); + } + + // @GetMapping("list") +// @Operation(summary="列表") +// @Parameters({ +// @Parameter(name = Constant.PAGE,description ="当前页码,从1开始") , +// @Parameter(name = Constant.LIMIT,description ="每页显示记录数") , +// @Parameter(name = Constant.ORDER_FIELD,description ="排序字段") , +// @Parameter(name = Constant.ORDER,description ="排序方式,可选值(asc、desc)") +// }) +// public Result> list(@RequestParam Map params){ +// List list = iotValueAddedService.findAllList(params); +// return new Result>().ok(list); +// } +// + @GetMapping("{id}") + @Operation(summary="信息") + public Result get(@PathVariable("id") Long id){ + IotValueAddDTO data = iotValueAddedService.getByIds(id); + return new Result().ok(data); + } + + @PostMapping + @Operation(summary="保存") + @LogOperation("保存") + public Result save(@RequestBody IotValueAddDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class); + iotValueAddedService.addTarget(dto); + return new Result<>(); + } + + @PutMapping + @Operation(summary="修改") + @LogOperation("修改") + public Result update(@RequestBody IotValueAddDTO dto){ + // 效验数据 + ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class); + iotValueAddedService.updateList(dto); + return new Result<>(); + } + + @DeleteMapping + @Operation(summary="删除") + @LogOperation("删除") + public Result delete(@RequestBody Long[] ids){ + // 效验数据 + AssertUtils.isArrayEmpty(ids, "id"); + iotValueAddedService.deleteByids(ids); + return new Result<>(); + } + + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/dto/IotAddedDateDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/dto/IotAddedDateDTO.java new file mode 100644 index 0000000..110266b --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/dto/IotAddedDateDTO.java @@ -0,0 +1,26 @@ +package com.thing.qingyuan.regionalenterprises.consumptionTarget.dto; + +import com.thing.common.orm.entity.BaseDateEntity; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class IotAddedDateDTO extends BaseDateEntity { + + + @Schema(description = "租户code") + private Long tenantCode; + + @Schema(description = "能耗目标") + private BigDecimal addedValue; + + @Schema(description = "月份") + private String month; + + @Schema(description = "类型") + private Integer type; + + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/dto/IotDataValueDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/dto/IotDataValueDTO.java new file mode 100644 index 0000000..48a716c --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/dto/IotDataValueDTO.java @@ -0,0 +1,26 @@ +package com.thing.qingyuan.regionalenterprises.consumptionTarget.dto; + +import com.thing.common.orm.entity.BaseDateEntity; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class IotDataValueDTO extends BaseDateEntity { + + + @Schema(description = "租户code") + private Long tenantCode; + + @Schema(description = "增加值") + private BigDecimal targetValue; + + @Schema(description = "月份") + private String month; + + @Schema(description = "类型") + private Integer type; + + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/dto/IotEnergyConsumptionTargetDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/dto/IotEnergyConsumptionTargetDTO.java new file mode 100644 index 0000000..d2038e4 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/dto/IotEnergyConsumptionTargetDTO.java @@ -0,0 +1,41 @@ +package com.thing.qingyuan.regionalenterprises.consumptionTarget.dto; + +import com.thing.common.core.validator.group.DefaultGroup; +import com.thing.common.orm.entity.BaseDateEntity; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +@Data +@Schema( description= "能耗管理") +public class IotEnergyConsumptionTargetDTO extends BaseDateEntity implements Serializable { + + @Schema(description = "租户code") + private Long tenantCode; + @Schema(description = "增加值") + private String targetValue; + @Schema(description = "类型 0-年 1-月") + private Integer type; + @Schema(description = "年份") + private String year; + @Schema(description = "月数据") + private List values; + @Schema(description = "企业名称") + @NotBlank(message = "企业名称不能为空", groups = DefaultGroup.class) + private String name; + @Schema(description = "行业大类编码") + private String industryType; + @Schema(description = "行业大类名称") + private String industryTypeName; + @Schema(description = "地区code") + @NotBlank(message = "地区不能为空", groups = DefaultGroup.class) + private Long regionCode; + @Schema(description = "地区名称") + private String regionCodeName; + + + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/dto/IotEnergyValueDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/dto/IotEnergyValueDTO.java new file mode 100644 index 0000000..be2ceca --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/dto/IotEnergyValueDTO.java @@ -0,0 +1,50 @@ +package com.thing.qingyuan.regionalenterprises.consumptionTarget.dto; + +import com.thing.common.core.validator.group.AddGroup; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.Null; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.List; + +@Data +@Schema( description= "能耗管理") +public class IotEnergyValueDTO implements Serializable { + + @Schema(description = "主键") + @Null(message="{id.null}", groups = AddGroup.class) + private Long id; + @Schema(description = "租户code") + private Long tenantCode; + @Schema(description = "增加值") + private BigDecimal targetValue; + @Schema(description = "类型 0-年 1-月") + private Integer type; + @Schema(description = "年份") + private String year; + @Schema(description = "月数据") + private List values; + /** + * 创建者 + */ + private Long creator; + /** + * 创建时间 + */ + private Long createDate; + + /** + * 修改人 + */ + private Long updater; + + /** + * 修改时间 + */ + private Long updateDate; + + + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/dto/IotValueAddDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/dto/IotValueAddDTO.java new file mode 100644 index 0000000..f96cf51 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/dto/IotValueAddDTO.java @@ -0,0 +1,47 @@ +package com.thing.qingyuan.regionalenterprises.consumptionTarget.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.List; + +@Data +@Schema( description= "工业增加值") +public class IotValueAddDTO implements Serializable { + + @Schema(description = "主键") + private Long id; + @Schema(description = "租户code") + private Long tenantCode; + @Schema(description = "能耗目标") + private BigDecimal addedValue; + @Schema(description = "类型 0-年 1-月") + private Integer type; + @Schema(description = "年份") + private String year; + @Schema(description = "月数据") + private List values; + /** + * 创建者 + */ + private Long creator; + /** + * 创建时间 + */ + private Long createDate; + + /** + * 修改人 + */ + private Long updater; + + /** + * 修改时间 + */ + private Long updateDate; + + + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/dto/iotValueAddedDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/dto/iotValueAddedDTO.java new file mode 100644 index 0000000..382310f --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/dto/iotValueAddedDTO.java @@ -0,0 +1,40 @@ +package com.thing.qingyuan.regionalenterprises.consumptionTarget.dto; + +import com.thing.common.core.validator.group.DefaultGroup; +import com.thing.common.orm.entity.BaseDateEntity; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.List; + +@Data +@Schema( description= "能耗管理") +public class iotValueAddedDTO extends BaseDateEntity implements Serializable { + + @Schema(description = "租户code") + private Long tenantCode; + @Schema(description = "能耗目标") + private BigDecimal addedValue; + @Schema(description = "类型") + private Integer type; + @Schema(description = "年份") + private String year; + @Schema(description = "月数据") + private List values; + @Schema(description = "企业名称") + @NotBlank(message = "企业名称不能为空", groups = DefaultGroup.class) + private String name; + @Schema(description = "行业大类编码") + private String industryType; + @Schema(description = "行业大类名称") + private String industryTypeName; + @Schema(description = "地区code") + @NotBlank(message = "地区不能为空", groups = DefaultGroup.class) + private Long regionCode; + @Schema(description = "地区名称") + private String regionCodeName; + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/entity/IotEnergyConsumptionTargetEntity.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/entity/IotEnergyConsumptionTargetEntity.java new file mode 100644 index 0000000..2d5d42e --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/entity/IotEnergyConsumptionTargetEntity.java @@ -0,0 +1,63 @@ +package com.thing.qingyuan.regionalenterprises.consumptionTarget.entity; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.Table; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; + +@Data +@EqualsAndHashCode(callSuper=false) +@Table("iot_energy_consumption_target") +public class IotEnergyConsumptionTargetEntity implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + /** + * id + */ + @Id + private Long id; + /** + * 租户code + */ + private Long tenantCode; + /** + * 创建人 + */ + private Long creator; + /** + * 创建时间 + */ + private Long createDate; + /** + * 修改人 + */ + private Long updater; + /** + * 修改时间 + */ + private Long updateDate; + /** + * 能耗目标 + */ + private BigDecimal targetValue; + /** + * 类型 0-年 1-月 + */ + private Integer type; + /** + * 年份 + */ + private String year; + /** + * 月份 + */ + private String month; + + + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/entity/IotValueAddedEntity.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/entity/IotValueAddedEntity.java new file mode 100644 index 0000000..6178c18 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/entity/IotValueAddedEntity.java @@ -0,0 +1,63 @@ +package com.thing.qingyuan.regionalenterprises.consumptionTarget.entity; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.Table; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; + +@Data +@EqualsAndHashCode(callSuper=false) +@Table("iot_value_added") +public class IotValueAddedEntity implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + /** + * id + */ + @Id + private Long id; + /** + * 租户code + */ + private Long tenantCode; + /** + * 创建人 + */ + private Long creator; + /** + * 创建时间 + */ + private Long createDate; + /** + * 修改人 + */ + private Long updater; + /** + * 修改时间 + */ + private Long updateDate; + /** + * 增加值 + */ + private BigDecimal addedValue; + /** + * 类型 0-年 1-月 + */ + private Integer type; + /** + * 年份 + */ + private String year; + /** + * 月份 + */ + private String month; + + + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/mapper/IotEnergyConsumptionTargetMapper.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/mapper/IotEnergyConsumptionTargetMapper.java new file mode 100644 index 0000000..0b32b30 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/mapper/IotEnergyConsumptionTargetMapper.java @@ -0,0 +1,36 @@ +package com.thing.qingyuan.regionalenterprises.consumptionTarget.mapper; + + +import com.thing.qingyuan.regionalenterprises.consumptionTarget.dto.IotEnergyConsumptionTargetDTO; +import com.thing.qingyuan.regionalenterprises.consumptionTarget.entity.IotEnergyConsumptionTargetEntity; +import com.thing.common.orm.mapper.PowerBaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Map; + +@Mapper +public interface IotEnergyConsumptionTargetMapper extends PowerBaseMapper { + + List pageList(Map params); + + List getTypeList(@Param("year") String year,@Param("tenantCode") Long tenantCode); + + void insertList(@Param("iotEnergyConsumptionTargetEntity")IotEnergyConsumptionTargetEntity iotEnergyConsumptionTargetEntity); + + IotEnergyConsumptionTargetEntity getByIds(@Param("id")Long id); + + void deleteByIdList(@Param("ids") List ids); + + List getByIdList(Long[] ids); + + List pageLists(Map params); + + BigDecimal getValueByYear(@Param("year") String year,@Param("tenantCode")Long tenantCode); + + BigDecimal getValueByYearAndMonth(@Param("year")String year, @Param("month")String month, @Param("tenantCode")Long tenantCode); + + IotEnergyConsumptionTargetEntity getLists(@Param("tenantCode") Long tenantCode, @Param("year") String year); +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/mapper/IotValueAddedMapper.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/mapper/IotValueAddedMapper.java new file mode 100644 index 0000000..c8aea4e --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/mapper/IotValueAddedMapper.java @@ -0,0 +1,39 @@ +package com.thing.qingyuan.regionalenterprises.consumptionTarget.mapper; + + +import com.mybatisflex.core.BaseMapper; +import com.thing.qingyuan.regionalenterprises.consumptionTarget.dto.iotValueAddedDTO; +import com.thing.qingyuan.regionalenterprises.consumptionTarget.entity.IotValueAddedEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Map; + +@Mapper +public interface IotValueAddedMapper extends BaseMapper { + + List pageList(Map params); + + List getTypeList(@Param("year") String year, @Param("tenantCode") Long tenantCode); + + void insertList(@Param("iotEnergyConsumptionTargetEntity")IotValueAddedEntity iotEnergyConsumptionTargetEntity); + + IotValueAddedEntity getByIds(@Param("id")Long id); + + void deleteByIdList(@Param("ids") List ids); + + List getByIdList(Long[] ids); + + + List pageLists(Map params); + + BigDecimal getSumValueByTenantCodesAndYear(@Param("tenantCodes")List tenantCodes, @Param("year")String year); + + BigDecimal getValueByTenantCodeAndYear(@Param("tenantCode")Long tenantCode, @Param("year") String year); + + BigDecimal getValueByTenantCodeAndYearAndMonth(@Param("tenantCode")Long tenantCode, @Param("year")String year, @Param("month") String month); + + IotValueAddedEntity getyearAndTenanCode(@Param("year") String year, @Param("tenantCode") Long tenantCode); +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/service/IotEnergyConsumptionTargetService.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/service/IotEnergyConsumptionTargetService.java new file mode 100644 index 0000000..d4deeea --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/service/IotEnergyConsumptionTargetService.java @@ -0,0 +1,32 @@ +package com.thing.qingyuan.regionalenterprises.consumptionTarget.service; + + + +import com.thing.qingyuan.regionalenterprises.consumptionTarget.dto.IotEnergyConsumptionTargetDTO; +import com.thing.qingyuan.regionalenterprises.consumptionTarget.dto.IotEnergyValueDTO; +import com.thing.qingyuan.regionalenterprises.consumptionTarget.entity.IotEnergyConsumptionTargetEntity; +import com.thing.common.core.web.response.PageData; +import com.thing.common.orm.service.IBaseService; + +import java.math.BigDecimal; +import java.util.Map; + +public interface IotEnergyConsumptionTargetService extends IBaseService { + + + PageData pageList(Map params); + + IotEnergyValueDTO getByIds(Long id); + + void addTarget(IotEnergyValueDTO dto); + + void updateList(IotEnergyValueDTO dto); + + void deleteByids(Long[] ids); + + PageData page(Map params); + + BigDecimal getValueByYear(String year,Long tenantCode); + + BigDecimal getValueByYearAndMonth(String year, String month, Long tenantCode); +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/service/IotValueAddedService.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/service/IotValueAddedService.java new file mode 100644 index 0000000..6e57985 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/service/IotValueAddedService.java @@ -0,0 +1,34 @@ +package com.thing.qingyuan.regionalenterprises.consumptionTarget.service; + + + +import com.thing.qingyuan.regionalenterprises.consumptionTarget.dto.IotValueAddDTO; +import com.thing.qingyuan.regionalenterprises.consumptionTarget.dto.iotValueAddedDTO; +import com.thing.qingyuan.regionalenterprises.consumptionTarget.entity.IotValueAddedEntity; +import com.thing.common.core.web.response.PageData; +import com.thing.common.orm.service.IBaseService; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Map; + +public interface IotValueAddedService extends IBaseService { + + PageData pageList(Map params); + + IotValueAddDTO getByIds(Long id); + + void addTarget(IotValueAddDTO dto); + + void updateList(IotValueAddDTO dto); + + void deleteByids(Long[] ids); + + BigDecimal getSumValueByTenantCodesAndYear(List tenantCodes, String year); + + BigDecimal getValueByTenantCodeAndYear(Long tenantCode, String year); + + BigDecimal getValueByTenantCodeAndYearAndMonth(Long tenantCode, String year, String month); + + IotValueAddedEntity getyearAndTenanCode(Long id, String year); +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/service/impl/IotEnergyConsumptionTargetServiceImpl.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/service/impl/IotEnergyConsumptionTargetServiceImpl.java new file mode 100644 index 0000000..b8983fd --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/service/impl/IotEnergyConsumptionTargetServiceImpl.java @@ -0,0 +1,342 @@ +package com.thing.qingyuan.regionalenterprises.consumptionTarget.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import com.mybatisflex.core.paginate.Page; +import com.mybatisflex.core.query.QueryWrapper; +import com.thing.qingyuan.regionalenterprises.consumptionTarget.dto.IotDataValueDTO; +import com.thing.qingyuan.regionalenterprises.consumptionTarget.dto.IotEnergyConsumptionTargetDTO; +import com.thing.qingyuan.regionalenterprises.consumptionTarget.dto.IotEnergyValueDTO; +import com.thing.qingyuan.regionalenterprises.consumptionTarget.entity.IotEnergyConsumptionTargetEntity; +import com.thing.qingyuan.regionalenterprises.consumptionTarget.mapper.IotEnergyConsumptionTargetMapper; +import com.thing.qingyuan.regionalenterprises.consumptionTarget.service.IotEnergyConsumptionTargetService; +import com.thing.common.core.exception.SysException; +import com.thing.common.core.utils.DateTimeUtils; +import com.thing.common.core.web.response.PageData; +import com.thing.common.orm.service.impl.BaseServiceImpl; +import com.thing.sys.security.domain.SecurityUser; +import com.thing.sys.security.domain.UserDetail; +import com.thing.sys.tenant.service.SysTenantGroupService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; + +@Service +public class IotEnergyConsumptionTargetServiceImpl extends BaseServiceImpl implements IotEnergyConsumptionTargetService { + + @Autowired + private IotEnergyConsumptionTargetMapper iotEnergyConsumptionTargetMapper; + + @Autowired + private SysTenantGroupService sysTenantGroupService; + + @Override + public QueryWrapper getWrapper(Map params) { + QueryWrapper wrapper = new QueryWrapper(); + wrapper.eq("type", 0); + return wrapper; + } + + @Override + public PageData pageList(Map params) { + //条件查询-分页 + List list = mapper.pageList(params); + for (IotEnergyConsumptionTargetDTO energyConsumptionTargetDTO : list) { + List iotEnergyConsumptionTargetDTO = iotEnergyConsumptionTargetMapper.getTypeList(energyConsumptionTargetDTO.getYear(),energyConsumptionTargetDTO.getTenantCode()); + List sysTenantDetailDTOS = new ArrayList<>(); + for (IotEnergyConsumptionTargetEntity iotEnergyConsumptionTargetEntity : iotEnergyConsumptionTargetDTO) { + IotDataValueDTO iotEnergyValueDTO = new IotDataValueDTO(); + //id + iotEnergyValueDTO.setId(iotEnergyConsumptionTargetEntity.getId()); + //租户编码 + iotEnergyValueDTO.setTenantCode(iotEnergyConsumptionTargetEntity.getTenantCode()); + //能耗 + iotEnergyValueDTO.setTargetValue(iotEnergyConsumptionTargetEntity.getTargetValue()); + //类型 0-年 1-月 + iotEnergyValueDTO.setType(iotEnergyConsumptionTargetEntity.getType()); + //月份 + iotEnergyValueDTO.setMonth(iotEnergyConsumptionTargetEntity.getMonth()); + //创建人 + iotEnergyValueDTO.setCreator(iotEnergyConsumptionTargetEntity.getCreator()); + //创建时间 + iotEnergyValueDTO.setCreateDate(iotEnergyConsumptionTargetEntity.getCreateDate()); + //修改人 + iotEnergyValueDTO.setUpdater(iotEnergyConsumptionTargetEntity.getUpdater()); + //修改时间 + iotEnergyValueDTO.setUpdateDate(iotEnergyConsumptionTargetEntity.getUpdateDate()); + sysTenantDetailDTOS.add(iotEnergyValueDTO); + } + energyConsumptionTargetDTO.setValues(sysTenantDetailDTOS); + } +// List list1 = mapper.pageLists(params); + List iotEnergyConsumptionTargetDTOS = startPage(list, Integer.valueOf(params.get("page").toString()), Integer.valueOf(params.get("limit").toString())); + return new PageData<>(iotEnergyConsumptionTargetDTOS,list.size()); + } + + @Override + public void addTarget(IotEnergyValueDTO dto) { + if(ObjectUtil.isNotEmpty(dto)){ + IotEnergyConsumptionTargetEntity iotEnergyConsumptionTargetEntity2 = iotEnergyConsumptionTargetMapper.getLists(dto.getTenantCode(),dto.getYear()); + if(ObjectUtil.isNotEmpty(iotEnergyConsumptionTargetEntity2)){ + throw new SysException("企业信息已重复,请重新选择"); + } + + IotEnergyConsumptionTargetEntity iotEnergyConsumptionTargetEntity = new IotEnergyConsumptionTargetEntity(); + UserDetail user = SecurityUser.getUser(); + //租户编码 + iotEnergyConsumptionTargetEntity.setTenantCode(dto.getTenantCode()); + //创建人 + iotEnergyConsumptionTargetEntity.setCreator(user.getId()); + Date date = new Date(); + SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DateTimeUtils.DATE_TIME_PATTERN_STR); + String format = simpleDateFormat.format(date); + Long aLong = DateTimeUtils.dateToStamp(format); + //创建时间 + iotEnergyConsumptionTargetEntity.setCreateDate(aLong); + //能耗目标 + iotEnergyConsumptionTargetEntity.setTargetValue(dto.getTargetValue()); + //类型 + iotEnergyConsumptionTargetEntity.setType(dto.getType()); + //年份 + iotEnergyConsumptionTargetEntity.setYear(dto.getYear()); + if(CollectionUtil.isNotEmpty(dto.getValues())){ + ArrayList iotEnergyConsumptionTargetEntities = new ArrayList<>(); + List values = dto.getValues(); + for (IotDataValueDTO value : values) { + IotEnergyConsumptionTargetEntity iotEnergyConsumptionTargetEntity1 = new IotEnergyConsumptionTargetEntity(); + UserDetail user1 = SecurityUser.getUser(); + //租户编码 + iotEnergyConsumptionTargetEntity1.setTenantCode(dto.getTenantCode()); + //创建人 + iotEnergyConsumptionTargetEntity1.setCreator(user1.getId()); + Date date1 = new Date(); + SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat(DateTimeUtils.DATE_TIME_PATTERN_STR); + String format1 = simpleDateFormat1.format(date1); + Long aLong1 = DateTimeUtils.dateToStamp(format1); + //创建时间 + iotEnergyConsumptionTargetEntity1.setCreateDate(aLong1); + //能耗目标 + iotEnergyConsumptionTargetEntity1.setTargetValue(value.getTargetValue()); + //类型 + iotEnergyConsumptionTargetEntity1.setType(value.getType()); + //年份 + iotEnergyConsumptionTargetEntity1.setYear(dto.getYear()); + //月份 + iotEnergyConsumptionTargetEntity1.setMonth(value.getMonth()); + iotEnergyConsumptionTargetEntities.add(iotEnergyConsumptionTargetEntity1); + } + //月份增加 + iotEnergyConsumptionTargetMapper.insertBatch(iotEnergyConsumptionTargetEntities); + } + //年份增加 + iotEnergyConsumptionTargetMapper.insert(iotEnergyConsumptionTargetEntity); + } + } + + @Override + public IotEnergyValueDTO getByIds(Long id) { + IotEnergyValueDTO iotEnergyValueDTO = new IotEnergyValueDTO(); + IotEnergyConsumptionTargetEntity iotEnergyConsumptionTargetEntity = iotEnergyConsumptionTargetMapper.getByIds(id); + //id + iotEnergyValueDTO.setId(iotEnergyConsumptionTargetEntity.getId()); + //租户编码 + iotEnergyValueDTO.setTenantCode(iotEnergyConsumptionTargetEntity.getTenantCode()); + //能耗 + iotEnergyValueDTO.setTargetValue(iotEnergyConsumptionTargetEntity.getTargetValue()); + //类型 0-年 1-月 + iotEnergyValueDTO.setType(iotEnergyConsumptionTargetEntity.getType()); + //年份 + iotEnergyValueDTO.setYear(iotEnergyConsumptionTargetEntity.getYear()); + //创建人 + iotEnergyValueDTO.setCreator(iotEnergyConsumptionTargetEntity.getCreator()); + //创建时间 + iotEnergyValueDTO.setCreateDate(iotEnergyConsumptionTargetEntity.getCreateDate()); + //修改人 + iotEnergyValueDTO.setUpdater(iotEnergyConsumptionTargetEntity.getUpdater()); + //修改时间 + iotEnergyValueDTO.setUpdateDate(iotEnergyConsumptionTargetEntity.getUpdateDate()); + //根据同一个租户编码和年份 类型为1的数据 + List typeList = iotEnergyConsumptionTargetMapper.getTypeList(iotEnergyConsumptionTargetEntity.getYear(), iotEnergyConsumptionTargetEntity.getTenantCode()); + ArrayList sysTenantDetailsDTOS = new ArrayList<>(); + for (IotEnergyConsumptionTargetEntity energyConsumptionTargetEntity : typeList) { + IotDataValueDTO sysTenantDetailsDTO = new IotDataValueDTO(); + //id + sysTenantDetailsDTO.setId(energyConsumptionTargetEntity.getId()); + //租户编码 + sysTenantDetailsDTO.setTargetValue(energyConsumptionTargetEntity.getTargetValue()); + //月份 + sysTenantDetailsDTO.setMonth(energyConsumptionTargetEntity.getMonth()); + //类型 0-年 1-月 + sysTenantDetailsDTO.setType(energyConsumptionTargetEntity.getType()); + //创建人 + sysTenantDetailsDTO.setCreator(energyConsumptionTargetEntity.getCreator()); + //创建时间 + sysTenantDetailsDTO.setCreateDate(energyConsumptionTargetEntity.getCreateDate()); + //修改人 + iotEnergyValueDTO.setUpdater(energyConsumptionTargetEntity.getUpdater()); + //修改时间 + iotEnergyValueDTO.setUpdateDate(energyConsumptionTargetEntity.getUpdateDate()); + sysTenantDetailsDTOS.add(sysTenantDetailsDTO); + } + //同一个租户code和年份 类型为1的数据添加进来 + iotEnergyValueDTO.setValues(sysTenantDetailsDTOS); + return iotEnergyValueDTO; + } + + @Override + public void updateList(IotEnergyValueDTO dto) { + if(ObjectUtil.isNotEmpty(dto)){ +// IotEnergyConsumptionTargetEntity iotEnergyConsumptionTargetEntity2 = iotEnergyConsumptionTargetMapper.getByIds(dto.getId()); +// List typeList = iotEnergyConsumptionTargetMapper.getTypeList(iotEnergyConsumptionTargetEntity2.getYear(), iotEnergyConsumptionTargetEntity2.getTenantCode()); +// List longs = new ArrayList<>(); +// longs.add(iotEnergyConsumptionTargetEntity2.getId()); +// for (IotEnergyConsumptionTargetEntity energyConsumptionTargetEntity : typeList) { +// longs.add(energyConsumptionTargetEntity.getId()); +// } +// //先删除 后添加 +// iotEnergyConsumptionTargetMapper.deleteByIdList(longs); + + IotEnergyConsumptionTargetEntity iotEnergyConsumptionTargetEntity = new IotEnergyConsumptionTargetEntity(); + UserDetail user = SecurityUser.getUser(); + //id + iotEnergyConsumptionTargetEntity.setId(dto.getId()); + //租户编码 + iotEnergyConsumptionTargetEntity.setTenantCode(dto.getTenantCode()); + //创建人 + iotEnergyConsumptionTargetEntity.setCreator(dto.getCreator()); + //创建时间 + iotEnergyConsumptionTargetEntity.setCreateDate(dto.getCreateDate()); + //修改人 + iotEnergyConsumptionTargetEntity.setUpdater(user.getId()); + //修改时间 + Date date = new Date(); + SimpleDateFormat simpleDateFormat= new SimpleDateFormat(DateTimeUtils.DATE_TIME_PATTERN_STR); + String format = simpleDateFormat.format(date); + Long aLong1 = DateTimeUtils.dateToStamp(format); + iotEnergyConsumptionTargetEntity.setUpdateDate(aLong1); + //能耗目标 + iotEnergyConsumptionTargetEntity.setTargetValue(dto.getTargetValue()); + //类型 + iotEnergyConsumptionTargetEntity.setType(dto.getType()); + //年份 + iotEnergyConsumptionTargetEntity.setYear(dto.getYear()); + if(CollectionUtil.isNotEmpty(dto.getValues())){ +// ArrayList iotEnergyConsumptionTargetEntities = new ArrayList<>(); + List values = dto.getValues(); + for (IotDataValueDTO value : values) { + IotEnergyConsumptionTargetEntity iotEnergyConsumptionTargetEntity1 = new IotEnergyConsumptionTargetEntity(); + UserDetail user1 = SecurityUser.getUser(); + iotEnergyConsumptionTargetEntity1.setId(value.getId()); + //租户编码 + iotEnergyConsumptionTargetEntity1.setTenantCode(dto.getTenantCode()); + //修改人 + iotEnergyConsumptionTargetEntity1.setUpdater(user1.getId()); + //修改时间 + Date date1 = new Date(); + SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat(DateTimeUtils.DATE_TIME_PATTERN_STR); + String format1 = simpleDateFormat1.format(date1); + Long aLong2 = DateTimeUtils.dateToStamp(format1); + iotEnergyConsumptionTargetEntity1.setUpdateDate(aLong2); + //能耗目标 + iotEnergyConsumptionTargetEntity1.setTargetValue(value.getTargetValue()); + //类型 + iotEnergyConsumptionTargetEntity1.setType(value.getType()); + //年份 + iotEnergyConsumptionTargetEntity1.setYear(dto.getYear()); + //月份 + iotEnergyConsumptionTargetEntity1.setMonth(value.getMonth()); +// iotEnergyConsumptionTargetEntities.add(iotEnergyConsumptionTargetEntity1); + if(value.getId()==null){ + //创建人 + iotEnergyConsumptionTargetEntity1.setCreator(user1.getId()); + //创建时间 + iotEnergyConsumptionTargetEntity1.setCreateDate(aLong2); + iotEnergyConsumptionTargetMapper.insert(iotEnergyConsumptionTargetEntity1); + }else { + //创建人 + iotEnergyConsumptionTargetEntity1.setCreator(value.getCreator()); + //创建时间 + iotEnergyConsumptionTargetEntity1.setCreateDate(value.getCreateDate()); + //月份修改 + iotEnergyConsumptionTargetMapper.update(iotEnergyConsumptionTargetEntity1); + } + } + } + //年份增加 + iotEnergyConsumptionTargetMapper.update(iotEnergyConsumptionTargetEntity); + } + } + + @Override + public void deleteByids(Long[] ids) { + //根据id来进行批量查询 + List list = iotEnergyConsumptionTargetMapper.getByIdList(ids); + List longs = new ArrayList<>(); + for (IotEnergyConsumptionTargetEntity iotEnergyConsumptionTargetEntity : list) { + longs.add(iotEnergyConsumptionTargetEntity.getId()); + //根据同一个租户code和年份 类型为1来进行查询 + List typeList = iotEnergyConsumptionTargetMapper.getTypeList(iotEnergyConsumptionTargetEntity.getYear(), iotEnergyConsumptionTargetEntity.getTenantCode()); + for (IotEnergyConsumptionTargetEntity energyConsumptionTargetEntity : typeList) { + longs.add(energyConsumptionTargetEntity.getId()); + } + } + //批量删除 + iotEnergyConsumptionTargetMapper.deleteByIdList(longs); + } + + @Override + public PageData page(Map params) { + params.put("type",0); + Page pages = mapper.paginate( + getPage(params), + buildOrderWrapper(params, "type", false) + ); + + //条件查询-分页 + List list = mapper.pageList(params); + for (IotEnergyConsumptionTargetDTO energyConsumptionTargetDTO : list) { + List iotEnergyConsumptionTargetDTO = iotEnergyConsumptionTargetMapper.getTypeList(energyConsumptionTargetDTO.getYear(),energyConsumptionTargetDTO.getTenantCode()); + List sysTenantDetailDTOS = new ArrayList<>(); + for (IotEnergyConsumptionTargetEntity iotEnergyConsumptionTargetEntity : iotEnergyConsumptionTargetDTO) { + IotDataValueDTO iotEnergyValueDTO = new IotDataValueDTO(); + //id + iotEnergyValueDTO.setId(iotEnergyConsumptionTargetEntity.getId()); + //租户编码 + iotEnergyValueDTO.setTenantCode(iotEnergyConsumptionTargetEntity.getTenantCode()); + //能耗 + iotEnergyValueDTO.setTargetValue(iotEnergyConsumptionTargetEntity.getTargetValue()); + //类型 0-年 1-月 + iotEnergyValueDTO.setType(iotEnergyConsumptionTargetEntity.getType()); + //月份 + iotEnergyValueDTO.setMonth(iotEnergyConsumptionTargetEntity.getMonth()); + //创建人 + iotEnergyValueDTO.setCreator(iotEnergyConsumptionTargetEntity.getCreator()); + //创建时间 + iotEnergyValueDTO.setCreateDate(iotEnergyConsumptionTargetEntity.getCreateDate()); + //修改人 + iotEnergyValueDTO.setUpdater(iotEnergyConsumptionTargetEntity.getUpdater()); + //修改时间 + iotEnergyValueDTO.setUpdateDate(iotEnergyConsumptionTargetEntity.getUpdateDate()); + sysTenantDetailDTOS.add(iotEnergyValueDTO); + } + energyConsumptionTargetDTO.setValues(sysTenantDetailDTOS); + } + return new PageData<>(list, pages.getTotalRow()); + } + + @Override + public BigDecimal getValueByYear(String year,Long tenantCode) { + return iotEnergyConsumptionTargetMapper.getValueByYear(year,tenantCode); + } + + @Override + public BigDecimal getValueByYearAndMonth(String year, String month, Long tenantCode) { + return iotEnergyConsumptionTargetMapper.getValueByYearAndMonth(year,month,tenantCode); + } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/service/impl/IotValueAddedServiceImpl.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/service/impl/IotValueAddedServiceImpl.java new file mode 100644 index 0000000..833d836 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/consumptionTarget/service/impl/IotValueAddedServiceImpl.java @@ -0,0 +1,292 @@ +package com.thing.qingyuan.regionalenterprises.consumptionTarget.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import com.mybatisflex.core.query.QueryWrapper; +import com.thing.qingyuan.regionalenterprises.consumptionTarget.dto.IotAddedDateDTO; +import com.thing.qingyuan.regionalenterprises.consumptionTarget.dto.IotValueAddDTO; +import com.thing.qingyuan.regionalenterprises.consumptionTarget.dto.iotValueAddedDTO; +import com.thing.qingyuan.regionalenterprises.consumptionTarget.entity.IotValueAddedEntity; +import com.thing.qingyuan.regionalenterprises.consumptionTarget.mapper.IotValueAddedMapper; +import com.thing.qingyuan.regionalenterprises.consumptionTarget.service.IotValueAddedService; +import com.thing.common.core.exception.SysException; +import com.thing.common.core.utils.DateTimeUtils; +import com.thing.common.core.web.response.PageData; +import com.thing.common.orm.service.impl.BaseServiceImpl; +import com.thing.sys.security.domain.SecurityUser; +import com.thing.sys.security.domain.UserDetail; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; + +@Service +public class IotValueAddedServiceImpl extends BaseServiceImpl implements IotValueAddedService { + + @Autowired + private IotValueAddedMapper iotValueAddedMapper; + + @Override + public QueryWrapper getWrapper(Map params) { + return QueryWrapper.create(); + } + + @Override + public PageData pageList(Map params) { + List list = mapper.pageList(params); + for (iotValueAddedDTO iotValueAddedDTO : list) { + List iotValueAddedEntities = iotValueAddedMapper.getTypeList(iotValueAddedDTO.getYear(),iotValueAddedDTO.getTenantCode()); + List sysTenantDetailDTOS = new ArrayList<>(); + for (IotValueAddedEntity iotValueAdded : iotValueAddedEntities) { + IotAddedDateDTO iotAddedDateDTO = new IotAddedDateDTO(); + //id + iotAddedDateDTO.setId(iotValueAdded.getId()); + //租户code + iotAddedDateDTO.setTenantCode(iotValueAdded.getTenantCode()); + //增加值 + iotAddedDateDTO.setAddedValue(iotValueAdded.getAddedValue()); + //类型 0-年 1-月 + iotAddedDateDTO.setType(iotValueAdded.getType()); + //月份 + iotAddedDateDTO.setMonth(iotValueAdded.getMonth()); + //创建人 + iotAddedDateDTO.setCreator(iotValueAdded.getCreator()); + //创建时间 + iotAddedDateDTO.setCreateDate(iotValueAdded.getCreateDate()); + //修改人 + iotAddedDateDTO.setUpdater(iotValueAdded.getUpdater()); + //修改时间 + iotAddedDateDTO.setUpdateDate(iotValueAdded.getUpdateDate()); + sysTenantDetailDTOS.add(iotAddedDateDTO); + } + iotValueAddedDTO.setValues(sysTenantDetailDTOS); + } + List iotEnergyConsumptionTargetDTOS = startPage(list, Integer.valueOf(params.get("page").toString()), Integer.valueOf(params.get("limit").toString())); + + return new PageData<>(iotEnergyConsumptionTargetDTOS,list.size()); + } + + @Override + public IotValueAddDTO getByIds(Long id) { + IotValueAddDTO iotEnergyValueDTO = new IotValueAddDTO(); + IotValueAddedEntity iotValueAddedEntity = iotValueAddedMapper.getByIds(id); + //id + iotEnergyValueDTO.setId(iotValueAddedEntity.getId()); + //租户code + iotEnergyValueDTO.setTenantCode(iotValueAddedEntity.getTenantCode()); + //增加值 + iotEnergyValueDTO.setAddedValue(iotValueAddedEntity.getAddedValue()); + //类型 0-年 1-月 + iotEnergyValueDTO.setType(iotValueAddedEntity.getType()); + //年份 + iotEnergyValueDTO.setYear(iotValueAddedEntity.getYear()); + //创建人 + iotEnergyValueDTO.setCreator(iotValueAddedEntity.getCreator()); + //创建时间 + iotEnergyValueDTO.setCreateDate(iotValueAddedEntity.getCreateDate()); + //修改人 + iotEnergyValueDTO.setUpdater(iotValueAddedEntity.getUpdater()); + //修改时间 + iotEnergyValueDTO.setUpdateDate(iotValueAddedEntity.getUpdateDate()); + //根据同一个租户编码和年份 类型为1的数据 + List typeList = iotValueAddedMapper.getTypeList(iotValueAddedEntity.getYear(), iotValueAddedEntity.getTenantCode()); + List iotAddedDateDTOS = new ArrayList<>(); + for (IotValueAddedEntity iotValueAddedEntity1 : typeList) { + IotAddedDateDTO iotAddedDateDTO = new IotAddedDateDTO(); + //id + iotAddedDateDTO.setId(iotValueAddedEntity1.getId()); + //租户code + iotAddedDateDTO.setAddedValue(iotValueAddedEntity1.getAddedValue()); + //月份 + iotAddedDateDTO.setMonth(iotValueAddedEntity1.getMonth()); + //类型 0-年 1-月 + iotAddedDateDTO.setType(iotValueAddedEntity1.getType()); + //创建人 + iotAddedDateDTO.setCreator(iotValueAddedEntity1.getCreator()); + //创建时间 + iotAddedDateDTO.setCreateDate(iotValueAddedEntity1.getCreateDate()); + //修改人 + iotAddedDateDTO.setUpdater(iotValueAddedEntity1.getCreator()); + //修改时间 + iotAddedDateDTO.setUpdateDate(iotValueAddedEntity1.getCreateDate()); + iotAddedDateDTOS.add(iotAddedDateDTO); + } + iotEnergyValueDTO.setValues(iotAddedDateDTOS); + return iotEnergyValueDTO; + } + + @Override + public void addTarget(IotValueAddDTO dto) { + if(ObjectUtil.isNotEmpty(dto)){ + + IotValueAddedEntity iotValueAddedEntity2 = iotValueAddedMapper.getyearAndTenanCode(dto.getYear(), dto.getTenantCode()); + if(ObjectUtil.isNotEmpty(iotValueAddedEntity2)){ + throw new SysException("企业信息已重复,请重新选择"); + } + + IotValueAddedEntity iotValueAddedEntity = new IotValueAddedEntity(); + UserDetail user = SecurityUser.getUser(); + //租户编码 + iotValueAddedEntity.setTenantCode(dto.getTenantCode()); + //创建人 + iotValueAddedEntity.setCreator(user.getId()); + Date date = new Date(); + SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DateTimeUtils.DATE_TIME_PATTERN_STR); + String format = simpleDateFormat.format(date); + Long aLong = DateTimeUtils.dateToStamp(format); + //创建时间 + iotValueAddedEntity.setCreateDate(aLong); + //增加值 + iotValueAddedEntity.setAddedValue(dto.getAddedValue()); + //类型 + iotValueAddedEntity.setType(dto.getType()); + //年份 + iotValueAddedEntity.setYear(dto.getYear()); + if(CollectionUtil.isNotEmpty(dto.getValues())){ + ArrayList iotValueAddedEntities = new ArrayList<>(); + List values = dto.getValues(); + for (IotAddedDateDTO value : values) { + IotValueAddedEntity iotValueAddedEntity1 = new IotValueAddedEntity(); + UserDetail user1 = SecurityUser.getUser(); + //租户编码 + iotValueAddedEntity1.setTenantCode(dto.getTenantCode()); + //创建人 + iotValueAddedEntity1.setCreator(user1.getId()); + Date date1 = new Date(); + SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat(DateTimeUtils.DATE_TIME_PATTERN_STR); + String format1 = simpleDateFormat1.format(date1); + Long aLong1 = DateTimeUtils.dateToStamp(format1); + //创建时间 + iotValueAddedEntity1.setCreateDate(aLong1); + //增加值 + iotValueAddedEntity1.setAddedValue(value.getAddedValue()); + //类型 + iotValueAddedEntity1.setType(value.getType()); + //年份 + iotValueAddedEntity1.setYear(dto.getYear()); + //月份 + iotValueAddedEntity1.setMonth(value.getMonth()); + iotValueAddedEntities.add(iotValueAddedEntity1); + } + //月份增加 + iotValueAddedMapper.insertBatch(iotValueAddedEntities); + } + //年份增加 + iotValueAddedMapper.insert(iotValueAddedEntity); + } + } + + @Override + public void updateList(IotValueAddDTO dto) { + if(ObjectUtil.isNotEmpty(dto)){ +// IotValueAddedEntity iotValueAddedEntity1 = iotValueAddedMapper.getByIds(dto.getId()); +// List typeList = iotValueAddedMapper.getTypeList(iotValueAddedEntity1.getYear(), iotValueAddedEntity1.getTenantCode()); +// List longs = new ArrayList<>(); +// longs.add(iotValueAddedEntity1.getId()); +// for (IotValueAddedEntity iotValueAddedEntity : typeList) { +// longs.add(iotValueAddedEntity.getId()); +// } +// //先删除 后添加 +// iotValueAddedMapper.deleteByIdList(longs); + IotValueAddedEntity iotValueAdded = new IotValueAddedEntity(); + UserDetail user = SecurityUser.getUser(); + //id + iotValueAdded.setId(dto.getId()); + //租户编码 + iotValueAdded.setTenantCode(dto.getTenantCode()); + //创建人 + iotValueAdded.setCreator(dto.getCreator()); + //创建时间 + iotValueAdded.setCreateDate(dto.getCreateDate()); + //修改人 + iotValueAdded.setUpdater(user.getId()); + //修改时间 + Date date = new Date(); + SimpleDateFormat simpleDateFormat= new SimpleDateFormat(DateTimeUtils.DATE_TIME_PATTERN_STR); + String format = simpleDateFormat.format(date); + Long aLong1 = DateTimeUtils.dateToStamp(format); + iotValueAdded.setUpdateDate(aLong1); + //增加值 + iotValueAdded.setAddedValue(dto.getAddedValue()); + //类型 + iotValueAdded.setType(0); + //年份 + iotValueAdded.setYear(dto.getYear()); + if(CollectionUtil.isNotEmpty(dto.getValues())){ +// ArrayList iotValueAddedEntities = new ArrayList<>(); + List values = dto.getValues(); + for (IotAddedDateDTO value : values) { + IotValueAddedEntity iotValueAddedEntity = new IotValueAddedEntity(); + UserDetail user1 = SecurityUser.getUser(); + iotValueAddedEntity.setId(value.getId()); + //租户编码 + iotValueAddedEntity.setTenantCode(dto.getTenantCode()); + //创建人 + iotValueAddedEntity.setCreator(value.getCreator()); + //创建时间 + iotValueAddedEntity.setCreateDate(value.getCreateDate()); + //修改人 + iotValueAddedEntity.setUpdater(user1.getId()); + //修改时间 + Date date1 = new Date(); + SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat(DateTimeUtils.DATE_TIME_PATTERN_STR); + String format1 = simpleDateFormat1.format(date1); + Long aLong2 = DateTimeUtils.dateToStamp(format1); + iotValueAddedEntity.setUpdateDate(aLong2); + //增加值 + iotValueAddedEntity.setAddedValue(value.getAddedValue()); + //类型 + iotValueAddedEntity.setType(1); + //年份 + iotValueAddedEntity.setYear(dto.getYear()); + //月份 + iotValueAddedEntity.setMonth(value.getMonth()); +// iotValueAddedEntities.add(iotValueAddedEntity); + //月份增加 + iotValueAddedMapper.update(iotValueAddedEntity); + } + } + //年份增加 + iotValueAddedMapper.update(iotValueAdded); + } + } + + @Override + public void deleteByids(Long[] ids) { + List list = iotValueAddedMapper.getByIdList(ids); + List longs = new ArrayList<>(); + for (IotValueAddedEntity iotValueAddedEntity : list) { + longs.add(iotValueAddedEntity.getId()); + List typeList = iotValueAddedMapper.getTypeList(iotValueAddedEntity.getYear(), iotValueAddedEntity.getTenantCode()); + for (IotValueAddedEntity energyConsumptionTargetEntity : typeList) { + longs.add(energyConsumptionTargetEntity.getId()); + } + } + iotValueAddedMapper.deleteByIdList(longs); + } + + @Override + public BigDecimal getSumValueByTenantCodesAndYear(List tenantCodes, String year) { + return iotValueAddedMapper.getSumValueByTenantCodesAndYear(tenantCodes,year); + } + + @Override + public BigDecimal getValueByTenantCodeAndYear(Long tenantCode, String year) { + return iotValueAddedMapper.getValueByTenantCodeAndYear(tenantCode,year); + } + + @Override + public BigDecimal getValueByTenantCodeAndYearAndMonth(Long tenantCode, String year, String month) { + return iotValueAddedMapper.getValueByTenantCodeAndYearAndMonth(tenantCode,year,month); + } + + @Override + public IotValueAddedEntity getyearAndTenanCode(Long id, String year) { + return iotValueAddedMapper.getyearAndTenanCode(year,id); + } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/controller/DetailsMonitoringController.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/controller/DetailsMonitoringController.java new file mode 100644 index 0000000..4b94b77 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/controller/DetailsMonitoringController.java @@ -0,0 +1,114 @@ +package com.thing.qingyuan.regionalenterprises.detailsMonitoring.controller; + + +import com.thing.qingyuan.regionalenterprises.detailsMonitoring.dto.*; +import com.thing.qingyuan.regionalenterprises.detailsMonitoring.service.DetailsMonitoringService; +import com.thing.qingyuan.screen.ScreenData; +import com.thing.common.core.web.response.Result; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; +import java.util.Map; + +@RestController +@RequestMapping("details/board") +@Tag(name = "区域企业-监控详情") +public class DetailsMonitoringController { + + @Autowired + private DetailsMonitoringService detailsMonitoringService; + + + @GetMapping("annual/regional") + @Operation(summary="年度区域能耗情况") + @Parameters({ + @Parameter(name = "year",description ="年份,格式2024",required = true) + }) + public Result> annualRegionalEnergyConsumption(@Parameter(hidden = true) @RequestParam Map params){ + List result = detailsMonitoringService.annualRegionalEnergyConsumption(params); + return new Result>().ok(result); + } + + + @GetMapping("current/regional") + @Operation(summary="当前地区企业清单") + @Parameters({ + @Parameter(name = "regionCode",description ="乡镇code",required = true), + @Parameter(name = "tenantName",description ="企业名称"), + @Parameter(name = "year",description ="年份,格式2024",required = true) + }) + public Result> currentRegionalEnterprises(@Parameter(hidden = true) @RequestParam Map params){ + List result = detailsMonitoringService.currentRegionalEnterprises(params); + return new Result>().ok(result); + } + + @GetMapping("typeEnergyUsed") + @Operation(summary="用能种类") + @Parameters({ + @Parameter(name = "tenantCode",description ="企业code",required = true), + }) + public Result> typeEnergyUsed(@Parameter(hidden = true) @RequestParam Map params){ + List result = detailsMonitoringService.typeEnergyUsed(params); + return new Result>().ok(result); + } + + + @GetMapping("energy/consumption") + @Operation(summary="企业年度用能趋势") + @Parameters({ + @Parameter(name = "energyConsumption",description ="种类能耗code",required = true), + @Parameter(name = "tenantCode",description ="企业code",required = true), + @Parameter(name = "year",description ="年份,格式2024",required = true) + }) + public Result energyConsumptionCarbonEmissionTrend(@Parameter(hidden = true) @RequestParam Map params){ + CarbonEmissionTrendDTO result = detailsMonitoringService.energyConsumptionCarbonEmissionTrend(params); + return new Result().ok(result); + } + + + @GetMapping("carbon/emissionTrend") + @Operation(summary="企业年度碳排趋势") + @Parameters({ + @Parameter(name = "carbonEmission",description ="种类碳排code",required = true), + @Parameter(name = "tenantCode",description ="企业code",required = true), + @Parameter(name = "year",description ="年份,格式2024",required = true) + }) + public Result carbonEmissionTrend(@Parameter(hidden = true) @RequestParam Map params){ + EnergyConsumptionTrendDTO result = detailsMonitoringService.carbonEmissionTrend(params); + return new Result().ok(result); + } + + + @GetMapping("thermodynamic/diagram") + @Operation(summary="区域企业-热力图") + @Parameters({ + @Parameter(name = "year",description ="年份,格式2024",required = true), + @Parameter(name = "regionCode",description ="乡镇code",required = true), + }) + public Result> thermodynamicDiagram(@Parameter(hidden = true) @RequestParam Map params){ + List result = detailsMonitoringService.thermodynamicDiagram(params); + return new Result>().ok(result); + } + + @GetMapping("clean/energy") + @Operation(summary="清洁能源") + @Parameters({ + @Parameter(name = "year",description ="年份,格式2024",required = true) + }) + public Result cleanEnergy(@Parameter(hidden = true) @RequestParam Map params){ + CleanEnergyDTO result = detailsMonitoringService.cleanEnergy(params); + return new Result().ok(result); + } + + + + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/dto/CarbonEmissionTrendDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/dto/CarbonEmissionTrendDTO.java new file mode 100644 index 0000000..a468760 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/dto/CarbonEmissionTrendDTO.java @@ -0,0 +1,19 @@ +package com.thing.qingyuan.regionalenterprises.detailsMonitoring.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +@Data +public class CarbonEmissionTrendDTO { + + @Schema(description = "今年用能数据及同比数据") + private List thisAnnualEnergyTrend; + + @Schema(description = "去年用能数据") + private List lastAnnualEnergyTrend; + + + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/dto/CleanEnergyDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/dto/CleanEnergyDTO.java new file mode 100644 index 0000000..401d11c --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/dto/CleanEnergyDTO.java @@ -0,0 +1,17 @@ +package com.thing.qingyuan.regionalenterprises.detailsMonitoring.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class CleanEnergyDTO { + + @Schema(description = "清洁能源") + private BigDecimal cleanEnergy; + + @Schema(description = "单位") + private String unit; + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/dto/EnergyConsumptionDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/dto/EnergyConsumptionDTO.java new file mode 100644 index 0000000..8b43afa --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/dto/EnergyConsumptionDTO.java @@ -0,0 +1,29 @@ +package com.thing.qingyuan.regionalenterprises.detailsMonitoring.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class EnergyConsumptionDTO { + + @Schema(description = "乡镇code") + private Long villagesTownsCode; + + @Schema(description = "乡镇名称") + private String villagesTowns; + + @Schema(description = "企业数量") + private Integer numberEnterprise; + + @Schema(description = "企业用能") + private BigDecimal enterpriseEnergyUse; + + @Schema(description = "占比") + private BigDecimal proportion; + + + + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/dto/EnergyConsumptionTrendDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/dto/EnergyConsumptionTrendDTO.java new file mode 100644 index 0000000..85da25a --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/dto/EnergyConsumptionTrendDTO.java @@ -0,0 +1,19 @@ +package com.thing.qingyuan.regionalenterprises.detailsMonitoring.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +@Data +public class EnergyConsumptionTrendDTO { + + @Schema(name = "今年碳排数据及同比数据") + private List thisAnnualCarbonEmission; + + @Schema(name = "去年碳排数据") + private List lastAnnualCarbonEmission; + + + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/dto/EnergyDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/dto/EnergyDTO.java new file mode 100644 index 0000000..5b14061 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/dto/EnergyDTO.java @@ -0,0 +1,23 @@ +package com.thing.qingyuan.regionalenterprises.detailsMonitoring.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class EnergyDTO { + + @Schema(description = "日期") + private String date; + + @Schema(description = "值") + private BigDecimal value; + + @Schema(description = "同比") + private String yoy; + + @Schema(description = "上升或下降 0下降 1上升") + private Integer upOrDown; + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/dto/EnergyTrendDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/dto/EnergyTrendDTO.java new file mode 100644 index 0000000..f6dd29c --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/dto/EnergyTrendDTO.java @@ -0,0 +1,18 @@ +package com.thing.qingyuan.regionalenterprises.detailsMonitoring.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class EnergyTrendDTO { + + @Schema(description = "日期") + private String date; + + @Schema(description = "值") + private BigDecimal value; + + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/dto/EnterprisesDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/dto/EnterprisesDTO.java new file mode 100644 index 0000000..62a4bc5 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/dto/EnterprisesDTO.java @@ -0,0 +1,44 @@ +package com.thing.qingyuan.regionalenterprises.detailsMonitoring.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class EnterprisesDTO { + + @Schema(description = "企业名称") + private String name; + + @Schema(description = "企业code") + private Long tenantCode; + + @Schema(description = "经纬度") + private String lngLat; + + @Schema(description = "图片路径") + private String urlAdd; + + @Schema(description = "能耗总量") + private BigDecimal totalEnergyConsumption; + + @Schema(description = "能耗指标") + private BigDecimal energyConsumption; + + @Schema(description = "指标进度") + private BigDecimal progressIndicators; + + @Schema(description = "0-红色 1-黄色 2-绿色") + private Integer colour; + + @Schema(description = "碳排总量") + private BigDecimal totalCarbonEmissions; + + + + + + + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/dto/TypeEnergyUsedDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/dto/TypeEnergyUsedDTO.java new file mode 100644 index 0000000..d01a18f --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/dto/TypeEnergyUsedDTO.java @@ -0,0 +1,21 @@ +package com.thing.qingyuan.regionalenterprises.detailsMonitoring.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class TypeEnergyUsedDTO { + + @Schema(description = "种类名称") + private String nameType; + + @Schema(description = "种类名称") + private String unit; + + @Schema(description = "种类能耗") + private String energyConsumption; + + @Schema(description = "种类碳排") + private String carbonEmission; + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/service/DetailsMonitoringService.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/service/DetailsMonitoringService.java new file mode 100644 index 0000000..ad5ff22 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/service/DetailsMonitoringService.java @@ -0,0 +1,58 @@ +package com.thing.qingyuan.regionalenterprises.detailsMonitoring.service; + +import com.thing.qingyuan.regionalenterprises.detailsMonitoring.dto.*; +import com.thing.qingyuan.screen.ScreenData; + +import java.util.List; +import java.util.Map; + +public interface DetailsMonitoringService { + /** + * 年度区域能耗情况 + * @param params + * @return + */ + List annualRegionalEnergyConsumption(Map params); + + /** + * 当前地区企业清单 + * @param params + * @return + */ + List currentRegionalEnterprises(Map params); + + /** + * 用能种类 + * @param params + * @return + */ + List typeEnergyUsed(Map params); + + /** + * 企业年度用能趋势 + * @param params + * @return + */ + CarbonEmissionTrendDTO energyConsumptionCarbonEmissionTrend(Map params); + + /** + * 区域企业-热力图 + * @param params + * @return + */ + List thermodynamicDiagram(Map params); + + /** + * 企业年度碳排趋势 + * @param params + * @return + */ + EnergyConsumptionTrendDTO carbonEmissionTrend(Map params); + + /** + * 清洁能源 + * @param params + * @return + */ + CleanEnergyDTO cleanEnergy(Map params); +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/service/impl/DetailsMonitoringServiceImpl.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/service/impl/DetailsMonitoringServiceImpl.java new file mode 100644 index 0000000..345b61c --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/detailsMonitoring/service/impl/DetailsMonitoringServiceImpl.java @@ -0,0 +1,765 @@ +package com.thing.qingyuan.regionalenterprises.detailsMonitoring.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import com.github.xiaoymin.knife4j.core.util.CollectionUtils; +import com.thing.carbon.config.dto.CarbonEnergyVarietyDTO; +import com.thing.carbon.config.service.CarbonEnergyDictRelationService; +import com.thing.carbon.config.service.CarbonEnergyVarietyService; +import com.thing.qingyuan.regionalenterprises.consumptionTarget.entity.IotValueAddedEntity; +import com.thing.qingyuan.regionalenterprises.consumptionTarget.service.IotValueAddedService; +import com.thing.qingyuan.regionalenterprises.detailsMonitoring.dto.*; +import com.thing.qingyuan.regionalenterprises.detailsMonitoring.service.DetailsMonitoringService; +import com.thing.qingyuan.screen.ScreenData; +import com.thing.common.core.utils.DateTimeUtils; +import com.thing.common.data.tskv.TsKvDTO; +import com.thing.common.tskv.service.TsKvService; +import com.thing.sys.biz.dto.SysRegionDTO; +import com.thing.sys.biz.service.SysIndustryTypeService; +import com.thing.sys.biz.service.SysRegionService; +import com.thing.sys.security.context.TenantContext; +import com.thing.sys.security.domain.SecurityUser; +import com.thing.sys.tenant.dto.RegionIndustryTenantInfoDTO; +import com.thing.sys.tenant.dto.SysTenantDTO; +import com.thing.sys.tenant.dto.SysTenantDetailDTO; +import com.thing.sys.tenant.service.SysTenantDetailService; +import com.thing.sys.tenant.service.SysTenantService; +import com.thing.thing.dict.dto.IotThingDictDTO; +import com.thing.thing.dict.entity.IotThingDictEntity; +import com.thing.thing.dict.service.IotThingDictService; +import com.thing.thing.dictRelation.service.IotThingDictRelationService; +import com.thing.thing.entity.dto.IotThingEntityDTO; +import com.thing.thing.entity.service.IotThingEntityService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.util.*; +import java.util.stream.Collectors; + +@Service +public class DetailsMonitoringServiceImpl implements DetailsMonitoringService { + + @Autowired + private IotThingDictRelationService iotThingDictRelationService; + + @Autowired + private CarbonEnergyDictRelationService carbonEnergyDictRelationService; + + @Autowired + private SysRegionService sysRegionService; + + @Autowired + private SysTenantService sysTenantService; + + @Autowired + private SysIndustryTypeService sysIndustryTypeService; + + @Autowired + private TsKvService tsKvService; + + @Autowired + private IotThingDictService iotThingDictService; + + @Autowired + private IotValueAddedService iotValueAddedService; + + @Autowired + private SysTenantDetailService sysTenantDetailService; + + @Autowired + private CarbonEnergyVarietyService carbonEnergyVarietyService; + + @Autowired + private IotThingEntityService iotThingEntityService; + + + @Override + public List annualRegionalEnergyConsumption(Map params) { + + ArrayList energyConsumptionDTOS = new ArrayList<>(); + Long tenantCode = TenantContext.getTenantCode(SecurityUser.getUser()); +// Long tenantCode = 1749690716702932992L; + String year; + if (params!=null && ObjectUtil.isNotEmpty(params.get("year"))){ + year = params.get("year").toString(); + }else{ + year = DateTimeUtils.getCurrentYear(); + } + Long currentYearTime = DateTimeUtils.dateToTimestamp(year+"-01-01 00:00:00"); + List keys = new ArrayList<>(); + keys.add("tce_runyy"); + //获取所有企业的thing_code,行业门类,行业大类,区域 + List industryTenantInfoDTOS = sysTenantService.getByGroupTenantCode(tenantCode); + + //根据区域分组,获取区域thingCode + Map> industryTypeMap = industryTenantInfoDTOS.stream() + .collect(Collectors.groupingBy(RegionIndustryTenantInfoDTO::getRegionCode, + Collectors.mapping(RegionIndustryTenantInfoDTO::getThingCode, Collectors.toList()))); + Map pidParams = new HashMap<>(); + pidParams.put("pid","320581"); + //获取区域 + List list = sysRegionService.list(pidParams); + BigDecimal values = BigDecimal.ZERO; + if (CollectionUtil.isNotEmpty(list)){ + for (SysRegionDTO sysRegionDTO: list){ + List thingCodes = industryTypeMap.get(sysRegionDTO.getId()); + if(CollectionUtil.isNotEmpty(thingCodes)){ + EnergyConsumptionDTO areaConsumptionDTO = new EnergyConsumptionDTO(); + areaConsumptionDTO.setVillagesTownsCode(sysRegionDTO.getId()); + areaConsumptionDTO.setVillagesTowns(sysRegionDTO.getName()); + areaConsumptionDTO.setNumberEnterprise(thingCodes.size()); + Map> codeAndKeyMap1 = new HashMap<>(); + for (String code:thingCodes){ + codeAndKeyMap1.put(code,keys); + } + //获取区域企业数据,并以属性分组合计 + List dataList1 = tsKvService.findTsKvByMultiMap(codeAndKeyMap1,currentYearTime-1000L,currentYearTime+1000L,Boolean.FALSE); + Map dataResult1 = null; + if (CollectionUtil.isNotEmpty(dataList1)){ + dataResult1 = dataList1.stream().filter(dto -> dto.getVal() != null) + .collect(Collectors.groupingBy(TsKvDTO::getAttrKey, Collectors.mapping(TsKvDTO::getVal, + Collectors.reducing(BigDecimal.ZERO, BigDecimal::new, BigDecimal::add)))); + } +// BigDecimal value = BigDecimal.ZERO; + if (dataResult1!=null){ + if (ObjectUtil.isNotEmpty(dataResult1.get("tce_runyy"))){ + BigDecimal bigDecimal = dataResult1.get("tce_runyy").setScale(2, BigDecimal.ROUND_HALF_UP); + areaConsumptionDTO.setEnterpriseEnergyUse(bigDecimal); + values = values.add(bigDecimal); + } + } + energyConsumptionDTOS.add(areaConsumptionDTO); + } + } + } + if(CollectionUtil.isNotEmpty(energyConsumptionDTOS)){ + for (EnergyConsumptionDTO energyConsumptionDTO : energyConsumptionDTOS) { + BigDecimal enterpriseEnergyUse = energyConsumptionDTO.getEnterpriseEnergyUse(); + if(energyConsumptionDTO.getEnterpriseEnergyUse()!=null&& values!=null && values.compareTo(BigDecimal.ZERO)!=0){ + energyConsumptionDTO.setProportion(enterpriseEnergyUse.divide(values,2,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100))); + } + } + } + // 根据 enterpriseEnergyUse 进行由高到低排序 + Collections.sort(energyConsumptionDTOS, Comparator.comparing(EnergyConsumptionDTO::getEnterpriseEnergyUse, Comparator.nullsFirst(BigDecimal::compareTo)).reversed()); +// energyConsumptionDTOS.sort(Comparator.comparing(EnterprisesDTO::getProgressIndicators, Comparator.nullsFirst(BigDecimal::compareTo).reversed())); + return energyConsumptionDTOS; + } + + /** + * 当前地区企业清单 + * @param params + * @return + */ + @Override + public List currentRegionalEnterprises(Map params) { + ArrayList energyConsumptionDTOS = new ArrayList<>(); + String year; + if (params!=null && ObjectUtil.isNotEmpty(params.get("year"))){ + year = params.get("year").toString(); + }else{ + year = DateTimeUtils.getCurrentYear(); + } + Long currentYearTime = DateTimeUtils.dateToTimestamp(year+"-01-01 00:00:00"); + List keys = new ArrayList<>(); + keys.add("tce_runyy"); + keys.add("CO2_runyy"); + params.put("tenantType","0"); + List list = sysTenantDetailService.selectList(params); + for (SysTenantDetailDTO sysTenantDetailDTO : list) { + EnterprisesDTO energyConsumptionDTOS1 = new EnterprisesDTO(); + SysTenantDTO tenantCode = sysTenantService.getTenantCode(sysTenantDetailDTO.getId()); + energyConsumptionDTOS1.setUrlAdd(sysTenantDetailDTO.getImageUrl()); + energyConsumptionDTOS1.setName(sysTenantDetailDTO.getName()); + energyConsumptionDTOS1.setTenantCode(sysTenantDetailDTO.getId()); + energyConsumptionDTOS1.setLngLat(sysTenantDetailDTO.getLngLat()); + IotValueAddedEntity iotValueAddedEntity = iotValueAddedService.getyearAndTenanCode(sysTenantDetailDTO.getId(), year); + if(ObjectUtil.isNotEmpty(iotValueAddedEntity)){ + BigDecimal addedValue = iotValueAddedEntity.getAddedValue(); + energyConsumptionDTOS1.setEnergyConsumption(addedValue); + } + Map> codeAndKeyMap1 = new HashMap<>(); + codeAndKeyMap1.put(tenantCode.getThingCode(),keys); + //获取区域企业数据,并以属性分组合计 + List dataList1 = tsKvService.findTsKvByMultiMap(codeAndKeyMap1,currentYearTime-1000L,currentYearTime+1000L,Boolean.FALSE); + Map dataResult1 = null; + if (CollectionUtil.isNotEmpty(dataList1)){ + dataResult1 = dataList1.stream().filter(dto -> dto.getVal() != null) + .collect(Collectors.groupingBy(TsKvDTO::getAttrKey, Collectors.mapping(TsKvDTO::getVal, + Collectors.reducing(BigDecimal.ZERO, BigDecimal::new, BigDecimal::add)))); + } + if (dataResult1!=null){ + if (ObjectUtil.isNotEmpty(dataResult1.get("tce_runyy"))){ + energyConsumptionDTOS1.setTotalEnergyConsumption(dataResult1.get("tce_runyy").setScale(2,BigDecimal.ROUND_HALF_UP)); + } + if (ObjectUtil.isNotEmpty(dataResult1.get("CO2_runyy"))){ + energyConsumptionDTOS1.setTotalCarbonEmissions(dataResult1.get("CO2_runyy").setScale(2,BigDecimal.ROUND_HALF_UP)); + } + } + + if(energyConsumptionDTOS1.getEnergyConsumption() != null + &&energyConsumptionDTOS1.getTotalEnergyConsumption()!=null){ + BigDecimal energyConsumption = energyConsumptionDTOS1.getEnergyConsumption(); + BigDecimal totalEnergyConsumption = energyConsumptionDTOS1.getTotalEnergyConsumption(); + BigDecimal divide = totalEnergyConsumption.divide(energyConsumption,2,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)); + energyConsumptionDTOS1.setProgressIndicators(divide); + if (energyConsumptionDTOS1.getProgressIndicators().compareTo(new BigDecimal(100)) > 0) { + // 如果值超过 100,赋值为 1 + energyConsumptionDTOS1.setColour(0); + } else if (energyConsumptionDTOS1.getProgressIndicators().compareTo(new BigDecimal(80)) >= 0 && energyConsumptionDTOS1.getProgressIndicators().compareTo(new BigDecimal(100)) < 0) { + // 如果值大于等于 80 且小于 100,赋值为 1 + energyConsumptionDTOS1.setColour(1); + } else if(energyConsumptionDTOS1.getProgressIndicators().compareTo(new BigDecimal(80)) < 0){ + // 如果值小于 80,赋值为 2 + energyConsumptionDTOS1.setColour(2); + } + } + if(energyConsumptionDTOS1.getProgressIndicators()==null){ + energyConsumptionDTOS1.setColour(2); + } + energyConsumptionDTOS.add(energyConsumptionDTOS1); + } +// // 根据 enterpriseEnergyUse 进行由高到低排序 + energyConsumptionDTOS.sort(Comparator.comparing(EnterprisesDTO::getProgressIndicators, Comparator.nullsFirst(BigDecimal::compareTo).reversed())); + return energyConsumptionDTOS; + } + + @Override + public List typeEnergyUsed(Map params) { + ArrayList typeEnergyUsedDTOS = new ArrayList<>(); + + //获取属性 + Map newParams = new HashMap<>(); + newParams.put("page",1); + newParams.put("limit",100); + newParams.put("attrType","base"); + TypeEnergyUsedDTO typeEnergyUsedDTO1 = new TypeEnergyUsedDTO(); + typeEnergyUsedDTO1.setNameType("总量"); + typeEnergyUsedDTO1.setUnit("tce_runmm"); + typeEnergyUsedDTO1.setEnergyConsumption("tce_runmm"); + typeEnergyUsedDTO1.setCarbonEmission("CO2_runmm"); + typeEnergyUsedDTOS.add(typeEnergyUsedDTO1); + + String tenantCode = params.get("tenantCode").toString(); + //实体表根据tenantCode查询 + SysTenantDTO byThingCode = sysTenantService.getTenantCode(Long.parseLong(tenantCode)); + if(ObjectUtil.isEmpty(byThingCode)){ + return typeEnergyUsedDTOS; + } + /* IotThingEntityDTO byThingCode1 = iotThingEntityService.getIotThingTenantByThingCode(byThingCode.getThingCode()); + if(ObjectUtil.isEmpty(byThingCode1)){ + return typeEnergyUsedDTOS; + } + List iotThingDictDTOS = iotThingDictRelationService.getFormById(byThingCode1.getId()); + if(CollectionUtil.isEmpty(iotThingDictDTOS)){ + return typeEnergyUsedDTOS; + } + List allByIdIn = iotThingDictService.findAllByIdIn(iotThingDictDTOS); + if(CollectionUtil.isEmpty(allByIdIn)){ + return typeEnergyUsedDTOS; + } + //获取基础能源品种 + params.put("tenantCode","1001"); + List list = carbonEnergyVarietyService.listCarbonEnergyVarietyDTO(params); +// List list = page.getList(); + List keys = new ArrayList<>(); + for (CarbonEnergyVarietyDTO carbonEnergyDictRelationDTO : list) { + for (IotThingDictEntity iotThingDictEntity : allByIdIn) { + if(carbonEnergyDictRelationDTO.getCode().contains(iotThingDictEntity.getCode())){ + TypeEnergyUsedDTO typeEnergyUsedDTO = new TypeEnergyUsedDTO(); + typeEnergyUsedDTO.setNameType(carbonEnergyDictRelationDTO.getName()); + typeEnergyUsedDTO.setUnit(carbonEnergyDictRelationDTO.getCode()); + typeEnergyUsedDTO.setEnergyConsumption("tce_"+carbonEnergyDictRelationDTO.getCode()+"mm"); + typeEnergyUsedDTO.setCarbonEmission("CO2_"+carbonEnergyDictRelationDTO.getCode()+"mm"); + if(typeEnergyUsedDTOS.contains(typeEnergyUsedDTO)){ + continue; + }else { + typeEnergyUsedDTOS.add(typeEnergyUsedDTO); + } + } + } + } + //获取属性的单位 + Map dictMap = new HashMap<>(); + List dictDTOList = iotThingDictService.getIotEntityDictDTOList("attr",keys); + if (CollectionUtils.isNotEmpty(dictDTOList)){ + for (IotThingDictDTO dictDTO:dictDTOList){ + dictMap.put(dictDTO.getCode(),dictDTO.getUnit()); + } + } + for (TypeEnergyUsedDTO typeEnergyUsedDTO : typeEnergyUsedDTOS) { + if(dictMap!=null && dictMap.get(typeEnergyUsedDTO.getUnit())!=null){ + String s = dictMap.get(typeEnergyUsedDTO.getUnit()); + typeEnergyUsedDTO.setUnit(s); + } + }*/ + return typeEnergyUsedDTOS; + } + + @Override + public CarbonEmissionTrendDTO energyConsumptionCarbonEmissionTrend(Map params) { + CarbonEmissionTrendDTO result = new CarbonEmissionTrendDTO(); + ArrayList keys = new ArrayList<>(); + ArrayList keys1 = new ArrayList<>(); + String energyConsumption; + if (params!=null && ObjectUtil.isNotEmpty(params.get("energyConsumption"))){ + energyConsumption = params.get("energyConsumption").toString(); + keys.add(energyConsumption); + }else{ + return null; + } + String tenantCode; + if (params!=null && ObjectUtil.isNotEmpty(params.get("tenantCode"))){ + tenantCode = params.get("tenantCode").toString(); + }else{ + return null; + } + String year; + if (params!=null && ObjectUtil.isNotEmpty(params.get("year"))){ + year = params.get("year").toString(); + }else{ + year = DateTimeUtils.getCurrentYear(); + } + //今年月份 + List currentMonths = DateTimeUtils.getMonthList(year); + String lastYear = String.valueOf(Integer.parseInt(year)-1); + //去年月份 + List lastMonths = DateTimeUtils.getMonthList(lastYear); + Long lastYearStartTime = DateTimeUtils.dateToTimestamp(lastYear+"-01-01 00:00:00"); + Long currentYearEndTime = DateTimeUtils.dateToTimestamp(year+"-12-01 00:00:00"); + SysTenantDTO tenantCode1 = sysTenantService.getTenantCode(Long.parseLong(tenantCode)); + + Map> codeAndKeyMap = new HashMap<>(); + codeAndKeyMap.put(tenantCode1.getThingCode(),keys); + //获取数据,并以时间分组求和 + List dataList = tsKvService.findTsKvByMultiMap(codeAndKeyMap,lastYearStartTime-1000L,currentYearEndTime+1000L,Boolean.FALSE); + Map dataResult = new HashMap<>(); + if (CollectionUtil.isNotEmpty(dataList)){ + dataResult = dataList.stream().filter(dto -> dto.getVal() != null) + .collect(Collectors.groupingBy(TsKvDTO::getTs, Collectors.mapping(TsKvDTO::getVal, + Collectors.reducing(BigDecimal.ZERO, BigDecimal::new, BigDecimal::add)))); + } + //今年用能 + ArrayList thisAnnualEnergyTrend = new ArrayList<>(); + //去年用能 + ArrayList lastAnnualEnergyTrend = new ArrayList<>(); + Map lastYearData = new HashMap<>(); + for (String month : lastMonths){ + EnergyTrendDTO energyDTO = new EnergyTrendDTO(); + energyDTO.setDate(month); + Long monthTs = DateTimeUtils.dateToTimestamp(month+"-01 00:00:00"); + BigDecimal value =null; + if (dataResult!=null && dataResult.get(monthTs)!=null){ + value = dataResult.get(monthTs); + energyDTO.setValue(value); + } + lastYearData.put(month.substring(5),value); + lastAnnualEnergyTrend.add(energyDTO); + } + for (String month : currentMonths){ + EnergyDTO energyDTO = new EnergyDTO(); + energyDTO.setDate(month); + Long monthTs = DateTimeUtils.dateToTimestamp(month+"-01 00:00:00"); + BigDecimal value = null; + if (dataResult!=null && dataResult.get(monthTs)!=null){ + value = dataResult.get(monthTs); + energyDTO.setValue(value); + } + energyDTO.setValue(value); + //计算同比 + if (value!=null && lastYearData!=null && lastYearData.get(month.substring(5))!=null && lastYearData.get(month.substring(5)).compareTo(BigDecimal.ZERO)!=0){ + BigDecimal lastValue = lastYearData.get(month.substring(5)); + BigDecimal yearOnYearGrowthRate = (value.subtract(lastValue)).divide(lastValue, 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100")); + energyDTO.setYoy(yearOnYearGrowthRate+"%"); + //大于0上升,小于0下降 + if (yearOnYearGrowthRate.compareTo(BigDecimal.ZERO)==1){ + energyDTO.setUpOrDown(1); + }else if (yearOnYearGrowthRate.compareTo(BigDecimal.ZERO)==-1){ + energyDTO.setUpOrDown(0); + } + } + thisAnnualEnergyTrend.add(energyDTO); + } + result.setThisAnnualEnergyTrend(thisAnnualEnergyTrend); + result.setLastAnnualEnergyTrend(lastAnnualEnergyTrend); + return result; + } + + @Override + public List thermodynamicDiagram(Map params) { + + List screenDatas = new ArrayList<>(); + Long tenantCode1 = TenantContext.getTenantCode(SecurityUser.getUser()); +// Long tenantCode = 1749690716702932992L; + String year; + if (params!=null && ObjectUtil.isNotEmpty(params.get("year"))){ + year = params.get("year").toString(); + }else{ + year = DateTimeUtils.getCurrentYear(); + } + Long currentYearTime = DateTimeUtils.dateToTimestamp(year+"-01-01 00:00:00"); + List keys = new ArrayList<>(); + keys.add("tce_runyy"); + List keys1 = new ArrayList<>(); + keys1.add("CO2_runyy"); + + params.put("tenantType","0"); + List list = sysTenantDetailService.selectList(params); + for (SysTenantDetailDTO sysTenantDetailDTO : list) { + SysTenantDTO tenantCode = sysTenantService.getTenantCode(sysTenantDetailDTO.getId()); + SysTenantDetailDTO detail = sysTenantDetailService.getDetail(tenantCode.getTenantCode()); + ScreenData screenData = new ScreenData(); + screenData.setId(detail.getId()); + screenData.setName(detail.getName()); + screenData.setImg(detail.getImageUrl()); + String lngLat = detail.getLngLat(); + String[] split = lngLat.split(","); + screenData.setLon(new BigDecimal(split[0])); + screenData.setLat(new BigDecimal(split[1])); + + + Map> codeAndKeyMap1 = new HashMap<>(); + codeAndKeyMap1.put(detail.getThingCode(),keys); + //获取区域企业数据,并以属性分组合计 + List dataList1 = tsKvService.findTsKvByMultiMap(codeAndKeyMap1,currentYearTime-1000L,currentYearTime+1000L,Boolean.FALSE); + Map dataResult1 = null; + if (CollectionUtil.isNotEmpty(dataList1)){ + dataResult1 = dataList1.stream().filter(dto -> dto.getVal() != null) + .collect(Collectors.groupingBy(TsKvDTO::getAttrKey, Collectors.mapping(TsKvDTO::getVal, + Collectors.reducing(BigDecimal.ZERO, BigDecimal::new, BigDecimal::add)))); + } + BigDecimal value = BigDecimal.ZERO; + if (dataResult1!=null){ + if (ObjectUtil.isNotEmpty(dataResult1.get("tce_runyy"))){ + value = value.add(dataResult1.get("tce_runyy").setScale(2,BigDecimal.ROUND_HALF_UP)); + } + } + screenData.setMeasure(value); + + ArrayList attrData = new ArrayList<>(); + ScreenData.AttrData attrData1 = new ScreenData.AttrData(); + attrData1.setAttrName("能耗总量"); + attrData1.setAttrValue(value.toString()); + attrData1.setAttrUnit("tce"); + attrData.add(attrData1); + IotValueAddedEntity yearCode = iotValueAddedService.getyearAndTenanCode(detail.getId(), year); + ScreenData.AttrData attrData2 = new ScreenData.AttrData(); + attrData2.setAttrName("能耗指标"); + if(ObjectUtil.isNotEmpty(yearCode) && yearCode.getAddedValue()!=null){ + attrData2.setAttrValue(yearCode.getAddedValue().toString()); + } + attrData2.setAttrUnit("tce"); + attrData.add(attrData2); + + ScreenData.AttrData attrData3 = new ScreenData.AttrData(); + attrData3.setAttrName("指标进度"); + ScreenData.AttrData attrData5 = new ScreenData.AttrData(); + if (ObjectUtil.isNotEmpty(yearCode) && yearCode.getAddedValue()!=null && value!=null){ + BigDecimal multiply = value.divide(yearCode.getAddedValue(), 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)); + attrData3.setAttrValue(multiply.toString()); + if (multiply.compareTo(new BigDecimal(100)) > 0) { + // 如果值超过 100,赋值为 0 + attrData5.setAttrName("0红色 1黄色 2绿色"); + attrData5.setAttrValue("0"); + } else if (multiply.compareTo(new BigDecimal(80)) > 0 && multiply.compareTo(new BigDecimal(100)) < 0) { + // 如果值大于等于 80 且小于 100,赋值为 1 + attrData5.setAttrName("0红色 1黄色 2绿色"); + attrData5.setAttrValue("1"); + } else if(multiply.compareTo(new BigDecimal(80)) <=0){ + // 如果值小于 80,赋值为 2 + attrData5.setAttrName("0红色 1黄色 2绿色"); + attrData5.setAttrValue("2"); + } + attrData.add(attrData5); + }else { + attrData5.setAttrName("0红色 1黄色 2绿色"); + attrData5.setAttrValue("2"); + attrData.add(attrData5); + } + attrData3.setAttrUnit("%"); + attrData.add(attrData3); + + + + Map> codeAndKeyMap = new HashMap<>(); + codeAndKeyMap.put(detail.getThingCode(),keys1); + //获取区域企业数据,并以属性分组合计 + List dataList = tsKvService.findTsKvByMultiMap(codeAndKeyMap,currentYearTime-1000L,currentYearTime+1000L,Boolean.FALSE); + Map dataResult = null; + if (CollectionUtil.isNotEmpty(dataList1)){ + dataResult = dataList.stream().filter(dto -> dto.getVal() != null) + .collect(Collectors.groupingBy(TsKvDTO::getAttrKey, Collectors.mapping(TsKvDTO::getVal, + Collectors.reducing(BigDecimal.ZERO, BigDecimal::new, BigDecimal::add)))); + } + BigDecimal value1 = BigDecimal.ZERO; + if (dataResult1!=null){ + if (ObjectUtil.isNotEmpty(dataResult.get("CO2_runyy"))){ + value1 = value1.add(dataResult.get("CO2_runyy").setScale(2,BigDecimal.ROUND_HALF_UP)); + } + } + ScreenData.AttrData attrData4 = new ScreenData.AttrData(); + attrData4.setAttrName("碳排总量"); + attrData4.setAttrValue(value1.toString()); + attrData4.setAttrUnit("tCO₂"); + attrData.add(attrData4); + screenData.setData(attrData); + screenDatas.add(screenData); + + + + +// EnterprisesDTO energyConsumptionDTOS1 = new EnterprisesDTO(); +// energyConsumptionDTOS1.setUrlAdd(sysTenantDetailDTO.getImageUrl()); +// energyConsumptionDTOS1.setName(sysTenantDetailDTO.getName()); +// energyConsumptionDTOS1.setTenantCode(sysTenantDetailDTO.getId()); +// energyConsumptionDTOS1.setLngLat(sysTenantDetailDTO.getLngLat()); +// IotValueAddedEntity iotValueAddedEntity = iotValueAddedService.getyearAndTenanCode(sysTenantDetailDTO.getId(), year); +// if(ObjectUtil.isNotEmpty(iotValueAddedEntity)){ +// BigDecimal addedValue = iotValueAddedEntity.getAddedValue(); +// energyConsumptionDTOS1.setEnergyConsumption(addedValue); +// } +// Map> codeAndKeyMap1 = new HashMap<>(); +// codeAndKeyMap1.put(tenantCode.getThingCode(),keys); +// //获取区域企业数据,并以属性分组合计 +// List dataList1 = tsKvService.findTsKvByMultiMap(codeAndKeyMap1,currentYearTime-1000L,currentYearTime+1000L,Boolean.FALSE); +// Map dataResult1 = null; +// if (CollectionUtil.isNotEmpty(dataList1)){ +// dataResult1 = dataList1.stream().filter(dto -> dto.getVal() != null) +// .collect(Collectors.groupingBy(TsKvDTO::getAttrKey, Collectors.mapping(TsKvDTO::getVal, +// Collectors.reducing(BigDecimal.ZERO, BigDecimal::new, BigDecimal::add)))); +// } +// if (dataResult1!=null){ +// if (ObjectUtil.isNotEmpty(dataResult1.get("tce_runyy"))){ +// energyConsumptionDTOS1.setTotalEnergyConsumption(dataResult1.get("tce_runyy").setScale(2,BigDecimal.ROUND_HALF_UP)); +// } +// if (ObjectUtil.isNotEmpty(dataResult1.get("CO2_runyy"))){ +// energyConsumptionDTOS1.setTotalCarbonEmissions(dataResult1.get("CO2_runyy").setScale(2,BigDecimal.ROUND_HALF_UP)); +// } +// } +// +// if(energyConsumptionDTOS1.getEnergyConsumption() != null +// &&energyConsumptionDTOS1.getTotalEnergyConsumption()!=null){ +// BigDecimal energyConsumption = energyConsumptionDTOS1.getEnergyConsumption(); +// BigDecimal totalEnergyConsumption = energyConsumptionDTOS1.getTotalEnergyConsumption(); +// BigDecimal divide = totalEnergyConsumption.divide(energyConsumption,2,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)); +// energyConsumptionDTOS1.setProgressIndicators(divide); +// if (energyConsumptionDTOS1.getProgressIndicators().compareTo(new BigDecimal(100)) > 0) { +// // 如果值超过 100,赋值为 1 +// energyConsumptionDTOS1.setColour(0); +// } else if (energyConsumptionDTOS1.getProgressIndicators().compareTo(new BigDecimal(80)) >= 0 && energyConsumptionDTOS1.getProgressIndicators().compareTo(new BigDecimal(100)) < 0) { +// // 如果值大于等于 80 且小于 100,赋值为 1 +// energyConsumptionDTOS1.setColour(1); +// } else if(energyConsumptionDTOS1.getProgressIndicators().compareTo(new BigDecimal(80)) < 0){ +// // 如果值小于 80,赋值为 2 +// energyConsumptionDTOS1.setColour(2); +// } +// } +// if(energyConsumptionDTOS1.getProgressIndicators()==null){ +// energyConsumptionDTOS1.setColour(2); +// } +// energyConsumptionDTOS.add(energyConsumptionDTOS1); + } + + + +// //获取所有企业的thing_code,行业门类,行业大类,区域 +// List industryTenantInfoDTOS = sysTenantService.getByGroupTenantCode(tenantCode); +// +// for (RegionIndustryTenantInfoDTO industryTenantInfoDTO : industryTenantInfoDTOS) { +// SysTenantDetailDTO detail = sysTenantDetailService.getDetail(industryTenantInfoDTO.getTenantCode()); +// ScreenData screenData = new ScreenData(); +// screenData.setId(detail.getId()); +// screenData.setName(detail.getName()); +// screenData.setImg(detail.getImageUrl()); +// String lngLat = detail.getLngLat(); +// String[] split = lngLat.split(","); +// screenData.setLon(new BigDecimal(split[0])); +// screenData.setLat(new BigDecimal(split[1])); +// Map> codeAndKeyMap1 = new HashMap<>(); +// codeAndKeyMap1.put(detail.getThingCode(),keys); +// //获取区域企业数据,并以属性分组合计 +// List dataList1 = tsKvService.findTsKvByMultiMap(codeAndKeyMap1,currentYearTime-1000L,currentYearTime+1000L,Boolean.FALSE); +// Map dataResult1 = null; +// if (CollectionUtil.isNotEmpty(dataList1)){ +// dataResult1 = dataList1.stream().filter(dto -> dto.getVal() != null) +// .collect(Collectors.groupingBy(TsKvDTO::getAttrKey, Collectors.mapping(TsKvDTO::getVal, +// Collectors.reducing(BigDecimal.ZERO, BigDecimal::new, BigDecimal::add)))); +// } +// BigDecimal value = BigDecimal.ZERO; +// if (dataResult1!=null){ +// if (ObjectUtil.isNotEmpty(dataResult1.get("tce_runyy"))){ +// value = value.add(dataResult1.get("tce_runyy").setScale(2,BigDecimal.ROUND_HALF_UP)); +// } +// } +// screenData.setMeasure(value); +// +// ArrayList attrData = new ArrayList<>(); +// ScreenData.AttrData attrData1 = new ScreenData.AttrData(); +// attrData1.setAttrName("能耗总量"); +// attrData1.setAttrValue(value.toString()); +// attrData1.setAttrUnit("tce"); +// attrData.add(attrData1); +// IotValueAddedEntity yearCode = iotValueAddedService.getyearAndTenanCode(detail.getId(), year); +// ScreenData.AttrData attrData2 = new ScreenData.AttrData(); +// attrData2.setAttrName("能耗指标"); +// if(ObjectUtil.isNotEmpty(yearCode) && yearCode.getAddedValue()!=null){ +// attrData2.setAttrValue(yearCode.getAddedValue().toString()); +// } +// attrData2.setAttrUnit("tce"); +// attrData.add(attrData2); +// +// ScreenData.AttrData attrData3 = new ScreenData.AttrData(); +// attrData3.setAttrName("指标进度"); +// ScreenData.AttrData attrData5 = new ScreenData.AttrData(); +// if (ObjectUtil.isNotEmpty(yearCode) && yearCode.getAddedValue()!=null && value!=null){ +// BigDecimal multiply = value.divide(yearCode.getAddedValue(), 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)); +// attrData3.setAttrValue(multiply.toString()); +// if (multiply.compareTo(new BigDecimal(100)) > 0) { +// // 如果值超过 100,赋值为 0 +// attrData5.setAttrName("0红色 1黄色 2绿色"); +// attrData5.setAttrValue("0"); +// } else if (multiply.compareTo(new BigDecimal(80)) > 0 && multiply.compareTo(new BigDecimal(100)) < 0) { +// // 如果值大于等于 80 且小于 100,赋值为 1 +// attrData5.setAttrName("0红色 1黄色 2绿色"); +// attrData5.setAttrValue("1"); +// } else if(multiply.compareTo(new BigDecimal(80)) <=0){ +// // 如果值小于 80,赋值为 2 +// attrData5.setAttrName("0红色 1黄色 2绿色"); +// attrData5.setAttrValue("2"); +// } +// attrData.add(attrData5); +// }else { +// attrData5.setAttrName("0红色 1黄色 2绿色"); +// attrData5.setAttrValue("2"); +// attrData.add(attrData5); +// } +// attrData3.setAttrUnit("%"); +// attrData.add(attrData3); +// +// +// +// Map> codeAndKeyMap = new HashMap<>(); +// codeAndKeyMap.put(detail.getThingCode(),keys1); +// //获取区域企业数据,并以属性分组合计 +// List dataList = tsKvService.findTsKvByMultiMap(codeAndKeyMap,currentYearTime-1000L,currentYearTime+1000L,Boolean.FALSE); +// Map dataResult = null; +// if (CollectionUtil.isNotEmpty(dataList1)){ +// dataResult = dataList.stream().filter(dto -> dto.getVal() != null) +// .collect(Collectors.groupingBy(TsKvDTO::getAttrKey, Collectors.mapping(TsKvDTO::getVal, +// Collectors.reducing(BigDecimal.ZERO, BigDecimal::new, BigDecimal::add)))); +// } +// BigDecimal value1 = BigDecimal.ZERO; +// if (dataResult1!=null){ +// if (ObjectUtil.isNotEmpty(dataResult.get("CO2_runmm"))){ +// value1 = value1.add(dataResult.get("CO2_runmm").setScale(2,BigDecimal.ROUND_HALF_UP)); +// } +// } +// ScreenData.AttrData attrData4 = new ScreenData.AttrData(); +// attrData4.setAttrName("碳排总量"); +// attrData4.setAttrValue(value1.toString()); +// attrData4.setAttrUnit("tCO₂"); +// attrData.add(attrData4); +// screenData.setData(attrData); +// screenDatas.add(screenData); +// } + return screenDatas; + } + + @Override + public EnergyConsumptionTrendDTO carbonEmissionTrend(Map params) { + EnergyConsumptionTrendDTO result = new EnergyConsumptionTrendDTO(); + ArrayList keys1 = new ArrayList<>(); + String carbonEmission; + if (params!=null && ObjectUtil.isNotEmpty(params.get("carbonEmission"))){ + carbonEmission = params.get("carbonEmission").toString(); + keys1.add(carbonEmission); + }else{ + return null; + } + String tenantCode; + if (params!=null && ObjectUtil.isNotEmpty(params.get("tenantCode"))){ + tenantCode = params.get("tenantCode").toString(); + }else{ + return null; + } + String year; + if (params!=null && ObjectUtil.isNotEmpty(params.get("year"))){ + year = params.get("year").toString(); + }else{ + year = DateTimeUtils.getCurrentYear(); + } + //今年月份 + List currentMonths = DateTimeUtils.getMonthList(year); + String lastYear = String.valueOf(Integer.parseInt(year)-1); + //去年月份 + List lastMonths = DateTimeUtils.getMonthList(lastYear); + Long lastYearStartTime = DateTimeUtils.dateToTimestamp(lastYear+"-01-01 00:00:00"); + Long currentYearEndTime = DateTimeUtils.dateToTimestamp(year+"-12-01 00:00:00"); + SysTenantDTO tenantCode1 = sysTenantService.getTenantCode(Long.parseLong(tenantCode)); + + Map> codeAndKeyMap1 = new HashMap<>(); + codeAndKeyMap1.put(tenantCode1.getThingCode(),keys1); + //获取数据,并以时间分组求和 + List dataList1 = tsKvService.findTsKvByMultiMap(codeAndKeyMap1,lastYearStartTime-1000L,currentYearEndTime+1000L,Boolean.FALSE); + Map dataResult1 = new HashMap<>(); + if (CollectionUtil.isNotEmpty(dataList1)){ + dataResult1 = dataList1.stream().filter(dto -> dto.getVal() != null) + .collect(Collectors.groupingBy(TsKvDTO::getTs, Collectors.mapping(TsKvDTO::getVal, + Collectors.reducing(BigDecimal.ZERO, BigDecimal::new, BigDecimal::add)))); + } + //今年碳排 + ArrayList thisAnnualCarbonEmission = new ArrayList<>(); + //去年碳排 + ArrayList lastAnnualCarbonEmission = new ArrayList<>(); + Map lastYearData1 = new HashMap<>(); + for (String month : lastMonths){ + EnergyTrendDTO energyDTO = new EnergyTrendDTO(); + energyDTO.setDate(month); + Long monthTs = DateTimeUtils.dateToTimestamp(month+"-01 00:00:00"); + BigDecimal value =null; + if (dataResult1!=null && dataResult1.get(monthTs)!=null){ + value = dataResult1.get(monthTs); + energyDTO.setValue(value); + } + lastYearData1.put(month.substring(5),value); + lastAnnualCarbonEmission.add(energyDTO); + } + for (String month : currentMonths){ + EnergyDTO energyDTO = new EnergyDTO(); + energyDTO.setDate(month); + Long monthTs = DateTimeUtils.dateToTimestamp(month+"-01 00:00:00"); + BigDecimal value = null; + if (dataResult1!=null && dataResult1.get(monthTs)!=null){ + value = dataResult1.get(monthTs); + energyDTO.setValue(value); + } + energyDTO.setValue(value); + //计算同比 + if (value!=null && lastYearData1!=null && lastYearData1.get(month.substring(5))!=null && lastYearData1.get(month.substring(5)).compareTo(BigDecimal.ZERO)!=0){ + BigDecimal lastValue = lastYearData1.get(month.substring(5)); + BigDecimal yearOnYearGrowthRate = (value.subtract(lastValue)).divide(lastValue, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100")); + energyDTO.setYoy(yearOnYearGrowthRate+"%"); + //大于0上升,小于0下降 + if (yearOnYearGrowthRate.compareTo(BigDecimal.ZERO)==1){ + energyDTO.setUpOrDown(1); + }else if (yearOnYearGrowthRate.compareTo(BigDecimal.ZERO)==-1){ + energyDTO.setUpOrDown(0); + } + } + thisAnnualCarbonEmission.add(energyDTO); + } + result.setThisAnnualCarbonEmission(thisAnnualCarbonEmission); + result.setLastAnnualCarbonEmission(lastAnnualCarbonEmission); + return result; + } + + @Override + public CleanEnergyDTO cleanEnergy(Map params) { + CleanEnergyDTO cleanEnergyDTO = new CleanEnergyDTO(); + cleanEnergyDTO.setCleanEnergy(new BigDecimal(0)); + cleanEnergyDTO.setUnit("kWh"); + return cleanEnergyDTO; + } + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/controller/RegionBoardController.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/controller/RegionBoardController.java new file mode 100644 index 0000000..48c92d1 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/controller/RegionBoardController.java @@ -0,0 +1,114 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.controller; + + +import com.thing.qingyuan.regionalenterprises.regionalboard.dto.*; +import com.thing.qingyuan.regionalenterprises.regionalboard.service.RegionBoardService; +import com.thing.common.core.web.response.Result; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; +import java.util.Map; + +/** + * 区域企业看板 + * + * @author xiezw + * @since 2024-01-20 + */ + +@RestController +@RequestMapping("regional/board") +@Tag(name = "区域企业总看板") +public class RegionBoardController { + + @Autowired + private RegionBoardService regionBoardService; + + @GetMapping("totalConsumption/trend") + @Operation(summary="总能耗趋势") + @Parameters({ + @Parameter(name = "year",description ="年份,格式2024",required = true) + }) + public Result> getTotalConsumptionTrend( @Parameter(hidden = true) @RequestParam Map params){ + List result = regionBoardService.getTotalConsumptionTrend(params); + return new Result>().ok(result); + } + + @GetMapping("totalCarbon/trend") + @Operation(summary="总碳排趋势") + @Parameters({ + @Parameter(name = "year",description ="年份,格式2024",required = true) + }) + public Result getTotalCarbonTrend(@Parameter(hidden = true) @RequestParam Map params){ + RegionTotalCarbonDTO result = regionBoardService.getTotalCarbonTrend(params); + return new Result().ok(result); + } + + @GetMapping("industryTypeConsumption") + @Operation(summary="行业能耗") + @Parameters({ + @Parameter(name = "year",description ="年份,格式2024",required = true) + }) + public Result> getQuotaTypeConsumption(@Parameter(hidden = true) @RequestParam Map params){ + List result = regionBoardService.getQuotaTypeConsumption(params); + return new Result>().ok(result); + } + + @GetMapping("industryTypeCarbon") + @Operation(summary="行业碳排") + @Parameters({ + @Parameter(name = "year",description ="年份,格式2024",required = true) + }) + public Result> getIndustryTypeCarbon(@Parameter(hidden = true) @RequestParam Map params){ + List result = regionBoardService.getIndustryTypeCarbon(params); + return new Result>().ok(result); + } + + @GetMapping("totalConsumption/analyse") + @Operation(summary="总能耗同比分析") + @Parameters({ + @Parameter(name = "year",description ="年份,格式2024",required = true) + }) + public Result getTotalConsumptionAnalyse(@Parameter(hidden = true) @RequestParam Map params){ + RegionTotalConsumptionAnalyseDTO result = regionBoardService.getTotalConsumptionAnalyse(params); + return new Result().ok(result); + } + + @GetMapping("energyFlow") + @Operation(summary="能源流向图") + @Parameters({ + @Parameter(name = "year",description ="年份,格式2024",required = true) + }) + public Result getEnergyFlow(@Parameter(hidden = true) @RequestParam Map params){ + RegionSubNodeRespDTO result = regionBoardService.getEnergyFlow(params); + return new Result().ok(result); + } + + @GetMapping("areaEnergyData") + @Operation(summary="各区域能耗及碳排数据") + @Parameters({ + @Parameter(name = "year",description ="年份,格式2024",required = true) + }) + public Result> getAreaEnergyData(@Parameter(hidden = true) @RequestParam Map params){ + List result = regionBoardService.getAreaEnergyData(params); + return new Result>().ok(result); + } + + @GetMapping("totalData") + @Operation(summary="看板总数据") + @Parameters({ + @Parameter(name = "year",description ="年份,格式2024",required = true) + }) + public Result getTotalData(@Parameter(hidden = true) @RequestParam Map params){ + RegionTotalDataDTO result = regionBoardService.getTotalData(params); + return new Result().ok(result); + } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/controller/RegionEnergyConsumptionReportController.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/controller/RegionEnergyConsumptionReportController.java new file mode 100644 index 0000000..ba4c619 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/controller/RegionEnergyConsumptionReportController.java @@ -0,0 +1,136 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.controller; + + +import cn.afterturn.easypoi.excel.ExcelExportUtil; +import cn.afterturn.easypoi.excel.entity.ExportParams; +import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity; +import cn.hutool.core.collection.CollectionUtil; +import com.thing.qingyuan.regionalenterprises.regionalboard.dto.*; +import com.thing.qingyuan.regionalenterprises.regionalboard.service.RegionEnergyConsumptionReportService; +import com.thing.common.core.utils.ConvertUtils; +import com.thing.common.core.utils.excel.ExcelUtils; +import com.thing.common.core.web.response.Result; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletResponse; +import org.apache.poi.ss.usermodel.Workbook; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 用能预警 + * + * @author xiezw + * @since 2023-08-11 + */ + +@RestController +@RequestMapping("region/consumption/report") +@Tag(name = "区域企业报表") +public class RegionEnergyConsumptionReportController { + + @Autowired + private RegionEnergyConsumptionReportService regionEnergyConsumptionReportService; + + @GetMapping("list") + @Operation(summary="基础报表") + @Parameters({ + @Parameter(name = "tenantName",description ="机构名称"), + @Parameter(name = "regionCode",description ="区域编号"), + @Parameter(name = "dateType",description ="时间类型 0年 1月",required = true), + @Parameter(name = "date",description ="月份格式2023-08,年格式2023",required = true) + }) + public Result> getBaseReportList(@Parameter(hidden = true) @RequestParam Map params){ + List result = regionEnergyConsumptionReportService.getBaseReportList(params); + return new Result>().ok(result); + } + @GetMapping("export") + @Operation(summary="基础报表导出") + @Parameters({ + @Parameter(name = "tenantName",description ="机构名称"), + @Parameter(name = "regionCode",description ="区域编号"), + @Parameter(name = "dateType",description ="时间类型 0年 1月",required = true), + @Parameter(name = "date",description ="月份格式2023-08,年格式2023",required = true) + }) + public void getBaseReportExport(@Parameter(hidden = true) @RequestParam Map params, HttpServletResponse response) throws UnsupportedEncodingException { + List result = regionEnergyConsumptionReportService.getBaseReportList(params); + List list = ConvertUtils.sourceToTarget(result, RegionEnergyBaseExportExcel.class); + ExcelUtils.exportExcel(list, "基础报表", "基础报表", RegionEnergyBaseExportExcel.class, URLEncoder.encode("基础报表", "UTF-8")+ ".xls", response); + } + + + @GetMapping("list/energy") + @Operation(summary="能耗报表") + @Parameters({ + @Parameter(name = "tenantName",description ="机构名称"), + @Parameter(name = "regionCode",description ="区域编号"), + @Parameter(name = "dateType",description ="时间类型 0年 1月",required = true), + @Parameter(name = "date",description ="月份格式2023-08,年格式2023",required = true) + }) + public Result> getEnergyConsumptionList(@Parameter(hidden = true) @RequestParam Map params){ + List result = regionEnergyConsumptionReportService.getEnergyConsumptionList(params); + return new Result>().ok(result); + } + @GetMapping("energy/export") + @Operation(summary="能耗报表导出") + @Parameters({ + @Parameter(name = "tenantName",description ="机构名称"), + @Parameter(name = "regionCode",description ="区域编号"), + @Parameter(name = "dateType",description ="时间类型 0年 1月",required = true), + @Parameter(name = "date",description ="月份格式2023-08,年格式2023",required = true) + }) + public void getEnergyReportExport(@Parameter(hidden = true) @RequestParam Map params, HttpServletResponse response) throws Exception { + List result = regionEnergyConsumptionReportService.getEnergyConsumptionList(params); + List list = ConvertUtils.sourceToTarget(result, RegionEnergyConsumptionExportExcel.class); + List entityList = prepareColumnConfig(list.get(0).getKeyValueList()); + List> dataList = new ArrayList<>(); + ExportParams exportParams = new ExportParams("能耗报表", "能耗报表"); + for (RegionEnergyConsumptionExportExcel excel:list){ + Map map = new HashMap<>(); + map.put("orgName",excel.getOrgName()); + map.put("regionName",excel.getRegionName()); + map.put("totalConsumption",excel.getTotalConsumption()); + if (CollectionUtil.isNotEmpty(excel.getKeyValueList())){ + for (RegionEnergyDetailExportExcel exportExcel:excel.getKeyValueList()){ + map.put(exportExcel.getKey(),exportExcel.getValue()); + } + } + dataList.add(map); + } + Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entityList, dataList); + // 导出 Excel + ExcelUtils.downLoadExcel("能耗报表.xls", response, workbook); + } + + private static List prepareColumnConfig(List keyValueList) { + // 创建列配置列表 + List entityList = new ArrayList<>(); + entityList.add(new ExcelExportEntity("机构名称", "orgName")); + entityList.add(new ExcelExportEntity("地区名称", "regionName")); + entityList.add(new ExcelExportEntity("能耗总量", "totalConsumption")); + // 遍历动态列头,创建对应的列配置 + for (RegionEnergyDetailExportExcel excel : keyValueList) { + ExcelExportEntity entity = new ExcelExportEntity(); + entity.setName(excel.getKey()); // 设置列标题 + entity.setKey(excel.getKey()); // 设置列名 + entity.setWidth(10); + entityList.add(entity); + } + + return entityList; + } + +} + diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/controller/RegionEnergyWarningController.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/controller/RegionEnergyWarningController.java new file mode 100644 index 0000000..434e0d3 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/controller/RegionEnergyWarningController.java @@ -0,0 +1,188 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.controller; + + +import cn.hutool.core.collection.CollectionUtil; +import com.thing.qingyuan.regionalenterprises.regionalboard.dto.*; +import com.thing.qingyuan.regionalenterprises.regionalboard.service.RegionEnergyWarningService; +import com.thing.common.core.utils.ConvertUtils; +import com.thing.common.core.utils.excel.ExcelUtils; +import com.thing.common.core.web.response.Result; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.List; +import java.util.Map; + +/** + * 用能预警 + * + * @author xiezw + * @since 2023-08-11 + */ + +@RestController +@RequestMapping("region/energy/warning") +@Tag(name = "区域企业用能预警") +public class RegionEnergyWarningController { + + @Autowired + private RegionEnergyWarningService regionEnergyWarningService; + +// @PostMapping("list") +// @Operation(summary="用能预警列表") +// public Result> getEnergyWarningList(@RequestBody RegionEnergyWarningRequestDTO dto){ +// List result = regionEnergyWarningService.getEnergyWarningList(dto); +// return new Result>().ok(result); +// } + + @GetMapping("list") + @Operation(summary="用能预警列表") + @Parameters({ + @Parameter(name = "tenantName",description ="机构名称"), + @Parameter(name = "industryType",description ="行业代码"), + @Parameter(name = "regionCode",description ="区域编号"), + @Parameter(name = "dateType",description ="时间类型 0年 1月",required = true), + @Parameter(name = "date",description ="月份格式2023-08,年格式2023",required = true) + }) + public Result> getEnergyWarningList(@Parameter(hidden = true) @RequestParam Map params){ + List result = regionEnergyWarningService.getEnergyWarningList(params); + return new Result>().ok(result); + } + + + @GetMapping("export") + @Operation(summary="用能预警导出") + @Parameters({ + @Parameter(name = "tenantName",description ="机构名称"), + @Parameter(name = "industryType",description ="行业代码"), + @Parameter(name = "regionCode",description ="区域编号"), + @Parameter(name = "dateType",description ="时间类型 0年 1月",required = true), + @Parameter(name = "date",description ="月份格式2023-08,年格式2023",required = true) + }) + public void getEnergyWarningPageList(@Parameter(hidden = true) @RequestParam Map params, HttpServletResponse response) throws UnsupportedEncodingException { + List result = regionEnergyWarningService.getEnergyWarningList(params); + if (params.get("dateType").equals("0")){ + List list = ConvertUtils.sourceToTarget(result, RegionEnergyWarningExcel1.class); + ExcelUtils.exportExcel(list, "年度用能预警", "年度用能预警", RegionEnergyWarningExcel1.class, URLEncoder.encode("年度用能预警", "UTF-8")+ ".xls", response); + }else{ + List list = ConvertUtils.sourceToTarget(result, RegionEnergyWarningExcel.class); + ExcelUtils.exportExcel(list, "月度用能预警", "月度用能预警", RegionEnergyWarningExcel.class, URLEncoder.encode("月度用能预警", "UTF-8")+".xls", response); + } + } + + + @GetMapping("getWarningCount") + @Operation(summary="获取告警数量(超限,临限,正常数量)") + @Parameters({ + @Parameter(name = "dateType",description ="时间类型 0年 1月",required = true), + @Parameter(name = "date",description ="月份格式2023-08,年格式2023",required = true) + }) + public Result getWarningCount(@Parameter(hidden = true) @RequestParam Map params){ + List list = regionEnergyWarningService.getEnergyWarningList(params); + RegionWarningCountDTO result = new RegionWarningCountDTO(); + Integer upLimitCount = 0; + Integer normalCount = 0; + Integer proLimitCount=0; + if (CollectionUtil.isNotEmpty(list)){ + for (RegionEnergyWarningDataDTO warningDataDTO:list){ + if (warningDataDTO.getTotalConsumptionLimit()==0){ + normalCount++; + }else if (warningDataDTO.getTotalConsumptionLimit()==1){ + proLimitCount++; + }else if (warningDataDTO.getTotalConsumptionLimit()==2){ + upLimitCount++; + } + } + } + result.setNormalCount(normalCount); + result.setProLimitCount(proLimitCount); + result.setUpLimitCount(upLimitCount); + return new Result().ok(result); + } + + @GetMapping("getRegionList") + @Operation(summary="获取区域列表(用能告警下拉列表)") + public Result> getRegionList(){ + List result = regionEnergyWarningService.getRegionList(); + return new Result>().ok(result); + } + + @GetMapping("getIndustryList") + @Operation(summary="获取行业列表(用能告警下拉列表)") + public Result> getIndustryList(){ + List result = regionEnergyWarningService.getIndustryList(); + return new Result>().ok(result); + } + + @GetMapping("monthConsumption/proportion") + @Operation(summary="月度能耗占比(月-单个企业)") + @Parameters({ + @Parameter(name = "date",description ="月份格式2023-08",required = true), + @Parameter(name = "thingCode",description ="物编码",required = true) + }) + public Result getMonthConsumptionProportion( @Parameter(hidden = true) @RequestParam Map params){ + RegionMonthConsumptionDTO result = regionEnergyWarningService.getMonthConsumptionProportion(params); + return new Result().ok(result); + } + + @GetMapping("yearConsumption/analyse") + @Operation(summary="年度能耗预警分析(年-单个企业)") + @Parameters({ + @Parameter(name = "date",description ="年格式2024",required = true), + @Parameter(name = "thingCode",description ="物编码",required = true), + @Parameter(name = "tenantCode",description ="租户编码",required = true) + }) + public Result> getYearConsumptionAnalyse( @Parameter(hidden = true) @RequestParam Map params){ + List result = regionEnergyWarningService.getYearConsumptionAnalyse(params); + return new Result>().ok(result); + } + + @GetMapping("consumption/analyse") + @Operation(summary="能耗同比分析(月/年-单个企业)") + @Parameters({ + @Parameter(name = "dateType",description ="时间类型 0年 1月",required = true), + @Parameter(name = "date",description ="月份格式2023-08,年格式2023",required = true), + @Parameter(name = "thingCode",description ="物编码",required = true) + }) + public Result getConsumptionAnalyse(@Parameter(hidden = true) @RequestParam Map params){ + RegionTotalConsumptionAnalyseDTO result = regionEnergyWarningService.getConsumptionAnalyse(params); + return new Result().ok(result); + } + + @GetMapping("consumption/target") + @Operation(summary="能耗指标进度(月/年-单个企业)") + @Parameters({ + @Parameter(name = "dateType",description ="时间类型 0年 1月",required = true), + @Parameter(name = "date",description ="月份格式2023-08,年格式2023",required = true), + @Parameter(name = "thingCode",description ="物编码",required = true), + @Parameter(name = "tenantCode",description ="租户编码",required = true) + }) + public Result getConsumptionAndTarget(@Parameter(hidden = true) @RequestParam Map params){ + RegionConsumptionTargetDTO result = regionEnergyWarningService.getConsumptionAndTarget(params); + return new Result().ok(result); + } + + @GetMapping("orgDataCompare") + @Operation(summary="三年同期总能耗对比分析") + @Parameters({ + @Parameter(name = "dateType",description ="时间类型 0年 1月",required = true), + @Parameter(name = "date",description ="月份格式2023-08,年格式2023",required = true), + @Parameter(name = "thingCode",description ="物编码",required = true) + }) + public Result getOrgDataCompare( @Parameter(hidden = true) @RequestParam Map params){ + RegionOrgConsumptionCompareDTO result = regionEnergyWarningService.getOrgDataCompare(params); + return new Result().ok(result); + } + + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionAreaConsumptionDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionAreaConsumptionDTO.java new file mode 100644 index 0000000..c1084b4 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionAreaConsumptionDTO.java @@ -0,0 +1,43 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.dto; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + + +/** + * @author xiezw + * @date 2023-08-09 + **/ +@Data +public class RegionAreaConsumptionDTO { + + @Schema(description = "地区名称") + private String regionName; + @Schema(description = "地区编号") + private Long regionCode; + @Schema(description = "监测单位数量") + private Integer orgCount; + @Schema(description = "总能耗") + private BigDecimal totalConsumption; + @Schema(description = "总碳排") + private BigDecimal totalCarbon; + +// public BigDecimal getTotalConsumption() { +// if (totalConsumption!=null){ +// return totalConsumption.divide(new BigDecimal(10000)).setScale(2, RoundingMode.HALF_UP); +// }else{ +// return totalConsumption; +// } +// } +// +// public BigDecimal getTotalCarbon() { +// if (totalCarbon!=null){ +// return totalCarbon.divide(new BigDecimal(10000)).setScale(2, RoundingMode.HALF_UP); +// }else{ +// return totalCarbon; +// } +// } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionAreaInfoDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionAreaInfoDTO.java new file mode 100644 index 0000000..0e5894f --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionAreaInfoDTO.java @@ -0,0 +1,19 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.dto; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + + +/** + * @author xiezw + * @date 2023-08-09 + **/ +@Data +public class RegionAreaInfoDTO { + + @Schema(description = "地区名称") + private String regionName; + @Schema(description = "地区编号") + private Long regionCode; +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionConsumptionDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionConsumptionDTO.java new file mode 100644 index 0000000..6d48e16 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionConsumptionDTO.java @@ -0,0 +1,27 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.dto; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + + +/** + * @author xiezw + * @date 2023-08-09 + **/ +@Data +@Schema(description="区域能耗") +public class RegionConsumptionDTO { + + @Schema(description = "属性") + private String key; + + @Schema(description = "属性名称") + private String keyName; + + @Schema(description = "数据") + private List datas; + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionConsumptionTargetDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionConsumptionTargetDTO.java new file mode 100644 index 0000000..3301121 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionConsumptionTargetDTO.java @@ -0,0 +1,22 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.dto; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + + +/** + * @author xiezw + * @date 2023-08-09 + **/ +@Data +public class RegionConsumptionTargetDTO { + + @Schema(description = "计划能耗") + private BigDecimal planValue; + + @Schema(description = "累计能耗") + private BigDecimal sumValue; +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyBaseExportExcel.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyBaseExportExcel.java new file mode 100644 index 0000000..02e1712 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyBaseExportExcel.java @@ -0,0 +1,48 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.dto; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import com.alibaba.excel.annotation.write.style.ColumnWidth; +import com.alibaba.excel.annotation.write.style.ContentRowHeight; +import com.alibaba.excel.annotation.write.style.HeadRowHeight; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 用能预警导出 + * + * @author xiezw 806671840@qq.com + * @since 3.0 2023-08-01 + */ +@Data +@ContentRowHeight(20) +@HeadRowHeight(20) +@ColumnWidth(25) +public class RegionEnergyBaseExportExcel { + + @Excel(name = "企业名称") + private String orgName; + + @Excel(name = "区域") + private String regionName; + + @Excel(name = "企业能效质量") + private String consumptionQuality; + + @Excel(name = "能耗总量(tce)") + private BigDecimal totalConsumption; + + @Excel(name = "增加值能耗强度(tce/万元)") + private BigDecimal consumptionIntensity; + + @Excel(name = "碳排总量(tCO₂)") + private BigDecimal totalCarbon; + + @Excel(name = "增加值碳排强度(tCO₂/万元)") + private BigDecimal carbonIntensity; + + @Excel(name = "能效达标") + private String compliance; + + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyBaseReportDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyBaseReportDTO.java new file mode 100644 index 0000000..30a8cc1 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyBaseReportDTO.java @@ -0,0 +1,50 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.dto; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + + +/** + * @author xiezw + * @date 2023-08-09 + **/ +@Data +public class RegionEnergyBaseReportDTO { + @Schema(description = "租户code") + private Long tenantCode; + + @Schema(description = "机构名称") + private String orgName; + + @Schema(description = "物编码") + private String thingCode; + + @Schema(description = "地区名称") + private String regionName; + @Schema(description = "地区编号") + private Long regionCode; + + @Schema(description = "企业能效质量") + private String consumptionQuality; + + @Schema(description = "能耗总量") + private BigDecimal totalConsumption; + + @Schema(description = "增加值能耗强度") + private BigDecimal consumptionIntensity; + + @Schema(description = "碳排总量") + private BigDecimal totalCarbon; + + @Schema(description = "增加值碳排强度") + private BigDecimal carbonIntensity; + + @Schema(description = "能效达标") + private String compliance; + + + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyConsumptionAnalyseDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyConsumptionAnalyseDTO.java new file mode 100644 index 0000000..09addf1 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyConsumptionAnalyseDTO.java @@ -0,0 +1,44 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.dto; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + + +/** + * @author xiezw + * @date 2023-08-09 + **/ +@Data +public class RegionEnergyConsumptionAnalyseDTO { + + @Schema(description = "日期") + private String date; + + @Schema(description = "值") + private BigDecimal value; + + @Schema(description = "同比") + private String yoy; + + @Schema(description = "上升或下降 0下降 1上升") + private Integer upOrDown; + +// public BigDecimal getValue() { +// if (value!=null){ +// return value.divide(new BigDecimal(10000)).setScale(2, RoundingMode.HALF_UP); +// }else{ +// return value; +// } +// } + +// public BigDecimal getYoy() { +// if (yoy!=null){ +// return yoy.setScale(2, RoundingMode.HALF_UP); +// }else{ +// return yoy; +// } +// } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyConsumptionDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyConsumptionDTO.java new file mode 100644 index 0000000..3a361b7 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyConsumptionDTO.java @@ -0,0 +1,31 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.dto; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + + +/** + * @author xiezw + * @date 2023-08-09 + **/ +@Data +@Schema(description = "区域企业能耗明细") +public class RegionEnergyConsumptionDTO { + + @Schema(description = "日期") + private String date; + + @Schema(description = "值") + private BigDecimal value; + +// public BigDecimal getValue() { +// if (value!=null){ +// return value.divide(new BigDecimal(10000)).setScale(2, RoundingMode.HALF_UP); +// }else{ +// return value; +// } +// } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyConsumptionExportExcel.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyConsumptionExportExcel.java new file mode 100644 index 0000000..f7ddfe3 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyConsumptionExportExcel.java @@ -0,0 +1,40 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.dto; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import com.alibaba.excel.annotation.write.style.ColumnWidth; +import com.alibaba.excel.annotation.write.style.ContentRowHeight; +import com.alibaba.excel.annotation.write.style.HeadRowHeight; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +/** + * 用能预警导出 + * + * @author xiezw 806671840@qq.com + * @since 3.0 2023-08-01 + */ +@Data +@ContentRowHeight(20) +@HeadRowHeight(20) +@ColumnWidth(25) +public class RegionEnergyConsumptionExportExcel { + + @Excel(name = "企业名称") + private String orgName; + + @Excel(name = "区域") + private String regionName; + + @Excel(name = "能耗总量") + private BigDecimal totalConsumption; + +// @Excel(name = "数据") +// private Map keyValue; + +// @ExcelCollection(name = "数据") + private List keyValueList; + + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyConsumptionReportDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyConsumptionReportDTO.java new file mode 100644 index 0000000..5b46d91 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyConsumptionReportDTO.java @@ -0,0 +1,40 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.dto; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + + +/** + * @author xiezw + * @date 2023-08-09 + **/ +@Data +public class RegionEnergyConsumptionReportDTO { + @Schema(description = "租户code") + private Long tenantCode; + + @Schema(description = "物code") + private String thingCode; + @Schema(description = "机构名称") + private String orgName; + + @Schema(description = "地区名称") + private String regionName; + @Schema(description = "地区编号") + private Long regionCode; + + @Schema(description = "能耗总量") + private BigDecimal totalConsumption; + +// @Schema(description = "数据") +// private Map keyValue; + + @Schema(description = "数据") + private List keyValueList; + + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyDetailExportExcel.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyDetailExportExcel.java new file mode 100644 index 0000000..88ababd --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyDetailExportExcel.java @@ -0,0 +1,30 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.dto; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import com.alibaba.excel.annotation.write.style.ColumnWidth; +import com.alibaba.excel.annotation.write.style.ContentRowHeight; +import com.alibaba.excel.annotation.write.style.HeadRowHeight; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 用能预警导出 + * + * @author xiezw 806671840@qq.com + * @since 3.0 2023-08-01 + */ +@Data +@ContentRowHeight(20) +@HeadRowHeight(20) +@ColumnWidth(25) +public class RegionEnergyDetailExportExcel { + + @Excel(name = "名称") + private String key; + + @Excel(name = "值") + private BigDecimal value; + + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyWarningDataDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyWarningDataDTO.java new file mode 100644 index 0000000..cb65cee --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyWarningDataDTO.java @@ -0,0 +1,49 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.dto; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + + +/** + * @author xiezw + * @date 2023-08-09 + **/ +@Data +public class RegionEnergyWarningDataDTO { + @Schema(description = "租户code") + private Long tenantCode; + @Schema(description = "机构名称") + private String orgName; + + @Schema(description = "物编码") + private String thingCode; + + @Schema(description = "地区名称") + private String regionName; + @Schema(description = "地区编号") + private Long regionCode; + + @Schema(description = "行业代码") + private String industryCode; + @Schema(description = "行业名称") + private String industryName; + + @Schema(description = "控制目标") + private BigDecimal targetValue; + @Schema(description = "能耗") + private BigDecimal totalConsumption; + @Schema(description = "能耗是否超标 0正常 1临限,2超限") + private Integer totalConsumptionLimit=0; + + @Schema(description = "能耗指标进度") + private String totalConsumptionProcess; + @Schema(description = "能耗指标进度是否超标 0正常 1临限,2超限") + private Integer totalConsumptionProcessLimit=0; + + @Schema(description = "排序") + private Integer sort; + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyWarningExcel.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyWarningExcel.java new file mode 100644 index 0000000..4ea5a4e --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyWarningExcel.java @@ -0,0 +1,39 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.dto; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import com.alibaba.excel.annotation.write.style.ColumnWidth; +import com.alibaba.excel.annotation.write.style.ContentRowHeight; +import com.alibaba.excel.annotation.write.style.HeadRowHeight; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 用能预警导出 + * + * @author xiezw 806671840@qq.com + * @since 3.0 2023-08-01 + */ +@Data +@ContentRowHeight(20) +@HeadRowHeight(20) +@ColumnWidth(25) +public class RegionEnergyWarningExcel { + + @Excel(name = "企业名称") + private String orgName; + @Excel(name = "区域") + private String regionName; + @Excel(name = "行业名称") + private String industryName; + @Excel(name = "用能排行") + private Integer sort; + @Excel(name = "月度控制目标(tce)") + private BigDecimal targetValue; + @Excel(name = "月度能耗(tce)") + private BigDecimal totalConsumption; + @Excel(name = "能耗指标进度(%)") + private String totalConsumptionProcess; + + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyWarningExcel1.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyWarningExcel1.java new file mode 100644 index 0000000..ab1d495 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyWarningExcel1.java @@ -0,0 +1,39 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.dto; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import com.alibaba.excel.annotation.write.style.ColumnWidth; +import com.alibaba.excel.annotation.write.style.ContentRowHeight; +import com.alibaba.excel.annotation.write.style.HeadRowHeight; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 用能预警导出 + * + * @author xiezw 806671840@qq.com + * @since 3.0 2023-08-01 + */ +@Data +@ContentRowHeight(20) +@HeadRowHeight(20) +@ColumnWidth(25) +public class RegionEnergyWarningExcel1 { + + @Excel(name = "企业名称") + private String orgName; + @Excel(name = "区域") + private String regionName; + @Excel(name = "行业名称") + private String industryName; + @Excel(name = "用能排行") + private Integer sort; + @Excel(name = "年度控制目标(tce)") + private BigDecimal targetValue; + @Excel(name = "年度能耗(tce)") + private BigDecimal totalConsumption; + @Excel(name = "能耗指标进度(%)") + private String totalConsumptionProcess; + + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyWarningRequestDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyWarningRequestDTO.java new file mode 100644 index 0000000..443c46b --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionEnergyWarningRequestDTO.java @@ -0,0 +1,33 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.dto; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + + +/** + * @author xiezw + * @date 2023-08-09 + **/ +@Data +public class RegionEnergyWarningRequestDTO { + + @Schema(description = "机构名称") + private String orgName; + @Schema(description = "行业代码") + private String industryCode; + @Schema(description = "区域编号") + private String regionCode; + @Schema(description = "时间类型 0月 1年") + private String dateType; + @Schema(description = "年格式2023,月份格式2023-08,年-默认当前年,月默认当前月") + private String date; + +// @Schema(description = "时间类型 0年 1月 ----当点击页面上方 年或月超限/安全单位,类型按年月区分对应传参") +// private String dateType; +// @Schema(description = "年格式2023,月份格式2023-08,年-默认当前年,月默认当前月,----当点击页面上方 年或月超限/安全单位,默认当前年或月") +// private String date; +// +// @Schema(description = "机构租户idList,点击页面上方超限/安全单位 传入该参") +// private List tenantCodes; +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionIndustryCarbonDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionIndustryCarbonDTO.java new file mode 100644 index 0000000..575260e --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionIndustryCarbonDTO.java @@ -0,0 +1,30 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.dto; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + + +/** + * @author xiezw + * @date 2023-08-09 + **/ +@Data +public class RegionIndustryCarbonDTO { + + @Schema(description = "行业code") + private String industryCode; + + @Schema(description = "行业名称名称") + private String industryName; + + @Schema(description = "碳排值") + private BigDecimal value; + + @Schema(description = "占比") + private String proportion; + + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionIndustryDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionIndustryDTO.java new file mode 100644 index 0000000..7eded0c --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionIndustryDTO.java @@ -0,0 +1,28 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.dto; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Map; + + +/** + * @author xiezw + * @date 2023-08-09 + **/ +@Data +public class RegionIndustryDTO { + + @Schema(description = "行业code") + private String industryCode; + + @Schema(description = "行业名称名称") + private String industryName; + + @Schema(description = "品种&数据") + private Map valueMap; + + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionIndustryInfoDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionIndustryInfoDTO.java new file mode 100644 index 0000000..b930345 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionIndustryInfoDTO.java @@ -0,0 +1,23 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.dto; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + + +/** + * @author xiezw + * @date 2023-08-09 + **/ +@Data +public class RegionIndustryInfoDTO { + + @Schema(description = "行业code") + private String industryCode; + + @Schema(description = "行业名称名称") + private String industryName; + + + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionLinkDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionLinkDTO.java new file mode 100644 index 0000000..4f41f0d --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionLinkDTO.java @@ -0,0 +1,33 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.dto; + +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.math.RoundingMode; + +/** + * @author xzw + */ +@Data +public class RegionLinkDTO implements Serializable { + + private static final long serialVersionUID = -8762182832474042437L; + + private String source; + + private String target; + + private BigDecimal value; + private String unit; + private String proportion; + + public BigDecimal getValue() { + if (value!=null){ + return value.divide(new BigDecimal(10000)).setScale(2, RoundingMode.HALF_UP); + }else{ + return value; + } + } + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionMonthConsumptionDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionMonthConsumptionDTO.java new file mode 100644 index 0000000..0cfea68 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionMonthConsumptionDTO.java @@ -0,0 +1,24 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.dto; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + + +/** + * @author xiezw + * @date 2023-08-09 + **/ +@Data +public class RegionMonthConsumptionDTO { + + @Schema(description = "总量") + private BigDecimal totalValue; + + @Schema(description = "数据") + private List datas; + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionMonthEnergyConsumptionDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionMonthEnergyConsumptionDTO.java new file mode 100644 index 0000000..8af1130 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionMonthEnergyConsumptionDTO.java @@ -0,0 +1,29 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.dto; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + + +/** + * @author xiezw + * @date 2023-08-09 + **/ +@Data +public class RegionMonthEnergyConsumptionDTO { + + @Schema(description = "属性") + private String key; + + @Schema(description = "属性名称") + private String keyName; + + @Schema(description = "值") + private BigDecimal value; + + @Schema(description = "占比") + private String proportion; + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionNodeDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionNodeDTO.java new file mode 100644 index 0000000..6f73a73 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionNodeDTO.java @@ -0,0 +1,18 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.dto; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @author xzw + */ +@Data +public class RegionNodeDTO implements Serializable { + + private static final long serialVersionUID = 2846662403940590185L; + + private String name; + + private String id; +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionOrgConsumptionCompareDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionOrgConsumptionCompareDTO.java new file mode 100644 index 0000000..0e66b26 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionOrgConsumptionCompareDTO.java @@ -0,0 +1,38 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.dto; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + + +/** + * @author xiezw + * @date 2023-08-09 + **/ +@Data +public class RegionOrgConsumptionCompareDTO { + + @Schema(description = "当前时间") + private String currentDate; + @Schema(description = "当前总能耗") + private BigDecimal currentValue; + @Schema(description = "当前总能耗占比") + private String currentValueProportion; + + @Schema(description = "上期时间") + private String lastDate; + @Schema(description = "上期总能耗") + private BigDecimal lastValue; + @Schema(description = "上期总能耗占比") + private String lastValueProportion; + + @Schema(description = "上上期时间") + private String beforeLastDate; + @Schema(description = "上上期总能耗") + private BigDecimal beforeLastValue; + @Schema(description = "上上期总能耗占比") + private String beforeLastValueProportion; + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionSubNodeRespDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionSubNodeRespDTO.java new file mode 100644 index 0000000..77d8eda --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionSubNodeRespDTO.java @@ -0,0 +1,20 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.dto; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @author xzw + */ +@Data +public class RegionSubNodeRespDTO implements Serializable { + + private static final long serialVersionUID = 889248616749990247L; + + private List nodes; + + private List links; + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionTotalCarbonDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionTotalCarbonDTO.java new file mode 100644 index 0000000..d118bfa --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionTotalCarbonDTO.java @@ -0,0 +1,23 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.dto; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + + +/** + * @author xiezw + * @date 2023-08-09 + **/ +@Data +public class RegionTotalCarbonDTO { + + @Schema(description = "今年数据") + private List currentYearDatas; + + @Schema(description = "去年数据") + private List lastYearDatas; + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionTotalConsumptionAnalyseDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionTotalConsumptionAnalyseDTO.java new file mode 100644 index 0000000..7fdbaf3 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionTotalConsumptionAnalyseDTO.java @@ -0,0 +1,23 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.dto; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + + +/** + * @author xiezw + * @date 2023-08-09 + **/ +@Data +public class RegionTotalConsumptionAnalyseDTO { + + @Schema(description = "今年能耗及同比数据") + private List currentYearDatas; + + @Schema(description = "去年能耗数据") + private List lastYearDatas; + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionTotalDataDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionTotalDataDTO.java new file mode 100644 index 0000000..063f93c --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionTotalDataDTO.java @@ -0,0 +1,49 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.dto; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + + +/** + * @author xiezw + * @date 2023-08-09 + **/ +@Data +public class RegionTotalDataDTO { + + @Schema(description = "总能耗") + private BigDecimal totalConsumption; + + @Schema(description = "总碳排") + private BigDecimal totalCarbon; + + @Schema(description = "增加值能耗强度") + private BigDecimal consumptionIntensity; + + @Schema(description = "增加值碳排强度") + private BigDecimal carbonIntensity; + + @Schema(description = "接入单位数量") + private Integer orgCount; + +// public BigDecimal getTotalConsumption() { +// if (totalConsumption!=null){ +// return totalConsumption.divide(new BigDecimal(10000)).setScale(2, RoundingMode.HALF_UP); +// }else{ +// return totalConsumption; +// } +// } +// +// public BigDecimal getTotalCarbon() { +// if (totalCarbon!=null){ +// return totalCarbon.divide(new BigDecimal(10000)).setScale(2, RoundingMode.HALF_UP); +// }else{ +// return totalCarbon; +// } +// } + + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionUnitConsumptionDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionUnitConsumptionDTO.java new file mode 100644 index 0000000..1621132 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionUnitConsumptionDTO.java @@ -0,0 +1,32 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.dto; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; +import java.math.RoundingMode; + + +/** + * @author xiezw + * @date 2023-08-09 + **/ +@Data +public class RegionUnitConsumptionDTO { + + @Schema(description = "机构名称") + private String orgName; + + @Schema(description = "数据") + private BigDecimal value; + + public BigDecimal getValue() { + if (value!=null){ + return value.setScale(2, RoundingMode.HALF_UP); + }else{ + return value; + } + } + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionWarningCountDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionWarningCountDTO.java new file mode 100644 index 0000000..a72576d --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionWarningCountDTO.java @@ -0,0 +1,24 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.dto; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + + +/** + * @author xiezw + * @date 2023-08-09 + **/ +@Data +public class RegionWarningCountDTO { + + @Schema(description = "超限数量") + private Integer upLimitCount; + + @Schema(description = "正常数量") + private Integer normalCount; + + @Schema(description = "临限数量") + private Integer proLimitCount; + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionYearEnergyConsumptionAnalyseDTO.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionYearEnergyConsumptionAnalyseDTO.java new file mode 100644 index 0000000..3611caa --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/dto/RegionYearEnergyConsumptionAnalyseDTO.java @@ -0,0 +1,29 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.dto; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + + +/** + * @author xiezw + * @date 2023-08-09 + **/ +@Data +public class RegionYearEnergyConsumptionAnalyseDTO { + + @Schema(description = "日期") + private String date; + + @Schema(description = "能耗") + private BigDecimal value; + + @Schema(description = "目标") + private BigDecimal target; + + @Schema(description = "是否预警,0否,1是") + private String waring; + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/service/RegionBoardService.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/service/RegionBoardService.java new file mode 100644 index 0000000..6a957a0 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/service/RegionBoardService.java @@ -0,0 +1,33 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.service; + + +import com.thing.qingyuan.regionalenterprises.regionalboard.dto.*; + +import java.util.List; +import java.util.Map; + +/** + * 看板 + * + * @author wzf 56583086@qq.com + * @since 1.0.0 2020-09-27 + */ + +public interface RegionBoardService { + + List getTotalConsumptionTrend(Map params); + + RegionTotalCarbonDTO getTotalCarbonTrend(Map params); + + List getQuotaTypeConsumption(Map params); + + RegionTotalConsumptionAnalyseDTO getTotalConsumptionAnalyse(Map params); + + RegionSubNodeRespDTO getEnergyFlow(Map params); + + List getAreaEnergyData(Map params); + + RegionTotalDataDTO getTotalData(Map params); + + List getIndustryTypeCarbon(Map params); +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/service/RegionEnergyConsumptionReportService.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/service/RegionEnergyConsumptionReportService.java new file mode 100644 index 0000000..268c647 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/service/RegionEnergyConsumptionReportService.java @@ -0,0 +1,18 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.service; + + +import com.thing.qingyuan.regionalenterprises.regionalboard.dto.*; + +import java.util.List; +import java.util.Map; + +/** + * @author xzw + */ + +public interface RegionEnergyConsumptionReportService { + + List getBaseReportList(Map params); + + List getEnergyConsumptionList(Map params); +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/service/RegionEnergyWarningService.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/service/RegionEnergyWarningService.java new file mode 100644 index 0000000..345bba9 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/service/RegionEnergyWarningService.java @@ -0,0 +1,29 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.service; + + +import com.thing.qingyuan.regionalenterprises.regionalboard.dto.*; + +import java.util.List; +import java.util.Map; + +/** + * @author xzw + */ + +public interface RegionEnergyWarningService { + List getEnergyWarningList(Map params); + + List getRegionList(); + + List getIndustryList(); + + RegionMonthConsumptionDTO getMonthConsumptionProportion(Map params); + + List getYearConsumptionAnalyse(Map params); + + RegionTotalConsumptionAnalyseDTO getConsumptionAnalyse(Map params); + + RegionConsumptionTargetDTO getConsumptionAndTarget(Map params); + + RegionOrgConsumptionCompareDTO getOrgDataCompare(Map params); +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/service/impl/RegionBoardServiceImpl.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/service/impl/RegionBoardServiceImpl.java new file mode 100644 index 0000000..cd0e6a9 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/service/impl/RegionBoardServiceImpl.java @@ -0,0 +1,671 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.service.impl; + + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import com.github.xiaoymin.knife4j.core.util.CollectionUtils; +import com.thing.carbon.config.dto.CarbonEnergyVarietyDTO; +import com.thing.carbon.config.service.CarbonEnergyVarietyService; +import com.thing.qingyuan.regionalenterprises.consumptionTarget.service.IotValueAddedService; +import com.thing.qingyuan.regionalenterprises.regionalboard.dto.*; +import com.thing.qingyuan.regionalenterprises.regionalboard.service.RegionBoardService; +import com.thing.common.core.utils.DateTimeUtils; +import com.thing.common.core.web.response.PageData; +import com.thing.common.data.tskv.TsKvDTO; +import com.thing.common.tskv.service.TsKvService; +import com.thing.sys.biz.dto.SysRegionDTO; +import com.thing.sys.biz.service.SysIndustryTypeService; +import com.thing.sys.biz.service.SysRegionService; +import com.thing.sys.security.context.TenantContext; +import com.thing.sys.security.domain.SecurityUser; +import com.thing.sys.security.domain.UserDetail; +import com.thing.sys.tenant.dto.RegionIndustryTenantInfoDTO; +import com.thing.sys.tenant.service.SysTenantService; +import com.thing.thing.dict.dto.IotThingDictDTO; +import com.thing.thing.dict.service.IotThingDictService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 昆山公共机构看板 + * + * @author xiezw + * @since 2023-08-08 + */ +@Service +public class RegionBoardServiceImpl implements RegionBoardService { + +// @Autowired +// private CarbonEnergyDictRelationService carbonEnergyDictRelationService; + + @Autowired + private SysRegionService sysRegionService; + + @Autowired + private SysTenantService sysTenantService; + + @Autowired + private SysIndustryTypeService sysIndustryTypeService; + + @Autowired + private TsKvService tsKvService; + + @Autowired + private IotThingDictService iotThingDictService; + + @Autowired + private IotValueAddedService iotValueAddedService; + + @Autowired + private CarbonEnergyVarietyService carbonEnergyVarietyService; + + + + + @Override + public List getTotalConsumptionTrend(Map params) { + List result = new ArrayList<>(); + UserDetail userDetail = SecurityUser.getUser(); + Long tenantCode = TenantContext.getTenantCode(userDetail); + String year; + if (params!=null && ObjectUtil.isNotEmpty(params.get("year"))){ + year = params.get("year").toString(); + }else{ + year = DateTimeUtils.getCurrentYear(); + } + Long yearStartTime = DateTimeUtils.dateToTimestamp(year+"-01-01 00:00:00"); + Long yearEndTime = DateTimeUtils.dateToTimestamp(year+"-12-01 00:00:00"); + //获取属性 + Map newParams = new HashMap<>(); + newParams.put("page",1); + newParams.put("limit",100); +// newParams.put("attrType","base"); +// PageData page = carbonEnergyDictRelationService.handlePage(newParams); +// List list = page.getList(); + //获取基础能源品种 + PageData page = carbonEnergyVarietyService.pageCarbonEnergyVarietyDTO(params); + List list = page.getList(); + List keys = list.stream().map(item -> "tce_"+item.getCode()+"mm").collect(Collectors.toList()); + List thingCodes = sysTenantService.getThingCodesByTenantCode(tenantCode); + Map> codeAndKeyMap = new HashMap<>(); + if (CollectionUtil.isEmpty(thingCodes)){ + return result; + } + for (String code:thingCodes){ + codeAndKeyMap.put(code,keys); + } + + //获取数据,并以属性分组 + Map> dataMap = new HashMap<>(); + List dataList = tsKvService.findTsKvByMultiMap(codeAndKeyMap,yearStartTime-1000L,yearEndTime+1000L,Boolean.FALSE); + dataMap = dataList.stream().collect(Collectors.groupingBy(TsKvDTO::getAttrKey)); + //拆分月份 + List monthList = DateTimeUtils.getMonthList(year); + + for (CarbonEnergyVarietyDTO energyVarietyDTO:list){ + RegionConsumptionDTO regionConsumptionDTO = new RegionConsumptionDTO(); + regionConsumptionDTO.setKey(energyVarietyDTO.getCode()); + regionConsumptionDTO.setKeyName(energyVarietyDTO.getName()); + List datas = dataMap.get("tce_"+energyVarietyDTO.getCode()+"mm"); + Map tsSumValueMap = new HashMap<>(); + if (CollectionUtil.isNotEmpty(datas)){ + //以ts分组,并合计用量 + tsSumValueMap = datas.stream().filter(dto -> dto.getVal() != null) + .collect(Collectors.groupingBy(TsKvDTO::getTs, Collectors.mapping(TsKvDTO::getVal, + Collectors.reducing(BigDecimal.ZERO, BigDecimal::new, BigDecimal::add)))); + } + List dataResults = new ArrayList<>(); + for (String month:monthList){ + Long monthTs = DateTimeUtils.dateToTimestamp(month+"-01 00:00:00"); + RegionEnergyConsumptionDTO energyConsumptionDTO = new RegionEnergyConsumptionDTO(); + energyConsumptionDTO.setDate(month); + if (CollectionUtil.isNotEmpty(tsSumValueMap)){ + if (tsSumValueMap.get(monthTs)!=null){ + energyConsumptionDTO.setValue(tsSumValueMap.get(monthTs)); + } + } + //把数据再以时间分组,获取该时间的汇总值,赋值 + dataResults.add(energyConsumptionDTO); + } + regionConsumptionDTO.setDatas(dataResults); + result.add(regionConsumptionDTO); + } + return result; + } + + @Override + public RegionTotalCarbonDTO getTotalCarbonTrend(Map params) { + RegionTotalCarbonDTO result = new RegionTotalCarbonDTO(); + UserDetail userDetail = SecurityUser.getUser(); + Long tenantCode = TenantContext.getTenantCode(userDetail); + String year; + if (params!=null && ObjectUtil.isNotEmpty(params.get("year"))){ + year = params.get("year").toString(); + }else{ + year = DateTimeUtils.getCurrentYear(); + } + //今年月份 + List currentMonths = DateTimeUtils.getMonthList(year); + String lastYear = String.valueOf(Integer.parseInt(year)-1); + //去年月份 + List lastMonths = DateTimeUtils.getMonthList(lastYear); + Long lastYearStartTime = DateTimeUtils.dateToTimestamp(lastYear+"-01-01 00:00:00"); + Long currentYearEndTime = DateTimeUtils.dateToTimestamp(year+"-12-01 00:00:00"); + List keys = new ArrayList<>(); + keys.add("CO2_runmm"); + List thingCodes = sysTenantService.getThingCodesByTenantCode(tenantCode); + if (CollectionUtil.isEmpty(thingCodes)){ + return result; + } + Map> codeAndKeyMap = new HashMap<>(); + for (String code:thingCodes){ + codeAndKeyMap.put(code,keys); + } + + //获取数据,并以时间分组求和 + List dataList = tsKvService.findTsKvByMultiMap(codeAndKeyMap,lastYearStartTime-1000L,currentYearEndTime+1000L,Boolean.FALSE); + Map dataResult = new HashMap<>(); + if (CollectionUtil.isNotEmpty(dataList)){ + dataResult = dataList.stream().filter(dto -> dto.getVal() != null) + .collect(Collectors.groupingBy(TsKvDTO::getTs, Collectors.mapping(TsKvDTO::getVal, + Collectors.reducing(BigDecimal.ZERO, BigDecimal::new, BigDecimal::add)))); + } + List currentYearDatas = new ArrayList<>(); + List lastYearDatas = new ArrayList<>(); + for (String month : currentMonths){ + Long monthTs = DateTimeUtils.dateToTimestamp(month+"-01 00:00:00"); + RegionEnergyConsumptionDTO energyConsumptionDTO = new RegionEnergyConsumptionDTO(); + energyConsumptionDTO.setDate(month); + if (dataResult!=null && dataResult.get(monthTs)!=null){ + BigDecimal value = dataResult.get(monthTs); + energyConsumptionDTO.setValue(value); + } + currentYearDatas.add(energyConsumptionDTO); + } + for (String month : lastMonths){ + Long monthTs = DateTimeUtils.dateToTimestamp(month+"-01 00:00:00"); + RegionEnergyConsumptionDTO energyConsumptionDTO = new RegionEnergyConsumptionDTO(); + energyConsumptionDTO.setDate(month); + if (dataResult!=null && dataResult.get(monthTs)!=null){ + BigDecimal value = dataResult.get(monthTs); + energyConsumptionDTO.setValue(value); + } + lastYearDatas.add(energyConsumptionDTO); + } + result.setCurrentYearDatas(currentYearDatas); + result.setLastYearDatas(lastYearDatas); + return result; + } + + @Override + public List getQuotaTypeConsumption(Map params) { + List result = new ArrayList<>(); + UserDetail userDetail = SecurityUser.getUser(); + Long tenantCode = TenantContext.getTenantCode(userDetail); + + String year; + if (params!=null && ObjectUtil.isNotEmpty(params.get("year"))){ + year = params.get("year").toString(); + }else{ + year = DateTimeUtils.getCurrentYear(); + } + Long currentYearTime = DateTimeUtils.dateToTimestamp(year+"-01-01 00:00:00"); + + //获取属性 + Map newParams = new HashMap<>(); + newParams.put("page",1); + newParams.put("limit",100); +// newParams.put("attrType","base"); +// //获取基础能源品种 +// PageData page = carbonEnergyDictRelationService.handlePage(newParams); +// List list = page.getList(); + PageData page = carbonEnergyVarietyService.pageCarbonEnergyVarietyDTO(params); + List list = page.getList(); + List keys = new ArrayList<>(); + keys.add("tce_runyy"); + Map keyMap = new HashMap<>(); + keyMap.put("tce_runyy","能耗总量"); + if (CollectionUtil.isNotEmpty(list)){ + for (CarbonEnergyVarietyDTO dictRelationDTO:list){ + String key = dictRelationDTO.getCode()+"yy"; + keys.add(key); + keyMap.put(key,dictRelationDTO.getName()); + } + } + //获取所有企业的thing_code,行业门类,行业大类,区域 + List industryTenantInfoDTOS = sysTenantService.getByGroupTenantCode(tenantCode); + //根据行业分组,获取行业thingCode + Map> industryTypeMap = industryTenantInfoDTOS.stream() + .collect(Collectors.groupingBy(RegionIndustryTenantInfoDTO::getIndustryCategory, + Collectors.mapping(RegionIndustryTenantInfoDTO::getThingCode, Collectors.toList()))); + for (Map.Entry> mapEntry : industryTypeMap.entrySet()) { + RegionIndustryDTO regionIndustryDTO = new RegionIndustryDTO(); + regionIndustryDTO.setIndustryCode(mapEntry.getKey()); + String industryName = sysIndustryTypeService.getByCode(mapEntry.getKey()); + regionIndustryDTO.setIndustryName(industryName); + + List thingCodes = mapEntry.getValue(); + Map> codeAndKeyMap = new HashMap<>(); + for (String thingCode:thingCodes){ + codeAndKeyMap.put(thingCode,keys); + } + //获取数据,以属性分组求和 + List dataList = tsKvService.findTsKvByMultiMap(codeAndKeyMap,currentYearTime-1000L,currentYearTime+1000L,Boolean.FALSE); + Map dataResult = dataList.stream().filter(dto -> dto.getVal() != null) + .collect(Collectors.groupingBy(TsKvDTO::getAttrKey, Collectors.mapping(TsKvDTO::getVal, + Collectors.reducing(BigDecimal.ZERO, BigDecimal::new, BigDecimal::add)))); + Map valueMap = new HashMap<>(); + if (dataResult!=null){ + for (Map.Entry dataMapEntry : dataResult.entrySet()) { + String keyName=dataMapEntry.getKey(); + if (keyMap!=null && ObjectUtil.isNotEmpty(keyMap.get(dataMapEntry.getKey()))){ + keyName = keyMap.get(dataMapEntry.getKey()); + } + if (dataMapEntry.getKey().equals("A29yy")){ + valueMap.put(keyName,dataMapEntry.getValue().divide(new BigDecimal(10000))); + }else{ + valueMap.put(keyName,dataMapEntry.getValue()); + } + } + } + regionIndustryDTO.setValueMap(valueMap); + result.add(regionIndustryDTO); + } + return result; + } + + @Override + public List getIndustryTypeCarbon(Map params) { + List result = new ArrayList<>(); + UserDetail userDetail = SecurityUser.getUser(); + Long tenantCode = TenantContext.getTenantCode(userDetail); + + String year; + if (params!=null && ObjectUtil.isNotEmpty(params.get("year"))){ + year = params.get("year").toString(); + }else{ + year = DateTimeUtils.getCurrentYear(); + } + Long currentYearTime = DateTimeUtils.dateToTimestamp(year+"-01-01 00:00:00"); + + List keys = new ArrayList<>(); + keys.add("CO2_runyy"); + //获取所有企业的thing_code,行业门类,行业大类,区域 + List industryTenantInfoDTOS = sysTenantService.getByGroupTenantCode(tenantCode); + //根据行业分组,获取行业thingCode + Map> industryTypeMap = industryTenantInfoDTOS.stream() + .collect(Collectors.groupingBy(RegionIndustryTenantInfoDTO::getIndustryCategory, + Collectors.mapping(RegionIndustryTenantInfoDTO::getThingCode, Collectors.toList()))); + BigDecimal totalCatbon =null; + for (Map.Entry> mapEntry : industryTypeMap.entrySet()) { + RegionIndustryCarbonDTO industryCarbonDTO = new RegionIndustryCarbonDTO(); + industryCarbonDTO.setIndustryCode(mapEntry.getKey()); + String industryName = sysIndustryTypeService.getByCode(mapEntry.getKey()); + industryCarbonDTO.setIndustryName(industryName); + + List thingCodes = mapEntry.getValue(); + Map> codeAndKeyMap = new HashMap<>(); + for (String thingCode:thingCodes){ + codeAndKeyMap.put(thingCode.toString(),keys); + } + //获取数据,以属性分组求和 + List dataList = tsKvService.findTsKvByMultiMap(codeAndKeyMap,currentYearTime-1000L,currentYearTime+1000L,Boolean.FALSE); + BigDecimal totalValue = null; + if (CollectionUtil.isNotEmpty(dataList)){ + totalValue = dataList.stream() + .filter(dto -> dto.getVal() != null) + .map(dto -> new BigDecimal(dto.getVal())) + .reduce(BigDecimal.ZERO, BigDecimal::add); + } + industryCarbonDTO.setValue(totalValue); + if (totalValue!=null){ + totalCatbon= totalCatbon==null?BigDecimal.ZERO.add(totalValue):totalCatbon.add(totalValue); + } + result.add(industryCarbonDTO); + } + if (CollectionUtil.isNotEmpty(result) && totalCatbon!=null && totalCatbon.compareTo(BigDecimal.ZERO)!=0){ + for (RegionIndustryCarbonDTO carbonDTO:result){ + if (carbonDTO.getValue()!=null){ + carbonDTO.setProportion(carbonDTO.getValue().divide(totalCatbon,2,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100))+"%"); + } + } + } + return result; + } + + @Override + public RegionTotalConsumptionAnalyseDTO getTotalConsumptionAnalyse(Map params) { + RegionTotalConsumptionAnalyseDTO result = new RegionTotalConsumptionAnalyseDTO(); + UserDetail userDetail = SecurityUser.getUser(); + Long tenantCode = TenantContext.getTenantCode(userDetail); + String year; + if (params!=null && ObjectUtil.isNotEmpty(params.get("year"))){ + year = params.get("year").toString(); + }else{ + year = DateTimeUtils.getCurrentYear(); + } + //今年月份 + List currentMonths = DateTimeUtils.getMonthList(year); + String lastYear = String.valueOf(Integer.parseInt(year)-1); + //去年月份 + List lastMonths = DateTimeUtils.getMonthList(lastYear); + Long lastYearStartTime = DateTimeUtils.dateToTimestamp(lastYear+"-01-01 00:00:00"); + Long currentYearEndTime = DateTimeUtils.dateToTimestamp(year+"-12-01 00:00:00"); + List keys = new ArrayList<>(); + keys.add("tce_runmm"); + List thingCodes = sysTenantService.getThingCodesByTenantCode(tenantCode); + if (CollectionUtil.isEmpty(thingCodes)){ + return result; + } + Map> codeAndKeyMap = new HashMap<>(); + for (String code:thingCodes){ + codeAndKeyMap.put(code,keys); + } + + //获取数据,并以时间分组求和 + List dataList = tsKvService.findTsKvByMultiMap(codeAndKeyMap,lastYearStartTime-1000L,currentYearEndTime+1000L,Boolean.FALSE); + Map dataResult = new HashMap<>(); + if (CollectionUtil.isNotEmpty(dataList)){ + dataResult = dataList.stream().filter(dto -> dto.getVal() != null) + .collect(Collectors.groupingBy(TsKvDTO::getTs, Collectors.mapping(TsKvDTO::getVal, + Collectors.reducing(BigDecimal.ZERO, BigDecimal::new, BigDecimal::add)))); + } + + List currentYearDatas = new ArrayList<>(); + List lastYearDatas = new ArrayList<>(); + Map lastYearData = new HashMap<>(); + for (String month : lastMonths){ + RegionEnergyConsumptionDTO energyConsumptionDTO = new RegionEnergyConsumptionDTO(); + energyConsumptionDTO.setDate(month); + Long monthTs = DateTimeUtils.dateToTimestamp(month+"-01 00:00:00"); + BigDecimal value =null; + if (dataResult!=null && dataResult.get(monthTs)!=null){ + value = dataResult.get(monthTs); + energyConsumptionDTO.setValue(value); + } + lastYearData.put(month.substring(5),value); + lastYearDatas.add(energyConsumptionDTO); + } + for (String month : currentMonths){ + RegionEnergyConsumptionAnalyseDTO energyConsumptionDTO = new RegionEnergyConsumptionAnalyseDTO(); + energyConsumptionDTO.setDate(month); + Long monthTs = DateTimeUtils.dateToTimestamp(month+"-01 00:00:00"); + BigDecimal value = null; + if (dataResult!=null && dataResult.get(monthTs)!=null){ + value = dataResult.get(monthTs); + energyConsumptionDTO.setValue(value); + } + energyConsumptionDTO.setValue(value); + //计算同比 + if (value!=null && lastYearData!=null && lastYearData.get(month.substring(5))!=null && lastYearData.get(month.substring(5)).compareTo(BigDecimal.ZERO)!=0){ + BigDecimal lastValue = lastYearData.get(month.substring(5)); + BigDecimal yearOnYearGrowthRate = (value.subtract(lastValue)).divide(lastValue, 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100")); + energyConsumptionDTO.setYoy(yearOnYearGrowthRate+"%"); + //大于0上升,小于0下降 + if (yearOnYearGrowthRate.compareTo(BigDecimal.ZERO)==1){ + energyConsumptionDTO.setUpOrDown(1); + }else if (yearOnYearGrowthRate.compareTo(BigDecimal.ZERO)==-1){ + energyConsumptionDTO.setUpOrDown(0); + } + } + currentYearDatas.add(energyConsumptionDTO); + } + result.setCurrentYearDatas(currentYearDatas); + result.setLastYearDatas(lastYearDatas); + return result; + } + + @Override + public RegionSubNodeRespDTO getEnergyFlow(Map params) { + RegionSubNodeRespDTO result = new RegionSubNodeRespDTO(); + UserDetail userDetail = SecurityUser.getUser(); + Long tenantCode = TenantContext.getTenantCode(userDetail); + + String year; + if (params!=null && ObjectUtil.isNotEmpty(params.get("year"))){ + year = params.get("year").toString(); + }else{ + year = DateTimeUtils.getCurrentYear(); + } + Long currentYearTime = DateTimeUtils.dateToTimestamp(year+"-01-01 00:00:00"); + + List nodes = new ArrayList<>(); + + List links = new ArrayList<>(); + //获取属性 + Map newParams = new HashMap<>(); + newParams.put("page",1); + newParams.put("limit",100); +// newParams.put("attrType","base"); +// //获取基础能源品种 +// PageData page = carbonEnergyDictRelationService.handlePage(newParams); +// List list = page.getList(); + + PageData page = carbonEnergyVarietyService.pageCarbonEnergyVarietyDTO(params); + List list = page.getList(); + List keys = new ArrayList<>(); + for (CarbonEnergyVarietyDTO dictRelationDTO : list){ + RegionNodeDTO publicNodeDTO = new RegionNodeDTO(); + publicNodeDTO.setId(dictRelationDTO.getCode()+"yy"); + publicNodeDTO.setName(dictRelationDTO.getName()); + nodes.add(publicNodeDTO); + keys.add(dictRelationDTO.getCode()+"yy"); + } + + //获取所有企业的thing_code,行业门类,行业大类,区域 + List industryTenantInfoDTOS = sysTenantService.getByGroupTenantCode(tenantCode); + Map> codeAndKeyMap1 = new HashMap<>(); + for (RegionIndustryTenantInfoDTO tenantInfoDTO:industryTenantInfoDTOS){ + codeAndKeyMap1.put(tenantInfoDTO.getThingCode(),keys); + } + //获取所有企业总数据,并以属性分组合计 + List dataList1 = tsKvService.findTsKvByMultiMap(codeAndKeyMap1,currentYearTime-1000L,currentYearTime+1000L,Boolean.FALSE); + Map dataResult1 = null; + if (CollectionUtil.isNotEmpty(dataList1)){ + dataResult1 = dataList1.stream().filter(dto -> dto.getVal() != null) + .collect(Collectors.groupingBy(TsKvDTO::getAttrKey, Collectors.mapping(TsKvDTO::getVal, + Collectors.reducing(BigDecimal.ZERO, BigDecimal::new, BigDecimal::add)))); + } + + //获取属性的单位 + Map dictMap = new HashMap<>(); + /* List dictDTOList = iotThingDictService.getIotEntityDictDTOList("attr",keys); + if (CollectionUtils.isNotEmpty(dictDTOList)){ + for (IotThingDictDTO dictDTO:dictDTOList){ + dictMap.put(dictDTO.getCode(),dictDTO.getUnit()); + } + }*/ + + //根据行业分组,获取行业thingCode + Map> industryTypeMap = industryTenantInfoDTOS.stream() + .collect(Collectors.groupingBy(RegionIndustryTenantInfoDTO::getIndustryCategory, + Collectors.mapping(RegionIndustryTenantInfoDTO::getThingCode, Collectors.toList()))); + + Integer Id = 1; + //先遍历行业 + for (Map.Entry> entry : industryTypeMap.entrySet()){ + RegionNodeDTO publicNodeDTO = new RegionNodeDTO(); + publicNodeDTO.setId(Id.toString()); + String industryName = sysIndustryTypeService.getByCode(entry.getKey()); + publicNodeDTO.setName(industryName); + Map> codeAndKeyMap = new HashMap<>(); + for (String code:entry.getValue()){ + codeAndKeyMap.put(code,keys); + } + //获取数据,并以属性分组 + List dataList = tsKvService.findTsKvByMultiMap(codeAndKeyMap,currentYearTime-1000L,currentYearTime+1000L,Boolean.FALSE); + Map dataResult = null; + if (CollectionUtil.isNotEmpty(dataList)){ + dataResult = dataList.stream().filter(dto -> dto.getVal() != null) + .collect(Collectors.groupingBy(TsKvDTO::getAttrKey, Collectors.mapping(TsKvDTO::getVal, + Collectors.reducing(BigDecimal.ZERO, BigDecimal::new, BigDecimal::add)))); + } + if (dataResult!=null){ + for (Map.Entry entry1 : dataResult.entrySet()){ + RegionLinkDTO publicLinkDTO = new RegionLinkDTO(); + publicLinkDTO.setSource(entry1.getKey()); + publicLinkDTO.setTarget(Id.toString()); + BigDecimal value = entry1.getValue(); + publicLinkDTO.setValue(value); + if (dataResult1!=null && dataResult1.get(entry1.getKey())!=null){ + BigDecimal totalValue = dataResult1.get(entry1.getKey()); + if (value!=null && totalValue!=null && totalValue.compareTo(BigDecimal.ZERO)!=0){ + BigDecimal proportion = value.divide(totalValue,2,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)); + publicLinkDTO.setProportion(proportion+"%"); + } + } + if (dictMap!=null && dictMap.get(entry1.getKey())!=null){ + publicLinkDTO.setUnit(dictMap.get(entry1.getKey())); + } + links.add(publicLinkDTO); + } + } + nodes.add(publicNodeDTO); + Id++; + } + result.setNodes(nodes); + result.setLinks(links); + return result; + } + + + + @Override + public List getAreaEnergyData(Map params) { + + List result = new ArrayList<>(); + UserDetail userDetail = SecurityUser.getUser(); + Long tenantCode = TenantContext.getTenantCode(userDetail); + + String year; + if (params!=null && ObjectUtil.isNotEmpty(params.get("year"))){ + year = params.get("year").toString(); + }else{ + year = DateTimeUtils.getCurrentYear(); + } + Long currentYearTime = DateTimeUtils.dateToTimestamp(year+"-01-01 00:00:00"); + List keys = new ArrayList<>(); + keys.add("tce_runyy"); + keys.add("CO2_runyy"); + //获取所有企业的thing_code,行业门类,行业大类,区域 + List industryTenantInfoDTOS = sysTenantService.getByGroupTenantCode(tenantCode); + + if (CollectionUtil.isEmpty(industryTenantInfoDTOS)){ + return result; + } + //根据区域分组,获取行业thingCode + Map> industryTypeMap = industryTenantInfoDTOS.stream() + .collect(Collectors.groupingBy(RegionIndustryTenantInfoDTO::getRegionCode, + Collectors.mapping(RegionIndustryTenantInfoDTO::getThingCode, Collectors.toList()))); + Map pidParams = new HashMap<>(); + pidParams.put("pid","320581"); + //获取区域 + List list = sysRegionService.list(pidParams); + if (CollectionUtil.isNotEmpty(list)){ + for (SysRegionDTO sysRegionDTO: list){ + RegionAreaConsumptionDTO areaConsumptionDTO = new RegionAreaConsumptionDTO(); + areaConsumptionDTO.setRegionCode(sysRegionDTO.getId()); + areaConsumptionDTO.setRegionName(sysRegionDTO.getName()); + List thingCodes = industryTypeMap.get(sysRegionDTO.getId()); + Map> codeAndKeyMap1 = new HashMap<>(); + if (CollectionUtil.isNotEmpty(thingCodes)){ + areaConsumptionDTO.setOrgCount(thingCodes.size()); + for (String code:thingCodes){ + codeAndKeyMap1.put(code,keys); + } + }else{ + areaConsumptionDTO.setOrgCount(0); + } + List dataList1 = null; + //获取区域企业数据,并以属性分组合计 + if (codeAndKeyMap1!=null){ + dataList1 = tsKvService.findTsKvByMultiMap(codeAndKeyMap1,currentYearTime-1000L,currentYearTime+1000L,Boolean.FALSE); + } + Map dataResult1 = null; + if (CollectionUtil.isNotEmpty(dataList1)){ + dataResult1 = dataList1.stream().filter(dto -> dto.getVal() != null) + .collect(Collectors.groupingBy(TsKvDTO::getAttrKey, Collectors.mapping(TsKvDTO::getVal, + Collectors.reducing(BigDecimal.ZERO, BigDecimal::new, BigDecimal::add)))); + } + if (dataResult1!=null){ + if (ObjectUtil.isNotEmpty(dataResult1.get("tce_runyy"))){ + areaConsumptionDTO.setTotalConsumption(dataResult1.get("tce_runyy")); + } + if (ObjectUtil.isNotEmpty(dataResult1.get("CO2_runyy"))){ + areaConsumptionDTO.setTotalCarbon(dataResult1.get("CO2_runyy")); + } + } + result.add(areaConsumptionDTO); + } + } + return result; + } + + @Override + public RegionTotalDataDTO getTotalData(Map params) { + RegionTotalDataDTO result = new RegionTotalDataDTO(); + UserDetail userDetail = SecurityUser.getUser(); + Long tenantCode = TenantContext.getTenantCode(userDetail); + + String year; + if (params!=null && ObjectUtil.isNotEmpty(params.get("year"))){ + year = params.get("year").toString(); + }else{ + year = DateTimeUtils.getCurrentYear(); + } + Long currentYearTime = DateTimeUtils.dateToTimestamp(year+"-01-01 00:00:00"); + List keys = new ArrayList<>(); + keys.add("tce_runyy"); + keys.add("CO2_runyy"); + //获取所有企业的thing_code,行业门类,行业大类,区域 + List industryTenantInfoDTOS = sysTenantService.getByGroupTenantCode(tenantCode); + result.setOrgCount(industryTenantInfoDTOS.size()); + List tenantCodes = new ArrayList<>(); + Map> codeAndKeyMap1 = new HashMap<>(); + for (RegionIndustryTenantInfoDTO tenantInfoDTO:industryTenantInfoDTOS){ + codeAndKeyMap1.put(tenantInfoDTO.getThingCode(),keys); + tenantCodes.add(tenantInfoDTO.getTenantCode()); + } + //获取所有企业总数据,并以属性分组合计 + List dataList1 = tsKvService.findTsKvByMultiMap(codeAndKeyMap1,currentYearTime-1000L,currentYearTime+1000L,Boolean.FALSE); + Map dataResult1 = null; + if (CollectionUtil.isNotEmpty(dataList1)){ + dataResult1 = dataList1.stream().filter(dto -> dto.getVal() != null) + .collect(Collectors.groupingBy(TsKvDTO::getAttrKey, Collectors.mapping(TsKvDTO::getVal, + Collectors.reducing(BigDecimal.ZERO, BigDecimal::new, BigDecimal::add)))); + } + BigDecimal totalConsumption = null; + BigDecimal totalCarbon = null; + if (dataResult1!=null){ + if (ObjectUtil.isNotEmpty(dataResult1.get("tce_runyy"))){ + totalConsumption = dataResult1.get("tce_runyy"); + result.setTotalConsumption(totalConsumption); + } + if (ObjectUtil.isNotEmpty(dataResult1.get("CO2_runyy"))){ + totalCarbon = dataResult1.get("CO2_runyy"); + result.setTotalCarbon(totalCarbon); + } + } + //获取企业总增加值 + BigDecimal addValue = null; + if (CollectionUtil.isNotEmpty(tenantCodes)){ + addValue =iotValueAddedService.getSumValueByTenantCodesAndYear(tenantCodes,year); + } + if (addValue!=null && addValue.compareTo(BigDecimal.ZERO)!=0 ){ + if (totalConsumption!=null ){ + BigDecimal consumptionIntensity = totalConsumption.divide(addValue,2,BigDecimal.ROUND_HALF_UP); + result.setConsumptionIntensity(consumptionIntensity); + } + if (totalCarbon!=null ){ + BigDecimal carbonIntensity = totalCarbon.divide(addValue,2,BigDecimal.ROUND_HALF_UP); + result.setCarbonIntensity(carbonIntensity); + } + } + return result; + } + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/service/impl/RegionEnergyConsumptionReportServiceImpl.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/service/impl/RegionEnergyConsumptionReportServiceImpl.java new file mode 100644 index 0000000..c6c68bf --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/service/impl/RegionEnergyConsumptionReportServiceImpl.java @@ -0,0 +1,530 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import com.github.xiaoymin.knife4j.core.util.CollectionUtils; +import com.thing.carbon.config.dto.CarbonEnergyDictRelationDTO; +import com.thing.carbon.config.dto.CarbonEnergyVarietyDTO; +import com.thing.carbon.config.service.CarbonEnergyDictRelationService; +import com.thing.carbon.config.service.CarbonEnergyVarietyService; +import com.thing.qingyuan.regionalenterprises.consumptionTarget.service.IotEnergyConsumptionTargetService; +import com.thing.qingyuan.regionalenterprises.regionalboard.dto.*; +import com.thing.qingyuan.regionalenterprises.regionalboard.service.RegionEnergyConsumptionReportService; +import com.thing.common.core.utils.DateTimeUtils; +import com.thing.common.core.web.response.PageData; +import com.thing.common.data.tskv.TsKvDTO; +import com.thing.common.tskv.service.TsKvService; +import com.thing.sys.biz.dto.SysRegionDTO; +import com.thing.sys.biz.service.SysIndustryTypeService; +import com.thing.sys.biz.service.SysRegionService; +import com.thing.sys.security.context.TenantContext; +import com.thing.sys.security.domain.SecurityUser; +import com.thing.sys.security.domain.UserDetail; +import com.thing.sys.tenant.dto.RegionIndustryTenantInfoDTO; +import com.thing.sys.tenant.service.SysTenantService; +import com.thing.thing.dict.dto.IotThingDictDTO; +import com.thing.thing.dict.service.IotThingDictService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 昆山用能预警 + * + * @author xiezw + * @since 2023-08-08 + */ +@Service +public class RegionEnergyConsumptionReportServiceImpl implements RegionEnergyConsumptionReportService { + + @Autowired + private SysTenantService sysTenantService; + @Autowired + private SysRegionService sysRegionService; + @Autowired + private TsKvService tsKvService; + @Autowired + private SysIndustryTypeService sysIndustryTypeService; + @Autowired + private IotEnergyConsumptionTargetService iotEnergyConsumptionTargetService; + @Autowired + private CarbonEnergyDictRelationService carbonEnergyDictRelationService; + + @Autowired + private CarbonEnergyVarietyService carbonEnergyVarietyService; + + @Autowired + private IotThingDictService iotThingDictService; + + @Override + public List getBaseReportList(Map params) { + List result = new ArrayList<>(); + UserDetail userDetail = SecurityUser.getUser(); + Long tenantCode = TenantContext.getTenantCode(userDetail); + params.put("tenantCode",tenantCode); + + String originalDate = null; + String originalLastDate =null; + + String date = null; + String lastDate =null; + Long currentDateTime =null; + Long lastDateTime =null; + Integer dateType = null; + if (params!=null && ObjectUtil.isNotEmpty(params.get("dateType"))){ + dateType = Integer.valueOf(params.get("dateType").toString()); + date = params.get("date").toString(); + originalDate = params.get("date").toString(); + //年 + if (params.get("dateType").equals("0")){ + date = date+"-01-01 00:00:00"; + //上年时间 + lastDate = Integer.valueOf(originalDate)-1+"-01-01 00:00:00"; + originalLastDate =String.valueOf(Integer.valueOf(originalDate)-1); + }else{ + //月 + date = date+"-01 00:00:00"; + //上月时间 + lastDate = DateTimeUtils.getLastMonth(originalDate)+"-01 00:00:00"; + originalLastDate = DateTimeUtils.getLastMonth(originalDate); + } + currentDateTime = DateTimeUtils.dateToTimestamp(date); + lastDateTime = DateTimeUtils.dateToTimestamp(lastDate); + } + //今年,年月 + String year = date.substring(0,4); + String month = String.valueOf(Integer.valueOf(date.substring(5,7))); + String lastYear =null; + String lastMonthYear =null; + String lastMonth = null; + //年只取上一年 + if (dateType==0){ + lastYear = originalLastDate.substring(0,4); + }else{ + //月取,上个月的,年和月 + lastMonthYear = originalLastDate.substring(0,4); + lastMonth = String.valueOf(Integer.valueOf(originalLastDate.substring(5,7))); + } + + Map regionMap = new HashMap<>(); + Map pidParams = new HashMap<>(); + pidParams.put("pid","320581"); + //获取区域 + List list = sysRegionService.list(pidParams); + if (CollectionUtil.isNotEmpty(list)){ + for (SysRegionDTO sysRegionDTO:list){ + regionMap.put(sysRegionDTO.getId(),sysRegionDTO.getName()); + } + } + + List keys = new ArrayList<>(); + if (dateType==0){ + keys.add("tce_runyy"); + keys.add("CO2_runyy"); + }else{ + keys.add("tce_runmm"); + keys.add("CO2_runmm"); + } + //获取企业的thing_code,行业门类,行业大类,区域 + List industryTenantInfoDTOS = sysTenantService.getTenantListByParams(params); + if (CollectionUtil.isEmpty(industryTenantInfoDTOS)){ + return result; + } + Map> codeAndKeyMap = new HashMap<>(); + for (RegionIndustryTenantInfoDTO tenantInfoDTO:industryTenantInfoDTOS){ + codeAndKeyMap.put(tenantInfoDTO.getThingCode(),keys); + } + //获取企业数据,并以thing_code分组 + List dataList = tsKvService.findTsKvByMultiMap(codeAndKeyMap,lastDateTime-1000L,currentDateTime+1000L,Boolean.FALSE); + Map> dataResult = null; + if (CollectionUtil.isNotEmpty(dataList)){ + dataResult = dataList.stream().collect(Collectors.groupingBy(TsKvDTO::getThingCode)); + } + for (RegionIndustryTenantInfoDTO infoDTO:industryTenantInfoDTOS){ + RegionEnergyBaseReportDTO baseReportDTO = new RegionEnergyBaseReportDTO(); + baseReportDTO.setOrgName(infoDTO.getTenantName()); + baseReportDTO.setTenantCode(infoDTO.getTenantCode()); + baseReportDTO.setRegionCode(infoDTO.getRegionCode()); + baseReportDTO.setThingCode(infoDTO.getThingCode()); + if (regionMap!=null && ObjectUtil.isNotEmpty(regionMap.get(infoDTO.getRegionCode()))){ + baseReportDTO.setRegionName(regionMap.get(infoDTO.getRegionCode())); + } + BigDecimal consumptionValue = null; + BigDecimal carbonValue = null; + BigDecimal lastConsumptionValue =null; + BigDecimal lastCarbonValue =null; + if (dataResult!=null && CollectionUtil.isNotEmpty(dataResult.get(infoDTO.getThingCode()))){ + List tsKvDTOS = dataResult.get(infoDTO.getThingCode()); + //以属性分组 + Map> dataResult1 = null; + if (CollectionUtil.isNotEmpty(tsKvDTOS)){ + dataResult1 = tsKvDTOS.stream().collect(Collectors.groupingBy(TsKvDTO::getAttrKey)); + if (dataResult1!=null){ + List tceTsKvDtos = new ArrayList<>(); + List coTsKvDtos = new ArrayList<>(); + if (dateType==0){ + tceTsKvDtos = dataResult1.get("tce_runyy"); + coTsKvDtos = dataResult1.get("CO2_runyy"); + }else{ + tceTsKvDtos = dataResult1.get("tce_runmm"); + coTsKvDtos = dataResult1.get("CO2_runmm"); + } + Map dataResult2 = null; + Map dataResult3 = null; + if (CollectionUtil.isNotEmpty(tceTsKvDtos)){ + dataResult2 = tceTsKvDtos.stream().filter(dto -> dto.getVal() != null) + .collect(Collectors.groupingBy(TsKvDTO::getTs, Collectors.mapping(TsKvDTO::getVal, + Collectors.reducing(BigDecimal.ZERO, BigDecimal::new, BigDecimal::add)))); + } + if (CollectionUtil.isNotEmpty(coTsKvDtos)){ + dataResult3 = coTsKvDtos.stream().filter(dto -> dto.getVal() != null) + .collect(Collectors.groupingBy(TsKvDTO::getTs, Collectors.mapping(TsKvDTO::getVal, + Collectors.reducing(BigDecimal.ZERO, BigDecimal::new, BigDecimal::add)))); + } + if (dataResult2!=null){ + if (ObjectUtil.isNotEmpty(dataResult2.get(currentDateTime))){ + consumptionValue = dataResult2.get(currentDateTime); + } + if (ObjectUtil.isNotEmpty(dataResult2.get(lastDateTime))){ + lastConsumptionValue = dataResult2.get(lastDateTime); + } + } + if (dataResult3!=null){ + if (ObjectUtil.isNotEmpty(dataResult3.get(currentDateTime))){ + carbonValue = dataResult3.get(currentDateTime); + } + if (ObjectUtil.isNotEmpty(dataResult3.get(lastDateTime))){ + lastCarbonValue = dataResult3.get(lastDateTime); + } + } + } + } + if (consumptionValue!=null){ + baseReportDTO.setTotalConsumption(consumptionValue.setScale(2,BigDecimal.ROUND_HALF_UP)); + } + if (carbonValue!=null){ + baseReportDTO.setTotalCarbon(carbonValue.setScale(2,BigDecimal.ROUND_HALF_UP)); + } + } + //获取增加值 + BigDecimal addValue =null; + BigDecimal lastAddValue =null; +// if (dateType==0){ +// //年增加值 +// addValue =iotValueAddedService.getValueByTenantCodeAndYear(infoDTO.getTenantCode(),year); +// lastAddValue = iotValueAddedService.getValueByTenantCodeAndYear(infoDTO.getTenantCode(),lastYear); +// }else{ +// //月增加值 +// addValue = iotValueAddedService.getValueByTenantCodeAndYearAndMonth(infoDTO.getTenantCode(),year,month); +// lastAddValue = iotValueAddedService.getValueByTenantCodeAndYearAndMonth(infoDTO.getTenantCode(),lastMonthYear,lastMonth); +// } + + if (dateType==0){ + addValue = iotEnergyConsumptionTargetService.getValueByYear(year,infoDTO.getTenantCode()); + lastAddValue = iotEnergyConsumptionTargetService.getValueByYear(lastYear,infoDTO.getTenantCode()); + }else{ + addValue = iotEnergyConsumptionTargetService.getValueByYearAndMonth(year,month,infoDTO.getTenantCode()); + lastAddValue = iotEnergyConsumptionTargetService.getValueByYearAndMonth(lastMonthYear,lastMonth,infoDTO.getTenantCode()); + } + //能耗强度 + BigDecimal consumptionIntensity = null; + BigDecimal lastConsumptionIntensity = null; + //碳排强度 + BigDecimal carbonIntensity = null; + BigDecimal lastCarbonIntensity = null; + if (addValue!=null && addValue.compareTo(BigDecimal.ZERO)!=0){ + if (consumptionValue!=null){ + consumptionIntensity = consumptionValue.divide(addValue,2,BigDecimal.ROUND_HALF_UP); + } + if (carbonValue !=null){ + carbonIntensity = carbonValue.divide(addValue,2,BigDecimal.ROUND_HALF_UP); + } + } + if (lastAddValue!=null && lastAddValue.compareTo(BigDecimal.ZERO)!=0){ + if (lastConsumptionValue!=null){ + lastConsumptionIntensity = lastConsumptionValue.divide(lastAddValue,2,BigDecimal.ROUND_HALF_UP); + } + if (lastCarbonValue !=null){ + lastCarbonIntensity = lastCarbonValue.divide(lastAddValue,2,BigDecimal.ROUND_HALF_UP); + } + } + baseReportDTO.setConsumptionIntensity(consumptionIntensity); + baseReportDTO.setCarbonIntensity(carbonIntensity); + //企业能效质量 + String consumptionQuality ="--" ; + StringBuilder str = new StringBuilder(); + //判断企业能效质量 + extracted(dateType, lastConsumptionValue, str, lastCarbonIntensity); + if (str.length()!=0 || str.length()>4){ + consumptionQuality = str.toString(); + } + baseReportDTO.setConsumptionQuality(consumptionQuality); + //能效达标 + String compliance ="--"; + BigDecimal consumptionIntensityCompare = null; + BigDecimal carbonIntensityCompare =null; + //计算能耗强度同比 + if (consumptionIntensity!=null && lastConsumptionIntensity!=null && lastConsumptionIntensity.compareTo(BigDecimal.ZERO)!=0){ + consumptionIntensityCompare = ((consumptionIntensity.subtract(lastConsumptionIntensity)).divide(lastConsumptionIntensity, 2, BigDecimal.ROUND_HALF_UP)); + } + //计算碳排强度同比 + if (carbonIntensity!=null && lastCarbonIntensity!=null && lastCarbonIntensity.compareTo(BigDecimal.ZERO)!=0){ + carbonIntensityCompare = ((carbonIntensity.subtract(lastCarbonIntensity)).divide(lastCarbonIntensity, 2, BigDecimal.ROUND_HALF_UP)); + } + if (consumptionIntensityCompare!=null && carbonIntensityCompare!=null){ + if (consumptionIntensityCompare.compareTo(new BigDecimal(-2.86))!=1 && carbonIntensityCompare.compareTo(new BigDecimal(-3.89))!=1){ + compliance ="达标"; + }else{ + compliance ="不达标"; + } + } + baseReportDTO.setCompliance(compliance); + result.add(baseReportDTO); + } + Comparator comparator = Comparator.comparing(RegionEnergyBaseReportDTO::getTotalConsumption, Comparator.nullsLast(Comparator.reverseOrder())); + List sortedList = result.stream() + .sorted(comparator) + .collect(Collectors.toList()); + return sortedList; + } + + @Override + public List getEnergyConsumptionList(Map params) { + List result = new ArrayList<>(); + UserDetail userDetail = SecurityUser.getUser(); + Long tenantCode = TenantContext.getTenantCode(userDetail); + params.put("tenantCode",tenantCode); + String date = null; + Long dateTime =null; + Integer dateType = null; + if (params!=null && ObjectUtil.isNotEmpty(params.get("dateType"))){ + dateType = Integer.valueOf(params.get("dateType").toString()); + date = params.get("date").toString(); + //年 + if (params.get("dateType").equals("0")){ + date = date+"-01-01 00:00:00"; + }else{ + //月 + date = date+"-01 00:00:00"; + } + dateTime = DateTimeUtils.dateToTimestamp(date); + } + + Map regionMap = new HashMap<>(); + Map pidParams = new HashMap<>(); + pidParams.put("pid","320581"); + //获取区域 + List list = sysRegionService.list(pidParams); + if (CollectionUtil.isNotEmpty(list)){ + for (SysRegionDTO sysRegionDTO:list){ + regionMap.put(sysRegionDTO.getId(),sysRegionDTO.getName()); + } + } + + List keys = new ArrayList<>(); + if (dateType==0){ + keys.add("tce_runyy"); + }else{ + keys.add("tce_runmm"); + } + + //获取属性的单位 + Map dictMap = new HashMap<>(); + /*List dictDTOList = iotThingDictService.getIotEntityDictDTOList("attr",keys); + if (CollectionUtils.isNotEmpty(dictDTOList)){ + for (IotThingDictDTO dictDTO:dictDTOList){ + dictMap.put(dictDTO.getCode(),dictDTO.getUnit()); + } + }*/ + //获取属性 + Map newParams = new HashMap<>(); + newParams.put("page",1); + newParams.put("limit",100); +// newParams.put("attrType","base"); +// //获取基础能源品种 +// PageData page = carbonEnergyDictRelationService.handlePage(newParams); +// List keyList = page.getList(); + PageData page = carbonEnergyVarietyService.pageCarbonEnergyVarietyDTO(params); + List keyList = page.getList(); + List newkeyList = new ArrayList<>(); + if (CollectionUtil.isNotEmpty(keyList)){ + for (CarbonEnergyVarietyDTO carbonEnergyDictRelationDTO:keyList){ + String code =carbonEnergyDictRelationDTO.getCode(); + String name =carbonEnergyDictRelationDTO.getName(); + CarbonEnergyDictRelationDTO carbonEnergyDictRelationDTO1 = new CarbonEnergyDictRelationDTO(); + String unit = getUnit(dictMap, code); + if (dateType==0){ + keys.add(code+"yy"); + carbonEnergyDictRelationDTO1.setAttrCode(code+"yy"); + carbonEnergyDictRelationDTO1.setAttrName(name+"用量"+unit); + newkeyList.add(carbonEnergyDictRelationDTO1); + if (!code.equals("B2") && !code.equals("F2")){ + keys.add("tce_"+code+"yy"); + CarbonEnergyDictRelationDTO carbonEnergyDictRelationDTO2 = new CarbonEnergyDictRelationDTO(); + carbonEnergyDictRelationDTO2.setAttrCode("tce_"+code+"yy"); + carbonEnergyDictRelationDTO2.setAttrName(name+"用量折标煤(tce)"); + newkeyList.add(carbonEnergyDictRelationDTO2); + } + }else{ + keys.add(code+"mm"); + carbonEnergyDictRelationDTO1.setAttrCode(code+"mm"); + carbonEnergyDictRelationDTO1.setAttrName(name+"用量"+unit); + newkeyList.add(carbonEnergyDictRelationDTO1); + if (!code.equals("B2")&&!code.equals("F2")){ + keys.add("tce_"+code+"mm"); + CarbonEnergyDictRelationDTO carbonEnergyDictRelationDTO2 = new CarbonEnergyDictRelationDTO(); + carbonEnergyDictRelationDTO2.setAttrCode("tce_"+code+"mm"); + carbonEnergyDictRelationDTO2.setAttrName(name+"用量折标煤(tce)"); + newkeyList.add(carbonEnergyDictRelationDTO2); + } + } + } + } + //获取企业的thing_code,行业门类,行业大类,区域 + List industryTenantInfoDTOS = sysTenantService.getTenantListByParams(params); + if (CollectionUtil.isEmpty(industryTenantInfoDTOS)){ + return result; + } + Map> codeAndKeyMap = new HashMap<>(); + for (RegionIndustryTenantInfoDTO tenantInfoDTO:industryTenantInfoDTOS){ + codeAndKeyMap.put(tenantInfoDTO.getThingCode(),keys); + } + //获取企业数据,并以thing_code分组 + List dataList = tsKvService.findTsKvByMultiMap(codeAndKeyMap,dateTime-1000L,dateTime+1000L,Boolean.FALSE); + Map> dataResult = null; + if (CollectionUtil.isNotEmpty(dataList)){ + dataResult = dataList.stream().collect(Collectors.groupingBy(TsKvDTO::getThingCode)); + } + for (RegionIndustryTenantInfoDTO infoDTO:industryTenantInfoDTOS){ + RegionEnergyConsumptionReportDTO reportDTO = new RegionEnergyConsumptionReportDTO(); + reportDTO.setOrgName(infoDTO.getTenantName()); + reportDTO.setTenantCode(infoDTO.getTenantCode()); + reportDTO.setRegionCode(infoDTO.getRegionCode()); + reportDTO.setThingCode(infoDTO.getThingCode()); + if (regionMap!=null && ObjectUtil.isNotEmpty(regionMap.get(infoDTO.getRegionCode()))){ + reportDTO.setRegionName(regionMap.get(infoDTO.getRegionCode())); + } + List dataList1 =null; + if (dataResult!=null && CollectionUtil.isNotEmpty(dataResult.get(infoDTO.getThingCode()))){ + dataList1 = dataResult.get(infoDTO.getThingCode()); + } + Map dataResult1 = null; + if (CollectionUtil.isNotEmpty(dataList1)){ + dataResult1 = dataList1.stream().filter(dto -> dto.getVal() != null) + .collect(Collectors.groupingBy(TsKvDTO::getAttrKey, Collectors.mapping(TsKvDTO::getVal, + Collectors.reducing(BigDecimal.ZERO, BigDecimal::new, BigDecimal::add)))); + } + BigDecimal consumption = null; + if (dataResult1!=null){ + if (dateType==0){ + if (dataResult1.get("tce_runyy")!=null){ + consumption = dataResult1.get("tce_runyy").setScale(2,BigDecimal.ROUND_HALF_UP); + } + }else{ + if (dataResult1.get("tce_runmm")!=null){ + consumption = dataResult1.get("tce_runmm").setScale(2,BigDecimal.ROUND_HALF_UP); + } + } + } + reportDTO.setTotalConsumption(consumption); + List keyValueList = new ArrayList<>(); + if (CollectionUtil.isNotEmpty(newkeyList)){ + for (CarbonEnergyDictRelationDTO relationDTO:newkeyList){ + RegionEnergyDetailExportExcel excel = new RegionEnergyDetailExportExcel(); + excel.setKey(relationDTO.getAttrName()); + BigDecimal value = null; + if (dataResult1!=null && dataResult1.get(relationDTO.getAttrCode())!=null){ + value = dataResult1.get(relationDTO.getAttrCode()); + excel.setValue(value.setScale(2,BigDecimal.ROUND_HALF_UP)); + } + keyValueList.add(excel); + } + } + reportDTO.setKeyValueList(keyValueList); + result.add(reportDTO); + } + return result; + } + + private static String getUnit(Map dictMap, String code) { + String unit =null; + if (dictMap !=null && ObjectUtil.isNotEmpty(dictMap.get(code))){ + unit = "("+ dictMap.get(code)+")"; + }else { + if (code.equals("A29")){ + unit = "(kWh)"; + }else if (code.equals("B2")){ + unit = "(t)"; + }else if (code.equals("C6")){ + unit = "(Nm³)"; + }else if(code.equals("E3")){ + unit = "(Nm³)"; + }else if (code.equals("F2")){ + unit = "(Nm³)"; + }else if (code.equals("J2")){ + unit = "(Nm³)"; + } + } + return unit; + } + + private static void extracted(Integer dateType, BigDecimal lastConsumptionValue, StringBuilder str, BigDecimal lastCarbonIntensity) { + if (dateType ==0){ + if (lastConsumptionValue !=null){ + //上年能耗5000以下,低碳 + if (lastConsumptionValue.compareTo(new BigDecimal(5000))==-1){ + str.append("低碳"); + }else if (lastConsumptionValue.compareTo(new BigDecimal(5000))==1 && lastConsumptionValue.compareTo(new BigDecimal(10000))!=1){ + //上年能耗5000-10000,中碳 + str.append("中碳"); + }else if (lastConsumptionValue.compareTo(new BigDecimal(10000))==1 ){ + //上年能耗大于10000,高碳 + str.append("高碳"); + } + } + if (lastCarbonIntensity !=null){ + //上年碳排强度0.6以下,高效 + if (lastCarbonIntensity.compareTo(new BigDecimal(0.6))==-1){ + str.append("高效"); + }else if (lastCarbonIntensity.compareTo(new BigDecimal(0.6))==1 && lastCarbonIntensity.compareTo(new BigDecimal(2.0))!=1){ + //上年碳排强度0.6-2.0,中效 + str.append("中效"); + }else if (lastCarbonIntensity.compareTo(new BigDecimal(2.0))==1 ){ + //上年碳排强度大于2.0,低效 + str.append("低效"); + } + } + }else { + //月度 + if (lastConsumptionValue !=null){ + //上年能耗5000以下,低碳 + if (lastConsumptionValue.compareTo(new BigDecimal(416))==-1){ + str.append("低碳"); + }else if (lastConsumptionValue.compareTo(new BigDecimal(416))==1 && lastConsumptionValue.compareTo(new BigDecimal(833))!=1){ + //上年能耗5000-10000,中碳 + str.append("中碳"); + }else if (lastConsumptionValue.compareTo(new BigDecimal(833))==1 ){ + //上年能耗大于10000,高碳 + str.append("高碳"); + } + } + if (lastCarbonIntensity !=null){ + //上年碳排强度0.6以下,高效 + if (lastCarbonIntensity.compareTo(new BigDecimal(0.6))==-1){ + str.append("高效"); + }else if (lastCarbonIntensity.compareTo(new BigDecimal(0.6))==1 && lastCarbonIntensity.compareTo(new BigDecimal(2.0))!=1){ + //上年碳排强度0.6-2.0,中效 + str.append("中效"); + }else if (lastCarbonIntensity.compareTo(new BigDecimal(2.0))==1 ){ + //上年碳排强度大于2.0,低效 + str.append("低效"); + } + } + } + } + + +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/service/impl/RegionEnergyWarningServiceImpl.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/service/impl/RegionEnergyWarningServiceImpl.java new file mode 100644 index 0000000..c31997a --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/regionalenterprises/regionalboard/service/impl/RegionEnergyWarningServiceImpl.java @@ -0,0 +1,643 @@ +package com.thing.qingyuan.regionalenterprises.regionalboard.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import com.thing.carbon.config.dto.CarbonEnergyDictRelationDTO; +import com.thing.carbon.config.service.CarbonEnergyDictRelationService; +import com.thing.qingyuan.regionalenterprises.consumptionTarget.service.IotValueAddedService; +import com.thing.qingyuan.regionalenterprises.regionalboard.dto.*; +import com.thing.qingyuan.regionalenterprises.regionalboard.service.RegionEnergyWarningService; +import com.thing.common.core.utils.DateTimeUtils; +import com.thing.common.core.web.response.PageData; +import com.thing.common.data.tskv.TsKvDTO; +import com.thing.common.tskv.service.TsKvService; +import com.thing.sys.biz.dto.SysRegionDTO; +import com.thing.sys.biz.service.SysIndustryTypeService; +import com.thing.sys.biz.service.SysRegionService; +import com.thing.sys.security.context.TenantContext; +import com.thing.sys.security.domain.SecurityUser; +import com.thing.sys.security.domain.UserDetail; +import com.thing.sys.tenant.dto.RegionIndustryTenantInfoDTO; +import com.thing.sys.tenant.service.SysTenantService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 昆山用能预警 + * + * @author xiezw + * @since 2023-08-08 + */ +@Service +public class RegionEnergyWarningServiceImpl implements RegionEnergyWarningService { + + @Autowired + private SysTenantService sysTenantService; + @Autowired + private SysRegionService sysRegionService; + @Autowired + private TsKvService tsKvService; + @Autowired + private SysIndustryTypeService sysIndustryTypeService; +// @Autowired +// private IotEnergyConsumptionTargetService iotEnergyConsumptionTargetService; + @Autowired + private CarbonEnergyDictRelationService carbonEnergyDictRelationService; + @Autowired + private IotValueAddedService iotValueAddedService; + + @Override + public List getRegionList() { + List result = new ArrayList<>(); + Map pidParams = new HashMap<>(); + pidParams.put("pid","320581"); + //获取区域 + List list = sysRegionService.list(pidParams); + if (CollectionUtil.isNotEmpty(list)){ + for (SysRegionDTO sysRegionDTO:list){ + RegionAreaInfoDTO regionAreaInfoDTO = new RegionAreaInfoDTO(); + regionAreaInfoDTO.setRegionCode(sysRegionDTO.getId()); + regionAreaInfoDTO.setRegionName(sysRegionDTO.getName()); + result.add(regionAreaInfoDTO); + } + } + return result; + } + + @Override + public List getEnergyWarningList(Map params) { + List result = new ArrayList<>(); + UserDetail userDetail = SecurityUser.getUser(); + Long tenantCode = TenantContext.getTenantCode(userDetail); + params.put("tenantCode",tenantCode); + String date = null; + Long dateTime =null; + Integer dateType = null; + if (params!=null && ObjectUtil.isNotEmpty(params.get("dateType"))){ + dateType = Integer.valueOf(params.get("dateType").toString()); + date = params.get("date").toString(); + //年 + if (params.get("dateType").equals("0")){ + date = date+"-01-01 00:00:00"; + }else{ + //月 + date = date+"-01 00:00:00"; + } + dateTime = DateTimeUtils.dateToTimestamp(date); + } + String year = date.substring(0,4); + String month = String.valueOf(Integer.valueOf(date.substring(5,7))); + Map regionMap = new HashMap<>(); + Map pidParams = new HashMap<>(); + pidParams.put("pid","320581"); + //获取区域 + List list = sysRegionService.list(pidParams); + if (CollectionUtil.isNotEmpty(list)){ + for (SysRegionDTO sysRegionDTO:list){ + regionMap.put(sysRegionDTO.getId(),sysRegionDTO.getName()); + } + } + + List keys = new ArrayList<>(); + if (dateType==0){ + keys.add("tce_runyy"); + }else{ + keys.add("tce_runmm"); + } + //获取企业的thing_code,行业门类,行业大类,区域 + List industryTenantInfoDTOS = sysTenantService.getTenantListByParams(params); + if (CollectionUtil.isEmpty(industryTenantInfoDTOS)){ + return result; + } + Map> codeAndKeyMap = new HashMap<>(); + for (RegionIndustryTenantInfoDTO tenantInfoDTO:industryTenantInfoDTOS){ + codeAndKeyMap.put(tenantInfoDTO.getThingCode(),keys); + } + //获取企业数据,并以thing_code分组合计 + List dataList = tsKvService.findTsKvByMultiMap(codeAndKeyMap,dateTime-1000L,dateTime+1000L,Boolean.FALSE); + Map dataResult = null; + if (CollectionUtil.isNotEmpty(dataList)){ + dataResult = dataList.stream().filter(dto -> dto.getVal() != null) + .collect(Collectors.groupingBy(TsKvDTO::getThingCode, Collectors.mapping(TsKvDTO::getVal, + Collectors.reducing(BigDecimal.ZERO, BigDecimal::new, BigDecimal::add)))); + } + for (RegionIndustryTenantInfoDTO infoDTO:industryTenantInfoDTOS){ + RegionEnergyWarningDataDTO warningDataDTO = new RegionEnergyWarningDataDTO(); + warningDataDTO.setOrgName(infoDTO.getTenantName()); + warningDataDTO.setTenantCode(infoDTO.getTenantCode()); + warningDataDTO.setRegionCode(infoDTO.getRegionCode()); + warningDataDTO.setThingCode(infoDTO.getThingCode()); + if (regionMap!=null && ObjectUtil.isNotEmpty(regionMap.get(infoDTO.getRegionCode()))){ + warningDataDTO.setRegionName(regionMap.get(infoDTO.getRegionCode())); + } + warningDataDTO.setIndustryCode(infoDTO.getIndustryType()); + String industryName = sysIndustryTypeService.getByCode(infoDTO.getIndustryCategory()); + warningDataDTO.setIndustryName(industryName); + BigDecimal consumptionValue = null; + if (dataResult!=null && ObjectUtil.isNotEmpty(dataResult.get(infoDTO.getThingCode()))){ + consumptionValue = dataResult.get(infoDTO.getThingCode()); + warningDataDTO.setTotalConsumption(consumptionValue); + } +// BigDecimal targetValue =null; +// if (dateType==0){ +// targetValue = iotEnergyConsumptionTargetService.getValueByYear(year,infoDTO.getTenantCode()); +// }else{ +// targetValue = iotEnergyConsumptionTargetService.getValueByYearAndMonth(year,month,infoDTO.getTenantCode()); +// } + + //获取控制目标 + BigDecimal targetValue =null; + if (dateType==0){ + //年控制目标 + targetValue =iotValueAddedService.getValueByTenantCodeAndYear(infoDTO.getTenantCode(),year); + }else{ + //月控制目标 + targetValue = iotValueAddedService.getValueByTenantCodeAndYearAndMonth(infoDTO.getTenantCode(),year,month); + } + + warningDataDTO.setTargetValue(targetValue); + if (consumptionValue!=null && targetValue!=null){ + BigDecimal totalConsumptionProcess = consumptionValue.divide(targetValue,2,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)); + if (totalConsumptionProcess!=null){ + warningDataDTO.setTotalConsumptionProcess(totalConsumptionProcess+"%"); + } + //超限 + if (consumptionValue.compareTo(targetValue)==1){ + warningDataDTO.setTotalConsumptionLimit(2); + warningDataDTO.setTotalConsumptionProcessLimit(2); + } + //临限 + if (consumptionValue.compareTo(targetValue)!=1 && consumptionValue.compareTo(targetValue.multiply(new BigDecimal(0.8)))==1){ + warningDataDTO.setTotalConsumptionLimit(1); + warningDataDTO.setTotalConsumptionProcessLimit(1); + } + } + result.add(warningDataDTO); + } + Comparator comparator = Comparator.comparing(RegionEnergyWarningDataDTO::getTotalConsumption, Comparator.nullsLast(Comparator.reverseOrder())); + List sortedList = result.stream() + .sorted(comparator) + .collect(Collectors.toList()); + Integer sort =1; + if (CollectionUtil.isNotEmpty(sortedList)){ + for (RegionEnergyWarningDataDTO warningDataDTO:sortedList){ + warningDataDTO.setSort(sort); + sort++; + } + } + return sortedList; + } + @Override + public List getIndustryList() { + List result = new ArrayList<>(); + UserDetail userDetail = SecurityUser.getUser(); + Long tenantCode = TenantContext.getTenantCode(userDetail); + List industryTenantInfoDTOS = sysTenantService.getByGroupTenantCode(tenantCode); + + if (CollectionUtil.isNotEmpty(industryTenantInfoDTOS)){ + //根据行业分组 + Map> industryTypeMap = industryTenantInfoDTOS.stream() + .collect(Collectors.groupingBy(RegionIndustryTenantInfoDTO::getIndustryCategory, + Collectors.mapping(RegionIndustryTenantInfoDTO::getThingCode, Collectors.toList()))); + for (Map.Entry> mapEntry : industryTypeMap.entrySet()) { + RegionIndustryInfoDTO industryInfoDTO = new RegionIndustryInfoDTO(); + industryInfoDTO.setIndustryCode(mapEntry.getKey()); + String industryName = sysIndustryTypeService.getByCode(mapEntry.getKey()); + industryInfoDTO.setIndustryName(industryName); + result.add(industryInfoDTO); + } + } + return result; + } + + @Override + public RegionMonthConsumptionDTO getMonthConsumptionProportion(Map params) { + RegionMonthConsumptionDTO result = new RegionMonthConsumptionDTO(); + List datas = new ArrayList<>(); + String date = params.get("date").toString()+"-01 00:00:00"; + Long dateTime = DateTimeUtils.dateToTimestamp(date); + String thingCode = params.get("thingCode").toString(); + //获取属性 + Map newParams = new HashMap<>(); + newParams.put("page",1); + newParams.put("limit",100); + newParams.put("attrType","base"); + //获取基础能源品种 + PageData page = carbonEnergyDictRelationService.handlePage(newParams); + List list = page.getList(); + if (CollectionUtil.isEmpty(list)){ + return result; + } + List keys = list.stream().map(item -> "tce_"+item.getAttrCode()+"mm").collect(Collectors.toList()); + Map> codeAndKeyMap = new HashMap<>(); + codeAndKeyMap.put(thingCode,keys); + //获取数据,并以属性分组 + Map dataMap = new HashMap<>(); + List dataList = tsKvService.findTsKvByMultiMap(codeAndKeyMap,dateTime-1000L,dateTime+1000L,Boolean.FALSE); + if (CollectionUtil.isNotEmpty(dataList)){ + dataMap = dataList.stream().filter(dto -> dto.getVal() != null) + .collect(Collectors.groupingBy(TsKvDTO::getAttrKey, Collectors.mapping(TsKvDTO::getVal, + Collectors.reducing(BigDecimal.ZERO, BigDecimal::new, BigDecimal::add)))); + } + BigDecimal totalValue = null; + for (CarbonEnergyDictRelationDTO dictRelationDTO:list){ + RegionMonthEnergyConsumptionDTO energyConsumptionDTO = new RegionMonthEnergyConsumptionDTO(); + energyConsumptionDTO.setKey(dictRelationDTO.getAttrCode()); + energyConsumptionDTO.setKeyName(dictRelationDTO.getAttrName()); + if (dataMap!=null && dataMap.get("tce_"+dictRelationDTO.getAttrCode()+"mm")!=null){ + BigDecimal value = dataMap.get("tce_"+dictRelationDTO.getAttrCode()+"mm"); + energyConsumptionDTO.setValue(value); + if (value!=null){ + totalValue = totalValue==null? BigDecimal.ZERO.add(value):totalValue.add(value); + } + } + datas.add(energyConsumptionDTO); + } + result.setTotalValue(totalValue); + if (CollectionUtil.isNotEmpty(datas)){ + if (totalValue!=null && totalValue.compareTo(BigDecimal.ZERO)!=0) + for (RegionMonthEnergyConsumptionDTO energyConsumptionDTO:datas){ + if (energyConsumptionDTO.getValue()!=null){ + energyConsumptionDTO.setProportion(energyConsumptionDTO.getValue().divide(totalValue,2,BigDecimal.ROUND_HALF_UP)+"%"); + } + } + } + result.setDatas(datas); + return result; + } + + @Override + public List getYearConsumptionAnalyse(Map params) { + List result = new ArrayList<>(); + String year = params.get("date").toString(); + String date = year+"-01-01 00:00:00"; + Long dateTime = DateTimeUtils.dateToTimestamp(date); + String date1 = year+"-12-01 00:00:00"; + Long dateTime1 = DateTimeUtils.dateToTimestamp(date1); + String thingCode = params.get("thingCode").toString(); + String tenantCode = params.get("tenantCode").toString(); + + List keys = new ArrayList<>(); + keys.add("tce_runmm"); + Map> codeAndKeyMap = new HashMap<>(); + codeAndKeyMap.put(thingCode,keys); + //获取数据,并以属性分组 + Map dataMap = new HashMap<>(); + List dataList = tsKvService.findTsKvByMultiMap(codeAndKeyMap,dateTime-1000L,dateTime1+1000L,Boolean.FALSE); + if (CollectionUtil.isNotEmpty(dataList)){ + dataMap = dataList.stream().filter(dto -> dto.getVal() != null) + .collect(Collectors.groupingBy(TsKvDTO::getTs, Collectors.mapping(TsKvDTO::getVal, + Collectors.reducing(BigDecimal.ZERO, BigDecimal::new, BigDecimal::add)))); + } + //拆分月份 + List monthList = DateTimeUtils.getMonthList(year); + for (String month:monthList){ + RegionYearEnergyConsumptionAnalyseDTO consumptionAnalyseDTO = new RegionYearEnergyConsumptionAnalyseDTO(); + consumptionAnalyseDTO.setDate(month); + Long monthTs = DateTimeUtils.dateToTimestamp(month+"-01 00:00:00"); + consumptionAnalyseDTO.setDate(month); + BigDecimal consumption = null; + if (CollectionUtil.isNotEmpty(dataMap)){ + if (dataMap.get(monthTs)!=null){ + consumption = dataMap.get(monthTs); + consumptionAnalyseDTO.setValue(dataMap.get(monthTs)); + } + } + month = String.valueOf(Integer.valueOf(date.substring(5,7))); + BigDecimal targetValue = iotValueAddedService.getValueByTenantCodeAndYearAndMonth(Long.valueOf(tenantCode),year,month); +// BigDecimal targetValue = iotEnergyConsumptionTargetService.getValueByYearAndMonth(year,month,Long.valueOf(tenantCode)); + consumptionAnalyseDTO.setTarget(targetValue); + consumptionAnalyseDTO.setWaring("0"); + if (consumption!=null && targetValue!=null && consumption.compareTo(targetValue)==1){ + consumptionAnalyseDTO.setWaring("1"); + } + result.add(consumptionAnalyseDTO); + } + return result; + } + + @Override + public RegionTotalConsumptionAnalyseDTO getConsumptionAnalyse(Map params) { + RegionTotalConsumptionAnalyseDTO result = new RegionTotalConsumptionAnalyseDTO(); + String thingCode = params.get("thingCode").toString(); + List currentYearDatas = new ArrayList<>(); + List lastYearDatas = new ArrayList<>(); + //年 + if (params.get("dateType").equals("0")){ + String year; + if (params!=null && ObjectUtil.isNotEmpty(params.get("date"))){ + year = params.get("date").toString(); + }else{ + year = DateTimeUtils.getCurrentYear(); + } + //今年月份 + List currentMonths = DateTimeUtils.getMonthList(year); + String lastYear = String.valueOf(Integer.parseInt(year)-1); + //去年月份 + List lastMonths = DateTimeUtils.getMonthList(lastYear); + Long lastYearStartTime = DateTimeUtils.dateToTimestamp(lastYear+"-01-01 00:00:00"); + Long currentYearEndTime = DateTimeUtils.dateToTimestamp(year+"-12-01 00:00:00"); + List keys = new ArrayList<>(); + keys.add("tce_runmm"); + Map> codeAndKeyMap = new HashMap<>(); + codeAndKeyMap.put(thingCode,keys); + + //获取数据,并以时间分组求和 + List dataList = tsKvService.findTsKvByMultiMap(codeAndKeyMap,lastYearStartTime-1000L,currentYearEndTime+1000L,Boolean.FALSE); + Map dataResult = new HashMap<>(); + if (CollectionUtil.isNotEmpty(dataList)){ + dataResult = dataList.stream().filter(dto -> dto.getVal() != null) + .collect(Collectors.groupingBy(TsKvDTO::getTs, Collectors.mapping(TsKvDTO::getVal, + Collectors.reducing(BigDecimal.ZERO, BigDecimal::new, BigDecimal::add)))); + } + + Map lastYearData = new HashMap<>(); + for (String month : lastMonths){ + RegionEnergyConsumptionDTO energyConsumptionDTO = new RegionEnergyConsumptionDTO(); + energyConsumptionDTO.setDate(month); + Long monthTs = DateTimeUtils.dateToTimestamp(month+"-01 00:00:00"); + BigDecimal value =null; + if (dataResult!=null && dataResult.get(monthTs)!=null){ + value = dataResult.get(monthTs); + energyConsumptionDTO.setValue(value); + } + lastYearData.put(month.substring(5),value); + lastYearDatas.add(energyConsumptionDTO); + } + for (String month : currentMonths){ + RegionEnergyConsumptionAnalyseDTO energyConsumptionDTO = new RegionEnergyConsumptionAnalyseDTO(); + energyConsumptionDTO.setDate(month); + Long monthTs = DateTimeUtils.dateToTimestamp(month+"-01 00:00:00"); + BigDecimal value = null; + if (dataResult!=null && dataResult.get(monthTs)!=null){ + value = dataResult.get(monthTs); + energyConsumptionDTO.setValue(value); + } + energyConsumptionDTO.setValue(value); + //计算同比 + if (value!=null && lastYearData!=null && lastYearData.get(month.substring(5))!=null && lastYearData.get(month.substring(5)).compareTo(BigDecimal.ZERO)!=0){ + BigDecimal lastValue = lastYearData.get(month.substring(5)); + BigDecimal yearOnYearGrowthRate = (value.subtract(lastValue)).divide(lastValue, 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100")); + energyConsumptionDTO.setYoy(yearOnYearGrowthRate+"%"); + //大于0上升,小于0下降 + if (yearOnYearGrowthRate.compareTo(BigDecimal.ZERO)==1){ + energyConsumptionDTO.setUpOrDown(1); + }else if (yearOnYearGrowthRate.compareTo(BigDecimal.ZERO)==-1){ + energyConsumptionDTO.setUpOrDown(0); + } + } + currentYearDatas.add(energyConsumptionDTO); + } + }else{ + //月 + String month = params.get("date").toString(); + + //当月所有天数 + List currentMonths = DateTimeUtils.getDatesOfMonth(month); + String lastMonth = DateTimeUtils.getLastMonth(month); + //上月所有天数 + List lastMonths = DateTimeUtils.getDatesOfMonth(lastMonth); + //上月开始时间,本月结束时间 + Long lastMonthStartTime = DateTimeUtils.dateToTimestamp(lastMonth+"-01 00:00:00"); + Long currentMonthEndTime = DateTimeUtils.getEndTime(month+"-01 00:00:00","0"); + List keys = new ArrayList<>(); + keys.add("tce_rundd"); + Map> codeAndKeyMap = new HashMap<>(); + codeAndKeyMap.put(thingCode,keys); + + //获取数据,并以时间分组求和 + List dataList = tsKvService.findTsKvByMultiMap(codeAndKeyMap,lastMonthStartTime-1000L,currentMonthEndTime+1000L,Boolean.FALSE); + Map dataResult = new HashMap<>(); + if (CollectionUtil.isNotEmpty(dataList)){ + dataResult = dataList.stream().filter(dto -> dto.getVal() != null) + .collect(Collectors.groupingBy(TsKvDTO::getTs, Collectors.mapping(TsKvDTO::getVal, + Collectors.reducing(BigDecimal.ZERO, BigDecimal::new, BigDecimal::add)))); + } + + Map lastYearData = new HashMap<>(); + for (String day : lastMonths){ + RegionEnergyConsumptionDTO energyConsumptionDTO = new RegionEnergyConsumptionDTO(); + energyConsumptionDTO.setDate(day); + Long dayTs = DateTimeUtils.dateToTimestamp(day+" 00:00:00"); + BigDecimal value =null; + if (dataResult!=null && dataResult.get(dayTs)!=null){ + value = dataResult.get(dayTs); + energyConsumptionDTO.setValue(value); + } + lastYearData.put(day.substring(8,10),value); + lastYearDatas.add(energyConsumptionDTO); + } + for (String day : currentMonths){ + RegionEnergyConsumptionAnalyseDTO energyConsumptionDTO = new RegionEnergyConsumptionAnalyseDTO(); + + energyConsumptionDTO.setDate(day); + Long dayTs = DateTimeUtils.dateToTimestamp(day+" 00:00:00"); + BigDecimal value = null; + if (dataResult!=null && dataResult.get(dayTs)!=null){ + value = dataResult.get(dayTs); + energyConsumptionDTO.setValue(value); + } + energyConsumptionDTO.setValue(value); + //计算同比 + if (value!=null && lastYearData!=null && lastYearData.get(day.substring(8,10))!=null && lastYearData.get(day.substring(8,10)).compareTo(BigDecimal.ZERO)!=0){ + BigDecimal lastValue = lastYearData.get(day.substring(8,10)); + BigDecimal yearOnYearGrowthRate = (value.subtract(lastValue)).divide(lastValue, 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100")); + energyConsumptionDTO.setYoy(yearOnYearGrowthRate+"%"); + //大于0上升,小于0下降 + if (yearOnYearGrowthRate.compareTo(BigDecimal.ZERO)==1){ + energyConsumptionDTO.setUpOrDown(1); + }else if (yearOnYearGrowthRate.compareTo(BigDecimal.ZERO)==-1){ + energyConsumptionDTO.setUpOrDown(0); + } + } + currentYearDatas.add(energyConsumptionDTO); + } + } + result.setCurrentYearDatas(currentYearDatas); + result.setLastYearDatas(lastYearDatas); + return result; + } + + @Override + public RegionConsumptionTargetDTO getConsumptionAndTarget(Map params) { + String tenantCode = params.get("tenantCode").toString(); + RegionConsumptionTargetDTO result = new RegionConsumptionTargetDTO(); + if (StringUtils.isBlank(tenantCode)){ + return result; + } + String date = null; + Long dateTime =null; + Integer dateType = null; + if (params!=null && ObjectUtil.isNotEmpty(params.get("dateType"))){ + dateType = Integer.valueOf(params.get("dateType").toString()); + date = params.get("date").toString(); + //年 + if (params.get("dateType").equals("0")){ + date = date+"-01-01 00:00:00"; + }else{ + //月 + date = date+"-01 00:00:00"; + } + dateTime = DateTimeUtils.dateToTimestamp(date); + } + String year = date.substring(0,4); + String month = String.valueOf(Integer.valueOf(date.substring(5,7))); + + List keys = new ArrayList<>(); + if (dateType==0){ + keys.add("tce_runyy"); + }else{ + keys.add("tce_runmm"); + } + String thingCode = params.get("thingCode").toString(); + + Map> codeAndKeyMap = new HashMap<>(); + codeAndKeyMap.put(thingCode,keys); + + //获取企业数据,并以thing_code分组合计 + List dataList = tsKvService.findTsKvByMultiMap(codeAndKeyMap,dateTime-1000L,dateTime+1000L,Boolean.FALSE); + + BigDecimal sumValue = null; + if (CollectionUtil.isNotEmpty(dataList)){ + TsKvDTO tsKvDTO = dataList.get(0); + if (StringUtils.isNotBlank(tsKvDTO.getVal())){ + sumValue = new BigDecimal(tsKvDTO.getVal()); + } + } + BigDecimal targetValue =null; +// if (dateType==0){ +// targetValue = iotEnergyConsumptionTargetService.getValueByYear(year,Long.valueOf(tenantCode)); +// }else{ +// targetValue = iotEnergyConsumptionTargetService.getValueByYearAndMonth(year,month,Long.valueOf(tenantCode)); +// } + if (dateType==0){ + //年控制目标 + targetValue =iotValueAddedService.getValueByTenantCodeAndYear(Long.valueOf(tenantCode),year); + }else{ + //月控制目标 + targetValue = iotValueAddedService.getValueByTenantCodeAndYearAndMonth(Long.valueOf(tenantCode),year,month); + } + result.setSumValue(sumValue); + result.setPlanValue(targetValue); + + return result; + } + + @Override + public RegionOrgConsumptionCompareDTO getOrgDataCompare(Map params) { + RegionOrgConsumptionCompareDTO result = new RegionOrgConsumptionCompareDTO(); + String originalDate = null; + String originalLastDate =null; + String originalbeforeLastDate = null; + + String date = null; + String lastDate =null; + String beforeLastDate = null; + Long currentDateTime =null; + Long lastDateTime =null; + Long beforeDateTime =null; + Integer dateType = null; + if (params!=null && ObjectUtil.isNotEmpty(params.get("dateType"))){ + dateType = Integer.valueOf(params.get("dateType").toString()); + date = params.get("date").toString(); + originalDate = params.get("date").toString(); + //年 + if (params.get("dateType").equals("0")){ + date = date+"-01-01 00:00:00"; + lastDate = Integer.valueOf(originalDate)-1+"-01-01 00:00:00"; + originalLastDate =String.valueOf(Integer.valueOf(originalDate)-1); + beforeLastDate = Integer.valueOf(originalDate)-2+"-01-01 00:00:00"; + originalbeforeLastDate = String.valueOf(Integer.valueOf(originalDate)-2); + }else{ + //月 + date = date+"-01 00:00:00"; + lastDate = DateTimeUtils.getLastMonth(originalDate)+"-01 00:00:00"; + originalLastDate = DateTimeUtils.getLastMonth(originalDate); + beforeLastDate = DateTimeUtils.getLastMonth(lastDate)+"-01 00:00:00"; + originalbeforeLastDate = DateTimeUtils.getLastMonth(lastDate); + } + currentDateTime = DateTimeUtils.dateToTimestamp(date); + lastDateTime = DateTimeUtils.dateToTimestamp(lastDate); + beforeDateTime = DateTimeUtils.dateToTimestamp(beforeLastDate); + } + List keys = new ArrayList<>(); + if (dateType==0){ + keys.add("tce_runyy"); + }else{ + keys.add("tce_runmm"); + } + String thingCode = params.get("thingCode").toString(); + + Map> codeAndKeyMap = new HashMap<>(); + codeAndKeyMap.put(thingCode,keys); + + //当期数据 + List dataList = tsKvService.findTsKvByMultiMap(codeAndKeyMap,currentDateTime-1000L,currentDateTime+1000L,Boolean.FALSE); + BigDecimal sumValue = null; + if (CollectionUtil.isNotEmpty(dataList)){ + TsKvDTO tsKvDTO = dataList.get(0); + if (StringUtils.isNotBlank(tsKvDTO.getVal())){ + sumValue = new BigDecimal(tsKvDTO.getVal()); + } + } + + //上期数据 + List dataList1 = tsKvService.findTsKvByMultiMap(codeAndKeyMap,lastDateTime-1000L,lastDateTime+1000L,Boolean.FALSE); + BigDecimal sumValue1 = null; + if (CollectionUtil.isNotEmpty(dataList1)){ + TsKvDTO tsKvDTO = dataList1.get(0); + if (StringUtils.isNotBlank(tsKvDTO.getVal())){ + sumValue1 = new BigDecimal(tsKvDTO.getVal()); + } + } + + //上上期数据 + List dataList2 = tsKvService.findTsKvByMultiMap(codeAndKeyMap,beforeDateTime-1000L,beforeDateTime+1000L,Boolean.FALSE); + BigDecimal sumValue2 = null; + if (CollectionUtil.isNotEmpty(dataList2)){ + TsKvDTO tsKvDTO = dataList2.get(0); + if (StringUtils.isNotBlank(tsKvDTO.getVal())){ + sumValue2 = new BigDecimal(tsKvDTO.getVal()); + } + } + BigDecimal totalValue =null; + if (sumValue!=null){ + totalValue = totalValue==null?BigDecimal.ZERO.add(sumValue):totalValue.add(sumValue); + } + if (sumValue1!=null){ + totalValue = totalValue==null?BigDecimal.ZERO.add(sumValue1):totalValue.add(sumValue1); + } + if (sumValue2!=null){ + totalValue = totalValue==null?BigDecimal.ZERO.add(sumValue2):totalValue.add(sumValue2); + } + String currentValueProportion =null; + String lastValueProportion =null; + String beforeLastValueProportion =null; + if (totalValue!=null && totalValue.compareTo(BigDecimal.ZERO)!=0){ + if (sumValue!=null){ + currentValueProportion = sumValue.divide(totalValue,2,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100))+"%"; + } + if (sumValue1!=null){ + lastValueProportion = sumValue1.divide(totalValue,2,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100))+"%"; + } + if (sumValue2!=null){ + beforeLastValueProportion = sumValue2.divide(totalValue,2,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100))+"%"; + } + } + result.setCurrentDate(originalDate); + result.setCurrentValue(sumValue); + result.setCurrentValueProportion(currentValueProportion); + result.setLastDate(originalLastDate); + result.setLastValue(sumValue1); + result.setLastValueProportion(lastValueProportion); + result.setBeforeLastDate(originalbeforeLastDate); + result.setBeforeLastValue(sumValue2); + result.setBeforeLastValueProportion(beforeLastValueProportion); + return result; + } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/ScreenData.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/ScreenData.java new file mode 100644 index 0000000..39cfa85 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/ScreenData.java @@ -0,0 +1,70 @@ +package com.thing.qingyuan.screen; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.List; + +/** + * @author SiYang + * @date 2024/01/30 9:04 + * @description + */ +@Data +@Accessors(chain = true) +@Schema(description = "大屏数据信息") +public class ScreenData { + + @Schema(description = "区域-物的id 充电站-充电站id 光伏-光伏设备id") + private Serializable id; + + @Schema(description = "标题名称") + private String name; + + @Schema(description = "图片地址") + private String img; + + @Schema(description = "经度") + private BigDecimal lon; + + @Schema(description = "纬度") + private BigDecimal lat; + + @Schema(description = "热力图展示的量:区域-年能耗总量 光伏-日发电量 充电桩-日充电量") + private BigDecimal measure; + + @Schema(description = "属性数据") + private List data; + + @Data + @Accessors(chain = true) + @NoArgsConstructor + public static class AttrData { + + @Schema(description = "属性主键") + private Long attrId; + + @Schema(description = "属性名称") + private String attrName; + + @Schema(description = "属性编码") + private String attrCode; + + @Schema(description = "属性单位") + private String attrUnit; + + @Schema(description = "属性值") + private String attrValue; + + public AttrData(String attrName, String attrCode, String attrUnit, String attrValue) { + this.attrName = attrName; + this.attrCode = attrCode; + this.attrUnit = attrUnit; + this.attrValue = attrValue; + } + } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationChargeStatus.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationChargeStatus.java new file mode 100644 index 0000000..2d564b6 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationChargeStatus.java @@ -0,0 +1,123 @@ +package com.thing.qingyuan.screen; + +import com.thing.qingyuan.chargeStation.entity.ConnectorInfoEntity; +import com.thing.common.data.tskv.TsKvDTO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author SiYang + * @date 2024/02/05 9:20 + * @description 充电枪充电状态 + */ +@Data +@Accessors(chain = true) +@Schema(description = "充电枪充电状态") +public class StationChargeStatus { + public static final String DAILY_DURATION_CODE = "A201dd"; + + /*------------(今日)充电状态------------*/ + @Schema(description = "额定功率") + private BigDecimal power = BigDecimal.ZERO; + + @Schema(description = "总枪数") + private Integer totalGunCount = 0; + + @Schema(description = "充电中的枪数量") + private Integer inChargingGunCount = 0; + + @Schema(description = "空闲枪数") + private Integer freeGunCount = 0; + + @Schema(description = "离线枪数") + private Integer offLineGunCount = 0; + + @Schema(description = "故障枪数") + private Integer milGunCount = 0; + + /*------------(昨日)使用率------------*/ + @Schema(description = "昨日使用率,单位 %") + private BigDecimal usagePercent; + + @Schema(description = "枪使用时长排名") + private List gunUsageDurations; + + @Data + @Accessors(chain = true) + @AllArgsConstructor + public static class GunUsageDuration { + @Schema(description = "枪名") + private String gunName; + + @Schema(description = "枪使用时长,单位 h") + private BigDecimal hours; + } + + public static StationChargeStatus assemble( + List gunList, List tskvList) { + // 初始化并计算充电状态相关数据 + StationChargeStatus chargeStatus = + gunList.stream() + .reduce( + new StationChargeStatus(), + StationChargeStatus::add, + (x, y) -> null); + + Map gunMap = + gunList.stream() + .collect( + Collectors.toMap( + ConnectorInfoEntity::getConnectorId, + ConnectorInfoEntity::getConnectorName, + (v1, v2) -> v1)); + + // 汇总使用率数据 + List gunUsageDurationList = + new ArrayList<>( + tskvList.stream() + .map(e -> new GunUsageDuration(gunMap.get(e.getThingCode()), getDuration(e))) + .toList()); + gunUsageDurationList.sort(Comparator.comparing(GunUsageDuration::getHours).reversed()); + + BigDecimal totalUsageHours = + gunUsageDurationList.stream() + .map(GunUsageDuration::getHours) + .reduce(BigDecimal::add) + .orElse(BigDecimal.ZERO); + + BigDecimal usagePercent = + totalUsageHours.divide( + BigDecimal.valueOf(24 * (long) chargeStatus.getTotalGunCount()), + 3, + RoundingMode.HALF_UP); + + return chargeStatus + .setUsagePercent(usagePercent.multiply(new BigDecimal("100"))) + .setGunUsageDurations(gunUsageDurationList); + } + + private StationChargeStatus add(ConnectorInfoEntity gunInfo) { + // 0:离网;1:空闲;2:占用(未充电);3:占用(充电中); 4:占用(预约锁定); 255:故障 + Integer status = gunInfo.getStatus(); + switch (status) { + case 0 -> setOffLineGunCount(offLineGunCount + 1); + case 1 -> setFreeGunCount(freeGunCount + 1); + case 3 -> setInChargingGunCount(inChargingGunCount + 1); + case 255 -> setMilGunCount(milGunCount + 1); + } + return setPower(power.add(gunInfo.getPower())).setTotalGunCount(totalGunCount + 1); + } + + private static BigDecimal getDuration(TsKvDTO tskv) { + BigDecimal milliSec = + BigDecimal.valueOf(Long.parseLong(Optional.ofNullable(tskv.getVal()).orElse("0"))); + return milliSec.divide(BigDecimal.valueOf(60 * 60 * 1000), 1, RoundingMode.HALF_UP); + } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationChargeTrend.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationChargeTrend.java new file mode 100644 index 0000000..cdb12ea --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationChargeTrend.java @@ -0,0 +1,170 @@ +package com.thing.qingyuan.screen; + +import cn.hutool.core.collection.CollectionUtil; +import com.thing.common.core.utils.DateTimeUtils; +import com.thing.common.data.tskv.TsKvDTO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @author SiYang + * @date 2024/02/04 16:49 + * @description 充电趋势(同比数据) 充电量: A29 充电时长: A201 充电次数: A202 + */ +@Data +@Accessors(chain = true) +@Schema(description = "充电趋势(同比数据)") +@NoArgsConstructor +public class StationChargeTrend { + public static final List DAILY_ATTR_CODES = List.of("A29dd", "A202dd", "A201dd"); + public static final List MONTH_ATTR_CODES = List.of("A29mm", "A202mm", "A201mm"); + + @Schema(description = "时间类型: month, year") + private String timeType; + + @Schema(description = "当期充电电量, 单位 kWh") + private List currentEnergy; + + @Schema(description = "前期充电电量, 单位 kWh") + private List previousEnergy; + + @Schema(description = "当期充电次数, 单位 次") + private List currentCount; + + @Schema(description = "前期充电次数, 单位 次") + private List previousCount; + + @Schema(description = "当期充电时长, 单位 h") + private List currentDuration; + + @Schema(description = "前期充电时长, 单位 h") + private List previousDuration; + + public StationChargeTrend(String timeType) { + this.timeType = timeType; + } + + /** + * 先按属性分组,再按时间分组 + * + * @param tskvList 包含电量、时长、次数, 本期与前一期所有数据的列表 + */ + public StationChargeTrend assemble(List tskvList) { + long startTs = isMonth() ? DateTimeUtils.monthStartTs() : DateTimeUtils.yearStartTs(); + Map>> attrTimeGroupMap = + tskvList.stream() + .collect( + Collectors.groupingBy( + TsKvDTO::getAttrKey, + Collectors.groupingBy(e -> e.getTs() > startTs))); + return setCurrentEnergy(convertEnergy(attrTimeGroupMap, true)) + .setPreviousEnergy(convertEnergy(attrTimeGroupMap, false)) + .setCurrentCount(convertCount(attrTimeGroupMap, true)) + .setPreviousCount(convertCount(attrTimeGroupMap, false)) + .setCurrentDuration(convertDuration(attrTimeGroupMap, true)) + .setPreviousDuration(convertDuration(attrTimeGroupMap, false)); + } + + private List convertEnergy( + Map>> attrTimeGroupMap, boolean isCurrentPeriod) { + return convert( + attrTimeGroupMap, + isCurrentPeriod, + (x, y) -> energyMap(x).get(y), + StationTsValue::toDefaultVal); + } + + private List convertCount( + Map>> attrTimeGroupMap, boolean isCurrentPeriod) { + return convert( + attrTimeGroupMap, + isCurrentPeriod, + (x, y) -> chargeCountMap(x).get(y), + StationTsValue::toDefaultVal); + } + + private List convertDuration( + Map>> attrTimeGroupMap, boolean isCurrentPeriod) { + return convert( + attrTimeGroupMap, + isCurrentPeriod, + (x, y) -> durationMap(x).get(y), + StationTsValue::toHour); + } + + /** + * 从 attrTimeGroupMap 中取出当期或前期数据, 并转化为 StationTsValue 格式 + * + * @param attrTimeGroupMap 全量tskv按属性分组,再按ts分组后的map + * @param isCurrentPeriod 是否是当期 + * @param tskvFilter 从attrTimeGroupMap中过滤出指定数据的函数 + * @param valueHandler 对于tskv的val的特殊处理函数 + * @return Ts-Value列表 + */ + private List convert( + Map>> attrTimeGroupMap, + boolean isCurrentPeriod, + BiFunction>>, Boolean, List> tskvFilter, + Function valueHandler) { + List tsList = isCurrentPeriod ? currentPeriodTsList() : previousPeriodTsList(); + List tskvList = tskvFilter.apply(attrTimeGroupMap, isCurrentPeriod); + if(CollectionUtil.isNotEmpty(tskvList)){ + Map tskvMap = + tskvList.stream().collect(Collectors.toMap(TsKvDTO::getTs, TsKvDTO::getVal)); + return tsList.stream() + .map(ts -> new StationTsValue(ts).setVal(valueHandler.apply(tskvMap.get(ts)))) + .collect(Collectors.toList()); + } + return null; + } + + private Map> energyMap( + Map>> attrTimeGroupMap) { + return Optional.ofNullable(attrTimeGroupMap.get(energyCode())).orElse(new HashMap<>()); + } + + private Map> chargeCountMap( + Map>> attrTimeGroupMap) { + return Optional.ofNullable(attrTimeGroupMap.get(chargeCountCode())).orElse(new HashMap<>()); + } + + private Map> durationMap( + Map>> attrTimeGroupMap) { + return Optional.ofNullable(attrTimeGroupMap.get(durationCode())).orElse(new HashMap<>()); + } + + private String energyCode() { + return isMonth() ? "A29dd" : "A29mm"; + } + + private String durationCode() { + return isMonth() ? "A201dd" : "A201mm"; + } + + private String chargeCountCode() { + return isMonth() ? "A202dd" : "A202mm"; + } + + private List currentPeriodTsList() { + return isMonth() ? DateTimeUtils.allTsInMonth() : DateTimeUtils.allTsInYear(); + } + + private List previousPeriodTsList() { + return isMonth() ? DateTimeUtils.allTsInLastMonth() : DateTimeUtils.allTsInLastYear(); + } + + public boolean isMonth() { + return "month".equals(timeType); + } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationDailyInfo.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationDailyInfo.java new file mode 100644 index 0000000..7bea2aa --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationDailyInfo.java @@ -0,0 +1,76 @@ +package com.thing.qingyuan.screen; + +import com.thing.qingyuan.chargeStation.dto.EquipmentInfoDTO; +import com.thing.qingyuan.chargeStation.entity.StationInfoEntity; +import com.thing.common.data.tskv.TsKvDTO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * @author SiYang + * @date 2024/02/04 15:04 + * @description 驾驶舱充电站简要统计信息 + */ +@Data +@Accessors(chain = true) +@Schema(description = "充电站日统计信息") +public class StationDailyInfo { + public static final List DAILY_ATTR_CODES = + List.of("A204dd", "A29dd", "A202dd", "A201dd"); + + @Schema(description = "充电站物编码") + private String thingCode; + + @Schema(description = "充电站名称") + private String thingName; + + @Schema(description = "充电站地址") + private String address; + + @Schema(description = "充电枪数量") + private Integer gunNum = 0; + + @Schema(description = "装机功率") + private BigDecimal installedPower = BigDecimal.ZERO; + + @Schema(description = "今日订单金额") + private BigDecimal fee = BigDecimal.ZERO; + + @Schema(description = "今日充电量") + private BigDecimal energy = BigDecimal.ZERO; + + @Schema(description = "今日充电次数") + private Integer count = 0; + + @Schema(description = "今日充电时长") + private BigDecimal duration = BigDecimal.ZERO; + + public static StationDailyInfo assemble( + StationInfoEntity station, EquipmentInfoDTO summedPile, List tskvList) { + Map kv = + tskvList.stream() + .collect( + Collectors.toMap( + TsKvDTO::getAttrKey, TsKvDTO::getVal, (x, y) -> y)); + + StationDailyInfo dailyInfo = new StationDailyInfo(); + if (Objects.nonNull(summedPile)) { + dailyInfo.setGunNum(summedPile.getGunNum()).setInstalledPower(summedPile.getPower()); + } + return dailyInfo + .setThingCode(station.getStationId()) + .setThingName(station.getStationName()) + .setAddress(station.getAddress()) + .setFee(StationTsValue.toDefaultVal(kv.get("A204dd"))) + .setEnergy(StationTsValue.toDefaultVal(kv.get("A29dd"))) + .setCount(StationTsValue.toDefaultVal(kv.get("A202dd")).intValue()) + .setDuration(StationTsValue.toHour(kv.get("A201dd"))); + } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationMapData.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationMapData.java new file mode 100644 index 0000000..5daae5e --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationMapData.java @@ -0,0 +1,106 @@ +package com.thing.qingyuan.screen; + +import com.thing.qingyuan.chargeStation.dto.StationSimpleDTO; +import com.thing.qingyuan.screen.ScreenData.AttrData; +import com.thing.common.data.tskv.TsKvDTO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * @author SiYang + * @date 2024/02/06 13:54 + * @description 充电站地图数据 + */ +@Data +@Accessors(chain = true) +public class StationMapData { + @Schema(description = "充电站id") + private String stationId; + + @Schema(description = "充电站名称") + private String stationName; + + @Schema(description = "经度") + private BigDecimal stationLng; + + @Schema(description = "纬度") + private BigDecimal stationLat; + + @Schema(description = "充电枪数量") + private int gunCount; + + @Schema(description = "正在充电的枪数量") + private int inChargingGunCount; + + @Schema(description = "今日充电量") + private BigDecimal energy = BigDecimal.ZERO; + + @Schema(description = "今日充电时长") + private BigDecimal hours = BigDecimal.ZERO; + + @Schema(description = "今日充电次数") + private BigDecimal count = BigDecimal.ZERO; + + @Schema(description = "今日订单金额") + private BigDecimal fee = BigDecimal.ZERO; + + public static List assemble( + List stationList, List tskvList) { + List mapDataList = + stationList.stream() + .map( + e -> + new StationMapData() + .setStationId(e.getStationId()) + .setStationName(e.getStationName()) + .setStationLng(e.getStationLng()) + .setStationLat(e.getStationLat()) + .setGunCount(e.getTotalGunCount()) + .setInChargingGunCount(e.getInChargingCount())) + .toList(); + Map> stationKv = + tskvList.stream() + .collect( + Collectors.groupingBy( + TsKvDTO::getThingCode, + Collectors.toMap( + TsKvDTO::getAttrKey, + TsKvDTO::getVal, + (x, y) -> x))); + + mapDataList.forEach( + e -> { + Map kv = stationKv.get(e.getStationId()); + if (Objects.isNull(kv)) { + return; + } + e.setFee(StationTsValue.toDefaultVal(kv.get("A204dd"))) + .setEnergy(StationTsValue.toDefaultVal(kv.get("A29dd"))) + .setCount(StationTsValue.toDefaultVal(kv.get("A202dd"))) + .setHours(StationTsValue.toHour(kv.get("A201dd"))); + }); + + return mapDataList; + } + + public ScreenData toScreenData() { + return new ScreenData() + .setId(getStationId()) + .setName(getStationName()) + .setLon(getStationLng()) + .setLat(getStationLat()) + .setData( + List.of( + new AttrData("今日充电量", "A29dd", "kWh", getEnergy().toString()), + new AttrData("今日充电时长", "A201dd", "h", getHours().toString()), + new AttrData("今日充电次数", "A202dd", "次", getCount().toString()), + new AttrData("今日订单金额", "A204dd", "元", getFee().toString()))); + } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationMonthChargeAnalysis.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationMonthChargeAnalysis.java new file mode 100644 index 0000000..a3d6119 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationMonthChargeAnalysis.java @@ -0,0 +1,59 @@ +package com.thing.qingyuan.screen; + +import com.thing.common.core.utils.DateTimeUtils; +import com.thing.common.data.tskv.TsKvDTO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @author SiYang + * @date 2024/02/04 16:49 + * @description 充电站月度充电分析数据 + */ +@Data +@Accessors(chain = true) +@Schema(description = "充电站月度充电分析数据") +public class StationMonthChargeAnalysis { + public static final List DAILY_ATTR_CODES = List.of("A29dd", "A202dd", "A201dd"); + + @Schema(description = "充电电量, 单位 kWh") + private List energy; + + @Schema(description = "充电次数, 单位 次") + private List count; + + @Schema(description = "充电时长, 单位 h") + private List duration; + + public static StationMonthChargeAnalysis assemble(List tskvList) { + Map> tskvMap = tskvList.stream().collect(Collectors.groupingBy(TsKvDTO::getAttrKey)); + List tsList = DateTimeUtils.allTsInMonth(); + return new StationMonthChargeAnalysis() + .setEnergy(convert(tsList, tskvMap.getOrDefault("A29dd", new ArrayList<>()), false)) + .setCount(convert(tsList, tskvMap.getOrDefault("A202dd", new ArrayList<>()), false)) + .setDuration(convert(tsList, tskvMap.getOrDefault("A201dd", new ArrayList<>()), true)); + } + + private static List convert(List allTs, List tskvList, boolean isDuration) { + Map tsValueMap = tskvList.stream().collect(Collectors.toMap(TsKvDTO::getTs, TsKvDTO::getVal)); + return allTs.stream() + .map( + ts -> { + String val = tsValueMap.get(ts); + StationTsValue tsVal = new StationTsValue(ts); + if (isDuration) { + tsVal.setDurationVal(val); + } else { + tsVal.setDefaultVal(val); + } + return tsVal; + }) + .collect(Collectors.toList()); + } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationMonthUsageAnalysis.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationMonthUsageAnalysis.java new file mode 100644 index 0000000..f0afb32 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationMonthUsageAnalysis.java @@ -0,0 +1,44 @@ +package com.thing.qingyuan.screen; + +import com.thing.common.core.utils.DateTimeUtils; +import com.thing.common.data.tskv.TsKvDTO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @author SiYang + * @date 2024/02/05 11:18 + * @description 充电站月度使用率分析 + */ +@Data +@Schema(description = "充电站月度使用率分析") +@AllArgsConstructor +public class StationMonthUsageAnalysis { + public static final String DAILY_DURATION_CODE = "A201dd"; + + @Schema(description = "本月每日使用率详情") + private List dailyUsageList; + + public static StationMonthUsageAnalysis assemble(List tskvList, Integer gunCount) { + Map tsValMap = + tskvList.stream().collect(Collectors.toMap(TsKvDTO::getTs, TsKvDTO::getVal)); + List tsList = DateTimeUtils.allTsInMonth(); + List usageList = + tsList.stream() + .map(ts -> new StationTsValue(ts, getUsagePercent(tsValMap.get(ts), gunCount).multiply(new BigDecimal("100")))) + .toList(); + return new StationMonthUsageAnalysis(usageList); + } + + private static BigDecimal getUsagePercent(String val, Integer gunCount) { + return StationTsValue.toHour(val) + .divide(BigDecimal.valueOf(gunCount * 24), 3, RoundingMode.HALF_UP); + } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationRank.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationRank.java new file mode 100644 index 0000000..3a90e5e --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationRank.java @@ -0,0 +1,80 @@ +package com.thing.qingyuan.screen; + +import com.thing.qingyuan.chargeStation.entity.StationInfoEntity; +import com.thing.common.data.tskv.TsKvDTO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; +import org.jetbrains.annotations.NotNull; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @author SiYang + * @date 2024/02/04 10:45 + * @description 充电站排名 + */ +@Data +@Accessors(chain = true) +@Schema(description = "充电站排名") +public class StationRank implements Comparable { + public static final String DAILY_ATTR_CODE = "A29dd"; + public static final String YEAR_ATTR_CODE = "A29yy"; + + @Schema(description = "充电站物编码") + private String thingCode; + + @Schema(description = "充电站物名称") + private String thingName; + + @Schema(description = "充电站今日充电量") + private String todayPower; + + @Schema(description = "充电站年度充电量") + private String yearPower; + + @Override + public int compareTo(@NotNull StationRank another) { + return (int) (another.numPower() - numPower()); + } + + public static List assemble( + Set stationIds, + Map stationMap, + List todayTskvList, + List yearTskvList) { + Map dailyTskvMap = groupTskv(todayTskvList); + Map yearTskvMap = groupTskv(yearTskvList); + return stationIds.stream() + .map( + thingCode -> + { + String stationVal = stationMap.containsKey(thingCode) ? stationMap.get(thingCode).getStationName() : BigDecimal.ZERO.toString(); + String dailyVal = dailyTskvMap.containsKey(thingCode) ? dailyTskvMap.get(thingCode).getVal() : BigDecimal.ZERO.toString(); + String yearPower = yearTskvMap.containsKey(thingCode) ? yearTskvMap.get(thingCode).getVal() : BigDecimal.ZERO.toString(); + String powerOfTK = BigDecimal.valueOf(Double.parseDouble(yearPower)).divide(BigDecimal.valueOf(10000), 4, RoundingMode.HALF_UP).toPlainString(); + return new StationRank() + .setThingCode(thingCode) + .setThingName(stationVal) + .setTodayPower(dailyVal) + .setYearPower(powerOfTK); + } + ).collect(Collectors.toList()); + } + + private static Map groupTskv(List tskvList) { + return tskvList.stream() + .collect(Collectors.toMap(TsKvDTO::getThingCode, Function.identity(), (x, y) -> y)); + } + + private Double numPower() { + return Double.parseDouble(Optional.ofNullable(todayPower).orElse("0")); + } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationSummary.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationSummary.java new file mode 100644 index 0000000..5cb3406 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationSummary.java @@ -0,0 +1,64 @@ +package com.thing.qingyuan.screen; + +import com.thing.common.data.tskv.TsKvDTO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * @author SiYang + * @date 2024/02/05 17:27 + * @description 全量充电站汇总信息 + */ +@Data +@Accessors(chain = true) +@Schema(description = "全量(年度)充电站汇总信息") +@NoArgsConstructor +public class StationSummary { + public static final List YEAR_ATTR_CODES = List.of("A29yy", "A202yy"); + + @Schema(description = "充电站数量") + private int stationCount; + + @Schema(description = "充电枪数量") + private int gunCount; + + @Schema(description = "年度充电量") + private BigDecimal yearEnergy = BigDecimal.ZERO; + + @Schema(description = "年度充电次数") + private BigDecimal yearChargeCount = BigDecimal.ZERO; + + public StationSummary(int stationCount, int gunCount) { + this.stationCount = stationCount; + this.gunCount = gunCount; + } + + public StationSummary assemble(List tskvList) { + Map kv = + tskvList.stream() + .collect( + Collectors.groupingBy( + TsKvDTO::getAttrKey, + Collectors.reducing( + BigDecimal.ZERO, + tskv -> convert(tskv.getVal()), + BigDecimal::add))); + // 单位换算 + BigDecimal yearPower = kv.get("A29yy").divide(BigDecimal.valueOf(10000), 4, RoundingMode.HALF_UP); + BigDecimal yearCount = kv.get("A202yy").divide(BigDecimal.valueOf(10000), 4, RoundingMode.HALF_UP); + return setYearEnergy(yearPower).setYearChargeCount(yearCount); + } + + private BigDecimal convert(String val) { + return BigDecimal.valueOf(Double.parseDouble(Optional.ofNullable(val).orElse("0"))); + } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationTsValue.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationTsValue.java new file mode 100644 index 0000000..c7ace75 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/StationTsValue.java @@ -0,0 +1,51 @@ +package com.thing.qingyuan.screen; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.Optional; + +/** + * @author SiYang + * @date 2024/02/05 14:01 + * @description 充电站属性数据定义 + */ +@Data +@Accessors(chain = true) +@AllArgsConstructor +@Schema(description = "时间数据") +public class StationTsValue { + @Schema(description = "数据时间戳") + private Long ts; + + @Schema(description = "数据值") + private BigDecimal val; + + public StationTsValue(Long ts) { + this.ts = ts; + } + + public void setDefaultVal(String val) { + BigDecimal numVal = + BigDecimal.valueOf(Double.parseDouble(Optional.ofNullable(val).orElse("0"))); + setVal(numVal); + } + + public void setDurationVal(String milliDuration) { + setVal(toHour(milliDuration)); + } + + public static BigDecimal toDefaultVal(String val) { + return BigDecimal.valueOf(Double.parseDouble(Optional.ofNullable(val).orElse("0"))); + } + + public static BigDecimal toHour(String milliDuration) { + BigDecimal milliSec = + BigDecimal.valueOf(Long.parseLong(Optional.ofNullable(milliDuration).orElse("0"))); + return milliSec.divide(BigDecimal.valueOf(60 * 60 * 1000), 1, RoundingMode.HALF_UP); + } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/controller/StationScreenController.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/controller/StationScreenController.java new file mode 100644 index 0000000..2138cb6 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/controller/StationScreenController.java @@ -0,0 +1,104 @@ +package com.thing.qingyuan.screen.controller; + +import com.thing.common.core.web.response.Result; +import com.thing.qingyuan.screen.*; +import com.thing.qingyuan.screen.service.StationScreenService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +/** + * 充电站信息 + * + * @author ssy 2337720667@qq.com + * @since 3.0 2024-01-23 + */ +@RestController +@RequestMapping("screen/station") +@Tag(name = "充电站驾驶舱") +@RequiredArgsConstructor +public class StationScreenController { + private final StationScreenService service; + + @GetMapping("rank") + @Operation(summary = "充电站排名") + public Result> getRank() { + List data = service.getRank(); + return new Result>().ok(data); + } + + @GetMapping("daily/info") + @Operation(summary = "充电站信息") + @Parameters({ + @Parameter(name = "thingCode", description = "充电站物编码"), + }) + public Result getDailyInfo(@Parameter(hidden = true) String thingCode) { + StationDailyInfo data = service.getDailyInfo(thingCode); + return new Result().ok(data); + } + + @GetMapping("month/charge/analysis") + @Operation(summary = "月度充电分析") + @Parameters({ + @Parameter(name = "thingCode", description = "充电站物编码"), + }) + public Result getMonthChargeAnalysis( + @Parameter(hidden = true) String thingCode) { + StationMonthChargeAnalysis data = service.getMonthChargeAnalysis(thingCode); + return new Result().ok(data); + } + + @GetMapping("charge/status") + @Operation(summary = "充电状态") + @Parameters({ + @Parameter(name = "thingCode", description = "充电站物编码"), + }) + public Result getChargeStatus(@Parameter(hidden = true) String thingCode) { + StationChargeStatus data = service.getChargeStatus(thingCode); + return new Result().ok(data); + } + + @GetMapping("month/usage/analysis") + @Operation(summary = "月度使用率分析") + @Parameters({ + @Parameter(name = "thingCode", description = "充电站物编码"), + }) + public Result getMonthUsageAnalysis( + @Parameter(hidden = true) String thingCode) { + StationMonthUsageAnalysis data = service.getMonthUsageAnalysis(thingCode); + return new Result().ok(data); + } + + @GetMapping("charge/trend") + @Operation(summary = "充电趋势") + @Parameters({ + @Parameter(name = "thingCode", description = "充电站物编码"), + @Parameter(name = "timeType", description = "时间类型: month, year"), + }) + public Result getChargeTrend( + @Parameter(hidden = true) String thingCode, @Parameter(hidden = true) String timeType) { + StationChargeTrend data = service.getChargeTrend(thingCode, timeType); + return new Result().ok(data); + } + + @GetMapping("summary") + @Operation(summary = "全量(年度)充电站汇总信息") + public Result getSummary() { + StationSummary data = service.getSummary(); + return new Result().ok(data); + } + + @GetMapping("map") + @Operation(summary = "地图数据") + public Result> getScreenData() { + List data = service.getScreenData(); + return new Result>().ok(data); + } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/service/StationScreenService.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/service/StationScreenService.java new file mode 100644 index 0000000..3fa3e16 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/service/StationScreenService.java @@ -0,0 +1,29 @@ +package com.thing.qingyuan.screen.service; + + +import com.thing.qingyuan.screen.*; + +import java.util.List; + +/** + * @author SiYang + * @date 2024/01/31 16:53 + * @description 充电站驾驶舱服务 + */ +public interface StationScreenService { + List getRank(); + + StationDailyInfo getDailyInfo(String thingCode); + + StationMonthChargeAnalysis getMonthChargeAnalysis(String thingCode); + + StationChargeStatus getChargeStatus(String thingCode); + + StationMonthUsageAnalysis getMonthUsageAnalysis(String thingCode); + + StationChargeTrend getChargeTrend(String thingCode, String timeType); + + StationSummary getSummary(); + + List getScreenData(); +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/service/impl/StationScreenServiceImpl.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/service/impl/StationScreenServiceImpl.java new file mode 100644 index 0000000..4e906e2 --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/screen/service/impl/StationScreenServiceImpl.java @@ -0,0 +1,179 @@ +package com.thing.qingyuan.screen.service.impl; + +import com.thing.common.core.utils.DateTimeUtils; +import com.thing.common.data.tskv.TsKvDTO; +import com.thing.common.tskv.service.TsKvService; +import com.thing.qingyuan.chargeStation.dto.EquipmentInfoDTO; +import com.thing.qingyuan.chargeStation.dto.StationSimpleDTO; +import com.thing.qingyuan.chargeStation.entity.ConnectorInfoEntity; +import com.thing.qingyuan.chargeStation.entity.StationInfoEntity; +import com.thing.qingyuan.chargeStation.service.ConnectorInfoService; +import com.thing.qingyuan.chargeStation.service.EquipmentInfoService; +import com.thing.qingyuan.chargeStation.service.StationInfoService; +import com.thing.qingyuan.screen.*; +import com.thing.qingyuan.screen.service.StationScreenService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @author SiYang + * @date 2024/01/31 16:53 + * @description 充电站驾驶舱服务实现类 + */ +@Service +@RequiredArgsConstructor +public class StationScreenServiceImpl implements StationScreenService { + private final TsKvService tsKvService; + private final StationInfoService stationInfoService; + private final EquipmentInfoService equipmentInfoService; + private final ConnectorInfoService connectorInfoService; + + @Override + public List getRank() { + List stationList = stationInfoService.getSimpleList(); + Map stationMap = + stationList.stream() + .collect( + Collectors.toMap( + StationInfoEntity::getStationId, Function.identity())); + Set stationIds = stationMap.keySet(); + + // daily数据 + Long todayStartTs = DateTimeUtils.todayStartTs(); + long endTs = System.currentTimeMillis(); + List todayTskvList = + tsKvService.findTsKvByCodesAndAttrs( + stationIds, + Collections.singletonList(StationRank.DAILY_ATTR_CODE), + todayStartTs, + endTs, + true); + + // year数据 + Long yearStartTs = DateTimeUtils.yearStartTs(); + List yearTskvList = + tsKvService.findTsKvByCodesAndAttrs( + stationIds, + Collections.singletonList(StationRank.YEAR_ATTR_CODE), + yearStartTs, + endTs, + true); + + List stationRanks = + StationRank.assemble(stationIds, stationMap, todayTskvList, yearTskvList); + stationRanks.sort(null); + return stationRanks; + } + + @Override + public StationDailyInfo getDailyInfo(String thingCode) { + StationInfoEntity station = stationInfoService.getById(thingCode); + List pileList = equipmentInfoService.getByStationId(thingCode); + EquipmentInfoDTO summedPile = pileList.stream().reduce(EquipmentInfoDTO::add).orElse(null); + List tskvList = + tsKvService.findTsKvByCodeAndAttrs( + thingCode, + StationDailyInfo.DAILY_ATTR_CODES, + DateTimeUtils.todayStartTs(), + System.currentTimeMillis(), + true); + return StationDailyInfo.assemble(station, summedPile, tskvList); + } + + @Override + public StationMonthChargeAnalysis getMonthChargeAnalysis(String thingCode) { + List tskvList = + tsKvService.findTsKvByCodeAndAttrs( + thingCode, + StationMonthChargeAnalysis.DAILY_ATTR_CODES, + DateTimeUtils.monthStartTs(), + System.currentTimeMillis(), + true); + return StationMonthChargeAnalysis.assemble(tskvList); + } + + @Override + public StationChargeStatus getChargeStatus(String thingCode) { + List simpleGunList = connectorInfoService.simpleList(thingCode); + List gunCodes = + simpleGunList.stream().map(ConnectorInfoEntity::getConnectorId).toList(); + List tskvList = + tsKvService.findTsKvByCodesAndAttrs( + gunCodes, + Collections.singletonList(StationChargeStatus.DAILY_DURATION_CODE), + DateTimeUtils.yesterdayStartTs(), + DateTimeUtils.todayStartTs(), + true); + return StationChargeStatus.assemble(simpleGunList, tskvList); + } + + @Override + public StationMonthUsageAnalysis getMonthUsageAnalysis(String thingCode) { + Integer gunCount = + connectorInfoService.getCountByStationIds(Collections.singletonList(thingCode)); + List tskvList = + tsKvService.findTsKvByCodeAndAttr( + thingCode, + StationChargeStatus.DAILY_DURATION_CODE, + DateTimeUtils.monthStartTs(), + DateTimeUtils.todayStartTs(), + true); + return StationMonthUsageAnalysis.assemble(tskvList, gunCount); + } + + @Override + public StationChargeTrend getChargeTrend(String thingCode, String timeType) { + StationChargeTrend chargeTrend = new StationChargeTrend(timeType); + boolean isMonth = chargeTrend.isMonth(); + + List codes = + isMonth ? StationChargeTrend.DAILY_ATTR_CODES : StationChargeTrend.MONTH_ATTR_CODES; + Long startTs = isMonth ? DateTimeUtils.lastMonthStartTs() : DateTimeUtils.lastYearStartTs(); + + List tskvList = + tsKvService.findTsKvByCodeAndAttrs( + thingCode, codes, startTs, System.currentTimeMillis(), true); + + return chargeTrend.assemble(tskvList); + } + + @Override + public StationSummary getSummary() { + long gunCount = connectorInfoService.count(); + List stationList = stationInfoService.getSimpleList(); + List stationIds = + stationList.stream().map(StationInfoEntity::getStationId).toList(); + + List tskvList = + tsKvService.findTsKvByCodesAndAttrs( + stationIds, + StationSummary.YEAR_ATTR_CODES, + DateTimeUtils.yearStartTs(), + System.currentTimeMillis(), + true); + + return new StationSummary(stationIds.size(), (int) gunCount).assemble(tskvList); + } + + @Override + public List getScreenData() { + List stationList = stationInfoService.getSimpleListWithGunStatus(); + List stationIds = stationList.stream().map(StationSimpleDTO::getStationId).toList(); + List tskvList = + tsKvService.findTsKvByCodesAndAttrs( + stationIds, + StationDailyInfo.DAILY_ATTR_CODES, + DateTimeUtils.todayStartTs(), + System.currentTimeMillis(), + true); + List mapDataList = StationMapData.assemble(stationList, tskvList); + return mapDataList.stream().map(StationMapData::toScreenData).collect(Collectors.toList()); + } +} diff --git a/modules/qingyuan/src/main/java/com/thing/qingyuan/util/CalculationUtil.java b/modules/qingyuan/src/main/java/com/thing/qingyuan/util/CalculationUtil.java new file mode 100644 index 0000000..aae40fe --- /dev/null +++ b/modules/qingyuan/src/main/java/com/thing/qingyuan/util/CalculationUtil.java @@ -0,0 +1,77 @@ +package com.thing.qingyuan.util; + +import cn.hutool.core.comparator.CompareUtil; + +import java.math.BigDecimal; +import java.math.RoundingMode; + +public class CalculationUtil { + + + /** + * 获取 年减排量 + * 或者今日减碳量 + * 或者年节能量 + * @param electricityUsage 用电量 + * @param reductionFactor 因子 比如0.475 + * @param coefficient 系数 + * @param scale 保留小数位数 + * @return electricityUsage* reductionFactor * coefficient + */ + public static BigDecimal getCarbonUsage(BigDecimal electricityUsage,BigDecimal reductionFactor,BigDecimal coefficient,Integer scale){ + return electricityUsage.multiply(reductionFactor).multiply(coefficient).setScale(scale, RoundingMode.HALF_UP); + } + + /** + * 获取 俩个数据的比值: + * 性能比 + * 或者消纳率 + * @param scale 保留小数位数 + * @return electricityUsage* reductionFactor * coefficient + */ + public static BigDecimal getPerformance (BigDecimal one,BigDecimal two,Integer scale){ + if(CompareUtil.compare(two,BigDecimal.ZERO) == 0 ){ + return BigDecimal.ZERO; + } + return one.divide(two,scale, RoundingMode.HALF_UP); + } + + /** + * 获取 获取俩个数据的同比 + * @param currentPeriod 本期数 + * @param previousPeriod 同期数 + * @return 同比 + */ +// public static BigDecimal getYOY(BigDecimal currentPeriod,BigDecimal previousPeriod){ +// if(CompareUtil.compare(previousPeriod,BigDecimal.ZERO) == 0 ){ +// return BigDecimal.ZERO; +// } +// return currentPeriod.subtract(previousPeriod).divide(previousPeriod).setScale(4, RoundingMode.HALF_UP) +// .multiply(new BigDecimal(100)); +// } + public static BigDecimal getYOY(BigDecimal currentPeriod, BigDecimal previousPeriod) { + if (CompareUtil.compare(previousPeriod, BigDecimal.ZERO) == 0) { + return BigDecimal.ZERO; + } + return currentPeriod.subtract(previousPeriod) + .divide(previousPeriod, 4, RoundingMode.HALF_UP) // 使用指定精度和取舍模式进行除法运算 + .multiply(new BigDecimal(100)); + } + + + /** + * 装机容量*日照小时数*衰减率得2次方 + * 性能比 + * @param capacity 装机容量 + * @param hour 日照小时数 + * @param attenuation 衰减率 + * @param scale scale + * @return capacity * hour * attenuation ^ scale + */ + public static BigDecimal theoryPowerGeneration(BigDecimal capacity ,BigDecimal hour,BigDecimal attenuation,Integer scale){ + BigDecimal decimal = new BigDecimal("1").subtract(attenuation); + BigDecimal result = capacity.multiply(hour).multiply(decimal).pow(scale); + return result.setScale(4,RoundingMode.UP); + } + +} diff --git a/modules/qingyuan/src/main/resources/application-changshu.yml b/modules/qingyuan/src/main/resources/application-changshu.yml new file mode 100644 index 0000000..2d448b0 --- /dev/null +++ b/modules/qingyuan/src/main/resources/application-changshu.yml @@ -0,0 +1,11 @@ +# 常熟江南集团业务配置 +qingyuan: + # 充电桩配置 + charge-station: + # 物关系 + relationId: 1752221447803006976 + # 运营商 + operators: + - id: MA264UBBX + name: 江南爱充电 + diff --git a/modules/qingyuan/src/main/resources/mapper/chargeStation/ChargeOrderDetailsMapper.xml b/modules/qingyuan/src/main/resources/mapper/chargeStation/ChargeOrderDetailsMapper.xml new file mode 100644 index 0000000..d3cf7d4 --- /dev/null +++ b/modules/qingyuan/src/main/resources/mapper/chargeStation/ChargeOrderDetailsMapper.xml @@ -0,0 +1,18 @@ + + + + + + + + diff --git a/modules/qingyuan/src/main/resources/mapper/chargeStation/ConnectorInfoMapper.xml b/modules/qingyuan/src/main/resources/mapper/chargeStation/ConnectorInfoMapper.xml new file mode 100644 index 0000000..4ddc04c --- /dev/null +++ b/modules/qingyuan/src/main/resources/mapper/chargeStation/ConnectorInfoMapper.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + diff --git a/modules/qingyuan/src/main/resources/mapper/chargeStation/EquipmentInfoMapper.xml b/modules/qingyuan/src/main/resources/mapper/chargeStation/EquipmentInfoMapper.xml new file mode 100644 index 0000000..cde7746 --- /dev/null +++ b/modules/qingyuan/src/main/resources/mapper/chargeStation/EquipmentInfoMapper.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/modules/qingyuan/src/main/resources/mapper/chargeStation/StationInfoMapper.xml b/modules/qingyuan/src/main/resources/mapper/chargeStation/StationInfoMapper.xml new file mode 100644 index 0000000..060871e --- /dev/null +++ b/modules/qingyuan/src/main/resources/mapper/chargeStation/StationInfoMapper.xml @@ -0,0 +1,22 @@ + + + + + + + + diff --git a/modules/qingyuan/src/main/resources/mapper/regionalenterprises/consumptionTarget/IotEnergyConsumptionTargetMapper.xml b/modules/qingyuan/src/main/resources/mapper/regionalenterprises/consumptionTarget/IotEnergyConsumptionTargetMapper.xml new file mode 100644 index 0000000..7e37fab --- /dev/null +++ b/modules/qingyuan/src/main/resources/mapper/regionalenterprises/consumptionTarget/IotEnergyConsumptionTargetMapper.xml @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + insert into iot_energy_consumption_target (tenant_code,creator,create_date,target_value,type,year,month) values + (#{iotEnergyConsumptionTargetEntity.tenantCode}, + #{iotEnergyConsumptionTargetEntity.creator}, + #{iotEnergyConsumptionTargetEntity.createDate}, + #{iotEnergyConsumptionTargetEntity.targetValue}, + #{iotEnergyConsumptionTargetEntity.type}, + #{iotEnergyConsumptionTargetEntity.year}, + #{iotEnergyConsumptionTargetEntity.month} + ) + + + + + + DELETE FROM iot_energy_consumption_target WHERE id IN + + #{ids} + + + + + + + + + + + + + diff --git a/modules/qingyuan/src/main/resources/mapper/regionalenterprises/consumptionTarget/IotValueAddedMapper.xml b/modules/qingyuan/src/main/resources/mapper/regionalenterprises/consumptionTarget/IotValueAddedMapper.xml new file mode 100644 index 0000000..27a6dd9 --- /dev/null +++ b/modules/qingyuan/src/main/resources/mapper/regionalenterprises/consumptionTarget/IotValueAddedMapper.xml @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + insert into iot_value_added (tenant_code,creator,create_date,added_value,type,year,month) values + (#{iotEnergyConsumptionTargetEntity.tenantCode}, + #{iotEnergyConsumptionTargetEntity.creator}, + #{iotEnergyConsumptionTargetEntity.createDate}, + #{iotEnergyConsumptionTargetEntity.addedValue}, + #{iotEnergyConsumptionTargetEntity.type}, + #{iotEnergyConsumptionTargetEntity.year}, + #{iotEnergyConsumptionTargetEntity.month} + ) + + + DELETE FROM iot_value_added WHERE id IN + + #{ids} + + + + + + + + + + + + + + diff --git a/modules/thing/src/main/java/com/thing/thing/model/thread/ThingModelExecutor.java b/modules/thing/src/main/java/com/thing/thing/model/thread/ThingModelExecutor.java new file mode 100644 index 0000000..a6b3cd3 --- /dev/null +++ b/modules/thing/src/main/java/com/thing/thing/model/thread/ThingModelExecutor.java @@ -0,0 +1,24 @@ +package com.thing.thing.model.thread; + + +import com.thing.common.util.thread.AbstractListeningExecutor; +import org.springframework.stereotype.Component; + +/** + * Author: SiYang + * Date: 2023/12/27 11:35 + * Description: 物模型/实体执行器 + */ +@Component +public class ThingModelExecutor extends AbstractListeningExecutor { + + @Override + public String getTaskName() { + return "thingModelTask"; + } + + @Override + protected int getThreadPollSize() { + return 5; + } +} diff --git a/modules/thing/src/main/java/com/thing/websocket/SimulateSocketEventListener.java b/modules/thing/src/main/java/com/thing/websocket/SimulateSocketEventListener.java new file mode 100644 index 0000000..409ad35 --- /dev/null +++ b/modules/thing/src/main/java/com/thing/websocket/SimulateSocketEventListener.java @@ -0,0 +1,110 @@ +package com.thing.websocket; + +import cn.hutool.core.collection.CollectionUtil; +import com.google.common.collect.Lists; +import com.thing.common.core.event.QueueSocketEvent; +import com.thing.common.data.dto.QueueMsgDTO; +import com.thing.common.data.tskv.TsKvDTO; +import com.thing.common.tskv.event.TsKvEvent; +import com.thing.common.tskv.service.TsKvService; +import com.thing.queue.util.Topics; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author zhenghh. 2022-10-21 + **/ +@Slf4j +@Component +public class SimulateSocketEventListener { + + + @Resource + private TsKvService tsKvService; + @Resource + private ApplicationEventPublisher publisher; + + @EventListener(QueueSocketEvent.class) + public void onBoardEvent(QueueSocketEvent event) { + List list = event.getList(); + if(CollectionUtil.isEmpty(list)){ + return; + } + List tsKvDTOList = new ArrayList<>(); + for (QueueMsgDTO queueMsgDTO : list) { + TsKvDTO tsKvDTO = new TsKvDTO(); + String thingCode = queueMsgDTO.getThingCode(); + if(StringUtils.equals("A_11003130_8",thingCode)){ + tsKvDTO.setThingCode("CO_527858751223365632"); + } else if(StringUtils.equals("A_11002079_136",thingCode)){ + tsKvDTO.setThingCode("CO_527860863864930304"); + } else if(StringUtils.equals("A_11002736_2",thingCode)){ + tsKvDTO.setThingCode("CO_527861769297723392"); + } else if(StringUtils.equals("A_10001513_3",thingCode)){ + tsKvDTO.setThingCode("CO_527862023594180608"); + } else if(StringUtils.equals("A_11003156_5",thingCode)){ + tsKvDTO.setThingCode("CO_527862443683086336"); + }else if(StringUtils.equals("A_11003969_7",thingCode)){ + tsKvDTO.setThingCode("CO_527863103161892864"); + }else if(StringUtils.equals("A_11004059_42",thingCode)){ + tsKvDTO.setThingCode("CO_527863564740853760"); + }else if(StringUtils.equals("A_11004019_5",thingCode)){ + tsKvDTO.setThingCode("CO_527864032657408000"); + }else if(StringUtils.equals("A_11003822_18",thingCode)){ + tsKvDTO.setThingCode("CO_527864769449820160"); + }else{ + continue; + } + tsKvDTO.setAttrKey(queueMsgDTO.getAttrKey()); + tsKvDTO.setTs(queueMsgDTO.getTs()); + tsKvDTO.setVal(queueMsgDTO.getVal()); + tsKvDTOList.add(tsKvDTO); + } for (QueueMsgDTO queueMsgDTO : list) { + TsKvDTO tsKvDTO = new TsKvDTO(); + String thingCode = queueMsgDTO.getThingCode(); + if(StringUtils.equals("A_11003130_8",thingCode) || StringUtils.equals("C_11000610_23",thingCode) || StringUtils.equals("B_11004323_3",thingCode) || StringUtils.equals("H_11003039_2",thingCode)){ + tsKvDTO.setThingCode("CO_527858751223365632"); //青原区 + } else if(StringUtils.equals("A_11002079_136",thingCode) || StringUtils.equals("C_10000424_24",thingCode) || StringUtils.equals("B_11000443_2",thingCode) || StringUtils.equals("H_11000598_4",thingCode)){ + tsKvDTO.setThingCode("CO_527860863864930304"); //天玉镇 + } else if(StringUtils.equals("A_11002736_2",thingCode) || StringUtils.equals("C_10000913_3",thingCode) || StringUtils.equals("B_10001247_1",thingCode) || StringUtils.equals("H_11000575_1",thingCode)){ + tsKvDTO.setThingCode("CO_527861769297723392"); //河东街道 + } else if(StringUtils.equals("A_10001513_3",thingCode) || StringUtils.equals("C_11002634_3",thingCode) || StringUtils.equals("B_11001089_1",thingCode) || StringUtils.equals("H_11003039_1",thingCode)){ + tsKvDTO.setThingCode("CO_527862023594180608"); //富滩镇 + } else if(StringUtils.equals("A_11003156_5",thingCode) || StringUtils.equals("C_11003447_1",thingCode) || StringUtils.equals("B_11004023_2",thingCode) || StringUtils.equals("H_11000575_1",thingCode)){ + tsKvDTO.setThingCode("CO_527862443683086336"); //值夏镇 + }else if(StringUtils.equals("A_11003969_7",thingCode) || StringUtils.equals("C_10000656_1",thingCode) || StringUtils.equals("B_11000742_88",thingCode) || StringUtils.equals("H_11003039_1",thingCode)){ + tsKvDTO.setThingCode("CO_527863103161892864"); //文陂镇 + }else if(StringUtils.equals("A_11004059_42",thingCode) || StringUtils.equals("C_11004059_42",thingCode) || StringUtils.equals("B_11004059_42",thingCode) || StringUtils.equals("H_11003039_1",thingCode)){ + tsKvDTO.setThingCode("CO_527863564740853760"); //新圩镇 + }else if(StringUtils.equals("A_11004019_5",thingCode) || StringUtils.equals("C_11003447_2",thingCode) || StringUtils.equals("B_11000836_88",thingCode) || StringUtils.equals("H_11000575_1",thingCode)){ + tsKvDTO.setThingCode("CO_527864032657408000"); //富田镇 + }else if(StringUtils.equals("A_11003822_18",thingCode) || StringUtils.equals("C_V0000059_2",thingCode) || StringUtils.equals("B_11004059_42",thingCode) || StringUtils.equals("H_11000598_4",thingCode)){ + tsKvDTO.setThingCode("CO_527864769449820160"); //东固畲族乡 + }else{ + continue; + } + tsKvDTO.setAttrKey(queueMsgDTO.getAttrKey()); + tsKvDTO.setTs(queueMsgDTO.getTs()); + tsKvDTO.setVal(queueMsgDTO.getVal()); + tsKvDTOList.add(tsKvDTO); + } + //send 队列 + publisher.publishEvent(new TsKvEvent(Topics.V1_TSKV_HISTORY.getValue(), TsKvDTO.toDataProtoList(tsKvDTOList))); + Map> collect = tsKvDTOList.stream().collect(Collectors.groupingBy(TsKvDTO::getThingCode)); + for (Map.Entry> entry : collect.entrySet()) { + + Optional max = entry.getValue().stream().max(Comparator.comparing(TsKvDTO::getTs)); + + TsKvDTO tsKvDTO = max.get(); + publisher.publishEvent(new TsKvEvent(Topics.V1_TSKV_LATEST.getValue(), TsKvDTO.toDataProtoList(Lists.newArrayList(tsKvDTO)))); + } + } + +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index f02b49e..995f652 100644 --- a/pom.xml +++ b/pom.xml @@ -613,25 +613,25 @@ com.thing.modules - carbon-public + qingyuan ${project.version} com.thing.modules - cqc-service + carbon-public ${project.version} com.thing.modules - visual-design + cqc-service ${project.version} - com.thing.modules - cbam + visual-design ${project.version} + com.thing.tools